Skip to content

Commit 04da773

Browse files
authored
Allow empty range attribute and add assert for full range (#100601)
fix #99619
1 parent be40c72 commit 04da773

File tree

6 files changed

+23
-7
lines changed

6 files changed

+23
-7
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+
- The empty range is represented using ``0,0``.
1679+
- Otherwise, ``a`` and ``b`` are not allowed to be equal.
16791680

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

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.isZero())
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/IR/Attributes.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
171171
const ConstantRange &CR) {
172172
assert(Attribute::isConstantRangeAttrKind(Kind) &&
173173
"Not a ConstantRange attribute");
174+
assert(!CR.isFullSet() && "ConstantRange attribute must not be full");
174175
LLVMContextImpl *pImpl = Context.pImpl;
175176
FoldingSetNodeID ID;
176177
ID.AddInteger(Kind);
@@ -2020,6 +2021,9 @@ AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) {
20202021

20212022
AttrBuilder &AttrBuilder::addConstantRangeAttr(Attribute::AttrKind Kind,
20222023
const ConstantRange &CR) {
2024+
if (CR.isFullSet())
2025+
return *this;
2026+
20232027
return addAttribute(Attribute::get(Ctx, Kind, CR));
20242028
}
20252029

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
@@ -537,8 +537,8 @@ define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
537537
ret i32 0
538538
}
539539

540-
; CHECK: define range(i32 0, 42) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a)
541-
define range(i32 0, 42) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a) {
540+
; CHECK: define range(i32 0, 0) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a)
541+
define range(i32 0, 0) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a) {
542542
ret i32 0
543543
}
544544

llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,14 @@ define i8 @caller15_okay_intersect_ranges() {
410410
call void @use.val(i8 %r)
411411
ret i8 %r
412412
}
413+
414+
define i8 @caller16_not_intersecting_ranges() {
415+
; CHECK-LABEL: define i8 @caller16_not_intersecting_ranges() {
416+
; CHECK-NEXT: [[R_I:%.*]] = call range(i8 0, 0) i8 @val8()
417+
; CHECK-NEXT: call void @use.val(i8 [[R_I]])
418+
; CHECK-NEXT: ret i8 [[R_I]]
419+
;
420+
%r = call range(i8 0, 5) i8 @callee15()
421+
call void @use.val(i8 %r)
422+
ret i8 %r
423+
}

0 commit comments

Comments
 (0)