// RUN: llvm-tblgen -I %p/../../../include -gen-global-isel-combiner \ // RUN: -gicombiner-stop-after-parse -combiners=MyCombiner %s | \ // RUN: FileCheck %s include "llvm/Target/Target.td" include "llvm/Target/GlobalISel/Combine.td" def MyTargetISA : InstrInfo; def MyTarget : Target { let InstructionSet = MyTargetISA; } def dummy; def HasAnswerToEverything : Predicate<"Subtarget->getAnswerToUniverse() == 42 && Subtarget->getAnswerToLife() == 42">; def reg_matchinfo : GIDefMatchData<"Register">; // CHECK: (CombineRule name:WipOpcodeTest0 id:0 root:d // CHECK-NEXT: (MatchPats // CHECK-NEXT: d:(AnyOpcodePattern [G_TRUNC]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __WipOpcodeTest0_apply_0:(CXXPattern apply code:"APPLY") // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats ) // CHECK-NEXT: (OperandTable ApplyPats ) // CHECK-NEXT: ) def WipOpcodeTest0 : GICombineRule< (defs root:$d), (match (wip_match_opcode G_TRUNC):$d), (apply [{ APPLY }])>; // CHECK: (CombineRule name:WipOpcodeTest1 id:1 root:d // CHECK-NEXT: (MatchPats // CHECK-NEXT: d:(AnyOpcodePattern [G_TRUNC, G_SEXT]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __WipOpcodeTest1_apply_0:(CXXPattern apply code:"APPLY") // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats ) // CHECK-NEXT: (OperandTable ApplyPats ) // CHECK-NEXT: ) def WipOpcodeTest1 : GICombineRule< (defs root:$d), (match (wip_match_opcode G_TRUNC, G_SEXT):$d), (apply [{ APPLY }])>; // CHECK: (CombineRule name:InstTest0 id:2 root:d // CHECK-NEXT: (MatchPats // CHECK-NEXT: d:(CodeGenInstructionPattern COPY operands:[$a, $b]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __InstTest0_apply_0:(CXXPattern apply code:"APPLY") // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: a -> d // CHECK-NEXT: b -> // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats ) // CHECK-NEXT: ) def InstTest0 : GICombineRule< (defs root:$d), (match (COPY $a, $b):$d), (apply [{ APPLY }])>; // CHECK: (CombineRule name:InstTest1 id:3 root:d // CHECK-NEXT: (MatchDatas // CHECK-NEXT: (MatchDataInfo pattern_symbol:r0 type:'Register' var_name:MDInfo0) // CHECK-NEXT: ) // CHECK-NEXT: (MatchPats // CHECK-NEXT: d:(CodeGenInstructionPattern COPY operands:[$a, i32:$b]) // CHECK-NEXT: __InstTest1_match_1:(CodeGenInstructionPattern G_ZEXT operands:[$x, 0]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __InstTest1_apply_0:(CXXPattern apply code:"APPLY") // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: a -> d // CHECK-NEXT: b -> // CHECK-NEXT: x -> __InstTest1_match_1 // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats ) // CHECK-NEXT: ) let Predicates = [HasAnswerToEverything] in def InstTest1 : GICombineRule< (defs root:$d, reg_matchinfo:$r0), (match (COPY $a, i32:$b):$d, (G_ZEXT $x, 0)), (apply [{ APPLY }])>; // CHECK: (CombineRule name:InstTest2 id:4 root:d // CHECK-NEXT: (MatchDatas // CHECK-NEXT: (MatchDataInfo pattern_symbol:r0 type:'Register' var_name:MDInfo0) // CHECK-NEXT: ) // CHECK-NEXT: (MatchPats // CHECK-NEXT: __InstTest2_match_0:(CodeGenInstructionPattern COPY operands:[$d, (i32 0):$x]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __InstTest2_apply_0:(CXXPattern apply code:"APPLY") // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: d -> __InstTest2_match_0 // CHECK-NEXT: x -> // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats ) // CHECK-NEXT: ) def InstTest2 : GICombineRule< (defs root:$d, reg_matchinfo:$r0), (match (COPY $d, (i32 0):$x)), (apply [{ APPLY }])>; // CHECK: (CombineRule name:InOutInstTest0 id:5 root:dst // CHECK-NEXT: (MatchPats // CHECK-NEXT: __InOutInstTest0_match_0:(CodeGenInstructionPattern COPY operands:[$dst, $tmp]) // CHECK-NEXT: __InOutInstTest0_match_1:(CodeGenInstructionPattern G_ZEXT operands:[$tmp, $src]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __InOutInstTest0_apply_0:(CodeGenInstructionPattern G_TRUNC operands:[$dst, $src]) // CHECK-NEXT: __InOutInstTest0_apply_1:(CXXPattern apply code:"APPLY ${src}") // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: dst -> __InOutInstTest0_match_0 // CHECK-NEXT: src -> // CHECK-NEXT: tmp -> __InOutInstTest0_match_1 // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats // CHECK-NEXT: dst -> __InOutInstTest0_apply_0 // CHECK-NEXT: src -> // CHECK-NEXT: ) // CHECK-NEXT: ) def InOutInstTest0 : GICombineRule< (defs root:$dst), (match (COPY $dst, $tmp), (G_ZEXT $tmp, $src)), (apply (G_TRUNC $dst, $src), "APPLY ${src}")>; def MatchICst: GICombinePatFrag< (outs), (ins gi_mo:$foo, gi_imm:$cst), [(pattern "return matchIConstant(${foo}, ${cst})")]>; // CHECK: (CombineRule name:PatFragTest0 id:6 root:dst // CHECK-NEXT: (PatFrags // CHECK-NEXT: (PatFrag name:MatchICst // CHECK-NEXT: (ins [foo:machine_operand, cst:imm]) // CHECK-NEXT: (alternatives [ // CHECK-NEXT: [ // CHECK-NEXT: (CXXPattern name:__MatchICst_alt0_pattern_0 match code:"return matchIConstant(${foo}, ${cst})"), // CHECK-NEXT: ], // CHECK-NEXT: ]) // CHECK-NEXT: ) // CHECK-NEXT: ) // CHECK-NEXT: (MatchPats // CHECK-NEXT: __PatFragTest0_match_0:(CodeGenInstructionPattern G_ZEXT operands:[$dst, $cst]) // CHECK-NEXT: __PatFragTest0_match_1:(PatFragPattern MatchICst operands:[$cst, (i32 0)]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __PatFragTest0_apply_0:(CodeGenInstructionPattern COPY operands:[$dst, (i32 0)]) // CHECK-NEXT: __PatFragTest0_apply_1:(CXXPattern apply code:"APPLY ${src}") // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: cst -> // CHECK-NEXT: dst -> __PatFragTest0_match_0 // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats // CHECK-NEXT: dst -> __PatFragTest0_apply_0 // CHECK-NEXT: ) // CHECK-NEXT: ) def PatFragTest0 : GICombineRule< (defs root:$dst), (match (G_ZEXT $dst, $cst), (MatchICst $cst, (i32 0))), (apply (COPY $dst, (i32 0)), "APPLY ${src}")>; def MatchFooPerms: GICombinePatFrag< (outs), (ins gi_mo:$foo, gi_imm:$cst), [ (pattern "return foo(${foo}, ${cst})"), (pattern "return bar(${foo}, ${cst})"), (pattern "return bux(${foo}, ${cst})"), ]>; // CHECK: (CombineRule name:PatFragTest1 id:7 root:dst // CHECK-NEXT: (PatFrags // CHECK-NEXT: (PatFrag name:MatchFooPerms // CHECK-NEXT: (ins [foo:machine_operand, cst:imm]) // CHECK-NEXT: (alternatives [ // CHECK-NEXT: [ // CHECK-NEXT: (CXXPattern name:__MatchFooPerms_alt0_pattern_0 match code:"return foo(${foo}, ${cst})"), // CHECK-NEXT: ], // CHECK-NEXT: [ // CHECK-NEXT: (CXXPattern name:__MatchFooPerms_alt1_pattern_0 match code:"return bar(${foo}, ${cst})"), // CHECK-NEXT: ], // CHECK-NEXT: [ // CHECK-NEXT: (CXXPattern name:__MatchFooPerms_alt2_pattern_0 match code:"return bux(${foo}, ${cst})"), // CHECK-NEXT: ], // CHECK-NEXT: ]) // CHECK-NEXT: ) // CHECK-NEXT: ) // CHECK-NEXT: (MatchPats // CHECK-NEXT: __PatFragTest1_match_0:(CodeGenInstructionPattern G_ZEXT operands:[$dst, $cst]) // CHECK-NEXT: a:(PatFragPattern MatchFooPerms operands:[$cst, (i32 0)]) // CHECK-NEXT: b:(PatFragPattern MatchFooPerms operands:[$cst, (i32 0)]) // CHECK-NEXT: c:(PatFragPattern MatchFooPerms operands:[$cst, (i32 0)]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __PatFragTest1_apply_0:(CodeGenInstructionPattern COPY operands:[$dst, (i32 0)]) // CHECK-NEXT: __PatFragTest1_apply_1:(CXXPattern apply code:"APPLY ${src}") // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: cst -> // CHECK-NEXT: dst -> __PatFragTest1_match_0 // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats // CHECK-NEXT: dst -> __PatFragTest1_apply_0 // CHECK-NEXT: ) // CHECK-NEXT: (PermutationsToEmit // CHECK-NEXT: [a[0], b[0], c[0]], // CHECK-NEXT: [a[0], b[0], c[1]], // CHECK-NEXT: [a[0], b[0], c[2]], // CHECK-NEXT: [a[0], b[1], c[0]], // CHECK-NEXT: [a[0], b[1], c[1]], // CHECK-NEXT: [a[0], b[1], c[2]], // CHECK-NEXT: [a[0], b[2], c[0]], // CHECK-NEXT: [a[0], b[2], c[1]], // CHECK-NEXT: [a[0], b[2], c[2]], // CHECK-NEXT: [a[1], b[0], c[0]], // CHECK-NEXT: [a[1], b[0], c[1]], // CHECK-NEXT: [a[1], b[0], c[2]], // CHECK-NEXT: [a[1], b[1], c[0]], // CHECK-NEXT: [a[1], b[1], c[1]], // CHECK-NEXT: [a[1], b[1], c[2]], // CHECK-NEXT: [a[1], b[2], c[0]], // CHECK-NEXT: [a[1], b[2], c[1]], // CHECK-NEXT: [a[1], b[2], c[2]], // CHECK-NEXT: [a[2], b[0], c[0]], // CHECK-NEXT: [a[2], b[0], c[1]], // CHECK-NEXT: [a[2], b[0], c[2]], // CHECK-NEXT: [a[2], b[1], c[0]], // CHECK-NEXT: [a[2], b[1], c[1]], // CHECK-NEXT: [a[2], b[1], c[2]], // CHECK-NEXT: [a[2], b[2], c[0]], // CHECK-NEXT: [a[2], b[2], c[1]], // CHECK-NEXT: [a[2], b[2], c[2]], // CHECK-NEXT: ) // CHECK-NEXT: ) let MaxPermutations = -1 in def PatFragTest1 : GICombineRule< (defs root:$dst), (match (G_ZEXT $dst, $cst), (MatchFooPerms $cst, (i32 0)):$a, (MatchFooPerms $cst, (i32 0)):$b, (MatchFooPerms $cst, (i32 0)):$c ), (apply (COPY $dst, (i32 0)), "APPLY ${src}")>; // CHECK: (CombineRule name:VariadicsInTest id:8 root:dst // CHECK-NEXT: (MatchPats // CHECK-NEXT: __VariadicsInTest_match_0:(CodeGenInstructionPattern G_BUILD_VECTOR operands:[$dst, $a, $b]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __VariadicsInTest_apply_0:(CodeGenInstructionPattern COPY operands:[$dst, (i32 0)]) // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: a -> // CHECK-NEXT: b -> // CHECK-NEXT: dst -> __VariadicsInTest_match_0 // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats // CHECK-NEXT: dst -> __VariadicsInTest_apply_0 // CHECK-NEXT: ) // CHECK-NEXT: ) def VariadicsInTest : GICombineRule< (defs root:$dst), (match (G_BUILD_VECTOR $dst, $a, $b)), (apply (COPY $dst, (i32 0)))>; // CHECK: (CombineRule name:VariadicsOutTest id:9 root:a // CHECK-NEXT: (MatchPats // CHECK-NEXT: __VariadicsOutTest_match_0:(CodeGenInstructionPattern G_UNMERGE_VALUES operands:[$a, $b, $src]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __VariadicsOutTest_apply_0:(CodeGenInstructionPattern COPY operands:[$a, (i32 0)]) // CHECK-NEXT: __VariadicsOutTest_apply_1:(CodeGenInstructionPattern COPY operands:[$b, (i32 0)]) // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: a -> __VariadicsOutTest_match_0 // CHECK-NEXT: b -> __VariadicsOutTest_match_0 // CHECK-NEXT: src -> // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats // CHECK-NEXT: a -> __VariadicsOutTest_apply_0 // CHECK-NEXT: b -> __VariadicsOutTest_apply_1 // CHECK-NEXT: ) // CHECK-NEXT: ) def VariadicsOutTest : GICombineRule< (defs root:$a), (match (G_UNMERGE_VALUES $a, $b, $src)), (apply (COPY $a, (i32 0)), (COPY $b, (i32 0)))>; // CHECK: (CombineRule name:TypeOfTest id:10 root:dst // CHECK-NEXT: (MatchPats // CHECK-NEXT: __TypeOfTest_match_0:(CodeGenInstructionPattern COPY operands:[$dst, $tmp]) // CHECK-NEXT: __TypeOfTest_match_1:(CodeGenInstructionPattern G_ZEXT operands:[$tmp, $src]) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __TypeOfTest_apply_0:(CodeGenInstructionPattern G_MUL operands:[$dst, (GITypeOf<$src> 0), (GITypeOf<$dst> -1)]) // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: dst -> __TypeOfTest_match_0 // CHECK-NEXT: src -> // CHECK-NEXT: tmp -> __TypeOfTest_match_1 // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats // CHECK-NEXT: dst -> __TypeOfTest_apply_0 // CHECK-NEXT: ) // CHECK-NEXT: ) def TypeOfTest : GICombineRule< (defs root:$dst), (match (COPY $dst, $tmp), (G_ZEXT $tmp, $src)), (apply (G_MUL $dst, (GITypeOf<"$src"> 0), (GITypeOf<"$dst"> -1)))>; // CHECK: (CombineRule name:MIFlagsTest id:11 root:dst // CHECK-NEXT: (MatchPats // CHECK-NEXT: mi:(CodeGenInstructionPattern G_ZEXT operands:[$dst, $src] (MIFlags (set MachineInstr::FmReassoc) (unset MachineInstr::FmNoNans, MachineInstr::FmArcp))) // CHECK-NEXT: ) // CHECK-NEXT: (ApplyPats // CHECK-NEXT: __MIFlagsTest_apply_0:(CodeGenInstructionPattern G_MUL operands:[$dst, $src, $src] (MIFlags (set MachineInstr::FmReassoc) (unset MachineInstr::FmNsz, MachineInstr::FmArcp) (copy mi))) // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable MatchPats // CHECK-NEXT: dst -> mi // CHECK-NEXT: src -> // CHECK-NEXT: ) // CHECK-NEXT: (OperandTable ApplyPats // CHECK-NEXT: dst -> __MIFlagsTest_apply_0 // CHECK-NEXT: src -> // CHECK-NEXT: ) // CHECK-NEXT: ) def MIFlagsTest : GICombineRule< (defs root:$dst), (match (G_ZEXT $dst, $src, (MIFlags FmReassoc, (not FmNoNans, FmArcp))):$mi), (apply (G_MUL $dst, $src, $src, (MIFlags $mi, FmReassoc, (not FmNsz, FmArcp))))>; def MyCombiner: GICombiner<"GenMyCombiner", [ WipOpcodeTest0, WipOpcodeTest1, InstTest0, InstTest1, InstTest2, InOutInstTest0, PatFragTest0, PatFragTest1, VariadicsInTest, VariadicsOutTest, TypeOfTest, MIFlagsTest ]>;