[PATCH] D123991: [LangRef] Clarify load/store of non-byte-sized types

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 19 02:19:58 PDT 2022


nikic created this revision.
nikic added reviewers: nlopes, aqjune, spatel, lebedev.ri, efriedma.
Herald added a subscriber: jdoerfert.
Herald added a project: All.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

For non-byte-sized types like `i20`, we currently specify that:

> When loading a value of a type like i20 with a size that is not an integral number of bytes, the result is undefined if the value was not originally written using a store of the same type.



> When writing a value of a type like i20 with a size that is not an integral number of bytes, it is unspecified what happens to the extra bits that do not belong to the type, but they will typically be overwritten.

These semantics are somewhat unclear, and likely incompatible with current optimization assumptions. If "undefined" in load specification is in the sense of "undefined behavior" that means that non-byte-sized loads may not be speculatable despite the memory being dereferenceable, which is not something we're taking into account right now. The "unspecified" in the store specification is just unclear, does this mean the bits become undef, or poison, or something else?

This patch specifies that poison is stored for padding of both aggregates and non-byte-sized types. Loads of such types don't require special treatment, as the padding is not observable anyway.

I believe this covers the practical requirements for non-byte-sized types, in that a) a hardware store will likely zero out the padding bits, which is compatible with poison and b) it is possible to eliminate a store of non-byte-sized type (e.g. due to "store of loaded value"), which will leave behind the original bits (which might be poison, so making the padding anything weaker than that would render the optimization illegal).


https://reviews.llvm.org/D123991

Files:
  llvm/docs/LangRef.rst


Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -9934,13 +9934,10 @@
 The location of memory pointed to is loaded. If the value being loaded
 is of scalar type then the number of bytes read does not exceed the
 minimum number of bytes needed to hold all bits of the type. For
-example, loading an ``i24`` reads at most three bytes. When loading a
-value of a type like ``i20`` with a size that is not an integral number
-of bytes, the result is undefined if the value was not originally
-written using a store of the same type.
-If the value being loaded is of aggregate type, the bytes that correspond to
-padding may be accessed but are ignored, because it is impossible to observe
-padding from the loaded aggregate value.
+example, loading an ``i24`` reads at most three bytes.
+If the value being loaded is of aggregate or non-byte-sized type, the bits that
+correspond to padding may be accessed but are ignored, because it is impossible
+to observe padding from the loaded value.
 If ``<pointer>`` is not a well-defined value, the behavior is undefined.
 
 Examples:
@@ -10029,12 +10026,9 @@
 location specified by the ``<pointer>`` operand. If ``<value>`` is
 of scalar type then the number of bytes written does not exceed the
 minimum number of bytes needed to hold all bits of the type. For
-example, storing an ``i24`` writes at most three bytes. When writing a
-value of a type like ``i20`` with a size that is not an integral number
-of bytes, it is unspecified what happens to the extra bits that do not
-belong to the type, but they will typically be overwritten.
-If ``<value>`` is of aggregate type, padding is filled with
-:ref:`undef <undefvalues>`.
+example, storing an ``i24`` writes at most three bytes.
+If ``<value>`` is of aggregate or non-byte-sized type, padding is filled with
+:ref:`poison <poisonvalues>`.
 If ``<pointer>`` is not a well-defined value, the behavior is undefined.
 
 Example:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D123991.423561.patch
Type: text/x-patch
Size: 2027 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220419/6deef4c5/attachment.bin>


More information about the llvm-commits mailing list