OSDN Git Service

getSExtValue() doesn't work for ConstantInts with bitwidth > 64 bits. Use all
authorBill Wendling <isanbard@gmail.com>
Sun, 30 Nov 2008 12:38:24 +0000 (12:38 +0000)
committerBill Wendling <isanbard@gmail.com>
Sun, 30 Nov 2008 12:38:24 +0000 (12:38 +0000)
APInt calls instead.

This fixes PR3144.

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

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/sdiv-2.ll [new file with mode: 0644]

index f3cb747..93510f0 100644 (file)
@@ -2957,21 +2957,21 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
       return BinaryOperator::CreateNeg(Op0);
 
     ConstantInt *RHSNeg = cast<ConstantInt>(ConstantExpr::getNeg(RHS));
-    APInt RHSNegAPI(RHSNeg->getBitWidth(), RHSNeg->getSExtValue(), true);
+    APInt RHSNegAPI(RHSNeg->getValue());
 
     APInt NegOne = -APInt(RHSNeg->getBitWidth(), 1, true);
     APInt TwoToExp(RHSNeg->getBitWidth(), 1 << (RHSNeg->getBitWidth() - 1));
 
     // -X/C -> X/-C, if and only if negation doesn't overflow.
-    if ((RHS->getSExtValue() < 0 && RHSNegAPI.slt(TwoToExp - 1)) ||
-        (RHS->getSExtValue() > 0 && RHSNegAPI.sgt(TwoToExp * NegOne))) {
+    if ((RHS->getValue().isNegative() && RHSNegAPI.slt(TwoToExp - 1)) ||
+        (RHS->getValue().isNonNegative() && RHSNegAPI.sgt(TwoToExp * NegOne))) {
       if (Value *LHSNeg = dyn_castNegVal(Op0)) {
         if (ConstantInt *CI = dyn_cast<ConstantInt>(LHSNeg)) {
           ConstantInt *CINeg = cast<ConstantInt>(ConstantExpr::getNeg(CI));
           APInt CINegAPI(CINeg->getBitWidth(), CINeg->getSExtValue(), true);
 
-          if ((CI->getSExtValue() < 0 && CINegAPI.slt(TwoToExp - 1)) ||
-              (CI->getSExtValue() > 0 && CINegAPI.sgt(TwoToExp * NegOne)))
+          if ((CI->getValue().isNegative() && CINegAPI.slt(TwoToExp - 1)) ||
+              (CI->getValue().isNonNegative() && CINegAPI.sgt(TwoToExp*NegOne)))
             return BinaryOperator::CreateSDiv(LHSNeg,
                                               ConstantExpr::getNeg(RHS));
         }
diff --git a/test/Transforms/InstCombine/sdiv-2.ll b/test/Transforms/InstCombine/sdiv-2.ll
new file mode 100644 (file)
index 0000000..db0c7fb
--- /dev/null
@@ -0,0 +1,28 @@
+; RUN: llvm-as < %s | opt -instcombine -disable-output
+; PR3144
+
+define fastcc i32 @func(i32 %length) nounwind {
+entry:
+       %0 = icmp ne i32 %length, -1            ; <i1> [#uses=1]
+       %iftmp.13.0 = select i1 %0, i128 0, i128 200000000              ; <i128> [#uses=2]
+       %1 = sdiv i128 %iftmp.13.0, 10          ; <i128> [#uses=1]
+       br label %bb5
+
+bb5:           ; preds = %bb8, %entry
+       %v.0 = phi i128 [ 0, %entry ], [ %6, %bb8 ]             ; <i128> [#uses=2]
+       %2 = icmp sgt i128 %v.0, %1             ; <i1> [#uses=1]
+       br i1 %2, label %overflow, label %bb7
+
+bb7:           ; preds = %bb5
+       %3 = mul i128 %v.0, 10          ; <i128> [#uses=2]
+       %4 = sub i128 %iftmp.13.0, 0            ; <i128> [#uses=1]
+       %5 = icmp slt i128 %4, %3               ; <i1> [#uses=1]
+       br i1 %5, label %overflow, label %bb8
+
+bb8:           ; preds = %bb7
+       %6 = add i128 0, %3             ; <i128> [#uses=1]
+       br label %bb5
+
+overflow:              ; preds = %bb7, %bb5
+       ret i32 1
+}