[aarch64] PR target/94591: Don't generate invalid REV64 insns
authorAlex Coplan <alex.coplan@arm.com>
Tue, 19 May 2020 19:33:20 +0000 (20:33 +0100)
committerAlex Coplan <alex.coplan@arm.com>
Tue, 19 May 2020 19:43:57 +0000 (20:43 +0100)
This fixes PR94591. The problem was the function aarch64_evpc_rev_local()
matching vector permutations that were not reversals. In particular, prior to
this patch, this function matched the identity permutation which led to
generating bogus REV64 insns which were rejected by the assembler.

gcc/
PR target/94591
* config/aarch64/aarch64.c (aarch64_evpc_rev_local): Don't match
identity permutation.

gcc/testsuite/
PR target/94591
* gcc.c-torture/execute/pr94591.c: New test.

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr94591.c [new file with mode: 0644]

index 703b6349516dd5ee86f92ae78be14fa9084fc98f..9eee988e12cd4bf7e36afdb2bb6f132c43df2766 100644 (file)
@@ -1,3 +1,9 @@
+2020-05-19  Alex Coplan  <alex.coplan@arm.com>
+
+       PR target/94591
+       * config/aarch64/aarch64.c (aarch64_evpc_rev_local): Don't match
+       identity permutation.
+
 2020-05-19  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
        * doc/sourcebuild.texi: Document new short_eq_int, ptr_eq_short,
index 70aa2f752b543cde62041d2e2c1f7870f7f7b65b..79c016f4dc37c5cc02934dddee20db3a4fa9e8df 100644 (file)
@@ -20191,7 +20191,8 @@ aarch64_evpc_rev_local (struct expand_vec_perm_d *d)
 
   if (d->vec_flags == VEC_SVE_PRED
       || !d->one_vector_p
-      || !d->perm[0].is_constant (&diff))
+      || !d->perm[0].is_constant (&diff)
+      || !diff)
     return false;
 
   size = (diff + 1) * GET_MODE_UNIT_SIZE (d->vmode);
index 0e54d3916da6af61d2ac5e7993a406a24b11de1b..48671f1105a2baa3c8e03db7b2b1e38f159c445d 100644 (file)
@@ -1,3 +1,8 @@
+2020-05-19  Alex Coplan  <alex.coplan@arm.com>
+
+       PR target/94591
+       * gcc.c-torture/execute/pr94591.c: New test.
+
 2020-05-19  Nathan Sidwell  <nathan@acm.org>
 
        * c-c++-common/raw-string-14.c: Adjust errors.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94591.c b/gcc/testsuite/gcc.c-torture/execute/pr94591.c
new file mode 100644 (file)
index 0000000..42271ad
--- /dev/null
@@ -0,0 +1,32 @@
+typedef unsigned __attribute__((__vector_size__(8))) V2SI_u;
+typedef int __attribute__((__vector_size__(8))) V2SI_d;
+
+typedef unsigned long __attribute__((__vector_size__(16))) V2DI_u;
+typedef long __attribute__((__vector_size__(16))) V2DI_d;
+
+void id_V2SI(V2SI_d *v)
+{
+  *v = __builtin_shuffle(*v, (V2SI_d)(V2SI_u) { 0, 1 });
+}
+
+void id_V2DI(V2DI_d *v)
+{
+  *v = __builtin_shuffle(*v, (V2DI_d)(V2DI_u) { 0, 1 });
+}
+
+extern void abort(void);
+
+int main(void)
+{
+  V2SI_d si = { 35, 42 };
+  id_V2SI(&si);
+
+  if (si[0] != 35 || si[1] != 42)
+    abort();
+
+  V2DI_d di = { 63, 38 };
+  id_V2DI(&di);
+
+  if (di[0] != 63 || di[1] != 38)
+    abort();
+}