Skip to content

Commit 2dbb454

Browse files
committed
[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.
1 parent 0778b5d commit 2dbb454

File tree

4 files changed

+46
-38
lines changed

4 files changed

+46
-38
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,9 @@ bool isOverflowIntrinsicNoWrap(const WithOverflowInst *WO,
904904
/// based on the vscale_range function attribute.
905905
ConstantRange getVScaleRange(const Function *F, unsigned BitWidth);
906906

907+
/// Determine the possible constant range of a vector constant.
908+
ConstantRange getVectorConstantRange(const Constant *C);
909+
907910
/// Determine the possible constant range of an integer or vector of integer
908911
/// value. This is intended as a cheap, non-recursive check.
909912
ConstantRange computeConstantRange(const Value *V, bool ForSigned,

llvm/lib/Analysis/LazyValueInfo.cpp

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -836,24 +836,6 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
836836
}
837837
}
838838

839-
static ConstantRange getConstantRangeFromFixedVector(Constant *C,
840-
FixedVectorType *Ty) {
841-
unsigned BW = Ty->getScalarSizeInBits();
842-
ConstantRange CR = ConstantRange::getEmpty(BW);
843-
for (unsigned I = 0; I < Ty->getNumElements(); ++I) {
844-
Constant *Elem = C->getAggregateElement(I);
845-
if (!Elem)
846-
return ConstantRange::getFull(BW);
847-
if (isa<PoisonValue>(Elem))
848-
continue;
849-
auto *CI = dyn_cast<ConstantInt>(Elem);
850-
if (!CI)
851-
return ConstantRange::getFull(BW);
852-
CR = CR.unionWith(CI->getValue());
853-
}
854-
return CR;
855-
}
856-
857839
static ConstantRange toConstantRange(const ValueLatticeElement &Val,
858840
Type *Ty, bool UndefAllowed = false) {
859841
assert(Ty->isIntOrIntVectorTy() && "Must be integer type");
@@ -862,13 +844,8 @@ static ConstantRange toConstantRange(const ValueLatticeElement &Val,
862844
unsigned BW = Ty->getScalarSizeInBits();
863845
if (Val.isUnknown())
864846
return ConstantRange::getEmpty(BW);
865-
if (Val.isConstant() && Ty->isVectorTy()) {
866-
if (auto *CI = dyn_cast_or_null<ConstantInt>(
867-
Val.getConstant()->getSplatValue(/*AllowPoison=*/true)))
868-
return ConstantRange(CI->getValue());
869-
if (auto *VTy = dyn_cast<FixedVectorType>(Ty))
870-
return getConstantRangeFromFixedVector(Val.getConstant(), VTy);
871-
}
847+
if (Val.isConstant() && Ty->isVectorTy())
848+
return getVectorConstantRange(Val.getConstant());
872849
return ConstantRange::getFull(BW);
873850
}
874851

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9498,6 +9498,39 @@ static void setLimitForFPToI(const Instruction *I, APInt &Lower, APInt &Upper) {
94989498
}
94999499
}
95009500

9501+
ConstantRange llvm::getVectorConstantRange(const Constant *C) {
9502+
assert(C->getType()->isVectorTy() && "Expected vector constant");
9503+
if (auto *CI = dyn_cast_or_null<ConstantInt>(
9504+
C->getSplatValue(/*AllowPoison=*/true)))
9505+
return ConstantRange(CI->getValue());
9506+
9507+
unsigned BitWidth = C->getType()->getScalarSizeInBits();
9508+
if (auto *CDV = dyn_cast<ConstantDataVector>(C)) {
9509+
ConstantRange CR = ConstantRange::getEmpty(BitWidth);
9510+
for (unsigned I = 0, E = CDV->getNumElements(); I < E; ++I)
9511+
CR = CR.unionWith(CDV->getElementAsAPInt(I));
9512+
return CR;
9513+
}
9514+
9515+
if (auto *CV = dyn_cast<ConstantVector>(C)) {
9516+
ConstantRange CR = ConstantRange::getEmpty(BitWidth);
9517+
for (unsigned I = 0, E = CV->getNumOperands(); I < E; ++I) {
9518+
Constant *Elem = C->getAggregateElement(I);
9519+
if (!Elem)
9520+
return ConstantRange::getFull(BitWidth);
9521+
if (isa<PoisonValue>(Elem))
9522+
continue;
9523+
auto *CI = dyn_cast<ConstantInt>(Elem);
9524+
if (!CI)
9525+
return ConstantRange::getFull(BitWidth);
9526+
CR = CR.unionWith(CI->getValue());
9527+
}
9528+
return CR;
9529+
}
9530+
9531+
return ConstantRange::getFull(BitWidth);
9532+
}
9533+
95019534
ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
95029535
bool UseInstrInfo, AssumptionCache *AC,
95039536
const Instruction *CtxI,
@@ -9508,19 +9541,15 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
95089541
if (Depth == MaxAnalysisRecursionDepth)
95099542
return ConstantRange::getFull(V->getType()->getScalarSizeInBits());
95109543

9511-
const APInt *C;
9512-
if (match(V, m_APInt(C)))
9513-
return ConstantRange(*C);
9514-
unsigned BitWidth = V->getType()->getScalarSizeInBits();
9515-
9516-
if (auto *VC = dyn_cast<ConstantDataVector>(V)) {
9517-
ConstantRange CR = ConstantRange::getEmpty(BitWidth);
9518-
for (unsigned ElemIdx = 0, NElem = VC->getNumElements(); ElemIdx < NElem;
9519-
++ElemIdx)
9520-
CR = CR.unionWith(VC->getElementAsAPInt(ElemIdx));
9521-
return CR;
9544+
if (auto *C = dyn_cast<Constant>(V)) {
9545+
if (auto *CI = dyn_cast<ConstantInt>(C))
9546+
return ConstantRange(CI->getValue());
9547+
if (C->getType()->isVectorTy())
9548+
return getVectorConstantRange(C);
9549+
return ConstantRange::getFull(C->getType()->getScalarSizeInBits());
95229550
}
95239551

9552+
unsigned BitWidth = V->getType()->getScalarSizeInBits();
95249553
InstrInfoQuery IIQ(UseInstrInfo);
95259554
ConstantRange CR = ConstantRange::getFull(BitWidth);
95269555
if (auto *BO = dyn_cast<BinaryOperator>(V)) {

llvm/test/Transforms/InstCombine/saturating-add-sub.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,8 +1064,7 @@ define <2 x i8> @test_vector_usub_add_nuw_no_ov_nonsplat1(<2 x i8> %a) {
10641064

10651065
define <3 x i8> @test_vector_usub_add_nuw_no_ov_nonsplat1_poison(<3 x i8> %a) {
10661066
; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov_nonsplat1_poison(
1067-
; CHECK-NEXT: [[B:%.*]] = add nuw <3 x i8> [[A:%.*]], <i8 10, i8 10, i8 10>
1068-
; CHECK-NEXT: [[R:%.*]] = call <3 x i8> @llvm.usub.sat.v3i8(<3 x i8> [[B]], <3 x i8> <i8 10, i8 9, i8 poison>)
1067+
; CHECK-NEXT: [[R:%.*]] = add <3 x i8> [[A:%.*]], <i8 0, i8 1, i8 poison>
10691068
; CHECK-NEXT: ret <3 x i8> [[R]]
10701069
;
10711070
%b = add nuw <3 x i8> %a, <i8 10, i8 10, i8 10>

0 commit comments

Comments
 (0)