diff options
author | Nikita Popov <npopov@redhat.com> | 2024-07-03 15:06:27 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2024-07-03 15:19:26 +0200 |
commit | 2dbb454791044e3ef91c8e7069f953b7406d78c6 (patch) | |
tree | a1d6dfd818e5b0a9f750db80b7fce3d0934aae4b /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 0778b5d0d296edaca2ac52f2c8d2c806d492355a (diff) | |
download | llvm-2dbb454791044e3ef91c8e7069f953b7406d78c6.zip llvm-2dbb454791044e3ef91c8e7069f953b7406d78c6.tar.gz llvm-2dbb454791044e3ef91c8e7069f953b7406d78c6.tar.bz2 |
[ValueTracking][LVI] Consolidate vector constant range calculation
Add a common helper used for computeConstantRange() and LVI. The
implementation is a mix of both, with the efficient handling for
ConstantDataVector taken from computeConstantRange(), and the
general handling (including non-splat poison) from LVI.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 7660009..5476dc5 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -9498,6 +9498,39 @@ static void setLimitForFPToI(const Instruction *I, APInt &Lower, APInt &Upper) { } } +ConstantRange llvm::getVectorConstantRange(const Constant *C) { + assert(C->getType()->isVectorTy() && "Expected vector constant"); + if (auto *CI = dyn_cast_or_null<ConstantInt>( + C->getSplatValue(/*AllowPoison=*/true))) + return ConstantRange(CI->getValue()); + + unsigned BitWidth = C->getType()->getScalarSizeInBits(); + if (auto *CDV = dyn_cast<ConstantDataVector>(C)) { + ConstantRange CR = ConstantRange::getEmpty(BitWidth); + for (unsigned I = 0, E = CDV->getNumElements(); I < E; ++I) + CR = CR.unionWith(CDV->getElementAsAPInt(I)); + return CR; + } + + if (auto *CV = dyn_cast<ConstantVector>(C)) { + ConstantRange CR = ConstantRange::getEmpty(BitWidth); + for (unsigned I = 0, E = CV->getNumOperands(); I < E; ++I) { + Constant *Elem = C->getAggregateElement(I); + if (!Elem) + return ConstantRange::getFull(BitWidth); + if (isa<PoisonValue>(Elem)) + continue; + auto *CI = dyn_cast<ConstantInt>(Elem); + if (!CI) + return ConstantRange::getFull(BitWidth); + CR = CR.unionWith(CI->getValue()); + } + return CR; + } + + return ConstantRange::getFull(BitWidth); +} + ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned, bool UseInstrInfo, AssumptionCache *AC, const Instruction *CtxI, @@ -9508,19 +9541,15 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned, if (Depth == MaxAnalysisRecursionDepth) return ConstantRange::getFull(V->getType()->getScalarSizeInBits()); - const APInt *C; - if (match(V, m_APInt(C))) - return ConstantRange(*C); - unsigned BitWidth = V->getType()->getScalarSizeInBits(); - - if (auto *VC = dyn_cast<ConstantDataVector>(V)) { - ConstantRange CR = ConstantRange::getEmpty(BitWidth); - for (unsigned ElemIdx = 0, NElem = VC->getNumElements(); ElemIdx < NElem; - ++ElemIdx) - CR = CR.unionWith(VC->getElementAsAPInt(ElemIdx)); - return CR; + if (auto *C = dyn_cast<Constant>(V)) { + if (auto *CI = dyn_cast<ConstantInt>(C)) + return ConstantRange(CI->getValue()); + if (C->getType()->isVectorTy()) + return getVectorConstantRange(C); + return ConstantRange::getFull(C->getType()->getScalarSizeInBits()); } + unsigned BitWidth = V->getType()->getScalarSizeInBits(); InstrInfoQuery IIQ(UseInstrInfo); ConstantRange CR = ConstantRange::getFull(BitWidth); if (auto *BO = dyn_cast<BinaryOperator>(V)) { |