The function `vect_check_gather_scatter` requires the `base` of the load
to be loop-invariant and the `off`set to be not loop-invariant. When faced
with a scenario where `base` is not loop-invariant, instead of giving up
immediately we can try swapping the `base` and `off`, if `off` is
actually loop-invariant.
Previously, it would only swap if `off` was the constant zero (and so
trivially loop-invariant). This is too conservative: we can still
perform the swap if `off` is a more complex but still loop-invariant
expression, such as a variable defined outside of the loop.
This patch allows loops like the function below to be vectorised, if the
target has masked loads and sufficiently large vector registers (eg
`-march=armv8-a+sve -msve-vector-bits=128`):
```c
typedef struct Array {
int elems[3];
} Array;
int loop(Array **pp, int len, int idx) {
int nRet = 0;
for (int i = 0; i < len; i++) {
Array *p = pp[i];
if (p) {
nRet += p->elems[idx];
}
}
return nRet;
}
```
Changelog:
- v1: Initial patch
Karl Meakin (2):
AArch64: precommit test for masked load vectorisation.
middle-end: Enable masked load with non-constant offset
.../gcc.target/aarch64/sve/mask_load_2.c | 23 ++++++++++++++++
gcc/tree-vect-data-refs.cc | 26 ++++++++-----------
2 files changed, 34 insertions(+), 15 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/mask_load_2.c
--
2.45.2