forked from OSchip/llvm-project
[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:
parent
de19f749e0
commit
9cf08c6de1
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue