summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanya Lattner <tonic@nondot.org>2008-10-17 17:50:35 +0000
committerTanya Lattner <tonic@nondot.org>2008-10-17 17:50:35 +0000
commitb42f08779132821078ffe6b9a74a0537940c6c93 (patch)
tree0a854bf7130fa16856b6a8ddaf3a13015a7b99eb
parentde2ede8989a4308e53b85884c46b142d5a338c06 (diff)
downloadllvm-b42f08779132821078ffe6b9a74a0537940c6c93.tar.gz
Merge from mainline.
Fix PR2697 by rewriting the '(X / pos) op neg' logic. This also changes a couple other cases for clarity, but shouldn't affect correctness. llvm-svn: 57698
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp25
-rw-r--r--llvm/test/Transforms/InstCombine/2008-10-11-DivCompareFold.ll8
2 files changed, 23 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 6f9893cc8fa2..233356fe777a 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -5784,6 +5784,11 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
return 0;
if (DivRHS->isZero())
return 0; // The ProdOV computation fails on divide by zero.
+ if (DivIsSigned && DivRHS->isAllOnesValue())
+ return 0; // The overflow computation also screws up here
+ if (DivRHS->isOne())
+ return 0; // Not worth bothering, and eliminates some funny cases
+ // with INT_MIN.
// Compute Prod = CI * DivRHS. We are essentially solving an equation
// of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and
@@ -5810,7 +5815,6 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
int LoOverflow = 0, HiOverflow = 0;
ConstantInt *LoBound = 0, *HiBound = 0;
-
if (!DivIsSigned) { // udiv
// e.g. X/5 op 3 --> [15, 20)
LoBound = Prod;
@@ -5829,11 +5833,13 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
HiOverflow = AddWithOverflow(HiBound, Prod, DivRHS, true);
} else { // (X / pos) op neg
// e.g. X/5 op -3 --> [-15-4, -15+1) --> [-19, -14)
- Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS));
- LoOverflow = AddWithOverflow(LoBound, Prod,
- cast<ConstantInt>(DivRHSH), true) ? -1 : 0;
HiBound = AddOne(Prod);
- HiOverflow = ProdOV ? -1 : 0;
+ LoOverflow = HiOverflow = ProdOV ? -1 : 0;
+ if (!LoOverflow) {
+ ConstantInt* DivNeg = cast<ConstantInt>(ConstantExpr::getNeg(DivRHS));
+ LoOverflow = AddWithOverflow(LoBound, HiBound, DivNeg,
+ true) ? -1 : 0;
+ }
}
} else if (DivRHS->getValue().isNegative()) { // Divisor is < 0.
if (CmpRHSV == 0) { // (X / neg) op 0
@@ -5846,14 +5852,13 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
}
} else if (CmpRHSV.isStrictlyPositive()) { // (X / neg) op pos
// e.g. X/-5 op 3 --> [-19, -14)
+ HiBound = AddOne(Prod);
HiOverflow = LoOverflow = ProdOV ? -1 : 0;
if (!LoOverflow)
- LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS), true) ?-1:0;
- HiBound = AddOne(Prod);
+ LoOverflow = AddWithOverflow(LoBound, HiBound, DivRHS, true) ? -1 : 0;
} else { // (X / neg) op neg
- // e.g. X/-5 op -3 --> [15, 20)
- LoBound = Prod;
- LoOverflow = HiOverflow = ProdOV ? 1 : 0;
+ LoBound = Prod; // e.g. X/-5 op -3 --> [15, 20)
+ LoOverflow = HiOverflow = ProdOV;
if (!HiOverflow)
HiOverflow = SubWithOverflow(HiBound, Prod, DivRHS, true);
}
diff --git a/llvm/test/Transforms/InstCombine/2008-10-11-DivCompareFold.ll b/llvm/test/Transforms/InstCombine/2008-10-11-DivCompareFold.ll
new file mode 100644
index 000000000000..dfe9c4a16c89
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/2008-10-11-DivCompareFold.ll
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i1 false}
+; PR2697
+
+define i1 @x(i32 %x) nounwind {
+ %div = sdiv i32 %x, 65536 ; <i32> [#uses=1]
+ %cmp = icmp slt i32 %div, -65536
+ ret i1 %cmp
+}