1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[docs] Make it clear shifts yield poison when shift amount >= bitwidth

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
This commit is contained in:
Nuno Lopes 2017-06-06 08:28:17 +00:00
parent 9d4d8b5728
commit 77b6a5876a

View File

@ -6691,15 +6691,14 @@ Semantics:
The value produced is ``op1`` \* 2\ :sup:`op2` mod 2\ :sup:`n`, 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 where ``n`` is the width of the result. If ``op2`` is (statically or
dynamically) equal to or larger than the number of bits in dynamically) equal to or larger than the number of bits in
``op1``, the result is undefined. If the arguments are vectors, each ``op1``, this instruction returns a :ref:`poison value <poisonvalues>`.
vector element of ``op1`` is shifted by the corresponding shift amount If the arguments are vectors, each vector element of ``op1`` is shifted
in ``op2``. by the corresponding shift amount in ``op2``.
If the ``nuw`` keyword is present, then the shift produces a :ref:`poison If the ``nuw`` keyword is present, then the shift produces a poison
value <poisonvalues>` if it shifts out any non-zero bits. If the value if it shifts out any non-zero bits.
``nsw`` keyword is present, then the shift produces a :ref:`poison If the ``nsw`` keyword is present, then the shift produces a poison
value <poisonvalues>` if it shifts out any bits that disagree with the value it shifts out any bits that disagree with the resultant sign bit.
resultant sign bit.
Example: Example:
"""""""" """"""""
@ -6742,13 +6741,12 @@ Semantics:
This instruction always performs a logical shift right operation. The This instruction always performs a logical shift right operation. The
most significant bits of the result will be filled with zero bits after 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 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 than the number of bits in ``op1``, this instruction returns a :ref:`poison
arguments are vectors, each vector element of ``op1`` is shifted by the value <poisonvalues>`. If the arguments are vectors, each vector element
corresponding shift amount in ``op2``. of ``op1`` is shifted by the corresponding shift amount in ``op2``.
If the ``exact`` keyword is present, the result value of the ``lshr`` is 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 a poison value if any of the bits shifted out are non-zero.
non-zero.
Example: Example:
"""""""" """"""""
@ -6793,13 +6791,12 @@ Semantics:
This instruction always performs an arithmetic shift right operation, This instruction always performs an arithmetic shift right operation,
The most significant bits of the result will be filled with the sign bit 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 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 than the number of bits in ``op1``, this instruction returns a :ref:`poison
arguments are vectors, each vector element of ``op1`` is shifted by the value <poisonvalues>`. If the arguments are vectors, each vector element
corresponding shift amount in ``op2``. of ``op1`` is shifted by the corresponding shift amount in ``op2``.
If the ``exact`` keyword is present, the result value of the ``ashr`` is 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 a poison value if any of the bits shifted out are non-zero.
non-zero.
Example: Example:
"""""""" """"""""