1// RUN: llvm-tblgen -I %p/../../../../include -gen-global-isel-combiner \ 2// RUN: -combiners=MyCombiner %s | \ 3// RUN: FileCheck %s 4 5include "llvm/Target/Target.td" 6include "llvm/Target/GlobalISel/Combine.td" 7 8def MyTargetISA : InstrInfo; 9def MyTarget : Target { let InstructionSet = MyTargetISA; } 10 11def ReplaceMatched : GICombineRule< 12 (defs root:$dst), 13 (match (G_FNEG $tmp, $src), 14 (G_FNEG $dst, $tmp)), 15 (apply (GIReplaceReg $dst, $src))>; 16 17def ReplaceTemp : GICombineRule< 18 (defs root:$a), 19 (match (G_BUILD_VECTOR $tmp, $x, $y), 20 (G_UNMERGE_VALUES $a, $b, $tmp)), 21 (apply (G_UNMERGE_VALUES $a, i32:$new, $y), 22 (GIReplaceReg $b, $new))>; 23 24def MyCombiner: GICombiner<"GenMyCombiner", [ 25 ReplaceMatched, 26 ReplaceTemp 27]>; 28 29// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const { 30// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = { 31// CHECK-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2({{[0-9]+}}), GIMT_Encode2({{[0-9]+}}), /*)*//*default:*//*Label 2*/ GIMT_Encode4([[L562:[0-9]+]]), 32// CHECK-NEXT: /*TargetOpcode::G_UNMERGE_VALUES*//*Label 0*/ GIMT_Encode4([[L478:[0-9]+]]), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), 33// CHECK-NEXT: /*TargetOpcode::G_FNEG*//*Label 1*/ GIMT_Encode4([[L530:[0-9]+]]), 34// CHECK-NEXT: // Label 0: @[[L478]] 35// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 3*/ GIMT_Encode4([[L529:[0-9]+]]), // Rule ID 1 // 36// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled), 37// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 38// CHECK-NEXT: // MIs[0] a 39// CHECK-NEXT: // No operand predicates 40// CHECK-NEXT: // MIs[0] b 41// CHECK-NEXT: // No operand predicates 42// CHECK-NEXT: // MIs[0] tmp 43// CHECK-NEXT: GIM_RecordInsnIgnoreCopies, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, // MIs[1] 44// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_BUILD_VECTOR), 45// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 46// CHECK-NEXT: // MIs[1] x 47// CHECK-NEXT: // No operand predicates 48// CHECK-NEXT: // MIs[1] y 49// CHECK-NEXT: // No operand predicates 50// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1, 51// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32, 52// CHECK-NEXT: // Combiner Rule #1: ReplaceTemp 53// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_UNMERGE_VALUES), 54// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // a 55// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(RegState::Define), 56// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // y 57// CHECK-NEXT: GIR_ReplaceRegWithTempReg, /*OldInsnID*/0, /*OldOpIdx*/1, /*TempRegID*/0, 58// CHECK-NEXT: GIR_EraseRootFromParent_Done, 59// CHECK-NEXT: // Label 3: @[[L529]] 60// CHECK-NEXT: GIM_Reject, 61// CHECK-NEXT: // Label 1: @[[L530]] 62// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 4*/ GIMT_Encode4([[L561:[0-9]+]]), // Rule ID 0 // 63// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled), 64// CHECK-NEXT: // MIs[0] dst 65// CHECK-NEXT: // No operand predicates 66// CHECK-NEXT: // MIs[0] tmp 67// CHECK-NEXT: GIM_RecordInsnIgnoreCopies, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] 68// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_FNEG), 69// CHECK-NEXT: // MIs[1] src 70// CHECK-NEXT: // No operand predicates 71// CHECK-NEXT: GIM_CheckCanReplaceReg, /*OldInsnID*/0, /*OldOpIdx*/0, /*NewInsnId*/1, /*NewOpIdx*/1, 72// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1, 73// CHECK-NEXT: // Combiner Rule #0: ReplaceMatched 74// CHECK-NEXT: GIR_ReplaceReg, /*OldInsnID*/0, /*OldOpIdx*/0, /*NewInsnId*/1, /*NewOpIdx*/1, 75// CHECK-NEXT: GIR_EraseRootFromParent_Done, 76// CHECK-NEXT: // Label 4: @[[L561]] 77// CHECK-NEXT: GIM_Reject, 78// CHECK-NEXT: // Label 2: @[[L562]] 79// CHECK-NEXT: GIM_Reject, 80// CHECK-NEXT: }; // Size: {{[0-9]+}} bytes 81// CHECK-NEXT: return MatchTable0; 82// CHECK-NEXT: } 83