aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-03-23 05:33:23 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-03-23 05:33:23 +0000
commitb8f1c1657f1b63f92957c5b1c5a4e26e4945c34d (patch)
tree6bc837c298cdd4082a9d97631b702db984dd94ef
parentf62cc9f9e5ddd95adcb0f7317ef4458bbdbebffd (diff)
downloadexternal_llvm-b8f1c1657f1b63f92957c5b1c5a4e26e4945c34d.tar.gz
external_llvm-b8f1c1657f1b63f92957c5b1c5a4e26e4945c34d.tar.bz2
external_llvm-b8f1c1657f1b63f92957c5b1c5a4e26e4945c34d.zip
Fix constant fold of div by zero and rem by zero to match IEEE 754
requirements. We must return NaN in some cases and correctly signed infinity in other cases. Passes CFP2006 (not that that says much). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35277 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/VMCore/ConstantFold.cpp26
1 files changed, 18 insertions, 8 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 05a75883a1..d7e51956e4 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -651,17 +651,27 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
case Instruction::Mul:
return ConstantFP::get(CFP1->getType(), C1Val * C2Val);
case Instruction::FDiv:
- if (CFP2->isExactlyValue(0.0))
- return ConstantFP::get(CFP1->getType(),
- std::numeric_limits<double>::infinity());
- if (CFP2->isExactlyValue(-0.0))
- return ConstantFP::get(CFP1->getType(),
- -std::numeric_limits<double>::infinity());
+ if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0))
+ if (CFP1->isExactlyValue(0.0) || CFP1->isExactlyValue(-0.0))
+ // IEEE 754, Section 7.1, #4
+ return ConstantFP::get(CFP1->getType(),
+ std::numeric_limits<double>::quiet_NaN());
+ else if (CFP2->isExactlyValue(-0.0) || C1Val < 0.0)
+ // IEEE 754, Section 7.2, negative infinity case
+ return ConstantFP::get(CFP1->getType(),
+ -std::numeric_limits<double>::infinity());
+ else
+ // IEEE 754, Section 7.2, positive infinity case
+ return ConstantFP::get(CFP1->getType(),
+ std::numeric_limits<double>::infinity());
return ConstantFP::get(CFP1->getType(), C1Val / C2Val);
case Instruction::FRem:
- if (CFP2->isNullValue())
- return 0;
+ if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0))
+ // IEEE 754, Section 7.1, #5
+ return ConstantFP::get(CFP1->getType(),
+ std::numeric_limits<double>::quiet_NaN());
return ConstantFP::get(CFP1->getType(), std::fmod(C1Val, C2Val));
+
}
}
} else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) {