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
/// 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;
#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"
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;
// 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
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.