Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3493,6 +3493,13 @@ bool isLegalCmpImmed(APInt C) {
return isLegalArithImmed(C.abs().getZExtValue());
}

unsigned numberOfInstrToLoadImm(APInt C) {
uint64_t Imm = C.getZExtValue();
SmallVector<AArch64_IMM::ImmInsnModel> Insn;
AArch64_IMM::expandMOVImm(Imm, 32, Insn);
return Insn.size();
}

static bool isSafeSignedCMN(SDValue Op, SelectionDAG &DAG) {
// 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
if (Op->getFlags().hasNoSignedWrap())
Expand Down Expand Up @@ -3962,6 +3969,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
// CC has already been adjusted.
RHS = DAG.getConstant(0, DL, VT);
} else if (!isLegalCmpImmed(C)) {
unsigned NumImmForC = numberOfInstrToLoadImm(C);
// Constant does not fit, try adjusting it by one?
switch (CC) {
default:
Expand All @@ -3970,43 +3978,48 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
case ISD::SETGE:
if (!C.isMinSignedValue()) {
APInt CMinusOne = C - 1;
if (isLegalCmpImmed(CMinusOne)) {
if (isLegalCmpImmed(CMinusOne) ||
(NumImmForC > numberOfInstrToLoadImm(CMinusOne))) {
CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
RHS = DAG.getConstant(CMinusOne, DL, VT);
}
}
break;
case ISD::SETULT:
case ISD::SETUGE:
if (!C.isZero()) {
APInt CMinusOne = C - 1;
if (isLegalCmpImmed(CMinusOne)) {
CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
RHS = DAG.getConstant(CMinusOne, DL, VT);
}
case ISD::SETUGE: {
// C is not 0 because it is a legal immediate.
assert(!C.isZero() && "C should not be zero here");
APInt CMinusOne = C - 1;
if (isLegalCmpImmed(CMinusOne) ||
(NumImmForC > numberOfInstrToLoadImm(CMinusOne))) {
CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
RHS = DAG.getConstant(CMinusOne, DL, VT);
}
break;
}
case ISD::SETLE:
case ISD::SETGT:
if (!C.isMaxSignedValue()) {
APInt CPlusOne = C + 1;
if (isLegalCmpImmed(CPlusOne)) {
if (isLegalCmpImmed(CPlusOne) ||
(NumImmForC > numberOfInstrToLoadImm(CPlusOne))) {
CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
RHS = DAG.getConstant(CPlusOne, DL, VT);
}
}
break;
case ISD::SETULE:
case ISD::SETUGT:
if (!C.isAllOnes()) {
APInt CPlusOne = C + 1;
if (isLegalCmpImmed(CPlusOne)) {
CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
RHS = DAG.getConstant(CPlusOne, DL, VT);
}
case ISD::SETUGT: {
assert(!C.isAllOnes() && "C should not be -1 here");
APInt CPlusOne = C + 1;
if (isLegalCmpImmed(CPlusOne) ||
(NumImmForC > numberOfInstrToLoadImm(CPlusOne))) {
CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
RHS = DAG.getConstant(CPlusOne, DL, VT);
}
break;
}
}
}
}

Expand Down
16 changes: 6 additions & 10 deletions llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,8 +614,7 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
// x uge c => x ugt c - 1
//
// When c is not zero.
if (C == 0)
return std::nullopt;
assert(C != 0 && "C should not be zero here!");
P = (P == CmpInst::ICMP_ULT) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
C -= 1;
break;
Expand All @@ -640,10 +639,8 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
// x ule c => x ult c + 1
// x ugt c => s uge c + 1
//
// When c is not the largest possible unsigned integer.
if ((Size == 32 && static_cast<uint32_t>(C) == UINT32_MAX) ||
(Size == 64 && C == UINT64_MAX))
return std::nullopt;
assert(C != (Size == 32 ? UINT32_MAX : UINT64_MAX) &&
"C should not be -1 here!");
P = (P == CmpInst::ICMP_ULE) ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
C += 1;
break;
Expand All @@ -656,14 +653,13 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
if (isLegalArithImmed(C))
return {{C, P}};

auto IsMaterializableInSingleInstruction = [=](uint64_t Imm) {
auto NumberOfInstrToLoadImm = [=](uint64_t Imm) {
SmallVector<AArch64_IMM::ImmInsnModel> Insn;
AArch64_IMM::expandMOVImm(Imm, 32, Insn);
return Insn.size() == 1;
return Insn.size();
};

if (!IsMaterializableInSingleInstruction(OriginalC) &&
IsMaterializableInSingleInstruction(C))
if (NumberOfInstrToLoadImm(OriginalC) > NumberOfInstrToLoadImm(C))
return {{C, P}};

return std::nullopt;
Expand Down
Loading