]> granicus.if.org Git - llvm/commitdiff
[ARM] Treat cmn immediates as legal in isLegalICmpImmediate.
authorEli Friedman <efriedma@codeaurora.org>
Tue, 10 Jul 2018 23:44:37 +0000 (23:44 +0000)
committerEli Friedman <efriedma@codeaurora.org>
Tue, 10 Jul 2018 23:44:37 +0000 (23:44 +0000)
The original code attempted to do this, but the std::abs() call didn't
actually do anything due to implicit type conversions.  Fix the type
conversions, and perform the correct check for negative immediates.

This probably has very little practical impact, but it's worth fixing
just to avoid confusion in the future, I think.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336742 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
test/CodeGen/ARM/arm-shrink-wrapping-linux.ll
test/CodeGen/ARM/sub-cmp-peephole.ll
test/CodeGen/Thumb2/thumb2-cmp.ll

index 9b143dcff738a7376a07893c935ec09314b44dff..a57bb567b8cc14d3f135ce6b89094764514b51dc 100644 (file)
@@ -3857,8 +3857,8 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
                                      const SDLoc &dl) const {
   if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
     unsigned C = RHSC->getZExtValue();
-    if (!isLegalICmpImmediate(C)) {
-      // Constant does not fit, try adjusting it by one?
+    if (!isLegalICmpImmediate((int32_t)C)) {
+      // Constant does not fit, try adjusting it by one.
       switch (CC) {
       default: break;
       case ISD::SETLT:
@@ -13208,9 +13208,11 @@ bool ARMTargetLowering::isLegalAddressingMode(const DataLayout &DL,
 bool ARMTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
   // Thumb2 and ARM modes can use cmn for negative immediates.
   if (!Subtarget->isThumb())
-    return ARM_AM::getSOImmVal(std::abs(Imm)) != -1;
+    return ARM_AM::getSOImmVal((uint32_t)Imm) != -1 ||
+           ARM_AM::getSOImmVal(-(uint32_t)Imm) != -1;
   if (Subtarget->isThumb2())
-    return ARM_AM::getT2SOImmVal(std::abs(Imm)) != -1;
+    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;
 }
index 7007018dd0b29492854efdc6fd033936c190190a..a4ea42dccaf4ffe64db1249c7f35a867e90dca07 100644 (file)
@@ -19,13 +19,13 @@ target triple = "armv7--linux-gnueabi"
 ; without shrink-wrapping.
 ; DISABLE: push
 ;
-; CHECK: cmp r1, #0
+; CHECK: cmn r1, #1
 ;
 ; With shrink-wrapping, we branch to a pre-header, where the prologue
 ; is located.
-; ENABLE-NEXT: blt [[LOOP_PREHEADER:[.a-zA-Z0-9_]+]]
+; ENABLE-NEXT: ble [[LOOP_PREHEADER:[.a-zA-Z0-9_]+]]
 ; Without shrink-wrapping, we go straight into the loop.
-; DISABLE-NEXT: blt [[LOOP_HEADER:[.a-zA-Z0-9_]+]]
+; DISABLE-NEXT: ble [[LOOP_HEADER:[.a-zA-Z0-9_]+]]
 ;
 ; CHECK: @ %if.end29
 ; DISABLE-NEXT: pop
index 80a4272ec0a36dc71aa465b83d3b6e78f7e0eee7..45964e534114de9b48957427551dc97497b62063 100644 (file)
@@ -167,8 +167,8 @@ define i32 @cmp_slt0(i32 %a, i32 %b, i32 %x, i32 %y) {
 entry:
 ; CHECK-LABEL: cmp_slt0
 ; CHECK: sub
-; CHECK: cmp
-; CHECK: bge
+; CHECK: cmn
+; CHECK: bgt
   %load = load i32, i32* @t, align 4
   %sub = sub i32 %load, 17
   %cmp = icmp slt i32 %sub, 0
index 57ea557131130de61f49af7082304d5b5b40e562..7d92c4d0ee43ddf4b26ed9d276d9d0d681d396d8 100644 (file)
@@ -169,7 +169,7 @@ false:
 
 define i32 @slt_neg_soimm(i32 %a) {
 ; CHECK-LABEL: slt_neg_soimm:
-; CHECK: mvn     r1, #7929856
+; CHECK: cmn.w r0, #7929856
   %b = icmp slt i32 %a, -7929856
   br i1 %b, label %true, label %false
 
@@ -208,8 +208,7 @@ false:
 
 define i32 @sgt_neg_soimm(i32 %a) {
 ; CHECK-LABEL: sgt_neg_soimm:
-; CHECK: movs    r1, #1
-; CHECK: movt    r1, #65415
+; CHECK: cmn.w r0, #7929856
   %b = icmp sgt i32 %a, -7929856
   br i1 %b, label %true, label %false