brintos

brintos / llvm-project-archived public Read only

0
0
Text · 31.5 KiB · ffb78c2 Raw
780 lines · plain
1// RUN: mlir-opt -test-greedy-patterns -mlir-print-debuginfo -mlir-print-local-scope %s | FileCheck %s2 3// CHECK-LABEL: verifyFusedLocs4func.func @verifyFusedLocs(%arg0 : i32) -> i32 {5  %0 = "test.op_a"(%arg0) {attr = 10 : i32} : (i32) -> i32 loc("a")6  %result = "test.op_a"(%0) {attr = 20 : i32} : (i32) -> i32 loc("b")7 8  // CHECK: "test.op_b"(%arg0) <{attr = 10 : i32}> : (i32) -> i32 loc("a")9  // CHECK: "test.op_b"(%arg0) <{attr = 20 : i32}> : (i32) -> i32 loc(fused["b", "a"])10  return %result : i3211}12 13// CHECK-LABEL: verifyDesignatedLoc14func.func @verifyDesignatedLoc(%arg0 : i32) -> i32 {15  %0 = "test.loc_src"(%arg0) : (i32) -> i32 loc("loc3")16  %1 = "test.loc_src"(%0) : (i32) -> i32 loc("loc2")17  %2 = "test.loc_src"(%1) : (i32) -> i32 loc("loc1")18  "test.loc_src_no_res"(%2) : (i32) -> () loc("loc4")19 20  // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc("loc1")21  // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc("named")22  // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc(fused<"fused">["loc2", "loc3"])23  // CHECK: "test.loc_dst_no_res"({{.*}}) : (i32) -> () loc("loc4")24  return %1 : i3225}26 27// CHECK-LABEL: verifyZeroResult28func.func @verifyZeroResult(%arg0 : i32) {29  // CHECK: "test.op_i"(%arg0) : (i32) -> ()30  "test.op_h"(%arg0) : (i32) -> ()31  return32}33 34// CHECK-LABEL: verifyZeroArg35func.func @verifyZeroArg() -> i32 {36  // CHECK: "test.op_k"() : () -> i3237  %0 = "test.op_j"() : () -> i3238  return %0 : i3239}40 41// CHECK-LABEL: testIgnoreArgMatch42// CHECK-SAME: (%{{[a-z0-9]*}}: i32 loc({{[^)]*}}), %[[ARG1:[a-z0-9]*]]: i32 loc({{[^)]*}}),43func.func @testIgnoreArgMatch(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: f32) {44  // CHECK: "test.ignore_arg_match_dst"(%[[ARG1]]) <{f = 15 : i64}>45  "test.ignore_arg_match_src"(%arg0, %arg1, %arg2) {d = 42, e = 24, f = 15} : (i32, i32, i32) -> ()46 47  // CHECK: test.ignore_arg_match_src48  // Not match because wrong type for $c.49  "test.ignore_arg_match_src"(%arg0, %arg1, %arg3) {d = 42, e = 24, f = 15} : (i32, i32, f32) -> ()50 51  // CHECK: test.ignore_arg_match_src52  // Not match because wrong type for $f.53  "test.ignore_arg_match_src"(%arg0, %arg1, %arg2) {d = 42 : i32, e = 24, f = 15} : (i32, i32, i32) -> ()54  return55}56 57// CHECK-LABEL: verifyInterleavedOperandAttribute58// CHECK-SAME:    %[[ARG0:.*]]: i32 loc({{[^)]*}}), %[[ARG1:.*]]: i32 loc({{[^)]*}})59func.func @verifyInterleavedOperandAttribute(%arg0: i32, %arg1: i32) {60  // CHECK: "test.interleaved_operand_attr2"(%[[ARG0]], %[[ARG1]]) <{attr1 = 15 : i64, attr2 = 42 : i64}>61  "test.interleaved_operand_attr1"(%arg0, %arg1) {attr1 = 15, attr2 = 42} : (i32, i32) -> ()62  return63}64 65// CHECK-LABEL: verifyBenefit66func.func @verifyBenefit(%arg0 : i32) -> i32 {67  %0 = "test.op_d"(%arg0) : (i32) -> i3268  %1 = "test.op_g"(%arg0) : (i32) -> i3269  %2 = "test.op_g"(%1) : (i32) -> i3270 71  // CHECK: "test.op_f"(%arg0)72  // CHECK: "test.op_b"(%arg0) <{attr = 34 : i32}>73  return %0 : i3274}75 76// CHECK-LABEL: verifyNativeCodeCall77func.func @verifyNativeCodeCall(%arg0: i32, %arg1: i32) -> (i32, i32) {78  // CHECK: %0 = "test.native_code_call2"(%arg0) <{attr = [42, 24]}> : (i32) -> i3279  // CHECK:  return %0, %arg180  %0 = "test.native_code_call1"(%arg0, %arg1) {choice = true, attr1 = 42, attr2 = 24} : (i32, i32) -> (i32)81  %1 = "test.native_code_call1"(%arg0, %arg1) {choice = false, attr1 = 42, attr2 = 24} : (i32, i32) -> (i32)82  return %0, %1: i32, i3283}84 85// CHECK-LABEL: verifyAuxiliaryNativeCodeCall86func.func @verifyAuxiliaryNativeCodeCall(%arg0: i32) -> (i32) {87  // CHECK: test.op_i88  // CHECK: test.op_k89  %0 = "test.native_code_call3"(%arg0) : (i32) -> (i32)90  return %0 : i3291}92 93// CHECK-LABEL: verifyNativeCodeCallBinding94func.func @verifyNativeCodeCallBinding(%arg0 : i32) -> (i32) {95  %0 = "test.op_k"() : () -> (i32)96  // CHECK: %[[A:.*]], %[[B:.*]] = "test.native_code_call5"(%1, %1) : (i32, i32) -> (i32, i32)97  %1, %2 = "test.native_code_call4"(%0) : (i32) -> (i32, i32)98  %3 = "test.constant"() {value = 1 : i8} : () -> i899  // %3 is i8 so it'll fail at GetFirstI32Result match. The operation should100  // keep the same form.101  // CHECK: %{{.*}}, %{{.*}} = "test.native_code_call4"({{%.*}}) : (i8) -> (i32, i32)102  %4, %5 = "test.native_code_call4"(%3) : (i8) -> (i32, i32)103  // CHECK: return %[[A]]104  return %1 : i32105}106 107// CHECK-LABEL: verifyMultipleNativeCodeCallBinding108func.func @verifyMultipleNativeCodeCallBinding(%arg0 : i32) -> (i32) {109  %0 = "test.op_k"() : () -> (i32)110  %1 = "test.op_k"() : () -> (i32)111  // CHECK: %[[A:.*]] = "test.native_code_call7"(%1) : (i32) -> i32112  // CHECK: %[[A:.*]] = "test.native_code_call7"(%0) : (i32) -> i32113  %2, %3 = "test.native_code_call6"(%0, %1) : (i32, i32) -> (i32, i32)114  return %2 : i32115}116 117// CHECK-LABEL: verifyAllAttrConstraintOf118func.func @verifyAllAttrConstraintOf() -> (i32, i32, i32) {119  // CHECK: "test.all_attr_constraint_of2"120  %0 = "test.all_attr_constraint_of1"() {attr = [0, 1]} : () -> (i32)121  // CHECK: "test.all_attr_constraint_of1"122  %1 = "test.all_attr_constraint_of1"() {attr = [0, 2]} : () -> (i32)123  // CHECK: "test.all_attr_constraint_of1"124  %2 = "test.all_attr_constraint_of1"() {attr = [-1, 1]} : () -> (i32)125  return %0, %1, %2: i32, i32, i32126}127 128// CHECK-LABEL: verifyManyArgs129// CHECK-SAME: (%[[ARG:.*]]: i32 loc({{[^)]*}}))130func.func @verifyManyArgs(%arg: i32) {131  // CHECK: "test.many_arguments"(%[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]])132  // CHECK-SAME: {attr1 = 24 : i64, attr2 = 42 : i64, attr3 = 42 : i64, attr4 = 42 : i64, attr5 = 42 : i64, attr6 = 42 : i64, attr7 = 42 : i64, attr8 = 42 : i64, attr9 = 42 : i64}133  "test.many_arguments"(%arg, %arg, %arg, %arg, %arg, %arg, %arg, %arg, %arg) {134    attr1 = 42, attr2 = 42, attr3 = 42, attr4 = 42, attr5 = 42,135    attr6 = 42, attr7 = 42, attr8 = 42, attr9 = 42136  } : (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> ()137  return138}139 140// CHECK-LABEL: verifyEqualArgs141func.func @verifyEqualArgs(%arg0: i32, %arg1: i32) {142  // def TestEqualArgsPattern : Pat<(OpN $a, $a), (OpO $a)>;143 144  // CHECK: "test.op_o"(%arg0) : (i32) -> i32145  "test.op_n"(%arg0, %arg0) : (i32, i32) -> (i32)146 147  // CHECK: "test.op_n"(%arg0, %arg1) : (i32, i32) -> i32148  "test.op_n"(%arg0, %arg1) : (i32, i32) -> (i32)149 150  return151}152 153// CHECK-LABEL: verifyNestedOpEqualArgs154func.func @verifyNestedOpEqualArgs(155  %arg0: i32, %arg1: i32, %arg2 : i32, %arg3 : i32, %arg4 : i32, %arg5 : i32) {156  // def TestNestedOpEqualArgsPattern :157  //   Pat<(OpN $b, (OpP $a, $b, $c, $d, $e, $f)), (replaceWithValue $b)>;158 159  // CHECK: "test.op_o"(%arg1)160  %0 = "test.op_p"(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5)161    : (i32, i32, i32, i32, i32, i32) -> (i32)162  %1 = "test.op_n"(%arg1, %0) : (i32, i32) -> (i32)163  %2 = "test.op_o"(%1) : (i32) -> (i32)164 165  // CHECK-NEXT: %[[P:.*]] = "test.op_p"166  // CHECK-NEXT: %[[N:.*]] = "test.op_n"(%arg0, %[[P]])167  // CHECK-NEXT: "test.op_o"(%[[N]])168  %3 = "test.op_p"(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5)169    : (i32, i32, i32, i32, i32, i32) -> (i32)170  %4 = "test.op_n"(%arg0, %3) : (i32, i32) -> (i32)171  %5 = "test.op_o"(%4) : (i32) -> (i32)172 173  return174}175 176// CHECK-LABEL: verifyNestedSameOpAndSameArgEquality177func.func @verifyNestedSameOpAndSameArgEquality(%arg0: i32, %arg1: i32) -> i32 {178  // def TestNestedSameOpAndSameArgEqualityPattern:179  //   Pat<(OpN (OpN $_, $x), $x), (replaceWithValue $x)>;180 181  %0 = "test.op_n"(%arg1, %arg0) : (i32, i32) -> (i32)182  %1 = "test.op_n"(%0, %arg0) : (i32, i32) -> (i32)183  // CHECK: return %arg0 : i32184  return %1 : i32185}186 187// CHECK-LABEL: verifyMultipleEqualArgs188func.func @verifyMultipleEqualArgs(189  %arg0: i32, %arg1 : i32, %arg2 : i32, %arg3 : i32, %arg4 : i32) {190  // def TestMultipleEqualArgsPattern :191  //   Pat<(OpP $a, $b, $a, $a, $b, $c), (OpN $c, $b)>;192 193  // CHECK: "test.op_n"(%arg2, %arg1) : (i32, i32) -> i32194  "test.op_p"(%arg0, %arg1, %arg0, %arg0, %arg1, %arg2) :195    (i32, i32, i32, i32 , i32, i32) -> i32196 197  // CHECK: test.op_p198  "test.op_p"(%arg0, %arg1, %arg0, %arg0, %arg0, %arg2) :199    (i32, i32, i32, i32 , i32, i32) -> i32200 201  // CHECK: test.op_p202  "test.op_p"(%arg0, %arg1, %arg1, %arg0, %arg1, %arg2) :203    (i32, i32, i32, i32 , i32, i32) -> i32204 205   // CHECK: test.op_p206  "test.op_p"(%arg0, %arg1, %arg2, %arg2, %arg3, %arg4) :207    (i32, i32, i32, i32 , i32, i32) -> i32208 209  return210}211 212func.func @verifyEqualArgsCheckBeforeUserConstraints(%arg0: i32, %arg1: f32) {213  // def TestEqualArgsCheckBeforeUserConstraintsPattern :214  //   Pat<(OpQ:$op $x, $x),215  //       (replaceWithValue $x),216  //       [(AssertBinOpEqualArgsAndReturnTrue $op)]>;217 218  // CHECK: "test.op_q"(%arg0, %arg1)219  %0 = "test.op_q"(%arg0, %arg1) : (i32, f32) -> (i32)220 221  // CHECK: "test.op_q"(%arg1, %arg0)222  %1 = "test.op_q"(%arg1, %arg0) : (f32, i32) -> (i32)223 224  return225}226 227//===----------------------------------------------------------------------===//228// Test Symbol Binding229//===----------------------------------------------------------------------===//230 231// CHECK-LABEL: symbolBinding232func.func @symbolBinding(%arg0: i32) -> i32 {233  // An op with one use is matched.234  // CHECK: %0 = "test.symbol_binding_b"(%arg0)235  // CHECK: %1 = "test.symbol_binding_c"(%0)236  // CHECK: %2 = "test.symbol_binding_d"(%0, %1) <{attr = 42 : i64}>237  %0 = "test.symbol_binding_a"(%arg0) {attr = 42} : (i32) -> (i32)238 239  // An op without any use is not matched.240  // CHECK: "test.symbol_binding_a"(%arg0)241  %1 = "test.symbol_binding_a"(%arg0) {attr = 42} : (i32) -> (i32)242 243  // CHECK: return %2244  return %0: i32245}246 247// CHECK-LABEL: symbolBindingNoResult248func.func @symbolBindingNoResult(%arg0: i32) {249  // CHECK: test.symbol_binding_b250  "test.symbol_binding_no_result"(%arg0) : (i32) -> ()251  return252}253 254//===----------------------------------------------------------------------===//255// Test Attributes256//===----------------------------------------------------------------------===//257 258// CHECK-LABEL: succeedMatchOpAttr259func.func @succeedMatchOpAttr() -> i32 {260  // CHECK: "test.match_op_attribute2"() <{default_valued_attr = 3 : i32, more_attr = 4 : i32, optional_attr = 2 : i32, required_attr = 1 : i32}>261  %0 = "test.match_op_attribute1"() {required_attr = 1: i32, optional_attr = 2: i32, default_valued_attr = 3: i32, more_attr = 4: i32} : () -> (i32)262  return %0: i32263}264 265// CHECK-LABEL: succeedMatchMissingOptionalAttr266func.func @succeedMatchMissingOptionalAttr() -> i32 {267  // CHECK: "test.match_op_attribute2"() <{default_valued_attr = 3 : i32, more_attr = 4 : i32, required_attr = 1 : i32}>268  %0 = "test.match_op_attribute1"() {required_attr = 1: i32, default_valued_attr = 3: i32, more_attr = 4: i32} : () -> (i32)269  return %0: i32270}271 272// CHECK-LABEL: succeedMatchMissingDefaultValuedAttr273func.func @succeedMatchMissingDefaultValuedAttr() -> i32 {274  // CHECK: "test.match_op_attribute2"() <{default_valued_attr = 42 : i32, more_attr = 4 : i32, optional_attr = 2 : i32, required_attr = 1 : i32}>275  %0 = "test.match_op_attribute1"() {required_attr = 1: i32, optional_attr = 2: i32, more_attr = 4: i32} : () -> (i32)276  return %0: i32277}278 279// CHECK-LABEL: failedMatchAdditionalConstraintNotSatisfied280func.func @failedMatchAdditionalConstraintNotSatisfied() -> i32 {281  // CHECK: "test.match_op_attribute1"()282  %0 = "test.match_op_attribute1"() {required_attr = 1: i32, optional_attr = 2: i32, more_attr = 5: i32} : () -> (i32)283  return %0: i32284}285 286// CHECK-LABEL: verifyConstantAttr287func.func @verifyConstantAttr(%arg0 : i32) -> i32 {288  // CHECK: "test.op_b"(%arg0) <{attr = 17 : i32}> : (i32) -> i32 loc("a")289  %0 = "test.op_c"(%arg0) : (i32) -> i32 loc("a")290  return %0 : i32291}292 293// CHECK-LABEL: verifyUnitAttr294func.func @verifyUnitAttr() -> (i32, i32) {295  // Unit attribute present in the matched op is propagated as attr2.296  // CHECK: "test.match_op_attribute4"() <{attr1, attr2}> : () -> i32297  %0 = "test.match_op_attribute3"() {attr} : () -> i32298 299  // Since the original op doesn't have the unit attribute, the new op300  // only has the constant-constructed unit attribute attr1.301  // CHECK: "test.match_op_attribute4"() <{attr1}> : () -> i32302  %1 = "test.match_op_attribute3"() : () -> i32303  return %0, %1 : i32, i32304}305 306//===----------------------------------------------------------------------===//307// Test Constant Matching308//===----------------------------------------------------------------------===//309 310// CHECK-LABEL: testConstOp311func.func @testConstOp() -> (i32) {312  // CHECK-NEXT: [[C0:%.+]] = "test.constant"() <{value = 1313  %0 = "test.constant"() {value = 1 : i32} : () -> i32314 315  // CHECK-NEXT: return [[C0]]316  return %0 : i32317}318 319// CHECK-LABEL: testConstOpUsed320func.func @testConstOpUsed() -> (i32) {321  // CHECK-NEXT: [[C0:%.+]] = "test.constant"() <{value = 1322  %0 = "test.constant"() {value = 1 : i32} : () -> i32323 324  // CHECK-NEXT: [[V0:%.+]] = "test.op_s"([[C0]])325  %1 = "test.op_s"(%0) {value = 1 : i32} : (i32) -> i32326 327  // CHECK-NEXT: return [[V0]]328  return %1 : i32329}330 331// CHECK-LABEL: testConstOpReplaced332func.func @testConstOpReplaced() -> (i32) {333  // CHECK-NEXT: [[C0:%.+]] = "test.constant"() <{value = 1334  %0 = "test.constant"() {value = 1 : i32} : () -> i32335  %1 = "test.constant"() {value = 2 : i32} : () -> i32336 337  // CHECK: [[V0:%.+]] = "test.op_s"([[C0]]) <{value = 2 : i32}338  %2 = "test.op_r"(%0, %1) : (i32, i32) -> i32339 340  // CHECK: [[V0]]341  return %2 : i32342}343 344// CHECK-LABEL: testConstOpMatchFailure345func.func @testConstOpMatchFailure() -> (i64) {346  // CHECK-DAG: [[C0:%.+]] = "test.constant"() <{value = 1347  %0 = "test.constant"() {value = 1 : i64} : () -> i64348 349  // CHECK-DAG: [[C1:%.+]] = "test.constant"() <{value = 2350  %1 = "test.constant"() {value = 2 : i64} : () -> i64351 352  // CHECK: [[V0:%.+]] = "test.op_r"([[C0]], [[C1]])353  %2 = "test.op_r"(%0, %1) : (i64, i64) -> i64354 355  // CHECK: [[V0]]356  return %2 : i64357}358 359// CHECK-LABEL: testConstOpMatchNonConst360func.func @testConstOpMatchNonConst(%arg0 : i32) -> (i32) {361  // CHECK-DAG: [[C0:%.+]] = "test.constant"() <{value = 1362  %0 = "test.constant"() {value = 1 : i32} : () -> i32363 364  // CHECK: [[V0:%.+]] = "test.op_r"([[C0]], %arg0)365  %1 = "test.op_r"(%0, %arg0) : (i32, i32) -> i32366 367  // CHECK: [[V0]]368  return %1 : i32369}370 371 372 373//===----------------------------------------------------------------------===//374// Test Enum Attributes375//===----------------------------------------------------------------------===//376 377// CHECK-LABEL: verifyI32EnumAttr378func.func @verifyI32EnumAttr() -> i32 {379  // CHECK: "test.i32_enum_attr"() <{attr = 10 : i32}380  %0 = "test.i32_enum_attr"() {attr = 5: i32} : () -> i32381  return %0 : i32382}383 384// CHECK-LABEL: verifyI64EnumAttr385func.func @verifyI64EnumAttr() -> i32 {386  // CHECK: "test.i64_enum_attr"() <{attr = 10 : i64}387  %0 = "test.i64_enum_attr"() {attr = 5: i64} : () -> i32388  return %0 : i32389}390 391//===----------------------------------------------------------------------===//392// Test ElementsAttr393//===----------------------------------------------------------------------===//394 395// CHECK-LABEL: rewrite_i32elementsattr396func.func @rewrite_i32elementsattr() -> () {397  // CHECK: attr = dense<0> : tensor<i32>398  "test.i32ElementsAttr"() {attr = dense<[3, 5]>:tensor<2xi32>} : () -> ()399  return400}401 402// CHECK-LABEL: rewrite_f64elementsattr403func.func @rewrite_f64elementsattr() -> () {404  "test.float_elements_attr"() {405    // Should match406    // CHECK: scalar_f32_attr = dense<[5.000000e+00, 6.000000e+00]> : tensor<2xf32>407    scalar_f32_attr = dense<[3.0, 4.0]> : tensor<2xf32>,408    tensor_f64_attr = dense<6.0> : tensor<4x8xf64>409  } : () -> ()410 411  "test.float_elements_attr"() {412    // Should not match413    // CHECK: scalar_f32_attr = dense<7.000000e+00> : tensor<2xf32>414    scalar_f32_attr = dense<7.0> : tensor<2xf32>,415    tensor_f64_attr = dense<3.0> : tensor<4x8xf64>416  } : () -> ()417  return418}419 420//===----------------------------------------------------------------------===//421// Test Multi-result Ops422//===----------------------------------------------------------------------===//423 424// CHECK-LABEL: @useMultiResultOpToReplaceWhole425func.func @useMultiResultOpToReplaceWhole() -> (i32, f32, f32) {426  // CHECK: %[[A:.*]], %[[B:.*]], %[[C:.*]] = "test.another_three_result"()427  // CHECK: return %[[A]], %[[B]], %[[C]]428  %0:3 = "test.three_result"() {kind = 1} : () -> (i32, f32, f32)429  return %0#0, %0#1, %0#2 : i32, f32, f32430}431 432// CHECK-LABEL: @useMultiResultOpToReplacePartial1433func.func @useMultiResultOpToReplacePartial1() -> (i32, f32, f32) {434  // CHECK: %[[A:.*]], %[[B:.*]] = "test.two_result"()435  // CHECK: %[[C:.*]] = "test.one_result1"()436  // CHECK: return %[[A]], %[[B]], %[[C]]437  %0:3 = "test.three_result"() {kind = 2} : () -> (i32, f32, f32)438  return %0#0, %0#1, %0#2 : i32, f32, f32439}440 441// CHECK-LABEL: @useMultiResultOpToReplacePartial2442func.func @useMultiResultOpToReplacePartial2() -> (i32, f32, f32) {443  // CHECK: %[[A:.*]] = "test.one_result2"()444  // CHECK: %[[B:.*]], %[[C:.*]] = "test.another_two_result"()445  // CHECK: return %[[A]], %[[B]], %[[C]]446  %0:3 = "test.three_result"() {kind = 3} : () -> (i32, f32, f32)447  return %0#0, %0#1, %0#2 : i32, f32, f32448}449 450// CHECK-LABEL: @useMultiResultOpResultsSeparately451func.func @useMultiResultOpResultsSeparately() -> (i32, f32, f32) {452  // CHECK: %[[A:.*]], %[[B:.*]] = "test.two_result"()453  // CHECK: %[[C:.*]] = "test.one_result1"()454  // CHECK: %[[D:.*]], %[[E:.*]] = "test.two_result"()455  // CHECK: return %[[A]], %[[C]], %[[E]]456  %0:3 = "test.three_result"() {kind = 4} : () -> (i32, f32, f32)457  return %0#0, %0#1, %0#2 : i32, f32, f32458}459 460// CHECK-LABEL: @constraintOnSourceOpResult461func.func @constraintOnSourceOpResult() -> (i32, f32, i32) {462  // CHECK: %[[A:.*]], %[[B:.*]] = "test.two_result"()463  // CHECK: %[[C:.*]] = "test.one_result2"()464  // CHECK: %[[D:.*]] = "test.one_result1"()465  // CHECK: return %[[A]], %[[B]], %[[C]]466  %0:2 = "test.two_result"() {kind = 5} : () -> (i32, f32)467  %1:2 = "test.two_result"() {kind = 5} : () -> (i32, f32)468  return %0#0, %0#1, %1#0 : i32, f32, i32469}470 471// CHECK-LABEL: @useAuxiliaryOpToReplaceMultiResultOp472func.func @useAuxiliaryOpToReplaceMultiResultOp() -> (i32, f32, f32) {473  // An auxiliary op is generated to help building the op for replacing the474  // matched op.475  // CHECK: %[[A:.*]], %[[B:.*]] = "test.two_result"()476 477  // CHECK: %[[C:.*]] = "test.one_result3"(%[[B]])478  // CHECK: %[[D:.*]], %[[E:.*]] = "test.another_two_result"()479  // CHECK: return %[[C]], %[[D]], %[[E]]480  %0:3 = "test.three_result"() {kind = 6} : () -> (i32, f32, f32)481  return %0#0, %0#1, %0#2 : i32, f32, f32482}483 484//===----------------------------------------------------------------------===//485// Test Multi-result Ops486//===----------------------------------------------------------------------===//487 488// CHECK-LABEL: @replaceOneVariadicOutOneVariadicInOp489func.func @replaceOneVariadicOutOneVariadicInOp(%arg0: i32, %arg1: i32, %arg2: i32) -> (i32, i32, i32, i32, i32, i32) {490  // CHECK: %[[cnt1:.*]] = "test.one_variadic_out_one_variadic_in2"(%arg0)491  // CHECK: %[[cnt2:.*]]:2 = "test.one_variadic_out_one_variadic_in2"(%arg0, %arg1)492  // CHECK: %[[cnt3:.*]]:3 = "test.one_variadic_out_one_variadic_in2"(%arg0, %arg1, %arg2)493  // CHECK: return %[[cnt1]], %[[cnt2]]#0, %[[cnt2]]#1, %[[cnt3]]#0, %[[cnt3]]#1, %[[cnt3]]#2494 495  %0   = "test.one_variadic_out_one_variadic_in1"(%arg0) : (i32) -> (i32)496  %1:2 = "test.one_variadic_out_one_variadic_in1"(%arg0, %arg1) : (i32, i32) -> (i32, i32)497  %2:3 = "test.one_variadic_out_one_variadic_in1"(%arg0, %arg1, %arg2) : (i32, i32, i32) -> (i32, i32, i32)498  return %0, %1#0, %1#1, %2#0, %2#1, %2#2 : i32, i32, i32, i32, i32, i32499}500 501// CHECK-LABEL: @replaceMixedVariadicInputOp502func.func @replaceMixedVariadicInputOp(%arg0: i32, %arg1: f32, %arg2: i32) -> () {503  // CHECK: "test.mixed_variadic_in2"(%arg1)504  // CHECK: "test.mixed_variadic_in2"(%arg0, %arg1, %arg2)505  // CHECK: "test.mixed_variadic_in2"(%arg0, %arg0, %arg1, %arg2, %arg2)506 507  "test.mixed_variadic_in1"(%arg1) : (f32) -> ()508  "test.mixed_variadic_in1"(%arg0, %arg1, %arg2) : (i32, f32, i32) -> ()509  "test.mixed_variadic_in1"(%arg0, %arg0, %arg1, %arg2, %arg2) : (i32, i32, f32, i32, i32) -> ()510  return511}512 513// CHECK-LABEL: @replaceMixedVariadicOutputOp514func.func @replaceMixedVariadicOutputOp() -> (f32, i32, f32, i32, i32, i32, f32, i32, i32) {515  // CHECK: %[[cnt1:.*]] = "test.mixed_variadic_out2"()516  // CHECK: %[[cnt3_a:.*]], %[[cnt3_b:.*]], %[[cnt3_c:.*]] = "test.mixed_variadic_out2"()517  // CHECK: %[[cnt5_a:.*]]:2, %[[cnt5_b:.*]], %[[cnt5_c:.*]]:2 = "test.mixed_variadic_out2"()518  // CHECK: return %[[cnt1]], %[[cnt3_a]], %[[cnt3_b]], %[[cnt3_c]], %[[cnt5_a]]#0, %[[cnt5_a]]#1, %[[cnt5_b]], %[[cnt5_c]]#0, %[[cnt5_c]]#1519 520  %0   = "test.mixed_variadic_out1"() : () -> (f32)521  %1:3 = "test.mixed_variadic_out1"() : () -> (i32, f32, i32)522  %2:5 = "test.mixed_variadic_out1"() : () -> (i32, i32, f32, i32, i32)523  return %0, %1#0, %1#1, %1#2, %2#0, %2#1, %2#2, %2#3, %2#4 : f32, i32, f32, i32, i32, i32, f32, i32, i32524}525 526// CHECK-LABEL: @generateVariadicOutputOpInNestedPattern527func.func @generateVariadicOutputOpInNestedPattern() -> (i32) {528  // CHECK: %[[cnt5_a:.*]], %[[cnt5_b:.*]]:2, %[[cnt5_c:.*]]:2 = "test.mixed_variadic_out3"()529  // CHECK: %[[res:.*]] = "test.mixed_variadic_in3"(%[[cnt5_a]], %[[cnt5_b]]#0, %[[cnt5_b]]#1, %[[cnt5_c]]#0, %[[cnt5_c]]#1)530  // CHECK: return %[[res]]531 532  %0 = "test.one_i32_out"() : () -> (i32)533  return %0 : i32534}535 536// CHECK-LABEL: @testMatchVariadic537func.func @testMatchVariadic(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {538  // CHECK: "test.mixed_variadic_in5"(%arg0, %arg1, %arg2) <{attr1 = 0 : i32, pattern_name = "MatchVariadic"}> : (i32, i32, i32) -> ()539  "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) {attr1 = 0 : i32} : (i32, i32, i32) -> ()540 541  // Note: Not rewritten because variadic operand size mismatches.542  // CHECK: "test.mixed_variadic_in4"(%arg0, %arg1, %arg2, %arg3) <{attr1 = 0 : i32}> : (i32, i32, i32, i32) -> ()543  "test.mixed_variadic_in4"(%arg0, %arg1, %arg2, %arg3) {attr1 = 0 : i32} : (i32, i32, i32, i32) -> ()544 545  return546}547 548// CHECK-LABEL: @testReplaceVariadic549func.func @testReplaceVariadic(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {550  // CHECK: "test.mixed_variadic_in3"(%arg2, %arg1, %arg0) <{count = 1 : i32}>551  "test.mixed_variadic_in5"(%arg0, %arg1, %arg2) <{attr1 = 0 : i32, pattern_name = "MatchInverseVariadic"}> : (i32, i32, i32) -> ()552 553  return554}555 556// CHECK-LABEL: @testMatchVariadicSubDag557func.func @testMatchVariadicSubDag(%arg0: i32, %arg1: i32, %arg2: i32) -> () {558  // CHECK: %[[IN0:.*]] = "test.mixed_variadic_in_out_i32"(%arg0) : (i32) -> i32559  %0 = "test.mixed_variadic_in_out_i32"(%arg0) : (i32) -> i32560  // CHECK: %[[IN1:.*]] = "test.mixed_variadic_in_out_i32"(%arg1) : (i32) -> i32561  %1 = "test.mixed_variadic_in_out_i32"(%arg1) : (i32) -> i32562 563  // CHECK: "test.mixed_variadic_in5"(%arg0, %arg1, %arg2) <{attr1 = 1 : i32, pattern_name = "MatchVariadicSubDag"}> : (i32, i32, i32) -> ()564  "test.mixed_variadic_in4"(%0, %1, %arg2) {attr1 = 1 : i32} : (i32, i32, i32) -> ()565 566  // Note: MatchVariadicSubDag doesn't apply567  // CHECK: "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) <{attr1 = 1 : i32}> : (i32, i32, i32) -> ()568  "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) {attr1 = 1 : i32} : (i32, i32, i32) -> ()569 570  return571}572 573// CHECK-LABEL: @testMatchVariadicSameSymbol574func.func @testMatchVariadicSameSymbol(%arg0: i32, %arg1: i32, %arg2: i32) -> () {575  // CHECK: "test.mixed_variadic_in5"(%arg0, %arg0, %arg2) <{attr1 = 2 : i32, pattern_name = "MatchVariadicSameSymbol"}> : (i32, i32, i32) -> ()576  "test.mixed_variadic_in4"(%arg0, %arg0, %arg2) {attr1 = 2 : i32} : (i32, i32, i32) -> ()577 578  // Note: MatchVariadicSameSymbol doesn't apply.579  // CHECK: "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) <{attr1 = 2 : i32}> : (i32, i32, i32) -> ()580  "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) {attr1 = 2 : i32} : (i32, i32, i32) -> ()581 582  return583}584 585// CHECK-LABEL: @testMatchAndRewriteVariadicFullRange586func.func @testMatchAndRewriteVariadicFullRange(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {587  // CHECK: "test.mixed_variadic_in6"(%arg2, %arg3, %arg0, %arg1) <{attr1 = -1 : i32}> : (i32, i32, i32, i32) -> ()588  "test.mixed_variadic_in6"(%arg0, %arg1, %arg2, %arg3) {attr1 = 1 : i32} : (i32, i32, i32, i32) -> ()589 590  // Note: MatchAndRewriteVariadicFullRange doesn't apply because the length of each variadic operand is not equal to 2.591  // CHECK: "test.mixed_variadic_in6"(%arg0, %arg1) <{attr1 = 1 : i32}> : (i32, i32) -> ()592  "test.mixed_variadic_in6"(%arg0, %arg1) {attr1 = 1 : i32} : (i32, i32) -> ()593 594  return595}596 597// CHECK-LABEL: @testMatchMultiVariadicSubSymbol598func.func @testMatchMultiVariadicSubSymbol(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {599  // CHECK: "test.mixed_variadic_in5"(%arg2, %arg3, %arg1) <{attr1 = 2 : i32, pattern_name = "MatchMultiVariadicSubSymbol"}> : (i32, i32, i32) -> ()600  "test.mixed_variadic_in6"(%arg0, %arg1, %arg2, %arg3) {attr1 = 2 : i32} : (i32, i32, i32, i32) -> ()601 602  return603}604 605// CHECK-LABEL: @testMatchMixedVaradicOptional606func.func @testMatchMixedVaradicOptional(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {607  // CHECK: "test.mixed_variadic_in6"(%arg0, %arg1, %arg2) <{attr1 = 2 : i32}> : (i32, i32, i32) -> ()608  "test.mixed_variadic_optional_in7"(%arg0, %arg1, %arg2) {attr1 = 2 : i32, operandSegmentSizes = array<i32: 2, 1>} : (i32, i32, i32) -> ()609  // CHECK: test.mixed_variadic_optional_in7610  "test.mixed_variadic_optional_in7"(%arg0, %arg1) {attr1 = 2 : i32, operandSegmentSizes = array<i32: 2, 0>} : (i32, i32) -> ()611 612  return613}614 615//===----------------------------------------------------------------------===//616// Test patterns that operate on properties617//===----------------------------------------------------------------------===//618 619// CHECK-LABEL: @testSimplePropertyRewrite620func.func @testSimplePropertyRewrite() {621  // CHECK-NEXT: test.prop_pattern_op_1 "o1" 2 true622  test.prop_pattern_op_1 "o1" 1 false623  // Pattern not applied when predicate not met624  // CHECK-NEXT: test.prop_pattern_op_1 "o2" -1 false625  test.prop_pattern_op_1 "o2" -1 false626  // Pattern not applied when constant doesn't match627  // CHCEK-NEXT: test.prop_pattern_op_1 "o3" 1 true628  test.prop_pattern_op_1 "o3" 1 true629  return630}631 632// CHECK-LABEL: @testNestedPropertyRewrite633func.func @testNestedPropertyRewrite() {634  // CHECK: %[[v:.*]] = test.prop_pattern_op_1 "s1" -2 false635  // CHECK: test.prop_pattern_op_2 %[[v]] "s1.t1"636  %v = test.prop_pattern_op_1 "s1" 1 false637  test.prop_pattern_op_2 %v "t1"638  return639}640 641//===----------------------------------------------------------------------===//642// Test that natives calls are only called once during rewrites.643//===----------------------------------------------------------------------===//644 645// CHECK-LABEL: redundantTest646func.func @redundantTest(%arg0: i32) -> i32 {647  %0 = "test.op_m"(%arg0) : (i32) -> i32648  // CHECK: "test.op_m"(%arg0) <{optional_attr = 314159265 : i32}> : (i32) -> i32649  return %0 : i32650}651 652//===----------------------------------------------------------------------===//653// Test either directive654//===----------------------------------------------------------------------===//655 656// CHECK-LABEL: @eitherDagLeafOnly657func.func @eitherDagLeafOnly(%arg0 : i32, %arg1 : i16, %arg2 : i8) -> () {658  // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32659  %0 = "test.either_op_a"(%arg0, %arg1, %arg2) : (i32, i16, i8) -> i32660  // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32661  %1 = "test.either_op_a"(%arg1, %arg0, %arg2) : (i16, i32, i8) -> i32662  return663}664 665// CHECK-LABEL: @eitherDagLeafDagNode666func.func @eitherDagLeafDagNode(%arg0 : i32, %arg1 : i16, %arg2 : i8) -> () {667  %0 = "test.either_op_b"(%arg0, %arg0) : (i32, i32) -> i32668  // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32669  %1 = "test.either_op_a"(%0, %arg1, %arg2) : (i32, i16, i8) -> i32670  // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32671  %2 = "test.either_op_a"(%arg1, %0, %arg2) : (i16, i32, i8) -> i32672  return673}674 675// CHECK-LABEL: @eitherDagNodeDagNode676func.func @eitherDagNodeDagNode(%arg0 : i32, %arg1 : i16, %arg2 : i8) -> () {677  %0 = "test.either_op_b"(%arg0, %arg0) : (i32, i32) -> i32678  %1 = "test.either_op_b"(%arg1, %arg1) : (i16, i16) -> i32679  // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32680  %2 = "test.either_op_a"(%0, %1, %arg2) : (i32, i32, i8) -> i32681  // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32682  %3 = "test.either_op_a"(%1, %0, %arg2) : (i32, i32, i8) -> i32683  return684}685 686// CHECK-LABEL: @testEitherOpWithAttr687func.func @testEitherOpWithAttr(%arg0 : i32, %arg1 : i16) -> () {688  // CHECK: "test.either_op_b"(%arg1, %arg0) : (i16, i32) -> i32689  %0 = "test.either_op_c"(%arg0, %arg1) {attr = 0 : i32} : (i32, i16) -> i32690  // CHECK: "test.either_op_b"(%arg1, %arg0) : (i16, i32) -> i32691  %1 = "test.either_op_c"(%arg1, %arg0) {attr = 0 : i32} : (i16, i32) -> i32692  // CHECK: "test.either_op_c"(%arg0, %arg1) <{attr = 1 : i32}> : (i32, i16) -> i32693  %2 = "test.either_op_c"(%arg0, %arg1) {attr = 1 : i32} : (i32, i16) -> i32694  return695}696 697//===----------------------------------------------------------------------===//698// Test that ops without type deduction can be created with type builders.699//===----------------------------------------------------------------------===//700 701// CHECK-LABEL: @explicitReturnTypeTest702func.func @explicitReturnTypeTest(%arg0 : i64) -> i8 {703  %0 = "test.source_op"(%arg0) {tag = 11 : i32} : (i64) -> i8704  // CHECK: "test.op_x"(%arg0) : (i64) -> i32705  // CHECK: "test.op_x"(%0) : (i32) -> i8706  return %0 : i8707}708 709// CHECK-LABEL: @returnTypeBuilderTest710func.func @returnTypeBuilderTest(%arg0 : i1) -> i8 {711  %0 = "test.source_op"(%arg0) {tag = 22 : i32} : (i1) -> i8712  // CHECK: "test.op_x"(%arg0) : (i1) -> i1713  // CHECK: "test.op_x"(%0) : (i1) -> i8714  return %0 : i8715}716 717// CHECK-LABEL: @multipleReturnTypeBuildTest718func.func @multipleReturnTypeBuildTest(%arg0 : i1) -> i1 {719  %0 = "test.source_op"(%arg0) {tag = 33 : i32} : (i1) -> i1720  // CHECK: "test.one_to_two"(%arg0) : (i1) -> (i64, i32)721  // CHECK: "test.op_x"(%0#0) : (i64) -> i32722  // CHECK: "test.op_x"(%0#1) : (i32) -> i64723  // CHECK: "test.two_to_one"(%1, %2) : (i32, i64) -> i1724  return %0 : i1725}726 727// CHECK-LABEL: @copyValueType728func.func @copyValueType(%arg0 : i8) -> i32 {729  %0 = "test.source_op"(%arg0) {tag = 44 : i32} : (i8) -> i32730  // CHECK: "test.op_x"(%arg0) : (i8) -> i8731  // CHECK: "test.op_x"(%0) : (i8) -> i32732  return %0 : i32733}734 735// CHECK-LABEL: @multipleReturnTypeDifferent736func.func @multipleReturnTypeDifferent(%arg0 : i1) -> i64 {737  %0 = "test.source_op"(%arg0) {tag = 55 : i32} : (i1) -> i64738  // CHECK: "test.one_to_two"(%arg0) : (i1) -> (i1, i64)739  // CHECK: "test.two_to_one"(%0#0, %0#1) : (i1, i64) -> i64740  return %0 : i64741}742 743//===----------------------------------------------------------------------===//744// Test that multiple trailing directives can be mixed in patterns.745//===----------------------------------------------------------------------===//746 747// CHECK-LABEL: @returnTypeAndLocation748func.func @returnTypeAndLocation(%arg0 : i32) -> i1 {749  %0 = "test.source_op"(%arg0) {tag = 66 : i32} : (i32) -> i1750  // CHECK: "test.op_x"(%arg0) : (i32) -> i32 loc("loc1")751  // CHECK: "test.op_x"(%arg0) : (i32) -> i32 loc("loc2")752  // CHECK: "test.two_to_one"(%0, %1) : (i32, i32) -> i1753  return %0 : i1754}755 756//===----------------------------------------------------------------------===//757// Test that patterns can create ConstantStrAttr758//===----------------------------------------------------------------------===//759 760// CHECK-LABEL: @testConstantStrAttr761func.func @testConstantStrAttr() -> () {762  // CHECK: test.has_str_value {value = "foo"}763  test.no_str_value {value = "bar"}764  return765}766 767//===----------------------------------------------------------------------===//768// Test that patterns with variadics propagate sizes769//===----------------------------------------------------------------------===//770 771// CHECK-LABEL: @testVariadic772func.func @testVariadic(%arg_0: i32, %arg_1: i32, %brg: i64,773    %crg_0: f32, %crg_1: f32, %crg_2: f32, %crg_3: f32) -> () {774  // CHECK: "test.variadic_rewrite_dst_op"(%arg2, %arg3, %arg4, %arg5, %arg6, %arg0, %arg1) <{operandSegmentSizes = array<i32: 1, 4, 2>}> : (i64, f32, f32, f32, f32, i32, i32) -> ()775  "test.variadic_rewrite_src_op"(%arg_0, %arg_1, %brg,776    %crg_0, %crg_1, %crg_2, %crg_3) {operandSegmentSizes = array<i32: 2, 1, 4>} :777    (i32, i32, i64, f32, f32, f32, f32) -> ()778  return779}780