aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Coplan <alex.coplan@arm.com>2020-05-19 20:33:20 +0100
committerAlex Coplan <alex.coplan@arm.com>2020-05-19 20:43:57 +0100
commit98452668d362bb9e6358f7eb5cff69f4f5ab1d45 (patch)
tree597495ab1d146c96945da3edd2dc3a4d80d49ce6
parent25c284f14881eeb68b9ddf16c6760b9535d824a8 (diff)
downloadgcc-98452668d362bb9e6358f7eb5cff69f4f5ab1d45.zip
gcc-98452668d362bb9e6358f7eb5cff69f4f5ab1d45.tar.gz
gcc-98452668d362bb9e6358f7eb5cff69f4f5ab1d45.tar.bz2
[aarch64] PR target/94591: Don't generate invalid REV64 insns
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.
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/aarch64/aarch64.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr94591.c32
4 files changed, 45 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 703b634..9eee988 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 70aa2f7..79c016f 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0e54d39..48671f1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..42271ad
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr94591.c
@@ -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();
+}