diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1359,8 +1359,9 @@ 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(V1)) { if (!isa(V2)) { @@ -1855,7 +1856,6 @@ 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 @@ 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. diff --git a/llvm/test/Transforms/ConstProp/bitcast.ll b/llvm/test/Transforms/ConstProp/bitcast.ll --- a/llvm/test/Transforms/ConstProp/bitcast.ll +++ b/llvm/test/Transforms/ConstProp/bitcast.ll @@ -23,21 +23,21 @@ 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