diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3416,6 +3416,7 @@ To ensure all uses of a given register observe the same value (even if '``undef``'), the :ref:`freeze instruction ` can be used. +A value is frozen if its uses see the same value. .. code-block:: llvm @@ -3452,7 +3453,34 @@ location could clobber arbitrary memory, therefore, it has undefined behavior. -**MemorySanitizer**, a detector of uses of uninitialized memory, +Branching on an undefined value is undefined behavior. +This explains optimizations that depend on branch conditions to construct +predicates, such as Correlated Value Propagation and Global Value Numbering. +In case of switch instruction, the branch condition should be frozen, otherwise +it is undefined behavior. + +.. 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 +7063,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: """""""" @@ -7086,7 +7115,8 @@ for the given value. If the value is found, control flow is transferred to the corresponding destination; otherwise, control flow is transferred to the default destination. -If '``value``' is ``poison``, this instruction has undefined behavior. +If '``value``' is ``poison`` or ``undef``, this instruction has undefined +behavior. Implementation: """"""""""""""" @@ -7151,7 +7181,8 @@ possible destination blocks must be listed in the label list, otherwise this instruction has undefined behavior. This implies that jumps to labels defined in other functions have undefined behavior as well. -If '``address``' is ``poison``, this instruction has undefined behavior. +If '``address``' is ``poison`` or ``undef``, this instruction has undefined +behavior. Implementation: """""""""""""""