diff options
-rw-r--r-- | lib/Target/ARM/ARMFastISel.cpp | 17 | ||||
-rw-r--r-- | test/CodeGen/ARM/fast-isel-cmp-imm.ll | 19 |
2 files changed, 27 insertions, 9 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 4651a3a..6f33556 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -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) diff --git a/test/CodeGen/ARM/fast-isel-cmp-imm.ll b/test/CodeGen/ARM/fast-isel-cmp-imm.ll index 1693066..660156a 100644 --- a/test/CodeGen/ARM/fast-isel-cmp-imm.ll +++ b/test/CodeGen/ARM/fast-isel-cmp-imm.ll @@ -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 +} + |