From 727bca8fefc0fb28463b678ceb36fcff28bcea46 Mon Sep 17 00:00:00 2001 From: Richard Ball Date: Fri, 6 Feb 2026 22:59:23 +0000 Subject: [PATCH] aarch64: Fix FEAT_PCDPHINT for C++ This patch rewrites the _Generic in arm_acle.h into a resolve_overloaded_builtin. The reason for this was the lack of support in C++ for _Generic. gcc/ChangeLog: * config/aarch64/aarch64-builtins.cc (enum aarch64_builtins): Add ptr and generic variants. (aarch64_init_pcdphint_builtins): Likewise. (aarch64_general_expand_builtin): Add ptr variant. (aarch64_resolve_overloaded_builtin_stshh): Function to handle overloaded atomic_store_with_stshh. (aarch64_resolve_overloaded_builtin_general): Add call to stshh function. * config/aarch64/aarch64-c.cc (aarch64_resolve_overloaded_builtin): Allow fndecl to return. * config/aarch64/arm_acle.h (__atomic_store_with_stshh): Remove __Generic. gcc/testsuite/ChangeLog: * gcc.target/aarch64/atomic_store_with_stshh.c: Testcase change. * g++.target/aarch64/atomic_store_with_stshh.C: New test. --- gcc/config/aarch64/aarch64-builtins.cc | 62 ++++++ gcc/config/aarch64/aarch64-c.cc | 3 +- gcc/config/aarch64/arm_acle.h | 24 +-- .../aarch64/atomic_store_with_stshh.C | 186 ++++++++++++++++++ .../aarch64/atomic_store_with_stshh.c | 7 +- 5 files changed, 257 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index dd74cf06ef2..5bb873c3923 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -903,12 +903,14 @@ enum aarch64_builtins AARCH64_BUILTIN_GCSPOPM, AARCH64_BUILTIN_GCSSS, /* Armv9.6-A builtins. */ + AARCH64_BUILTIN_STSHH, AARCH64_BUILTIN_STSHH_QI, AARCH64_BUILTIN_STSHH_HI, AARCH64_BUILTIN_STSHH_SI, AARCH64_BUILTIN_STSHH_DI, AARCH64_BUILTIN_STSHH_SF, AARCH64_BUILTIN_STSHH_DF, + AARCH64_BUILTIN_STSHH_PTR, AARCH64_BUILTIN_MAX }; @@ -2487,6 +2489,14 @@ aarch64_init_pcdphint_builtins (void) { tree ftype; + ftype = build_function_type_list (void_type_node, ptr_type_node, + void_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_STSHH] + = aarch64_general_add_builtin ("__builtin_aarch64_stshh", ftype, + AARCH64_BUILTIN_STSHH); + ftype = build_function_type_list (void_type_node, ptr_type_node, unsigned_char_type_node, unsigned_type_node, @@ -2535,6 +2545,14 @@ aarch64_init_pcdphint_builtins (void) = aarch64_general_add_builtin ("__builtin_aarch64_stshh_df", ftype, AARCH64_BUILTIN_STSHH_DF); + ftype = build_function_type_list (void_type_node, ptr_type_node, + ptr_type_node, + unsigned_type_node, + unsigned_type_node, NULL_TREE); + aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_PTR] + = aarch64_general_add_builtin ("__builtin_aarch64_stshh_ptr", ftype, + AARCH64_BUILTIN_STSHH_PTR); + } /* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */ @@ -4598,6 +4616,7 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target, case AARCH64_BUILTIN_STSHH_DI: case AARCH64_BUILTIN_STSHH_SF: case AARCH64_BUILTIN_STSHH_DF: + case AARCH64_BUILTIN_STSHH_PTR: aarch64_expand_stshh_builtin (exp, fcode); return target; } @@ -5760,6 +5779,46 @@ aarch64_resolve_overloaded_memtag (location_t loc, return NULL_TREE; } +static tree +aarch64_resolve_overloaded_builtin_stshh (void *pass_params) +{ + vec *params = static_cast *> (pass_params); + if (vec_safe_length (params) != 4) + return NULL_TREE; + + tree addr = (*params)[0]; + tree val = (*params)[1]; + addr = tree_strip_nop_conversions (addr); + val = tree_strip_nop_conversions (val); + + tree addr_type = TREE_TYPE (addr); + if (!POINTER_TYPE_P (addr_type)) + return NULL_TREE; + + tree ptr_type = TYPE_MAIN_VARIANT (TREE_TYPE (addr_type)); + + if (POINTER_TYPE_P (ptr_type)) + return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_PTR]; + + switch (TYPE_MODE (ptr_type)) + { + case QImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_QI]; + case HImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_HI]; + case SImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_SI]; + case DImode: + return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_DI]; + case SFmode: + return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_SF]; + case DFmode: + return aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_DF]; + default: + return NULL_TREE; + } +} + /* Called at aarch64_resolve_overloaded_builtin in aarch64-c.cc. */ tree aarch64_resolve_overloaded_builtin_general (location_t loc, tree function, @@ -5771,6 +5830,9 @@ aarch64_resolve_overloaded_builtin_general (location_t loc, tree function, && fcode <= AARCH64_MEMTAG_BUILTIN_END) return aarch64_resolve_overloaded_memtag(loc, function, pass_params); + if (fcode == AARCH64_BUILTIN_STSHH) + return aarch64_resolve_overloaded_builtin_stshh (pass_params); + return NULL_TREE; } diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc index f8be998da16..dbe940a8ba9 100644 --- a/gcc/config/aarch64/aarch64-c.cc +++ b/gcc/config/aarch64/aarch64-c.cc @@ -431,8 +431,9 @@ aarch64_resolve_overloaded_builtin (location_t location, switch (code & AARCH64_BUILTIN_CLASS) { case AARCH64_BUILTIN_GENERAL: - return aarch64_resolve_overloaded_builtin_general (location, fndecl, + new_fndecl = aarch64_resolve_overloaded_builtin_general (location, fndecl, uncast_arglist); + break; case AARCH64_BUILTIN_SVE: new_fndecl = aarch64_sve::resolve_overloaded_builtin (location, subcode, arglist); diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h index 794ea32b178..b31e23e6cba 100644 --- a/gcc/config/aarch64/arm_acle.h +++ b/gcc/config/aarch64/arm_acle.h @@ -102,27 +102,9 @@ __sqrtf (float __x) return __builtin_aarch64_sqrtsf (__x); } -#define __atomic_store_with_stshh(addr, value, memory_order, ret) \ -({ \ - __auto_type ptr = (addr); \ - typedef __typeof__ (*ptr) ptr_type; \ - _Generic ((*ptr), \ - char: __builtin_aarch64_stshh_qi, \ - unsigned char: __builtin_aarch64_stshh_qi, \ - signed char: __builtin_aarch64_stshh_qi, \ - unsigned short: __builtin_aarch64_stshh_hi, \ - short: __builtin_aarch64_stshh_hi, \ - unsigned int: __builtin_aarch64_stshh_si, \ - int: __builtin_aarch64_stshh_si, \ - unsigned long: __builtin_aarch64_stshh_di, \ - long: __builtin_aarch64_stshh_di, \ - unsigned long long: __builtin_aarch64_stshh_di, \ - long long: __builtin_aarch64_stshh_di, \ - float: __builtin_aarch64_stshh_sf, \ - double: __builtin_aarch64_stshh_df, \ - default: __builtin_aarch64_stshh_di \ - )((ptr), (ptr_type)(value), (memory_order), (ret)); \ -}) +#define __atomic_store_with_stshh(__addr, __value, __memory_order, __ret) \ + __builtin_aarch64_stshh ((__addr), (__value), \ + (__memory_order), (__ret)) #pragma GCC push_options #pragma GCC target ("+nothing+jscvt") diff --git a/gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C b/gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C new file mode 100644 index 00000000000..d22412369ef --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/atomic_store_with_stshh.C @@ -0,0 +1,186 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8-a -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +/* +** _Z8testFun1v: +** ... +** stshh keep +** strb w[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun1 () +{ + char item1 = 0; + char* ptr1 = &item1; + char test1 = 1; + + __atomic_store_with_stshh (ptr1, test1, __ATOMIC_RELAXED, 0); +} + +/* +** _Z8testFun2v: +** ... +** stshh keep +** stlrh w[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun2 () +{ + short item2 = 10; + short* ptr2 = &item2; + short test2 = 11; + __atomic_store_with_stshh (ptr2, test2, __ATOMIC_RELEASE, 0); +} + +/* +** _Z8testFun3v: +** ... +** stshh strm +** stlr w[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun3 () +{ + unsigned int item3 = 10; + unsigned int* ptr3 = &item3; + unsigned int test3 = 11; + __atomic_store_with_stshh (ptr3, test3, __ATOMIC_SEQ_CST, 1); +} + +/* +** _Z8testFun4v: +** ... +** stshh strm +** str x[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun4 () +{ + long item4 = 10; + long* ptr4 = &item4; + long test4 = 11; + __atomic_store_with_stshh (ptr4, test4, __ATOMIC_RELAXED, 1); +} + +/* +** _Z8testFun5v: +** ... +** stshh keep +** stlr x[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun5 () +{ + long item5 = 10; + long *ptritem = &item5; + long **ptr5 = &ptritem; + long test5item = 11; + long *test5 = &test5item; + __atomic_store_with_stshh (ptr5, test5, __ATOMIC_SEQ_CST, 0); +} + +/* +** _Z8testFun6v: +** ... +** stshh keep +** stlr w[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun6 () +{ + float item6 = 10; + float* ptr6 = &item6; + float test6 = 11; + __atomic_store_with_stshh (ptr6, test6, __ATOMIC_SEQ_CST, 0); +} + +/* +** _Z8testFun7v: +** ... +** stshh strm +** str x[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun7 () +{ + double item7 = 10; + double* ptr7 = &item7; + double test7 = 11; + __atomic_store_with_stshh (ptr7, test7, __ATOMIC_RELAXED, 1); +} + +/* +** _Z8testFun8v: +** ... +** stshh keep +** strb w[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun8 () +{ + char item8 = 0; + char* ptr8 = &item8; + long test8 = 1; + + __atomic_store_with_stshh (ptr8, test8, __ATOMIC_RELAXED, 0); +} + +/* +** _Z8testFun9v: +** ... +** stshh strm +** str w[0-9]+, \[x[0-9]+\] +** ... +*/ +void +testFun9 () +{ + int item9 = 0; + int* ptr9 = &item9; + float test9 = 1; + + __atomic_store_with_stshh (ptr9, test9, __ATOMIC_RELAXED, 1); +} + +/* +** _Z9testFun10v: +** ... +** add (x[0-9]+), \1, 1 +** mov (w[0-9]+), 7 +** stshh strm +** strb \2, \[\1\] +** ... +*/ +static char buf[8]; +void +testFun10 (void) +{ + __atomic_store_with_stshh((buf + 1), (char)7, __ATOMIC_RELAXED, 1); +} + +/* +** _Z9testFun11v: +** ... +** stshh strm +** str wzr, \[x[0-9]+\] +** ... +*/ +void +testFun11 () +{ + int item11 = 10; + int* ptr11 = &item11; + + __atomic_store_with_stshh (ptr11, 0, __ATOMIC_RELAXED, 1); +} diff --git a/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c b/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c index 9be42574b9c..516a45aa781 100644 --- a/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c +++ b/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c @@ -73,16 +73,17 @@ testFun4 () ** testFun5: ** ... ** stshh keep -** stlr x[0-9]+, \[sp\] +** stlr x[0-9]+, \[x[0-9]+\] ** ... */ void testFun5 () { long item5 = 10; - long* ptr5 = &item5; + long *ptritem = &item5; + long **ptr5 = &ptritem; long test5item = 11; - long* test5 = &test5item; + long *test5 = &test5item; __atomic_store_with_stshh (ptr5, test5, __ATOMIC_SEQ_CST, 0); } -- 2.47.3