Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -3218,10 +3218,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 +3257,21 @@ 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, if dereferencing ``null`` + is undefined behavior based on address space and function attributes. +- 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 +3286,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. 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: @@ -4369,6 +4371,8 @@ const Value *llvm::getGuaranteedNonFullPoisonOp(const Instruction *I) { switch (I->getOpcode()) { + // TODO: These should be limited to address space 0 and absence of the + // null-pointer-is-valid attribute. case Instruction::Store: return cast(I)->getPointerOperand();