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