Skip to content

Commit 5fa2318

Browse files
committed
[AArch64] Adjust comparison constant if adjusting it means less instructions
Prefer constants that require less instructions to materialize, in both Global-ISel and Selection-DAG
1 parent e0f5e28 commit 5fa2318

File tree

6 files changed

+262
-540
lines changed

6 files changed

+262
-540
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

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

3496+
unsigned numberOfInstrToLoadImm(APInt C) {
3497+
uint64_t Imm = C.getZExtValue();
3498+
SmallVector<AArch64_IMM::ImmInsnModel> Insn;
3499+
AArch64_IMM::expandMOVImm(Imm, 32, Insn);
3500+
return Insn.size();
3501+
}
3502+
34963503
static bool isSafeSignedCMN(SDValue Op, SelectionDAG &DAG) {
34973504
// 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
34983505
if (Op->getFlags().hasNoSignedWrap())
@@ -3962,6 +3969,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
39623969
// CC has already been adjusted.
39633970
RHS = DAG.getConstant(0, DL, VT);
39643971
} else if (!isLegalCmpImmed(C)) {
3972+
unsigned NumImmForC = numberOfInstrToLoadImm(C);
39653973
// Constant does not fit, try adjusting it by one?
39663974
switch (CC) {
39673975
default:
@@ -3970,43 +3978,48 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
39703978
case ISD::SETGE:
39713979
if (!C.isMinSignedValue()) {
39723980
APInt CMinusOne = C - 1;
3973-
if (isLegalCmpImmed(CMinusOne)) {
3981+
if (isLegalCmpImmed(CMinusOne) ||
3982+
(NumImmForC > numberOfInstrToLoadImm(CMinusOne))) {
39743983
CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
39753984
RHS = DAG.getConstant(CMinusOne, DL, VT);
39763985
}
39773986
}
39783987
break;
39793988
case ISD::SETULT:
3980-
case ISD::SETUGE:
3981-
if (!C.isZero()) {
3982-
APInt CMinusOne = C - 1;
3983-
if (isLegalCmpImmed(CMinusOne)) {
3984-
CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
3985-
RHS = DAG.getConstant(CMinusOne, DL, VT);
3986-
}
3989+
case ISD::SETUGE: {
3990+
// C is not 0 because it is a legal immediate.
3991+
assert(!C.isZero() && "C should not be zero here");
3992+
APInt CMinusOne = C - 1;
3993+
if (isLegalCmpImmed(CMinusOne) ||
3994+
(NumImmForC > numberOfInstrToLoadImm(CMinusOne))) {
3995+
CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
3996+
RHS = DAG.getConstant(CMinusOne, DL, VT);
39873997
}
39883998
break;
3999+
}
39894000
case ISD::SETLE:
39904001
case ISD::SETGT:
39914002
if (!C.isMaxSignedValue()) {
39924003
APInt CPlusOne = C + 1;
3993-
if (isLegalCmpImmed(CPlusOne)) {
4004+
if (isLegalCmpImmed(CPlusOne) ||
4005+
(NumImmForC > numberOfInstrToLoadImm(CPlusOne))) {
39944006
CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
39954007
RHS = DAG.getConstant(CPlusOne, DL, VT);
39964008
}
39974009
}
39984010
break;
39994011
case ISD::SETULE:
4000-
case ISD::SETUGT:
4001-
if (!C.isAllOnes()) {
4002-
APInt CPlusOne = C + 1;
4003-
if (isLegalCmpImmed(CPlusOne)) {
4004-
CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4005-
RHS = DAG.getConstant(CPlusOne, DL, VT);
4006-
}
4012+
case ISD::SETUGT: {
4013+
assert(!C.isAllOnes() && "C should not be -1 here");
4014+
APInt CPlusOne = C + 1;
4015+
if (isLegalCmpImmed(CPlusOne) ||
4016+
(NumImmForC > numberOfInstrToLoadImm(CPlusOne))) {
4017+
CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4018+
RHS = DAG.getConstant(CPlusOne, DL, VT);
40074019
}
40084020
break;
40094021
}
4022+
}
40104023
}
40114024
}
40124025

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

Lines changed: 4 additions & 6 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 && "Expected non-zero unsigned immediate");
619618
P = (P == CmpInst::ICMP_ULT) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
620619
C -= 1;
621620
break;
@@ -656,14 +655,13 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
656655
if (isLegalArithImmed(C))
657656
return {{C, P}};
658657

659-
auto IsMaterializableInSingleInstruction = [=](uint64_t Imm) {
658+
auto NumberOfInstrToLoadImm = [=](uint64_t Imm) {
660659
SmallVector<AArch64_IMM::ImmInsnModel> Insn;
661660
AArch64_IMM::expandMOVImm(Imm, 32, Insn);
662-
return Insn.size() == 1;
661+
return Insn.size();
663662
};
664663

665-
if (!IsMaterializableInSingleInstruction(OriginalC) &&
666-
IsMaterializableInSingleInstruction(C))
664+
if (NumberOfInstrToLoadImm(OriginalC) > NumberOfInstrToLoadImm(C))
667665
return {{C, P}};
668666

669667
return std::nullopt;

0 commit comments

Comments
 (0)