Skip to content

Commit

Permalink
[docs] Make it clear shifts yield poison when shift amount >= bitwidth
Browse files Browse the repository at this point in the history
Some InstCombine optimizations already rely on the result being poison
rather than undef.

For example, the following rewrite is wrong if undef is used:
; (1 << Y) * X  ->  X << Y
%Op0 = shl 1, %Y
%r = mul %Op0, %Op1
  =>
%r = shl %Op1, %Y

ERROR: Mismatch in values for i4 %r

Example:
i4 %Y = 0x8 (8, -8)
i4 %Op0 = 0x0 (0)
i4 %Op1 = 0x0 (0)
source: 0x0 (0)
target: 0x1 (1)

The optimization is correct if poison is returned instead:
http://rise4fun.com/Alive/ygX


Differential Revision: https://reviews.llvm.org/D33654

llvm-svn: 304780
  • Loading branch information
nunoplopes committed Jun 6, 2017
1 parent 56d87ef commit b2781fb
Showing 1 changed file with 15 additions and 18 deletions.
33 changes: 15 additions & 18 deletions llvm/docs/LangRef.rst
Expand Up @@ -6691,15 +6691,14 @@ Semantics:
The value produced is ``op1`` \* 2\ :sup:`op2` mod 2\ :sup:`n`,
where ``n`` is the width of the result. If ``op2`` is (statically or
dynamically) equal to or larger than the number of bits in
``op1``, the result is undefined. If the arguments are vectors, each
vector element of ``op1`` is shifted by the corresponding shift amount
in ``op2``.
``op1``, this instruction returns a :ref:`poison value <poisonvalues>`.
If the arguments are vectors, each vector element of ``op1`` is shifted
by the corresponding shift amount in ``op2``.

If the ``nuw`` keyword is present, then the shift produces a :ref:`poison
value <poisonvalues>` if it shifts out any non-zero bits. If the
``nsw`` keyword is present, then the shift produces a :ref:`poison
value <poisonvalues>` if it shifts out any bits that disagree with the
resultant sign bit.
If the ``nuw`` keyword is present, then the shift produces a poison
value if it shifts out any non-zero bits.
If the ``nsw`` keyword is present, then the shift produces a poison
value it shifts out any bits that disagree with the resultant sign bit.

Example:
""""""""
Expand Down Expand Up @@ -6742,13 +6741,12 @@ Semantics:
This instruction always performs a logical shift right operation. The
most significant bits of the result will be filled with zero bits after
the shift. If ``op2`` is (statically or dynamically) equal to or larger
than the number of bits in ``op1``, the result is undefined. If the
arguments are vectors, each vector element of ``op1`` is shifted by the
corresponding shift amount in ``op2``.
than the number of bits in ``op1``, this instruction returns a :ref:`poison
value <poisonvalues>`. If the arguments are vectors, each vector element
of ``op1`` is shifted by the corresponding shift amount in ``op2``.

If the ``exact`` keyword is present, the result value of the ``lshr`` is
a :ref:`poison value <poisonvalues>` if any of the bits shifted out are
non-zero.
a poison value if any of the bits shifted out are non-zero.

Example:
""""""""
Expand Down Expand Up @@ -6793,13 +6791,12 @@ Semantics:
This instruction always performs an arithmetic shift right operation,
The most significant bits of the result will be filled with the sign bit
of ``op1``. If ``op2`` is (statically or dynamically) equal to or larger
than the number of bits in ``op1``, the result is undefined. If the
arguments are vectors, each vector element of ``op1`` is shifted by the
corresponding shift amount in ``op2``.
than the number of bits in ``op1``, this instruction returns a :ref:`poison
value <poisonvalues>`. If the arguments are vectors, each vector element
of ``op1`` is shifted by the corresponding shift amount in ``op2``.

If the ``exact`` keyword is present, the result value of the ``ashr`` is
a :ref:`poison value <poisonvalues>` if any of the bits shifted out are
non-zero.
a poison value if any of the bits shifted out are non-zero.

Example:
""""""""
Expand Down

0 comments on commit b2781fb

Please sign in to comment.