[llvm] Assert range attribute is not empty nor full (PR #100601)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 6 12:39:47 PDT 2024
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/100601
>From cfe9f5c86d2affec6cd8de295618ee4d244c8eb3 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sun, 28 Jul 2024 17:51:27 +0200
Subject: [PATCH 1/2] Add pre-commit tests. NFC
---
.../Transforms/Inline/ret_attr_align_and_noundef.ll | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
index f4cebf1fcb5da..dc685d2c4d136 100644
--- a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
+++ b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
@@ -410,3 +410,14 @@ define i8 @caller15_okay_intersect_ranges() {
call void @use.val(i8 %r)
ret i8 %r
}
+
+define i8 @caller16_not_intersecting_ranges() {
+; CHECK-LABEL: define i8 @caller16_not_intersecting_ranges() {
+; CHECK-NEXT: [[R_I:%.*]] = call range(i8 0, 0) i8 @val8()
+; CHECK-NEXT: call void @use.val(i8 [[R_I]])
+; CHECK-NEXT: ret i8 [[R_I]]
+;
+ %r = call range(i8 0, 5) i8 @callee15()
+ call void @use.val(i8 %r)
+ ret i8 %r
+}
>From ffd7c1651633e90eea481a2c88465f80c209db87 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Tue, 6 Aug 2024 19:29:47 +0200
Subject: [PATCH 2/2] Allow empty range attribute and add assert for full range
---
llvm/docs/LangRef.rst | 3 ++-
llvm/include/llvm/IR/Attributes.h | 1 +
llvm/lib/AsmParser/LLParser.cpp | 4 ++--
llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 4 +++-
llvm/lib/IR/Attributes.cpp | 11 ++++++++++-
llvm/lib/IR/Core.cpp | 8 ++++----
llvm/test/Assembler/range-attribute-invalid-range.ll | 4 ++--
llvm/test/Bitcode/attributes.ll | 4 ++--
8 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index b17e3c828ed3d..b97def0a3c6d4 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1675,7 +1675,8 @@ Currently, only the following parameter attributes are defined:
- The pair ``a,b`` represents the range ``[a,b)``.
- Both ``a`` and ``b`` are constants.
- The range is allowed to wrap.
- - The range should not represent the full or empty set. That is, ``a!=b``.
+ - Only for the empty set is ``a`` and ``b`` allowed to be equal and
+ only for the value 0.
This attribute may only be applied to parameters or return values with integer
or vector of integer types.
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index 5a80a072dbbd2..cefbe1d760588 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -160,6 +160,7 @@ class Attribute {
static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind);
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME);
static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask);
+ static Attribute getWithRange(LLVMContext &Context, const ConstantRange &CR);
/// For a typed attribute, return the equivalent attribute with the type
/// changed to \p ReplacementTy.
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 9358f89e2bf9d..426b625109c84 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3109,8 +3109,8 @@ bool LLParser::parseRangeAttr(AttrBuilder &B) {
if (ParseAPSInt(BitWidth, Lower) ||
parseToken(lltok::comma, "expected ','") || ParseAPSInt(BitWidth, Upper))
return true;
- if (Lower == Upper)
- return tokError("the range should not represent the full or empty set!");
+ if (Lower == Upper && !Lower.isMinValue())
+ return tokError("the range represent the empty set but limits aren't 0!");
if (parseToken(lltok::rparen, "expected ')'"))
return true;
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index fd4ae109b4bb8..091065cf6d55f 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2369,7 +2369,9 @@ Error BitcodeReader::parseAttributeGroupBlock() {
return MaybeCR.takeError();
i--;
- B.addConstantRangeAttr(Kind, MaybeCR.get());
+ assert(Kind == Attribute::Range &&
+ "Unhandled ConstantRangeAttribute");
+ B.addRangeAttr(MaybeCR.get());
} else if (Record[i] == 8) {
Attribute::AttrKind Kind;
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index abd05e316bec1..8efe8551f7c71 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -286,6 +286,12 @@ Attribute Attribute::getWithNoFPClass(LLVMContext &Context,
return get(Context, NoFPClass, ClassMask);
}
+Attribute Attribute::getWithRange(LLVMContext &Context,
+ const ConstantRange &CR) {
+ assert(!CR.isFullSet() && "Range must not be full!");
+ return get(Context, Range, CR);
+}
+
Attribute
Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
const std::optional<unsigned> &NumElemsArg) {
@@ -2024,7 +2030,10 @@ AttrBuilder &AttrBuilder::addConstantRangeAttr(Attribute::AttrKind Kind,
}
AttrBuilder &AttrBuilder::addRangeAttr(const ConstantRange &CR) {
- return addConstantRangeAttr(Attribute::Range, CR);
+ if (CR.isFullSet())
+ return *this;
+
+ return addAttribute(Attribute::getWithRange(Ctx, CR));
}
AttrBuilder &
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 17c0bf72ef05d..f3e0ed385ae2b 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -191,11 +191,11 @@ LLVMAttributeRef LLVMCreateConstantRangeAttribute(LLVMContextRef C,
const uint64_t UpperWords[]) {
auto &Ctx = *unwrap(C);
auto AttrKind = (Attribute::AttrKind)KindID;
+ assert(AttrKind == Attribute::Range && "Unhandled ConstantRangeAttribute");
unsigned NumWords = divideCeil(NumBits, 64);
- return wrap(Attribute::get(
- Ctx, AttrKind,
- ConstantRange(APInt(NumBits, ArrayRef(LowerWords, NumWords)),
- APInt(NumBits, ArrayRef(UpperWords, NumWords)))));
+ return wrap(Attribute::getWithRange(
+ Ctx, ConstantRange(APInt(NumBits, ArrayRef(LowerWords, NumWords)),
+ APInt(NumBits, ArrayRef(UpperWords, NumWords)))));
}
LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
diff --git a/llvm/test/Assembler/range-attribute-invalid-range.ll b/llvm/test/Assembler/range-attribute-invalid-range.ll
index cf6d3f0801838..1ddb6745e5dc2 100644
--- a/llvm/test/Assembler/range-attribute-invalid-range.ll
+++ b/llvm/test/Assembler/range-attribute-invalid-range.ll
@@ -1,6 +1,6 @@
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
-; CHECK: the range should not represent the full or empty set!
-define void @range_empty(i8 range(i8 0, 0) %a) {
+; CHECK: the range represent the empty set but limits aren't 0!
+define void @range_empty(i8 range(i8 1, 1) %a) {
ret void
}
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index f4dc9b9849827..c6d8fe1937644 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -531,8 +531,8 @@ define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
ret i32 0
}
-; CHECK: define range(i32 0, 42) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a)
-define range(i32 0, 42) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a) {
+; CHECK: define range(i32 0, 0) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a)
+define range(i32 0, 0) i32 @range_attribute_same_range_other_bitwidth(i8 range(i8 0, 42) %a) {
ret i32 0
}
More information about the llvm-commits
mailing list