-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[AArch64] Support MI and PL #150314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[AArch64] Support MI and PL #150314
Conversation
Now, why would we want to do this? There are a small number of places where this works: 1. It helps peepholeopt when less flag checking. 2. It allows the folding of things such as x - 0x80000000 < 0 to be folded to cmp x, register holding this value 3. We can refine the other passes over time for this.
@llvm/pr-subscribers-backend-aarch64 Author: AZero13 (AZero13) ChangesNow, why would we want to do this? There are a small number of places where this works:
Patch is 111.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/150314.diff 37 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ff23f76fadccd..4c8adb55606da 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3235,7 +3235,8 @@ static bool isZerosVector(const SDNode *N) {
/// changeIntCCToAArch64CC - Convert a DAG integer condition code to an AArch64
/// CC
-static AArch64CC::CondCode changeIntCCToAArch64CC(ISD::CondCode CC) {
+static AArch64CC::CondCode changeIntCCToAArch64CC(ISD::CondCode CC, SDValue RHS,
+ bool canUsePLOrMI = true) {
switch (CC) {
default:
llvm_unreachable("Unknown condition code!");
@@ -3246,9 +3247,9 @@ static AArch64CC::CondCode changeIntCCToAArch64CC(ISD::CondCode CC) {
case ISD::SETGT:
return AArch64CC::GT;
case ISD::SETGE:
- return AArch64CC::GE;
+ return canUsePLOrMI && isNullConstant(RHS) ? AArch64CC::PL : AArch64CC::GE;
case ISD::SETLT:
- return AArch64CC::LT;
+ return canUsePLOrMI && isNullConstant(RHS) ? AArch64CC::MI : AArch64CC::LT;
case ISD::SETLE:
return AArch64CC::LE;
case ISD::SETUGT:
@@ -3691,7 +3692,7 @@ static SDValue emitConjunctionRec(SelectionDAG &DAG, SDValue Val,
SDLoc DL(Val);
// Determine OutCC and handle FP special case.
if (isInteger) {
- OutCC = changeIntCCToAArch64CC(CC);
+ OutCC = changeIntCCToAArch64CC(CC, RHS);
} else {
assert(LHS.getValueType().isFloatingPoint());
AArch64CC::CondCode ExtraCC;
@@ -3974,7 +3975,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
Cmp = emitComparison(
SExt, DAG.getSignedConstant(ValueofRHS, DL, RHS.getValueType()), CC,
DL, DAG);
- AArch64CC = changeIntCCToAArch64CC(CC);
+ AArch64CC = changeIntCCToAArch64CC(CC, RHS);
}
}
@@ -3988,7 +3989,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
if (!Cmp) {
Cmp = emitComparison(LHS, RHS, CC, DL, DAG);
- AArch64CC = changeIntCCToAArch64CC(CC);
+ AArch64CC = changeIntCCToAArch64CC(CC, RHS);
}
AArch64cc = DAG.getConstant(AArch64CC, DL, MVT_CC);
return Cmp;
@@ -10555,10 +10556,10 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
// Try to emit Armv9.6 CB instructions. We prefer tb{n}z/cb{n}z due to their
// larger branch displacement but do prefer CB over cmp + br.
if (Subtarget->hasCMPBR() &&
- AArch64CC::isValidCBCond(changeIntCCToAArch64CC(CC)) &&
+ AArch64CC::isValidCBCond(changeIntCCToAArch64CC(CC, RHS, false)) &&
ProduceNonFlagSettingCondBr) {
- SDValue Cond =
- DAG.getTargetConstant(changeIntCCToAArch64CC(CC), DL, MVT::i32);
+ SDValue Cond = DAG.getTargetConstant(
+ changeIntCCToAArch64CC(CC, RHS, false), DL, MVT::i32);
return DAG.getNode(AArch64ISD::CB, DL, MVT::Other, Chain, Cond, LHS, RHS,
Dest);
}
@@ -11115,8 +11116,8 @@ SDValue AArch64TargetLowering::LowerSETCCCARRY(SDValue Op,
ISD::CondCode Cond = cast<CondCodeSDNode>(Op.getOperand(3))->get();
ISD::CondCode CondInv = ISD::getSetCCInverse(Cond, VT);
- SDValue CCVal =
- DAG.getConstant(changeIntCCToAArch64CC(CondInv), DL, MVT::i32);
+ SDValue CCVal = DAG.getConstant(changeIntCCToAArch64CC(CondInv, RHS, false),
+ DL, MVT::i32);
// Inputs are swapped because the condition is inverted. This will allow
// matching with a single CSINC instruction.
return DAG.getNode(AArch64ISD::CSEL, DL, OpVT, FVal, TVal, CCVal,
@@ -11394,7 +11395,7 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(
ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS);
if (Opcode == AArch64ISD::CSEL && RHSVal && !RHSVal->isOne() &&
!RHSVal->isZero() && !RHSVal->isAllOnes()) {
- AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC);
+ AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC, RHS);
// Transform "a == C ? C : x" to "a == C ? a : x" and "a != C ? x : C" to
// "a != C ? x : a" to avoid materializing C.
if (CTVal && CTVal == RHSVal && AArch64CC == AArch64CC::EQ)
@@ -11405,7 +11406,7 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(
assert (CTVal && CFVal && "Expected constant operands for CSNEG.");
// Use a CSINV to transform "a == C ? 1 : -1" to "a == C ? a : -1" to
// avoid materializing C.
- AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC);
+ AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC, RHS);
if (CTVal == RHSVal && AArch64CC == AArch64CC::EQ) {
Opcode = AArch64ISD::CSINV;
TVal = LHS;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 1381a9b70df87..d9813a5bedc74 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -1349,7 +1349,10 @@ AArch64InstructionSelector::emitSelect(Register Dst, Register True,
return &*SelectInst;
}
-static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
+static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P,
+ Register RHS,
+ MachineRegisterInfo *MRI,
+ bool canUsePLOrMI = true) {
switch (P) {
default:
llvm_unreachable("Unknown condition code!");
@@ -1360,8 +1363,18 @@ static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
case CmpInst::ICMP_SGT:
return AArch64CC::GT;
case CmpInst::ICMP_SGE:
+ if (canUsePLOrMI) {
+ auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS, *MRI);
+ if (ValAndVReg && ValAndVReg->Value == 0)
+ return AArch64CC::PL;
+ }
return AArch64CC::GE;
case CmpInst::ICMP_SLT:
+ if (canUsePLOrMI) {
+ auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS, *MRI);
+ if (ValAndVReg && ValAndVReg->Value == 0)
+ return AArch64CC::MI;
+ }
return AArch64CC::LT;
case CmpInst::ICMP_SLE:
return AArch64CC::LE;
@@ -1813,7 +1826,8 @@ bool AArch64InstructionSelector::selectCompareBranchFedByICmp(
auto PredOp = ICmp.getOperand(1);
emitIntegerCompare(ICmp.getOperand(2), ICmp.getOperand(3), PredOp, MIB);
const AArch64CC::CondCode CC = changeICMPPredToAArch64CC(
- static_cast<CmpInst::Predicate>(PredOp.getPredicate()));
+ static_cast<CmpInst::Predicate>(PredOp.getPredicate()),
+ ICmp.getOperand(3).getReg(), MIB.getMRI());
MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC).addMBB(DestMBB);
I.eraseFromParent();
return true;
@@ -2507,8 +2521,8 @@ bool AArch64InstructionSelector::earlySelect(MachineInstr &I) {
}
auto &PredOp = Cmp->getOperand(1);
auto Pred = static_cast<CmpInst::Predicate>(PredOp.getPredicate());
- const AArch64CC::CondCode InvCC =
- changeICMPPredToAArch64CC(CmpInst::getInversePredicate(Pred));
+ const AArch64CC::CondCode InvCC = changeICMPPredToAArch64CC(
+ CmpInst::getInversePredicate(Pred), Cmp->getOperand(3).getReg(), &MRI);
MIB.setInstrAndDebugLoc(I);
emitIntegerCompare(/*LHS=*/Cmp->getOperand(2),
/*RHS=*/Cmp->getOperand(3), PredOp, MIB);
@@ -3575,8 +3589,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
}
auto Pred = static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
- const AArch64CC::CondCode InvCC =
- changeICMPPredToAArch64CC(CmpInst::getInversePredicate(Pred));
+ const AArch64CC::CondCode InvCC = changeICMPPredToAArch64CC(
+ CmpInst::getInversePredicate(Pred), I.getOperand(3).getReg(), &MRI);
emitIntegerCompare(I.getOperand(2), I.getOperand(3), I.getOperand(1), MIB);
emitCSINC(/*Dst=*/I.getOperand(0).getReg(), /*Src1=*/AArch64::WZR,
/*Src2=*/AArch64::WZR, InvCC, MIB);
@@ -4930,7 +4944,7 @@ MachineInstr *AArch64InstructionSelector::emitConjunctionRec(
if (Negate)
CC = CmpInst::getInversePredicate(CC);
if (isa<GICmp>(Cmp)) {
- OutCC = changeICMPPredToAArch64CC(CC);
+ OutCC = changeICMPPredToAArch64CC(CC, RHS, MIB.getMRI());
} else {
// Handle special FP cases.
AArch64CC::CondCode ExtraCC;
@@ -5098,7 +5112,8 @@ bool AArch64InstructionSelector::tryOptSelect(GSelect &I) {
if (CondOpc == TargetOpcode::G_ICMP) {
auto Pred =
static_cast<CmpInst::Predicate>(CondDef->getOperand(1).getPredicate());
- CondCode = changeICMPPredToAArch64CC(Pred);
+ CondCode =
+ changeICMPPredToAArch64CC(Pred, CondDef->getOperand(3).getReg(), &MRI);
emitIntegerCompare(CondDef->getOperand(2), CondDef->getOperand(3),
CondDef->getOperand(1), MIB);
} else {
diff --git a/llvm/test/CodeGen/AArch64/16bit-float-promotion-with-nofp.ll b/llvm/test/CodeGen/AArch64/16bit-float-promotion-with-nofp.ll
index 5d4f9204e7063..c9560e705280b 100644
--- a/llvm/test/CodeGen/AArch64/16bit-float-promotion-with-nofp.ll
+++ b/llvm/test/CodeGen/AArch64/16bit-float-promotion-with-nofp.ll
@@ -77,7 +77,7 @@ define double @selectcc_f64(double %a, double %b, i32 %d) {
; CHECK-LABEL: selectcc_f64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w2, #0
-; CHECK-NEXT: csel x0, x0, x1, lt
+; CHECK-NEXT: csel x0, x0, x1, mi
; CHECK-NEXT: ret
entry:
%c = icmp slt i32 %d, 0
@@ -89,7 +89,7 @@ define float @selectcc_f32(float %a, float %b, i32 %d) {
; CHECK-LABEL: selectcc_f32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w2, #0
-; CHECK-NEXT: csel w0, w0, w1, lt
+; CHECK-NEXT: csel w0, w0, w1, mi
; CHECK-NEXT: ret
entry:
%c = icmp slt i32 %d, 0
@@ -101,7 +101,7 @@ define half @selectcc_f16(half %a, half %b, i32 %d) {
; CHECK-LABEL: selectcc_f16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w2, #0
-; CHECK-NEXT: csel w0, w0, w1, lt
+; CHECK-NEXT: csel w0, w0, w1, mi
; CHECK-NEXT: ret
entry:
%c = icmp slt i32 %d, 0
@@ -113,7 +113,7 @@ define bfloat @selectcc_bf16(bfloat %a, bfloat %b, i32 %d) {
; CHECK-LABEL: selectcc_bf16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w2, #0
-; CHECK-NEXT: csel w0, w0, w1, lt
+; CHECK-NEXT: csel w0, w0, w1, mi
; CHECK-NEXT: ret
entry:
%c = icmp slt i32 %d, 0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/opt-and-tbnz-tbz.mir b/llvm/test/CodeGen/AArch64/GlobalISel/opt-and-tbnz-tbz.mir
index 95ae12f6d59db..a5b6ea487aac4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/opt-and-tbnz-tbz.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/opt-and-tbnz-tbz.mir
@@ -149,7 +149,7 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri [[COPY]], 0, implicit-def $nzcv
- ; CHECK-NEXT: Bcc 11, %bb.1, implicit $nzcv
+ ; CHECK-NEXT: Bcc 4, %bb.1, implicit $nzcv
; CHECK-NEXT: B %bb.0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
index edc33e340c9b6..3b991c3d910d5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
@@ -661,7 +661,7 @@ body: |
; SELECT-NEXT: %reg0:gpr32common = COPY $w0
; SELECT-NEXT: %reg1:gpr32 = COPY $w1
; SELECT-NEXT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg0, 0, 0, implicit-def $nzcv
- ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 11, implicit $nzcv
+ ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 4, implicit $nzcv
; SELECT-NEXT: $w0 = COPY %select
; SELECT-NEXT: RET_ReallyLR implicit $w0
%reg0:_(s32) = COPY $w0
@@ -699,7 +699,7 @@ body: |
; SELECT-NEXT: {{ $}}
; SELECT-NEXT: %reg0:gpr64 = COPY $x0
; SELECT-NEXT: [[ANDSXri:%[0-9]+]]:gpr64 = ANDSXri %reg0, 8000, implicit-def $nzcv
- ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv
+ ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 4, implicit $nzcv
; SELECT-NEXT: $w0 = COPY %cmp
; SELECT-NEXT: RET_ReallyLR implicit $w0
%reg0:gpr(s64) = COPY $x0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir
index 30db00aa97813..67262c27e2059 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir
@@ -166,7 +166,7 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %copy:gpr64 = COPY $x0
; CHECK-NEXT: [[ANDSXri:%[0-9]+]]:gpr64 = ANDSXri %copy, 8000, implicit-def $nzcv
- ; CHECK-NEXT: Bcc 11, %bb.1, implicit $nzcv
+ ; CHECK-NEXT: Bcc 4, %bb.1, implicit $nzcv
; CHECK-NEXT: B %bb.0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
diff --git a/llvm/test/CodeGen/AArch64/arm64-ccmp.ll b/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
index 06e957fdcc6a2..fe67d0495e74e 100644
--- a/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
@@ -600,7 +600,7 @@ define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
; SDISEL-LABEL: select_noccmp1:
; SDISEL: ; %bb.0:
; SDISEL-NEXT: cmp x0, #0
-; SDISEL-NEXT: ccmp x0, #13, #4, lt
+; SDISEL-NEXT: ccmp x0, #13, #4, mi
; SDISEL-NEXT: cset w8, gt
; SDISEL-NEXT: cmp x2, #2
; SDISEL-NEXT: ccmp x2, #4, #4, lt
@@ -630,7 +630,7 @@ define i64 @select_noccmp2(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
; SDISEL-LABEL: select_noccmp2:
; SDISEL: ; %bb.0:
; SDISEL-NEXT: cmp x0, #0
-; SDISEL-NEXT: ccmp x0, #13, #0, ge
+; SDISEL-NEXT: ccmp x0, #13, #0, pl
; SDISEL-NEXT: cset w8, gt
; SDISEL-NEXT: cmp w8, #0
; SDISEL-NEXT: csel x0, xzr, x3, ne
@@ -664,7 +664,7 @@ define i32 @select_noccmp3(i32 %v0, i32 %v1, i32 %v2) {
; SDISEL-LABEL: select_noccmp3:
; SDISEL: ; %bb.0:
; SDISEL-NEXT: cmp w0, #0
-; SDISEL-NEXT: ccmp w0, #13, #0, ge
+; SDISEL-NEXT: ccmp w0, #13, #0, pl
; SDISEL-NEXT: cset w8, gt
; SDISEL-NEXT: cmp w0, #22
; SDISEL-NEXT: mov w9, #44 ; =0x2c
@@ -937,11 +937,11 @@ define i32 @f128_select_and_olt_oge(fp128 %v0, fp128 %v1, fp128 %v2, fp128 %v3,
; SDISEL-NEXT: stp q2, q3, [sp] ; 32-byte Folded Spill
; SDISEL-NEXT: bl ___lttf2
; SDISEL-NEXT: cmp w0, #0
-; SDISEL-NEXT: cset w21, lt
+; SDISEL-NEXT: cset w21, mi
; SDISEL-NEXT: ldp q0, q1, [sp] ; 32-byte Folded Reload
; SDISEL-NEXT: bl ___getf2
; SDISEL-NEXT: cmp w0, #0
-; SDISEL-NEXT: cset w8, ge
+; SDISEL-NEXT: cset w8, pl
; SDISEL-NEXT: tst w8, w21
; SDISEL-NEXT: csel w0, w20, w19, ne
; SDISEL-NEXT: ldp x29, x30, [sp, #64] ; 16-byte Folded Reload
@@ -964,8 +964,8 @@ define i32 @f128_select_and_olt_oge(fp128 %v0, fp128 %v1, fp128 %v2, fp128 %v3,
; GISEL-NEXT: ldp q1, q0, [sp] ; 32-byte Folded Reload
; GISEL-NEXT: bl ___getf2
; GISEL-NEXT: cmp w21, #0
-; GISEL-NEXT: ccmp w0, #0, #8, lt
-; GISEL-NEXT: csel w0, w19, w20, ge
+; GISEL-NEXT: ccmp w0, #0, #8, mi
+; GISEL-NEXT: csel w0, w19, w20, pl
; GISEL-NEXT: ldp x29, x30, [sp, #64] ; 16-byte Folded Reload
; GISEL-NEXT: ldp x20, x19, [sp, #48] ; 16-byte Folded Reload
; GISEL-NEXT: ldp x22, x21, [sp, #32] ; 16-byte Folded Reload
diff --git a/llvm/test/CodeGen/AArch64/arm64-fmax.ll b/llvm/test/CodeGen/AArch64/arm64-fmax.ll
index d7d54a6e48a92..85104775339b6 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fmax.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fmax.ll
@@ -60,7 +60,7 @@ define i64 @test_integer(i64 %in) {
; CHECK-LABEL: test_integer:
; CHECK: // %bb.0:
; CHECK-NEXT: cmp x0, #0
-; CHECK-NEXT: csel x0, xzr, x0, lt
+; CHECK-NEXT: csel x0, xzr, x0, mi
; CHECK-NEXT: ret
%cmp = icmp slt i64 %in, 0
%val = select i1 %cmp, i64 0, i64 %in
diff --git a/llvm/test/CodeGen/AArch64/arm64-fp128.ll b/llvm/test/CodeGen/AArch64/arm64-fp128.ll
index a75f6419d5a5a..3e4b887fed55d 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fp128.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fp128.ll
@@ -258,7 +258,7 @@ define i32 @test_br_cc(fp128 %lhs, fp128 %rhs) {
; CHECK-SD-NEXT: mov w8, #29 // =0x1d
; CHECK-SD-NEXT: cmp w0, #0
; CHECK-SD-NEXT: mov w9, #42 // =0x2a
-; CHECK-SD-NEXT: csel w0, w9, w8, lt
+; CHECK-SD-NEXT: csel w0, w9, w8, mi
; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-SD-NEXT: ret
;
@@ -271,7 +271,7 @@ define i32 @test_br_cc(fp128 %lhs, fp128 %rhs) {
; CHECK-GI-NEXT: mov w8, #29 // =0x1d
; CHECK-GI-NEXT: mov w9, #42 // =0x2a
; CHECK-GI-NEXT: cmp w0, #0
-; CHECK-GI-NEXT: csel w0, w9, w8, lt
+; CHECK-GI-NEXT: csel w0, w9, w8, mi
; CHECK-GI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-GI-NEXT: ret
%cond = fcmp olt fp128 %lhs, %rhs
diff --git a/llvm/test/CodeGen/AArch64/arm64-vabs.ll b/llvm/test/CodeGen/AArch64/arm64-vabs.ll
index b3258514aaa26..73fd118c55866 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vabs.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vabs.ll
@@ -1830,10 +1830,10 @@ define <2 x i128> @uabd_i64(<2 x i64> %a, <2 x i64> %b) {
; CHECK-GI-NEXT: subs x10, x11, x13
; CHECK-GI-NEXT: sbc x11, x14, x15
; CHECK-GI-NEXT: cmp x9, #0
-; CHECK-GI-NEXT: cset w12, lt
+; CHECK-GI-NEXT: cset w12, mi
; CHECK-GI-NEXT: csel w12, wzr, w12, eq
; CHECK-GI-NEXT: cmp x11, #0
-; CHECK-GI-NEXT: cset w13, lt
+; CHECK-GI-NEXT: cset w13, mi
; CHECK-GI-NEXT: csel w13, wzr, w13, eq
; CHECK-GI-NEXT: negs x14, x8
; CHECK-GI-NEXT: ngc x15, x9
diff --git a/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll b/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
index 1d60929f2b94c..0960c4c2a3342 100644
--- a/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
+++ b/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
@@ -80,7 +80,7 @@ define i32 @g_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind {
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxtb w8, w0
; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csel w8, w1, w2, lt
+; CHECK-NEXT: csel w8, w1, w2, mi
; CHECK-NEXT: add w0, w8, w0, uxtb
; CHECK-NEXT: ret
entry:
@@ -102,7 +102,7 @@ define i32 @g_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind {
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxth w8, w0
; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csel w8, w1, w2, lt
+; CHECK-NEXT: csel w8, w1, w2, mi
; CHECK-NEXT: add w0, w8, w0, uxth
; CHECK-NEXT: ret
entry:
@@ -123,7 +123,7 @@ define i64 @g_i32_sign_extend_inreg(i32 %in, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: g_i32_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: csel x8, x1, x2, lt
+; CHECK-NEXT: csel x8, x1, x2, mi
; CHECK-NEXT: add x0, x8, w0, uxtw
; CHECK-NEXT: ret
entry:
@@ -170,7 +170,7 @@ define i64 @g_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind {
; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
; CHECK-NEXT: sxtw x8, w0
; CHECK-NEXT: cmp x8, #0
-; CHECK-NEXT: csel x8, x1, x2, lt
+; CHECK-NEXT: csel x8, x1, x2, mi
; CHECK-NEXT: add x0, x8, w0, uxtw
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/AArch64/combine-sdiv.ll b/llvm/test/CodeGen/AArch64/combine-sdiv.ll
index 2b7fa085cf603..ef0bc08db2b6e 100644
--- a/llvm/test/CodeGen/AArch64/combine-sdiv.ll
+++ b/llvm/test/CodeGen/AArch64/combine-sdiv.ll
@@ -1464,7 +1464,7 @@ define i32 @combine_i32_sdiv_pow2(i32 %x) {
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: add w8, w0, #15
; CHECK-SD-NEXT: cmp w0, #0
-; CHECK-SD-NEXT: csel w8, w8, w0, lt
+; CHECK-SD-NEXT: csel w8, w8, w0, mi
; CHECK-SD-NEXT: asr w0, w8, #4
; CHECK-SD-NEXT: ret
;
@@ -1483,7 +1483,7 @@ define i32 @combine_i32_sdiv_negpow2(i32 %x) {
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: add w8, w0, #255
; CHECK-SD-NEXT: cmp w0, #0
-; CHECK-SD-NEXT: csel w8, w8, w0, lt
+; CHECK-SD-NEXT: csel w8, w8, w0, mi
; CHECK-SD-NEXT: ne...
[truncated]
|
@llvm/pr-subscribers-llvm-globalisel Author: AZero13 (AZero13) ChangesNow, why would we want to do this? There are a small number of places where this works:
Patch is 111.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/150314.diff 37 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ff23f76fadccd..4c8adb55606da 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3235,7 +3235,8 @@ static bool isZerosVector(const SDNode *N) {
/// changeIntCCToAArch64CC - Convert a DAG integer condition code to an AArch64
/// CC
-static AArch64CC::CondCode changeIntCCToAArch64CC(ISD::CondCode CC) {
+static AArch64CC::CondCode changeIntCCToAArch64CC(ISD::CondCode CC, SDValue RHS,
+ bool canUsePLOrMI = true) {
switch (CC) {
default:
llvm_unreachable("Unknown condition code!");
@@ -3246,9 +3247,9 @@ static AArch64CC::CondCode changeIntCCToAArch64CC(ISD::CondCode CC) {
case ISD::SETGT:
return AArch64CC::GT;
case ISD::SETGE:
- return AArch64CC::GE;
+ return canUsePLOrMI && isNullConstant(RHS) ? AArch64CC::PL : AArch64CC::GE;
case ISD::SETLT:
- return AArch64CC::LT;
+ return canUsePLOrMI && isNullConstant(RHS) ? AArch64CC::MI : AArch64CC::LT;
case ISD::SETLE:
return AArch64CC::LE;
case ISD::SETUGT:
@@ -3691,7 +3692,7 @@ static SDValue emitConjunctionRec(SelectionDAG &DAG, SDValue Val,
SDLoc DL(Val);
// Determine OutCC and handle FP special case.
if (isInteger) {
- OutCC = changeIntCCToAArch64CC(CC);
+ OutCC = changeIntCCToAArch64CC(CC, RHS);
} else {
assert(LHS.getValueType().isFloatingPoint());
AArch64CC::CondCode ExtraCC;
@@ -3974,7 +3975,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
Cmp = emitComparison(
SExt, DAG.getSignedConstant(ValueofRHS, DL, RHS.getValueType()), CC,
DL, DAG);
- AArch64CC = changeIntCCToAArch64CC(CC);
+ AArch64CC = changeIntCCToAArch64CC(CC, RHS);
}
}
@@ -3988,7 +3989,7 @@ static SDValue getAArch64Cmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
if (!Cmp) {
Cmp = emitComparison(LHS, RHS, CC, DL, DAG);
- AArch64CC = changeIntCCToAArch64CC(CC);
+ AArch64CC = changeIntCCToAArch64CC(CC, RHS);
}
AArch64cc = DAG.getConstant(AArch64CC, DL, MVT_CC);
return Cmp;
@@ -10555,10 +10556,10 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
// Try to emit Armv9.6 CB instructions. We prefer tb{n}z/cb{n}z due to their
// larger branch displacement but do prefer CB over cmp + br.
if (Subtarget->hasCMPBR() &&
- AArch64CC::isValidCBCond(changeIntCCToAArch64CC(CC)) &&
+ AArch64CC::isValidCBCond(changeIntCCToAArch64CC(CC, RHS, false)) &&
ProduceNonFlagSettingCondBr) {
- SDValue Cond =
- DAG.getTargetConstant(changeIntCCToAArch64CC(CC), DL, MVT::i32);
+ SDValue Cond = DAG.getTargetConstant(
+ changeIntCCToAArch64CC(CC, RHS, false), DL, MVT::i32);
return DAG.getNode(AArch64ISD::CB, DL, MVT::Other, Chain, Cond, LHS, RHS,
Dest);
}
@@ -11115,8 +11116,8 @@ SDValue AArch64TargetLowering::LowerSETCCCARRY(SDValue Op,
ISD::CondCode Cond = cast<CondCodeSDNode>(Op.getOperand(3))->get();
ISD::CondCode CondInv = ISD::getSetCCInverse(Cond, VT);
- SDValue CCVal =
- DAG.getConstant(changeIntCCToAArch64CC(CondInv), DL, MVT::i32);
+ SDValue CCVal = DAG.getConstant(changeIntCCToAArch64CC(CondInv, RHS, false),
+ DL, MVT::i32);
// Inputs are swapped because the condition is inverted. This will allow
// matching with a single CSINC instruction.
return DAG.getNode(AArch64ISD::CSEL, DL, OpVT, FVal, TVal, CCVal,
@@ -11394,7 +11395,7 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(
ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS);
if (Opcode == AArch64ISD::CSEL && RHSVal && !RHSVal->isOne() &&
!RHSVal->isZero() && !RHSVal->isAllOnes()) {
- AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC);
+ AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC, RHS);
// Transform "a == C ? C : x" to "a == C ? a : x" and "a != C ? x : C" to
// "a != C ? x : a" to avoid materializing C.
if (CTVal && CTVal == RHSVal && AArch64CC == AArch64CC::EQ)
@@ -11405,7 +11406,7 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(
assert (CTVal && CFVal && "Expected constant operands for CSNEG.");
// Use a CSINV to transform "a == C ? 1 : -1" to "a == C ? a : -1" to
// avoid materializing C.
- AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC);
+ AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC, RHS);
if (CTVal == RHSVal && AArch64CC == AArch64CC::EQ) {
Opcode = AArch64ISD::CSINV;
TVal = LHS;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 1381a9b70df87..d9813a5bedc74 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -1349,7 +1349,10 @@ AArch64InstructionSelector::emitSelect(Register Dst, Register True,
return &*SelectInst;
}
-static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
+static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P,
+ Register RHS,
+ MachineRegisterInfo *MRI,
+ bool canUsePLOrMI = true) {
switch (P) {
default:
llvm_unreachable("Unknown condition code!");
@@ -1360,8 +1363,18 @@ static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
case CmpInst::ICMP_SGT:
return AArch64CC::GT;
case CmpInst::ICMP_SGE:
+ if (canUsePLOrMI) {
+ auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS, *MRI);
+ if (ValAndVReg && ValAndVReg->Value == 0)
+ return AArch64CC::PL;
+ }
return AArch64CC::GE;
case CmpInst::ICMP_SLT:
+ if (canUsePLOrMI) {
+ auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS, *MRI);
+ if (ValAndVReg && ValAndVReg->Value == 0)
+ return AArch64CC::MI;
+ }
return AArch64CC::LT;
case CmpInst::ICMP_SLE:
return AArch64CC::LE;
@@ -1813,7 +1826,8 @@ bool AArch64InstructionSelector::selectCompareBranchFedByICmp(
auto PredOp = ICmp.getOperand(1);
emitIntegerCompare(ICmp.getOperand(2), ICmp.getOperand(3), PredOp, MIB);
const AArch64CC::CondCode CC = changeICMPPredToAArch64CC(
- static_cast<CmpInst::Predicate>(PredOp.getPredicate()));
+ static_cast<CmpInst::Predicate>(PredOp.getPredicate()),
+ ICmp.getOperand(3).getReg(), MIB.getMRI());
MIB.buildInstr(AArch64::Bcc, {}, {}).addImm(CC).addMBB(DestMBB);
I.eraseFromParent();
return true;
@@ -2507,8 +2521,8 @@ bool AArch64InstructionSelector::earlySelect(MachineInstr &I) {
}
auto &PredOp = Cmp->getOperand(1);
auto Pred = static_cast<CmpInst::Predicate>(PredOp.getPredicate());
- const AArch64CC::CondCode InvCC =
- changeICMPPredToAArch64CC(CmpInst::getInversePredicate(Pred));
+ const AArch64CC::CondCode InvCC = changeICMPPredToAArch64CC(
+ CmpInst::getInversePredicate(Pred), Cmp->getOperand(3).getReg(), &MRI);
MIB.setInstrAndDebugLoc(I);
emitIntegerCompare(/*LHS=*/Cmp->getOperand(2),
/*RHS=*/Cmp->getOperand(3), PredOp, MIB);
@@ -3575,8 +3589,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
}
auto Pred = static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
- const AArch64CC::CondCode InvCC =
- changeICMPPredToAArch64CC(CmpInst::getInversePredicate(Pred));
+ const AArch64CC::CondCode InvCC = changeICMPPredToAArch64CC(
+ CmpInst::getInversePredicate(Pred), I.getOperand(3).getReg(), &MRI);
emitIntegerCompare(I.getOperand(2), I.getOperand(3), I.getOperand(1), MIB);
emitCSINC(/*Dst=*/I.getOperand(0).getReg(), /*Src1=*/AArch64::WZR,
/*Src2=*/AArch64::WZR, InvCC, MIB);
@@ -4930,7 +4944,7 @@ MachineInstr *AArch64InstructionSelector::emitConjunctionRec(
if (Negate)
CC = CmpInst::getInversePredicate(CC);
if (isa<GICmp>(Cmp)) {
- OutCC = changeICMPPredToAArch64CC(CC);
+ OutCC = changeICMPPredToAArch64CC(CC, RHS, MIB.getMRI());
} else {
// Handle special FP cases.
AArch64CC::CondCode ExtraCC;
@@ -5098,7 +5112,8 @@ bool AArch64InstructionSelector::tryOptSelect(GSelect &I) {
if (CondOpc == TargetOpcode::G_ICMP) {
auto Pred =
static_cast<CmpInst::Predicate>(CondDef->getOperand(1).getPredicate());
- CondCode = changeICMPPredToAArch64CC(Pred);
+ CondCode =
+ changeICMPPredToAArch64CC(Pred, CondDef->getOperand(3).getReg(), &MRI);
emitIntegerCompare(CondDef->getOperand(2), CondDef->getOperand(3),
CondDef->getOperand(1), MIB);
} else {
diff --git a/llvm/test/CodeGen/AArch64/16bit-float-promotion-with-nofp.ll b/llvm/test/CodeGen/AArch64/16bit-float-promotion-with-nofp.ll
index 5d4f9204e7063..c9560e705280b 100644
--- a/llvm/test/CodeGen/AArch64/16bit-float-promotion-with-nofp.ll
+++ b/llvm/test/CodeGen/AArch64/16bit-float-promotion-with-nofp.ll
@@ -77,7 +77,7 @@ define double @selectcc_f64(double %a, double %b, i32 %d) {
; CHECK-LABEL: selectcc_f64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w2, #0
-; CHECK-NEXT: csel x0, x0, x1, lt
+; CHECK-NEXT: csel x0, x0, x1, mi
; CHECK-NEXT: ret
entry:
%c = icmp slt i32 %d, 0
@@ -89,7 +89,7 @@ define float @selectcc_f32(float %a, float %b, i32 %d) {
; CHECK-LABEL: selectcc_f32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w2, #0
-; CHECK-NEXT: csel w0, w0, w1, lt
+; CHECK-NEXT: csel w0, w0, w1, mi
; CHECK-NEXT: ret
entry:
%c = icmp slt i32 %d, 0
@@ -101,7 +101,7 @@ define half @selectcc_f16(half %a, half %b, i32 %d) {
; CHECK-LABEL: selectcc_f16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w2, #0
-; CHECK-NEXT: csel w0, w0, w1, lt
+; CHECK-NEXT: csel w0, w0, w1, mi
; CHECK-NEXT: ret
entry:
%c = icmp slt i32 %d, 0
@@ -113,7 +113,7 @@ define bfloat @selectcc_bf16(bfloat %a, bfloat %b, i32 %d) {
; CHECK-LABEL: selectcc_bf16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w2, #0
-; CHECK-NEXT: csel w0, w0, w1, lt
+; CHECK-NEXT: csel w0, w0, w1, mi
; CHECK-NEXT: ret
entry:
%c = icmp slt i32 %d, 0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/opt-and-tbnz-tbz.mir b/llvm/test/CodeGen/AArch64/GlobalISel/opt-and-tbnz-tbz.mir
index 95ae12f6d59db..a5b6ea487aac4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/opt-and-tbnz-tbz.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/opt-and-tbnz-tbz.mir
@@ -149,7 +149,7 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri [[COPY]], 0, implicit-def $nzcv
- ; CHECK-NEXT: Bcc 11, %bb.1, implicit $nzcv
+ ; CHECK-NEXT: Bcc 4, %bb.1, implicit $nzcv
; CHECK-NEXT: B %bb.0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
index edc33e340c9b6..3b991c3d910d5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
@@ -661,7 +661,7 @@ body: |
; SELECT-NEXT: %reg0:gpr32common = COPY $w0
; SELECT-NEXT: %reg1:gpr32 = COPY $w1
; SELECT-NEXT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg0, 0, 0, implicit-def $nzcv
- ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 11, implicit $nzcv
+ ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 4, implicit $nzcv
; SELECT-NEXT: $w0 = COPY %select
; SELECT-NEXT: RET_ReallyLR implicit $w0
%reg0:_(s32) = COPY $w0
@@ -699,7 +699,7 @@ body: |
; SELECT-NEXT: {{ $}}
; SELECT-NEXT: %reg0:gpr64 = COPY $x0
; SELECT-NEXT: [[ANDSXri:%[0-9]+]]:gpr64 = ANDSXri %reg0, 8000, implicit-def $nzcv
- ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv
+ ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 4, implicit $nzcv
; SELECT-NEXT: $w0 = COPY %cmp
; SELECT-NEXT: RET_ReallyLR implicit $w0
%reg0:gpr(s64) = COPY $x0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir
index 30db00aa97813..67262c27e2059 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir
@@ -166,7 +166,7 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %copy:gpr64 = COPY $x0
; CHECK-NEXT: [[ANDSXri:%[0-9]+]]:gpr64 = ANDSXri %copy, 8000, implicit-def $nzcv
- ; CHECK-NEXT: Bcc 11, %bb.1, implicit $nzcv
+ ; CHECK-NEXT: Bcc 4, %bb.1, implicit $nzcv
; CHECK-NEXT: B %bb.0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
diff --git a/llvm/test/CodeGen/AArch64/arm64-ccmp.ll b/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
index 06e957fdcc6a2..fe67d0495e74e 100644
--- a/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-ccmp.ll
@@ -600,7 +600,7 @@ define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
; SDISEL-LABEL: select_noccmp1:
; SDISEL: ; %bb.0:
; SDISEL-NEXT: cmp x0, #0
-; SDISEL-NEXT: ccmp x0, #13, #4, lt
+; SDISEL-NEXT: ccmp x0, #13, #4, mi
; SDISEL-NEXT: cset w8, gt
; SDISEL-NEXT: cmp x2, #2
; SDISEL-NEXT: ccmp x2, #4, #4, lt
@@ -630,7 +630,7 @@ define i64 @select_noccmp2(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
; SDISEL-LABEL: select_noccmp2:
; SDISEL: ; %bb.0:
; SDISEL-NEXT: cmp x0, #0
-; SDISEL-NEXT: ccmp x0, #13, #0, ge
+; SDISEL-NEXT: ccmp x0, #13, #0, pl
; SDISEL-NEXT: cset w8, gt
; SDISEL-NEXT: cmp w8, #0
; SDISEL-NEXT: csel x0, xzr, x3, ne
@@ -664,7 +664,7 @@ define i32 @select_noccmp3(i32 %v0, i32 %v1, i32 %v2) {
; SDISEL-LABEL: select_noccmp3:
; SDISEL: ; %bb.0:
; SDISEL-NEXT: cmp w0, #0
-; SDISEL-NEXT: ccmp w0, #13, #0, ge
+; SDISEL-NEXT: ccmp w0, #13, #0, pl
; SDISEL-NEXT: cset w8, gt
; SDISEL-NEXT: cmp w0, #22
; SDISEL-NEXT: mov w9, #44 ; =0x2c
@@ -937,11 +937,11 @@ define i32 @f128_select_and_olt_oge(fp128 %v0, fp128 %v1, fp128 %v2, fp128 %v3,
; SDISEL-NEXT: stp q2, q3, [sp] ; 32-byte Folded Spill
; SDISEL-NEXT: bl ___lttf2
; SDISEL-NEXT: cmp w0, #0
-; SDISEL-NEXT: cset w21, lt
+; SDISEL-NEXT: cset w21, mi
; SDISEL-NEXT: ldp q0, q1, [sp] ; 32-byte Folded Reload
; SDISEL-NEXT: bl ___getf2
; SDISEL-NEXT: cmp w0, #0
-; SDISEL-NEXT: cset w8, ge
+; SDISEL-NEXT: cset w8, pl
; SDISEL-NEXT: tst w8, w21
; SDISEL-NEXT: csel w0, w20, w19, ne
; SDISEL-NEXT: ldp x29, x30, [sp, #64] ; 16-byte Folded Reload
@@ -964,8 +964,8 @@ define i32 @f128_select_and_olt_oge(fp128 %v0, fp128 %v1, fp128 %v2, fp128 %v3,
; GISEL-NEXT: ldp q1, q0, [sp] ; 32-byte Folded Reload
; GISEL-NEXT: bl ___getf2
; GISEL-NEXT: cmp w21, #0
-; GISEL-NEXT: ccmp w0, #0, #8, lt
-; GISEL-NEXT: csel w0, w19, w20, ge
+; GISEL-NEXT: ccmp w0, #0, #8, mi
+; GISEL-NEXT: csel w0, w19, w20, pl
; GISEL-NEXT: ldp x29, x30, [sp, #64] ; 16-byte Folded Reload
; GISEL-NEXT: ldp x20, x19, [sp, #48] ; 16-byte Folded Reload
; GISEL-NEXT: ldp x22, x21, [sp, #32] ; 16-byte Folded Reload
diff --git a/llvm/test/CodeGen/AArch64/arm64-fmax.ll b/llvm/test/CodeGen/AArch64/arm64-fmax.ll
index d7d54a6e48a92..85104775339b6 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fmax.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fmax.ll
@@ -60,7 +60,7 @@ define i64 @test_integer(i64 %in) {
; CHECK-LABEL: test_integer:
; CHECK: // %bb.0:
; CHECK-NEXT: cmp x0, #0
-; CHECK-NEXT: csel x0, xzr, x0, lt
+; CHECK-NEXT: csel x0, xzr, x0, mi
; CHECK-NEXT: ret
%cmp = icmp slt i64 %in, 0
%val = select i1 %cmp, i64 0, i64 %in
diff --git a/llvm/test/CodeGen/AArch64/arm64-fp128.ll b/llvm/test/CodeGen/AArch64/arm64-fp128.ll
index a75f6419d5a5a..3e4b887fed55d 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fp128.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fp128.ll
@@ -258,7 +258,7 @@ define i32 @test_br_cc(fp128 %lhs, fp128 %rhs) {
; CHECK-SD-NEXT: mov w8, #29 // =0x1d
; CHECK-SD-NEXT: cmp w0, #0
; CHECK-SD-NEXT: mov w9, #42 // =0x2a
-; CHECK-SD-NEXT: csel w0, w9, w8, lt
+; CHECK-SD-NEXT: csel w0, w9, w8, mi
; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-SD-NEXT: ret
;
@@ -271,7 +271,7 @@ define i32 @test_br_cc(fp128 %lhs, fp128 %rhs) {
; CHECK-GI-NEXT: mov w8, #29 // =0x1d
; CHECK-GI-NEXT: mov w9, #42 // =0x2a
; CHECK-GI-NEXT: cmp w0, #0
-; CHECK-GI-NEXT: csel w0, w9, w8, lt
+; CHECK-GI-NEXT: csel w0, w9, w8, mi
; CHECK-GI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-GI-NEXT: ret
%cond = fcmp olt fp128 %lhs, %rhs
diff --git a/llvm/test/CodeGen/AArch64/arm64-vabs.ll b/llvm/test/CodeGen/AArch64/arm64-vabs.ll
index b3258514aaa26..73fd118c55866 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vabs.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vabs.ll
@@ -1830,10 +1830,10 @@ define <2 x i128> @uabd_i64(<2 x i64> %a, <2 x i64> %b) {
; CHECK-GI-NEXT: subs x10, x11, x13
; CHECK-GI-NEXT: sbc x11, x14, x15
; CHECK-GI-NEXT: cmp x9, #0
-; CHECK-GI-NEXT: cset w12, lt
+; CHECK-GI-NEXT: cset w12, mi
; CHECK-GI-NEXT: csel w12, wzr, w12, eq
; CHECK-GI-NEXT: cmp x11, #0
-; CHECK-GI-NEXT: cset w13, lt
+; CHECK-GI-NEXT: cset w13, mi
; CHECK-GI-NEXT: csel w13, wzr, w13, eq
; CHECK-GI-NEXT: negs x14, x8
; CHECK-GI-NEXT: ngc x15, x9
diff --git a/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll b/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
index 1d60929f2b94c..0960c4c2a3342 100644
--- a/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
+++ b/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
@@ -80,7 +80,7 @@ define i32 @g_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind {
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxtb w8, w0
; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csel w8, w1, w2, lt
+; CHECK-NEXT: csel w8, w1, w2, mi
; CHECK-NEXT: add w0, w8, w0, uxtb
; CHECK-NEXT: ret
entry:
@@ -102,7 +102,7 @@ define i32 @g_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind {
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxth w8, w0
; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csel w8, w1, w2, lt
+; CHECK-NEXT: csel w8, w1, w2, mi
; CHECK-NEXT: add w0, w8, w0, uxth
; CHECK-NEXT: ret
entry:
@@ -123,7 +123,7 @@ define i64 @g_i32_sign_extend_inreg(i32 %in, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: g_i32_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: csel x8, x1, x2, lt
+; CHECK-NEXT: csel x8, x1, x2, mi
; CHECK-NEXT: add x0, x8, w0, uxtw
; CHECK-NEXT: ret
entry:
@@ -170,7 +170,7 @@ define i64 @g_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind {
; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
; CHECK-NEXT: sxtw x8, w0
; CHECK-NEXT: cmp x8, #0
-; CHECK-NEXT: csel x8, x1, x2, lt
+; CHECK-NEXT: csel x8, x1, x2, mi
; CHECK-NEXT: add x0, x8, w0, uxtw
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/AArch64/combine-sdiv.ll b/llvm/test/CodeGen/AArch64/combine-sdiv.ll
index 2b7fa085cf603..ef0bc08db2b6e 100644
--- a/llvm/test/CodeGen/AArch64/combine-sdiv.ll
+++ b/llvm/test/CodeGen/AArch64/combine-sdiv.ll
@@ -1464,7 +1464,7 @@ define i32 @combine_i32_sdiv_pow2(i32 %x) {
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: add w8, w0, #15
; CHECK-SD-NEXT: cmp w0, #0
-; CHECK-SD-NEXT: csel w8, w8, w0, lt
+; CHECK-SD-NEXT: csel w8, w8, w0, mi
; CHECK-SD-NEXT: asr w0, w8, #4
; CHECK-SD-NEXT: ret
;
@@ -1483,7 +1483,7 @@ define i32 @combine_i32_sdiv_negpow2(i32 %x) {
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: add w8, w0, #255
; CHECK-SD-NEXT: cmp w0, #0
-; CHECK-SD-NEXT: csel w8, w8, w0, lt
+; CHECK-SD-NEXT: csel w8, w8, w0, mi
; CHECK-SD-NEXT: ne...
[truncated]
|
@davemgreen thoughts on this? |
Now, why would we want to do this?
There are a small number of places where this works: