diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3452,7 +3452,36 @@ location could clobber arbitrary memory, therefore, it has undefined behavior. -**MemorySanitizer**, a detector of uses of uninitialized memory, +Execution of a conditional branch is undefined behavior if its condition is +a not-frozen expression containing undef and it can be evaluted into different +values. +This explains optimizations that depend on branch conditions to construct +predicates, such as Correlated Value Propagation and Global Value Numbering. +As it raises undefined behavior otherwise, we can assume that the branch +condition is frozen at destination blocks. + +.. code-block:: text + + Unsafe: + br undef, BB1, BB2 ; UB + + %X = and i32 undef, 255 + switch %X, label %ret [ .. ] ; UB + + store undef, i8* %ptr + %X = load i8* %ptr ; %X is undef + switch i8 %X, label %ret [ .. ] ; UB + + Safe: + %X = or i8 undef, 255 ; always 255 + switch i8 %X, label %ret [ .. ] ; Well-defined + + %X = freeze i1 undef + br %X, BB1, BB2 ; Well-defined (non-deterministic jump) + + +This is also consistent with the behavior of MemorySanitizer. +MemorySanitizer, detector of uses of uninitialized memory, defines a branch with condition that depends on an undef value (or certain other values, like e.g. a result of a load from heap-allocated memory that has never been stored to) to have an externally visible @@ -7035,7 +7064,8 @@ argument is evaluated. If the value is ``true``, control flows to the '``iftrue``' ``label`` argument. If "cond" is ``false``, control flows to the '``iffalse``' ``label`` argument. -If '``cond``' is ``poison``, this instruction has undefined behavior. +If '``cond``' is ``poison`` or ``undef``, this instruction has undefined +behavior. Example: """"""""