1136 lines · plain
1// RUN: mlir-opt -allow-unregistered-dialect -split-input-file -verify-diagnostics %s | FileCheck %s2 3//===----------------------------------------------------------------------===//4// spirv.Branch5//===----------------------------------------------------------------------===//6 7func.func @branch() -> () {8 // CHECK: spirv.Branch ^bb19 spirv.Branch ^next10^next:11 spirv.Return12}13 14// -----15 16func.func @branch_argument() -> () {17 %zero = spirv.Constant 0 : i3218 // CHECK: spirv.Branch ^bb1(%{{.*}}, %{{.*}} : i32, i32)19 spirv.Branch ^next(%zero, %zero: i32, i32)20^next(%arg0: i32, %arg1: i32):21 spirv.Return22}23 24// -----25 26func.func @missing_accessor() -> () {27 // expected-error @+1 {{expected block name}}28 spirv.Branch29}30 31// -----32 33func.func @wrong_accessor_count() -> () {34 %true = spirv.Constant true35 // expected-error @+1 {{requires 1 successor but found 2}}36 "spirv.Branch"()[^one, ^two] : () -> ()37^one:38 spirv.Return39^two:40 spirv.Return41}42 43// -----44 45//===----------------------------------------------------------------------===//46// spirv.BranchConditional47//===----------------------------------------------------------------------===//48 49func.func @cond_branch() -> () {50 %true = spirv.Constant true51 // CHECK: spirv.BranchConditional %{{.*}}, ^bb1, ^bb252 spirv.BranchConditional %true, ^one, ^two53// CHECK: ^bb154^one:55 spirv.Return56// CHECK: ^bb257^two:58 spirv.Return59}60 61// -----62 63func.func @cond_branch_argument() -> () {64 %true = spirv.Constant true65 %zero = spirv.Constant 0 : i3266 // CHECK: spirv.BranchConditional %{{.*}}, ^bb1(%{{.*}}, %{{.*}} : i32, i32), ^bb267 spirv.BranchConditional %true, ^true1(%zero, %zero: i32, i32), ^false168^true1(%arg0: i32, %arg1: i32):69 // CHECK: spirv.BranchConditional %{{.*}}, ^bb3, ^bb4(%{{.*}}, %{{.*}} : i32, i32)70 spirv.BranchConditional %true, ^true2, ^false2(%zero, %zero: i32, i32)71^false1:72 spirv.Return73^true2:74 spirv.Return75^false2(%arg3: i32, %arg4: i32):76 spirv.Return77}78 79// -----80 81func.func @cond_branch_with_weights() -> () {82 %true = spirv.Constant true83 // CHECK: spirv.BranchConditional %{{.*}} [5, 10]84 spirv.BranchConditional %true [5, 10], ^one, ^two85^one:86 spirv.Return87^two:88 spirv.Return89}90 91// -----92 93func.func @missing_condition() -> () {94 // expected-error @+1 {{expected SSA operand}}95 spirv.BranchConditional ^one, ^two96^one:97 spirv.Return98^two:99 spirv.Return100}101 102// -----103 104func.func @wrong_condition_type() -> () {105 // expected-note @+1 {{prior use here}}106 %zero = spirv.Constant 0 : i32107 // expected-error @+1 {{use of value '%zero' expects different type than prior uses: 'i1' vs 'i32'}}108 spirv.BranchConditional %zero, ^one, ^two109^one:110 spirv.Return111^two:112 spirv.Return113}114 115// -----116 117func.func @wrong_accessor_count() -> () {118 %true = spirv.Constant true119 // expected-error @+1 {{requires 2 successors but found 1}}120 "spirv.BranchConditional"(%true)[^one] {operandSegmentSizes = array<i32: 1, 0, 0>} : (i1) -> ()121^one:122 spirv.Return123^two:124 spirv.Return125}126 127// -----128 129func.func @wrong_number_of_weights() -> () {130 %true = spirv.Constant true131 // expected-error @+1 {{must have exactly two branch weights}}132 "spirv.BranchConditional"(%true)[^one, ^two] {branch_weights = [1 : i32, 2 : i32, 3 : i32],133 operandSegmentSizes = array<i32: 1, 0, 0>} : (i1) -> ()134^one:135 spirv.Return136^two:137 spirv.Return138}139 140// -----141 142func.func @weights_cannot_both_be_zero() -> () {143 %true = spirv.Constant true144 // expected-error @+1 {{branch weights cannot both be zero}}145 spirv.BranchConditional %true [0, 0], ^one, ^two146^one:147 spirv.Return148^two:149 spirv.Return150}151 152// -----153 154//===----------------------------------------------------------------------===//155// spirv.FunctionCall156//===----------------------------------------------------------------------===//157 158spirv.module Logical GLSL450 {159 spirv.func @fmain(%arg0 : vector<4xf32>, %arg1 : vector<4xf32>, %arg2 : i32) -> i32 "None" {160 // CHECK: {{%.*}} = spirv.FunctionCall @f_0({{%.*}}, {{%.*}}) : (vector<4xf32>, vector<4xf32>) -> vector<4xf32>161 %0 = spirv.FunctionCall @f_0(%arg0, %arg1) : (vector<4xf32>, vector<4xf32>) -> vector<4xf32>162 // CHECK: spirv.FunctionCall @f_1({{%.*}}, {{%.*}}) : (vector<4xf32>, vector<4xf32>) -> ()163 spirv.FunctionCall @f_1(%0, %arg1) : (vector<4xf32>, vector<4xf32>) -> ()164 // CHECK: spirv.FunctionCall @f_2() : () -> ()165 spirv.FunctionCall @f_2() : () -> ()166 // CHECK: {{%.*}} = spirv.FunctionCall @f_3({{%.*}}) : (i32) -> i32167 %1 = spirv.FunctionCall @f_3(%arg2) : (i32) -> i32168 spirv.ReturnValue %1 : i32169 }170 171 spirv.func @f_0(%arg0 : vector<4xf32>, %arg1 : vector<4xf32>) -> (vector<4xf32>) "None" {172 spirv.ReturnValue %arg0 : vector<4xf32>173 }174 175 spirv.func @f_1(%arg0 : vector<4xf32>, %arg1 : vector<4xf32>) -> () "None" {176 spirv.Return177 }178 179 spirv.func @f_2() -> () "None" {180 spirv.Return181 }182 183 spirv.func @f_3(%arg0 : i32) -> (i32) "None" {184 spirv.ReturnValue %arg0 : i32185 }186}187 188// -----189 190// Allow calling functions in other module-like ops191spirv.func @callee() "None" {192 spirv.Return193}194 195func.func @caller() {196 // CHECK: spirv.FunctionCall197 spirv.FunctionCall @callee() : () -> ()198 spirv.Return199}200 201// -----202 203spirv.module Logical GLSL450 {204 spirv.func @f_invalid_result_type(%arg0 : i32, %arg1 : i32) -> () "None" {205 // expected-error @+1 {{result group starting at #0 requires 0 or 1 element, but found 2}}206 %0:2 = spirv.FunctionCall @f_invalid_result_type(%arg0, %arg1) : (i32, i32) -> (i32, i32)207 spirv.Return208 }209}210 211// -----212 213spirv.module Logical GLSL450 {214 spirv.func @f_result_type_mismatch(%arg0 : i32, %arg1 : i32) -> () "None" {215 // expected-error @+1 {{has incorrect number of results has for callee: expected 0, but provided 1}}216 %1 = spirv.FunctionCall @f_result_type_mismatch(%arg0, %arg0) : (i32, i32) -> (i32)217 spirv.Return218 }219}220 221// -----222 223spirv.module Logical GLSL450 {224 spirv.func @f_type_mismatch(%arg0 : i32, %arg1 : i32) -> () "None" {225 // expected-error @+1 {{has incorrect number of operands for callee: expected 2, but provided 1}}226 spirv.FunctionCall @f_type_mismatch(%arg0) : (i32) -> ()227 spirv.Return228 }229}230 231// -----232 233spirv.module Logical GLSL450 {234 spirv.func @f_type_mismatch(%arg0 : i32, %arg1 : i32) -> () "None" {235 %0 = spirv.Constant 2.0 : f32236 // expected-error @+1 {{operand type mismatch: expected operand type 'i32', but provided 'f32' for operand number 1}}237 spirv.FunctionCall @f_type_mismatch(%arg0, %0) : (i32, f32) -> ()238 spirv.Return239 }240}241 242// -----243 244spirv.module Logical GLSL450 {245 spirv.func @f_type_mismatch(%arg0 : i32, %arg1 : i32) -> i32 "None" {246 %cst = spirv.Constant 0: i32247 // expected-error @+1 {{result type mismatch: expected 'i32', but provided 'f32'}}248 %0 = spirv.FunctionCall @f_type_mismatch(%arg0, %arg0) : (i32, i32) -> f32249 spirv.ReturnValue %cst: i32250 }251}252 253// -----254 255spirv.module Logical GLSL450 {256 spirv.func @f_foo(%arg0 : i32, %arg1 : i32) -> i32 "None" {257 // expected-error @+1 {{op callee function 'f_undefined' not found in nearest symbol table}}258 %0 = spirv.FunctionCall @f_undefined(%arg0, %arg0) : (i32, i32) -> i32259 spirv.ReturnValue %0: i32260 }261}262 263// -----264 265"builtin.module"() ({266 "spirv.module"() <{267 addressing_model = #spirv.addressing_model<Logical>,268 memory_model = #spirv.memory_model<GLSL450>269 }> ({270 "spirv.func"() <{271 function_control = #spirv.function_control<None>,272 function_type = (f32) -> f32,273 sym_name = "bar"274 }> ({275 ^bb0(%arg0: f32):276 %0 = "spirv.FunctionCall"(%arg0) <{callee = @foo}> : (f32) -> f32277 "spirv.ReturnValue"(%0) : (f32) -> ()278 }) : () -> ()279 // expected-error @+1 {{requires attribute 'function_type'}}280 "spirv.func"() <{281 function_control = #spirv.function_control<None>,282 message = "2nd parent",283 sym_name = "foo"284 // This is invalid MLIR because function_type is missing from spirv.func.285 }> ({286 ^bb0(%arg0: f32):287 "spirv.ReturnValue"(%arg0) : (f32) -> ()288 }) : () -> ()289 }) : () -> ()290}) : () -> ()291 292// -----293 294//===----------------------------------------------------------------------===//295// spirv.mlir.loop296//===----------------------------------------------------------------------===//297 298// for (int i = 0; i < count; ++i) {}299func.func @loop(%count : i32) -> () {300 %zero = spirv.Constant 0: i32301 %one = spirv.Constant 1: i32302 %var = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>303 304 // CHECK: spirv.mlir.loop {305 spirv.mlir.loop {306 // CHECK-NEXT: spirv.Branch ^bb1307 spirv.Branch ^header308 309 // CHECK-NEXT: ^bb1:310 ^header:311 %val0 = spirv.Load "Function" %var : i32312 %cmp = spirv.SLessThan %val0, %count : i32313 // CHECK: spirv.BranchConditional %{{.*}}, ^bb2, ^bb4314 spirv.BranchConditional %cmp, ^body, ^merge315 316 // CHECK-NEXT: ^bb2:317 ^body:318 // Do nothing319 // CHECK-NEXT: spirv.Branch ^bb3320 spirv.Branch ^continue321 322 // CHECK-NEXT: ^bb3:323 ^continue:324 %val1 = spirv.Load "Function" %var : i32325 %add = spirv.IAdd %val1, %one : i32326 spirv.Store "Function" %var, %add : i32327 // CHECK: spirv.Branch ^bb1328 spirv.Branch ^header329 330 // CHECK-NEXT: ^bb4:331 ^merge:332 spirv.mlir.merge333 }334 return335}336 337// -----338 339// CHECK-LABEL: @empty_region340func.func @empty_region() -> () {341 // CHECK: spirv.mlir.loop342 spirv.mlir.loop {343 }344 return345}346 347// -----348 349// CHECK-LABEL: @loop_with_control350func.func @loop_with_control() -> () {351 // CHECK: spirv.mlir.loop control(Unroll)352 spirv.mlir.loop control(Unroll) {353 }354 return355}356 357// -----358 359func.func @wrong_merge_block() -> () {360 // expected-error @+1 {{last block must be the merge block with only one 'spirv.mlir.merge' op}}361 spirv.mlir.loop {362 spirv.Return363 }364 return365}366 367// -----368 369func.func @missing_entry_block() -> () {370 // expected-error @+1 {{must have an entry block branching to the loop header block}}371 spirv.mlir.loop {372 spirv.mlir.merge373 }374 return375}376 377// -----378 379func.func @missing_header_block() -> () {380 // expected-error @+1 {{must have a loop header block branched from the entry block}}381 spirv.mlir.loop {382 ^entry:383 spirv.Branch ^merge384 ^merge:385 spirv.mlir.merge386 }387 return388}389 390// -----391 392func.func @entry_should_branch_to_header() -> () {393 // expected-error @+1 {{entry block must only have one 'spirv.Branch' op to the second block}}394 spirv.mlir.loop {395 ^entry:396 spirv.Branch ^merge397 ^header:398 spirv.Branch ^merge399 ^merge:400 spirv.mlir.merge401 }402 return403}404 405// -----406 407func.func @missing_continue_block() -> () {408 // expected-error @+1 {{requires a loop continue block branching to the loop header block}}409 spirv.mlir.loop {410 ^entry:411 spirv.Branch ^header412 ^header:413 spirv.Branch ^merge414 ^merge:415 spirv.mlir.merge416 }417 return418}419 420// -----421 422func.func @continue_should_branch_to_header() -> () {423 // expected-error @+1 {{second to last block must be the loop continue block that branches to the loop header block}}424 spirv.mlir.loop {425 ^entry:426 spirv.Branch ^header427 ^header:428 spirv.Branch ^continue429 ^continue:430 spirv.Branch ^merge431 ^merge:432 spirv.mlir.merge433 }434 return435}436 437// -----438 439func.func @only_entry_and_continue_branch_to_header() -> () {440 // expected-error @+1 {{can only have the entry and loop continue block branching to the loop header block}}441 spirv.mlir.loop {442 ^entry:443 spirv.Branch ^header444 ^header:445 spirv.Branch ^cont1446 ^cont1:447 spirv.Branch ^header448 ^cont2:449 spirv.Branch ^header450 ^merge:451 spirv.mlir.merge452 }453 return454}455 456// -----457 458func.func @loop_yield(%count : i32) -> () {459 %zero = spirv.Constant 0: i32460 %one = spirv.Constant 1: i32461 %var = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>462 463 // CHECK: {{%.*}} = spirv.mlir.loop -> i32 {464 %final_i = spirv.mlir.loop -> i32 {465 // CHECK-NEXT: spirv.Branch ^bb1({{%.*}}: i32)466 spirv.Branch ^header(%zero: i32)467 468 // CHECK-NEXT: ^bb1({{%.*}}: i32):469 ^header(%i : i32):470 %cmp = spirv.SLessThan %i, %count : i32471 // CHECK: spirv.BranchConditional %{{.*}}, ^bb2, ^bb4472 spirv.BranchConditional %cmp, ^body, ^merge473 474 // CHECK-NEXT: ^bb2:475 ^body:476 // CHECK-NEXT: spirv.Branch ^bb3477 spirv.Branch ^continue478 479 // CHECK-NEXT: ^bb3:480 ^continue:481 %new_i = spirv.IAdd %i, %one : i32482 // CHECK: spirv.Branch ^bb1({{%.*}}: i32)483 spirv.Branch ^header(%new_i: i32)484 485 // CHECK-NEXT: ^bb4:486 ^merge:487 // CHECK-NEXT: spirv.mlir.merge {{%.*}} : i32488 spirv.mlir.merge %i : i32489 }490 491 // CHECK: spirv.Store "Function" {{%.*}}, {{%.*}} : i32492 spirv.Store "Function" %var, %final_i : i32493 494 return495}496 497// -----498 499//===----------------------------------------------------------------------===//500// spirv.mlir.merge501//===----------------------------------------------------------------------===//502 503func.func @merge() -> () {504 // expected-error @+1 {{expects parent op to be one of 'spirv.mlir.selection, spirv.mlir.loop'}}505 spirv.mlir.merge506}507 508// -----509 510func.func @only_allowed_in_last_block(%cond : i1) -> () {511 // expected-error @+1 {{'spirv.mlir.selection' op should not have 'spirv.mlir.merge' op outside the merge block}}512 spirv.mlir.selection {513 spirv.BranchConditional %cond, ^then, ^merge514 ^then:515 spirv.mlir.merge516 ^merge:517 spirv.mlir.merge518 }519 spirv.Return520}521 522// -----523 524// Ensure this case not crash525 526func.func @last_block_no_terminator(%cond : i1) -> () {527 // expected-error @+1 {{empty block: expect at least a terminator}}528 spirv.mlir.selection {529 spirv.BranchConditional %cond, ^then, ^merge530 ^then:531 spirv.mlir.merge532 ^merge:533 }534 spirv.Return535}536 537// -----538 539func.func @only_allowed_in_last_block() -> () {540 %true = spirv.Constant true541 // expected-error @+1 {{'spirv.mlir.loop' op should not have 'spirv.mlir.merge' op outside the merge block}}542 spirv.mlir.loop {543 spirv.Branch ^header544 ^header:545 spirv.BranchConditional %true, ^body, ^merge546 ^body:547 spirv.mlir.merge548 ^continue:549 spirv.Branch ^header550 ^merge:551 spirv.mlir.merge552 }553 return554}555 556// -----557 558//===----------------------------------------------------------------------===//559// spirv.Return560//===----------------------------------------------------------------------===//561 562// CHECK-LABEL: func @in_selection563func.func @in_selection(%cond : i1) -> () {564 spirv.mlir.selection {565 spirv.BranchConditional %cond, ^then, ^merge566 ^then:567 // CHECK: spirv.Return568 spirv.Return569 ^merge:570 spirv.mlir.merge571 }572 spirv.Return573}574 575// CHECK-LABEL: func @in_loop576func.func @in_loop(%cond : i1) -> () {577 spirv.mlir.loop {578 spirv.Branch ^header579 ^header:580 spirv.BranchConditional %cond, ^body, ^merge581 ^body:582 // CHECK: spirv.Return583 spirv.Return584 ^continue:585 spirv.Branch ^header586 ^merge:587 spirv.mlir.merge588 }589 spirv.Return590}591 592// CHECK-LABEL: in_other_func_like_op593func.func @in_other_func_like_op() {594 // CHECK: spirv.Return595 spirv.Return596}597 598// -----599 600"foo.function"() ({601 // expected-error @+1 {{op must appear in a function-like op's block}}602 spirv.Return603}) : () -> ()604 605// -----606 607// Return mismatches function signature608spirv.module Logical GLSL450 {609 spirv.func @work() -> (i32) "None" {610 // expected-error @+1 {{cannot be used in functions returning value}}611 spirv.Return612 }613}614 615// -----616 617spirv.module Logical GLSL450 {618 spirv.func @in_nested_region(%cond: i1) -> (i32) "None" {619 spirv.mlir.selection {620 spirv.BranchConditional %cond, ^then, ^merge621 ^then:622 // expected-error @+1 {{cannot be used in functions returning value}}623 spirv.Return624 ^merge:625 spirv.mlir.merge626 }627 628 %zero = spirv.Constant 0: i32629 spirv.ReturnValue %zero: i32630 }631}632 633// -----634 635//===----------------------------------------------------------------------===//636// spirv.ReturnValue637//===----------------------------------------------------------------------===//638 639func.func @ret_val() -> (i32) {640 %0 = spirv.Constant 42 : i32641 // CHECK: spirv.ReturnValue %{{.*}} : i32642 spirv.ReturnValue %0 : i32643}644 645// CHECK-LABEL: func @in_selection646func.func @in_selection(%cond : i1) -> (i32) {647 spirv.mlir.selection {648 spirv.BranchConditional %cond, ^then, ^merge649 ^then:650 %zero = spirv.Constant 0 : i32651 // CHECK: spirv.ReturnValue652 spirv.ReturnValue %zero : i32653 ^merge:654 spirv.mlir.merge655 }656 %one = spirv.Constant 1 : i32657 spirv.ReturnValue %one : i32658}659 660// CHECK-LABEL: func @in_loop661func.func @in_loop(%cond : i1) -> (i32) {662 spirv.mlir.loop {663 spirv.Branch ^header664 ^header:665 spirv.BranchConditional %cond, ^body, ^merge666 ^body:667 %zero = spirv.Constant 0 : i32668 // CHECK: spirv.ReturnValue669 spirv.ReturnValue %zero : i32670 ^continue:671 spirv.Branch ^header672 ^merge:673 spirv.mlir.merge674 }675 %one = spirv.Constant 1 : i32676 spirv.ReturnValue %one : i32677}678 679// CHECK-LABEL: in_other_func_like_op680func.func @in_other_func_like_op(%arg: i32) -> i32 {681 // CHECK: spirv.ReturnValue682 spirv.ReturnValue %arg: i32683}684 685// -----686 687"foo.function"() ({688 %0 = spirv.Constant true689 // expected-error @+1 {{op must appear in a function-like op's block}}690 spirv.ReturnValue %0 : i1691}) : () -> ()692 693// -----694 695spirv.module Logical GLSL450 {696 spirv.func @value_count_mismatch() -> () "None" {697 %0 = spirv.Constant 42 : i32698 // expected-error @+1 {{op returns 1 value but enclosing function requires 0 results}}699 spirv.ReturnValue %0 : i32700 }701}702 703// -----704 705spirv.module Logical GLSL450 {706 spirv.func @value_type_mismatch() -> (f32) "None" {707 %0 = spirv.Constant 42 : i32708 // expected-error @+1 {{return value's type ('i32') mismatch with function's result type ('f32')}}709 spirv.ReturnValue %0 : i32710 }711}712 713// -----714 715spirv.module Logical GLSL450 {716 spirv.func @in_nested_region(%cond: i1) -> () "None" {717 spirv.mlir.selection {718 spirv.BranchConditional %cond, ^then, ^merge719 ^then:720 %cst = spirv.Constant 0: i32721 // expected-error @+1 {{op returns 1 value but enclosing function requires 0 results}}722 spirv.ReturnValue %cst: i32723 ^merge:724 spirv.mlir.merge725 }726 727 spirv.Return728 }729}730 731// -----732 733//===----------------------------------------------------------------------===//734// spirv.mlir.selection735//===----------------------------------------------------------------------===//736 737func.func @selection(%cond: i1) -> () {738 %zero = spirv.Constant 0: i32739 %one = spirv.Constant 1: i32740 %var = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>741 742 // CHECK: spirv.mlir.selection {743 spirv.mlir.selection {744 // CHECK-NEXT: spirv.BranchConditional %{{.*}}, ^bb1, ^bb2745 spirv.BranchConditional %cond, ^then, ^merge746 747 // CHECK: ^bb1748 ^then:749 spirv.Store "Function" %var, %one : i32750 // CHECK: spirv.Branch ^bb2751 spirv.Branch ^merge752 753 // CHECK: ^bb2754 ^merge:755 // CHECK-NEXT: spirv.mlir.merge756 spirv.mlir.merge757 }758 759 spirv.Return760}761 762// -----763 764func.func @selection(%cond: i1) -> () {765 %zero = spirv.Constant 0: i32766 %one = spirv.Constant 1: i32767 %two = spirv.Constant 2: i32768 %var = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>769 770 // CHECK: spirv.mlir.selection {771 spirv.mlir.selection {772 // CHECK-NEXT: spirv.BranchConditional %{{.*}}, ^bb1, ^bb2773 spirv.BranchConditional %cond, ^then, ^else774 775 // CHECK: ^bb1776 ^then:777 spirv.Store "Function" %var, %one : i32778 // CHECK: spirv.Branch ^bb3779 spirv.Branch ^merge780 781 // CHECK: ^bb2782 ^else:783 spirv.Store "Function" %var, %two : i32784 // CHECK: spirv.Branch ^bb3785 spirv.Branch ^merge786 787 // CHECK: ^bb3788 ^merge:789 // CHECK-NEXT: spirv.mlir.merge790 spirv.mlir.merge791 }792 793 spirv.Return794}795 796// -----797 798func.func @selection_switch(%selector: i32) -> () {799 %zero = spirv.Constant 0: i32800 %one = spirv.Constant 1: i32801 %two = spirv.Constant 2: i32802 %three = spirv.Constant 3: i32803 %var = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>804 805 // CHECK: spirv.mlir.selection {806 spirv.mlir.selection {807 // CHECK-NEXT: spirv.Switch {{%.*}} : i32, [808 // CHECK-NEXT: default: ^bb1,809 // CHECK-NEXT: 0: ^bb2,810 // CHECK-NEXT: 1: ^bb3811 spirv.Switch %selector : i32, [812 default: ^default,813 0: ^case0,814 1: ^case1815 ]816 // CHECK: ^bb1817 ^default:818 spirv.Store "Function" %var, %one : i32819 // CHECK: spirv.Branch ^bb4820 spirv.Branch ^merge821 822 // CHECK: ^bb2823 ^case0:824 spirv.Store "Function" %var, %two : i32825 // CHECK: spirv.Branch ^bb4826 spirv.Branch ^merge827 828 // CHECK: ^bb3829 ^case1:830 spirv.Store "Function" %var, %three : i32831 // CHECK: spirv.Branch ^bb4832 spirv.Branch ^merge833 834 // CHECK: ^bb4835 ^merge:836 // CHECK-NEXT: spirv.mlir.merge837 spirv.mlir.merge838 }839 840 spirv.Return841}842 843// -----844 845// CHECK-LABEL: @empty_region846func.func @empty_region() -> () {847 // CHECK: spirv.mlir.selection848 spirv.mlir.selection {849 }850 return851}852 853// -----854 855// CHECK-LABEL: @selection_with_control856func.func @selection_with_control() -> () {857 // CHECK: spirv.mlir.selection control(Flatten)858 spirv.mlir.selection control(Flatten) {859 }860 return861}862 863// -----864 865func.func @wrong_merge_block() -> () {866 // expected-error @+1 {{last block must be the merge block with only one 'spirv.mlir.merge' op}}867 spirv.mlir.selection {868 spirv.Return869 }870 return871}872 873// -----874 875func.func @missing_entry_block() -> () {876 // expected-error @+1 {{must have a selection header block}}877 spirv.mlir.selection {878 spirv.mlir.merge879 }880 return881}882 883// -----884 885func.func @selection_yield(%cond: i1) -> () {886 %zero = spirv.Constant 0: i32887 %var1 = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>888 %var2 = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>889 890 // CHECK: {{%.*}}:2 = spirv.mlir.selection -> i32, i32 {891 %yield:2 = spirv.mlir.selection -> i32, i32 {892 // CHECK-NEXT: spirv.BranchConditional {{%.*}}, ^bb1, ^bb2893 spirv.BranchConditional %cond, ^then, ^else894 895 // CHECK: ^bb1896 ^then:897 %one = spirv.Constant 1: i32898 %three = spirv.Constant 3: i32899 // CHECK: spirv.Branch ^bb3({{%.*}}, {{%.*}} : i32, i32)900 spirv.Branch ^merge(%one, %three : i32, i32)901 902 // CHECK: ^bb2903 ^else:904 %two = spirv.Constant 2: i32905 %four = spirv.Constant 4 : i32906 // CHECK: spirv.Branch ^bb3({{%.*}}, {{%.*}} : i32, i32)907 spirv.Branch ^merge(%two, %four : i32, i32)908 909 // CHECK: ^bb3({{%.*}}: i32, {{%.*}}: i32)910 ^merge(%merged_1_2: i32, %merged_3_4: i32):911 // CHECK-NEXT: spirv.mlir.merge {{%.*}}, {{%.*}} : i32, i32912 spirv.mlir.merge %merged_1_2, %merged_3_4 : i32, i32913 }914 915 // CHECK: spirv.Store "Function" {{%.*}}, {{%.*}}#0 : i32916 spirv.Store "Function" %var1, %yield#0 : i32917 // CHECK: spirv.Store "Function" {{%.*}}, {{%.*}}#1 : i32918 spirv.Store "Function" %var2, %yield#1 : i32919 920 spirv.Return921}922 923// -----924 925//===----------------------------------------------------------------------===//926// spirv.Unreachable927//===----------------------------------------------------------------------===//928 929// CHECK-LABEL: func @unreachable_no_pred930func.func @unreachable_no_pred() {931 spirv.Return932 933 ^next:934 // CHECK: spirv.Unreachable935 spirv.Unreachable936}937 938// CHECK-LABEL: func @unreachable_with_pred939func.func @unreachable_with_pred() {940 spirv.Return941 942 ^parent:943 spirv.Branch ^unreachable944 945 ^unreachable:946 // CHECK: spirv.Unreachable947 spirv.Unreachable948}949 950// -----951 952func.func @unreachable() {953 // expected-error @+1 {{cannot be used in reachable block}}954 spirv.Unreachable955}956 957// -----958 959//===----------------------------------------------------------------------===//960// spirv.Kill961//===----------------------------------------------------------------------===//962 963// CHECK-LABEL: func @kill964func.func @kill() {965 // CHECK: spirv.Kill966 spirv.Kill967}968 969// -----970 971//===----------------------------------------------------------------------===//972// spirv.Switch973//===----------------------------------------------------------------------===//974 975func.func @switch(%selector: i32) -> () {976 // CHECK: spirv.Switch {{%.*}} : i32, [977 // CHECK-NEXT: default: ^bb1,978 // CHECK-NEXT: 0: ^bb2,979 // CHECK-NEXT: 1: ^bb3,980 // CHECK-NEXT: 2: ^bb4981 spirv.Switch %selector : i32, [982 default: ^default,983 0: ^case0,984 1: ^case1,985 2: ^case2986 ]987^default:988 spirv.Branch ^merge989 990^case0:991 spirv.Branch ^merge992 993^case1:994 spirv.Branch ^merge995 996^case2:997 spirv.Branch ^merge998 999^merge:1000 spirv.Return1001}1002 1003func.func @switch_only_default(%selector: i32) -> () {1004 // CHECK: spirv.Switch {{%.*}} : i32, [1005 // CHECK-NEXT: default: ^bb11006 spirv.Switch %selector : i32, [1007 default: ^default1008 ]1009^default:1010 spirv.Branch ^merge1011 1012^merge:1013 spirv.Return1014}1015 1016func.func @switch_operands(%selector : i32, %operand : i32) {1017 // CHECK: spirv.Switch {{%.*}} : i32, [1018 // CHECK-NEXT: default: ^bb1({{%.*}} : i32),1019 // CHECK-NEXT: 0: ^bb2({{%.*}} : i32),1020 // CHECK-NEXT: 1: ^bb3({{%.*}} : i32)1021 spirv.Switch %selector : i32, [1022 default: ^default(%operand : i32),1023 0: ^case0(%operand : i32),1024 1: ^case1(%operand : i32)1025 ]1026^default(%argd : i32):1027 spirv.Branch ^merge1028 1029^case0(%arg0 : i32):1030 spirv.Branch ^merge1031 1032^case1(%arg1 : i32):1033 spirv.Branch ^merge1034 1035^merge:1036 spirv.Return1037}1038 1039// -----1040 1041func.func @switch_float_selector(%selector: f32) -> () {1042 // expected-error@+1 {{expected builtin.integer, but found 'f32'}}1043 spirv.Switch %selector : f32, [1044 default: ^default1045 ]1046^default:1047 spirv.Branch ^merge1048 1049^merge:1050 spirv.Return1051}1052 1053// -----1054 1055func.func @switch_float_selector(%selector: i32) -> () {1056 // expected-error@+3 {{expected integer value}}1057 spirv.Switch %selector : i32, [1058 default: ^default,1059 0.0: ^case01060 ]1061^default:1062 spirv.Branch ^merge1063 1064^case 0:1065 spirv.Branch ^merge1066 1067^merge:1068 spirv.Return1069}1070 1071// -----1072 1073func.func @switch_missing_default(%selector: i32) -> () {1074 // expected-error@+2 {{expected 'default'}}1075 spirv.Switch %selector : i32, [1076 0: ^case01077 ]1078^case 0:1079 spirv.Branch ^merge1080 1081^merge:1082 spirv.Return1083}1084 1085// -----1086 1087func.func @switch_default_no_target(%selector: i32) -> () {1088 // expected-error@+2 {{expected block name}}1089 spirv.Switch %selector : i32, [1090 default:1091 ]1092^default:1093 spirv.Branch ^merge1094 1095^merge:1096 spirv.Return1097}1098 1099// -----1100 1101func.func @switch_case_no_target(%selector: i32) -> () {1102 // expected-error@+3 {{expected block name}}1103 spirv.Switch %selector : i32, [1104 default: ^default,1105 0:1106 ]1107^default:1108 spirv.Branch ^merge1109 1110^case 0:1111 spirv.Branch ^merge1112 1113^merge:1114 spirv.Return1115}1116 1117// -----1118 1119func.func @switch_missing_operand_type(%selector: i32) -> () {1120 %0 = spirv.Constant 0 : i321121 // expected-error@+2 {{expected ':'}}1122 spirv.Switch %selector : i32, [1123 default: ^default (%0),1124 0.0: ^case01125 ]1126^default(%argd : i32):1127 spirv.Branch ^merge1128 1129^case 0:1130 spirv.Branch ^merge1131 1132^merge:1133 spirv.Return1134}1135 1136