[llvm] r354381 - [ConstantFold] Fix misfolding fcmp of a ConstantExpr NaN with itself.
Andrew Scheidecker via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 19 13:21:54 PST 2019
Author: andrewscheidecker
Date: Tue Feb 19 13:21:54 2019
New Revision: 354381
URL: http://llvm.org/viewvc/llvm-project?rev=354381&view=rev
Log:
[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
Modified:
llvm/trunk/lib/IR/ConstantFold.cpp
llvm/trunk/test/Transforms/ConstProp/bitcast.ll
Modified: llvm/trunk/lib/IR/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantFold.cpp?rev=354381&r1=354380&r2=354381&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantFold.cpp (original)
+++ llvm/trunk/lib/IR/ConstantFold.cpp Tue Feb 19 13:21:54 2019
@@ -1359,8 +1359,9 @@ static FCmpInst::Predicate evaluateFCmpR
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::ConstantFoldCompareInstr
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::ConstantFoldCompareInstr
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.
Modified: llvm/trunk/test/Transforms/ConstProp/bitcast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/bitcast.ll?rev=354381&r1=354380&r2=354381&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/ConstProp/bitcast.ll (original)
+++ llvm/trunk/test/Transforms/ConstProp/bitcast.ll Tue Feb 19 13:21:54 2019
@@ -36,21 +36,21 @@ define i1 @bad_fcmp_constexpr_bitcast()
ret i1 %cmp
}
-; FIXME: If the bitcasts result in a NaN FP value, then "ordered and equal" would be false.
+; Ensure that an "ordered and equal" fcmp of a ConstantExpr to itself is not folded, since the ConstantExpr may be a NaN.
define i1 @fcmp_constexpr_oeq(float %conv) {
; CHECK-LABEL: @fcmp_constexpr_oeq(
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: ret i1 fcmp oeq (float bitcast (i32 ptrtoint (i16* @a to i32) to float), float bitcast (i32 ptrtoint (i16* @a to i32) to float))
;
%cmp = fcmp oeq float bitcast (i32 ptrtoint (i16* @a to i32) to float), bitcast (i32 ptrtoint (i16* @a to i32) to float)
ret i1 %cmp
}
-; FIXME: If the bitcasts result in a NaN FP value, then "unordered or not equal" would be true.
+; Ensure that an "unordered or not equal" fcmp of a ConstantExpr to itself is not folded, since the ConstantExpr may be a NaN.
define i1 @fcmp_constexpr_une(float %conv) {
; CHECK-LABEL: @fcmp_constexpr_une(
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: ret i1 fcmp une (float bitcast (i32 ptrtoint (i16* @a to i32) to float), float bitcast (i32 ptrtoint (i16* @a to i32) to float))
;
%cmp = fcmp une float bitcast (i32 ptrtoint (i16* @a to i32) to float), bitcast (i32 ptrtoint (i16* @a to i32) to float)
ret i1 %cmp
More information about the llvm-commits
mailing list