[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