[PATCH] D47854: [LangRef] Clarify semantics of load metadata.

Eli Friedman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 6 16:45:34 PDT 2018


efriedma created this revision.
efriedma added reviewers: sanjoy, spatel, hfinkel, chandlerc, nlopes.

We need to explicitly state what happens when an invariant promised by load metadata is violated at runtime, since it's come up repeatedly.

It's possible we want to specify that the result of the load is poison in some cases, rather than undefined behavior, if the constraint is violated. That would allow preserving the metadata when the load is hoisted, but doesn't allow propagating metadata based on control flow.  We currently do transforms based on control-flow for nonnull metadata (in PromoteMemToReg).

The dereferenceable metadata is a little weird; not sure I'm capturing the intended semantics, but it matches the logic in  Value::getPointerDereferenceableBytes.


Repository:
  rL LLVM

https://reviews.llvm.org/D47854

Files:
  docs/LangRef.rst


Index: docs/LangRef.rst
===================================================================
--- docs/LangRef.rst
+++ docs/LangRef.rst
@@ -4933,10 +4933,11 @@
 
 ``range`` metadata may be attached only to ``load``, ``call`` and ``invoke`` of
 integer types. It expresses the possible ranges the loaded value or the value
-returned by the called function at this call site is in. The ranges are
-represented with a flattened list of integers. The loaded value or the value
-returned is known to be in the union of the ranges defined by each consecutive
-pair. Each pair has the following properties:
+returned by the called function at this call site is in. If the loaded or
+returned value is not in the specified range, the behavior is undefined. The
+ranges are represented with a flattened list of integers. The loaded value or
+the value returned is known to be in the union of the ranges defined by each
+consecutive pair. Each pair has the following properties:
 
 -  The type must match the type loaded by the instruction.
 -  The pair ``a,b`` represents the range ``[a,b)``.
@@ -7936,7 +7937,8 @@
 entries. If a load instruction tagged with the ``!invariant.load``
 metadata is executed, the optimizer may assume the memory location
 referenced by the load contains the same value at all points in the
-program where the memory location is known to be dereferenceable.
+program where the memory location is known to be dereferenceable;
+otherwise, the behavior is undefined.
 
 The optional ``!invariant.group`` metadata must reference a single metadata name
  ``<index>`` corresponding to a metadata node with no entries.
@@ -7946,14 +7948,16 @@
 metadata name ``<index>`` corresponding to a metadata node with no
 entries. The existence of the ``!nonnull`` metadata on the
 instruction tells the optimizer that the value loaded is known to
-never be null. This is analogous to the ``nonnull`` attribute
-on parameters and return values. This metadata can only be applied
-to loads of a pointer type.
+never be null. If the value is null at runtime, the behavior is undefined.
+This is analogous to the ``nonnull`` attribute on parameters and return
+values. This metadata can only be applied to loads of a pointer type.
 
 The optional ``!dereferenceable`` metadata must reference a single metadata
 name ``<deref_bytes_node>`` corresponding to a metadata node with one ``i64``
 entry. The existence of the ``!dereferenceable`` metadata on the instruction
-tells the optimizer that the value loaded is known to be dereferenceable.
+tells the optimizer that the value loaded is known to be dereferenceable at
+any later point in the program. If the memory cannot be dereferenced at
+runtime, the behavior is undefined.
 The number of bytes known to be dereferenceable is specified by the integer
 value in the metadata node. This is analogous to the ''dereferenceable''
 attribute on parameters and return values. This metadata can only be applied
@@ -7963,7 +7967,8 @@
 metadata name ``<deref_bytes_node>`` corresponding to a metadata node with one
 ``i64`` entry. The existence of the ``!dereferenceable_or_null`` metadata on the
 instruction tells the optimizer that the value loaded is known to be either
-dereferenceable or null.
+dereferenceable or null at any later point in the program. If the memory
+is not null and cannot be dereferenced at runtime, the behavior is undefined.
 The number of bytes known to be dereferenceable is specified by the integer
 value in the metadata node. This is analogous to the ''dereferenceable_or_null''
 attribute on parameters and return values. This metadata can only be applied
@@ -7975,7 +7980,8 @@
 optimizer that the value loaded is known to be aligned to a boundary specified
 by the integer value in the metadata node. The alignment must be a power of 2.
 This is analogous to the ''align'' attribute on parameters and return values.
-This metadata can only be applied to loads of a pointer type.
+This metadata can only be applied to loads of a pointer type. If the returned
+value is not appropriately aligned at runtime, the behavior is undefined.
 
 Semantics:
 """"""""""


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47854.150221.patch
Type: text/x-patch
Size: 4137 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180606/308b7b4c/attachment.bin>


More information about the llvm-commits mailing list