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