[llvm] r325323 - [ARM] Materialise some boolean values to avoid a branch

Roger Ferrer Ibanez via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 16 01:23:59 PST 2018


Author: rogfer01
Date: Fri Feb 16 01:23:59 2018
New Revision: 325323

URL: http://llvm.org/viewvc/llvm-project?rev=325323&view=rev
Log:
[ARM] Materialise some boolean values to avoid a branch

This patch combines some cases of ARMISD::CMOV for integers that arise in comparisons of the form

  a != b ? x : 0
  a == b ? 0 : x

and that currently (e.g. in Thumb1) are emitted as branches.

Differential Revision: https://reviews.llvm.org/D34515


Modified:
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
    llvm/trunk/test/CodeGen/ARM/and-load-combine.ll
    llvm/trunk/test/CodeGen/ARM/atomic-cmpxchg.ll
    llvm/trunk/test/CodeGen/ARM/cmn.ll
    llvm/trunk/test/CodeGen/ARM/cmp.ll
    llvm/trunk/test/CodeGen/ARM/cmpxchg-O0.ll
    llvm/trunk/test/CodeGen/ARM/fp16-promote.ll
    llvm/trunk/test/CodeGen/ARM/long-setcc.ll
    llvm/trunk/test/CodeGen/ARM/select-imm.ll
    llvm/trunk/test/CodeGen/ARM/setcc-logic.ll
    llvm/trunk/test/CodeGen/Thumb/branchless-cmp.ll
    llvm/trunk/test/CodeGen/Thumb/constants.ll
    llvm/trunk/test/CodeGen/Thumb/long-setcc.ll
    llvm/trunk/test/CodeGen/Thumb2/float-cmp.ll
    llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn.ll
    llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll
    llvm/trunk/test/CodeGen/Thumb2/thumb2-cmp.ll
    llvm/trunk/test/CodeGen/Thumb2/thumb2-teq.ll
    llvm/trunk/test/CodeGen/Thumb2/thumb2-teq2.ll
    llvm/trunk/test/CodeGen/Thumb2/thumb2-tst.ll
    llvm/trunk/test/CodeGen/Thumb2/thumb2-tst2.ll

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Feb 16 01:23:59 2018
@@ -4044,11 +4044,10 @@ static SDValue ConvertBooleanCarryToCarr
   SDLoc DL(BoolCarry);
   EVT CarryVT = BoolCarry.getValueType();
 
-  APInt NegOne = APInt::getAllOnesValue(CarryVT.getScalarSizeInBits());
   // This converts the boolean value carry into the carry flag by doing
-  // ARMISD::ADDC Carry, ~0
-  return DAG.getNode(ARMISD::ADDC, DL, DAG.getVTList(CarryVT, MVT::i32),
-                     BoolCarry, DAG.getConstant(NegOne, DL, CarryVT));
+  // ARMISD::SUBC Carry, 1
+  return DAG.getNode(ARMISD::SUBC, DL, DAG.getVTList(CarryVT, MVT::i32),
+                     BoolCarry, DAG.getConstant(1, DL, CarryVT));
 }
 
 static SDValue ConvertCarryFlagToBooleanCarry(SDValue Flags, EVT VT,
@@ -7663,12 +7662,9 @@ static SDValue LowerADDSUBCARRY(SDValue
   SDVTList VTs = DAG.getVTList(VT, MVT::i32);
 
   SDValue Carry = Op.getOperand(2);
-  EVT CarryVT = Carry.getValueType();
 
   SDLoc DL(Op);
 
-  APInt NegOne = APInt::getAllOnesValue(CarryVT.getScalarSizeInBits());
-
   SDValue Result;
   if (Op.getOpcode() == ISD::ADDCARRY) {
     // This converts the boolean value carry into the carry flag.
@@ -10254,13 +10250,13 @@ static SDValue PerformAddcSubcCombine(SD
                                       const ARMSubtarget *Subtarget) {
   SelectionDAG &DAG(DCI.DAG);
 
-  if (N->getOpcode() == ARMISD::ADDC) {
-    // (ADDC (ADDE 0, 0, C), -1) -> C
+  if (N->getOpcode() == ARMISD::SUBC) {
+    // (SUBC (ADDE 0, 0, C), 1) -> C
     SDValue LHS = N->getOperand(0);
     SDValue RHS = N->getOperand(1);
     if (LHS->getOpcode() == ARMISD::ADDE &&
         isNullConstant(LHS->getOperand(0)) &&
-        isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
+        isNullConstant(LHS->getOperand(1)) && isOneConstant(RHS)) {
       return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
     }
   }
@@ -12493,6 +12489,89 @@ ARMTargetLowering::PerformCMOVCombine(SD
     }
   }
 
+  if (!VT.isInteger())
+      return SDValue();
+
+  // Materialize a boolean comparison for integers so we can avoid branching.
+  if (isNullConstant(FalseVal)) {
+    if (CC == ARMCC::EQ && isOneConstant(TrueVal)) {
+      if (!Subtarget->isThumb1Only() && Subtarget->hasV5TOps()) {
+        // If x == y then x - y == 0 and ARM's CLZ will return 32, shifting it
+        // right 5 bits will make that 32 be 1, otherwise it will be 0.
+        // CMOV 0, 1, ==, (CMPZ x, y) -> SRL (CTLZ (SUB x, y)), 5
+        SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
+        Res = DAG.getNode(ISD::SRL, dl, VT, DAG.getNode(ISD::CTLZ, dl, VT, Sub),
+                          DAG.getConstant(5, dl, MVT::i32));
+      } else {
+        // CMOV 0, 1, ==, (CMPZ x, y) ->
+        //     (ADDCARRY (SUB x, y), t:0, t:1)
+        // where t = (SUBCARRY 0, (SUB x, y), 0)
+        //
+        // The SUBCARRY computes 0 - (x - y) and this will give a borrow when
+        // x != y. In other words, a carry C == 1 when x == y, C == 0
+        // otherwise.
+        // The final ADDCARRY computes
+        //     x - y + (0 - (x - y)) + C == C
+        SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
+        SDVTList VTs = DAG.getVTList(VT, MVT::i32);
+        SDValue Neg = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, Sub);
+        // ISD::SUBCARRY returns a borrow but we want the carry here
+        // actually.
+        SDValue Carry =
+            DAG.getNode(ISD::SUB, dl, MVT::i32,
+                        DAG.getConstant(1, dl, MVT::i32), Neg.getValue(1));
+        Res = DAG.getNode(ISD::ADDCARRY, dl, VTs, Sub, Neg, Carry);
+      }
+    } else if (CC == ARMCC::NE && LHS != RHS &&
+               (!Subtarget->isThumb1Only() || isPowerOf2Constant(TrueVal))) {
+      // This seems pointless but will allow us to combine it further below.
+      // CMOV 0, z, !=, (CMPZ x, y) -> CMOV (SUB x, y), z, !=, (CMPZ x, y)
+      SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
+      Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, TrueVal, ARMcc,
+                        N->getOperand(3), Cmp);
+    }
+  } else if (isNullConstant(TrueVal)) {
+    if (CC == ARMCC::EQ && LHS != RHS &&
+        (!Subtarget->isThumb1Only() || isPowerOf2Constant(FalseVal))) {
+      // This seems pointless but will allow us to combine it further below
+      // Note that we change == for != as this is the dual for the case above.
+      // CMOV z, 0, ==, (CMPZ x, y) -> CMOV (SUB x, y), z, !=, (CMPZ x, y)
+      SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
+      Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, FalseVal,
+                        DAG.getConstant(ARMCC::NE, dl, MVT::i32),
+                        N->getOperand(3), Cmp);
+    }
+  }
+
+  // On Thumb1, the DAG above may be further combined if z is a power of 2
+  // (z == 2 ^ K).
+  // CMOV (SUB x, y), z, !=, (CMPZ x, y) ->
+  //       merge t3, t4
+  // where t1 = (SUBCARRY (SUB x, y), z, 0)
+  //       t2 = (SUBCARRY (SUB x, y), t1:0, t1:1)
+  //       t3 = if K != 0 then (SHL t2:0, K) else t2:0
+  //       t4 = (SUB 1, t2:1)   [ we want a carry, not a borrow ]
+  const APInt *TrueConst;
+  if (Subtarget->isThumb1Only() && CC == ARMCC::NE &&
+      (FalseVal.getOpcode() == ISD::SUB) && (FalseVal.getOperand(0) == LHS) &&
+      (FalseVal.getOperand(1) == RHS) &&
+      (TrueConst = isPowerOf2Constant(TrueVal))) {
+    SDVTList VTs = DAG.getVTList(VT, MVT::i32);
+    unsigned ShiftAmount = TrueConst->logBase2();
+    if (ShiftAmount)
+      TrueVal = DAG.getConstant(1, dl, VT);
+    SDValue Subc = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, TrueVal);
+    Res = DAG.getNode(ISD::SUBCARRY, dl, VTs, FalseVal, Subc, Subc.getValue(1));
+    // Make it a carry, not a borrow.
+    SDValue Carry = DAG.getNode(
+        ISD::SUB, dl, VT, DAG.getConstant(1, dl, MVT::i32), Res.getValue(1));
+    Res = DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Res, Carry);
+
+    if (ShiftAmount)
+      Res = DAG.getNode(ISD::SHL, dl, VT, Res,
+                        DAG.getConstant(ShiftAmount, dl, MVT::i32));
+  }
+
   if (Res.getNode()) {
     KnownBits Known;
     DAG.computeKnownBits(SDValue(N,0), Known);

Modified: llvm/trunk/test/CodeGen/ARM/and-load-combine.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/and-load-combine.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/and-load-combine.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/and-load-combine.ll Fri Feb 16 01:23:59 2018
@@ -7,41 +7,40 @@
 define arm_aapcscc zeroext i1 @cmp_xor8_short_short(i16* nocapture readonly %a,
                                                     i16* nocapture readonly %b) {
 ; ARM-LABEL: cmp_xor8_short_short:
-; ARM:         ldrb r2, [r0]
-; ARM-NEXT:    mov r0, #0
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrb r0, [r0]
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    teq r1, r2
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    eor r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_xor8_short_short:
-; ARMEB:        ldrb r2, [r0, #1]
-; ARMEB-NEXT:    mov r0, #0
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrb r0, [r0, #1]
 ; ARMEB-NEXT:    ldrb r1, [r1, #1]
-; ARMEB-NEXT:    teq r1, r2
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    eor r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_xor8_short_short:
-; THUMB1:         ldrb r0, [r0]
-; THUMB1-NEXT:    ldrb r2, [r1]
-; THUMB1-NEXT:    eors r2, r0
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r2, #0
-; THUMB1-NEXT:    beq .LBB0_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB0_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    eors r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_xor8_short_short:
-; THUMB2:         ldrb r2, [r0]
-; THUMB2-NEXT:    movs r0, #0
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrb r0, [r0]
 ; THUMB2-NEXT:    ldrb r1, [r1]
-; THUMB2-NEXT:    teq.w r1, r2
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    eors r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i16, i16* %a, align 2
@@ -55,41 +54,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_xor8_short_int(i16* nocapture readonly %a,
                                                   i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_xor8_short_int:
-; ARM:         ldrb r2, [r0]
-; ARM-NEXT:    mov r0, #0
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrb r0, [r0]
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    teq r1, r2
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    eor r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_xor8_short_int:
-; ARMEB:         ldrb r2, [r0, #1]
-; ARMEB-NEXT:    mov r0, #0
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrb r0, [r0, #1]
 ; ARMEB-NEXT:    ldrb r1, [r1, #3]
-; ARMEB-NEXT:    teq r1, r2
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    eor r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_xor8_short_int:
-; THUMB1:         ldrb r0, [r0]
-; THUMB1-NEXT:    ldrb r2, [r1]
-; THUMB1-NEXT:    eors r2, r0
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r2, #0
-; THUMB1-NEXT:    beq .LBB1_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB1_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    eors r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_xor8_short_int:
-; THUMB2:         ldrb r2, [r0]
-; THUMB2-NEXT:    movs r0, #0
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrb r0, [r0]
 ; THUMB2-NEXT:    ldrb r1, [r1]
-; THUMB2-NEXT:    teq.w r1, r2
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    eors r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i16, i16* %a, align 2
@@ -104,41 +102,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_xor8_int_int(i32* nocapture readonly %a,
                                                 i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_xor8_int_int:
-; ARM:         ldrb r2, [r0]
-; ARM-NEXT:    mov r0, #0
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrb r0, [r0]
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    teq r1, r2
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    eor r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_xor8_int_int:
-; ARMEB:         ldrb r2, [r0, #3]
-; ARMEB-NEXT:    mov r0, #0
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrb r0, [r0, #3]
 ; ARMEB-NEXT:    ldrb r1, [r1, #3]
-; ARMEB-NEXT:    teq r1, r2
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    eor r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_xor8_int_int:
-; THUMB1:         ldrb r0, [r0]
-; THUMB1-NEXT:    ldrb r2, [r1]
-; THUMB1-NEXT:    eors r2, r0
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r2, #0
-; THUMB1-NEXT:    beq .LBB2_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB2_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    eors r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_xor8_int_int:
-; THUMB2:         ldrb r2, [r0]
-; THUMB2-NEXT:    movs r0, #0
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrb r0, [r0]
 ; THUMB2-NEXT:    ldrb r1, [r1]
-; THUMB2-NEXT:    teq.w r1, r2
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    eors r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i32, i32* %a, align 4
@@ -152,41 +149,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_xor16(i32* nocapture readonly %a,
                                          i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_xor16:
-; ARM:         ldrh r2, [r0]
-; ARM-NEXT:    mov r0, #0
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrh r0, [r0]
 ; ARM-NEXT:    ldrh r1, [r1]
-; ARM-NEXT:    teq r1, r2
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    eor r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_xor16:
-; ARMEB:         ldrh r2, [r0, #2]
-; ARMEB-NEXT:    mov r0, #0
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrh r0, [r0, #2]
 ; ARMEB-NEXT:    ldrh r1, [r1, #2]
-; ARMEB-NEXT:    teq r1, r2
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    eor r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_xor16:
-; THUMB1:         ldrh r0, [r0]
-; THUMB1-NEXT:    ldrh r2, [r1]
-; THUMB1-NEXT:    eors r2, r0
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r2, #0
-; THUMB1-NEXT:    beq .LBB3_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB3_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrh r0, [r0]
+; THUMB1-NEXT:    ldrh r1, [r1]
+; THUMB1-NEXT:    eors r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_xor16:
-; THUMB2:         ldrh r2, [r0]
-; THUMB2-NEXT:    movs r0, #0
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrh r0, [r0]
 ; THUMB2-NEXT:    ldrh r1, [r1]
-; THUMB2-NEXT:    teq.w r1, r2
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    eors r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i32, i32* %a, align 4
@@ -200,41 +196,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_or8_short_short(i16* nocapture readonly %a,
                                                    i16* nocapture readonly %b) {
 ; ARM-LABEL: cmp_or8_short_short:
-; ARM:         ldrb r0, [r0]
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrb r0, [r0]
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    orrs r0, r1, r0
-; ARM-NEXT:    mov r0, #0
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    orr r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_or8_short_short:
-; ARMEB:         ldrb r0, [r0, #1]
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrb r0, [r0, #1]
 ; ARMEB-NEXT:    ldrb r1, [r1, #1]
-; ARMEB-NEXT:    orrs r0, r1, r0
-; ARMEB-NEXT:    mov r0, #0
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    orr r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_or8_short_short:
-; THUMB1:         ldrb r0, [r0]
-; THUMB1-NEXT:    ldrb r2, [r1]
-; THUMB1-NEXT:    orrs r2, r0
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r2, #0
-; THUMB1-NEXT:    beq .LBB4_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB4_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    orrs r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_or8_short_short:
-; THUMB2:         ldrb r0, [r0]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrb r0, [r0]
 ; THUMB2-NEXT:    ldrb r1, [r1]
 ; THUMB2-NEXT:    orrs r0, r1
-; THUMB2-NEXT:    mov.w r0, #0
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i16, i16* %a, align 2
@@ -248,41 +243,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_or8_short_int(i16* nocapture readonly %a,
                                                  i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_or8_short_int:
-; ARM:         ldrb r0, [r0]
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrb r0, [r0]
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    orrs r0, r1, r0
-; ARM-NEXT:    mov r0, #0
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    orr r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_or8_short_int:
-; ARMEB:         ldrb r0, [r0, #1]
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrb r0, [r0, #1]
 ; ARMEB-NEXT:    ldrb r1, [r1, #3]
-; ARMEB-NEXT:    orrs r0, r1, r0
-; ARMEB-NEXT:    mov r0, #0
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    orr r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_or8_short_int:
-; THUMB1:         ldrb r0, [r0]
-; THUMB1-NEXT:    ldrb r2, [r1]
-; THUMB1-NEXT:    orrs r2, r0
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r2, #0
-; THUMB1-NEXT:    beq .LBB5_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB5_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    orrs r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_or8_short_int:
-; THUMB2:         ldrb r0, [r0]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrb r0, [r0]
 ; THUMB2-NEXT:    ldrb r1, [r1]
 ; THUMB2-NEXT:    orrs r0, r1
-; THUMB2-NEXT:    mov.w r0, #0
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i16, i16* %a, align 2
@@ -297,41 +291,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_or8_int_int(i32* nocapture readonly %a,
                                                i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_or8_int_int:
-; ARM:         ldrb r0, [r0]
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrb r0, [r0]
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    orrs r0, r1, r0
-; ARM-NEXT:    mov r0, #0
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    orr r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_or8_int_int:
-; ARMEB:         ldrb r0, [r0, #3]
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrb r0, [r0, #3]
 ; ARMEB-NEXT:    ldrb r1, [r1, #3]
-; ARMEB-NEXT:    orrs r0, r1, r0
-; ARMEB-NEXT:    mov r0, #0
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    orr r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_or8_int_int:
-; THUMB1:         ldrb r0, [r0]
-; THUMB1-NEXT:    ldrb r2, [r1]
-; THUMB1-NEXT:    orrs r2, r0
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r2, #0
-; THUMB1-NEXT:    beq .LBB6_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB6_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    orrs r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_or8_int_int:
-; THUMB2:         ldrb r0, [r0]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrb r0, [r0]
 ; THUMB2-NEXT:    ldrb r1, [r1]
 ; THUMB2-NEXT:    orrs r0, r1
-; THUMB2-NEXT:    mov.w r0, #0
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i32, i32* %a, align 4
@@ -345,41 +338,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_or16(i32* nocapture readonly %a,
                                         i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_or16:
-; ARM:         ldrh r0, [r0]
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrh r0, [r0]
 ; ARM-NEXT:    ldrh r1, [r1]
-; ARM-NEXT:    orrs r0, r1, r0
-; ARM-NEXT:    mov r0, #0
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    orr r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_or16:
-; ARMEB:         ldrh r0, [r0, #2]
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrh r0, [r0, #2]
 ; ARMEB-NEXT:    ldrh r1, [r1, #2]
-; ARMEB-NEXT:    orrs r0, r1, r0
-; ARMEB-NEXT:    mov r0, #0
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    orr r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_or16:
-; THUMB1:         ldrh r0, [r0]
-; THUMB1-NEXT:    ldrh r2, [r1]
-; THUMB1-NEXT:    orrs r2, r0
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r2, #0
-; THUMB1-NEXT:    beq .LBB7_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB7_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrh r0, [r0]
+; THUMB1-NEXT:    ldrh r1, [r1]
+; THUMB1-NEXT:    orrs r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_or16:
-; THUMB2:         ldrh r0, [r0]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrh r0, [r0]
 ; THUMB2-NEXT:    ldrh r1, [r1]
 ; THUMB2-NEXT:    orrs r0, r1
-; THUMB2-NEXT:    mov.w r0, #0
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i32, i32* %a, align 4
@@ -393,40 +385,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_and8_short_short(i16* nocapture readonly %a,
                                                     i16* nocapture readonly %b) {
 ; ARM-LABEL: cmp_and8_short_short:
-; ARM:         ldrb r2, [r0]
-; ARM-NEXT:    mov r0, #0
+; ARM:       @ %bb.0: @ %entry
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    tst r2, r1
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    ldrb r0, [r0]
+; ARM-NEXT:    and r0, r0, r1
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_and8_short_short:
-; ARMEB:         ldrb r2, [r0, #1]
-; ARMEB-NEXT:    mov r0, #0
+; ARMEB:       @ %bb.0: @ %entry
 ; ARMEB-NEXT:    ldrb r1, [r1, #1]
-; ARMEB-NEXT:    tst r2, r1
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    ldrb r0, [r0, #1]
+; ARMEB-NEXT:    and r0, r0, r1
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_and8_short_short:
-; THUMB1:         ldrb r2, [r1]
-; THUMB1-NEXT:    ldrb r3, [r0]
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    tst r3, r2
-; THUMB1-NEXT:    beq .LBB8_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB8_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    ldrb r2, [r0]
+; THUMB1-NEXT:    ands r2, r1
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r2
+; THUMB1-NEXT:    adcs r0, r2
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_and8_short_short:
-; THUMB2:         ldrb r2, [r0]
-; THUMB2-NEXT:    movs r0, #0
+; THUMB2:       @ %bb.0: @ %entry
 ; THUMB2-NEXT:    ldrb r1, [r1]
-; THUMB2-NEXT:    tst r2, r1
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    ldrb r0, [r0]
+; THUMB2-NEXT:    ands r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i16, i16* %a, align 2
@@ -440,40 +432,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_and8_short_int(i16* nocapture readonly %a,
                                                   i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_and8_short_int:
-; ARM:         ldrb r2, [r0]
-; ARM-NEXT:    mov r0, #0
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldrb r0, [r0]
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    tst r1, r2
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    and r0, r1, r0
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_and8_short_int:
-; ARMEB:         ldrb r2, [r0, #1]
-; ARMEB-NEXT:    mov r0, #0
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldrb r0, [r0, #1]
 ; ARMEB-NEXT:    ldrb r1, [r1, #3]
-; ARMEB-NEXT:    tst r1, r2
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    and r0, r1, r0
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_and8_short_int:
-; THUMB1:         ldrb r2, [r0]
-; THUMB1-NEXT:    ldrb r3, [r1]
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    tst r3, r2
-; THUMB1-NEXT:    beq .LBB9_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB9_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    ands r1, r0
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_and8_short_int:
-; THUMB2:         ldrb r2, [r0]
-; THUMB2-NEXT:    movs r0, #0
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrb r0, [r0]
 ; THUMB2-NEXT:    ldrb r1, [r1]
-; THUMB2-NEXT:    tst r1, r2
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    ands r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i16, i16* %a, align 2
@@ -488,40 +480,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_and8_int_int(i32* nocapture readonly %a,
                                                 i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_and8_int_int:
-; ARM:         ldrb r2, [r0]
-; ARM-NEXT:    mov r0, #0
+; ARM:       @ %bb.0: @ %entry
 ; ARM-NEXT:    ldrb r1, [r1]
-; ARM-NEXT:    tst r2, r1
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    ldrb r0, [r0]
+; ARM-NEXT:    and r0, r0, r1
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_and8_int_int:
-; ARMEB:         ldrb r2, [r0, #3]
-; ARMEB-NEXT:    mov r0, #0
+; ARMEB:       @ %bb.0: @ %entry
 ; ARMEB-NEXT:    ldrb r1, [r1, #3]
-; ARMEB-NEXT:    tst r2, r1
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    ldrb r0, [r0, #3]
+; ARMEB-NEXT:    and r0, r0, r1
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_and8_int_int:
-; THUMB1:         ldrb r2, [r1]
-; THUMB1-NEXT:    ldrb r3, [r0]
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    tst r3, r2
-; THUMB1-NEXT:    beq .LBB10_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB10_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrb r1, [r1]
+; THUMB1-NEXT:    ldrb r2, [r0]
+; THUMB1-NEXT:    ands r2, r1
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r2
+; THUMB1-NEXT:    adcs r0, r2
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_and8_int_int:
-; THUMB2:         ldrb r2, [r0]
-; THUMB2-NEXT:    movs r0, #0
+; THUMB2:       @ %bb.0: @ %entry
 ; THUMB2-NEXT:    ldrb r1, [r1]
-; THUMB2-NEXT:    tst r2, r1
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    ldrb r0, [r0]
+; THUMB2-NEXT:    ands r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i32, i32* %a, align 4
@@ -535,40 +527,40 @@ entry:
 define arm_aapcscc zeroext i1 @cmp_and16(i32* nocapture readonly %a,
                                          i32* nocapture readonly %b) {
 ; ARM-LABEL: cmp_and16:
-; ARM:         ldrh r2, [r0]
-; ARM-NEXT:    mov r0, #0
+; ARM:       @ %bb.0: @ %entry
 ; ARM-NEXT:    ldrh r1, [r1]
-; ARM-NEXT:    tst r2, r1
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    ldrh r0, [r0]
+; ARM-NEXT:    and r0, r0, r1
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: cmp_and16:
-; ARMEB:         ldrh r2, [r0, #2]
-; ARMEB-NEXT:    mov r0, #0
+; ARMEB:       @ %bb.0: @ %entry
 ; ARMEB-NEXT:    ldrh r1, [r1, #2]
-; ARMEB-NEXT:    tst r2, r1
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    ldrh r0, [r0, #2]
+; ARMEB-NEXT:    and r0, r0, r1
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: cmp_and16:
-; THUMB1:         ldrh r2, [r1]
-; THUMB1-NEXT:    ldrh r3, [r0]
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    tst r3, r2
-; THUMB1-NEXT:    beq .LBB11_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB11_2: @ %entry
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldrh r1, [r1]
+; THUMB1-NEXT:    ldrh r2, [r0]
+; THUMB1-NEXT:    ands r2, r1
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r2
+; THUMB1-NEXT:    adcs r0, r2
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: cmp_and16:
-; THUMB2:         ldrh r2, [r0]
-; THUMB2-NEXT:    movs r0, #0
+; THUMB2:       @ %bb.0: @ %entry
 ; THUMB2-NEXT:    ldrh r1, [r1]
-; THUMB2-NEXT:    tst r2, r1
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    ldrh r0, [r0]
+; THUMB2-NEXT:    ands r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i32, i32* %a, align 4
@@ -581,28 +573,32 @@ entry:
 
 define arm_aapcscc i32 @add_and16(i32* nocapture readonly %a, i32 %y, i32 %z) {
 ; ARM-LABEL: add_and16:
-; ARM:         add r1, r1, r2
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    add r1, r1, r2
 ; ARM-NEXT:    ldrh r0, [r0]
 ; ARM-NEXT:    uxth r1, r1
 ; ARM-NEXT:    orr r0, r0, r1
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: add_and16:
-; ARMEB:         add r1, r1, r2
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    add r1, r1, r2
 ; ARMEB-NEXT:    ldrh r0, [r0, #2]
 ; ARMEB-NEXT:    uxth r1, r1
 ; ARMEB-NEXT:    orr r0, r0, r1
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: add_and16:
-; THUMB1:         adds r1, r1, r2
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    adds r1, r1, r2
 ; THUMB1-NEXT:    uxth r1, r1
 ; THUMB1-NEXT:    ldrh r0, [r0]
 ; THUMB1-NEXT:    orrs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: add_and16:
-; THUMB2:         add r1, r2
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    add r1, r2
 ; THUMB2-NEXT:    ldrh r0, [r0]
 ; THUMB2-NEXT:    uxth r1, r1
 ; THUMB2-NEXT:    orrs r0, r1
@@ -617,7 +613,8 @@ entry:
 
 define arm_aapcscc i32 @test1(i32* %a, i32* %b, i32 %x, i32 %y) {
 ; ARM-LABEL: test1:
-; ARM:         mul r2, r2, r3
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    mul r2, r2, r3
 ; ARM-NEXT:    ldrh r1, [r1]
 ; ARM-NEXT:    ldrh r0, [r0]
 ; ARM-NEXT:    eor r0, r0, r1
@@ -626,7 +623,8 @@ define arm_aapcscc i32 @test1(i32* %a, i
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: test1:
-; ARMEB:         mul r2, r2, r3
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    mul r2, r2, r3
 ; ARMEB-NEXT:    ldrh r1, [r1, #2]
 ; ARMEB-NEXT:    ldrh r0, [r0, #2]
 ; ARMEB-NEXT:    eor r0, r0, r1
@@ -635,16 +633,19 @@ define arm_aapcscc i32 @test1(i32* %a, i
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: test1:
-; THUMB1:         ldrh r1, [r1]
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    push {r4, lr}
+; THUMB1-NEXT:    ldrh r1, [r1]
 ; THUMB1-NEXT:    ldrh r4, [r0]
 ; THUMB1-NEXT:    eors r4, r1
 ; THUMB1-NEXT:    muls r2, r3, r2
 ; THUMB1-NEXT:    uxth r0, r2
 ; THUMB1-NEXT:    orrs r0, r4
-; THUMB1-NEXT:    pop
+; THUMB1-NEXT:    pop {r4, pc}
 ;
 ; THUMB2-LABEL: test1:
-; THUMB2:         ldrh r1, [r1]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrh r1, [r1]
 ; THUMB2-NEXT:    ldrh r0, [r0]
 ; THUMB2-NEXT:    eors r0, r1
 ; THUMB2-NEXT:    mul r1, r2, r3
@@ -663,7 +664,8 @@ entry:
 
 define arm_aapcscc i32 @test2(i32* %a, i32* %b, i32 %x, i32 %y) {
 ; ARM-LABEL: test2:
-; ARM:         ldr r1, [r1]
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldr r1, [r1]
 ; ARM-NEXT:    ldr r0, [r0]
 ; ARM-NEXT:    mul r1, r2, r1
 ; ARM-NEXT:    eor r0, r0, r3
@@ -672,7 +674,8 @@ define arm_aapcscc i32 @test2(i32* %a, i
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: test2:
-; ARMEB:         ldr r1, [r1]
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldr r1, [r1]
 ; ARMEB-NEXT:    ldr r0, [r0]
 ; ARMEB-NEXT:    mul r1, r2, r1
 ; ARMEB-NEXT:    eor r0, r0, r3
@@ -681,7 +684,8 @@ define arm_aapcscc i32 @test2(i32* %a, i
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: test2:
-; THUMB1:         ldr r1, [r1]
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldr r1, [r1]
 ; THUMB1-NEXT:    muls r1, r2, r1
 ; THUMB1-NEXT:    ldr r0, [r0]
 ; THUMB1-NEXT:    eors r0, r3
@@ -690,7 +694,8 @@ define arm_aapcscc i32 @test2(i32* %a, i
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: test2:
-; THUMB2:         ldr r1, [r1]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldr r1, [r1]
 ; THUMB2-NEXT:    ldr r0, [r0]
 ; THUMB2-NEXT:    muls r1, r2, r1
 ; THUMB2-NEXT:    eors r0, r3
@@ -709,7 +714,8 @@ entry:
 
 define arm_aapcscc i32 @test3(i32* %a, i32* %b, i32 %x, i16* %y) {
 ; ARM-LABEL: test3:
-; ARM:         ldr r0, [r0]
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldr r0, [r0]
 ; ARM-NEXT:    mul r1, r2, r0
 ; ARM-NEXT:    ldrh r2, [r3]
 ; ARM-NEXT:    eor r0, r0, r2
@@ -718,7 +724,8 @@ define arm_aapcscc i32 @test3(i32* %a, i
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: test3:
-; ARMEB:         ldr r0, [r0]
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldr r0, [r0]
 ; ARMEB-NEXT:    mul r1, r2, r0
 ; ARMEB-NEXT:    ldrh r2, [r3]
 ; ARMEB-NEXT:    eor r0, r0, r2
@@ -727,7 +734,8 @@ define arm_aapcscc i32 @test3(i32* %a, i
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: test3:
-; THUMB1:         ldr r0, [r0]
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    ldr r0, [r0]
 ; THUMB1-NEXT:    muls r2, r0, r2
 ; THUMB1-NEXT:    ldrh r1, [r3]
 ; THUMB1-NEXT:    eors r1, r0
@@ -736,7 +744,8 @@ define arm_aapcscc i32 @test3(i32* %a, i
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: test3:
-; THUMB2:         ldr r0, [r0]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldr r0, [r0]
 ; THUMB2-NEXT:    mul r1, r2, r0
 ; THUMB2-NEXT:    ldrh r2, [r3]
 ; THUMB2-NEXT:    eors r0, r2
@@ -756,7 +765,8 @@ entry:
 
 define arm_aapcscc i32 @test4(i32* %a, i32* %b, i32 %x, i32 %y) {
 ; ARM-LABEL: test4:
-; ARM:         mul r2, r2, r3
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    mul r2, r2, r3
 ; ARM-NEXT:    ldrh r1, [r1]
 ; ARM-NEXT:    ldrh r0, [r0]
 ; ARM-NEXT:    eor r0, r0, r1
@@ -765,7 +775,8 @@ define arm_aapcscc i32 @test4(i32* %a, i
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: test4:
-; ARMEB:         mul r2, r2, r3
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    mul r2, r2, r3
 ; ARMEB-NEXT:    ldrh r1, [r1, #2]
 ; ARMEB-NEXT:    ldrh r0, [r0, #2]
 ; ARMEB-NEXT:    eor r0, r0, r1
@@ -774,16 +785,19 @@ define arm_aapcscc i32 @test4(i32* %a, i
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: test4:
-; THUMB1:         ldrh r1, [r1]
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    push {r4, lr}
+; THUMB1-NEXT:    ldrh r1, [r1]
 ; THUMB1-NEXT:    ldrh r4, [r0]
 ; THUMB1-NEXT:    eors r4, r1
 ; THUMB1-NEXT:    muls r2, r3, r2
 ; THUMB1-NEXT:    uxth r0, r2
 ; THUMB1-NEXT:    orrs r0, r4
-; THUMB1-NEXT:    pop
+; THUMB1-NEXT:    pop {r4, pc}
 ;
 ; THUMB2-LABEL: test4:
-; THUMB2:         ldrh r1, [r1]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldrh r1, [r1]
 ; THUMB2-NEXT:    ldrh r0, [r0]
 ; THUMB2-NEXT:    eors r0, r1
 ; THUMB2-NEXT:    mul r1, r2, r3
@@ -802,7 +816,8 @@ entry:
 
 define arm_aapcscc i32 @test5(i32* %a, i32* %b, i32 %x, i16 zeroext %y) {
 ; ARM-LABEL: test5:
-; ARM:         ldr r1, [r1]
+; ARM:       @ %bb.0: @ %entry
+; ARM-NEXT:    ldr r1, [r1]
 ; ARM-NEXT:    ldrh r0, [r0]
 ; ARM-NEXT:    mul r1, r2, r1
 ; ARM-NEXT:    eor r0, r0, r3
@@ -811,7 +826,8 @@ define arm_aapcscc i32 @test5(i32* %a, i
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: test5:
-; ARMEB:         ldr r1, [r1]
+; ARMEB:       @ %bb.0: @ %entry
+; ARMEB-NEXT:    ldr r1, [r1]
 ; ARMEB-NEXT:    ldrh r0, [r0, #2]
 ; ARMEB-NEXT:    mul r1, r2, r1
 ; ARMEB-NEXT:    eor r0, r0, r3
@@ -820,16 +836,19 @@ define arm_aapcscc i32 @test5(i32* %a, i
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: test5:
-; THUMB1:         ldrh r4, [r0]
+; THUMB1:       @ %bb.0: @ %entry
+; THUMB1-NEXT:    push {r4, lr}
+; THUMB1-NEXT:    ldrh r4, [r0]
 ; THUMB1-NEXT:    eors r4, r3
 ; THUMB1-NEXT:    ldr r0, [r1]
 ; THUMB1-NEXT:    muls r0, r2, r0
 ; THUMB1-NEXT:    uxth r0, r0
 ; THUMB1-NEXT:    orrs r0, r4
-; THUMB1-NEXT:    pop
+; THUMB1-NEXT:    pop {r4, pc}
 ;
 ; THUMB2-LABEL: test5:
-; THUMB2:         ldr r1, [r1]
+; THUMB2:       @ %bb.0: @ %entry
+; THUMB2-NEXT:    ldr r1, [r1]
 ; THUMB2-NEXT:    ldrh r0, [r0]
 ; THUMB2-NEXT:    muls r1, r2, r1
 ; THUMB2-NEXT:    eors r0, r3
@@ -851,46 +870,42 @@ define arm_aapcscc i1 @test6(i8* %x, i8
 ; ARM-LABEL: test6:
 ; ARM:       @ %bb.0: @ %entry
 ; ARM-NEXT:    ldrb r0, [r0]
-; ARM-NEXT:    uxtb r2, r2
-; ARM-NEXT:    and r1, r0, r1
-; ARM-NEXT:    mov r0, #0
-; ARM-NEXT:    cmp r1, r2
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    and r0, r0, r1
+; ARM-NEXT:    uxtb r1, r2
+; ARM-NEXT:    sub r0, r0, r1
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: test6:
 ; ARMEB:       @ %bb.0: @ %entry
 ; ARMEB-NEXT:    ldrb r0, [r0]
-; ARMEB-NEXT:    uxtb r2, r2
-; ARMEB-NEXT:    and r1, r0, r1
-; ARMEB-NEXT:    mov r0, #0
-; ARMEB-NEXT:    cmp r1, r2
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    and r0, r0, r1
+; ARMEB-NEXT:    uxtb r1, r2
+; ARMEB-NEXT:    sub r0, r0, r1
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: test6:
 ; THUMB1:       @ %bb.0: @ %entry
-; THUMB1-NEXT:    ldrb r3, [r0]
-; THUMB1-NEXT:    ands r3, r1
-; THUMB1-NEXT:    uxtb r2, r2
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r3, r2
-; THUMB1-NEXT:    beq .LBB18_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB18_2: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ands r0, r1
+; THUMB1-NEXT:    uxtb r1, r2
+; THUMB1-NEXT:    subs r1, r0, r1
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: test6:
 ; THUMB2:       @ %bb.0: @ %entry
 ; THUMB2-NEXT:    ldrb r0, [r0]
-; THUMB2-NEXT:    uxtb r2, r2
-; THUMB2-NEXT:    ands r1, r0
-; THUMB2-NEXT:    movs r0, #0
-; THUMB2-NEXT:    cmp r1, r2
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    ands r0, r1
+; THUMB2-NEXT:    uxtb r1, r2
+; THUMB2-NEXT:    subs r0, r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i8, i8* %x, align 4
@@ -903,46 +918,42 @@ define arm_aapcscc i1 @test7(i16* %x, i1
 ; ARM-LABEL: test7:
 ; ARM:       @ %bb.0: @ %entry
 ; ARM-NEXT:    ldrb r0, [r0]
-; ARM-NEXT:    uxtb r2, r2
-; ARM-NEXT:    and r1, r0, r1
-; ARM-NEXT:    mov r0, #0
-; ARM-NEXT:    cmp r1, r2
-; ARM-NEXT:    movweq r0, #1
+; ARM-NEXT:    and r0, r0, r1
+; ARM-NEXT:    uxtb r1, r2
+; ARM-NEXT:    sub r0, r0, r1
+; ARM-NEXT:    clz r0, r0
+; ARM-NEXT:    lsr r0, r0, #5
 ; ARM-NEXT:    bx lr
 ;
 ; ARMEB-LABEL: test7:
 ; ARMEB:       @ %bb.0: @ %entry
 ; ARMEB-NEXT:    ldrb r0, [r0, #1]
-; ARMEB-NEXT:    uxtb r2, r2
-; ARMEB-NEXT:    and r1, r0, r1
-; ARMEB-NEXT:    mov r0, #0
-; ARMEB-NEXT:    cmp r1, r2
-; ARMEB-NEXT:    movweq r0, #1
+; ARMEB-NEXT:    and r0, r0, r1
+; ARMEB-NEXT:    uxtb r1, r2
+; ARMEB-NEXT:    sub r0, r0, r1
+; ARMEB-NEXT:    clz r0, r0
+; ARMEB-NEXT:    lsr r0, r0, #5
 ; ARMEB-NEXT:    bx lr
 ;
 ; THUMB1-LABEL: test7:
 ; THUMB1:       @ %bb.0: @ %entry
-; THUMB1-NEXT:    ldrb r3, [r0]
-; THUMB1-NEXT:    ands r3, r1
-; THUMB1-NEXT:    uxtb r2, r2
-; THUMB1-NEXT:    movs r0, #1
-; THUMB1-NEXT:    movs r1, #0
-; THUMB1-NEXT:    cmp r3, r2
-; THUMB1-NEXT:    beq .LBB19_2
-; THUMB1-NEXT:  @ %bb.1: @ %entry
-; THUMB1-NEXT:    mov r0, r1
-; THUMB1-NEXT:  .LBB19_2: @ %entry
+; THUMB1-NEXT:    ldrb r0, [r0]
+; THUMB1-NEXT:    ands r0, r1
+; THUMB1-NEXT:    uxtb r1, r2
+; THUMB1-NEXT:    subs r1, r0, r1
+; THUMB1-NEXT:    movs r0, #0
+; THUMB1-NEXT:    subs r0, r0, r1
+; THUMB1-NEXT:    adcs r0, r1
 ; THUMB1-NEXT:    bx lr
 ;
 ; THUMB2-LABEL: test7:
 ; THUMB2:       @ %bb.0: @ %entry
 ; THUMB2-NEXT:    ldrb r0, [r0]
-; THUMB2-NEXT:    uxtb r2, r2
-; THUMB2-NEXT:    ands r1, r0
-; THUMB2-NEXT:    movs r0, #0
-; THUMB2-NEXT:    cmp r1, r2
-; THUMB2-NEXT:    it eq
-; THUMB2-NEXT:    moveq r0, #1
+; THUMB2-NEXT:    ands r0, r1
+; THUMB2-NEXT:    uxtb r1, r2
+; THUMB2-NEXT:    subs r0, r0, r1
+; THUMB2-NEXT:    clz r0, r0
+; THUMB2-NEXT:    lsrs r0, r0, #5
 ; THUMB2-NEXT:    bx lr
 entry:
   %0 = load i16, i16* %x, align 4

Modified: llvm/trunk/test/CodeGen/ARM/atomic-cmpxchg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/atomic-cmpxchg.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/atomic-cmpxchg.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/atomic-cmpxchg.ll Fri Feb 16 01:23:59 2018
@@ -16,20 +16,17 @@ entry:
 
 ; CHECK-ARM-LABEL: test_cmpxchg_res_i8
 ; CHECK-ARM: bl __sync_val_compare_and_swap_1
-; CHECK-ARM: mov [[REG:r[0-9]+]], #0
-; CHECK-ARM: cmp r0, {{r[0-9]+}}
-; CHECK-ARM: moveq [[REG]], #1
-; CHECK-ARM: mov r0, [[REG]]
+; CHECK-ARM: sub r0, r0, {{r[0-9]+}}
+; CHECK-ARM: rsbs [[REG:r[0-9]+]], r0, #0
+; CHECK-ARM: adc r0, r0, [[REG]]
 
 ; CHECK-THUMB-LABEL: test_cmpxchg_res_i8
 ; CHECK-THUMB: bl __sync_val_compare_and_swap_1
 ; CHECK-THUMB-NOT: mov [[R1:r[0-7]]], r0
-; CHECK-THUMB: movs [[R1:r[0-7]]], r0
-; CHECK-THUMB: movs r0, #1
-; CHECK-THUMB: movs [[R2:r[0-9]+]], #0
-; CHECK-THUMB: cmp [[R1]], {{r[0-9]+}}
-; CHECK-THUMB: beq
-; CHECK-THUMB: movs r0, [[R2]]
+; CHECK-THUMB: subs [[R1:r[0-7]]], r0, {{r[0-9]+}}
+; CHECK-THUMB: movs r0, #0
+; CHECK-THUMB: subs r0, r0, [[R1]]
+; CHECK-THUMB: adcs r0, [[R1]]
 
 ; CHECK-ARMV6-LABEL: test_cmpxchg_res_i8:
 ; CHECK-ARMV6-NEXT:  .fnstart
@@ -48,15 +45,11 @@ entry:
 ; CHECK-THUMBV6-LABEL: test_cmpxchg_res_i8:
 ; CHECK-THUMBV6:       mov [[EXPECTED:r[0-9]+]], r1
 ; CHECK-THUMBV6-NEXT:  bl __sync_val_compare_and_swap_1
-; CHECK-THUMBV6-NEXT:  mov [[RES:r[0-9]+]], r0
-; CHECK-THUMBV6-NEXT:  uxtb [[EXPECTED_ZEXT:r[0-9]+]], [[EXPECTED]]
-; CHECK-THUMBV6-NEXT:  movs r0, #1
-; CHECK-THUMBV6-NEXT:  movs [[ZERO:r[0-9]+]], #0
-; CHECK-THUMBV6-NEXT:  cmp [[RES]], [[EXPECTED_ZEXT]]
-; CHECK-THUMBV6-NEXT:  beq [[END:.LBB[0-9_]+]]
-; CHECK-THUMBV6-NEXT:  mov r0, [[ZERO]]
-; CHECK-THUMBV6-NEXT: [[END]]:
-; CHECK-THUMBV6-NEXT:  pop {{.*}}pc}
+; CHECK-THUMBV6-NEXT:  uxtb r1, r4
+; CHECK-THUMBV6-NEXT:  subs [[R1:r[0-7]]], r0, {{r[0-9]+}}
+; CHECK-THUMBV6-NEXT:  movs r0, #0
+; CHECK-THUMBV6-NEXT:  subs r0, r0, [[R1]]
+; CHECK-THUMBV6-NEXT:  adcs r0, [[R1]]
 
 ; CHECK-ARMV7-LABEL: test_cmpxchg_res_i8:
 ; CHECK-ARMV7-NEXT: .fnstart

Modified: llvm/trunk/test/CodeGen/ARM/cmn.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/cmn.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/cmn.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/cmn.ll Fri Feb 16 01:23:59 2018
@@ -7,8 +7,8 @@ entry:
 ; CHECK-NOT: mvn
 ; CHECK:     cmn
   %cmp = icmp sgt i32 %a, -78
-  %. = zext i1 %cmp to i32
-  ret i32 %.
+  %ret = select i1 %cmp, i32 42, i32 24
+  ret i32 %ret
 }
 
 define i32 @compare_r_eq(i32 %a, i32 %b) {
@@ -17,6 +17,6 @@ entry:
 ; CHECK: cmn
   %sub = sub nsw i32 0, %b
   %cmp = icmp eq i32 %a, %sub
-  %. = zext i1 %cmp to i32
-  ret i32 %.
+  %ret = select i1 %cmp, i32 42, i32 24
+  ret i32 %ret
 }

Modified: llvm/trunk/test/CodeGen/ARM/cmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/cmp.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/cmp.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/cmp.ll Fri Feb 16 01:23:59 2018
@@ -3,42 +3,35 @@
 
 define i1 @f1(i32 %a, i32 %b) {
 ; CHECK-LABEL: f1:
-; CHECK: mov r2, #0
-; CHECK: cmp r0, r1
-; CHECK: movwne r2, #1
-; CHECK: mov r0, r2
-; CHECK-T2: mov{{.*}} r2, #0
-; CHECK-T2: cmp r0, r1
-; CHECK-T2: movne r2, #1
-; CHECK-T2: mov r0, r2
+; CHECK: subs r0, r0, r1
+; CHECK: movwne r0, #1
+; CHECK-T2: subs    r0, r0, r1
+; CHECK-T2: it      ne
+; CHECK-T2: movne   r0, #1
     %tmp = icmp ne i32 %a, %b
     ret i1 %tmp
 }
 
 define i1 @f2(i32 %a, i32 %b) {
 ; CHECK-LABEL: f2:
-; CHECK: mov r2, #0
-; CHECK: cmp r0, r1
-; CHECK: movweq r2, #1
-; CHECK: mov r0, r2
-; CHECK-T2: mov{{.*}} r2, #0
-; CHECK-T2: cmp r0, r1
-; CHECK-T2: moveq r2, #1
-; CHECK-T2: mov r0, r2
+; CHECK: sub     r0, r0, r1
+; CHECK: clz     r0, r0
+; CHECK: lsr     r0, r0, #5
+; CHECK-T2: subs    r0, r0, r1
+; CHECK-T2: clz     r0, r0
+; CHECK-T2: lsrs    r0, r0, #5
     %tmp = icmp eq i32 %a, %b
     ret i1 %tmp
 }
 
 define i1 @f6(i32 %a, i32 %b) {
 ; CHECK-LABEL: f6:
-; CHECK: mov r2, #0
-; CHECK: cmp {{.*}}, r1, lsl #5
-; CHECK: movweq r2, #1
-; CHECK: mov r0, r2
-; CHECK-T2: mov{{.*}} r2, #0
-; CHECK-T2: cmp.w r0, r1, lsl #5
-; CHECK-T2: moveq r2, #1
-; CHECK-T2: mov r0, r2
+; CHECK: sub     r0, r0, r1, lsl #5
+; CHECK: clz     r0, r0
+; CHECK: lsr     r0, r0, #5
+; CHECK-T2: sub.w   r0, r0, r1, lsl #5
+; CHECK-T2: clz     r0, r0
+; CHECK-T2: lsrs    r0, r0, #5
     %tmp = shl i32 %b, 5
     %tmp1 = icmp eq i32 %a, %tmp
     ret i1 %tmp1
@@ -46,14 +39,15 @@ define i1 @f6(i32 %a, i32 %b) {
 
 define i1 @f7(i32 %a, i32 %b) {
 ; CHECK-LABEL: f7:
-; CHECK: mov r2, #0
-; CHECK: cmp r0, r1, lsr #6
-; CHECK: movwne r2, #1
-; CHECK: mov r0, r2
-; CHECK-T2: mov{{.*}} r2, #0
-; CHECK-T2: cmp.w r0, r1, lsr #6
-; CHECK-T2: movne r2, #1
-; CHECK-T2: mov r0, r2
+; CHECK: sub     r2, r0, r1, lsr #6
+; CHECK: cmp     r0, r1, lsr #6
+; CHECK: movwne  r2, #1
+; CHECK: mov     r0, r2
+; CHECK-T2: sub.w   r2, r0, r1, lsr #6
+; CHECK-T2: cmp.w   r0, r1, lsr #6
+; CHECK-T2: it      ne
+; CHECK-T2: movne   r2, #1
+; CHECK-T2: mov     r0, r2
     %tmp = lshr i32 %b, 6
     %tmp1 = icmp ne i32 %a, %tmp
     ret i1 %tmp1
@@ -61,14 +55,12 @@ define i1 @f7(i32 %a, i32 %b) {
 
 define i1 @f8(i32 %a, i32 %b) {
 ; CHECK-LABEL: f8:
-; CHECK: mov r2, #0
-; CHECK: cmp r0, r1, asr #7
-; CHECK: movweq r2, #1
-; CHECK: mov r0, r2
-; CHECK-T2: mov{{.*}} r2, #0
-; CHECK-T2: cmp.w r0, r1, asr #7
-; CHECK-T2: moveq r2, #1
-; CHECK-T2: mov r0, r2
+; CHECK: sub     r0, r0, r1, asr #7
+; CHECK: clz     r0, r0
+; CHECK: lsr     r0, r0, #5
+; CHECK-T2: sub.w   r0, r0, r1, asr #7
+; CHECK-T2: clz     r0, r0
+; CHECK-T2: lsrs    r0, r0, #5
     %tmp = ashr i32 %b, 7
     %tmp1 = icmp eq i32 %a, %tmp
     ret i1 %tmp1
@@ -76,14 +68,15 @@ define i1 @f8(i32 %a, i32 %b) {
 
 define i1 @f9(i32 %a) {
 ; CHECK-LABEL: f9:
-; CHECK: mov r1, #0
-; CHECK: cmp r0, r0, ror #8
-; CHECK: movwne r1, #1
-; CHECK: mov r0, r1
-; CHECK-T2: mov{{.*}} r1, #0
-; CHECK-T2: cmp.w r0, r0, ror #8
-; CHECK-T2: movne r1, #1
-; CHECK-T2: mov r0, r1
+; CHECK: sub     r1, r0, r0, ror #8
+; CHECK: cmp     r0, r0, ror #8
+; CHECK: movwne  r1, #1
+; CHECK: mov     r0, r1
+; CHECK-T2: sub.w   r1, r0, r0, ror #8
+; CHECK-T2: cmp.w   r0, r0, ror #8
+; CHECK-T2: it      ne
+; CHECK-T2: movne   r1, #1
+; CHECK-T2: mov     r0, r1
     %l8 = shl i32 %a, 24
     %r8 = lshr i32 %a, 8
     %tmp = or i32 %l8, %r8

Modified: llvm/trunk/test/CodeGen/ARM/cmpxchg-O0.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/cmpxchg-O0.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/cmpxchg-O0.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/cmpxchg-O0.ll Fri Feb 16 01:23:59 2018
@@ -17,9 +17,11 @@ define { i8, i1 } @test_cmpxchg_8(i8* %a
 ; CHECK:     cmp{{(\.w)?}} [[STATUS]], #0
 ; CHECK:     bne [[RETRY]]
 ; CHECK: [[DONE]]:
-; CHECK:     uxtb [[DESIRED_ZEXT:r[0-9]+]], [[DESIRED]]
-; CHECK:     cmp{{(\.w)?}} [[OLD]], [[DESIRED_ZEXT]]
-; CHECK:     {{moveq|movweq}} {{r[0-9]+}}, #1
+; Materialisation of a boolean is done with sub/clz/lsr
+; CHECK:     uxtb [[CMP1:r[0-9]+]], [[DESIRED]]
+; CHECK:     sub{{(s)?}} [[CMP1]], [[OLD]], [[CMP1]]
+; CHECK:     clz [[CMP2:r[0-9]+]], [[CMP1]]
+; CHECK:     lsr{{(s)?}} {{r[0-9]+}}, [[CMP2]], #5
 ; CHECK:     dmb ish
   %res = cmpxchg i8* %addr, i8 %desired, i8 %new seq_cst monotonic
   ret { i8, i1 } %res
@@ -37,9 +39,11 @@ define { i16, i1 } @test_cmpxchg_16(i16*
 ; CHECK:     cmp{{(\.w)?}} [[STATUS]], #0
 ; CHECK:     bne [[RETRY]]
 ; CHECK: [[DONE]]:
-; CHECK:     uxth [[DESIRED_ZEXT:r[0-9]+]], [[DESIRED]]
-; CHECK:     cmp{{(\.w)?}} [[OLD]], [[DESIRED_ZEXT]]
-; CHECK:     {{moveq|movweq}} {{r[0-9]+}}, #1
+; Materialisation of a boolean is done with sub/clz/lsr
+; CHECK:     uxth [[CMP1:r[0-9]+]], [[DESIRED]]
+; CHECK:     sub{{(s)?}} [[CMP1]], [[OLD]], [[CMP1]]
+; CHECK:     clz [[CMP2:r[0-9]+]], [[CMP1]]
+; CHECK:     lsr{{(s)?}} {{r[0-9]+}}, [[CMP2]], #5
 ; CHECK:     dmb ish
   %res = cmpxchg i16* %addr, i16 %desired, i16 %new seq_cst monotonic
   ret { i16, i1 } %res
@@ -57,8 +61,10 @@ define { i32, i1 } @test_cmpxchg_32(i32*
 ; CHECK:     cmp{{(\.w)?}} [[STATUS]], #0
 ; CHECK:     bne [[RETRY]]
 ; CHECK: [[DONE]]:
-; CHECK:     cmp{{(\.w)?}} [[OLD]], [[DESIRED]]
-; CHECK:     {{moveq|movweq}} {{r[0-9]+}}, #1
+; Materialisation of a boolean is done with sub/clz/lsr
+; CHECK:     sub{{(s)?}} [[CMP1:r[0-9]+]], [[OLD]], [[DESIRED]]
+; CHECK:     clz [[CMP2:r[0-9]+]], [[CMP1]]
+; CHECK:     lsr{{(s)?}} {{r[0-9]+}}, [[CMP2]], #5
 ; CHECK:     dmb ish
   %res = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst monotonic
   ret { i32, i1 } %res

Modified: llvm/trunk/test/CodeGen/ARM/fp16-promote.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fp16-promote.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/fp16-promote.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/fp16-promote.ll Fri Feb 16 01:23:59 2018
@@ -170,8 +170,10 @@ define void @test_select(half* %p, half*
 ; CHECK-LIBCALL: bl __aeabi_h2f
 ; CHECK-VFP: vcmp.f32
 ; CHECK-NOVFP: bl __aeabi_fcmpeq
-; CHECK-FP16: vmrs APSR_nzcv, fpscr
-; CHECK-ALL: movw{{ne|eq}}
+; CHECK-VFP-NEXT: vmrs APSR_nzcv, fpscr
+; CHECK-VFP-NEXT: movwne
+; CHECK-NOVFP-NEXT: clz r0, r0
+; CHECK-NOVFP-NEXT: lsr r0, r0, #5
 define i1 @test_fcmp_une(half* %p, half* %q) #0 {
   %a = load half, half* %p, align 2
   %b = load half, half* %q, align 2

Modified: llvm/trunk/test/CodeGen/ARM/long-setcc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/long-setcc.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/long-setcc.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/long-setcc.ll Fri Feb 16 01:23:59 2018
@@ -9,9 +9,8 @@ define i1 @t1(i64 %x) {
 
 define i1 @t2(i64 %x) {
 ; CHECK-LABEL: t2:
-; CHECK: mov	r0, #0
-; CHECK: cmp	r1, #0
-; CHECK: moveq	r0, #1
+; CHECK: rsbs	r0, r1, #0
+; CHECK: adc	r0, r1, r0
 	%tmp = icmp ult i64 %x, 4294967296
 	ret i1 %tmp
 }

Modified: llvm/trunk/test/CodeGen/ARM/select-imm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/select-imm.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/select-imm.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/select-imm.ll Fri Feb 16 01:23:59 2018
@@ -67,23 +67,21 @@ entry:
 define i32 @t3(i32 %a) nounwind readnone {
 entry:
 ; ARM-LABEL: t3:
-; ARM: mov [[R:r[0-1]]], #0
-; ARM: moveq [[R]], #1
+; ARM: rsbs r1, r0, #0
+; ARM: adc  r0, r0, r1
 
 ; ARMT2-LABEL: t3:
-; ARMT2: mov [[R:r[0-1]]], #0
-; ARMT2: movweq [[R]], #1
+; ARMT2: clz r0, r0
+; ARMT2: lsr r0, r0, #5
 
 ; THUMB1-LABEL: t3:
-; THUMB1: mov     r1, r0
-; THUMB1: movs    r0, #1
-; THUMB1: movs    r2, #0
-; THUMB1: cmp     r1, #160
-; THUMB1: beq
+; THUMB1: movs r1, #0
+; THUMB1: subs r1, r1, r0
+; THUMB1: adcs r0, r1
 
 ; THUMB2-LABEL: t3:
-; THUMB2: mov{{(s|\.w)}} [[R:r[0-1]]], #0
-; THUMB2: moveq [[R]], #1
+; THUMB2: clz r0, r0
+; THUMB2: lsrs r0, r0, #5
   %0 = icmp eq i32 %a, 160
   %1 = zext i1 %0 to i32
   ret i32 %1
@@ -115,21 +113,23 @@ define i32 @t5(i32 %a) nounwind {
 entry:
 ; ARM-LABEL: t5:
 ; ARM-NOT: mov
-; ARM: cmp r0, #1
+; ARM: sub  r0, r0, #1
 ; ARM-NOT: mov
-; ARM: movne r0, #0
+; ARM: rsbs r1, r0, #0
+; ARM: adc  r0, r0, r1
 
 ; THUMB1-LABEL: t5:
-; THUMB1: mov     r1, r0
-; THUMB1: movs    r0, #0
-; THUMB1: cmp     r1, #1
-; THUMB1: bne
+; THUMB1-NOT: bne
+; THUMB1: movs r0, #0
+; THUMB1: subs r0, r0, r1
+; THUMB1: adcs r0, r1
 
 ; THUMB2-LABEL: t5:
 ; THUMB2-NOT: mov
-; THUMB2: cmp r0, #1
-; THUMB2: it ne
-; THUMB2: movne r0, #0
+; THUMB2: subs r0, #1
+; THUMB2: clz  r0, r0
+; THUMB2: lsrs r0, r0, #5
+
   %cmp = icmp eq i32 %a, 1
   %conv = zext i1 %cmp to i32
   ret i32 %conv
@@ -159,32 +159,26 @@ entry:
 define i32 @t7(i32 %a, i32 %b) nounwind readnone {
 entry:
 ; ARM-LABEL: t7:
-; ARM: mov     r2, #0
-; ARM: cmp     r0, r1
-; ARM: movne   r2, #1
-; ARM: lsl     r0, r2, #2
+; ARM: subs r0, r0, r1
+; ARM: movne   r0, #1
+; ARM: lsl     r0, r0, #2
 
 ; ARMT2-LABEL: t7:
-; ARMT2: mov     r2, #0
-; ARMT2: cmp     r0, r1
-; ARMT2: movwne  r2, #1
-; ARMT2: lsl     r0, r2, #2
+; ARMT2: subs r0, r0, r1
+; ARMT2: movwne r0, #1
+; ARMT2: lsl     r0, r0, #2
 
 ; THUMB1-LABEL: t7:
-; THUMB1: movs    r2, #1
-; THUMB1: movs    r3, #0
-; THUMB1: cmp     r0, r1
-; THUMB1: bne     .LBB6_2
-; THUMB1: mov     r2, r3
-; THUMB1: .LBB6_2:
-; THUMB1: lsls    r0, r2, #2
+; THUMB1: subs r0, r0, r1
+; THUMB1: subs r1, r0, #1
+; THUMB1: sbcs r0, r1
+; THUMB1: lsls r0, r0, #2
 
 ; THUMB2-LABEL: t7:
-; THUMB2: movs    r2, #0
-; THUMB2: cmp     r0, r1
-; THUMB2: it      ne
-; THUMB2: movne   r2, #1
-; THUMB2: lsls    r0, r2, #2
+; THUMB2: subs r0, r0, r1
+; THUMB2: it ne
+; THUMB2: movne r0, #1
+; THUMB2: lsls    r0, r0, #2
   %0 = icmp ne i32 %a, %b
   %1 = select i1 %0, i32 4, i32 0
   ret i32 %1
@@ -196,27 +190,27 @@ entry:
 ; ARM scheduler emits icmp/zext before both calls, so isn't relevant
 
 ; ARMT2-LABEL: t8:
-; ARMT2: mov     r1, r0
-; ARMT2: cmp     r0, #5
-; ARMT2: mov     r0, #9
-; ARMT2: mov     r4, #0
-; ARMT2: movweq  r4, #1
-; ARMT2: bl      t7
+; ARMT2: bl t7
+; ARMT2: mov r1, r0
+; ARMT2: sub r0, r4, #5
+; ARMT2: clz r0, r0
+; ARMT2: lsr r0, r0, #5
 
 ; THUMB1-LABEL: t8:
-; THUMB1: mov     r1, r0
-; THUMB1: movs    r4, #1
-; THUMB1: movs    r0, #0
-; THUMB1: cmp     r1, #5
-; THUMB1: beq     .LBB7_2
-; THUMB1: mov     r4, r0
+; THUMB1: bl t7
+; THUMB1: mov r1, r0
+; THUMB1: subs r2, r4, #5
+; THUMB1: movs r0, #0
+; THUMB1: subs r0, r0, r2
+; THUMB1: adcs r0, r2
 
 ; THUMB2-LABEL: t8:
-; THUMB2: mov     r1, r0
-; THUMB2: cmp     r0, #5
-; THUMB2: mov.w   r4, #0
-; THUMB2: it      eq
-; THUMB2: moveq   r4, #1
+; THUMB2: bl t7
+; THUMB2: mov r1, r0
+; THUMB2: subs r0, r4, #5
+; THUMB2: clz r0, r0
+; THUMB2: lsrs r0, r0, #5
+
   %cmp = icmp eq i32 %a, 5
   %conv = zext i1 %cmp to i32
   %call = tail call i32 @t7(i32 9, i32 %a)
@@ -230,18 +224,38 @@ entry:
 ; ARM scheduler emits icmp/zext before both calls, so isn't relevant
 
 ; ARMT2-LABEL: t9:
-; ARMT2: cmp     r4, r4
-; ARMT2: movweq  r0, #1
+; ARMT2: bl f
+; ARMT2: uxtb r0, r4
+; ARMT2: cmp  r0, r0
+; ARMT2: add  r1, r4, #1
+; ARMT2: mov  r2, r0
+; ARMT2: add  r2, r2, #1
+; ARMT2: add  r1, r1, #1
+; ARMT2: uxtb r3, r2
+; ARMT2: cmp  r3, r0
 
 ; THUMB1-LABEL: t9:
-; THUMB1: cmp     r4, r4
-; THUMB1: beq     .LBB8_2
-; THUMB1: mov     r0, r1
+; THUMB1: bl f
+; THUMB1: sxtb r1, r4
+; THUMB1: uxtb r0, r1
+; THUMB1: cmp  r0, r0
+; THUMB1: adds r1, r1, #1
+; THUMB1: mov  r2, r0
+; THUMB1: adds r1, r1, #1
+; THUMB1: adds r2, r2, #1
+; THUMB1: uxtb r3, r2
+; THUMB1: cmp  r3, r0
 
 ; THUMB2-LABEL: t9:
-; THUMB2: cmp     r4, r4
-; THUMB2: it      eq
-; THUMB2: moveq   r0, #1
+; THUMB2: bl f
+; THUMB2: uxtb r0, r4
+; THUMB2: cmp  r0, r0
+; THUMB2: adds r1, r4, #1
+; THUMB2: mov  r2, r0
+; THUMB2: adds r2, #1
+; THUMB2: adds r1, #1
+; THUMB2: uxtb r3, r2
+; THUMB2: cmp  r3, r0
 
   %0 = load i8, i8* %a
   %conv = sext i8 %0 to i32
@@ -284,27 +298,21 @@ entry:
   ret i1 %cmp
 
 ; ARM-LABEL: t10:
-; ARM: mov     r0, #0
-; ARM: cmn     r1, #3
-; ARM: moveq   r0, #1
+; ARM: rsbs r1, r0, #0
+; ARM: adc  r0, r0, r1
 
 ; ARMT2-LABEL: t10:
-; ARMT2: mov     r0, #0
-; ARMT2: cmn     r1, #3
-; ARMT2: movweq  r0, #1
+; ARMT2: clz r0, r0
+; ARMT2: lsr r0, r0, #5
 
 ; THUMB1-LABEL: t10:
-; THUMB1: movs    r0, #1
-; THUMB1: movs    r1, #0
-; THUMB1: cmp     r2, r5
-; THUMB1: beq     .LBB9_2
-; THUMB1: mov     r0, r1
+; THUMB1: movs r0, #0
+; THUMB1: subs r0, r0, r1
+; THUMB1: adcs r0, r1
 
 ; THUMB2-LABEL: t10:
-; THUMB2: adds    r0, #3
-; THUMB2: mov.w   r0, #0
-; THUMB2: it      eq
-; THUMB2: moveq   r0, #1
+; THUMB2: clz r0, r0
+; THUMB2: lsrs r0, r0, #5
 
 ; V8MBASE-LABEL: t10:
 ; V8MBASE-NOT: movs r0, #0
@@ -331,26 +339,22 @@ entry:
   ret i1 %cmp
 
 ; ARM-LABEL: t11:
-; ARM: mov     r0, #0
-; ARM: cmp     r1, #3
-; ARM: moveq   r0, #1
+; ARM: rsbs r1, r0, #0
+; ARM: adc  r0, r0, r1
 
 ; ARMT2-LABEL: t11:
-; ARMT2: mov     r0, #0
-; ARMT2: cmp     r1, #3
-; ARMT2: movweq  r0, #1
+; ARMT2: clz r0, r0
+; ARMT2: lsr r0, r0, #5
 
 ; THUMB1-LABEL: t11:
 ; THUMB1-NOT: movs r0, #0
 ; THUMB1: movs r0, #5
 
 ; THUMB2-LABEL: t11:
-; THUMB2: movs    r0, #0
-; THUMB2: cmp     r1, #3
-; THUMB2: it      eq
-; THUMB2: moveq   r0, #1
+; THUMB2: clz r0, r0
+; THUMB2: lsrs r0, r0, #5
 
 ; V8MBASE-LABEL: t11:
 ; V8MBASE-NOT: movs r0, #0
-; V8MBASE: movw  r0, #40960
+; V8MBASE: movw	r0, #40960
 }

Modified: llvm/trunk/test/CodeGen/ARM/setcc-logic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/setcc-logic.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/setcc-logic.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/setcc-logic.ll Fri Feb 16 01:23:59 2018
@@ -20,12 +20,12 @@ define zeroext i1 @ne_neg1_and_ne_zero(i
 define zeroext i1 @and_eq(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
 ; CHECK-LABEL: and_eq:
 ; CHECK:       @ %bb.0:
-; CHECK-NEXT:    eor r2, r2, r3
-; CHECK-NEXT:    eor r0, r0, r1
-; CHECK-NEXT:    orrs r0, r0, r2
-; CHECK-NEXT:    mov r0, #0
-; CHECK-NEXT:    movweq r0, #1
-; CHECK-NEXT:    bx lr
+; CHECK: eor     r2, r2, r3
+; CHECK: eor     r0, r0, r1
+; CHECK: orr     r0, r0, r2
+; CHECK: clz     r0, r0
+; CHECK: lsr     r0, r0, #5
+; CHECK: bx      lr
   %cmp1 = icmp eq i32 %a, %b
   %cmp2 = icmp eq i32 %c, %d
   %and = and i1 %cmp1, %cmp2

Modified: llvm/trunk/test/CodeGen/Thumb/branchless-cmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb/branchless-cmp.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb/branchless-cmp.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb/branchless-cmp.ll Fri Feb 16 01:23:59 2018
@@ -1,149 +1,109 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m0 %s -verify-machineinstrs -o - | FileCheck %s
 
 define i32 @test1a(i32 %a, i32 %b) {
-; CHECK-LABEL: test1a:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    mov r2, r0
-; CHECK-NEXT:    movs r0, #1
-; CHECK-NEXT:    movs r3, #0
-; CHECK-NEXT:    cmp r2, r1
-; CHECK-NEXT:    bne .LBB0_2
-; CHECK-NEXT:  @ %bb.1: @ %entry
-; CHECK-NEXT:    mov r0, r3
-; CHECK-NEXT:  .LBB0_2: @ %entry
-; CHECK-NEXT:    bx lr
 entry:
   %cmp = icmp ne i32 %a, %b
   %cond = zext i1 %cmp to i32
   ret i32 %cond
+; CHECK-LABEL: test1a:
+; CHECK-NOT: b{{(ne)|(eq)}}
+; CHECK:       subs r0, r0, r1
+; CHECK-NEXT:  subs r1, r0, #1
+; CHECK-NEXT:  sbcs r0, r1
 }
 
 define i32 @test1b(i32 %a, i32 %b) {
-; CHECK-LABEL: test1b:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    mov r2, r0
-; CHECK-NEXT:    movs r0, #1
-; CHECK-NEXT:    movs r3, #0
-; CHECK-NEXT:    cmp r2, r1
-; CHECK-NEXT:    beq .LBB1_2
-; CHECK-NEXT:  @ %bb.1: @ %entry
-; CHECK-NEXT:    mov r0, r3
-; CHECK-NEXT:  .LBB1_2: @ %entry
-; CHECK-NEXT:    bx lr
 entry:
   %cmp = icmp eq i32 %a, %b
   %cond = zext i1 %cmp to i32
   ret i32 %cond
+; CHECK-LABEL: test1b:
+; CHECK-NOT: b{{(ne)|(eq)}}
+; CHECK:       subs    r1, r0, r1
+; CHECK-NEXT:  movs    r0, #0
+; CHECK-NEXT:  subs    r0, r0, r1
+; CHECK-NEXT:  adcs    r0, r1
 }
 
 define i32 @test2a(i32 %a, i32 %b) {
-; CHECK-LABEL: test2a:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    mov r2, r0
-; CHECK-NEXT:    movs r0, #1
-; CHECK-NEXT:    movs r3, #0
-; CHECK-NEXT:    cmp r2, r1
-; CHECK-NEXT:    beq .LBB2_2
-; CHECK-NEXT:  @ %bb.1: @ %entry
-; CHECK-NEXT:    mov r0, r3
-; CHECK-NEXT:  .LBB2_2: @ %entry
-; CHECK-NEXT:    bx lr
 entry:
   %cmp = icmp eq i32 %a, %b
   %cond = zext i1 %cmp to i32
   ret i32 %cond
+; CHECK-LABEL: test2a:
+; CHECK-NOT: b{{(ne)|(eq)}}
+; CHECK:       subs    r1, r0, r1
+; CHECK-NEXT:  movs    r0, #0
+; CHECK-NEXT:  subs    r0, r0, r1
+; CHECK-NEXT:  adcs    r0, r1
 }
 
 define i32 @test2b(i32 %a, i32 %b) {
-; CHECK-LABEL: test2b:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    mov r2, r0
-; CHECK-NEXT:    movs r0, #1
-; CHECK-NEXT:    movs r3, #0
-; CHECK-NEXT:    cmp r2, r1
-; CHECK-NEXT:    bne .LBB3_2
-; CHECK-NEXT:  @ %bb.1: @ %entry
-; CHECK-NEXT:    mov r0, r3
-; CHECK-NEXT:  .LBB3_2: @ %entry
-; CHECK-NEXT:    bx lr
 entry:
   %cmp = icmp ne i32 %a, %b
   %cond = zext i1 %cmp to i32
   ret i32 %cond
+; CHECK-LABEL: test2b:
+; CHECK-NOT: b{{(ne)|(eq)}}
+; CHECK:       subs    r0, r0, r1
+; CHECK-NEXT:  subs    r1, r0, #1
+; CHECK-NEXT:  sbcs    r0, r1
 }
 
 define i32 @test3a(i32 %a, i32 %b) {
-; CHECK-LABEL: test3a:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    mov r2, r0
-; CHECK-NEXT:    movs r0, #0
-; CHECK-NEXT:    movs r3, #4
-; CHECK-NEXT:    cmp r2, r1
-; CHECK-NEXT:    beq .LBB4_2
-; CHECK-NEXT:  @ %bb.1: @ %entry
-; CHECK-NEXT:    mov r0, r3
-; CHECK-NEXT:  .LBB4_2: @ %entry
-; CHECK-NEXT:    bx lr
 entry:
   %cmp = icmp eq i32 %a, %b
   %cond = select i1 %cmp, i32 0, i32 4
   ret i32 %cond
+; CHECK-LABEL: test3a:
+; CHECK-NOT: b{{(ne)|(eq)}}
+; CHECK:       subs    r0, r0, r1
+; CHECK-NEXT:  subs    r1, r0, #1
+; CHECK-NEXT:  sbcs    r0, r1
+; CHECK-NEXT:  lsls    r0, r0, #2
 }
 
 define i32 @test3b(i32 %a, i32 %b) {
-; CHECK-LABEL: test3b:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movs r2, #1
-; CHECK-NEXT:    movs r3, #0
-; CHECK-NEXT:    cmp r0, r1
-; CHECK-NEXT:    beq .LBB5_2
-; CHECK-NEXT:  @ %bb.1: @ %entry
-; CHECK-NEXT:    mov r2, r3
-; CHECK-NEXT:  .LBB5_2: @ %entry
-; CHECK-NEXT:    lsls r0, r2, #2
-; CHECK-NEXT:    bx lr
 entry:
   %cmp = icmp eq i32 %a, %b
   %cond = select i1 %cmp, i32 4, i32 0
   ret i32 %cond
+; CHECK-LABEL: test3b:
+; CHECK-NOT: b{{(ne)|(eq)}}
+; CHECK:      subs	r0, r0, r1
+; CHECK-NEXT: movs	r1, #0
+; CHECK-NEXT: subs	r1, r1, r0
+; CHECK-NEXT: adcs	r1, r0
+; CHECK-NEXT: lsls	r0, r1, #2
 }
 
 ; FIXME: This one hasn't changed actually
 ; but could look like test3b
 define i32 @test4a(i32 %a, i32 %b) {
-; CHECK-LABEL: test4a:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    mov r2, r0
-; CHECK-NEXT:    movs r0, #0
-; CHECK-NEXT:    movs r3, #4
-; CHECK-NEXT:    cmp r2, r1
-; CHECK-NEXT:    bne .LBB6_2
-; CHECK-NEXT:  @ %bb.1: @ %entry
-; CHECK-NEXT:    mov r0, r3
-; CHECK-NEXT:  .LBB6_2: @ %entry
-; CHECK-NEXT:    bx lr
 entry:
   %cmp = icmp ne i32 %a, %b
   %cond = select i1 %cmp, i32 0, i32 4
   ret i32 %cond
+; CHECK-LABEL: test4a:
+; CHECK-NOT: b{{(ne)|(eq)}}
+; CHECK:       mov     r2, r0
+; CHECK-NEXT:  movs    r0, #0
+; CHECK-NEXT:  movs    r3, #4
+; CHECK-NEXT:  cmp     r2, r1
+; CHECK-NEXT:  bne     .[[BRANCH:[A-Z0-9_]+]]
+; CHECK:       mov     r0, r3
+; CHECK:       .[[BRANCH]]:
 }
 
 define i32 @test4b(i32 %a, i32 %b) {
-; CHECK-LABEL: test4b:
-; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    movs r2, #1
-; CHECK-NEXT:    movs r3, #0
-; CHECK-NEXT:    cmp r0, r1
-; CHECK-NEXT:    bne .LBB7_2
-; CHECK-NEXT:  @ %bb.1: @ %entry
-; CHECK-NEXT:    mov r2, r3
-; CHECK-NEXT:  .LBB7_2: @ %entry
-; CHECK-NEXT:    lsls r0, r2, #2
-; CHECK-NEXT:    bx lr
 entry:
   %cmp = icmp ne i32 %a, %b
   %cond = select i1 %cmp, i32 4, i32 0
   ret i32 %cond
+; CHECK-LABEL: test4b:
+; CHECK-NOT: b{{(ne)|(eq)}}
+; CHECK:       subs  r0, r0, r1
+; CHECK-NEXT:  subs  r1, r0, #1
+; CHECK-NEXT:  sbcs  r0, r1
+; CHECK-NEXT:  lsls  r0, r0, #2
 }
-

Modified: llvm/trunk/test/CodeGen/Thumb/constants.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb/constants.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb/constants.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb/constants.ll Fri Feb 16 01:23:59 2018
@@ -17,3 +17,20 @@ define i32 @mov_and_add() {
 define i32 @mov_and_add2() {
   ret i32 511
 }
+
+; CHECK-T1-LABEL: @test64
+; CHECK-T2-LABEL: @test64
+; CHECK-T1: movs r4, #0
+; CHECK-T1: mvns r5, r4
+; CHECK-T1: mov r0, r5
+; CHECK-T1: subs r0, #15
+; CHECK-T2: subs.w r0, r{{[0-9]+}}, #15
+; CHECK-T2-NEXT: sbc r1, r{{[0-9]+}}, #0
+define i32 @test64() {
+entry:
+  tail call void @fn1(i64 -1)
+  tail call void @fn1(i64 -1)
+  tail call void @fn1(i64 -16)
+  ret i32 0
+}
+declare void @fn1(i64) ;

Modified: llvm/trunk/test/CodeGen/Thumb/long-setcc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb/long-setcc.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb/long-setcc.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb/long-setcc.ll Fri Feb 16 01:23:59 2018
@@ -9,10 +9,9 @@ define i1 @t1(i64 %x) {
 
 define i1 @t2(i64 %x) {
 ; CHECK-LABEL: t2:
-; CHECK: movs    r0, #1
-; CHECK: movs    r2, #0
-; CHECK: cmp     r1, #0
-; CHECK: beq     .LBB1_2
+; CHECK: movs  r0, #0
+; CHECK: subs  r0, r0, r1
+; CHECK: adcs  r0, r1
   %tmp = icmp ult i64 %x, 4294967296
   ret i1 %tmp
 }
@@ -24,5 +23,4 @@ define i1 @t3(i32 %x) {
   ret i1 %tmp
 }
 
-
 ; CHECK-NOT: cmp

Modified: llvm/trunk/test/CodeGen/Thumb2/float-cmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/float-cmp.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/float-cmp.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/float-cmp.ll Fri Feb 16 01:23:59 2018
@@ -69,7 +69,8 @@ define i1 @cmp_f_ord(float %a, float %b)
 ; HARD: movvc r0, #1
   %1 = fcmp ord float %a, %b
   ret i1 %1
-}define i1 @cmp_f_ueq(float %a, float %b) {
+}
+define i1 @cmp_f_ueq(float %a, float %b) {
 ; CHECK-LABEL: cmp_f_ueq:
 ; NONE: bl __aeabi_fcmpeq
 ; NONE: bl __aeabi_fcmpun
@@ -82,8 +83,8 @@ define i1 @cmp_f_ord(float %a, float %b)
 define i1 @cmp_f_ugt(float %a, float %b) {
 ; CHECK-LABEL: cmp_f_ugt:
 ; NONE: bl __aeabi_fcmple
-; NONE: cmp r0, #0
-; NONE-NEXT: it eq
+; NONE-NEXT: clz r0, r0
+; NONE-NEXT: lsrs r0, r0, #5
 ; HARD: vcmpe.f32
 ; HARD: movhi r0, #1
   %1 = fcmp ugt float %a, %b
@@ -92,8 +93,8 @@ define i1 @cmp_f_ugt(float %a, float %b)
 define i1 @cmp_f_uge(float %a, float %b) {
 ; CHECK-LABEL: cmp_f_uge:
 ; NONE: bl __aeabi_fcmplt
-; NONE: cmp r0, #0
-; NONE-NEXT: it eq
+; NONE-NEXT: clz r0, r0
+; NONE-NEXT: lsrs r0, r0, #5
 ; HARD: vcmpe.f32
 ; HARD: movpl r0, #1
   %1 = fcmp uge float %a, %b
@@ -102,8 +103,8 @@ define i1 @cmp_f_uge(float %a, float %b)
 define i1 @cmp_f_ult(float %a, float %b) {
 ; CHECK-LABEL: cmp_f_ult:
 ; NONE: bl __aeabi_fcmpge
-; NONE: cmp r0, #0
-; NONE-NEXT: it eq
+; NONE-NEXT: clz r0, r0
+; NONE-NEXT: lsrs r0, r0, #5
 ; HARD: vcmpe.f32
 ; HARD: movlt r0, #1
   %1 = fcmp ult float %a, %b
@@ -112,8 +113,8 @@ define i1 @cmp_f_ult(float %a, float %b)
 define i1 @cmp_f_ule(float %a, float %b) {
 ; CHECK-LABEL: cmp_f_ule:
 ; NONE: bl __aeabi_fcmpgt
-; NONE: cmp r0, #0
-; NONE-NEXT: it eq
+; NONE-NEXT: clz r0, r0
+; NONE-NEXT: lsrs r0, r0, #5
 ; HARD: vcmpe.f32
 ; HARD: movle r0, #1
   %1 = fcmp ule float %a, %b

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn.ll Fri Feb 16 01:23:59 2018
@@ -3,72 +3,80 @@
 ; These tests could be improved by 'movs r0, #0' being rematerialized below the
 ; test as 'mov.w r0, #0'.
 
-define i1 @f1(i32 %a, i32 %b) {
+define i32 @f1(i32 %a, i32 %b) {
     %nb = sub i32 0, %b
     %tmp = icmp ne i32 %a, %nb
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f1:
 ; CHECK: 	cmn	{{.*}}, r1
 
-define i1 @f2(i32 %a, i32 %b) {
+define i32 @f2(i32 %a, i32 %b) {
     %nb = sub i32 0, %b
     %tmp = icmp ne i32 %nb, %a
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f2:
 ; CHECK: 	cmn	{{.*}}, r1
 
-define i1 @f3(i32 %a, i32 %b) {
+define i32 @f3(i32 %a, i32 %b) {
     %nb = sub i32 0, %b
     %tmp = icmp eq i32 %a, %nb
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f3:
 ; CHECK: 	cmn	{{.*}}, r1
 
-define i1 @f4(i32 %a, i32 %b) {
+define i32 @f4(i32 %a, i32 %b) {
     %nb = sub i32 0, %b
     %tmp = icmp eq i32 %nb, %a
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f4:
 ; CHECK: 	cmn	{{.*}}, r1
 
-define i1 @f5(i32 %a, i32 %b) {
+define i32 @f5(i32 %a, i32 %b) {
     %tmp = shl i32 %b, 5
     %nb = sub i32 0, %tmp
     %tmp1 = icmp eq i32 %nb, %a
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f5:
 ; CHECK: 	cmn.w	{{.*}}, r1, lsl #5
 
-define i1 @f6(i32 %a, i32 %b) {
+define i32 @f6(i32 %a, i32 %b) {
     %tmp = lshr i32 %b, 6
     %nb = sub i32 0, %tmp
     %tmp1 = icmp ne i32 %nb, %a
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f6:
 ; CHECK: 	cmn.w	{{.*}}, r1, lsr #6
 
-define i1 @f7(i32 %a, i32 %b) {
+define i32 @f7(i32 %a, i32 %b) {
     %tmp = ashr i32 %b, 7
     %nb = sub i32 0, %tmp
     %tmp1 = icmp eq i32 %a, %nb
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f7:
 ; CHECK: 	cmn.w	{{.*}}, r1, asr #7
 
-define i1 @f8(i32 %a, i32 %b) {
+define i32 @f8(i32 %a, i32 %b) {
     %l8 = shl i32 %a, 24
     %r8 = lshr i32 %a, 8
     %tmp = or i32 %l8, %r8
     %nb = sub i32 0, %tmp
     %tmp1 = icmp ne i32 %a, %nb
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f8:
 ; CHECK: 	cmn.w	{{.*}}, {{.*}}, ror #8

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll Fri Feb 16 01:23:59 2018
@@ -1,33 +1,37 @@
 ; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s
 
 ; -0x000000bb = 4294967109
-define i1 @f1(i32 %a) {
+define i32 @f1(i32 %a) {
 ; CHECK-LABEL: f1:
 ; CHECK: adds {{r.*}}, #187
     %tmp = icmp ne i32 %a, 4294967109
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 
 ; -0x00aa00aa = 4283826006
-define i1 @f2(i32 %a) {
+define i32 @f2(i32 %a) {
 ; CHECK-LABEL: f2:
 ; CHECK: cmn.w {{r.*}}, #11141290
     %tmp = icmp eq i32 %a, 4283826006
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 
 ; -0xcc00cc00 = 872363008
-define i1 @f3(i32 %a) {
+define i32 @f3(i32 %a) {
 ; CHECK-LABEL: f3:
 ; CHECK: cmn.w {{r.*}}, #-872363008
     %tmp = icmp ne i32 %a, 872363008
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 
 ; -0x00110000 = 4293853184
-define i1 @f4(i32 %a) {
+define i32 @f4(i32 %a) {
 ; CHECK-LABEL: f4:
 ; CHECK: cmn.w {{r.*}}, #1114112
     %tmp = icmp eq i32 %a, 4293853184
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-cmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-cmp.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-cmp.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-cmp.ll Fri Feb 16 01:23:59 2018
@@ -4,43 +4,48 @@
 ; test as 'mov.w r0, #0'.
 
 ; 0x000000bb = 187
-define i1 @f1(i32 %a) {
+define i32 @f1(i32 %a) {
 ; CHECK-LABEL: f1:
 ; CHECK: cmp {{.*}}, #187
     %tmp = icmp ne i32 %a, 187
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 
 ; 0x00aa00aa = 11141290
-define i1 @f2(i32 %a) {
+define i32 @f2(i32 %a) {
 ; CHECK-LABEL: f2:
 ; CHECK: cmp.w {{.*}}, #11141290
     %tmp = icmp eq i32 %a, 11141290 
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 
 ; 0xcc00cc00 = 3422604288
-define i1 @f3(i32 %a) {
+define i32 @f3(i32 %a) {
 ; CHECK-LABEL: f3:
 ; CHECK: cmp.w {{.*}}, #-872363008
     %tmp = icmp ne i32 %a, 3422604288
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 
 ; 0xdddddddd = 3722304989
-define i1 @f4(i32 %a) {
+define i32 @f4(i32 %a) {
 ; CHECK-LABEL: f4:
 ; CHECK: cmp.w {{.*}}, #-572662307
     %tmp = icmp ne i32 %a, 3722304989
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 
 ; 0x00110000 = 1114112
-define i1 @f5(i32 %a) {
+define i32 @f5(i32 %a) {
 ; CHECK-LABEL: f5:
 ; CHECK: cmp.w {{.*}}, #1114112
     %tmp = icmp eq i32 %a, 1114112
-    ret i1 %tmp
+    %ret = select i1 %tmp, i32 42, i32 24
+    ret i32 %ret
 }
 
 ; Check that we don't do an invalid (a > b) --> !(a < b + 1) transform.

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-teq.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-teq.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-teq.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-teq.ll Fri Feb 16 01:23:59 2018
@@ -4,54 +4,107 @@
 ; test as 'mov.w r0, #0'.
 
 ; 0x000000bb = 187
-define i1 @f2(i32 %a) {
+define i32 @f2(i32 %a) {
     %tmp = xor i32 %a, 187
     %tmp1 = icmp eq i32 0, %tmp
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f2:
 ; CHECK: 	teq.w	{{.*}}, #187
 
 ; 0x00aa00aa = 11141290
-define i1 @f3(i32 %a) {
+define i32 @f3(i32 %a) {
     %tmp = xor i32 %a, 11141290 
     %tmp1 = icmp eq i32 %tmp, 0
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f3:
 ; CHECK: 	teq.w	{{.*}}, #11141290
 
 ; 0xcc00cc00 = 3422604288
-define i1 @f6(i32 %a) {
+define i32 @f6(i32 %a) {
     %tmp = xor i32 %a, 3422604288
     %tmp1 = icmp eq i32 0, %tmp
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f6:
 ; CHECK: 	teq.w	{{.*}}, #-872363008
 
 ; 0xdddddddd = 3722304989
-define i1 @f7(i32 %a) {
+define i32 @f7(i32 %a) {
     %tmp = xor i32 %a, 3722304989
     %tmp1 = icmp eq i32 %tmp, 0
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f7:
 ; CHECK: 	teq.w	{{.*}}, #-572662307
 
+; 0x00110000 = 1114112
+define i32 @f10(i32 %a) {
+    %tmp = xor i32 %a, 1114112
+    %tmp1 = icmp eq i32 0, %tmp
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
+}
+; CHECK-LABEL: f10:
+; CHECK: 	teq.w	{{.*}}, #1114112
+
+; 0x000000bb = 187
+define i1 @f12(i32 %a) {
+    %tmp = xor i32 %a, 187
+    %tmp1 = icmp eq i32 0, %tmp
+    ret i1 %tmp1
+}
+; CHECK-LABEL: f12:
+; CHECK:      eor r0, r0, #187
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
+
+; 0x00aa00aa = 11141290
+define i1 @f13(i32 %a) {
+    %tmp = xor i32 %a, 11141290 
+    %tmp1 = icmp eq i32 %tmp, 0
+    ret i1 %tmp1
+}
+; CHECK-LABEL: f13:
+; CHECK:      eor r0, r0, #11141290
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
+
+; 0xcc00cc00 = 3422604288
+define i1 @f16(i32 %a) {
+    %tmp = xor i32 %a, 3422604288
+    %tmp1 = icmp eq i32 0, %tmp
+    ret i1 %tmp1
+}
+; CHECK-LABEL: f16:
+; CHECK:      eor r0, r0, #-872363008
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
+
 ; 0xdddddddd = 3722304989
-define i1 @f8(i32 %a) {
+define i1 @f17(i32 %a) {
     %tmp = xor i32 %a, 3722304989
-    %tmp1 = icmp ne i32 0, %tmp
+    %tmp1 = icmp eq i32 %tmp, 0
     ret i1 %tmp1
 }
+; CHECK-LABEL: f17:
+; CHECK:      eor r0, r0, #-572662307
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
 
 ; 0x00110000 = 1114112
-define i1 @f10(i32 %a) {
+define i1 @f18(i32 %a) {
     %tmp = xor i32 %a, 1114112
     %tmp1 = icmp eq i32 0, %tmp
     ret i1 %tmp1
 }
-; CHECK-LABEL: f10:
-; CHECK: 	teq.w	{{.*}}, #1114112
+; CHECK-LABEL: f18:
+; CHECK:      eor r0, r0, #1114112
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
 

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-teq2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-teq2.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-teq2.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-teq2.ll Fri Feb 16 01:23:59 2018
@@ -3,50 +3,55 @@
 ; These tests would be improved by 'movs r0, #0' being rematerialized below the
 ; tst as 'mov.w r0, #0'.
 
-define i1 @f2(i32 %a, i32 %b) {
+define i32 @f2(i32 %a, i32 %b) {
 ; CHECK: f2
 ; CHECK: teq.w {{.*}}, r1
     %tmp = xor i32 %a, %b
     %tmp1 = icmp eq i32 %tmp, 0
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f4(i32 %a, i32 %b) {
+define i32 @f4(i32 %a, i32 %b) {
 ; CHECK: f4
 ; CHECK: teq.w  {{.*}}, r1
     %tmp = xor i32 %a, %b
     %tmp1 = icmp eq i32 0, %tmp
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f6(i32 %a, i32 %b) {
+define i32 @f6(i32 %a, i32 %b) {
 ; CHECK: f6
 ; CHECK: teq.w  {{.*}}, r1, lsl #5
     %tmp = shl i32 %b, 5
     %tmp1 = xor i32 %a, %tmp
     %tmp2 = icmp eq i32 %tmp1, 0
-    ret i1 %tmp2
+    %ret = select i1 %tmp2, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f7(i32 %a, i32 %b) {
+define i32 @f7(i32 %a, i32 %b) {
 ; CHECK: f7
 ; CHECK: teq.w  {{.*}}, r1, lsr #6
     %tmp = lshr i32 %b, 6
     %tmp1 = xor i32 %a, %tmp
     %tmp2 = icmp eq i32 %tmp1, 0
-    ret i1 %tmp2
+    %ret = select i1 %tmp2, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f8(i32 %a, i32 %b) {
+define i32 @f8(i32 %a, i32 %b) {
 ; CHECK: f8
 ; CHECK: teq.w  {{.*}}, r1, asr #7
     %tmp = ashr i32 %b, 7
     %tmp1 = xor i32 %a, %tmp
     %tmp2 = icmp eq i32 %tmp1, 0
-    ret i1 %tmp2
+    %ret = select i1 %tmp2, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f9(i32 %a, i32 %b) {
+define i32 @f9(i32 %a, i32 %b) {
 ; CHECK: f9
 ; CHECK: teq.w  {{.*}}, {{.*}}, ror #8
     %l8 = shl i32 %a, 24
@@ -54,5 +59,6 @@ define i1 @f9(i32 %a, i32 %b) {
     %tmp = or i32 %l8, %r8
     %tmp1 = xor i32 %a, %tmp
     %tmp2 = icmp eq i32 %tmp1, 0
-    ret i1 %tmp2
+    %ret = select i1 %tmp2, i32 42, i32 24
+    ret i32 %ret
 }

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-tst.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-tst.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-tst.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-tst.ll Fri Feb 16 01:23:59 2018
@@ -4,46 +4,107 @@
 ; tst as 'mov.w r0, #0'.
 
 ; 0x000000bb = 187
-define i1 @f2(i32 %a) {
+define i32 @f2(i32 %a) {
     %tmp = and i32 %a, 187
     %tmp1 = icmp eq i32 0, %tmp
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f2:
 ; CHECK: 	tst.w	{{.*}}, #187
 
 ; 0x00aa00aa = 11141290
-define i1 @f3(i32 %a) {
+define i32 @f3(i32 %a) {
     %tmp = and i32 %a, 11141290 
     %tmp1 = icmp eq i32 %tmp, 0
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f3:
 ; CHECK: 	tst.w	{{.*}}, #11141290
 
 ; 0xcc00cc00 = 3422604288
-define i1 @f6(i32 %a) {
+define i32 @f6(i32 %a) {
     %tmp = and i32 %a, 3422604288
     %tmp1 = icmp eq i32 0, %tmp
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f6:
 ; CHECK: 	tst.w	{{.*}}, #-872363008
 
 ; 0xdddddddd = 3722304989
-define i1 @f7(i32 %a) {
+define i32 @f7(i32 %a) {
     %tmp = and i32 %a, 3722304989
     %tmp1 = icmp eq i32 %tmp, 0
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f7:
 ; CHECK: 	tst.w	{{.*}}, #-572662307
 
 ; 0x00110000 = 1114112
-define i1 @f10(i32 %a) {
+define i32 @f10(i32 %a) {
     %tmp = and i32 %a, 1114112
     %tmp1 = icmp eq i32 0, %tmp
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 ; CHECK-LABEL: f10:
 ; CHECK: 	tst.w	{{.*}}, #1114112
+
+; 0x000000bb = 187
+define i1 @f12(i32 %a) {
+    %tmp = and i32 %a, 187
+    %tmp1 = icmp eq i32 0, %tmp
+    ret i1 %tmp1
+}
+; CHECK-LABEL: f12:
+; CHECK: 	  and r0, r0, #187
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
+
+; 0x00aa00aa = 11141290
+define i1 @f13(i32 %a) {
+    %tmp = and i32 %a, 11141290
+    %tmp1 = icmp eq i32 %tmp, 0
+    ret i1 %tmp1
+}
+; CHECK-LABEL: f13:
+; CHECK: 	  and r0, r0, #11141290
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
+
+; 0xcc00cc00 = 3422604288
+define i1 @f16(i32 %a) {
+    %tmp = and i32 %a, 3422604288
+    %tmp1 = icmp eq i32 0, %tmp
+    ret i1 %tmp1
+}
+; CHECK-LABEL: f16:
+; CHECK: 	  and r0, r0, #-872363008
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
+
+; 0xdddddddd = 3722304989
+define i1 @f17(i32 %a) {
+    %tmp = and i32 %a, 3722304989
+    %tmp1 = icmp eq i32 %tmp, 0
+    ret i1 %tmp1
+}
+; CHECK-LABEL: f17:
+; CHECK: 	  bic r0, r0, #572662306
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
+
+; 0x00110000 = 1114112
+define i1 @f18(i32 %a) {
+    %tmp = and i32 %a, 1114112
+    %tmp1 = icmp eq i32 0, %tmp
+    ret i1 %tmp1
+}
+; CHECK-LABEL: f18:
+; CHECK: 	  and r0, r0, #1114112
+; CHECK-NEXT: clz r0, r0
+; CHECK-NEXT: lsrs r0, r0, #5
+

Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-tst2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-tst2.ll?rev=325323&r1=325322&r2=325323&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-tst2.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-tst2.ll Fri Feb 16 01:23:59 2018
@@ -3,50 +3,55 @@
 ; These tests would be improved by 'movs r0, #0' being rematerialized below the
 ; tst as 'mov.w r0, #0'.
 
-define i1 @f2(i32 %a, i32 %b) {
+define i32 @f2(i32 %a, i32 %b) {
 ; CHECK-LABEL: f2:
 ; CHECK: tst {{.*}}, r1
     %tmp = and i32 %a, %b
     %tmp1 = icmp eq i32 %tmp, 0
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f4(i32 %a, i32 %b) {
+define i32 @f4(i32 %a, i32 %b) {
 ; CHECK-LABEL: f4:
 ; CHECK: tst {{.*}}, r1
     %tmp = and i32 %a, %b
     %tmp1 = icmp eq i32 0, %tmp
-    ret i1 %tmp1
+    %ret = select i1 %tmp1, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f6(i32 %a, i32 %b) {
+define i32 @f6(i32 %a, i32 %b) {
 ; CHECK-LABEL: f6:
 ; CHECK: tst.w {{.*}}, r1, lsl #5
     %tmp = shl i32 %b, 5
     %tmp1 = and i32 %a, %tmp
     %tmp2 = icmp eq i32 %tmp1, 0
-    ret i1 %tmp2
+    %ret = select i1 %tmp2, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f7(i32 %a, i32 %b) {
+define i32 @f7(i32 %a, i32 %b) {
 ; CHECK-LABEL: f7:
 ; CHECK: tst.w {{.*}}, r1, lsr #6
     %tmp = lshr i32 %b, 6
     %tmp1 = and i32 %a, %tmp
     %tmp2 = icmp eq i32 %tmp1, 0
-    ret i1 %tmp2
+    %ret = select i1 %tmp2, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f8(i32 %a, i32 %b) {
+define i32 @f8(i32 %a, i32 %b) {
 ; CHECK-LABEL: f8:
 ; CHECK: tst.w {{.*}}, r1, asr #7
     %tmp = ashr i32 %b, 7
     %tmp1 = and i32 %a, %tmp
     %tmp2 = icmp eq i32 %tmp1, 0
-    ret i1 %tmp2
+    %ret = select i1 %tmp2, i32 42, i32 24
+    ret i32 %ret
 }
 
-define i1 @f9(i32 %a, i32 %b) {
+define i32 @f9(i32 %a, i32 %b) {
 ; CHECK-LABEL: f9:
 ; CHECK: tst.w {{.*}}, {{.*}}, ror #8
     %l8 = shl i32 %a, 24
@@ -54,5 +59,6 @@ define i1 @f9(i32 %a, i32 %b) {
     %tmp = or i32 %l8, %r8
     %tmp1 = and i32 %a, %tmp
     %tmp2 = icmp eq i32 %tmp1, 0
-    ret i1 %tmp2
+    %ret = select i1 %tmp2, i32 42, i32 24
+    ret i32 %ret
 }




More information about the llvm-commits mailing list