diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-10-11 10:20:01 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-10-11 10:20:01 +0000 |
commit | cb9d59665531cb2a894ac8af7e7cf476fba40600 (patch) | |
tree | ab0f8a8ced3fe61c01f5cbd807dabda731b62411 /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | 3cac85e07120f0cfcbc8e78a975f68ae99fcebbb (diff) | |
download | bcm5719-llvm-cb9d59665531cb2a894ac8af7e7cf476fba40600.tar.gz bcm5719-llvm-cb9d59665531cb2a894ac8af7e7cf476fba40600.zip |
InstCombine, InstSimplify: (%X /s C1) /s C2 isn't always 0 when C1 * C2 overflow
consider:
C1 = INT_MIN
C2 = -1
C1 * C2 overflows without a doubt but consider the following:
%x = i32 INT_MIN
This means that (%X /s C1) is 1 and (%X /s C1) /s C2 is -1.
N. B. Move the unsigned version of this transform to InstSimplify, it
doesn't create any new instructions.
This fixes PR21243.
llvm-svn: 219567
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index f2f67067d15..a01bac2077f 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -1057,6 +1057,16 @@ static Value *SimplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, (!isSigned && match(Op0, m_URem(m_Value(), m_Specific(Op1))))) return Constant::getNullValue(Op0->getType()); + // (X /u C1) /u C2 -> 0 if C1 * C2 overflow + ConstantInt *C1, *C2; + if (!isSigned && match(Op0, m_UDiv(m_Value(X), m_ConstantInt(C1))) && + match(Op1, m_ConstantInt(C2))) { + bool Overflow; + C1->getValue().umul_ov(C2->getValue(), Overflow); + if (Overflow) + return Constant::getNullValue(Op0->getType()); + } + // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) |