llvm.org GIT mirror llvm / 7f3bc26
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_24@57698 91177308-0d34-0410-b5e6-96231b3b80d8 Tanya Lattner 10 years ago
2 changed file(s) with 23 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
57835783 return 0;
57845784 if (DivRHS->isZero())
57855785 return 0; // The ProdOV computation fails on divide by zero.
5786 if (DivIsSigned && DivRHS->isAllOnesValue())
5787 return 0; // The overflow computation also screws up here
5788 if (DivRHS->isOne())
5789 return 0; // Not worth bothering, and eliminates some funny cases
5790 // with INT_MIN.
57865791
57875792 // Compute Prod = CI * DivRHS. We are essentially solving an equation
57885793 // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and
58085813 // -1 if overflowed off the bottom end, or +1 if overflowed off the top end.
58095814 int LoOverflow = 0, HiOverflow = 0;
58105815 ConstantInt *LoBound = 0, *HiBound = 0;
5811
58125816
58135817 if (!DivIsSigned) { // udiv
58145818 // e.g. X/5 op 3 --> [15, 20)
58285832 HiOverflow = AddWithOverflow(HiBound, Prod, DivRHS, true);
58295833 } else { // (X / pos) op neg
58305834 // e.g. X/5 op -3 --> [-15-4, -15+1) --> [-19, -14)
5831 Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS));
5832 LoOverflow = AddWithOverflow(LoBound, Prod,
5833 cast(DivRHSH), true) ? -1 : 0;
58345835 HiBound = AddOne(Prod);
5835 HiOverflow = ProdOV ? -1 : 0;
5836 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
5837 if (!LoOverflow) {
5838 ConstantInt* DivNeg = cast(ConstantExpr::getNeg(DivRHS));
5839 LoOverflow = AddWithOverflow(LoBound, HiBound, DivNeg,
5840 true) ? -1 : 0;
5841 }
58365842 }
58375843 } else if (DivRHS->getValue().isNegative()) { // Divisor is < 0.
58385844 if (CmpRHSV == 0) { // (X / neg) op 0
58455851 }
58465852 } else if (CmpRHSV.isStrictlyPositive()) { // (X / neg) op pos
58475853 // e.g. X/-5 op 3 --> [-19, -14)
5854 HiBound = AddOne(Prod);
58485855 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
58495856 if (!LoOverflow)
5850 LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS), true) ?-1:0;
5851 HiBound = AddOne(Prod);
5857 LoOverflow = AddWithOverflow(LoBound, HiBound, DivRHS, true) ? -1 : 0;
58525858 } else { // (X / neg) op neg
5853 // e.g. X/-5 op -3 --> [15, 20)
5854 LoBound = Prod;
5855 LoOverflow = HiOverflow = ProdOV ? 1 : 0;
5859 LoBound = Prod; // e.g. X/-5 op -3 --> [15, 20)
5860 LoOverflow = HiOverflow = ProdOV;
58565861 if (!HiOverflow)
58575862 HiOverflow = SubWithOverflow(HiBound, Prod, DivRHS, true);
58585863 }
0 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i1 false}
1 ; PR2697
2
3 define i1 @x(i32 %x) nounwind {
4 %div = sdiv i32 %x, 65536 ; [#uses=1]
5 %cmp = icmp slt i32 %div, -65536
6 ret i1 %cmp
7 }