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