]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
vect: Don't allow vect_emulated_vector_p type in vectorizable_call [PR106322]
authorKewen Lin <linkw@linux.ibm.com>
Tue, 16 Aug 2022 05:18:51 +0000 (00:18 -0500)
committerKewen Lin <linkw@linux.ibm.com>
Tue, 16 Aug 2022 05:19:38 +0000 (00:19 -0500)
As PR106322 shows, in some cases for some vector type whose
TYPE_MODE is a scalar integral mode instead of a vector mode,
it's possible to obtain wrong target support information when
querying with the scalar integral mode.  For example, for the
test case in PR106322, on ppc64 32bit vectorizer gets vector
type "vector(2) short unsigned int" for scalar type "short
unsigned int", its mode is SImode instead of V2HImode.  The
target support querying checks umul_highpart optab with SImode
and considers it's supported, then vectorizer further generates
.MULH IFN call for that vector type.  Unfortunately it's wrong
to use SImode support for that vector type multiply highpart
here.

This patch is to teach vectorizable_call analysis not to allow
vect_emulated_vector_p type for both vectype_in and vectype_out
as Richi suggested.

PR tree-optimization/106322

gcc/ChangeLog:

* tree-vect-stmts.cc (vectorizable_call): Don't allow
vect_emulated_vector_p type for both vectype_in and vectype_out.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr106322.c: New test.
* gcc.target/powerpc/pr106322.c: New test.

gcc/testsuite/gcc.target/i386/pr106322.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr106322.c [new file with mode: 0644]
gcc/tree-vect-stmts.cc

diff --git a/gcc/testsuite/gcc.target/i386/pr106322.c b/gcc/testsuite/gcc.target/i386/pr106322.c
new file mode 100644 (file)
index 0000000..31333c5
--- /dev/null
@@ -0,0 +1,51 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-O2 -mtune=generic -march=i686" } */
+
+/* As PR106322, verify this can execute well (not abort).  */
+
+#define N 64
+typedef unsigned short int uh;
+typedef unsigned short int uw;
+uh a[N];
+uh b[N];
+uh c[N];
+uh e[N];
+
+__attribute__ ((noipa)) void
+foo ()
+{
+  for (int i = 0; i < N; i++)
+    c[i] = ((uw) b[i] * (uw) a[i]) >> 16;
+}
+
+__attribute__ ((optimize ("-O0"))) void
+init ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      a[i] = (uh) (0x7ABC - 0x5 * i);
+      b[i] = (uh) (0xEAB + 0xF * i);
+      e[i] = ((uw) b[i] * (uw) a[i]) >> 16;
+    }
+}
+
+__attribute__ ((optimize ("-O0"))) void
+check ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      if (c[i] != e[i])
+       __builtin_abort ();
+    }
+}
+
+int
+main ()
+{
+  init ();
+  foo ();
+  check ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106322.c b/gcc/testsuite/gcc.target/powerpc/pr106322.c
new file mode 100644 (file)
index 0000000..c05072d
--- /dev/null
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mdejagnu-cpu=power4" } */
+
+/* As PR106322, verify this can execute well (not abort).  */
+
+#define N 64
+typedef unsigned short int uh;
+typedef unsigned short int uw;
+uh a[N];
+uh b[N];
+uh c[N];
+uh e[N];
+
+__attribute__ ((noipa)) void
+foo ()
+{
+  for (int i = 0; i < N; i++)
+    c[i] = ((uw) b[i] * (uw) a[i]) >> 16;
+}
+
+__attribute__ ((optimize ("-O0"))) void
+init ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      a[i] = (uh) (0x7ABC - 0x5 * i);
+      b[i] = (uh) (0xEAB + 0xF * i);
+      e[i] = ((uw) b[i] * (uw) a[i]) >> 16;
+    }
+}
+
+__attribute__ ((optimize ("-O0"))) void
+check ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      if (c[i] != e[i])
+       __builtin_abort ();
+    }
+}
+
+int
+main ()
+{
+  init ();
+  foo ();
+  check ();
+
+  return 0;
+}
index f582d238984fbd083650a45d87997f72b6cd3839..c9dab217f059f17e91e9a7582523e627d7a45b66 100644 (file)
@@ -3423,6 +3423,14 @@ vectorizable_call (vec_info *vinfo,
       return false;
     }
 
+  if (vect_emulated_vector_p (vectype_in) || vect_emulated_vector_p (vectype_out))
+  {
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                        "use emulated vector type for call\n");
+      return false;
+  }
+
   /* FORNOW */
   nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);