mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-03 17:24:24 +00:00
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
This commit is contained in:
parent
6578f1beb1
commit
895316336e
@ -27,12 +27,14 @@
|
|||||||
#include "llvm/IR/GlobalVariable.h"
|
#include "llvm/IR/GlobalVariable.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/Operator.h"
|
#include "llvm/IR/Operator.h"
|
||||||
|
#include "llvm/IR/PatternMatch.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
using namespace llvm::PatternMatch;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ConstantFold*Instruction Implementations
|
// ConstantFold*Instruction Implementations
|
||||||
@ -923,19 +925,27 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
|||||||
// X * undef -> 0 otherwise
|
// X * undef -> 0 otherwise
|
||||||
return Constant::getNullValue(C1->getType());
|
return Constant::getNullValue(C1->getType());
|
||||||
}
|
}
|
||||||
case Instruction::UDiv:
|
|
||||||
case Instruction::SDiv:
|
case Instruction::SDiv:
|
||||||
|
case Instruction::UDiv:
|
||||||
|
// X / undef -> undef
|
||||||
|
if (match(C1, m_Zero()))
|
||||||
|
return C2;
|
||||||
|
// undef / 0 -> undef
|
||||||
// undef / 1 -> undef
|
// undef / 1 -> undef
|
||||||
if (Opcode == Instruction::UDiv || Opcode == Instruction::SDiv)
|
if (match(C2, m_Zero()) || match(C2, m_One()))
|
||||||
if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2))
|
return C1;
|
||||||
if (CI2->isOne())
|
// undef / X -> 0 otherwise
|
||||||
return C1;
|
return Constant::getNullValue(C1->getType());
|
||||||
// FALL THROUGH
|
|
||||||
case Instruction::URem:
|
case Instruction::URem:
|
||||||
case Instruction::SRem:
|
case Instruction::SRem:
|
||||||
if (!isa<UndefValue>(C2)) // undef / X -> 0
|
// X % undef -> undef
|
||||||
return Constant::getNullValue(C1->getType());
|
if (match(C2, m_Undef()))
|
||||||
return C2; // X / undef -> 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
|
case Instruction::Or: // X | undef -> -1
|
||||||
if (isa<UndefValue>(C1) && isa<UndefValue>(C2)) // undef | undef -> undef
|
if (isa<UndefValue>(C1) && isa<UndefValue>(C2)) // undef | undef -> undef
|
||||||
return C1;
|
return C1;
|
||||||
|
@ -188,3 +188,10 @@ define i32 @test23(i32 %a) {
|
|||||||
%b = lshr exact i32 undef, %a
|
%b = lshr exact i32 undef, %a
|
||||||
ret i32 %b
|
ret i32 %b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test24
|
||||||
|
; CHECK: ret i32 undef
|
||||||
|
define i32 @test24(i32 %a) {
|
||||||
|
%b = udiv i32 undef, 0
|
||||||
|
ret i32 %b
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user