[PATCH] D51216: Fix IRBuilder.CreateFCmp(X, X) misfolding
Andrew Scheidecker via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 19 13:20:34 PDT 2018
AndrewScheidecker updated this revision to Diff 166176.
AndrewScheidecker added a comment.
I made the test a little simpler by bitcasting a GlobalVariable pointer to a float to get a FP typed ConstantExpr, instead of using a bitcast vector.
Repository:
rL LLVM
https://reviews.llvm.org/D51216
Files:
lib/IR/ConstantFold.cpp
unittests/IR/IRBuilderTest.cpp
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<ConstantExpr>(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<ConstantInt>(FCmpOEQ));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpOGT));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpOGE));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpOLT));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpOLE));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpORD));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpUNE));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpUGT));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpUGE));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpULT));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpULE));
+ EXPECT_FALSE(isa<ConstantInt>(FCmpUNO));
+}
}
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<ConstantExpr>(V1)) {
if (!isa<ConstantExpr>(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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51216.166176.patch
Type: text/x-patch
Size: 3374 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180919/8ee24e4f/attachment.bin>
More information about the llvm-commits
mailing list