Skip to content

Commit ffd7c16

Browse files
committed
Allow empty range attribute and add assert for full range
1 parent cfe9f5c commit ffd7c16

File tree

8 files changed

+26
-13
lines changed

8 files changed

+26
-13
lines changed

llvm/docs/LangRef.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,8 @@ Currently, only the following parameter attributes are defined:
16751675
- The pair ``a,b`` represents the range ``[a,b)``.
16761676
- Both ``a`` and ``b`` are constants.
16771677
- The range is allowed to wrap.
1678-
- The range should not represent the full or empty set. That is, ``a!=b``.
1678+
- Only for the empty set is ``a`` and ``b`` allowed to be equal and
1679+
only for the value 0.
16791680

16801681
This attribute may only be applied to parameters or return values with integer
16811682
or vector of integer types.

llvm/include/llvm/IR/Attributes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class Attribute {
160160
static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind);
161161
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME);
162162
static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask);
163+
static Attribute getWithRange(LLVMContext &Context, const ConstantRange &CR);
163164

164165
/// For a typed attribute, return the equivalent attribute with the type
165166
/// changed to \p ReplacementTy.

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,8 +3109,8 @@ bool LLParser::parseRangeAttr(AttrBuilder &B) {
31093109
if (ParseAPSInt(BitWidth, Lower) ||
31103110
parseToken(lltok::comma, "expected ','") || ParseAPSInt(BitWidth, Upper))
31113111
return true;
3112-
if (Lower == Upper)
3113-
return tokError("the range should not represent the full or empty set!");
3112+
if (Lower == Upper && !Lower.isMinValue())
3113+
return tokError("the range represent the empty set but limits aren't 0!");
31143114

31153115
if (parseToken(lltok::rparen, "expected ')'"))
31163116
return true;

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2369,7 +2369,9 @@ Error BitcodeReader::parseAttributeGroupBlock() {
23692369
return MaybeCR.takeError();
23702370
i--;
23712371

2372-
B.addConstantRangeAttr(Kind, MaybeCR.get());
2372+
assert(Kind == Attribute::Range &&
2373+
"Unhandled ConstantRangeAttribute");
2374+
B.addRangeAttr(MaybeCR.get());
23732375
} else if (Record[i] == 8) {
23742376
Attribute::AttrKind Kind;
23752377

llvm/lib/IR/Attributes.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,12 @@ Attribute Attribute::getWithNoFPClass(LLVMContext &Context,
286286
return get(Context, NoFPClass, ClassMask);
287287
}
288288

289+
Attribute Attribute::getWithRange(LLVMContext &Context,
290+
const ConstantRange &CR) {
291+
assert(!CR.isFullSet() && "Range must not be full!");
292+
return get(Context, Range, CR);
293+
}
294+
289295
Attribute
290296
Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
291297
const std::optional<unsigned> &NumElemsArg) {
@@ -2024,7 +2030,10 @@ AttrBuilder &AttrBuilder::addConstantRangeAttr(Attribute::AttrKind Kind,
20242030
}
20252031

20262032
AttrBuilder &AttrBuilder::addRangeAttr(const ConstantRange &CR) {
2027-
return addConstantRangeAttr(Attribute::Range, CR);
2033+
if (CR.isFullSet())
2034+
return *this;
2035+
2036+
return addAttribute(Attribute::getWithRange(Ctx, CR));
20282037
}
20292038

20302039
AttrBuilder &

llvm/lib/IR/Core.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,11 @@ LLVMAttributeRef LLVMCreateConstantRangeAttribute(LLVMContextRef C,
191191
const uint64_t UpperWords[]) {
192192
auto &Ctx = *unwrap(C);
193193
auto AttrKind = (Attribute::AttrKind)KindID;
194+
assert(AttrKind == Attribute::Range && "Unhandled ConstantRangeAttribute");
194195
unsigned NumWords = divideCeil(NumBits, 64);
195-
return wrap(Attribute::get(
196-
Ctx, AttrKind,
197-
ConstantRange(APInt(NumBits, ArrayRef(LowerWords, NumWords)),
198-
APInt(NumBits, ArrayRef(UpperWords, NumWords)))));
196+
return wrap(Attribute::getWithRange(
197+
Ctx, ConstantRange(APInt(NumBits, ArrayRef(LowerWords, NumWords)),
198+
APInt(NumBits, ArrayRef(UpperWords, NumWords)))));
199199
}
200200

201201
LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
22

3-
; CHECK: the range should not represent the full or empty set!
4-
define void @range_empty(i8 range(i8 0, 0) %a) {
3+
; CHECK: the range represent the empty set but limits aren't 0!
4+
define void @range_empty(i8 range(i8 1, 1) %a) {
55
ret void
66
}

llvm/test/Bitcode/attributes.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,8 @@ define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
531531
ret i32 0
532532
}
533533

534-
; CHECK: define range(i32 0, 42) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a)
535-
define range(i32 0, 42) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a) {
534+
; CHECK: define range(i32 0, 0) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a)
535+
define range(i32 0, 0) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a) {
536536
ret i32 0
537537
}
538538

0 commit comments

Comments
 (0)