brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.2 KiB · d944518 Raw
584 lines · plain
1// RUN: mlir-opt %s -transform-interpreter -split-input-file -verify-diagnostics | FileCheck %s2 3// Outlined functions:4//5// CHECK: func @foo(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}})6// CHECK:   scf.for7// CHECK:     arith.addi8//9// CHECK: func @foo[[$SUFFIX:.+]](%{{.+}}, %{{.+}}, %{{.+}})10// CHECK:   scf.for11// CHECK:     arith.addi12//13// CHECK-LABEL: @loop_outline_op14func.func @loop_outline_op(%arg0: index, %arg1: index, %arg2: index) {15  // CHECK: scf.for16  // CHECK-NOT: scf.for17  // CHECK:   scf.execute_region18  // CHECK:     func.call @foo19  scf.for %i = %arg0 to %arg1 step %arg2 {20    scf.for %j = %arg0 to %arg1 step %arg2 {21      arith.addi %i, %j : index22    }23  }24  // CHECK: scf.execute_region25  // CHECK-NOT: scf.for26  // CHECK:   func.call @foo[[$SUFFIX]]27  scf.for %j = %arg0 to %arg1 step %arg2 {28    arith.addi %j, %j : index29  }30  return31}32 33module attributes {transform.with_named_sequence} {34  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {35    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op36    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">37    // CHECK: = transform.loop.outline %{{.*}}38    transform.loop.outline %1 {func_name = "foo"} : (!transform.op<"scf.for">) -> (!transform.any_op, !transform.any_op)39    transform.yield40  }41}42 43// -----44 45// CHECK-LABEL: @loop_peel_op46func.func @loop_peel_op() {47  // CHECK: %[[C0:.+]] = arith.constant 048  // CHECK: %[[C41:.+]] = arith.constant 4149  // CHECK: %[[C5:.+]] = arith.constant 550  // CHECK: %[[C40:.+]] = arith.constant 4051  // CHECK: scf.for %{{.+}} = %[[C0]] to %[[C40]] step %[[C5]]52  // CHECK:   arith.addi53  // CHECK: scf.for %{{.+}} = %[[C40]] to %[[C41]] step %[[C5]]54  // CHECK:   arith.addi55  %0 = arith.constant 0 : index56  %1 = arith.constant 41 : index57  %2 = arith.constant 5 : index58  // expected-remark @below {{main loop}}59  // expected-remark @below {{remainder loop}}60  scf.for %i = %0 to %1 step %2 {61    arith.addi %i, %i : index62  }63  return64}65 66module attributes {transform.with_named_sequence} {67  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {68    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op69    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">70    %main_loop, %remainder = transform.loop.peel %1 : (!transform.op<"scf.for">) -> (!transform.op<"scf.for">, !transform.op<"scf.for">)71    // Make sure 72    transform.debug.emit_remark_at %main_loop, "main loop" : !transform.op<"scf.for">73    transform.debug.emit_remark_at %remainder, "remainder loop" : !transform.op<"scf.for">74    transform.yield75  }76}77 78// -----79 80// CHECK-LABEL: @loop_peel_first_iter_op81func.func @loop_peel_first_iter_op() {82  // CHECK: %[[C0:.+]] = arith.constant 083  // CHECK: %[[C41:.+]] = arith.constant 4184  // CHECK: %[[C5:.+]] = arith.constant 585  // CHECK: %[[C5_0:.+]] = arith.constant 586  // CHECK: scf.for %{{.+}} = %[[C0]] to %[[C5_0]] step %[[C5]]87  // CHECK:   arith.addi88  // CHECK: scf.for %{{.+}} = %[[C5_0]] to %[[C41]] step %[[C5]]89  // CHECK:   arith.addi90  %0 = arith.constant 0 : index91  %1 = arith.constant 41 : index92  %2 = arith.constant 5 : index93  scf.for %i = %0 to %1 step %2 {94    arith.addi %i, %i : index95  }96  return97}98 99module attributes {transform.with_named_sequence} {100  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {101    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op102    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">103    %main_loop, %remainder = transform.loop.peel %1 {peel_front = true} : (!transform.op<"scf.for">) -> (!transform.op<"scf.for">, !transform.op<"scf.for">)104    transform.yield105  }106}107 108// -----109 110func.func @loop_pipeline_op(%A: memref<?xf32>, %result: memref<?xf32>) {111  %c0 = arith.constant 0 : index112  %c1 = arith.constant 1 : index113  %c4 = arith.constant 4 : index114  %cf = arith.constant 1.0 : f32115  // CHECK: memref.load %[[MEMREF:.+]][%{{.+}}]116  // CHECK: memref.load %[[MEMREF]]117  // CHECK: arith.addf118  // CHECK: scf.for119  // CHECK:   memref.load120  // CHECK:   arith.addf121  // CHECK:   memref.store122  // CHECK: arith.addf123  // CHECK: memref.store124  // CHECK: memref.store125  // expected-remark @below {{transformed}}126  scf.for %i0 = %c0 to %c4 step %c1 {127    %A_elem = memref.load %A[%i0] : memref<?xf32>128    %A1_elem = arith.addf %A_elem, %cf : f32129    memref.store %A1_elem, %result[%i0] : memref<?xf32>130  }131  return132}133 134module attributes {transform.with_named_sequence} {135  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {136    %0 = transform.structured.match ops{["arith.addf"]} in %arg1 : (!transform.any_op) -> !transform.any_op137    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">138    %2 = transform.loop.pipeline %1 : (!transform.op<"scf.for">) -> !transform.any_op139    // Verify that the returned handle is usable.140    transform.debug.emit_remark_at %2, "transformed" : !transform.any_op141    transform.yield142  }143}144 145// -----146 147// CHECK-LABEL: @loop_unroll_op148func.func @loop_unroll_op() {149  %c0 = arith.constant 0 : index150  %c42 = arith.constant 42 : index151  %c5 = arith.constant 5 : index152  // CHECK: scf.for %[[I:.+]] =153  scf.for %i = %c0 to %c42 step %c5 {154    // CHECK-COUNT-4: arith.addi %[[I]]155    arith.addi %i, %i : index156  }157  return158}159 160module attributes {transform.with_named_sequence} {161  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {162    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op163    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">164    transform.loop.unroll %1 { factor = 4 } : !transform.op<"scf.for">165    transform.yield166  }167}168 169// -----170 171// CHECK-LABEL: @loop_unroll_and_jam_op172func.func @loop_unroll_and_jam_op() {173  // CHECK:           %[[VAL_0:.*]] = arith.constant 0 : index174  // CHECK:           %[[VAL_1:.*]] = arith.constant 40 : index175  // CHECK:           %[[VAL_2:.*]] = arith.constant 2 : index176  // CHECK:           %[[FACTOR:.*]] = arith.constant 4 : index177  // CHECK:           %[[STEP:.*]] = arith.constant 8 : index178  %c0 = arith.constant 0 : index179  %c40 = arith.constant 40 : index180  %c2 = arith.constant 2 : index181  // CHECK:           scf.for %[[VAL_5:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[STEP]] {182  scf.for %i = %c0 to %c40 step %c2 {183  // CHECK:             %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %[[VAL_5]] : index184  // CHECK:             %[[VAL_7:.*]] = arith.constant 2 : index185  // CHECK:             %[[VAL_8:.*]] = arith.addi %[[VAL_5]], %[[VAL_7]] : index186  // CHECK:             %[[VAL_9:.*]] = arith.addi %[[VAL_8]], %[[VAL_8]] : index187  // CHECK:             %[[VAL_10:.*]] = arith.constant 4 : index188  // CHECK:             %[[VAL_11:.*]] = arith.addi %[[VAL_5]], %[[VAL_10]] : index189  // CHECK:             %[[VAL_12:.*]] = arith.addi %[[VAL_11]], %[[VAL_11]] : index190  // CHECK:             %[[VAL_13:.*]] = arith.constant 6 : index191  // CHECK:             %[[VAL_14:.*]] = arith.addi %[[VAL_5]], %[[VAL_13]] : index192  // CHECK:             %[[VAL_15:.*]] = arith.addi %[[VAL_14]], %[[VAL_14]] : index193    arith.addi %i, %i : index194  }195  return196}197 198module attributes {transform.with_named_sequence} {199  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {200    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op201    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">202    transform.loop.unroll_and_jam %1 { factor = 4 } : !transform.op<"scf.for">203    transform.yield204  }205}206 207// -----208 209// CHECK-LABEL: @loop_unroll_and_jam_op210// CHECK:       %[[VAL_0:.*]]: memref<96x128xi8, 3>, %[[VAL_1:.*]]: memref<128xi8, 3>) {211func.func private @loop_unroll_and_jam_op(%arg0: memref<96x128xi8, 3>, %arg1: memref<128xi8, 3>) {212  // CHECK:           %[[UB_INNER:.*]] = arith.constant 96213  // CHECK:           %[[STEP_INNER:.*]] = arith.constant 1214  // CHECK:           %[[UB_OUTER:.*]] = arith.constant 128215  // CHECK:           %[[LB:.*]] = arith.constant 0216  // CHECK:           %[[UNUSED:.*]] = arith.constant 4217  // CHECK:           %[[UNROLL_FACTOR:.*]] = arith.constant 4218  %c96 = arith.constant 96 : index219  %c1 = arith.constant 1 : index220  %c128 = arith.constant 128 : index221  %c0 = arith.constant 0 : index222  // CHECK:           scf.for %[[OUTER_I:.*]] = %[[LB]] to %[[UB_OUTER]] step %[[UNROLL_FACTOR]] {223	scf.for %arg2 = %c0 to %c128 step %c1 {224    // CHECK:             %[[LOAD0:.*]] = memref.load %[[VAL_1]]{{\[}}%[[OUTER_I]]]225    // CHECK:             %[[ONE_0:.*]] = arith.constant 1226    // CHECK:             %[[INC_LOAD1:.*]] = arith.addi %[[OUTER_I]], %[[ONE_0]]227    // CHECK:             %[[LOAD1:.*]] = memref.load %[[VAL_1]]{{\[}}%[[INC_LOAD1]]]228    // CHECK:             %[[TWO_0:.*]] = arith.constant 2229    // CHECK:             %[[INC_LOAD2:.*]] = arith.addi %[[OUTER_I]], %[[TWO_0]]230    // CHECK:             %[[LOAD2:.*]] = memref.load %[[VAL_1]]{{\[}}%[[INC_LOAD2]]]231    // CHECK:             %[[THREE_0:.*]] = arith.constant 3232    // CHECK:             %[[INC_LOAD3:.*]] = arith.addi %[[OUTER_I]], %[[THREE_0]]233    // CHECK:             %[[LOAD3:.*]] = memref.load %[[VAL_1]]{{\[}}%[[INC_LOAD3]]]234	  %3 = memref.load %arg1[%arg2] : memref<128xi8, 3>235    // CHECK:             %[[VAL_19:.*]]:4 = scf.for %[[VAL_20:.*]] = %[[LB]] to %[[UB_INNER]] step %[[STEP_INNER]] iter_args(%[[VAL_21:.*]] = %[[LOAD0]], %[[VAL_22:.*]] = %[[LOAD1]], %[[VAL_23:.*]] = %[[LOAD2]], %[[VAL_24:.*]] = %[[LOAD3]])236	  %sum = scf.for %arg3 = %c0 to %c96 step %c1 iter_args(%does_not_alias_aggregated = %3) -> (i8) {237    // CHECK:               %[[LOAD0_INNER:.*]] = memref.load %[[VAL_0]]{{\[}}%[[VAL_20]], %[[OUTER_I]]]238    // CHECK:               %[[SUM_0:.*]] = arith.addi %[[LOAD0_INNER]], %[[LOAD0]]239    // CHECK:               %[[ONE_1:.*]] = arith.constant 1240    // CHECK:               %[[INC1_INNER:.*]] = arith.addi %[[OUTER_I]], %[[ONE_1]]241    // CHECK:               %[[LOAD1_INNER:.*]] = memref.load %[[VAL_0]]{{\[}}%[[VAL_20]], %[[INC1_INNER]]]242    // CHECK:               %[[SUM_1:.*]] = arith.addi %[[LOAD1_INNER]], %[[LOAD1]]243    // CHECK:               %[[TWO_1:.*]] = arith.constant 2244    // CHECK:               %[[INC2_INNER:.*]] = arith.addi %[[OUTER_I]], %[[TWO_1]]245    // CHECK:               %[[LOAD2_INNER:.*]] = memref.load %[[VAL_0]]{{\[}}%[[VAL_20]], %[[INC2_INNER]]]246    // CHECK:               %[[SUM_2:.*]] = arith.addi %[[LOAD2_INNER]], %[[LOAD2]]247    // CHECK:               %[[THREE_1:.*]] = arith.constant 3248    // CHECK:               %[[INC3_INNER:.*]] = arith.addi %[[OUTER_I]], %[[THREE_1]]249    // CHECK:               %[[LOAD3_INNER:.*]] = memref.load %[[VAL_0]]{{\[}}%[[VAL_20]], %[[INC3_INNER]]]250    // CHECK:               %[[SUM_3:.*]] = arith.addi %[[LOAD3_INNER]], %[[LOAD3]]251		%2 = memref.load %arg0[%arg3, %arg2] : memref<96x128xi8, 3>252		%4 = arith.addi %2, %3 : i8253    // CHECK:               scf.yield %[[SUM_0]], %[[SUM_1]], %[[SUM_2]], %[[SUM_3]]254		scf.yield %4 : i8255	  }256	  memref.store %sum, %arg1[%arg2] : memref<128xi8, 3>257    // CHECK:             memref.store %[[VAL_39:.*]]#0, %[[VAL_1]]{{\[}}%[[OUTER_I]]]258    // CHECK:             %[[ONE_2:.*]] = arith.constant 1259    // CHECK:             %[[INC_STORE1:.*]] = arith.addi %[[OUTER_I]], %[[ONE_2]]260    // CHECK:             memref.store %[[VAL_39]]#1, %[[VAL_1]]{{\[}}%[[INC_STORE1]]]261    // CHECK:             %[[TWO_2:.*]] = arith.constant 2262    // CHECK:             %[[INC_STORE2:.*]] = arith.addi %[[OUTER_I]], %[[TWO_2]]263    // CHECK:             memref.store %[[VAL_39]]#2, %[[VAL_1]]{{\[}}%[[INC_STORE2]]]264    // CHECK:             %[[THREE_2:.*]] = arith.constant 3265    // CHECK:             %[[INC_STORE3:.*]] = arith.addi %[[OUTER_I]], %[[THREE_2]]266    // CHECK:             memref.store %[[VAL_39]]#3, %[[VAL_1]]{{\[}}%[[INC_STORE3]]]267	}268  return269}270 271module attributes {transform.with_named_sequence} {272  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {273    %0 = transform.structured.match ops{["memref.store"]} in %arg1 : (!transform.any_op) -> !transform.any_op274    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">275    transform.loop.unroll_and_jam %1 { factor = 4 } : !transform.op<"scf.for">276    transform.yield277  }278}279 280// -----281 282// CHECK-LABEL: @loop_unroll_and_jam_op283func.func @loop_unroll_and_jam_op() {284  // CHECK:           %[[ZERO:.*]] = arith.constant 0285  // CHECK:           %[[UNUSED_FACTOR:.*]] = arith.constant 4286  // CHECK:           %[[UNUSED_STEP:.*]] = arith.constant 2287  // CHECK:           %[[UNUSED_STEP2:.*]] = arith.constant 2288  // CHECK:           %[[UNUSED_UB:.*]] = arith.constant 4289  // CHECK:           %[[ITER_0_RES:.*]] = arith.addi %[[ZERO]], %[[ZERO]]290  // CHECK:           %[[TWO:.*]] = arith.constant 2291  // CHECK:           %[[STEP_1_I:.*]] = arith.addi %[[ZERO]], %[[TWO]]292  // CHECK:           %[[ITER_1_RES:.*]] = arith.addi %[[STEP_1_I]], %[[STEP_1_I]]293  %c0 = arith.constant 0 : index294  %c4 = arith.constant 4 : index295  %c2 = arith.constant 2 : index296  scf.for %i = %c0 to %c4 step %c2 {297    arith.addi %i, %i : index298  }299  return300}301 302module attributes {transform.with_named_sequence} {303  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {304    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op305    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">306    transform.loop.unroll_and_jam %1 { factor = 4 } : !transform.op<"scf.for">307    transform.yield308  }309}310 311// -----312 313// CHECK-LABEL: @loop_unroll_and_jam_op314func.func @loop_unroll_and_jam_op() {315  // CHECK:           %[[LB:.*]] = arith.constant 0316  // CHECK:           %[[UB:.*]] = arith.constant 4317  // CHECK:           %[[STEP:.*]] = arith.constant 2318  %c0 = arith.constant 0 : index319  %c4 = arith.constant 4 : index320  %c2 = arith.constant 2 : index321  // CHECK:           scf.for %[[I:.*]] = %[[LB]] to %[[UB]] step %[[STEP]] {322  scf.for %i = %c0 to %c4 step %c2 {323    scf.yield324  }325  return326}327 328module attributes {transform.with_named_sequence} {329  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {330    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op331    %1 = transform.get_parent_op %0 {op_name = "scf.for"} : (!transform.any_op) -> !transform.op<"scf.for">332    transform.loop.unroll_and_jam %1 { factor = 2 } : !transform.op<"scf.for">333    transform.yield334  }335}336 337// -----338 339// CHECK-LABEL: @loop_unroll_and_jam_op340// CHECK:  %[[VAL_0:.*]]: memref<21x30xf32, 1>, %[[INIT0:.*]]: f32, %[[INIT1:.*]]: f32) {341func.func @loop_unroll_and_jam_op(%arg0: memref<21x30xf32, 1>, %init : f32, %init1 : f32) {342  // CHECK:           %[[LAST_OUT_ITER:.*]] = arith.constant 20343  // CHECK:           %[[VAL_4:.*]]:2 = affine.for %[[OUTER_I:.*]] = 0 to 20 step 2 iter_args(%[[VAL_6:.*]] = %[[INIT0]], %[[VAL_7:.*]] = %[[INIT0]])344  %0 = affine.for %arg3 = 0 to 21 iter_args(%arg4 = %init) -> (f32) {345    // CHECK:             %[[VAL_8:.*]]:2 = affine.for %[[INNER_I:.*]] = 0 to 30 iter_args(%[[SUM0:.*]] = %[[INIT1]], %[[SUM1:.*]] = %[[INIT1]])346    %1 = affine.for %arg5 = 0 to 30 iter_args(%arg6 = %init1) -> (f32) {347      // CHECK:               %[[LOAD0:.*]] = affine.load %[[VAL_0]]{{\[}}%[[OUTER_I]], %[[INNER_I]]]348      // CHECK:               %[[ITER_SUM0:.*]] = arith.addf %[[SUM0]], %[[LOAD0]]349      // CHECK:               %[[APPLY_OUTER_I:.*]] = affine.apply #map(%[[OUTER_I]])350      // CHECK:               %[[LOAD1:.*]] = affine.load %[[VAL_0]]{{\[}}%[[APPLY_OUTER_I]], %[[INNER_I]]]351      // CHECK:               %[[ITER_SUM1:.*]] = arith.addf %[[SUM1]], %[[LOAD1]]352      // CHECK:               affine.yield %[[ITER_SUM0]], %[[ITER_SUM1]]353      %3 = affine.load %arg0[%arg3, %arg5] : memref<21x30xf32, 1>354      %4 = arith.addf %arg6, %3 : f32355      affine.yield %4 : f32356    }357    // CHECK:             %[[MUL0:.*]] = arith.mulf %[[VAL_6]], %[[VAL_18:.*]]#0358    // CHECK:             %[[VAL_19:.*]] = affine.apply #map(%[[OUTER_I]])359    // CHECK:             %[[MUL1:.*]] = arith.mulf %[[VAL_7]], %[[VAL_18]]#1360    // CHECK:             affine.yield %[[MUL0]], %[[MUL1]]361    // CHECK:           }362    // CHECK:           %[[VAL_21:.*]] = arith.mulf %[[VAL_22:.*]]#0, %[[VAL_22]]#1363    // CHECK:           %[[VAL_23:.*]] = affine.for %[[SUFFIX_I:.*]] = 0 to 30 iter_args(%[[ITER_I:.*]] = %[[INIT1]])364    // CHECK:             %[[LOAD_SUFFIX:.*]] = affine.load %[[VAL_0]]{{\[}}%[[LAST_OUT_ITER]], %[[SUFFIX_I]]]365    // CHECK:             %[[RES:.*]] = arith.addf %[[ITER_I]], %[[LOAD_SUFFIX]]366    // CHECK:             affine.yield %[[RES]]367    %2 = arith.mulf %arg4, %1 : f32368    affine.yield %2 : f32369  }370  // CHECK:           %[[VAL_28:.*]] = arith.mulf %[[VAL_21]], %[[VAL_29:.*]]371  return372}373 374module attributes {transform.with_named_sequence} {375  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {376    %0 = transform.structured.match ops{["arith.addf"]} in %arg1 : (!transform.any_op) -> !transform.any_op377    %1 = transform.get_parent_op %0 {op_name = "affine.for"} : (!transform.any_op) -> !transform.op<"affine.for">378    %2 = transform.get_parent_op %1 {op_name = "affine.for"} : (!transform.op<"affine.for">) -> !transform.op<"affine.for">379    transform.loop.unroll_and_jam %2 { factor = 2 } : !transform.op<"affine.for">380    transform.yield381  }382}383 384// -----385 386func.func @loop_unroll_op() {387  %c0 = arith.constant 0 : index388  %c42 = arith.constant 42 : index389  %c5 = arith.constant 5 : index390  // CHECK: affine.for %[[I:.+]] =391  // expected-remark @below {{affine for loop}}392  affine.for %i = %c0 to %c42 {393    // CHECK-COUNT-4: arith.addi394    arith.addi %i, %i : index395  }396  return397}398 399module attributes {transform.with_named_sequence} {400  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {401    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op402    %1 = transform.get_parent_op %0 {op_name = "affine.for"} : (!transform.any_op) -> !transform.op<"affine.for">403    transform.debug.emit_remark_at %1, "affine for loop" : !transform.op<"affine.for">404    transform.loop.unroll %1 { factor = 4, affine = true } : !transform.op<"affine.for">405    transform.yield406  }407}408 409// -----410 411func.func @test_mixed_loops() {412  %c0 = arith.constant 0 : index413  %c42 = arith.constant 42 : index414  %c5 = arith.constant 5 : index415  scf.for %j = %c0 to %c42 step %c5 {416    // CHECK: affine.for %[[I:.+]] =417    // expected-remark @below {{affine for loop}}418    affine.for %i = %c0 to %c42 {419      // CHECK-COUNT-4: arith.addi420      arith.addi %i, %i : index421    }422  }423  return424}425 426module attributes {transform.with_named_sequence} {427  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {428    %0 = transform.structured.match ops{["arith.addi"]} in %arg1 : (!transform.any_op) -> !transform.any_op429    %1 = transform.get_parent_op %0 {op_name = "affine.for"} : (!transform.any_op) -> !transform.op<"affine.for">430    transform.debug.emit_remark_at %1, "affine for loop" : !transform.op<"affine.for">431    transform.loop.unroll %1 { factor = 4 } : !transform.op<"affine.for">432    transform.yield433  }434}435 436// -----437 438// CHECK-LABEL: func @test_promote_if_one_iteration(439//   CHECK-NOT:   scf.for440//       CHECK:   %[[r:.*]] = "test.foo"441//       CHECK:   return %[[r]]442func.func @test_promote_if_one_iteration(%a: index) -> index {443  %c0 = arith.constant 0 : index444  %c1 = arith.constant 1 : index445  %0 = scf.for %j = %c0 to %c1 step %c1 iter_args(%arg0 = %a) -> index {446    %1 = "test.foo"(%a) : (index) -> (index)447    scf.yield %1 : index448  }449  return %0 : index450}451 452module attributes {transform.with_named_sequence} {453  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {454    %0 = transform.structured.match ops{["scf.for"]} in %arg1 : (!transform.any_op) -> !transform.any_op455    transform.loop.promote_if_one_iteration %0 : !transform.any_op456    transform.yield457  }458}459 460 461// -----462 463// CHECK-LABEL: func @test_structural_conversion_patterns(464// CHECK: scf.for {{.*}} -> (memref<f32>) {465 466func.func @test_structural_conversion_patterns(%a: tensor<f32>) -> tensor<f32> {467  %c0 = arith.constant 0 : index468  %c1 = arith.constant 1 : index469  %c10 = arith.constant 10 : index470  %0 = scf.for %j = %c0 to %c10 step %c1 iter_args(%arg0 = %a) -> tensor<f32> {471    %1 = "test.foo"(%arg0) : (tensor<f32>) -> (tensor<f32>)472    scf.yield %1 : tensor<f32>473  }474  return %0 : tensor<f32>475}476 477module attributes {transform.with_named_sequence} {478  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {479    %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op480    transform.apply_conversion_patterns to %0 {481      transform.apply_conversion_patterns.scf.structural_conversions482    } with type_converter {483      transform.apply_conversion_patterns.transform.test_type_converter484    } {  partial_conversion  } : !transform.any_op485    transform.yield486  }487}488 489// -----490 491// CHECK-LABEL: func @coalesce_i32_loops(492 493// This test checks for loop coalescing success for non-index loop boundaries and step type494func.func @coalesce_i32_loops() {495  // CHECK:           %[[VAL_0:.*]] = arith.constant 0 : i32496  // CHECK:           %[[VAL_1:.*]] = arith.constant 128 : i32497  // CHECK:           %[[VAL_2:.*]] = arith.constant 2 : i32498  // CHECK:           %[[VAL_3:.*]] = arith.constant 64 : i32499  %0 = arith.constant 0 : i32500  %1 = arith.constant 128 : i32501  %2 = arith.constant 2 : i32502  %3 = arith.constant 64 : i32503  // CHECK:           %[[VAL_4:.*]] = arith.constant 64 : i32504  // CHECK:           %[[ZERO:.*]] = arith.constant 0 : i32505  // CHECK:           %[[ONE:.*]] = arith.constant 1 : i32506  // CHECK:           %[[VAL_7:.*]] = arith.constant 32 : i32507  // CHECK:           %[[VAL_8:.*]] = arith.constant 0 : i32508  // CHECK:           %[[VAL_9:.*]] = arith.constant 1 : i32509  // CHECK:           %[[UB:.*]] = arith.muli %[[VAL_4]], %[[VAL_7]] : i32510  // CHECK:           scf.for %[[VAL_11:.*]] = %[[ZERO]] to %[[UB]] step %[[ONE]]  : i32 {511  scf.for %i = %0 to %1 step %2 : i32 {512    scf.for %j = %0 to %3 step %2 : i32 {513      arith.addi %i, %j : i32514    }515  } {coalesce}516  return517}518 519module attributes {transform.with_named_sequence} {520  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {521    %0 = transform.structured.match ops{["scf.for"]} attributes {coalesce} in %arg1 : (!transform.any_op) -> !transform.any_op522    %1 = transform.cast %0 : !transform.any_op to !transform.op<"scf.for">523    %2 = transform.loop.coalesce %1: (!transform.op<"scf.for">) -> (!transform.op<"scf.for">)524    transform.yield525  }526}527 528 529// -----530 531// CHECK-LABEL: func.func @loop_pipeline532func.func @loop_pipeline(%arg0: memref<4x16xf32>, %arg1: vector<16xf32>) -> vector<16xf32> {533   %c0 = arith.constant 0 : index534  %c1 = arith.constant 1 : index535  %cst = arith.constant 0.000000e+00 : f32536  %c3 = arith.constant 3 : index537  // CHECK: vector.transfer_read538  // CHECK: vector.transfer_read539  // CHECK: vector.transfer_read540  // CHECK: arith.addf541  // CHECK: arith.addf542  // CHECK: arith.addf543  %0 = scf.for %arg2 = %c0 to %c3 step %c1 iter_args(%arg3 = %arg1) -> (vector<16xf32>) {544    %1 = vector.transfer_read %arg0[%arg2, %c0], %cst {in_bounds = [true]} : memref<4x16xf32>, vector<16xf32>545    %2 = arith.addf %1, %arg3 : vector<16xf32>546    scf.yield %2 : vector<16xf32>547  }548  return %0 : vector<16xf32>549}550module attributes {transform.with_named_sequence} {551  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {552    %0 = transform.structured.match ops{["scf.for"]} in %arg1 : (!transform.any_op) -> !transform.op<"scf.for">553    %1 = transform.loop.pipeline %0 {iteration_interval = 1 : i64, read_latency = 5 : i64,  scheduling_type = "full-loops"} : (!transform.op<"scf.for">) -> !transform.any_op554     transform.yield555 }556}557 558 559// -----560 561// CHECK-LABEL: func.func @loop_pipeline_lb_gt_0562func.func @loop_pipeline_lb_gt_0(%arg0: memref<4x16xf32>, %arg1: vector<16xf32>) -> vector<16xf32> {563  %c1 = arith.constant 1 : index564  %cst = arith.constant 0.000000e+00 : f32565  %c3 = arith.constant 3 : index566  // CHECK: vector.transfer_read567  // CHECK: vector.transfer_read568  // CHECK: arith.addf569  // CHECK: arith.addf570  %0 = scf.for %arg2 = %c1 to %c3 step %c1 iter_args(%arg3 = %arg1) -> (vector<16xf32>) {571    %1 = vector.transfer_read %arg0[%arg2, %c1], %cst {in_bounds = [true]} : memref<4x16xf32>, vector<16xf32>572    %2 = arith.addf %1, %arg3 : vector<16xf32>573    scf.yield %2 : vector<16xf32>574  }575  return %0 : vector<16xf32>576}577module attributes {transform.with_named_sequence} {578  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {579    %0 = transform.structured.match ops{["scf.for"]} in %arg1 : (!transform.any_op) -> !transform.op<"scf.for">580    %1 = transform.loop.pipeline %0 {iteration_interval = 1 : i64, read_latency = 5 : i64,  scheduling_type = "full-loops"} : (!transform.op<"scf.for">) -> !transform.any_op581     transform.yield582 }583}584