1 // RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
3 //===----------------------------------------------------------------------===//
5 //===----------------------------------------------------------------------===//
7 // CHECK-LABEL: @access_chain
8 spirv.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>
18 // CHECK-LABEL: @access_chain_array
19 spirv.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>
28 //===----------------------------------------------------------------------===//
29 // spirv.GlobalVariable and spirv.mlir.addressof
30 //===----------------------------------------------------------------------===//
32 spirv.module Logical GLSL450 {
33 // CHECK: llvm.mlir.global external constant @var() {addr_space = 0 : i32} : f32
34 spirv.GlobalVariable @var : !spirv.ptr<f32, Input>
37 spirv.module Logical GLSL450 {
38 // CHECK: llvm.mlir.global private @struct() {addr_space = 0 : i32} : !llvm.struct<packed (f32, array<10 x f32>)>
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>
48 spirv.module Logical GLSL450 {
49 // CHECK: llvm.mlir.global external @bar_descriptor_set0_binding0() {addr_space = 0 : i32} : i32
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>
59 spirv.module @name Logical GLSL450 {
60 // CHECK: llvm.mlir.global external @name_bar_descriptor_set0_binding0() {addr_space = 0 : i32} : i32
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>
70 spirv.module Logical GLSL450 {
71 // CHECK: llvm.mlir.global external @bar() {addr_space = 0 : i32, location = 1 : i32} : i32
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>
80 spirv.module Logical GLSL450 {
81 // CHECK: llvm.mlir.global external constant @bar() {addr_space = 0 : i32, location = 3 : i32} : f32
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>
90 //===----------------------------------------------------------------------===//
92 //===----------------------------------------------------------------------===//
95 spirv.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
102 // CHECK-LABEL: @load_none
103 spirv.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
110 // CHECK-LABEL: @load_with_alignment
111 spirv.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
118 // CHECK-LABEL: @load_volatile
119 spirv.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
126 // CHECK-LABEL: @load_nontemporal
127 spirv.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
134 //===----------------------------------------------------------------------===//
136 //===----------------------------------------------------------------------===//
138 // CHECK-LABEL: @store
139 spirv.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
146 // CHECK-LABEL: @store_composite
147 spirv.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)>
154 // CHECK-LABEL: @store_with_alignment
155 spirv.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
162 // CHECK-LABEL: @store_volatile
163 spirv.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
170 // CHECK-LABEL: @store_nontemporal
171 spirv.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
178 //===----------------------------------------------------------------------===//
180 //===----------------------------------------------------------------------===//
182 // CHECK-LABEL: @variable_scalar
183 spirv.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>
193 // CHECK-LABEL: @variable_scalar_with_initialization
194 spirv.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>
204 // CHECK-LABEL: @variable_vector
205 spirv.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>
212 // CHECK-LABEL: @variable_vector_with_initialization
213 spirv.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>
223 // CHECK-LABEL: @variable_array
224 spirv.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>