/// Return true if a constant shift amount is always less than the specified
/// bit-width. If not, the shift could create poison in the narrower type.
static bool canNarrowShiftAmt(Constant *C, unsigned BitWidth) {
- if (auto *ScalarC = dyn_cast<ConstantInt>(C))
- return ScalarC->getZExtValue() < BitWidth;
-
- if (C->getType()->isVectorTy()) {
- // Check each element of a constant vector.
- unsigned NumElts = cast<FixedVectorType>(C->getType())->getNumElements();
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *Elt = C->getAggregateElement(i);
- if (!Elt)
- return false;
- if (isa<UndefValue>(Elt))
- continue;
- auto *CI = dyn_cast<ConstantInt>(Elt);
- if (!CI || CI->getZExtValue() >= BitWidth)
- return false;
- }
- return true;
- }
-
- // The constant is a constant expression or unknown.
- return false;
+ APInt Threshold(C->getType()->getScalarSizeInBits(), BitWidth);
+ return match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold));
}
/// Try to use narrower ops (sink zext ops) for an 'and' with binop operand and