[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.

llvm-svn: 369842
This commit is contained in:
Roman Lebedev 2019-08-24 06:49:51 +00:00
parent de19f749e0
commit 9cf08c6de1
3 changed files with 23 additions and 16 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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.