[llvm] [GlobalISel] Combine [S,U]SUBO (PR #116489)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 16 09:54:40 PST 2024
================
@@ -84,3 +84,75 @@ bool CombinerHelper::matchMergeXAndZero(const MachineInstr &MI,
};
return true;
}
+
+bool CombinerHelper::matchSuboCarryOut(const MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ const GSubCarryOut *Subo = cast<GSubCarryOut>(&MI);
+
+ Register Dst = Subo->getReg(0);
+ Register LHS = Subo->getLHSReg();
+ Register RHS = Subo->getRHSReg();
+ Register Carry = Subo->getCarryOutReg();
+ LLT DstTy = MRI.getType(Dst);
+ LLT CarryTy = MRI.getType(Carry);
+
+ // Check legality before known bits.
+ if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SUB, {DstTy}}) ||
+ !isConstantLegalOrBeforeLegalizer(CarryTy))
+ return false;
+
+ if (Subo->isSigned()) {
+ // G_SSUBO
+ ConstantRange KBLHS = ConstantRange::fromKnownBits(KB->getKnownBits(LHS),
+ /* IsSigned= */ true);
+ ConstantRange KBRHS = ConstantRange::fromKnownBits(KB->getKnownBits(RHS),
+ /* IsSigned= */ true);
+ switch (KBLHS.signedSubMayOverflow(KBRHS)) {
+ case ConstantRange::OverflowResult::MayOverflow:
+ return false;
+ case ConstantRange::OverflowResult::NeverOverflows: {
+ MatchInfo = [=](MachineIRBuilder &B) {
+ B.buildSub(Dst, LHS, RHS, MachineInstr::MIFlag::NoSWrap);
+ B.buildConstant(Carry, 0);
+ };
+ return true;
+ }
+ case ConstantRange::OverflowResult::AlwaysOverflowsLow:
+ case ConstantRange::OverflowResult::AlwaysOverflowsHigh: {
+ MatchInfo = [=](MachineIRBuilder &B) {
+ B.buildSub(Dst, LHS, RHS);
+ B.buildConstant(Carry, 1);
+ };
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // G_USUBO
+ ConstantRange KBLHS = ConstantRange::fromKnownBits(KB->getKnownBits(LHS),
+ /* IsSigned= */ false);
+ ConstantRange KBRHS = ConstantRange::fromKnownBits(KB->getKnownBits(RHS),
+ /* IsSigned= */ false);
----------------
arsenm wrote:
Can avoid duplicating these in the signed / unsigned cases
https://github.com/llvm/llvm-project/pull/116489
More information about the llvm-commits
mailing list