Explorar el Código

[Constant] Add 'isElementWiseEqual()' method

Promoting it from InstCombine's tryToReuseConstantFromSelectInComparison().

Return true if this constant and a constant 'Y' are element-wise equal.
This is identical to just comparing the pointers, with the exception that
for vectors, if only one of the constants has an `undef` element in some
lane, the constants still match.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369842 91177308-0d34-0410-b5e6-96231b3b80d8
Roman Lebedev hace 6 años
padre
commit
bce7b42941

+ 6 - 0
include/llvm/IR/Constant.h

@@ -86,6 +86,12 @@ public:
   /// floating-point constant with all NaN elements.
   bool isNaN() const;
 
+  /// Return true if this constant and a constant 'Y' are element-wise equal.
+  /// This is identical to just comparing the pointers, with the exception that
+  /// for vectors, if only one of the constants has an `undef` element in some
+  /// lane, the constants still match.
+  bool isElementWiseEqual(Value *Y) const;
+
   /// Return true if this is a vector constant that includes any undefined
   /// elements.
   bool containsUndefElement() const;

+ 15 - 0
lib/IR/Constants.cpp

@@ -22,6 +22,7 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/PatternMatch.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
@@ -250,6 +251,20 @@ bool Constant::isNaN() const {
   return true;
 }
 
+bool Constant::isElementWiseEqual(Value *Y) const {
+  // Are they fully identical?
+  if (this == Y)
+    return true;
+  // They may still be identical element-wise (if they have `undef`s).
+  auto *Cy = dyn_cast<Constant>(Y);
+  if (!Cy)
+    return false;
+  return PatternMatch::match(ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_EQ,
+                                                   const_cast<Constant *>(this),
+                                                   Cy),
+                             PatternMatch::m_One());
+}
+
 bool Constant::containsUndefElement() const {
   if (!getType()->isVectorTy())
     return false;

+ 2 - 16
lib/Transforms/InstCombine/InstCombineSelect.cpp

@@ -1296,18 +1296,6 @@ tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
 
   // FIXME: are there any magic icmp predicate+constant pairs we must not touch?
 
-  auto ConstantsAreElementWiseEqual = [](Constant *Cx, Value *Y) {
-    // Are they fully identical?
-    if (Cx == Y)
-      return true;
-    // They may still be identical element-wise (if they have `undef`s).
-    auto *Cy = dyn_cast<Constant>(Y);
-    if (!Cy)
-      return false;
-    return match(ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_EQ, Cx, Cy),
-                 m_One());
-  };
-
   Value *SelVal0, *SelVal1; // We do not care which one is from where.
   match(&Sel, m_Select(m_Value(), m_Value(SelVal0), m_Value(SelVal1)));
   // At least one of these values we are selecting between must be a constant
@@ -1317,10 +1305,8 @@ tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
     return nullptr;
 
   // Does this constant C match any of the `select` values?
-  auto MatchesSelectValue = [ConstantsAreElementWiseEqual, SelVal0,
-                             SelVal1](Constant *C) {
-    return ConstantsAreElementWiseEqual(C, SelVal0) ||
-           ConstantsAreElementWiseEqual(C, SelVal1);
+  auto MatchesSelectValue = [SelVal0, SelVal1](Constant *C) {
+    return C->isElementWiseEqual(SelVal0) || C->isElementWiseEqual(SelVal1);
   };
 
   // If C0 *already* matches true/false value of select, we are done.