[fast-isel] Address Eli's comments for r152847. Specifically, add a test case
authorChad Rosier <mcrosier@apple.com>
Thu, 15 Mar 2012 22:54:20 +0000 (22:54 +0000)
committerChad Rosier <mcrosier@apple.com>
Thu, 15 Mar 2012 22:54:20 +0000 (22:54 +0000)
and still allow immediate encoding, just not with cmn.
rdar://11038907

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

lib/Target/ARM/ARMFastISel.cpp
test/CodeGen/ARM/fast-isel-cmp-imm.ll

index 4651a3ac929edcac31dbc598c916278e8eaf2af5..6f33556760790a8ae4e6b1a20b2de604ae7e85e7 100644 (file)
@@ -1384,16 +1384,15 @@ bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
         SrcVT == MVT::i1) {
       const APInt &CIVal = ConstInt->getValue();
       Imm = (isZExt) ? (int)CIVal.getZExtValue() : (int)CIVal.getSExtValue();
-      // We can't encode LONG_MIN (i.e., 0x80000000) as an immediate because
-      // there is no way to represent 2147483648 as a signed 32-bit int.
-      if (Imm != (int)0x80000000) {
-        if (Imm < 0) {
-          isNegativeImm = true;
-          Imm = -Imm;
-        }
-        UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
-          (ARM_AM::getSOImmVal(Imm) != -1);
+      // For INT_MIN/LONG_MIN (i.e., 0x80000000) we need to use a cmp, rather
+      // then a cmn, because there is no way to represent 2147483648 as a 
+      // signed 32-bit int.
+      if (Imm < 0 && Imm != (int)0x80000000) {
+        isNegativeImm = true;
+        Imm = -Imm;
       }
+      UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
+        (ARM_AM::getSOImmVal(Imm) != -1);
     }
   } else if (const ConstantFP *ConstFP = dyn_cast<ConstantFP>(Src2Value)) {
     if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
index 16930663abd86088c067d34f1b46249979f476ca..660156aa48bd18dd5ba4abe9ace3c2091d155e94 100644 (file)
@@ -229,3 +229,22 @@ if.then:                                          ; preds = %entry
 if.end:                                           ; preds = %if.then, %entry
   ret void
 }
+
+; rdar://11038907
+; When comparing LONG_MIN/INT_MIN use a cmp instruction.
+define void @t13() nounwind ssp {
+entry:
+; ARM: t13
+; THUMB: t13
+  %cmp = icmp slt i32 -123, -2147483648
+; ARM: cmp r{{[0-9]}}, #-2147483648
+; THUMB: cmp.w r{{[0-9]}}, #-2147483648
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  ret void
+
+if.end:                                           ; preds = %entry
+  ret void
+}
+