Hi, on 2024/5/30 00:10, Carl Love wrote: > This was patch 10 from the previous series. The patch was updated to > address feedback comments. > > Carl > --------------------------------------------------- > > rs6000, extend vec_xxpermdi built-in for __int128 args > > Add a new signed and unsigned overloaded instances for vec_xxpermdi > > __int128 vec_xxpermdi (__int128, __int128, const int); > __uint128 vec_xxpermdi (__uint128, __uint128, const int); > > Update the documentation to include a reference to the new built-in > instances. > > Add test cases for the new overloaded instances. > > gcc/ChangeLog: > * config/rs6000/rs6000-overload.def (vec_xxpermdi): Add new > overloaded built-in instances. > * doc/extend.texi: Add documentation for new overloaded built-in > instances. > > gcc/testsuite/ChangeLog:gcc/testsuite/ChangeLog: > * gcc.target/powerpc/vec_perm-runnable-i128.c: New test file. > --- > gcc/config/rs6000/rs6000-overload.def | 4 + > gcc/doc/extend.texi | 2 + > .../powerpc/vec_perm-runnable-i128.c | 229 ++++++++++++++++++ > 3 files changed, 235 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/powerpc/vec_perm-runnable-i128.c > > diff --git a/gcc/config/rs6000/rs6000-overload.def > b/gcc/config/rs6000/rs6000-overload.def > index a210c5ad10d..45000f161e4 100644 > --- a/gcc/config/rs6000/rs6000-overload.def > +++ b/gcc/config/rs6000/rs6000-overload.def > @@ -4932,6 +4932,10 @@ > XXPERMDI_4SF XXPERMDI_VF > vd __builtin_vsx_xxpermdi (vd, vd, const int); > XXPERMDI_2DF XXPERMDI_VD > + vsq __builtin_vsx_xxpermdi (vsq, vsq, const int); > + XXPERMDI_1TI XXPERMDI_1TI > + vuq __builtin_vsx_xxpermdi (vuq, vuq, const int); > + XXPERMDI_1TI XXPERMDI_1TUI
Nits: - Move them before "vf __builtin_vsx_xxpermdi (vf, vf, const int);" so they are close to instances for other integral types. - As the existing name convention, _{SQ,UQ} are better. vsq __builtin_vsx_xxpermdi (vsq, vsq, const int); XXPERMDI_1TI XXPERMDI_1SQ vuq __builtin_vsx_xxpermdi (vuq, vuq, const int); XXPERMDI_1TI XXPERMDI_1UQ > > [VEC_XXSLDWI, vec_xxsldwi, __builtin_vsx_xxsldwi] > vsc __builtin_vsx_xxsldwi (vsc, vsc, const int); > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > index 0756230b19e..edfef1bdab7 100644 > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -22555,6 +22555,8 @@ void vec_vsx_st (vector bool char, int, signed char > *); > vector double vec_xxpermdi (vector double, vector double, const int); > vector float vec_xxpermdi (vector float, vector float, const int); > vector long long vec_xxpermdi (vector long long, vector long long, const > int); > +vector __int128 vec_xxpermdi (vector __int128, vector __int128, const int); > +vector __int128 vec_xxpermdi (vector __uint128, vector __uint128, const int); Nit: These two lines break the long long and unsigned long long lines, can you move them one line upward? Also using the explicit "signed" and "unsigned" would be better than "__{u,}int128". > vector unsigned long long vec_xxpermdi (vector unsigned long long, > vector unsigned long long, const > int); > vector int vec_xxpermdi (vector int, vector int, const int); > diff --git a/gcc/testsuite/gcc.target/powerpc/vec_perm-runnable-i128.c > b/gcc/testsuite/gcc.target/powerpc/vec_perm-runnable-i128.c > new file mode 100644 > index 00000000000..2d5dce09404 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/vec_perm-runnable-i128.c > @@ -0,0 +1,229 @@ > +/* { dg-do run } */ > +/* { dg-require-effective-target vmx_hw } */ > +/* { dg-options "-save-temps" } */ Nit: dg-options line isn't needed as it doesn't check assembly. BR, Kewen > + > +#include <altivec.h> > + > +#define DEBUG 0 > + > +#if DEBUG > +#include <stdio.h> > +void print_i128 (unsigned __int128 val) > +{ > + printf(" 0x%016llx%016llx", > + (unsigned long long)(val >> 64), > + (unsigned long long)(val & 0xFFFFFFFFFFFFFFFF)); > +} > +#endif > + > +extern void abort (void); > + > +union convert_union { > + vector signed __int128 s128; > + vector unsigned __int128 u128; > + char val[16]; > +} convert; > + > +int check_u128_result(vector unsigned __int128 vresult_u128, > + vector unsigned __int128 expected_vresult_u128) > +{ > + /* Use a for loop to check each byte manually so the test case will > + run with ISA 2.06. > + > + Return 1 if they match, 0 otherwise. */ > + > + int i; > + > + union convert_union result; > + union convert_union expected; > + > + result.u128 = vresult_u128; > + expected.u128 = expected_vresult_u128; > + > + /* Check if each byte of the result and expected match. */ > + for (i = 0; i < 16; i++) > + { > + if (result.val[i] != expected.val[i]) > + return 0; > + } > + return 1; > +} > + > +int check_s128_result(vector signed __int128 vresult_s128, > + vector signed __int128 expected_vresult_s128) > +{ > + /* Convert the arguments to unsigned, then check equality. */ > + union convert_union result; > + union convert_union expected; > + > + result.s128 = vresult_s128; > + expected.s128 = expected_vresult_s128; > + > + return check_u128_result (result.u128, expected.u128); > +} > + > + > +int > +main (int argc, char *argv []) > +{ > + int i; > + > + vector signed __int128 src_va_s128; > + vector signed __int128 src_vb_s128; > + vector signed __int128 vresult_s128; > + vector signed __int128 expected_vresult_s128; > + > + vector unsigned __int128 src_va_u128; > + vector unsigned __int128 src_vb_u128; > + vector unsigned __int128 src_vc_u128; > + vector unsigned __int128 vresult_u128; > + vector unsigned __int128 expected_vresult_u128; > + > + src_va_s128 = (vector signed __int128) {0x123456789ABCDEF0}; > + src_va_s128 = src_va_s128 << 64; > + src_va_s128 |= (vector signed __int128) {0x22446688AACCEE00}; > + src_vb_s128 = (vector signed __int128) {0xFEDCBA9876543210}; > + src_vb_s128 = src_vb_s128 << 64; > + src_vb_s128 |= (vector signed __int128) {0x3333333333333333}; > + > + src_va_u128 = (vector unsigned __int128) {0x13579ACE02468BDF}; > + src_va_u128 = src_va_u128 << 64; > + src_va_u128 |= (vector unsigned __int128) {0x1133557799BBDD00}; > + src_vb_u128 = (vector unsigned __int128) {0xA987654FEDCB3210}; > + src_vb_u128 = src_vb_u128 << 64; > + src_vb_u128 |= (vector unsigned __int128) {0x5555555555555555}; > + > + > + /* Signed 128-bit arguments. */ > + vresult_s128 = vec_xxpermdi (src_va_s128, src_vb_s128, 0x1); > + > +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ > + /* BE expected results */ > + expected_vresult_s128 = (vector signed __int128) {0x123456789ABCDEF0}; > + expected_vresult_s128 = expected_vresult_s128 << 64; > + expected_vresult_s128 |= (vector signed __int128) {0x3333333333333333}; > +#else > + /* LE expected results */ > + expected_vresult_s128 = (vector signed __int128) {0xFEDCBA9876543210}; > + expected_vresult_s128 = expected_vresult_s128 << 64; > + expected_vresult_s128 |= (vector signed __int128) {0x22446688AACCEE00}; > +#endif > + > + if (!check_s128_result (vresult_s128, expected_vresult_s128)) > +#if DEBUG > + { > + printf ("ERROR, vec_xxpermdi (src_va_s128, src_vb_s128, 0x1) result > does not match expected output.\n"); > + printf (" src_va_s128: "); > + print_i128 ((unsigned __int128) src_va_s128); > + printf ("\n src_vb_s128: "); > + print_i128 ((unsigned __int128) src_vb_s128); > + printf ("\n Result: "); > + print_i128 ((unsigned __int128) vresult_s128); > + printf ("\n Expected result: "); > + print_i128 ((unsigned __int128) expected_vresult_s128); > + printf ("\n"); > + } > +#else > + abort (); > +#endif > + > + vresult_s128 = vec_xxpermdi (src_va_s128, src_vb_s128, 0x2); > + > +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ > + /* BE expected results */ > + expected_vresult_s128 = (vector signed __int128) {0x22446688AACCEE00}; > + expected_vresult_s128 = expected_vresult_s128 << 64; > + expected_vresult_s128 |= (vector signed __int128) {0xFEDCBA9876543210}; > +#else > + /* LE expected results */ > + expected_vresult_s128 = (vector signed __int128) {0x3333333333333333}; > + expected_vresult_s128 = expected_vresult_s128 << 64; > + expected_vresult_s128 |= (vector signed __int128) {0x123456789ABCDEF0}; > +#endif > + > + if (!check_s128_result (vresult_s128, expected_vresult_s128)) > +#if DEBUG > + { > + printf ("ERROR, vec_xxpermdi (src_va_s128, src_vb_s128, 0x2) result > does not match expected output.\n"); > + printf (" src_va_s128: "); > + print_i128 ((unsigned __int128) src_va_s128); > + printf ("\n src_vb_s128: "); > + print_i128 ((unsigned __int128) src_vb_s128); > + printf ("\n Result: "); > + print_i128 ((unsigned __int128) vresult_s128); > + printf ("\n Expected result: "); > + print_i128 ((unsigned __int128) expected_vresult_s128); > + printf ("\n"); > + } > +#else > + abort (); > +#endif > + > + /* Unigned arguments. */ > + vresult_u128 = vec_xxpermdi (src_va_u128, src_vb_u128, 0x1); > + > + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ > + /* BE expected results */ > + expected_vresult_u128 = (vector unsigned __int128) {0x13579ACE02468BDF}; > + expected_vresult_u128 = expected_vresult_u128 << 64; > + expected_vresult_u128 |= (vector unsigned __int128) {0x5555555555555555}; > +#else > + /* LE expected results */ > + expected_vresult_u128 = (vector unsigned __int128) {0xA987654FEDCB3210}; > + expected_vresult_u128 = expected_vresult_u128 << 64; > + expected_vresult_u128 |= (vector unsigned __int128) {0x1133557799BBDD00}; > +#endif > + > + if (!check_u128_result (vresult_u128, expected_vresult_u128)) > +#if DEBUG > + { > + printf ("ERROR, vec_xxpermdi (src_va_u128, src_vb_u128, 0x1) result > does not match expected output.\n"); > + printf (" src_va_s128: "); > + print_i128 ((unsigned __int128) src_va_s128); > + printf ("\n src_vb_s128: "); > + print_i128 ((unsigned __int128) src_vb_s128); > + printf ("\n Result: "); > + print_i128 ((unsigned __int128) vresult_u128); > + printf ("\n Expected result: "); > + print_i128 ((unsigned __int128) expected_vresult_u128); > + printf ("\n"); > + } > +#else > + abort (); > +#endif > + > + /* Unigned arguments. */ > + vresult_u128 = vec_xxpermdi (src_va_u128, src_vb_u128, 0x2); > + > +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ > + /* BE expected results */ > + expected_vresult_u128 = (vector unsigned __int128) {0x1133557799BBDD00}; > + expected_vresult_u128 = expected_vresult_u128 << 64; > + expected_vresult_u128 |= (vector unsigned __int128) {0xA987654FEDCB3210}; > +#else > + /* LE expected results */ > + expected_vresult_u128 = (vector unsigned __int128) {0x5555555555555555}; > + expected_vresult_u128 = expected_vresult_u128 << 64; > + expected_vresult_u128 |= (vector unsigned __int128) {0x13579ACE02468BDF}; > +#endif > + > + if (!check_u128_result (vresult_u128, expected_vresult_u128)) > +#if DEBUG > + { > + printf ("ERROR, vec_xxpermdi (src_va_u128, src_vb_u128, 0x2) result > does not match expected output.\n"); > + printf (" src_va_s128: "); > + print_i128 ((unsigned __int128) src_va_s128); > + printf ("\n src_vb_s128: "); > + print_i128 ((unsigned __int128) src_vb_s128); > + printf ("\n Result: "); > + print_i128 ((unsigned __int128) vresult_u128); > + printf ("\n Expected result: "); > + print_i128 ((unsigned __int128) expected_vresult_u128); > + printf ("\n"); > + } > +#else > + abort (); > +#endif > + > + return 0; > +}