xref: /llvm-project/mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir (revision bdf00e2216280edef1ec91ccc07987db92197b59)
1// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
2
3//===----------------------------------------------------------------------===//
4// spirv.AccessChain
5//===----------------------------------------------------------------------===//
6
7// CHECK-LABEL: @access_chain
8spirv.func @access_chain() "None" {
9  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i32
10  %0 = spirv.Constant 1: i32
11  %1 = spirv.Variable : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>
12  // CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i32) : i32
13  // CHECK: llvm.getelementptr %{{.*}}[%[[ZERO]], 1, %[[ONE]]] : (!llvm.ptr, i32, i32) -> !llvm.ptr, !llvm.struct<packed (f32, array<4 x f32>)>
14  %2 = spirv.AccessChain %1[%0, %0] : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>, i32, i32 -> !spirv.ptr<f32, Function>
15  spirv.Return
16}
17
18// CHECK-LABEL: @access_chain_array
19spirv.func @access_chain_array(%arg0 : i32) "None" {
20  %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>
21  // CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i32) : i32
22  // CHECK: llvm.getelementptr %{{.*}}[%[[ZERO]], %{{.*}}] : (!llvm.ptr, i32, i32) -> !llvm.ptr, !llvm.array<4 x array<4 x f32>>
23  %1 = spirv.AccessChain %0[%arg0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32 -> !spirv.ptr<!spirv.array<4xf32>, Function>
24  %2 = spirv.Load "Function" %1 ["Volatile"] : !spirv.array<4xf32>
25  spirv.Return
26}
27
28//===----------------------------------------------------------------------===//
29// spirv.GlobalVariable and spirv.mlir.addressof
30//===----------------------------------------------------------------------===//
31
32spirv.module Logical GLSL450 {
33  // CHECK: llvm.mlir.global external constant @var() {addr_space = 0 : i32} : f32
34  spirv.GlobalVariable @var : !spirv.ptr<f32, Input>
35}
36
37spirv.module Logical GLSL450 {
38  //       CHECK: llvm.mlir.global private @struct() {addr_space = 0 : i32} : !llvm.struct<packed (f32, array<10 x f32>)>
39  // CHECK-LABEL: @func
40  //       CHECK:   llvm.mlir.addressof @struct : !llvm.ptr
41  spirv.GlobalVariable @struct : !spirv.ptr<!spirv.struct<(f32, !spirv.array<10xf32>)>, Private>
42  spirv.func @func() "None" {
43    %0 = spirv.mlir.addressof @struct : !spirv.ptr<!spirv.struct<(f32, !spirv.array<10xf32>)>, Private>
44    spirv.Return
45  }
46}
47
48spirv.module Logical GLSL450 {
49  //       CHECK: llvm.mlir.global external @bar_descriptor_set0_binding0() {addr_space = 0 : i32} : i32
50  // CHECK-LABEL: @foo
51  //       CHECK:   llvm.mlir.addressof @bar_descriptor_set0_binding0 : !llvm.ptr
52  spirv.GlobalVariable @bar bind(0, 0) : !spirv.ptr<i32, StorageBuffer>
53  spirv.func @foo() "None" {
54    %0 = spirv.mlir.addressof @bar : !spirv.ptr<i32, StorageBuffer>
55    spirv.Return
56  }
57}
58
59spirv.module @name Logical GLSL450 {
60  //       CHECK: llvm.mlir.global external @name_bar_descriptor_set0_binding0() {addr_space = 0 : i32} : i32
61  // CHECK-LABEL: @foo
62  //       CHECK:   llvm.mlir.addressof @name_bar_descriptor_set0_binding0 : !llvm.ptr
63  spirv.GlobalVariable @bar bind(0, 0) : !spirv.ptr<i32, StorageBuffer>
64  spirv.func @foo() "None" {
65    %0 = spirv.mlir.addressof @bar : !spirv.ptr<i32, StorageBuffer>
66    spirv.Return
67  }
68}
69
70spirv.module Logical GLSL450 {
71  // CHECK: llvm.mlir.global external @bar() {addr_space = 0 : i32, location = 1 : i32} : i32
72  // CHECK-LABEL: @foo
73  spirv.GlobalVariable @bar {location = 1 : i32} : !spirv.ptr<i32, Output>
74  spirv.func @foo() "None" {
75    %0 = spirv.mlir.addressof @bar : !spirv.ptr<i32, Output>
76    spirv.Return
77  }
78}
79
80spirv.module Logical GLSL450 {
81  // CHECK: llvm.mlir.global external constant @bar() {addr_space = 0 : i32, location = 3 : i32} : f32
82  // CHECK-LABEL: @foo
83  spirv.GlobalVariable @bar {descriptor_set = 0 : i32, location = 3 : i32} : !spirv.ptr<f32, UniformConstant>
84  spirv.func @foo() "None" {
85    %0 = spirv.mlir.addressof @bar : !spirv.ptr<f32, UniformConstant>
86    spirv.Return
87  }
88}
89
90//===----------------------------------------------------------------------===//
91// spirv.Load
92//===----------------------------------------------------------------------===//
93
94// CHECK-LABEL: @load
95spirv.func @load() "None" {
96  %0 = spirv.Variable : !spirv.ptr<f32, Function>
97  //  CHECK: llvm.load %{{.*}} : !llvm.ptr -> f32
98  %1 = spirv.Load "Function" %0 : f32
99  spirv.Return
100}
101
102// CHECK-LABEL: @load_none
103spirv.func @load_none() "None" {
104  %0 = spirv.Variable : !spirv.ptr<f32, Function>
105  //  CHECK: llvm.load %{{.*}} : !llvm.ptr -> f32
106  %1 = spirv.Load "Function" %0 ["None"] : f32
107  spirv.Return
108}
109
110// CHECK-LABEL: @load_with_alignment
111spirv.func @load_with_alignment() "None" {
112  %0 = spirv.Variable : !spirv.ptr<f32, Function>
113  // CHECK: llvm.load %{{.*}} {alignment = 4 : i64} : !llvm.ptr -> f32
114  %1 = spirv.Load "Function" %0 ["Aligned", 4] : f32
115  spirv.Return
116}
117
118// CHECK-LABEL: @load_volatile
119spirv.func @load_volatile() "None" {
120  %0 = spirv.Variable : !spirv.ptr<f32, Function>
121  // CHECK: llvm.load volatile %{{.*}} : !llvm.ptr -> f32
122  %1 = spirv.Load "Function" %0 ["Volatile"] : f32
123  spirv.Return
124}
125
126// CHECK-LABEL: @load_nontemporal
127spirv.func @load_nontemporal() "None" {
128  %0 = spirv.Variable : !spirv.ptr<f32, Function>
129  // CHECK: llvm.load %{{.*}} {nontemporal} : !llvm.ptr -> f32
130  %1 = spirv.Load "Function" %0 ["Nontemporal"] : f32
131  spirv.Return
132}
133
134//===----------------------------------------------------------------------===//
135// spirv.Store
136//===----------------------------------------------------------------------===//
137
138// CHECK-LABEL: @store
139spirv.func @store(%arg0 : f32) "None" {
140  %0 = spirv.Variable : !spirv.ptr<f32, Function>
141  // CHECK: llvm.store %{{.*}}, %{{.*}} : f32, !llvm.ptr
142  spirv.Store "Function" %0, %arg0 : f32
143  spirv.Return
144}
145
146// CHECK-LABEL: @store_composite
147spirv.func @store_composite(%arg0 : !spirv.struct<(f64)>) "None" {
148  %0 = spirv.Variable : !spirv.ptr<!spirv.struct<(f64)>, Function>
149  // CHECK: llvm.store %{{.*}}, %{{.*}} : !llvm.struct<packed (f64)>, !llvm.ptr
150  spirv.Store "Function" %0, %arg0 : !spirv.struct<(f64)>
151  spirv.Return
152}
153
154// CHECK-LABEL: @store_with_alignment
155spirv.func @store_with_alignment(%arg0 : f32) "None" {
156  %0 = spirv.Variable : !spirv.ptr<f32, Function>
157  // CHECK: llvm.store %{{.*}}, %{{.*}} {alignment = 4 : i64} : f32, !llvm.ptr
158  spirv.Store "Function" %0, %arg0 ["Aligned", 4] : f32
159  spirv.Return
160}
161
162// CHECK-LABEL: @store_volatile
163spirv.func @store_volatile(%arg0 : f32) "None" {
164  %0 = spirv.Variable : !spirv.ptr<f32, Function>
165  // CHECK: llvm.store volatile %{{.*}}, %{{.*}} : f32, !llvm.ptr
166  spirv.Store "Function" %0, %arg0 ["Volatile"] : f32
167  spirv.Return
168}
169
170// CHECK-LABEL: @store_nontemporal
171spirv.func @store_nontemporal(%arg0 : f32) "None" {
172  %0 = spirv.Variable : !spirv.ptr<f32, Function>
173  // CHECK: llvm.store %{{.*}}, %{{.*}} {nontemporal} : f32, !llvm.ptr
174  spirv.Store "Function" %0, %arg0 ["Nontemporal"] : f32
175  spirv.Return
176}
177
178//===----------------------------------------------------------------------===//
179// spirv.Variable
180//===----------------------------------------------------------------------===//
181
182// CHECK-LABEL: @variable_scalar
183spirv.func @variable_scalar() "None" {
184  // CHECK: %[[SIZE1:.*]] = llvm.mlir.constant(1 : i32) : i32
185  // CHECK: llvm.alloca %[[SIZE1]] x f32 : (i32) -> !llvm.ptr
186  %0 = spirv.Variable : !spirv.ptr<f32, Function>
187  // CHECK: %[[SIZE2:.*]] = llvm.mlir.constant(1 : i32) : i32
188  // CHECK: llvm.alloca %[[SIZE2]] x i8 : (i32) -> !llvm.ptr
189  %1 = spirv.Variable : !spirv.ptr<i8, Function>
190  spirv.Return
191}
192
193// CHECK-LABEL: @variable_scalar_with_initialization
194spirv.func @variable_scalar_with_initialization() "None" {
195  // CHECK: %[[VALUE:.*]] = llvm.mlir.constant(0 : i64) : i64
196  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : i32
197  // CHECK: %[[ALLOCATED:.*]] = llvm.alloca %[[SIZE]] x i64 : (i32) -> !llvm.ptr
198  // CHECK: llvm.store %[[VALUE]], %[[ALLOCATED]] : i64, !llvm.ptr
199  %c = spirv.Constant 0 : i64
200  %0 = spirv.Variable init(%c) : !spirv.ptr<i64, Function>
201  spirv.Return
202}
203
204// CHECK-LABEL: @variable_vector
205spirv.func @variable_vector() "None" {
206  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : i32
207  // CHECK: llvm.alloca  %[[SIZE]] x vector<3xf32> : (i32) -> !llvm.ptr
208  %0 = spirv.Variable : !spirv.ptr<vector<3xf32>, Function>
209  spirv.Return
210}
211
212// CHECK-LABEL: @variable_vector_with_initialization
213spirv.func @variable_vector_with_initialization() "None" {
214  // CHECK: %[[VALUE:.*]] = llvm.mlir.constant(dense<false> : vector<3xi1>) : vector<3xi1>
215  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : i32
216  // CHECK: %[[ALLOCATED:.*]] = llvm.alloca %[[SIZE]] x vector<3xi1> : (i32) -> !llvm.ptr
217  // CHECK: llvm.store %[[VALUE]], %[[ALLOCATED]] : vector<3xi1>, !llvm.ptr
218  %c = spirv.Constant dense<false> : vector<3xi1>
219  %0 = spirv.Variable init(%c) : !spirv.ptr<vector<3xi1>, Function>
220  spirv.Return
221}
222
223// CHECK-LABEL: @variable_array
224spirv.func @variable_array() "None" {
225  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : i32
226  // CHECK: llvm.alloca %[[SIZE]] x !llvm.array<10 x i32> : (i32) -> !llvm.ptr
227  %0 = spirv.Variable : !spirv.ptr<!spirv.array<10 x i32>, Function>
228  spirv.Return
229}
230