Skip to content

Commit 7ece560

Browse files
authored
[GISel] Support narrowing G_ICMP with more than 2 parts. (llvm#119335)
This allows us to support i128 G_ICMP on RV32. I'm not sure how to test the "left over" part of this as RISC-V always widens to a power of 2 before narrowing.
1 parent 52db903 commit 7ece560

29 files changed

+969
-897
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,14 +1716,9 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
17161716
case TargetOpcode::G_ICMP: {
17171717
Register LHS = MI.getOperand(2).getReg();
17181718
LLT SrcTy = MRI.getType(LHS);
1719-
uint64_t SrcSize = SrcTy.getSizeInBits();
17201719
CmpInst::Predicate Pred =
17211720
static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
17221721

1723-
// TODO: Handle the non-equality case for weird sizes.
1724-
if (NarrowSize * 2 != SrcSize && !ICmpInst::isEquality(Pred))
1725-
return UnableToLegalize;
1726-
17271722
LLT LeftoverTy; // Example: s88 -> s64 (NarrowTy) + s24 (leftover)
17281723
SmallVector<Register, 4> LHSPartRegs, LHSLeftoverRegs;
17291724
if (!extractParts(LHS, SrcTy, NarrowTy, LeftoverTy, LHSPartRegs,
@@ -1775,19 +1770,59 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
17751770
Or = MIRBuilder.buildOr(NarrowTy, Or, Xors[I]);
17761771
MIRBuilder.buildICmp(Pred, Dst, Or, Zero);
17771772
} else {
1778-
// TODO: Handle non-power-of-two types.
1779-
assert(LHSPartRegs.size() == 2 && "Expected exactly 2 LHS part regs?");
1780-
assert(RHSPartRegs.size() == 2 && "Expected exactly 2 RHS part regs?");
1781-
Register LHSL = LHSPartRegs[0];
1782-
Register LHSH = LHSPartRegs[1];
1783-
Register RHSL = RHSPartRegs[0];
1784-
Register RHSH = RHSPartRegs[1];
1785-
MachineInstrBuilder CmpH = MIRBuilder.buildICmp(Pred, ResTy, LHSH, RHSH);
1786-
MachineInstrBuilder CmpHEQ =
1787-
MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, ResTy, LHSH, RHSH);
1788-
MachineInstrBuilder CmpLU = MIRBuilder.buildICmp(
1789-
ICmpInst::getUnsignedPredicate(Pred), ResTy, LHSL, RHSL);
1790-
MIRBuilder.buildSelect(Dst, CmpHEQ, CmpLU, CmpH);
1773+
Register CmpIn;
1774+
for (unsigned I = 0, E = LHSPartRegs.size(); I != E; ++I) {
1775+
Register CmpOut;
1776+
CmpInst::Predicate PartPred;
1777+
1778+
if (I == E - 1 && LHSLeftoverRegs.empty()) {
1779+
PartPred = Pred;
1780+
CmpOut = Dst;
1781+
} else {
1782+
PartPred = ICmpInst::getUnsignedPredicate(Pred);
1783+
CmpOut = MRI.createGenericVirtualRegister(ResTy);
1784+
}
1785+
1786+
if (!CmpIn) {
1787+
MIRBuilder.buildICmp(PartPred, CmpOut, LHSPartRegs[I],
1788+
RHSPartRegs[I]);
1789+
} else {
1790+
auto Cmp = MIRBuilder.buildICmp(PartPred, ResTy, LHSPartRegs[I],
1791+
RHSPartRegs[I]);
1792+
auto CmpEq = MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, ResTy,
1793+
LHSPartRegs[I], RHSPartRegs[I]);
1794+
MIRBuilder.buildSelect(CmpOut, CmpEq, CmpIn, Cmp);
1795+
}
1796+
1797+
CmpIn = CmpOut;
1798+
}
1799+
1800+
for (unsigned I = 0, E = LHSLeftoverRegs.size(); I != E; ++I) {
1801+
Register CmpOut;
1802+
CmpInst::Predicate PartPred;
1803+
1804+
if (I == E - 1 && LHSLeftoverRegs.empty()) {
1805+
PartPred = Pred;
1806+
CmpOut = Dst;
1807+
} else {
1808+
PartPred = ICmpInst::getUnsignedPredicate(Pred);
1809+
CmpOut = MRI.createGenericVirtualRegister(ResTy);
1810+
}
1811+
1812+
if (!CmpIn) {
1813+
MIRBuilder.buildICmp(PartPred, CmpOut, LHSLeftoverRegs[I],
1814+
RHSLeftoverRegs[I]);
1815+
} else {
1816+
auto Cmp = MIRBuilder.buildICmp(PartPred, ResTy, LHSLeftoverRegs[I],
1817+
RHSLeftoverRegs[I]);
1818+
auto CmpEq =
1819+
MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, ResTy,
1820+
LHSLeftoverRegs[I], RHSLeftoverRegs[I]);
1821+
MIRBuilder.buildSelect(CmpOut, CmpEq, CmpIn, Cmp);
1822+
}
1823+
1824+
CmpIn = CmpOut;
1825+
}
17911826
}
17921827
MI.eraseFromParent();
17931828
return Legalized;

0 commit comments

Comments
 (0)