From: Artemiy Volkov Date: Wed, 31 Dec 2025 11:30:05 +0000 (+0000) Subject: aarch64: add zeroing forms for predicated SVE integer extends X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=be498c1e13560ef029df20ee96471ec66eaad000;p=thirdparty%2Fgcc.git aarch64: add zeroing forms for predicated SVE integer extends SVE2.2 (or in streaming mode, SME2.2) adds support for zeroing predication for the following SVE integer extension instructions: - SXTB, SXTH, SXTW (Signed byte / halfword / word extend (predicated)) - UXTB, UXTH, UXTW (Unsigned byte / halfword / word extend (predicated)) The functional change is limited to two patterns in aarch64-sve.md handling SVE extends merging with an independent value, to which this patch adds a new alternative that emits a single zeroing-predication form of an instruction as long as the sve2p2_or_sme2p2 condition holds. The tests that have been added are based on the original SVE tests for corresponding instructions, but all have a "_z" suffix in their name since they only test codegen for the "_z" variants of the corresponding intrinsics. gcc/ChangeLog: * config/aarch64/aarch64-sve.md (@aarch64_cond_sxt): New alternative for zeroing predication. Add `arch` attribute to every alternative. (*cond_uxt_any): Likewise. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sve2/acle/asm/extb_s16_z.c: New test. * gcc.target/aarch64/sve2/acle/asm/extb_s32_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/extb_s64_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/extb_u16_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/extb_u32_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/extb_u64_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/exth_s32_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/exth_s64_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/exth_u32_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/exth_u64_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/extw_s64_z.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/extw_u64_z.c: Likewise. --- diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 411988d33d9..1bc0e7136cb 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -3711,10 +3711,11 @@ UNSPEC_SEL))] "TARGET_SVE && (~ & ) == 0" - {@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx ] - [ w , Upl , w , 0 ; * ] sxt\t%0., %1/m, %2. - [ ?&w , Upl , w , Dz ; yes ] movprfx\t%0., %1/z, %2.\;sxt\t%0., %1/m, %2. - [ ?&w , Upl , w , w ; yes ] movprfx\t%0, %3\;sxt\t%0., %1/m, %2. + {@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx, arch ] + [ w , Upl , w , 0 ; * , * ] sxt\t%0., %1/m, %2. + [ w , Upl , w , Dz ; * , sve2p2_or_sme2p2 ] sxt\t%0., %1/z, %2. + [ ?&w , Upl , w , Dz ; yes , * ] movprfx\t%0., %1/z, %2.\;sxt\t%0., %1/m, %2. + [ ?&w , Upl , w , w ; yes , * ] movprfx\t%0, %3\;sxt\t%0., %1/m, %2. } [(set_attr "sve_type" "sve_int_extend")] ) @@ -3759,10 +3760,11 @@ (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero")] UNSPEC_SEL))] "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])" - {@ [ cons: =0 , 1 , 2 , 4 ; attrs: movprfx ] - [ &w , Upl , w , 0 ; * ] uxt%e3\t%0., %1/m, %2. - [ ?&w , Upl , w , Dz ; yes ] movprfx\t%0., %1/z, %2.\;uxt%e3\t%0., %1/m, %2. - [ ?&w , Upl , w , w ; yes ] movprfx\t%0, %4\;uxt%e3\t%0., %1/m, %2. + {@ [ cons: =0 , 1 , 2 , 4 ; attrs: movprfx, arch ] + [ &w , Upl , w , 0 ; * , * ] uxt%e3\t%0., %1/m, %2. + [ &w , Upl , w , Dz ; * , sve2p2_or_sme2p2 ] uxt%e3\t%0., %1/z, %2. + [ ?&w , Upl , w , Dz ; yes , * ] movprfx\t%0., %1/z, %2.\;uxt%e3\t%0., %1/m, %2. + [ ?&w , Upl , w , w ; yes , * ] movprfx\t%0, %4\;uxt%e3\t%0., %1/m, %2. } [(set_attr "sve_type" "sve_int_extend")] ) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s16_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s16_z.c new file mode 100644 index 00000000000..1f73aaa8882 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s16_z.c @@ -0,0 +1,28 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** extb_s16_z_tied1: +** sxtb z0\.h, p0/z, z0\.h +** ret +*/ +TEST_UNIFORM_Z (extb_s16_z_tied1, svint16_t, + z0 = svextb_s16_z (p0, z0), + z0 = svextb_z (p0, z0)) + +/* +** extb_s16_z_untied: +** sxtb z0\.h, p0/z, z1\.h +** ret +*/ +TEST_UNIFORM_Z (extb_s16_z_untied, svint16_t, + z0 = svextb_s16_z (p0, z1), + z0 = svextb_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s32_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s32_z.c new file mode 100644 index 00000000000..06bc7773749 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s32_z.c @@ -0,0 +1,28 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** extb_s32_z_tied1: +** sxtb z0\.s, p0/z, z0\.s +** ret +*/ +TEST_UNIFORM_Z (extb_s32_z_tied1, svint32_t, + z0 = svextb_s32_z (p0, z0), + z0 = svextb_z (p0, z0)) + +/* +** extb_s32_z_untied: +** sxtb z0\.s, p0/z, z1\.s +** ret +*/ +TEST_UNIFORM_Z (extb_s32_z_untied, svint32_t, + z0 = svextb_s32_z (p0, z1), + z0 = svextb_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s64_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s64_z.c new file mode 100644 index 00000000000..bf0157b963f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_s64_z.c @@ -0,0 +1,28 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** extb_s64_z_tied1: +** sxtb z0\.d, p0/z, z0\.d +** ret +*/ +TEST_UNIFORM_Z (extb_s64_z_tied1, svint64_t, + z0 = svextb_s64_z (p0, z0), + z0 = svextb_z (p0, z0)) + +/* +** extb_s64_z_untied: +** sxtb z0\.d, p0/z, z1\.d +** ret +*/ +TEST_UNIFORM_Z (extb_s64_z_untied, svint64_t, + z0 = svextb_s64_z (p0, z1), + z0 = svextb_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u16_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u16_z.c new file mode 100644 index 00000000000..21030a77563 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u16_z.c @@ -0,0 +1,29 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** extb_u16_z_tied1: +** mov (z[0-9]+)\.d, z0\.d +** uxtb z0\.h, p0/z, \1\.h +** ret +*/ +TEST_UNIFORM_Z (extb_u16_z_tied1, svuint16_t, + z0 = svextb_u16_z (p0, z0), + z0 = svextb_z (p0, z0)) + +/* +** extb_u16_z_untied: +** uxtb z0\.h, p0/z, z1\.h +** ret +*/ +TEST_UNIFORM_Z (extb_u16_z_untied, svuint16_t, + z0 = svextb_u16_z (p0, z1), + z0 = svextb_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u32_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u32_z.c new file mode 100644 index 00000000000..5dd8d9f55b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u32_z.c @@ -0,0 +1,29 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** extb_u32_z_tied1: +** mov (z[0-9]+)\.d, z0\.d +** uxtb z0\.s, p0/z, \1\.s +** ret +*/ +TEST_UNIFORM_Z (extb_u32_z_tied1, svuint32_t, + z0 = svextb_u32_z (p0, z0), + z0 = svextb_z (p0, z0)) + +/* +** extb_u32_z_untied: +** uxtb z0\.s, p0/z, z1\.s +** ret +*/ +TEST_UNIFORM_Z (extb_u32_z_untied, svuint32_t, + z0 = svextb_u32_z (p0, z1), + z0 = svextb_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u64_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u64_z.c new file mode 100644 index 00000000000..c10daa83352 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extb_u64_z.c @@ -0,0 +1,29 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** extb_u64_z_tied1: +** mov (z[0-9]+\.d), z0\.d +** uxtb z0\.d, p0/z, \1 +** ret +*/ +TEST_UNIFORM_Z (extb_u64_z_tied1, svuint64_t, + z0 = svextb_u64_z (p0, z0), + z0 = svextb_z (p0, z0)) + +/* +** extb_u64_z_untied: +** uxtb z0\.d, p0/z, z1\.d +** ret +*/ +TEST_UNIFORM_Z (extb_u64_z_untied, svuint64_t, + z0 = svextb_u64_z (p0, z1), + z0 = svextb_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_s32_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_s32_z.c new file mode 100644 index 00000000000..430964034c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_s32_z.c @@ -0,0 +1,28 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** exth_s32_z_tied1: +** sxth z0\.s, p0/z, z0\.s +** ret +*/ +TEST_UNIFORM_Z (exth_s32_z_tied1, svint32_t, + z0 = svexth_s32_z (p0, z0), + z0 = svexth_z (p0, z0)) + +/* +** exth_s32_z_untied: +** sxth z0\.s, p0/z, z1\.s +** ret +*/ +TEST_UNIFORM_Z (exth_s32_z_untied, svint32_t, + z0 = svexth_s32_z (p0, z1), + z0 = svexth_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_s64_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_s64_z.c new file mode 100644 index 00000000000..16d3c735259 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_s64_z.c @@ -0,0 +1,28 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** exth_s64_z_tied1: +** sxth z0\.d, p0/z, z0\.d +** ret +*/ +TEST_UNIFORM_Z (exth_s64_z_tied1, svint64_t, + z0 = svexth_s64_z (p0, z0), + z0 = svexth_z (p0, z0)) + +/* +** exth_s64_z_untied: +** sxth z0\.d, p0/z, z1\.d +** ret +*/ +TEST_UNIFORM_Z (exth_s64_z_untied, svint64_t, + z0 = svexth_s64_z (p0, z1), + z0 = svexth_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_u32_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_u32_z.c new file mode 100644 index 00000000000..46b4894dffd --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_u32_z.c @@ -0,0 +1,29 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** exth_u32_z_tied1: +** mov (z[0-9]+)\.d, z0\.d +** uxth z0\.s, p0/z, \1\.s +** ret +*/ +TEST_UNIFORM_Z (exth_u32_z_tied1, svuint32_t, + z0 = svexth_u32_z (p0, z0), + z0 = svexth_z (p0, z0)) + +/* +** exth_u32_z_untied: +** uxth z0\.s, p0/z, z1\.s +** ret +*/ +TEST_UNIFORM_Z (exth_u32_z_untied, svuint32_t, + z0 = svexth_u32_z (p0, z1), + z0 = svexth_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_u64_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_u64_z.c new file mode 100644 index 00000000000..35fc5f64304 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/exth_u64_z.c @@ -0,0 +1,29 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** exth_u64_z_tied1: +** mov (z[0-9]+\.d), z0\.d +** uxth z0\.d, p0/z, \1 +** ret +*/ +TEST_UNIFORM_Z (exth_u64_z_tied1, svuint64_t, + z0 = svexth_u64_z (p0, z0), + z0 = svexth_z (p0, z0)) + +/* +** exth_u64_z_untied: +** uxth z0\.d, p0/z, z1\.d +** ret +*/ +TEST_UNIFORM_Z (exth_u64_z_untied, svuint64_t, + z0 = svexth_u64_z (p0, z1), + z0 = svexth_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extw_s64_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extw_s64_z.c new file mode 100644 index 00000000000..5757ab1edb3 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extw_s64_z.c @@ -0,0 +1,28 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** extw_s64_z_tied1: +** sxtw z0\.d, p0/z, z0\.d +** ret +*/ +TEST_UNIFORM_Z (extw_s64_z_tied1, svint64_t, + z0 = svextw_s64_z (p0, z0), + z0 = svextw_z (p0, z0)) + +/* +** extw_s64_z_untied: +** sxtw z0\.d, p0/z, z1\.d +** ret +*/ +TEST_UNIFORM_Z (extw_s64_z_untied, svint64_t, + z0 = svextw_s64_z (p0, z1), + z0 = svextw_z (p0, z1)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extw_u64_z.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extw_u64_z.c new file mode 100644 index 00000000000..626df5edef0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/extw_u64_z.c @@ -0,0 +1,29 @@ +/* { dg-do assemble { target aarch64_asm_sve2p2_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p2_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#include "test_sve_acle.h" + +#pragma GCC target "+sve2p2" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p2" +#endif + +/* +** extw_u64_z_tied1: +** mov (z[0-9]+\.d), z0\.d +** uxtw z0\.d, p0/z, \1 +** ret +*/ +TEST_UNIFORM_Z (extw_u64_z_tied1, svuint64_t, + z0 = svextw_u64_z (p0, z0), + z0 = svextw_z (p0, z0)) + +/* +** extw_u64_z_untied: +** uxtw z0\.d, p0/z, z1\.d +** ret +*/ +TEST_UNIFORM_Z (extw_u64_z_untied, svuint64_t, + z0 = svextw_u64_z (p0, z1), + z0 = svextw_z (p0, z1))