diff options
author | Kai Nacke <kai@redstar.de> | 2022-09-08 09:15:12 -0400 |
---|---|---|
committer | Kai Nacke <kai@redstar.de> | 2022-11-13 11:07:57 -0500 |
commit | b99c558013e5bd99e91d9b78d732dc9d7bf21b94 (patch) | |
tree | 98f57607d6cdcb44fbd3b13c8d555a6279aed230 | |
parent | db0b5cd5909e2e6a35a0d892f54868906be295d0 (diff) | |
download | llvm-b99c558013e5bd99e91d9b78d732dc9d7bf21b94.zip llvm-b99c558013e5bd99e91d9b78d732dc9d7bf21b94.tar.gz llvm-b99c558013e5bd99e91d9b78d732dc9d7bf21b94.tar.bz2 |
[m88k] Add another combine pattern.
- Handles call to @llvm.usub.with.overflow.i32()
- Turns carry into a bit
- Adds some more tests
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def | 4 | ||||
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/Target/M88k/M88kCombine.td | 15 | ||||
-rw-r--r-- | llvm/test/CodeGen/M88k/add.ll | 27 |
5 files changed, 91 insertions, 10 deletions
diff --git a/llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def b/llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def index 8cd362a..292981f 100644 --- a/llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def +++ b/llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def @@ -23,8 +23,8 @@ RegisterBankInfo::PartialMapping M88kGenRegisterBankInfo::PartMappings[]{ {0, 32, M88k::GRRegBank}, // 4: GPR 64-bit value. {0, 64, M88k::GRRegBank}, - // 5: CR 32-bit value. - {0, 32, M88k::CRRegBank}, + // 5: CR 1-bit value. + {0, 1, M88k::CRRegBank}, }; // ValueMappings. diff --git a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp index 8533953..d03779e 100644 --- a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp @@ -87,9 +87,10 @@ M88kLegalizerInfo::M88kLegalizerInfo(const M88kSubtarget &ST) { all(typeInSet(0, {V8S8, V4S16, V2S32}), LegalityPredicate(IsMC88110))) .clampScalar(0, S32, S32); getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_USUBO, G_USUBE}) - .legalFor({S32, S32}) + .legalFor({{S32, S1}}) .clampScalar(0, S32, S32) - .clampScalar(1, S32, S32); + .lower(); + getActionDefinitionsBuilder({G_SADDO, G_SADDE, G_SSUBO, G_SSUBE}).lower(); getActionDefinitionsBuilder({G_MUL, G_UDIV}) .legalFor({S32}) .customIf(all(typeInSet(0, {S64}), LegalityPredicate(IsMC88110))) diff --git a/llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp b/llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp index 79ec7c40..65f6aee 100644 --- a/llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp @@ -109,9 +109,9 @@ bool applyAddCmpToSubAdd(MachineInstr &MI, MachineRegisterInfo &MRI, std::tie(SrcRegA, SrcRegB, ZeroReg) = MatchInfo; MachineIRBuilder B(MI); - Register Carry = MRI.createGenericVirtualRegister(LLT::scalar(32)); + Register Carry = MRI.createGenericVirtualRegister(LLT::scalar(1)); Register UnusedReg = MRI.createGenericVirtualRegister(LLT::scalar(32)); - Register UnusedCarry = MRI.createGenericVirtualRegister(LLT::scalar(32)); + Register UnusedCarry = MRI.createGenericVirtualRegister(LLT::scalar(1)); B.buildInstr(TargetOpcode::G_USUBO, {UnusedReg, Carry}, {ZeroReg, SrcRegB}); B.buildInstr(TargetOpcode::G_UADDE, {DstReg, UnusedCarry}, @@ -158,9 +158,9 @@ bool matchAddCmpToSubAdd2(MachineInstr &MI, MachineOperand &Src1, return false; } - Register Carry = MRI.createGenericVirtualRegister(LLT::scalar(32)); + Register Carry = MRI.createGenericVirtualRegister(LLT::scalar(1)); Register UnusedReg = MRI.createGenericVirtualRegister(LLT::scalar(32)); - Register UnusedCarry = MRI.createGenericVirtualRegister(LLT::scalar(32)); + Register UnusedCarry = MRI.createGenericVirtualRegister(LLT::scalar(1)); MatchInfo = [=](MachineIRBuilder &B) { if (Pred != CmpInst::ICMP_EQ) @@ -223,9 +223,9 @@ bool matchAddSubFromAddICmp(MachineInstr &MI, MachineRegisterInfo &MRI, return false; } - Register Carry = MRI.createGenericVirtualRegister(LLT::scalar(32)); + Register Carry = MRI.createGenericVirtualRegister(LLT::scalar(1)); Register UnusedReg = MRI.createGenericVirtualRegister(LLT::scalar(32)); - Register UnusedCarry = MRI.createGenericVirtualRegister(LLT::scalar(32)); + Register UnusedCarry = MRI.createGenericVirtualRegister(LLT::scalar(1)); MatchInfo = [=](MachineIRBuilder &B) { if (Pred != CmpInst::ICMP_EQ) @@ -238,6 +238,44 @@ bool matchAddSubFromAddICmp(MachineInstr &MI, MachineRegisterInfo &MRI, return true; } +// Match +// Unused, CarryBit = G_USUBU SrcB, SrcC +// Carry = G_ZEXT CarryBit +// Dst = G_UADD SrcA, Carry +// The returned MatchInfo transforms this sequence into +// Unused, Carry = G_USUBU SrcB, SrcC +// Dst, UnusedCarry = G_UADDE SrcA, Zero, Carry +// inserting a zero constant value if necessary. +bool matchAddSubFromAddSub(MachineInstr &MI, MachineRegisterInfo &MRI, + BuildFnTy &MatchInfo) { + assert(MI.getOpcode() == TargetOpcode::G_ADD); + + Register DstReg = MI.getOperand(0).getReg(); + Register SrcRegA; + Register Carry; + Register ZeroReg = MRI.createGenericVirtualRegister(LLT::scalar(32)); + MachineInstr *SubMI; + if (!mi_match( + MI, MRI, + m_GAdd(m_Reg(SrcRegA), m_GZExt(m_Reg(Carry))))) + return false; + SubMI = MRI.getVRegDef(Carry); + if (SubMI->getOpcode() != TargetOpcode::G_USUBO) + return false; + if (SubMI->getOperand(1).getReg() != Carry) + return false; + + Register UnusedCarry = MRI.createGenericVirtualRegister(LLT::scalar(1)); + + MatchInfo = [=](MachineIRBuilder &B) { + B.buildConstant(ZeroReg, 0); + B.buildInstr(TargetOpcode::G_UADDE, {DstReg, UnusedCarry}, + {SrcRegA, ZeroReg, Carry}); + }; + + return true; +} + #define M88KPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS #include "M88kGenPostLegalizeGICombiner.inc" #undef M88KPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS diff --git a/llvm/lib/Target/M88k/M88kCombine.td b/llvm/lib/Target/M88k/M88kCombine.td index e61e168..63f51fe 100644 --- a/llvm/lib/Target/M88k/M88kCombine.td +++ b/llvm/lib/Target/M88k/M88kCombine.td @@ -93,12 +93,27 @@ def addsub_from_addicmp : GICombineRule< [{ return matchAddSubFromAddICmp(*${root}, MRI, ${matchinfo}); }]), (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>; +// Combine +// Unused, CarryBit = G_USUBU SrcB, SrcC +// Carry = G_ZEXT CarryBit +// Dst = G_UADD SrcA, Carry +// into the instruction sequence +// Unused, Carry = G_USUBU SrcB, SrcC +// Dst, UnusedCarry = G_UADDE SrcA, Zero, Carry +// inserting a zero constant value if necessary. +def addsub_from_addsub : GICombineRule< + (defs root:$root, build_fn_matchinfo:$matchinfo), + (match (wip_match_opcode G_ADD):$root, + [{ return matchAddSubFromAddSub(*${root}, MRI, ${matchinfo}); }]), + (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>; + // Post-legalization combines which are primarily optimizations. def M88kPostLegalizerCombinerHelper: GICombinerHelper< "M88kGenPostLegalizerCombinerHelper", [ //subadd_from_icmpadd1, //subadd_from_icmpadd2, addsub_from_addicmp, + addsub_from_addsub, form_bitfield_extract, // Some rules require legalizer rotate_out_of_range // Required for left rotates, which produce a negative constant ]> { diff --git a/llvm/test/CodeGen/M88k/add.ll b/llvm/test/CodeGen/M88k/add.ll index b570d464..c8d9050 100644 --- a/llvm/test/CodeGen/M88k/add.ll +++ b/llvm/test/CodeGen/M88k/add.ll @@ -65,3 +65,30 @@ define i32 @f7(i32 %a, i32 %b) { %sum = add i32 %conv, %b ret i32 %sum } + +; Same, but using intrinsic +define i32 @f8(i32 %a, i32 %b) { +; CHECK-LABEL: f8: +; CHECK: subu.co %r2, %r4, %r2 +; CHECK-NEXT: addu.ci %r2, %r3, %r4 +; CHECK-NEXT: jmp %r1 + %res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 %a) + %carrybit = extractvalue { i32, i1 } %res, 1 + %carry = zext i1 %carrybit to i32 + %sum = add i32 %carry, %b + ret i32 %sum +} + +declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) + +; Special case: return (a >= b) + c +define i32 @f9(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: f9: +; CHECK: subu.co %r2, %r3, %r2 +; CHECK-NEXT: addu.ci %r2, %r4, %r5 +; CHECK-NEXT: jmp %r1 + %cmp = icmp uge i32 %a, %b + %conv = zext i1 %cmp to i32 + %sum = add i32 %conv, %c + ret i32 %sum +} |