Skip to content

Commit 2569767

Browse files
committed
[Attributes] Support int attributes with zero value
This regularly comes up as a stumbling stone when adding int attributes: They currently need to be encoded in a way to avoids the zero value. This adds support for zero-value int attributes by a) making the ctor determine int/enum attribute based on attribute kind, not whether the value is non-zero and b) switching getRawIntAttr() to return an Optional, so that it's possible to distinguish a zero value from non-existence. Differential Revision: https://reviews.llvm.org/D135572
1 parent 24b1340 commit 2569767

File tree

3 files changed

+27
-17
lines changed

3 files changed

+27
-17
lines changed

llvm/include/llvm/IR/Attributes.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,30 +1096,30 @@ class AttrBuilder {
10961096
/// invalid if the Kind is not present in the builder.
10971097
Attribute getAttribute(StringRef Kind) const;
10981098

1099-
/// Return raw (possibly packed/encoded) value of integer attribute or 0 if
1099+
/// Return raw (possibly packed/encoded) value of integer attribute or None if
11001100
/// not set.
1101-
uint64_t getRawIntAttr(Attribute::AttrKind Kind) const;
1101+
Optional<uint64_t> getRawIntAttr(Attribute::AttrKind Kind) const;
11021102

11031103
/// Retrieve the alignment attribute, if it exists.
11041104
MaybeAlign getAlignment() const {
1105-
return MaybeAlign(getRawIntAttr(Attribute::Alignment));
1105+
return MaybeAlign(getRawIntAttr(Attribute::Alignment).value_or(0));
11061106
}
11071107

11081108
/// Retrieve the stack alignment attribute, if it exists.
11091109
MaybeAlign getStackAlignment() const {
1110-
return MaybeAlign(getRawIntAttr(Attribute::StackAlignment));
1110+
return MaybeAlign(getRawIntAttr(Attribute::StackAlignment).value_or(0));
11111111
}
11121112

11131113
/// Retrieve the number of dereferenceable bytes, if the
11141114
/// dereferenceable attribute exists (zero is returned otherwise).
11151115
uint64_t getDereferenceableBytes() const {
1116-
return getRawIntAttr(Attribute::Dereferenceable);
1116+
return getRawIntAttr(Attribute::Dereferenceable).value_or(0);
11171117
}
11181118

11191119
/// Retrieve the number of dereferenceable_or_null bytes, if the
11201120
/// dereferenceable_or_null attribute exists (zero is returned otherwise).
11211121
uint64_t getDereferenceableOrNullBytes() const {
1122-
return getRawIntAttr(Attribute::DereferenceableOrNull);
1122+
return getRawIntAttr(Attribute::DereferenceableOrNull).value_or(0);
11231123
}
11241124

11251125
/// Retrieve type for the given type attribute.

llvm/lib/IR/AttributeImpl.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class AttributeImpl : public FoldingSetNode {
7676

7777
void Profile(FoldingSetNodeID &ID) const {
7878
if (isEnumAttribute())
79-
Profile(ID, getKindAsEnum(), static_cast<uint64_t>(0));
79+
Profile(ID, getKindAsEnum());
8080
else if (isIntAttribute())
8181
Profile(ID, getKindAsEnum(), getValueAsInt());
8282
else if (isStringAttribute())
@@ -85,10 +85,16 @@ class AttributeImpl : public FoldingSetNode {
8585
Profile(ID, getKindAsEnum(), getValueAsType());
8686
}
8787

88+
static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind) {
89+
assert(Attribute::isEnumAttrKind(Kind) && "Expected enum attribute");
90+
ID.AddInteger(Kind);
91+
}
92+
8893
static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,
8994
uint64_t Val) {
95+
assert(Attribute::isIntAttrKind(Kind) && "Expected int attribute");
9096
ID.AddInteger(Kind);
91-
if (Val) ID.AddInteger(Val);
97+
ID.AddInteger(Val);
9298
}
9399

94100
static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) {

llvm/lib/IR/Attributes.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,23 +89,25 @@ unpackVScaleRangeArgs(uint64_t Value) {
8989

9090
Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
9191
uint64_t Val) {
92-
if (Val)
93-
assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
94-
else
95-
assert(Attribute::isEnumAttrKind(Kind) && "Not an enum attribute");
92+
bool IsIntAttr = Attribute::isIntAttrKind(Kind);
93+
assert((IsIntAttr || Attribute::isEnumAttrKind(Kind)) &&
94+
"Not an enum or int attribute");
9695

9796
LLVMContextImpl *pImpl = Context.pImpl;
9897
FoldingSetNodeID ID;
9998
ID.AddInteger(Kind);
100-
if (Val) ID.AddInteger(Val);
99+
if (IsIntAttr)
100+
ID.AddInteger(Val);
101+
else
102+
assert(Val == 0 && "Value must be zero for enum attributes");
101103

102104
void *InsertPoint;
103105
AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
104106

105107
if (!PA) {
106108
// If we didn't find any existing attributes of the same shape then create a
107109
// new one and insert it.
108-
if (!Val)
110+
if (!IsIntAttr)
109111
PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
110112
else
111113
PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
@@ -1638,10 +1640,12 @@ AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
16381640
return *this;
16391641
}
16401642

1641-
uint64_t AttrBuilder::getRawIntAttr(Attribute::AttrKind Kind) const {
1643+
Optional<uint64_t> AttrBuilder::getRawIntAttr(Attribute::AttrKind Kind) const {
16421644
assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
16431645
Attribute A = getAttribute(Kind);
1644-
return A.isValid() ? A.getValueAsInt() : 0;
1646+
if (A.isValid())
1647+
return A.getValueAsInt();
1648+
return None;
16451649
}
16461650

16471651
AttrBuilder &AttrBuilder::addRawIntAttr(Attribute::AttrKind Kind,
@@ -1650,7 +1654,7 @@ AttrBuilder &AttrBuilder::addRawIntAttr(Attribute::AttrKind Kind,
16501654
}
16511655

16521656
std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1653-
return unpackAllocSizeArgs(getRawIntAttr(Attribute::AllocSize));
1657+
return unpackAllocSizeArgs(getRawIntAttr(Attribute::AllocSize).value_or(0));
16541658
}
16551659

16561660
AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {

0 commit comments

Comments
 (0)