[PATCH] D51216: Fix IRBuilder.CreateFCmp(X, X) misfolding
Andrew Scheidecker via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 24 07:03:25 PDT 2018
AndrewScheidecker created this revision.
AndrewScheidecker added a reviewer: majnemer.
The code incorrectly inferred that the relationship of a constant expression X to itself is FCMP_OEQ (ordered and equal), when it's actually FCMP_UEQ (unordered or equal).
This corrects that, and adds some more limited folds that can be done in this case.
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,50 @@
EXPECT_EQ(MN2, MF2->getRawElements());
EXPECT_TRUE(verifyModule(*M));
}
+
+TEST_F(IRBuilderTest, FCmpFolding) {
+ IRBuilder<> Builder(BB);
+
+ // Use a bitcast vector to get a constant expression instead of a literal
+ // constant.
+ auto I64x1 = ConstantVector::get({ConstantInt::get(
+ Type::getInt64Ty(Ctx), APInt(64, 0x7fffffff7fffffffull))});
+ auto F32x2 =
+ Builder.CreateBitCast(I64x1, VectorType::get(Type::getFloatTy(Ctx), 2));
+ auto F32 = Builder.CreateExtractElement(F32x2, uint64_t(0));
+
+ 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.162375.patch
Type: text/x-patch
Size: 3494 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180824/abb2005e/attachment.bin>
More information about the llvm-commits
mailing list