[PATCH] D72784: [IR] fix crash in Constant::isElementWiseEqual() with FP types

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 15 09:44:33 PST 2020


spatel created this revision.
spatel added reviewers: lebedev.ri, nikic.
Herald added subscribers: hiraditya, mcrosier.
Herald added a project: LLVM.

We lifted this code from InstCombine for general usage in:
rL369842 <https://reviews.llvm.org/rL369842>
...but it's not safe as-is. There are no existing users that can trigger this bug, but I discovered it via crashing several regression tests when trying to use it for select folding in InstSimplify.

ICmp requires (vector) integer types, so bitcast the constants before trying the match. That matches the definition of "equal or undef" that I was looking for. If someone wants an FP-aware version of equality (deal with NaN, -0.0), that could be a different mode or different function.


https://reviews.llvm.org/D72784

Files:
  llvm/lib/IR/Constants.cpp
  llvm/unittests/IR/ConstantsTest.cpp


Index: llvm/unittests/IR/ConstantsTest.cpp
===================================================================
--- llvm/unittests/IR/ConstantsTest.cpp
+++ llvm/unittests/IR/ConstantsTest.cpp
@@ -607,7 +607,6 @@
   EXPECT_FALSE(C12U1->isElementWiseEqual(C12U2));
   EXPECT_FALSE(C12U21->isElementWiseEqual(C12U2));
 
-/* FIXME: This will crash.
   Type *FltTy = Type::getFloatTy(Context);
   Constant *CFU = UndefValue::get(FltTy);
   Constant *CF1 = ConstantFP::get(FltTy, 1.0);
@@ -621,7 +620,6 @@
   EXPECT_TRUE(CF12U1->isElementWiseEqual(CF1211));
   EXPECT_FALSE(CF12U2->isElementWiseEqual(CF12U1));
   EXPECT_FALSE(CF12U1->isElementWiseEqual(CF12U2));
-*/
 }
 
 }  // end anonymous namespace
Index: llvm/lib/IR/Constants.cpp
===================================================================
--- llvm/lib/IR/Constants.cpp
+++ llvm/lib/IR/Constants.cpp
@@ -287,11 +287,11 @@
     return false;
 
   // They may still be identical element-wise (if they have `undef`s).
-  // FIXME: This crashes on FP vector constants.
-  return match(ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_EQ,
-                                     const_cast<Constant *>(this),
-                                     cast<Constant>(Y)),
-               m_One());
+  // Bitcast to integer to allow exact bitwise comparison for all types.
+  Type *IntTy = VectorType::getInteger(cast<VectorType>(Ty));
+  Constant *C0 = ConstantExpr::getBitCast(const_cast<Constant *>(this), IntTy);
+  Constant *C1 = ConstantExpr::getBitCast(cast<Constant>(Y), IntTy);
+  return match(ConstantExpr::getICmp(ICmpInst::ICMP_EQ, C0, C1), m_One());
 }
 
 bool Constant::containsUndefElement() const {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72784.238297.patch
Type: text/x-patch
Size: 1659 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200115/6efc5c55/attachment.bin>


More information about the llvm-commits mailing list