The patch at [1] changes these builtins to accept unsigned vector arguments to be consistent with other LSX/LASX bitwise builtins, but there's some concern about the backward compatibility. Make use of the existing built-in function overloading mechanism to provide the backward compatibility.
Depends on [1]. [1]:https://gcc.gnu.org/pipermail/gcc-patches/2024-October/667065.html gcc/ChangeLog: * config/loongarch/loongarch-protos.h (loongarch_register_pragmas): New function prototype. (loongarch_resolve_overloaded_builtin_decl): Likewise. * config/loongarch/loongarch-builtins.cc (__builtin_lsx_vorn_v_signed): New built-in function intended for internal use. (__builtin_lasx_xvorn_v_signed): Likewise. (loongarch_resolve_overloaded_builtin_decl): Implement, return the decl of __builtin_lsx_vorn_v_signed or __builtin_lasx_xvorn_v_signed or __builtin_lsx_vorn_v or __builtin_lasx_xvorn_v calls with signed operands. * config/loongarch/loongarch-c.cc (loongarch_register_pragmas): Implement, register the target hook loongarch_resolve_overloaded_builtin for C-family frontends. (loongarch_resolve_overloaded_builtin): New static function, implementing targetm.resolve_overloaded_builtin. * config/loongarch/loongarch.h (REGISTER_TARGET_PRAGMAS): Define as loongarch_register_pragmas. gcc/testsuite/ChangeLog: * gcc.target/loongarch/vorn-signed-backward.c: New test. * g++.target/loongarch/vorn-signed-backward.C: New test. --- Bootstrap and regtest are on-going, will update the status once them finish. Posted early following up the review on [1]. gcc/config/loongarch/loongarch-builtins.cc | 47 +++++++++++++++++++ gcc/config/loongarch/loongarch-c.cc | 22 +++++++++ gcc/config/loongarch/loongarch-protos.h | 7 ++- gcc/config/loongarch/loongarch.h | 2 + .../loongarch/vorn-signed-backward.C | 15 ++++++ .../loongarch/vorn-signed-backward.c | 15 ++++++ 6 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.target/loongarch/vorn-signed-backward.C create mode 100644 gcc/testsuite/gcc.target/loongarch/vorn-signed-backward.c diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc index c95bea6f036..b86403cdaaa 100644 --- a/gcc/config/loongarch/loongarch-builtins.cc +++ b/gcc/config/loongarch/loongarch-builtins.cc @@ -461,6 +461,7 @@ AVAIL_ALL (lasx_frecipe, ISA_HAS_LASX && ISA_HAS_FRECIPE) #define CODE_FOR_lsx_vftint_lu_d CODE_FOR_lsx_vftint_u_lu_d #define CODE_FOR_lsx_vandn_v CODE_FOR_andnv16qi3 #define CODE_FOR_lsx_vorn_v CODE_FOR_iornv16qi3 +#define CODE_FOR_lsx_vorn_v_signed CODE_FOR_iornv16qi3 #define CODE_FOR_lsx_vneg_b CODE_FOR_vnegv16qi2 #define CODE_FOR_lsx_vneg_h CODE_FOR_vnegv8hi2 #define CODE_FOR_lsx_vneg_w CODE_FOR_vnegv4si2 @@ -695,6 +696,7 @@ AVAIL_ALL (lasx_frecipe, ISA_HAS_LASX && ISA_HAS_FRECIPE) #define CODE_FOR_lasx_xvandn_v CODE_FOR_andnv32qi3 #define CODE_FOR_lasx_xvorn_v CODE_FOR_iornv32qi3 +#define CODE_FOR_lasx_xvorn_v_signed CODE_FOR_iornv32qi3 #define CODE_FOR_lasx_xvneg_b CODE_FOR_negv32qi2 #define CODE_FOR_lasx_xvneg_h CODE_FOR_negv16hi2 #define CODE_FOR_lasx_xvneg_w CODE_FOR_negv8si2 @@ -1570,6 +1572,7 @@ static const struct loongarch_builtin_description loongarch_builtins[] = { LSX_BUILTIN (vssrln_h_w, LARCH_V8HI_FTYPE_V4SI_V4SI), LSX_BUILTIN (vssrln_w_d, LARCH_V4SI_FTYPE_V2DI_V2DI), LSX_BUILTIN (vorn_v, LARCH_UV16QI_FTYPE_UV16QI_UV16QI), + LSX_BUILTIN (vorn_v_signed, LARCH_V16QI_FTYPE_V16QI_V16QI), LSX_BUILTIN (vldi, LARCH_V2DI_FTYPE_HI), LSX_BUILTIN (vshuf_b, LARCH_V16QI_FTYPE_V16QI_V16QI_V16QI), LSX_BUILTIN (vldx, LARCH_V16QI_FTYPE_CVPOINTER_DI), @@ -2120,6 +2123,7 @@ static const struct loongarch_builtin_description loongarch_builtins[] = { LASX_BUILTIN (xvssrln_h_w, LARCH_V16HI_FTYPE_V8SI_V8SI), LASX_BUILTIN (xvssrln_w_d, LARCH_V8SI_FTYPE_V4DI_V4DI), LASX_BUILTIN (xvorn_v, LARCH_UV32QI_FTYPE_UV32QI_UV32QI), + LASX_BUILTIN (xvorn_v_signed, LARCH_V32QI_FTYPE_V32QI_V32QI), LASX_BUILTIN (xvldi, LARCH_V4DI_FTYPE_HI), LASX_BUILTIN (xvldx, LARCH_V32QI_FTYPE_CVPOINTER_DI), LASX_NO_TARGET_BUILTIN (xvstx, LARCH_VOID_FTYPE_V32QI_CVPOINTER_DI), @@ -3189,3 +3193,46 @@ loongarch_build_builtin_va_list (void) { return ptr_type_node; } + +static bool +is_signed_i8_vec (tree arg) +{ + tree type = TREE_TYPE (arg); + return VECTOR_TYPE_P (type) && TREE_TYPE (type) == signed_char_type_node; +} + +tree +loongarch_resolve_overloaded_builtin_decl (location_t loc, + tree fndecl, + vec<tree, va_gc> *arglist) +{ + unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); + gcc_assert (fcode < ARRAY_SIZE (loongarch_builtins)); + + const struct loongarch_builtin_description *d = &loongarch_builtins[fcode]; + + if (((d->avail == loongarch_builtin_avail_lsx + && d->icode == CODE_FOR_lsx_vorn_v) + || (d->avail == loongarch_builtin_avail_lasx + && d->icode == CODE_FOR_lasx_xvorn_v)) + && arglist && arglist->length () == 2 + && is_signed_i8_vec ((*arglist)[0]) + && is_signed_i8_vec ((*arglist)[1])) + { + bool is_lasx = (d->icode == CODE_FOR_lasx_xvorn_v); + + inform (loc, "calling %qF with signed vector arguments is only " + "supported for backward compatibility; " + "vector built-in functions are not documented and " + "they may subject to changes in the future, " + "use the intrinsic %qs from %qs instead", + fndecl, + is_lasx ? "__lasx_vorn_v" : "__lsx_vorn_v", + is_lasx ? "lasxintrin.h" : "lsxintrin.h"); + + return is_lasx ? LARCH_GET_BUILTIN (lasx_xvorn_v) + : LARCH_GET_BUILTIN (lsx_vorn_v); + } + + return NULL; +} diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc index 97e1baffc42..083fd26e808 100644 --- a/gcc/config/loongarch/loongarch-c.cc +++ b/gcc/config/loongarch/loongarch-c.cc @@ -26,6 +26,9 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "c-family/c-common.h" #include "cpplib.h" +#include "target.h" + +#include "loongarch-protos.h" #define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM) #define builtin_define(TXT) cpp_define (pfile, TXT) @@ -145,3 +148,22 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile) builtin_define_with_int_value ("_LOONGARCH_SPFPSET", 32); } + +static tree +loongarch_resolve_overloaded_builtin (unsigned int loc, tree fndecl, + void *uncast_arglist) +{ + vec<tree, va_gc> *arglist = (vec<tree, va_gc> *) uncast_arglist; + tree new_fndecl = loongarch_resolve_overloaded_builtin_decl ( + (location_t) loc, fndecl, arglist); + + return new_fndecl ? build_function_call_vec (loc, vNULL, new_fndecl, + arglist, NULL, fndecl) + : NULL; +} + +void +loongarch_register_pragmas (void) +{ + targetm.resolve_overloaded_builtin = loongarch_resolve_overloaded_builtin; +} diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h index 85f6e894399..99fe0d794b5 100644 --- a/gcc/config/loongarch/loongarch-protos.h +++ b/gcc/config/loongarch/loongarch-protos.h @@ -195,7 +195,7 @@ extern void loongarch_expand_vec_cond_mask_expr (machine_mode, machine_mode, rtx *); extern void loongarch_expand_vec_widen_hilo (rtx, rtx, rtx, bool, bool, const char *); -/* Routines implemented in loongarch-c.c. */ +/* Routines implemented in loongarch-c.cc. */ void loongarch_cpu_cpp_builtins (cpp_reader *); extern void loongarch_init_builtins (void); @@ -212,4 +212,9 @@ extern void loongarch_emit_swrsqrtsf (rtx, rtx, machine_mode, bool); extern void loongarch_emit_swdivsf (rtx, rtx, rtx, machine_mode); extern bool loongarch_explicit_relocs_p (enum loongarch_symbol_type); extern bool loongarch_symbol_extreme_p (enum loongarch_symbol_type); +extern void loongarch_register_pragmas (void); + +/* Routines implemented in loongarch-builtins.cc. */ +extern tree loongarch_resolve_overloaded_builtin_decl (location_t, tree, + vec<tree, va_gc> *); #endif /* ! GCC_LOONGARCH_PROTOS_H */ diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h index 5efeae53be6..fbab4fef256 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -1259,3 +1259,5 @@ struct GTY (()) machine_function #define TARGET_EXPLICIT_RELOCS \ (la_opt_explicit_relocs == EXPLICIT_RELOCS_ALWAYS) + +#define REGISTER_TARGET_PRAGMAS() loongarch_register_pragmas () diff --git a/gcc/testsuite/g++.target/loongarch/vorn-signed-backward.C b/gcc/testsuite/g++.target/loongarch/vorn-signed-backward.C new file mode 100644 index 00000000000..859a9a6d120 --- /dev/null +++ b/gcc/testsuite/g++.target/loongarch/vorn-signed-backward.C @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-mlasx" } */ + +typedef signed char v16i8 __attribute__ ((vector_size (16))); +typedef signed char v32i8 __attribute__ ((vector_size (32))); + +v16i8 f1 (v16i8 a, v16i8 b) +{ + return __builtin_lsx_vorn_v (a, b); /* { dg-message "" } */ +} + +v32i8 f2 (v32i8 a, v32i8 b) +{ + return __builtin_lasx_xvorn_v (a, b); /* { dg-message "" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/vorn-signed-backward.c b/gcc/testsuite/gcc.target/loongarch/vorn-signed-backward.c new file mode 100644 index 00000000000..859a9a6d120 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vorn-signed-backward.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-mlasx" } */ + +typedef signed char v16i8 __attribute__ ((vector_size (16))); +typedef signed char v32i8 __attribute__ ((vector_size (32))); + +v16i8 f1 (v16i8 a, v16i8 b) +{ + return __builtin_lsx_vorn_v (a, b); /* { dg-message "" } */ +} + +v32i8 f2 (v32i8 a, v32i8 b) +{ + return __builtin_lasx_xvorn_v (a, b); /* { dg-message "" } */ +} -- 2.47.0