-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the 'initializes' attribute langref and support #84803
Conversation
@llvm/pr-subscribers-llvm-adt @llvm/pr-subscribers-llvm-ir Author: Haopeng Liu (haopliu) ChangesWe propose adding a new LLVM attribute, Will commit the attribute inferring in the follow-up PRs. Full diff: https://github.com/llvm/llvm-project/pull/84803.diff 1 Files Affected:
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index b70220dec92615..39a555edfa80d6 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1621,6 +1621,28 @@ Currently, only the following parameter attributes are defined:
``readonly`` or a ``memory`` attribute that does not contain
``argmem: write``.
+``initialized((Lo1,Hi1),...)``
+ This attribute is a list of const ranges in ascending order with no
+ overlapping or continuous. It indicates that the function initializes the
+ memory through the pointer argument, [%p+LoN, %p+HiN): there are no reads,
+ and no special accesses (such as volatile access or untrackable capture)
+ before the initialization in the function. LoN/HiN are 64-bit ints;
+ negative values are allowed in case a pointer to partway through the
+ allocation is passed to.
+
+ This attribute implies that the function initializes and does not read
+ before initialization through this pointer argument, even though it may
+ read the memory before initialization that the pointer points to, such
+ as through other arguments.
+
+ The ``writable`` or ``dereferenceable`` attribute does not imply
+ ``initialized`` attribute, and ``initialized`` does not imply ``writeonly``
+ since cases that read from the pointer after write, can be ``initialized``
+ but not ``writeonly``.
+
+ Note that this attribute does not apply to the unwind edge: the memory may
+ not actually be written to when unwinding happens.
+
``dead_on_unwind``
At a high level, this attribute indicates that the pointer argument is dead
if the call unwinds, in the sense that the caller will not depend on the
|
llvm/docs/LangRef.rst
Outdated
@@ -1621,6 +1621,28 @@ Currently, only the following parameter attributes are defined: | |||
``readonly`` or a ``memory`` attribute that does not contain | |||
``argmem: write``. | |||
|
|||
``initialized((Lo1,Hi1),...)`` | |||
This attribute is a list of const ranges in ascending order with no | |||
overlapping or continuous. It indicates that the function initializes the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "with no overlapping or adjoining list elements"? or something like that (felt like it was missing a word at the end at least)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should start this off with a one sentence overview of the attribute. So starting with something like "This indicates that the function initializes the ranges of the pointer parameter's memory." Then describe what "initialize" means. Then the random details like non-overlapping/continuous ranges at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
llvm/docs/LangRef.rst
Outdated
and no special accesses (such as volatile access or untrackable capture) | ||
before the initialization in the function. LoN/HiN are 64-bit ints; | ||
negative values are allowed in case a pointer to partway through the | ||
allocation is passed to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "in case the argument points partway into an allocation." ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
llvm/docs/LangRef.rst
Outdated
as through other arguments. | ||
|
||
The ``writable`` or ``dereferenceable`` attribute does not imply | ||
``initialized`` attribute, and ``initialized`` does not imply ``writeonly`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "does not imply [the] initialized
attribute, and ... writeonly
, since initialized
allows reading from the pointer after writing." ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
we should combine this PR with the PR that adds support for this in LLVM, or else it's weird if we're documenting something that LLVM doesn't support yet |
llvm/docs/LangRef.rst
Outdated
since cases that read from the pointer after write, can be ``initialized`` | ||
but not ``writeonly``. | ||
|
||
Note that this attribute does not apply to the unwind edge: the memory may |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as mentioned in the RFC, we should be more accurate here. the part of the attribute where the memory is read from before a write still must apply on the unwind edge. Also, I'd move this up since this is important to the semantics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, I meant that the memory is not read from before a write
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
unintentional add of FunctionAttrs.cpp change?
specifically just the attribute support (e.g. bitcode) not any of the inference or usage of it |
llvm/docs/LangRef.rst
Outdated
special accesses (such as volatile access or untrackable capture) before | ||
the initialization write in the function. | ||
|
||
This attribute implies that the function initializes and does not read |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't use implies
.
`This attribute only holds for the memory accessed via this pointer parameter. Other arbitrary accesses to the same memory via other pointers are allowed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
llvm/docs/LangRef.rst
Outdated
written to when unwinding happens. | ||
|
||
The ``writable`` or ``dereferenceable`` attribute does not imply the | ||
``initialized`` attribute, and ``initialized`` does not imply ``writeonly`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd separate this into two sentences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
llvm/docs/LangRef.rst
Outdated
``initialized`` attribute, and ``initialized`` does not imply ``writeonly`` | ||
since ``initialized`` allows reading from the pointer after writing. | ||
|
||
This attribute is a list of const ranges in ascending order with no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/const/constant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, done!
llvm/docs/LangRef.rst
Outdated
since ``initialized`` allows reading from the pointer after writing. | ||
|
||
This attribute is a list of const ranges in ascending order with no | ||
overlapping or adjoining list elements. LoN/HiN are 64-bit ints, and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't heard "adjoining" used in this context, I think "consecutive" is more commonly used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
llvm/docs/LangRef.rst
Outdated
since ``initialized`` allows reading from the pointer after writing. | ||
|
||
This attribute is a list of const ranges in ascending order with no | ||
overlapping or adjoining list elements. LoN/HiN are 64-bit ints, and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put LoN
/HiN
in double backticks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
As a heads up, the inference implementation for this (or at least the available prototype) does not look viable from a compile-time perspective: https://llvm-compile-time-tracker.com/compare.php?from=69b09b43b0a2057918078edb401adab888d1014b&to=0bd68ae2d56783377acc0aa5d7958b47411b8342&stat=instructions:u |
Thanks for this heads up! This PR only adds the attribute support. Will further tune the inferring performance and post the updated compile time tracker in the inference PR. |
Thank you all! Update the LangRef, and add the attribute support. Please take another look :-D |
llvm/include/llvm/IR/Attributes.td
Outdated
@@ -38,6 +38,9 @@ class IntAttr<string S, list<AttrProperty> P> : Attr<S, P>; | |||
/// Type attribute. | |||
class TypeAttr<string S, list<AttrProperty> P> : Attr<S, P>; | |||
|
|||
/// Const range list attribute. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: put closer to the ConstantRangeAttr?
llvm/include/llvm/IR/Attributes.td
Outdated
@@ -318,6 +321,9 @@ def Writable : EnumAttr<"writable", [ParamAttr]>; | |||
/// Function only writes to memory. | |||
def WriteOnly : EnumAttr<"writeonly", [ParamAttr]>; | |||
|
|||
/// Pointer argument memory [%p+LoN, %p+HiN) is initialized. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list looks almost sorted, so may be better to put it near InAlloca or ?
@@ -307,6 +308,10 @@ namespace llvm { | |||
bool AllowParens = false); | |||
bool parseOptionalCodeModel(CodeModel::Model &model); | |||
bool parseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes); | |||
bool parseConstRange(std::pair<int64_t, int64_t> &Range); | |||
bool parseInitializedRanges( | |||
lltok::Kind AttrKind, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can the AttrKind be hardcoded within the function instead of taking as parameter? (unlike DerefAttrBytes, there is only one variation of the attribute, I believe?)
llvm/include/llvm/IR/Attributes.h
Outdated
@@ -94,6 +94,8 @@ class Attribute { | |||
|
|||
static const unsigned NumIntAttrKinds = LastIntAttr - FirstIntAttr + 1; | |||
static const unsigned NumTypeAttrKinds = LastTypeAttr - FirstTypeAttr + 1; | |||
static const unsigned NumConstRangeListAttrKinds = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used by anything (if not, can remove)? I don't see the ConstantRangeAttrKind version of it, and hard to see "NumTypeAttrKinds" used
llvm/include/llvm/IR/Attributes.h
Outdated
@@ -186,6 +193,9 @@ class Attribute { | |||
/// Return true if the attribute is a type attribute. | |||
bool isTypeAttribute() const; | |||
|
|||
/// Return true if the attribute is a const range list attribute. | |||
bool isConstRangeListAttribute() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: wonder if should s/Const/Constant/ to be consistent with isConstantRangeAttribute, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, no need to abbreviate
llvm/include/llvm/ADT/FoldingSet.h
Outdated
@@ -362,6 +362,21 @@ class FoldingSetNodeID { | |||
} | |||
} | |||
|
|||
void AddRanges(const SmallVector<std::pair<int64_t, int64_t>, 16> &Ranges) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to use ArrayRef or something to not need specific SmallVector inline size of 16 here? "Prefer to use ArrayRef or SmallVectorImpl as a parameter type." under https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
llvm/include/llvm/IR/Attributes.h
Outdated
@@ -226,6 +236,10 @@ class Attribute { | |||
/// attribute to be a ConstantRange attribute. | |||
ConstantRange getValueAsConstantRange() const; | |||
|
|||
/// Return the attribute's value as a const range list. This requires the | |||
/// attribute to be a const range list attribute. | |||
SmallVector<std::pair<int64_t, int64_t>, 16> getValueAsRanges() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to return an ArrayRef instead of a copy? Will the underlying storage lifetime work out?
llvm/lib/AsmParser/LLParser.cpp
Outdated
if (parseInt64(Range.first)) | ||
return true; | ||
|
||
if (EatIfPresent(lltok::comma)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be an error to be missing the comma?
@@ -930,11 +932,24 @@ void ModuleBitcodeWriter::writeAttributeGroupTable() { | |||
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); | |||
if (Ty) | |||
Record.push_back(VE.getTypeID(Attr.getValueAsType())); | |||
} else { | |||
} else if (Attr.isConstantRangeAttribute()) { | |||
assert(Attr.isConstantRangeAttribute()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can remove the assert?
llvm/lib/IR/Verifier.cpp
Outdated
Check(!Inits.empty(), "Attribute 'initialized' does not support empty list", | ||
V); | ||
|
||
for (size_t i = 1; i < Inits.size(); i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps check low < high for the same "i"?
llvm/include/llvm/IR/Attributes.h
Outdated
@@ -226,6 +236,10 @@ class Attribute { | |||
/// attribute to be a ConstantRange attribute. | |||
ConstantRange getValueAsConstantRange() const; | |||
|
|||
/// Return the attribute's value as a const range list. This requires the | |||
/// attribute to be a const range list attribute. | |||
SmallVector<std::pair<int64_t, int64_t>, 16> getValueAsRanges() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should use ConstantRange
instead of std::pair
, especially since it already has intersection/union methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, 16 elements for the small vector optimization seems very high, I feel the vast majority of cases will be at most 4. I'd choose 4 (or even 2)
llvm/lib/IR/Attributes.cpp
Outdated
@@ -616,6 +652,23 @@ std::string Attribute::getAsString(bool InAttrGrp) const { | |||
return Result; | |||
} | |||
|
|||
if (hasAttribute(Attribute::Initialized)) { | |||
auto Ranges = getValueAsRanges(); | |||
if (Ranges.empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this allowed? I think we should forbid an empty list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I see the verifier check below, so I don't think we need this check
llvm/lib/IR/Verifier.cpp
Outdated
@@ -1993,6 +1993,14 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty, | |||
Attrs.hasAttribute(Attribute::ReadOnly)), | |||
"Attributes writable and readonly are incompatible!", V); | |||
|
|||
Check(!(Attrs.hasAttribute(Attribute::Initialized) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is true. A function that immediately unwinds can be marked as initializing all arguments according to our semantics, but is also readnone
llvm/include/llvm/IR/Attributes.h
Outdated
@@ -186,6 +193,9 @@ class Attribute { | |||
/// Return true if the attribute is a type attribute. | |||
bool isTypeAttribute() const; | |||
|
|||
/// Return true if the attribute is a const range list attribute. | |||
bool isConstRangeListAttribute() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, no need to abbreviate
llvm/docs/LangRef.rst
Outdated
parameter. Other arbitrary accesses to the same memory via other pointers | ||
are allowed. | ||
|
||
Note that this attribute does not apply to the unwind edge: the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is now redundant with the unwind comment above
The main thing I would be concerned about at this point is whether the entire approach is viable or not -- I'd rather not add the attribute (plus a whole new attribute kind) if it later turns out that this is too expensive. Anyway, a couple of high level comments:
|
+1
Makes sense,
Yes the concern was padding holes. @haopliu do you have any data on how often padding prevents whole object initialization? |
Even if we represent padding more precisely with multiple ranges in I think |
godbolt seems to not show metadata (I'm not seeing it on a |
actually I'm unsure if it would be legal to remove stores on padding bytes |
@nikic any more concerns? |
ping @nikic |
llvm/lib/IR/AttributeImpl.h
Outdated
assert(Size > 0); | ||
unsigned BitWidth = Val.front().getLower().getBitWidth(); | ||
for (unsigned I = 0; I != Size; ++I) { | ||
assert(BitWidth == Val[I].getLower().getBitWidth()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert(BitWidth == Val[I].getLower().getBitWidth()); | |
assert(BitWidth == Val[I].getBitWidth()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this code snippet.
llvm/lib/IR/AttributeImpl.h
Outdated
unsigned BitWidth = Val.front().getLower().getBitWidth(); | ||
for (unsigned I = 0; I != Size; ++I) { | ||
assert(BitWidth == Val[I].getLower().getBitWidth()); | ||
new (&TrailingCR[I]) ConstantRange(BitWidth, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you use uninitialized_copy
instead of performing a dummy initialization first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this code snippet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to uninitialized_copy
!
llvm/lib/IR/Attributes.cpp
Outdated
// If we didn't find any existing attributes of the same shape then create a | ||
// new one and insert it. | ||
PA = new (pImpl->ConstantRangeListAttributeAlloc.Allocate( | ||
ConstantRangeListAttributeImpl::totalSizeToAlloc(Val))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, this does something completely different from what you think it does. It allocates an array of sizeof(ConstantRangeListAttributeImpl) * totalSizeToAlloc(Val)
.
It's not possible to use SpecificBumpPtrAllocator with a dynamically sized class, it can only be used to allocate objects of fixed size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we have a variable number of ConstantRange
s in a ConstantRangeListAttributeImpl
and they need a destructor, I don't see a nice way of using trailing objects and bump allocators. I think we should go back to ConstantRangeListAttributeImpl
containing a ConstantRangeList
and using SpecificBumpPtrAllocator<ConstantRangeListAttributeImpl>
so that we allocate the right amount of memory and properly call the destructor. most of the time we'll be in the non-allocating version of the SmallVector<ConstantRange>
anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the attr implementation back to ConstantRangeList.
Thanks for the comments, Nikita and Arthur! @nikic please take another look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikic ping
@@ -858,6 +859,14 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { | |||
} | |||
} | |||
|
|||
Expected<ConstantRange> | |||
readBitWidthAndConstantRange(ArrayRef<uint64_t> Record, unsigned &OpNum) { | |||
if (Record.size() - OpNum < 3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd check 1
instead of 3
and let readConstantRange
deal with its own reading error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
llvm/lib/IR/AttributeImpl.h
Outdated
static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind, | ||
const ConstantRangeList &CRL) { | ||
ID.AddInteger(Kind); | ||
ID.AddInteger(CRL.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should also add bit width here now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, nice catch. Done!
return error("Too few records for constant range list"); | ||
unsigned RangeSize = Record[i++]; | ||
unsigned BitWidth = Record[i++]; | ||
if (i + 2 * RangeSize > e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can remove this hoisted i + 2 * RangeSize > e
check, since it's not always 2 elements per RangeSize anymore and readConstantRange is doing the checks in the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, done!
I think @nikic's concerns have been addressed and there are no major objections to this patch going in. We can address any post-commit feedback with followup PRs, but I'd like to get this in so we can start reviewing the DSE + inference PRs. |
Why did this change back to storing ConstantRangeList in the Attribute rather than the efficient TrailingObjects / ArrayRef representation? If this was just because of the memory leak issue, I think an easy to solve that would have been to a) use the normal Alloc for allocation (instead of a separate SpecificBumpPtrAllocator) and b) add a vector to which all allocated pointers are added. Then in the LLVMContext dtor call the dtors of everything in the vector. |
Good point. Changed the attr impl to use normal Alloc w/ a vector and explicitly call each attr's dtor in LLVMContext dtor. Please take another look. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more nits, but mostly this looks good to me.
llvm/lib/IR/ConstantRangeList.cpp
Outdated
[](const ConstantRange &a, const ConstantRange &b) { | ||
return a.getLower().slt(b.getLower()); | ||
}); | ||
if (LowerBound != Ranges.end() && *LowerBound == NewRange) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of checking strict equality here, could check whether LowerBound contains NewRange instead? That would handle more cases via fast path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, changed to check whether LowerBound contains NewRange.
llvm/lib/IR/Verifier.cpp
Outdated
V); | ||
|
||
Check(Inits[0].getLower().slt(Inits[0].getUpper()), | ||
"Attribute 'initializes' requires interval lower less than upper", V); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reuse isOrderedRanges here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
llvm/lib/IR/ConstantRangeList.cpp
Outdated
LowerBound->getLower().eq(NewRange.getLower()) && | ||
LowerBound->getUpper().sge(NewRange.getUpper())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LowerBound->getLower().eq(NewRange.getLower()) && | |
LowerBound->getUpper().sge(NewRange.getUpper())) | |
LowerBound->contains(NewRange)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, didn't notice ConstantRange::contains()
. Nice!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/101/builds/483 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/15/builds/486 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/69/builds/467 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/92/builds/447 Here is the relevant piece of the build log for the reference:
|
We propose adding a new LLVM attribute, `initializes((Lo1,Hi1),(Lo2,Hi2),...)`, which expresses the notion of memory space (i.e., intervals, in bytes) that the argument pointing to is initialized in the function. Will commit the attribute inferring in the follow-up PRs. https://discourse.llvm.org/t/rfc-llvm-new-initialized-parameter-attribute-for-improved-interprocedural-dse/77337
We propose adding a new LLVM attribute,
initializes((Lo1,Hi1),(Lo2,Hi2),...)
, which expresses the notion of memory space (i.e., intervals, in bytes) that the argument pointing to is initialized in the function.Will commit the attribute inferring in the follow-up PRs.
https://discourse.llvm.org/t/rfc-llvm-new-initialized-parameter-attribute-for-improved-interprocedural-dse/77337