aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Nacke <kai@redstar.de>2022-09-02 08:47:30 -0400
committerKai Nacke <kai@redstar.de>2022-11-13 11:07:56 -0500
commitc84e7977c35ee139b39da9a5137f4d2e62914fd1 (patch)
treea00965ddf4bd85c1e504c2a692840002a0dd5eef
parent67a418b5657de6712502cd50c4a12118debce25e (diff)
downloadllvm-c84e7977c35ee139b39da9a5137f4d2e62914fd1.zip
llvm-c84e7977c35ee139b39da9a5137f4d2e62914fd1.tar.gz
llvm-c84e7977c35ee139b39da9a5137f4d2e62914fd1.tar.bz2
[m88k] First steps with new optimization
Not yet enabled since it exposes a bug in the instruction selector.
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp76
-rw-r--r--llvm/lib/Target/M88k/M88kCombine.td14
2 files changed, 90 insertions, 0 deletions
diff --git a/llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp b/llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp
index 8f4322f..7722274 100644
--- a/llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kPostLegalizerCombiner.cpp
@@ -41,6 +41,82 @@
using namespace llvm;
using namespace MIPatternMatch;
+/*
+Match:
+
+ %2:gr(s32) = G_CONSTANT i32 0
+ %3:gr(s1) = G_ICMP intpred(eq), %0(s32), %2
+ %4:gr(s32) = G_ZEXT %3(s1)
+ %5:gr(s32) = nsw G_ADD %4, %1
+=>
+ %2:gr(s32) = G_CONSTANT i32 0
+ = G_USUBO %2, %0(s32)
+ = G_UADDE
+ subu.co %r0,%r0,%r2
+ addu.ci %r4,%r3,%r0
+
+ %2:gr(s32) = G_CONSTANT i32 0
+ %3:gr(s1) = G_ICMP intpred(ne), %1(s32), %2
+ %4:gr(s32) = G_SEXT %3(s1)
+ %5:gr(s32) = G_ADD %4, %0
+=>
+ subu.co %r0,%r0,%r3
+ subu.ci %r2,%r2,%r0
+*/
+
+// Match G_ADD ...
+bool matchAddCmpToSubAdd(MachineInstr &MI, MachineRegisterInfo &MRI,
+ std::tuple<Register, Register, Register> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_ADD);
+
+ Register SrcRegA;
+ Register SrcRegB;
+ Optional<ValueAndVReg> CstValReg;
+ CmpInst::Predicate Pred;
+ if (!mi_match(
+ MI, MRI,
+ m_GAdd(m_Reg(SrcRegA), m_GZExt(m_GICmp(m_Pred(Pred), m_Reg(SrcRegB),
+ m_GCst(CstValReg))))))
+ return false;
+
+ if (Pred != CmpInst::ICMP_EQ || !CstValReg || CstValReg->Value != 0)
+ return false;
+
+ MatchInfo = std::make_tuple(SrcRegA, SrcRegB, CstValReg->VReg);
+/*
+ MatchInfo = [=](MachineIRBuilder &B) {
+ Register CarryOut = MRI.createGenericVirtualRegister(LLT::scalar(32));
+
+ B.buildInstr(TargetOpcode::G_USUBO, {}, {});
+ B.buildInstr(TargetOpcode::G_UADDE, {}, {});
+ };
+*/
+ return true;
+}
+
+// Lower to ...
+bool applyAddCmpToSubAdd(MachineInstr &MI, MachineRegisterInfo &MRI,
+ std::tuple<Register, Register, Register> &MatchInfo) {
+ assert(MI.getOpcode() == TargetOpcode::G_ADD);
+
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcRegA;
+ Register SrcRegB;
+ Register ZeroReg;
+ std::tie(SrcRegA, SrcRegB, ZeroReg) = MatchInfo;
+
+ MachineIRBuilder B(MI);
+ Register Carry = MRI.createGenericVirtualRegister(LLT::scalar(32));
+ Register UnusedReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
+ Register UnusedCarry = MRI.createGenericVirtualRegister(LLT::scalar(32));
+
+ B.buildInstr(TargetOpcode::G_USUBO, {UnusedReg, Carry}, {ZeroReg, SrcRegB});
+ B.buildInstr(TargetOpcode::G_UADDE, {DstReg, UnusedCarry},
+ {SrcRegA, ZeroReg, Carry});
+ MI.eraseFromParent();
+ 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 94f8792..93abe58 100644
--- a/llvm/lib/Target/M88k/M88kCombine.td
+++ b/llvm/lib/Target/M88k/M88kCombine.td
@@ -54,9 +54,23 @@ def M88kPreLegalizerCombinerHelper: GICombinerHelper<
let AdditionalArguments = [];
}
+// Combine
+// G_ADD $dst, (G_ZEXT (G_ICMP eq, $src, 0))
+// into
+// G_UADDE $dst, (G_USUBO 0, %src)
+// under certain restrictions.
+def subadd_from_icmpadd_matchdata : GIDefMatchData<"std::tuple<Register, Register, Register>">;
+def subadd_from_icmpadd : GICombineRule<
+ (defs root:$root, subadd_from_icmpadd_matchdata:$matchinfo),
+ (match (wip_match_opcode G_ADD):$root,
+ [{ return matchAddCmpToSubAdd(*${root}, MRI,
+ ${matchinfo}); }]),
+ (apply [{ applyAddCmpToSubAdd(*${root}, MRI, ${matchinfo}); }])>;
+
// Post-legalization combines which are primarily optimizations.
def M88kPostLegalizerCombinerHelper: GICombinerHelper<
"M88kGenPostLegalizerCombinerHelper", [
+ //subadd_from_icmpadd,
form_bitfield_extract, // Some rules require legalizer
rotate_out_of_range // Required for left rotates, which produce a negative constant
]> {