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