Hi,

This fixes a small inefficiency for riscv gather detection.  We have a
widening conversion like:

  _3 = *sp_i;         // unsigned char
  _4 = (sizetype) _3;
  _5 = asdf + _4;
  _6 = *_5;

Walking backwards from the gather, we first try if _4 is supported by
the target.  Since the "synthesis" changes last year it always is, as we
just extend the type ourselves without actual target support.
For riscv, in the example above, this pessimizes codegen a bit because
we would have supported _3 as offset directly but stopped looking
further because it looks like _4 is good already.

_4, i.e. sizetype works as well, but requires us to materialize an
offset vector of its type which will obviously be huge and requires a
larger LMUL (register group).

The patch basically adds a "would we support the unconverted smaller 
offset?" guard.

Bootstrapped and regtested on x86, power10, and aarch64.
Regtested on riscv64.

Regards
 Robin


gcc/ChangeLog:

        * tree-vect-data-refs.cc (vect_check_gather_scatter): Guard
        gather offset check.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/autovec/gather-scatter/gather-offset-1.c: New 
test.
---
 .../autovec/gather-scatter/gather-offset-1.c   | 14 ++++++++++++++
 gcc/tree-vect-data-refs.cc                     | 18 +++++++++++++++++-
 2 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather-offset-1.c

diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather-offset-1.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather-offset-1.c
new file mode 100644
index 00000000000..8abc6303441
--- /dev/null
+++ 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/gather-offset-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rva23u64 -mabi=lp64d -O3 -mrvv-max-lmul=m8 
--param=riscv-autovec-mode=RVVM1QI" } */
+
+void
+f (unsigned char *restrict dst, unsigned char *restrict idx,
+   unsigned char *restrict off, int n)
+{
+  for (int i = 0; i < n; i++)
+    dst[i] = off[idx[i]];
+}
+
+/* { dg-final { scan-assembler-not {vzext\.vf8} } } */
+/* { dg-final { scan-assembler-not {vluxei64\.v} } } */
+/* { dg-final { scan-assembler {vluxei8\.v} } } */
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 08b94149e7c..9ce979aeac7 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -4943,7 +4943,23 @@ vect_check_gather_scatter (stmt_vec_info stmt_info, tree 
vectype,
                                           &offset_vectype,
                                           &tmp_offset_vectype,
                                           elsvals))
-           break;
+           {
+             /* But if we're widening and the target also supports the
+                unconverted offset directly, use that.  */
+             bool supports_unwidened_directly_p
+               = TYPE_PRECISION (TREE_TYPE (op0))
+               < TYPE_PRECISION (TREE_TYPE (off))
+               && vect_gather_scatter_fn_p (loop_vinfo, DR_IS_READ (dr),
+                                            masked_p, vectype, memory_type,
+                                            TREE_TYPE (op0), scale, &tmp_scale,
+                                            &ifn, &offset_vectype,
+                                            &tmp_offset_vectype, elsvals)
+               && !tmp_scale
+               && !tmp_offset_vectype;
+
+             if (!supports_unwidened_directly_p)
+               break;
+           }
 
          if (TYPE_PRECISION (TREE_TYPE (op0))
              == TYPE_PRECISION (TREE_TYPE (off)))
-- 
2.56.0

Reply via email to