[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