From: Roman Lebedev Date: Sat, 24 Aug 2019 06:49:51 +0000 (+0000) Subject: [Constant] Add 'isElementWiseEqual()' method X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bce7b429412865ee1fffec09a1ca65d5280f0f66;p=llvm [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 --- diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h index 93157665122..2b6a6e4141b 100644 --- a/include/llvm/IR/Constant.h +++ b/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; diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index ee0c1e1f5f6..f792f01efc1 100644 --- a/lib/IR/Constants.cpp +++ b/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(Y); + if (!Cy) + return false; + return PatternMatch::match(ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_EQ, + const_cast(this), + Cy), + PatternMatch::m_One()); +} + bool Constant::containsUndefElement() const { if (!getType()->isVectorTy()) return false; diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp index d5de10c32c4..50f6b2bdfd8 100644 --- a/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/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(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.