[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