From: Kyrylo Tkachov <[email protected]>
aarch64_expand_vec_perm_const_1 normalizes a permutation whose first index
selects the second operand by rotating the indices and swapping op0 and op1.
It left zero_op0_p and zero_op1_p pointing at the old operands, so the later
recognizers that consult them, aarch64_evpc_and and aarch64_evpc_tbl, read
the wrong vector.
Swap the two flags together with the operands.
For
typedef int v4si __attribute__ ((vector_size (16)));
v4si f (v4si x)
{
const v4si m = { 4, 1, 2, 3 };
return __builtin_shuffle (x, (v4si) { 0, 0, 0, 0 }, m);
}
at -O0 the AND was applied to the all-zero operand, so the function returned
{0,0,0,0} instead of {0,x1,x2,x3}:
sub sp, sp, #32
str q0, [sp]
adrp x0, .LC0
add x0, x0, :lo12:.LC0
ldr q31, [x0]
str q31, [sp, 16]
movi v31.4s, 0
fmov s31, s31
mov v0.16b, v31.16b
add sp, sp, 32
ret
With the fix the AND is applied to the incoming vector:
sub sp, sp, #32
str q0, [sp]
adrp x0, .LC0
add x0, x0, :lo12:.LC0
ldr q31, [x0]
str q31, [sp, 16]
ldr q30, [sp]
adrp x0, .LC1
add x0, x0, :lo12:.LC1
ldr q31, [x0]
and v31.16b, v30.16b, v31.16b
mov v0.16b, v31.16b
add sp, sp, 32
ret
Bootstrapped and tested on aarch64-none-linux-gnu.
Pusing to trunk.
Thanks,
Kyrill
gcc/ChangeLog:
PR target/126597
* config/aarch64/aarch64.cc (aarch64_expand_vec_perm_const_1): Swap
zero_op0_p and zero_op1_p along with the operands.
gcc/testsuite/ChangeLog:
PR target/126597
* gcc.target/aarch64/pr126597.c: New test.
Signed-off-by: Kyrylo Tkachov <[email protected]>
---
gcc/config/aarch64/aarch64.cc | 1 +
gcc/testsuite/gcc.target/aarch64/pr126597.c | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/aarch64/pr126597.c
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 2e440ce916d..f36864a10da 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -28812,6 +28812,7 @@ aarch64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
{
d->perm.rotate_inputs (1);
std::swap (d->op0, d->op1);
+ std::swap (d->zero_op0_p, d->zero_op1_p);
}
if (((d->vec_flags == VEC_ADVSIMD && TARGET_SIMD)
diff --git a/gcc/testsuite/gcc.target/aarch64/pr126597.c b/gcc/testsuite/gcc.target/aarch64/pr126597.c
new file mode 100644
index 00000000000..922d673fa6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr126597.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+__attribute__((noipa)) v4si
+f (v4si x)
+{
+ const v4si mask = { 4, 1, 2, 3 };
+ return __builtin_shuffle (x, (v4si) { 0, 0, 0, 0 }, mask);
+}
+
+int
+main (void)
+{
+ v4si x = { 1, 2, 3, 4 };
+ v4si r = f (x);
+ if (r[0] != 0 || r[1] != 2 || r[2] != 3 || r[3] != 4)
+ __builtin_abort ();
+ return 0;
+}
--
2.50.1 (Apple Git-155)
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.