diff options
author | Andrew Scheidecker <andrew@scheidecker.net> | 2019-02-19 21:21:54 +0000 |
---|---|---|
committer | Andrew Scheidecker <andrew@scheidecker.net> | 2019-02-19 21:21:54 +0000 |
commit | 8ca3f3863ed065b4c7167fe750d414ecf63114f7 (patch) | |
tree | f4ea866ba865fb581c825baf29a1c07078bda34f /llvm/lib/IR/ConstantFold.cpp | |
parent | bddf892a6d3afadaeeb3c9431c5e89a207739bdc (diff) | |
download | llvm-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.cpp | 13 |
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. |