Add support for SVE scatter stores
commit0bf8b382dfe1e26de5b3a7f5b9493032d07b0eaa
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 13 Jan 2018 18:01:59 +0000 (13 18:01 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 13 Jan 2018 18:01:59 +0000 (13 18:01 +0000)
tree9ca0c22b0248297a39205d4c22b9d5d778dd4f4a
parent1d2c127d7cc46ae64197419e9272c543f7d229c4
Add support for SVE scatter stores

This is mostly a mechanical extension of the previous gather load
support to scatter stores.  The internal functions in this case are:

  IFN_SCATTER_STORE (base, offsets, scale, values)
  IFN_MASK_SCATTER_STORE (base, offsets, scale, values, mask)

However, one nonobvious change is to vect_analyze_data_ref_access.
If we're treating an access as a gather load or scatter store
(i.e. if STMT_VINFO_GATHER_SCATTER_P is true), the existing code
would create a dummy data_reference whose step is 0.  There's not
really much else it could do, since the whole point is that the
step isn't predictable from iteration to iteration.  We then
went into this code in vect_analyze_data_ref_access:

  /* Allow loads with zero step in inner-loop vectorization.  */
  if (loop_vinfo && integer_zerop (step))
    {
      GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = NULL;
      if (!nested_in_vect_loop_p (loop, stmt))
return DR_IS_READ (dr);

I.e. we'd take the step literally and assume that this is a load
or store to an invariant address.  Loads from invariant addresses
are supported but stores to them aren't.

The code therefore had the effect of disabling all scatter stores.
AFAICT this is true of AVX too: although tests like avx512f-scatter-1.c
test for the correctness of a scatter-like loop, they don't seem to
check whether a scatter instruction is actually used.

The patch therefore makes vect_analyze_data_ref_access return true
for scatters.  We do seem to handle the aliasing correctly;
that's tested by other functions, and is symmetrical to the
already-working gather case.

2018-01-13  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* doc/sourcebuild.texi (vect_scatter_store): Document.
* optabs.def (scatter_store_optab, mask_scatter_store_optab): New
optabs.
* doc/md.texi (scatter_store@var{m}, mask_scatter_store@var{m}):
Document.
* genopinit.c (main): Add supports_vec_scatter_store and
supports_vec_scatter_store_cached to target_optabs.
* gimple.h (gimple_expr_type): Handle IFN_SCATTER_STORE and
IFN_MASK_SCATTER_STORE.
* internal-fn.def (SCATTER_STORE, MASK_SCATTER_STORE): New internal
functions.
* internal-fn.h (internal_store_fn_p): Declare.
(internal_fn_stored_value_index): Likewise.
* internal-fn.c (scatter_store_direct): New macro.
(expand_scatter_store_optab_fn): New function.
(direct_scatter_store_optab_supported_p): New macro.
(internal_store_fn_p): New function.
(internal_gather_scatter_fn_p): Handle IFN_SCATTER_STORE and
IFN_MASK_SCATTER_STORE.
(internal_fn_mask_index): Likewise.
(internal_fn_stored_value_index): New function.
(internal_gather_scatter_fn_supported_p): Adjust operand numbers
for scatter stores.
* optabs-query.h (supports_vec_scatter_store_p): Declare.
* optabs-query.c (supports_vec_scatter_store_p): New function.
* tree-vectorizer.h (vect_get_store_rhs): Declare.
* tree-vect-data-refs.c (vect_analyze_data_ref_access): Return
true for scatter stores.
(vect_gather_scatter_fn_p): Handle scatter stores too.
(vect_check_gather_scatter): Consider using scatter stores if
supports_vec_scatter_store_p.
* tree-vect-patterns.c (vect_try_gather_scatter_pattern): Handle
scatter stores too.
* tree-vect-stmts.c (exist_non_indexing_operands_for_use_p): Use
internal_fn_stored_value_index.
(check_load_store_masking): Handle scatter stores too.
(vect_get_store_rhs): Make public.
(vectorizable_call): Use internal_store_fn_p.
(vectorizable_store): Handle scatter store internal functions.
(vect_transform_stmt): Compare GROUP_STORE_COUNT with GROUP_SIZE
when deciding whether the end of the group has been reached.
* config/aarch64/aarch64.md (UNSPEC_ST1_SCATTER): New unspec.
* config/aarch64/aarch64-sve.md (scatter_store<mode>): New expander.
(mask_scatter_store<mode>): New insns.

gcc/testsuite/
* lib/target-supports.exp (check_effective_target_vect_scatter_store):
New proc.
* gcc.dg/vect/pr25413a.c: Expect both loops to be optimized on
targets with scatter stores.
* gcc.dg/vect/vect-71.c: Restrict XFAIL to targets without scatter
stores.
* gcc.target/aarch64/sve/mask_scatter_store_1.c: New test.
* gcc.target/aarch64/sve/mask_scatter_store_2.c: Likewise.
* gcc.target/aarch64/sve/scatter_store_1.c: Likewise.
* gcc.target/aarch64/sve/scatter_store_2.c: Likewise.
* gcc.target/aarch64/sve/scatter_store_3.c: Likewise.
* gcc.target/aarch64/sve/scatter_store_4.c: Likewise.
* gcc.target/aarch64/sve/scatter_store_5.c: Likewise.
* gcc.target/aarch64/sve/scatter_store_6.c: Likewise.
* gcc.target/aarch64/sve/scatter_store_7.c: Likewise.
* gcc.target/aarch64/sve/strided_store_1.c: Likewise.
* gcc.target/aarch64/sve/strided_store_2.c: Likewise.
* gcc.target/aarch64/sve/strided_store_3.c: Likewise.
* gcc.target/aarch64/sve/strided_store_4.c: Likewise.
* gcc.target/aarch64/sve/strided_store_5.c: Likewise.
* gcc.target/aarch64/sve/strided_store_6.c: Likewise.
* gcc.target/aarch64/sve/strided_store_7.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@256643 138bc75d-0d04-0410-961f-82ee72b054a4
37 files changed:
gcc/ChangeLog
gcc/config/aarch64/aarch64-sve.md
gcc/config/aarch64/aarch64.md
gcc/doc/md.texi
gcc/doc/sourcebuild.texi
gcc/genopinit.c
gcc/gimple.h
gcc/internal-fn.c
gcc/internal-fn.def
gcc/internal-fn.h
gcc/optabs-query.c
gcc/optabs-query.h
gcc/optabs.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr25413a.c
gcc/testsuite/gcc.dg/vect/vect-71.c
gcc/testsuite/gcc.target/aarch64/sve/mask_scatter_store_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/mask_scatter_store_2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/scatter_store_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/scatter_store_2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/scatter_store_3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/scatter_store_4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/scatter_store_5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/scatter_store_6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/scatter_store_7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/strided_store_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/strided_store_2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/strided_store_3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/strided_store_4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/strided_store_5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/strided_store_6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/strided_store_7.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp
gcc/tree-vect-data-refs.c
gcc/tree-vect-patterns.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h