1// RUN: mlir-opt -allow-unregistered-dialect -split-input-file -verify-diagnostics %s | FileCheck %s 2 3//===----------------------------------------------------------------------===// 4// spv.AccessChain 5//===----------------------------------------------------------------------===// 6 7func @access_chain_struct() -> () { 8 %0 = spv.constant 1: i32 9 %1 = spv.Variable : !spv.ptr<!spv.struct<(f32, !spv.array<4xf32>)>, Function> 10 // CHECK: spv.AccessChain {{.*}}[{{.*}}, {{.*}}] : !spv.ptr<!spv.struct<(f32, !spv.array<4 x f32>)>, Function> 11 %2 = spv.AccessChain %1[%0, %0] : !spv.ptr<!spv.struct<(f32, !spv.array<4xf32>)>, Function>, i32, i32 12 return 13} 14 15func @access_chain_1D_array(%arg0 : i32) -> () { 16 %0 = spv.Variable : !spv.ptr<!spv.array<4xf32>, Function> 17 // CHECK: spv.AccessChain {{.*}}[{{.*}}] : !spv.ptr<!spv.array<4 x f32>, Function> 18 %1 = spv.AccessChain %0[%arg0] : !spv.ptr<!spv.array<4xf32>, Function>, i32 19 return 20} 21 22func @access_chain_2D_array_1(%arg0 : i32) -> () { 23 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 24 // CHECK: spv.AccessChain {{.*}}[{{.*}}, {{.*}}] : !spv.ptr<!spv.array<4 x !spv.array<4 x f32>>, Function> 25 %1 = spv.AccessChain %0[%arg0, %arg0] : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>, i32, i32 26 %2 = spv.Load "Function" %1 ["Volatile"] : f32 27 return 28} 29 30func @access_chain_2D_array_2(%arg0 : i32) -> () { 31 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 32 // CHECK: spv.AccessChain {{.*}}[{{.*}}] : !spv.ptr<!spv.array<4 x !spv.array<4 x f32>>, Function> 33 %1 = spv.AccessChain %0[%arg0] : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>, i32 34 %2 = spv.Load "Function" %1 ["Volatile"] : !spv.array<4xf32> 35 return 36} 37 38func @access_chain_rtarray(%arg0 : i32) -> () { 39 %0 = spv.Variable : !spv.ptr<!spv.rtarray<f32>, Function> 40 // CHECK: spv.AccessChain {{.*}}[{{.*}}] : !spv.ptr<!spv.rtarray<f32>, Function> 41 %1 = spv.AccessChain %0[%arg0] : !spv.ptr<!spv.rtarray<f32>, Function>, i32 42 %2 = spv.Load "Function" %1 ["Volatile"] : f32 43 return 44} 45 46// ----- 47 48func @access_chain_non_composite() -> () { 49 %0 = spv.constant 1: i32 50 %1 = spv.Variable : !spv.ptr<f32, Function> 51 // expected-error @+1 {{cannot extract from non-composite type 'f32' with index 0}} 52 %2 = spv.AccessChain %1[%0] : !spv.ptr<f32, Function>, i32 53 return 54} 55 56// ----- 57 58func @access_chain_no_indices(%index0 : i32) -> () { 59 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 60 // expected-error @+1 {{expected at least one index}} 61 %1 = spv.AccessChain %0[] : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>, i32 62 return 63} 64 65// ----- 66 67func @access_chain_missing_comma(%index0 : i32) -> () { 68 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 69 // expected-error @+1 {{expected ','}} 70 %1 = spv.AccessChain %0[%index0] : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> i32 71 return 72} 73 74// ----- 75 76func @access_chain_invalid_indices_types_count(%index0 : i32) -> () { 77 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 78 // expected-error @+1 {{'spv.AccessChain' op indices types' count must be equal to indices info count}} 79 %1 = spv.AccessChain %0[%index0] : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>, i32, i32 80 return 81} 82 83// ----- 84 85func @access_chain_missing_indices_type(%index0 : i32) -> () { 86 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 87 // expected-error @+1 {{'spv.AccessChain' op indices types' count must be equal to indices info count}} 88 %1 = spv.AccessChain %0[%index0, %index0] : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>, i32 89 return 90} 91 92// ----- 93 94func @access_chain_invalid_type(%index0 : i32) -> () { 95 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 96 %1 = spv.Load "Function" %0 ["Volatile"] : !spv.array<4x!spv.array<4xf32>> 97 // expected-error @+1 {{expected a pointer to composite type, but provided '!spv.array<4 x !spv.array<4 x f32>>'}} 98 %2 = spv.AccessChain %1[%index0] : !spv.array<4x!spv.array<4xf32>>, i32 99 return 100} 101 102// ----- 103 104func @access_chain_invalid_index_1(%index0 : i32) -> () { 105 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 106 // expected-error @+1 {{expected SSA operand}} 107 %1 = spv.AccessChain %0[%index, 4] : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>, i32, i32 108 return 109} 110 111// ----- 112 113func @access_chain_invalid_index_2(%index0 : i32) -> () { 114 %0 = spv.Variable : !spv.ptr<!spv.struct<(f32, !spv.array<4xf32>)>, Function> 115 // expected-error @+1 {{index must be an integer spv.constant to access element of spv.struct}} 116 %1 = spv.AccessChain %0[%index0, %index0] : !spv.ptr<!spv.struct<(f32, !spv.array<4xf32>)>, Function>, i32, i32 117 return 118} 119 120// ----- 121 122func @access_chain_invalid_constant_type_1() -> () { 123 %0 = std.constant 1: i32 124 %1 = spv.Variable : !spv.ptr<!spv.struct<(f32, !spv.array<4xf32>)>, Function> 125 // expected-error @+1 {{index must be an integer spv.constant to access element of spv.struct, but provided std.constant}} 126 %2 = spv.AccessChain %1[%0, %0] : !spv.ptr<!spv.struct<(f32, !spv.array<4xf32>)>, Function>, i32, i32 127 return 128} 129 130// ----- 131 132func @access_chain_out_of_bounds() -> () { 133 %index0 = "spv.constant"() { value = 12: i32} : () -> i32 134 %0 = spv.Variable : !spv.ptr<!spv.struct<(f32, !spv.array<4xf32>)>, Function> 135 // expected-error @+1 {{'spv.AccessChain' op index 12 out of bounds for '!spv.struct<(f32, !spv.array<4 x f32>)>'}} 136 %1 = spv.AccessChain %0[%index0, %index0] : !spv.ptr<!spv.struct<(f32, !spv.array<4xf32>)>, Function>, i32, i32 137 return 138} 139 140// ----- 141 142func @access_chain_invalid_accessing_type(%index0 : i32) -> () { 143 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 144 // expected-error @+1 {{cannot extract from non-composite type 'f32' with index 0}} 145 %1 = spv.AccessChain %0[%index, %index0, %index0] : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>, i32, i32, i32 146 return 147 148// ----- 149 150//===----------------------------------------------------------------------===// 151// spv.Bitcast 152//===----------------------------------------------------------------------===// 153 154func @cast1(%arg0 : f32) { 155 // CHECK: {{%.*}} = spv.Bitcast {{%.*}} : f32 to i32 156 %0 = spv.Bitcast %arg0 : f32 to i32 157 return 158} 159 160func @cast2(%arg0 : vector<2xf32>) { 161 // CHECK: {{%.*}} = spv.Bitcast {{%.*}} : vector<2xf32> to vector<2xi32> 162 %0 = spv.Bitcast %arg0 : vector<2xf32> to vector<2xi32> 163 return 164} 165 166func @cast3(%arg0 : vector<2xf32>) { 167 // CHECK: {{%.*}} = spv.Bitcast {{%.*}} : vector<2xf32> to i64 168 %0 = spv.Bitcast %arg0 : vector<2xf32> to i64 169 return 170} 171 172func @cast4(%arg0 : !spv.ptr<f32, Function>) { 173 // CHECK: {{%.*}} = spv.Bitcast {{%.*}} : !spv.ptr<f32, Function> to !spv.ptr<i32, Function> 174 %0 = spv.Bitcast %arg0 : !spv.ptr<f32, Function> to !spv.ptr<i32, Function> 175 return 176} 177 178func @cast5(%arg0 : !spv.ptr<f32, Function>) { 179 // CHECK: {{%.*}} = spv.Bitcast {{%.*}} : !spv.ptr<f32, Function> to !spv.ptr<vector<2xi32>, Function> 180 %0 = spv.Bitcast %arg0 : !spv.ptr<f32, Function> to !spv.ptr<vector<2xi32>, Function> 181 return 182} 183 184func @cast6(%arg0 : vector<4xf32>) { 185 // CHECK: {{%.*}} = spv.Bitcast {{%.*}} : vector<4xf32> to vector<2xi64> 186 %0 = spv.Bitcast %arg0 : vector<4xf32> to vector<2xi64> 187 return 188} 189 190// ----- 191 192func @cast1(%arg0 : f32) { 193 // expected-error @+1 {{result type must be different from operand type}} 194 %0 = spv.Bitcast %arg0 : f32 to f32 195 return 196} 197 198// ----- 199 200func @cast1(%arg0 : f32) { 201 // expected-error @+1 {{mismatch in result type bitwidth 64 and operand type bitwidth 32}} 202 %0 = spv.Bitcast %arg0 : f32 to i64 203 return 204} 205 206// ----- 207 208func @cast1(%arg0 : vector<2xf32>) { 209 // expected-error @+1 {{mismatch in result type bitwidth 96 and operand type bitwidth 64}} 210 %0 = spv.Bitcast %arg0 : vector<2xf32> to vector<3xf32> 211 return 212} 213 214// ----- 215 216func @cast3(%arg0 : !spv.ptr<f32, Function>) { 217 // expected-error @+1 {{unhandled bit cast conversion from pointer type to non-pointer type}} 218 %0 = spv.Bitcast %arg0 : !spv.ptr<f32, Function> to i64 219 return 220} 221 222// ----- 223 224func @cast3(%arg0 : i64) { 225 // expected-error @+1 {{unhandled bit cast conversion from non-pointer type to pointer type}} 226 %0 = spv.Bitcast %arg0 : i64 to !spv.ptr<f32, Function> 227 return 228} 229 230// ----- 231 232//===----------------------------------------------------------------------===// 233// spv.BitCount 234//===----------------------------------------------------------------------===// 235 236func @bitcount(%arg: i32) -> i32 { 237 // CHECK: spv.BitCount {{%.*}} : i32 238 %0 = spv.BitCount %arg : i32 239 spv.ReturnValue %0 : i32 240} 241 242// ----- 243 244//===----------------------------------------------------------------------===// 245// spv.BitFieldInsert 246//===----------------------------------------------------------------------===// 247 248func @bit_field_insert_vec(%base: vector<3xi32>, %insert: vector<3xi32>, %offset: i32, %count: i16) -> vector<3xi32> { 249 // CHECK: {{%.*}} = spv.BitFieldInsert {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : vector<3xi32>, i32, i16 250 %0 = spv.BitFieldInsert %base, %insert, %offset, %count : vector<3xi32>, i32, i16 251 spv.ReturnValue %0 : vector<3xi32> 252} 253 254// ----- 255 256func @bit_field_insert_invalid_insert_type(%base: vector<3xi32>, %insert: vector<2xi32>, %offset: i32, %count: i16) -> vector<3xi32> { 257 // expected-error @+1 {{all of {base, insert, result} have same type}} 258 %0 = "spv.BitFieldInsert" (%base, %insert, %offset, %count) : (vector<3xi32>, vector<2xi32>, i32, i16) -> vector<3xi32> 259 spv.ReturnValue %0 : vector<3xi32> 260} 261 262// ----- 263 264//===----------------------------------------------------------------------===// 265// spv.BitFieldSExtract 266//===----------------------------------------------------------------------===// 267 268func @bit_field_s_extract_vec(%base: vector<3xi32>, %offset: i8, %count: i8) -> vector<3xi32> { 269 // CHECK: {{%.*}} = spv.BitFieldSExtract {{%.*}}, {{%.*}}, {{%.*}} : vector<3xi32>, i8, i8 270 %0 = spv.BitFieldSExtract %base, %offset, %count : vector<3xi32>, i8, i8 271 spv.ReturnValue %0 : vector<3xi32> 272} 273 274//===----------------------------------------------------------------------===// 275// spv.BitFieldUExtract 276//===----------------------------------------------------------------------===// 277 278func @bit_field_u_extract_vec(%base: vector<3xi32>, %offset: i8, %count: i8) -> vector<3xi32> { 279 // CHECK: {{%.*}} = spv.BitFieldUExtract {{%.*}}, {{%.*}}, {{%.*}} : vector<3xi32>, i8, i8 280 %0 = spv.BitFieldUExtract %base, %offset, %count : vector<3xi32>, i8, i8 281 spv.ReturnValue %0 : vector<3xi32> 282} 283 284// ----- 285 286func @bit_field_u_extract_invalid_result_type(%base: vector<3xi32>, %offset: i32, %count: i16) -> vector<4xi32> { 287 // expected-error @+1 {{failed to verify that all of {base, result} have same type}} 288 %0 = "spv.BitFieldUExtract" (%base, %offset, %count) : (vector<3xi32>, i32, i16) -> vector<4xi32> 289 spv.ReturnValue %0 : vector<4xi32> 290} 291 292// ----- 293 294//===----------------------------------------------------------------------===// 295// spv.BitReverse 296//===----------------------------------------------------------------------===// 297 298func @bitreverse(%arg: i32) -> i32 { 299 // CHECK: spv.BitReverse {{%.*}} : i32 300 %0 = spv.BitReverse %arg : i32 301 spv.ReturnValue %0 : i32 302} 303 304// ----- 305 306//===----------------------------------------------------------------------===// 307// spv.ControlBarrier 308//===----------------------------------------------------------------------===// 309 310func @control_barrier_0() -> () { 311 // CHECK: spv.ControlBarrier "Workgroup", "Device", "Acquire|UniformMemory" 312 spv.ControlBarrier "Workgroup", "Device", "Acquire|UniformMemory" 313 return 314} 315 316// ----- 317 318func @control_barrier_1() -> () { 319 // expected-error @+1 {{invalid execution_scope attribute specification: "Something"}} 320 spv.ControlBarrier "Something", "Device", "Acquire|UniformMemory" 321 return 322} 323 324// ----- 325 326//===----------------------------------------------------------------------===// 327// spv.ConvertFToS 328//===----------------------------------------------------------------------===// 329 330func @convert_f_to_s_scalar(%arg0 : f32) -> i32 { 331 // CHECK: {{%.*}} = spv.ConvertFToS {{%.*}} : f32 to i32 332 %0 = spv.ConvertFToS %arg0 : f32 to i32 333 spv.ReturnValue %0 : i32 334} 335 336// ----- 337 338func @convert_f64_to_s32_scalar(%arg0 : f64) -> i32 { 339 // CHECK: {{%.*}} = spv.ConvertFToS {{%.*}} : f64 to i32 340 %0 = spv.ConvertFToS %arg0 : f64 to i32 341 spv.ReturnValue %0 : i32 342} 343 344// ----- 345 346func @convert_f_to_s_vector(%arg0 : vector<3xf32>) -> vector<3xi32> { 347 // CHECK: {{%.*}} = spv.ConvertFToS {{%.*}} : vector<3xf32> to vector<3xi32> 348 %0 = spv.ConvertFToS %arg0 : vector<3xf32> to vector<3xi32> 349 spv.ReturnValue %0 : vector<3xi32> 350} 351 352// ----- 353 354//===----------------------------------------------------------------------===// 355// spv.ConvertFToU 356//===----------------------------------------------------------------------===// 357 358func @convert_f_to_u_scalar(%arg0 : f32) -> i32 { 359 // CHECK: {{%.*}} = spv.ConvertFToU {{%.*}} : f32 to i32 360 %0 = spv.ConvertFToU %arg0 : f32 to i32 361 spv.ReturnValue %0 : i32 362} 363 364// ----- 365 366func @convert_f64_to_u32_scalar(%arg0 : f64) -> i32 { 367 // CHECK: {{%.*}} = spv.ConvertFToU {{%.*}} : f64 to i32 368 %0 = spv.ConvertFToU %arg0 : f64 to i32 369 spv.ReturnValue %0 : i32 370} 371 372// ----- 373 374func @convert_f_to_u_vector(%arg0 : vector<3xf32>) -> vector<3xi32> { 375 // CHECK: {{%.*}} = spv.ConvertFToU {{%.*}} : vector<3xf32> to vector<3xi32> 376 %0 = spv.ConvertFToU %arg0 : vector<3xf32> to vector<3xi32> 377 spv.ReturnValue %0 : vector<3xi32> 378} 379 380// ----- 381 382func @convert_f_to_u_coopmatrix(%arg0 : !spv.coopmatrix<8x16xf32, Subgroup>) { 383 // CHECK: {{%.*}} = spv.ConvertFToU {{%.*}} : !spv.coopmatrix<8x16xf32, Subgroup> to !spv.coopmatrix<8x16xi32, Subgroup> 384 %0 = spv.ConvertFToU %arg0 : !spv.coopmatrix<8x16xf32, Subgroup> to !spv.coopmatrix<8x16xi32, Subgroup> 385 spv.Return 386} 387 388// ----- 389 390//===----------------------------------------------------------------------===// 391// spv.ConvertSToF 392//===----------------------------------------------------------------------===// 393 394func @convert_s_to_f_scalar(%arg0 : i32) -> f32 { 395 // CHECK: {{%.*}} = spv.ConvertSToF {{%.*}} : i32 to f32 396 %0 = spv.ConvertSToF %arg0 : i32 to f32 397 spv.ReturnValue %0 : f32 398} 399 400// ----- 401 402func @convert_s64_to_f32_scalar(%arg0 : i64) -> f32 { 403 // CHECK: {{%.*}} = spv.ConvertSToF {{%.*}} : i64 to f32 404 %0 = spv.ConvertSToF %arg0 : i64 to f32 405 spv.ReturnValue %0 : f32 406} 407 408// ----- 409 410func @convert_s_to_f_vector(%arg0 : vector<3xi32>) -> vector<3xf32> { 411 // CHECK: {{%.*}} = spv.ConvertSToF {{%.*}} : vector<3xi32> to vector<3xf32> 412 %0 = spv.ConvertSToF %arg0 : vector<3xi32> to vector<3xf32> 413 spv.ReturnValue %0 : vector<3xf32> 414} 415 416// ----- 417 418//===----------------------------------------------------------------------===// 419// spv.ConvertUToF 420//===----------------------------------------------------------------------===// 421 422func @convert_u_to_f_scalar(%arg0 : i32) -> f32 { 423 // CHECK: {{%.*}} = spv.ConvertUToF {{%.*}} : i32 to f32 424 %0 = spv.ConvertUToF %arg0 : i32 to f32 425 spv.ReturnValue %0 : f32 426} 427 428// ----- 429 430func @convert_u64_to_f32_scalar(%arg0 : i64) -> f32 { 431 // CHECK: {{%.*}} = spv.ConvertUToF {{%.*}} : i64 to f32 432 %0 = spv.ConvertUToF %arg0 : i64 to f32 433 spv.ReturnValue %0 : f32 434} 435 436// ----- 437 438func @convert_u_to_f_vector(%arg0 : vector<3xi32>) -> vector<3xf32> { 439 // CHECK: {{%.*}} = spv.ConvertUToF {{%.*}} : vector<3xi32> to vector<3xf32> 440 %0 = spv.ConvertUToF %arg0 : vector<3xi32> to vector<3xf32> 441 spv.ReturnValue %0 : vector<3xf32> 442} 443 444// ----- 445 446//===----------------------------------------------------------------------===// 447// spv.FConvert 448//===----------------------------------------------------------------------===// 449 450func @f_convert_scalar(%arg0 : f32) -> f64 { 451 // CHECK: {{%.*}} = spv.FConvert {{%.*}} : f32 to f64 452 %0 = spv.FConvert %arg0 : f32 to f64 453 spv.ReturnValue %0 : f64 454} 455 456// ----- 457 458func @f_convert_vector(%arg0 : vector<3xf32>) -> vector<3xf64> { 459 // CHECK: {{%.*}} = spv.FConvert {{%.*}} : vector<3xf32> to vector<3xf64> 460 %0 = spv.FConvert %arg0 : vector<3xf32> to vector<3xf64> 461 spv.ReturnValue %0 : vector<3xf64> 462} 463 464// ----- 465 466func @f_convert_coop_matrix(%arg0 : !spv.coopmatrix<8x16xf32, Subgroup>) { 467 // CHECK: {{%.*}} = spv.FConvert {{%.*}} : !spv.coopmatrix<8x16xf32, Subgroup> to !spv.coopmatrix<8x16xf64, Subgroup> 468 %0 = spv.FConvert %arg0 : !spv.coopmatrix<8x16xf32, Subgroup> to !spv.coopmatrix<8x16xf64, Subgroup> 469 spv.Return 470} 471 472// ----- 473 474func @f_convert_vector(%arg0 : f32) -> f32 { 475 // expected-error @+1 {{expected the different bit widths for operand type and result type, but provided 'f32' and 'f32'}} 476 %0 = spv.FConvert %arg0 : f32 to f32 477 spv.ReturnValue %0 : f32 478} 479 480// ----- 481 482//===----------------------------------------------------------------------===// 483// spv.SConvert 484//===----------------------------------------------------------------------===// 485 486func @s_convert_scalar(%arg0 : i32) -> i64 { 487 // CHECK: {{%.*}} = spv.SConvert {{%.*}} : i32 to i64 488 %0 = spv.SConvert %arg0 : i32 to i64 489 spv.ReturnValue %0 : i64 490} 491 492// ----- 493 494//===----------------------------------------------------------------------===// 495// spv.UConvert 496//===----------------------------------------------------------------------===// 497 498func @u_convert_scalar(%arg0 : i32) -> i64 { 499 // CHECK: {{%.*}} = spv.UConvert {{%.*}} : i32 to i64 500 %0 = spv.UConvert %arg0 : i32 to i64 501 spv.ReturnValue %0 : i64 502} 503 504// ----- 505 506//===----------------------------------------------------------------------===// 507// spv.ExecutionMode 508//===----------------------------------------------------------------------===// 509 510spv.module Logical GLSL450 { 511 spv.func @do_nothing() -> () "None" { 512 spv.Return 513 } 514 spv.EntryPoint "GLCompute" @do_nothing 515 // CHECK: spv.ExecutionMode {{@.*}} "ContractionOff" 516 spv.ExecutionMode @do_nothing "ContractionOff" 517} 518 519spv.module Logical GLSL450 { 520 spv.func @do_nothing() -> () "None" { 521 spv.Return 522 } 523 spv.EntryPoint "GLCompute" @do_nothing 524 // CHECK: spv.ExecutionMode {{@.*}} "LocalSizeHint", 3, 4, 5 525 spv.ExecutionMode @do_nothing "LocalSizeHint", 3, 4, 5 526} 527 528// ----- 529 530spv.module Logical GLSL450 { 531 spv.func @do_nothing() -> () "None" { 532 spv.Return 533 } 534 spv.EntryPoint "GLCompute" @do_nothing 535 // expected-error @+1 {{custom op 'spv.ExecutionMode' invalid execution_mode attribute specification: "GLCompute"}} 536 spv.ExecutionMode @do_nothing "GLCompute", 3, 4, 5 537} 538 539// ----- 540 541//===----------------------------------------------------------------------===// 542// spv.LoadOp 543//===----------------------------------------------------------------------===// 544 545// CHECK-LABEL: @simple_load 546func @simple_load() -> () { 547 %0 = spv.Variable : !spv.ptr<f32, Function> 548 // CHECK: spv.Load "Function" %{{.*}} : f32 549 %1 = spv.Load "Function" %0 : f32 550 return 551} 552 553// CHECK-LABEL: @load_none_access 554func @load_none_access() -> () { 555 %0 = spv.Variable : !spv.ptr<f32, Function> 556 // CHECK: spv.Load "Function" %{{.*}} ["None"] : f32 557 %1 = spv.Load "Function" %0 ["None"] : f32 558 return 559} 560 561// CHECK-LABEL: @volatile_load 562func @volatile_load() -> () { 563 %0 = spv.Variable : !spv.ptr<f32, Function> 564 // CHECK: spv.Load "Function" %{{.*}} ["Volatile"] : f32 565 %1 = spv.Load "Function" %0 ["Volatile"] : f32 566 return 567} 568 569// CHECK-LABEL: @aligned_load 570func @aligned_load() -> () { 571 %0 = spv.Variable : !spv.ptr<f32, Function> 572 // CHECK: spv.Load "Function" %{{.*}} ["Aligned", 4] : f32 573 %1 = spv.Load "Function" %0 ["Aligned", 4] : f32 574 return 575} 576 577// CHECK-LABEL: @volatile_aligned_load 578func @volatile_aligned_load() -> () { 579 %0 = spv.Variable : !spv.ptr<f32, Function> 580 // CHECK: spv.Load "Function" %{{.*}} ["Volatile|Aligned", 4] : f32 581 %1 = spv.Load "Function" %0 ["Volatile|Aligned", 4] : f32 582 return 583} 584 585// ----- 586 587// CHECK-LABEL: load_none_access 588func @load_none_access() -> () { 589 %0 = spv.Variable : !spv.ptr<f32, Function> 590 // CHECK: spv.Load 591 // CHECK-SAME: ["None"] 592 %1 = "spv.Load"(%0) {memory_access = 0 : i32} : (!spv.ptr<f32, Function>) -> (f32) 593 return 594} 595 596// CHECK-LABEL: volatile_load 597func @volatile_load() -> () { 598 %0 = spv.Variable : !spv.ptr<f32, Function> 599 // CHECK: spv.Load 600 // CHECK-SAME: ["Volatile"] 601 %1 = "spv.Load"(%0) {memory_access = 1 : i32} : (!spv.ptr<f32, Function>) -> (f32) 602 return 603} 604 605// CHECK-LABEL: aligned_load 606func @aligned_load() -> () { 607 %0 = spv.Variable : !spv.ptr<f32, Function> 608 // CHECK: spv.Load 609 // CHECK-SAME: ["Aligned", 4] 610 %1 = "spv.Load"(%0) {memory_access = 2 : i32, alignment = 4 : i32} : (!spv.ptr<f32, Function>) -> (f32) 611 return 612} 613 614// CHECK-LABEL: volatile_aligned_load 615func @volatile_aligned_load() -> () { 616 %0 = spv.Variable : !spv.ptr<f32, Function> 617 // CHECK: spv.Load 618 // CHECK-SAME: ["Volatile|Aligned", 4] 619 %1 = "spv.Load"(%0) {memory_access = 3 : i32, alignment = 4 : i32} : (!spv.ptr<f32, Function>) -> (f32) 620 return 621} 622 623// ----- 624 625func @simple_load_missing_storageclass() -> () { 626 %0 = spv.Variable : !spv.ptr<f32, Function> 627 // expected-error @+1 {{expected non-function type}} 628 %1 = spv.Load %0 : f32 629 return 630} 631 632// ----- 633 634func @simple_load_missing_operand() -> () { 635 %0 = spv.Variable : !spv.ptr<f32, Function> 636 // expected-error @+1 {{expected SSA operand}} 637 %1 = spv.Load "Function" : f32 638 return 639} 640 641// ----- 642 643func @simple_load_missing_rettype() -> () { 644 %0 = spv.Variable : !spv.ptr<f32, Function> 645 // expected-error @+2 {{expected ':'}} 646 %1 = spv.Load "Function" %0 647 return 648} 649 650// ----- 651 652func @volatile_load_missing_lbrace() -> () { 653 %0 = spv.Variable : !spv.ptr<f32, Function> 654 // expected-error @+1 {{expected ':'}} 655 %1 = spv.Load "Function" %0 "Volatile"] : f32 656 return 657} 658 659// ----- 660 661func @volatile_load_missing_rbrace() -> () { 662 %0 = spv.Variable : !spv.ptr<f32, Function> 663 // expected-error @+1 {{expected ']'}} 664 %1 = spv.Load "Function" %0 ["Volatile"} : f32 665 return 666} 667 668// ----- 669 670func @aligned_load_missing_alignment() -> () { 671 %0 = spv.Variable : !spv.ptr<f32, Function> 672 // expected-error @+1 {{expected ','}} 673 %1 = spv.Load "Function" %0 ["Aligned"] : f32 674 return 675} 676 677// ----- 678 679func @aligned_load_missing_comma() -> () { 680 %0 = spv.Variable : !spv.ptr<f32, Function> 681 // expected-error @+1 {{expected ','}} 682 %1 = spv.Load "Function" %0 ["Aligned" 4] : f32 683 return 684} 685 686// ----- 687 688func @load_incorrect_attributes() -> () { 689 %0 = spv.Variable : !spv.ptr<f32, Function> 690 // expected-error @+1 {{expected ']'}} 691 %1 = spv.Load "Function" %0 ["Volatile", 4] : f32 692 return 693} 694 695// ----- 696 697func @load_unknown_memory_access() -> () { 698 %0 = spv.Variable : !spv.ptr<f32, Function> 699 // expected-error @+1 {{custom op 'spv.Load' invalid memory_access attribute specification: "Something"}} 700 %1 = spv.Load "Function" %0 ["Something"] : f32 701 return 702} 703 704// ----- 705 706func @load_unknown_memory_access() -> () { 707 %0 = spv.Variable : !spv.ptr<f32, Function> 708 // expected-error @+1 {{custom op 'spv.Load' invalid memory_access attribute specification: "Volatile|Something"}} 709 %1 = spv.Load "Function" %0 ["Volatile|Something"] : f32 710 return 711} 712 713// ----- 714 715func @load_unknown_memory_access() -> () { 716 %0 = spv.Variable : !spv.ptr<f32, Function> 717 // expected-error @+1 {{failed to satisfy constraint: valid SPIR-V MemoryAccess}} 718 %1 = "spv.Load"(%0) {memory_access = 0x80000000 : i32} : (!spv.ptr<f32, Function>) -> (f32) 719 return 720} 721 722// ----- 723 724func @aligned_load_incorrect_attributes() -> () { 725 %0 = spv.Variable : !spv.ptr<f32, Function> 726 // expected-error @+1 {{expected ']'}} 727 %1 = spv.Load "Function" %0 ["Aligned", 4, 23] : f32 728 return 729} 730 731// ----- 732 733spv.module Logical GLSL450 { 734 spv.globalVariable @var0 : !spv.ptr<f32, Input> 735 // CHECK_LABEL: @simple_load 736 spv.func @simple_load() -> () "None" { 737 // CHECK: spv.Load "Input" {{%.*}} : f32 738 %0 = spv.mlir.addressof @var0 : !spv.ptr<f32, Input> 739 %1 = spv.Load "Input" %0 : f32 740 spv.Return 741 } 742} 743 744// ----- 745 746//===----------------------------------------------------------------------===// 747// spv.LogicalAnd 748//===----------------------------------------------------------------------===// 749 750func @logicalBinary(%arg0 : i1, %arg1 : i1, %arg2 : i1) 751{ 752 // CHECK: [[TMP:%.*]] = spv.LogicalAnd {{%.*}}, {{%.*}} : i1 753 %0 = spv.LogicalAnd %arg0, %arg1 : i1 754 // CHECK: {{%.*}} = spv.LogicalAnd [[TMP]], {{%.*}} : i1 755 %1 = spv.LogicalAnd %0, %arg2 : i1 756 return 757} 758 759func @logicalBinary2(%arg0 : vector<4xi1>, %arg1 : vector<4xi1>) 760{ 761 // CHECK: {{%.*}} = spv.LogicalAnd {{%.*}}, {{%.*}} : vector<4xi1> 762 %0 = spv.LogicalAnd %arg0, %arg1 : vector<4xi1> 763 return 764} 765 766// ----- 767 768func @logicalBinary(%arg0 : i1, %arg1 : i1) 769{ 770 // expected-error @+2 {{expected ':'}} 771 %0 = spv.LogicalAnd %arg0, %arg1 772 return 773} 774 775// ----- 776 777func @logicalBinary(%arg0 : i1, %arg1 : i1) 778{ 779 // expected-error @+2 {{expected non-function type}} 780 %0 = spv.LogicalAnd %arg0, %arg1 : 781 return 782} 783 784// ----- 785 786func @logicalBinary(%arg0 : i1, %arg1 : i1) 787{ 788 // expected-error @+1 {{custom op 'spv.LogicalAnd' expected 2 operands}} 789 %0 = spv.LogicalAnd %arg0 : i1 790 return 791} 792 793// ----- 794 795//===----------------------------------------------------------------------===// 796// spv.LogicalNot 797//===----------------------------------------------------------------------===// 798 799func @logicalUnary(%arg0 : i1, %arg1 : i1) 800{ 801 // CHECK: [[TMP:%.*]] = spv.LogicalNot {{%.*}} : i1 802 %0 = spv.LogicalNot %arg0 : i1 803 // CHECK: {{%.*}} = spv.LogicalNot [[TMP]] : i1 804 %1 = spv.LogicalNot %0 : i1 805 return 806} 807 808func @logicalUnary2(%arg0 : vector<4xi1>) 809{ 810 // CHECK: {{%.*}} = spv.LogicalNot {{%.*}} : vector<4xi1> 811 %0 = spv.LogicalNot %arg0 : vector<4xi1> 812 return 813} 814 815// ----- 816 817func @logicalUnary(%arg0 : i1) 818{ 819 // expected-error @+2 {{expected ':'}} 820 %0 = spv.LogicalNot %arg0 821 return 822} 823 824// ----- 825 826func @logicalUnary(%arg0 : i1) 827{ 828 // expected-error @+2 {{expected non-function type}} 829 %0 = spv.LogicalNot %arg0 : 830 return 831} 832 833// ----- 834 835func @logicalUnary(%arg0 : i1) 836{ 837 // expected-error @+1 {{expected SSA operand}} 838 %0 = spv.LogicalNot : i1 839 return 840} 841 842// ----- 843 844func @logicalUnary(%arg0 : i32) 845{ 846 // expected-error @+1 {{operand #0 must be bool or vector of bool values of length 2/3/4/8/16, but got 'i32'}} 847 %0 = spv.LogicalNot %arg0 : i32 848 return 849} 850 851// ----- 852 853//===----------------------------------------------------------------------===// 854// spv.MemoryBarrier 855//===----------------------------------------------------------------------===// 856 857func @memory_barrier_0() -> () { 858 // CHECK: spv.MemoryBarrier "Device", "Acquire|UniformMemory" 859 spv.MemoryBarrier "Device", "Acquire|UniformMemory" 860 return 861} 862 863// ----- 864 865func @memory_barrier_1() -> () { 866 // CHECK: spv.MemoryBarrier "Workgroup", "Acquire" 867 spv.MemoryBarrier "Workgroup", "Acquire" 868 return 869} 870 871// ----- 872 873func @memory_barrier_2() -> () { 874 // expected-error @+1 {{expected at most one of these four memory constraints to be set: `Acquire`, `Release`,`AcquireRelease` or `SequentiallyConsistent`}} 875 spv.MemoryBarrier "Device", "Acquire|Release" 876 return 877} 878 879// ----- 880 881//===----------------------------------------------------------------------===// 882// spv.Not 883//===----------------------------------------------------------------------===// 884 885func @not(%arg: i32) -> i32 { 886 // CHECK: spv.Not {{%.*}} : i32 887 %0 = spv.Not %arg : i32 888 spv.ReturnValue %0 : i32 889} 890 891// ----- 892 893//===----------------------------------------------------------------------===// 894// spv.SelectOp 895//===----------------------------------------------------------------------===// 896 897func @select_op_bool(%arg0: i1) -> () { 898 %0 = spv.constant true 899 %1 = spv.constant false 900 // CHECK : spv.Select {{%.*}}, {{%.*}}, {{%.*}} : i1, i1 901 %2 = spv.Select %arg0, %0, %1 : i1, i1 902 return 903} 904 905func @select_op_int(%arg0: i1) -> () { 906 %0 = spv.constant 2 : i32 907 %1 = spv.constant 3 : i32 908 // CHECK : spv.Select {{%.*}}, {{%.*}}, {{%.*}} : i1, i32 909 %2 = spv.Select %arg0, %0, %1 : i1, i32 910 return 911} 912 913func @select_op_float(%arg0: i1) -> () { 914 %0 = spv.constant 2.0 : f32 915 %1 = spv.constant 3.0 : f32 916 // CHECK : spv.Select {{%.*}}, {{%.*}}, {{%.*}} : i1, f32 917 %2 = spv.Select %arg0, %0, %1 : i1, f32 918 return 919} 920 921func @select_op_ptr(%arg0: i1) -> () { 922 %0 = spv.Variable : !spv.ptr<f32, Function> 923 %1 = spv.Variable : !spv.ptr<f32, Function> 924 // CHECK : spv.Select {{%.*}}, {{%.*}}, {{%.*}} : i1, !spv.ptr<f32, Function> 925 %2 = spv.Select %arg0, %0, %1 : i1, !spv.ptr<f32, Function> 926 return 927} 928 929func @select_op_vec(%arg0: i1) -> () { 930 %0 = spv.constant dense<[2.0, 3.0, 4.0]> : vector<3xf32> 931 %1 = spv.constant dense<[5.0, 6.0, 7.0]> : vector<3xf32> 932 // CHECK : spv.Select {{%.*}}, {{%.*}}, {{%.*}} : i1, vector<3xf32> 933 %2 = spv.Select %arg0, %0, %1 : i1, vector<3xf32> 934 return 935} 936 937func @select_op_vec_condn_vec(%arg0: vector<3xi1>) -> () { 938 %0 = spv.constant dense<[2.0, 3.0, 4.0]> : vector<3xf32> 939 %1 = spv.constant dense<[5.0, 6.0, 7.0]> : vector<3xf32> 940 // CHECK : spv.Select {{%.*}}, {{%.*}}, {{%.*}} : vector<3xi1>, vector<3xf32> 941 %2 = spv.Select %arg0, %0, %1 : vector<3xi1>, vector<3xf32> 942 return 943} 944 945// ----- 946 947func @select_op(%arg0: i1) -> () { 948 %0 = spv.constant 2 : i32 949 %1 = spv.constant 3 : i32 950 // expected-error @+2 {{expected ','}} 951 %2 = spv.Select %arg0, %0, %1 : i1 952 return 953} 954 955// ----- 956 957func @select_op(%arg1: vector<3xi1>) -> () { 958 %0 = spv.constant 2 : i32 959 %1 = spv.constant 3 : i32 960 // expected-error @+1 {{result expected to be of vector type when condition is of vector type}} 961 %2 = spv.Select %arg1, %0, %1 : vector<3xi1>, i32 962 return 963} 964 965// ----- 966 967func @select_op(%arg1: vector<4xi1>) -> () { 968 %0 = spv.constant dense<[2, 3, 4]> : vector<3xi32> 969 %1 = spv.constant dense<[5, 6, 7]> : vector<3xi32> 970 // expected-error @+1 {{result should have the same number of elements as the condition when condition is of vector type}} 971 %2 = spv.Select %arg1, %0, %1 : vector<4xi1>, vector<3xi32> 972 return 973} 974 975// ----- 976 977func @select_op(%arg1: vector<4xi1>) -> () { 978 %0 = spv.constant dense<[2.0, 3.0, 4.0]> : vector<3xf32> 979 %1 = spv.constant dense<[5, 6, 7]> : vector<3xi32> 980 // expected-error @+1 {{all of {true_value, false_value, result} have same type}} 981 %2 = "spv.Select"(%arg1, %0, %1) : (vector<4xi1>, vector<3xf32>, vector<3xi32>) -> vector<3xi32> 982 return 983} 984 985// ----- 986 987func @select_op(%arg1: vector<4xi1>) -> () { 988 %0 = spv.constant dense<[2.0, 3.0, 4.0]> : vector<3xf32> 989 %1 = spv.constant dense<[5, 6, 7]> : vector<3xi32> 990 // expected-error @+1 {{all of {true_value, false_value, result} have same type}} 991 %2 = "spv.Select"(%arg1, %1, %0) : (vector<4xi1>, vector<3xi32>, vector<3xf32>) -> vector<3xi32> 992 return 993} 994 995// ----- 996 997//===----------------------------------------------------------------------===// 998// spv.ShiftLeftLogical 999//===----------------------------------------------------------------------===// 1000 1001func @shift_left_logical(%arg0: i32, %arg1 : i16) -> i32 { 1002 // CHECK: {{%.*}} = spv.ShiftLeftLogical {{%.*}}, {{%.*}} : i32, i16 1003 %0 = spv.ShiftLeftLogical %arg0, %arg1: i32, i16 1004 spv.ReturnValue %0 : i32 1005} 1006 1007// ----- 1008 1009func @shift_left_logical_invalid_result_type(%arg0: i32, %arg1 : i16) -> i16 { 1010 // expected-error @+1 {{expected the same type for the first operand and result, but provided 'i32' and 'i16'}} 1011 %0 = "spv.ShiftLeftLogical" (%arg0, %arg1) : (i32, i16) -> (i16) 1012 spv.ReturnValue %0 : i16 1013} 1014 1015// ----- 1016 1017//===----------------------------------------------------------------------===// 1018// spv.ShiftRightArithmetic 1019//===----------------------------------------------------------------------===// 1020 1021func @shift_right_arithmetic(%arg0: vector<4xi32>, %arg1 : vector<4xi8>) -> vector<4xi32> { 1022 // CHECK: {{%.*}} = spv.ShiftRightArithmetic {{%.*}}, {{%.*}} : vector<4xi32>, vector<4xi8> 1023 %0 = spv.ShiftRightArithmetic %arg0, %arg1: vector<4xi32>, vector<4xi8> 1024 spv.ReturnValue %0 : vector<4xi32> 1025} 1026 1027// ----- 1028 1029//===----------------------------------------------------------------------===// 1030// spv.ShiftRightLogical 1031//===----------------------------------------------------------------------===// 1032 1033func @shift_right_logical(%arg0: vector<2xi32>, %arg1 : vector<2xi8>) -> vector<2xi32> { 1034 // CHECK: {{%.*}} = spv.ShiftRightLogical {{%.*}}, {{%.*}} : vector<2xi32>, vector<2xi8> 1035 %0 = spv.ShiftRightLogical %arg0, %arg1: vector<2xi32>, vector<2xi8> 1036 spv.ReturnValue %0 : vector<2xi32> 1037} 1038 1039// ----- 1040 1041//===----------------------------------------------------------------------===// 1042// spv.StoreOp 1043//===----------------------------------------------------------------------===// 1044 1045func @simple_store(%arg0 : f32) -> () { 1046 %0 = spv.Variable : !spv.ptr<f32, Function> 1047 // CHECK: spv.Store "Function" %0, %arg0 : f32 1048 spv.Store "Function" %0, %arg0 : f32 1049 return 1050} 1051 1052// CHECK_LABEL: @volatile_store 1053func @volatile_store(%arg0 : f32) -> () { 1054 %0 = spv.Variable : !spv.ptr<f32, Function> 1055 // CHECK: spv.Store "Function" %0, %arg0 ["Volatile"] : f32 1056 spv.Store "Function" %0, %arg0 ["Volatile"] : f32 1057 return 1058} 1059 1060// CHECK_LABEL: @aligned_store 1061func @aligned_store(%arg0 : f32) -> () { 1062 %0 = spv.Variable : !spv.ptr<f32, Function> 1063 // CHECK: spv.Store "Function" %0, %arg0 ["Aligned", 4] : f32 1064 spv.Store "Function" %0, %arg0 ["Aligned", 4] : f32 1065 return 1066} 1067 1068// ----- 1069 1070func @simple_store_missing_ptr_type(%arg0 : f32) -> () { 1071 %0 = spv.Variable : !spv.ptr<f32, Function> 1072 // expected-error @+1 {{expected non-function type}} 1073 spv.Store %0, %arg0 : f32 1074 return 1075} 1076 1077// ----- 1078 1079func @simple_store_missing_operand(%arg0 : f32) -> () { 1080 %0 = spv.Variable : !spv.ptr<f32, Function> 1081 // expected-error @+1 {{custom op 'spv.Store' invalid operand}} : f32 1082 spv.Store "Function" , %arg0 : f32 1083 return 1084} 1085 1086// ----- 1087 1088func @simple_store_missing_operand(%arg0 : f32) -> () { 1089 %0 = spv.Variable : !spv.ptr<f32, Function> 1090 // expected-error @+1 {{custom op 'spv.Store' expected 2 operands}} : f32 1091 spv.Store "Function" %0 : f32 1092 return 1093} 1094 1095// ----- 1096 1097func @volatile_store_missing_lbrace(%arg0 : f32) -> () { 1098 %0 = spv.Variable : !spv.ptr<f32, Function> 1099 // expected-error @+1 {{expected ':'}} 1100 spv.Store "Function" %0, %arg0 "Volatile"] : f32 1101 return 1102} 1103 1104// ----- 1105 1106func @volatile_store_missing_rbrace(%arg0 : f32) -> () { 1107 %0 = spv.Variable : !spv.ptr<f32, Function> 1108 // expected-error @+1 {{expected ']'}} 1109 spv.Store "Function" %0, %arg0 ["Volatile"} : f32 1110 return 1111} 1112 1113// ----- 1114 1115func @aligned_store_missing_alignment(%arg0 : f32) -> () { 1116 %0 = spv.Variable : !spv.ptr<f32, Function> 1117 // expected-error @+1 {{expected ','}} 1118 spv.Store "Function" %0, %arg0 ["Aligned"] : f32 1119 return 1120} 1121 1122// ----- 1123 1124func @aligned_store_missing_comma(%arg0 : f32) -> () { 1125 %0 = spv.Variable : !spv.ptr<f32, Function> 1126 // expected-error @+1 {{expected ','}} 1127 spv.Store "Function" %0, %arg0 ["Aligned" 4] : f32 1128 return 1129} 1130 1131// ----- 1132 1133func @load_incorrect_attributes(%arg0 : f32) -> () { 1134 %0 = spv.Variable : !spv.ptr<f32, Function> 1135 // expected-error @+1 {{expected ']'}} 1136 spv.Store "Function" %0, %arg0 ["Volatile", 4] : f32 1137 return 1138} 1139 1140// ----- 1141 1142func @aligned_store_incorrect_attributes(%arg0 : f32) -> () { 1143 %0 = spv.Variable : !spv.ptr<f32, Function> 1144 // expected-error @+1 {{expected ']'}} 1145 spv.Store "Function" %0, %arg0 ["Aligned", 4, 23] : f32 1146 return 1147} 1148 1149// ----- 1150 1151spv.module Logical GLSL450 { 1152 spv.globalVariable @var0 : !spv.ptr<f32, Input> 1153 spv.func @simple_store(%arg0 : f32) -> () "None" { 1154 %0 = spv.mlir.addressof @var0 : !spv.ptr<f32, Input> 1155 // CHECK: spv.Store "Input" {{%.*}}, {{%.*}} : f32 1156 spv.Store "Input" %0, %arg0 : f32 1157 spv.Return 1158 } 1159} 1160 1161// ----- 1162 1163//===----------------------------------------------------------------------===// 1164// spv.SubgroupBallotKHR 1165//===----------------------------------------------------------------------===// 1166 1167func @subgroup_ballot(%predicate: i1) -> vector<4xi32> { 1168 %0 = spv.SubgroupBallotKHR %predicate: vector<4xi32> 1169 return %0: vector<4xi32> 1170} 1171 1172// ----- 1173 1174//===----------------------------------------------------------------------===// 1175// spv.undef 1176//===----------------------------------------------------------------------===// 1177 1178func @undef() -> () { 1179 %0 = spv.undef : f32 1180 %1 = spv.undef : vector<4xf32> 1181 spv.Return 1182} 1183 1184// ----- 1185 1186func @undef() -> () { 1187 // expected-error @+2{{expected non-function type}} 1188 %0 = spv.undef : 1189 spv.Return 1190} 1191 1192// ----- 1193 1194func @undef() -> () { 1195 // expected-error @+2{{expected ':'}} 1196 %0 = spv.undef 1197 spv.Return 1198} 1199 1200// ----- 1201 1202 1203//===----------------------------------------------------------------------===// 1204// spv.Variable 1205//===----------------------------------------------------------------------===// 1206 1207func @variable(%arg0: f32) -> () { 1208 // CHECK: spv.Variable : !spv.ptr<f32, Function> 1209 %0 = spv.Variable : !spv.ptr<f32, Function> 1210 return 1211} 1212 1213// ----- 1214 1215func @variable_init_normal_constant() -> () { 1216 %0 = spv.constant 4.0 : f32 1217 // CHECK: spv.Variable init(%0) : !spv.ptr<f32, Function> 1218 %1 = spv.Variable init(%0) : !spv.ptr<f32, Function> 1219 return 1220} 1221 1222// ----- 1223 1224spv.module Logical GLSL450 { 1225 spv.globalVariable @global : !spv.ptr<f32, Workgroup> 1226 spv.func @variable_init_global_variable() -> () "None" { 1227 %0 = spv.mlir.addressof @global : !spv.ptr<f32, Workgroup> 1228 // CHECK: spv.Variable init({{.*}}) : !spv.ptr<!spv.ptr<f32, Workgroup>, Function> 1229 %1 = spv.Variable init(%0) : !spv.ptr<!spv.ptr<f32, Workgroup>, Function> 1230 spv.Return 1231 } 1232} 1233 1234// ----- 1235 1236spv.module Logical GLSL450 { 1237 spv.specConstant @sc = 42 : i32 1238 // CHECK-LABEL: @variable_init_spec_constant 1239 spv.func @variable_init_spec_constant() -> () "None" { 1240 %0 = spv.mlir.referenceof @sc : i32 1241 // CHECK: spv.Variable init(%0) : !spv.ptr<i32, Function> 1242 %1 = spv.Variable init(%0) : !spv.ptr<i32, Function> 1243 spv.Return 1244 } 1245} 1246 1247// ----- 1248 1249func @variable_bind() -> () { 1250 // expected-error @+1 {{cannot have 'descriptor_set' attribute (only allowed in spv.globalVariable)}} 1251 %0 = spv.Variable bind(1, 2) : !spv.ptr<f32, Function> 1252 return 1253} 1254 1255// ----- 1256 1257func @variable_init_bind() -> () { 1258 %0 = spv.constant 4.0 : f32 1259 // expected-error @+1 {{cannot have 'binding' attribute (only allowed in spv.globalVariable)}} 1260 %1 = spv.Variable init(%0) {binding = 5 : i32} : !spv.ptr<f32, Function> 1261 return 1262} 1263 1264// ----- 1265 1266func @variable_builtin() -> () { 1267 // expected-error @+1 {{cannot have 'built_in' attribute (only allowed in spv.globalVariable)}} 1268 %1 = spv.Variable built_in("GlobalInvocationID") : !spv.ptr<vector<3xi32>, Function> 1269 return 1270} 1271 1272// ----- 1273 1274func @expect_ptr_result_type(%arg0: f32) -> () { 1275 // expected-error @+1 {{expected spv.ptr type}} 1276 %0 = spv.Variable : f32 1277 return 1278} 1279 1280// ----- 1281 1282func @variable_init(%arg0: f32) -> () { 1283 // expected-error @+1 {{op initializer must be the result of a constant or spv.globalVariable op}} 1284 %0 = spv.Variable init(%arg0) : !spv.ptr<f32, Function> 1285 return 1286} 1287 1288// ----- 1289 1290func @cannot_be_generic_storage_class(%arg0: f32) -> () { 1291 // expected-error @+1 {{op can only be used to model function-level variables. Use spv.globalVariable for module-level variables}} 1292 %0 = spv.Variable : !spv.ptr<f32, Generic> 1293 return 1294} 1295 1296// ----- 1297 1298func @copy_memory_incompatible_ptrs() { 1299 %0 = spv.Variable : !spv.ptr<f32, Function> 1300 %1 = spv.Variable : !spv.ptr<i32, Function> 1301 // expected-error @+1 {{both operands must be pointers to the same type}} 1302 "spv.CopyMemory"(%0, %1) {} : (!spv.ptr<f32, Function>, !spv.ptr<i32, Function>) -> () 1303 spv.Return 1304} 1305 1306// ----- 1307 1308func @copy_memory_invalid_maa() { 1309 %0 = spv.Variable : !spv.ptr<f32, Function> 1310 %1 = spv.Variable : !spv.ptr<f32, Function> 1311 // expected-error @+1 {{missing alignment value}} 1312 "spv.CopyMemory"(%0, %1) {memory_access=0x0002 : i32} : (!spv.ptr<f32, Function>, !spv.ptr<f32, Function>) -> () 1313 spv.Return 1314} 1315 1316// ----- 1317 1318func @copy_memory_invalid_source_maa() { 1319 %0 = spv.Variable : !spv.ptr<f32, Function> 1320 %1 = spv.Variable : !spv.ptr<f32, Function> 1321 // expected-error @+1 {{invalid alignment specification with non-aligned memory access specification}} 1322 "spv.CopyMemory"(%0, %1) {source_memory_access=0x0001 : i32, memory_access=0x0002 : i32, source_alignment=8 : i32, alignment=4 : i32} : (!spv.ptr<f32, Function>, !spv.ptr<f32, Function>) -> () 1323 spv.Return 1324} 1325 1326// ----- 1327 1328func @copy_memory_invalid_source_maa2() { 1329 %0 = spv.Variable : !spv.ptr<f32, Function> 1330 %1 = spv.Variable : !spv.ptr<f32, Function> 1331 // expected-error @+1 {{missing alignment value}} 1332 "spv.CopyMemory"(%0, %1) {source_memory_access=0x0002 : i32, memory_access=0x0002 : i32, alignment=4 : i32} : (!spv.ptr<f32, Function>, !spv.ptr<f32, Function>) -> () 1333 spv.Return 1334} 1335 1336// ----- 1337 1338func @copy_memory_print_maa() { 1339 %0 = spv.Variable : !spv.ptr<f32, Function> 1340 %1 = spv.Variable : !spv.ptr<f32, Function> 1341 1342 // CHECK: spv.CopyMemory "Function" %{{.*}}, "Function" %{{.*}} ["Volatile"] : f32 1343 "spv.CopyMemory"(%0, %1) {memory_access=0x0001 : i32} : (!spv.ptr<f32, Function>, !spv.ptr<f32, Function>) -> () 1344 1345 // CHECK: spv.CopyMemory "Function" %{{.*}}, "Function" %{{.*}} ["Aligned", 4] : f32 1346 "spv.CopyMemory"(%0, %1) {memory_access=0x0002 : i32, alignment=4 : i32} : (!spv.ptr<f32, Function>, !spv.ptr<f32, Function>) -> () 1347 1348 // CHECK: spv.CopyMemory "Function" %{{.*}}, "Function" %{{.*}} ["Aligned", 4], ["Volatile"] : f32 1349 "spv.CopyMemory"(%0, %1) {source_memory_access=0x0001 : i32, memory_access=0x0002 : i32, alignment=4 : i32} : (!spv.ptr<f32, Function>, !spv.ptr<f32, Function>) -> () 1350 1351 // CHECK: spv.CopyMemory "Function" %{{.*}}, "Function" %{{.*}} ["Aligned", 4], ["Aligned", 8] : f32 1352 "spv.CopyMemory"(%0, %1) {source_memory_access=0x0002 : i32, memory_access=0x0002 : i32, source_alignment=8 : i32, alignment=4 : i32} : (!spv.ptr<f32, Function>, !spv.ptr<f32, Function>) -> () 1353 1354 spv.Return 1355} 1356