brintos

brintos / llvm-project-archived public Read only

0
0
Text · 73.0 KiB · ac590fc Raw
2174 lines · plain
1// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(canonicalize{test-convergence}))' -split-input-file | FileCheck %s2 3func.func @single_iteration_some(%A: memref<?x?x?xi32>) {4  %c0 = arith.constant 0 : index5  %c1 = arith.constant 1 : index6  %c2 = arith.constant 2 : index7  %c3 = arith.constant 3 : index8  %c6 = arith.constant 6 : index9  %c7 = arith.constant 7 : index10  %c10 = arith.constant 10 : index11  scf.parallel (%i0, %i1, %i2) = (%c0, %c3, %c7) to (%c1, %c6, %c10) step (%c1, %c2, %c3) {12    %c42 = arith.constant 42 : i3213    memref.store %c42, %A[%i0, %i1, %i2] : memref<?x?x?xi32>14    scf.reduce15  }16  return17}18 19// CHECK-LABEL:   func @single_iteration_some(20// CHECK-SAME:                        [[ARG0:%.*]]: memref<?x?x?xi32>) {21// CHECK-DAG:           [[C42:%.*]] = arith.constant 42 : i3222// CHECK-DAG:           [[C7:%.*]] = arith.constant 7 : index23// CHECK-DAG:           [[C6:%.*]] = arith.constant 6 : index24// CHECK-DAG:           [[C3:%.*]] = arith.constant 3 : index25// CHECK-DAG:           [[C2:%.*]] = arith.constant 2 : index26// CHECK-DAG:           [[C0:%.*]] = arith.constant 0 : index27// CHECK:           scf.parallel ([[V0:%.*]]) = ([[C3]]) to ([[C6]]) step ([[C2]]) {28// CHECK:             memref.store [[C42]], [[ARG0]]{{\[}}[[C0]], [[V0]], [[C7]]] : memref<?x?x?xi32>29// CHECK:             scf.reduce30// CHECK:           }31// CHECK:           return32 33// -----34 35func.func @single_iteration_all(%A: memref<?x?x?xi32>) {36  %c0 = arith.constant 0 : index37  %c1 = arith.constant 1 : index38  %c3 = arith.constant 3 : index39  %c6 = arith.constant 6 : index40  %c7 = arith.constant 7 : index41  %c10 = arith.constant 10 : index42  scf.parallel (%i0, %i1, %i2) = (%c0, %c3, %c7) to (%c1, %c6, %c10) step (%c1, %c3, %c3) {43    %c42 = arith.constant 42 : i3244    memref.store %c42, %A[%i0, %i1, %i2] : memref<?x?x?xi32>45    scf.reduce46  }47  return48}49 50// CHECK-LABEL:   func @single_iteration_all(51// CHECK-SAME:                        [[ARG0:%.*]]: memref<?x?x?xi32>) {52// CHECK-DAG:           [[C42:%.*]] = arith.constant 42 : i3253// CHECK-DAG:           [[C7:%.*]] = arith.constant 7 : index54// CHECK-DAG:           [[C3:%.*]] = arith.constant 3 : index55// CHECK-DAG:           [[C0:%.*]] = arith.constant 0 : index56// CHECK-NOT:           scf.parallel57// CHECK:               memref.store [[C42]], [[ARG0]]{{\[}}[[C0]], [[C3]], [[C7]]] : memref<?x?x?xi32>58// CHECK-NOT:           scf.reduce59// CHECK:               return60 61// -----62 63func.func @single_iteration_reduce(%A: index, %B: index) -> (index, index) {64  %c0 = arith.constant 0 : index65  %c1 = arith.constant 1 : index66  %c2 = arith.constant 2 : index67  %c3 = arith.constant 3 : index68  %c6 = arith.constant 6 : index69  %0:2 = scf.parallel (%i0, %i1) = (%c1, %c3) to (%c2, %c6) step (%c1, %c3) init(%A, %B) -> (index, index) {70    scf.reduce(%i0, %i1 : index, index)  {71    ^bb0(%lhs: index, %rhs: index):72      %1 = arith.addi %lhs, %rhs : index73      scf.reduce.return %1 : index74    }, {75    ^bb0(%lhs: index, %rhs: index):76      %2 = arith.muli %lhs, %rhs : index77      scf.reduce.return %2 : index78    }79  }80  return %0#0, %0#1 : index, index81}82 83// CHECK-LABEL:   func @single_iteration_reduce(84// CHECK-SAME:                        [[ARG0:%.*]]: index, [[ARG1:%.*]]: index)85// CHECK-DAG:           [[C3:%.*]] = arith.constant 3 : index86// CHECK-DAG:           [[C1:%.*]] = arith.constant 1 : index87// CHECK-NOT:           scf.parallel88// CHECK-NOT:           scf.reduce89// CHECK-NOT:           scf.reduce.return90// CHECK-NOT:           scf.yield91// CHECK:               [[V0:%.*]] = arith.addi [[ARG0]], [[C1]]92// CHECK:               [[V1:%.*]] = arith.muli [[ARG1]], [[C3]]93// CHECK:               return [[V0]], [[V1]]94 95// -----96 97func.func @nested_parallel(%0: memref<?x?x?xf64>) -> memref<?x?x?xf64> {98  %c0 = arith.constant 0 : index99  %c1 = arith.constant 1 : index100  %c2 = arith.constant 2 : index101  %1 = memref.dim %0, %c0 : memref<?x?x?xf64>102  %2 = memref.dim %0, %c1 : memref<?x?x?xf64>103  %3 = memref.dim %0, %c2 : memref<?x?x?xf64>104  %4 = memref.alloc(%1, %2, %3) : memref<?x?x?xf64>105  scf.parallel (%arg1) = (%c0) to (%1) step (%c1) {106    scf.parallel (%arg2) = (%c0) to (%2) step (%c1) {107      scf.parallel (%arg3) = (%c0) to (%3) step (%c1) {108        %5 = memref.load %0[%arg1, %arg2, %arg3] : memref<?x?x?xf64>109        memref.store %5, %4[%arg1, %arg2, %arg3] : memref<?x?x?xf64>110        scf.reduce111      }112      scf.reduce113    }114    scf.reduce115  }116  return %4 : memref<?x?x?xf64>117}118 119// CHECK-LABEL:   func @nested_parallel(120// CHECK-DAG:       [[C0:%.*]] = arith.constant 0 : index121// CHECK-DAG:       [[C1:%.*]] = arith.constant 1 : index122// CHECK-DAG:       [[C2:%.*]] = arith.constant 2 : index123// CHECK:           [[B0:%.*]] = memref.dim {{.*}}, [[C0]]124// CHECK:           [[B1:%.*]] = memref.dim {{.*}}, [[C1]]125// CHECK:           [[B2:%.*]] = memref.dim {{.*}}, [[C2]]126// CHECK:           scf.parallel ([[V0:%.*]], [[V1:%.*]], [[V2:%.*]]) = ([[C0]], [[C0]], [[C0]]) to ([[B0]], [[B1]], [[B2]]) step ([[C1]], [[C1]], [[C1]])127// CHECK:           memref.load {{.*}}{{\[}}[[V0]], [[V1]], [[V2]]]128// CHECK:           memref.store {{.*}}{{\[}}[[V0]], [[V1]], [[V2]]]129 130// -----131 132func.func private @side_effect()133func.func @one_unused(%cond: i1) -> (index) {134  %0, %1 = scf.if %cond -> (index, index) {135    func.call @side_effect() : () -> ()136    %c0 = "test.value0"() : () -> (index)137    %c1 = "test.value1"() : () -> (index)138    scf.yield %c0, %c1 : index, index139  } else {140    %c2 = "test.value2"() : () -> (index)141    %c3 = "test.value3"() : () -> (index)142    scf.yield %c2, %c3 : index, index143  }144  return %1 : index145}146 147// CHECK-LABEL:   func @one_unused148// CHECK:           [[V0:%.*]] = scf.if %{{.*}} -> (index) {149// CHECK:             call @side_effect() : () -> ()150// CHECK:             [[C1:%.*]] = "test.value1"151// CHECK:             scf.yield [[C1]] : index152// CHECK:           } else {153// CHECK:             [[C3:%.*]] = "test.value3"154// CHECK:             scf.yield [[C3]] : index155// CHECK:           }156// CHECK:           return [[V0]] : index157 158// -----159 160func.func private @side_effect()161func.func @nested_unused(%cond1: i1, %cond2: i1) -> (index) {162  %0, %1 = scf.if %cond1 -> (index, index) {163    %2, %3 = scf.if %cond2 -> (index, index) {164      func.call @side_effect() : () -> ()165      %c0 = "test.value0"() : () -> (index)166      %c1 = "test.value1"() : () -> (index)167      scf.yield %c0, %c1 : index, index168    } else {169      %c2 = "test.value2"() : () -> (index)170      %c3 = "test.value3"() : () -> (index)171      scf.yield %c2, %c3 : index, index172    }173    scf.yield %2, %3 : index, index174  } else {175    %c0 = "test.value0_2"() : () -> (index)176    %c1 = "test.value1_2"() : () -> (index)177    scf.yield %c0, %c1 : index, index178  }179  return %1 : index180}181 182// CHECK-LABEL:   func @nested_unused183// CHECK:           [[V0:%.*]] = scf.if {{.*}} -> (index) {184// CHECK:             [[V1:%.*]] = scf.if {{.*}} -> (index) {185// CHECK:               call @side_effect() : () -> ()186// CHECK:               [[C1:%.*]] = "test.value1"187// CHECK:               scf.yield [[C1]] : index188// CHECK:             } else {189// CHECK:               [[C3:%.*]] = "test.value3"190// CHECK:               scf.yield [[C3]] : index191// CHECK:             }192// CHECK:             scf.yield [[V1]] : index193// CHECK:           } else {194// CHECK:             [[C1_2:%.*]] = "test.value1_2"195// CHECK:             scf.yield [[C1_2]] : index196// CHECK:           }197// CHECK:           return [[V0]] : index198 199// -----200 201func.func private @side_effect()202func.func @all_unused(%cond: i1) {203  %c0 = arith.constant 0 : index204  %c1 = arith.constant 1 : index205  %0, %1 = scf.if %cond -> (index, index) {206    func.call @side_effect() : () -> ()207    scf.yield %c0, %c1 : index, index208  } else {209    func.call @side_effect() : () -> ()210    scf.yield %c0, %c1 : index, index211  }212  return213}214 215// CHECK-LABEL:   func @all_unused216// CHECK:           scf.if %{{.*}} {217// CHECK:             call @side_effect() : () -> ()218// CHECK:           } else {219// CHECK:             call @side_effect() : () -> ()220// CHECK:           }221// CHECK:           return222 223// -----224 225func.func @empty_if1(%cond: i1) {226  scf.if %cond {227    scf.yield228  }229  return230}231 232// CHECK-LABEL:   func @empty_if1233// CHECK-NOT:       scf.if234// CHECK:           return235 236// -----237 238func.func @empty_if2(%cond: i1) {239  scf.if %cond {240    scf.yield241  } else {242    scf.yield243  }244  return245}246 247// CHECK-LABEL:   func @empty_if2248// CHECK-NOT:       scf.if249// CHECK:           return250 251// -----252 253func.func @empty_else(%cond: i1, %v : memref<i1>) {254  scf.if %cond {255    memref.store %cond, %v[] : memref<i1>256  } else {257  }258  return259}260 261// CHECK-LABEL: func @empty_else262// CHECK:         scf.if263// CHECK-NOT:     else264 265// -----266 267func.func @to_select1(%cond: i1) -> index {268  %c0 = arith.constant 0 : index269  %c1 = arith.constant 1 : index270  %0 = scf.if %cond -> index {271    scf.yield %c0 : index272  } else {273    scf.yield %c1 : index274  }275  return %0 : index276}277 278// CHECK-LABEL:   func @to_select1279// CHECK-DAG:       [[C0:%.*]] = arith.constant 0 : index280// CHECK-DAG:       [[C1:%.*]] = arith.constant 1 : index281// CHECK:           [[V0:%.*]] = arith.select {{.*}}, [[C0]], [[C1]]282// CHECK:           return [[V0]] : index283 284// -----285 286func.func @to_select_same_val(%cond: i1) -> (index, index) {287  %c0 = arith.constant 0 : index288  %c1 = arith.constant 1 : index289  %0, %1 = scf.if %cond -> (index, index) {290    scf.yield %c0, %c1 : index, index291  } else {292    scf.yield %c1, %c1 : index, index293  }294  return %0, %1 : index, index295}296 297// CHECK-LABEL:   func @to_select_same_val298// CHECK-DAG:       [[C0:%.*]] = arith.constant 0 : index299// CHECK-DAG:       [[C1:%.*]] = arith.constant 1 : index300// CHECK:           [[V0:%.*]] = arith.select {{.*}}, [[C0]], [[C1]]301// CHECK:           return [[V0]], [[C1]] : index, index302 303// -----304 305func.func @to_select_with_body(%cond: i1) -> index {306  %c0 = arith.constant 0 : index307  %c1 = arith.constant 1 : index308  %0 = scf.if %cond -> index {309    "test.op"() : () -> ()310    scf.yield %c0 : index311  } else {312    scf.yield %c1 : index313  }314  return %0 : index315}316 317// CHECK-LABEL:   func @to_select_with_body318// CHECK-DAG:       [[C0:%.*]] = arith.constant 0 : index319// CHECK-DAG:       [[C1:%.*]] = arith.constant 1 : index320// CHECK:           [[V0:%.*]] = arith.select {{.*}}, [[C0]], [[C1]]321// CHECK:           scf.if {{.*}} {322// CHECK:             "test.op"() : () -> ()323// CHECK:           }324// CHECK:           return [[V0]] : index325 326// -----327 328func.func @to_select2(%cond: i1) -> (index, index) {329  %c0 = arith.constant 0 : index330  %c1 = arith.constant 1 : index331  %c2 = arith.constant 2 : index332  %c3 = arith.constant 3 : index333  %0, %1 = scf.if %cond -> (index, index) {334    scf.yield %c0, %c1 : index, index335  } else {336    scf.yield %c2, %c3 : index, index337  }338  return %0, %1 : index, index339}340 341// CHECK-LABEL:   func @to_select2342// CHECK-DAG:       [[C0:%.*]] = arith.constant 0 : index343// CHECK-DAG:       [[C1:%.*]] = arith.constant 1 : index344// CHECK-DAG:       [[C2:%.*]] = arith.constant 2 : index345// CHECK-DAG:       [[C3:%.*]] = arith.constant 3 : index346// CHECK:           [[V0:%.*]] = arith.select {{.*}}, [[C0]], [[C2]]347// CHECK:           [[V1:%.*]] = arith.select {{.*}}, [[C1]], [[C3]]348// CHECK:           return [[V0]], [[V1]] : index349 350// -----351 352func.func private @make_i32() -> i32353 354func.func @for_yields_2(%lb : index, %ub : index, %step : index) -> i32 {355  %a = call @make_i32() : () -> (i32)356  %b = scf.for %i = %lb to %ub step %step iter_args(%0 = %a) -> i32 {357    scf.yield %0 : i32358  }359  return %b : i32360}361 362// CHECK-LABEL:   func @for_yields_2363//  CHECK-NEXT:     %[[R:.*]] = call @make_i32() : () -> i32364//  CHECK-NEXT:     return %[[R]] : i32365 366// -----367 368func.func private @make_i32() -> i32369 370func.func @for_yields_3(%lb : index, %ub : index, %step : index) -> (i32, i32, i32) {371  %a = call @make_i32() : () -> (i32)372  %b = call @make_i32() : () -> (i32)373  %r:3 = scf.for %i = %lb to %ub step %step iter_args(%0 = %a, %1 = %a, %2 = %b) -> (i32, i32, i32) {374    %c = func.call @make_i32() : () -> (i32)375    scf.yield %0, %c, %2 : i32, i32, i32376  } {some_attr}377  return %r#0, %r#1, %r#2 : i32, i32, i32378}379 380// CHECK-LABEL:   func @for_yields_3381//  CHECK-NEXT:     %[[a:.*]] = call @make_i32() : () -> i32382//  CHECK-NEXT:     %[[b:.*]] = call @make_i32() : () -> i32383//  CHECK-NEXT:     %[[r1:.*]] = scf.for {{.*}} iter_args(%arg4 = %[[a]]) -> (i32) {384//  CHECK-NEXT:       %[[c:.*]] = func.call @make_i32() : () -> i32385//  CHECK-NEXT:       scf.yield %[[c]] : i32386//  CHECK-NEXT:     } {some_attr}387//  CHECK-NEXT:     return %[[a]], %[[r1]], %[[b]] : i32, i32, i32388 389// -----390 391// Test that an empty loop which iterates at least once and only returns392// values defined outside of the loop is folded away.393func.func @for_yields_4() -> i32 {394  %c0 = arith.constant 0 : index395  %c1 = arith.constant 1 : index396  %c2 = arith.constant 2 : index397  %a = arith.constant 3 : i32398  %b = arith.constant 4 : i32399  %r = scf.for %i = %c0 to %c2 step %c1 iter_args(%0 = %a) -> i32 {400    scf.yield %b : i32401  }402  return %r : i32403}404 405// CHECK-LABEL:   func @for_yields_4406//  CHECK-NEXT:     %[[b:.*]] = arith.constant 4 : i32407//  CHECK-NEXT:     return %[[b]] : i32408 409// -----410 411// CHECK-LABEL: @constant_iter_arg412func.func @constant_iter_arg(%arg0: index, %arg1: index, %arg2: index) {413  %c0_i32 = arith.constant 0 : i32414  // CHECK: scf.for %arg3 = %arg0 to %arg1 step %arg2 {415  %0 = scf.for %i = %arg0 to %arg1 step %arg2 iter_args(%arg3 = %c0_i32) -> i32 {416    // CHECK-NEXT: "test.use"(%c0_i32)417    "test.use"(%arg3) : (i32) -> ()418    scf.yield %c0_i32 : i32419  }420  return421}422 423// -----424 425// CHECK-LABEL: @replace_true_if426func.func @replace_true_if() {427  %true = arith.constant true428  // CHECK-NOT: scf.if429  // CHECK: "test.op"430  scf.if %true {431    "test.op"() : () -> ()432    scf.yield433  }434  return435}436 437// -----438 439// CHECK-LABEL: @remove_false_if440func.func @remove_false_if() {441  %false = arith.constant false442  // CHECK-NOT: scf.if443  // CHECK-NOT: "test.op"444  scf.if %false {445    "test.op"() : () -> ()446    scf.yield447  }448  return449}450 451// -----452 453// CHECK-LABEL: @replace_true_if_with_values454func.func @replace_true_if_with_values() {455  %true = arith.constant true456  // CHECK-NOT: scf.if457  // CHECK: %[[VAL:.*]] = "test.op"458  %0 = scf.if %true -> (i32) {459    %1 = "test.op"() : () -> i32460    scf.yield %1 : i32461  } else {462    %2 = "test.other_op"() : () -> i32463    scf.yield %2 : i32464  }465  // CHECK: "test.consume"(%[[VAL]])466  "test.consume"(%0) : (i32) -> ()467  return468}469 470// -----471 472// CHECK-LABEL: @replace_false_if_with_values473func.func @replace_false_if_with_values() {474  %false = arith.constant false475  // CHECK-NOT: scf.if476  // CHECK: %[[VAL:.*]] = "test.other_op"477  %0 = scf.if %false -> (i32) {478    %1 = "test.op"() : () -> i32479    scf.yield %1 : i32480  } else {481    %2 = "test.other_op"() : () -> i32482    scf.yield %2 : i32483  }484  // CHECK: "test.consume"(%[[VAL]])485  "test.consume"(%0) : (i32) -> ()486  return487}488 489// -----490 491// CHECK-LABEL: @merge_nested_if492// CHECK-SAME: (%[[ARG0:.*]]: i1, %[[ARG1:.*]]: i1)493func.func @merge_nested_if(%arg0: i1, %arg1: i1) {494// CHECK: %[[COND:.*]] = arith.andi %[[ARG0]], %[[ARG1]]495// CHECK: scf.if %[[COND]] {496// CHECK-NEXT: "test.op"()497  scf.if %arg0 {498    scf.if %arg1 {499      "test.op"() : () -> ()500      scf.yield501    }502    scf.yield503  }504  return505}506 507// -----508 509// CHECK-LABEL: @merge_yielding_nested_if510// CHECK-SAME: (%[[ARG0:.*]]: i1, %[[ARG1:.*]]: i1)511func.func @merge_yielding_nested_if(%arg0: i1, %arg1: i1) -> (i32, f32, i32, i8) {512// CHECK: %[[PRE0:.*]] = "test.op"() : () -> i32513// CHECK: %[[PRE1:.*]] = "test.op1"() : () -> f32514// CHECK: %[[PRE2:.*]] = "test.op2"() : () -> i32515// CHECK: %[[PRE3:.*]] = "test.op3"() : () -> i8516// CHECK: %[[COND:.*]] = arith.andi %[[ARG0]], %[[ARG1]]517// CHECK: %[[RES:.*]]:2 = scf.if %[[COND]] -> (f32, i32)518// CHECK:   %[[IN0:.*]] = "test.inop"() : () -> i32519// CHECK:   %[[IN1:.*]] = "test.inop1"() : () -> f32520// CHECK:   scf.yield %[[IN1]], %[[IN0]] : f32, i32521// CHECK: } else {522// CHECK:   scf.yield %[[PRE1]], %[[PRE2]] : f32, i32523// CHECK: }524// CHECK: return %[[PRE0]], %[[RES]]#0, %[[RES]]#1, %[[PRE3]] : i32, f32, i32, i8525  %0 = "test.op"() : () -> (i32)526  %1 = "test.op1"() : () -> (f32)527  %2 = "test.op2"() : () -> (i32)528  %3 = "test.op3"() : () -> (i8)529  %r:4 = scf.if %arg0 -> (i32, f32, i32, i8) {530    %a:2 = scf.if %arg1 -> (i32, f32) {531      %i = "test.inop"() : () -> (i32)532      %i1 = "test.inop1"() : () -> (f32)533      scf.yield %i, %i1 : i32, f32534    } else {535      scf.yield %2, %1 : i32, f32536    }537    scf.yield %0, %a#1, %a#0, %3 : i32, f32, i32, i8538  } else {539    scf.yield %0, %1, %2, %3 : i32, f32, i32, i8540  }541  return %r#0, %r#1, %r#2, %r#3 : i32, f32, i32, i8542}543 544// -----545 546// CHECK-LABEL: @merge_yielding_nested_if_nv1547// CHECK-SAME: (%[[ARG0:.*]]: i1, %[[ARG1:.*]]: i1)548func.func @merge_yielding_nested_if_nv1(%arg0: i1, %arg1: i1) {549// CHECK: %[[PRE0:.*]] = "test.op"() : () -> i32550// CHECK: %[[PRE1:.*]] = "test.op1"() : () -> f32551// CHECK: %[[COND:.*]] = arith.andi %[[ARG0]], %[[ARG1]]552// CHECK: scf.if %[[COND]]553// CHECK:   %[[IN0:.*]] = "test.inop"() : () -> i32554// CHECK:   %[[IN1:.*]] = "test.inop1"() : () -> f32555// CHECK: }556  %0 = "test.op"() : () -> (i32)557  %1 = "test.op1"() : () -> (f32)558  scf.if %arg0 {559    %a:2 = scf.if %arg1 -> (i32, f32) {560      %i = "test.inop"() : () -> (i32)561      %i1 = "test.inop1"() : () -> (f32)562      scf.yield %i, %i1 : i32, f32563    } else {564      scf.yield %0, %1 : i32, f32565    }566  }567  return568}569 570// -----571 572// CHECK-LABEL: @merge_yielding_nested_if_nv2573// CHECK-SAME: (%[[ARG0:.*]]: i1, %[[ARG1:.*]]: i1)574func.func @merge_yielding_nested_if_nv2(%arg0: i1, %arg1: i1) -> i32 {575// CHECK: %[[PRE0:.*]] = "test.op"() : () -> i32576// CHECK: %[[PRE1:.*]] = "test.op1"() : () -> i32577// CHECK: %[[COND:.*]] = arith.andi %[[ARG0]], %[[ARG1]]578// CHECK: %[[RES:.*]] = arith.select %[[ARG0]], %[[PRE0]], %[[PRE1]]579// CHECK: scf.if %[[COND]]580// CHECK:   "test.run"() : () -> ()581// CHECK: }582// CHECK: return %[[RES]]583  %0 = "test.op"() : () -> (i32)584  %1 = "test.op1"() : () -> (i32)585  %r = scf.if %arg0 -> i32 {586    scf.if %arg1 {587      "test.run"() : () -> ()588    }589    scf.yield %0 : i32590  } else {591    scf.yield %1 : i32592  }593  return %r : i32594}595 596// -----597 598// CHECK-LABEL: @merge_fail_yielding_nested_if599// CHECK-SAME: (%[[ARG0:.*]]: i1, %[[ARG1:.*]]: i1)600func.func @merge_fail_yielding_nested_if(%arg0: i1, %arg1: i1) -> (i32, f32, i32, i8) {601// CHECK-NOT: andi602  %0 = "test.op"() : () -> (i32)603  %1 = "test.op1"() : () -> (f32)604  %2 = "test.op2"() : () -> (i32)605  %3 = "test.op3"() : () -> (i8)606  %r:4 = scf.if %arg0 -> (i32, f32, i32, i8) {607    %a:2 = scf.if %arg1 -> (i32, f32) {608      %i = "test.inop"() : () -> (i32)609      %i1 = "test.inop1"() : () -> (f32)610      scf.yield %i, %i1 : i32, f32611    } else {612      scf.yield %0, %1 : i32, f32613    }614    scf.yield %0, %a#1, %a#0, %3 : i32, f32, i32, i8615  } else {616    scf.yield %0, %1, %2, %3 : i32, f32, i32, i8617  }618  return %r#0, %r#1, %r#2, %r#3 : i32, f32, i32, i8619}620 621// -----622 623// CHECK-LABEL:   func @if_condition_swap624// CHECK-NEXT:     %{{.*}} = scf.if %arg0 -> (index) {625// CHECK-NEXT:       %[[i1:.+]] = "test.origFalse"() : () -> index626// CHECK-NEXT:       scf.yield %[[i1]] : index627// CHECK-NEXT:     } else {628// CHECK-NEXT:       %[[i2:.+]] = "test.origTrue"() : () -> index629// CHECK-NEXT:       scf.yield %[[i2]] : index630// CHECK-NEXT:     }631func.func @if_condition_swap(%cond: i1) -> index {632  %true = arith.constant true633  %not = arith.xori %cond, %true : i1634  %0 = scf.if %not -> (index) {635    %1 = "test.origTrue"() : () -> index636    scf.yield %1 : index637  } else {638    %1 = "test.origFalse"() : () -> index639    scf.yield %1 : index640  }641  return %0 : index642}643 644// -----645 646// CHECK-LABEL: @remove_zero_iteration_loop647func.func @remove_zero_iteration_loop() {648  %c42 = arith.constant 42 : index649  %c1 = arith.constant 1 : index650  // CHECK: %[[INIT:.*]] = "test.init"651  %init = "test.init"() : () -> i32652  // CHECK-NOT: scf.for653  %0 = scf.for %i = %c42 to %c1 step %c1 iter_args(%arg = %init) -> (i32) {654    %1 = "test.op"(%i, %arg) : (index, i32) -> i32655    scf.yield %1 : i32656  }657  // CHECK: "test.consume"(%[[INIT]])658  "test.consume"(%0) : (i32) -> ()659  return660}661 662// -----663 664// CHECK-LABEL: @remove_zero_iteration_loop_vals665func.func @remove_zero_iteration_loop_vals(%arg0: index) {666  %c2 = arith.constant 2 : index667  // CHECK: %[[INIT:.*]] = "test.init"668  %init = "test.init"() : () -> i32669  // CHECK-NOT: scf.for670  // CHECK-NOT: test.op671  %0 = scf.for %i = %arg0 to %arg0 step %c2 iter_args(%arg = %init) -> (i32) {672    %1 = "test.op"(%i, %arg) : (index, i32) -> i32673    scf.yield %1 : i32674  }675  // CHECK: "test.consume"(%[[INIT]])676  "test.consume"(%0) : (i32) -> ()677  return678}679 680// -----681 682// CHECK-LABEL: @replace_single_iteration_loop_1683func.func @replace_single_iteration_loop_1() {684  // CHECK: %[[LB:.*]] = arith.constant 42685  %c42 = arith.constant 42 : index686  %c43 = arith.constant 43 : index687  %c1 = arith.constant 1 : index688  // CHECK: %[[INIT:.*]] = "test.init"689  %init = "test.init"() : () -> i32690  // CHECK-NOT: scf.for691  // CHECK: %[[VAL:.*]] = "test.op"(%[[LB]], %[[INIT]])692  %0 = scf.for %i = %c42 to %c43 step %c1 iter_args(%arg = %init) -> (i32) {693    %1 = "test.op"(%i, %arg) : (index, i32) -> i32694    scf.yield %1 : i32695  }696  // CHECK: "test.consume"(%[[VAL]])697  "test.consume"(%0) : (i32) -> ()698  return699}700 701// -----702 703// CHECK-LABEL: @replace_single_iteration_loop_2704func.func @replace_single_iteration_loop_2() {705  // CHECK: %[[LB:.*]] = arith.constant 5706  %c5 = arith.constant 5 : index707  %c6 = arith.constant 6 : index708  %c11 = arith.constant 11 : index709  // CHECK: %[[INIT:.*]] = "test.init"710  %init = "test.init"() : () -> i32711  // CHECK-NOT: scf.for712  // CHECK: %[[VAL:.*]] = "test.op"(%[[LB]], %[[INIT]])713  %0 = scf.for %i = %c5 to %c11 step %c6 iter_args(%arg = %init) -> (i32) {714    %1 = "test.op"(%i, %arg) : (index, i32) -> i32715    scf.yield %1 : i32716  }717  // CHECK: "test.consume"(%[[VAL]])718  "test.consume"(%0) : (i32) -> ()719  return720}721 722// -----723 724// CHECK-LABEL: @replace_single_iteration_loop_non_unit_step725func.func @replace_single_iteration_loop_non_unit_step() {726  // CHECK: %[[LB:.*]] = arith.constant 42727  %c42 = arith.constant 42 : index728  %c47 = arith.constant 47 : index729  %c5 = arith.constant 5 : index730  // CHECK: %[[INIT:.*]] = "test.init"731  %init = "test.init"() : () -> i32732  // CHECK-NOT: scf.for733  // CHECK: %[[VAL:.*]] = "test.op"(%[[LB]], %[[INIT]])734  %0 = scf.for %i = %c42 to %c47 step %c5 iter_args(%arg = %init) -> (i32) {735    %1 = "test.op"(%i, %arg) : (index, i32) -> i32736    scf.yield %1 : i32737  }738  // CHECK: "test.consume"(%[[VAL]])739  "test.consume"(%0) : (i32) -> ()740  return741}742 743 744// -----745 746// CHECK-LABEL: func @replace_single_iteration_const_diff(747//  CHECK-SAME: %[[A0:.*]]: index)748func.func @replace_single_iteration_const_diff(%arg0 : index) {749  // CHECK-NEXT: %[[CST:.*]] = arith.constant 2750  %c1 = arith.constant 1 : index751  %c2 = arith.constant 2 : index752  %5 = arith.addi %arg0, %c1 overflow<nsw> : index753  // CHECK-NOT: scf.for754  scf.for %arg2 = %arg0 to %5 step %c1 {755    // CHECK-NEXT: %[[MUL:.*]] = arith.muli %[[A0]], %[[CST]]756    %7 = arith.muli %c2, %arg2 : index757    // CHECK-NEXT: "test.consume"(%[[MUL]])758    "test.consume"(%7) : (index) -> ()759  }760  return761}762 763// -----764 765// CHECK-LABEL: @remove_empty_parallel_loop766func.func @remove_empty_parallel_loop(%lb: index, %ub: index, %s: index) {767  // CHECK: %[[INIT:.*]] = "test.init"768  %init = "test.init"() : () -> f32769  // CHECK-NOT: scf.parallel770  // CHECK-NOT: test.produce771  // CHECK-NOT: test.transform772  %0 = scf.parallel (%i, %j, %k) = (%lb, %ub, %lb) to (%ub, %ub, %ub) step (%s, %s, %s) init(%init) -> f32 {773    %1 = "test.produce"() : () -> f32774    scf.reduce(%1 : f32) {775    ^bb0(%lhs: f32, %rhs: f32):776      %2 = "test.transform"(%lhs, %rhs) : (f32, f32) -> f32777      scf.reduce.return %2 : f32778    }779  }780  // CHECK: "test.consume"(%[[INIT]])781  "test.consume"(%0) : (f32) -> ()782  return783}784 785// -----786 787// CHECK-LABEL: fold_away_iter_with_no_use_and_yielded_input788//  CHECK-SAME:   %[[A0:[0-9a-z]*]]: i32789func.func @fold_away_iter_with_no_use_and_yielded_input(%arg0 : i32,790                    %ub : index, %lb : index, %step : index) -> (i32, i32) {791  // CHECK-NEXT: %[[C32:.*]] = arith.constant 32 : i32792  %cst = arith.constant 32 : i32793  // CHECK-NEXT: %[[FOR_RES:.*]] = scf.for {{.*}} iter_args({{.*}} = %[[A0]]) -> (i32) {794  %0:2 = scf.for %arg1 = %lb to %ub step %step iter_args(%arg2 = %arg0, %arg3 = %cst)795    -> (i32, i32) {796    %1 = arith.addi %arg2, %cst : i32797    scf.yield %1, %cst : i32, i32798  }799 800  // CHECK: return %[[FOR_RES]], %[[C32]] : i32, i32801  return %0#0, %0#1 : i32, i32802}803 804// -----805 806// CHECK-LABEL: fold_away_iter_and_result_with_no_use807//  CHECK-SAME:   %[[A0:[0-9a-z]*]]: i32808func.func @fold_away_iter_and_result_with_no_use(%arg0 : i32,809                    %ub : index, %lb : index, %step : index) -> (i32) {810  %cst = arith.constant 32 : i32811  // CHECK: %[[FOR_RES:.*]] = scf.for {{.*}} iter_args({{.*}} = %[[A0]]) -> (i32) {812  %0:2 = scf.for %arg1 = %lb to %ub step %step iter_args(%arg2 = %arg0, %arg3 = %cst)813    -> (i32, i32) {814    %1 = arith.addi %arg2, %cst : i32815    scf.yield %1, %1 : i32, i32816  }817 818  // CHECK: return %[[FOR_RES]] : i32819  return %0#0 : i32820}821 822// -----823 824// CHECK-LABEL: @replace_duplicate_iter_args825// CHECK-SAME: [[LB:%arg[0-9]]]: index, [[UB:%arg[0-9]]]: index, [[STEP:%arg[0-9]]]: index, [[A:%arg[0-9]]]: index, [[B:%arg[0-9]]]: index826func.func @replace_duplicate_iter_args(%lb: index, %ub: index, %step: index, %a: index, %b: index) -> (index, index, index, index) {827  // CHECK-NEXT: [[RES:%.*]]:2 = scf.for {{.*}} iter_args([[K0:%.*]] = [[A]], [[K1:%.*]] = [[B]])828  %0:4 = scf.for %i = %lb to %ub step %step iter_args(%k0 = %a, %k1 = %b, %k2 = %b, %k3 = %a) -> (index, index, index, index) {829    // CHECK-NEXT: [[V0:%.*]] = arith.addi [[K0]], [[K1]]830    %1 = arith.addi %k0, %k1 : index831    // CHECK-NEXT: [[V1:%.*]] = arith.addi [[K1]], [[K0]]832    %2 = arith.addi %k2, %k3 : index833    // CHECK-NEXT: yield [[V0]], [[V1]]834    scf.yield %1, %2, %2, %1 : index, index, index, index835  }836  // CHECK: return [[RES]]#0, [[RES]]#1, [[RES]]#1, [[RES]]#0837  return %0#0, %0#1, %0#2, %0#3 : index, index, index, index838}839 840// -----841 842func.func private @do(%arg0: tensor<?x?xf32>) -> tensor<?x?xf32>843 844func.func @matmul_on_tensors(%t0: tensor<32x1024xf32>) -> tensor<?x?xf32> {845  %c0 = arith.constant 0 : index846  %c32 = arith.constant 32 : index847  %c1024 = arith.constant 1024 : index848  %0 = tensor.cast %t0 : tensor<32x1024xf32> to tensor<?x?xf32>849  %1 = scf.for %i = %c0 to %c1024 step %c32 iter_args(%iter_t0 = %0) -> (tensor<?x?xf32>) {850    %2 = func.call @do(%iter_t0) : (tensor<?x?xf32>) -> tensor<?x?xf32>851    scf.yield %2 : tensor<?x?xf32>852  } {some_attr}853  return %1 : tensor<?x?xf32>854}855// CHECK-LABEL: matmul_on_tensors856//  CHECK-SAME:   %[[T0:[0-9a-z]*]]: tensor<32x1024xf32>857 858//   CHECK-NOT: tensor.cast859//       CHECK: %[[FOR_RES:.*]] = scf.for {{.*}} iter_args(%[[ITER_T0:.*]] = %[[T0]]) -> (tensor<32x1024xf32>) {860//       CHECK:   %[[CAST:.*]] = tensor.cast %[[ITER_T0]] : tensor<32x1024xf32> to tensor<?x?xf32>861//       CHECK:   %[[DONE:.*]] = func.call @do(%[[CAST]]) : (tensor<?x?xf32>) -> tensor<?x?xf32>862//       CHECK:   %[[UNCAST:.*]] = tensor.cast %[[DONE]] : tensor<?x?xf32> to tensor<32x1024xf32>863//       CHECK:   scf.yield %[[UNCAST]] : tensor<32x1024xf32>864//       CHECK: } {some_attr}865//       CHECK: %[[RES:.*]] = tensor.cast866//       CHECK: return %[[RES]] : tensor<?x?xf32>867 868// -----869 870// CHECK-LABEL: @cond_prop871func.func @cond_prop(%arg0 : i1) -> index {872  %res = scf.if %arg0 -> index {873    %res1 = scf.if %arg0 -> index {874      %v1 = "test.get_some_value1"() : () -> index875      scf.yield %v1 : index876    } else {877      %v2 = "test.get_some_value2"() : () -> index878      scf.yield %v2 : index879    }880    scf.yield %res1 : index881  } else {882    %res2 = scf.if %arg0 -> index {883      %v3 = "test.get_some_value3"() : () -> index884      scf.yield %v3 : index885    } else {886      %v4 = "test.get_some_value4"() : () -> index887      scf.yield %v4 : index888    }889    scf.yield %res2 : index890  }891  return %res : index892}893// CHECK-NEXT:  %[[if:.+]] = scf.if %arg0 -> (index) {894// CHECK-NEXT:    %[[c1:.+]] = "test.get_some_value1"() : () -> index895// CHECK-NEXT:    scf.yield %[[c1]] : index896// CHECK-NEXT:  } else {897// CHECK-NEXT:    %[[c4:.+]] = "test.get_some_value4"() : () -> index898// CHECK-NEXT:    scf.yield %[[c4]] : index899// CHECK-NEXT:  }900// CHECK-NEXT:  return %[[if]] : index901// CHECK-NEXT:}902 903// -----904 905// CHECK-LABEL: @replace_if_with_cond1906func.func @replace_if_with_cond1(%arg0 : i1) -> (i32, i1) {907  %true = arith.constant true908  %false = arith.constant false909  %res:2 = scf.if %arg0 -> (i32, i1) {910    %v = "test.get_some_value"() : () -> i32911    scf.yield %v, %true : i32, i1912  } else {913    %v2 = "test.get_some_value"() : () -> i32914    scf.yield %v2, %false : i32, i1915  }916  return %res#0, %res#1 : i32, i1917}918// CHECK-NEXT:    %[[if:.+]] = scf.if %arg0 -> (i32) {919// CHECK-NEXT:      %[[sv1:.+]] = "test.get_some_value"() : () -> i32920// CHECK-NEXT:      scf.yield %[[sv1]] : i32921// CHECK-NEXT:    } else {922// CHECK-NEXT:      %[[sv2:.+]] = "test.get_some_value"() : () -> i32923// CHECK-NEXT:      scf.yield %[[sv2]] : i32924// CHECK-NEXT:    }925// CHECK-NEXT:    return %[[if]], %arg0 : i32, i1926 927// -----928 929// CHECK-LABEL: @replace_if_with_cond2930func.func @replace_if_with_cond2(%arg0 : i1) -> (i32, i1) {931  %true = arith.constant true932  %false = arith.constant false933  %res:2 = scf.if %arg0 -> (i32, i1) {934    %v = "test.get_some_value"() : () -> i32935    scf.yield %v, %false : i32, i1936  } else {937    %v2 = "test.get_some_value"() : () -> i32938    scf.yield %v2, %true : i32, i1939  }940  return %res#0, %res#1 : i32, i1941}942// CHECK-NEXT:     %true = arith.constant true943// CHECK-NEXT:     %[[toret:.+]] = arith.xori %arg0, %true : i1944// CHECK-NEXT:     %[[if:.+]] = scf.if %arg0 -> (i32) {945// CHECK-NEXT:       %[[sv1:.+]] = "test.get_some_value"() : () -> i32946// CHECK-NEXT:       scf.yield %[[sv1]] : i32947// CHECK-NEXT:     } else {948// CHECK-NEXT:       %[[sv2:.+]] = "test.get_some_value"() : () -> i32949// CHECK-NEXT:       scf.yield %[[sv2]] : i32950// CHECK-NEXT:     }951// CHECK-NEXT:     return %[[if]], %[[toret]] : i32, i1952 953// -----954 955// CHECK-LABEL: @replace_if_with_cond3956func.func @replace_if_with_cond3(%arg0 : i1, %arg2: i64) -> (i32, i64) {957  %res:2 = scf.if %arg0 -> (i32, i64) {958    %v = "test.get_some_value"() : () -> i32959    scf.yield %v, %arg2 : i32, i64960  } else {961    %v2 = "test.get_some_value"() : () -> i32962    scf.yield %v2, %arg2 : i32, i64963  }964  return %res#0, %res#1 : i32, i64965}966// CHECK-NEXT:     %[[if:.+]] = scf.if %arg0 -> (i32) {967// CHECK-NEXT:       %[[sv1:.+]] = "test.get_some_value"() : () -> i32968// CHECK-NEXT:       scf.yield %[[sv1]] : i32969// CHECK-NEXT:     } else {970// CHECK-NEXT:       %[[sv2:.+]] = "test.get_some_value"() : () -> i32971// CHECK-NEXT:       scf.yield %[[sv2]] : i32972// CHECK-NEXT:     }973// CHECK-NEXT:     return %[[if]], %arg1 : i32, i64974 975// -----976 977// CHECK-LABEL: @while_move_if_down978func.func @while_move_if_down() -> i32 {979  %defined_outside = "test.get_some_value0" () : () -> (i32)980  %0 = scf.while () : () -> (i32) {981    %used_value = "test.get_some_value1" () : () -> (i32)982    %used_by_subregion = "test.get_some_value2" () : () -> (i32)983    %else_value = "test.get_some_value3" () : () -> (i32)984    %condition = "test.condition"() : () -> i1985    %res = scf.if %condition -> (i32) {986      "test.use0" (%defined_outside) : (i32) -> ()987      "test.use1" (%used_value) : (i32) -> ()988      test.alloca_scope_region {989        "test.use2" (%used_by_subregion) : (i32) -> ()990      }991      %then_value = "test.get_some_value4" () : () -> (i32)992      scf.yield %then_value : i32993    } else {994      scf.yield %else_value : i32995    }996    scf.condition(%condition) %res : i32997  } do {998  ^bb0(%res_arg: i32):999    "test.use3" (%res_arg) : (i32) -> ()1000    scf.yield1001  }1002  return %0 : i321003}1004// CHECK:           %[[defined_outside:.*]] = "test.get_some_value0"() : () -> i321005// CHECK:           %[[WHILE_RES:.*]]:3 = scf.while : () -> (i32, i32, i32) {1006// CHECK:             %[[used_value:.*]] = "test.get_some_value1"() : () -> i321007// CHECK:             %[[used_by_subregion:.*]] = "test.get_some_value2"() : () -> i321008// CHECK:             %[[else_value:.*]] = "test.get_some_value3"() : () -> i321009// CHECK:             %[[condition:.*]] = "test.condition"() : () -> i11010// CHECK:             scf.condition(%[[condition]]) %[[else_value]], %[[used_value]], %[[used_by_subregion]] : i32, i32, i321011// CHECK:           } do {1012// CHECK:           ^bb0(%[[res_arg:.*]]: i32, %[[used_value_arg:.*]]: i32, %[[used_by_subregion_arg:.*]]: i32):1013// CHECK:             "test.use0"(%[[defined_outside]]) : (i32) -> ()1014// CHECK:             "test.use1"(%[[used_value_arg]]) : (i32) -> ()1015// CHECK:             test.alloca_scope_region {1016// CHECK:               "test.use2"(%[[used_by_subregion_arg]]) : (i32) -> ()1017// CHECK:             }1018// CHECK:             %[[then_value:.*]] = "test.get_some_value4"() : () -> i321019// CHECK:             "test.use3"(%[[then_value]]) : (i32) -> ()1020// CHECK:             scf.yield1021// CHECK:           }1022// CHECK:           return %[[WHILE_RES]]#0 : i321023// CHECK:         }1024 1025// -----1026 1027// CHECK-LABEL: @while_cond_true1028func.func @while_cond_true() -> i1 {1029  %0 = scf.while () : () -> i1 {1030    %condition = "test.condition"() : () -> i11031    scf.condition(%condition) %condition : i11032  } do {1033  ^bb0(%arg0: i1):1034    "test.use"(%arg0) : (i1) -> ()1035    scf.yield1036  }1037  return %0 : i11038}1039// CHECK-NEXT:         %[[true:.+]] = arith.constant true1040// CHECK-NEXT:         %{{.+}} = scf.while : () -> i1 {1041// CHECK-NEXT:           %[[cmp:.+]] = "test.condition"() : () -> i11042// CHECK-NEXT:           scf.condition(%[[cmp]]) %[[cmp]] : i11043// CHECK-NEXT:         } do {1044// CHECK-NEXT:         ^bb0(%arg0: i1):1045// CHECK-NEXT:           "test.use"(%[[true]]) : (i1) -> ()1046// CHECK-NEXT:           scf.yield1047// CHECK-NEXT:         }1048 1049// -----1050 1051// CHECK-LABEL: @invariant_loop_args_in_same_order1052// CHECK-SAME: (%[[FUNC_ARG0:.*]]: tensor<i32>)1053func.func @invariant_loop_args_in_same_order(%f_arg0: tensor<i32>) -> (tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>) {1054  %cst_0 = arith.constant dense<0> : tensor<i32>1055  %cst_1 = arith.constant dense<1> : tensor<i32>1056  %cst_42 = arith.constant dense<42> : tensor<i32>1057 1058  %0:5 = scf.while (%arg0 = %cst_0, %arg1 = %f_arg0, %arg2 = %cst_1, %arg3 = %cst_1, %arg4 = %cst_0) : (tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>) -> (tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>) {1059    %1 = arith.cmpi slt, %arg0, %cst_42 : tensor<i32>1060    %2 = tensor.extract %1[] : tensor<i1>1061    scf.condition(%2) %arg0, %arg1, %arg2, %arg3, %arg4 : tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>1062  } do {1063  ^bb0(%arg0: tensor<i32>, %arg1: tensor<i32>, %arg2: tensor<i32>, %arg3: tensor<i32>, %arg4: tensor<i32>): // no predecessors1064    // %arg1 here will get replaced by %cst_11065    %1 = arith.addi %arg0, %arg1 : tensor<i32>1066    %2 = arith.addi %arg2, %arg3 : tensor<i32>1067    scf.yield %1, %arg1, %2, %2, %arg4 : tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>1068  }1069  return %0#0, %0#1, %0#2, %0#3, %0#4 : tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>1070}1071// CHECK:    %[[ZERO:.*]] = arith.constant dense<0>1072// CHECK:    %[[ONE:.*]] = arith.constant dense<1>1073// CHECK:    %[[CST42:.*]] = arith.constant dense<42>1074// CHECK:    %[[WHILE:.*]]:3 = scf.while (%[[ARG0:.*]] = %[[ZERO]], %[[ARG2:.*]] = %[[ONE]], %[[ARG3:.*]] = %[[ONE]])1075// CHECK:       arith.cmpi slt, %[[ARG0]], %{{.*}}1076// CHECK:       tensor.extract %{{.*}}[]1077// CHECK:       scf.condition(%{{.*}}) %[[ARG0]], %[[ARG2]], %[[ARG3]]1078// CHECK:    } do {1079// CHECK:     ^{{.*}}(%[[ARG0:.*]]: tensor<i32>, %[[ARG2:.*]]: tensor<i32>, %[[ARG3:.*]]: tensor<i32>):1080// CHECK:       %[[VAL0:.*]] = arith.addi %[[ARG0]], %[[FUNC_ARG0]]1081// CHECK:       %[[VAL1:.*]] = arith.addi %[[ARG2]], %[[ARG3]]1082// CHECK:       scf.yield %[[VAL0]], %[[VAL1]], %[[VAL1]]1083// CHECK:    }1084// CHECK:    return %[[WHILE]]#0, %[[FUNC_ARG0]], %[[WHILE]]#1, %[[WHILE]]#2, %[[ZERO]]1085 1086// CHECK-LABEL: @while_loop_invariant_argument_different_order1087func.func @while_loop_invariant_argument_different_order(%arg : tensor<i32>) -> (tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>) {1088  %cst_0 = arith.constant dense<0> : tensor<i32>1089  %cst_1 = arith.constant dense<1> : tensor<i32>1090  %cst_42 = arith.constant dense<42> : tensor<i32>1091 1092  %0:6 = scf.while (%arg0 = %cst_0, %arg1 = %cst_1, %arg2 = %cst_1, %arg3 = %cst_1, %arg4 = %cst_0) : (tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>) -> (tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>) {1093    %1 = arith.cmpi slt, %arg0, %arg : tensor<i32>1094    %2 = tensor.extract %1[] : tensor<i1>1095    scf.condition(%2) %arg1, %arg0, %arg2, %arg0, %arg3, %arg4 : tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>1096  } do {1097  ^bb0(%arg0: tensor<i32>, %arg1: tensor<i32>, %arg2: tensor<i32>, %arg3: tensor<i32>, %arg4: tensor<i32>, %arg5: tensor<i32>): // no predecessors1098    %1 = arith.addi %arg0, %cst_1 : tensor<i32>1099    %2 = arith.addi %arg2, %arg3 : tensor<i32>1100    scf.yield %arg3, %arg1, %2, %2, %arg4 : tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>1101  }1102  return %0#0, %0#1, %0#2, %0#3, %0#4, %0#5 : tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>, tensor<i32>1103}1104// CHECK-SAME: (%[[ARG:.+]]: tensor<i32>)1105// CHECK:    %[[ZERO:.*]] = arith.constant dense<0>1106// CHECK:    %[[ONE:.*]] = arith.constant dense<1>1107// CHECK:    %[[WHILE:.*]]:2 = scf.while (%[[ARG1:.*]] = %[[ONE]], %[[ARG4:.*]] = %[[ZERO]])1108// CHECK:       arith.cmpi sgt, %[[ARG]], %[[ZERO]]1109// CHECK:       tensor.extract %{{.*}}[]1110// CHECK:       scf.condition(%{{.*}}) %[[ARG1]], %[[ARG4]]1111// CHECK:    } do {1112// CHECK:     ^{{.*}}(%{{.*}}: tensor<i32>, %{{.*}}: tensor<i32>):1113// CHECK:       scf.yield %[[ZERO]], %[[ONE]]1114// CHECK:    }1115// CHECK:    return %[[WHILE]]#0, %[[ZERO]], %[[ONE]], %[[ZERO]], %[[ONE]], %[[WHILE]]#11116 1117// -----1118 1119// CHECK-LABEL: @while_unused_result1120func.func @while_unused_result() -> i32 {1121  %0:2 = scf.while () : () -> (i32, i64) {1122    %condition = "test.condition"() : () -> i11123    %v1 = "test.get_some_value"() : () -> i321124    %v2 = "test.get_some_value"() : () -> i641125    scf.condition(%condition) %v1, %v2 : i32, i641126  } do {1127  ^bb0(%arg0: i32, %arg1: i64):1128    "test.use"(%arg0) : (i32) -> ()1129    scf.yield1130  }1131  return %0#0 : i321132}1133// CHECK-NEXT:         %[[res:.*]] = scf.while : () -> i32 {1134// CHECK-NEXT:           %[[cmp:.*]] = "test.condition"() : () -> i11135// CHECK-NEXT:           %[[val:.*]] = "test.get_some_value"() : () -> i321136// CHECK-NEXT:           %{{.*}} = "test.get_some_value"() : () -> i641137// CHECK-NEXT:           scf.condition(%[[cmp]]) %[[val]] : i321138// CHECK-NEXT:         } do {1139// CHECK-NEXT:         ^bb0(%[[arg:.*]]: i32):1140// CHECK-NEXT:           "test.use"(%[[arg]]) : (i32) -> ()1141// CHECK-NEXT:           scf.yield1142// CHECK-NEXT:         }1143// CHECK-NEXT:         return %[[res]] : i321144 1145// -----1146 1147// CHECK-LABEL: @while_cmp_lhs1148func.func @while_cmp_lhs(%arg0 : i32) {1149  %0 = scf.while () : () -> i32 {1150    %val = "test.val"() : () -> i321151    %condition = arith.cmpi ne, %val, %arg0 : i321152    scf.condition(%condition) %val : i321153  } do {1154  ^bb0(%val2: i32):1155    %condition2 = arith.cmpi ne, %val2, %arg0 : i321156    %negcondition2 = arith.cmpi eq, %val2, %arg0 : i321157    "test.use"(%condition2, %negcondition2, %val2) : (i1, i1, i32) -> ()1158    scf.yield1159  }1160  return1161}1162// CHECK-DAG:         %[[true:.+]] = arith.constant true1163// CHECK-DAG:         %[[false:.+]] = arith.constant false1164// CHECK-DAG:         %{{.+}} = scf.while : () -> i32 {1165// CHECK-NEXT:         %[[val:.+]] = "test.val"1166// CHECK-NEXT:         %[[cmp:.+]] = arith.cmpi ne, %[[val]], %arg0 : i321167// CHECK-NEXT:           scf.condition(%[[cmp]]) %[[val]] : i321168// CHECK-NEXT:         } do {1169// CHECK-NEXT:         ^bb0(%arg1: i32):1170// CHECK-NEXT:           "test.use"(%[[true]], %[[false]], %arg1) : (i1, i1, i32) -> ()1171// CHECK-NEXT:           scf.yield1172// CHECK-NEXT:         }1173 1174// -----1175 1176// CHECK-LABEL: @while_cmp_rhs1177func.func @while_cmp_rhs(%arg0 : i32) {1178  %0 = scf.while () : () -> i32 {1179    %val = "test.val"() : () -> i321180    %condition = arith.cmpi ne, %arg0, %val : i321181    scf.condition(%condition) %val : i321182  } do {1183  ^bb0(%val2: i32):1184    %condition2 = arith.cmpi ne, %arg0, %val2 : i321185    %negcondition2 = arith.cmpi eq, %arg0, %val2 : i321186    "test.use"(%condition2, %negcondition2, %val2) : (i1, i1, i32) -> ()1187    scf.yield1188  }1189  return1190}1191// CHECK-DAG:         %[[true:.+]] = arith.constant true1192// CHECK-DAG:         %[[false:.+]] = arith.constant false1193// CHECK-DAG:         %{{.+}} = scf.while : () -> i32 {1194// CHECK-NEXT:         %[[val:.+]] = "test.val"1195// CHECK-NEXT:         %[[cmp:.+]] = arith.cmpi ne, %arg0, %[[val]] : i321196// CHECK-NEXT:           scf.condition(%[[cmp]]) %[[val]] : i321197// CHECK-NEXT:         } do {1198// CHECK-NEXT:         ^bb0(%arg1: i32):1199// CHECK-NEXT:           "test.use"(%[[true]], %[[false]], %arg1) : (i1, i1, i32) -> ()1200// CHECK-NEXT:           scf.yield1201// CHECK-NEXT:         }1202 1203// -----1204 1205// CHECK-LABEL: @while_duplicated_res1206func.func @while_duplicated_res() -> (i32, i32) {1207  %0:2 = scf.while () : () -> (i32, i32) {1208    %val = "test.val"() : () -> i321209    %condition = "test.condition"() : () -> i11210    scf.condition(%condition) %val, %val : i32, i321211  } do {1212  ^bb0(%val2: i32, %val3: i32):1213    "test.use"(%val2, %val3) : (i32, i32) -> ()1214    scf.yield1215  }1216  return %0#0, %0#1: i32, i321217}1218// CHECK:         %[[RES:.*]] = scf.while : () -> i32 {1219// CHECK:         %[[VAL:.*]] = "test.val"() : () -> i321220// CHECK:         %[[COND:.*]] = "test.condition"() : () -> i11221// CHECK:           scf.condition(%[[COND]]) %[[VAL]] : i321222// CHECK:         } do {1223// CHECK:         ^bb0(%[[ARG:.*]]: i32):1224// CHECK:           "test.use"(%[[ARG]], %[[ARG]]) : (i32, i32) -> ()1225// CHECK:           scf.yield1226// CHECK:         }1227// CHECK:         return %[[RES]], %[[RES]] : i32, i321228 1229 1230// -----1231 1232// CHECK-LABEL: @while_unused_arg11233func.func @while_unused_arg1(%x : i32, %y : f64) -> i32 {1234  %0 = scf.while (%arg1 = %x, %arg2 = %y) : (i32, f64) -> (i32) {1235    %condition = "test.condition"(%arg1) : (i32) -> i11236    scf.condition(%condition) %arg1 : i321237  } do {1238  ^bb0(%arg1: i32):1239    %next = "test.use"(%arg1) : (i32) -> (i32)1240    scf.yield %next, %y : i32, f641241  }1242  return %0 : i321243}1244// CHECK-NEXT:         %[[res:.*]] = scf.while (%[[arg2:.*]] = %{{.*}}) : (i32) -> i32 {1245// CHECK-NEXT:           %[[cmp:.*]] = "test.condition"(%[[arg2]]) : (i32) -> i11246// CHECK-NEXT:           scf.condition(%[[cmp]]) %[[arg2]] : i321247// CHECK-NEXT:         } do {1248// CHECK-NEXT:         ^bb0(%[[post:.*]]: i32):1249// CHECK-NEXT:           %[[next:.*]] = "test.use"(%[[post]]) : (i32) -> i321250// CHECK-NEXT:           scf.yield %[[next]] : i321251// CHECK-NEXT:         }1252// CHECK-NEXT:         return %[[res]] : i321253 1254 1255// -----1256 1257// CHECK-LABEL: @while_unused_arg21258func.func @while_unused_arg2(%val0: i32) -> i32 {1259  %0 = scf.while (%val1 = %val0) : (i32) -> i32 {1260    %val = "test.val"() : () -> i321261    %condition = "test.condition"() : () -> i11262    scf.condition(%condition) %val: i321263  } do {1264  ^bb0(%val2: i32):1265    "test.use"(%val2) : (i32) -> ()1266    %val1 = "test.val1"() : () -> i321267    scf.yield %val1 : i321268  }1269  return %0 : i321270}1271// CHECK:         %[[RES:.*]] = scf.while : () -> i32 {1272// CHECK:         %[[VAL:.*]] = "test.val"() : () -> i321273// CHECK:         %[[COND:.*]] = "test.condition"() : () -> i11274// CHECK:           scf.condition(%[[COND]]) %[[VAL]] : i321275// CHECK:         } do {1276// CHECK:         ^bb0(%[[ARG:.*]]: i32):1277// CHECK:           "test.use"(%[[ARG]]) : (i32) -> ()1278// CHECK:           scf.yield1279// CHECK:         }1280// CHECK:         return %[[RES]] : i321281 1282 1283// -----1284 1285// CHECK-LABEL: func @test_align_args1286//       CHECK:  %[[RES:.*]]:3 = scf.while (%[[ARG0:.*]] = %{{.*}}, %[[ARG1:.*]] = %{{.*}}, %[[ARG2:.*]] = %{{.*}}) : (f32, i32, i64) -> (f32, i32, i64) {1287//       CHECK:  scf.condition(%{{.*}}) %[[ARG0]], %[[ARG1]], %[[ARG2]] : f32, i32, i641288//       CHECK:  ^bb0(%[[ARG3:.*]]: f32, %[[ARG4:.*]]: i32, %[[ARG5:.*]]: i64):1289//       CHECK:  %[[R1:.*]] = "test.test"(%[[ARG5]]) : (i64) -> f321290//       CHECK:  %[[R2:.*]] = "test.test"(%[[ARG3]]) : (f32) -> i321291//       CHECK:  %[[R3:.*]] = "test.test"(%[[ARG4]]) : (i32) -> i641292//       CHECK:  scf.yield %[[R1]], %[[R2]], %[[R3]] : f32, i32, i641293//       CHECK:  return %[[RES]]#2, %[[RES]]#0, %[[RES]]#11294func.func @test_align_args() -> (i64, f32, i32) {1295  %0 = "test.test"() : () -> (f32)1296  %1 = "test.test"() : () -> (i32)1297  %2 = "test.test"() : () -> (i64)1298  %3:3 = scf.while (%arg0 = %0, %arg1 = %1, %arg2 = %2) : (f32, i32, i64) -> (i64, f32, i32) {1299    %cond = "test.test"() : () -> (i1)1300    scf.condition(%cond) %arg2, %arg0, %arg1 : i64, f32, i321301  } do {1302  ^bb0(%arg3: i64, %arg4: f32, %arg5: i32):1303    %4 = "test.test"(%arg3) : (i64) -> (f32)1304    %5 = "test.test"(%arg4) : (f32) -> (i32)1305    %6 = "test.test"(%arg5) : (i32) -> (i64)1306    scf.yield %4, %5, %6 : f32, i32, i641307  }1308  return %3#0, %3#1, %3#2 : i64, f32, i321309}1310 1311 1312// -----1313 1314// CHECK-LABEL: @combineIfs1315func.func @combineIfs(%arg0 : i1, %arg2: i64) -> (i32, i32) {1316  %res = scf.if %arg0 -> i32 {1317    %v = "test.firstCodeTrue"() : () -> i321318    scf.yield %v : i321319  } else {1320    %v2 = "test.firstCodeFalse"() : () -> i321321    scf.yield %v2 : i321322  }1323  %res2 = scf.if %arg0 -> i32 {1324    %v = "test.secondCodeTrue"() : () -> i321325    scf.yield %v : i321326  } else {1327    %v2 = "test.secondCodeFalse"() : () -> i321328    scf.yield %v2 : i321329  }1330  return %res, %res2 : i32, i321331}1332// CHECK-NEXT:     %[[res:.+]]:2 = scf.if %arg0 -> (i32, i32) {1333// CHECK-NEXT:       %[[tval0:.+]] = "test.firstCodeTrue"() : () -> i321334// CHECK-NEXT:       %[[tval:.+]] = "test.secondCodeTrue"() : () -> i321335// CHECK-NEXT:       scf.yield %[[tval0]], %[[tval]] : i32, i321336// CHECK-NEXT:     } else {1337// CHECK-NEXT:       %[[fval0:.+]] = "test.firstCodeFalse"() : () -> i321338// CHECK-NEXT:       %[[fval:.+]] = "test.secondCodeFalse"() : () -> i321339// CHECK-NEXT:       scf.yield %[[fval0]], %[[fval]] : i32, i321340// CHECK-NEXT:     }1341// CHECK-NEXT:     return %[[res]]#0, %[[res]]#1 : i32, i321342 1343// -----1344 1345// CHECK-LABEL: @combineIfs21346func.func @combineIfs2(%arg0 : i1, %arg2: i64) -> i32 {1347  scf.if %arg0 {1348    "test.firstCodeTrue"() : () -> ()1349    scf.yield1350  }1351  %res = scf.if %arg0 -> i32 {1352    %v = "test.secondCodeTrue"() : () -> i321353    scf.yield %v : i321354  } else {1355    %v2 = "test.secondCodeFalse"() : () -> i321356    scf.yield %v2 : i321357  }1358  return %res : i321359}1360// CHECK-NEXT:     %[[res:.+]] = scf.if %arg0 -> (i32) {1361// CHECK-NEXT:       "test.firstCodeTrue"() : () -> ()1362// CHECK-NEXT:       %[[tval:.+]] = "test.secondCodeTrue"() : () -> i321363// CHECK-NEXT:       scf.yield %[[tval]] : i321364// CHECK-NEXT:     } else {1365// CHECK-NEXT:       %[[fval:.+]] = "test.secondCodeFalse"() : () -> i321366// CHECK-NEXT:       scf.yield %[[fval]] : i321367// CHECK-NEXT:     }1368// CHECK-NEXT:     return %[[res]] : i321369 1370// -----1371 1372// CHECK-LABEL: @combineIfs31373func.func @combineIfs3(%arg0 : i1, %arg2: i64) -> i32 {1374  %res = scf.if %arg0 -> i32 {1375    %v = "test.firstCodeTrue"() : () -> i321376    scf.yield %v : i321377  } else {1378    %v2 = "test.firstCodeFalse"() : () -> i321379    scf.yield %v2 : i321380  }1381  scf.if %arg0 {1382    "test.secondCodeTrue"() : () -> ()1383    scf.yield1384  }1385  return %res : i321386}1387// CHECK-NEXT:     %[[res:.+]] = scf.if %arg0 -> (i32) {1388// CHECK-NEXT:       %[[tval:.+]] = "test.firstCodeTrue"() : () -> i321389// CHECK-NEXT:       "test.secondCodeTrue"() : () -> ()1390// CHECK-NEXT:       scf.yield %[[tval]] : i321391// CHECK-NEXT:     } else {1392// CHECK-NEXT:       %[[fval:.+]] = "test.firstCodeFalse"() : () -> i321393// CHECK-NEXT:       scf.yield %[[fval]] : i321394// CHECK-NEXT:     }1395// CHECK-NEXT:     return %[[res]] : i321396 1397// -----1398 1399// CHECK-LABEL: @combineIfs41400func.func @combineIfs4(%arg0 : i1, %arg2: i64) {1401  scf.if %arg0 {1402    "test.firstCodeTrue"() : () -> ()1403    scf.yield1404  }1405  scf.if %arg0 {1406    "test.secondCodeTrue"() : () -> ()1407    scf.yield1408  }1409  return1410}1411 1412// CHECK-NEXT:     scf.if %arg0 {1413// CHECK-NEXT:       "test.firstCodeTrue"() : () -> ()1414// CHECK-NEXT:       "test.secondCodeTrue"() : () -> ()1415// CHECK-NEXT:     }1416 1417// -----1418 1419// CHECK-LABEL: @combineIfsUsed1420// CHECK-SAME: %[[arg0:.+]]: i11421func.func @combineIfsUsed(%arg0 : i1, %arg2: i64) -> (i32, i32) {1422  %res = scf.if %arg0 -> i32 {1423    %v = "test.firstCodeTrue"() : () -> i321424    scf.yield %v : i321425  } else {1426    %v2 = "test.firstCodeFalse"() : () -> i321427    scf.yield %v2 : i321428  }1429  %res2 = scf.if %arg0 -> i32 {1430    %v = "test.secondCodeTrue"(%res) : (i32) -> i321431    scf.yield %v : i321432  } else {1433    %v2 = "test.secondCodeFalse"(%res) : (i32) -> i321434    scf.yield %v2 : i321435  }1436  return %res, %res2 : i32, i321437}1438// CHECK-NEXT:     %[[res:.+]]:2 = scf.if %[[arg0]] -> (i32, i32) {1439// CHECK-NEXT:       %[[tval0:.+]] = "test.firstCodeTrue"() : () -> i321440// CHECK-NEXT:       %[[tval:.+]] = "test.secondCodeTrue"(%[[tval0]]) : (i32) -> i321441// CHECK-NEXT:       scf.yield %[[tval0]], %[[tval]] : i32, i321442// CHECK-NEXT:     } else {1443// CHECK-NEXT:       %[[fval0:.+]] = "test.firstCodeFalse"() : () -> i321444// CHECK-NEXT:       %[[fval:.+]] = "test.secondCodeFalse"(%[[fval0]]) : (i32) -> i321445// CHECK-NEXT:       scf.yield %[[fval0]], %[[fval]] : i32, i321446// CHECK-NEXT:     }1447// CHECK-NEXT:     return %[[res]]#0, %[[res]]#1 : i32, i321448 1449// -----1450 1451// CHECK-LABEL: @combineIfsNot1452// CHECK-SAME: %[[arg0:.+]]: i11453func.func @combineIfsNot(%arg0 : i1, %arg2: i64) {1454  %true = arith.constant true1455  %not = arith.xori %arg0, %true : i11456  scf.if %arg0 {1457    "test.firstCodeTrue"() : () -> ()1458    scf.yield1459  }1460  scf.if %not {1461    "test.secondCodeTrue"() : () -> ()1462    scf.yield1463  }1464  return1465}1466 1467// CHECK-NEXT:     scf.if %[[arg0]] {1468// CHECK-NEXT:       "test.firstCodeTrue"() : () -> ()1469// CHECK-NEXT:     } else {1470// CHECK-NEXT:       "test.secondCodeTrue"() : () -> ()1471// CHECK-NEXT:     }1472 1473// -----1474 1475// CHECK-LABEL: @combineIfsNot21476// CHECK-SAME: %[[arg0:.+]]: i11477func.func @combineIfsNot2(%arg0 : i1, %arg2: i64) {1478  %true = arith.constant true1479  %not = arith.xori %arg0, %true : i11480  scf.if %not {1481    "test.firstCodeTrue"() : () -> ()1482    scf.yield1483  }1484  scf.if %arg0 {1485    "test.secondCodeTrue"() : () -> ()1486    scf.yield1487  }1488  return1489}1490 1491// CHECK-NEXT:     scf.if %[[arg0]] {1492// CHECK-NEXT:       "test.secondCodeTrue"() : () -> ()1493// CHECK-NEXT:     } else {1494// CHECK-NEXT:       "test.firstCodeTrue"() : () -> ()1495// CHECK-NEXT:     }1496 1497// -----1498 1499// CHECK-LABEL: func @propagate_into_execute_region1500func.func @propagate_into_execute_region() {1501  %cond = arith.constant 0 : i11502  affine.for %i = 0 to 100 {1503    "test.foo"() : () -> ()1504    %v = scf.execute_region -> i64 {1505      cf.cond_br %cond, ^bb1, ^bb21506 1507    ^bb1:1508      %c1 = arith.constant 1 : i641509      cf.br ^bb3(%c1 : i64)1510 1511    ^bb2:1512      %c2 = arith.constant 2 : i641513      cf.br ^bb3(%c2 : i64)1514 1515    ^bb3(%x : i64):1516      scf.yield %x : i641517    }1518    "test.bar"(%v) : (i64) -> ()1519    // CHECK:      %[[C2:.*]] = arith.constant 2 : i641520    // CHECK: "test.foo"1521    // CHECK-NEXT: "test.bar"(%[[C2]]) : (i64) -> ()1522  }1523  return1524}1525 1526// -----1527 1528// CHECK-LABEL: func @execute_region_inline1529func.func @execute_region_inline() {1530  affine.for %i = 0 to 100 {1531    "test.foo"() : () -> ()1532    %v = scf.execute_region -> i64 {1533      %x = "test.val"() : () -> i641534      scf.yield %x : i641535    }1536    "test.bar"(%v) : (i64) -> ()1537  }1538  return1539}1540 1541// CHECK-NEXT:     affine.for %arg0 = 0 to 100 {1542// CHECK-NEXT:       "test.foo"() : () -> ()1543// CHECK-NEXT:       %[[VAL:.*]] = "test.val"() : () -> i641544// CHECK-NEXT:       "test.bar"(%[[VAL]]) : (i64) -> ()1545// CHECK-NEXT:     }1546 1547// -----1548 1549// CHECK-LABEL: func @execute_region_no_inline1550func.func @execute_region_no_inline() {1551  affine.for %i = 0 to 100 {1552    "test.foo"() : () -> ()1553    %v = scf.execute_region -> i64 no_inline {1554      %x = "test.val"() : () -> i641555      scf.yield %x : i641556    }1557    "test.bar"(%v) : (i64) -> ()1558  }1559  return1560}1561 1562// CHECK-NEXT:     affine.for %arg0 = 0 to 100 {1563// CHECK-NEXT:       "test.foo"() : () -> ()1564// CHECK-NEXT:       scf.execute_region1565// CHECK-NEXT:       %[[VAL:.*]] = "test.val"() : () -> i641566// CHECK-NEXT:       scf.yield %[[VAL]] : i641567// CHECK-NOT:      no_inline1568 1569// -----1570 1571// CHECK-LABEL: func @execute_region_under_func_no_inline1572func.func @execute_region_under_func_no_inline() {1573    "test.foo"() : () -> ()1574    %v = scf.execute_region -> i64 no_inline {1575      %x = "test.val"() : () -> i641576      scf.yield %x : i641577    }1578    "test.bar"(%v) : (i64) -> ()1579  return1580}1581 1582// CHECK-NEXT:       "test.foo"() : () -> ()1583// CHECK-NEXT:       scf.execute_region1584// CHECK-NEXT:       %[[VAL:.*]] = "test.val"() : () -> i641585// CHECK-NEXT:       scf.yield %[[VAL]] : i641586 1587// -----1588 1589// CHECK-LABEL: func @func_execute_region_inline1590func.func @func_execute_region_inline() {1591    "test.foo"() : () -> ()1592    %v = scf.execute_region -> i64 {1593      %c = "test.cmp"() : () -> i11594      cf.cond_br %c, ^bb2, ^bb31595    ^bb2:1596      %x = "test.val1"() : () -> i641597      cf.br ^bb4(%x : i64)1598    ^bb3:1599      %y = "test.val2"() : () -> i641600      cf.br ^bb4(%y : i64)1601    ^bb4(%z : i64):1602      scf.yield %z : i641603    }1604    "test.bar"(%v) : (i64) -> ()1605  return1606}1607 1608// CHECK-NOT: execute_region1609// CHECK:     "test.foo"1610// CHECK:     %[[cmp:.+]] = "test.cmp"1611// CHECK:     cf.cond_br %[[cmp]], ^[[bb1:.+]], ^[[bb2:.+]]1612// CHECK:   ^[[bb1]]:1613// CHECK:     %[[x:.+]] = "test.val1"1614// CHECK:     cf.br ^[[bb3:.+]](%[[x]] : i64)1615// CHECK:   ^[[bb2]]:1616// CHECK:     %[[y:.+]] = "test.val2"1617// CHECK:     cf.br ^[[bb3]](%[[y:.+]] : i64)1618// CHECK:   ^[[bb3]](%[[z:.+]]: i64):1619// CHECK:     "test.bar"(%[[z]])1620// CHECK:     return1621 1622// -----1623 1624// CHECK-LABEL: func @func_execute_region_inline_multi_yield1625func.func @func_execute_region_inline_multi_yield() {1626    "test.foo"() : () -> ()1627    %v = scf.execute_region -> i64 {1628      %c = "test.cmp"() : () -> i11629      cf.cond_br %c, ^bb2, ^bb31630    ^bb2:1631      %x = "test.val1"() : () -> i641632      scf.yield %x : i641633    ^bb3:1634      %y = "test.val2"() : () -> i641635      scf.yield %y : i641636    }1637    "test.bar"(%v) : (i64) -> ()1638  return1639}1640 1641// CHECK-NOT: execute_region1642// CHECK:     "test.foo"1643// CHECK:     %[[cmp:.+]] = "test.cmp"1644// CHECK:     cf.cond_br %[[cmp]], ^[[bb1:.+]], ^[[bb2:.+]]1645// CHECK:   ^[[bb1]]:1646// CHECK:     %[[x:.+]] = "test.val1"1647// CHECK:     cf.br ^[[bb3:.+]](%[[x]] : i64)1648// CHECK:   ^[[bb2]]:1649// CHECK:     %[[y:.+]] = "test.val2"1650// CHECK:     cf.br ^[[bb3]](%[[y:.+]] : i64)1651// CHECK:   ^[[bb3]](%[[z:.+]]: i64):1652// CHECK:     "test.bar"(%[[z]])1653// CHECK:     return1654 1655// -----1656 1657// Test case with single scf.yield op inside execute_region and its operand is defined outside the execute_region op.1658// Make scf.execute_region not to return anything.1659 1660// CHECK:           scf.execute_region no_inline {1661// CHECK:             func.call @foo() : () -> ()1662// CHECK:             scf.yield1663// CHECK:           }1664 1665module {1666func.func private @foo()->()1667func.func private @execute_region_yeilding_external_value() -> memref<1x60xui8> {1668  %alloc = memref.alloc() {alignment = 64 : i64} : memref<1x60xui8>  1669  %1 = scf.execute_region -> memref<1x60xui8> no_inline {    1670    func.call @foo():()->()1671    scf.yield %alloc: memref<1x60xui8>1672  }  1673  return %1 : memref<1x60xui8>1674}1675}1676 1677// -----1678 1679// Test case with scf.yield op inside execute_region with multiple operands.1680// One of operands is defined outside the execute_region op.1681// Remove just this operand from the op results.1682 1683// CHECK:           %[[VAL_1:.*]] = scf.execute_region -> memref<1x120xui8> no_inline {1684// CHECK:             %[[VAL_2:.*]] = memref.alloc() {alignment = 64 : i64} : memref<1x120xui8>1685// CHECK:             func.call @foo() : () -> ()1686// CHECK:             scf.yield %[[VAL_2]] : memref<1x120xui8>1687// CHECK:           }1688module {1689func.func private @foo()->()1690func.func private @execute_region_yeilding_external_and_local_values() -> (memref<1x60xui8>, memref<1x120xui8>) {1691  %alloc = memref.alloc() {alignment = 64 : i64} : memref<1x60xui8>  1692  %1, %2 = scf.execute_region -> (memref<1x60xui8>, memref<1x120xui8>) no_inline {    1693    %alloc_1 = memref.alloc() {alignment = 64 : i64} : memref<1x120xui8>1694    func.call @foo():()->()1695    scf.yield %alloc, %alloc_1: memref<1x60xui8>,  memref<1x120xui8>1696  }  1697  return %1, %2 : memref<1x60xui8>, memref<1x120xui8>1698}1699}1700 1701// -----1702 1703// Test case with multiple scf.yield ops inside execute_region with same operands and those operands are defined outside the execute_region op..1704// Make scf.execute_region not to return anything.1705// scf.yield must remain, cause scf.execute_region can't be empty.1706 1707// CHECK:           scf.execute_region no_inline {1708// CHECK:             %[[VAL_3:.*]] = "test.cmp"() : () -> i11709// CHECK:             cf.cond_br %[[VAL_3]], ^bb1, ^bb21710// CHECK:           ^bb1:1711// CHECK:             scf.yield1712// CHECK:           ^bb2:1713// CHECK:             scf.yield1714// CHECK:           }1715 1716module {1717  func.func private @foo()->()1718  func.func private @execute_region_multiple_yields_same_operands() -> (memref<1x60xui8>, memref<1x120xui8>) {1719    %alloc = memref.alloc() {alignment = 64 : i64} : memref<1x60xui8>  1720    %alloc_1 = memref.alloc() {alignment = 64 : i64} : memref<1x120xui8>  1721    %1, %2 = scf.execute_region -> (memref<1x60xui8>, memref<1x120xui8>) no_inline {1722      %c = "test.cmp"() : () -> i11723      cf.cond_br %c, ^bb2, ^bb31724    ^bb2:    1725      func.call @foo():()->()1726      scf.yield %alloc, %alloc_1 : memref<1x60xui8>, memref<1x120xui8>1727    ^bb3: 1728      func.call @foo():()->()   1729      scf.yield %alloc, %alloc_1 : memref<1x60xui8>, memref<1x120xui8>1730    }  1731    return %1, %2 : memref<1x60xui8>, memref<1x120xui8>1732  }1733}1734 1735// -----1736 1737// Test case with multiple scf.yield ops with at least one different operand, then no change.1738 1739// CHECK:           %[[VAL_3:.*]]:2 = scf.execute_region -> (memref<1x60xui8>, memref<1x120xui8>) no_inline {1740// CHECK:           ^bb1:1741// CHECK:             scf.yield %{{.*}}, %{{.*}} : memref<1x60xui8>, memref<1x120xui8>1742// CHECK:           ^bb2:1743// CHECK:             scf.yield %{{.*}}, %{{.*}} : memref<1x60xui8>, memref<1x120xui8>1744// CHECK:           }1745 1746module {1747  func.func private @foo()->()1748  func.func private @execute_region_multiple_yields_different_operands() -> (memref<1x60xui8>, memref<1x120xui8>) {1749    %alloc = memref.alloc() {alignment = 64 : i64} : memref<1x60xui8>  1750    %alloc_1 = memref.alloc() {alignment = 64 : i64} : memref<1x120xui8>  1751    %alloc_2 = memref.alloc() {alignment = 64 : i64} : memref<1x120xui8>  1752    %1, %2 = scf.execute_region -> (memref<1x60xui8>, memref<1x120xui8>) no_inline {1753      %c = "test.cmp"() : () -> i11754      cf.cond_br %c, ^bb2, ^bb31755    ^bb2:    1756      func.call @foo():()->()1757      scf.yield %alloc, %alloc_1 : memref<1x60xui8>, memref<1x120xui8>1758    ^bb3: 1759      func.call @foo():()->()   1760      scf.yield %alloc, %alloc_2 : memref<1x60xui8>, memref<1x120xui8>1761    }  1762    return %1, %2 : memref<1x60xui8>, memref<1x120xui8>1763  }1764}1765 1766// -----1767 1768// Test case with multiple scf.yield ops each has different operand.1769// In this case scf.execute_region isn't changed.1770 1771// CHECK:           %[[VAL_2:.*]] = scf.execute_region -> memref<1x60xui8> no_inline {1772// CHECK:           ^bb1:1773// CHECK:             scf.yield %{{.*}} : memref<1x60xui8>1774// CHECK:           ^bb2:1775// CHECK:             scf.yield %{{.*}} : memref<1x60xui8>1776// CHECK:           }1777 1778module {1779func.func private @foo()->()1780func.func private @execute_region_multiple_yields_different_operands() -> (memref<1x60xui8>) {1781  %alloc = memref.alloc() {alignment = 64 : i64} : memref<1x60xui8>  1782  %alloc_1 = memref.alloc() {alignment = 64 : i64} : memref<1x60xui8>   1783  %1 = scf.execute_region -> (memref<1x60xui8>) no_inline {1784    %c = "test.cmp"() : () -> i11785    cf.cond_br %c, ^bb2, ^bb31786  ^bb2:    1787    func.call @foo():()->()1788    scf.yield %alloc : memref<1x60xui8>1789  ^bb3:    1790    func.call @foo():()->()1791    scf.yield %alloc_1 : memref<1x60xui8>1792  }    1793  return %1 : memref<1x60xui8>1794}1795}1796 1797// -----1798 1799// CHECK-LABEL: func @canonicalize_parallel_insert_slice_indices(1800//  CHECK-SAME:     %[[arg0:.*]]: tensor<1x5xf32>, %[[arg1:.*]]: tensor<?x?xf32>1801func.func @canonicalize_parallel_insert_slice_indices(1802    %arg0 : tensor<1x5xf32>, %arg1: tensor<?x?xf32>, %num_threads : index) -> index1803{1804  // CHECK: %[[c1:.*]] = arith.constant 1 : index1805  %c1 = arith.constant 1 : index1806 1807  %2 = scf.forall (%tidx) in (%num_threads) shared_outs(%o = %arg1) -> (tensor<?x?xf32>) {1808    scf.forall.in_parallel {1809      tensor.parallel_insert_slice %arg0 into %o[%tidx, 0] [1, 5] [1, 1] : tensor<1x5xf32> into tensor<?x?xf32>1810    }1811  }1812 1813  // CHECK: %[[dim:.*]] = tensor.dim %[[arg1]], %[[c1]]1814  %dim = tensor.dim %2, %c1 : tensor<?x?xf32>1815  // CHECK: return %[[dim]]1816  return %dim : index1817}1818 1819// -----1820 1821// CHECK-LABEL: func @forall_fold_control_operands1822func.func @forall_fold_control_operands(1823    %arg0 : tensor<?x10xf32>, %arg1: tensor<?x10xf32>) -> tensor<?x10xf32> {1824  %c0 = arith.constant 0 : index1825  %c1 = arith.constant 1 : index1826  %dim0 = tensor.dim %arg0, %c0 : tensor<?x10xf32>1827  %dim1 = tensor.dim %arg0, %c1 : tensor<?x10xf32>1828 1829  %result = scf.forall (%i, %j) = (%c0, %c0) to (%dim0, %dim1)1830      step (%c1, %c1) shared_outs(%o = %arg1) -> (tensor<?x10xf32>) {1831    %slice = tensor.extract_slice %arg1[%i, %j] [1, 1] [1, 1]1832      : tensor<?x10xf32> to tensor<1x1xf32>1833 1834    scf.forall.in_parallel {1835      tensor.parallel_insert_slice %slice into %o[%i, %j] [1, 1] [1, 1]1836        : tensor<1x1xf32> into tensor<?x10xf32>1837    }1838  }1839 1840  return %result : tensor<?x10xf32>1841}1842// CHECK: forall (%{{.*}}, %{{.*}}) in (%{{.*}}, 10)1843 1844// -----1845 1846func.func @inline_forall_loop(%in: tensor<8x8xf32>) -> tensor<8x8xf32> {1847  %c8 = arith.constant 8 : index1848  %c0 = arith.constant 0 : index1849  %c1 = arith.constant 1 : index1850  %cst = arith.constant 0.000000e+00 : f321851  %0 = tensor.empty() : tensor<8x8xf32>1852  %1 = scf.forall (%i, %j) = (%c0, %c0) to (%c1, %c1)1853        step (%c8, %c8) shared_outs (%out_ = %0) -> (tensor<8x8xf32>) {1854    %slice = tensor.extract_slice %out_[%i, %j] [2, 3] [1, 1]1855      : tensor<8x8xf32> to tensor<2x3xf32>1856    %fill = linalg.fill ins(%cst : f32) outs(%slice : tensor<2x3xf32>)1857          -> tensor<2x3xf32>1858    scf.forall.in_parallel {1859      tensor.parallel_insert_slice %fill into %out_[%i, %j] [2, 3] [1, 1]1860        : tensor<2x3xf32> into tensor<8x8xf32>1861    }1862  }1863  return %1 : tensor<8x8xf32>1864}1865// CHECK-LABEL: @inline_forall_loop1866// CHECK-NOT:     scf.forall1867// CHECK:         %[[OUT:.*]] = tensor.empty1868 1869// CHECK-NEXT:    %[[SLICE:.*]] = tensor.extract_slice %[[OUT]]1870// CHECK-SAME:      : tensor<8x8xf32> to tensor<2x3xf32>1871 1872// CHECK-NEXT:    %[[FILL:.*]] = linalg.fill1873// CHECK-SAME:      outs(%[[SLICE]]1874 1875// CHECK-NEXT:    tensor.insert_slice %[[FILL]]1876// CHECK-SAME:      : tensor<2x3xf32> into tensor<8x8xf32>1877 1878// -----1879 1880func.func @do_not_inline_distributed_forall_loop(1881    %in: tensor<8x8xf32>) -> tensor<8x8xf32> {1882  %cst = arith.constant 0.000000e+00 : f321883  %0 = tensor.empty() : tensor<8x8xf32>1884  %1 = scf.forall (%i, %j) = (0, 4) to (1, 5) step (8, 8)1885      shared_outs (%out_ = %0) -> (tensor<8x8xf32>) {1886    %slice = tensor.extract_slice %out_[%i, %j] [2, 3] [1, 1]1887      : tensor<8x8xf32> to tensor<2x3xf32>1888    %fill = linalg.fill ins(%cst : f32) outs(%slice : tensor<2x3xf32>)1889          -> tensor<2x3xf32>1890    scf.forall.in_parallel {1891      tensor.parallel_insert_slice %fill into %out_[%i, %j] [2, 3] [1, 1]1892        : tensor<2x3xf32> into tensor<8x8xf32>1893    }1894  }{ mapping = [#gpu.thread<y>, #gpu.thread<x>] }1895  return %1 : tensor<8x8xf32>1896}1897// CHECK-LABEL: @do_not_inline_distributed_forall_loop1898// CHECK: scf.forall1899// CHECK:   tensor.extract_slice %{{.*}}[0, 4] [2, 3] [1, 1]1900// CHECK:   tensor.parallel_insert_slice %{{.*}}[0, 4] [2, 3] [1, 1]1901 1902// -----1903 1904func.func @inline_empty_loop_with_empty_mapping(1905    %in: tensor<16xf32>) -> tensor<16xf32> {1906  %cst = arith.constant 0.000000e+00 : f321907  %0 = tensor.empty() : tensor<16xf32>1908  %1 = scf.forall () in () shared_outs (%out_ = %0) -> (tensor<16xf32>) {1909    %slice = tensor.extract_slice %out_[0] [16] [1]1910      : tensor<16xf32> to tensor<16xf32>1911    %generic = linalg.generic {1912        indexing_maps = [affine_map<(d0) -> (d0)>, affine_map<(d0) -> (d0)>],1913        iterator_types = ["parallel"]}1914        ins(%slice : tensor<16xf32>) outs(%0 : tensor<16xf32>) {1915      ^bb0(%b0 : f32, %b1 : f32):1916        %2 = arith.addf %b0, %b0 : f321917        linalg.yield %2 : f321918    } -> tensor<16xf32>1919    scf.forall.in_parallel {1920      tensor.parallel_insert_slice %generic into %out_[0] [16] [1]1921        : tensor<16xf32> into tensor<16xf32>1922    }1923  }{ mapping = [] }1924  return %1 : tensor<16xf32>1925}1926// CHECK-LABEL: func @inline_empty_loop_with_empty_mapping1927//   CHECK-NOT:   scf.forall1928 1929// -----1930 1931func.func @collapse_one_dim_parallel(%in: tensor<8x8xf32>) -> tensor<8x8xf32> {1932  %c8 = arith.constant 8 : index1933  %c0 = arith.constant 0 : index1934  %c1 = arith.constant 1 : index1935  %c16 = arith.constant 16 : index1936  %cst = arith.constant 0.000000e+00 : f321937  %0 = tensor.empty() : tensor<8x8xf32>1938  %1 = scf.forall (%i, %j) = (0, %c0) to (1, %c16)1939        step (8, %c8) shared_outs (%out_ = %0) -> (tensor<8x8xf32>) {1940    %fill = linalg.fill ins(%cst : f32) outs(%out_ : tensor<8x8xf32>)1941          -> tensor<8x8xf32>1942    scf.forall.in_parallel {1943      tensor.parallel_insert_slice %fill into %out_[%i, %j] [8, 8] [1, 1]1944        : tensor<8x8xf32> into tensor<8x8xf32>1945    }1946  }1947  return %1 : tensor<8x8xf32>1948}1949// CHECK-LABEL: @collapse_one_dim_parallel1950// CHECK:         scf.forall (%[[ARG:.*]]) = (0) to (16) step (8)1951// CHECK:           linalg.fill1952// CHECK:           tensor.parallel_insert_slice1953 1954// -----1955 1956func.func @remove_empty_forall(%in: tensor<8x8xf32>) -> tensor<8x8xf32> {1957  %c8 = arith.constant 8 : index1958  %c0 = arith.constant 0 : index1959  %c1 = arith.constant 1 : index1960  %c16 = arith.constant 16 : index1961  %cst = arith.constant 0.000000e+00 : f321962  %0 = tensor.empty() : tensor<8x8xf32>1963  %1 = scf.forall (%i, %j) = (%c0, %c16) to (%c1, %c16)1964        step (%c8, %c8) shared_outs (%out_ = %0) -> (tensor<8x8xf32>) {1965    %fill = linalg.fill ins(%cst : f32) outs(%out_ : tensor<8x8xf32>)1966          -> tensor<8x8xf32>1967    scf.forall.in_parallel {1968      tensor.parallel_insert_slice %fill into %out_[%i, %j] [8, 8] [1, 1]1969        : tensor<8x8xf32> into tensor<8x8xf32>1970    }1971  }1972  return %1 : tensor<8x8xf32>1973}1974// CHECK-LABEL: @remove_empty_forall1975// CHECK-NOT:   scf.forall1976// CHECK:       %[[EMPTY:.*]] = tensor.empty1977// CHECK:       return %[[EMPTY]]1978 1979// -----1980 1981func.func @fold_tensor_cast_into_forall(1982    %in: tensor<2xi32>, %out: tensor<2xi32>) -> tensor<2xi32> {1983  %cst = arith.constant dense<[100500]> : tensor<1xi32>1984 1985 1986  %out_cast = tensor.cast %out : tensor<2xi32> to tensor<?xi32>1987  %result = scf.forall (%i) = (0) to (2) step (1)1988      shared_outs (%out_ = %out_cast) -> tensor<?xi32> {1989 1990    scf.forall.in_parallel {1991      tensor.parallel_insert_slice %cst into %out_[%i] [1] [1]1992        : tensor<1xi32> into tensor<?xi32>1993    }1994  }1995  %result_cast = tensor.cast %result : tensor<?xi32> to tensor<2xi32>1996  func.return %result_cast : tensor<2xi32>1997}1998// CHECK-LABEL: @fold_tensor_cast_into_forall1999// CHECK-NOT:     tensor.cast2000// CHECK:         parallel_insert_slice2001// CHECK-SAME:      : tensor<1xi32> into tensor<2xi32>2002// CHECK-NOT:     tensor.cast2003 2004// -----2005 2006func.func @do_not_fold_tensor_cast_from_dynamic_to_static_type_into_forall(2007    %in: tensor<?xi32>, %out: tensor<?xi32>) -> tensor<?xi32> {2008  %cst = arith.constant dense<[100500]> : tensor<1xi32>2009 2010 2011  %out_cast = tensor.cast %out : tensor<?xi32> to tensor<2xi32>2012  %result = scf.forall (%i) = (0) to (2) step (1)2013      shared_outs (%out_ = %out_cast) -> tensor<2xi32> {2014 2015    scf.forall.in_parallel {2016      tensor.parallel_insert_slice %cst into %out_[%i] [1] [1]2017        : tensor<1xi32> into tensor<2xi32>2018    }2019  }2020  %result_cast = tensor.cast %result : tensor<2xi32> to tensor<?xi32>2021  func.return %result_cast : tensor<?xi32>2022}2023// CHECK-LABEL: @do_not_fold_tensor_cast_2024// CHECK:         tensor.cast2025// CHECK:         parallel_insert_slice2026// CHECK-SAME:      : tensor<1xi32> into tensor<2xi32>2027// CHECK:         tensor.cast2028 2029// -----2030 2031#map = affine_map<()[s0, s1] -> (s0 ceildiv s1)>2032#map1 = affine_map<(d0)[s0] -> (d0 * s0)>2033#map2 = affine_map<(d0)[s0, s1] -> (-(d0 * s1) + s0, s1)>2034module {2035  func.func @fold_iter_args_not_being_modified_within_scfforall(%arg0: index, %arg1: tensor<?xf32>, %arg2: tensor<?xf32>) -> (tensor<?xf32>, tensor<?xf32>) {2036    %c0 = arith.constant 0 : index2037    %cst = arith.constant 4.200000e+01 : f322038    %0 = linalg.fill ins(%cst : f32) outs(%arg1 : tensor<?xf32>) -> tensor<?xf32>2039    %dim = tensor.dim %arg1, %c0 : tensor<?xf32>2040    %1 = affine.apply #map()[%dim, %arg0]2041    %2:2 = scf.forall (%arg3) in (%1) shared_outs(%arg4 = %arg1, %arg5 = %arg2) -> (tensor<?xf32>, tensor<?xf32>) {2042      %3 = affine.apply #map1(%arg3)[%arg0]2043      %4 = affine.min #map2(%arg3)[%dim, %arg0]2044      %extracted_slice0 = tensor.extract_slice %arg4[%3] [%4] [1] : tensor<?xf32> to tensor<?xf32>2045      %extracted_slice1 = tensor.extract_slice %arg5[%3] [%4] [1] : tensor<?xf32> to tensor<?xf32>2046      %5 = linalg.exp ins(%extracted_slice0 : tensor<?xf32>) outs(%extracted_slice1 : tensor<?xf32>) -> tensor<?xf32>2047      scf.forall.in_parallel {2048        tensor.parallel_insert_slice %5 into %arg5[%3] [%4] [1] : tensor<?xf32> into tensor<?xf32>2049      }2050    }2051    return %2#0, %2#1 : tensor<?xf32>, tensor<?xf32>2052  }2053}2054// CHECK-LABEL: @fold_iter_args_not_being_modified_within_scfforall2055//  CHECK-SAME:   (%{{.*}}: index, %[[ARG1:.*]]: tensor<?xf32>, %[[ARG2:.*]]: tensor<?xf32>) -> (tensor<?xf32>, tensor<?xf32>) {2056//       CHECK:    %[[RESULT:.*]] = scf.forall2057//  CHECK-SAME:                       shared_outs(%[[ITER_ARG_5:.*]] = %[[ARG2]]) -> (tensor<?xf32>) {2058//       CHECK:      %[[OPERAND0:.*]] = tensor.extract_slice %[[ARG1]]2059//       CHECK:      %[[OPERAND1:.*]] = tensor.extract_slice %[[ITER_ARG_5]]2060//       CHECK:      %[[ELEM:.*]] = linalg.exp ins(%[[OPERAND0]] : tensor<?xf32>) outs(%[[OPERAND1]] : tensor<?xf32>) -> tensor<?xf32>2061//       CHECK:      scf.forall.in_parallel {2062//  CHECK-NEXT:         tensor.parallel_insert_slice %[[ELEM]] into %[[ITER_ARG_5]]2063//  CHECK-NEXT:      }2064//  CHECK-NEXT:    }2065//  CHECK-NEXT:    return %[[ARG1]], %[[RESULT]]2066 2067// -----2068 2069#map = affine_map<()[s0, s1] -> (s0 ceildiv s1)>2070#map1 = affine_map<(d0)[s0] -> (d0 * s0)>2071#map2 = affine_map<(d0)[s0, s1] -> (-(d0 * s1) + s0, s1)>2072module {2073  func.func @fold_iter_args_with_no_use_of_result_scfforall(%arg0: index, %arg1: tensor<?xf32>, %arg2: tensor<?xf32>, %arg3: tensor<?xf32>) -> tensor<?xf32> {2074    %cst = arith.constant 4.200000e+01 : f322075    %c0 = arith.constant 0 : index2076    %0 = linalg.fill ins(%cst : f32) outs(%arg1 : tensor<?xf32>) -> tensor<?xf32>2077    %dim = tensor.dim %arg1, %c0 : tensor<?xf32>2078    %1 = affine.apply #map()[%dim, %arg0]2079    %2:3 = scf.forall (%arg4) in (%1) shared_outs(%arg5 = %arg1, %arg6 = %arg2, %arg7 = %arg3) -> (tensor<?xf32>, tensor<?xf32>, tensor<?xf32>) {2080      %3 = affine.apply #map1(%arg4)[%arg0]2081      %4 = affine.min #map2(%arg4)[%dim, %arg0]2082      %extracted_slice = tensor.extract_slice %arg5[%3] [%4] [1] : tensor<?xf32> to tensor<?xf32>2083      %extracted_slice_0 = tensor.extract_slice %arg6[%3] [%4] [1] : tensor<?xf32> to tensor<?xf32>2084      %extracted_slice_1 = tensor.extract_slice %arg7[%3] [%4] [1] : tensor<?xf32> to tensor<?xf32>2085      %extracted_slice_2 = tensor.extract_slice %0[%3] [%4] [1] : tensor<?xf32> to tensor<?xf32>2086      %5 = linalg.exp ins(%extracted_slice : tensor<?xf32>) outs(%extracted_slice_1 : tensor<?xf32>) -> tensor<?xf32>2087      scf.forall.in_parallel {2088        tensor.parallel_insert_slice %5 into %arg6[%3] [%4] [1] : tensor<?xf32> into tensor<?xf32>2089        tensor.parallel_insert_slice %extracted_slice into %arg5[%3] [%4] [1] : tensor<?xf32> into tensor<?xf32>2090        tensor.parallel_insert_slice %extracted_slice_0 into %arg7[%3] [%4] [1] : tensor<?xf32> into tensor<?xf32>2091        tensor.parallel_insert_slice %5 into %arg7[%4] [%3] [1] : tensor<?xf32> into tensor<?xf32>2092      }2093    }2094    return %2#1 : tensor<?xf32>2095  }2096}2097// CHECK-LABEL: @fold_iter_args_with_no_use_of_result_scfforall2098//  CHECK-SAME:   (%{{.*}}: index, %[[ARG1:.*]]: tensor<?xf32>, %[[ARG2:.*]]: tensor<?xf32>, %[[ARG3:.*]]: tensor<?xf32>) -> tensor<?xf32> {2099//       CHECK:    %[[RESULT:.*]] = scf.forall2100//  CHECK-SAME:                       shared_outs(%[[ITER_ARG_6:.*]] = %[[ARG2]]) -> (tensor<?xf32>) {2101//       CHECK:      %[[OPERAND0:.*]] = tensor.extract_slice %[[ARG1]]2102//       CHECK:      %[[OPERAND1:.*]] = tensor.extract_slice %[[ARG3]]2103//       CHECK:      %[[ELEM:.*]] = linalg.exp ins(%[[OPERAND0]] : tensor<?xf32>) outs(%[[OPERAND1]] : tensor<?xf32>) -> tensor<?xf32>2104//       CHECK:      scf.forall.in_parallel {2105//  CHECK-NEXT:         tensor.parallel_insert_slice %[[ELEM]] into %[[ITER_ARG_6]]2106//  CHECK-NEXT:      }2107//  CHECK-NEXT:    }2108//  CHECK-NEXT:    return %[[RESULT]]2109 2110// -----2111 2112func.func @index_switch_fold() -> (f32, f32) {2113  %switch_cst = arith.constant 1: index2114  %0 = scf.index_switch %switch_cst -> f322115  case 1 {2116    %y = arith.constant 1.0 : f322117    scf.yield %y : f322118  }2119  default {2120    %y = arith.constant 42.0 : f322121    scf.yield %y : f322122  }2123 2124  %switch_cst_2 = arith.constant 2: index2125  %1 = scf.index_switch %switch_cst_2 -> f322126  case 0 {2127    %y = arith.constant 0.0 : f322128    scf.yield %y : f322129  }2130  default {2131    %y = arith.constant 42.0 : f322132    scf.yield %y : f322133  }2134 2135  return %0, %1 : f32, f322136}2137 2138// CHECK-LABEL: func.func @index_switch_fold()2139//  CHECK-NEXT:   %[[c1:.*]] = arith.constant 1.000000e+00 : f322140//  CHECK-NEXT:   %[[c42:.*]] = arith.constant 4.200000e+01 : f322141//  CHECK-NEXT:   return %[[c1]], %[[c42]] : f32, f322142 2143// -----2144 2145func.func @index_switch_fold_no_res() {2146  %c1 = arith.constant 1 : index2147  scf.index_switch %c12148  case 0 {2149    scf.yield2150  }2151  default {2152    "test.op"() : () -> ()2153    scf.yield2154  }2155  return2156}2157 2158// CHECK-LABEL: func.func @index_switch_fold_no_res()2159//  CHECK-NEXT: "test.op"() : () -> ()2160 2161// -----2162 2163// Step 0 is invalid, the loop is eliminated.2164// CHECK-LABEL: func @scf_for_all_step_size_0()2165//       CHECK-NOT:   scf.forall2166func.func @scf_for_all_step_size_0()  {2167  %x = arith.constant 0 : index2168  scf.forall (%i, %j) = (0, 4) to (1, 5) step (%x, 8) {2169    vector.print %x : index2170    scf.forall.in_parallel {}2171  }2172  return2173}2174