Skip to content

Commit 0395e01

Browse files
committed
[IR] Split vscale_range interface
Interface is split from: std::pair<unsigned, unsigned> getVScaleRangeArgs() into separate functions for min/max: unsigned getVScaleRangeMin(); Optional<unsigned> getVScaleRangeMax(); Reviewed By: sdesmalen, paulwalker-arm Differential Revision: https://reviews.llvm.org/D114075
1 parent 3460cc2 commit 0395e01

File tree

11 files changed

+108
-83
lines changed

11 files changed

+108
-83
lines changed

llvm/include/llvm/IR/Attributes.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,12 @@ class Attribute {
216216
/// if not known).
217217
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
218218

219-
/// Returns the argument numbers for the vscale_range attribute (or pair(1, 0)
220-
/// if not known).
221-
std::pair<unsigned, unsigned> getVScaleRangeArgs() const;
219+
/// Returns the minimum value for the vscale_range attribute.
220+
unsigned getVScaleRangeMin() const;
221+
222+
/// Returns the maximum value for the vscale_range attribute or None when
223+
/// unknown.
224+
Optional<unsigned> getVScaleRangeMax() const;
222225

223226
/// The Attribute is converted to a string of equivalent mnemonic. This
224227
/// is, presumably, for writing out the mnemonics for the assembly writer.
@@ -348,7 +351,8 @@ class AttributeSet {
348351
Type *getInAllocaType() const;
349352
Type *getElementType() const;
350353
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
351-
std::pair<unsigned, unsigned> getVScaleRangeArgs() const;
354+
unsigned getVScaleRangeMin() const;
355+
Optional<unsigned> getVScaleRangeMax() const;
352356
std::string getAsString(bool InAttrGrp = false) const;
353357

354358
/// Return true if this attribute set belongs to the LLVMContext.
@@ -1053,9 +1057,11 @@ class AttrBuilder {
10531057
/// doesn't exist, pair(0, 0) is returned.
10541058
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
10551059

1056-
/// Retrieve the vscale_range args, if the vscale_range attribute exists. If
1057-
/// it doesn't exist, pair(1, 0) is returned.
1058-
std::pair<unsigned, unsigned> getVScaleRangeArgs() const;
1060+
/// Retrieve the minimum value of 'vscale_range'.
1061+
unsigned getVScaleRangeMin() const;
1062+
1063+
/// Retrieve the maximum value of 'vscale_range' or None when unknown.
1064+
Optional<unsigned> getVScaleRangeMax() const;
10591065

10601066
/// Add integer attribute with raw value (packed/encoded if necessary).
10611067
AttrBuilder &addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value);
@@ -1097,7 +1103,8 @@ class AttrBuilder {
10971103
const Optional<unsigned> &NumElemsArg);
10981104

10991105
/// This turns two ints into the form used internally in Attribute.
1100-
AttrBuilder &addVScaleRangeAttr(unsigned MinValue, unsigned MaxValue);
1106+
AttrBuilder &addVScaleRangeAttr(unsigned MinValue,
1107+
Optional<unsigned> MaxValue);
11011108

11021109
/// Add a type attribute with the given type.
11031110
AttrBuilder &addTypeAttr(Attribute::AttrKind Kind, Type *Ty);

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5886,9 +5886,9 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
58865886
auto Attr = Call->getFunction()->getFnAttribute(Attribute::VScaleRange);
58875887
if (!Attr.isValid())
58885888
return nullptr;
5889-
unsigned VScaleMin, VScaleMax;
5890-
std::tie(VScaleMin, VScaleMax) = Attr.getVScaleRangeArgs();
5891-
if (VScaleMin == VScaleMax && VScaleMax != 0)
5889+
unsigned VScaleMin = Attr.getVScaleRangeMin();
5890+
Optional<unsigned> VScaleMax = Attr.getVScaleRangeMax();
5891+
if (VScaleMax && VScaleMin == VScaleMax)
58925892
return ConstantInt::get(F->getReturnType(), VScaleMin);
58935893
return nullptr;
58945894
}

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,23 +1709,25 @@ static void computeKnownBitsFromOperator(const Operator *I,
17091709
!II->getFunction()->hasFnAttribute(Attribute::VScaleRange))
17101710
break;
17111711

1712-
auto VScaleRange = II->getFunction()
1713-
->getFnAttribute(Attribute::VScaleRange)
1714-
.getVScaleRangeArgs();
1712+
auto Attr = II->getFunction()->getFnAttribute(Attribute::VScaleRange);
1713+
Optional<unsigned> VScaleMax = Attr.getVScaleRangeMax();
17151714

1716-
if (VScaleRange.second == 0)
1715+
if (!VScaleMax)
17171716
break;
17181717

1718+
unsigned VScaleMin = Attr.getVScaleRangeMin();
1719+
17191720
// If vscale min = max then we know the exact value at compile time
17201721
// and hence we know the exact bits.
1721-
if (VScaleRange.first == VScaleRange.second) {
1722-
Known.One = VScaleRange.first;
1723-
Known.Zero = VScaleRange.first;
1722+
if (VScaleMin == VScaleMax) {
1723+
Known.One = VScaleMin;
1724+
Known.Zero = VScaleMin;
17241725
Known.Zero.flipAllBits();
17251726
break;
17261727
}
17271728

1728-
unsigned FirstZeroHighBit = 32 - countLeadingZeros(VScaleRange.second);
1729+
unsigned FirstZeroHighBit =
1730+
32 - countLeadingZeros(VScaleMax.getValue());
17291731
if (FirstZeroHighBit < BitWidth)
17301732
Known.Zero.setBitsFrom(FirstZeroHighBit);
17311733

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,8 @@ bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
13061306
unsigned MinValue, MaxValue;
13071307
if (parseVScaleRangeArguments(MinValue, MaxValue))
13081308
return true;
1309-
B.addVScaleRangeAttr(MinValue, MaxValue);
1309+
B.addVScaleRangeAttr(MinValue,
1310+
MaxValue > 0 ? MaxValue : Optional<unsigned>());
13101311
return false;
13111312
}
13121313
case Attribute::Dereferenceable: {

llvm/lib/IR/AttributeImpl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ class AttributeSetNode final
253253
uint64_t getDereferenceableBytes() const;
254254
uint64_t getDereferenceableOrNullBytes() const;
255255
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
256-
std::pair<unsigned, unsigned> getVScaleRangeArgs() const;
256+
unsigned getVScaleRangeMin() const;
257+
Optional<unsigned> getVScaleRangeMax() const;
257258
std::string getAsString(bool InAttrGrp) const;
258259
Type *getAttributeType(Attribute::AttrKind Kind) const;
259260

llvm/lib/IR/Attributes.cpp

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,18 @@ unpackAllocSizeArgs(uint64_t Num) {
7878
return std::make_pair(ElemSizeArg, NumElemsArg);
7979
}
8080

81-
static uint64_t packVScaleRangeArgs(unsigned MinValue, unsigned MaxValue) {
82-
return uint64_t(MinValue) << 32 | MaxValue;
81+
static uint64_t packVScaleRangeArgs(unsigned MinValue,
82+
Optional<unsigned> MaxValue) {
83+
return uint64_t(MinValue) << 32 | MaxValue.getValueOr(0);
8384
}
8485

85-
static std::pair<unsigned, unsigned> unpackVScaleRangeArgs(uint64_t Value) {
86+
static std::pair<unsigned, Optional<unsigned>>
87+
unpackVScaleRangeArgs(uint64_t Value) {
8688
unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
8789
unsigned MinValue = Value >> 32;
8890

89-
return std::make_pair(MinValue, MaxValue);
91+
return std::make_pair(MinValue,
92+
MaxValue > 0 ? MaxValue : Optional<unsigned>());
9093
}
9194

9295
Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
@@ -354,10 +357,16 @@ std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
354357
return unpackAllocSizeArgs(pImpl->getValueAsInt());
355358
}
356359

357-
std::pair<unsigned, unsigned> Attribute::getVScaleRangeArgs() const {
360+
unsigned Attribute::getVScaleRangeMin() const {
358361
assert(hasAttribute(Attribute::VScaleRange) &&
359362
"Trying to get vscale args from non-vscale attribute");
360-
return unpackVScaleRangeArgs(pImpl->getValueAsInt());
363+
return unpackVScaleRangeArgs(pImpl->getValueAsInt()).first;
364+
}
365+
366+
Optional<unsigned> Attribute::getVScaleRangeMax() const {
367+
assert(hasAttribute(Attribute::VScaleRange) &&
368+
"Trying to get vscale args from non-vscale attribute");
369+
return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second;
361370
}
362371

363372
std::string Attribute::getAsString(bool InAttrGrp) const {
@@ -428,13 +437,13 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
428437
}
429438

430439
if (hasAttribute(Attribute::VScaleRange)) {
431-
unsigned MinValue, MaxValue;
432-
std::tie(MinValue, MaxValue) = getVScaleRangeArgs();
440+
unsigned MinValue = getVScaleRangeMin();
441+
Optional<unsigned> MaxValue = getVScaleRangeMax();
433442

434443
std::string Result = "vscale_range(";
435444
Result += utostr(MinValue);
436445
Result += ',';
437-
Result += utostr(MaxValue);
446+
Result += utostr(MaxValue.getValueOr(0));
438447
Result += ')';
439448
return Result;
440449
}
@@ -717,9 +726,12 @@ std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
717726
: std::pair<unsigned, Optional<unsigned>>(0, 0);
718727
}
719728

720-
std::pair<unsigned, unsigned> AttributeSet::getVScaleRangeArgs() const {
721-
return SetNode ? SetNode->getVScaleRangeArgs()
722-
: std::pair<unsigned, unsigned>(1, 0);
729+
unsigned AttributeSet::getVScaleRangeMin() const {
730+
return SetNode ? SetNode->getVScaleRangeMin() : 1;
731+
}
732+
733+
Optional<unsigned> AttributeSet::getVScaleRangeMax() const {
734+
return SetNode ? SetNode->getVScaleRangeMax() : None;
723735
}
724736

725737
std::string AttributeSet::getAsString(bool InAttrGrp) const {
@@ -897,10 +909,16 @@ AttributeSetNode::getAllocSizeArgs() const {
897909
return std::make_pair(0, 0);
898910
}
899911

900-
std::pair<unsigned, unsigned> AttributeSetNode::getVScaleRangeArgs() const {
912+
unsigned AttributeSetNode::getVScaleRangeMin() const {
901913
if (auto A = findEnumAttribute(Attribute::VScaleRange))
902-
return A->getVScaleRangeArgs();
903-
return std::make_pair(1, 0);
914+
return A->getVScaleRangeMin();
915+
return 1;
916+
}
917+
918+
Optional<unsigned> AttributeSetNode::getVScaleRangeMax() const {
919+
if (auto A = findEnumAttribute(Attribute::VScaleRange))
920+
return A->getVScaleRangeMax();
921+
return None;
904922
}
905923

906924
std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
@@ -1623,8 +1641,12 @@ std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
16231641
return unpackAllocSizeArgs(getRawIntAttr(Attribute::AllocSize));
16241642
}
16251643

1626-
std::pair<unsigned, unsigned> AttrBuilder::getVScaleRangeArgs() const {
1627-
return unpackVScaleRangeArgs(getRawIntAttr(Attribute::VScaleRange));
1644+
unsigned AttrBuilder::getVScaleRangeMin() const {
1645+
return unpackVScaleRangeArgs(getRawIntAttr(Attribute::VScaleRange)).first;
1646+
}
1647+
1648+
Optional<unsigned> AttrBuilder::getVScaleRangeMax() const {
1649+
return unpackVScaleRangeArgs(getRawIntAttr(Attribute::VScaleRange)).second;
16281650
}
16291651

16301652
AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
@@ -1669,7 +1691,7 @@ AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
16691691
}
16701692

16711693
AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue,
1672-
unsigned MaxValue) {
1694+
Optional<unsigned> MaxValue) {
16731695
return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
16741696
}
16751697

llvm/lib/IR/Verifier.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,13 +2055,12 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
20552055
}
20562056

20572057
if (Attrs.hasFnAttr(Attribute::VScaleRange)) {
2058-
std::pair<unsigned, unsigned> Args =
2059-
Attrs.getFnAttrs().getVScaleRangeArgs();
2060-
2061-
if (Args.first == 0)
2058+
unsigned VScaleMin = Attrs.getFnAttrs().getVScaleRangeMin();
2059+
if (VScaleMin == 0)
20622060
CheckFailed("'vscale_range' minimum must be greater than 0", V);
20632061

2064-
if (Args.first > Args.second && Args.second != 0)
2062+
Optional<unsigned> VScaleMax = Attrs.getFnAttrs().getVScaleRangeMax();
2063+
if (VScaleMax && VScaleMin > VScaleMax)
20652064
CheckFailed("'vscale_range' minimum cannot be greater than maximum", V);
20662065
}
20672066

llvm/lib/Target/AArch64/AArch64TargetMachine.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,9 @@ AArch64TargetMachine::getSubtargetImpl(const Function &F) const {
382382
unsigned MaxSVEVectorSize = 0;
383383
Attribute VScaleRangeAttr = F.getFnAttribute(Attribute::VScaleRange);
384384
if (VScaleRangeAttr.isValid()) {
385-
std::tie(MinSVEVectorSize, MaxSVEVectorSize) =
386-
VScaleRangeAttr.getVScaleRangeArgs();
387-
MinSVEVectorSize *= 128;
388-
MaxSVEVectorSize *= 128;
385+
Optional<unsigned> VScaleMax = VScaleRangeAttr.getVScaleRangeMax();
386+
MinSVEVectorSize = VScaleRangeAttr.getVScaleRangeMin() * 128;
387+
MaxSVEVectorSize = VScaleMax ? VScaleMax.getValue() * 128 : 0;
389388
} else {
390389
MinSVEVectorSize = SVEVectorBitsMinOpt;
391390
MaxSVEVectorSize = SVEVectorBitsMaxOpt;

llvm/lib/Target/AArch64/SVEIntrinsicOpts.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,10 @@ bool SVEIntrinsicOpts::optimizePredicateStore(Instruction *I) {
287287
if (!Attr.isValid())
288288
return false;
289289

290-
unsigned MinVScale, MaxVScale;
291-
std::tie(MinVScale, MaxVScale) = Attr.getVScaleRangeArgs();
290+
unsigned MinVScale = Attr.getVScaleRangeMin();
291+
Optional<unsigned> MaxVScale = Attr.getVScaleRangeMax();
292292
// The transform needs to know the exact runtime length of scalable vectors
293-
if (MinVScale != MaxVScale || MinVScale == 0)
293+
if (!MaxVScale || MinVScale != MaxVScale)
294294
return false;
295295

296296
auto *PredType =
@@ -351,10 +351,10 @@ bool SVEIntrinsicOpts::optimizePredicateLoad(Instruction *I) {
351351
if (!Attr.isValid())
352352
return false;
353353

354-
unsigned MinVScale, MaxVScale;
355-
std::tie(MinVScale, MaxVScale) = Attr.getVScaleRangeArgs();
354+
unsigned MinVScale = Attr.getVScaleRangeMin();
355+
Optional<unsigned> MaxVScale = Attr.getVScaleRangeMax();
356356
// The transform needs to know the exact runtime length of scalable vectors
357-
if (MinVScale != MaxVScale || MinVScale == 0)
357+
if (!MaxVScale || MinVScale != MaxVScale)
358358
return false;
359359

360360
auto *PredType =

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -965,13 +965,13 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
965965
if (match(Src, m_VScale(DL))) {
966966
if (Trunc.getFunction() &&
967967
Trunc.getFunction()->hasFnAttribute(Attribute::VScaleRange)) {
968-
unsigned MaxVScale = Trunc.getFunction()
969-
->getFnAttribute(Attribute::VScaleRange)
970-
.getVScaleRangeArgs()
971-
.second;
972-
if (MaxVScale > 0 && Log2_32(MaxVScale) < DestWidth) {
973-
Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
974-
return replaceInstUsesWith(Trunc, VScale);
968+
Attribute Attr =
969+
Trunc.getFunction()->getFnAttribute(Attribute::VScaleRange);
970+
if (Optional<unsigned> MaxVScale = Attr.getVScaleRangeMax()) {
971+
if (Log2_32(MaxVScale.getValue()) < DestWidth) {
972+
Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
973+
return replaceInstUsesWith(Trunc, VScale);
974+
}
975975
}
976976
}
977977
}
@@ -1337,14 +1337,13 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) {
13371337
if (match(Src, m_VScale(DL))) {
13381338
if (CI.getFunction() &&
13391339
CI.getFunction()->hasFnAttribute(Attribute::VScaleRange)) {
1340-
unsigned MaxVScale = CI.getFunction()
1341-
->getFnAttribute(Attribute::VScaleRange)
1342-
.getVScaleRangeArgs()
1343-
.second;
1344-
unsigned TypeWidth = Src->getType()->getScalarSizeInBits();
1345-
if (MaxVScale > 0 && Log2_32(MaxVScale) < TypeWidth) {
1346-
Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
1347-
return replaceInstUsesWith(CI, VScale);
1340+
Attribute Attr = CI.getFunction()->getFnAttribute(Attribute::VScaleRange);
1341+
if (Optional<unsigned> MaxVScale = Attr.getVScaleRangeMax()) {
1342+
unsigned TypeWidth = Src->getType()->getScalarSizeInBits();
1343+
if (Log2_32(MaxVScale.getValue()) < TypeWidth) {
1344+
Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
1345+
return replaceInstUsesWith(CI, VScale);
1346+
}
13481347
}
13491348
}
13501349
}
@@ -1608,13 +1607,12 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) {
16081607
if (match(Src, m_VScale(DL))) {
16091608
if (CI.getFunction() &&
16101609
CI.getFunction()->hasFnAttribute(Attribute::VScaleRange)) {
1611-
unsigned MaxVScale = CI.getFunction()
1612-
->getFnAttribute(Attribute::VScaleRange)
1613-
.getVScaleRangeArgs()
1614-
.second;
1615-
if (MaxVScale > 0 && Log2_32(MaxVScale) < (SrcBitSize - 1)) {
1616-
Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
1617-
return replaceInstUsesWith(CI, VScale);
1610+
Attribute Attr = CI.getFunction()->getFnAttribute(Attribute::VScaleRange);
1611+
if (Optional<unsigned> MaxVScale = Attr.getVScaleRangeMax()) {
1612+
if (Log2_32(MaxVScale.getValue()) < (SrcBitSize - 1)) {
1613+
Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
1614+
return replaceInstUsesWith(CI, VScale);
1615+
}
16181616
}
16191617
}
16201618
}

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5366,13 +5366,9 @@ LoopVectorizationCostModel::getMaxLegalScalableVF(unsigned MaxSafeElements) {
53665366

53675367
// Limit MaxScalableVF by the maximum safe dependence distance.
53685368
Optional<unsigned> MaxVScale = TTI.getMaxVScale();
5369-
if (!MaxVScale && TheFunction->hasFnAttribute(Attribute::VScaleRange)) {
5370-
unsigned VScaleMax = TheFunction->getFnAttribute(Attribute::VScaleRange)
5371-
.getVScaleRangeArgs()
5372-
.second;
5373-
if (VScaleMax > 0)
5374-
MaxVScale = VScaleMax;
5375-
}
5369+
if (!MaxVScale && TheFunction->hasFnAttribute(Attribute::VScaleRange))
5370+
MaxVScale =
5371+
TheFunction->getFnAttribute(Attribute::VScaleRange).getVScaleRangeMax();
53765372
MaxScalableVF = ElementCount::getScalable(
53775373
MaxVScale ? (MaxSafeElements / MaxVScale.getValue()) : 0);
53785374
if (!MaxScalableVF)

0 commit comments

Comments
 (0)