[llvm] [ARM] Use adds to implement integer cmn in thumb1 and thumb2 (PR #199247)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 22 11:41:39 PDT 2026


https://github.com/LumioseSil updated https://github.com/llvm/llvm-project/pull/199247

>From 6a1c41d3cbbd452b4244c08c8797a36e7707300a Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Fri, 22 May 2026 14:10:52 -0400
Subject: [PATCH] [ARM] Use adds to implement integer cmn in thumb1 and thumb2

This saves us from having to materialize the negative.
---
 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp       |  87 +++++----
 llvm/lib/Target/ARM/ARMISelLowering.cpp       |  32 +--
 llvm/lib/Target/ARM/ARMInstrThumb.td          |  11 ++
 llvm/lib/Target/ARM/ARMInstrThumb2.td         |  14 +-
 llvm/test/CodeGen/ARM/cmn.ll                  |   6 +-
 llvm/test/CodeGen/ARM/consthoist-icmpimm.ll   | 112 +++++------
 llvm/test/CodeGen/ARM/sadd_sat.ll             | 165 +++++++++++-----
 llvm/test/CodeGen/ARM/sat-to-bitop.ll         |  36 ++--
 llvm/test/CodeGen/ARM/select-constant-xor.ll  |  12 +-
 llvm/test/CodeGen/ARM/select_xform.ll         |  26 +--
 llvm/test/CodeGen/ARM/ssub_sat.ll             |  12 +-
 llvm/test/CodeGen/ARM/ssub_sat_plus.ll        |  12 +-
 .../CodeGen/ARM/thumb-cmp-neg-imm-adds.ll     |  48 +++++
 llvm/test/CodeGen/Thumb/cmp-add-fold.ll       |  10 +-
 llvm/test/CodeGen/Thumb/long.ll               |  15 +-
 llvm/test/CodeGen/Thumb/smul_fix_sat.ll       | 133 ++++++-------
 llvm/test/CodeGen/Thumb2/active_lane_mask.ll  |   4 +-
 .../test/CodeGen/Thumb2/mve-blockplacement.ll |  20 +-
 .../CodeGen/Thumb2/mve-fpclamptosat_vec.ll    |  32 +--
 llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll    |   2 +-
 llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll  |  16 +-
 .../CodeGen/Thumb2/mve-saturating-arith.ll    |   4 +-
 llvm/test/CodeGen/Thumb2/mve-vqmovn.ll        |   8 +-
 llvm/test/CodeGen/Thumb2/mve-vqshrn.ll        |   8 +-
 .../CodeGen/Thumb2/mve-vselect-constants.ll   |   4 +-
 .../CodeGen/Thumb2/pacbti-m-outliner-4.ll     |   2 +-
 llvm/test/CodeGen/Thumb2/thumb2-cmp.ll        | 184 +++++++++++++++---
 27 files changed, 626 insertions(+), 389 deletions(-)
 create mode 100644 llvm/test/CodeGen/ARM/thumb-cmp-neg-imm-adds.ll

diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 61b679d55fb47..7c7739cf98224 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -315,6 +315,10 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
 
   void SelectCMPZ(SDNode *N, bool &SwitchEQNEToPLMI);
 
+  /// Thumb compare-with-negative-immediate -> tADDSi / t2ADDSri with a dead
+  /// GPR def; compare users take the CPSR result (not the GPR).
+  bool selectCmpNegImmToAdds(SDNode *N);
+
   void SelectCMP_SWAP(SDNode *N);
 
   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
@@ -3678,6 +3682,48 @@ static unsigned getVectorShuffleOpcode(EVT VT, unsigned Opc64[3],
   }
 }
 
+bool ARMDAGToDAGISel::selectCmpNegImmToAdds(SDNode *N) {
+  assert((N->getOpcode() == ARMISD::CMP || N->getOpcode() == ARMISD::CMPZ) &&
+         "expected an ARM compare node");
+
+  // ARM-mode functions use CMP/CMN; this transform is Thumb-only.
+  if (!Subtarget->isThumb())
+    return false;
+
+  auto *RHSC = dyn_cast<ConstantSDNode>(N->getOperand(1));
+  if (!RHSC || RHSC->getSExtValue() >= 0)
+    return false;
+
+  int64_t Addend = -RHSC->getSExtValue();
+  // Thumb1 only has 16-bit ADD/S with immediates up to 255.
+  if (Addend >= 256)
+    return false;
+
+  // Thumb2: use 32-bit CMN when the addend does not fit a narrow ADDS.
+  if (Subtarget->hasThumb2() && ARM_AM::getT2SOImmVal(Addend) == -1)
+    return false;
+
+  SDLoc dl(N);
+  SDValue LHS = N->getOperand(0);
+  SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
+
+  // Select directly to a flag-setting ADDS with two results (GPR, CPSR).
+  // Compare users must use result 1; result 0 is an unused in-place add.
+  if (Subtarget->hasThumb2()) {
+    SDValue Ops[] = {LHS, getI32Imm(Addend, dl), getAL(CurDAG, dl), Reg0};
+    CurDAG->SelectNodeTo(N, ARM::t2ADDSri, MVT::i32, MVT::i32, Ops);
+  } else {
+    unsigned Opc = Addend < 8 ? ARM::tADDSi3 : ARM::tADDSi8;
+    SDValue Ops[] = {LHS, getI32Imm(Addend, dl)};
+    CurDAG->SelectNodeTo(N, Opc, MVT::i32, MVT::i32, Ops);
+  }
+
+  // ARMcmp/CMPZ only expose flags on result 0; after SelectNodeTo that slot
+  // is the GPR def. Rewire all compare users to result 1 (CPSR).
+  ReplaceUses(SDValue(N, 0), SDValue(N, 1));
+  return true;
+}
+
 void ARMDAGToDAGISel::Select(SDNode *N) {
   SDLoc dl(N);
 
@@ -4196,44 +4242,11 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
     CurDAG->SelectNodeTo(N, Opc, MVT::Other, Ops);
     return;
   }
-
-  case ARMISD::CMPZ: {
-    // select (CMPZ X, #-C) -> (CMPZ (ADDS X, #C), #0)
-    //   This allows us to avoid materializing the expensive negative constant.
-    //   The CMPZ #0 is useless and will be peepholed away but we need to keep
-    //   it for its flags output.
-    SDValue X = N->getOperand(0);
-    auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1).getNode());
-    if (C && C->getSExtValue() < 0 && Subtarget->isThumb()) {
-      int64_t Addend = -C->getSExtValue();
-
-      SDNode *Add = nullptr;
-      // ADDS can be better than CMN if the immediate fits in a
-      // 16-bit ADDS, which means either [0,256) for tADDi8 or [0,8) for tADDi3.
-      // Outside that range we can just use a CMN which is 32-bit but has a
-      // 12-bit immediate range.
-      if (Addend < 1<<8) {
-        if (Subtarget->isThumb2()) {
-          SDValue Ops[] = { X, CurDAG->getTargetConstant(Addend, dl, MVT::i32),
-                            getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32),
-                            CurDAG->getRegister(0, MVT::i32) };
-          Add = CurDAG->getMachineNode(ARM::t2ADDri, dl, MVT::i32, Ops);
-        } else {
-          unsigned Opc = (Addend < 1<<3) ? ARM::tADDi3 : ARM::tADDi8;
-          SDValue Ops[] = {CurDAG->getRegister(ARM::CPSR, MVT::i32), X,
-                           CurDAG->getTargetConstant(Addend, dl, MVT::i32),
-                           getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32)};
-          Add = CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops);
-        }
-      }
-      if (Add) {
-        SDValue Ops2[] = {SDValue(Add, 0), CurDAG->getConstant(0, dl, MVT::i32)};
-        CurDAG->MorphNodeTo(N, ARMISD::CMPZ, N->getVTList(), Ops2);
-      }
-    }
-    // Other cases are autogenerated.
+  case ARMISD::CMP:
+  case ARMISD::CMPZ:
+    if (selectCmpNegImmToAdds(N))
+      return;
     break;
-  }
 
   case ARMISD::CMOV: {
     SDValue Flags = N->getOperand(3);
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 635a5f4e6ca94..4bdff2b90d49e 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -13055,9 +13055,7 @@ static SDValue PerformUMLALCombine(SDNode *N, SelectionDAG &DAG,
 }
 
 static SDValue PerformAddcSubcCombine(SDNode *N,
-                                      TargetLowering::DAGCombinerInfo &DCI,
-                                      const ARMSubtarget *Subtarget) {
-  SelectionDAG &DAG(DCI.DAG);
+                                      TargetLowering::DAGCombinerInfo &DCI) {
 
   if (N->getOpcode() == ARMISD::SUBC && N->hasAnyUseOfValue(1)) {
     // (SUBC (ADDE 0, 0, C), 1) -> C
@@ -13070,20 +13068,6 @@ static SDValue PerformAddcSubcCombine(SDNode *N,
     }
   }
 
-  if (Subtarget->isThumb1Only()) {
-    SDValue RHS = N->getOperand(1);
-    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) {
-      int32_t imm = C->getSExtValue();
-      if (imm < 0 && imm > std::numeric_limits<int>::min()) {
-        SDLoc DL(N);
-        RHS = DAG.getConstant(-imm, DL, MVT::i32);
-        unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC
-                                                           : ARMISD::ADDC;
-        return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS);
-      }
-    }
-  }
-
   return SDValue();
 }
 
@@ -19031,7 +19015,7 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N,
   case ISD::BRCOND:
   case ISD::BR_CC:      return PerformHWLoopCombine(N, DCI, Subtarget);
   case ARMISD::ADDC:
-  case ARMISD::SUBC:    return PerformAddcSubcCombine(N, DCI, Subtarget);
+  case ARMISD::SUBC:    return PerformAddcSubcCombine(N, DCI);
   case ARMISD::SUBE:    return PerformAddeSubeCombine(N, DCI, Subtarget);
   case ARMISD::BFI:     return PerformBFICombine(N, DCI.DAG);
   case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
@@ -19729,16 +19713,12 @@ bool ARMTargetLowering::isLegalAddressingMode(const DataLayout &DL,
 /// icmp immediate, that is the target has icmp instructions which can compare
 /// a register against the immediate without having to materialize the
 /// immediate into a register.
+
+// Integer comparisons have the same range as ADDS/SUBS, and for thumb1,
+// implemented as adds.
 bool ARMTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
   // Thumb2 and ARM modes can use cmn for negative immediates.
-  if (!Subtarget->isThumb())
-    return ARM_AM::getSOImmVal((uint32_t)Imm) != -1 ||
-           ARM_AM::getSOImmVal(-(uint32_t)Imm) != -1;
-  if (Subtarget->isThumb2())
-    return ARM_AM::getT2SOImmVal((uint32_t)Imm) != -1 ||
-           ARM_AM::getT2SOImmVal(-(uint32_t)Imm) != -1;
-  // Thumb1 doesn't have cmn, and only 8-bit immediates.
-  return Imm >= 0 && Imm <= 255;
+  return isLegalAddImmediate(Imm);
 }
 
 /// isLegalAddImmediate - Return true if the specified immediate is a legal add
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td
index 1e2e3c30a78f7..04a25c5257b13 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -1406,6 +1406,17 @@ let hasPostISelHook = 1, Defs = [CPSR] in {
                 Sched<[WriteALU]>;
 }
 
+let AddedComplexity = 1 in {
+def : T1Pat<(ARMaddc tGPR:$src, mod_imm1_7_neg:$imm),
+            (tSUBSi3 tGPR:$src, mod_imm1_7_neg:$imm)>;
+def : T1Pat<(ARMaddc tGPR:$src, mod_imm8_255_neg:$imm),
+            (tSUBSi8 tGPR:$src, mod_imm8_255_neg:$imm)>;
+def : T1Pat<(ARMsubc tGPR:$src, mod_imm1_7_neg:$imm),
+            (tADDSi3 tGPR:$src, mod_imm1_7_neg:$imm)>;
+def : T1Pat<(ARMsubc tGPR:$src, mod_imm8_255_neg:$imm),
+            (tADDSi8 tGPR:$src, mod_imm8_255_neg:$imm)>;
+}
+
 // Sign-extend byte
 def tSXTB :                     // A8.6.222
   T1pIMiscEncode<{0,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index 228baa9df6226..b62c02a66e6f0 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -2505,11 +2505,13 @@ defm t2RSBS : T2I_rbin_s_is <ARMsubc>;
 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
 // details.
-// The AddedComplexity preferences the first variant over the others since
-// it can be shrunk to a 16-bit wide encoding, while the others cannot.
-let AddedComplexity = 1 in
+let AddedComplexity = 1 in {
 def : T2Pat<(add        rGPR:$src, imm1_255_neg:$imm),
             (t2SUBri    rGPR:$src, imm1_255_neg:$imm)>;
+def : T2Pat<(sub        rGPR:$src, imm1_255_neg:$imm),
+            (t2ADDri    rGPR:$src, imm1_255_neg:$imm)>;
+}
+
 def : T2Pat<(add        rGPR:$src, t2_so_imm_neg:$imm),
             (t2SUBri    rGPR:$src, t2_so_imm_neg:$imm)>;
 def : T2Pat<(add        rGPR:$src, imm0_4095_neg:$imm),
@@ -2522,9 +2524,13 @@ def : T1Pat<(add tGPR:$src, imm0_65535_neg:$imm),
              (tSUBrr tGPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>,
              Requires<[HasV8MBaseline]>;
 
-let AddedComplexity = 1 in
+let AddedComplexity = 1 in {
 def : T2Pat<(ARMaddc    rGPR:$src, imm1_255_neg:$imm),
             (t2SUBSri   rGPR:$src, imm1_255_neg:$imm)>;
+def : T2Pat<(ARMsubc    rGPR:$src, imm1_255_neg:$imm),
+            (t2ADDSri   rGPR:$src, imm1_255_neg:$imm)>;
+}
+
 def : T2Pat<(ARMaddc    rGPR:$src, t2_so_imm_neg:$imm),
             (t2SUBSri   rGPR:$src, t2_so_imm_neg:$imm)>;
 def : T2Pat<(ARMaddc    rGPR:$src, imm0_65535_neg:$imm),
diff --git a/llvm/test/CodeGen/ARM/cmn.ll b/llvm/test/CodeGen/ARM/cmn.ll
index fbcee5196b63d..e506e49731f6b 100644
--- a/llvm/test/CodeGen/ARM/cmn.ll
+++ b/llvm/test/CodeGen/ARM/cmn.ll
@@ -7,7 +7,7 @@ define i32 @compare_i_gt(i32 %a) {
 ; T2-LABEL: compare_i_gt:
 ; T2:       @ %bb.0: @ %entry
 ; T2-NEXT:    movs r1, #24
-; T2-NEXT:    cmn.w r0, #78
+; T2-NEXT:    adds r0, #78
 ; T2-NEXT:    it gt
 ; T2-NEXT:    movgt r1, #42
 ; T2-NEXT:    mov r0, r1
@@ -15,9 +15,7 @@ define i32 @compare_i_gt(i32 %a) {
 ;
 ; T1-LABEL: compare_i_gt:
 ; T1:       @ %bb.0: @ %entry
-; T1-NEXT:    movs r1, #77
-; T1-NEXT:    mvns r1, r1
-; T1-NEXT:    cmp r0, r1
+; T1-NEXT:    adds r0, #78
 ; T1-NEXT:    bgt .LBB0_2
 ; T1-NEXT:  @ %bb.1: @ %entry
 ; T1-NEXT:    movs r0, #24
diff --git a/llvm/test/CodeGen/ARM/consthoist-icmpimm.ll b/llvm/test/CodeGen/ARM/consthoist-icmpimm.ll
index 16b7403bdb932..541b2b679a613 100644
--- a/llvm/test/CodeGen/ARM/consthoist-icmpimm.ll
+++ b/llvm/test/CodeGen/ARM/consthoist-icmpimm.ll
@@ -12,26 +12,26 @@ define i32 @icmp64_sge_0(i64 %x, i64 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV6M-NEXT:    ldr r0, [sp]
 ; CHECKV6M-NEXT:    beq .LBB0_4
 ; CHECKV6M-NEXT:  @ %bb.1: @ %then
-; CHECKV6M-NEXT:    cmp r3, #0
+; CHECKV6M-NEXT:    adds r3, r3, #1
 ; CHECKV6M-NEXT:    mov r3, r0
-; CHECKV6M-NEXT:    blt .LBB0_7
+; CHECKV6M-NEXT:    ble .LBB0_7
 ; CHECKV6M-NEXT:  @ %bb.2: @ %then
-; CHECKV6M-NEXT:    cmp r1, #0
-; CHECKV6M-NEXT:    blt .LBB0_8
+; CHECKV6M-NEXT:    adds r1, r1, #1
+; CHECKV6M-NEXT:    ble .LBB0_8
 ; CHECKV6M-NEXT:  .LBB0_3: @ %then
 ; CHECKV6M-NEXT:    adds r0, r0, r3
 ; CHECKV6M-NEXT:    bx lr
 ; CHECKV6M-NEXT:  .LBB0_4: @ %else
-; CHECKV6M-NEXT:    cmp r1, #0
-; CHECKV6M-NEXT:    bge .LBB0_6
+; CHECKV6M-NEXT:    adds r1, r1, #1
+; CHECKV6M-NEXT:    bgt .LBB0_6
 ; CHECKV6M-NEXT:  @ %bb.5: @ %else
 ; CHECKV6M-NEXT:    mov r0, r2
 ; CHECKV6M-NEXT:  .LBB0_6: @ %else
 ; CHECKV6M-NEXT:    bx lr
 ; CHECKV6M-NEXT:  .LBB0_7: @ %then
 ; CHECKV6M-NEXT:    mov r3, r2
-; CHECKV6M-NEXT:    cmp r1, #0
-; CHECKV6M-NEXT:    bge .LBB0_3
+; CHECKV6M-NEXT:    adds r1, r1, #1
+; CHECKV6M-NEXT:    bgt .LBB0_3
 ; CHECKV6M-NEXT:  .LBB0_8: @ %then
 ; CHECKV6M-NEXT:    mov r0, r2
 ; CHECKV6M-NEXT:    adds r0, r0, r3
@@ -44,17 +44,17 @@ define i32 @icmp64_sge_0(i64 %x, i64 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV7M-NEXT:    ldrd r2, r0, [sp]
 ; CHECKV7M-NEXT:    beq .LBB0_2
 ; CHECKV7M-NEXT:  @ %bb.1: @ %then
-; CHECKV7M-NEXT:    cmp.w r3, #-1
+; CHECKV7M-NEXT:    adds r3, #1
 ; CHECKV7M-NEXT:    mov r3, r0
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r3, r2
-; CHECKV7M-NEXT:    cmp.w r1, #-1
+; CHECKV7M-NEXT:    adds r1, #1
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r0, r2
 ; CHECKV7M-NEXT:    add r0, r3
 ; CHECKV7M-NEXT:    bx lr
 ; CHECKV7M-NEXT:  .LBB0_2: @ %else
-; CHECKV7M-NEXT:    cmp.w r1, #-1
+; CHECKV7M-NEXT:    adds r1, #1
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r0, r2
 ; CHECKV7M-NEXT:    bx lr
@@ -66,17 +66,17 @@ define i32 @icmp64_sge_0(i64 %x, i64 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV7A-NEXT:    lsls r2, r2, #31
 ; CHECKV7A-NEXT:    beq .LBB0_2
 ; CHECKV7A-NEXT:  @ %bb.1: @ %then
-; CHECKV7A-NEXT:    cmp.w r3, #-1
+; CHECKV7A-NEXT:    adds r2, r3, #1
 ; CHECKV7A-NEXT:    mov r2, r0
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r2, r12
-; CHECKV7A-NEXT:    cmp.w r1, #-1
+; CHECKV7A-NEXT:    adds r1, #1
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r0, r12
 ; CHECKV7A-NEXT:    add r0, r2
 ; CHECKV7A-NEXT:    bx lr
 ; CHECKV7A-NEXT:  .LBB0_2: @ %else
-; CHECKV7A-NEXT:    cmp.w r1, #-1
+; CHECKV7A-NEXT:    adds r1, #1
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r0, r12
 ; CHECKV7A-NEXT:    bx lr
@@ -103,26 +103,26 @@ define i32 @icmp64_sgt_m1(i64 %x, i64 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV6M-NEXT:    ldr r0, [sp]
 ; CHECKV6M-NEXT:    beq .LBB1_4
 ; CHECKV6M-NEXT:  @ %bb.1: @ %then
-; CHECKV6M-NEXT:    cmp r3, #0
+; CHECKV6M-NEXT:    adds r3, r3, #1
 ; CHECKV6M-NEXT:    mov r3, r0
-; CHECKV6M-NEXT:    blt .LBB1_7
+; CHECKV6M-NEXT:    ble .LBB1_7
 ; CHECKV6M-NEXT:  @ %bb.2: @ %then
-; CHECKV6M-NEXT:    cmp r1, #0
-; CHECKV6M-NEXT:    blt .LBB1_8
+; CHECKV6M-NEXT:    adds r1, r1, #1
+; CHECKV6M-NEXT:    ble .LBB1_8
 ; CHECKV6M-NEXT:  .LBB1_3: @ %then
 ; CHECKV6M-NEXT:    adds r0, r0, r3
 ; CHECKV6M-NEXT:    bx lr
 ; CHECKV6M-NEXT:  .LBB1_4: @ %else
-; CHECKV6M-NEXT:    cmp r3, #0
-; CHECKV6M-NEXT:    bge .LBB1_6
+; CHECKV6M-NEXT:    adds r1, r3, #1
+; CHECKV6M-NEXT:    bgt .LBB1_6
 ; CHECKV6M-NEXT:  @ %bb.5: @ %else
 ; CHECKV6M-NEXT:    mov r0, r2
 ; CHECKV6M-NEXT:  .LBB1_6: @ %else
 ; CHECKV6M-NEXT:    bx lr
 ; CHECKV6M-NEXT:  .LBB1_7: @ %then
 ; CHECKV6M-NEXT:    mov r3, r2
-; CHECKV6M-NEXT:    cmp r1, #0
-; CHECKV6M-NEXT:    bge .LBB1_3
+; CHECKV6M-NEXT:    adds r1, r1, #1
+; CHECKV6M-NEXT:    bgt .LBB1_3
 ; CHECKV6M-NEXT:  .LBB1_8: @ %then
 ; CHECKV6M-NEXT:    mov r0, r2
 ; CHECKV6M-NEXT:    adds r0, r0, r3
@@ -135,17 +135,17 @@ define i32 @icmp64_sgt_m1(i64 %x, i64 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV7M-NEXT:    ldrd r2, r0, [sp]
 ; CHECKV7M-NEXT:    beq .LBB1_2
 ; CHECKV7M-NEXT:  @ %bb.1: @ %then
-; CHECKV7M-NEXT:    cmp.w r3, #-1
+; CHECKV7M-NEXT:    adds r3, #1
 ; CHECKV7M-NEXT:    mov r3, r0
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r3, r2
-; CHECKV7M-NEXT:    cmp.w r1, #-1
+; CHECKV7M-NEXT:    adds r1, #1
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r0, r2
 ; CHECKV7M-NEXT:    add r0, r3
 ; CHECKV7M-NEXT:    bx lr
 ; CHECKV7M-NEXT:  .LBB1_2: @ %else
-; CHECKV7M-NEXT:    cmp.w r3, #-1
+; CHECKV7M-NEXT:    adds r1, r3, #1
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r0, r2
 ; CHECKV7M-NEXT:    bx lr
@@ -157,17 +157,17 @@ define i32 @icmp64_sgt_m1(i64 %x, i64 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV7A-NEXT:    lsls r2, r2, #31
 ; CHECKV7A-NEXT:    beq .LBB1_2
 ; CHECKV7A-NEXT:  @ %bb.1: @ %then
-; CHECKV7A-NEXT:    cmp.w r3, #-1
+; CHECKV7A-NEXT:    adds r2, r3, #1
 ; CHECKV7A-NEXT:    mov r2, r0
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r2, r12
-; CHECKV7A-NEXT:    cmp.w r1, #-1
+; CHECKV7A-NEXT:    adds r1, #1
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r0, r12
 ; CHECKV7A-NEXT:    add r0, r2
 ; CHECKV7A-NEXT:    bx lr
 ; CHECKV7A-NEXT:  .LBB1_2: @ %else
-; CHECKV7A-NEXT:    cmp.w r3, #-1
+; CHECKV7A-NEXT:    adds r1, r3, #1
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r0, r12
 ; CHECKV7A-NEXT:    bx lr
@@ -194,18 +194,18 @@ define i32 @icmp32_sge_0(i32 %x, i32 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV6M-NEXT:    lsls r4, r4, #31
 ; CHECKV6M-NEXT:    beq .LBB2_4
 ; CHECKV6M-NEXT:  @ %bb.1: @ %then
-; CHECKV6M-NEXT:    cmp r1, #0
+; CHECKV6M-NEXT:    adds r1, r1, #1
 ; CHECKV6M-NEXT:    mov r1, r2
-; CHECKV6M-NEXT:    blt .LBB2_7
+; CHECKV6M-NEXT:    ble .LBB2_7
 ; CHECKV6M-NEXT:  @ %bb.2: @ %then
-; CHECKV6M-NEXT:    cmp r0, #0
-; CHECKV6M-NEXT:    blt .LBB2_8
+; CHECKV6M-NEXT:    adds r0, r0, #1
+; CHECKV6M-NEXT:    ble .LBB2_8
 ; CHECKV6M-NEXT:  .LBB2_3: @ %then
 ; CHECKV6M-NEXT:    adds r0, r2, r1
 ; CHECKV6M-NEXT:    pop {r4, pc}
 ; CHECKV6M-NEXT:  .LBB2_4: @ %else
-; CHECKV6M-NEXT:    cmp r0, #0
-; CHECKV6M-NEXT:    bge .LBB2_6
+; CHECKV6M-NEXT:    adds r0, r0, #1
+; CHECKV6M-NEXT:    bgt .LBB2_6
 ; CHECKV6M-NEXT:  @ %bb.5: @ %else
 ; CHECKV6M-NEXT:    mov r2, r3
 ; CHECKV6M-NEXT:  .LBB2_6: @ %else
@@ -213,8 +213,8 @@ define i32 @icmp32_sge_0(i32 %x, i32 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV6M-NEXT:    pop {r4, pc}
 ; CHECKV6M-NEXT:  .LBB2_7: @ %then
 ; CHECKV6M-NEXT:    mov r1, r3
-; CHECKV6M-NEXT:    cmp r0, #0
-; CHECKV6M-NEXT:    bge .LBB2_3
+; CHECKV6M-NEXT:    adds r0, r0, #1
+; CHECKV6M-NEXT:    bgt .LBB2_3
 ; CHECKV6M-NEXT:  .LBB2_8: @ %then
 ; CHECKV6M-NEXT:    mov r2, r3
 ; CHECKV6M-NEXT:    adds r0, r2, r1
@@ -227,17 +227,17 @@ define i32 @icmp32_sge_0(i32 %x, i32 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV7M-NEXT:    lsls r3, r3, #31
 ; CHECKV7M-NEXT:    beq .LBB2_2
 ; CHECKV7M-NEXT:  @ %bb.1: @ %then
-; CHECKV7M-NEXT:    cmp.w r1, #-1
+; CHECKV7M-NEXT:    adds r1, #1
 ; CHECKV7M-NEXT:    mov r1, r12
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r1, r2
-; CHECKV7M-NEXT:    cmp.w r0, #-1
+; CHECKV7M-NEXT:    adds r0, #1
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r12, r2
 ; CHECKV7M-NEXT:    add.w r0, r12, r1
 ; CHECKV7M-NEXT:    bx lr
 ; CHECKV7M-NEXT:  .LBB2_2: @ %else
-; CHECKV7M-NEXT:    cmp.w r0, #-1
+; CHECKV7M-NEXT:    adds r0, #1
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r12, r2
 ; CHECKV7M-NEXT:    mov r0, r12
@@ -250,17 +250,17 @@ define i32 @icmp32_sge_0(i32 %x, i32 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV7A-NEXT:    lsls r3, r3, #31
 ; CHECKV7A-NEXT:    beq .LBB2_2
 ; CHECKV7A-NEXT:  @ %bb.1: @ %then
-; CHECKV7A-NEXT:    cmp.w r1, #-1
+; CHECKV7A-NEXT:    adds r1, #1
 ; CHECKV7A-NEXT:    mov r1, r12
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r1, r2
-; CHECKV7A-NEXT:    cmp.w r0, #-1
+; CHECKV7A-NEXT:    adds r0, #1
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r12, r2
 ; CHECKV7A-NEXT:    add.w r0, r12, r1
 ; CHECKV7A-NEXT:    bx lr
 ; CHECKV7A-NEXT:  .LBB2_2: @ %else
-; CHECKV7A-NEXT:    cmp.w r0, #-1
+; CHECKV7A-NEXT:    adds r0, #1
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r12, r2
 ; CHECKV7A-NEXT:    mov r0, r12
@@ -288,18 +288,18 @@ define i32 @icmp32_sgt_m1(i32 %x, i32 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV6M-NEXT:    lsls r4, r4, #31
 ; CHECKV6M-NEXT:    beq .LBB3_4
 ; CHECKV6M-NEXT:  @ %bb.1: @ %then
-; CHECKV6M-NEXT:    cmp r1, #0
+; CHECKV6M-NEXT:    adds r1, r1, #1
 ; CHECKV6M-NEXT:    mov r1, r2
-; CHECKV6M-NEXT:    blt .LBB3_7
+; CHECKV6M-NEXT:    ble .LBB3_7
 ; CHECKV6M-NEXT:  @ %bb.2: @ %then
-; CHECKV6M-NEXT:    cmp r0, #0
-; CHECKV6M-NEXT:    blt .LBB3_8
+; CHECKV6M-NEXT:    adds r0, r0, #1
+; CHECKV6M-NEXT:    ble .LBB3_8
 ; CHECKV6M-NEXT:  .LBB3_3: @ %then
 ; CHECKV6M-NEXT:    adds r0, r2, r1
 ; CHECKV6M-NEXT:    pop {r4, pc}
 ; CHECKV6M-NEXT:  .LBB3_4: @ %else
-; CHECKV6M-NEXT:    cmp r1, #0
-; CHECKV6M-NEXT:    bge .LBB3_6
+; CHECKV6M-NEXT:    adds r0, r1, #1
+; CHECKV6M-NEXT:    bgt .LBB3_6
 ; CHECKV6M-NEXT:  @ %bb.5: @ %else
 ; CHECKV6M-NEXT:    mov r2, r3
 ; CHECKV6M-NEXT:  .LBB3_6: @ %else
@@ -307,8 +307,8 @@ define i32 @icmp32_sgt_m1(i32 %x, i32 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV6M-NEXT:    pop {r4, pc}
 ; CHECKV6M-NEXT:  .LBB3_7: @ %then
 ; CHECKV6M-NEXT:    mov r1, r3
-; CHECKV6M-NEXT:    cmp r0, #0
-; CHECKV6M-NEXT:    bge .LBB3_3
+; CHECKV6M-NEXT:    adds r0, r0, #1
+; CHECKV6M-NEXT:    bgt .LBB3_3
 ; CHECKV6M-NEXT:  .LBB3_8: @ %then
 ; CHECKV6M-NEXT:    mov r2, r3
 ; CHECKV6M-NEXT:    adds r0, r2, r1
@@ -321,17 +321,17 @@ define i32 @icmp32_sgt_m1(i32 %x, i32 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV7M-NEXT:    lsls r3, r3, #31
 ; CHECKV7M-NEXT:    beq .LBB3_2
 ; CHECKV7M-NEXT:  @ %bb.1: @ %then
-; CHECKV7M-NEXT:    cmp.w r1, #-1
+; CHECKV7M-NEXT:    adds r1, #1
 ; CHECKV7M-NEXT:    mov r1, r12
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r1, r2
-; CHECKV7M-NEXT:    cmp.w r0, #-1
+; CHECKV7M-NEXT:    adds r0, #1
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r12, r2
 ; CHECKV7M-NEXT:    add.w r0, r12, r1
 ; CHECKV7M-NEXT:    bx lr
 ; CHECKV7M-NEXT:  .LBB3_2: @ %else
-; CHECKV7M-NEXT:    cmp.w r1, #-1
+; CHECKV7M-NEXT:    adds r0, r1, #1
 ; CHECKV7M-NEXT:    it gt
 ; CHECKV7M-NEXT:    movgt r12, r2
 ; CHECKV7M-NEXT:    mov r0, r12
@@ -344,17 +344,17 @@ define i32 @icmp32_sgt_m1(i32 %x, i32 %y, i32 %a, i32 %b, i1 %c) {
 ; CHECKV7A-NEXT:    lsls r3, r3, #31
 ; CHECKV7A-NEXT:    beq .LBB3_2
 ; CHECKV7A-NEXT:  @ %bb.1: @ %then
-; CHECKV7A-NEXT:    cmp.w r1, #-1
+; CHECKV7A-NEXT:    adds r1, #1
 ; CHECKV7A-NEXT:    mov r1, r12
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r1, r2
-; CHECKV7A-NEXT:    cmp.w r0, #-1
+; CHECKV7A-NEXT:    adds r0, #1
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r12, r2
 ; CHECKV7A-NEXT:    add.w r0, r12, r1
 ; CHECKV7A-NEXT:    bx lr
 ; CHECKV7A-NEXT:  .LBB3_2: @ %else
-; CHECKV7A-NEXT:    cmp.w r1, #-1
+; CHECKV7A-NEXT:    adds r0, r1, #1
 ; CHECKV7A-NEXT:    it gt
 ; CHECKV7A-NEXT:    movgt r12, r2
 ; CHECKV7A-NEXT:    mov r0, r12
diff --git a/llvm/test/CodeGen/ARM/sadd_sat.ll b/llvm/test/CodeGen/ARM/sadd_sat.ll
index f0366fe459abb..eba09c4e5d1cd 100644
--- a/llvm/test/CodeGen/ARM/sadd_sat.ll
+++ b/llvm/test/CodeGen/ARM/sadd_sat.ll
@@ -144,28 +144,28 @@ define i64 @func2(i64 %x, i64 %y) nounwind {
 }
 
 define signext i16 @func16(i16 signext %x, i16 signext %y) nounwind {
-; CHECK-T1-LABEL: func16:
-; CHECK-T1:       @ %bb.0:
-; CHECK-T1-NEXT:    adds r0, r0, r1
-; CHECK-T1-NEXT:    ldr r1, .LCPI2_0
-; CHECK-T1-NEXT:    cmp r0, r1
-; CHECK-T1-NEXT:    blt .LBB2_2
-; CHECK-T1-NEXT:  @ %bb.1:
-; CHECK-T1-NEXT:    {{movs|mov}} r0, r1
-; CHECK-T1-NEXT:  .LBB2_2:
-; CHECK-T1-NEXT:    ldr r1, .LCPI2_1
-; CHECK-T1-NEXT:    cmp r0, r1
-; CHECK-T1-NEXT:    bgt .LBB2_4
-; CHECK-T1-NEXT:  @ %bb.3:
-; CHECK-T1-NEXT:    {{movs|mov}} r0, r1
-; CHECK-T1-NEXT:  .LBB2_4:
-; CHECK-T1-NEXT:    bx lr
-; CHECK-T1-NEXT:    .p2align 2
-; CHECK-T1-NEXT:  @ %bb.5:
-; CHECK-T1-NEXT:  .LCPI2_0:
-; CHECK-T1-NEXT:    .long 32767 @ 0x7fff
-; CHECK-T1-NEXT:  .LCPI2_1:
-; CHECK-T1-NEXT:    .long 4294934528 @ 0xffff8000
+; CHECK-T16-LABEL: func16:
+; CHECK-T16:       @ %bb.0:
+; CHECK-T16-NEXT:    adds r0, r0, r1
+; CHECK-T16-NEXT:    ldr r1, .LCPI2_0
+; CHECK-T16-NEXT:    cmp r0, r1
+; CHECK-T16-NEXT:    blt .LBB2_2
+; CHECK-T16-NEXT:  @ %bb.1:
+; CHECK-T16-NEXT:    mov r0, r1
+; CHECK-T16-NEXT:  .LBB2_2:
+; CHECK-T16-NEXT:    ldr r1, .LCPI2_1
+; CHECK-T16-NEXT:    cmp r0, r1
+; CHECK-T16-NEXT:    bgt .LBB2_4
+; CHECK-T16-NEXT:  @ %bb.3:
+; CHECK-T16-NEXT:    mov r0, r1
+; CHECK-T16-NEXT:  .LBB2_4:
+; CHECK-T16-NEXT:    bx lr
+; CHECK-T16-NEXT:    .p2align 2
+; CHECK-T16-NEXT:  @ %bb.5:
+; CHECK-T16-NEXT:  .LCPI2_0:
+; CHECK-T16-NEXT:    .long 32767 @ 0x7fff
+; CHECK-T16-NEXT:  .LCPI2_1:
+; CHECK-T16-NEXT:    .long 4294934528 @ 0xffff8000
 ;
 ; CHECK-T2NODSP-LABEL: func16:
 ; CHECK-T2NODSP:       @ %bb.0:
@@ -203,6 +203,29 @@ define signext i16 @func16(i16 signext %x, i16 signext %y) nounwind {
 ; CHECK-ARMBASEDSP-NEXT:    asr r0, r0, #16
 ; CHECK-ARMBASEDSP-NEXT:    bx lr
 ;
+; CHECK-T15TE-LABEL: func16:
+; CHECK-T15TE:       @ %bb.0:
+; CHECK-T15TE-NEXT:    adds r0, r0, r1
+; CHECK-T15TE-NEXT:    ldr r1, .LCPI2_0
+; CHECK-T15TE-NEXT:    cmp r0, r1
+; CHECK-T15TE-NEXT:    blt .LBB2_2
+; CHECK-T15TE-NEXT:  @ %bb.1:
+; CHECK-T15TE-NEXT:    movs r0, r1
+; CHECK-T15TE-NEXT:  .LBB2_2:
+; CHECK-T15TE-NEXT:    ldr r1, .LCPI2_1
+; CHECK-T15TE-NEXT:    cmp r0, r1
+; CHECK-T15TE-NEXT:    bgt .LBB2_4
+; CHECK-T15TE-NEXT:  @ %bb.3:
+; CHECK-T15TE-NEXT:    movs r0, r1
+; CHECK-T15TE-NEXT:  .LBB2_4:
+; CHECK-T15TE-NEXT:    bx lr
+; CHECK-T15TE-NEXT:    .p2align 2
+; CHECK-T15TE-NEXT:  @ %bb.5:
+; CHECK-T15TE-NEXT:  .LCPI2_0:
+; CHECK-T15TE-NEXT:    .long 32767 @ 0x7fff
+; CHECK-T15TE-NEXT:  .LCPI2_1:
+; CHECK-T15TE-NEXT:    .long 4294934528 @ 0xffff8000
+;
 ; CHECK-ARMDSP-LABEL: func16:
 ; CHECK-ARMDSP:       @ %bb.0:
 ; CHECK-ARMDSP-NEXT:    qadd16 r0, r0, r1
@@ -213,22 +236,22 @@ define signext i16 @func16(i16 signext %x, i16 signext %y) nounwind {
 }
 
 define signext i8 @func8(i8 signext %x, i8 signext %y) nounwind {
-; CHECK-T1-LABEL: func8:
-; CHECK-T1:       @ %bb.0:
-; CHECK-T1-NEXT:    adds r0, r0, r1
-; CHECK-T1-NEXT:    movs r1, #127
-; CHECK-T1-NEXT:    cmp r0, #127
-; CHECK-T1-NEXT:    blt .LBB3_2
-; CHECK-T1-NEXT:  @ %bb.1:
-; CHECK-T1-NEXT:    {{movs|mov}} r0, r1
-; CHECK-T1-NEXT:  .LBB3_2:
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    cmp r0, r1
-; CHECK-T1-NEXT:    bgt .LBB3_4
-; CHECK-T1-NEXT:  @ %bb.3:
-; CHECK-T1-NEXT:    {{movs|mov}} r0, r1
-; CHECK-T1-NEXT:  .LBB3_4:
-; CHECK-T1-NEXT:    bx lr
+; CHECK-T16-LABEL: func8:
+; CHECK-T16:       @ %bb.0:
+; CHECK-T16-NEXT:    adds r0, r0, r1
+; CHECK-T16-NEXT:    movs r1, #127
+; CHECK-T16-NEXT:    cmp r0, #127
+; CHECK-T16-NEXT:    blt .LBB3_2
+; CHECK-T16-NEXT:  @ %bb.1:
+; CHECK-T16-NEXT:    mov r0, r1
+; CHECK-T16-NEXT:  .LBB3_2:
+; CHECK-T16-NEXT:    mov r2, r0
+; CHECK-T16-NEXT:    adds r2, #128
+; CHECK-T16-NEXT:    bgt .LBB3_4
+; CHECK-T16-NEXT:  @ %bb.3:
+; CHECK-T16-NEXT:    mvns r0, r1
+; CHECK-T16-NEXT:  .LBB3_4:
+; CHECK-T16-NEXT:    bx lr
 ;
 ; CHECK-T2NODSP-LABEL: func8:
 ; CHECK-T2NODSP:       @ %bb.0:
@@ -259,6 +282,23 @@ define signext i8 @func8(i8 signext %x, i8 signext %y) nounwind {
 ; CHECK-ARMBASEDSP-NEXT:    asr r0, r0, #24
 ; CHECK-ARMBASEDSP-NEXT:    bx lr
 ;
+; CHECK-T15TE-LABEL: func8:
+; CHECK-T15TE:       @ %bb.0:
+; CHECK-T15TE-NEXT:    adds r0, r0, r1
+; CHECK-T15TE-NEXT:    movs r1, #127
+; CHECK-T15TE-NEXT:    cmp r0, #127
+; CHECK-T15TE-NEXT:    blt .LBB3_2
+; CHECK-T15TE-NEXT:  @ %bb.1:
+; CHECK-T15TE-NEXT:    movs r0, r1
+; CHECK-T15TE-NEXT:  .LBB3_2:
+; CHECK-T15TE-NEXT:    movs r2, r0
+; CHECK-T15TE-NEXT:    adds r2, #128
+; CHECK-T15TE-NEXT:    bgt .LBB3_4
+; CHECK-T15TE-NEXT:  @ %bb.3:
+; CHECK-T15TE-NEXT:    mvns r0, r1
+; CHECK-T15TE-NEXT:  .LBB3_4:
+; CHECK-T15TE-NEXT:    bx lr
+;
 ; CHECK-ARMDSP-LABEL: func8:
 ; CHECK-ARMDSP:       @ %bb.0:
 ; CHECK-ARMDSP-NEXT:    qadd8 r0, r0, r1
@@ -269,22 +309,22 @@ define signext i8 @func8(i8 signext %x, i8 signext %y) nounwind {
 }
 
 define signext i4 @func3(i4 signext %x, i4 signext %y) nounwind {
-; CHECK-T1-LABEL: func3:
-; CHECK-T1:       @ %bb.0:
-; CHECK-T1-NEXT:    adds r0, r0, r1
-; CHECK-T1-NEXT:    movs r1, #7
-; CHECK-T1-NEXT:    cmp r0, #7
-; CHECK-T1-NEXT:    blt .LBB4_2
-; CHECK-T1-NEXT:  @ %bb.1:
-; CHECK-T1-NEXT:    {{movs|mov}} r0, r1
-; CHECK-T1-NEXT:  .LBB4_2:
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    cmp r0, r1
-; CHECK-T1-NEXT:    bgt .LBB4_4
-; CHECK-T1-NEXT:  @ %bb.3:
-; CHECK-T1-NEXT:    {{movs|mov}} r0, r1
-; CHECK-T1-NEXT:  .LBB4_4:
-; CHECK-T1-NEXT:    bx lr
+; CHECK-T16-LABEL: func3:
+; CHECK-T16:       @ %bb.0:
+; CHECK-T16-NEXT:    adds r0, r0, r1
+; CHECK-T16-NEXT:    movs r1, #7
+; CHECK-T16-NEXT:    cmp r0, #7
+; CHECK-T16-NEXT:    blt .LBB4_2
+; CHECK-T16-NEXT:  @ %bb.1:
+; CHECK-T16-NEXT:    mov r0, r1
+; CHECK-T16-NEXT:  .LBB4_2:
+; CHECK-T16-NEXT:    mov r2, r0
+; CHECK-T16-NEXT:    adds r2, #8
+; CHECK-T16-NEXT:    bgt .LBB4_4
+; CHECK-T16-NEXT:  @ %bb.3:
+; CHECK-T16-NEXT:    mvns r0, r1
+; CHECK-T16-NEXT:  .LBB4_4:
+; CHECK-T16-NEXT:    bx lr
 ;
 ; CHECK-T2NODSP-LABEL: func3:
 ; CHECK-T2NODSP:       @ %bb.0:
@@ -317,6 +357,23 @@ define signext i4 @func3(i4 signext %x, i4 signext %y) nounwind {
 ; CHECK-ARMBASEDSP-NEXT:    asr r0, r0, #28
 ; CHECK-ARMBASEDSP-NEXT:    bx lr
 ;
+; CHECK-T15TE-LABEL: func3:
+; CHECK-T15TE:       @ %bb.0:
+; CHECK-T15TE-NEXT:    adds r0, r0, r1
+; CHECK-T15TE-NEXT:    movs r1, #7
+; CHECK-T15TE-NEXT:    cmp r0, #7
+; CHECK-T15TE-NEXT:    blt .LBB4_2
+; CHECK-T15TE-NEXT:  @ %bb.1:
+; CHECK-T15TE-NEXT:    movs r0, r1
+; CHECK-T15TE-NEXT:  .LBB4_2:
+; CHECK-T15TE-NEXT:    movs r2, r0
+; CHECK-T15TE-NEXT:    adds r2, #8
+; CHECK-T15TE-NEXT:    bgt .LBB4_4
+; CHECK-T15TE-NEXT:  @ %bb.3:
+; CHECK-T15TE-NEXT:    mvns r0, r1
+; CHECK-T15TE-NEXT:  .LBB4_4:
+; CHECK-T15TE-NEXT:    bx lr
+;
 ; CHECK-ARMDSP-LABEL: func3:
 ; CHECK-ARMDSP:       @ %bb.0:
 ; CHECK-ARMDSP-NEXT:    lsl r0, r0, #28
diff --git a/llvm/test/CodeGen/ARM/sat-to-bitop.ll b/llvm/test/CodeGen/ARM/sat-to-bitop.ll
index dcd396749ce57..e9cb26cfb560a 100644
--- a/llvm/test/CodeGen/ARM/sat-to-bitop.ll
+++ b/llvm/test/CodeGen/ARM/sat-to-bitop.ll
@@ -165,22 +165,20 @@ define i16 @sat1_base_16bit(i16 %x) #0 {
 ;
 ; CHECK-T-LABEL: sat1_base_16bit:
 ; CHECK-T:       @ %bb.0: @ %entry
-; CHECK-T-NEXT:    movs r1, #0
-; CHECK-T-NEXT:    mvns r1, r1
-; CHECK-T-NEXT:    lsls r2, r0, #16
-; CHECK-T-NEXT:    asrs r2, r2, #16
-; CHECK-T-NEXT:    cmp r2, r1
-; CHECK-T-NEXT:    blt .LBB5_2
-; CHECK-T-NEXT:  @ %bb.1: @ %entry
-; CHECK-T-NEXT:    movs r1, r0
+; CHECK-T-NEXT:    lsls r1, r0, #16
+; CHECK-T-NEXT:    asrs r1, r1, #16
+; CHECK-T-NEXT:    adds r1, r1, #1
+; CHECK-T-NEXT:    bge .LBB5_2
+; CHECK-T-NEXT:  @ %bb.1:
+; CHECK-T-NEXT:    movs r0, #0
+; CHECK-T-NEXT:    mvns r0, r0
 ; CHECK-T-NEXT:  .LBB5_2: @ %entry
-; CHECK-T-NEXT:    movs r0, r1
 ; CHECK-T-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: sat1_base_16bit:
 ; CHECK-T2:       @ %bb.0: @ %entry
 ; CHECK-T2-NEXT:    sxth r1, r0
-; CHECK-T2-NEXT:    cmp.w r1, #-1
+; CHECK-T2-NEXT:    adds r1, #1
 ; CHECK-T2-NEXT:    it lt
 ; CHECK-T2-NEXT:    movlt.w r0, #-1
 ; CHECK-T2-NEXT:    bx lr
@@ -203,22 +201,20 @@ define i8 @sat1_base_8bit(i8 %x) #0 {
 ;
 ; CHECK-T-LABEL: sat1_base_8bit:
 ; CHECK-T:       @ %bb.0: @ %entry
-; CHECK-T-NEXT:    movs r1, #0
-; CHECK-T-NEXT:    mvns r1, r1
-; CHECK-T-NEXT:    lsls r2, r0, #24
-; CHECK-T-NEXT:    asrs r2, r2, #24
-; CHECK-T-NEXT:    cmp r2, r1
-; CHECK-T-NEXT:    blt .LBB6_2
-; CHECK-T-NEXT:  @ %bb.1: @ %entry
-; CHECK-T-NEXT:    movs r1, r0
+; CHECK-T-NEXT:    lsls r1, r0, #24
+; CHECK-T-NEXT:    asrs r1, r1, #24
+; CHECK-T-NEXT:    adds r1, r1, #1
+; CHECK-T-NEXT:    bge .LBB6_2
+; CHECK-T-NEXT:  @ %bb.1:
+; CHECK-T-NEXT:    movs r0, #0
+; CHECK-T-NEXT:    mvns r0, r0
 ; CHECK-T-NEXT:  .LBB6_2: @ %entry
-; CHECK-T-NEXT:    movs r0, r1
 ; CHECK-T-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: sat1_base_8bit:
 ; CHECK-T2:       @ %bb.0: @ %entry
 ; CHECK-T2-NEXT:    sxtb r1, r0
-; CHECK-T2-NEXT:    cmp.w r1, #-1
+; CHECK-T2-NEXT:    adds r1, #1
 ; CHECK-T2-NEXT:    it lt
 ; CHECK-T2-NEXT:    movlt.w r0, #-1
 ; CHECK-T2-NEXT:    bx lr
diff --git a/llvm/test/CodeGen/ARM/select-constant-xor.ll b/llvm/test/CodeGen/ARM/select-constant-xor.ll
index 543ddcd3efac9..a1071f3ebf7fd 100644
--- a/llvm/test/CodeGen/ARM/select-constant-xor.ll
+++ b/llvm/test/CodeGen/ARM/select-constant-xor.ll
@@ -86,8 +86,8 @@ define i32 @selecti64i32(i64 %a) {
 ; CHECK6M-LABEL: selecti64i32:
 ; CHECK6M:       @ %bb.0:
 ; CHECK6M-NEXT:    ldr r0, .LCPI2_0
-; CHECK6M-NEXT:    cmp r1, #0
-; CHECK6M-NEXT:    bge .LBB2_2
+; CHECK6M-NEXT:    adds r1, r1, #1
+; CHECK6M-NEXT:    bgt .LBB2_2
 ; CHECK6M-NEXT:  @ %bb.1:
 ; CHECK6M-NEXT:    adds r0, r0, #1
 ; CHECK6M-NEXT:  .LBB2_2:
@@ -327,8 +327,8 @@ define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ;
 ; CHECK6M-LABEL: icmpasrne:
 ; CHECK6M:       @ %bb.0:
-; CHECK6M-NEXT:    cmp r0, #0
-; CHECK6M-NEXT:    bge .LBB9_2
+; CHECK6M-NEXT:    adds r0, r0, #1
+; CHECK6M-NEXT:    bgt .LBB9_2
 ; CHECK6M-NEXT:  @ %bb.1:
 ; CHECK6M-NEXT:    mov r1, r2
 ; CHECK6M-NEXT:  .LBB9_2:
@@ -337,7 +337,7 @@ define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ;
 ; CHECK7M-LABEL: icmpasrne:
 ; CHECK7M:       @ %bb.0:
-; CHECK7M-NEXT:    cmp.w r0, #-1
+; CHECK7M-NEXT:    adds r0, #1
 ; CHECK7M-NEXT:    it le
 ; CHECK7M-NEXT:    movle r1, r2
 ; CHECK7M-NEXT:    mov r0, r1
@@ -345,7 +345,7 @@ define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ;
 ; CHECK81M-LABEL: icmpasrne:
 ; CHECK81M:       @ %bb.0:
-; CHECK81M-NEXT:    cmp.w r0, #-1
+; CHECK81M-NEXT:    adds r0, #1
 ; CHECK81M-NEXT:    csel r0, r1, r2, gt
 ; CHECK81M-NEXT:    bx lr
   %sh = ashr i32 %input, 31
diff --git a/llvm/test/CodeGen/ARM/select_xform.ll b/llvm/test/CodeGen/ARM/select_xform.ll
index 382536fc91d6d..d8f4753b5a321 100644
--- a/llvm/test/CodeGen/ARM/select_xform.ll
+++ b/llvm/test/CodeGen/ARM/select_xform.ll
@@ -406,14 +406,14 @@ define i32 @t17(i32 %x, i32 %y) #0 {
 ; T2-LABEL: t17:
 ; T2:       @ %bb.0: @ %entry
 ; T2-NEXT:    adds r0, #1
-; T2-NEXT:    mov.w r0, #2
+; T2-NEXT:    mov.w r2, #2
+; T2-NEXT:    mov.w r0, #4
 ; T2-NEXT:    it eq
-; T2-NEXT:    moveq r0, #5
+; T2-NEXT:    moveq r2, #5
 ; T2-NEXT:    adds r1, #1
-; T2-NEXT:    mov.w r1, #4
 ; T2-NEXT:    it eq
-; T2-NEXT:    moveq r1, #3
-; T2-NEXT:    ands r0, r1
+; T2-NEXT:    moveq r0, #3
+; T2-NEXT:    ands r0, r2
 ; T2-NEXT:    bx lr
 entry:
   %cmp = icmp eq i32 %x, -1
@@ -442,11 +442,11 @@ define i32 @t18(i32 %x, i32 %y) #0 {
 ; T2-NEXT:    cmp r0, #0
 ; T2-NEXT:    it ne
 ; T2-NEXT:    movne r1, #5
+; T2-NEXT:    movs r2, #4
 ; T2-NEXT:    adds r0, #1
-; T2-NEXT:    mov.w r0, #4
 ; T2-NEXT:    it ne
-; T2-NEXT:    movne r0, #3
-; T2-NEXT:    ands r0, r1
+; T2-NEXT:    movne r2, #3
+; T2-NEXT:    and.w r0, r2, r1
 ; T2-NEXT:    bx lr
 entry:
   %cmp = icmp ne i32 %x, 0
@@ -505,14 +505,14 @@ define i32 @t20(i32 %x, i32 %y) #0 {
 ; T2-LABEL: t20:
 ; T2:       @ %bb.0: @ %entry
 ; T2-NEXT:    adds r0, #1
-; T2-NEXT:    mov.w r0, #2
+; T2-NEXT:    mov.w r2, #2
+; T2-NEXT:    mov.w r0, #4
 ; T2-NEXT:    it ne
-; T2-NEXT:    movne r0, #5
+; T2-NEXT:    movne r2, #5
 ; T2-NEXT:    adds r1, #1
-; T2-NEXT:    mov.w r1, #4
 ; T2-NEXT:    it ne
-; T2-NEXT:    movne r1, #3
-; T2-NEXT:    orrs r0, r1
+; T2-NEXT:    movne r0, #3
+; T2-NEXT:    orrs r0, r2
 ; T2-NEXT:    bx lr
 entry:
   %cmp = icmp ne i32 %x, -1
diff --git a/llvm/test/CodeGen/ARM/ssub_sat.ll b/llvm/test/CodeGen/ARM/ssub_sat.ll
index 8cce3a76a50db..232c3067391ea 100644
--- a/llvm/test/CodeGen/ARM/ssub_sat.ll
+++ b/llvm/test/CodeGen/ARM/ssub_sat.ll
@@ -190,11 +190,11 @@ define signext i8 @func8(i8 signext %x, i8 signext %y) nounwind {
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:    mov r0, r1
 ; CHECK-T1-NEXT:  .LBB3_2:
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    cmp r0, r1
+; CHECK-T1-NEXT:    mov r2, r0
+; CHECK-T1-NEXT:    adds r2, #128
 ; CHECK-T1-NEXT:    bgt .LBB3_4
 ; CHECK-T1-NEXT:  @ %bb.3:
-; CHECK-T1-NEXT:    mov r0, r1
+; CHECK-T1-NEXT:    mvns r0, r1
 ; CHECK-T1-NEXT:  .LBB3_4:
 ; CHECK-T1-NEXT:    bx lr
 ;
@@ -246,11 +246,11 @@ define signext i4 @func3(i4 signext %x, i4 signext %y) nounwind {
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:    mov r0, r1
 ; CHECK-T1-NEXT:  .LBB4_2:
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    cmp r0, r1
+; CHECK-T1-NEXT:    mov r2, r0
+; CHECK-T1-NEXT:    adds r2, #8
 ; CHECK-T1-NEXT:    bgt .LBB4_4
 ; CHECK-T1-NEXT:  @ %bb.3:
-; CHECK-T1-NEXT:    mov r0, r1
+; CHECK-T1-NEXT:    mvns r0, r1
 ; CHECK-T1-NEXT:  .LBB4_4:
 ; CHECK-T1-NEXT:    bx lr
 ;
diff --git a/llvm/test/CodeGen/ARM/ssub_sat_plus.ll b/llvm/test/CodeGen/ARM/ssub_sat_plus.ll
index 9690918d1f702..a87d92322e858 100644
--- a/llvm/test/CodeGen/ARM/ssub_sat_plus.ll
+++ b/llvm/test/CodeGen/ARM/ssub_sat_plus.ll
@@ -172,11 +172,11 @@ define signext i8 @func8(i8 signext %x, i8 signext %y, i8 signext %z) nounwind {
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:    mov r0, r1
 ; CHECK-T1-NEXT:  .LBB3_2:
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    cmp r0, r1
+; CHECK-T1-NEXT:    mov r2, r0
+; CHECK-T1-NEXT:    adds r2, #128
 ; CHECK-T1-NEXT:    bgt .LBB3_4
 ; CHECK-T1-NEXT:  @ %bb.3:
-; CHECK-T1-NEXT:    mov r0, r1
+; CHECK-T1-NEXT:    mvns r0, r1
 ; CHECK-T1-NEXT:  .LBB3_4:
 ; CHECK-T1-NEXT:    bx lr
 ;
@@ -219,11 +219,11 @@ define signext i4 @func4(i4 signext %x, i4 signext %y, i4 signext %z) nounwind {
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:    mov r0, r1
 ; CHECK-T1-NEXT:  .LBB4_2:
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    cmp r0, r1
+; CHECK-T1-NEXT:    mov r2, r0
+; CHECK-T1-NEXT:    adds r2, #8
 ; CHECK-T1-NEXT:    bgt .LBB4_4
 ; CHECK-T1-NEXT:  @ %bb.3:
-; CHECK-T1-NEXT:    mov r0, r1
+; CHECK-T1-NEXT:    mvns r0, r1
 ; CHECK-T1-NEXT:  .LBB4_4:
 ; CHECK-T1-NEXT:    bx lr
 ;
diff --git a/llvm/test/CodeGen/ARM/thumb-cmp-neg-imm-adds.ll b/llvm/test/CodeGen/ARM/thumb-cmp-neg-imm-adds.ll
new file mode 100644
index 0000000000000..e981bda5c8ca9
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/thumb-cmp-neg-imm-adds.ll
@@ -0,0 +1,48 @@
+; RUN: llc -mtriple=thumbv6m %s -o - | FileCheck %s --check-prefix=T1
+; RUN: llc -mtriple=thumbv7 %s -o - | FileCheck %s --check-prefix=T2
+
+; Compare against a small negative constant should use 16-bit ADDS, not CMN.
+define i1 @cmp_eq_small_neg(i32 %a) {
+; T1-LABEL: cmp_eq_small_neg:
+; T1:       adds{{[ \t]}}
+; T1-NOT:   {{[ \t]}}cmn{{[ \t]}}
+; T1-NOT:   {{[ \t]}}cmp{{[ \t]}}r
+; T1-NOT:   {{[ \t]}}cmp{{[ \t]}}#
+;
+; T2-LABEL: cmp_eq_small_neg:
+; T2:       adds{{[ \t]}}
+; T2-NOT:   {{[ \t]}}cmn
+; T2-NOT:   {{[ \t]}}cmp{{[ \t]}}r
+; T2-NOT:   {{[ \t]}}cmp{{[ \t]}}#
+entry:
+  %cmp = icmp eq i32 %a, -5
+  ret i1 %cmp
+}
+
+define i1 @cmp_sgt_small_neg(i32 %a) {
+; T1-LABEL: cmp_sgt_small_neg:
+; T1:       adds{{[ \t]}}r0, #42
+; T1-NOT:   {{[ \t]}}cmn{{[ \t]}}
+;
+; T2-LABEL: cmp_sgt_small_neg:
+; T2:       adds{{[ \t]}}r0, #42
+; T2-NOT:   {{[ \t]}}cmn.w
+entry:
+  %cmp = icmp sgt i32 %a, -42
+  ret i1 %cmp
+}
+
+; Large negative immediates still need a full compare, not 32-bit CMN on Thumb1.
+define i1 @cmp_large_neg(i32 %a) {
+; T1-LABEL: cmp_large_neg:
+; T1:       cmp{{[ \t]}}r0,
+; T1-NOT:   {{[ \t]}}cmn{{[ \t]}}
+; T1-NOT:   {{[ \t]}}adds{{[ \t]}}
+;
+; T2-LABEL: cmp_large_neg:
+; T2:       cmn.w{{[ \t]}}r0,
+; T2-NOT:   {{[ \t]}}adds{{[ \t]}}
+entry:
+  %cmp = icmp sgt i32 %a, -50529027
+  ret i1 %cmp
+}
diff --git a/llvm/test/CodeGen/Thumb/cmp-add-fold.ll b/llvm/test/CodeGen/Thumb/cmp-add-fold.ll
index 4dc0bc70440dd..3baa4e7097d13 100644
--- a/llvm/test/CodeGen/Thumb/cmp-add-fold.ll
+++ b/llvm/test/CodeGen/Thumb/cmp-add-fold.ll
@@ -16,10 +16,11 @@ define i32 @addri1(i32 %a, i32 %b) {
 ;
 ; T2-LABEL: addri1:
 ; T2:       @ %bb.0: @ %entry
+; T2-NEXT:    movs r1, #5
 ; T2-NEXT:    adds r0, #3
-; T2-NEXT:    mov.w r0, #5
 ; T2-NEXT:    it eq
-; T2-NEXT:    moveq r0, #4
+; T2-NEXT:    moveq r1, #4
+; T2-NEXT:    mov r0, r1
 ; T2-NEXT:    bx lr
 entry:
   %c = add i32 %a, 3
@@ -47,10 +48,11 @@ define i32 @addri2(i32 %a, i32 %b) {
 ;
 ; T2-LABEL: addri2:
 ; T2:       @ %bb.0: @ %entry
+; T2-NEXT:    movs r1, #5
 ; T2-NEXT:    adds r0, #254
-; T2-NEXT:    mov.w r0, #5
 ; T2-NEXT:    it eq
-; T2-NEXT:    moveq r0, #4
+; T2-NEXT:    moveq r1, #4
+; T2-NEXT:    mov r0, r1
 ; T2-NEXT:    bx lr
 entry:
   %c = add i32 %a, 254
diff --git a/llvm/test/CodeGen/Thumb/long.ll b/llvm/test/CodeGen/Thumb/long.ll
index e2559d407e000..b28943c7cb3c1 100644
--- a/llvm/test/CodeGen/Thumb/long.ll
+++ b/llvm/test/CodeGen/Thumb/long.ll
@@ -187,14 +187,13 @@ entry:
         %tmp2 = add i64 %tmp1, -1000
         ret i64 %tmp2
 ; CHECK-LABEL: f11:
-; CHECK: movs r1, r3
-; CHECK: movs r0, #125
-; CHECK: lsls r0, r0, #3
-; CHECK: movs r3, #0
-; CHECK: subs r2, r2, r0
-; CHECK: sbcs r1, r3
-; CHECK: subs r0, r2, r0
-; CHECK: sbcs r1, r3
+; CHECK:         movs r1, r3
+; CHECK-NEXT:    movs r3, #0
+; CHECK-NEXT:    ldr r0,
+; CHECK-NEXT:    adds r2, r2, r0
+; CHECK-NEXT:    sbcs r1, r3
+; CHECK-NEXT:    adds r0, r2, r0
+; CHECK-NEXT:    sbcs r1, r3
 }
 
 ; "sub 2147483648" has to be lowered into "add -2147483648"
diff --git a/llvm/test/CodeGen/Thumb/smul_fix_sat.ll b/llvm/test/CodeGen/Thumb/smul_fix_sat.ll
index 52921f0f347b9..a6bab001a2145 100644
--- a/llvm/test/CodeGen/Thumb/smul_fix_sat.ll
+++ b/llvm/test/CodeGen/Thumb/smul_fix_sat.ll
@@ -20,20 +20,20 @@ define i32 @func(i32 %x, i32 %y) nounwind {
 ; ARM-NEXT:    lsrs r0, r0, #2
 ; ARM-NEXT:    lsls r2, r1, #30
 ; ARM-NEXT:    adds r0, r2, r0
-; ARM-NEXT:    b .LBB0_3
+; ARM-NEXT:    adds r1, r1, #2
+; ARM-NEXT:    blt .LBB0_3
+; ARM-NEXT:    b .LBB0_4
 ; ARM-NEXT:  .LBB0_2:
 ; ARM-NEXT:    ldr r0, .LCPI0_0
+; ARM-NEXT:    adds r1, r1, #2
+; ARM-NEXT:    bge .LBB0_4
 ; ARM-NEXT:  .LBB0_3:
-; ARM-NEXT:    movs r2, #1
-; ARM-NEXT:    mvns r3, r2
-; ARM-NEXT:    cmp r1, r3
-; ARM-NEXT:    bge .LBB0_5
-; ARM-NEXT:  @ %bb.4:
-; ARM-NEXT:    lsls r0, r2, #31
-; ARM-NEXT:  .LBB0_5:
+; ARM-NEXT:    movs r0, #1
+; ARM-NEXT:    lsls r0, r0, #31
+; ARM-NEXT:  .LBB0_4:
 ; ARM-NEXT:    pop {r7, pc}
 ; ARM-NEXT:    .p2align 2
-; ARM-NEXT:  @ %bb.6:
+; ARM-NEXT:  @ %bb.5:
 ; ARM-NEXT:  .LCPI0_0:
 ; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
   %tmp = call i32 @llvm.smul.fix.sat.i32(i32 %x, i32 %y, i32 2)
@@ -105,51 +105,47 @@ define i64 @func2(i64 %x, i64 %y) nounwind {
 ; ARM-NEXT:  .LBB1_2:
 ; ARM-NEXT:    ands r2, r5
 ; ARM-NEXT:    cmp r1, #0
-; ARM-NEXT:    mov r5, r0
+; ARM-NEXT:    mov r7, r0
 ; ARM-NEXT:    bgt .LBB1_4
 ; ARM-NEXT:  @ %bb.3:
-; ARM-NEXT:    mov r5, r4
+; ARM-NEXT:    mov r7, r4
 ; ARM-NEXT:  .LBB1_4:
-; ARM-NEXT:    orrs r5, r2
+; ARM-NEXT:    orrs r7, r2
 ; ARM-NEXT:    lsls r2, r3, #30
-; ARM-NEXT:    ldr r7, [sp, #16] @ 4-byte Reload
-; ARM-NEXT:    lsrs r6, r7, #2
-; ARM-NEXT:    adds r2, r2, r6
-; ARM-NEXT:    str r2, [sp, #24] @ 4-byte Spill
-; ARM-NEXT:    lsls r6, r7, #30
-; ARM-NEXT:    ldr r2, [sp, #20] @ 4-byte Reload
-; ARM-NEXT:    lsrs r7, r2, #2
-; ARM-NEXT:    adds r7, r6, r7
-; ARM-NEXT:    mvns r6, r4
-; ARM-NEXT:    cmp r5, #0
+; ARM-NEXT:    ldr r6, [sp, #16] @ 4-byte Reload
+; ARM-NEXT:    lsrs r5, r6, #2
+; ARM-NEXT:    adds r2, r2, r5
+; ARM-NEXT:    lsls r5, r6, #30
+; ARM-NEXT:    ldr r6, [sp, #20] @ 4-byte Reload
+; ARM-NEXT:    lsrs r6, r6, #2
+; ARM-NEXT:    adds r6, r5, r6
+; ARM-NEXT:    mvns r5, r4
+; ARM-NEXT:    cmp r7, #0
 ; ARM-NEXT:    beq .LBB1_6
 ; ARM-NEXT:  @ %bb.5:
 ; ARM-NEXT:    ldr r2, .LCPI1_0
-; ARM-NEXT:    str r2, [sp, #24] @ 4-byte Spill
 ; ARM-NEXT:  .LBB1_6:
-; ARM-NEXT:    mov r5, r6
 ; ARM-NEXT:    bne .LBB1_8
 ; ARM-NEXT:  @ %bb.7:
-; ARM-NEXT:    mov r5, r7
+; ARM-NEXT:    mov r5, r6
 ; ARM-NEXT:  .LBB1_8:
-; ARM-NEXT:    adds r2, r1, #1
-; ARM-NEXT:    rsbs r7, r2, #0
-; ARM-NEXT:    adcs r7, r2
-; ARM-NEXT:    mvns r2, r0
-; ARM-NEXT:    cmp r3, r2
+; ARM-NEXT:    adds r7, r1, #1
+; ARM-NEXT:    rsbs r6, r7, #0
+; ARM-NEXT:    adcs r6, r7
+; ARM-NEXT:    adds r3, r3, #2
 ; ARM-NEXT:    mov r3, r0
 ; ARM-NEXT:    blo .LBB1_10
 ; ARM-NEXT:  @ %bb.9:
 ; ARM-NEXT:    mov r3, r4
 ; ARM-NEXT:  .LBB1_10:
-; ARM-NEXT:    ands r7, r3
-; ARM-NEXT:    cmp r1, r6
+; ARM-NEXT:    ands r6, r3
+; ARM-NEXT:    adds r1, r1, #1
 ; ARM-NEXT:    mov r3, r0
 ; ARM-NEXT:    blt .LBB1_12
 ; ARM-NEXT:  @ %bb.11:
 ; ARM-NEXT:    mov r3, r4
 ; ARM-NEXT:  .LBB1_12:
-; ARM-NEXT:    orrs r3, r7
+; ARM-NEXT:    orrs r3, r6
 ; ARM-NEXT:    lsls r1, r0, #31
 ; ARM-NEXT:    cmp r3, #0
 ; ARM-NEXT:    bne .LBB1_14
@@ -158,7 +154,7 @@ define i64 @func2(i64 %x, i64 %y) nounwind {
 ; ARM-NEXT:  .LBB1_14:
 ; ARM-NEXT:    bne .LBB1_16
 ; ARM-NEXT:  @ %bb.15:
-; ARM-NEXT:    ldr r1, [sp, #24] @ 4-byte Reload
+; ARM-NEXT:    mov r1, r2
 ; ARM-NEXT:  .LBB1_16:
 ; ARM-NEXT:    mov r0, r4
 ; ARM-NEXT:    add sp, #28
@@ -189,21 +185,21 @@ define i4 @func3(i4 %x, i4 %y) nounwind {
 ; ARM-NEXT:    lsrs r0, r0, #2
 ; ARM-NEXT:    lsls r2, r1, #30
 ; ARM-NEXT:    adds r0, r2, r0
-; ARM-NEXT:    b .LBB2_3
+; ARM-NEXT:    adds r1, r1, #2
+; ARM-NEXT:    blt .LBB2_3
+; ARM-NEXT:    b .LBB2_4
 ; ARM-NEXT:  .LBB2_2:
 ; ARM-NEXT:    ldr r0, .LCPI2_0
+; ARM-NEXT:    adds r1, r1, #2
+; ARM-NEXT:    bge .LBB2_4
 ; ARM-NEXT:  .LBB2_3:
-; ARM-NEXT:    movs r2, #1
-; ARM-NEXT:    mvns r3, r2
-; ARM-NEXT:    cmp r1, r3
-; ARM-NEXT:    bge .LBB2_5
-; ARM-NEXT:  @ %bb.4:
-; ARM-NEXT:    lsls r0, r2, #31
-; ARM-NEXT:  .LBB2_5:
+; ARM-NEXT:    movs r0, #1
+; ARM-NEXT:    lsls r0, r0, #31
+; ARM-NEXT:  .LBB2_4:
 ; ARM-NEXT:    asrs r0, r0, #28
 ; ARM-NEXT:    pop {r4, pc}
 ; ARM-NEXT:    .p2align 2
-; ARM-NEXT:  @ %bb.6:
+; ARM-NEXT:  @ %bb.5:
 ; ARM-NEXT:  .LCPI2_0:
 ; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
   %tmp = call i4 @llvm.smul.fix.sat.i4(i4 %x, i4 %y, i32 2)
@@ -421,62 +417,59 @@ define i64 @func7(i64 %x, i64 %y) nounwind {
 ; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
 ; ARM-NEXT:    mov r3, r5
 ; ARM-NEXT:    bl __aeabi_lmul
-; ARM-NEXT:    adds r3, r0, r7
+; ARM-NEXT:    adds r5, r0, r7
 ; ARM-NEXT:    adcs r1, r6
 ; ARM-NEXT:    rsbs r0, r1, #0
 ; ARM-NEXT:    adcs r0, r1
-; ARM-NEXT:    lsrs r2, r3, #31
+; ARM-NEXT:    lsrs r2, r5, #31
 ; ARM-NEXT:    ands r2, r0
 ; ARM-NEXT:    movs r0, #1
 ; ARM-NEXT:    cmp r1, #0
-; ARM-NEXT:    mov r5, r0
+; ARM-NEXT:    mov r6, r0
 ; ARM-NEXT:    bgt .LBB6_2
 ; ARM-NEXT:  @ %bb.1:
-; ARM-NEXT:    mov r5, r4
+; ARM-NEXT:    mov r6, r4
 ; ARM-NEXT:  .LBB6_2:
-; ARM-NEXT:    orrs r5, r2
-; ARM-NEXT:    mvns r6, r4
-; ARM-NEXT:    cmp r5, #0
+; ARM-NEXT:    orrs r6, r2
+; ARM-NEXT:    mvns r3, r4
+; ARM-NEXT:    cmp r6, #0
 ; ARM-NEXT:    bne .LBB6_4
 ; ARM-NEXT:  @ %bb.3:
-; ARM-NEXT:    str r3, [sp, #16] @ 4-byte Spill
-; ARM-NEXT:    mov r5, r6
+; ARM-NEXT:    mov r2, r5
 ; ARM-NEXT:    beq .LBB6_5
 ; ARM-NEXT:    b .LBB6_6
 ; ARM-NEXT:  .LBB6_4:
 ; ARM-NEXT:    ldr r2, .LCPI6_0
-; ARM-NEXT:    str r2, [sp, #16] @ 4-byte Spill
-; ARM-NEXT:    mov r5, r6
 ; ARM-NEXT:    bne .LBB6_6
 ; ARM-NEXT:  .LBB6_5:
-; ARM-NEXT:    ldr r5, [sp] @ 4-byte Reload
+; ARM-NEXT:    ldr r3, [sp] @ 4-byte Reload
 ; ARM-NEXT:  .LBB6_6:
-; ARM-NEXT:    adds r2, r1, #1
-; ARM-NEXT:    rsbs r7, r2, #0
-; ARM-NEXT:    adcs r7, r2
-; ARM-NEXT:    cmp r3, #0
-; ARM-NEXT:    mov r3, r0
-; ARM-NEXT:    bge .LBB6_8
+; ARM-NEXT:    adds r7, r1, #1
+; ARM-NEXT:    rsbs r6, r7, #0
+; ARM-NEXT:    adcs r6, r7
+; ARM-NEXT:    adds r5, r5, #1
+; ARM-NEXT:    mov r5, r0
+; ARM-NEXT:    bgt .LBB6_8
 ; ARM-NEXT:  @ %bb.7:
-; ARM-NEXT:    mov r3, r4
+; ARM-NEXT:    mov r5, r4
 ; ARM-NEXT:  .LBB6_8:
-; ARM-NEXT:    ands r7, r3
-; ARM-NEXT:    cmp r1, r6
-; ARM-NEXT:    mov r3, r0
+; ARM-NEXT:    ands r6, r5
+; ARM-NEXT:    adds r1, r1, #1
+; ARM-NEXT:    mov r5, r0
 ; ARM-NEXT:    blt .LBB6_10
 ; ARM-NEXT:  @ %bb.9:
-; ARM-NEXT:    mov r3, r4
+; ARM-NEXT:    mov r5, r4
 ; ARM-NEXT:  .LBB6_10:
-; ARM-NEXT:    orrs r3, r7
+; ARM-NEXT:    orrs r5, r6
 ; ARM-NEXT:    lsls r1, r0, #31
-; ARM-NEXT:    cmp r3, #0
+; ARM-NEXT:    cmp r5, #0
 ; ARM-NEXT:    bne .LBB6_12
 ; ARM-NEXT:  @ %bb.11:
-; ARM-NEXT:    mov r4, r5
+; ARM-NEXT:    mov r4, r3
 ; ARM-NEXT:  .LBB6_12:
 ; ARM-NEXT:    bne .LBB6_14
 ; ARM-NEXT:  @ %bb.13:
-; ARM-NEXT:    ldr r1, [sp, #16] @ 4-byte Reload
+; ARM-NEXT:    mov r1, r2
 ; ARM-NEXT:  .LBB6_14:
 ; ARM-NEXT:    mov r0, r4
 ; ARM-NEXT:    add sp, #20
diff --git a/llvm/test/CodeGen/Thumb2/active_lane_mask.ll b/llvm/test/CodeGen/Thumb2/active_lane_mask.ll
index deb4dc7450640..8f672d13c26f2 100644
--- a/llvm/test/CodeGen/Thumb2/active_lane_mask.ll
+++ b/llvm/test/CodeGen/Thumb2/active_lane_mask.ll
@@ -14,12 +14,12 @@ define <2 x i64> @v2i64(i32 %index, i32 %TC, <2 x i64> %V1, <2 x i64> %V2) {
 ; CHECK-NEXT:    vmov lr, r12, d2
 ; CHECK-NEXT:    adds r6, r0, #1
 ; CHECK-NEXT:    adc r4, r4, #0
-; CHECK-NEXT:    subs.w r0, lr, #-1
+; CHECK-NEXT:    adds.w r0, lr, #1
 ; CHECK-NEXT:    vmov q1[2], q1[0], lr, r6
 ; CHECK-NEXT:    sbcs r0, r12, #0
 ; CHECK-NEXT:    vmov q1[3], q1[1], r12, r4
 ; CHECK-NEXT:    csetm r12, lo
-; CHECK-NEXT:    subs.w r6, r6, #-1
+; CHECK-NEXT:    adds r6, #1
 ; CHECK-NEXT:    bfi r5, r12, #0, #8
 ; CHECK-NEXT:    sbcs r6, r4, #0
 ; CHECK-NEXT:    mov.w r0, #0
diff --git a/llvm/test/CodeGen/Thumb2/mve-blockplacement.ll b/llvm/test/CodeGen/Thumb2/mve-blockplacement.ll
index 706a7c34c3df5..d87dc6a683bec 100644
--- a/llvm/test/CodeGen/Thumb2/mve-blockplacement.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-blockplacement.ll
@@ -396,15 +396,15 @@ define i32 @d(i64 %e, i32 %f, i64 %g, i32 %h) {
 ; CHECK-NEXT:    b .LBB1_6
 ; CHECK-NEXT:  .LBB1_2: @ %for.body6.preheader
 ; CHECK-NEXT:    @ in Loop: Header=BB1_6 Depth=1
+; CHECK-NEXT:    adds.w r0, r11, #4
+; CHECK-NEXT:    movw r2, #18725
 ; CHECK-NEXT:    mov r0, r11
-; CHECK-NEXT:    cmn.w r11, #4
+; CHECK-NEXT:    movt r2, #9362
 ; CHECK-NEXT:    it le
 ; CHECK-NEXT:    mvnle r0, #3
-; CHECK-NEXT:    movw r2, #18725
+; CHECK-NEXT:    mov r10, r3
 ; CHECK-NEXT:    adds r0, #6
-; CHECK-NEXT:    movt r2, #9362
 ; CHECK-NEXT:    sub.w r1, r0, r11
-; CHECK-NEXT:    mov r10, r3
 ; CHECK-NEXT:    umull r2, r3, r1, r2
 ; CHECK-NEXT:    subs r2, r1, r3
 ; CHECK-NEXT:    add.w r2, r3, r2, lsr #1
@@ -426,7 +426,7 @@ define i32 @d(i64 %e, i32 %f, i64 %g, i32 %h) {
 ; CHECK-NEXT:    subs.w r1, r5, lr
 ; CHECK-NEXT:    asr.w r0, r5, #31
 ; CHECK-NEXT:    sbcs.w r0, r0, r12
-; CHECK-NEXT:    bge.w .LBB1_28
+; CHECK-NEXT:    bge .LBB1_28
 ; CHECK-NEXT:  .LBB1_6: @ %for.cond2.preheader
 ; CHECK-NEXT:    @ =>This Loop Header: Depth=1
 ; CHECK-NEXT:    @ Child Loop BB1_19 Depth 2
@@ -460,7 +460,7 @@ define i32 @d(i64 %e, i32 %f, i64 %g, i32 %h) {
 ; CHECK-NEXT:  .LBB1_9: @ %for.cond.cleanup17.us
 ; CHECK-NEXT:    @ in Loop: Header=BB1_10 Depth=2
 ; CHECK-NEXT:    add.w r11, r0, #7
-; CHECK-NEXT:    cmn.w r0, #4
+; CHECK-NEXT:    adds r0, #4
 ; CHECK-NEXT:    mov.w r10, #0
 ; CHECK-NEXT:    mov r0, r11
 ; CHECK-NEXT:    bge .LBB1_5
@@ -537,20 +537,20 @@ define i32 @d(i64 %e, i32 %f, i64 %g, i32 %h) {
 ; CHECK-NEXT:    bne .LBB1_27
 ; CHECK-NEXT:  @ %bb.20: @ %for.cond.cleanup17.us63
 ; CHECK-NEXT:    @ in Loop: Header=BB1_19 Depth=2
-; CHECK-NEXT:    cmn.w r0, #4
+; CHECK-NEXT:    adds r1, r0, #4
 ; CHECK-NEXT:    bge.w .LBB1_3
 ; CHECK-NEXT:  @ %bb.21: @ %for.cond.cleanup17.us63.1
 ; CHECK-NEXT:    @ in Loop: Header=BB1_19 Depth=2
-; CHECK-NEXT:    cmn.w r0, #12
+; CHECK-NEXT:    adds.w r1, r0, #12
 ; CHECK-NEXT:    bgt .LBB1_24
 ; CHECK-NEXT:  @ %bb.22: @ %for.cond.cleanup17.us63.2
 ; CHECK-NEXT:    @ in Loop: Header=BB1_19 Depth=2
-; CHECK-NEXT:    cmn.w r0, #19
+; CHECK-NEXT:    adds.w r1, r0, #19
 ; CHECK-NEXT:    bgt .LBB1_25
 ; CHECK-NEXT:  @ %bb.23: @ %for.cond.cleanup17.us63.3
 ; CHECK-NEXT:    @ in Loop: Header=BB1_19 Depth=2
 ; CHECK-NEXT:    add.w r11, r0, #28
-; CHECK-NEXT:    cmn.w r0, #25
+; CHECK-NEXT:    adds r0, #25
 ; CHECK-NEXT:    mov.w r10, #0
 ; CHECK-NEXT:    mov r0, r11
 ; CHECK-NEXT:    blt .LBB1_19
diff --git a/llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll b/llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll
index 0134ee48ad421..384d357c8b23c 100644
--- a/llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll
@@ -87,12 +87,12 @@ define arm_aapcs_vfpcc <2 x i32> @utest_f64i32(<2 x double> %x) {
 ; CHECK-NEXT:    mov r5, r1
 ; CHECK-NEXT:    vmov r0, r1, d9
 ; CHECK-NEXT:    bl __aeabi_d2ulz
-; CHECK-NEXT:    subs.w r3, r4, #-1
+; CHECK-NEXT:    adds r3, r4, #1
 ; CHECK-NEXT:    vmov q1[2], q1[0], r4, r0
 ; CHECK-NEXT:    sbcs r3, r5, #0
 ; CHECK-NEXT:    mov.w r2, #0
 ; CHECK-NEXT:    csetm r3, lo
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    sbcs r0, r1, #0
 ; CHECK-NEXT:    bfi r2, r3, #0, #8
 ; CHECK-NEXT:    csetm r0, lo
@@ -125,12 +125,12 @@ define arm_aapcs_vfpcc <2 x i32> @ustest_f64i32(<2 x double> %x) {
 ; CHECK-NEXT:    mov r5, r1
 ; CHECK-NEXT:    vmov r0, r1, d9
 ; CHECK-NEXT:    bl __aeabi_d2lz
-; CHECK-NEXT:    subs.w r3, r4, #-1
+; CHECK-NEXT:    adds r3, r4, #1
 ; CHECK-NEXT:    vmov q1[2], q1[0], r4, r0
 ; CHECK-NEXT:    sbcs r3, r5, #0
 ; CHECK-NEXT:    vmov q1[3], q1[1], r5, r1
 ; CHECK-NEXT:    csetm r3, lt
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    mov.w r5, #0
 ; CHECK-NEXT:    sbcs r0, r1, #0
 ; CHECK-NEXT:    bfi r5, r3, #0, #8
@@ -680,7 +680,7 @@ define arm_aapcs_vfpcc <2 x i64> @stest_f64i64(<2 x double> %x) {
 ; CHECK-NEXT:    vmov r0, r1, d8
 ; CHECK-NEXT:    bl __fixdfti
 ; CHECK-NEXT:    vmov r12, lr, d9
-; CHECK-NEXT:    subs.w r5, r0, #-1
+; CHECK-NEXT:    adds r5, r0, #1
 ; CHECK-NEXT:    mvn r4, #-2147483648
 ; CHECK-NEXT:    sbcs.w r5, r1, r4
 ; CHECK-NEXT:    sbcs r5, r2, #0
@@ -704,7 +704,7 @@ define arm_aapcs_vfpcc <2 x i64> @stest_f64i64(<2 x double> %x) {
 ; CHECK-NEXT:    mov r0, r12
 ; CHECK-NEXT:    mov r1, lr
 ; CHECK-NEXT:    bl __fixdfti
-; CHECK-NEXT:    subs.w r6, r0, #-1
+; CHECK-NEXT:    adds r6, r0, #1
 ; CHECK-NEXT:    sbcs.w r6, r1, r4
 ; CHECK-NEXT:    sbcs r6, r2, #0
 ; CHECK-NEXT:    sbcs r6, r3, #0
@@ -844,7 +844,7 @@ define arm_aapcs_vfpcc <2 x i64> @stest_f32i64(<2 x float> %x) {
 ; CHECK-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, lr}
 ; CHECK-NEXT:    vmov r0, r9, d0
 ; CHECK-NEXT:    bl __fixsfti
-; CHECK-NEXT:    subs.w r7, r0, #-1
+; CHECK-NEXT:    adds r7, r0, #1
 ; CHECK-NEXT:    mvn r5, #-2147483648
 ; CHECK-NEXT:    sbcs.w r7, r1, r5
 ; CHECK-NEXT:    mov.w r6, #-1
@@ -867,7 +867,7 @@ define arm_aapcs_vfpcc <2 x i64> @stest_f32i64(<2 x float> %x) {
 ; CHECK-NEXT:    csel r10, r0, r1, ne
 ; CHECK-NEXT:    mov r0, r9
 ; CHECK-NEXT:    bl __fixsfti
-; CHECK-NEXT:    subs.w r4, r0, #-1
+; CHECK-NEXT:    adds r4, r0, #1
 ; CHECK-NEXT:    sbcs.w r4, r1, r5
 ; CHECK-NEXT:    sbcs r4, r2, #0
 ; CHECK-NEXT:    sbcs r4, r3, #0
@@ -1172,12 +1172,12 @@ define arm_aapcs_vfpcc <2 x i32> @utest_f64i32_mm(<2 x double> %x) {
 ; CHECK-NEXT:    mov r5, r1
 ; CHECK-NEXT:    vmov r0, r1, d9
 ; CHECK-NEXT:    bl __aeabi_d2ulz
-; CHECK-NEXT:    subs.w r3, r4, #-1
+; CHECK-NEXT:    adds r3, r4, #1
 ; CHECK-NEXT:    vmov q1[2], q1[0], r4, r0
 ; CHECK-NEXT:    sbcs r3, r5, #0
 ; CHECK-NEXT:    mov.w r2, #0
 ; CHECK-NEXT:    csetm r3, lo
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    sbcs r0, r1, #0
 ; CHECK-NEXT:    bfi r2, r3, #0, #8
 ; CHECK-NEXT:    csetm r0, lo
@@ -1209,12 +1209,12 @@ define arm_aapcs_vfpcc <2 x i32> @ustest_f64i32_mm(<2 x double> %x) {
 ; CHECK-NEXT:    mov r5, r1
 ; CHECK-NEXT:    vmov r0, r1, d9
 ; CHECK-NEXT:    bl __aeabi_d2lz
-; CHECK-NEXT:    subs.w r3, r4, #-1
+; CHECK-NEXT:    adds r3, r4, #1
 ; CHECK-NEXT:    vmov q1[2], q1[0], r4, r0
 ; CHECK-NEXT:    sbcs r3, r5, #0
 ; CHECK-NEXT:    vmov q1[3], q1[1], r5, r1
 ; CHECK-NEXT:    csetm r3, lt
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    mov.w r5, #0
 ; CHECK-NEXT:    sbcs r0, r1, #0
 ; CHECK-NEXT:    bfi r5, r3, #0, #8
@@ -1737,7 +1737,7 @@ define arm_aapcs_vfpcc <2 x i64> @stest_f64i64_mm(<2 x double> %x) {
 ; CHECK-NEXT:    vmov r0, r1, d9
 ; CHECK-NEXT:    bl __fixdfti
 ; CHECK-NEXT:    vmov r12, lr, d8
-; CHECK-NEXT:    subs.w r5, r0, #-1
+; CHECK-NEXT:    adds r5, r0, #1
 ; CHECK-NEXT:    mvn r4, #-2147483648
 ; CHECK-NEXT:    sbcs.w r5, r1, r4
 ; CHECK-NEXT:    sbcs r5, r2, #0
@@ -1761,7 +1761,7 @@ define arm_aapcs_vfpcc <2 x i64> @stest_f64i64_mm(<2 x double> %x) {
 ; CHECK-NEXT:    mov r0, r12
 ; CHECK-NEXT:    mov r1, lr
 ; CHECK-NEXT:    bl __fixdfti
-; CHECK-NEXT:    subs.w r7, r0, #-1
+; CHECK-NEXT:    adds r7, r0, #1
 ; CHECK-NEXT:    sbcs.w r7, r1, r4
 ; CHECK-NEXT:    sbcs r7, r2, #0
 ; CHECK-NEXT:    sbcs r7, r3, #0
@@ -1884,7 +1884,7 @@ define arm_aapcs_vfpcc <2 x i64> @stest_f32i64_mm(<2 x float> %x) {
 ; CHECK-NEXT:    push.w {r4, r5, r6, r7, r8, r9, r10, lr}
 ; CHECK-NEXT:    vmov r8, r0, d0
 ; CHECK-NEXT:    bl __fixsfti
-; CHECK-NEXT:    subs.w r7, r0, #-1
+; CHECK-NEXT:    adds r7, r0, #1
 ; CHECK-NEXT:    mvn r5, #-2147483648
 ; CHECK-NEXT:    sbcs.w r7, r1, r5
 ; CHECK-NEXT:    mov.w r6, #-2147483648
@@ -1907,7 +1907,7 @@ define arm_aapcs_vfpcc <2 x i64> @stest_f32i64_mm(<2 x float> %x) {
 ; CHECK-NEXT:    mov r0, r8
 ; CHECK-NEXT:    csel r9, r1, r6, ne
 ; CHECK-NEXT:    bl __fixsfti
-; CHECK-NEXT:    subs.w r4, r0, #-1
+; CHECK-NEXT:    adds r4, r0, #1
 ; CHECK-NEXT:    sbcs.w r4, r1, r5
 ; CHECK-NEXT:    sbcs r4, r2, #0
 ; CHECK-NEXT:    sbcs r4, r3, #0
diff --git a/llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll b/llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll
index da59cb259db61..5b886ce3286cc 100644
--- a/llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-memtp-loop.ll
@@ -211,7 +211,7 @@ entry:
 define void @test11(ptr nocapture %x, ptr nocapture %y, i32 %n) {
 ; CHECK-LABEL: test11:
 ; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    cmp.w r2, #-1
+; CHECK-NEXT:    adds r3, r2, #1
 ; CHECK-NEXT:    it gt
 ; CHECK-NEXT:    bxgt lr
 ; CHECK-NEXT:  .LBB10_1: @ %prehead
diff --git a/llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll b/llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll
index 40d534a0ebfc5..b83e71308479c 100644
--- a/llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll
@@ -642,13 +642,13 @@ define arm_aapcs_vfpcc void @usatmul_2_q31(ptr nocapture readonly %pSrcA, ptr no
 ; CHECK-NEXT:    ldrd r7, r3, [r1], #8
 ; CHECK-NEXT:    umull r4, r9, r7, r4
 ; CHECK-NEXT:    lsrl r4, r9, #31
-; CHECK-NEXT:    subs.w r5, r4, #-1
+; CHECK-NEXT:    adds r5, r4, #1
 ; CHECK-NEXT:    sbcs r5, r9, #0
 ; CHECK-NEXT:    csetm r5, lo
 ; CHECK-NEXT:    bfi r8, r5, #0, #8
 ; CHECK-NEXT:    umull r6, r5, r3, r6
 ; CHECK-NEXT:    lsrl r6, r5, #31
-; CHECK-NEXT:    subs.w r7, r6, #-1
+; CHECK-NEXT:    adds r7, r6, #1
 ; CHECK-NEXT:    vmov q1[2], q1[0], r4, r6
 ; CHECK-NEXT:    sbcs r3, r5, #0
 ; CHECK-NEXT:    vmov q1[3], q1[1], r9, r5
@@ -672,7 +672,7 @@ define arm_aapcs_vfpcc void @usatmul_2_q31(ptr nocapture readonly %pSrcA, ptr no
 ; CHECK-NEXT:    ldr r1, [r10], #4
 ; CHECK-NEXT:    umull r0, r1, r1, r0
 ; CHECK-NEXT:    lsrl r0, r1, #31
-; CHECK-NEXT:    subs.w r2, r0, #-1
+; CHECK-NEXT:    adds r2, r0, #1
 ; CHECK-NEXT:    sbcs r1, r1, #0
 ; CHECK-NEXT:    it hs
 ; CHECK-NEXT:    movhs.w r0, #-1
@@ -799,14 +799,14 @@ define arm_aapcs_vfpcc void @usatmul_4_q31(ptr nocapture readonly %pSrcA, ptr no
 ; CHECK-NEXT:    vmov r4, r9, d10
 ; CHECK-NEXT:    lsrl r4, r9, #31
 ; CHECK-NEXT:    vmov.f32 s10, s9
-; CHECK-NEXT:    subs.w r5, r4, #-1
+; CHECK-NEXT:    adds r5, r4, #1
 ; CHECK-NEXT:    sbcs r5, r9, #0
 ; CHECK-NEXT:    vmullb.u32 q4, q2, q1
 ; CHECK-NEXT:    csetm r5, lo
 ; CHECK-NEXT:    bfi r6, r5, #0, #8
 ; CHECK-NEXT:    vmov r8, r5, d11
 ; CHECK-NEXT:    lsrl r8, r5, #31
-; CHECK-NEXT:    subs.w r11, r8, #-1
+; CHECK-NEXT:    adds.w r11, r8, #1
 ; CHECK-NEXT:    vmov q3[2], q3[0], r4, r8
 ; CHECK-NEXT:    sbcs r7, r5, #0
 ; CHECK-NEXT:    vmov q3[3], q3[1], r9, r5
@@ -815,7 +815,7 @@ define arm_aapcs_vfpcc void @usatmul_4_q31(ptr nocapture readonly %pSrcA, ptr no
 ; CHECK-NEXT:    vmov r4, r7, d8
 ; CHECK-NEXT:    lsrl r4, r7, #31
 ; CHECK-NEXT:    vmsr p0, r6
-; CHECK-NEXT:    subs.w r5, r4, #-1
+; CHECK-NEXT:    adds r5, r4, #1
 ; CHECK-NEXT:    mov.w r6, #0
 ; CHECK-NEXT:    sbcs r5, r7, #0
 ; CHECK-NEXT:    vpsel q3, q3, q0
@@ -823,7 +823,7 @@ define arm_aapcs_vfpcc void @usatmul_4_q31(ptr nocapture readonly %pSrcA, ptr no
 ; CHECK-NEXT:    bfi r6, r5, #0, #8
 ; CHECK-NEXT:    vmov r2, r5, d9
 ; CHECK-NEXT:    lsrl r2, r5, #31
-; CHECK-NEXT:    subs.w r3, r2, #-1
+; CHECK-NEXT:    adds r3, r2, #1
 ; CHECK-NEXT:    vmov q1[2], q1[0], r4, r2
 ; CHECK-NEXT:    sbcs r3, r5, #0
 ; CHECK-NEXT:    vmov q1[3], q1[1], r7, r5
@@ -850,7 +850,7 @@ define arm_aapcs_vfpcc void @usatmul_4_q31(ptr nocapture readonly %pSrcA, ptr no
 ; CHECK-NEXT:    ldr r2, [r10], #4
 ; CHECK-NEXT:    umull r0, r3, r2, r0
 ; CHECK-NEXT:    lsrl r0, r3, #31
-; CHECK-NEXT:    subs.w r2, r0, #-1
+; CHECK-NEXT:    adds r2, r0, #1
 ; CHECK-NEXT:    sbcs r2, r3, #0
 ; CHECK-NEXT:    it hs
 ; CHECK-NEXT:    movhs.w r0, #-1
diff --git a/llvm/test/CodeGen/Thumb2/mve-saturating-arith.ll b/llvm/test/CodeGen/Thumb2/mve-saturating-arith.ll
index 118b8ac6682b2..c8699281e73c4 100644
--- a/llvm/test/CodeGen/Thumb2/mve-saturating-arith.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-saturating-arith.ll
@@ -187,7 +187,7 @@ define arm_aapcs_vfpcc <2 x i64> @ssub_int64_t(<2 x i64> %src1, <2 x i64> %src2)
 ; CHECK-NEXT:    vmov r2, r4, d0
 ; CHECK-NEXT:    sbcs.w r0, r3, r1
 ; CHECK-NEXT:    mrs r1, apsr
-; CHECK-NEXT:    cmp.w r0, #-1
+; CHECK-NEXT:    adds r3, r0, #1
 ; CHECK-NEXT:    cset r3, gt
 ; CHECK-NEXT:    msr apsr_nzcvq, r1
 ; CHECK-NEXT:    vmov r1, lr, d2
@@ -196,7 +196,7 @@ define arm_aapcs_vfpcc <2 x i64> @ssub_int64_t(<2 x i64> %src1, <2 x i64> %src2)
 ; CHECK-NEXT:    subs r5, r2, r1
 ; CHECK-NEXT:    sbcs.w r2, r4, lr
 ; CHECK-NEXT:    mrs r4, apsr
-; CHECK-NEXT:    cmp.w r2, #-1
+; CHECK-NEXT:    adds r1, r2, #1
 ; CHECK-NEXT:    vmov q0[2], q0[0], r5, r12
 ; CHECK-NEXT:    cset r1, gt
 ; CHECK-NEXT:    msr apsr_nzcvq, r4
diff --git a/llvm/test/CodeGen/Thumb2/mve-vqmovn.ll b/llvm/test/CodeGen/Thumb2/mve-vqmovn.ll
index 75f7350fcd5b1..d4c4a0bef39b1 100644
--- a/llvm/test/CodeGen/Thumb2/mve-vqmovn.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-vqmovn.ll
@@ -278,13 +278,13 @@ define arm_aapcs_vfpcc <2 x i64> @vqmovni64_umaxmin(<2 x i64> %s0) {
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    vmov r0, r1, d0
 ; CHECK-NEXT:    vmov.i64 q1, #0xffffffff
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    sbcs r0, r1, #0
 ; CHECK-NEXT:    mov.w r1, #0
 ; CHECK-NEXT:    csetm r0, lo
 ; CHECK-NEXT:    bfi r1, r0, #0, #8
 ; CHECK-NEXT:    vmov r0, r2, d1
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    sbcs r0, r2, #0
 ; CHECK-NEXT:    csetm r0, lo
 ; CHECK-NEXT:    bfi r1, r0, #8, #8
@@ -302,13 +302,13 @@ define arm_aapcs_vfpcc <2 x i64> @vqmovni64_uminmax(<2 x i64> %s0) {
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    vmov r0, r1, d0
 ; CHECK-NEXT:    vmov.i64 q1, #0xffffffff
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    sbcs r0, r1, #0
 ; CHECK-NEXT:    mov.w r1, #0
 ; CHECK-NEXT:    csetm r0, lo
 ; CHECK-NEXT:    bfi r1, r0, #0, #8
 ; CHECK-NEXT:    vmov r0, r2, d1
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    sbcs r0, r2, #0
 ; CHECK-NEXT:    csetm r0, lo
 ; CHECK-NEXT:    bfi r1, r0, #8, #8
diff --git a/llvm/test/CodeGen/Thumb2/mve-vqshrn.ll b/llvm/test/CodeGen/Thumb2/mve-vqshrn.ll
index f78d36222c312..e0e65e608c208 100644
--- a/llvm/test/CodeGen/Thumb2/mve-vqshrn.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-vqshrn.ll
@@ -312,11 +312,11 @@ define arm_aapcs_vfpcc <2 x i64> @vqshrni64_umaxmin(<2 x i64> %so) {
 ; CHECK-NEXT:    lsrl r0, r1, #3
 ; CHECK-NEXT:    lsrl r2, r3, #3
 ; CHECK-NEXT:    vmov q0[2], q0[0], r2, r0
-; CHECK-NEXT:    subs.w r2, r2, #-1
+; CHECK-NEXT:    adds r2, #1
 ; CHECK-NEXT:    sbcs r2, r3, #0
 ; CHECK-NEXT:    vmov q0[3], q0[1], r3, r1
 ; CHECK-NEXT:    csetm r2, lo
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    mov.w r3, #0
 ; CHECK-NEXT:    sbcs r0, r1, #0
 ; CHECK-NEXT:    bfi r3, r2, #0, #8
@@ -341,11 +341,11 @@ define arm_aapcs_vfpcc <2 x i64> @vqshrni64_uminmax(<2 x i64> %so) {
 ; CHECK-NEXT:    lsrl r0, r1, #3
 ; CHECK-NEXT:    lsrl r2, r3, #3
 ; CHECK-NEXT:    vmov q0[2], q0[0], r2, r0
-; CHECK-NEXT:    subs.w r2, r2, #-1
+; CHECK-NEXT:    adds r2, #1
 ; CHECK-NEXT:    sbcs r2, r3, #0
 ; CHECK-NEXT:    vmov q0[3], q0[1], r3, r1
 ; CHECK-NEXT:    csetm r2, lo
-; CHECK-NEXT:    subs.w r0, r0, #-1
+; CHECK-NEXT:    adds r0, #1
 ; CHECK-NEXT:    mov.w r3, #0
 ; CHECK-NEXT:    sbcs r0, r1, #0
 ; CHECK-NEXT:    bfi r3, r2, #0, #8
diff --git a/llvm/test/CodeGen/Thumb2/mve-vselect-constants.ll b/llvm/test/CodeGen/Thumb2/mve-vselect-constants.ll
index 256456a2e9d0a..68c9074d63a22 100644
--- a/llvm/test/CodeGen/Thumb2/mve-vselect-constants.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-vselect-constants.ll
@@ -276,11 +276,11 @@ define arm_aapcs_vfpcc <2 x i64> @not_signbit_mask_v2i64(<2 x i64> %a, <2 x i64>
 ; CHECK-NEXT:    vmov r1, s1
 ; CHECK-NEXT:    movs r0, #0
 ; CHECK-NEXT:    vmov.i32 q2, #0x0
-; CHECK-NEXT:    cmp.w r1, #-1
+; CHECK-NEXT:    adds r1, #1
 ; CHECK-NEXT:    csetm r1, gt
 ; CHECK-NEXT:    bfi r0, r1, #0, #8
 ; CHECK-NEXT:    vmov r1, s3
-; CHECK-NEXT:    cmp.w r1, #-1
+; CHECK-NEXT:    adds r1, #1
 ; CHECK-NEXT:    csetm r1, gt
 ; CHECK-NEXT:    bfi r0, r1, #8, #8
 ; CHECK-NEXT:    vmsr p0, r0
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
index 5a154f4f4adbe..571fbadeb8fa4 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
@@ -40,7 +40,7 @@ define hidden i32 @_Z1hii(i32 %a, i32 %b) local_unnamed_addr #0 {
 ; CHECK-NEXT:    .cfi_offset lr, -4
 ; CHECK-NEXT:    .cfi_offset ra_auth_code, -8
 ; CHECK-NEXT:    .cfi_offset r7, -12
-; CHECK-NEXT:    cmp.w r0, #-1
+; CHECK-NEXT:    adds r2, r0, #1
 ; CHECK-NEXT:    ble .LBB0_2
 ; CHECK-NEXT:  @ %bb.1: @ %if.end
 ; CHECK-NEXT:    add r0, r1
diff --git a/llvm/test/CodeGen/Thumb2/thumb2-cmp.ll b/llvm/test/CodeGen/Thumb2/thumb2-cmp.ll
index 7d92c4d0ee43d..bd0cc6ecef939 100644
--- a/llvm/test/CodeGen/Thumb2/thumb2-cmp.ll
+++ b/llvm/test/CodeGen/Thumb2/thumb2-cmp.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s
 
 ; These tests would be improved by 'movs r0, #0' being rematerialized below the
@@ -6,7 +7,13 @@
 ; 0x000000bb = 187
 define i32 @f1(i32 %a) {
 ; CHECK-LABEL: f1:
-; CHECK: cmp {{.*}}, #187
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #24
+; CHECK-NEXT:    cmp r0, #187
+; CHECK-NEXT:    it ne
+; CHECK-NEXT:    movne r1, #42
+; CHECK-NEXT:    mov r0, r1
+; CHECK-NEXT:    bx lr
     %tmp = icmp ne i32 %a, 187
     %ret = select i1 %tmp, i32 42, i32 24
     ret i32 %ret
@@ -15,8 +22,14 @@ define i32 @f1(i32 %a) {
 ; 0x00aa00aa = 11141290
 define i32 @f2(i32 %a) {
 ; CHECK-LABEL: f2:
-; CHECK: cmp.w {{.*}}, #11141290
-    %tmp = icmp eq i32 %a, 11141290 
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #24
+; CHECK-NEXT:    cmp.w r0, #11141290
+; CHECK-NEXT:    it eq
+; CHECK-NEXT:    moveq r1, #42
+; CHECK-NEXT:    mov r0, r1
+; CHECK-NEXT:    bx lr
+    %tmp = icmp eq i32 %a, 11141290
     %ret = select i1 %tmp, i32 42, i32 24
     ret i32 %ret
 }
@@ -24,7 +37,13 @@ define i32 @f2(i32 %a) {
 ; 0xcc00cc00 = 3422604288
 define i32 @f3(i32 %a) {
 ; CHECK-LABEL: f3:
-; CHECK: cmp.w {{.*}}, #-872363008
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #24
+; CHECK-NEXT:    cmp.w r0, #-872363008
+; CHECK-NEXT:    it ne
+; CHECK-NEXT:    movne r1, #42
+; CHECK-NEXT:    mov r0, r1
+; CHECK-NEXT:    bx lr
     %tmp = icmp ne i32 %a, 3422604288
     %ret = select i1 %tmp, i32 42, i32 24
     ret i32 %ret
@@ -33,7 +52,13 @@ define i32 @f3(i32 %a) {
 ; 0xdddddddd = 3722304989
 define i32 @f4(i32 %a) {
 ; CHECK-LABEL: f4:
-; CHECK: cmp.w {{.*}}, #-572662307
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #24
+; CHECK-NEXT:    cmp.w r0, #-572662307
+; CHECK-NEXT:    it ne
+; CHECK-NEXT:    movne r1, #42
+; CHECK-NEXT:    mov r0, r1
+; CHECK-NEXT:    bx lr
     %tmp = icmp ne i32 %a, 3722304989
     %ret = select i1 %tmp, i32 42, i32 24
     ret i32 %ret
@@ -42,7 +67,13 @@ define i32 @f4(i32 %a) {
 ; 0x00110000 = 1114112
 define i32 @f5(i32 %a) {
 ; CHECK-LABEL: f5:
-; CHECK: cmp.w {{.*}}, #1114112
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #24
+; CHECK-NEXT:    cmp.w r0, #1114112
+; CHECK-NEXT:    it eq
+; CHECK-NEXT:    moveq r1, #42
+; CHECK-NEXT:    mov r0, r1
+; CHECK-NEXT:    bx lr
     %tmp = icmp eq i32 %a, 1114112
     %ret = select i1 %tmp, i32 42, i32 24
     ret i32 %ret
@@ -54,6 +85,14 @@ define i32 @f5(i32 %a) {
 ; CHECK-NOT: cmp.w {{.*}}, #-2147483648
 ; CHECK: bx lr
 define i32 @f6(i32 %a) {
+; CHECK-LABEL: f6:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    mvn r1, #-2147483648
+; CHECK-NEXT:    cmp r0, r1
+; CHECK-NEXT:    ite le
+; CHECK-NEXT:    movle r0, #0
+; CHECK-NEXT:    movgt r0, #2
+; CHECK-NEXT:    bx lr
     %tmp = icmp sgt i32 %a, 2147483647
     br i1 %tmp, label %true, label %false
 true:
@@ -64,7 +103,12 @@ false:
 
 define i32 @slt_poweroftwo(i32 %a) {
 ; CHECK-LABEL: slt_poweroftwo:
-; CHECK: cmp.w   r0, #4096
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #4096
+; CHECK-NEXT:    ite ge
+; CHECK-NEXT:    movge r0, #2
+; CHECK-NEXT:    movlt r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp slt i32 %a, 4096
   br i1 %b, label %true, label %false
 
@@ -77,7 +121,12 @@ false:
 
 define i32 @sle_poweroftwo(i32 %a) {
 ; CHECK-LABEL: sle_poweroftwo:
-; CHECK: cmp.w   r0, #4096
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #4096
+; CHECK-NEXT:    ite gt
+; CHECK-NEXT:    movgt r0, #2
+; CHECK-NEXT:    movle r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sle i32 %a, 4096
   br i1 %b, label %true, label %false
 
@@ -90,7 +139,12 @@ false:
 
 define i32 @sge_poweroftwo(i32 %a) {
 ; CHECK-LABEL: sge_poweroftwo:
-; CHECK: cmp.w   r0, #4096
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #4096
+; CHECK-NEXT:    ite lt
+; CHECK-NEXT:    movlt r0, #2
+; CHECK-NEXT:    movge r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sge i32 %a, 4096
   br i1 %b, label %true, label %false
 
@@ -103,7 +157,12 @@ false:
 
 define i32 @sgt_poweroftwo(i32 %a) {
 ; CHECK-LABEL: sgt_poweroftwo:
-; CHECK: cmp.w   r0, #4096
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #4096
+; CHECK-NEXT:    ite le
+; CHECK-NEXT:    movle r0, #2
+; CHECK-NEXT:    movgt r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sgt i32 %a, 4096
   br i1 %b, label %true, label %false
 
@@ -116,7 +175,12 @@ false:
 
 define i32 @slt_nearpoweroftwo(i32 %a) {
 ; CHECK-LABEL: slt_nearpoweroftwo:
-; CHECK: cmp.w   r0, #4096
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #4096
+; CHECK-NEXT:    ite gt
+; CHECK-NEXT:    movgt r0, #2
+; CHECK-NEXT:    movle r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp slt i32 %a, 4097
   br i1 %b, label %true, label %false
 
@@ -129,7 +193,12 @@ false:
 
 define i32 @sle_nearpoweroftwo(i32 %a) {
 ; CHECK-LABEL: sle_nearpoweroftwo:
-; CHECK: cmp.w   r0, #4096
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #4096
+; CHECK-NEXT:    ite ge
+; CHECK-NEXT:    movge r0, #2
+; CHECK-NEXT:    movlt r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sle i32 %a, 4095
   br i1 %b, label %true, label %false
 
@@ -143,7 +212,12 @@ false:
 
 define i32 @sge_nearpoweroftwo(i32 %a) {
 ; CHECK-LABEL: sge_nearpoweroftwo:
-; CHECK: cmp.w   r0, #4096
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #4096
+; CHECK-NEXT:    ite le
+; CHECK-NEXT:    movle r0, #2
+; CHECK-NEXT:    movgt r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sge i32 %a, 4097
   br i1 %b, label %true, label %false
 
@@ -156,7 +230,12 @@ false:
 
 define i32 @sgt_nearpoweroftwo(i32 %a) {
 ; CHECK-LABEL: sgt_nearpoweroftwo:
-; CHECK: cmp.w   r0, #4096
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #4096
+; CHECK-NEXT:    ite lt
+; CHECK-NEXT:    movlt r0, #2
+; CHECK-NEXT:    movge r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sgt i32 %a, 4095
   br i1 %b, label %true, label %false
 
@@ -169,7 +248,13 @@ false:
 
 define i32 @slt_neg_soimm(i32 %a) {
 ; CHECK-LABEL: slt_neg_soimm:
-; CHECK: cmn.w r0, #7929856
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    mvn r1, #7929856
+; CHECK-NEXT:    cmp r0, r1
+; CHECK-NEXT:    ite gt
+; CHECK-NEXT:    movgt r0, #2
+; CHECK-NEXT:    movle r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp slt i32 %a, -7929856
   br i1 %b, label %true, label %false
 
@@ -182,7 +267,12 @@ false:
 
 define i32 @sle_neg_soimm(i32 %a) {
 ; CHECK-LABEL: sle_neg_soimm:
-; CHECK: cmn.w   r0, #7929856
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmn.w r0, #7929856
+; CHECK-NEXT:    ite gt
+; CHECK-NEXT:    movgt r0, #2
+; CHECK-NEXT:    movle r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sle i32 %a, -7929856
   br i1 %b, label %true, label %false
 
@@ -195,7 +285,12 @@ false:
 
 define i32 @sge_neg_soimm(i32 %a) {
 ; CHECK-LABEL: sge_neg_soimm:
-; CHECK: cmn.w   r0, #7929856
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmn.w r0, #7929856
+; CHECK-NEXT:    ite lt
+; CHECK-NEXT:    movlt r0, #2
+; CHECK-NEXT:    movge r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sge i32 %a, -7929856
   br i1 %b, label %true, label %false
 
@@ -208,7 +303,14 @@ false:
 
 define i32 @sgt_neg_soimm(i32 %a) {
 ; CHECK-LABEL: sgt_neg_soimm:
-; CHECK: cmn.w r0, #7929856
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #1
+; CHECK-NEXT:    movt r1, #65415
+; CHECK-NEXT:    cmp r0, r1
+; CHECK-NEXT:    ite lt
+; CHECK-NEXT:    movlt r0, #2
+; CHECK-NEXT:    movge r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sgt i32 %a, -7929856
   br i1 %b, label %true, label %false
 
@@ -221,7 +323,12 @@ false:
 
 define i32 @slt_notneg_soimm(i32 %a) {
 ; CHECK-LABEL: slt_notneg_soimm:
-; CHECK: cmp.w r0, #-2013231104
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #-2013231104
+; CHECK-NEXT:    ite ge
+; CHECK-NEXT:    movge r0, #2
+; CHECK-NEXT:    movlt r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp slt i32 %a, -2013231104
   br i1 %b, label %true, label %false
 
@@ -234,7 +341,12 @@ false:
 
 define i32 @sle_notneg_soimm(i32 %a) {
 ; CHECK-LABEL: sle_notneg_soimm:
-; CHECK: cmp.w   r0, #-2013231104
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #-2013231104
+; CHECK-NEXT:    ite gt
+; CHECK-NEXT:    movgt r0, #2
+; CHECK-NEXT:    movle r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sle i32 %a, -2013231104
   br i1 %b, label %true, label %false
 
@@ -247,7 +359,12 @@ false:
 
 define i32 @sge_notneg_soimm(i32 %a) {
 ; CHECK-LABEL: sge_notneg_soimm:
-; CHECK: cmp.w   r0, #-2013231104
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #-2013231104
+; CHECK-NEXT:    ite lt
+; CHECK-NEXT:    movlt r0, #2
+; CHECK-NEXT:    movge r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sge i32 %a, -2013231104
   br i1 %b, label %true, label %false
 
@@ -260,7 +377,12 @@ false:
 
 define i32 @sgt_notneg_soimm(i32 %a) {
 ; CHECK-LABEL: sgt_notneg_soimm:
-; CHECK: cmp.w r0, #-2013231104
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    cmp.w r0, #-2013231104
+; CHECK-NEXT:    ite le
+; CHECK-NEXT:    movle r0, #2
+; CHECK-NEXT:    movgt r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sgt i32 %a, -2013231104
   br i1 %b, label %true, label %false
 
@@ -273,7 +395,13 @@ false:
 
 define i32 @sgt_movw(i32 %a) {
 ; CHECK-LABEL: sgt_movw:
-; CHECK: movw  r1, #2167
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movw r1, #2167
+; CHECK-NEXT:    cmp r0, r1
+; CHECK-NEXT:    ite lt
+; CHECK-NEXT:    movlt r0, #2
+; CHECK-NEXT:    movge r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sgt i32 %a, 2166
   br i1 %b, label %true, label %false
 
@@ -286,8 +414,14 @@ false:
 
 define i32 @sgt_neg_movw(i32 %a) {
 ; CHECK-LABEL: sgt_neg_movw:
-; CHECK: movw    r1, #63371
-; CHECK: movt    r1, #65535
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movw r1, #63371
+; CHECK-NEXT:    movt r1, #65535
+; CHECK-NEXT:    cmp r0, r1
+; CHECK-NEXT:    ite lt
+; CHECK-NEXT:    movlt r0, #2
+; CHECK-NEXT:    movge r0, #1
+; CHECK-NEXT:    bx lr
   %b = icmp sgt i32 %a, -2166
   br i1 %b, label %true, label %false
 



More information about the llvm-commits mailing list