[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