diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-12-10 09:14:55 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-12-10 09:14:55 +0000 |
commit | 7b86b77248e261cc99b00bd6105cbfa859f0de81 (patch) | |
tree | 0abc54ce343cea7eb5c82d49601963a569604bdf /llvm/lib/IR/ConstantFold.cpp | |
parent | ae707582c024e5db30f13d3fc3a7f21e72c4bc18 (diff) | |
download | llvm-7b86b77248e261cc99b00bd6105cbfa859f0de81.zip llvm-7b86b77248e261cc99b00bd6105cbfa859f0de81.tar.gz llvm-7b86b77248e261cc99b00bd6105cbfa859f0de81.tar.bz2 |
ConstantFold: div undef, 0 should fold to undef, not zero
Dividing by zero yields an undefined value.
llvm-svn: 223924
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 4cb22bc..cd40908 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -27,12 +27,14 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/PatternMatch.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include <limits> using namespace llvm; +using namespace llvm::PatternMatch; //===----------------------------------------------------------------------===// // ConstantFold*Instruction Implementations @@ -923,19 +925,27 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, // X * undef -> 0 otherwise return Constant::getNullValue(C1->getType()); } - case Instruction::UDiv: case Instruction::SDiv: + case Instruction::UDiv: + // X / undef -> undef + if (match(C1, m_Zero())) + return C2; + // undef / 0 -> undef // undef / 1 -> undef - if (Opcode == Instruction::UDiv || Opcode == Instruction::SDiv) - if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) - if (CI2->isOne()) - return C1; - // FALL THROUGH + if (match(C2, m_Zero()) || match(C2, m_One())) + return C1; + // undef / X -> 0 otherwise + return Constant::getNullValue(C1->getType()); case Instruction::URem: case Instruction::SRem: - if (!isa<UndefValue>(C2)) // undef / X -> 0 - return Constant::getNullValue(C1->getType()); - return C2; // X / undef -> undef + // X % undef -> undef + if (match(C2, m_Undef())) + return C2; + // undef % 0 -> undef + if (match(C2, m_Zero())) + return C1; + // undef % X -> 0 otherwise + return Constant::getNullValue(C1->getType()); case Instruction::Or: // X | undef -> -1 if (isa<UndefValue>(C1) && isa<UndefValue>(C2)) // undef | undef -> undef return C1; |