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