[PATCH] D63044: [LangRef] Clarify poison semantics
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 9 12:23:19 PDT 2019
nikic updated this revision to Diff 203751.
nikic marked 2 inline comments as done.
nikic edited the summary of this revision.
nikic added a comment.
Dereferencing poison is always UB, independent of whether dereferencing null is UB.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63044/new/
https://reviews.llvm.org/D63044
Files:
llvm/docs/LangRef.rst
llvm/lib/Analysis/ValueTracking.cpp
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -4336,6 +4336,8 @@
}
bool llvm::propagatesFullPoison(const Instruction *I) {
+ // TODO: This should include all instructions apart from phis, selects and
+ // call-like instructions.
switch (I->getOpcode()) {
case Instruction::Add:
case Instruction::Sub:
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -2156,6 +2156,8 @@
address range of the allocated storage.
- A null pointer in the default address-space is associated with no
address.
+- An :ref:`undef value <undefvalues>` in *any* address-space is
+ associated with no address.
- An integer constant other than zero or a pointer value returned from
a function not defined within LLVM may be associated with address
ranges allocated through mechanisms other than those provided by
@@ -3218,10 +3220,9 @@
Poison Values
-------------
-Poison values are similar to :ref:`undef values <undefvalues>`, however
-they also represent the fact that an instruction or constant expression
-that cannot evoke side effects has nevertheless detected a condition
-that results in undefined behavior.
+In order to facilitate speculative execution, many instructions do not
+invoke immediate undefined behavior when provided with illegal operands,
+and return a poison value instead.
There is currently no way of representing a poison value in the IR; they
only exist when produced by operations such as :ref:`add <i_add>` with
@@ -3258,9 +3259,20 @@
successor.
- Dependence is transitive.
-Poison values have the same behavior as :ref:`undef values <undefvalues>`,
-with the additional effect that any instruction that has a *dependence*
-on a poison value has undefined behavior.
+An instruction that *depends* on a poison value, produces a poison value
+itself. A poison value may be relaxed into an
+:ref:`undef value <undefvalues>`, which takes an arbitrary bit-pattern.
+
+This means that immediate undefined behavior occurs if a poison value is
+used as an instruction operand that has any values that trigger undefined
+behavior. Notably this includes (but is not limited to):
+
+- The pointer operand of a :ref:`load <i_load>`, :ref:`store <i_store>` or
+ any other pointer dereferencing instruction.
+- The divisor operand of a ``udiv``, ``sdiv``, ``urem`` or ``srem``
+ instruction.
+
+Additionally, undefined behavior occurs if a side effect depends on poison.
Here are some examples:
@@ -3275,8 +3287,6 @@
store i32 %poison, i32* @g ; Poison value stored to memory.
%poison2 = load i32, i32* @g ; Poison value loaded back from memory.
- store volatile i32 %poison, i32* @g ; External observation; undefined behavior.
-
%narrowaddr = bitcast i32* @g to i16*
%wideaddr = bitcast i32* @g to i64*
%poison3 = load i16, i16* %narrowaddr ; Returns a poison value.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63044.203751.patch
Type: text/x-patch
Size: 3132 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190609/04e8820c/attachment.bin>
More information about the llvm-commits
mailing list