From 895316336e4a774a47b1a4daada070e0ac97f46e Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 10 Dec 2014 09:14:55 +0000 Subject: [PATCH] ConstantFold: div undef, 0 should fold to undef, not zero Dividing by zero yields an undefined value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223924 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/ConstantFold.cpp | 28 ++++++++++++++++++--------- test/Transforms/InstSimplify/undef.ll | 7 +++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 4cb22bc97a7..cd409083afc 100644 --- a/lib/IR/ConstantFold.cpp +++ b/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 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(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(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(C1) && isa(C2)) // undef | undef -> undef return C1; diff --git a/test/Transforms/InstSimplify/undef.ll b/test/Transforms/InstSimplify/undef.ll index 3742d7450af..5787badfd14 100644 --- a/test/Transforms/InstSimplify/undef.ll +++ b/test/Transforms/InstSimplify/undef.ll @@ -188,3 +188,10 @@ define i32 @test23(i32 %a) { %b = lshr exact i32 undef, %a ret i32 %b } + +; CHECK-LABEL: @test24 +; CHECK: ret i32 undef +define i32 @test24(i32 %a) { + %b = udiv i32 undef, 0 + ret i32 %b +} -- 2.34.1