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 ` 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 `, 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 ` with @@ -3258,9 +3259,22 @@ successor. - Dependence is transitive. -Poison values have the same behavior as :ref:`undef values `, -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 `, 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 `, :ref:`store ` or + any other pointer dereferencing instruction (independent of address + space). +- The divisor operand of a ``udiv``, ``sdiv``, ``urem`` or ``srem`` + instruction. + +Additionally, undefined behavior occurs if a side effect *depends* on poison. +This includes side effects that are control dependent on a poisoned branch. Here are some examples: @@ -3270,13 +3284,12 @@ %poison = sub nuw i32 0, 1 ; Results in a poison value. %still_poison = and i32 %poison, 0 ; 0, but also poison. %poison_yet_again = getelementptr i32, i32* @h, i32 %still_poison - store i32 0, i32* %poison_yet_again ; memory at @h[0] is poisoned + store i32 0, i32* %poison_yet_again ; Undefined behavior due to + ; store to poison. 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. 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: