brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.3 KiB · 75d8386 Raw
491 lines · plain
1// RUN: mlir-opt --allow-unregistered-dialect --transform-interpreter --split-input-file --verify-diagnostics %s | FileCheck %s2 3// Check simple move of dependent operation before insertion.4func.func @simple_move() -> f32 {5  %0 = "before"() : () -> (f32)6  %1 = "moved_op"() : () -> (f32)7  %2 = "foo"(%1) : (f32) -> (f32)8  return %2 : f329}10// CHECK-LABEL: func @simple_move()11//       CHECK:   %[[MOVED:.+]] = "moved_op"12//       CHECK:   %[[BEFORE:.+]] = "before"13//       CHECK:   %[[FOO:.+]] = "foo"(%[[MOVED]])14//       CHECK:   return %[[FOO]]15 16module attributes {transform.with_named_sequence} {17  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {18    %op1 = transform.structured.match ops{["foo"]} in %arg019        : (!transform.any_op) -> !transform.any_op20    %op2 = transform.structured.match ops{["before"]} in %arg021        : (!transform.any_op) -> !transform.any_op22    transform.test.move_operand_deps %op1 before %op223        : !transform.any_op, !transform.any_op24    transform.yield25  }26}27 28// -----29 30// Move operands that are implicitly captured by the op31func.func @move_region_dependencies() -> f32 {32  %0 = "before"() : () -> (f32)33  %1 = "moved_op"() : () -> (f32)34  %2 = "foo"() ({35    %3 = "inner_op"(%1) : (f32) -> (f32)36    "yield"(%3) : (f32) -> ()37  }) : () -> (f32)38  return %2 : f3239}40// CHECK-LABEL: func @move_region_dependencies()41//       CHECK:   %[[MOVED:.+]] = "moved_op"42//       CHECK:   %[[BEFORE:.+]] = "before"43//       CHECK:   %[[FOO:.+]] = "foo"44//       CHECK:   return %[[FOO]]45 46module attributes {transform.with_named_sequence} {47  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {48    %op1 = transform.structured.match ops{["foo"]} in %arg049        : (!transform.any_op) -> !transform.any_op50    %op2 = transform.structured.match ops{["before"]} in %arg051        : (!transform.any_op) -> !transform.any_op52    transform.test.move_operand_deps %op1 before %op253        : !transform.any_op, !transform.any_op54    transform.yield55  }56}57 58// -----59 60// Move operations in toplogical sort order61func.func @move_in_topological_sort_order() -> f32 {62  %0 = "before"() : () -> (f32)63  %1 = "moved_op_1"() : () -> (f32)64  %2 = "moved_op_2"() : () -> (f32)65  %3 = "moved_op_3"(%1) : (f32) -> (f32)66  %4 = "moved_op_4"(%1, %3) : (f32, f32) -> (f32)67  %5 = "moved_op_5"(%2) : (f32) -> (f32)68  %6 = "foo"(%4, %5) : (f32, f32) -> (f32)69  return %6 : f3270}71// CHECK-LABEL: func @move_in_topological_sort_order()72//       CHECK:   %[[MOVED_1:.+]] = "moved_op_1"73//   CHECK-DAG:   %[[MOVED_2:.+]] = "moved_op_3"(%[[MOVED_1]])74//   CHECK-DAG:   %[[MOVED_3:.+]] = "moved_op_4"(%[[MOVED_1]], %[[MOVED_2]])75//   CHECK-DAG:   %[[MOVED_4:.+]] = "moved_op_2"76//   CHECK-DAG:   %[[MOVED_5:.+]] = "moved_op_5"(%[[MOVED_4]])77//       CHECK:   %[[BEFORE:.+]] = "before"78//       CHECK:   %[[FOO:.+]] = "foo"(%[[MOVED_3]], %[[MOVED_5]])79//       CHECK:   return %[[FOO]]80 81module attributes {transform.with_named_sequence} {82  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {83    %op1 = transform.structured.match ops{["foo"]} in %arg084        : (!transform.any_op) -> !transform.any_op85    %op2 = transform.structured.match ops{["before"]} in %arg086        : (!transform.any_op) -> !transform.any_op87    transform.test.move_operand_deps %op1 before %op288        : !transform.any_op, !transform.any_op89    transform.yield90  }91}92 93// -----94 95func.func @move_region_dependencies() -> f32 {96  %0 = "before"() : () -> (f32)97  %1 = "moved_op_1"() : () -> (f32)98  %2 = "moved_op_2"() ({99    "yield"(%1) : (f32) -> ()100  }) : () -> (f32)101  %3 = "foo"() ({102    "yield"(%2) : (f32) -> ()103  }) : () -> (f32)104  return %3 : f32105}106 107module attributes {transform.with_named_sequence} {108  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {109    %op1 = transform.structured.match ops{["foo"]} in %arg0110        : (!transform.any_op) -> !transform.any_op111    %op2 = transform.structured.match ops{["before"]} in %arg0112        : (!transform.any_op) -> !transform.any_op113    transform.test.move_operand_deps %op1 before %op2114        : !transform.any_op, !transform.any_op115    transform.yield116  }117}118// CHECK-LABEL: func @move_region_dependencies()119//       CHECK:   %[[MOVED_1:.+]] = "moved_op_1"120//       CHECK:   %[[MOVED_2:.+]] = "moved_op_2"121//       CHECK:     "yield"(%[[MOVED_1]])122//       CHECK:   "before"123//       CHECK:   %[[FOO:.+]] = "foo"124//       CHECK:   return %[[FOO]]125 126// -----127 128// Current implementation omits following basic block argument when129// computing slices. Verify that this gives expected result.130func.func @ignore_basic_block_arguments() -> f32 {131^bb0():132  %8 = "test"() : () -> (f32)133  return %8: f32134^bb1(%bbArg : f32):135  %0 = "before"() : () -> (f32)136  %1 = "moved_op"() ({137    "yield"(%bbArg) : (f32) -> ()138  }) : () -> (f32)139  %2 = "foo"() ({140    "yield"(%1) : (f32) -> ()141  }) : () -> (f32)142  return %2 : f32143}144 145module attributes {transform.with_named_sequence} {146  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {147    %op1 = transform.structured.match ops{["foo"]} in %arg0148        : (!transform.any_op) -> !transform.any_op149    %op2 = transform.structured.match ops{["before"]} in %arg0150        : (!transform.any_op) -> !transform.any_op151    transform.test.move_operand_deps %op1 before %op2152        : !transform.any_op, !transform.any_op153    transform.yield154  }155}156// CHECK-LABEL: func @ignore_basic_block_arguments()157//       CHECK:   %[[MOVED_1:.+]] = "moved_op"158//       CHECK:   "before"159//       CHECK:   %[[FOO:.+]] = "foo"160//       CHECK:   return %[[FOO]]161 162// -----163 164// Fail when the "before" operation is part of the operation slice.165func.func @do_not_move_slice() -> f32 {166  %0 = "before"() : () -> (f32)167  %1 = "moved_op"(%0) : (f32) -> (f32)168  %2 = "foo"(%1) : (f32) -> (f32)169  return %2 : f32170}171 172module attributes {transform.with_named_sequence} {173  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {174    %op1 = transform.structured.match ops{["foo"]} in %arg0175        : (!transform.any_op) -> !transform.any_op176    %op2 = transform.structured.match ops{["before"]} in %arg0177        : (!transform.any_op) -> !transform.any_op178    // expected-remark@+1{{cannot move dependencies before operation in backward slice of op}}179    transform.test.move_operand_deps %op1 before %op2180        : !transform.any_op, !transform.any_op181    transform.yield182  }183}184 185// -----186 187// Fail when the "before" operation is part of the operation slice (computed188// when looking through implicitly captured values).189func.func @do_not_move_slice() -> f32 {190  %0 = "before"() : () -> (f32)191  %1 = "moved_op"() ({192    "yield"(%0) : (f32) -> ()193  }) : () -> (f32)194  %2 = "foo"() ({195    "yield"(%1) : (f32) -> ()196  }) : () -> (f32)197  return %2 : f32198}199 200module attributes {transform.with_named_sequence} {201  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {202    %op1 = transform.structured.match ops{["foo"]} in %arg0203        : (!transform.any_op) -> !transform.any_op204    %op2 = transform.structured.match ops{["before"]} in %arg0205        : (!transform.any_op) -> !transform.any_op206    // expected-remark@+1{{cannot move dependencies before operation in backward slice of op}}207    transform.test.move_operand_deps %op1 before %op2208        : !transform.any_op, !transform.any_op209    transform.yield210  }211}212 213// -----214 215// Dont move ops when insertion point does not dominate the op216func.func @do_not_move() -> f32 {217  %1 = "moved_op"() : () -> (f32)218  %2 = "foo"() ({219    "yield"(%1) : (f32) -> ()220  }) : () -> (f32)221  %3 = "before"() : () -> f32222  return %2 : f32223}224 225module attributes {transform.with_named_sequence} {226  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {227    %op1 = transform.structured.match ops{["foo"]} in %arg0228        : (!transform.any_op) -> !transform.any_op229    %op2 = transform.structured.match ops{["before"]} in %arg0230        : (!transform.any_op) -> !transform.any_op231    // expected-remark@+1{{insertion point does not dominate op}}232    transform.test.move_operand_deps %op1 before %op2233        : !transform.any_op, !transform.any_op234    transform.yield235  }236}237 238// -----239 240// Check simple move value definitions before insertion operation.241func.func @simple_move_values() -> f32 {242  %0 = "before"() : () -> (f32)243  %1 = "moved_op_1"() : () -> (f32)244  %2 = "moved_op_2"() : () -> (f32)245  %3 = "foo"(%1, %2) : (f32, f32) -> (f32)246  return %3 : f32247}248// CHECK-LABEL: func @simple_move_values()249//       CHECK:   %[[MOVED1:.+]] = "moved_op_1"250//       CHECK:   %[[MOVED2:.+]] = "moved_op_2"251//       CHECK:   %[[BEFORE:.+]] = "before"252//       CHECK:   %[[FOO:.+]] = "foo"(%[[MOVED1]], %[[MOVED2]])253//       CHECK:   return %[[FOO]]254 255module attributes {transform.with_named_sequence} {256  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {257    %op1 = transform.structured.match ops{["moved_op_1"]} in %arg0258        : (!transform.any_op) -> !transform.any_op259    %op2 = transform.structured.match ops{["moved_op_2"]} in %arg0260        : (!transform.any_op) -> !transform.any_op261    %op3 = transform.structured.match ops{["before"]} in %arg0262        : (!transform.any_op) -> !transform.any_op263    %v1 = transform.get_result %op1[0] : (!transform.any_op) -> !transform.any_value264    %v2 = transform.get_result %op2[0] : (!transform.any_op) -> !transform.any_value265    transform.test.move_value_defns %v1, %v2 before %op3266        : (!transform.any_value, !transform.any_value), !transform.any_op267    transform.yield268  }269}270 271// -----272 273// Compute slice including the implicitly captured values.274func.func @move_region_dependencies_values() -> f32 {275  %0 = "before"() : () -> (f32)276  %1 = "moved_op_1"() : () -> (f32)277  %2 = "moved_op_2"() ({278    %3 = "inner_op"(%1) : (f32) -> (f32)279    "yield"(%3) : (f32) -> ()280  }) : () -> (f32)281  return %2 : f32282}283// CHECK-LABEL: func @move_region_dependencies_values()284//       CHECK:   %[[MOVED1:.+]] = "moved_op_1"285//       CHECK:   %[[MOVED2:.+]] = "moved_op_2"286//       CHECK:   %[[BEFORE:.+]] = "before"287 288module attributes {transform.with_named_sequence} {289  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {290    %op1 = transform.structured.match ops{["moved_op_2"]} in %arg0291        : (!transform.any_op) -> !transform.any_op292    %op2 = transform.structured.match ops{["before"]} in %arg0293        : (!transform.any_op) -> !transform.any_op294    %v1 = transform.get_result %op1[0] : (!transform.any_op) -> !transform.any_value295    transform.test.move_value_defns %v1 before %op2296        : (!transform.any_value), !transform.any_op297    transform.yield298  }299}300 301// -----302 303// Move operations in toplogical sort order304func.func @move_values_in_topological_sort_order() -> f32 {305  %0 = "before"() : () -> (f32)306  %1 = "moved_op_1"() : () -> (f32)307  %2 = "moved_op_2"() : () -> (f32)308  %3 = "moved_op_3"(%1) : (f32) -> (f32)309  %4 = "moved_op_4"(%1, %3) : (f32, f32) -> (f32)310  %5 = "moved_op_5"(%2) : (f32) -> (f32)311  %6 = "foo"(%4, %5) : (f32, f32) -> (f32)312  return %6 : f32313}314// CHECK-LABEL: func @move_values_in_topological_sort_order()315//       CHECK:   %[[MOVED_1:.+]] = "moved_op_1"316//   CHECK-DAG:   %[[MOVED_2:.+]] = "moved_op_3"(%[[MOVED_1]])317//   CHECK-DAG:   %[[MOVED_3:.+]] = "moved_op_4"(%[[MOVED_1]], %[[MOVED_2]])318//   CHECK-DAG:   %[[MOVED_4:.+]] = "moved_op_2"319//   CHECK-DAG:   %[[MOVED_5:.+]] = "moved_op_5"(%[[MOVED_4]])320//       CHECK:   %[[BEFORE:.+]] = "before"321//       CHECK:   %[[FOO:.+]] = "foo"(%[[MOVED_3]], %[[MOVED_5]])322//       CHECK:   return %[[FOO]]323 324module attributes {transform.with_named_sequence} {325  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {326    %op1 = transform.structured.match ops{["moved_op_4"]} in %arg0327        : (!transform.any_op) -> !transform.any_op328    %op2 = transform.structured.match ops{["moved_op_5"]} in %arg0329        : (!transform.any_op) -> !transform.any_op330    %op3 = transform.structured.match ops{["before"]} in %arg0331        : (!transform.any_op) -> !transform.any_op332    %v1 = transform.get_result %op1[0] : (!transform.any_op) -> !transform.any_value333    %v2 = transform.get_result %op2[0] : (!transform.any_op) -> !transform.any_value334    transform.test.move_value_defns %v1, %v2 before %op3335        : (!transform.any_value, !transform.any_value), !transform.any_op336    transform.yield337  }338}339 340// -----341 342// Move only those value definitions that are not dominated by insertion point343 344func.func @move_only_required_defns() -> (f32, f32, f32, f32) {345  %0 = "unmoved_op"() : () -> (f32)346  %1 = "dummy_op"() : () -> (f32)347  %2 = "before"() : () -> (f32)348  %3 = "moved_op"() : () -> (f32)349  return %0, %1, %2, %3 : f32, f32, f32, f32350}351// CHECK-LABEL: func @move_only_required_defns()352//       CHECK:   %[[UNMOVED:.+]] = "unmoved_op"353//       CHECK:   %[[DUMMY:.+]] = "dummy_op"354//       CHECK:   %[[MOVED:.+]] = "moved_op"355//       CHECK:   %[[BEFORE:.+]] = "before"356 357module attributes {transform.with_named_sequence} {358  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {359    %op1 = transform.structured.match ops{["unmoved_op"]} in %arg0360        : (!transform.any_op) -> !transform.any_op361    %op2 = transform.structured.match ops{["dummy_op"]} in %arg0362        : (!transform.any_op) -> !transform.any_op363    %op3 = transform.structured.match ops{["before"]} in %arg0364        : (!transform.any_op) -> !transform.any_op365    %op4 = transform.structured.match ops{["moved_op"]} in %arg0366        : (!transform.any_op) -> !transform.any_op367    %v1 = transform.get_result %op1[0] : (!transform.any_op) -> !transform.any_value368    %v2 = transform.get_result %op4[0] : (!transform.any_op) -> !transform.any_value369    transform.test.move_value_defns %v1, %v2 before %op3370        : (!transform.any_value, !transform.any_value), !transform.any_op371    transform.yield372  }373}374 375// -----376 377// Move only those value definitions that are not dominated by insertion point378 379func.func @move_only_required_defns() -> (f32, f32, f32, f32) {380  %0 = "unmoved_op"() : () -> (f32)381  %1 = "dummy_op"() : () -> (f32)382  %2 = "before"() : () -> (f32)383  %3 = "moved_op"() : () -> (f32)384  return %0, %1, %2, %3 : f32, f32, f32, f32385}386// CHECK-LABEL: func @move_only_required_defns()387//       CHECK:   %[[UNMOVED:.+]] = "unmoved_op"388//       CHECK:   %[[DUMMY:.+]] = "dummy_op"389//       CHECK:   %[[MOVED:.+]] = "moved_op"390//       CHECK:   %[[BEFORE:.+]] = "before"391 392module attributes {transform.with_named_sequence} {393  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {394    %op1 = transform.structured.match ops{["unmoved_op"]} in %arg0395        : (!transform.any_op) -> !transform.any_op396    %op2 = transform.structured.match ops{["dummy_op"]} in %arg0397        : (!transform.any_op) -> !transform.any_op398    %op3 = transform.structured.match ops{["before"]} in %arg0399        : (!transform.any_op) -> !transform.any_op400    %op4 = transform.structured.match ops{["moved_op"]} in %arg0401        : (!transform.any_op) -> !transform.any_op402    %v1 = transform.get_result %op1[0] : (!transform.any_op) -> !transform.any_value403    %v2 = transform.get_result %op4[0] : (!transform.any_op) -> !transform.any_value404    transform.test.move_value_defns %v1, %v2 before %op3405        : (!transform.any_value, !transform.any_value), !transform.any_op406    transform.yield407  }408}409 410// -----411 412// Check handling of block arguments413func.func @move_only_required_defns() -> (f32, f32) {414  %0 = "unmoved_op"() : () -> (f32)415  cf.br ^bb0(%0 : f32) 416 ^bb0(%arg0 : f32) :417  %1 = "before"() : () -> (f32)418  %2 = "moved_op"(%arg0) : (f32) -> (f32)419  return %1, %2 : f32, f32420}421// CHECK-LABEL: func @move_only_required_defns()422//       CHECK:   %[[MOVED:.+]] = "moved_op"423//       CHECK:   %[[BEFORE:.+]] = "before"424 425module attributes {transform.with_named_sequence} {426  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {427    %op1 = transform.structured.match ops{["before"]} in %arg0428        : (!transform.any_op) -> !transform.any_op429    %op2 = transform.structured.match ops{["moved_op"]} in %arg0430        : (!transform.any_op) -> !transform.any_op431    %v1 = transform.get_result %op2[0] : (!transform.any_op) -> !transform.any_value432    transform.test.move_value_defns %v1 before %op1433        : (!transform.any_value), !transform.any_op434    transform.yield435  }436}437 438// -----439 440// Do not move across basic blocks441func.func @no_move_across_basic_blocks() -> (f32, f32) {442  %0 = "unmoved_op"() : () -> (f32)443  %1 = "before"() : () -> (f32)444  cf.br ^bb0(%0 : f32) 445 ^bb0(%arg0 : f32) :446  %2 = "moved_op"(%arg0) : (f32) -> (f32)447  return %1, %2 : f32, f32448}449 450module attributes {transform.with_named_sequence} {451  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {452    %op1 = transform.structured.match ops{["before"]} in %arg0453        : (!transform.any_op) -> !transform.any_op454    %op2 = transform.structured.match ops{["moved_op"]} in %arg0455        : (!transform.any_op) -> !transform.any_op456    %v1 = transform.get_result %op2[0] : (!transform.any_op) -> !transform.any_value457    // expected-remark@+1{{unsupported case of moving definition of value before an insertion point in a different basic block}}458    transform.test.move_value_defns %v1 before %op1459        : (!transform.any_value), !transform.any_op460    transform.yield461  }462}463 464// -----465 466func.func @move_isolated_from_above() -> () {467  %1 = "before"() : () -> (f32)468  %2 = "moved0"() : () -> (f32)469  %3 = test.isolated_one_region_op %2 {} : f32 -> f32470  %4 = "moved1"(%3) : (f32) -> (f32)471  return472}473// CHECK-LABEL: func @move_isolated_from_above()474//       CHECK:   %[[MOVED0:.+]] = "moved0"475//       CHECK:   %[[ISOLATED:.+]] = test.isolated_one_region_op %[[MOVED0]]476//       CHECK:   %[[MOVED1:.+]] = "moved1"(%[[ISOLATED]])477//       CHECK:   %[[BEFORE:.+]] = "before"478 479module attributes {transform.with_named_sequence} {480  transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {481    %op1 = transform.structured.match ops{["before"]} in %arg0482        : (!transform.any_op) -> !transform.any_op483    %op2 = transform.structured.match ops{["moved1"]} in %arg0484        : (!transform.any_op) -> !transform.any_op485    %v1 = transform.get_result %op2[0] : (!transform.any_op) -> !transform.any_value486    transform.test.move_value_defns %v1 before %op1487        : (!transform.any_value), !transform.any_op488    transform.yield489  }490}491