While the SVE2 NBSL instruction accepts MOVPRFX to add more flexibility
due to its tied operands, the destination of the movprfx cannot be also
a source operand. But the offending pattern in aarch64-sve2.md tries
to do exactly that for the "=?&w,w,w" alternative and gas warns for the
attached testcase.
This patch adjusts that alternative to avoid taking operand 0 as an input
in the NBSL again.
So for the testcase in the patch we now generate:
nor_z:
movprfx z0, z1
nbsl z0.d, z0.d, z2.d, z1.d
ret
instead of the previous:
nor_z:
movprfx z0, z1
nbsl z0.d, z0.d, z2.d, z0.d
ret
which generated a gas warning.
Bootstrapped and tested on aarch64-none-linux-gnu.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
gcc/
PR target/120999
* config/aarch64/aarch64-sve2.md (*aarch64_sve2_nor<mode>):
Adjust movprfx alternative.
gcc/testsuite/
PR target/120999
* gcc.target/aarch64/sve2/pr120999.c: New test.
"TARGET_SVE2"
{@ [ cons: =0 , %1 , 2 ; attrs: movprfx ]
[ w , 0 , w ; * ] nbsl\t%0.d, %0.d, %2.d, %0.d
- [ ?&w , w , w ; yes ] movprfx\t%0, %1\;nbsl\t%0.d, %0.d, %2.d, %0.d
+ [ ?&w , w , w ; yes ] movprfx\t%0, %1\;nbsl\t%0.d, %0.d, %2.d, %1.d
}
"&& !CONSTANT_P (operands[3])"
{
--- /dev/null
+/* PR target/120999. */
+/* { dg-do assemble } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <arm_sve.h>
+
+#define NOR(x, y) (~((x) | (y)))
+
+/*
+** nor_z:
+** movprfx z0, z1
+** nbsl z0.d, z0.d, z2.d, z1.d
+** ret
+*/
+svuint64_t nor_z(svuint64_t c, svuint64_t a, svuint64_t b) { return NOR(a, b); }
+