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

Reply via email to