[PATCH] D61652: [LangRef][Attr] Clarify dereferenceable(_in_scope)

Johannes Doerfert via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 7 13:27:00 PDT 2019


jdoerfert created this revision.
jdoerfert added reviewers: efriedma, hfinkel, chandlerc, rsmith, sanjoy, dberris, nlopes, a.elovikov.
Herald added a subscriber: bollu.
Herald added a project: LLVM.

The current uses of the "dereferenceable" attribute throughout
LLVM/Clang are not consistent in their interpretation of the meaning.

Clang, and some parts of LLVM, assume the annotated pointer value to be
dereferenceable "now", thus at the program point where the annotation is
(which happens to be the definition of the value).

LLVM optimizations and high-level front-ends tend to interpret the
dereferenceable attribute as a persistent property for the pointer.

Now having different interpretations is obviously problematic [1].

There has been ample discussion about which definition we should use and
which one should get its very own attribute [1,2]. (That we need both
seems to be unanimously accepted.)

With this patch we limit the meaning of "dereferenceable" to
"dereferenceable at the definition of the value".
For dereferenceability stretching the whole lifetime of a pointer value,
or at least all program points where the SSA value can be accessed, we
introduced "dereferenceable_in_scope" [7].

Some pros and cons where summarized by @hfinkel [6].

I think the most important reason why we should go this way is that this
change is conservatively correct with regards to existing/currently
produced IR. This is especially important because auto-update is not
applicable when we keep the original dereferenceable name around (what
was updated what wasn't?). We also do not break front-ends that produce
dereferenceable with the same meaning Clang uses. This way forward was
also "suggested" by @rsmith [3] and @chandlerc [4]. The alternative
approach, which was preferred by people as well ([5] to name one), gives
us "correct" and "better" optimizations but breaks with the IR.

Either way, it is clear that we need to fix something and introduce a
new attribute.

NOTE: With this patch we try to settle the discussion one way or another:
  - If accepted, the changes clarify the dereferenceable definition and
    describe the new attribute.
  - If rejected, we will provide a new patch that does it the other way
    around.

[1] http://lists.llvm.org/pipermail/llvm-dev/2018-July/124555.html
[2] https://reviews.llvm.org/D48239
[3] https://reviews.llvm.org/D48239#1135582
[4] https://reviews.llvm.org/D48239#1155026
[5] https://reviews.llvm.org/D48239#1134816
[6] http://lists.llvm.org/pipermail/llvm-dev/2018-July/124557.html
[7] https://twitter.com/codinghorror/status/506010907021828096?lang=en


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D61652

Files:
  llvm/docs/LangRef.rst


Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -1132,15 +1132,23 @@
     the behavior is undefined.
 
 ``dereferenceable(<n>)``
-    This indicates that the parameter or return pointer is dereferenceable. This
-    attribute may only be applied to pointer typed parameters. A pointer that
-    is dereferenceable can be loaded from speculatively without a risk of
-    trapping. The number of bytes known to be dereferenceable must be provided
-    in parentheses. It is legal for the number of bytes to be less than the
-    size of the pointee type. The ``nonnull`` attribute does not imply
-    dereferenceability (consider a pointer to one element past the end of an
-    array), however ``dereferenceable(<n>)`` does imply ``nonnull`` in
-    ``addrspace(0)`` (which is the default address space).
+    This indicates that the annotated value, e.g., a parameter or return
+    value, is dereferenceable *at its definition*, which would be the beginning
+    of the function entry or the call site for annotated parameters and return
+    values respectively. This attribute may only be applied to values with
+    pointer type. A pointer that is known to be dereferenceable (and properly
+    aligned) can be loaded from speculatively without a risk of trapping. The
+    number of bytes known to be dereferenceable must be provided in
+    parentheses. It is legal for the number of bytes to be less than the
+    size of the pointee type. If, at runtime, the annotated pointer is not
+    dereferenceable, the behavior is undefined. The ``nonnull`` attribute does
+    not imply dereferenceability (consider a pointer to one element past the
+    end of an array), however ``dereferenceable(<n>)`` does imply ``nonnull``
+    in ``addrspace(0)`` (which is the default address space). The
+    dereferenceability property provided through this argument is tied to the
+    definition because it can be lost, e.g., via a call to ``free``. Use
+    ``dereferenceable_in_scope(<n>)`` for pointer values that cannot be
+    deallocated in a their respective scope.
 
 ``dereferenceable_or_null(<n>)``
     This indicates that the parameter or return value isn't both
@@ -1151,9 +1159,23 @@
     a pointer is exactly one of ``dereferenceable(<n>)`` or ``null``,
     and in other address spaces ``dereferenceable_or_null(<n>)``
     implies that a pointer is at least one of ``dereferenceable(<n>)``
-    or ``null`` (i.e. it may be both ``null`` and
-    ``dereferenceable(<n>)``). This attribute may only be applied to
-    pointer typed parameters.
+    or ``null`` (i.e. it may be both ``null`` and ``dereferenceable(<n>)``).
+
+``dereferenceable_in_scope(<n>)``
+    This indicates that the annotated pointer value has the
+    ``dereferenceable(<n>)`` property *at any program point* in its scope (as
+    defined by the SSA dominance property). Thus, unlike pointer values
+    annotated with ``dereferenceable(<n>)``, ``dereferenceable_in_scope(<n>)``
+    pointer values can never lose the ``dereferenceable(<n>)`` property as long
+    as the annotated value is accessible as an SSA value.
+
+``dereferenceable_or_null_in_scope(<n>)``
+    This indicates that the annotated pointer value has the
+    ``dereferenceable_or_null(<n>)`` property *at any program point* in its
+    scope. Thus, unlike pointer values annotated with
+    ``dereferenceable_or_null(<n>)``,
+    ``dereferenceable_or_null_in_scope(<n>)`` pointer values can never lose the
+    ``dereferenceable_or_null(<n>)`` property.
 
 ``swiftself``
     This indicates that the parameter is the self/context parameter. This is not


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61652.198520.patch
Type: text/x-patch
Size: 3711 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190507/30702c15/attachment.bin>


More information about the llvm-commits mailing list