llvm.org GIT mirror
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).
 5783 5783 return 0; 5784 5784 if (DivRHS->isZero()) 5785 5785 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. 5786 5791 5787 5792 // Compute Prod = CI * DivRHS. We are essentially solving an equation 5788 5793 // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and 5808 5813 // -1 if overflowed off the bottom end, or +1 if overflowed off the top end. 5809 5814 int LoOverflow = 0, HiOverflow = 0; 5810 5815 ConstantInt *LoBound = 0, *HiBound = 0; 5811 5812 5816 5813 5817 if (!DivIsSigned) { // udiv 5814 5818 // e.g. X/5 op 3 --> [15, 20) 5828 5832 HiOverflow = AddWithOverflow(HiBound, Prod, DivRHS, true); 5829 5833 } else { // (X / pos) op neg 5830 5834 // 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; 5834 5835 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 } 5836 5842 } 5837 5843 } else if (DivRHS->getValue().isNegative()) { // Divisor is < 0. 5838 5844 if (CmpRHSV == 0) { // (X / neg) op 0 5845 5851 } 5846 5852 } else if (CmpRHSV.isStrictlyPositive()) { // (X / neg) op pos 5847 5853 // e.g. X/-5 op 3 --> [-19, -14) 5854 HiBound = AddOne(Prod); 5848 5855 HiOverflow = LoOverflow = ProdOV ? -1 : 0; 5849 5856 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;⏎ 5852 5858 } 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; 5856 5861 if (!HiOverflow) 5857 5862 HiOverflow = SubWithOverflow(HiBound, Prod, DivRHS, true); 5858 5863 }
 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 }