1// RUN: mlir-opt -allow-unregistered-dialect -split-input-file -convert-std-to-spirv -canonicalize -verify-diagnostics %s -o - | FileCheck %s
2
3//===----------------------------------------------------------------------===//
4// std allocation/deallocation ops
5//===----------------------------------------------------------------------===//
6
7module attributes {
8  spv.target_env = #spv.target_env<
9    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
10  }
11{
12  func @alloc_dealloc_workgroup_mem(%arg0 : index, %arg1 : index) {
13    %0 = alloc() : memref<4x5xf32, 3>
14    %1 = load %0[%arg0, %arg1] : memref<4x5xf32, 3>
15    store %1, %0[%arg0, %arg1] : memref<4x5xf32, 3>
16    dealloc %0 : memref<4x5xf32, 3>
17    return
18  }
19}
20//     CHECK: spv.globalVariable @[[VAR:.+]] : !spv.ptr<!spv.struct<(!spv.array<20 x f32, stride=4>)>, Workgroup>
21//     CHECK: func @alloc_dealloc_workgroup_mem
22// CHECK-NOT:   alloc
23//     CHECK:   %[[PTR:.+]] = spv.mlir.addressof @[[VAR]]
24//     CHECK:   %[[LOADPTR:.+]] = spv.AccessChain %[[PTR]]
25//     CHECK:   %[[VAL:.+]] = spv.Load "Workgroup" %[[LOADPTR]] : f32
26//     CHECK:   %[[STOREPTR:.+]] = spv.AccessChain %[[PTR]]
27//     CHECK:   spv.Store "Workgroup" %[[STOREPTR]], %[[VAL]] : f32
28// CHECK-NOT:   dealloc
29//     CHECK:   spv.Return
30
31// -----
32
33module attributes {
34  spv.target_env = #spv.target_env<
35    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
36  }
37{
38  func @alloc_dealloc_workgroup_mem(%arg0 : index, %arg1 : index) {
39    %0 = alloc() : memref<4x5xi16, 3>
40    %1 = load %0[%arg0, %arg1] : memref<4x5xi16, 3>
41    store %1, %0[%arg0, %arg1] : memref<4x5xi16, 3>
42    dealloc %0 : memref<4x5xi16, 3>
43    return
44  }
45}
46
47//       CHECK: spv.globalVariable @__workgroup_mem__{{[0-9]+}}
48//  CHECK-SAME:   !spv.ptr<!spv.struct<(!spv.array<20 x i32, stride=4>)>, Workgroup>
49// CHECK_LABEL: spv.func @alloc_dealloc_workgroup_mem
50//       CHECK:   %[[VAR:.+]] = spv.mlir.addressof @__workgroup_mem__0
51//       CHECK:   %[[LOC:.+]] = spv.SDiv
52//       CHECK:   %[[PTR:.+]] = spv.AccessChain %[[VAR]][%{{.+}}, %[[LOC]]]
53//       CHECK:   %{{.+}} = spv.Load "Workgroup" %[[PTR]] : i32
54//       CHECK:   %[[LOC:.+]] = spv.SDiv
55//       CHECK:   %[[PTR:.+]] = spv.AccessChain %[[VAR]][%{{.+}}, %[[LOC]]]
56//       CHECK:   %{{.+}} = spv.AtomicAnd "Workgroup" "AcquireRelease" %[[PTR]], %{{.+}} : !spv.ptr<i32, Workgroup>
57//       CHECK:   %{{.+}} = spv.AtomicOr "Workgroup" "AcquireRelease" %[[PTR]], %{{.+}} : !spv.ptr<i32, Workgroup>
58
59
60// -----
61
62module attributes {
63  spv.target_env = #spv.target_env<
64    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
65  }
66{
67  func @two_allocs() {
68    %0 = alloc() : memref<4x5xf32, 3>
69    %1 = alloc() : memref<2x3xi32, 3>
70    return
71  }
72}
73
74//  CHECK-DAG: spv.globalVariable @__workgroup_mem__{{[0-9]+}}
75// CHECK-SAME:   !spv.ptr<!spv.struct<(!spv.array<6 x i32, stride=4>)>, Workgroup>
76//  CHECK-DAG: spv.globalVariable @__workgroup_mem__{{[0-9]+}}
77// CHECK-SAME:   !spv.ptr<!spv.struct<(!spv.array<20 x f32, stride=4>)>, Workgroup>
78//      CHECK: spv.func @two_allocs()
79//      CHECK: spv.Return
80
81// -----
82
83module attributes {
84  spv.target_env = #spv.target_env<
85    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
86  }
87{
88  func @two_allocs_vector() {
89    %0 = alloc() : memref<4xvector<4xf32>, 3>
90    %1 = alloc() : memref<2xvector<2xi32>, 3>
91    return
92  }
93}
94
95//  CHECK-DAG: spv.globalVariable @__workgroup_mem__{{[0-9]+}}
96// CHECK-SAME:   !spv.ptr<!spv.struct<(!spv.array<2 x vector<2xi32>, stride=8>)>, Workgroup>
97//  CHECK-DAG: spv.globalVariable @__workgroup_mem__{{[0-9]+}}
98// CHECK-SAME:   !spv.ptr<!spv.struct<(!spv.array<4 x vector<4xf32>, stride=16>)>, Workgroup>
99//      CHECK: spv.func @two_allocs_vector()
100//      CHECK: spv.Return
101
102
103// -----
104
105module attributes {
106  spv.target_env = #spv.target_env<
107    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
108  }
109{
110  func @alloc_dealloc_dynamic_workgroup_mem(%arg0 : index) {
111    // expected-error @+2 {{unhandled allocation type}}
112    // expected-error @+1 {{'std.alloc' op operand #0 must be index}}
113    %0 = alloc(%arg0) : memref<4x?xf32, 3>
114    return
115  }
116}
117
118// -----
119
120module attributes {
121  spv.target_env = #spv.target_env<
122    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
123  }
124{
125  func @alloc_dealloc_mem() {
126    // expected-error @+1 {{unhandled allocation type}}
127    %0 = alloc() : memref<4x5xf32>
128    return
129  }
130}
131
132
133// -----
134
135module attributes {
136  spv.target_env = #spv.target_env<
137    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
138  }
139{
140  func @alloc_dealloc_dynamic_workgroup_mem(%arg0 : memref<4x?xf32, 3>) {
141    // expected-error @+2 {{unhandled deallocation type}}
142    // expected-error @+1 {{'std.dealloc' op operand #0 must be memref of any type values}}
143    dealloc %arg0 : memref<4x?xf32, 3>
144    return
145  }
146}
147
148// -----
149
150module attributes {
151  spv.target_env = #spv.target_env<
152    #spv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, {}>
153  }
154{
155  func @alloc_dealloc_mem(%arg0 : memref<4x5xf32>) {
156    // expected-error @+2 {{unhandled deallocation type}}
157    // expected-error @+1 {{op operand #0 must be memref of any type values}}
158    dealloc %arg0 : memref<4x5xf32>
159    return
160  }
161}
162