]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
vect: Check gather/scatter offset types [PR108316]
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 8 Feb 2023 13:40:29 +0000 (13:40 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 8 Feb 2023 13:40:29 +0000 (13:40 +0000)
The gather/scatter support can over-widen an offset if the target
requires it, but this relies on using a pattern sequence to add
the widening conversion.  That failed in the testcase because an
earlier pattern (bool) took priority.

I think we should allow patterns to be applied to other patterns,
but that's quite an invasive change and isn't suitable for stage 4.
This patch instead punts if the offset type doesn't match the
expected one.

If we switched to using the SLP representation for everything,
we would probably handle both patterns by rewriting the graph,
which should be much easier.

gcc/
PR tree-optimization/108316
* tree-vect-stmts.cc (get_load_store_type): When using
internal functions for gather/scatter, make sure that the type
of the offset argument is consistent with the offset vector type.

gcc/testsuite/
PR tree-optimization/108316
* gcc.dg/vect/pr108316.c: New test.

gcc/testsuite/gcc.dg/vect/pr108316.c [new file with mode: 0644]
gcc/tree-vect-stmts.cc

diff --git a/gcc/testsuite/gcc.dg/vect/pr108316.c b/gcc/testsuite/gcc.dg/vect/pr108316.c
new file mode 100644 (file)
index 0000000..540b7f2
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+extern _Bool a[];
+
+void
+foo (short i, int b[][64][1])
+{
+  for (; i < 64; i += 4)
+    a[i] = b[0][i] != 0;
+}
index eb4ca1f184e374d177eb43d5eb93acf6e6a8fde9..c86249adcc399a93ec31c4b296589aaba6386a5c 100644 (file)
@@ -2474,6 +2474,23 @@ get_load_store_type (vec_info  *vinfo, stmt_vec_info stmt_info,
       *memory_access_type = VMAT_GATHER_SCATTER;
       if (!vect_check_gather_scatter (stmt_info, loop_vinfo, gs_info))
        gcc_unreachable ();
+      /* When using internal functions, we rely on pattern recognition
+        to convert the type of the offset to the type that the target
+        requires, with the result being a call to an internal function.
+        If that failed for some reason (e.g. because another pattern
+        took priority), just handle cases in which the offset already
+        has the right type.  */
+      else if (gs_info->ifn != IFN_LAST
+              && !is_gimple_call (stmt_info->stmt)
+              && !tree_nop_conversion_p (TREE_TYPE (gs_info->offset),
+                                         TREE_TYPE (gs_info->offset_vectype)))
+       {
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                            "%s offset requires a conversion\n",
+                            vls_type == VLS_LOAD ? "gather" : "scatter");
+         return false;
+       }
       else if (!vect_is_simple_use (gs_info->offset, vinfo,
                                    &gs_info->offset_dt,
                                    &gs_info->offset_vectype))