return const_cast<Constant*>(
static_cast<const Constant *>(this)->stripPointerCasts());
}
+
+ /// Try to replace undefined constant C or undefined elements in C with
+ /// Replacement. If no changes are made, the constant C is returned.
+ static Constant *replaceUndefsWith(Constant *C, Constant *Replacement);
};
} // end namespace llvm
#include <algorithm>
using namespace llvm;
+using namespace PatternMatch;
//===----------------------------------------------------------------------===//
// Constant Class
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());
+ return match(ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_EQ,
+ const_cast<Constant *>(this), Cy),
+ m_One());
}
bool Constant::containsUndefElement() const {
}
}
+Constant *Constant::replaceUndefsWith(Constant *C, Constant *Replacement) {
+ Type *Ty = C->getType();
+ if (C && match(C, m_Undef())) {
+ assert(Ty == Replacement->getType() && "Expected matching types");
+ return Replacement;
+ }
+
+ // Don't know how to deal with this constant.
+ if (!Ty->isVectorTy())
+ return C;
+
+ unsigned NumElts = Ty->getVectorNumElements();
+ SmallVector<Constant *, 32> NewC(NumElts);
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *EltC = C->getAggregateElement(i);
+ assert(EltC->getType() == Replacement->getType() &&
+ "Expected matching types");
+ NewC[i] = EltC && match(EltC, m_Undef()) ? Replacement : EltC;
+ }
+ return ConstantVector::get(NewC);
+}
//===----------------------------------------------------------------------===//
return Ret;
}
-// Try to replace `undef` constants in C with Replacement.
-static Constant *replaceUndefsWith(Constant *C, Constant *Replacement) {
- if (C && match(C, m_Undef()))
- return Replacement;
-
- if (auto *CV = dyn_cast<ConstantVector>(C)) {
- llvm::SmallVector<Constant *, 32> NewOps(CV->getNumOperands());
- for (unsigned i = 0, NumElts = NewOps.size(); i != NumElts; ++i) {
- Constant *EltC = CV->getOperand(i);
- NewOps[i] = EltC && match(EltC, m_Undef()) ? Replacement : EltC;
- }
- return ConstantVector::get(NewOps);
- }
-
- // Don't know how to deal with this constant.
- return C;
-}
-
// If we have some pattern that leaves only some low bits set, and then performs
// left-shift of those bits, if none of the bits that are left after the final
// shift are modified by the mask, we can omit the mask.
// completely unknown. Replace the the `undef` shift amounts with final
// shift bitwidth to ensure that the value remains undef when creating the
// subsequent shift op.
- SumOfShAmts = replaceUndefsWith(
+ SumOfShAmts = Constant::replaceUndefsWith(
SumOfShAmts, ConstantInt::get(SumOfShAmts->getType()->getScalarType(),
ExtendedTy->getScalarSizeInBits()));
auto *ExtendedSumOfShAmts = ConstantExpr::getZExt(SumOfShAmts, ExtendedTy);
// bitwidth of innermost shift to ensure that the value remains undef when
// creating the subsequent shift op.
unsigned WidestTyBitWidth = WidestTy->getScalarSizeInBits();
- ShAmtsDiff = replaceUndefsWith(
+ ShAmtsDiff = Constant::replaceUndefsWith(
ShAmtsDiff, ConstantInt::get(ShAmtsDiff->getType()->getScalarType(),
-WidestTyBitWidth));
auto *ExtendedNumHighBitsToClear = ConstantExpr::getZExt(