summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-01-19 21:55:26 +0000
committerChris Lattner <sabre@nondot.org>2009-01-19 21:55:26 +0000
commitdd8ef1bf30637000efd4856d278d6a323374fba1 (patch)
tree52d6e17bc3b366bd74a579c8f0826845bfa5f39c
parentcd0b1bf0a06dec7da3860090d5a9d214a220753c (diff)
downloadbcm5719-llvm-dd8ef1bf30637000efd4856d278d6a323374fba1.tar.gz
bcm5719-llvm-dd8ef1bf30637000efd4856d278d6a323374fba1.zip
div/rem by zero and div/rem overflow are both undefined according to
langref. Constant fold them to undef instead of trying to preserve the trap. This fixes PR3354. llvm-svn: 62534
-rw-r--r--llvm/lib/VMCore/ConstantFold.cpp22
1 files changed, 11 insertions, 11 deletions
diff --git a/llvm/lib/VMCore/ConstantFold.cpp b/llvm/lib/VMCore/ConstantFold.cpp
index 9fa41b373cd..0c5297fccb3 100644
--- a/llvm/lib/VMCore/ConstantFold.cpp
+++ b/llvm/lib/VMCore/ConstantFold.cpp
@@ -655,11 +655,15 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
case Instruction::SDiv:
if (CI2->equalsInt(1))
return const_cast<Constant*>(C1); // X / 1 == X
+ if (CI2->equalsInt(0))
+ return UndefValue::get(CI2->getType()); // X / 0 == undef
break;
case Instruction::URem:
case Instruction::SRem:
if (CI2->equalsInt(1))
return Constant::getNullValue(CI2->getType()); // X % 1 == 0
+ if (CI2->equalsInt(0))
+ return UndefValue::get(CI2->getType()); // X % 0 == undef
break;
case Instruction::And:
if (CI2->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0
@@ -733,24 +737,20 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
case Instruction::Mul:
return ConstantInt::get(C1V * C2V);
case Instruction::UDiv:
- if (CI2->isNullValue())
- return 0; // X / 0 -> can't fold
+ assert(!CI2->isNullValue() && "Div by zero handled above");
return ConstantInt::get(C1V.udiv(C2V));
case Instruction::SDiv:
- if (CI2->isNullValue())
- return 0; // X / 0 -> can't fold
+ assert(!CI2->isNullValue() && "Div by zero handled above");
if (C2V.isAllOnesValue() && C1V.isMinSignedValue())
- return 0; // MIN_INT / -1 -> overflow
+ return UndefValue::get(CI1->getType()); // MIN_INT / -1 -> undef
return ConstantInt::get(C1V.sdiv(C2V));
case Instruction::URem:
- if (C2->isNullValue())
- return 0; // X / 0 -> can't fold
+ assert(!CI2->isNullValue() && "Div by zero handled above");
return ConstantInt::get(C1V.urem(C2V));
- case Instruction::SRem:
- if (CI2->isNullValue())
- return 0; // X % 0 -> can't fold
+ case Instruction::SRem:
+ assert(!CI2->isNullValue() && "Div by zero handled above");
if (C2V.isAllOnesValue() && C1V.isMinSignedValue())
- return 0; // MIN_INT % -1 -> overflow
+ return UndefValue::get(CI1->getType()); // MIN_INT % -1 -> undef
return ConstantInt::get(C1V.srem(C2V));
case Instruction::And:
return ConstantInt::get(C1V & C2V);
OpenPOWER on IntegriCloud