aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-07-03 15:06:27 +0200
committerNikita Popov <npopov@redhat.com>2024-07-03 15:19:26 +0200
commit2dbb454791044e3ef91c8e7069f953b7406d78c6 (patch)
treea1d6dfd818e5b0a9f750db80b7fce3d0934aae4b /llvm/lib/Analysis/ValueTracking.cpp
parent0778b5d0d296edaca2ac52f2c8d2c806d492355a (diff)
downloadllvm-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.cpp51
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)) {