[LV][REVEC][AArch64] Proof of concept for re-vectorisation
This shows the changes required to enable basic re-vectorisation support in LoopVectorizer. Most of the diff comes from the added tests, the changes to LoopVectorizer files are rather minimal. This proof-of-concept has obvious limitations and only represents the first building block.
My hope is that this helps discussions and complements the RFC at https://discourse.llvm.org/t/rfc-re-vectorisation-to-wider-vectors-in-loopvectorizer/91071.
Support for re-vectorisation is hidden behind a -vectorize-vector-loops flag and LV will bail out if it encounters constructs that are not yet supported. For example:
- shufflevectors
- gather/scatter and interleaved accesses
- target intrinsics
- reductions
- if-conversion or tail folding
[IR] Define llvm.vector.broadcast intrinsic
This is used broadcast a smaller vector into a wider one. The patch adds
basic legalisation support and ISel for AArch64.
[AArch64] Use [SU]ADALP for partial (nx)v4i32 -> (nx)v2i64 add reduce. (#213915)
The previously used AArch64ISD::[SU]ADDW[BT] became unused after this
change, so I've removed them.
[OpenMP][OMPT] Error when registering EMI and non-EMI callbacks (#213697)
The OpenMP specification includes a restriction for registering both EMI
and non-EMI callbacks (e.g. `ompt_callback_target`, OpenMP v5.2, p. 503,
l. 18-20):
These callbacks must not be registered at the same time.
However, this was not respected in the runtime. A tool was able to
register both, receiving `ompt_set_always` for each `ompt_set_callback`
call. When an event associated with the EMI or non-EMI callbacks was
dispatched and both callbacks were registered, only the EMI version was
dispatched.
To align the runtime behavior with the OpenMP specification, return
`ompt_set_error` when a tool tries to register both the EMI and non-EMI
variant for a callback. With this, only the tool's first registration is
used.
[5 lines not shown]
[IVDescriptors] Implement MonotonicDescriptor
RFC link: https://discourse.llvm.org/t/rfc-loop-vectorization-of-compress-store-expand-load-patterns/86442
"Monotonic" variable is similar to induction variable, but its value is updated under some condition, e.g.:
```
int idx = 0;
for(int i = 0; i < n; ++i) {
// some uses of idx
if (cond)
++idx;
}
```
In this example, `i` is induction variable and `idx` is monotonic variable: it's updated only when cond == true. In LLVM IR, this looks like:
```
loop_header:
%monotonic_phi = [%start, %prehader], [ %chain_phi0, %latch]
step_bb:
[26 lines not shown]
[lldb][AArch64] Use unique_ptr instead of statics in RegisterTypeDetector
Fixes #214264.
I used static variables for the created types, on the assumption
that only one detector would be used and that the host's
features would not change.
That is true for an lldb-server on a real Linux/FreeBSD system.
It is not true when we use the detector with core files. In the
same LLDB session you might load several files that came from
systems with different features.
The result was that the first detection sets up the static variables
and future detections do not update them. So subsequent core
files can have incorrect types.
(and in future if types vary per-process, we could have the same
issue in lldb-server)
[31 lines not shown]
[flang][OpenMP] Gate the allocate clause at OpenMP 5.0 (#213980)
`allocate` is an OpenMP 5.0 clause, but 58 of the 62 directives that
allow it declare it as
bare `VersionedClause<OMPC_Allocate>`. The default in `DirectiveBase.td`
is `min = 1`:
```
class VersionedClause<Clause c, int min = 1, int max = 0x7FFFFFFF> : Versioned<min, max>
```
so those 58 accept the clause at every version. Only four are gated
today: `do`, `taskgroup`
and `parallel do` at 50, and `scope` at 52.
This is reachable in practice because flang defaults to OpenMP 3.1
(`newestFullySupported = 31`, `CompilerInvocation.cpp`). An invocation
with no
`-fopenmp-version=` lands in the ungated range, semantics accepts the
[81 lines not shown]