1// RUN: mlir-opt -split-input-file -spirv-unify-aliased-resource -verify-diagnostics %s | FileCheck %s 2 3spirv.module Logical GLSL450 { 4 spirv.GlobalVariable @var01s bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 5 spirv.GlobalVariable @var01v bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 6 7 spirv.func @load_store_scalar(%index: i32) -> f32 "None" { 8 %c0 = spirv.Constant 0 : i32 9 %addr = spirv.mlir.addressof @var01s : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 10 %ac = spirv.AccessChain %addr[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 11 %value = spirv.Load "StorageBuffer" %ac : f32 12 spirv.Store "StorageBuffer" %ac, %value : f32 13 spirv.ReturnValue %value : f32 14 } 15} 16 17// CHECK-LABEL: spirv.module 18 19// CHECK-NOT: @var01s 20// CHECK: spirv.GlobalVariable @var01v bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 21// CHECK-NOT: @var01s 22 23// CHECK: spirv.func @load_store_scalar(%[[INDEX:.+]]: i32) 24// CHECK-DAG: %[[C0:.+]] = spirv.Constant 0 : i32 25// CHECK-DAG: %[[C4:.+]] = spirv.Constant 4 : i32 26// CHECK-DAG: %[[ADDR:.+]] = spirv.mlir.addressof @var01v 27// CHECK: %[[DIV:.+]] = spirv.SDiv %[[INDEX]], %[[C4]] : i32 28// CHECK: %[[MOD:.+]] = spirv.SMod %[[INDEX]], %[[C4]] : i32 29// CHECK: %[[AC:.+]] = spirv.AccessChain %[[ADDR]][%[[C0]], %[[DIV]], %[[MOD]]] 30// CHECK: spirv.Load "StorageBuffer" %[[AC]] 31// CHECK: spirv.Store "StorageBuffer" %[[AC]] 32 33// ----- 34 35spirv.module Logical GLSL450 { 36 spirv.GlobalVariable @var01s bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 37 spirv.GlobalVariable @var01v bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 38 39 spirv.func @load_store_scalar_64bit(%index: i64) -> f32 "None" { 40 %c0 = spirv.Constant 0 : i64 41 %addr = spirv.mlir.addressof @var01s : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 42 %ac = spirv.AccessChain %addr[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i64, i64 -> !spirv.ptr<f32, StorageBuffer> 43 %value = spirv.Load "StorageBuffer" %ac : f32 44 spirv.Store "StorageBuffer" %ac, %value : f32 45 spirv.ReturnValue %value : f32 46 } 47} 48 49// CHECK-LABEL: spirv.module 50 51// CHECK-NOT: @var01s 52// CHECK: spirv.GlobalVariable @var01v bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 53// CHECK-NOT: @var01s 54 55// CHECK: spirv.func @load_store_scalar_64bit(%[[INDEX:.+]]: i64) 56// CHECK-DAG: %[[C4:.+]] = spirv.Constant 4 : i64 57// CHECK: spirv.SDiv %[[INDEX]], %[[C4]] : i64 58// CHECK: spirv.SMod %[[INDEX]], %[[C4]] : i64 59 60// ----- 61 62spirv.module Logical GLSL450 { 63 spirv.GlobalVariable @var01s bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 64 spirv.GlobalVariable @var01v bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 65 66 spirv.func @multiple_uses(%i0: i32, %i1: i32) -> f32 "None" { 67 %c0 = spirv.Constant 0 : i32 68 %addr = spirv.mlir.addressof @var01s : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 69 %ac0 = spirv.AccessChain %addr[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 70 %val0 = spirv.Load "StorageBuffer" %ac0 : f32 71 %ac1 = spirv.AccessChain %addr[%c0, %i1] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 72 %val1 = spirv.Load "StorageBuffer" %ac1 : f32 73 %value = spirv.FAdd %val0, %val1 : f32 74 spirv.ReturnValue %value : f32 75 } 76} 77 78// CHECK-LABEL: spirv.module 79 80// CHECK-NOT: @var01s 81// CHECK: spirv.GlobalVariable @var01v bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 82// CHECK-NOT: @var01s 83 84// CHECK: spirv.func @multiple_uses 85// CHECK: %[[ADDR:.+]] = spirv.mlir.addressof @var01v 86// CHECK: spirv.AccessChain %[[ADDR]][%{{.+}}, %{{.+}}, %{{.+}}] 87// CHECK: spirv.AccessChain %[[ADDR]][%{{.+}}, %{{.+}}, %{{.+}}] 88 89// ----- 90 91spirv.module Logical GLSL450 { 92 spirv.GlobalVariable @var01s bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 93 spirv.GlobalVariable @var01v bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<3xf32>, stride=16> [0])>, StorageBuffer> 94 95 spirv.func @vector3(%index: i32) -> f32 "None" { 96 %c0 = spirv.Constant 0 : i32 97 %addr = spirv.mlir.addressof @var01s : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 98 %ac = spirv.AccessChain %addr[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 99 %value = spirv.Load "StorageBuffer" %ac : f32 100 spirv.ReturnValue %value : f32 101 } 102} 103 104// CHECK-LABEL: spirv.module 105 106// CHECK: spirv.GlobalVariable @var01s bind(0, 1) {aliased} 107// CHECK: spirv.GlobalVariable @var01v bind(0, 1) {aliased} 108// CHECK: spirv.func @vector3 109 110// ----- 111 112spirv.module Logical GLSL450 { 113 spirv.GlobalVariable @var01s bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 114 spirv.GlobalVariable @var01v bind(1, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 115 116 spirv.func @not_aliased(%index: i32) -> f32 "None" { 117 %c0 = spirv.Constant 0 : i32 118 %addr = spirv.mlir.addressof @var01s : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 119 %ac = spirv.AccessChain %addr[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 120 %value = spirv.Load "StorageBuffer" %ac : f32 121 spirv.Store "StorageBuffer" %ac, %value : f32 122 spirv.ReturnValue %value : f32 123 } 124} 125 126// CHECK-LABEL: spirv.module 127 128// CHECK: spirv.GlobalVariable @var01s bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 129// CHECK: spirv.GlobalVariable @var01v bind(1, 0) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 130// CHECK: spirv.func @not_aliased 131 132// ----- 133 134spirv.module Logical GLSL450 { 135 spirv.GlobalVariable @var01s bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 136 spirv.GlobalVariable @var01s_1 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 137 spirv.GlobalVariable @var01v bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 138 spirv.GlobalVariable @var01v_1 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 139 140 spirv.func @multiple_aliases(%index: i32) -> f32 "None" { 141 %c0 = spirv.Constant 0 : i32 142 143 %addr0 = spirv.mlir.addressof @var01s : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 144 %ac0 = spirv.AccessChain %addr0[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 145 %val0 = spirv.Load "StorageBuffer" %ac0 : f32 146 147 %addr1 = spirv.mlir.addressof @var01s_1 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 148 %ac1 = spirv.AccessChain %addr1[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 149 %val1 = spirv.Load "StorageBuffer" %ac1 : f32 150 151 %addr2 = spirv.mlir.addressof @var01v_1 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 152 %ac2 = spirv.AccessChain %addr2[%c0, %index, %c0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 153 %val2 = spirv.Load "StorageBuffer" %ac2 : f32 154 155 %add0 = spirv.FAdd %val0, %val1 : f32 156 %add1 = spirv.FAdd %add0, %val2 : f32 157 spirv.ReturnValue %add1 : f32 158 } 159} 160 161// CHECK-LABEL: spirv.module 162 163// CHECK-NOT: @var01s 164// CHECK: spirv.GlobalVariable @var01v bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 165// CHECK-NOT: @var01v_1 166 167// CHECK: spirv.func @multiple_aliases 168// CHECK: %[[ADDR0:.+]] = spirv.mlir.addressof @var01v : 169// CHECK: spirv.AccessChain %[[ADDR0]][%{{.+}}, %{{.+}}, %{{.+}}] 170// CHECK: %[[ADDR1:.+]] = spirv.mlir.addressof @var01v : 171// CHECK: spirv.AccessChain %[[ADDR1]][%{{.+}}, %{{.+}}, %{{.+}}] 172// CHECK: %[[ADDR2:.+]] = spirv.mlir.addressof @var01v : 173// CHECK: spirv.AccessChain %[[ADDR2]][%{{.+}}, %{{.+}}, %{{.+}}] 174 175// ----- 176 177spirv.module Logical GLSL450 { 178 spirv.GlobalVariable @var01s_i32 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer> 179 spirv.GlobalVariable @var01s_f32 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 180 181 spirv.func @different_scalar_type(%index: i32, %val1: f32) -> i32 "None" { 182 %c0 = spirv.Constant 0 : i32 183 184 %addr0 = spirv.mlir.addressof @var01s_i32 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer> 185 %ac0 = spirv.AccessChain %addr0[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<i32, StorageBuffer> 186 %val0 = spirv.Load "StorageBuffer" %ac0 : i32 187 188 %addr1 = spirv.mlir.addressof @var01s_f32 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 189 %ac1 = spirv.AccessChain %addr1[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 190 spirv.Store "StorageBuffer" %ac1, %val1 : f32 191 192 spirv.ReturnValue %val0 : i32 193 } 194} 195 196// CHECK-LABEL: spirv.module 197 198// CHECK-NOT: @var01s_f32 199// CHECK: spirv.GlobalVariable @var01s_i32 bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer> 200// CHECK-NOT: @var01s_f32 201 202// CHECK: spirv.func @different_scalar_type(%[[INDEX:.+]]: i32, %[[VAL1:.+]]: f32) 203 204// CHECK: %[[IADDR:.+]] = spirv.mlir.addressof @var01s_i32 205// CHECK: %[[IAC:.+]] = spirv.AccessChain %[[IADDR]][%{{.+}}, %[[INDEX]]] 206// CHECK: spirv.Load "StorageBuffer" %[[IAC]] : i32 207 208// CHECK: %[[FADDR:.+]] = spirv.mlir.addressof @var01s_i32 209// CHECK: %[[FAC:.+]] = spirv.AccessChain %[[FADDR]][%cst0_i32, %[[INDEX]]] 210// CHECK: %[[CAST:.+]] = spirv.Bitcast %[[VAL1]] : f32 to i32 211// CHECK: spirv.Store "StorageBuffer" %[[FAC]], %[[CAST]] : i32 212 213// ----- 214 215spirv.module Logical GLSL450 { 216 spirv.GlobalVariable @var01s bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer> 217 spirv.GlobalVariable @var01v bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 218 219 spirv.func @different_primitive_type(%index: i32, %val0: i32) -> i32 "None" { 220 %c0 = spirv.Constant 0 : i32 221 %addr = spirv.mlir.addressof @var01s : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer> 222 %ac = spirv.AccessChain %addr[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<i32, StorageBuffer> 223 %val1 = spirv.Load "StorageBuffer" %ac : i32 224 spirv.Store "StorageBuffer" %ac, %val0 : i32 225 spirv.ReturnValue %val1 : i32 226 } 227} 228 229// CHECK-LABEL: spirv.module 230 231// CHECK-NOT: @var01s 232// CHECK: spirv.GlobalVariable @var01v bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 233// CHECK-NOT: @var01s 234 235// CHECK: spirv.func @different_primitive_type(%{{.+}}: i32, %[[VAL0:.+]]: i32) 236// CHECK: %[[ADDR:.+]] = spirv.mlir.addressof @var01v 237// CHECK: %[[AC:.+]] = spirv.AccessChain %[[ADDR]][%{{.+}}, %{{.+}}, %{{.+}}] 238// CHECK: %[[VAL1:.+]] = spirv.Load "StorageBuffer" %[[AC]] : f32 239// CHECK: %[[CAST1:.+]] = spirv.Bitcast %[[VAL1]] : f32 to i32 240// CHECK: %[[CAST2:.+]] = spirv.Bitcast %[[VAL0]] : i32 to f32 241// CHECK: spirv.Store "StorageBuffer" %[[AC]], %[[CAST2]] : f32 242// CHECK: spirv.ReturnValue %[[CAST1]] : i32 243 244// ----- 245 246spirv.module Logical GLSL450 { 247 spirv.GlobalVariable @var01s_i64 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=4> [0])>, StorageBuffer> 248 spirv.GlobalVariable @var01s_f32 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 249 250 spirv.func @load_different_scalar_bitwidth(%index: i32) -> i64 "None" { 251 %c0 = spirv.Constant 0 : i32 252 253 %addr0 = spirv.mlir.addressof @var01s_i64 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=4> [0])>, StorageBuffer> 254 %ac0 = spirv.AccessChain %addr0[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<i64, StorageBuffer> 255 %val0 = spirv.Load "StorageBuffer" %ac0 : i64 256 257 spirv.ReturnValue %val0 : i64 258 } 259} 260 261// CHECK-LABEL: spirv.module 262 263// CHECK-NOT: @var01s_i64 264// CHECK: spirv.GlobalVariable @var01s_f32 bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 265// CHECK-NOT: @var01s_i64 266 267// CHECK: spirv.func @load_different_scalar_bitwidth(%[[INDEX:.+]]: i32) 268// CHECK: %[[ZERO:.+]] = spirv.Constant 0 : i32 269// CHECK: %[[ADDR:.+]] = spirv.mlir.addressof @var01s_f32 270 271// CHECK: %[[TWO:.+]] = spirv.Constant 2 : i32 272// CHECK: %[[BASE:.+]] = spirv.IMul %[[INDEX]], %[[TWO]] : i32 273// CHECK: %[[AC0:.+]] = spirv.AccessChain %[[ADDR]][%[[ZERO]], %[[BASE]]] 274// CHECK: %[[LOAD0:.+]] = spirv.Load "StorageBuffer" %[[AC0]] : f32 275 276// CHECK: %[[ONE:.+]] = spirv.Constant 1 : i32 277// CHECK: %[[ADD:.+]] = spirv.IAdd %[[BASE]], %[[ONE]] : i32 278// CHECK: %[[AC1:.+]] = spirv.AccessChain %[[ADDR]][%[[ZERO]], %[[ADD]]] 279// CHECK: %[[LOAD1:.+]] = spirv.Load "StorageBuffer" %[[AC1]] : f32 280 281// CHECK: %[[CC:.+]] = spirv.CompositeConstruct %[[LOAD0]], %[[LOAD1]] 282// CHECK: %[[CAST:.+]] = spirv.Bitcast %[[CC]] : vector<2xf32> to i64 283// CHECK: spirv.ReturnValue %[[CAST]] 284 285// ----- 286 287spirv.module Logical GLSL450 { 288 spirv.GlobalVariable @var01s_i64 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=4> [0])>, StorageBuffer> 289 spirv.GlobalVariable @var01s_f32 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 290 291 spirv.func @store_different_scalar_bitwidth(%i0: i32, %i1: i32) "None" { 292 %c0 = spirv.Constant 0 : i32 293 294 %addr0 = spirv.mlir.addressof @var01s_f32 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 295 %ac0 = spirv.AccessChain %addr0[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 296 %f32val = spirv.Load "StorageBuffer" %ac0 : f32 297 %f64val = spirv.FConvert %f32val : f32 to f64 298 %i64val = spirv.Bitcast %f64val : f64 to i64 299 300 %addr1 = spirv.mlir.addressof @var01s_i64 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=4> [0])>, StorageBuffer> 301 %ac1 = spirv.AccessChain %addr1[%c0, %i1] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<i64, StorageBuffer> 302 // expected-error@+1 {{failed to legalize operation 'spirv.Store'}} 303 spirv.Store "StorageBuffer" %ac1, %i64val : i64 304 305 spirv.Return 306 } 307} 308 309// ----- 310 311spirv.module Logical GLSL450 { 312 spirv.GlobalVariable @var01_scalar bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 313 spirv.GlobalVariable @var01_vec2 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=8> [0])>, StorageBuffer> 314 spirv.GlobalVariable @var01_vec4 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 315 316 spirv.func @load_different_vector_sizes(%i0: i32) -> vector<4xf32> "None" { 317 %c0 = spirv.Constant 0 : i32 318 319 %addr0 = spirv.mlir.addressof @var01_vec4 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 320 %ac0 = spirv.AccessChain %addr0[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xf32>, StorageBuffer> 321 %vec4val = spirv.Load "StorageBuffer" %ac0 : vector<4xf32> 322 323 %addr1 = spirv.mlir.addressof @var01_scalar : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 324 %ac1 = spirv.AccessChain %addr1[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 325 %scalarval = spirv.Load "StorageBuffer" %ac1 : f32 326 327 %val = spirv.CompositeInsert %scalarval, %vec4val[0 : i32] : f32 into vector<4xf32> 328 spirv.ReturnValue %val : vector<4xf32> 329 } 330} 331 332// CHECK-LABEL: spirv.module 333 334// CHECK-NOT: @var01_scalar 335// CHECK-NOT: @var01_vec4 336// CHECK: spirv.GlobalVariable @var01_vec2 bind(0, 1) : !spirv.ptr<{{.+}}> 337// CHECK-NOT: @var01_scalar 338// CHECK-NOT: @var01_vec4 339 340// CHECK: spirv.func @load_different_vector_sizes(%[[IDX:.+]]: i32) 341// CHECK: %[[ZERO:.+]] = spirv.Constant 0 : i32 342// CHECK: %[[ADDR:.+]] = spirv.mlir.addressof @var01_vec2 343// CHECK: %[[TWO:.+]] = spirv.Constant 2 : i32 344// CHECK: %[[IDX0:.+]] = spirv.IMul %[[IDX]], %[[TWO]] : i32 345// CHECK: %[[AC0:.+]] = spirv.AccessChain %[[ADDR]][%[[ZERO]], %[[IDX0]]] 346// CHECK: %[[LD0:.+]] = spirv.Load "StorageBuffer" %[[AC0]] : vector<2xf32> 347// CHECK: %[[ONE:.+]] = spirv.Constant 1 : i32 348// CHECK: %[[IDX1:.+]] = spirv.IAdd %0, %[[ONE]] : i32 349// CHECK: %[[AC1:.+]] = spirv.AccessChain %[[ADDR]][%[[ZERO]], %[[IDX1]]] 350// CHECK: %[[LD1:.+]] = spirv.Load "StorageBuffer" %[[AC1]] : vector<2xf32> 351// CHECK: spirv.CompositeConstruct %[[LD0]], %[[LD1]] : (vector<2xf32>, vector<2xf32>) -> vector<4xf32> 352 353// CHECK: %[[ADDR:.+]] = spirv.mlir.addressof @var01_vec2 354// CHECK: %[[TWO:.+]] = spirv.Constant 2 : i32 355// CHECK: %[[DIV:.+]] = spirv.SDiv %[[IDX]], %[[TWO]] : i32 356// CHECK: %[[MOD:.+]] = spirv.SMod %[[IDX]], %[[TWO]] : i32 357// CHECK: %[[AC:.+]] = spirv.AccessChain %[[ADDR]][%[[ZERO]], %[[DIV]], %[[MOD]]] 358// CHECK: %[[LD:.+]] = spirv.Load "StorageBuffer" %[[AC]] : f32 359 360// ----- 361 362spirv.module Logical GLSL450 { 363 spirv.GlobalVariable @var01_v4f32 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 364 spirv.GlobalVariable @var01_f32 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 365 spirv.GlobalVariable @var01_i64 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=8> [0])>, StorageBuffer> 366 367 spirv.func @load_mixed_scalar_vector_primitive_types(%i0: i32) -> vector<4xf32> "None" { 368 %c0 = spirv.Constant 0 : i32 369 370 %addr0 = spirv.mlir.addressof @var01_v4f32 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 371 %ac0 = spirv.AccessChain %addr0[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xf32>, StorageBuffer> 372 %vec4val = spirv.Load "StorageBuffer" %ac0 : vector<4xf32> 373 374 %addr1 = spirv.mlir.addressof @var01_f32 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer> 375 %ac1 = spirv.AccessChain %addr1[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 376 %f32val = spirv.Load "StorageBuffer" %ac1 : f32 377 378 %addr2 = spirv.mlir.addressof @var01_i64 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=8> [0])>, StorageBuffer> 379 %ac2 = spirv.AccessChain %addr2[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=8> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<i64, StorageBuffer> 380 %i64val = spirv.Load "StorageBuffer" %ac2 : i64 381 %i32val = spirv.SConvert %i64val : i64 to i32 382 %castval = spirv.Bitcast %i32val : i32 to f32 383 384 %val1 = spirv.CompositeInsert %f32val, %vec4val[0 : i32] : f32 into vector<4xf32> 385 %val2 = spirv.CompositeInsert %castval, %val1[1 : i32] : f32 into vector<4xf32> 386 spirv.ReturnValue %val2 : vector<4xf32> 387 } 388} 389 390// CHECK-LABEL: spirv.module 391 392// CHECK-NOT: @var01_f32 393// CHECK-NOT: @var01_i64 394// CHECK: spirv.GlobalVariable @var01_v4f32 bind(0, 1) : !spirv.ptr<{{.+}}> 395// CHECK-NOT: @var01_f32 396// CHECK-NOT: @var01_i64 397 398// CHECK: spirv.func @load_mixed_scalar_vector_primitive_types(%[[IDX:.+]]: i32) 399 400// CHECK: %[[ZERO:.+]] = spirv.Constant 0 : i32 401// CHECK: %[[ADDR0:.+]] = spirv.mlir.addressof @var01_v4f32 402// CHECK: %[[AC0:.+]] = spirv.AccessChain %[[ADDR0]][%[[ZERO]], %[[IDX]]] 403// CHECK: spirv.Load "StorageBuffer" %[[AC0]] : vector<4xf32> 404 405// CHECK: %[[ADDR1:.+]] = spirv.mlir.addressof @var01_v4f32 406// CHECK: %[[FOUR:.+]] = spirv.Constant 4 : i32 407// CHECK: %[[DIV:.+]] = spirv.SDiv %[[IDX]], %[[FOUR]] : i32 408// CHECK: %[[MOD:.+]] = spirv.SMod %[[IDX]], %[[FOUR]] : i32 409// CHECK: %[[AC1:.+]] = spirv.AccessChain %[[ADDR1]][%[[ZERO]], %[[DIV]], %[[MOD]]] 410// CHECK: spirv.Load "StorageBuffer" %[[AC1]] : f32 411 412// CHECK: %[[ADDR2:.+]] = spirv.mlir.addressof @var01_v4f32 413// CHECK: %[[TWO:.+]] = spirv.Constant 2 : i32 414// CHECK: %[[DIV0:.+]] = spirv.SDiv %[[IDX]], %[[TWO]] : i32 415// CHECK: %[[MOD0:.+]] = spirv.SMod %[[IDX]], %[[TWO]] : i32 416// CHECK: %[[AC2:.+]] = spirv.AccessChain %[[ADDR2]][%[[ZERO]], %[[DIV0]], %[[MOD0]]] 417// CHECK: %[[LD0:.+]] = spirv.Load "StorageBuffer" %[[AC2]] : f32 418 419// CHECK: %[[ONE:.+]] = spirv.Constant 1 : i32 420// CHECK: %[[MOD1:.+]] = spirv.IAdd %[[MOD0]], %[[ONE]] 421// CHECK: %[[AC3:.+]] = spirv.AccessChain %[[ADDR2]][%[[ZERO]], %[[DIV0]], %[[MOD1]]] 422// CHECK: %[[LD1:.+]] = spirv.Load "StorageBuffer" %[[AC3]] : f32 423// CHECK: %[[CC:.+]] = spirv.CompositeConstruct %[[LD0]], %[[LD1]] 424// CHECK: %[[BC:.+]] = spirv.Bitcast %[[CC]] : vector<2xf32> to i64 425 426// ----- 427 428spirv.module Logical GLSL450 { 429 spirv.GlobalVariable @var01_v2f2 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=16> [0])>, StorageBuffer> 430 spirv.GlobalVariable @var01_i64 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=8> [0])>, StorageBuffer> 431 432 spirv.func @load_mixed_scalar_vector_primitive_types(%i0: i32) -> i64 "None" { 433 %c0 = spirv.Constant 0 : i32 434 435 %addr = spirv.mlir.addressof @var01_i64 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=8> [0])>, StorageBuffer> 436 %ac = spirv.AccessChain %addr[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i64, stride=8> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<i64, StorageBuffer> 437 %val = spirv.Load "StorageBuffer" %ac : i64 438 439 spirv.ReturnValue %val : i64 440 } 441} 442 443// CHECK-LABEL: spirv.module 444 445// CHECK: spirv.func @load_mixed_scalar_vector_primitive_types(%[[IDX:.+]]: i32) 446 447// CHECK: %[[ADDR:.+]] = spirv.mlir.addressof @var01_v2f2 448// CHECK: %[[ONE:.+]] = spirv.Constant 1 : i32 449// CHECK: %[[DIV:.+]] = spirv.SDiv %[[IDX]], %[[ONE]] : i32 450// CHECK: %[[MOD:.+]] = spirv.SMod %[[IDX]], %[[ONE]] : i32 451// CHECK: spirv.AccessChain %[[ADDR]][%{{.+}}, %[[DIV]], %[[MOD]]] 452// CHECK: spirv.Load 453// CHECK: spirv.Load 454 455// ----- 456 457spirv.module Logical GLSL450 { 458 spirv.GlobalVariable @var01_v2f2 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=16> [0])>, StorageBuffer> 459 spirv.GlobalVariable @var01_i16 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i16, stride=2> [0])>, StorageBuffer> 460 461 spirv.func @scalar_type_bitwidth_smaller_than_vector(%i0: i32) -> i16 "None" { 462 %c0 = spirv.Constant 0 : i32 463 464 %addr = spirv.mlir.addressof @var01_i16 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i16, stride=2> [0])>, StorageBuffer> 465 %ac = spirv.AccessChain %addr[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<i16, stride=2> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<i16, StorageBuffer> 466 %val = spirv.Load "StorageBuffer" %ac : i16 467 468 spirv.ReturnValue %val : i16 469 } 470} 471 472// CHECK-LABEL: spirv.module 473 474// CHECK: spirv.GlobalVariable @var01_v2f2 bind(0, 1) {aliased} 475// CHECK: spirv.GlobalVariable @var01_i16 bind(0, 1) {aliased} 476 477// CHECK: spirv.func @scalar_type_bitwidth_smaller_than_vector 478 479// ----- 480 481spirv.module Logical GLSL450 { 482 spirv.GlobalVariable @var00_v4f32 bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 483 spirv.GlobalVariable @var00_v4f16 bind(0, 0) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf16>, stride=8> [0])>, StorageBuffer> 484 485 spirv.func @vector_type_same_size_different_element_type(%i0: i32) -> vector<4xf32> "None" { 486 %c0 = spirv.Constant 0 : i32 487 488 %addr = spirv.mlir.addressof @var00_v4f32 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer> 489 %ac = spirv.AccessChain %addr[%c0, %i0] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf32>, stride=16> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<4xf32>, StorageBuffer> 490 %val = spirv.Load "StorageBuffer" %ac : vector<4xf32> 491 492 spirv.ReturnValue %val : vector<4xf32> 493 } 494} 495 496// CHECK-LABEL: spirv.module 497 498// CHECK: spirv.GlobalVariable @var00_v4f16 bind(0, 0) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<4xf16>, stride=8> [0])>, StorageBuffer> 499 500// CHECK: spirv.func @vector_type_same_size_different_element_type 501 502// CHECK: %[[LD0:.+]] = spirv.Load "StorageBuffer" %{{.+}} : vector<4xf16> 503// CHECK: %[[LD1:.+]] = spirv.Load "StorageBuffer" %{{.+}} : vector<4xf16> 504// CHECK: %[[BC0:.+]] = spirv.Bitcast %[[LD0]] : vector<4xf16> to vector<2xf32> 505// CHECK: %[[BC1:.+]] = spirv.Bitcast %[[LD1]] : vector<4xf16> to vector<2xf32> 506// CHECK: %[[CC:.+]] = spirv.CompositeConstruct %[[BC0]], %[[BC1]] : (vector<2xf32>, vector<2xf32>) -> vector<4xf32> 507// CHECK: spirv.ReturnValue %[[CC]] 508 509// ----- 510 511spirv.module Logical GLSL450 { 512 spirv.GlobalVariable @var01_v2f16 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf16>, stride=4> [0])>, StorageBuffer> 513 spirv.GlobalVariable @var01_v2f32 bind(0, 1) {aliased} : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=8> [0])>, StorageBuffer> 514 515 spirv.func @aliased(%index: i32) -> vector<3xf32> "None" { 516 %c0 = spirv.Constant 0 : i32 517 %v0 = spirv.Constant dense<0.0> : vector<3xf32> 518 %addr0 = spirv.mlir.addressof @var01_v2f16 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf16>, stride=4> [0])>, StorageBuffer> 519 %ac0 = spirv.AccessChain %addr0[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf16>, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<2xf16>, StorageBuffer> 520 %value0 = spirv.Load "StorageBuffer" %ac0 : vector<2xf16> 521 522 %addr1 = spirv.mlir.addressof @var01_v2f32 : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=8> [0])>, StorageBuffer> 523 %ac1 = spirv.AccessChain %addr1[%c0, %index] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf32>, stride=8> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<vector<2xf32>, StorageBuffer> 524 %value1 = spirv.Load "StorageBuffer" %ac1 : vector<2xf32> 525 526 %val0_as_f32 = spirv.Bitcast %value0 : vector<2xf16> to f32 527 528 %res = spirv.CompositeConstruct %val0_as_f32, %value1 : (f32, vector<2xf32>) -> vector<3xf32> 529 530 spirv.ReturnValue %res : vector<3xf32> 531 } 532} 533 534// CHECK-LABEL: spirv.module 535 536// CHECK: spirv.GlobalVariable @var01_v2f16 bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.rtarray<vector<2xf16>, stride=4> [0])>, StorageBuffer> 537// CHECK: spirv.func @aliased 538 539// CHECK: %[[LD0:.+]] = spirv.Load "StorageBuffer" %{{.+}} : vector<2xf16> 540// CHECK: %[[LD1:.+]] = spirv.Load "StorageBuffer" %{{.+}} : vector<2xf16> 541// CHECK: %[[LD2:.+]] = spirv.Load "StorageBuffer" %{{.+}} : vector<2xf16> 542 543// CHECK-DAG: %[[ELEM0:.+]] = spirv.Bitcast %[[LD0]] : vector<2xf16> to f32 544// CHECK-DAG: %[[ELEM1:.+]] = spirv.Bitcast %[[LD1]] : vector<2xf16> to f32 545// CHECK-DAG: %[[ELEM2:.+]] = spirv.Bitcast %[[LD2]] : vector<2xf16> to f32 546 547// CHECK: %[[RES:.+]] = spirv.CompositeConstruct %[[ELEM0]], %{{.+}} : (f32, vector<2xf32>) -> vector<3xf32> 548// CHECK: spirv.ReturnValue %[[RES]] : vector<3xf32> 549 550// ----- 551 552// Make sure we do not crash on function arguments. 553 554spirv.module Logical GLSL450 { 555 spirv.func @main(%arg0: !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>) "None" { 556 %cst0_i32 = spirv.Constant 0 : i32 557 %0 = spirv.AccessChain %arg0[%cst0_i32, %cst0_i32] : !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>, i32, i32 -> !spirv.ptr<f32, StorageBuffer> 558 spirv.Return 559 } 560} 561 562// CHECK-LABEL: spirv.module 563// CHECK-LABEL: spirv.func @main 564// CHECK-SAME: (%{{.+}}: !spirv.ptr<!spirv.struct<(!spirv.rtarray<f32, stride=4> [0])>, StorageBuffer>) "None" 565// CHECK: spirv.Return 566