Skip to content

Commit fa8e465

Browse files
committed
[GISel] Support narrowing G_ICMP with more than 2 parts.
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 ef2e590 commit fa8e465

29 files changed

+970
-897
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

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

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

0 commit comments

Comments
 (0)