1// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -verify-diagnostics 2 3func.func @loop_for_lb(%arg0: f32, %arg1: index) { 4 // expected-error@+1 {{operand #0 must be signless integer or index}} 5 "scf.for"(%arg0, %arg1, %arg1) ({}) : (f32, index, index) -> () 6 return 7} 8 9// ----- 10 11func.func @loop_for_ub(%arg0: f32, %arg1: index) { 12 // expected-error@+1 {{operand #1 must be signless integer or index}} 13 "scf.for"(%arg1, %arg0, %arg1) ({}) : (index, f32, index) -> () 14 return 15} 16 17// ----- 18 19func.func @loop_for_step(%arg0: f32, %arg1: index) { 20 // expected-error@+1 {{operand #2 must be signless integer or index}} 21 "scf.for"(%arg1, %arg1, %arg0) ({}) : (index, index, f32) -> () 22 return 23} 24 25// ----- 26 27func.func @loop_for_mismatch(%arg0: i32, %arg1: index) { 28 // expected-error@+1 {{all of {lowerBound, upperBound, step} have same type}} 29 "scf.for"(%arg1, %arg0, %arg1) ({}) : (index, i32, index) -> () 30 return 31} 32 33// ----- 34 35func.func @loop_for_one_region(%arg0: index) { 36 // expected-error@+1 {{requires one region}} 37 "scf.for"(%arg0, %arg0, %arg0) ( 38 {scf.yield}, 39 {scf.yield} 40 ) : (index, index, index) -> () 41 return 42} 43 44// ----- 45 46func.func @loop_for_single_block(%arg0: index) { 47 // expected-error@+1 {{expects region #0 to have 0 or 1 blocks}} 48 "scf.for"(%arg0, %arg0, %arg0) ( 49 { 50 ^bb1: 51 scf.yield 52 ^bb2: 53 scf.yield 54 } 55 ) : (index, index, index) -> () 56 return 57} 58 59// ----- 60 61func.func @loop_for_single_index_argument(%arg0: index) { 62 // expected-error@+1 {{expected induction variable to be same type as bounds}} 63 "scf.for"(%arg0, %arg0, %arg0) ( 64 { 65 ^bb0(%i0 : f32): 66 scf.yield 67 } 68 ) : (index, index, index) -> () 69 return 70} 71 72// ----- 73 74func.func @not_enough_loop_results(%arg0: index, %init: f32) { 75 // expected-error @below{{mismatch in number of loop-carried values and defined values}} 76 "scf.for"(%arg0, %arg0, %arg0, %init) ( 77 { 78 ^bb0(%i0 : index, %iter: f32): 79 scf.yield %iter : f32 80 } 81 ) : (index, index, index, f32) -> () 82 return 83} 84 85// ----- 86 87func.func @scf_for_incorrect_result_type(%arg0: index, %init: f32) { 88 // expected-error @below{{0-th region iter_arg and 0-th loop result have different type: 'f32' != 'f64'}} 89 "scf.for"(%arg0, %arg0, %arg0, %init) ( 90 { 91 ^bb0(%i0 : index, %iter: f32): 92 scf.yield %iter : f32 93 } 94 ) : (index, index, index, f32) -> (f64) 95 return 96} 97 98// ----- 99 100func.func @too_many_iter_args(%arg0: index, %init: f32) { 101 // expected-error @below{{different number of inits and region iter_args: 1 != 2}} 102 %x = "scf.for"(%arg0, %arg0, %arg0, %init) ( 103 { 104 ^bb0(%i0 : index, %iter: f32, %iter2: f32): 105 scf.yield %iter, %iter : f32, f32 106 } 107 ) : (index, index, index, f32) -> (f32) 108 return 109} 110 111// ----- 112 113func.func @too_few_yielded_values(%arg0: index, %init: f32) { 114 // expected-error @below{{different number of region iter_args and yielded values: 2 != 1}} 115 %x, %x2 = "scf.for"(%arg0, %arg0, %arg0, %init, %init) ( 116 { 117 ^bb0(%i0 : index, %iter: f32, %iter2: f32): 118 scf.yield %iter : f32 119 } 120 ) : (index, index, index, f32, f32) -> (f32, f32) 121 return 122} 123 124// ----- 125 126func.func @loop_if_not_i1(%arg0: index) { 127 // expected-error@+1 {{operand #0 must be 1-bit signless integer}} 128 "scf.if"(%arg0) ({}, {}) : (index) -> () 129 return 130} 131 132// ----- 133 134func.func @loop_if_more_than_2_regions(%arg0: i1) { 135 // expected-error@+1 {{expected 2 regions}} 136 "scf.if"(%arg0) ({}, {}, {}): (i1) -> () 137 return 138} 139 140// ----- 141 142func.func @loop_if_not_one_block_per_region(%arg0: i1) { 143 // expected-error@+1 {{expects region #0 to have 0 or 1 blocks}} 144 "scf.if"(%arg0) ({ 145 ^bb0: 146 scf.yield 147 ^bb1: 148 scf.yield 149 }, {}): (i1) -> () 150 return 151} 152 153// ----- 154 155func.func @loop_if_illegal_block_argument(%arg0: i1) { 156 // expected-error@+1 {{region #0 should have no arguments}} 157 "scf.if"(%arg0) ({ 158 ^bb0(%0 : index): 159 scf.yield 160 }, {}): (i1) -> () 161 return 162} 163 164// ----- 165 166func.func @parallel_arguments_different_tuple_size( 167 %arg0: index, %arg1: index, %arg2: index) { 168 // expected-error@+1 {{custom op 'scf.parallel' expected 1 operands}} 169 scf.parallel (%i0) = (%arg0) to (%arg1, %arg2) step () { 170 } 171 return 172} 173 174// ----- 175 176func.func @parallel_body_arguments_wrong_type( 177 %arg0: index, %arg1: index, %arg2: index) { 178 // expected-error@+1 {{'scf.parallel' op expects arguments for the induction variable to be of index type}} 179 "scf.parallel"(%arg0, %arg1, %arg2) ({ 180 ^bb0(%i0: f32): 181 scf.yield 182 }) {operandSegmentSizes = array<i32: 1, 1, 1, 0>}: (index, index, index) -> () 183 return 184} 185 186// ----- 187 188func.func @parallel_body_wrong_number_of_arguments( 189 %arg0: index, %arg1: index, %arg2: index) { 190 // expected-error@+1 {{'scf.parallel' op expects the same number of induction variables: 2 as bound and step values: 1}} 191 "scf.parallel"(%arg0, %arg1, %arg2) ({ 192 ^bb0(%i0: index, %i1: index): 193 scf.yield 194 }) {operandSegmentSizes = array<i32: 1, 1, 1, 0>}: (index, index, index) -> () 195 return 196} 197 198// ----- 199 200func.func @parallel_no_tuple_elements() { 201 // expected-error@+1 {{'scf.parallel' op needs at least one tuple element for lowerBound, upperBound and step}} 202 scf.parallel () = () to () step () { 203 } 204 return 205} 206 207// ----- 208 209func.func @parallel_step_not_positive( 210 %arg0: index, %arg1: index, %arg2: index, %arg3: index) { 211 // expected-error@+3 {{constant step operand must be positive}} 212 %c0 = arith.constant 1 : index 213 %c1 = arith.constant 0 : index 214 scf.parallel (%i0, %i1) = (%arg0, %arg1) to (%arg2, %arg3) step (%c0, %c1) { 215 } 216 return 217} 218 219// ----- 220 221func.func @parallel_fewer_results_than_reduces( 222 %arg0 : index, %arg1: index, %arg2: index) { 223 // expected-error@+1 {{expects number of results: 0 to be the same as number of reductions: 1}} 224 scf.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) { 225 %c0 = arith.constant 1.0 : f32 226 scf.reduce(%c0 : f32) { 227 ^bb0(%lhs: f32, %rhs: f32): 228 scf.reduce.return %lhs : f32 229 } 230 } 231 return 232} 233 234// ----- 235 236func.func @parallel_more_results_than_reduces( 237 %arg0 : index, %arg1 : index, %arg2 : index) { 238 // expected-error@+2 {{expects number of results: 1 to be the same as number of reductions: 0}} 239 %zero = arith.constant 1.0 : f32 240 %res = scf.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) init (%zero) -> f32 { 241 } 242 243 return 244} 245 246// ----- 247 248func.func @parallel_more_results_than_initial_values( 249 %arg0 : index, %arg1: index, %arg2: index) { 250 // expected-error@+1 {{'scf.parallel' number of operands and types do not match: got 0 operands and 1 types}} 251 %res = scf.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) -> f32 { 252 scf.reduce(%arg0 : index) { 253 ^bb0(%lhs: index, %rhs: index): 254 scf.reduce.return %lhs : index 255 } 256 } 257} 258 259// ----- 260 261func.func @parallel_different_types_of_results_and_reduces( 262 %arg0 : index, %arg1: index, %arg2: index) { 263 %zero = arith.constant 0.0 : f32 264 %res = scf.parallel (%i0) = (%arg0) to (%arg1) 265 step (%arg2) init (%zero) -> f32 { 266 // expected-error@+1 {{expects type of 0-th reduction operand: 'index' to be the same as the 0-th result type: 'f32'}} 267 scf.reduce(%arg0 : index) { 268 ^bb0(%lhs: index, %rhs: index): 269 scf.reduce.return %lhs : index 270 } 271 } 272 return 273} 274 275// ----- 276 277func.func @top_level_reduce(%arg0 : f32) { 278 // expected-error@+1 {{expects parent op 'scf.parallel'}} 279 scf.reduce(%arg0 : f32) { 280 ^bb0(%lhs : f32, %rhs : f32): 281 scf.reduce.return %lhs : f32 282 } 283 return 284} 285 286// ----- 287 288func.func @reduce_empty_block(%arg0 : index, %arg1 : f32) { 289 %zero = arith.constant 0.0 : f32 290 %res = scf.parallel (%i0) = (%arg0) to (%arg0) 291 step (%arg0) init (%zero) -> f32 { 292 // expected-error@+1 {{empty block: expect at least a terminator}} 293 scf.reduce(%arg1 : f32) { 294 ^bb0(%lhs : f32, %rhs : f32): 295 } 296 } 297 return 298} 299 300// ----- 301 302func.func @reduce_too_many_args(%arg0 : index, %arg1 : f32) { 303 %zero = arith.constant 0.0 : f32 304 %res = scf.parallel (%i0) = (%arg0) to (%arg0) 305 step (%arg0) init (%zero) -> f32 { 306 // expected-error@+1 {{expected two block arguments with type 'f32' in the 0-th reduction region}} 307 scf.reduce(%arg1 : f32) { 308 ^bb0(%lhs : f32, %rhs : f32, %other : f32): 309 scf.reduce.return %lhs : f32 310 } 311 } 312 return 313} 314 315// ----- 316 317func.func @reduce_wrong_args(%arg0 : index, %arg1 : f32) { 318 %zero = arith.constant 0.0 : f32 319 %res = scf.parallel (%i0) = (%arg0) to (%arg0) 320 step (%arg0) init (%zero) -> f32 { 321 // expected-error@+1 {{expected two block arguments with type 'f32' in the 0-th reduction region}} 322 scf.reduce(%arg1 : f32) { 323 ^bb0(%lhs : f32, %rhs : i32): 324 scf.reduce.return %lhs : f32 325 } 326 } 327 return 328} 329 330 331// ----- 332 333func.func @reduce_wrong_terminator(%arg0 : index, %arg1 : f32) { 334 %zero = arith.constant 0.0 : f32 335 %res = scf.parallel (%i0) = (%arg0) to (%arg0) 336 step (%arg0) init (%zero) -> f32 { 337 // expected-error@+1 {{reduction bodies must be terminated with an 'scf.reduce.return' op}} 338 scf.reduce(%arg1 : f32) { 339 ^bb0(%lhs : f32, %rhs : f32): 340 "test.finish" () : () -> () 341 } 342 } 343 return 344} 345 346// ----- 347 348func.func @reduceReturn_wrong_type(%arg0 : index, %arg1: f32) { 349 %zero = arith.constant 0.0 : f32 350 %res = scf.parallel (%i0) = (%arg0) to (%arg0) 351 step (%arg0) init (%zero) -> f32 { 352 scf.reduce(%arg1 : f32) { 353 ^bb0(%lhs : f32, %rhs : f32): 354 %c0 = arith.constant 1 : index 355 // expected-error@+1 {{must have type 'f32' (the type of the reduction inputs)}} 356 scf.reduce.return %c0 : index 357 } 358 } 359 return 360} 361 362// ----- 363 364func.func @reduceReturn_not_inside_reduce(%arg0 : f32) { 365 "foo.region"() ({ 366 // expected-error@+1 {{expects parent op 'scf.reduce'}} 367 scf.reduce.return %arg0 : f32 368 }): () -> () 369 return 370} 371 372// ----- 373 374func.func @std_if_incorrect_yield(%arg0: i1, %arg1: f32) 375{ 376 // expected-error@+1 {{region control flow edge from Region #0 to parent results: source has 1 operands, but target successor needs 2}} 377 %x, %y = scf.if %arg0 -> (f32, f32) { 378 %0 = arith.addf %arg1, %arg1 : f32 379 scf.yield %0 : f32 380 } else { 381 %0 = arith.subf %arg1, %arg1 : f32 382 scf.yield %0, %0 : f32, f32 383 } 384 return 385} 386 387// ----- 388 389func.func @std_if_missing_else(%arg0: i1, %arg1: f32) 390{ 391 // expected-error@+1 {{must have an else block if defining values}} 392 %x = scf.if %arg0 -> (f32) { 393 %0 = arith.addf %arg1, %arg1 : f32 394 scf.yield %0 : f32 395 } 396 return 397} 398 399// ----- 400 401func.func @std_for_operands_mismatch(%arg0 : index, %arg1 : index, %arg2 : index) { 402 %s0 = arith.constant 0.0 : f32 403 %t0 = arith.constant 1 : i32 404 // expected-error@+1 {{mismatch in number of loop-carried values and defined values}} 405 %result1:3 = scf.for %i0 = %arg0 to %arg1 step %arg2 406 iter_args(%si = %s0, %ti = %t0) -> (f32, i32, f32) { 407 %sn = arith.addf %si, %si : f32 408 %tn = arith.addi %ti, %ti : i32 409 scf.yield %sn, %tn, %sn : f32, i32, f32 410 } 411 return 412} 413 414// ----- 415 416func.func @std_for_operands_mismatch_2(%arg0 : index, %arg1 : index, %arg2 : index) { 417 %s0 = arith.constant 0.0 : f32 418 %t0 = arith.constant 1 : i32 419 %u0 = arith.constant 1.0 : f32 420 // expected-error@+1 {{mismatch in number of loop-carried values and defined values}} 421 %result1:2 = scf.for %i0 = %arg0 to %arg1 step %arg2 422 iter_args(%si = %s0, %ti = %t0, %ui = %u0) -> (f32, i32) { 423 %sn = arith.addf %si, %si : f32 424 %tn = arith.addi %ti, %ti : i32 425 %un = arith.subf %ui, %ui : f32 426 scf.yield %sn, %tn, %un : f32, i32, f32 427 } 428 return 429} 430 431// ----- 432 433func.func @std_for_operands_mismatch_3(%arg0 : index, %arg1 : index, %arg2 : index) { 434 // expected-note@+1 {{prior use here}} 435 %s0 = arith.constant 0.0 : f32 436 %t0 = arith.constant 1.0 : f32 437 // expected-error@+2 {{expects different type than prior uses: 'i32' vs 'f32'}} 438 %result1:2 = scf.for %i0 = %arg0 to %arg1 step %arg2 439 iter_args(%si = %s0, %ti = %t0) -> (i32, i32) { 440 %sn = arith.addf %si, %si : i32 441 %tn = arith.addf %ti, %ti : i32 442 scf.yield %sn, %tn : i32, i32 443 } 444 return 445} 446 447// ----- 448 449func.func @std_for_operands_mismatch_4(%arg0 : index, %arg1 : index, %arg2 : index) { 450 %s0 = arith.constant 0.0 : f32 451 %t0 = arith.constant 1.0 : f32 452 // expected-error @below {{1-th region iter_arg and 1-th yielded value have different type: 'f32' != 'i32'}} 453 %result1:2 = scf.for %i0 = %arg0 to %arg1 step %arg2 454 iter_args(%si = %s0, %ti = %t0) -> (f32, f32) { 455 %sn = arith.addf %si, %si : f32 456 %ic = arith.constant 1 : i32 457 scf.yield %sn, %ic : f32, i32 458 } 459 return 460} 461 462// ----- 463 464func.func @parallel_invalid_yield( 465 %arg0: index, %arg1: index, %arg2: index) { 466 // expected-error@below {{expects body to terminate with 'scf.reduce'}} 467 scf.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) { 468 %c0 = arith.constant 1.0 : f32 469 // expected-note@below {{terminator here}} 470 scf.yield %c0 : f32 471 } 472 return 473} 474 475// ----- 476 477func.func @yield_invalid_parent_op() { 478 "my.op"() ({ 479 // expected-error@+1 {{'scf.yield' op expects parent op to be one of 'scf.execute_region, scf.for, scf.if, scf.index_switch, scf.while'}} 480 scf.yield 481 }) : () -> () 482 return 483} 484 485// ----- 486 487func.func @while_parser_type_mismatch() { 488 %true = arith.constant true 489 // expected-error@+1 {{expected as many input types as operands (expected 0 got 1)}} 490 scf.while : (i32) -> () { 491 scf.condition(%true) 492 } do { 493 scf.yield 494 } 495} 496 497// ----- 498 499func.func @while_bad_terminator() { 500 // expected-error@+1 {{expects the 'before' region to terminate with 'scf.condition'}} 501 scf.while : () -> () { 502 // expected-note@+1 {{terminator here}} 503 "some.other_terminator"() : () -> () 504 } do { 505 scf.yield 506 } 507} 508 509// ----- 510 511func.func @while_empty_region() { 512 // expected-error@+1 {{'scf.while' op region #0 ('before') failed to verify constraint: region with 1 blocks}} 513 scf.while : () -> () { 514 } do { 515 } 516} 517 518// ----- 519 520func.func @while_empty_block() { 521 // expected-error @below {{expects a non-empty block}} 522 scf.while : () -> () { 523 ^bb0: 524 } do { 525 ^bb0: 526 } 527} 528 529// ----- 530 531func.func @while_invalid_terminator() { 532 // expected-error @below {{expects the 'before' region to terminate with 'scf.condition'}} 533 scf.while : () -> () { 534 ^bb0: 535 // expected-note @below{{terminator here}} 536 "test.foo"() : () -> () 537 } do { 538 ^bb0: 539 "test.bar"() : () -> () 540 } 541} 542 543// ----- 544 545func.func @while_cross_region_type_mismatch() { 546 %true = arith.constant true 547 // expected-error@+1 {{'scf.while' op region control flow edge from Region #0 to Region #1: source has 0 operands, but target successor needs 1}} 548 scf.while : () -> () { 549 scf.condition(%true) 550 } do { 551 ^bb0(%arg0: i32): 552 scf.yield 553 } 554} 555 556// ----- 557 558func.func @while_cross_region_type_mismatch() { 559 %true = arith.constant true 560 // expected-error@+1 {{'scf.while' op along control flow edge from Region #0 to Region #1: source type #0 'i1' should match input type #0 'i32'}} 561 %0 = scf.while : () -> (i1) { 562 scf.condition(%true) %true : i1 563 } do { 564 ^bb0(%arg0: i32): 565 scf.yield 566 } 567} 568 569// ----- 570 571func.func @while_result_type_mismatch() { 572 %true = arith.constant true 573 // expected-error@+1 {{'scf.while' op region control flow edge from Region #0 to parent results: source has 1 operands, but target successor needs 0}} 574 scf.while : () -> () { 575 scf.condition(%true) %true : i1 576 } do { 577 ^bb0(%arg0: i1): 578 scf.yield 579 } 580} 581 582// ----- 583 584func.func @while_bad_terminator() { 585 %true = arith.constant true 586 // expected-error@+1 {{expects the 'after' region to terminate with 'scf.yield'}} 587 scf.while : () -> () { 588 scf.condition(%true) 589 } do { 590 // expected-note@+1 {{terminator here}} 591 "some.other_terminator"() : () -> () 592 } 593} 594 595// ----- 596 597func.func @execute_region() { 598 // expected-error @+1 {{region cannot have any arguments}} 599 "scf.execute_region"() ({ 600 ^bb0(%i : i32): 601 scf.yield 602 }) : () -> () 603 return 604} 605 606// ----- 607 608func.func @wrong_num_results(%in: tensor<100xf32>, %out: tensor<100xf32>) { 609 %c1 = arith.constant 1 : index 610 %num_threads = arith.constant 100 : index 611 612 // expected-error@+1 {{number of operands and types do not match: got 1 operands and 2 types}} 613 %result:2 = scf.forall (%thread_idx) in (%num_threads) shared_outs(%o = %out) -> (tensor<100xf32>, tensor<100xf32>) { 614 %1 = tensor.extract_slice %in[%thread_idx][1][1] : tensor<100xf32> to tensor<1xf32> 615 scf.forall.in_parallel { 616 tensor.parallel_insert_slice %1 into %o[%thread_idx][1][1] : 617 tensor<1xf32> into tensor<100xf32> 618 } 619 } 620 return 621} 622 623// ----- 624 625func.func @invalid_insert_dest(%in: tensor<100xf32>, %out: tensor<100xf32>) { 626 %c1 = arith.constant 1 : index 627 %num_threads = arith.constant 100 : index 628 629 %result = scf.forall (%thread_idx) in (%num_threads) shared_outs(%o = %out) -> (tensor<100xf32>) { 630 %1 = tensor.extract_slice %in[%thread_idx][1][1] : tensor<100xf32> to tensor<1xf32> 631 scf.forall.in_parallel { 632 // expected-error @+1 {{may only insert into an output block argument}} 633 tensor.parallel_insert_slice %1 into %out[%thread_idx][1][1] : 634 tensor<1xf32> into tensor<100xf32> 635 } 636 } 637 return 638} 639 640// ----- 641 642func.func @wrong_terminator_op(%in: tensor<100xf32>, %out: tensor<100xf32>) { 643 %c1 = arith.constant 1 : index 644 %num_threads = arith.constant 100 : index 645 646 %result = scf.forall (%thread_idx) in (%num_threads) shared_outs(%o = %out) -> (tensor<100xf32>) { 647 %1 = tensor.extract_slice %in[%thread_idx][1][1] : tensor<100xf32> to tensor<1xf32> 648 // expected-error @+1 {{expected only tensor.parallel_insert_slice ops}} 649 scf.forall.in_parallel { 650 tensor.parallel_insert_slice %1 into %o[%thread_idx][1][1] : 651 tensor<1xf32> into tensor<100xf32> 652 %0 = arith.constant 1: index 653 } 654 } 655 return 656} 657 658// ----- 659 660func.func @mismatched_mapping(%x: memref<2 x 32 x f32>, %y: memref<2 x 32 x f32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<2 x 32 x f32> { 661 %one = arith.constant 1 : index 662 %c65535 = arith.constant 65535 : index 663 // expected-error @below {{'scf.forall' op mapping attribute size must match op rank}} 664 scf.forall (%i, %j) in (%c65535, %c65535) { 665 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32> 666 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32> 667 %6 = math.fma %alpha, %4, %5 : f32 668 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32> 669 } { mapping = [#gpu.block<x>, #gpu.block<y>, #gpu.block<z>] } 670 return %y : memref<2 x 32 x f32> 671} 672 673// ----- 674 675func.func @switch_wrong_case_count(%arg0: index) { 676 // expected-error @below {{'scf.index_switch' op has 0 case regions but 1 case values}} 677 "scf.index_switch"(%arg0) ({ 678 scf.yield 679 }) {cases = array<i64: 1>} : (index) -> () 680 return 681} 682 683// ----- 684 685func.func @switch_duplicate_case(%arg0: index) { 686 // expected-error @below {{'scf.index_switch' op has duplicate case value: 0}} 687 scf.index_switch %arg0 688 case 0 { 689 scf.yield 690 } 691 case 0 { 692 scf.yield 693 } 694 default { 695 scf.yield 696 } 697 return 698} 699 700// ----- 701 702func.func @switch_wrong_types(%arg0: index) { 703 // expected-error @below {{'scf.index_switch' op expected each region to return 0 values, but default region returns 1}} 704 scf.index_switch %arg0 705 default { 706 // expected-note @below {{see yield operation here}} 707 scf.yield %arg0 : index 708 } 709 return 710} 711 712// ----- 713 714func.func @switch_wrong_types(%arg0: index, %arg1: i32) { 715 // expected-error @below {{'scf.index_switch' op expected result #0 of each region to be 'index'}} 716 scf.index_switch %arg0 -> index 717 case 0 { 718 // expected-note @below {{case region #0 returns 'i32' here}} 719 scf.yield %arg1 : i32 720 } 721 default { 722 scf.yield %arg0 : index 723 } 724 return 725} 726 727// ----- 728 729func.func @switch_missing_terminator(%arg0: index, %arg1: i32) { 730 // expected-error @below {{'scf.index_switch' op expected region to end with scf.yield, but got func.return}} 731 "scf.index_switch"(%arg0) ({ 732 "scf.yield"() : () -> () 733 }, { 734 return 735 }) {cases = array<i64: 1>} : (index) -> () 736} 737 738// ----- 739 740func.func @parallel_missing_terminator(%0 : index) { 741 // expected-error @below {{expects body to terminate with 'scf.reduce'}} 742 "scf.parallel"(%0, %0, %0) ({ 743 ^bb0(%arg1: index): 744 // expected-note @below {{terminator here}} 745 %2 = "arith.constant"() {value = 1.000000e+00 : f32} : () -> f32 746 }) {operandSegmentSizes = array<i32: 1, 1, 1, 0>} : (index, index, index) -> () 747 return 748} 749 750