730 lines · plain
1// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s2 3//===----------------------------------------------------------------------===//4// spirv.AccessChain5//===----------------------------------------------------------------------===//6 7func.func @access_chain_struct() -> () {8 %0 = spirv.Constant 1: i329 %1 = spirv.Variable : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>10 // CHECK: spirv.AccessChain {{.*}}[{{.*}}, {{.*}}] : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4 x f32>)>, Function>11 %2 = spirv.AccessChain %1[%0, %0] : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>, i32, i32 -> !spirv.ptr<f32, Function>12 return13}14 15func.func @access_chain_1D_array(%arg0 : i32) -> () {16 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4xf32>, Function>17 // CHECK: spirv.AccessChain {{.*}}[{{.*}}] : !spirv.ptr<!spirv.array<4 x f32>, Function>18 %1 = spirv.AccessChain %0[%arg0] : !spirv.ptr<!spirv.array<4xf32>, Function>, i32 -> !spirv.ptr<f32, Function>19 return20}21 22func.func @access_chain_2D_array_1(%arg0 : i32) -> () {23 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>24 // CHECK: spirv.AccessChain {{.*}}[{{.*}}, {{.*}}] : !spirv.ptr<!spirv.array<4 x !spirv.array<4 x f32>>, Function>25 %1 = spirv.AccessChain %0[%arg0, %arg0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32, i32 -> !spirv.ptr<f32, Function>26 %2 = spirv.Load "Function" %1 ["Volatile"] : f3227 return28}29 30func.func @access_chain_2D_array_2(%arg0 : i32) -> () {31 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>32 // CHECK: spirv.AccessChain {{.*}}[{{.*}}] : !spirv.ptr<!spirv.array<4 x !spirv.array<4 x f32>>, Function>33 %1 = spirv.AccessChain %0[%arg0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32 -> !spirv.ptr<!spirv.array<4xf32>, Function>34 %2 = spirv.Load "Function" %1 ["Volatile"] : !spirv.array<4xf32>35 return36}37 38func.func @access_chain_rtarray(%arg0 : i32) -> () {39 %0 = spirv.Variable : !spirv.ptr<!spirv.rtarray<f32>, Function>40 // CHECK: spirv.AccessChain {{.*}}[{{.*}}] : !spirv.ptr<!spirv.rtarray<f32>, Function>41 %1 = spirv.AccessChain %0[%arg0] : !spirv.ptr<!spirv.rtarray<f32>, Function>, i32 -> !spirv.ptr<f32, Function>42 %2 = spirv.Load "Function" %1 ["Volatile"] : f3243 return44}45 46// -----47 48func.func @access_chain_non_composite() -> () {49 %0 = spirv.Constant 1: i3250 %1 = spirv.Variable : !spirv.ptr<f32, Function>51 // expected-error @+1 {{cannot extract from non-composite type 'f32' with index 0}}52 %2 = spirv.AccessChain %1[%0] : !spirv.ptr<f32, Function>, i32 -> !spirv.ptr<f32, Function>53 return54}55 56// -----57 58func.func @access_chain_no_indices(%index0 : i32) -> () {59 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>60 // expected-error @+1 {{custom op 'spirv.AccessChain' number of operands and types do not match: got 0 operands and 1 types}}61 %1 = spirv.AccessChain %0[] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32 -> !spirv.ptr<f32, Function>62 return63}64 65// -----66 67func.func @access_chain_missing_comma(%index0 : i32) -> () {68 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>69 // expected-error @+1 {{expected ','}}70 %1 = spirv.AccessChain %0[%index0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function> i3271 return72}73 74// -----75 76func.func @access_chain_invalid_indices_types_count(%index0 : i32) -> () {77 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>78 // expected-error @+1 {{custom op 'spirv.AccessChain' number of operands and types do not match: got 1 operands and 2 types}}79 %1 = spirv.AccessChain %0[%index0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32, i32 -> !spirv.ptr<!spirv.array<4xf32>, Function>80 return81}82 83// -----84 85func.func @access_chain_missing_indices_type(%index0 : i32) -> () {86 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>87 // expected-error @+1 {{custom op 'spirv.AccessChain' number of operands and types do not match: got 2 operands and 1 types}}88 %1 = spirv.AccessChain %0[%index0, %index0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32 -> !spirv.ptr<f32, Function>89 return90}91 92// -----93 94func.func @access_chain_invalid_type(%index0 : i32) -> () {95 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>96 %1 = spirv.Load "Function" %0 ["Volatile"] : !spirv.array<4x!spirv.array<4xf32>>97 // expected-error @+1 {{'spirv.AccessChain' op operand #0 must be any SPIR-V pointer type, but got '!spirv.array<4 x !spirv.array<4 x f32>>'}}98 %2 = spirv.AccessChain %1[%index0] : !spirv.array<4x!spirv.array<4xf32>>, i32 -> f3299 return100}101 102// -----103 104func.func @access_chain_invalid_index_1(%index0 : i32) -> () {105 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>106 // expected-error @+1 {{expected SSA operand}}107 %1 = spirv.AccessChain %0[%index, 4] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32, i32108 return109}110 111// -----112 113func.func @access_chain_invalid_index_2(%index0 : i32) -> () {114 %0 = spirv.Variable : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>115 // expected-error @+1 {{index must be an integer spirv.Constant to access element of spirv.struct}}116 %1 = spirv.AccessChain %0[%index0, %index0] : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>, i32, i32 -> !spirv.ptr<f32, Function>117 return118}119 120// -----121 122func.func @access_chain_invalid_constant_type_1() -> () {123 %0 = arith.constant 1: i32124 %1 = spirv.Variable : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>125 // expected-error @+1 {{index must be an integer spirv.Constant to access element of spirv.struct, but provided arith.constant}}126 %2 = spirv.AccessChain %1[%0, %0] : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>, i32, i32 -> !spirv.ptr<f32, Function>127 return128}129 130// -----131 132func.func @access_chain_out_of_bounds() -> () {133 %index0 = "spirv.Constant"() { value = 12: i32} : () -> i32134 %0 = spirv.Variable : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>135 // expected-error @+1 {{'spirv.AccessChain' op index 12 out of bounds for '!spirv.struct<(f32, !spirv.array<4 x f32>)>'}}136 %1 = spirv.AccessChain %0[%index0, %index0] : !spirv.ptr<!spirv.struct<(f32, !spirv.array<4xf32>)>, Function>, i32, i32 -> !spirv.ptr<f32, Function>137 return138}139 140// -----141 142func.func @access_chain_invalid_accessing_type(%index0 : i32) -> () {143 %0 = spirv.Variable : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>144 // expected-error @+1 {{cannot extract from non-composite type 'f32' with index 0}}145 %1 = spirv.AccessChain %0[%index0, %index0, %index0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32, i32, i32 -> !spirv.ptr<f32, Function>146 return147}148// -----149 150//===----------------------------------------------------------------------===//151// spirv.LoadOp152//===----------------------------------------------------------------------===//153 154// CHECK-LABEL: @simple_load155func.func @simple_load() -> () {156 %0 = spirv.Variable : !spirv.ptr<f32, Function>157 // CHECK: spirv.Load "Function" %{{.*}} : f32158 %1 = spirv.Load "Function" %0 : f32159 return160}161 162// CHECK-LABEL: @load_none_access163func.func @load_none_access() -> () {164 %0 = spirv.Variable : !spirv.ptr<f32, Function>165 // CHECK: spirv.Load "Function" %{{.*}} ["None"] : f32166 %1 = spirv.Load "Function" %0 ["None"] : f32167 return168}169 170// CHECK-LABEL: @volatile_load171func.func @volatile_load() -> () {172 %0 = spirv.Variable : !spirv.ptr<f32, Function>173 // CHECK: spirv.Load "Function" %{{.*}} ["Volatile"] : f32174 %1 = spirv.Load "Function" %0 ["Volatile"] : f32175 return176}177 178// CHECK-LABEL: @aligned_load179func.func @aligned_load() -> () {180 %0 = spirv.Variable : !spirv.ptr<f32, Function>181 // CHECK: spirv.Load "Function" %{{.*}} ["Aligned", 4] : f32182 %1 = spirv.Load "Function" %0 ["Aligned", 4] : f32183 return184}185 186// CHECK-LABEL: @volatile_aligned_load187func.func @volatile_aligned_load() -> () {188 %0 = spirv.Variable : !spirv.ptr<f32, Function>189 // CHECK: spirv.Load "Function" %{{.*}} ["Volatile|Aligned", 4] : f32190 %1 = spirv.Load "Function" %0 ["Volatile|Aligned", 4] : f32191 return192}193 194// -----195 196// CHECK-LABEL: load_none_access197func.func @load_none_access() -> () {198 %0 = spirv.Variable : !spirv.ptr<f32, Function>199 // CHECK: spirv.Load200 // CHECK-SAME: ["None"]201 %1 = "spirv.Load"(%0) {memory_access = #spirv.memory_access<None>} : (!spirv.ptr<f32, Function>) -> (f32)202 return203}204 205// CHECK-LABEL: volatile_load206func.func @volatile_load() -> () {207 %0 = spirv.Variable : !spirv.ptr<f32, Function>208 // CHECK: spirv.Load209 // CHECK-SAME: ["Volatile"]210 %1 = "spirv.Load"(%0) {memory_access = #spirv.memory_access<Volatile>} : (!spirv.ptr<f32, Function>) -> (f32)211 return212}213 214// CHECK-LABEL: aligned_load215func.func @aligned_load() -> () {216 %0 = spirv.Variable : !spirv.ptr<f32, Function>217 // CHECK: spirv.Load218 // CHECK-SAME: ["Aligned", 4]219 %1 = "spirv.Load"(%0) {memory_access = #spirv.memory_access<Aligned>, alignment = 4 : i32} : (!spirv.ptr<f32, Function>) -> (f32)220 return221}222 223// CHECK-LABEL: volatile_aligned_load224func.func @volatile_aligned_load() -> () {225 %0 = spirv.Variable : !spirv.ptr<f32, Function>226 // CHECK: spirv.Load227 // CHECK-SAME: ["Volatile|Aligned", 4]228 %1 = "spirv.Load"(%0) {memory_access = #spirv.memory_access<Volatile|Aligned>, alignment = 4 : i32} : (!spirv.ptr<f32, Function>) -> (f32)229 return230}231 232// -----233 234func.func @simple_load_missing_storageclass() -> () {235 %0 = spirv.Variable : !spirv.ptr<f32, Function>236 // expected-error @+1 {{expected attribute value}}237 %1 = spirv.Load %0 : f32238 return239}240 241// -----242 243func.func @simple_load_missing_operand() -> () {244 %0 = spirv.Variable : !spirv.ptr<f32, Function>245 // expected-error @+1 {{expected SSA operand}}246 %1 = spirv.Load "Function" : f32247 return248}249 250// -----251 252func.func @simple_load_missing_rettype() -> () {253 %0 = spirv.Variable : !spirv.ptr<f32, Function>254 // expected-error @+1 {{expected ':'}}255 %1 = spirv.Load "Function" %0256 return257}258 259// -----260 261func.func @volatile_load_missing_lbrace() -> () {262 %0 = spirv.Variable : !spirv.ptr<f32, Function>263 // expected-error @+1 {{expected ':'}}264 %1 = spirv.Load "Function" %0 "Volatile"] : f32265 return266}267 268// -----269 270func.func @volatile_load_missing_rbrace() -> () {271 %0 = spirv.Variable : !spirv.ptr<f32, Function>272 // expected-error @+1 {{expected ']'}}273 %1 = spirv.Load "Function" %0 ["Volatile"} : f32274 return275}276 277// -----278 279func.func @aligned_load_missing_alignment() -> () {280 %0 = spirv.Variable : !spirv.ptr<f32, Function>281 // expected-error @+1 {{expected ','}}282 %1 = spirv.Load "Function" %0 ["Aligned"] : f32283 return284}285 286// -----287 288func.func @aligned_load_missing_comma() -> () {289 %0 = spirv.Variable : !spirv.ptr<f32, Function>290 // expected-error @+1 {{expected ','}}291 %1 = spirv.Load "Function" %0 ["Aligned" 4] : f32292 return293}294 295// -----296 297func.func @load_incorrect_attributes() -> () {298 %0 = spirv.Variable : !spirv.ptr<f32, Function>299 // expected-error @+1 {{expected ']'}}300 %1 = spirv.Load "Function" %0 ["Volatile", 4] : f32301 return302}303 304// -----305 306func.func @load_unknown_memory_access() -> () {307 %0 = spirv.Variable : !spirv.ptr<f32, Function>308 // expected-error @+1 {{custom op 'spirv.Load' invalid memory_access attribute specification: "Something"}}309 %1 = spirv.Load "Function" %0 ["Something"] : f32310 return311}312 313// -----314 315func.func @load_unknown_memory_access() -> () {316 %0 = spirv.Variable : !spirv.ptr<f32, Function>317 // expected-error @+1 {{custom op 'spirv.Load' invalid memory_access attribute specification: "Volatile|Something"}}318 %1 = spirv.Load "Function" %0 ["Volatile|Something"] : f32319 return320}321 322// -----323 324func.func @load_unknown_memory_access() -> () {325 %0 = spirv.Variable : !spirv.ptr<f32, Function>326 // expected-error @+1 {{failed to satisfy constraint: valid SPIR-V MemoryAccess}}327 %1 = "spirv.Load"(%0) {memory_access = 0x80000000 : i32} : (!spirv.ptr<f32, Function>) -> (f32)328 return329}330 331// -----332 333func.func @aligned_load_incorrect_attributes() -> () {334 %0 = spirv.Variable : !spirv.ptr<f32, Function>335 // expected-error @+1 {{expected ']'}}336 %1 = spirv.Load "Function" %0 ["Aligned", 4, 23] : f32337 return338}339 340// -----341 342spirv.module Logical GLSL450 {343 spirv.GlobalVariable @var0 : !spirv.ptr<f32, Input>344 spirv.GlobalVariable @var1 : !spirv.ptr<!spirv.sampled_image<!spirv.image<f32, Dim2D, IsDepth, Arrayed, SingleSampled, NeedSampler, Unknown>>, UniformConstant>345 // CHECK-LABEL: @simple_load346 spirv.func @simple_load() -> () "None" {347 // CHECK: spirv.Load "Input" {{%.*}} : f32348 %0 = spirv.mlir.addressof @var0 : !spirv.ptr<f32, Input>349 %1 = spirv.Load "Input" %0 : f32350 %2 = spirv.mlir.addressof @var1 : !spirv.ptr<!spirv.sampled_image<!spirv.image<f32, Dim2D, IsDepth, Arrayed, SingleSampled, NeedSampler, Unknown>>, UniformConstant>351 // CHECK: spirv.Load "UniformConstant" {{%.*}} : !spirv.sampled_image352 %3 = spirv.Load "UniformConstant" %2 : !spirv.sampled_image<!spirv.image<f32, Dim2D, IsDepth, Arrayed, SingleSampled, NeedSampler, Unknown>>353 spirv.Return354 }355}356 357// -----358 359// CHECK-LABEL: @image_load360func.func @image_load() -> () {361 %0 = spirv.Variable : !spirv.ptr<!spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, Function>362 // CHECK: spirv.Load "Function" %{{.*}} : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>363 %1 = spirv.Load "Function" %0 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>364 return365}366 367// -----368 369//===----------------------------------------------------------------------===//370// spirv.StoreOp371//===----------------------------------------------------------------------===//372 373func.func @simple_store(%arg0 : f32) -> () {374 %0 = spirv.Variable : !spirv.ptr<f32, Function>375 // CHECK: spirv.Store "Function" %0, %arg0 : f32376 spirv.Store "Function" %0, %arg0 : f32377 return378}379 380// CHECK-LABEL: @volatile_store381func.func @volatile_store(%arg0 : f32) -> () {382 %0 = spirv.Variable : !spirv.ptr<f32, Function>383 // CHECK: spirv.Store "Function" %0, %arg0 ["Volatile"] : f32384 spirv.Store "Function" %0, %arg0 ["Volatile"] : f32385 return386}387 388// CHECK-LABEL: @aligned_store389func.func @aligned_store(%arg0 : f32) -> () {390 %0 = spirv.Variable : !spirv.ptr<f32, Function>391 // CHECK: spirv.Store "Function" %0, %arg0 ["Aligned", 4] : f32392 spirv.Store "Function" %0, %arg0 ["Aligned", 4] : f32393 return394}395 396// -----397 398func.func @simple_store_missing_ptr_type(%arg0 : f32) -> () {399 %0 = spirv.Variable : !spirv.ptr<f32, Function>400 // expected-error @+1 {{expected attribute value}}401 spirv.Store %0, %arg0 : f32402 return403}404 405// -----406 407func.func @simple_store_missing_operand(%arg0 : f32) -> () {408 %0 = spirv.Variable : !spirv.ptr<f32, Function>409 // expected-error @+1 {{expected operand}}410 spirv.Store "Function" , %arg0 : f32411 return412}413 414// -----415 416func.func @simple_store_missing_operand(%arg0 : f32) -> () {417 %0 = spirv.Variable : !spirv.ptr<f32, Function>418 // expected-error @+1 {{custom op 'spirv.Store' expected 2 operands}}419 spirv.Store "Function" %0 : f32420 return421}422 423// -----424 425func.func @volatile_store_missing_lbrace(%arg0 : f32) -> () {426 %0 = spirv.Variable : !spirv.ptr<f32, Function>427 // expected-error @+1 {{expected ':'}}428 spirv.Store "Function" %0, %arg0 "Volatile"] : f32429 return430}431 432// -----433 434func.func @volatile_store_missing_rbrace(%arg0 : f32) -> () {435 %0 = spirv.Variable : !spirv.ptr<f32, Function>436 // expected-error @+1 {{expected ']'}}437 spirv.Store "Function" %0, %arg0 ["Volatile"} : f32438 return439}440 441// -----442 443func.func @aligned_store_missing_alignment(%arg0 : f32) -> () {444 %0 = spirv.Variable : !spirv.ptr<f32, Function>445 // expected-error @+1 {{expected ','}}446 spirv.Store "Function" %0, %arg0 ["Aligned"] : f32447 return448}449 450// -----451 452func.func @aligned_store_missing_comma(%arg0 : f32) -> () {453 %0 = spirv.Variable : !spirv.ptr<f32, Function>454 // expected-error @+1 {{expected ','}}455 spirv.Store "Function" %0, %arg0 ["Aligned" 4] : f32456 return457}458 459// -----460 461func.func @load_incorrect_attributes(%arg0 : f32) -> () {462 %0 = spirv.Variable : !spirv.ptr<f32, Function>463 // expected-error @+1 {{expected ']'}}464 spirv.Store "Function" %0, %arg0 ["Volatile", 4] : f32465 return466}467 468// -----469 470func.func @aligned_store_incorrect_attributes(%arg0 : f32) -> () {471 %0 = spirv.Variable : !spirv.ptr<f32, Function>472 // expected-error @+1 {{expected ']'}}473 spirv.Store "Function" %0, %arg0 ["Aligned", 4, 23] : f32474 return475}476 477// -----478 479spirv.module Logical GLSL450 {480 spirv.GlobalVariable @var0 : !spirv.ptr<f32, Input>481 spirv.func @simple_store(%arg0 : f32) -> () "None" {482 %0 = spirv.mlir.addressof @var0 : !spirv.ptr<f32, Input>483 // CHECK: spirv.Store "Input" {{%.*}}, {{%.*}} : f32484 spirv.Store "Input" %0, %arg0 : f32485 spirv.Return486 }487}488 489// -----490 491//===----------------------------------------------------------------------===//492// spirv.Variable493//===----------------------------------------------------------------------===//494 495func.func @variable(%arg0: f32) -> () {496 // CHECK: spirv.Variable : !spirv.ptr<f32, Function>497 %0 = spirv.Variable : !spirv.ptr<f32, Function>498 return499}500 501// -----502 503func.func @variable_init_normal_constant() -> () {504 // CHECK: %[[cst:.*]] = spirv.Constant505 %0 = spirv.Constant 4.0 : f32506 // CHECK: spirv.Variable init(%[[cst]]) : !spirv.ptr<f32, Function>507 %1 = spirv.Variable init(%0) : !spirv.ptr<f32, Function>508 return509}510 511// -----512 513spirv.module Logical GLSL450 {514 spirv.GlobalVariable @global : !spirv.ptr<f32, Workgroup>515 spirv.func @variable_init_global_variable() -> () "None" {516 %0 = spirv.mlir.addressof @global : !spirv.ptr<f32, Workgroup>517 // CHECK: spirv.Variable init({{.*}}) : !spirv.ptr<!spirv.ptr<f32, Workgroup>, Function>518 %1 = spirv.Variable init(%0) : !spirv.ptr<!spirv.ptr<f32, Workgroup>, Function>519 spirv.Return520 }521}522 523// -----524 525spirv.module Logical GLSL450 {526 spirv.SpecConstant @sc = 42 : i32527 // CHECK-LABEL: @variable_init_spec_constant528 spirv.func @variable_init_spec_constant() -> () "None" {529 %0 = spirv.mlir.referenceof @sc : i32530 // CHECK: spirv.Variable init(%0) : !spirv.ptr<i32, Function>531 %1 = spirv.Variable init(%0) : !spirv.ptr<i32, Function>532 spirv.Return533 }534}535 536// -----537 538func.func @variable_ptr_physical_buffer() -> () {539 %0 = spirv.Variable {aliased_pointer} :540 !spirv.ptr<!spirv.ptr<f32, PhysicalStorageBuffer>, Function>541 %1 = spirv.Variable {restrict_pointer} :542 !spirv.ptr<!spirv.ptr<f32, PhysicalStorageBuffer>, Function>543 return544}545 546// -----547 548func.func @variable_ptr_physical_buffer_no_decoration() -> () {549 // expected-error @+1 {{must be decorated either 'AliasedPointer' or 'RestrictPointer'}}550 %0 = spirv.Variable : !spirv.ptr<!spirv.ptr<f32, PhysicalStorageBuffer>, Function>551 return552}553 554// -----555 556func.func @variable_ptr_physical_buffer_two_alias_decorations() -> () {557 // expected-error @+1 {{must have exactly one aliasing decoration}}558 %0 = spirv.Variable {aliased_pointer, restrict_pointer} :559 !spirv.ptr<!spirv.ptr<f32, PhysicalStorageBuffer>, Function>560 return561}562 563// -----564 565func.func @variable_ptr_array_physical_buffer() -> () {566 %0 = spirv.Variable {aliased_pointer} :567 !spirv.ptr<!spirv.array<4x!spirv.ptr<f32, PhysicalStorageBuffer>>, Function>568 %1 = spirv.Variable {restrict_pointer} :569 !spirv.ptr<!spirv.array<4x!spirv.ptr<f32, PhysicalStorageBuffer>>, Function>570 return571}572 573// -----574 575func.func @variable_ptr_array_physical_buffer_no_decoration() -> () {576 // expected-error @+1 {{must be decorated either 'AliasedPointer' or 'RestrictPointer'}}577 %0 = spirv.Variable :578 !spirv.ptr<!spirv.array<4x!spirv.ptr<f32, PhysicalStorageBuffer>>, Function>579 return580}581 582// -----583 584func.func @variable_ptr_array_physical_buffer_two_alias_decorations() -> () {585 // expected-error @+1 {{must have exactly one aliasing decoration}}586 %0 = spirv.Variable {aliased_pointer, restrict_pointer} :587 !spirv.ptr<!spirv.array<4x!spirv.ptr<f32, PhysicalStorageBuffer>>, Function>588 return589}590 591// -----592 593func.func @variable_bind() -> () {594 // expected-error @+1 {{cannot have 'descriptor_set' attribute (only allowed in spirv.GlobalVariable)}}595 %0 = spirv.Variable bind(1, 2) : !spirv.ptr<f32, Function>596 return597}598 599// -----600 601func.func @variable_init_bind() -> () {602 %0 = spirv.Constant 4.0 : f32603 // expected-error @+1 {{cannot have 'binding' attribute (only allowed in spirv.GlobalVariable)}}604 %1 = spirv.Variable init(%0) {binding = 5 : i32} : !spirv.ptr<f32, Function>605 return606}607 608// -----609 610func.func @variable_builtin() -> () {611 // expected-error @+1 {{cannot have 'built_in' attribute (only allowed in spirv.GlobalVariable)}}612 %1 = spirv.Variable built_in("GlobalInvocationID") : !spirv.ptr<vector<3xi32>, Function>613 return614}615 616// -----617 618func.func @expect_ptr_result_type(%arg0: f32) -> () {619 // expected-error @+1 {{expected spirv.ptr type}}620 %0 = spirv.Variable : f32621 return622}623 624// -----625 626func.func @variable_init(%arg0: f32) -> () {627 // expected-error @+1 {{op initializer must be the result of a constant or spirv.GlobalVariable op}}628 %0 = spirv.Variable init(%arg0) : !spirv.ptr<f32, Function>629 return630}631 632// -----633 634func.func @cannot_be_generic_storage_class(%arg0: f32) -> () {635 // expected-error @+1 {{op can only be used to model function-level variables. Use spirv.GlobalVariable for module-level variables}}636 %0 = spirv.Variable : !spirv.ptr<f32, Generic>637 return638}639 640// -----641 642func.func @copy_memory_incompatible_ptrs() {643 %0 = spirv.Variable : !spirv.ptr<f32, Function>644 %1 = spirv.Variable : !spirv.ptr<i32, Function>645 // expected-error @+1 {{both operands must be pointers to the same type}}646 "spirv.CopyMemory"(%0, %1) {} : (!spirv.ptr<f32, Function>, !spirv.ptr<i32, Function>) -> ()647 spirv.Return648}649 650// -----651 652func.func @copy_memory_invalid_maa() {653 %0 = spirv.Variable : !spirv.ptr<f32, Function>654 %1 = spirv.Variable : !spirv.ptr<f32, Function>655 // expected-error @+1 {{missing alignment value}}656 "spirv.CopyMemory"(%0, %1) {memory_access=#spirv.memory_access<Aligned>} : (!spirv.ptr<f32, Function>, !spirv.ptr<f32, Function>) -> ()657 spirv.Return658}659 660// -----661 662func.func @copy_memory_invalid_source_maa() {663 %0 = spirv.Variable : !spirv.ptr<f32, Function>664 %1 = spirv.Variable : !spirv.ptr<f32, Function>665 // expected-error @+1 {{invalid alignment specification with non-aligned memory access specification}}666 "spirv.CopyMemory"(%0, %1) {source_memory_access=#spirv.memory_access<Volatile>, memory_access=#spirv.memory_access<Aligned>, source_alignment=8 : i32, alignment=4 : i32} : (!spirv.ptr<f32, Function>, !spirv.ptr<f32, Function>) -> ()667 spirv.Return668}669 670// -----671 672func.func @copy_memory_invalid_source_maa2() {673 %0 = spirv.Variable : !spirv.ptr<f32, Function>674 %1 = spirv.Variable : !spirv.ptr<f32, Function>675 // expected-error @+1 {{missing alignment value}}676 "spirv.CopyMemory"(%0, %1) {source_memory_access=#spirv.memory_access<Aligned>, memory_access=#spirv.memory_access<Aligned>, alignment=4 : i32} : (!spirv.ptr<f32, Function>, !spirv.ptr<f32, Function>) -> ()677 spirv.Return678}679 680// -----681 682func.func @copy_memory_print_maa() {683 %0 = spirv.Variable : !spirv.ptr<f32, Function>684 %1 = spirv.Variable : !spirv.ptr<f32, Function>685 686 // CHECK: spirv.CopyMemory "Function" %{{.*}}, "Function" %{{.*}} ["Volatile"] : f32687 "spirv.CopyMemory"(%0, %1) {memory_access=#spirv.memory_access<Volatile>} : (!spirv.ptr<f32, Function>, !spirv.ptr<f32, Function>) -> ()688 689 // CHECK: spirv.CopyMemory "Function" %{{.*}}, "Function" %{{.*}} ["Aligned", 4] : f32690 "spirv.CopyMemory"(%0, %1) {memory_access=#spirv.memory_access<Aligned>, alignment=4 : i32} : (!spirv.ptr<f32, Function>, !spirv.ptr<f32, Function>) -> ()691 692 // CHECK: spirv.CopyMemory "Function" %{{.*}}, "Function" %{{.*}} ["Aligned", 4], ["Volatile"] : f32693 "spirv.CopyMemory"(%0, %1) {source_memory_access=#spirv.memory_access<Volatile>, memory_access=#spirv.memory_access<Aligned>, alignment=4 : i32} : (!spirv.ptr<f32, Function>, !spirv.ptr<f32, Function>) -> ()694 695 // CHECK: spirv.CopyMemory "Function" %{{.*}}, "Function" %{{.*}} ["Aligned", 4], ["Aligned", 8] : f32696 "spirv.CopyMemory"(%0, %1) {source_memory_access=#spirv.memory_access<Aligned>, memory_access=#spirv.memory_access<Aligned>, source_alignment=8 : i32, alignment=4 : i32} : (!spirv.ptr<f32, Function>, !spirv.ptr<f32, Function>) -> ()697 698 spirv.Return699}700 701// -----702 703//===----------------------------------------------------------------------===//704// spirv.PtrAccessChain705//===----------------------------------------------------------------------===//706 707// CHECK-LABEL: func @ptr_access_chain1(708// CHECK-SAME: %[[ARG0:.*]]: !spirv.ptr<f32, CrossWorkgroup>,709// CHECK-SAME: %[[ARG1:.*]]: i64)710// CHECK: spirv.PtrAccessChain %[[ARG0]][%[[ARG1]]] : !spirv.ptr<f32, CrossWorkgroup>, i64711func.func @ptr_access_chain1(%arg0: !spirv.ptr<f32, CrossWorkgroup>, %arg1 : i64) -> () {712 %0 = spirv.PtrAccessChain %arg0[%arg1] : !spirv.ptr<f32, CrossWorkgroup>, i64 -> !spirv.ptr<f32, CrossWorkgroup>713 return714}715 716// -----717 718//===----------------------------------------------------------------------===//719// spirv.InBoundsPtrAccessChain720//===----------------------------------------------------------------------===//721 722// CHECK-LABEL: func @inbounds_ptr_access_chain1(723// CHECK-SAME: %[[ARG0:.*]]: !spirv.ptr<f32, CrossWorkgroup>,724// CHECK-SAME: %[[ARG1:.*]]: i64)725// CHECK: spirv.InBoundsPtrAccessChain %[[ARG0]][%[[ARG1]]] : !spirv.ptr<f32, CrossWorkgroup>, i64726func.func @inbounds_ptr_access_chain1(%arg0: !spirv.ptr<f32, CrossWorkgroup>, %arg1 : i64) -> () {727 %0 = spirv.InBoundsPtrAccessChain %arg0[%arg1] : !spirv.ptr<f32, CrossWorkgroup>, i64 -> !spirv.ptr<f32, CrossWorkgroup>728 return729}730