[llvm] [AArch64] Add should be adjusted to zero for GlobalISel (PR #195941)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 05:11:51 PDT 2026
https://github.com/LumioseSil updated https://github.com/llvm/llvm-project/pull/195941
>From 1e9b2388210af07e1f5fd239c2cdaba0af3ecf46 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Tue, 5 May 2026 17:07:48 -0400
Subject: [PATCH] [AArch64] Add should be adjusted to zero for GlobalISel
Realized that we can also get more out of it if it is pl/mi regardless of and, so I put that in SelectionDAG too.
---
.../Target/AArch64/AArch64ISelLowering.cpp | 17 +-
.../GISel/AArch64PostLegalizerLowering.cpp | 155 ++++++----
...postlegalizer-lowering-adjust-icmp-imm.mir | 8 +-
llvm/test/CodeGen/AArch64/arm64-csel.ll | 42 ++-
.../check-sign-bit-before-extension.ll | 12 +-
llvm/test/CodeGen/AArch64/cmp-to-cmn.ll | 280 +++++-------------
llvm/test/CodeGen/AArch64/fcvt-i256.ll | 24 +-
llvm/test/CodeGen/AArch64/fpclamptosat_vec.ll | 136 ++++-----
.../test/CodeGen/AArch64/fptosi-sat-scalar.ll | 16 +-
.../CodeGen/AArch64/select-constant-xor.ll | 12 +-
llvm/test/CodeGen/AArch64/signbit-shift.ll | 8 +-
llvm/test/CodeGen/AArch64/signbit-test.ll | 4 +-
.../CodeGen/AArch64/typepromotion-signed.ll | 8 +-
13 files changed, 310 insertions(+), 412 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 8c53ea0dd94eb..42101b83820ca 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3701,7 +3701,7 @@ static bool isLegalArithImmed(uint64_t C) {
return IsLegal;
}
-bool isLegalCmpImmed(APInt C) {
+bool isLegalCmpImmed(const APInt &C) {
// Works for negative immediates too, as it can be written as an ADDS
// instruction with a negated immediate.
return isLegalArithImmed(C.abs().getZExtValue());
@@ -4137,7 +4137,7 @@ static SDValue emitConjunction(SelectionDAG &DAG, SDValue Val,
/// Returns how profitable it is to fold a comparison's operand's shift and/or
/// extension operations.
static unsigned getCmpOperandFoldingProfit(SDValue Op) {
- auto isSupportedExtend = [&](SDValue V) {
+ auto isSupportedExtend = [&](const SDValue &V) {
if (V.getOpcode() == ISD::SIGN_EXTEND_INREG)
return true;
@@ -4173,16 +4173,19 @@ static unsigned getCmpOperandFoldingProfit(SDValue Op) {
// emitComparison() converts comparison with one or negative one to comparison
// with 0. Note that this only works for signed comparisons because of how ANDS
// works.
-static bool shouldBeAdjustedToZero(SDValue LHS, APInt C, ISD::CondCode &CC) {
- // Only works for ANDS and AND.
- if (LHS.getOpcode() != ISD::AND && LHS.getOpcode() != AArch64ISD::ANDS)
- return false;
+static bool shouldBeAdjustedToZero(SDValue LHS, const APInt &C,
+ ISD::CondCode &CC) {
- if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE)) {
+ const bool IsAndLHS =
+ LHS.getOpcode() == ISD::AND || LHS.getOpcode() == AArch64ISD::ANDS;
+ if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE) && IsAndLHS) {
CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
return true;
}
+ if (!LHS.hasOneUse() && !IsAndLHS)
+ return false;
+
if (C.isAllOnes() && (CC == ISD::SETLE || CC == ISD::SETGT)) {
CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
return true;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index f4e5649b9f449..5fdfc072a4ff4 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -604,6 +604,36 @@ void applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
MI.eraseFromParent();
}
+bool isLegalCmpImmed(const APInt &C) {
+ // Works for negative immediates too, as it can be written as an ADDS
+ // instruction with a negated immediate.
+ return isLegalArithImmed(C.abs().getZExtValue());
+}
+
+/// Adjust compares against 1/-1 to a compare against 0.
+static bool shouldBeAdjustedToZero(Register LHS, const APInt &C,
+ CmpInst::Predicate &P,
+ const MachineRegisterInfo &MRI) {
+ MachineInstr *LHSDef = getDefIgnoringCopies(LHS, MRI);
+ assert(LHSDef && "Expected compare LHS to have a defining instruction");
+ const bool IsAndLHS = LHSDef->getOpcode() == TargetOpcode::G_AND;
+
+ if (C.isOne() && (P == CmpInst::ICMP_SLT || P == CmpInst::ICMP_SGE) &&
+ IsAndLHS) {
+ P = (P == CmpInst::ICMP_SLT) ? CmpInst::ICMP_SLE : CmpInst::ICMP_SGT;
+ return true;
+ }
+
+ if (!IsAndLHS && !MRI.hasOneNonDBGUse(LHS))
+ return false;
+
+ if (C.isAllOnes() && (P == CmpInst::ICMP_SLE || P == CmpInst::ICMP_SGT)) {
+ P = (P == CmpInst::ICMP_SLE) ? CmpInst::ICMP_SLT : CmpInst::ICMP_SGE;
+ return true;
+ }
+ return false;
+}
+
/// Determine if it is possible to modify the \p RHS and predicate \p P of a
/// G_ICMP instruction such that the right-hand side is an arithmetic immediate.
///
@@ -612,22 +642,25 @@ void applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
///
/// \note This assumes that the comparison has been legalized.
std::optional<std::pair<uint64_t, CmpInst::Predicate>>
-tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
+tryAdjustICmpImmAndPred(Register LHS, Register RHS, CmpInst::Predicate P,
const MachineRegisterInfo &MRI) {
const auto &Ty = MRI.getType(RHS);
if (Ty.isVector())
return std::nullopt;
- unsigned Size = Ty.getSizeInBits();
- assert((Size == 32 || Size == 64) && "Expected 32 or 64 bit compare only?");
+ assert((Ty.getSizeInBits() == 32 || Ty.getSizeInBits() == 64) &&
+ "Expected 32 or 64 bit compare only?");
// If the RHS is not a constant, or the RHS is already a valid arithmetic
// immediate, then there is nothing to change.
auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS, MRI);
if (!ValAndVReg)
return std::nullopt;
- uint64_t OriginalC = ValAndVReg->Value.getZExtValue();
- uint64_t C = OriginalC;
- if (isLegalArithImmed(C))
+ APInt C = ValAndVReg->Value;
+ APInt OriginalC = C;
+ if (shouldBeAdjustedToZero(LHS, C, P, MRI))
+ return {{0, P}};
+
+ if (isLegalCmpImmed(C))
return std::nullopt;
// We have a non-arithmetic immediate. Check if adjusting the immediate and
@@ -643,11 +676,10 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
// x sge c => x sgt c - 1
//
// When c is not the smallest possible negative number.
- if ((Size == 64 && static_cast<int64_t>(C) == INT64_MIN) ||
- (Size == 32 && static_cast<int32_t>(C) == INT32_MIN))
+ if (C.isMinSignedValue())
return std::nullopt;
P = (P == CmpInst::ICMP_SLT) ? CmpInst::ICMP_SLE : CmpInst::ICMP_SGT;
- C -= 1;
+ C = C - 1;
break;
case CmpInst::ICMP_ULT:
case CmpInst::ICMP_UGE:
@@ -657,9 +689,9 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
// x uge c => x ugt c - 1
//
// When c is not zero.
- assert(C != 0 && "C should not be zero here!");
+ assert(!C.isZero() && "C should not be zero here!");
P = (P == CmpInst::ICMP_ULT) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
- C -= 1;
+ C = C - 1;
break;
case CmpInst::ICMP_SLE:
case CmpInst::ICMP_SGT:
@@ -669,11 +701,10 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
// x sgt c => s sge c + 1
//
// When c is not the largest possible signed integer.
- if ((Size == 32 && static_cast<int32_t>(C) == INT32_MAX) ||
- (Size == 64 && static_cast<int64_t>(C) == INT64_MAX))
+ if (C.isMaxSignedValue())
return std::nullopt;
P = (P == CmpInst::ICMP_SLE) ? CmpInst::ICMP_SLT : CmpInst::ICMP_SGE;
- C += 1;
+ C = C + 1;
break;
case CmpInst::ICMP_ULE:
case CmpInst::ICMP_UGT:
@@ -683,20 +714,17 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
// 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))
+ if (C.isAllOnes())
return std::nullopt;
P = (P == CmpInst::ICMP_ULE) ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
- C += 1;
+ C = C + 1;
break;
}
// Check if the new constant is valid, and return the updated constant and
// predicate if it is.
- if (Size == 32)
- C = static_cast<uint32_t>(C);
- if (isLegalArithImmed(C))
- return {{C, P}};
+ if (isLegalCmpImmed(C))
+ return {{C.getZExtValue(), P}};
auto NumberOfInstrToLoadImm = [=](uint64_t Imm) {
SmallVector<AArch64_IMM::ImmInsnModel> Insn;
@@ -704,8 +732,9 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
return Insn.size();
};
- if (NumberOfInstrToLoadImm(OriginalC) > NumberOfInstrToLoadImm(C))
- return {{C, P}};
+ if (NumberOfInstrToLoadImm(OriginalC.getZExtValue()) >
+ NumberOfInstrToLoadImm(C.getZExtValue()))
+ return {{C.getZExtValue(), P}};
return std::nullopt;
}
@@ -722,9 +751,10 @@ bool matchAdjustICmpImmAndPred(
MachineInstr &MI, const MachineRegisterInfo &MRI,
std::pair<uint64_t, CmpInst::Predicate> &MatchInfo) {
assert(MI.getOpcode() == TargetOpcode::G_ICMP);
+ Register LHS = MI.getOperand(2).getReg();
Register RHS = MI.getOperand(3).getReg();
auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
- if (auto MaybeNewImmAndPred = tryAdjustICmpImmAndPred(RHS, Pred, MRI)) {
+ if (auto MaybeNewImmAndPred = tryAdjustICmpImmAndPred(LHS, RHS, Pred, MRI)) {
MatchInfo = *MaybeNewImmAndPred;
return true;
}
@@ -898,55 +928,52 @@ void applyBuildVectorToDup(MachineInstr &MI, Register Src,
/// \returns how many instructions would be saved by folding a G_ICMP's shift
/// and/or extension operations.
-unsigned getCmpOperandFoldingProfit(Register CmpOp, MachineRegisterInfo &MRI) {
- // No instructions to save if there's more than one use or no uses.
- if (!MRI.hasOneNonDBGUse(CmpOp))
- return 0;
-
+static unsigned getCmpOperandFoldingProfit(Register CmpOp,
+ MachineRegisterInfo &MRI) {
// FIXME: This is duplicated with the selector. (See: selectShiftedRegister)
auto IsSupportedExtend = [&](const MachineInstr &MI) {
if (MI.getOpcode() == TargetOpcode::G_SEXT_INREG)
return true;
- if (MI.getOpcode() != TargetOpcode::G_AND)
- return false;
- auto ValAndVReg =
- getIConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI);
- if (!ValAndVReg)
- return false;
- uint64_t Mask = ValAndVReg->Value.getZExtValue();
- return (Mask == 0xFF || Mask == 0xFFFF || Mask == 0xFFFFFFFF);
+ if (MI.getOpcode() == TargetOpcode::G_AND) {
+ auto ValAndVReg =
+ getIConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI);
+ if (ValAndVReg) {
+ uint64_t Mask = ValAndVReg->Value.getZExtValue();
+ return (Mask == 0xFF || Mask == 0xFFFF || Mask == 0xFFFFFFFF);
+ }
+ }
+ return false;
};
+ // No instructions to save if there's more than one use or no uses.
+ if (!MRI.hasOneNonDBGUse(CmpOp))
+ return 0;
+
MachineInstr *Def = getDefIgnoringCopies(CmpOp, MRI);
if (IsSupportedExtend(*Def))
return 1;
unsigned Opc = Def->getOpcode();
- if (Opc != TargetOpcode::G_SHL && Opc != TargetOpcode::G_ASHR &&
- Opc != TargetOpcode::G_LSHR)
- return 0;
-
- auto MaybeShiftAmt =
- getIConstantVRegValWithLookThrough(Def->getOperand(2).getReg(), MRI);
- if (!MaybeShiftAmt)
- return 0;
- uint64_t ShiftAmt = MaybeShiftAmt->Value.getZExtValue();
- MachineInstr *ShiftLHS =
- getDefIgnoringCopies(Def->getOperand(1).getReg(), MRI);
-
- // Check if we can fold an extend and a shift.
- // FIXME: This is duplicated with the selector. (See:
- // selectArithExtendedRegister)
- if (IsSupportedExtend(*ShiftLHS))
- return (ShiftAmt <= 4) ? 2 : 1;
+ if (Opc == TargetOpcode::G_SHL || Opc == TargetOpcode::G_LSHR ||
+ Opc == TargetOpcode::G_ASHR) {
+ auto MaybeShiftAmt =
+ getIConstantVRegValWithLookThrough(Def->getOperand(2).getReg(), MRI);
+ if (MaybeShiftAmt) {
+ uint64_t ShiftAmt = MaybeShiftAmt->Value.getZExtValue();
+ MachineInstr *ShiftLHS =
+ getDefIgnoringCopies(Def->getOperand(1).getReg(), MRI);
+ if (IsSupportedExtend(*ShiftLHS))
+ return (ShiftAmt <= 4) ? 2 : 1;
+ LLT Ty = MRI.getType(Def->getOperand(0).getReg());
+ if (Ty.isVector())
+ return 0;
+ unsigned ShiftSize = Ty.getSizeInBits();
+ if ((ShiftSize == 32 && ShiftAmt <= 31) ||
+ (ShiftSize == 64 && ShiftAmt <= 63))
+ return 1;
+ }
+ }
- LLT Ty = MRI.getType(Def->getOperand(0).getReg());
- if (Ty.isVector())
- return 0;
- unsigned ShiftSize = Ty.getSizeInBits();
- if ((ShiftSize == 32 && ShiftAmt <= 31) ||
- (ShiftSize == 64 && ShiftAmt <= 63))
- return 1;
return 0;
}
@@ -963,11 +990,11 @@ bool trySwapICmpOperands(MachineInstr &MI, MachineRegisterInfo &MRI) {
// can be turned into:
// cmp w12, w11, lsl #1
- // Don't swap if there's a constant on the RHS, because we know we can fold
- // that.
+ // Don't swap if there's a constant on the RHS and it is a legal compare
+ // immediate, because we know we can fold that.
Register RHS = MI.getOperand(3).getReg();
auto RHSCst = getIConstantVRegValWithLookThrough(RHS, MRI);
- if (RHSCst && isLegalArithImmed(RHSCst->Value.getSExtValue()))
+ if (RHSCst && isLegalCmpImmed(RHSCst->Value))
return false;
Register LHS = MI.getOperand(2).getReg();
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 3b991c3d910d5..a86691b30f44d 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
@@ -649,8 +649,8 @@ body: |
; LOWER-NEXT: {{ $}}
; LOWER-NEXT: %reg0:_(s32) = COPY $w0
; LOWER-NEXT: %reg1:_(s32) = COPY $w1
- ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg0(s32), [[C]]
+ ; LOWER-NEXT: %cst:_(s32) = G_CONSTANT i32 -1
+ ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg0(s32), %cst
; LOWER-NEXT: %select:_(s32) = G_SELECT %cmp(s32), %reg0, %reg1
; LOWER-NEXT: $w0 = COPY %select(s32)
; LOWER-NEXT: RET_ReallyLR implicit $w0
@@ -660,8 +660,8 @@ body: |
; SELECT-NEXT: {{ $}}
; 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, 4, implicit $nzcv
+ ; SELECT-NEXT: [[ADDSWri:%[0-9]+]]:gpr32 = ADDSWri %reg0, 1, 0, implicit-def $nzcv
+ ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 13, implicit $nzcv
; SELECT-NEXT: $w0 = COPY %select
; SELECT-NEXT: RET_ReallyLR implicit $w0
%reg0:_(s32) = COPY $w0
diff --git a/llvm/test/CodeGen/AArch64/arm64-csel.ll b/llvm/test/CodeGen/AArch64/arm64-csel.ll
index f677f2f77fc61..ecdcbfe226e40 100644
--- a/llvm/test/CodeGen/AArch64/arm64-csel.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-csel.ll
@@ -65,11 +65,17 @@ entry:
; rdar://11632325
define i32 at foo4(i32 %a) nounwind ssp {
-; CHECK-LABEL: foo4:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: cneg w0, w0, mi
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: foo4:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: cmp w0, #0
+; CHECK-SD-NEXT: cneg w0, w0, mi
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: foo4:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: cmn w0, #1
+; CHECK-GI-NEXT: cneg w0, w0, le
+; CHECK-GI-NEXT: ret
%cmp = icmp sgt i32 %a, -1
%neg = sub nsw i32 0, %a
%cond = select i1 %cmp, i32 %a, i32 %neg
@@ -77,11 +83,18 @@ define i32 at foo4(i32 %a) nounwind ssp {
}
define i32 at foo5(i32 %a, i32 %b) nounwind ssp {
-; CHECK-LABEL: foo5:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: subs w8, w0, w1
-; CHECK-NEXT: cneg w0, w8, mi
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: foo5:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: subs w8, w0, w1
+; CHECK-SD-NEXT: cneg w0, w8, mi
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: foo5:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: sub w8, w0, w1
+; CHECK-GI-NEXT: cmn w8, #1
+; CHECK-GI-NEXT: cneg w0, w8, le
+; CHECK-GI-NEXT: ret
entry:
%sub = sub nsw i32 %a, %b
%cmp = icmp sgt i32 %sub, -1
@@ -121,12 +134,11 @@ define i32 @foo7(i32 %a, i32 %b) nounwind {
;
; CHECK-GI-LABEL: foo7:
; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: subs w8, w0, w1
-; CHECK-GI-NEXT: cneg w9, w8, mi
+; CHECK-GI-NEXT: sub w8, w0, w1
; CHECK-GI-NEXT: cmn w8, #1
-; CHECK-GI-NEXT: csel w10, w9, w0, lt
-; CHECK-GI-NEXT: cmp w8, #0
-; CHECK-GI-NEXT: csel w0, w10, w9, pl
+; CHECK-GI-NEXT: cneg w8, w8, le
+; CHECK-GI-NEXT: csel w9, w8, w0, lt
+; CHECK-GI-NEXT: csel w0, w9, w8, gt
; CHECK-GI-NEXT: ret
entry:
%sub = sub nsw i32 %a, %b
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 a56d5b1b49b38..13bc618ae5a35 100644
--- a/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
+++ b/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
@@ -14,8 +14,8 @@ define i32 @f_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: f_i8_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxtb w8, w0
-; CHECK-NEXT: cmn w8, #1
-; CHECK-NEXT: csel w8, w1, w2, gt
+; CHECK-NEXT: cmp w8, #0
+; CHECK-NEXT: csel w8, w1, w2, pl
; CHECK-NEXT: add w0, w8, w0, uxtb
; CHECK-NEXT: ret
entry:
@@ -36,8 +36,8 @@ define i32 @f_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: f_i16_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxth w8, w0
-; CHECK-NEXT: cmn w8, #1
-; CHECK-NEXT: csel w8, w1, w2, gt
+; CHECK-NEXT: cmp w8, #0
+; CHECK-NEXT: csel w8, w1, w2, pl
; CHECK-NEXT: add w0, w8, w0, uxth
; CHECK-NEXT: ret
entry:
@@ -143,8 +143,8 @@ define i64 @f_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind {
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
; CHECK-NEXT: sxtw x8, w0
-; CHECK-NEXT: cmn x8, #1
-; CHECK-NEXT: csel x8, x1, x2, gt
+; CHECK-NEXT: cmp x8, #0
+; CHECK-NEXT: csel x8, x1, x2, pl
; CHECK-NEXT: add x0, x8, w0, uxtw
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll b/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
index b3ce9d2369104..97498a4dc9ad8 100644
--- a/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
+++ b/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
@@ -501,281 +501,161 @@ define i1 @cmn_large_imm(i32 %a) {
}
define i1 @almost_immediate_neg_slt(i32 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_slt:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #4079, lsl #12 // =16707584
-; CHECK-SD-NEXT: cset w0, le
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_slt:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #4097 // =0x1001
-; CHECK-GI-NEXT: movk w8, #65281, lsl #16
-; CHECK-GI-NEXT: cmp w0, w8
-; CHECK-GI-NEXT: cset w0, lt
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_slt:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn w0, #4079, lsl #12 // =16707584
+; CHECK-NEXT: cset w0, le
+; CHECK-NEXT: ret
%cmp = icmp slt i32 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_slt_64(i64 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_slt_64:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn x0, #4079, lsl #12 // =16707584
-; CHECK-SD-NEXT: cset w0, le
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_slt_64:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x8, #-61439 // =0xffffffffffff1001
-; CHECK-GI-NEXT: movk x8, #65281, lsl #16
-; CHECK-GI-NEXT: cmp x0, x8
-; CHECK-GI-NEXT: cset w0, lt
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_slt_64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn x0, #4079, lsl #12 // =16707584
+; CHECK-NEXT: cset w0, le
+; CHECK-NEXT: ret
%cmp = icmp slt i64 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_sge(i32 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_sge:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #4079, lsl #12 // =16707584
-; CHECK-SD-NEXT: cset w0, gt
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_sge:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #4097 // =0x1001
-; CHECK-GI-NEXT: movk w8, #65281, lsl #16
-; CHECK-GI-NEXT: cmp w0, w8
-; CHECK-GI-NEXT: cset w0, ge
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_sge:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn w0, #4079, lsl #12 // =16707584
+; CHECK-NEXT: cset w0, gt
+; CHECK-NEXT: ret
%cmp = icmp sge i32 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_sge_64(i64 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_sge_64:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn x0, #4079, lsl #12 // =16707584
-; CHECK-SD-NEXT: cset w0, gt
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_sge_64:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x8, #-61439 // =0xffffffffffff1001
-; CHECK-GI-NEXT: movk x8, #65281, lsl #16
-; CHECK-GI-NEXT: cmp x0, x8
-; CHECK-GI-NEXT: cset w0, ge
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_sge_64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn x0, #4079, lsl #12 // =16707584
+; CHECK-NEXT: cset w0, gt
+; CHECK-NEXT: ret
%cmp = icmp sge i64 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_uge(i32 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_uge:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #4079, lsl #12 // =16707584
-; CHECK-SD-NEXT: cset w0, hi
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_uge:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #4097 // =0x1001
-; CHECK-GI-NEXT: movk w8, #65281, lsl #16
-; CHECK-GI-NEXT: cmp w0, w8
-; CHECK-GI-NEXT: cset w0, hs
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_uge:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn w0, #4079, lsl #12 // =16707584
+; CHECK-NEXT: cset w0, hi
+; CHECK-NEXT: ret
%cmp = icmp uge i32 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_uge_64(i64 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_uge_64:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn x0, #4079, lsl #12 // =16707584
-; CHECK-SD-NEXT: cset w0, hi
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_uge_64:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x8, #-61439 // =0xffffffffffff1001
-; CHECK-GI-NEXT: movk x8, #65281, lsl #16
-; CHECK-GI-NEXT: cmp x0, x8
-; CHECK-GI-NEXT: cset w0, hs
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_uge_64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn x0, #4079, lsl #12 // =16707584
+; CHECK-NEXT: cset w0, hi
+; CHECK-NEXT: ret
%cmp = icmp uge i64 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_ult(i32 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_ult:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #4079, lsl #12 // =16707584
-; CHECK-SD-NEXT: cset w0, ls
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_ult:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #4097 // =0x1001
-; CHECK-GI-NEXT: movk w8, #65281, lsl #16
-; CHECK-GI-NEXT: cmp w0, w8
-; CHECK-GI-NEXT: cset w0, lo
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_ult:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn w0, #4079, lsl #12 // =16707584
+; CHECK-NEXT: cset w0, ls
+; CHECK-NEXT: ret
%cmp = icmp ult i32 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_ult_64(i64 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_ult_64:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn x0, #4079, lsl #12 // =16707584
-; CHECK-SD-NEXT: cset w0, ls
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_ult_64:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x8, #-61439 // =0xffffffffffff1001
-; CHECK-GI-NEXT: movk x8, #65281, lsl #16
-; CHECK-GI-NEXT: cmp x0, x8
-; CHECK-GI-NEXT: cset w0, lo
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_ult_64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn x0, #4079, lsl #12 // =16707584
+; CHECK-NEXT: cset w0, ls
+; CHECK-NEXT: ret
%cmp = icmp ult i64 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_sle(i32 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_sle:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #4095, lsl #12 // =16773120
-; CHECK-SD-NEXT: cset w0, lt
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_sle:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #-16773121 // =0xff000fff
-; CHECK-GI-NEXT: cmp w0, w8
-; CHECK-GI-NEXT: cset w0, le
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_sle:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn w0, #4095, lsl #12 // =16773120
+; CHECK-NEXT: cset w0, lt
+; CHECK-NEXT: ret
%cmp = icmp sle i32 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_sle_64(i64 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_sle_64:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn x0, #4095, lsl #12 // =16773120
-; CHECK-SD-NEXT: cset w0, lt
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_sle_64:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x8, #-16773121 // =0xffffffffff000fff
-; CHECK-GI-NEXT: cmp x0, x8
-; CHECK-GI-NEXT: cset w0, le
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_sle_64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn x0, #4095, lsl #12 // =16773120
+; CHECK-NEXT: cset w0, lt
+; CHECK-NEXT: ret
%cmp = icmp sle i64 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_sgt(i32 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_sgt:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #4095, lsl #12 // =16773120
-; CHECK-SD-NEXT: cset w0, ge
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_sgt:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #-16773121 // =0xff000fff
-; CHECK-GI-NEXT: cmp w0, w8
-; CHECK-GI-NEXT: cset w0, gt
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_sgt:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn w0, #4095, lsl #12 // =16773120
+; CHECK-NEXT: cset w0, ge
+; CHECK-NEXT: ret
%cmp = icmp sgt i32 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_sgt_64(i64 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_sgt_64:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn x0, #4095, lsl #12 // =16773120
-; CHECK-SD-NEXT: cset w0, ge
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_sgt_64:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x8, #-16773121 // =0xffffffffff000fff
-; CHECK-GI-NEXT: cmp x0, x8
-; CHECK-GI-NEXT: cset w0, gt
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_sgt_64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn x0, #4095, lsl #12 // =16773120
+; CHECK-NEXT: cset w0, ge
+; CHECK-NEXT: ret
%cmp = icmp sgt i64 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_ule(i32 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_ule:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #4095, lsl #12 // =16773120
-; CHECK-SD-NEXT: cset w0, lo
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_ule:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #-16773121 // =0xff000fff
-; CHECK-GI-NEXT: cmp w0, w8
-; CHECK-GI-NEXT: cset w0, ls
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_ule:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn w0, #4095, lsl #12 // =16773120
+; CHECK-NEXT: cset w0, lo
+; CHECK-NEXT: ret
%cmp = icmp ule i32 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_ule_64(i64 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_ule_64:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn x0, #4095, lsl #12 // =16773120
-; CHECK-SD-NEXT: cset w0, lo
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_ule_64:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x8, #-16773121 // =0xffffffffff000fff
-; CHECK-GI-NEXT: cmp x0, x8
-; CHECK-GI-NEXT: cset w0, ls
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_ule_64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn x0, #4095, lsl #12 // =16773120
+; CHECK-NEXT: cset w0, lo
+; CHECK-NEXT: ret
%cmp = icmp ule i64 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_ugt(i32 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_ugt:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #4095, lsl #12 // =16773120
-; CHECK-SD-NEXT: cset w0, hs
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_ugt:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #-16773121 // =0xff000fff
-; CHECK-GI-NEXT: cmp w0, w8
-; CHECK-GI-NEXT: cset w0, hi
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_ugt:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn w0, #4095, lsl #12 // =16773120
+; CHECK-NEXT: cset w0, hs
+; CHECK-NEXT: ret
%cmp = icmp ugt i32 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_ugt_64(i64 %x) {
-; CHECK-SD-LABEL: almost_immediate_neg_ugt_64:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn x0, #4095, lsl #12 // =16773120
-; CHECK-SD-NEXT: cset w0, hs
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: almost_immediate_neg_ugt_64:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x8, #-16773121 // =0xffffffffff000fff
-; CHECK-GI-NEXT: cmp x0, x8
-; CHECK-GI-NEXT: cset w0, hi
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: almost_immediate_neg_ugt_64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: cmn x0, #4095, lsl #12 // =16773120
+; CHECK-NEXT: cset w0, hs
+; CHECK-NEXT: ret
%cmp = icmp ugt i64 %x, -16773121
ret i1 %cmp
}
diff --git a/llvm/test/CodeGen/AArch64/fcvt-i256.ll b/llvm/test/CodeGen/AArch64/fcvt-i256.ll
index 42fcbddea7ccf..0e741749d5cdb 100644
--- a/llvm/test/CodeGen/AArch64/fcvt-i256.ll
+++ b/llvm/test/CodeGen/AArch64/fcvt-i256.ll
@@ -643,8 +643,8 @@ define i256 @f32_to_s256(float %val) {
; CHECK-GI-NEXT: mov x2, xzr
; CHECK-GI-NEXT: mov x3, xzr
; CHECK-GI-NEXT: ubfx w11, w9, #23, #8
-; CHECK-GI-NEXT: cmp w9, #0
-; CHECK-GI-NEXT: cset w8, mi
+; CHECK-GI-NEXT: cmn w9, #1
+; CHECK-GI-NEXT: cset w8, le
; CHECK-GI-NEXT: cmp w11, #127
; CHECK-GI-NEXT: b.lo .LBB4_5
; CHECK-GI-NEXT: // %bb.1: // %fp-to-i-if-check.exp.size
@@ -1013,8 +1013,8 @@ define i256 @f64_to_s256(double %val) {
; CHECK-GI-NEXT: mov x2, xzr
; CHECK-GI-NEXT: mov x3, xzr
; CHECK-GI-NEXT: ubfx x11, x8, #52, #11
-; CHECK-GI-NEXT: cmp x8, #0
-; CHECK-GI-NEXT: cset w9, mi
+; CHECK-GI-NEXT: cmn x8, #1
+; CHECK-GI-NEXT: cset w9, le
; CHECK-GI-NEXT: cmp x11, #1023
; CHECK-GI-NEXT: b.lo .LBB6_5
; CHECK-GI-NEXT: // %bb.1: // %fp-to-i-if-check.exp.size
@@ -1397,8 +1397,8 @@ define i256 @f32_to_s256_sat(float %val) {
; CHECK-GI: // %bb.0: // %fp-to-i-entry
; CHECK-GI-NEXT: fmov w9, s0
; CHECK-GI-NEXT: ubfx w11, w9, #23, #8
-; CHECK-GI-NEXT: cmp w9, #0
-; CHECK-GI-NEXT: cset w8, mi
+; CHECK-GI-NEXT: cmn w9, #1
+; CHECK-GI-NEXT: cset w8, le
; CHECK-GI-NEXT: cmp w11, #127
; CHECK-GI-NEXT: b.lo .LBB8_4
; CHECK-GI-NEXT: // %bb.1: // %fp-to-i-entry
@@ -1408,9 +1408,9 @@ define i256 @f32_to_s256_sat(float %val) {
; CHECK-GI-NEXT: mov w10, #1 // =0x1
; CHECK-GI-NEXT: tbnz w10, #0, .LBB8_5
; CHECK-GI-NEXT: // %bb.3: // %fp-to-i-if-saturate
-; CHECK-GI-NEXT: cmp w9, #0
+; CHECK-GI-NEXT: cmn w9, #1
; CHECK-GI-NEXT: mov w8, wzr
-; CHECK-GI-NEXT: cset w9, pl
+; CHECK-GI-NEXT: cset w9, gt
; CHECK-GI-NEXT: cmp w8, #1
; CHECK-GI-NEXT: mov x8, #-9223372036854775808 // =0x8000000000000000
; CHECK-GI-NEXT: sbfx x0, x9, #0, #1
@@ -1834,8 +1834,8 @@ define i256 @f64_to_s256_sat(double %val) {
; CHECK-GI: // %bb.0: // %fp-to-i-entry
; CHECK-GI-NEXT: fmov x8, d0
; CHECK-GI-NEXT: ubfx x11, x8, #52, #11
-; CHECK-GI-NEXT: cmp x8, #0
-; CHECK-GI-NEXT: cset w9, mi
+; CHECK-GI-NEXT: cmn x8, #1
+; CHECK-GI-NEXT: cset w9, le
; CHECK-GI-NEXT: cmp x11, #1023
; CHECK-GI-NEXT: b.lo .LBB10_4
; CHECK-GI-NEXT: // %bb.1: // %fp-to-i-entry
@@ -1845,9 +1845,9 @@ define i256 @f64_to_s256_sat(double %val) {
; CHECK-GI-NEXT: cmp x11, #1278
; CHECK-GI-NEXT: b.lo .LBB10_5
; CHECK-GI-NEXT: // %bb.3: // %fp-to-i-if-saturate
-; CHECK-GI-NEXT: cmp x8, #0
+; CHECK-GI-NEXT: cmn x8, #1
; CHECK-GI-NEXT: mov w9, wzr
-; CHECK-GI-NEXT: cset w8, pl
+; CHECK-GI-NEXT: cset w8, gt
; CHECK-GI-NEXT: cmp w9, #1
; CHECK-GI-NEXT: mov x9, #-9223372036854775808 // =0x8000000000000000
; CHECK-GI-NEXT: sbfx x0, x8, #0, #1
diff --git a/llvm/test/CodeGen/AArch64/fpclamptosat_vec.ll b/llvm/test/CodeGen/AArch64/fpclamptosat_vec.ll
index 19494205f4155..dcb0051bd4c3c 100644
--- a/llvm/test/CodeGen/AArch64/fpclamptosat_vec.ll
+++ b/llvm/test/CodeGen/AArch64/fpclamptosat_vec.ll
@@ -570,22 +570,20 @@ define <2 x i64> @stest_f64i64(<2 x double> %x) {
; CHECK-CVT-GI-NEXT: csel x11, x1, xzr, ne
; CHECK-CVT-GI-NEXT: cmp x8, x22
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x10, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x10, #1
-; CHECK-CVT-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w10, gt
+; CHECK-CVT-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
+; CHECK-CVT-GI-NEXT: csel w10, w12, w10, eq
; CHECK-CVT-GI-NEXT: cmp x9, x22
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x11, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x11, #1
-; CHECK-CVT-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w11, gt
+; CHECK-CVT-GI-NEXT: csel w11, w12, w11, eq
; CHECK-CVT-GI-NEXT: tst w10, #0x1
; CHECK-CVT-GI-NEXT: csel x8, x8, x22, ne
; CHECK-CVT-GI-NEXT: tst w11, #0x1
; CHECK-CVT-GI-NEXT: fmov d0, x8
; CHECK-CVT-GI-NEXT: csel x9, x9, x22, ne
-; CHECK-CVT-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-CVT-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-CVT-GI-NEXT: mov v0.d[1], x9
; CHECK-CVT-GI-NEXT: ldr d8, [sp], #48 // 8-byte Folded Reload
@@ -632,22 +630,20 @@ define <2 x i64> @stest_f64i64(<2 x double> %x) {
; CHECK-FP16-GI-NEXT: csel x11, x1, xzr, ne
; CHECK-FP16-GI-NEXT: cmp x8, x22
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x10, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x10, #1
-; CHECK-FP16-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w10, gt
+; CHECK-FP16-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
+; CHECK-FP16-GI-NEXT: csel w10, w12, w10, eq
; CHECK-FP16-GI-NEXT: cmp x9, x22
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x11, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x11, #1
-; CHECK-FP16-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w11, gt
+; CHECK-FP16-GI-NEXT: csel w11, w12, w11, eq
; CHECK-FP16-GI-NEXT: tst w10, #0x1
; CHECK-FP16-GI-NEXT: csel x8, x8, x22, ne
; CHECK-FP16-GI-NEXT: tst w11, #0x1
; CHECK-FP16-GI-NEXT: fmov d0, x8
; CHECK-FP16-GI-NEXT: csel x9, x9, x22, ne
-; CHECK-FP16-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-FP16-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-FP16-GI-NEXT: mov v0.d[1], x9
; CHECK-FP16-GI-NEXT: ldr d8, [sp], #48 // 8-byte Folded Reload
@@ -1035,22 +1031,20 @@ define <2 x i64> @stest_f32i64(<2 x float> %x) {
; CHECK-CVT-GI-NEXT: csel x11, x1, xzr, ne
; CHECK-CVT-GI-NEXT: cmp x8, x22
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x10, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x10, #1
-; CHECK-CVT-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w10, gt
+; CHECK-CVT-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
+; CHECK-CVT-GI-NEXT: csel w10, w12, w10, eq
; CHECK-CVT-GI-NEXT: cmp x9, x22
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x11, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x11, #1
-; CHECK-CVT-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w11, gt
+; CHECK-CVT-GI-NEXT: csel w11, w12, w11, eq
; CHECK-CVT-GI-NEXT: tst w10, #0x1
; CHECK-CVT-GI-NEXT: csel x8, x8, x22, ne
; CHECK-CVT-GI-NEXT: tst w11, #0x1
; CHECK-CVT-GI-NEXT: fmov d0, x8
; CHECK-CVT-GI-NEXT: csel x9, x9, x22, ne
-; CHECK-CVT-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-CVT-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-CVT-GI-NEXT: mov v0.d[1], x9
; CHECK-CVT-GI-NEXT: ldr d8, [sp], #48 // 8-byte Folded Reload
@@ -1098,22 +1092,20 @@ define <2 x i64> @stest_f32i64(<2 x float> %x) {
; CHECK-FP16-GI-NEXT: csel x11, x1, xzr, ne
; CHECK-FP16-GI-NEXT: cmp x8, x22
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x10, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x10, #1
-; CHECK-FP16-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w10, gt
+; CHECK-FP16-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
+; CHECK-FP16-GI-NEXT: csel w10, w12, w10, eq
; CHECK-FP16-GI-NEXT: cmp x9, x22
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x11, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x11, #1
-; CHECK-FP16-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w11, gt
+; CHECK-FP16-GI-NEXT: csel w11, w12, w11, eq
; CHECK-FP16-GI-NEXT: tst w10, #0x1
; CHECK-FP16-GI-NEXT: csel x8, x8, x22, ne
; CHECK-FP16-GI-NEXT: tst w11, #0x1
; CHECK-FP16-GI-NEXT: fmov d0, x8
; CHECK-FP16-GI-NEXT: csel x9, x9, x22, ne
-; CHECK-FP16-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-FP16-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-FP16-GI-NEXT: mov v0.d[1], x9
; CHECK-FP16-GI-NEXT: ldr d8, [sp], #48 // 8-byte Folded Reload
@@ -1507,16 +1499,14 @@ define <2 x i64> @stest_f16i64(<2 x half> %x) {
; CHECK-CVT-GI-NEXT: csel x10, x13, xzr, ne
; CHECK-CVT-GI-NEXT: cmp x9, x16
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x11, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x11, #1
-; CHECK-CVT-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w11, gt
+; CHECK-CVT-GI-NEXT: csel w11, w12, w11, eq
; CHECK-CVT-GI-NEXT: cmp x8, x16
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x10, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x10, #1
-; CHECK-CVT-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w10, gt
+; CHECK-CVT-GI-NEXT: csel w10, w12, w10, eq
; CHECK-CVT-GI-NEXT: tst w11, #0x1
; CHECK-CVT-GI-NEXT: csel x9, x9, x16, ne
; CHECK-CVT-GI-NEXT: tst w10, #0x1
@@ -1553,16 +1543,14 @@ define <2 x i64> @stest_f16i64(<2 x half> %x) {
; CHECK-FP16-GI-NEXT: csel x10, x13, xzr, ne
; CHECK-FP16-GI-NEXT: cmp x9, x16
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x11, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x11, #1
-; CHECK-FP16-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w11, gt
+; CHECK-FP16-GI-NEXT: csel w11, w12, w11, eq
; CHECK-FP16-GI-NEXT: cmp x8, x16
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x10, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x10, #1
-; CHECK-FP16-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w10, gt
+; CHECK-FP16-GI-NEXT: csel w10, w12, w10, eq
; CHECK-FP16-GI-NEXT: tst w11, #0x1
; CHECK-FP16-GI-NEXT: csel x9, x9, x16, ne
; CHECK-FP16-GI-NEXT: tst w10, #0x1
@@ -2372,22 +2360,20 @@ define <2 x i64> @stest_f64i64_mm(<2 x double> %x) {
; CHECK-CVT-GI-NEXT: csel x11, x1, xzr, ne
; CHECK-CVT-GI-NEXT: cmp x8, x22
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x10, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x10, #1
-; CHECK-CVT-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w10, gt
+; CHECK-CVT-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
+; CHECK-CVT-GI-NEXT: csel w10, w12, w10, eq
; CHECK-CVT-GI-NEXT: cmp x9, x22
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x11, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x11, #1
-; CHECK-CVT-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w11, gt
+; CHECK-CVT-GI-NEXT: csel w11, w12, w11, eq
; CHECK-CVT-GI-NEXT: tst w10, #0x1
; CHECK-CVT-GI-NEXT: csel x8, x8, x22, ne
; CHECK-CVT-GI-NEXT: tst w11, #0x1
; CHECK-CVT-GI-NEXT: fmov d0, x8
; CHECK-CVT-GI-NEXT: csel x9, x9, x22, ne
-; CHECK-CVT-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-CVT-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-CVT-GI-NEXT: mov v0.d[1], x9
; CHECK-CVT-GI-NEXT: ldr d8, [sp], #48 // 8-byte Folded Reload
@@ -2434,22 +2420,20 @@ define <2 x i64> @stest_f64i64_mm(<2 x double> %x) {
; CHECK-FP16-GI-NEXT: csel x11, x1, xzr, ne
; CHECK-FP16-GI-NEXT: cmp x8, x22
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x10, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x10, #1
-; CHECK-FP16-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w10, gt
+; CHECK-FP16-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
+; CHECK-FP16-GI-NEXT: csel w10, w12, w10, eq
; CHECK-FP16-GI-NEXT: cmp x9, x22
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x11, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x11, #1
-; CHECK-FP16-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w11, gt
+; CHECK-FP16-GI-NEXT: csel w11, w12, w11, eq
; CHECK-FP16-GI-NEXT: tst w10, #0x1
; CHECK-FP16-GI-NEXT: csel x8, x8, x22, ne
; CHECK-FP16-GI-NEXT: tst w11, #0x1
; CHECK-FP16-GI-NEXT: fmov d0, x8
; CHECK-FP16-GI-NEXT: csel x9, x9, x22, ne
-; CHECK-FP16-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-FP16-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-FP16-GI-NEXT: mov v0.d[1], x9
; CHECK-FP16-GI-NEXT: ldr d8, [sp], #48 // 8-byte Folded Reload
@@ -2828,22 +2812,20 @@ define <2 x i64> @stest_f32i64_mm(<2 x float> %x) {
; CHECK-CVT-GI-NEXT: csel x11, x1, xzr, ne
; CHECK-CVT-GI-NEXT: cmp x8, x22
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x10, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x10, #1
-; CHECK-CVT-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w10, gt
+; CHECK-CVT-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
+; CHECK-CVT-GI-NEXT: csel w10, w12, w10, eq
; CHECK-CVT-GI-NEXT: cmp x9, x22
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x11, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x11, #1
-; CHECK-CVT-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w11, gt
+; CHECK-CVT-GI-NEXT: csel w11, w12, w11, eq
; CHECK-CVT-GI-NEXT: tst w10, #0x1
; CHECK-CVT-GI-NEXT: csel x8, x8, x22, ne
; CHECK-CVT-GI-NEXT: tst w11, #0x1
; CHECK-CVT-GI-NEXT: fmov d0, x8
; CHECK-CVT-GI-NEXT: csel x9, x9, x22, ne
-; CHECK-CVT-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-CVT-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-CVT-GI-NEXT: mov v0.d[1], x9
; CHECK-CVT-GI-NEXT: ldr d8, [sp], #48 // 8-byte Folded Reload
@@ -2891,22 +2873,20 @@ define <2 x i64> @stest_f32i64_mm(<2 x float> %x) {
; CHECK-FP16-GI-NEXT: csel x11, x1, xzr, ne
; CHECK-FP16-GI-NEXT: cmp x8, x22
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x10, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x10, #1
-; CHECK-FP16-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w10, gt
+; CHECK-FP16-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
+; CHECK-FP16-GI-NEXT: csel w10, w12, w10, eq
; CHECK-FP16-GI-NEXT: cmp x9, x22
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x11, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x11, #1
-; CHECK-FP16-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w11, gt
+; CHECK-FP16-GI-NEXT: csel w11, w12, w11, eq
; CHECK-FP16-GI-NEXT: tst w10, #0x1
; CHECK-FP16-GI-NEXT: csel x8, x8, x22, ne
; CHECK-FP16-GI-NEXT: tst w11, #0x1
; CHECK-FP16-GI-NEXT: fmov d0, x8
; CHECK-FP16-GI-NEXT: csel x9, x9, x22, ne
-; CHECK-FP16-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-FP16-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-FP16-GI-NEXT: mov v0.d[1], x9
; CHECK-FP16-GI-NEXT: ldr d8, [sp], #48 // 8-byte Folded Reload
@@ -3291,16 +3271,14 @@ define <2 x i64> @stest_f16i64_mm(<2 x half> %x) {
; CHECK-CVT-GI-NEXT: csel x10, x13, xzr, ne
; CHECK-CVT-GI-NEXT: cmp x9, x16
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x11, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x11, #1
-; CHECK-CVT-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w11, gt
+; CHECK-CVT-GI-NEXT: csel w11, w12, w11, eq
; CHECK-CVT-GI-NEXT: cmp x8, x16
; CHECK-CVT-GI-NEXT: cset w12, hi
-; CHECK-CVT-GI-NEXT: cmp x10, #0
-; CHECK-CVT-GI-NEXT: cset w13, pl
; CHECK-CVT-GI-NEXT: cmn x10, #1
-; CHECK-CVT-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-CVT-GI-NEXT: cset w10, gt
+; CHECK-CVT-GI-NEXT: csel w10, w12, w10, eq
; CHECK-CVT-GI-NEXT: tst w11, #0x1
; CHECK-CVT-GI-NEXT: csel x9, x9, x16, ne
; CHECK-CVT-GI-NEXT: tst w10, #0x1
@@ -3337,16 +3315,14 @@ define <2 x i64> @stest_f16i64_mm(<2 x half> %x) {
; CHECK-FP16-GI-NEXT: csel x10, x13, xzr, ne
; CHECK-FP16-GI-NEXT: cmp x9, x16
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x11, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x11, #1
-; CHECK-FP16-GI-NEXT: csel w11, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w11, gt
+; CHECK-FP16-GI-NEXT: csel w11, w12, w11, eq
; CHECK-FP16-GI-NEXT: cmp x8, x16
; CHECK-FP16-GI-NEXT: cset w12, hi
-; CHECK-FP16-GI-NEXT: cmp x10, #0
-; CHECK-FP16-GI-NEXT: cset w13, pl
; CHECK-FP16-GI-NEXT: cmn x10, #1
-; CHECK-FP16-GI-NEXT: csel w10, w12, w13, eq
+; CHECK-FP16-GI-NEXT: cset w10, gt
+; CHECK-FP16-GI-NEXT: csel w10, w12, w10, eq
; CHECK-FP16-GI-NEXT: tst w11, #0x1
; CHECK-FP16-GI-NEXT: csel x9, x9, x16, ne
; CHECK-FP16-GI-NEXT: tst w10, #0x1
diff --git a/llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll b/llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll
index b6cbe9eb46389..f95d338198c4d 100644
--- a/llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll
+++ b/llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll
@@ -33,8 +33,8 @@ define i1 @test_signed_i1_f32(float %f) nounwind {
; CHECK-GI-NEXT: fcvtzs w8, s0
; CHECK-GI-NEXT: cmp w8, #0
; CHECK-GI-NEXT: csel w8, w8, wzr, mi
-; CHECK-GI-NEXT: cmp w8, #0
-; CHECK-GI-NEXT: csinv w8, w8, wzr, pl
+; CHECK-GI-NEXT: cmn w8, #1
+; CHECK-GI-NEXT: csinv w8, w8, wzr, gt
; CHECK-GI-NEXT: and w0, w8, #0x1
; CHECK-GI-NEXT: ret
%x = call i1 @llvm.fptosi.sat.i1.f32(float %f)
@@ -278,8 +278,8 @@ define i1 @test_signed_i1_f64(double %f) nounwind {
; CHECK-GI-NEXT: fcvtzs w8, d0
; CHECK-GI-NEXT: cmp w8, #0
; CHECK-GI-NEXT: csel w8, w8, wzr, mi
-; CHECK-GI-NEXT: cmp w8, #0
-; CHECK-GI-NEXT: csinv w8, w8, wzr, pl
+; CHECK-GI-NEXT: cmn w8, #1
+; CHECK-GI-NEXT: csinv w8, w8, wzr, gt
; CHECK-GI-NEXT: and w0, w8, #0x1
; CHECK-GI-NEXT: ret
%x = call i1 @llvm.fptosi.sat.i1.f64(double %f)
@@ -537,8 +537,8 @@ define i1 @test_signed_i1_f16(half %f) nounwind {
; CHECK-GI-CVT-NEXT: fcvtzs w8, s0
; CHECK-GI-CVT-NEXT: cmp w8, #0
; CHECK-GI-CVT-NEXT: csel w8, w8, wzr, mi
-; CHECK-GI-CVT-NEXT: cmp w8, #0
-; CHECK-GI-CVT-NEXT: csinv w8, w8, wzr, pl
+; CHECK-GI-CVT-NEXT: cmn w8, #1
+; CHECK-GI-CVT-NEXT: csinv w8, w8, wzr, gt
; CHECK-GI-CVT-NEXT: and w0, w8, #0x1
; CHECK-GI-CVT-NEXT: ret
;
@@ -547,8 +547,8 @@ define i1 @test_signed_i1_f16(half %f) nounwind {
; CHECK-GI-FP16-NEXT: fcvtzs w8, h0
; CHECK-GI-FP16-NEXT: cmp w8, #0
; CHECK-GI-FP16-NEXT: csel w8, w8, wzr, mi
-; CHECK-GI-FP16-NEXT: cmp w8, #0
-; CHECK-GI-FP16-NEXT: csinv w8, w8, wzr, pl
+; CHECK-GI-FP16-NEXT: cmn w8, #1
+; CHECK-GI-FP16-NEXT: csinv w8, w8, wzr, gt
; CHECK-GI-FP16-NEXT: and w0, w8, #0x1
; CHECK-GI-FP16-NEXT: ret
%x = call i1 @llvm.fptosi.sat.i1.f16(half %f)
diff --git a/llvm/test/CodeGen/AArch64/select-constant-xor.ll b/llvm/test/CodeGen/AArch64/select-constant-xor.ll
index 97ad579a39f78..53c13fc2abace 100644
--- a/llvm/test/CodeGen/AArch64/select-constant-xor.ll
+++ b/llvm/test/CodeGen/AArch64/select-constant-xor.ll
@@ -155,8 +155,8 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
;
; CHECK-GI-LABEL: icmpasreq:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #-1 // =0xffffffff
-; CHECK-GI-NEXT: cmp w8, w0, asr #31
+; CHECK-GI-NEXT: asr w8, w0, #31
+; CHECK-GI-NEXT: cmn w8, #1
; CHECK-GI-NEXT: csel w0, w1, w2, eq
; CHECK-GI-NEXT: ret
%sh = ashr i32 %input, 31
@@ -168,14 +168,14 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
; CHECK-SD-LABEL: icmpasrne:
; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmn w0, #1
-; CHECK-SD-NEXT: csel w0, w1, w2, gt
+; CHECK-SD-NEXT: cmp w0, #0
+; CHECK-SD-NEXT: csel w0, w1, w2, pl
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: icmpasrne:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #-1 // =0xffffffff
-; CHECK-GI-NEXT: cmp w8, w0, asr #31
+; CHECK-GI-NEXT: asr w8, w0, #31
+; CHECK-GI-NEXT: cmn w8, #1
; CHECK-GI-NEXT: csel w0, w1, w2, ne
; CHECK-GI-NEXT: ret
%sh = ashr i32 %input, 31
diff --git a/llvm/test/CodeGen/AArch64/signbit-shift.ll b/llvm/test/CodeGen/AArch64/signbit-shift.ll
index ce8a96386d04c..0f64e7f485a5e 100644
--- a/llvm/test/CodeGen/AArch64/signbit-shift.ll
+++ b/llvm/test/CodeGen/AArch64/signbit-shift.ll
@@ -43,8 +43,8 @@ define i32 @sel_ifpos_tval_bigger(i32 %x) {
; CHECK-LABEL: sel_ifpos_tval_bigger:
; CHECK: // %bb.0:
; CHECK-NEXT: mov w8, #41 // =0x29
-; CHECK-NEXT: cmn w0, #1
-; CHECK-NEXT: cinc w0, w8, gt
+; CHECK-NEXT: cmp w0, #0
+; CHECK-NEXT: cinc w0, w8, pl
; CHECK-NEXT: ret
%c = icmp sgt i32 %x, -1
%r = select i1 %c, i32 42, i32 41
@@ -91,8 +91,8 @@ define i32 @sel_ifpos_fval_bigger(i32 %x) {
; CHECK-LABEL: sel_ifpos_fval_bigger:
; CHECK: // %bb.0:
; CHECK-NEXT: mov w8, #41 // =0x29
-; CHECK-NEXT: cmn w0, #1
-; CHECK-NEXT: cinc w0, w8, le
+; CHECK-NEXT: cmp w0, #0
+; CHECK-NEXT: cinc w0, w8, mi
; CHECK-NEXT: ret
%c = icmp sgt i32 %x, -1
%r = select i1 %c, i32 41, i32 42
diff --git a/llvm/test/CodeGen/AArch64/signbit-test.ll b/llvm/test/CodeGen/AArch64/signbit-test.ll
index 298495bcf5a01..a0a7909ce19f9 100644
--- a/llvm/test/CodeGen/AArch64/signbit-test.ll
+++ b/llvm/test/CodeGen/AArch64/signbit-test.ll
@@ -6,8 +6,8 @@ define i64 @test_clear_mask_i64_i32(i64 %x) nounwind {
; CHECK-SD-LABEL: test_clear_mask_i64_i32:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: mov w8, #42 // =0x2a
-; CHECK-SD-NEXT: cmn w0, #1
-; CHECK-SD-NEXT: csel x0, x8, x0, gt
+; CHECK-SD-NEXT: cmp w0, #0
+; CHECK-SD-NEXT: csel x0, x8, x0, pl
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_clear_mask_i64_i32:
diff --git a/llvm/test/CodeGen/AArch64/typepromotion-signed.ll b/llvm/test/CodeGen/AArch64/typepromotion-signed.ll
index 0feac24062647..ded6a1de2677d 100644
--- a/llvm/test/CodeGen/AArch64/typepromotion-signed.ll
+++ b/llvm/test/CodeGen/AArch64/typepromotion-signed.ll
@@ -60,9 +60,9 @@ define i32 @test_signext_b(ptr nocapture readonly %ptr, i8 signext %arg) {
; CHECK-NEXT: mov w8, #20894 // =0x519e
; CHECK-NEXT: add w9, w9, w1
; CHECK-NEXT: sxtb w9, w9
-; CHECK-NEXT: cmn w9, #1
+; CHECK-NEXT: cmp w9, #0
; CHECK-NEXT: mov w9, #42 // =0x2a
-; CHECK-NEXT: csel w0, w9, w8, gt
+; CHECK-NEXT: csel w0, w9, w8, pl
; CHECK-NEXT: ret
entry:
%0 = load i8, ptr %ptr, align 1
@@ -100,9 +100,9 @@ define i32 @test_signext_h(ptr nocapture readonly %ptr, i16 signext %arg) {
; CHECK-NEXT: mov w8, #20894 // =0x519e
; CHECK-NEXT: add w9, w9, w1
; CHECK-NEXT: sxth w9, w9
-; CHECK-NEXT: cmn w9, #1
+; CHECK-NEXT: cmp w9, #0
; CHECK-NEXT: mov w9, #42 // =0x2a
-; CHECK-NEXT: csel w0, w9, w8, gt
+; CHECK-NEXT: csel w0, w9, w8, pl
; CHECK-NEXT: ret
entry:
%0 = load i16, ptr %ptr, align 1
More information about the llvm-commits
mailing list