Fix an icmp+sdiv optimization to check for and handle an overflow

condition. This fixes PR2740.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56076 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2008-09-10 23:30:57 +00:00
parent 8c9c55fb48
commit 1df3fd6683
2 changed files with 24 additions and 1 deletions

View File

@ -4695,6 +4695,21 @@ static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1,
return Result->getValue().ult(In1->getValue());
}
/// SubWithOverflow - Compute Result = In1-In2, returning true if the result
/// overflowed for this type.
static bool SubWithOverflow(ConstantInt *&Result, ConstantInt *In1,
ConstantInt *In2, bool IsSigned = false) {
Result = cast<ConstantInt>(Add(In1, In2));
if (IsSigned)
if (In2->getValue().isNegative())
return Result->getValue().slt(In1->getValue());
else
return Result->getValue().sgt(In1->getValue());
else
return Result->getValue().ugt(In1->getValue());
}
/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
/// code necessary to compute the offset from the base pointer (without adding
/// in the base pointer). Return the result as a signed integer of intptr size.
@ -5774,7 +5789,7 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
// e.g. X/-5 op -3 --> [15, 20)
LoBound = Prod;
LoOverflow = HiOverflow = ProdOV ? 1 : 0;
HiBound = Subtract(Prod, DivRHS);
HiOverflow = SubWithOverflow(HiBound, Prod, DivRHS, true);
}
// Dividing by a negative swaps the condition. LT <-> GT

View File

@ -0,0 +1,8 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep sdiv
; PR2740
define i1 @func_75(i32 %i2) nounwind {
%i3 = sdiv i32 %i2, -1328634635
%i4 = icmp eq i32 %i3, -1
ret i1 %i4
}