Index: lib/IR/ConstantFold.cpp =================================================================== --- lib/IR/ConstantFold.cpp +++ lib/IR/ConstantFold.cpp @@ -1361,7 +1361,7 @@ "Cannot compare values of different types!"); // Handle degenerate case quickly - if (V1 == V2) return FCmpInst::FCMP_OEQ; + if (V1 == V2) return FCmpInst::FCMP_UEQ; if (!isa(V1)) { if (!isa(V2)) { @@ -1856,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: @@ -1902,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. Index: unittests/IR/IRBuilderTest.cpp =================================================================== --- unittests/IR/IRBuilderTest.cpp +++ unittests/IR/IRBuilderTest.cpp @@ -664,4 +664,47 @@ EXPECT_EQ(MN2, MF2->getRawElements()); EXPECT_TRUE(verifyModule(*M)); } + +TEST_F(IRBuilderTest, FCmpFolding) { + IRBuilder<> Builder(BB); + + // Create a FP ConstantExpr by bitcasting the address of a global variable. + auto I32 = ConstantExpr::getPtrToInt(GV, Type::getInt32Ty(Ctx)); + auto F32 = ConstantExpr::getBitCast(I32, Type::getFloatTy(Ctx)); + EXPECT_TRUE(isa(F32)); + + auto FCmpOEQ = Builder.CreateFCmpOEQ(F32, F32); + auto FCmpOGT = Builder.CreateFCmpOGT(F32, F32); + auto FCmpOGE = Builder.CreateFCmpOGE(F32, F32); + auto FCmpOLT = Builder.CreateFCmpOLT(F32, F32); + auto FCmpOLE = Builder.CreateFCmpOLE(F32, F32); + auto FCmpONE = Builder.CreateFCmpONE(F32, F32); + auto FCmpORD = Builder.CreateFCmpORD(F32, F32); + auto FCmpUEQ = Builder.CreateFCmpUEQ(F32, F32); + auto FCmpUGT = Builder.CreateFCmpUGT(F32, F32); + auto FCmpUGE = Builder.CreateFCmpUGE(F32, F32); + auto FCmpULT = Builder.CreateFCmpULT(F32, F32); + auto FCmpULE = Builder.CreateFCmpULE(F32, F32); + auto FCmpUNE = Builder.CreateFCmpUNE(F32, F32); + auto FCmpUNO = Builder.CreateFCmpUNO(F32, F32); + + // Assuming that the bitcast vector produced a constant expression rather than + // a constant, the folder should only be able to infer a constant value for + // FCMP_ONE (ordered and not-equal) and FCMP_UEQ (unordered or equal). + EXPECT_EQ(FCmpONE, ConstantInt::getFalse(Type::getInt1Ty(Ctx))); + EXPECT_EQ(FCmpUEQ, ConstantInt::getTrue(Type::getInt1Ty(Ctx))); + + EXPECT_FALSE(isa(FCmpOEQ)); + EXPECT_FALSE(isa(FCmpOGT)); + EXPECT_FALSE(isa(FCmpOGE)); + EXPECT_FALSE(isa(FCmpOLT)); + EXPECT_FALSE(isa(FCmpOLE)); + EXPECT_FALSE(isa(FCmpORD)); + EXPECT_FALSE(isa(FCmpUNE)); + EXPECT_FALSE(isa(FCmpUGT)); + EXPECT_FALSE(isa(FCmpUGE)); + EXPECT_FALSE(isa(FCmpULT)); + EXPECT_FALSE(isa(FCmpULE)); + EXPECT_FALSE(isa(FCmpUNO)); +} }