[PATCH] D51215: Fix misfolding of IRBuilder.CreateICmp(int_ty X, bitcast (float_ty Y) to int_ty)

Andrew Scheidecker via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 24 06:59:27 PDT 2018


AndrewScheidecker created this revision.
AndrewScheidecker added a reviewer: majnemer.

This code was incorrectly folding:

  IRBuilder.CreateICmp(int_ty X, bitcast (float_ty Y) to int_ty)

to:

  IRBuilder.CreateICmp(bitcast (int_ty X) to float_ty, float_ty Y)

which is malformed IR due to the mismatch between the integer predicate and the FP operands. In my case, this triggered a crash in an optimization pass.


Repository:
  rL LLVM

https://reviews.llvm.org/D51215

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,23 @@
   EXPECT_EQ(MN2, MF2->getRawElements());
   EXPECT_TRUE(verifyModule(*M));
 }
+TEST_F(IRBuilderTest, ICmpFolding) {
+  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), llvm::APInt(64, 1))});
+  auto F32x2 =
+      Builder.CreateBitCast(I64x1, VectorType::get(Type::getFloatTy(Ctx), 2));
+  auto F32 = Builder.CreateExtractElement(F32x2, uint64_t(0));
+  auto I32Type = Type::getInt32Ty(Ctx);
+  auto I32 = Builder.CreateBitCast(F32, I32Type);
+
+  // The operands of the folded ICmp should be 32-bit integers.
+  auto ICmp = Builder.CreateICmpEQ(Constant::getNullValue(I32Type), I32);
+  auto ICmpCE = dyn_cast<ConstantExpr>(ICmp);
+  EXPECT_TRUE(ICmpCE->getOperand(0)->getType() == I32Type);
+  EXPECT_TRUE(ICmpCE->getOperand(1)->getType() == I32Type);
+}
 }
Index: lib/IR/ConstantFold.cpp
===================================================================
--- lib/IR/ConstantFold.cpp
+++ lib/IR/ConstantFold.cpp
@@ -1981,11 +1981,13 @@
 
     // If the right hand side is a bitcast, try using its inverse to simplify
     // it by moving it to the left hand side.  We can't do this if it would turn
-    // a vector compare into a scalar compare or visa versa.
+    // a vector compare into a scalar compare or visa versa, or if it would turn
+    // the operands into FP values.
     if (ConstantExpr *CE2 = dyn_cast<ConstantExpr>(C2)) {
       Constant *CE2Op0 = CE2->getOperand(0);
       if (CE2->getOpcode() == Instruction::BitCast &&
-          CE2->getType()->isVectorTy() == CE2Op0->getType()->isVectorTy()) {
+          CE2->getType()->isVectorTy() == CE2Op0->getType()->isVectorTy() &&
+          !CE2Op0->getType()->isFPOrFPVectorTy()) {
         Constant *Inverse = ConstantExpr::getBitCast(C1, CE2Op0->getType());
         return ConstantExpr::getICmp(pred, Inverse, CE2Op0);
       }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51215.162373.patch
Type: text/x-patch
Size: 2155 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180824/29292411/attachment.bin>


More information about the llvm-commits mailing list