Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -2024,6 +2024,20 @@ return F->hasFnAttribute(Attribute::VScaleRange); } + const APInt *Shift; + if (Q.CxtI && match(V, m_Shl(m_VScale(), m_APInt(Shift)))) { + const Function *F = Q.CxtI->getFunction(); + // The vscale_range indicates vscale is a power-of-two. + if (F->hasFnAttribute(Attribute::VScaleRange)) { + Attribute Attr = F->getFnAttribute(Attribute::VScaleRange); + if (std::optional MaxVScale = Attr.getVScaleRangeMax()) { + unsigned Bitwidth = V->getType()->getScalarSizeInBits(); + if (Log2_32(*MaxVScale) + Shift->getZExtValue() < Bitwidth) + return true; + } + } + } + // 1 << X is clearly a power of two if the one is not shifted off the end. If // it is shifted off the end then the result is undefined. if (match(V, m_Shl(m_One(), m_Value())))