[PATCH] D93376: [LangRef] Clarify the semantics of lifetime intrinsics
Juneyoung Lee via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 15 23:53:22 PST 2020
aqjune created this revision.
aqjune added reviewers: craig.topper, thanm, arsenm, nikic, efriedma.
Herald added a subscriber: jdoerfert.
aqjune requested review of this revision.
Herald added subscribers: llvm-commits, wdng.
Herald added a project: LLVM.
This is a proposal for clarifying the semantics of `lifetime.start` / `lifetime.end` (with @nlopes, @RalfJung).
The proposal is consistent with a description about MIR's LIFETIME_START/LIFETIME_END markers
at StackColoring.cpp (https://github.com/llvm/llvm-project/blob/eb44682d671d66e422b02595a636050582a4d84a/llvm/lib/CodeGen/StackColoring.cpp#L163),
with additional syntactic constraints for valid lifetime intrinsic calls.
To summarize, this patch specifies that:
- Lifetime intrinsics' `ptr` should be either alloca or bitcast(alloca).
- The alloca is initially *dead* if it is syntactically used by any llvm.lifetime.start.
- Dereferencing a dead alloca is UB, but gep/ptrtoint to a dead alloca returns a valid value (explains LICM: https://gcc.godbolt.org/z/Wo9dbo)
- A program that contains a path executing lifetime.start twice to same alloca is ill-formed. LLVM may raise assertion failure when such program is given.
- lifetime.start may not be paired with lifetime.end in some execution (see https://gcc.godbolt.org/z/e7sdh1 (@nlopes))
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D93376
Files:
llvm/docs/LangRef.rst
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -17635,7 +17635,7 @@
Overview:
"""""""""
-The '``llvm.lifetime.start``' intrinsic specifies the start of a memory
+The '``llvm.lifetime.start``' intrinsic specifies the start of a stack-allocated
object's lifetime.
Arguments:
@@ -17643,15 +17643,36 @@
The first argument is a constant integer representing the size of the
object, or -1 if it is variable sized. The second argument is a pointer
-to the object.
+to the object. It should be either :ref:`alloca <i_alloca>` or a bitcast
+to :ref:`alloca <i_alloca>`.
Semantics:
""""""""""
-This intrinsic indicates that before this point in the code, the value
-of the memory pointed to by ``ptr`` is dead. This means that it is known
-to never be used and has an undefined value. A load from the pointer
-that precedes this intrinsic can be replaced with ``'undef'``.
+This intrinsic indicates the start of the lifetime of an alloca that
+``ptr`` points to.
+
+If an alloca is used by any '``llvm.lifetime.start``', the alloca is initially
+dead.
+Dereferencing a pointer to a dead alloca is undefined behavior, but operations
+that do not dereference the pointer such as
+:ref:`getelementptr <i_getelementptr>` or
+:ref:`ptrtoint <i_ptrtoint>` return a valid value.
+When '``llvm.lifetime.start``' to the alloca is executed, the alloca is marked
+as alive, its value is filled with '``undef``', and all operations on it work as
+expected. The alloca is dead again when either
+:ref:`llvm.lifetime.end <int_lifeend>` to the alloca is executed or the
+function returns.
+
+'``llvm.lifetime.start``' to the same alloca cannot be executed twice.
+It is an ill-formed program if there is a path between two
+'``llvm.lifetime.start``' calls to the same alloca without visiting any
+'``llvm.lifetime.end``' call to the alloca.
+
+'``llvm.lifetime.start``' cannot relocate the alloca. In other words,
+observation of the address of an alloca during different lifetimes should
+yield the same value.
+
.. _int_lifeend:
@@ -17668,7 +17689,7 @@
Overview:
"""""""""
-The '``llvm.lifetime.end``' intrinsic specifies the end of a memory
+The '``llvm.lifetime.end``' intrinsic specifies the end of a stack-allocated
object's lifetime.
Arguments:
@@ -17676,15 +17697,15 @@
The first argument is a constant integer representing the size of the
object, or -1 if it is variable sized. The second argument is a pointer
-to the object.
+to the object. It should be either :ref:`alloca <i_alloca>` or a bitcast
+to :ref:`alloca <i_alloca>`.
Semantics:
""""""""""
-This intrinsic indicates that after this point in the code, the value of
-the memory pointed to by ``ptr`` is dead. This means that it is known to
-never be used and has an undefined value. Any stores into the memory
-object following this intrinsic may be removed as dead.
+This intrinsic indicates that the alloca that ``ptr`` points to is dead. See
+:ref:`lifetime.start <int_lifestart> to see the definition of a dead alloca.
+Calling ``llvm.lifetime.end`` on a dead alloca is no-op.
'``llvm.invariant.start``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D93376.312130.patch
Type: text/x-patch
Size: 3251 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201216/baae7192/attachment.bin>
More information about the llvm-commits
mailing list