Hi,

In this PR we have a reduction of a vector constructor, where the
type of the constructor is int16x8_t and the elements are int16x4_t;
i.e. it is representing a concatenation of two vectors.

This triggers a match.pd pattern which looks like it was written to
handle reductions of vector constructors where the elements of the ctor
are scalars, not vectors.  There is no type check to enforce this
property, which leads to the pattern replacing a reduction to scalar
with an int16x4_t vector in this case, which of course is a type error,
leading to an invalid GIMPLE ICE.

This patch adds a type check to the pattern, only going ahead with the
transformation if the element type of the ctor matches that of the
reduction.

Bootstrapped/regtested on aarch64-linux-gnu and x86_64-linux-gnu.

OK for trunk?  What about backports?  The offending match.pd pattern was
introduced in r12-7326-g2ef0e75d0bbc80 but the ICE can only be
reproduced with the given testcase starting with
r13-1836-g8a1e05b7618fed (when we started lowering vcombine to GIMPLE in
the aarch64 backend).  Not sure how easy it would be to construct a
generic testcase since AFAIK we don't expose a general vector concat
operation on GCC vectors.  So I suppose we can either backport to 13 and
stop there or backport to 12 without a testcase (assuming a suitable one
can't be crafted).

Thanks,
Alex

gcc/ChangeLog:

        PR tree-optimization/121772
        * match.pd: Add type check to reduc(ctor) pattern.

gcc/testsuite/ChangeLog:

        PR tree-optimization/121772
        * gcc.target/aarch64/torture/pr121772.c: New test.
diff --git a/gcc/match.pd b/gcc/match.pd
index b1d7a3a1b73..295c6033cfd 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -11050,6 +11050,7 @@ and,
                         ? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)) : @0);
            tree elt = ctor_single_nonzero_element (ctor); }
       (if (elt
+          && types_match (type, TREE_TYPE (elt))
           && !HONOR_SNANS (type)
           && !HONOR_SIGNED_ZEROS (type))
        { elt; }))))
diff --git a/gcc/testsuite/gcc.target/aarch64/torture/pr121772.c 
b/gcc/testsuite/gcc.target/aarch64/torture/pr121772.c
new file mode 100644
index 00000000000..3b4cf4d7d18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/torture/pr121772.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+#include <arm_neon.h>
+int16_t f(int16x4_t b) {
+  return vaddvq_s16(vcombine_s16(b, vdup_n_s16 (0)));
+}

Reply via email to