aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorAndrew Scheidecker <andrew@scheidecker.net>2019-02-19 21:21:54 +0000
committerAndrew Scheidecker <andrew@scheidecker.net>2019-02-19 21:21:54 +0000
commit8ca3f3863ed065b4c7167fe750d414ecf63114f7 (patch)
treef4ea866ba865fb581c825baf29a1c07078bda34f /llvm/lib/IR/ConstantFold.cpp
parentbddf892a6d3afadaeeb3c9431c5e89a207739bdc (diff)
downloadllvm-8ca3f3863ed065b4c7167fe750d414ecf63114f7.zip
llvm-8ca3f3863ed065b4c7167fe750d414ecf63114f7.tar.gz
llvm-8ca3f3863ed065b4c7167fe750d414ecf63114f7.tar.bz2
[ConstantFold] Fix misfolding fcmp of a ConstantExpr NaN with itself.
The code incorrectly inferred that the relationship of a constant expression to itself is FCMP_OEQ (ordered and equal), when it's actually FCMP_UEQ (unordered *or* equal). This change corrects that, and adds some more limited folds that can be done in this case. Differential revision: https://reviews.llvm.org/D51216 llvm-svn: 354381
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 2c958c7..037f120 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -1359,8 +1359,9 @@ static FCmpInst::Predicate evaluateFCmpRelation(Constant *V1, Constant *V2) {
assert(V1->getType() == V2->getType() &&
"Cannot compare values of different types!");
- // Handle degenerate case quickly
- if (V1 == V2) return FCmpInst::FCMP_OEQ;
+ // We do not know if a constant expression will evaluate to a number or NaN.
+ // Therefore, we can only say that the relation is unordered or equal.
+ if (V1 == V2) return FCmpInst::FCMP_UEQ;
if (!isa<ConstantExpr>(V1)) {
if (!isa<ConstantExpr>(V2)) {
@@ -1855,7 +1856,6 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
default: llvm_unreachable("Unknown relation!");
case FCmpInst::FCMP_UNO:
case FCmpInst::FCMP_ORD:
- case FCmpInst::FCMP_UEQ:
case FCmpInst::FCMP_UNE:
case FCmpInst::FCMP_ULT:
case FCmpInst::FCMP_UGT:
@@ -1901,6 +1901,13 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
else if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE)
Result = 1;
break;
+ case FCmpInst::FCMP_UEQ: // We know that C1 == C2 || isUnordered(C1, C2).
+ // We can only partially decide this relation.
+ if (pred == FCmpInst::FCMP_ONE)
+ Result = 0;
+ else if (pred == FCmpInst::FCMP_UEQ)
+ Result = 1;
+ break;
}
// If we evaluated the result, return it now.