Skip to content

Commit 0e52092

Browse files
authored
[AArch64] Adjust comparison constant if adjusting it means less instructions (#151024)
Prefer constants that require less instructions to materialize, in both Global-ISel and Selection-DAG
1 parent 858d1df commit 0e52092

File tree

6 files changed

+277
-544
lines changed

6 files changed

+277
-544
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,6 +3518,13 @@ bool isLegalCmpImmed(APInt C) {
35183518
return isLegalArithImmed(C.abs().getZExtValue());
35193519
}
35203520

3521+
unsigned numberOfInstrToLoadImm(APInt C) {
3522+
uint64_t Imm = C.getZExtValue();
3523+
SmallVector<AArch64_IMM::ImmInsnModel> Insn;
3524+
AArch64_IMM::expandMOVImm(Imm, 32, Insn);
3525+
return Insn.size();
3526+
}
3527+
35213528
static bool isSafeSignedCMN(SDValue Op, SelectionDAG &DAG) {
35223529
// 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
35233530
if (Op->getFlags().hasNoSignedWrap())
@@ -3987,6 +3994,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
39873994
// CC has already been adjusted.
39883995
RHS = DAG.getConstant(0, DL, VT);
39893996
} else if (!isLegalCmpImmed(C)) {
3997+
unsigned NumImmForC = numberOfInstrToLoadImm(C);
39903998
// Constant does not fit, try adjusting it by one?
39913999
switch (CC) {
39924000
default:
@@ -3995,43 +4003,48 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
39954003
case ISD::SETGE:
39964004
if (!C.isMinSignedValue()) {
39974005
APInt CMinusOne = C - 1;
3998-
if (isLegalCmpImmed(CMinusOne)) {
4006+
if (isLegalCmpImmed(CMinusOne) ||
4007+
(NumImmForC > numberOfInstrToLoadImm(CMinusOne))) {
39994008
CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
40004009
RHS = DAG.getConstant(CMinusOne, DL, VT);
40014010
}
40024011
}
40034012
break;
40044013
case ISD::SETULT:
4005-
case ISD::SETUGE:
4006-
if (!C.isZero()) {
4007-
APInt CMinusOne = C - 1;
4008-
if (isLegalCmpImmed(CMinusOne)) {
4009-
CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
4010-
RHS = DAG.getConstant(CMinusOne, DL, VT);
4011-
}
4014+
case ISD::SETUGE: {
4015+
// C is not 0 because it is a legal immediate.
4016+
assert(!C.isZero() && "C should not be zero here");
4017+
APInt CMinusOne = C - 1;
4018+
if (isLegalCmpImmed(CMinusOne) ||
4019+
(NumImmForC > numberOfInstrToLoadImm(CMinusOne))) {
4020+
CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
4021+
RHS = DAG.getConstant(CMinusOne, DL, VT);
40124022
}
40134023
break;
4024+
}
40144025
case ISD::SETLE:
40154026
case ISD::SETGT:
40164027
if (!C.isMaxSignedValue()) {
40174028
APInt CPlusOne = C + 1;
4018-
if (isLegalCmpImmed(CPlusOne)) {
4029+
if (isLegalCmpImmed(CPlusOne) ||
4030+
(NumImmForC > numberOfInstrToLoadImm(CPlusOne))) {
40194031
CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
40204032
RHS = DAG.getConstant(CPlusOne, DL, VT);
40214033
}
40224034
}
40234035
break;
40244036
case ISD::SETULE:
4025-
case ISD::SETUGT:
4026-
if (!C.isAllOnes()) {
4027-
APInt CPlusOne = C + 1;
4028-
if (isLegalCmpImmed(CPlusOne)) {
4029-
CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4030-
RHS = DAG.getConstant(CPlusOne, DL, VT);
4031-
}
4037+
case ISD::SETUGT: {
4038+
assert(!C.isAllOnes() && "C should not be -1 here");
4039+
APInt CPlusOne = C + 1;
4040+
if (isLegalCmpImmed(CPlusOne) ||
4041+
(NumImmForC > numberOfInstrToLoadImm(CPlusOne))) {
4042+
CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4043+
RHS = DAG.getConstant(CPlusOne, DL, VT);
40324044
}
40334045
break;
40344046
}
4047+
}
40354048
}
40364049
}
40374050

llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,7 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
614614
// x uge c => x ugt c - 1
615615
//
616616
// When c is not zero.
617-
if (C == 0)
618-
return std::nullopt;
617+
assert(C != 0 && "C should not be zero here!");
619618
P = (P == CmpInst::ICMP_ULT) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
620619
C -= 1;
621620
break;
@@ -640,10 +639,8 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
640639
// x ule c => x ult c + 1
641640
// x ugt c => s uge c + 1
642641
//
643-
// When c is not the largest possible unsigned integer.
644-
if ((Size == 32 && static_cast<uint32_t>(C) == UINT32_MAX) ||
645-
(Size == 64 && C == UINT64_MAX))
646-
return std::nullopt;
642+
assert(C != (Size == 32 ? UINT32_MAX : UINT64_MAX) &&
643+
"C should not be -1 here!");
647644
P = (P == CmpInst::ICMP_ULE) ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
648645
C += 1;
649646
break;
@@ -656,14 +653,13 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
656653
if (isLegalArithImmed(C))
657654
return {{C, P}};
658655

659-
auto IsMaterializableInSingleInstruction = [=](uint64_t Imm) {
656+
auto NumberOfInstrToLoadImm = [=](uint64_t Imm) {
660657
SmallVector<AArch64_IMM::ImmInsnModel> Insn;
661658
AArch64_IMM::expandMOVImm(Imm, 32, Insn);
662-
return Insn.size() == 1;
659+
return Insn.size();
663660
};
664661

665-
if (!IsMaterializableInSingleInstruction(OriginalC) &&
666-
IsMaterializableInSingleInstruction(C))
662+
if (NumberOfInstrToLoadImm(OriginalC) > NumberOfInstrToLoadImm(C))
667663
return {{C, P}};
668664

669665
return std::nullopt;

0 commit comments

Comments
 (0)