1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[LangRef] Revise semantics of intrinsic get.active.lane.mask

A first version of get.active.lane.mask was committed in rG7fb8a40e5220. One of
the main purposes and uses of this intrinsic is to communicate information from
the middle-end to the back-end, but its current definition and semantics make
this actually very difficult. The intrinsic was defined as:

  @llvm.get.active.lane.mask(%IV, %BTC)

where %BTC is the Backedge-Taken Count (variable names are different in the
LangRef spec). This allows to implicitly communicate the loop tripcount, which
can be reconstructed by calculating BTC + 1. But it has been very difficult to
prove that calculating BTC + 1 is safe and doesn't overflow. We need
complicated range and SCEV analysis, and thus the problem is that this
intrinsic isn't really doing what it was supposed to solve. Examples of the
overflow checks that are required in the (ARM) back-end are D79175 and D86074,
which aren't even complete/correct yet.

To solve this problem, we are revising the definitions/semantics for
get.active.lane.mask to avoid all the complicated overflow analysis. This means
that instead of communicating the BTC, we are now using the loop tripcount. Now
using LangRef's variable names, its semantics is changed from:

  icmp ule (%base + i), %n

to:

  icmp ult (%base + i), %n

with %n > 0 and corresponding to the loop tripcount. The intrinsic signature
remains the same.

Differential Revision: https://reviews.llvm.org/D86147
This commit is contained in:
Sjoerd Meijer 2020-08-25 16:14:49 +01:00
parent 66453001f1
commit ac0a363b76

View File

@ -16930,27 +16930,28 @@ to:
::
%m[i] = icmp ule (%base + i), %n
%m[i] = icmp ult (%base + i), %n
where ``%m`` is a vector (mask) of active/inactive lanes with its elements
indexed by ``i``, and ``%base``, ``%n`` are the two arguments to
``llvm.get.active.lane.mask.*``, ``%imcp`` is an integer compare and ``ule``
the unsigned less-than-equal comparison operator. Overflow cannot occur in
``(%base + i)`` and its comparison against ``%n`` as it is performed in integer
numbers and not in machine numbers. The above is equivalent to:
``llvm.get.active.lane.mask.*``, ``%icmp`` is an integer compare and ``ult``
the unsigned less-than comparison operator. Overflow cannot occur in
``(%base + i)`` and its comparison against ``%n`` with ``%n > 0``, as it is
performed in integer numbers and not in machine numbers. The above is
equivalent to:
::
%m = @llvm.get.active.lane.mask(%base, %n)
This can, for example, be emitted by the loop vectorizer. Then, ``%base`` is
the first element of the vector induction variable (VIV), and ``%n`` is the
Back-edge Taken Count (BTC). Thus, these intrinsics perform an element-wise
less than or equal comparison of VIV with BTC, producing a mask of true/false
values representing active/inactive vector lanes, except if the VIV overflows
in which case they return false in the lanes where the VIV overflows. The
arguments are scalar types to accommodate scalable vector types, for which it is
unknown what the type of the step vector needs to be that enumerate its
This can, for example, be emitted by the loop vectorizer in which case
``%base`` is the first element of the vector induction variable (VIV) and
``%n`` is the loop tripcount. Thus, these intrinsics perform an element-wise
less than comparison of VIV with the loop tripcount, producing a mask of
true/false values representing active/inactive vector lanes, except if the VIV
overflows in which case they return false in the lanes where the VIV overflows.
The arguments are scalar types to accommodate scalable vector types, for which
it is unknown what the type of the step vector needs to be that enumerate its
lanes without overflow.
This mask ``%m`` can e.g. be used in masked load/store instructions. These