[gcc r14-9886] testsuite: Adjust pr113359-2_*.c with unsigned long long [PR114662]
https://gcc.gnu.org/g:4923ed49b93352bcf9e43cafac38345e4a54c3f8 commit r14-9886-g4923ed49b93352bcf9e43cafac38345e4a54c3f8 Author: Kewen Lin Date: Wed Apr 10 02:59:43 2024 -0500 testsuite: Adjust pr113359-2_*.c with unsigned long long [PR114662] pr113359-2_*.c define a struct having unsigned long type members ay and az which have 4 bytes size at -m32, while the related constants CL1 and CL2 used for equality check are always 8 bytes, it makes compiler consider the below 69 if (a.ay != CL1) 70 __builtin_abort (); always to abort and optimize away the following call to getb, which leads to the expected wpa dumping on "Semantic equality" missing. This patch is to modify the types with unsigned long long accordingly. PR testsuite/114662 gcc/testsuite/ChangeLog: * gcc.dg/lto/pr113359-2_0.c: Use unsigned long long instead of unsigned long. * gcc.dg/lto/pr113359-2_1.c: Likewise. Diff: --- gcc/testsuite/gcc.dg/lto/pr113359-2_0.c | 8 gcc/testsuite/gcc.dg/lto/pr113359-2_1.c | 8 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c b/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c index 8b2d5bdfab2..8495667599d 100644 --- a/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c +++ b/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c @@ -8,15 +8,15 @@ struct SA { unsigned int ax; - unsigned long ay; - unsigned long az; + unsigned long long ay; + unsigned long long az; }; struct SB { unsigned int bx; - unsigned long by; - unsigned long bz; + unsigned long long by; + unsigned long long bz; }; struct ZA diff --git a/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c b/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c index 61bc0547981..8320f347efe 100644 --- a/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c +++ b/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c @@ -5,15 +5,15 @@ struct SA { unsigned int ax; - unsigned long ay; - unsigned long az; + unsigned long long ay; + unsigned long long az; }; struct SB { unsigned int bx; - unsigned long by; - unsigned long bz; + unsigned long long by; + unsigned long long bz; }; struct ZA
[gcc r14-9887] c++: Implement C++26 P2809R3 - Trivial infinite loops are not Undefined Behavior
https://gcc.gnu.org/g:4be1cc5f50578fafcdcbd09160235066d76a3f86 commit r14-9887-g4be1cc5f50578fafcdcbd09160235066d76a3f86 Author: Jakub Jelinek Date: Wed Apr 10 10:08:12 2024 +0200 c++: Implement C++26 P2809R3 - Trivial infinite loops are not Undefined Behavior The following patch attempts to implement P2809R3, which has been voted in as a DR. The middle-end has its behavior documented: '-ffinite-loops' Assume that a loop with an exit will eventually take the exit and not loop indefinitely. This allows the compiler to remove loops that otherwise have no side-effects, not considering eventual endless looping as such. This option is enabled by default at '-O2' for C++ with -std=c++11 or higher. So, the following patch attempts to detect trivial infinite loops by detecting trivially empty loops, if their condition is not INTEGER_CST (that case is handled by the middle-end right already) trying to constant evaluate with mce=true their condition and if it evaluates to true (and -ffinite-loops and not processing_template_decl) wraps the condition into an ANNOTATE_EXPR which tells the middle-end that the loop shouldn't be loop->finite_p despite -ffinite-loops). Furthermore, the patch adds -Wtautological-compare warnings for loop conditions containing std::is_constant_evaluated(), either if those always evaluate to true, or always evaluate to false, or will evaluate to true just when checking if it is trivial infinite loop (and if in non-constexpr function also say that it will evaluate to false otherwise). The user is doing something weird in all those cases. 2024-04-10 Jakub Jelinek PR c++/114462 gcc/ * tree-core.h (enum annot_expr_kind): Add annot_expr_maybe_infinite_kind enumerator. * gimplify.cc (gimple_boolify): Handle annot_expr_maybe_infinite_kind. * tree-cfg.cc (replace_loop_annotate_in_block): Likewise. (replace_loop_annotate): Likewise. Move loop->finite_p initialization before the replace_loop_annotate_in_block calls. * tree-pretty-print.cc (dump_generic_node): Handle annot_expr_maybe_infinite_kind. gcc/cp/ * semantics.cc: Implement C++26 P2809R3 - Trivial infinite loops are not Undefined Behavior. (maybe_warn_for_constant_evaluated): Add trivial_infinite argument and emit special diagnostics for that case. (finish_if_stmt_cond): Adjust caller. (finish_loop_cond): New function. (finish_while_stmt): Use it. (finish_do_stmt): Likewise. (finish_for_stmt): Likewise. gcc/testsuite/ * g++.dg/cpp26/trivial-infinite-loop1.C: New test. * g++.dg/cpp26/trivial-infinite-loop2.C: New test. * g++.dg/cpp26/trivial-infinite-loop3.C: New test. Diff: --- gcc/cp/semantics.cc| 75 ++- gcc/gimplify.cc| 1 + .../g++.dg/cpp26/trivial-infinite-loop1.C | 148 + .../g++.dg/cpp26/trivial-infinite-loop2.C | 147 .../g++.dg/cpp26/trivial-infinite-loop3.C | 148 + gcc/tree-cfg.cc| 10 +- gcc/tree-core.h| 1 + gcc/tree-pretty-print.cc | 3 + 8 files changed, 527 insertions(+), 6 deletions(-) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 329c524a509..abaa4a3ca53 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -1090,7 +1090,8 @@ find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *) (e.g., in a non-constexpr non-consteval function) so give the user a clue. */ static void -maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if) +maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if, + bool trivial_infinite) { if (!warn_tautological_compare) return; @@ -1108,6 +1109,18 @@ maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if) warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare, "% always evaluates to " "true in %"); + else if (trivial_infinite) + { + auto_diagnostic_group d; + if (warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare, + "% evaluates to " + "true when checking if trivially empty iteration " + "statement is trivial infinite loop") + && !maybe_constexpr_fn (current_function_decl)) + inform (EXPR_LOCATION (cond), + "and evaluates to false when actually evaluating " + "the condition i
[gcc/ARM/heads/gcs] (924 commits) aarch64: Introduce indirect_return attribute
The branch 'ARM/heads/gcs' was updated to point to: 3458fa6e8c3... aarch64: Introduce indirect_return attribute It previously pointed to: 7f952ecef18... aarch64: Introduce indirect_return attribute Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 7f952ec... aarch64: Introduce indirect_return attribute af7a4e5... aarch64: libatomic: add GCS marking to asm 3bdac55... aarch64: libgcc: add GCS marking to asm 0c8f137... aarch64: Emit GNU property NOTE for GCS 49b5b4f... aarch64: Add GCS support to the unwinder d907060... aarch64: Add test for GCS ACLE defs 642ea9d... aarch64: Add ACLE feature macros for GCS 5e09337... aarch64: Add non-local goto and jump tests for GCS 701b6b5... aarch64: Add GCS support for nonlocal stack save 5011ae6... aarch64: Add __builtin_aarch64_gcs* tests 70e678a... aarch64: Add GCS builtins 9b2e109... aarch64: Add GCS instructions f0908f3... aarch64: Add __builtin_aarch64_chkfeat tests cd72de0... aarch64: Add __builtin_aarch64_chkfeat 3e65859... aarch64: Add support for chkfeat insn f98aa4a... aarch64: Add target pragma tests for gcs 76060fa... aarch64: Add branch-protection target pragma tests d6f5213... aarch64: Add -mbranch-protection=gcs option b8a248a... aarch64,arm: Move branch-protection data to targets Summary of changes (added commits): --- 3458fa6... aarch64: Introduce indirect_return attribute 9f2fe29... aarch64: libitm: Add GCS support 78b29b5... aarch64: libatomic: add GCS marking to asm b32a17f... aarch64: libgcc: add GCS marking to asm 99a291c... aarch64: Emit GNU property NOTE for GCS 2185dc7... aarch64: Add GCS support to the unwinder 2a9d500... aarch64: Add test for GCS ACLE defs f94cfda... aarch64: Add ACLE feature macros for GCS 87217fd... aarch64: Add non-local goto and jump tests for GCS d5a22a5... aarch64: Add GCS support for nonlocal stack save 90ff917... aarch64: Add __builtin_aarch64_gcs* tests 4880a14... aarch64: Add GCS builtins 57aec9c... aarch64: Add GCS instructions 0c0ee07... aarch64: Add __builtin_aarch64_chkfeat tests e26ccd3... aarch64: Add __builtin_aarch64_chkfeat 309f26c... aarch64: Add support for chkfeat insn 311c3aa... aarch64: Add target pragma tests for gcs 2c160a7... aarch64: Add branch-protection target pragma tests 50dc770... aarch64: Add -mbranch-protection=gcs option 4923ed4... testsuite: Adjust pr113359-2_*.c with unsigned long long [P (*) 109f1b2... Revert "combine: Don't combine if I2 does not change" (*) 7924e35... rs6000: Replace OPTION_MASK_DIRECT_MOVE with OPTION_MASK_P8 (*) 0774240... c++: Keep DECL_SAVED_TREE of cdtor instantiations in module (*) ea665f9... [APX] Prohibit SHA/KEYLOCKER usage of EGPR when APX enabled (*) 77c0b5b... c++: Track declarations imported from partitions [PR99377] (*) 0753ae1... Daily bump. (*) 92b38ec... libstdc++: Fix build for targets without FP std::from_chars (*) 639215c... btf: improve btf-datasec-3.c test [PR114642] (*) 1f719aa... s390x: Optimize vector permute with constant indexes (*) 8075477... btf: emit symbol refs in DATASEC entries only for BPF [PR11 (*) 685d822... aarch64: Fix ACLE SME streaming mode error in neon-sve-brid (*) de82b0c... Fortran: Fix ICE in trans-stmt.cc(gfc_trans_call) [PR114535 (*) 88aea12... Fortran: Fix ICE in gfc_trans_pointer_assignment [PR113956] (*) 32fb04a... lto/114655 - -flto=4 at link time doesn't override -flto=au (*) ce3c743... RTEMS: Fix powerpc configuration (*) dd78e6a... Guard function->cond_uids access [PR114601] (*) a79d13a... i386: Fix aes/vaes patterns [PR114576] (*) 897a241... modula2: remove description of fdebug-trace-quad, fdebug-tr (*) 46120d7... modula2: tidyup makeSystem (*) 8657d76... LoongArch: Enable switchable target (*) 73fb0a6... rust: Add rust.install-dvi and rust.install-html rules (*) a244755... Generate constant at start of loop, without UB (*) 2daeb89... Add tree-inlined gconds to caller cond->expr map (*) 21c9fd9... libquadmath: Provide __BYTE_ORDER, __LITTLE_ENDIAN and __BI (*) cfed80b... c++: Fix up maybe_warn_for_constant_evaluated calls [PR1145 (*) 64aa48c... Fix up duplicated words mostly in comments, part 2 (*) 7dd1f9d... bitint: Don't move debug stmts from before returns_twice ca (*) 46c9166... libgcc: Add basic support for aarch64-gnu (GNU/Hurd on AArc (*) 9670a23... aarch64: Add support for aarch64-gnu (GNU/Hurd on AArch64) (*) 532c57f... Move GNU/Hurd startfile spec from config/i386/gnu.h to conf (*) d76df69... middle-end/114604 - ranger allocates bitmap without initial (*) ddee437... RTEMS: Add multilib configuration for aarch64 (*) 481ba4f... libquadmath: Use soft-fp for sqrtq finite positive argument (*) 18e94e0... x86: Define __APX_INLINE_ASM_USE_GPR32__ (*) 9c97de6... testsuite: Add profile_update_atomic check to gcov-20.c [PR (*) 26eb5f8..
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add -mbranch-protection=gcs option
https://gcc.gnu.org/g:50dc77071139c477a10c78d3d73ff2db4dcd6ef7 commit 50dc77071139c477a10c78d3d73ff2db4dcd6ef7 Author: Szabolcs Nagy Date: Mon Jun 19 12:57:56 2023 +0100 aarch64: Add -mbranch-protection=gcs option This enables Guarded Control Stack (GCS) compatible code generation. The "standard" branch-protection type enables it, and the default depends on the compiler default. TODO: gcs compatibility marking is missing. gcc/ChangeLog: * config/aarch64/aarch64-protos.h (aarch_gcs_enabled): Declare. * config/aarch64/aarch64.cc (aarch_gcs_enabled): Define. (aarch_handle_no_branch_protection): Handle gcs. (aarch_handle_standard_branch_protection): Handle gcs. (aarch_handle_gcs_protection): New. * config/aarch64/aarch64.opt: Add aarch_enable_gcs. * configure: Regenerate. * configure.ac: Handle gcs in --enable-standard-branch-protection. * doc/invoke.texi: Document -mbranch-protection=gcs. Diff: --- gcc/config/aarch64/aarch64-protos.h | 2 ++ gcc/config/aarch64/aarch64.cc | 24 gcc/config/aarch64/aarch64.opt | 3 +++ gcc/configure | 2 +- gcc/configure.ac| 2 +- gcc/doc/invoke.texi | 5 +++-- 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 42639e9efcf..ed5f9622658 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -1113,4 +1113,6 @@ extern void aarch64_adjust_reg_alloc_order (); bool aarch64_optimize_mode_switching (aarch64_mode_entity); void aarch64_restore_za (rtx); +extern bool aarch64_gcs_enabled (); + #endif /* GCC_AARCH64_PROTOS_H */ diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 1ea84c8bd73..73969721906 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -8375,6 +8375,13 @@ aarch_bti_j_insn_p (rtx_insn *insn) return GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_BTI_J; } +/* Return TRUE if Guarded Control Stack is enabled. */ +bool +aarch64_gcs_enabled (void) +{ + return (aarch64_enable_gcs == 1); +} + /* Check if X (or any sub-rtx of X) is a PACIASP/PACIBSP instruction. */ bool aarch_pac_insn_p (rtx x) @@ -18694,6 +18701,7 @@ aarch64_handle_no_branch_protection (void) { aarch_ra_sign_scope = AARCH_FUNCTION_NONE; aarch_enable_bti = 0; + aarch64_enable_gcs = 0; } static void @@ -18702,6 +18710,7 @@ aarch64_handle_standard_branch_protection (void) aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF; aarch64_ra_sign_key = AARCH64_KEY_A; aarch_enable_bti = 1; + aarch64_enable_gcs = 1; } static void @@ -18728,6 +18737,11 @@ aarch64_handle_bti_protection (void) { aarch_enable_bti = 1; } +static void +aarch64_handle_gcs_protection (void) +{ + aarch64_enable_gcs = 1; +} static const struct aarch_branch_protect_type aarch64_pac_ret_subtypes[] = { { "leaf", false, aarch64_handle_pac_ret_leaf, NULL, 0 }, @@ -18742,6 +18756,7 @@ static const struct aarch_branch_protect_type aarch64_branch_protect_types[] = { "pac-ret", false, aarch64_handle_pac_ret_protection, aarch64_pac_ret_subtypes, ARRAY_SIZE (aarch64_pac_ret_subtypes) }, { "bti", false, aarch64_handle_bti_protection, NULL, 0 }, + { "gcs", false, aarch64_handle_gcs_protection, NULL, 0 }, { NULL, false, NULL, NULL, 0 } }; @@ -18842,6 +18857,15 @@ aarch64_override_options (void) #endif } + if (aarch64_enable_gcs == 2) +{ +#ifdef TARGET_ENABLE_GCS + aarch64_enable_gcs = 1; +#else + aarch64_enable_gcs = 0; +#endif +} + /* Return address signing is currently not supported for ILP32 targets. For LP64 targets use the configured option in the absence of a command-line option for -mbranch-protection. */ diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index 6356c419399..aeb710449fb 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -39,6 +39,9 @@ aarch64_feature_flags aarch64_isa_flags = 0 TargetVariable unsigned aarch_enable_bti = 2 +TargetVariable +unsigned aarch64_enable_gcs = 2 + TargetVariable enum aarch64_key_type aarch64_ra_sign_key = AARCH64_KEY_A diff --git a/gcc/configure b/gcc/configure index 266ab8f84b2..45725639fd2 100755 --- a/gcc/configure +++ b/gcc/configure @@ -28221,7 +28221,7 @@ if test "${enable_standard_branch_protection+set}" = set; then : enableval=$enable_standard_branch_protection; case $enableval in yes) -tm_defines="${tm_defines} TARGET_ENABLE_BTI=1 TARGET_ENABLE_PAC_RET=1" +tm_defines="${tm_defines} TARGET_ENABLE_BTI=1 TARGET_ENABLE_PAC_RET=1 TARGET_ENABLE_GCS=1" ;; no) ;; diff --git a/gcc/configure.ac b/gc
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add branch-protection target pragma tests
https://gcc.gnu.org/g:2c160a731e7764e97a2b8014149aaee47a11fbba commit 2c160a731e7764e97a2b8014149aaee47a11fbba Author: Szabolcs Nagy Date: Fri Jun 30 16:31:23 2023 +0100 aarch64: Add branch-protection target pragma tests gcc/testsuite/ChangeLog: * gcc.target/aarch64/pragma_cpp_predefs_4.c: Add branch-protection tests. Diff: --- .../gcc.target/aarch64/pragma_cpp_predefs_4.c | 50 ++ 1 file changed, 50 insertions(+) diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c index 23ebe5e4f50..8e707630774 100644 --- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c +++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c @@ -83,3 +83,53 @@ #ifndef __ARM_FEATURE_SME_F64F64 #error Foo #endif + +#pragma GCC target "branch-protection=standard" +#ifndef __ARM_FEATURE_BTI_DEFAULT +#error Foo +#endif +#if __ARM_FEATURE_PAC_DEFAULT != 1 +#error Foo +#endif + +#pragma GCC target ("branch-protection=none") +#ifdef __ARM_FEATURE_BTI_DEFAULT +#error Foo +#endif +#ifdef __ARM_FEATURE_PAC_DEFAULT +#error Foo +#endif + +#pragma GCC push_options +#pragma GCC target "branch-protection=bti+pac-ret" +#ifndef __ARM_FEATURE_BTI_DEFAULT +#error Foo +#endif +#pragma GCC pop_options +#ifdef __ARM_FEATURE_BTI_DEFAULT +#error Foo +#endif + +#pragma GCC target "branch-protection=bti" +#ifndef __ARM_FEATURE_BTI_DEFAULT +#error Foo +#endif +#ifdef __ARM_FEATURE_PAC_DEFAULT +#error Foo +#endif + +#pragma GCC target "branch-protection=pac-ret" +#ifdef __ARM_FEATURE_BTI_DEFAULT +#error Foo +#endif +#if __ARM_FEATURE_PAC_DEFAULT != 1 +#error Foo +#endif + +#pragma GCC target "branch-protection=pac-ret+leaf+b-key" +#ifdef __ARM_FEATURE_BTI_DEFAULT +#error Foo +#endif +#if __ARM_FEATURE_PAC_DEFAULT != 6 +#error Foo +#endif
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add target pragma tests for gcs
https://gcc.gnu.org/g:311c3aa1e58672c36991a193db5752d3dcf8e7d9 commit 311c3aa1e58672c36991a193db5752d3dcf8e7d9 Author: Szabolcs Nagy Date: Fri Jun 30 16:50:23 2023 +0100 aarch64: Add target pragma tests for gcs gcc/testsuite/ChangeLog: * gcc.target/aarch64/pragma_cpp_predefs_4.c: Add gcs specific tests. Diff: --- .../gcc.target/aarch64/pragma_cpp_predefs_4.c | 35 ++ 1 file changed, 35 insertions(+) diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c index 8e707630774..417293d4d5a 100644 --- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c +++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c @@ -91,6 +91,9 @@ #if __ARM_FEATURE_PAC_DEFAULT != 1 #error Foo #endif +#ifndef __ARM_FEATURE_GCS_DEFAULT +#error Foo +#endif #pragma GCC target ("branch-protection=none") #ifdef __ARM_FEATURE_BTI_DEFAULT @@ -99,6 +102,9 @@ #ifdef __ARM_FEATURE_PAC_DEFAULT #error Foo #endif +#ifdef __ARM_FEATURE_GCS_DEFAULT +#error Foo +#endif #pragma GCC push_options #pragma GCC target "branch-protection=bti+pac-ret" @@ -117,6 +123,9 @@ #ifdef __ARM_FEATURE_PAC_DEFAULT #error Foo #endif +#ifdef __ARM_FEATURE_GCS_DEFAULT +#error Foo +#endif #pragma GCC target "branch-protection=pac-ret" #ifdef __ARM_FEATURE_BTI_DEFAULT @@ -133,3 +142,29 @@ #if __ARM_FEATURE_PAC_DEFAULT != 6 #error Foo #endif + +#pragma GCC target "branch-protection=gcs" +#ifdef __ARM_FEATURE_BTI_DEFAULT +#error Foo +#endif +#ifdef __ARM_FEATURE_PAC_DEFAULT +#error Foo +#endif +#ifndef __ARM_FEATURE_GCS_DEFAULT +#error Foo +#endif + +#pragma GCC target "arch=armv8.8-a+gcs" +#ifndef __ARM_FEATURE_GCS +#error Foo +#endif + +#pragma GCC target "arch=armv8.8-a+nogcs" +#ifdef __ARM_FEATURE_GCS +#error Foo +#endif + +#pragma GCC target "arch=armv8.8-a" +#ifdef __ARM_FEATURE_GCS +#error Foo +#endif
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add support for chkfeat insn
https://gcc.gnu.org/g:309f26c5301d11891a6adddf9515adf5a9b0 commit 309f26c5301d11891a6adddf9515adf5a9b0 Author: Szabolcs Nagy Date: Tue May 9 15:37:49 2023 +0100 aarch64: Add support for chkfeat insn This is a hint space instruction to check for enabled HW features and update the x16 register accordingly. Use unspec_volatile to prevent reordering it around calls since calls can enable or disable HW features. gcc/ChangeLog: * config/aarch64/aarch64.md (aarch64_chkfeat): New. Diff: --- gcc/config/aarch64/aarch64.md | 9 + 1 file changed, 9 insertions(+) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 385a669b9b3..a20462303b5 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -378,6 +378,7 @@ UNSPECV_BTI_C ; Represent BTI c. UNSPECV_BTI_J ; Represent BTI j. UNSPECV_BTI_JC ; Represent BTI jc. +UNSPECV_CHKFEAT; Represent CHKFEAT X16. UNSPECV_TSTART ; Represent transaction start. UNSPECV_TCOMMIT; Represent transaction commit. UNSPECV_TCANCEL; Represent transaction cancel. @@ -8258,6 +8259,14 @@ "msr\tnzcv, %0" ) +;; CHKFEAT instruction +(define_insn "aarch64_chkfeat" + [(set (reg:DI R16_REGNUM) +(unspec_volatile:DI [(reg:DI R16_REGNUM)] UNSPECV_CHKFEAT))] + "" + "hint\\t40 // chkfeat x16" +) + ;; AdvSIMD Stuff (include "aarch64-simd.md")
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add __builtin_aarch64_chkfeat
https://gcc.gnu.org/g:e26ccd302f4face487da5b530d4dbeb4eebf7d43 commit e26ccd302f4face487da5b530d4dbeb4eebf7d43 Author: Szabolcs Nagy Date: Tue May 9 15:24:18 2023 +0100 aarch64: Add __builtin_aarch64_chkfeat Builtin for chkfeat: the input argument is used to initialize x16 then execute chkfeat and return the updated x16. Note: ACLE __chkfeat(x) plans to flip the bits to be more intuitive (xor the input to output), but for the builtin that seems unnecessary complication. gcc/ChangeLog: * config/aarch64/aarch64-builtins.cc (enum aarch64_builtins): Define AARCH64_BUILTIN_CHKFEAT. (aarch64_general_init_builtins): Handle chkfeat. (aarch64_general_expand_builtin): Handle chkfeat. Diff: --- gcc/config/aarch64/aarch64-builtins.cc | 18 ++ 1 file changed, 18 insertions(+) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 75d21de1401..1c08f56ab6b 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -788,6 +788,8 @@ enum aarch64_builtins AARCH64_PLDX, AARCH64_PLI, AARCH64_PLIX, + /* Armv8.9-A / Armv9.4-A builtins. */ + AARCH64_BUILTIN_CHKFEAT, AARCH64_BUILTIN_MAX }; @@ -2084,6 +2086,12 @@ aarch64_general_init_builtins (void) if (TARGET_MEMTAG) aarch64_init_memtag_builtins (); + tree ftype_chkfeat += build_function_type_list (uint64_type_node, uint64_type_node, NULL); + aarch64_builtin_decls[AARCH64_BUILTIN_CHKFEAT] += aarch64_general_add_builtin ("__builtin_aarch64_chkfeat", ftype_chkfeat, + AARCH64_BUILTIN_CHKFEAT); + if (in_lto_p) handle_arm_acle_h (); } @@ -3137,6 +3145,16 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target, case AARCH64_PLIX: aarch64_expand_prefetch_builtin (exp, fcode); return target; + +case AARCH64_BUILTIN_CHKFEAT: + { + rtx x16_reg = gen_rtx_REG (DImode, R16_REGNUM); + op0 = expand_normal (CALL_EXPR_ARG (exp, 0)); + emit_move_insn (x16_reg, op0); + expand_insn (CODE_FOR_aarch64_chkfeat, 0, 0); + emit_move_insn (target, x16_reg); + return target; + } } if (fcode >= AARCH64_SIMD_BUILTIN_BASE && fcode <= AARCH64_SIMD_BUILTIN_MAX)
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add __builtin_aarch64_chkfeat tests
https://gcc.gnu.org/g:0c0ee07e8b10e071c5b88fbae6f109778a4e578c commit 0c0ee07e8b10e071c5b88fbae6f109778a4e578c Author: Szabolcs Nagy Date: Fri Jun 2 16:15:25 2023 +0100 aarch64: Add __builtin_aarch64_chkfeat tests gcc/testsuite/ChangeLog: * gcc.target/aarch64/chkfeat-1.c: New test. * gcc.target/aarch64/chkfeat-2.c: New test. Diff: --- gcc/testsuite/gcc.target/aarch64/chkfeat-1.c | 75 gcc/testsuite/gcc.target/aarch64/chkfeat-2.c | 15 ++ 2 files changed, 90 insertions(+) diff --git a/gcc/testsuite/gcc.target/aarch64/chkfeat-1.c b/gcc/testsuite/gcc.target/aarch64/chkfeat-1.c new file mode 100644 index 000..2fae81e740f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/chkfeat-1.c @@ -0,0 +1,75 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mbranch-protection=none" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +**foo1: +** mov x16, 1 +** hint40 // chkfeat x16 +** mov x0, x16 +** ret +*/ +unsigned long long +foo1 (void) +{ + return __builtin_aarch64_chkfeat (1); +} + +/* +**foo2: +** mov x16, 1 +** movkx16, 0x5678, lsl 32 +** movkx16, 0x1234, lsl 48 +** hint40 // chkfeat x16 +** mov x0, x16 +** ret +*/ +unsigned long long +foo2 (void) +{ + return __builtin_aarch64_chkfeat (0x123456780001); +} + +/* +**foo3: +** mov x16, x0 +** hint40 // chkfeat x16 +** mov x0, x16 +** ret +*/ +unsigned long long +foo3 (unsigned long long x) +{ + return __builtin_aarch64_chkfeat (x); +} + +/* +**foo4: +** ldr x16, \[x0\] +** hint40 // chkfeat x16 +** str x16, \[x0\] +** ret +*/ +void +foo4 (unsigned long long *p) +{ + *p = __builtin_aarch64_chkfeat (*p); +} + +/* +**foo5: +** mov x16, 1 +** hint40 // chkfeat x16 +** cmp x16, 0 +**( +** cselw0, w1, w0, eq +**| +** cselw0, w0, w1, ne +**) +** ret +*/ +int +foo5 (int x, int y) +{ + return __builtin_aarch64_chkfeat (1) ? x : y; +} diff --git a/gcc/testsuite/gcc.target/aarch64/chkfeat-2.c b/gcc/testsuite/gcc.target/aarch64/chkfeat-2.c new file mode 100644 index 000..682524e244f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/chkfeat-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times {hint\t40 // chkfeat x16} 2 } } */ + +void bar (void); + +/* Extern call may change enabled HW features. */ +unsigned long long +foo (void) +{ + unsigned long long a = __builtin_aarch64_chkfeat (1); + bar (); + unsigned long long b = __builtin_aarch64_chkfeat (1); + return a + b; +}
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add GCS builtins
https://gcc.gnu.org/g:4880a14b6222839396bcb93ee27669db4e88ff01 commit 4880a14b6222839396bcb93ee27669db4e88ff01 Author: Szabolcs Nagy Date: Tue May 9 16:21:28 2023 +0100 aarch64: Add GCS builtins Add new builtins for GCS: void *__builtin_aarch64_gcspr (void) uint64_t __builtin_aarch64_gcspopm (void) void *__builtin_aarch64_gcsss (void *) The builtins are always enabled, but should be used behind runtime checks in case the target does not support GCS. They are thin wrappers around the corresponding instructions. The GCS pointer is modelled with void * type (normal stores do not work on GCS memory, but it is writable via the gcsss operation or via GCSSTR if enabled so not const) and an entry on the GCS is modelled with uint64_t (since it has fixed size and can be a token that's not a pointer). gcc/ChangeLog: * config/aarch64/aarch64-builtins.cc (enum aarch64_builtins): Add AARCH64_BUILTIN_GCSPR, AARCH64_BUILTIN_GCSPOPM, AARCH64_BUILTIN_GCSSS. (aarch64_init_gcs_builtins): New. (aarch64_general_init_builtins): Call aarch64_init_gcs_builtins. (aarch64_expand_gcs_builtin): New. (aarch64_general_expand_builtin): Call aarch64_expand_gcs_builtin. Diff: --- gcc/config/aarch64/aarch64-builtins.cc | 70 ++ 1 file changed, 70 insertions(+) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 1c08f56ab6b..30c977586f9 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -790,6 +790,9 @@ enum aarch64_builtins AARCH64_PLIX, /* Armv8.9-A / Armv9.4-A builtins. */ AARCH64_BUILTIN_CHKFEAT, + AARCH64_BUILTIN_GCSPR, + AARCH64_BUILTIN_GCSPOPM, + AARCH64_BUILTIN_GCSSS, AARCH64_BUILTIN_MAX }; @@ -2041,6 +2044,29 @@ aarch64_init_fpsr_fpcr_builtins (void) AARCH64_BUILTIN_SET_FPSR64); } +/* Add builtins for Guarded Control Stack instructions. */ + +static void +aarch64_init_gcs_builtins (void) +{ + tree ftype; + + ftype = build_function_type_list (ptr_type_node, NULL); + aarch64_builtin_decls[AARCH64_BUILTIN_GCSPR] += aarch64_general_add_builtin ("__builtin_aarch64_gcspr", ftype, + AARCH64_BUILTIN_GCSPR); + + ftype = build_function_type_list (uint64_type_node, NULL); + aarch64_builtin_decls[AARCH64_BUILTIN_GCSPOPM] += aarch64_general_add_builtin ("__builtin_aarch64_gcspopm", ftype, + AARCH64_BUILTIN_GCSPOPM); + + ftype = build_function_type_list (ptr_type_node, ptr_type_node, NULL); + aarch64_builtin_decls[AARCH64_BUILTIN_GCSSS] += aarch64_general_add_builtin ("__builtin_aarch64_gcsss", ftype, + AARCH64_BUILTIN_GCSSS); +} + /* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */ void @@ -2092,6 +2118,8 @@ aarch64_general_init_builtins (void) = aarch64_general_add_builtin ("__builtin_aarch64_chkfeat", ftype_chkfeat, AARCH64_BUILTIN_CHKFEAT); + aarch64_init_gcs_builtins (); + if (in_lto_p) handle_arm_acle_h (); } @@ -3020,6 +3048,43 @@ aarch64_expand_fpsr_fpcr_getter (enum insn_code icode, machine_mode mode, return op.value; } +/* Expand GCS builtin EXP with code FCODE, putting the result + int TARGET. If IGNORE is true the return value is ignored. */ + +rtx +aarch64_expand_gcs_builtin (tree exp, rtx target, int fcode, int ignore) +{ + if (fcode == AARCH64_BUILTIN_GCSPR) +{ + expand_operand op; + create_output_operand (&op, target, DImode); + expand_insn (CODE_FOR_aarch64_load_gcspr, 1, &op); + return op.value; +} + if (fcode == AARCH64_BUILTIN_GCSPOPM && ignore) +{ + expand_insn (CODE_FOR_aarch64_gcspopm_xzr, 0, 0); + return target; +} + if (fcode == AARCH64_BUILTIN_GCSPOPM) +{ + expand_operand op; + create_output_operand (&op, target, Pmode); + expand_insn (CODE_FOR_aarch64_gcspopm, 1, &op); + return op.value; +} + if (fcode == AARCH64_BUILTIN_GCSSS) +{ + expand_operand ops[2]; + rtx op1 = expand_normal (CALL_EXPR_ARG (exp, 0)); + create_output_operand (&ops[0], target, Pmode); + create_input_operand (&ops[1], op1, Pmode); + expand_insn (CODE_FOR_aarch64_gcsss, 2, ops); + return ops[0].value; +} + gcc_unreachable (); +} + /* Expand an expression EXP that calls built-in function FCODE, with result going to TARGET if that's convenient. IGNORE is true if the result of the builtin is ignored. */ @@ -3155,6 +3220,11 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target, emit_move_insn (target, x16_reg); return target; } + +case AARCH64_BUILTIN_GCSPR: +case AARCH64_BUILTIN_GCSPOPM: +case AARCH64_BUILTIN_GCSSS: +
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add __builtin_aarch64_gcs* tests
https://gcc.gnu.org/g:90ff9175ede4f4671755f0296b5ce89d8d69f966 commit 90ff9175ede4f4671755f0296b5ce89d8d69f966 Author: Szabolcs Nagy Date: Tue Jun 6 17:35:51 2023 +0100 aarch64: Add __builtin_aarch64_gcs* tests gcc/testsuite/ChangeLog: * gcc.target/aarch64/gcspopm-1.c: New test. * gcc.target/aarch64/gcspr-1.c: New test. * gcc.target/aarch64/gcsss-1.c: New test. Diff: --- gcc/testsuite/gcc.target/aarch64/gcspopm-1.c | 69 gcc/testsuite/gcc.target/aarch64/gcspr-1.c | 31 + gcc/testsuite/gcc.target/aarch64/gcsss-1.c | 49 3 files changed, 149 insertions(+) diff --git a/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c new file mode 100644 index 000..6e6add39cf7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c @@ -0,0 +1,69 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mbranch-protection=none" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +**foo1: +** syslxzr, #3, c7, c7, #1 // gcspopm +** ret +*/ +void +foo1 (void) +{ + __builtin_aarch64_gcspopm (); +} + +/* +**foo2: +** mov x0, 0 +** syslx0, #3, c7, c7, #1 // gcspopm +** ret +*/ +unsigned long long +foo2 (void) +{ + return __builtin_aarch64_gcspopm (); +} + +/* +**foo3: +** mov x16, 1 +** ( +** mov x0, 0 +** hint40 // chkfeat x16 +** | +** hint40 // chkfeat x16 +** mov x0, 0 +** ) +** cbz x16, .* +** ret +** mov x0, 0 +** syslx0, #3, c7, c7, #1 // gcspopm +** ret +*/ +unsigned long long +foo3 (void) +{ + if (__builtin_aarch64_chkfeat (1) == 0) +return __builtin_aarch64_gcspopm (); + return 0; +} + +/* +**foo4: +** syslxzr, #3, c7, c7, #1 // gcspopm +** mov x0, 0 +** syslx0, #3, c7, c7, #1 // gcspopm +** syslxzr, #3, c7, c7, #1 // gcspopm +** ret +*/ +unsigned long long +foo4 (void) +{ + unsigned long long a = __builtin_aarch64_gcspopm (); + unsigned long long b = __builtin_aarch64_gcspopm (); + unsigned long long c = __builtin_aarch64_gcspopm (); + (void) a; + (void) c; + return b; +} diff --git a/gcc/testsuite/gcc.target/aarch64/gcspr-1.c b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c new file mode 100644 index 000..0e651979551 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mbranch-protection=none" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +**foo1: +** mrs x0, s3_3_c2_c5_1 // gcspr_el0 +** ret +*/ +void * +foo1 (void) +{ + return __builtin_aarch64_gcspr (); +} + +/* +**foo2: +** mrs x[0-9]*, s3_3_c2_c5_1 // gcspr_el0 +** syslxzr, #3, c7, c7, #1 // gcspopm +** mrs x[0-9]*, s3_3_c2_c5_1 // gcspr_el0 +** sub x0, x[0-9]*, x[0-9]* +** ret +*/ +long +foo2 (void) +{ + const char *p = __builtin_aarch64_gcspr (); + __builtin_aarch64_gcspopm (); + const char *q = __builtin_aarch64_gcspr (); + return p - q; +} diff --git a/gcc/testsuite/gcc.target/aarch64/gcsss-1.c b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c new file mode 100644 index 000..025c7fee647 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mbranch-protection=none" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +**foo1: +** sys #3, c7, c7, #2, x0 // gcsss1 +** mov x[0-9]*, 0 +** syslx[0-9]*, #3, c7, c7, #3 // gcsss2 +** ret +*/ +void +foo1 (void *p) +{ + __builtin_aarch64_gcsss (p); +} + +/* +**foo2: +** sys #3, c7, c7, #2, x0 // gcsss1 +** mov x0, 0 +** syslx0, #3, c7, c7, #3 // gcsss2 +** ret +*/ +void * +foo2 (void *p) +{ + return __builtin_aarch64_gcsss (p); +} + +/* +**foo3: +** mov x16, 1 +** hint40 // chkfeat x16 +** cbnzx16, .* +** sys #3, c7, c7, #2, x0 // gcsss1 +** mov x0, 0 +** syslx0, #3, c7, c7, #3 // gcsss2 +** ret +** mov x0, 0 +** ret +*/ +void * +foo3 (void *p) +{ + if (__builtin_aarch64_chkfeat (1) == 0) +return __builtin_aarch64_gcsss (p); + return 0; +}
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add non-local goto and jump tests for GCS
https://gcc.gnu.org/g:87217fd89a9bd595a58897bafc593a7e25051ee4 commit 87217fd89a9bd595a58897bafc593a7e25051ee4 Author: Szabolcs Nagy Date: Wed Jun 7 10:58:06 2023 +0100 aarch64: Add non-local goto and jump tests for GCS These are scan asm tests only, relying on existing execution tests for runtime coverage. gcc/testsuite/ChangeLog: * gcc.target/aarch64/gcs-nonlocal-1.c: New test. * gcc.target/aarch64/gcs-nonlocal-2.c: New test. Diff: --- gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-1.c | 25 +++ gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-2.c | 21 +++ 2 files changed, 46 insertions(+) diff --git a/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-1.c b/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-1.c new file mode 100644 index 000..821fab816f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-1.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mbranch-protection=gcs" } */ +/* { dg-final { scan-assembler-times "hint\\t40 // chkfeat x16" 2 } } */ +/* { dg-final { scan-assembler-times "mrs\\tx\[0-9\]+, s3_3_c2_c5_1 // gcspr_el0" 2 } } */ +/* { dg-final { scan-assembler-times "sysl\\txzr, #3, c7, c7, #1 // gcspopm" 1 } } */ + +int bar1 (int); +int bar2 (int); + +void foo (int cmd) +{ + __label__ start; + int x = 0; + + void nonlocal_goto (void) + { +x++; +goto start; + } + +start: + while (bar1 (x)) +if (bar2 (x)) + nonlocal_goto (); +} diff --git a/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-2.c b/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-2.c new file mode 100644 index 000..63dbce36e1e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-2.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mbranch-protection=gcs" } */ +/* { dg-final { scan-assembler-times "hint\\t40 // chkfeat x16" 2 } } */ +/* { dg-final { scan-assembler-times "mrs\\tx\[0-9\]+, s3_3_c2_c5_1 // gcspr_el0" 2 } } */ +/* { dg-final { scan-assembler-times "sysl\\txzr, #3, c7, c7, #1 // gcspopm" 1 } } */ + +void longj (void *buf) +{ + __builtin_longjmp (buf, 1); +} + +void foo (void); +void bar (void); + +void setj (void *buf) +{ + if (__builtin_setjmp (buf)) +foo (); + else +bar (); +}
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add GCS instructions
https://gcc.gnu.org/g:57aec9c418f837bf427d8317bebdc0f825cbb043 commit 57aec9c418f837bf427d8317bebdc0f825cbb043 Author: Szabolcs Nagy Date: Tue May 9 16:00:01 2023 +0100 aarch64: Add GCS instructions Add instructions for the Guarded Control Stack extension. GCSSS1 and GCSSS2 are modelled as a single GCSSS unspec, because they are always used together in the compiler. Before GCSPOPM and GCSSS2 an extra "mov xn, 0" is added to clear the output register, this is needed to get reasonable result when GCS is disabled, when the instructions are NOPs. Since the instructions are expecetd to be used behind runtime feature checks, this is mainly relevant if GCS can be disabled asynchronously. The output of GCSPOPM is usually not needed, so a separate gcspopm_xzr was added to model that. Did not do the same for GCSSS as it is a less common operation. The used mnemonics do not depend on updated assembler since these instructions can be used without new -march setting behind a runtime check. Reading the GCSPR is modelled as unspec_volatile so it does not get reordered wrt the other instructions changing the GCSPR. TODO: - Do we care about async disable? - Do we need GCSSS_xzr? (to avoid the mov x,0) gcc/ChangeLog: * config/aarch64/aarch64.md (aarch64_load_gcspr): New. (aarch64_gcspopm): New. (aarch64_gcspopm_xzr): New. (aarch64_gcsss): New. Diff: --- gcc/config/aarch64/aarch64.md | 35 +++ 1 file changed, 35 insertions(+) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index a20462303b5..8defd6e0582 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -379,6 +379,9 @@ UNSPECV_BTI_J ; Represent BTI j. UNSPECV_BTI_JC ; Represent BTI jc. UNSPECV_CHKFEAT; Represent CHKFEAT X16. +UNSPECV_GCSPR ; Represent MRS Xn, GCSPR_EL0 +UNSPECV_GCSPOPM; Represent GCSPOPM. +UNSPECV_GCSSS ; Represent GCSSS1 and GCSSS2. UNSPECV_TSTART ; Represent transaction start. UNSPECV_TCOMMIT; Represent transaction commit. UNSPECV_TCANCEL; Represent transaction cancel. @@ -8267,6 +8270,38 @@ "hint\\t40 // chkfeat x16" ) +;; Guarded Control Stack (GCS) instructions +(define_insn "aarch64_load_gcspr" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec_volatile:DI [(const_int 0)] UNSPECV_GCSPR))] + "" + "mrs\\t%0, s3_3_c2_c5_1 // gcspr_el0" + [(set_attr "type" "mrs")] +) + +(define_insn "aarch64_gcspopm" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec_volatile:DI [(const_int 0)] UNSPECV_GCSPOPM))] + "" + "mov\\t%0, 0\;sysl\\t%0, #3, c7, c7, #1 // gcspopm" + [(set_attr "length" "8")] +) + +(define_insn "aarch64_gcspopm_xzr" + [(unspec_volatile [(const_int 0)] UNSPECV_GCSPOPM)] + "" + "sysl\\txzr, #3, c7, c7, #1 // gcspopm" +) + +(define_insn "aarch64_gcsss" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")] + UNSPECV_GCSSS))] + "" + "sys\\t#3, c7, c7, #2, %1 // gcsss1\;mov\\t%0, 0\;sysl\\t%0, #3, c7, c7, #3 // gcsss2" + [(set_attr "length" "12")] +) + ;; AdvSIMD Stuff (include "aarch64-simd.md")
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add ACLE feature macros for GCS
https://gcc.gnu.org/g:f94cfdab086f521592939f03408f59f39a4bdd5a commit f94cfdab086f521592939f03408f59f39a4bdd5a Author: Szabolcs Nagy Date: Tue May 9 17:04:34 2023 +0100 aarch64: Add ACLE feature macros for GCS gcc/ChangeLog: * config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): Define macros for GCS. Diff: --- gcc/config/aarch64/aarch64-c.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc index fe1a20e4e54..64c34e73573 100644 --- a/gcc/config/aarch64/aarch64-c.cc +++ b/gcc/config/aarch64/aarch64-c.cc @@ -246,6 +246,9 @@ aarch64_update_cpp_builtins (cpp_reader *pfile) aarch64_def_or_undef (TARGET_PAUTH, "__ARM_FEATURE_PAUTH", pfile); aarch64_def_or_undef (TARGET_BTI, "__ARM_FEATURE_BTI", pfile); + aarch64_def_or_undef (aarch64_gcs_enabled (), + "__ARM_FEATURE_GCS_DEFAULT", pfile); + aarch64_def_or_undef (TARGET_GCS, "__ARM_FEATURE_GCS", pfile); aarch64_def_or_undef (TARGET_I8MM, "__ARM_FEATURE_MATMUL_INT8", pfile); aarch64_def_or_undef (TARGET_BF16_SIMD, "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile);
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add GCS support for nonlocal stack save
https://gcc.gnu.org/g:d5a22a53f58403c888a43c75c5983ba3cb5023ae commit d5a22a53f58403c888a43c75c5983ba3cb5023ae Author: Szabolcs Nagy Date: Fri Apr 14 18:23:52 2023 +0100 aarch64: Add GCS support for nonlocal stack save Nonlocal stack save and restore has to also save and restore the GCS pointer. This is used in __builtin_setjmp/longjmp and nonlocal goto. The GCS specific code is only emitted if GCS branch-protection is enabled and the code always checks at runtime if GCS is enabled. The new -mbranch-protection=gcs and old -mbranch-protection=none code are ABI compatible: jmpbuf for __builtin_setjmp has space for 5 pointers, the layout is old layout: fp, pc, sp, unused, unused new layout: fp, pc, sp, gcsp, unused Note: the ILP32 code generation is wrong as it saves the pointers with Pmode (i.e. 8 bytes per pointer), but the user supplied buffer size is for 5 pointers (4 bytes per pointer), this is not fixed. The nonlocal goto has no ABI compatibility issues as the goto and its destination are in the same translation unit. TODO: - can we simplify the define_expand rtls? gcc/ChangeLog: * config/aarch64/aarch64.h (STACK_SAVEAREA_MODE): Make space for gcs. * config/aarch64/aarch64.md (save_stack_nonlocal): New. (restore_stack_nonlocal): New. Diff: --- gcc/config/aarch64/aarch64.h | 7 gcc/config/aarch64/aarch64.md | 82 +++ 2 files changed, 89 insertions(+) diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 45e901cda64..3238452f53f 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -1294,6 +1294,13 @@ typedef struct #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ ((VALUE) = GET_MODE_UNIT_BITSIZE (MODE), 2) +/* Have space for both SP and GCSPR in the NONLOCAL case in + emit_stack_save as well as in __builtin_setjmp, __builtin_longjmp + and __builtin_nonlocal_goto. + Note: On ILP32 the documented buf size is not enough PR84150. */ +#define STACK_SAVEAREA_MODE(LEVEL) \ + ((LEVEL) == SAVE_NONLOCAL ? TImode : Pmode) + #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM) #define RETURN_ADDR_RTX aarch64_return_addr diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 8defd6e0582..2d36af12cfb 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1183,6 +1183,88 @@ (const_int 1)))] ) +(define_expand "save_stack_nonlocal" + [(set (match_operand 0 "memory_operand") +(match_operand 1 "register_operand"))] + "" +{ + rtx stack_slot = adjust_address (operands[0], Pmode, 0); + emit_move_insn (stack_slot, operands[1]); + + if (aarch64_gcs_enabled ()) +{ + /* Save GCS with code like + mov x16, 1 + chkfeat x16 + tbnzx16, 0, .L_done + mrs tmp, gcspr_el0 + str tmp, [%0, 8] + .L_done: */ + + rtx done_label = gen_label_rtx (); + rtx r16 = gen_rtx_REG (DImode, R16_REGNUM); + emit_move_insn (r16, const1_rtx); + emit_insn (gen_aarch64_chkfeat ()); + emit_insn (gen_tbranch_neqi3 (r16, const0_rtx, done_label)); + rtx gcs_slot = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode)); + rtx gcs = force_reg (Pmode, const0_rtx); + emit_insn (gen_aarch64_load_gcspr (gcs)); + emit_move_insn (gcs_slot, gcs); + emit_label (done_label); +} + DONE; +}) + +(define_expand "restore_stack_nonlocal" + [(set (match_operand 0 "register_operand" "") + (match_operand 1 "memory_operand" ""))] + "" +{ + rtx stack_slot = adjust_address (operands[1], Pmode, 0); + emit_move_insn (operands[0], stack_slot); + + if (aarch64_gcs_enabled ()) +{ + /* Restore GCS with code like + mov x16, 1 + chkfeat x16 + tbnzx16, 0, .L_done + ldr tmp1, [%1, 8] + mrs tmp2, gcspr_el0 + substmp2, tmp1, tmp2 + b.eq.L_done + .L_loop: + gcspopm + substmp2, tmp2, 8 + b.ne.L_loop + .L_done: */ + + rtx loop_label = gen_label_rtx (); + rtx done_label = gen_label_rtx (); + rtx r16 = gen_rtx_REG (DImode, R16_REGNUM); + emit_move_insn (r16, const1_rtx); + emit_insn (gen_aarch64_chkfeat ()); + emit_insn (gen_tbranch_neqi3 (r16, const0_rtx, done_label)); + rtx gcs_slot = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode)); + rtx gcs_old = force_reg (Pmode, const0_rtx); + emit_move_insn (gcs_old, gcs_slot); + rtx gcs_now = force_reg (Pmode, const0_rtx); + emit_insn (gen_aarch64_load_gcspr (gcs_now)); + emit_insn (gen_subdi3_compare1 (gcs_now, gcs_old, gcs_now)); +
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add GCS support to the unwinder
https://gcc.gnu.org/g:2185dc7cdb6d536e4d9a49a77c552e58041cb0bc commit 2185dc7cdb6d536e4d9a49a77c552e58041cb0bc Author: Szabolcs Nagy Date: Wed Apr 19 14:01:36 2023 +0100 aarch64: Add GCS support to the unwinder TODO: - Follows the current linux ABI that uses single signal entry token and shared shadow stack between thread and alt stack. - Could be behind __ARM_FEATURE_GCS_DEFAULT ifdef (only do anything special with gcs compat codegen) but there is a runtime check anyway. libgcc/ChangeLog: * config/aarch64/aarch64-unwind.h (_Unwind_Frames_Extra): Update. (_Unwind_Frames_Increment): Define. Diff: --- libgcc/config/aarch64/aarch64-unwind.h | 59 +- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h index daf96624b5e..c22a3fc20d2 100644 --- a/libgcc/config/aarch64/aarch64-unwind.h +++ b/libgcc/config/aarch64/aarch64-unwind.h @@ -78,6 +78,9 @@ aarch64_demangle_return_addr (struct _Unwind_Context *context, return addr; } +/* GCS enable flag for chkfeat instruction. */ +#define CHKFEAT_GCS 1 + /* SME runtime function local to libgcc, streaming compatible and preserves more registers than the base PCS requires, but we don't rely on that here. */ @@ -85,12 +88,66 @@ __attribute__ ((visibility ("hidden"))) void __libgcc_arm_za_disable (void); /* Disable the SME ZA state in case an unwound frame used the ZA - lazy saving scheme. */ + lazy saving scheme. And unwind the GCS for EH. */ #undef _Unwind_Frames_Extra #define _Unwind_Frames_Extra(x)\ do \ { \ __libgcc_arm_za_disable (); \ + if (__builtin_aarch64_chkfeat (CHKFEAT_GCS) == 0)\ + { \ + for (_Unwind_Word n = (x); n != 0; n--) \ + __builtin_aarch64_gcspopm (); \ + } \ +} \ + while (0) + +/* On signal entry the OS places a token on the GCS that can be used to + verify the integrity of the GCS pointer on signal return. It also + places the signal handler return address (the restorer that calls the + signal return syscall) on the GCS so the handler can return. + Because of this token, each stack frame visited during unwinding has + exactly one corresponding entry on the GCS, so the frame count is + the number of entries that will have to be popped at EH return time. + + Note: This depends on the GCS signal ABI of the OS. + + When unwinding across a stack frame for each frame the corresponding + entry is checked on the GCS against the computed return address from + the normal stack. If they don't match then _URC_FATAL_PHASE2_ERROR + is returned. This check is omitted if + + 1. GCS is disabled. Note: asynchronous GCS disable is supported here + if GCSPR and the GCS remains readable. + 2. Non-catchable exception where exception_class == 0. Note: the + pthread cancellation implementation in glibc sets exception_class + to 0 when the unwinder is used for cancellation cleanup handling, + so this allows the GCS to get out of sync during cancellation. + This weakens security but avoids an ABI break in glibc. + 3. Zero return address which marks the outermost stack frame. + 4. Signal stack frame, the GCS entry is an OS specific token then + with the top bit set. + */ +#undef _Unwind_Frames_Increment +#define _Unwind_Frames_Increment(exc, context, frames) \ + do \ +{ \ + frames++;\ + if (__builtin_aarch64_chkfeat (CHKFEAT_GCS) != 0 \ + || exc->exception_class == 0 \ + || _Unwind_GetIP (context) == 0) \ + break; \ + const _Unwind_Word *gcs = __builtin_aarch64_gcspr (); \ + if (_Unwind_IsSignalFrame (context)) \ + { \ + if (gcs[frames] >> 63 == 0) \ + return _URC_FATAL_PHASE2_ERROR; \ + } \ + else \ + { \ + if (gcs[frames] != _Unwind_GetIP (context)) \ + return _URC_FATAL_PHASE2_ERROR; \ + } \ } \ while (0)
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add test for GCS ACLE defs
https://gcc.gnu.org/g:2a9d500c8f2fd1004cdcbcdec063681dbb0bb1f1 commit 2a9d500c8f2fd1004cdcbcdec063681dbb0bb1f1 Author: Szabolcs Nagy Date: Wed Jun 7 16:17:53 2023 +0100 aarch64: Add test for GCS ACLE defs gcc/testsuite/ChangeLog: * gcc.target/aarch64/pragma_cpp_predefs_1.c: GCS test. Diff: --- .../gcc.target/aarch64/pragma_cpp_predefs_1.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c index 307fa3d67da..6122cd55d66 100644 --- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c +++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c @@ -268,6 +268,36 @@ #error "__ARM_FEATURE_RCPC is not defined but should be!" #endif +#pragma GCC target ("arch=armv8.8-a+gcs") +#ifndef __ARM_FEATURE_GCS +#error "__ARM_FEATURE_GCS is not defined but should be!" +#endif + +#pragma GCC target ("arch=armv8.8-a+nogcs") +#ifdef __ARM_FEATURE_GCS +#error "__ARM_FEATURE_GCS is defined but should not be!" +#endif + +#pragma GCC target ("arch=armv8.8-a") +#ifdef __ARM_FEATURE_GCS +#error "__ARM_FEATURE_GCS is defined but should not be!" +#endif + +#pragma GCC target ("branch-protection=gcs") +#ifndef __ARM_FEATURE_GCS_DEFAULT +#error "__ARM_FEATURE_GCS_DEFAULT is not defined but should be!" +#endif + +#pragma GCC target ("branch-protection=none") +#ifdef __ARM_FEATURE_GCS_DEFAULT +#error "__ARM_FEATURE_GCS_DEFAULT is defined but should not be!" +#endif + +#pragma GCC target ("branch-protection=standard") +#ifndef __ARM_FEATURE_GCS_DEFAULT +#error "__ARM_FEATURE_GCS_DEFAULT is not defined but should be!" +#endif + int foo (int a) {
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: libgcc: add GCS marking to asm
https://gcc.gnu.org/g:b32a17f9f43d68859e31d7a6af7b21ac2ed42742 commit b32a17f9f43d68859e31d7a6af7b21ac2ed42742 Author: Szabolcs Nagy Date: Fri Dec 22 13:44:19 2023 + aarch64: libgcc: add GCS marking to asm libgcc/ChangeLog: * config/aarch64/aarch64-asm.h (FEATURE_1_GCS): Define. (GCS_FLAG): Define if GCS is enabled. (GNU_PROPERTY): Add GCS_FLAG. Diff: --- libgcc/config/aarch64/aarch64-asm.h | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libgcc/config/aarch64/aarch64-asm.h b/libgcc/config/aarch64/aarch64-asm.h index 83c2e5944b3..86a9a0e662e 100644 --- a/libgcc/config/aarch64/aarch64-asm.h +++ b/libgcc/config/aarch64/aarch64-asm.h @@ -38,6 +38,7 @@ #define FEATURE_1_AND 0xc000 #define FEATURE_1_BTI 1 #define FEATURE_1_PAC 2 +#define FEATURE_1_GCS 4 /* Supported features based on the code generation options. */ #if defined(__ARM_FEATURE_BTI_DEFAULT) @@ -58,6 +59,12 @@ # define AUTIASP #endif +#if __ARM_FEATURE_GCS_DEFAULT +# define GCS_FLAG FEATURE_1_GCS +#else +# define GCS_FLAG 0 +#endif + #ifdef __ELF__ #define HIDDEN(name) .hidden name #define SYMBOL_SIZE(name) .size name, .-name @@ -88,8 +95,8 @@ .previous /* Add GNU property note if built with branch protection. */ -# if (BTI_FLAG|PAC_FLAG) != 0 -GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG) +# if (BTI_FLAG|PAC_FLAG|GCS_FLAG) != 0 +GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG|GCS_FLAG) # endif #endif
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Emit GNU property NOTE for GCS
https://gcc.gnu.org/g:99a291c0313e8e839c3ffd1fdc5132b4d6462968 commit 99a291c0313e8e839c3ffd1fdc5132b4d6462968 Author: Szabolcs Nagy Date: Tue May 9 14:32:46 2023 +0100 aarch64: Emit GNU property NOTE for GCS TODO: relies on experimental binutils ABI, should use build attributes. gcc/ChangeLog: * config/aarch64/aarch64.cc (GNU_PROPERTY_AARCH64_FEATURE_1_GCS): Define. (aarch64_file_end_indicate_exec_stack): Set GCS property bit. Diff: --- gcc/config/aarch64/aarch64.cc | 5 + 1 file changed, 5 insertions(+) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 73969721906..0119cfdd67b 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -28962,6 +28962,7 @@ aarch64_can_tag_addresses () #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc000 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) +#define GNU_PROPERTY_AARCH64_FEATURE_1_GCS (1U << 2) void aarch64_file_end_indicate_exec_stack () { @@ -28974,6 +28975,9 @@ aarch64_file_end_indicate_exec_stack () if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE) feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC; + if (aarch64_gcs_enabled ()) +feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_GCS; + if (feature_1_and) { /* Generate .note.gnu.property section. */ @@ -29005,6 +29009,7 @@ aarch64_file_end_indicate_exec_stack () assemble_align (POINTER_SIZE); } } +#undef GNU_PROPERTY_AARCH64_FEATURE_1_GCS #undef GNU_PROPERTY_AARCH64_FEATURE_1_PAC #undef GNU_PROPERTY_AARCH64_FEATURE_1_BTI #undef GNU_PROPERTY_AARCH64_FEATURE_1_AND
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: libatomic: add GCS marking to asm
https://gcc.gnu.org/g:78b29b5934193bd7e057aa8196ab8645df092d44 commit 78b29b5934193bd7e057aa8196ab8645df092d44 Author: Szabolcs Nagy Date: Fri Dec 22 15:11:25 2023 + aarch64: libatomic: add GCS marking to asm libatomic/ChangeLog: * config/linux/aarch64/atomic_16.S (FEATURE_1_GCS): Define. (GCS_FLAG): Define if GCS is enabled. (GNU_PROPERTY): Add GCS_FLAG. Diff: --- libatomic/config/linux/aarch64/atomic_16.S | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libatomic/config/linux/aarch64/atomic_16.S b/libatomic/config/linux/aarch64/atomic_16.S index 4e3fa870b03..d6f34eee146 100644 --- a/libatomic/config/linux/aarch64/atomic_16.S +++ b/libatomic/config/linux/aarch64/atomic_16.S @@ -790,6 +790,7 @@ ALIAS2 (test_and_set_16) #define FEATURE_1_AND 0xc000 #define FEATURE_1_BTI 1 #define FEATURE_1_PAC 2 +#define FEATURE_1_GCS 4 /* Supported features based on the code generation options. */ #if defined(__ARM_FEATURE_BTI_DEFAULT) @@ -804,6 +805,12 @@ ALIAS2 (test_and_set_16) # define PAC_FLAG 0 #endif +#if __ARM_FEATURE_GCS_DEFAULT +# define GCS_FLAG FEATURE_1_GCS +#else +# define GCS_FLAG 0 +#endif + /* Add a NT_GNU_PROPERTY_TYPE_0 note. */ #define GNU_PROPERTY(type, value) \ .section .note.gnu.property, "a"; \ @@ -821,7 +828,7 @@ ALIAS2 (test_and_set_16) .section .note.GNU-stack, "", %progbits /* Add GNU property note if built with branch protection. */ -# if (BTI_FLAG|PAC_FLAG) != 0 -GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG) +# if (BTI_FLAG|PAC_FLAG|GCS_FLAG) != 0 +GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG|GCS_FLAG) # endif #endif
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: libitm: Add GCS support
https://gcc.gnu.org/g:9f2fe2932ca35b736685753a85bd5c43459f24de commit 9f2fe2932ca35b736685753a85bd5c43459f24de Author: Szabolcs Nagy Date: Tue Apr 2 15:43:23 2024 +0100 aarch64: libitm: Add GCS support Transaction begin and abort use setjmp/longjmp like operations that need to be updated for GCS compatibility. We use similar logic to libc setjmp/longjmp that support switching stack and thus switching GCS (e.g. due to longjmp out of a makecontext stack), this is kept even though it is likely not required for transaction aborts. The gtm_jmpbuf is internal to libitm so we can change its layout without breaking ABI. libitm/ChangeLog: * config/aarch64/sjlj.S: Add GCS support and mark GCS compatible. * config/aarch64/target.h: Add gcs field to gtm_jmpbuf. Diff: --- libitm/config/aarch64/sjlj.S | 60 +++--- libitm/config/aarch64/target.h | 1 + 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/libitm/config/aarch64/sjlj.S b/libitm/config/aarch64/sjlj.S index 6b248f7c040..e21d751ef21 100644 --- a/libitm/config/aarch64/sjlj.S +++ b/libitm/config/aarch64/sjlj.S @@ -29,6 +29,13 @@ #define AUTIASPhint29 #define PACIBSPhint27 #define AUTIBSPhint31 +#define CHKFEAT_X16hint40 +#define MRS_GCSPR(x) mrs x, s3_3_c2_c5_1 +#define GCSPOPM(x) syslx, #3, c7, c7, #1 +#define GCSSS1(x) sys #3, c7, c7, #2, x +#define GCSSS2(x) syslx, #3, c7, c7, #3 + +#define L(name) .L##name #if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__GCC_HAVE_DWARF2_CFI_ASM) # define cfi_window_save .cfi_window_save @@ -80,7 +87,16 @@ _ITM_beginTransaction: stp d10, d11, [sp, 7*16] stp d12, d13, [sp, 8*16] stp d14, d15, [sp, 9*16] - str x1, [sp, 10*16] + + /* GCS support. */ + mov x2, 0 + mov x16, 1 + CHKFEAT_X16 + tbnzx16, 0, L(gcs_done_sj) + MRS_GCSPR (x2) + add x2, x2, 8 /* GCS after _ITM_beginTransaction returns. */ +L(gcs_done_sj): + stp x2, x1, [sp, 10*16] /* Invoke GTM_begin_transaction with the struct we just built. */ mov x1, sp @@ -117,7 +133,38 @@ GTM_longjmp: ldp d10, d11, [x1, 7*16] ldp d12, d13, [x1, 8*16] ldp d14, d15, [x1, 9*16] + + /* GCS support. */ + mov x16, 1 + CHKFEAT_X16 + tbnzx16, 0, L(gcs_done_lj) + MRS_GCSPR (x7) ldr x3, [x1, 10*16] + mov x4, x3 + /* x7: GCSPR now. x3, x4: target GCSPR. x5, x6: tmp regs. */ +L(gcs_scan): + cmp x7, x4 + b.eqL(gcs_pop) + sub x4, x4, 8 + /* Check for a cap token. */ + ldr x5, [x4] + and x6, x4, 0xf000 + orr x6, x6, 1 + cmp x5, x6 + b.neL(gcs_scan) +L(gcs_switch): + add x7, x4, 8 + GCSSS1 (x4) + GCSSS2 (xzr) +L(gcs_pop): + cmp x7, x3 + b.eqL(gcs_done_lj) + GCSPOPM (xzr) + add x7, x7, 8 + b L(gcs_pop) +L(gcs_done_lj): + + ldr x3, [x1, 10*16 + 8] ldp x29, x30, [x1] cfi_def_cfa(x1, 0) CFI_PAC_TOGGLE @@ -132,6 +179,7 @@ GTM_longjmp: #define FEATURE_1_AND 0xc000 #define FEATURE_1_BTI 1 #define FEATURE_1_PAC 2 +#define FEATURE_1_GCS 4 /* Supported features based on the code generation options. */ #if defined(__ARM_FEATURE_BTI_DEFAULT) @@ -146,6 +194,12 @@ GTM_longjmp: # define PAC_FLAG 0 #endif +#if __ARM_FEATURE_GCS_DEFAULT +# define GCS_FLAG FEATURE_1_GCS +#else +# define GCS_FLAG 0 +#endif + /* Add a NT_GNU_PROPERTY_TYPE_0 note. */ #define GNU_PROPERTY(type, value) \ .section .note.gnu.property, "a";\ @@ -163,7 +217,7 @@ GTM_longjmp: .section .note.GNU-stack, "", %progbits /* Add GNU property note if built with branch protection. */ -# if (BTI_FLAG|PAC_FLAG) != 0 -GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG) +# if (BTI_FLAG|PAC_FLAG|GCS_FLAG) != 0 +GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG|GCS_FLAG) # endif #endif diff --git a/libitm/config/aarch64/target.h b/libitm/config/aarch64/target.h index 3d99197bfab..a1f39b4bf7a 100644 --- a/libitm/config/aarch64/target.h +++ b/libitm/config/aarch64/target.h @@ -30,6 +30,7 @@ typedef struct gtm_jmpbuf unsigned long long pc; /* x30 */ unsigned long long gr[10]; /* x19-x28 */ unsigned long long vr[8];/* d8-d15 */ + void *gcs; /* GCSPR_EL0 */ void *cfa; } gtm_jmpbuf;
[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Introduce indirect_return attribute
https://gcc.gnu.org/g:3458fa6e8c32f128c666b49cfcb65dfdd52d7e43 commit 3458fa6e8c32f128c666b49cfcb65dfdd52d7e43 Author: Szabolcs Nagy Date: Thu Dec 28 13:37:38 2023 + aarch64: Introduce indirect_return attribute Tail calls of indirect_return functions from non-indirect_return functions are disallowed even if BTI is disabled, since the call site may have BTI enabled. Following x86, mismatching attribute on function pointers is not a type error even though this can lead to bugs. Needed for swapcontext within the same function when GCS is enabled. TODO: arm? docs, tests. feature detection? gcc/ChangeLog: * config/aarch64/aarch64.cc (aarch64_gnu_attributes): Add indirect_return. (aarch64_function_ok_for_sibcall): Disallow tail calls if caller is non-indirect_return but callee is indirect_return. (aarch64_comp_type_attributes): Check indirect_return attribute. * config/arm/aarch-bti-insert.cc (call_needs_bti_j): New. (rest_of_insert_bti): Use call_needs_bti_j. Diff: --- gcc/config/aarch64/aarch64.cc | 11 +++ gcc/config/arm/aarch-bti-insert.cc | 36 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 0119cfdd67b..593b107c8a5 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -850,6 +850,7 @@ static const attribute_spec aarch64_gnu_attributes[] = affects_type_identity, handler, exclude } */ { "aarch64_vector_pcs", 0, 0, false, true, true, true, handle_aarch64_vector_pcs_attribute, NULL }, + { "indirect_return",0, 0, false, true, true, false, NULL, NULL }, { "arm_sve_vector_bits", 1, 1, false, true, false, true, aarch64_sve::handle_arm_sve_vector_bits_attribute, NULL }, @@ -6340,6 +6341,14 @@ aarch64_function_ok_for_sibcall (tree, tree exp) if (bool (aarch64_cfun_shared_flags (state)) != bool (aarch64_fntype_shared_flags (fntype, state))) return false; + + /* BTI J is needed where indirect_return functions may return + if bti is enabled there. */ + if (lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (fntype)) + && !lookup_attribute ("indirect_return", + TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl +return false; + return true; } @@ -28855,6 +28864,8 @@ aarch64_comp_type_attributes (const_tree type1, const_tree type2) if (!check_attr ("gnu", "aarch64_vector_pcs")) return 0; + if (!check_attr ("gnu", "indirect_return")) +return 0; if (!check_attr ("gnu", "Advanced SIMD type")) return 0; if (!check_attr ("gnu", "SVE type")) diff --git a/gcc/config/arm/aarch-bti-insert.cc b/gcc/config/arm/aarch-bti-insert.cc index 14d36971cd4..403afff9120 100644 --- a/gcc/config/arm/aarch-bti-insert.cc +++ b/gcc/config/arm/aarch-bti-insert.cc @@ -92,6 +92,35 @@ const pass_data pass_data_insert_bti = 0, /* todo_flags_finish. */ }; +/* Decide if BTI J is needed after a call instruction. */ +static bool +call_needs_bti_j (rtx_insn *insn) +{ + /* Call returns twice, one of which may be indirect. */ + if (find_reg_note (insn, REG_SETJMP, NULL)) +return true; + + /* Tail call does not return. */ + if (SIBLING_CALL_P (insn)) +return false; + + /* Check if the function is marked to return indirectly. */ + rtx call = get_call_rtx_from (insn); + rtx fnaddr = XEXP (call, 0); + tree fndecl = NULL_TREE; + if (GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF) +fndecl = SYMBOL_REF_DECL (XEXP (fnaddr, 0)); + if (fndecl == NULL_TREE) +fndecl = MEM_EXPR (fnaddr); + if (!fndecl) +return false; + if (TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE + && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE) +return false; + tree fntype = TREE_TYPE (fndecl); + return lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (fntype)); +} + /* Insert the BTI instruction. */ /* This is implemented as a late RTL pass that runs before branch shortening and does the following. */ @@ -147,10 +176,9 @@ rest_of_insert_bti (void) } } - /* Also look for calls to setjmp () which would be marked with -REG_SETJMP note and put a BTI J after. This is where longjump () -will return. */ - if (CALL_P (insn) && (find_reg_note (insn, REG_SETJMP, NULL))) + /* Also look for calls that may return indirectly, such as setjmp, +and put a BTI J after them. */ + if (CALL_P (insn) && call_needs_bti_j (insn)) { bti_insn = aarch_gen_bti_j (); emit_insn_after (bti_insn, insn);
[gcc r14-9888] libstdc++: Handle EMLINK and EFTYPE in std::filesystem::remove_all
https://gcc.gnu.org/g:9586d6248e89c6bc138f65ea1992de3a2f54a522 commit r14-9888-g9586d6248e89c6bc138f65ea1992de3a2f54a522 Author: Jonathan Wakely Date: Mon Apr 8 17:41:00 2024 +0100 libstdc++: Handle EMLINK and EFTYPE in std::filesystem::remove_all Although POSIX requires ELOOP, FreeBSD documents that openat with O_NOFOLLOW returns EMLINK if the last component of a filename is a symbolic link. Check for EMLINK as well as ELOOP, so that the TOCTTOU mitigation in remove_all works correctly. See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214633 or the FreeBSD man page for reference. According to its man page, DragonFlyBSD also uses EMLINK for this error, and NetBSD uses its own EFTYPE. OpenBSD follows POSIX and uses EMLINK. This fixes these failures on FreeBSD: FAIL: 27_io/filesystem/operations/remove_all.cc -std=gnu++17 execution test FAIL: experimental/filesystem/operations/remove_all.cc -std=gnu++17 execution test libstdc++-v3/ChangeLog: * src/c++17/fs_ops.cc (remove_all) [__FreeBSD__ || __DragonFly__]: Check for EMLINK as well as ELOOP. [__NetBSD__]: Check for EFTYPE as well as ELOOP. Diff: --- libstdc++-v3/src/c++17/fs_ops.cc | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc index 61df19753ef..07bc2a0fa88 100644 --- a/libstdc++-v3/src/c++17/fs_ops.cc +++ b/libstdc++-v3/src/c++17/fs_ops.cc @@ -1312,7 +1312,13 @@ fs::remove_all(const path& p) // Our work here is done. return 0; case ENOTDIR: - case ELOOP: + case ELOOP: // POSIX says openat with O_NOFOLLOW sets ELOOP for a symlink. +#if defined __FreeBSD__ || defined __DragonFly__ + case EMLINK: // Used instead of ELOOP +#endif +#if defined __NetBSD__ && defined EFTYPE + case EFTYPE: // Used instead of ELOOP +#endif // Not a directory, will remove below. break; #endif @@ -1352,7 +1358,13 @@ fs::remove_all(const path& p, error_code& ec) ec.clear(); return 0; case ENOTDIR: - case ELOOP: + case ELOOP: // POSIX says openat with O_NOFOLLOW sets ELOOP for a symlink. +#if defined __FreeBSD__ || defined __DragonFly__ + case EMLINK: // Used instead of ELOOP +#endif +#if defined __NetBSD__ && defined EFTYPE + case EFTYPE: // Used instead of ELOOP +#endif // Not a directory, will remove below. break; #endif
[gcc r14-9889] libstdc++: Adjust expected locale-dependent date formats in tests
https://gcc.gnu.org/g:4decc1062f0f6eb44209d9d5a26a744ffa474648 commit r14-9889-g4decc1062f0f6eb44209d9d5a26a744ffa474648 Author: Jonathan Wakely Date: Wed Apr 10 13:24:51 2024 +0100 libstdc++: Adjust expected locale-dependent date formats in tests The std/time/year_month_day/io.cc test assumes that %x in the fr_FR locale is %d/%m/%Y but on FreeBSD it is %d.%m.%Y instead. Make the test PASS for either format. Similarly, 27_io/manipulators/extended/get_time/char/2.cc expects that %a in the de_DE locale is "Di" but on FreeBSD it's "Di." with a trailing period. Adjust the input string to be "1971 Di." instead of "Di 1971" and that way if %a doesn't expect the trailing '.' it simply won't extract it from the stream. This fixes: FAIL: std/time/year_month_day/io.cc -std=gnu++20 execution test FAIL: 27_io/manipulators/extended/get_time/char/2.cc -std=gnu++17 execution test libstdc++-v3/ChangeLog: * testsuite/27_io/manipulators/extended/get_time/char/2.cc: Adjust input string so that it matches %a with or without a trailing period. * testsuite/std/time/year_month_day/io.cc: Adjust expected format for %x in the fr_FR locale. Diff: --- .../testsuite/27_io/manipulators/extended/get_time/char/2.cc| 6 +++--- libstdc++-v3/testsuite/std/time/year_month_day/io.cc| 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/testsuite/27_io/manipulators/extended/get_time/char/2.cc b/libstdc++-v3/testsuite/27_io/manipulators/extended/get_time/char/2.cc index 6104349d254..b582967fddc 100644 --- a/libstdc++-v3/testsuite/27_io/manipulators/extended/get_time/char/2.cc +++ b/libstdc++-v3/testsuite/27_io/manipulators/extended/get_time/char/2.cc @@ -35,9 +35,9 @@ void test01() VERIFY( loc_de != loc_c ); istringstream iss; iss.imbue(loc_de); - iss.str("Di 1971"); - tm time1; - iss >> get_time(&time1, "%a %Y"); + iss.str("1971 Di."); // %a is "Di" on some targets, "Di." on others. + tm time1{}; + iss >> get_time(&time1, "%Y %a"); VERIFY(time1.tm_wday == 2); VERIFY(time1.tm_year == 71); } diff --git a/libstdc++-v3/testsuite/std/time/year_month_day/io.cc b/libstdc++-v3/testsuite/std/time/year_month_day/io.cc index cb82ef3b612..632b7a0fc2d 100644 --- a/libstdc++-v3/testsuite/std/time/year_month_day/io.cc +++ b/libstdc++-v3/testsuite/std/time/year_month_day/io.cc @@ -84,7 +84,7 @@ test_format() s = std::format(loc_fr, "{:%x}", 2022y/December/19); VERIFY( s == "12/19/22" ); s = std::format(loc_fr, "{:L%x}", 2022y/December/19); - VERIFY( s == "19/12/2022" ); + VERIFY( s == "19/12/2022" || s == "19.12.2022" ); // depends on locale defs s = std::format(loc_fr, "{}", 2022y/December/19); VERIFY( s == "2022-12-19" ); s = std::format(loc_fr, "{:L%F}", 2022y/December/19);
[gcc(refs/users/meissner/heads/work164-bugs)] PR target/112886, Add %S to print_operand for vector pair support.
https://gcc.gnu.org/g:9e52245dd8aa2574bc1c215a45b2d7f8a8aa3cfd commit 9e52245dd8aa2574bc1c215a45b2d7f8a8aa3cfd Author: Michael Meissner Date: Wed Apr 10 11:34:46 2024 -0400 PR target/112886, Add %S to print_operand for vector pair support. In looking at support for load vector pair and store vector pair for the PowerPC in GCC, I noticed that we were missing a print_operand output modifier if you are dealing with vector pairs to print the 2nd register in the vector pair. If the instruction inside of the asm used the Altivec encoding, then we could use the %L modifier: __vector_pair *p, *q, *r; // ... __asm__ ("vaddudm %0,%1,%2\n\tvaddudm %L0,%L1,%L2" : "=v" (*p) : "v" (*q), "v" (*r)); Likewise if we know the value to be in a tradiational FPR register, %L will work for instructions that use the VSX encoding: __vector_pair *p, *q, *r; // ... __asm__ ("xvadddp %x0,%x1,%x2\n\txvadddp %L0,%L1,%L2" : "=f" (*p) : "f" (*q), "f" (*r)); But if have a value that is in a traditional Altivec register, and the instruction uses the VSX encoding, %L will a value between 0 and 31, when it should give a value between 32 and 63. This patch adds %S that acts like %x, except that it adds 1 to the register number. This is version 2 of the patch. The only difference is I made the test case simpler to read. I have tested this on power10 and power9 little endian systems and on a power9 big endian system. There were no regressions in the patch. Can I apply it to the trunk? It would be nice if I could apply it to the open branches. Can I backport it after a burn-in period? 2024-04-10 Michael Meissner gcc/ PR target/112886 * config/rs6000/rs6000.cc (print_operand): Add %S output modifier. * doc/md.texi (Modifiers): Mention %S can be used like %x. gcc/testsuite/ PR target/112886 * /gcc.target/powerpc/pr112886.c: New test. Diff: --- gcc/config/rs6000/rs6000.cc | 10 +++--- gcc/doc/md.texi | 5 +++-- gcc/testsuite/gcc.target/powerpc/pr112886.c | 29 + 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 2921e72aea8..ec860c13074 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -14454,13 +14454,17 @@ print_operand (FILE *file, rtx x, int code) print_operand (file, x, 0); return; +case 'S': case 'x': - /* X is a FPR or Altivec register used in a VSX context. */ + /* X is a FPR or Altivec register used in a VSX context. %x prints +the VSX register number, %S prints the 2nd register number for +vector pair, decimal 128-bit floating and IBM 128-bit binary floating +values. */ if (!REG_P (x) || !VSX_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%x value"); + output_operand_lossage ("invalid %%%c value", (code == 'S' ? 'S' : 'x')); else { - int reg = REGNO (x); + int reg = REGNO (x) + (code == 'S' ? 1 : 0); int vsx_reg = (FP_REGNO_P (reg) ? reg - 32 : reg - FIRST_ALTIVEC_REGNO + 32); diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 5730bda80dc..7b7e6507754 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -3386,8 +3386,9 @@ A VSX register (VSR), @code{vs0}@dots{}@code{vs63}. This is either an FPR (@code{vs0}@dots{}@code{vs31} are @code{f0}@dots{}@code{f31}) or a VR (@code{vs32}@dots{}@code{vs63} are @code{v0}@dots{}@code{v31}). -When using @code{wa}, you should use the @code{%x} output modifier, so that -the correct register number is printed. For example: +When using @code{wa}, you should use either the @code{%x} or @code{%S} +output modifier, so that the correct register number is printed. For +example: @smallexample asm ("xvadddp %x0,%x1,%x2" diff --git a/gcc/testsuite/gcc.target/powerpc/pr112886.c b/gcc/testsuite/gcc.target/powerpc/pr112886.c new file mode 100644 index 000..4e59dcda6ea --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr112886.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +/* PR target/112886: Test that print_operand %S gives the correct register + number for VSX registers (i.e. if the register is an Altivec register, the + register number is 32..63 instead of 0..31. */ + +void +test (__vector_pair *ptr1, __vector_pair *ptr2, __vector_pair *ptr3) +{ + register __vector_pair p asm ("vs10"); + register __vector_pair q asm ("vs42")
[gcc(refs/users/meissner/heads/work164-bugs)] Update ChangeLog.*
https://gcc.gnu.org/g:7258b3c700907ddf947ab5e85478456783138ada commit 7258b3c700907ddf947ab5e85478456783138ada Author: Michael Meissner Date: Wed Apr 10 11:36:10 2024 -0400 Update ChangeLog.* Diff: --- gcc/ChangeLog.bugs | 57 ++ 1 file changed, 57 insertions(+) diff --git a/gcc/ChangeLog.bugs b/gcc/ChangeLog.bugs index 56a8be15cb1..7aa77ab7504 100644 --- a/gcc/ChangeLog.bugs +++ b/gcc/ChangeLog.bugs @@ -1,3 +1,60 @@ + Branch work164-bugs, patch #204 + +PR target/112886, Add %S to print_operand for vector pair support. + +In looking at support for load vector pair and store vector pair for the +PowerPC in GCC, I noticed that we were missing a print_operand output modifier +if you are dealing with vector pairs to print the 2nd register in the vector +pair. + +If the instruction inside of the asm used the Altivec encoding, then we could +use the %L modifier: + + __vector_pair *p, *q, *r; + // ... + __asm__ ("vaddudm %0,%1,%2\n\tvaddudm %L0,%L1,%L2" +: "=v" (*p) +: "v" (*q), "v" (*r)); + +Likewise if we know the value to be in a tradiational FPR register, %L will +work for instructions that use the VSX encoding: + + __vector_pair *p, *q, *r; + // ... + __asm__ ("xvadddp %x0,%x1,%x2\n\txvadddp %L0,%L1,%L2" +: "=f" (*p) +: "f" (*q), "f" (*r)); + +But if have a value that is in a traditional Altivec register, and the +instruction uses the VSX encoding, %L will a value between 0 and 31, when it +should give a value between 32 and 63. + +This patch adds %S that acts like %x, except that it adds 1 to the +register number. + +This is version 2 of the patch. The only difference is I made the test case +simpler to read. + +I have tested this on power10 and power9 little endian systems and on a power9 +big endian system. There were no regressions in the patch. Can I apply it to +the trunk? + +It would be nice if I could apply it to the open branches. Can I backport it +after a burn-in period? + +2024-04-10 Michael Meissner + +gcc/ + + PR target/112886 + * config/rs6000/rs6000.cc (print_operand): Add %S output modifier. + * doc/md.texi (Modifiers): Mention %S can be used like %x. + +gcc/testsuite/ + + PR target/112886 + * /gcc.target/powerpc/pr112886.c: New test. + Branch work164-bugs, patch #203 Add power10 ori/oris and xori/xoris fusion support.
[gcc r14-9890] aarch64: Do not give ABI change diagnostics for _BitInt(N)
https://gcc.gnu.org/g:3a787e038fe3549d6ec9ec9aa6416dcbba664fd9 commit r14-9890-g3a787e038fe3549d6ec9ec9aa6416dcbba664fd9 Author: Andre Vieira Date: Wed Apr 10 16:29:21 2024 +0100 aarch64: Do not give ABI change diagnostics for _BitInt(N) This patch makes sure we do not give ABI change diagnostics for the ABI breaks of GCC 9, 13 and 14 for any type involving _BitInt(N), since that type did not exist before this GCC version. gcc/ChangeLog: * config/aarch64/aarch64.cc (bitint_or_aggr_of_bitint_p): New function. (aarch64_layout_arg): Don't emit diagnostics for types involving _BitInt(N). Diff: --- gcc/config/aarch64/aarch64.cc | 61 --- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 1ea84c8bd73..7479e4beb36 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -6744,6 +6744,37 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type, return alignment; } +/* Return true if TYPE describes a _BitInt(N) or an angreggate that uses the + _BitInt(N) type. These include ARRAY_TYPE's with an element that is a + _BitInt(N) or an aggregate that uses it, and a RECORD_TYPE or a UNION_TYPE + with a field member that is a _BitInt(N) or an aggregate that uses it. + Return false otherwise. */ + +static bool +bitint_or_aggr_of_bitint_p (tree type) +{ + if (!type) +return false; + + if (TREE_CODE (type) == BITINT_TYPE) +return true; + + /* If ARRAY_TYPE, check it's element type. */ + if (TREE_CODE (type) == ARRAY_TYPE) +return bitint_or_aggr_of_bitint_p (TREE_TYPE (type)); + + /* If RECORD_TYPE or UNION_TYPE, check the fields' types. */ + if (RECORD_OR_UNION_TYPE_P (type)) +for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + { + if (TREE_CODE (field) != FIELD_DECL) + continue; + if (bitint_or_aggr_of_bitint_p (TREE_TYPE (field))) + return true; + } + return false; +} + /* Layout a function argument according to the AAPCS64 rules. The rule numbers refer to the rule numbers in the AAPCS64. ORIG_MODE is the mode that was originally given to us by the target hook, whereas the @@ -6907,6 +6938,10 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) && (!alignment || abi_break_gcc_9 < alignment) && (!abi_break_gcc_13 || alignment < abi_break_gcc_13)); + /* _BitInt(N) was only added in GCC 14. */ + bool warn_pcs_change_le_gcc14 += warn_pcs_change && !bitint_or_aggr_of_bitint_p (type); + /* allocate_ncrn may be false-positive, but allocate_nvrn is quite reliable. The following code thus handles passing by SIMD/FP registers first. */ @@ -6978,14 +7013,14 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) { /* Emit a warning if the alignment changed when taking the 'packed' attribute into account. */ - if (warn_pcs_change + if (warn_pcs_change_le_gcc14 && abi_break_gcc_13 && ((abi_break_gcc_13 == 16 * BITS_PER_UNIT) != (alignment == 16 * BITS_PER_UNIT))) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 13.1", type); - if (warn_pcs_change + if (warn_pcs_change_le_gcc14 && abi_break_gcc_14 && ((abi_break_gcc_14 == 16 * BITS_PER_UNIT) != (alignment == 16 * BITS_PER_UNIT))) @@ -6998,7 +7033,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) passed by reference rather than value. */ if (alignment == 16 * BITS_PER_UNIT) { - if (warn_pcs_change && abi_break_gcc_9) + if (warn_pcs_change_le_gcc14 + && abi_break_gcc_9) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 9.1", type); ++ncrn; @@ -7056,14 +7092,14 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) on_stack: pcum->aapcs_stack_words = size / UNITS_PER_WORD; - if (warn_pcs_change + if (warn_pcs_change_le_gcc14 && abi_break_gcc_13 && ((abi_break_gcc_13 >= 16 * BITS_PER_UNIT) != (alignment >= 16 * BITS_PER_UNIT))) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 13.1", type); - if (warn_pcs_change + if (warn_pcs_change_le_gcc14 && abi_break_gcc_14 && ((abi_break_gcc_14 >= 16 * BITS_PER_UNIT) != (alignment >= 16 * BITS_PER_UNIT))) @@ -7075,7 +7111,8 @@ on_stack: int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD); if (pcum->aapcs_stack_size != new_
[gcc r14-9891] aarch64: Add support for _BitInt
https://gcc.gnu.org/g:5aa3fec38cc6f52285168b161bab1a869d864b44 commit r14-9891-g5aa3fec38cc6f52285168b161bab1a869d864b44 Author: Andre Vieira Date: Wed Apr 10 16:29:46 2024 +0100 aarch64: Add support for _BitInt This patch adds support for C23's _BitInt for the AArch64 port when compiling for little endianness. Big Endianness requires further target-agnostic support and we therefor disable it for now. gcc/ChangeLog: * config/aarch64/aarch64.cc (TARGET_C_BITINT_TYPE_INFO): Declare MACRO. (aarch64_bitint_type_info): New function. (aarch64_return_in_memory_1): Return large _BitInt's in memory. (aarch64_function_arg_alignment): Adapt to correctly return the ABI mandated alignment of _BitInt(N) where N > 128 as the alignment of TImode. (aarch64_composite_type_p): Return true for _BitInt(N), where N > 128. libgcc/ChangeLog: * config/aarch64/t-softfp (softfp_extras): Add floatbitinthf, floatbitintbf, floatbitinttf and fixtfbitint. * config/aarch64/libgcc-softfp.ver (GCC_14.0.0): Add __floatbitinthf, __floatbitintbf, __floatbitinttf and __fixtfbitint. gcc/testsuite/ChangeLog: * gcc.target/aarch64/bitint-alignments.c: New test. * gcc.target/aarch64/bitint-args.c: New test. * gcc.target/aarch64/bitint-sizes.c: New test. * gcc.target/aarch64/bitfield-bitint-abi.h: New header. * gcc.target/aarch64/bitfield-bitint-abi-align16.c: New test. * gcc.target/aarch64/bitfield-bitint-abi-align8.c: New test. Diff: --- gcc/config/aarch64/aarch64.cc | 45 +++ .../aarch64/bitfield-bitint-abi-align16.c | 384 .../aarch64/bitfield-bitint-abi-align8.c | 386 + .../gcc.target/aarch64/bitfield-bitint-abi.h | 101 ++ .../gcc.target/aarch64/bitint-alignments.c | 58 gcc/testsuite/gcc.target/aarch64/bitint-args.c | 105 ++ gcc/testsuite/gcc.target/aarch64/bitint-sizes.c| 60 libgcc/config/aarch64/libgcc-softfp.ver| 8 + libgcc/config/aarch64/t-softfp | 3 +- 9 files changed, 1149 insertions(+), 1 deletion(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 7479e4beb36..c763a8a6298 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -6583,6 +6583,7 @@ aarch64_return_in_memory_1 (const_tree type) int count; if (!AGGREGATE_TYPE_P (type) + && TREE_CODE (type) != BITINT_TYPE && TREE_CODE (type) != COMPLEX_TYPE && TREE_CODE (type) != VECTOR_TYPE) /* Simple scalar types always returned in registers. */ @@ -21995,6 +21996,11 @@ aarch64_composite_type_p (const_tree type, if (type && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)) return true; + if (type + && TREE_CODE (type) == BITINT_TYPE + && int_size_in_bytes (type) > 16) +return true; + if (mode == BLKmode || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) @@ -28476,6 +28482,42 @@ aarch64_excess_precision (enum excess_precision_type type) return FLT_EVAL_METHOD_UNPREDICTABLE; } +/* Implement TARGET_C_BITINT_TYPE_INFO. + Return true if _BitInt(N) is supported and fill its details into *INFO. */ +bool +aarch64_bitint_type_info (int n, struct bitint_info *info) +{ + if (TARGET_BIG_END) +return false; + + if (n <= 8) +info->limb_mode = QImode; + else if (n <= 16) +info->limb_mode = HImode; + else if (n <= 32) +info->limb_mode = SImode; + else if (n <= 64) +info->limb_mode = DImode; + else if (n <= 128) +info->limb_mode = TImode; + else +/* The AAPCS for AArch64 defines _BitInt(N > 128) as an array with + type {signed,unsigned} __int128[M] where M*128 >= N. However, to be + able to use libgcc's implementation to support large _BitInt's we need + to use a LIMB_MODE that is no larger than 'long long'. This is why we + use DImode for our internal LIMB_MODE and we define the ABI_LIMB_MODE to + be TImode to ensure we are ABI compliant. */ +info->limb_mode = DImode; + + if (n > 128) +info->abi_limb_mode = TImode; + else +info->abi_limb_mode = info->limb_mode; + info->big_endian = TARGET_BIG_END; + info->extended = false; + return true; +} + /* Implement TARGET_SCHED_CAN_SPECULATE_INSN. Return true if INSN can be scheduled for speculative execution. Reject the long-running division and square-root instructions. */ @@ -30600,6 +30642,9 @@ aarch64_run_selftests (void) #undef TARGET_C_EXCESS_PRECISION #define TARGET_C_EXCESS_PRECISION aarch64_excess_precision +#undef TARGET_C_BITINT_TYPE_INFO +#define TARGET_C_BITINT_TYPE_INFO aarch64_bitint_type_info + #undef TARGET_EXPAND_BU
[gcc(refs/users/meissner/heads/work164-bugs)] Improve 64->128 bit zero extension on PowerPC (PR target/108958)
https://gcc.gnu.org/g:a2026fb10fd00c5c6a7e262f8d5966f96ec8e49a commit a2026fb10fd00c5c6a7e262f8d5966f96ec8e49a Author: Michael Meissner Date: Wed Apr 10 12:08:48 2024 -0400 Improve 64->128 bit zero extension on PowerPC (PR target/108958) If we are converting an unsigned DImode to a TImode value, and the TImode value will go in a vector register, GCC currently does the DImode to TImode conversion in GPR registers, and then moves the value to the vector register via a mtvsrdd instruction. This patch adds a new zero_extendditi2 insn which optimizes moving a GPR to a vector register using the mtvsrdd instruction with RA=0, and using lxvrdx to load a 64-bit value into the bottom 64-bits of the vector register. I have tested this patch on the following systems and there was no degration. Can I check it into the trunk branch? * Power10, LE, --with-cpu=power10, IBM 128-bit long double * Power9, LE, --with-cpu=power9, IBM 128-bit long double * Power9, LE, --with-cpu=power9, IEEE 128-bit long double * Power9, LE, --with-cpu=power9, 64-bit default long double * Power9, BE, --with-cpu=power9, IBM 128-bit long double * Power8, BE, --with-cpu=power8, IBM 128-bit long double 2024-04-10 Michael Meissner gcc/ PR target/108958 * gcc/config/rs6000.md (zero_extendditi2): New insn. gcc/testsuite/ PR target/108958 * gcc.target/powerpc/pr108958.c: New test. Diff: --- gcc/config/rs6000/rs6000.md | 52 ++ gcc/testsuite/gcc.target/powerpc/pr108958.c | 57 + 2 files changed, 109 insertions(+) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index f626b68ebb2..f1f120199f3 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -994,6 +994,58 @@ (set_attr "dot" "yes") (set_attr "length" "4,8")]) +(define_insn_and_split "zero_extendditi2" + [(set (match_operand:TI 0 "gpc_reg_operand" "=r,r,wa,wa,wa") + (zero_extend:TI +(match_operand:DI 1 "reg_or_mem_operand" "r,m,b,Z,wa"))) + (clobber (match_scratch:DI 2 "=X,X,X,X,&wa"))] + "TARGET_POWERPC64 && TARGET_P9_VECTOR" + "@ + # + # + mtvsrdd %x0,0,%1 + lxvrdx %x0,%y1 + #" + "&& reload_completed + && (int_reg_operand (operands[0], TImode) + || (vsx_register_operand (operands[0], TImode) + && vsx_register_operand (operands[1], DImode)))" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 3) (const_int 0))] +{ + rtx dest = operands[0]; + rtx src = operands[1]; + + /* If we are converting a VSX DImode to VSX TImode, we need to move the upper + 64-bits (DImode) to the lower 64-bits. We can't just do a xxpermdi + instruction to swap the two 64-bit words, because can't rely on the bottom + 64-bits of the VSX register being 0. Instead we create a 0 and do the + xxpermdi operation to combine the two registers. */ + if (vsx_register_operand (dest, TImode) + && vsx_register_operand (src, DImode)) +{ + rtx tmp = operands[2]; + emit_move_insn (tmp, const0_rtx); + + rtx hi = tmp; + rtx lo = src; + if (!BYTES_BIG_ENDIAN) + std::swap (hi, lo); + + rtx dest_v2di = gen_rtx_REG (V2DImode, reg_or_subregno (dest)); + emit_insn (gen_vsx_concat_v2di (dest_v2di, hi, lo)); + DONE; +} + + /* If we are zero extending to a GPR register either from a GPR register, + a VSX register or from memory, do the zero extend operation to the + lower DI register, and set the upper DI register to 0. */ + operands[2] = gen_lowpart (DImode, dest); + operands[3] = gen_highpart (DImode, dest); +} + [(set_attr "type" "*,load,vecexts,vecload,vecperm") + (set_attr "isa" "*,*,p9v,p10,*") + (set_attr "length" "8,8,*,*,8")]) (define_insn "extendqi2" [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v") diff --git a/gcc/testsuite/gcc.target/powerpc/pr108958.c b/gcc/testsuite/gcc.target/powerpc/pr108958.c new file mode 100644 index 000..85ea0976f91 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr108958.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target int128 } */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +/* This patch makes sure the various optimization and code paths are done for + zero extending DImode to TImode on power10 (PR target/pr108958). */ + +__uint128_t +gpr_to_gpr (unsigned long long a) +{ + return a; /* li 4,0. */ +} + +__uint128_t +mem_to_gpr (unsigned long long *p) +{ + return *p; /* ld 3,0(3); li 4,0. */ +} + +__uint128_t +vsx_to_gpr (double d) +{ + return (unsigned long long)d;/* fctiduz 0,1; li 4,0; mfvsrd 3,0. */ +} + +void +gpr_to_vsx (__uint128_t *p, unsig
[gcc(refs/users/meissner/heads/work164-bugs)] Update ChangeLog.*
https://gcc.gnu.org/g:be19bba37f34c8993f27fcb9b65b63b30fa3b5fc commit be19bba37f34c8993f27fcb9b65b63b30fa3b5fc Author: Michael Meissner Date: Wed Apr 10 12:09:56 2024 -0400 Update ChangeLog.* Diff: --- gcc/ChangeLog.bugs | 35 +++ 1 file changed, 35 insertions(+) diff --git a/gcc/ChangeLog.bugs b/gcc/ChangeLog.bugs index 7aa77ab7504..c21696078f1 100644 --- a/gcc/ChangeLog.bugs +++ b/gcc/ChangeLog.bugs @@ -1,3 +1,38 @@ + Branch work164-bugs, patch #205 + +Improve 64->128 bit zero extension on PowerPC (PR target/108958) + +If we are converting an unsigned DImode to a TImode value, and the TImode value +will go in a vector register, GCC currently does the DImode to TImode conversion +in GPR registers, and then moves the value to the vector register via a mtvsrdd +instruction. + +This patch adds a new zero_extendditi2 insn which optimizes moving a GPR to a +vector register using the mtvsrdd instruction with RA=0, and using lxvrdx to +load a 64-bit value into the bottom 64-bits of the vector register. + +I have tested this patch on the following systems and there was no degration. +Can I check it into the trunk branch? + +* Power10, LE, --with-cpu=power10, IBM 128-bit long double +* Power9, LE, --with-cpu=power9, IBM 128-bit long double +* Power9, LE, --with-cpu=power9, IEEE 128-bit long double +* Power9, LE, --with-cpu=power9, 64-bit default long double +* Power9, BE, --with-cpu=power9, IBM 128-bit long double +* Power8, BE, --with-cpu=power8, IBM 128-bit long double + +2024-04-10 Michael Meissner + +gcc/ + + PR target/108958 + * gcc/config/rs6000.md (zero_extendditi2): New insn. + +gcc/testsuite/ + + PR target/108958 + * gcc.target/powerpc/pr108958.c: New test. + Branch work164-bugs, patch #204 PR target/112886, Add %S to print_operand for vector pair support.
[gcc r14-9892] tree-optimization/114672 - WIDEN_MULT_PLUS_EXPR type mismatch
https://gcc.gnu.org/g:912753cc5f18d786e334dd425469fa7f93155661 commit r14-9892-g912753cc5f18d786e334dd425469fa7f93155661 Author: Richard Biener Date: Wed Apr 10 10:33:40 2024 +0200 tree-optimization/114672 - WIDEN_MULT_PLUS_EXPR type mismatch The following makes sure to restrict WIDEN_MULT*_EXPR to a mode precision final compute type as the mode is used to find the optab and type checking chokes when seeing bit-precisions later which would likely also not properly expanded to RTL. PR tree-optimization/114672 * tree-ssa-math-opts.cc (convert_plusminus_to_widen): Only allow mode-precision results. * gcc.dg/torture/pr114672.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/torture/pr114672.c | 14 ++ gcc/tree-ssa-math-opts.cc | 5 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.dg/torture/pr114672.c b/gcc/testsuite/gcc.dg/torture/pr114672.c new file mode 100644 index 000..b69511fe8db --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr114672.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +struct { + __INT64_TYPE__ m : 60; +} s; + +short a; +short b; + +void +foo () +{ + s.m += a * b; +} diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index a8d25c2de48..705f4a4695a 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -2918,8 +2918,9 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt, lhs = gimple_assign_lhs (stmt); type = TREE_TYPE (lhs); - if (TREE_CODE (type) != INTEGER_TYPE - && TREE_CODE (type) != FIXED_POINT_TYPE) + if ((TREE_CODE (type) != INTEGER_TYPE + && TREE_CODE (type) != FIXED_POINT_TYPE) + || !type_has_mode_precision_p (type)) return false; if (code == MINUS_EXPR)
[gcc(refs/vendors/redhat/heads/gcc-14-branch)] Merge commit 'r14-9891-g5aa3fec38cc6f52285168b161bab1a869d864b44' into redhat/gcc-14-branch
https://gcc.gnu.org/g:fd39223a10b74b0ccb502d5da127142eb1b87826 commit fd39223a10b74b0ccb502d5da127142eb1b87826 Merge: 55ddd689ece 5aa3fec38cc Author: Jakub Jelinek Date: Wed Apr 10 18:43:25 2024 +0200 Merge commit 'r14-9891-g5aa3fec38cc6f52285168b161bab1a869d864b44' into redhat/gcc-14-branch Diff: ChangeLog | 22 + MAINTAINERS|6 +- Makefile.in| 33 + Makefile.tpl | 26 +- config/ChangeLog |5 + config/lcmessage.m4|4 +- contrib/ChangeLog |5 + contrib/gcc-changelog/git_update_version.py|3 +- gcc/ChangeLog | 856 ++ gcc/DATESTAMP |2 +- gcc/analyzer/ChangeLog | 22 + gcc/analyzer/access-diagram.cc |8 +- gcc/analyzer/analyzer.opt |2 +- gcc/analyzer/program-state.cc |4 +- gcc/analyzer/region-model-manager.cc |2 + gcc/analyzer/region-model.cc |5 +- gcc/auto-profile.cc|1 - gcc/btfout.cc |2 +- gcc/builtins.cc|2 +- gcc/c-family/ChangeLog |4 + gcc/c-family/c-warn.cc |1 - gcc/c/ChangeLog| 22 + gcc/c/c-decl.cc|4 +- gcc/cgraph.h |6 + gcc/cgraphunit.cc |2 + gcc/collect2.cc|7 +- gcc/combine.cc | 27 +- gcc/common.opt |9 + gcc/common.opt.urls|6 + gcc/common/config/riscv/riscv-common.cc|1 - gcc/config.gcc | 41 +- gcc/config/aarch64/aarch64-c.cc|6 +- gcc/config/aarch64/aarch64-gnu.h | 68 + gcc/config/aarch64/aarch64-ldp-fusion.cc |2 +- gcc/config/aarch64/aarch64-option-extensions.def | 16 +- gcc/config/aarch64/aarch64-protos.h|6 +- gcc/config/aarch64/aarch64-sve-builtins-base.cc| 52 +- gcc/config/aarch64/aarch64-sve-builtins.cc | 104 +- gcc/config/aarch64/aarch64-sve-builtins.h | 18 +- gcc/config/aarch64/aarch64-sve.md | 22 +- gcc/config/aarch64/aarch64.cc | 106 +- gcc/config/aarch64/driver-aarch64.cc |2 +- gcc/config/aarch64/t-aarch64-rtems | 42 + gcc/config/darwin.cc | 25 +- gcc/config/darwin.h|2 +- gcc/config/gcn/gcn.cc | 14 +- gcc/config/gcn/gcn.opt | 16 + gcc/config/gcn/mkoffload.cc| 90 +- gcc/config/gnu.h | 16 + gcc/config/h8300/extensions.md | 11 +- gcc/config/i386/gnu.h | 11 - gcc/config/i386/i386-c.cc |4 + gcc/config/i386/i386.md| 28 +- gcc/config/i386/i386.opt.urls |2 +- gcc/config/i386/sse.md | 116 +- gcc/config/loongarch/genopts/loongarch.opt.in | 22 +- gcc/config/loongarch/lasx.md | 12 +- gcc/config/loongarch/loongarch-builtins.cc | 25 +- gcc/config/loongarch/loongarch-def.cc | 11 +- gcc/config/loongarch/loongarch-def.h | 18 +- gcc/config/loongarch/loongarch-driver.cc |2 +- gcc/config/loongarch/loongarch-opts.cc | 272 ++- gcc/config/loongarch/loongarch-opts.h | 30 +- gcc/config/loongarch/loongarch-protos.h|3 - gcc/config/loongarch/loongarch-tune.h | 22 +- gcc/config/loongarch/loongarch.cc | 429 ++--- gcc/config/loongarch/loongarch.h | 20 +- gcc/config/loongarch/loongarch.md | 68 + gcc/config/loongarch/loongarch.opt | 22 +- gcc/config/loongarch/loongarch.opt.urls| 22 +- gcc/config/loongarch/lsx.md| 89 +- gcc/config/loongarch/t-loongarch |5 +- gcc/config/mips/mips.cc|8 +- gcc/config/nvptx/mkoffload.cc |2 + gcc/config/riscv/riscv-avlprop.cc |2 +- gcc/config/riscv/riscv-c.cc
[gcc/redhat/heads/gcc-14-branch] (188 commits) Merge commit 'r14-9891-g5aa3fec38cc6f52285168b161bab1a869d8
The branch 'redhat/heads/gcc-14-branch' was updated to point to: fd39223a10b... Merge commit 'r14-9891-g5aa3fec38cc6f52285168b161bab1a869d8 It previously pointed to: 55ddd689ece... Merge commit 'r14-9704-g7942558f27038461f948ca10140a156ae67 Diff: Summary of changes (added commits): --- fd39223... Merge commit 'r14-9891-g5aa3fec38cc6f52285168b161bab1a869d8 5aa3fec... aarch64: Add support for _BitInt (*) 3a787e0... aarch64: Do not give ABI change diagnostics for _BitInt(N) (*) 4decc10... libstdc++: Adjust expected locale-dependent date formats in (*) 9586d62... libstdc++: Handle EMLINK and EFTYPE in std::filesystem::rem (*) 4be1cc5... c++: Implement C++26 P2809R3 - Trivial infinite loops are n (*) 4923ed4... testsuite: Adjust pr113359-2_*.c with unsigned long long [P (*) 109f1b2... Revert "combine: Don't combine if I2 does not change" (*) 7924e35... rs6000: Replace OPTION_MASK_DIRECT_MOVE with OPTION_MASK_P8 (*) 0774240... c++: Keep DECL_SAVED_TREE of cdtor instantiations in module (*) ea665f9... [APX] Prohibit SHA/KEYLOCKER usage of EGPR when APX enabled (*) 77c0b5b... c++: Track declarations imported from partitions [PR99377] (*) 0753ae1... Daily bump. (*) 92b38ec... libstdc++: Fix build for targets without FP std::from_chars (*) 639215c... btf: improve btf-datasec-3.c test [PR114642] (*) 1f719aa... s390x: Optimize vector permute with constant indexes (*) 8075477... btf: emit symbol refs in DATASEC entries only for BPF [PR11 (*) 685d822... aarch64: Fix ACLE SME streaming mode error in neon-sve-brid (*) de82b0c... Fortran: Fix ICE in trans-stmt.cc(gfc_trans_call) [PR114535 (*) 88aea12... Fortran: Fix ICE in gfc_trans_pointer_assignment [PR113956] (*) 32fb04a... lto/114655 - -flto=4 at link time doesn't override -flto=au (*) ce3c743... RTEMS: Fix powerpc configuration (*) dd78e6a... Guard function->cond_uids access [PR114601] (*) a79d13a... i386: Fix aes/vaes patterns [PR114576] (*) 897a241... modula2: remove description of fdebug-trace-quad, fdebug-tr (*) 46120d7... modula2: tidyup makeSystem (*) 8657d76... LoongArch: Enable switchable target (*) 73fb0a6... rust: Add rust.install-dvi and rust.install-html rules (*) a244755... Generate constant at start of loop, without UB (*) 2daeb89... Add tree-inlined gconds to caller cond->expr map (*) 21c9fd9... libquadmath: Provide __BYTE_ORDER, __LITTLE_ENDIAN and __BI (*) cfed80b... c++: Fix up maybe_warn_for_constant_evaluated calls [PR1145 (*) 64aa48c... Fix up duplicated words mostly in comments, part 2 (*) 7dd1f9d... bitint: Don't move debug stmts from before returns_twice ca (*) 46c9166... libgcc: Add basic support for aarch64-gnu (GNU/Hurd on AArc (*) 9670a23... aarch64: Add support for aarch64-gnu (GNU/Hurd on AArch64) (*) 532c57f... Move GNU/Hurd startfile spec from config/i386/gnu.h to conf (*) d76df69... middle-end/114604 - ranger allocates bitmap without initial (*) ddee437... RTEMS: Add multilib configuration for aarch64 (*) 481ba4f... libquadmath: Use soft-fp for sqrtq finite positive argument (*) 18e94e0... x86: Define __APX_INLINE_ASM_USE_GPR32__ (*) 9c97de6... testsuite: Add profile_update_atomic check to gcov-20.c [PR (*) 26eb5f8... rs6000: Fix wrong align passed to build_aligned_type [PR883 (*) 600bf39... PR modula2/114648 cc1gm2 by default does not handle C pre-p (*) 45532e3... Daily bump. (*) eaccdba... combine: Fix ICE in try_combine on pr112494.c [PR112560] (*) df7625c... GCN: '--param=gcn-preferred-vectorization-factor=[default,3 (*) 3fa8bff... New effective-target 'asm_goto_with_outputs' (*) a02d7f0... GCN, nvptx: Errors during device probing are fatal (*) 477c8a8... Fortran: Accept again tab as alternative to space as separa (*) f4f7c52... Update gcc fr.po (*) 1e3312a... ICF&SRA: Make ICF and SRA agree on padding (*) 1162861... ipa: Compare jump functions in ICF (PR 113907) (*) feb6a2d... libstdc++: Use char for _Utf8_view if char8_t isn't availab (*) cd77e15... libstdc++: Fix tests that fail with -fno-char8_t (*) 87bc206... libstdc++: Combine two std::from_chars tests into one (*) 2c1c248... aarch64: Fix expansion of svsudot [PR114607] (*) 9706965... RISC-V: Implement TLS Descriptors. (*) d5d8448... s390: Fix s390_const_int_pool_entry_p and movdi peephole2 [ (*) 278cad8... aarch64: Fix vld1/st1_x4 intrinsic test (*) 080cac1... ChangeLog: Add by hand ChangeLog entry for PR114361 revert. (*) 1a96eb0... Daily bump. (*) b93836d... contrib: Add 8057f9aa1f7e70490064de796d7a8d42d446caf8 to ig (*) 97d5cd8... tree-optimization/114624 - fix use-after-free in SCCP (*) 7d051f7... RISC-V: Refine the error msg for RVV intrinisc required ext (*) 39cb6b8... Darwin: Sync coverage specs with gcc/gcc.cc. (*) aa2ab7b... RISC-V: Minor fix for max_point (*) af3a980... RISC-V: Allow RVV intrinsic for more function target (*) 8f0ff6b... LoongArch: Set default alignment for functions jumps a
[gcc r14-9893] Fortran: fix argument checking of intrinsics C_SIZEOF, C_F_POINTER [PR106500]
https://gcc.gnu.org/g:ded646c91d2c0fb908faf6fa8fe1df0d7df49d16 commit r14-9893-gded646c91d2c0fb908faf6fa8fe1df0d7df49d16 Author: Harald Anlauf Date: Tue Apr 9 23:07:59 2024 +0200 Fortran: fix argument checking of intrinsics C_SIZEOF, C_F_POINTER [PR106500] The interpretation of the F2018 standard regarding valid arguments to the intrinsic C_SIZEOF(X) was clarified in an edit to 18-007r1: https://j3-fortran.org/doc/year/22/22-101r1.txt loosening restrictions and giving examples. The F2023 text has: ! F2023:18.2.3.8 C_SIZEOF (X) ! ! X shall be a data entity with interoperable type and type parameters, ! and shall not be an assumed-size array, an assumed-rank array that ! is associated with an assumed-size array, an unallocated allocatable ! variable, or a pointer that is not associated. where ! 3.41 data entity ! data object, result of the evaluation of an expression, or the ! result of the execution of a function reference Update the checking code for interoperable arguments accordingly, and extend to reject functions returning pointer as FPTR argument to C_F_POINTER. gcc/fortran/ChangeLog: PR fortran/106500 * check.cc (is_c_interoperable): Fix checks for C_SIZEOF. (gfc_check_c_f_pointer): Reject function returning a pointer as FPTR, and improve an error message. gcc/testsuite/ChangeLog: PR fortran/106500 * gfortran.dg/c_sizeof_6.f90: Remove wrong dg-error. * gfortran.dg/sizeof_2.f90: Adjust pattern. * gfortran.dg/c_f_pointer_tests_9.f90: New test. * gfortran.dg/c_sizeof_7.f90: New test. Diff: --- gcc/fortran/check.cc | 26 -- gcc/testsuite/gfortran.dg/c_f_pointer_tests_9.f90 | 37 gcc/testsuite/gfortran.dg/c_sizeof_6.f90 | 2 +- gcc/testsuite/gfortran.dg/c_sizeof_7.f90 | 42 +++ gcc/testsuite/gfortran.dg/sizeof_2.f90| 2 +- 5 files changed, 96 insertions(+), 13 deletions(-) diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc index db74dcf3f40..2f50d84b876 100644 --- a/gcc/fortran/check.cc +++ b/gcc/fortran/check.cc @@ -5299,18 +5299,14 @@ is_c_interoperable (gfc_expr *expr, const char **msg, bool c_loc, bool c_f_ptr) return false; } - if (!c_loc && expr->rank > 0 && expr->expr_type != EXPR_ARRAY) + /* Checks for C_SIZEOF need to take into account edits to 18-007r1, see + https://j3-fortran.org/doc/year/22/22-101r1.txt . */ + if (!c_loc && !c_f_ptr && expr->rank > 0 && expr->expr_type == EXPR_VARIABLE) { gfc_array_ref *ar = gfc_find_array_ref (expr); - if (ar->type != AR_FULL) + if (ar->type == AR_FULL && ar->as->type == AS_ASSUMED_SIZE) { - *msg = "Only whole-arrays are interoperable"; - return false; - } - if (!c_f_ptr && ar->as->type != AS_EXPLICIT - && ar->as->type != AS_ASSUMED_SIZE) - { - *msg = "Only explicit-size and assumed-size arrays are interoperable"; + *msg = "Assumed-size arrays are not interoperable"; return false; } } @@ -5475,9 +5471,17 @@ gfc_check_c_f_pointer (gfc_expr *cptr, gfc_expr *fptr, gfc_expr *shape) return false; } + if (fptr->ts.type == BT_PROCEDURE && attr.function) +{ + gfc_error ("FPTR argument to C_F_POINTER at %L is a function " +"returning a pointer", &fptr->where); + return false; +} + if (fptr->rank > 0 && !is_c_interoperable (fptr, &msg, false, true)) -return gfc_notify_std (GFC_STD_F2018, "Noninteroperable array FPTR " - "at %L to C_F_POINTER: %s", &fptr->where, msg); +return gfc_notify_std (GFC_STD_F2018, + "Noninteroperable array FPTR argument to " + "C_F_POINTER at %L: %s", &fptr->where, msg); return true; } diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_tests_9.f90 b/gcc/testsuite/gfortran.dg/c_f_pointer_tests_9.f90 new file mode 100644 index 000..8c8b4a713a4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_f_pointer_tests_9.f90 @@ -0,0 +1,37 @@ +! { dg-do compile } +! +! A function returning a pointer cannot be interoperable +! and cannot be used as FPTR argument to C_F_POINTER. + +subroutine s () + use, intrinsic :: iso_c_binding + implicit none + type(c_ptr) :: cPtr + call c_f_pointer (cPtr, p0)! { dg-error "function returning a pointer" } + call c_f_pointer (cPtr, p1, shape=[2]) ! { dg-error "function returning a pointer" } +contains + function p0 () +integer, pointer :: p0 +nullify (p0) + end + function p1 () +integer, pointer :: p1(:) +nullify (p1) + end + function fp0 () +integer, pointer :: fp0 +call c_f_pointer (cPtr, fp0)! valid here +
[gcc r14-9896] analyzer, testuite: comment fixes
https://gcc.gnu.org/g:082374f6570a311b0ef95cdf712dbc6eb1e7cd17 commit r14-9896-g082374f6570a311b0ef95cdf712dbc6eb1e7cd17 Author: David Malcolm Date: Wed Apr 10 16:43:27 2024 -0400 analyzer, testuite: comment fixes gcc/testsuite/ChangeLog: * c-c++-common/analyzer/memset-1.c: Clarify some comments. Signed-off-by: David Malcolm Diff: --- gcc/testsuite/c-c++-common/analyzer/memset-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/c-c++-common/analyzer/memset-1.c b/gcc/testsuite/c-c++-common/analyzer/memset-1.c index 75aef53d348..d6695d49411 100644 --- a/gcc/testsuite/c-c++-common/analyzer/memset-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/memset-1.c @@ -58,7 +58,7 @@ void test_5 (int n) __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */ memset (buf, 0, n); - /* We can't know if buf[42] was written to or not. */ + /* We can't know if buf[42] was overwritten by the memset or not. */ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (buf[42] == '\0'); /* { dg-warning "UNKNOWN" } */ } @@ -72,7 +72,7 @@ void test_5a (int n) __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */ __builtin___memset_chk (buf, 0, n, __builtin_object_size (buf, 0)); - /* We can't know if buf[42] was written to or not. */ + /* We can't know if buf[42] was overwritten by the memset or not. */ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (buf[42] == '\0'); /* { dg-warning "UNKNOWN" } */ }
[gcc r14-9897] analyzer: fixes to internal docs
https://gcc.gnu.org/g:7f6599a201be2a3f7d1d799087e4ba283ec0bee8 commit r14-9897-g7f6599a201be2a3f7d1d799087e4ba283ec0bee8 Author: David Malcolm Date: Wed Apr 10 16:43:28 2024 -0400 analyzer: fixes to internal docs gcc/ChangeLog: * doc/analyzer.texi: Various tweaks. Signed-off-by: David Malcolm Diff: --- gcc/doc/analyzer.texi | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gcc/doc/analyzer.texi b/gcc/doc/analyzer.texi index 8eb40272cb7..b53096e7b7d 100644 --- a/gcc/doc/analyzer.texi +++ b/gcc/doc/analyzer.texi @@ -21,6 +21,9 @@ @subsection Overview +At a high-level, we're doing coverage-guided symbolic execution of the +user's code. + The analyzer implementation works on the gimple-SSA representation. (I chose this in the hopes of making it easy to work with LTO to do whole-program analysis). @@ -55,7 +58,9 @@ Next is the heart of the analyzer: we use a worklist to explore state within the supergraph, building an "exploded graph". Nodes in the exploded graph correspond to pairs, as in "Precise Interprocedural Dataflow Analysis via Graph Reachability" - (Thomas Reps, Susan Horwitz and Mooly Sagiv). + (Thomas Reps, Susan Horwitz and Mooly Sagiv) - but note that +we're not using the algorithm described in that paper, just the +``exploded graph'' terminology. We reuse nodes for pairs we've already seen, and avoid tracking state too closely, so that (hopefully) we rapidly converge @@ -499,7 +504,8 @@ which dumps a @file{SRC.eg.txt} file containing the full @code{exploded_graph}. Assuming that you have the @uref{https://gcc-newbies-guide.readthedocs.io/en/latest/debugging.html,,python support scripts for gdb} -installed, you can use: +installed (which you should do, it makes debugging GCC much easier), +you can use: @smallexample (gdb) break-on-saved-diagnostic
[gcc r14-9895] testsuite: add some missing -fanalyzer to plugin tests
https://gcc.gnu.org/g:d09d70cdb2a4bc45825fc887047ef4a20de590c6 commit r14-9895-gd09d70cdb2a4bc45825fc887047ef4a20de590c6 Author: David Malcolm Date: Wed Apr 10 16:43:27 2024 -0400 testsuite: add some missing -fanalyzer to plugin tests gcc/testsuite/ChangeLog: * gcc.dg/plugin/copy_from_user-1.c: Add missing directives for an analyzer test. * gcc.dg/plugin/taint-CVE-2011-0521-1-fixed.c: Add missing -fanalyzer to options. * gcc.dg/plugin/taint-CVE-2011-0521-1.c: Likewise. * gcc.dg/plugin/taint-CVE-2011-0521-2-fixed.c: Likewise. (dvb_usercopy): Add default case to avoid complaints about NULL derefs. * gcc.dg/plugin/taint-CVE-2011-0521-2.c: Likewise. * gcc.dg/plugin/taint-CVE-2011-0521-3-fixed.c: Add missing -fanalyzer to options. * gcc.dg/plugin/taint-CVE-2011-0521-3.c: Likewise. Drop xfail. Signed-off-by: David Malcolm Diff: --- gcc/testsuite/gcc.dg/plugin/copy_from_user-1.c| 4 gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1-fixed.c | 2 +- gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1.c | 2 +- gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2-fixed.c | 4 +++- gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2.c | 4 +++- gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-3-fixed.c | 2 +- gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-3.c | 5 ++--- 7 files changed, 15 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.dg/plugin/copy_from_user-1.c b/gcc/testsuite/gcc.dg/plugin/copy_from_user-1.c index a1415f38aa6..1acedc2e2ce 100644 --- a/gcc/testsuite/gcc.dg/plugin/copy_from_user-1.c +++ b/gcc/testsuite/gcc.dg/plugin/copy_from_user-1.c @@ -1,3 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-fanalyzer" } */ +/* { dg-require-effective-target analyzer } */ + typedef __SIZE_TYPE__ size_t; #define __user diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1-fixed.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1-fixed.c index 51526b831c0..9ad05ff670a 100644 --- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1-fixed.c +++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1-fixed.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target analyzer } */ -/* { dg-additional-options "-Wno-pedantic" } */ +/* { dg-additional-options "-fanalyzer -Wno-pedantic" } */ /* See notes in this header. */ #include "taint-CVE-2011-0521.h" diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1.c index 3d11a75073c..688d014956e 100644 --- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1.c +++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-Wno-pedantic" } */ +/* { dg-additional-options "-fanalyzer -Wno-pedantic" } */ /* { dg-require-effective-target analyzer } */ /* See notes in this header. */ diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2-fixed.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2-fixed.c index d035266b16a..7e597037ec2 100644 --- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2-fixed.c +++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2-fixed.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-Wno-pedantic" } */ +/* { dg-additional-options "-fanalyzer -Wno-pedantic" } */ /* { dg-require-effective-target analyzer } */ /* See notes in this header. */ @@ -67,6 +67,8 @@ int dvb_usercopy(struct file *file, if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) goto out; break; + default: + goto out; } /* call driver */ diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2.c index 5270e22f1a3..9189cdb2c37 100644 --- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2.c +++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-2.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target analyzer } */ -/* { dg-additional-options "-Wno-pedantic" } */ +/* { dg-additional-options "-fanalyzer -Wno-pedantic" } */ /* See notes in this header. */ #include "taint-CVE-2011-0521.h" @@ -67,6 +67,8 @@ int dvb_usercopy(struct file *file, if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) goto out; break; + default: + goto out; } /* call driver */ diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-3-fixed.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-3-fixed.c index b8268fa4a82..d10ce28b40e 100644 --- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-3-fixed.c +++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-3-fixed.c @@ -1,6 +1,6 @@ /* { dg-do compile }
[gcc r14-9902] analyzer: fix ICE on negative values for size_t [PR114472]
https://gcc.gnu.org/g:4a94551d7eaaf7a75c5195fc0bf4af94185a04c7 commit r14-9902-g4a94551d7eaaf7a75c5195fc0bf4af94185a04c7 Author: David Malcolm Date: Wed Apr 10 16:43:30 2024 -0400 analyzer: fix ICE on negative values for size_t [PR114472] I made several attempts to fix this properly, but for now apply a band-aid to at least prevent crashing on such cases. gcc/analyzer/ChangeLog: PR analyzer/114472 * access-diagram.cc (bit_size_expr::maybe_get_formatted_str): Reject attempts to print sizes that are too large. * region.cc (region_offset::calc_symbolic_bit_offset): Use a typeless svalue for the bit offset. * store.cc (bit_range::intersects_p): Replace assertion with test. (bit_range::exceeds_p): Likewise. (bit_range::falls_short_of_p): Likewise. gcc/testsuite/ChangeLog: * c-c++-common/analyzer/out-of-bounds-pr114472.c: New test. Signed-off-by: David Malcolm Diff: --- gcc/analyzer/access-diagram.cc | 4 gcc/analyzer/region.cc | 2 +- gcc/analyzer/store.cc| 20 .../c-c++-common/analyzer/out-of-bounds-pr114472.c | 17 + 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc index 85e1049bb89..500480b6832 100644 --- a/gcc/analyzer/access-diagram.cc +++ b/gcc/analyzer/access-diagram.cc @@ -373,6 +373,8 @@ bit_size_expr::maybe_get_formatted_str (text_art::style_manager &sm, if (tree cst = num_bytes->maybe_get_constant ()) { byte_size_t concrete_num_bytes = wi::to_offset (cst); + if (!wi::fits_uhwi_p (concrete_num_bytes)) + return nullptr; if (concrete_num_bytes == 1) return ::make_unique (fmt_styled_string (sm, concrete_single_byte_fmt, @@ -396,6 +398,8 @@ bit_size_expr::maybe_get_formatted_str (text_art::style_manager &sm, else if (tree cst = m_num_bits.maybe_get_constant ()) { bit_size_t concrete_num_bits = wi::to_offset (cst); + if (!wi::fits_uhwi_p (concrete_num_bits)) + return nullptr; if (concrete_num_bits == 1) return ::make_unique (fmt_styled_string (sm, concrete_single_bit_fmt, diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index 705816b6245..7d79b45563f 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -89,7 +89,7 @@ region_offset::calc_symbolic_bit_offset (region_model_manager *mgr) const m_sym_offset, bits_per_byte); } else -return *mgr->get_or_create_int_cst (size_type_node, m_offset); +return *mgr->get_or_create_int_cst (NULL_TREE, m_offset); } const svalue * diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index e85a19647f7..a36de13c174 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -290,7 +290,10 @@ bit_range::intersects_p (const bit_range &other, bit_offset_t overlap_next = MIN (get_next_bit_offset (), other.get_next_bit_offset ()); - gcc_assert (overlap_next > overlap_start); + if (overlap_next <= overlap_start) + /* If this has happened, some kind of overflow has happened in + our arithmetic. For now, reject such cases. */ + return false; bit_range abs_overlap_bits (overlap_start, overlap_next - overlap_start); *out_this = abs_overlap_bits - get_start_bit_offset (); *out_other = abs_overlap_bits - other.get_start_bit_offset (); @@ -316,7 +319,10 @@ bit_range::intersects_p (const bit_range &other, other.get_start_bit_offset ()); bit_offset_t overlap_next = MIN (get_next_bit_offset (), other.get_next_bit_offset ()); - gcc_assert (overlap_next > overlap_start); + if (overlap_next <= overlap_start) + /* If this has happened, some kind of overflow has happened in + our arithmetic. For now, reject such cases. */ + return false; *out_num_overlap_bits = overlap_next - overlap_start; return true; } @@ -339,7 +345,10 @@ bit_range::exceeds_p (const bit_range &other, bit_offset_t start = MAX (get_start_bit_offset (), other.get_next_bit_offset ()); bit_offset_t size = get_next_bit_offset () - start; - gcc_assert (size > 0); + if (size <= 0) + /* If this has happened, some kind of overflow has happened in + our arithmetic. For now, reject such cases. */ + return false; out_overhanging_bit_range->m_start_bit_offset = start; out_overhanging_bit_range->m_size_in_bits = size; return true; @@ -362,7 +371,10 @@ bit_range::falls_short_of_p (bit_offset_t offset, /* THIS fal
[gcc r14-9898] analyzer: show size in SARIF property bag for -Wanalyzer-tainted-allocation-size
https://gcc.gnu.org/g:115d5c6b009456e7e817dc5f1aeaea8d38929c93 commit r14-9898-g115d5c6b009456e7e817dc5f1aeaea8d38929c93 Author: David Malcolm Date: Wed Apr 10 16:43:28 2024 -0400 analyzer: show size in SARIF property bag for -Wanalyzer-tainted-allocation-size gcc/analyzer/ChangeLog: * sm-taint.cc (tainted_allocation_size::tainted_allocation_size): Add "size_in_bytes" param. (tainted_allocation_size::maybe_add_sarif_properties): New. (tainted_allocation_size::m_size_in_bytes): New field. (region_model::check_dynamic_size_for_taint): Pass size_in_bytes to tainted_allocation_size ctor. Signed-off-by: David Malcolm Diff: --- gcc/analyzer/sm-taint.cc | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc index 1d1e208fdf4..a9c6d4db43f 100644 --- a/gcc/analyzer/sm-taint.cc +++ b/gcc/analyzer/sm-taint.cc @@ -645,8 +645,10 @@ class tainted_allocation_size : public taint_diagnostic { public: tainted_allocation_size (const taint_state_machine &sm, tree arg, + const svalue *size_in_bytes, enum bounds has_bounds, enum memory_space mem_space) : taint_diagnostic (sm, arg, has_bounds), +m_size_in_bytes (size_in_bytes), m_mem_space (mem_space) { } @@ -781,7 +783,18 @@ public: } } + void maybe_add_sarif_properties (sarif_object &result_obj) +const final override + { +taint_diagnostic::maybe_add_sarif_properties (result_obj); +sarif_property_bag &props = result_obj.get_or_create_properties (); +#define PROPERTY_PREFIX "gcc/analyzer/tainted_allocation_size/" +props.set (PROPERTY_PREFIX "size_in_bytes", m_size_in_bytes->to_json ()); +#undef PROPERTY_PREFIX + } + private: + const svalue *m_size_in_bytes; enum memory_space m_mem_space; }; @@ -1678,7 +1691,7 @@ region_model::check_dynamic_size_for_taint (enum memory_space mem_space, { tree arg = get_representative_tree (size_in_bytes); ctxt->warn (make_unique - (taint_sm, arg, b, mem_space)); + (taint_sm, arg, size_in_bytes, b, mem_space)); } }
[gcc r14-9899] analyzer: add SARIF property bags to -Wanalyzer-overlapping-buffers
https://gcc.gnu.org/g:7a49d5dc0ef345fb2cb19a242272c973ead220e7 commit r14-9899-g7a49d5dc0ef345fb2cb19a242272c973ead220e7 Author: David Malcolm Date: Wed Apr 10 16:43:28 2024 -0400 analyzer: add SARIF property bags to -Wanalyzer-overlapping-buffers gcc/analyzer/ChangeLog: * call-details.cc: Include "diagnostic-format-sarif.h". (overlapping_buffers::overlapping_buffers): Add params for new fields. (overlapping_buffers::maybe_add_sarif_properties): New. (overlapping_buffers::m_byte_range_a): New field. (overlapping_buffers::byte_range_b): New field. (overlapping_buffers::m_num_bytes_read_sval): New field. (call_details::complain_about_overlap): Pass new params to overlapping_buffers ctor. * ranges.cc (symbolic_byte_offset::to_json): New. (symbolic_byte_range::to_json): New. * ranges.h (symbolic_byte_offset::to_json): New decl. (symbolic_byte_range::to_json): New decl. Signed-off-by: David Malcolm Diff: --- gcc/analyzer/call-details.cc | 33 ++--- gcc/analyzer/ranges.cc | 15 +++ gcc/analyzer/ranges.h| 4 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/gcc/analyzer/call-details.cc b/gcc/analyzer/call-details.cc index 5b145a2ce63..ca47953f146 100644 --- a/gcc/analyzer/call-details.cc +++ b/gcc/analyzer/call-details.cc @@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "attribs.h" #include "make-unique.h" +#include "diagnostic-format-sarif.h" #if ENABLE_ANALYZER @@ -425,8 +426,14 @@ class overlapping_buffers : public pending_diagnostic_subclass { public: - overlapping_buffers (tree fndecl) - : m_fndecl (fndecl) + overlapping_buffers (tree fndecl, + const symbolic_byte_range &byte_range_a, + const symbolic_byte_range &byte_range_b, + const svalue *num_bytes_read_sval) + : m_fndecl (fndecl), +m_byte_range_a (byte_range_a), +m_byte_range_b (byte_range_b), +m_num_bytes_read_sval (num_bytes_read_sval) { } @@ -469,8 +476,25 @@ public: m_fndecl); } + void maybe_add_sarif_properties (sarif_object &result_obj) +const final override + { +sarif_property_bag &props = result_obj.get_or_create_properties (); +#define PROPERTY_PREFIX "gcc/analyzer/overlapping_buffers/" +props.set (PROPERTY_PREFIX "bytes_range_a", + m_byte_range_a.to_json ()); +props.set (PROPERTY_PREFIX "bytes_range_b", + m_byte_range_b.to_json ()); +props.set (PROPERTY_PREFIX "num_bytes_read_sval", + m_num_bytes_read_sval->to_json ()); +#undef PROPERTY_PREFIX + } + private: tree m_fndecl; + symbolic_byte_range m_byte_range_a; + symbolic_byte_range m_byte_range_b; + const svalue *m_num_bytes_read_sval; }; @@ -517,7 +541,10 @@ call_details::complain_about_overlap (unsigned arg_idx_a, if (!byte_range_a.intersection (byte_range_b, *model).is_true ()) return; - ctxt->warn (make_unique (get_fndecl_for_call ())); + ctxt->warn (make_unique (get_fndecl_for_call (), + byte_range_a, + byte_range_b, + num_bytes_read_sval)); } } // namespace ana diff --git a/gcc/analyzer/ranges.cc b/gcc/analyzer/ranges.cc index ffdd0d4c572..659ada7609d 100644 --- a/gcc/analyzer/ranges.cc +++ b/gcc/analyzer/ranges.cc @@ -103,6 +103,12 @@ symbolic_byte_offset::dump (bool simple) const pp_flush (&pp); } +json::value * +symbolic_byte_offset::to_json () const +{ + return m_num_bytes_sval->to_json (); +} + tree symbolic_byte_offset::maybe_get_constant () const { @@ -156,6 +162,15 @@ symbolic_byte_range::dump (bool simple, region_model_manager &mgr) const pp_flush (&pp); } +json::value * +symbolic_byte_range::to_json () const +{ + json::object *obj = new json::object (); + obj->set ("start", m_start.to_json ()); + obj->set ("size", m_size.to_json ()); + return obj; +} + bool symbolic_byte_range::empty_p () const { diff --git a/gcc/analyzer/ranges.h b/gcc/analyzer/ranges.h index 92d963b7a2b..aca4554bde6 100644 --- a/gcc/analyzer/ranges.h +++ b/gcc/analyzer/ranges.h @@ -39,6 +39,8 @@ public: void dump_to_pp (pretty_printer *pp, bool) const; void dump (bool) const; + json::value *to_json () const; + bool operator== (const symbolic_byte_offset &other) const { return m_num_bytes_sval == other.m_num_bytes_sval; @@ -70,6 +72,8 @@ public: region_model_manager &mgr) const; void dump (bool, region_model_manager &mgr) const; + json::value *to_json () const; + bool empty_p () const; symbolic_byte_offset get_start_byte_offset () const
[gcc r14-9900] analyzer: add SARIF property bag to -Wanalyzer-infinite-recursion
https://gcc.gnu.org/g:960e07d73a5295adf059053907bcb395115606d2 commit r14-9900-g960e07d73a5295adf059053907bcb395115606d2 Author: David Malcolm Date: Wed Apr 10 16:43:29 2024 -0400 analyzer: add SARIF property bag to -Wanalyzer-infinite-recursion gcc/analyzer/ChangeLog: * infinite-recursion.cc: Include "diagnostic-format-sarif.h". (infinite_recursion_diagnostic::maybe_add_sarif_properties): New. Signed-off-by: David Malcolm Diff: --- gcc/analyzer/infinite-recursion.cc | 13 + 1 file changed, 13 insertions(+) diff --git a/gcc/analyzer/infinite-recursion.cc b/gcc/analyzer/infinite-recursion.cc index 112e4bd08f2..65f136ddad6 100644 --- a/gcc/analyzer/infinite-recursion.cc +++ b/gcc/analyzer/infinite-recursion.cc @@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see #include "make-unique.h" #include "analyzer/checker-path.h" #include "analyzer/feasible-graph.h" +#include "diagnostic-format-sarif.h" /* A subclass of pending_diagnostic for complaining about suspected infinite recursion. */ @@ -236,6 +237,18 @@ public: return false; } + void maybe_add_sarif_properties (sarif_object &result_obj) +const final override + { +sarif_property_bag &props = result_obj.get_or_create_properties (); +#define PROPERTY_PREFIX "gcc/analyzer/infinite_recursion_diagnostic/" +props.set_integer (PROPERTY_PREFIX "prev_entry_enode", + m_prev_entry_enode->m_index); +props.set_integer (PROPERTY_PREFIX "new_entry_enode", + m_new_entry_enode->m_index); +#undef PROPERTY_PREFIX + } + private: /* Return true iff control flow along FEDGE was affected by a conjured_svalue. */
[gcc r14-9901] analyzer: add SARIF property bag to -Wanalyzer-infinite-loop
https://gcc.gnu.org/g:107b0e63be023c11017aa53625a6557950df4d99 commit r14-9901-g107b0e63be023c11017aa53625a6557950df4d99 Author: David Malcolm Date: Wed Apr 10 16:43:29 2024 -0400 analyzer: add SARIF property bag to -Wanalyzer-infinite-loop gcc/analyzer/ChangeLog: * infinite-loop.cc: Include "diagnostic-format-sarif.h". (infinite_loop::to_json): New. (infinite_loop_diagnostic::maybe_add_sarif_properties): New. Signed-off-by: David Malcolm Diff: --- gcc/analyzer/infinite-loop.cc | 22 ++ 1 file changed, 22 insertions(+) diff --git a/gcc/analyzer/infinite-loop.cc b/gcc/analyzer/infinite-loop.cc index 296489b1146..e277a8384a0 100644 --- a/gcc/analyzer/infinite-loop.cc +++ b/gcc/analyzer/infinite-loop.cc @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/checker-path.h" #include "analyzer/feasible-graph.h" #include "make-unique.h" +#include "diagnostic-format-sarif.h" /* A bundle of data characterizing a particular infinite loop identified within the exploded graph. */ @@ -105,6 +106,18 @@ struct infinite_loop && m_loc == other.m_loc); } + json::object * + to_json () const + { +json::object *loop_obj = new json::object (); +loop_obj->set_integer ("enode", m_enode.m_index); +json::array *edge_arr = new json::array (); +for (auto eedge : m_eedge_vec) + edge_arr->append (eedge->to_json ()); +loop_obj->set ("eedges", edge_arr); +return loop_obj; + } + const exploded_node &m_enode; location_t m_loc; std::vector m_eedge_vec; @@ -297,6 +310,15 @@ public: } } + void maybe_add_sarif_properties (sarif_object &result_obj) +const final override + { +sarif_property_bag &props = result_obj.get_or_create_properties (); +#define PROPERTY_PREFIX "gcc/analyzer/infinite_loop_diagnostic/" +props.set (PROPERTY_PREFIX "inf_loop", m_inf_loop->to_json ()); +#undef PROPERTY_PREFIX + } + private: std::unique_ptr m_inf_loop; };
[gcc r14-9903] target: missing -Whardened with -fcf-protection=none [PR114606]
https://gcc.gnu.org/g:b8b148bc22673689fda19711b428b544462be2e4 commit r14-9903-gb8b148bc22673689fda19711b428b544462be2e4 Author: Marek Polacek Date: Fri Apr 5 12:37:19 2024 -0400 target: missing -Whardened with -fcf-protection=none [PR114606] -Whardened warns when -fhardened couldn't enable a hardening option because that option was disabled on the command line, e.g.: $ ./cc1plus -quiet g.C -fhardened -O2 -fstack-protector cc1plus: warning: '-fstack-protector-strong' is not enabled by '-fhardened' because it was specified on the command line [-Whardened] but it doesn't work as expected with -fcf-protection=none: $ ./cc1plus -quiet g.C -fhardened -O2 -fcf-protection=none because we're checking == CF_NONE which doesn't distinguish between nothing and -fcf-protection=none. I should have used opts_set, like below. PR target/114606 gcc/ChangeLog: * config/i386/i386-options.cc (ix86_option_override_internal): Use opts_set rather than checking == CF_NONE. gcc/testsuite/ChangeLog: * gcc.target/i386/fhardened-1.c: New test. * gcc.target/i386/fhardened-2.c: New test. Reviewed-by: Jakub Jelinek Diff: --- gcc/config/i386/i386-options.cc | 2 +- gcc/testsuite/gcc.target/i386/fhardened-1.c | 8 gcc/testsuite/gcc.target/i386/fhardened-2.c | 8 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index 7896d576977..68a2e1c6910 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -3242,7 +3242,7 @@ ix86_option_override_internal (bool main_args_p, on the command line. */ if (opts->x_flag_hardened && cf_okay_p) { - if (opts->x_flag_cf_protection == CF_NONE) + if (!opts_set->x_flag_cf_protection) opts->x_flag_cf_protection = CF_FULL; else if (opts->x_flag_cf_protection != CF_FULL) warning_at (UNKNOWN_LOCATION, OPT_Whardened, diff --git a/gcc/testsuite/gcc.target/i386/fhardened-1.c b/gcc/testsuite/gcc.target/i386/fhardened-1.c new file mode 100644 index 000..55d1718ff55 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/fhardened-1.c @@ -0,0 +1,8 @@ +/* PR target/114606 */ +/* { dg-options "-fhardened -O2 -fcf-protection=none" } */ + +#ifdef __CET__ +# error "-fcf-protection enabled when it should not be" +#endif + +/* { dg-warning ".-fcf-protection=full. is not enabled by .-fhardened. because it was specified" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/i386/fhardened-2.c b/gcc/testsuite/gcc.target/i386/fhardened-2.c new file mode 100644 index 000..9b8c1381c19 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/fhardened-2.c @@ -0,0 +1,8 @@ +/* PR target/114606 */ +/* { dg-options "-fhardened -O2" } */ + +#if __CET__ != 3 +# error "-fcf-protection not enabled" +#endif + +/* { dg-bogus ".-fcf-protection=full. is not enabled by .-fhardened. because it was specified" "" { target *-*-* } 0 } */
[gcc r14-9904] Revert "testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from combine improvement"
https://gcc.gnu.org/g:39f81924d88e3cc197fc3df74204c9b5e01e12f7 commit r14-9904-g39f81924d88e3cc197fc3df74204c9b5e01e12f7 Author: Hans-Peter Nilsson Date: Wed Apr 10 17:24:10 2024 +0200 Revert "testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from combine improvement" This reverts commit 4c8b3600c4856f7915281ae3ff4d97271c83a540. Diff: --- gcc/testsuite/gcc.target/cris/pr93372-2.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.target/cris/pr93372-2.c b/gcc/testsuite/gcc.target/cris/pr93372-2.c index 2ef6471a990..912069c018d 100644 --- a/gcc/testsuite/gcc.target/cris/pr93372-2.c +++ b/gcc/testsuite/gcc.target/cris/pr93372-2.c @@ -1,20 +1,19 @@ /* Check that eliminable compare-instructions are eliminated. */ /* { dg-do compile } */ /* { dg-options "-O2" } */ -/* { dg-final { scan-assembler-not "\tcmp|\ttest" } } */ -/* { dg-final { scan-assembler-not "\tnot" } } */ -/* { dg-final { scan-assembler-not "\tlsr" } } */ -/* We should get just one move, storing the result into *d. */ -/* { dg-final { scan-assembler-times "\tmove" 1 } } */ +/* { dg-final { scan-assembler-not "\tcmp|\ttest" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not "\tnot" { xfail cc0 } } } */ +/* { dg-final { scan-assembler-not "\tlsr" { xfail cc0 } } } */ int f(int a, int b, int *d) { int c = a - b; - /* We used to get a cmp.d with the original operands here. */ + /* Whoops! We get a cmp.d with the original operands here. */ *d = (c == 0); - /* We used to get a suboptimal sequence, but now we get the optimal "sge" - (a.k.a "spl") re-using flags from the subtraction. */ + /* Whoops! While we don't get a test.d for the result here for cc0, + we get a sequence of insns: a move, a "not" and a shift of the + subtraction-result, where a simple "spl" would have done. */ return c >= 0; }
[gcc r14-9906] ctf: fix PR debug/112878
https://gcc.gnu.org/g:5c869aa8a4538b218d9e59de6c96133971e7b965 commit r14-9906-g5c869aa8a4538b218d9e59de6c96133971e7b965 Author: Indu Bhagat Date: Wed Apr 10 17:27:52 2024 -0700 ctf: fix PR debug/112878 PR debug/112878: ICE: in ctf_add_slice, at ctfc.cc:499 with _BitInt > 255 in a struct and -gctf1 The CTF generation in GCC does not have a mechanism to roll-back an already added type. In this testcase presented in the PR, we hit a representation limit in CTF slices (for a member of a struct) and ICE, after the type for struct (CTF_K_STRUCT) has already been added to the container. To exit gracefully instead, we now check for both the offset and size of the bitfield to be explicitly <= 255. If the check fails, we emit the member with type CTF_K_UNKNOWN. Note that, the value 255 stems from the existing binutils libctf checks which were motivated to guard against malformed inputs. Although it is not accurate to say that this is a CTF representation limit, mark the code with TBD_CTF_REPRESENTATION_LIMIT for now so that this can be taken care of with the next format version bump, when libctf's checks for the slice data can be lifted as well. gcc/ChangeLog: PR debug/112878 * dwarf2ctf.cc (gen_ctf_sou_type): Check for conditions before call to ctf_add_slice. Use CTF_K_UNKNOWN type if fail. gcc/testsuite/ChangeLog: PR debug/112878 * gcc.dg/debug/ctf/ctf-bitfields-5.c: New test. Diff: --- gcc/dwarf2ctf.cc | 15 ++- gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c | 17 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc index 77d6bf89689..dc59569fe56 100644 --- a/gcc/dwarf2ctf.cc +++ b/gcc/dwarf2ctf.cc @@ -606,11 +606,16 @@ gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind) if (attr) bitpos += AT_unsigned (attr); - field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT, -field_type_id, -bitpos - field_location, -bitsize, -c); + /* This is not precisely a TBD_CTF_REPRESENTATION_LIMIT, but +surely something to look at for the next format version bump +for CTF. */ + if (bitsize <= 255 && (bitpos - field_location) <= 255) + field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT, + field_type_id, + bitpos - field_location, + bitsize, c); + else + field_type_id = gen_ctf_unknown_type (ctfc); } /* Add the field type to the struct or union type. */ diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c new file mode 100644 index 000..fee8228647c --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c @@ -0,0 +1,17 @@ +/* Bitfield where the bit offset is > 255 is not allowed in CTF. + + PR debug/112878. + This testcase is to ensure graceful handling. No slices are expected. */ + +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* No slices are expected, but a struct with one member is expected. + CTF_K_UNKNOWN is also expected. */ +/* { dg-final { scan-assembler-times "cts_type" 0 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1a01\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"unknown.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +struct { + _BitInt(282) a : 280; +} b;
[gcc r14-9907] btf: do not skip members of data type with type id BTF_VOID_TYPEID
https://gcc.gnu.org/g:936dd627cd90bdfa3f796712c043406958131d7c commit r14-9907-g936dd627cd90bdfa3f796712c043406958131d7c Author: Indu Bhagat Date: Mon Apr 8 11:01:45 2024 -0700 btf: do not skip members of data type with type id BTF_VOID_TYPEID The previous fix in gen_ctf_sou_type () exposes an issue in BTF generation, however: BTF emission was currently decrementing the vlen (indicating the number of members) to skip members of type CTF_K_UNKNOWN altogether, but still emitting the BTF for the corresponding member (in output_asm_btf_sou_fields ()). One can see malformed BTF by executing the newly added CTF testcase (gcc.dg/debug/ctf/ctf-bitfields-5.c) with -gbtf instead or even existing btf-struct-2.c without this patch. To fix the issue, it makes sense to rather _not_ skip members of data type of type id BTF_VOID_TYPEID. gcc/ChangeLog: * btfout.cc (btf_asm_type): Do not skip emitting members of unknown type. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-bitfields-4.c: Update the vlen check. * gcc.dg/debug/btf/btf-struct-2.c: Check that member named 'f' with void data type is emitted. Diff: --- gcc/btfout.cc| 5 - gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c | 6 +++--- gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c| 9 + 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 4a8ec4d1ff0..ab491f0297f 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -820,11 +820,6 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) /* Set kflag if this member is a representable bitfield. */ if (btf_dmd_representable_bitfield_p (ctfc, dmd)) btf_kflag = 1; - - /* Struct members that refer to unsupported types or bitfield formats -shall be skipped. These are marked during preprocessing. */ - else if (!btf_emit_id_p (dmd->dmd_type)) - btf_vlen -= 1; } } diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c index c00c8b3d87f..d4a6ef6a1eb 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c @@ -6,14 +6,14 @@ In this test, we construct a structure such that the bitfield will have an offset so large as to be unrepresentable in BTF. We expect that the resulting BTF will describe the rest of the structure, ignoring the - non-representable bitfield. */ + non-representable bitfield by simply using void data type for the same. */ /* { dg-do compile } */ /* { dg-options "-O0 -gbtf -dA" } */ /* { dg-require-effective-target size32plus } */ -/* Struct with 3 members and no bitfield (kind_flag not set). */ -/* { dg-final { scan-assembler-times "\[\t \]0x403\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Struct with 4 members and no bitfield (kind_flag not set). */ +/* { dg-final { scan-assembler-times "\[\t \]0x404\[\t \]+\[^\n\]*btt_info" 1 } } */ struct bigly { diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c index e9ff06883db..fa7231be75c 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c @@ -2,14 +2,15 @@ unsupported type. BTF does not support vector types (among other things). When - generating BTF for a struct (or union) type, members which refer to - unsupported types should be skipped. */ + generating BTF for a struct (or union) type. Members which refer to + unsupported types should not be skipped, however. */ /* { dg-do compile } */ /* { dg-options "-O0 -gbtf -dA" } */ -/* Expect a struct with only 2 members - 'f' should not be present. */ -/* { dg-final { scan-assembler-times "\[\t \]0x402\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Expect a struct with 3 members - 'f' is present but is of data type void. */ +/* { dg-final { scan-assembler-times "\[\t \]0x403\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times " MEMBER 'f' idx=1\[\\r\\n\]+\[^\\r\\n\]*0\[\t \]+\[^\n\]*btm_type: void" 1 } } */ struct with_float {
[gcc r13-8598] RISC-V: Fix __atomic_compare_exchange with 32 bit value on RV64
https://gcc.gnu.org/g:fb6ec6df54317ed3f6e6f878b6ea29dbef6bfe2d commit r13-8598-gfb6ec6df54317ed3f6e6f878b6ea29dbef6bfe2d Author: Kito Cheng Date: Wed Feb 28 16:01:52 2024 +0800 RISC-V: Fix __atomic_compare_exchange with 32 bit value on RV64 atomic_compare_and_swapsi will use lr.w to do obtain the original value, which sign extends to DI. RV64 only has DI comparisons, so we also need to sign extend the expected value to DI as otherwise the comparison will fail when the expected value has the 32nd bit set. gcc/ChangeLog: PR target/114130 * config/riscv/sync.md (atomic_compare_and_swap): Sign extend the expected value if needed. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr114130.c: New. Reviewed-by: Palmer Dabbelt (cherry picked from commit fd07a29e39f5347d6cef3e7042a32306f97a1719) Diff: --- gcc/config/riscv/sync.md | 9 + gcc/testsuite/gcc.target/riscv/pr114130.c | 12 2 files changed, 21 insertions(+) diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md index 9fc626267de..9fbd89d7cc8 100644 --- a/gcc/config/riscv/sync.md +++ b/gcc/config/riscv/sync.md @@ -383,6 +383,15 @@ (match_operand:SI 7 "const_int_operand" "")] ;; mod_f "TARGET_ATOMIC" { + if (word_mode != mode && operands[3] != const0_rtx) +{ + /* We don't have SI mode compare on RV64, so we need to make sure expected +value is sign-extended. */ + rtx tmp0 = gen_reg_rtx (word_mode); + emit_insn (gen_extend_insn (tmp0, operands[3], word_mode, mode, 0)); + operands[3] = simplify_gen_subreg (mode, tmp0, word_mode, 0); +} + emit_insn (gen_atomic_cas_value_strong (operands[1], operands[2], operands[3], operands[4], operands[6], operands[7])); diff --git a/gcc/testsuite/gcc.target/riscv/pr114130.c b/gcc/testsuite/gcc.target/riscv/pr114130.c new file mode 100644 index 000..cd0a4e8236c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr114130.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64 -O" } */ +#include + +void foo(uint32_t *p) { +uintptr_t x = *(uintptr_t *)p; +uint32_t e = !p ? 0 : (uintptr_t)p >> 1; +uint32_t d = (uintptr_t)x; +__atomic_compare_exchange(p, &e, &d, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler-times "sext.w\t" 1 } } */
[gcc r14-9908] RISC-V: Bugfix ICE for the vector return arg in mode switch
https://gcc.gnu.org/g:e40a3d86511efcea71e9eadde8fb9f96be52f790 commit r14-9908-ge40a3d86511efcea71e9eadde8fb9f96be52f790 Author: Pan Li Date: Thu Apr 11 09:39:44 2024 +0800 RISC-V: Bugfix ICE for the vector return arg in mode switch This patch would like to fix a ICE in mode sw for below example code. during RTL pass: mode_sw test.c: In function ‘vbool16_t j(vuint64m4_t)’: test.c:15:1: internal compiler error: in create_pre_exit, at mode-switching.cc:451 15 | } | ^ 0x3978f12 create_pre_exit __RISCV_BUILD__/../gcc/mode-switching.cc:451 0x3979e9e optimize_mode_switching __RISCV_BUILD__/../gcc/mode-switching.cc:849 0x397b9bc execute __RISCV_BUILD__/../gcc/mode-switching.cc:1324 extern size_t get_vl (); vbool16_t test (vuint64m4_t a) { unsigned long b; return __riscv_vmsne_vx_u64m4_b16 (a, b, get_vl ()); } The create_pre_exit would like to find a return value copy. If not, there will be a reason in assert but not available for above sample code when vector calling convension is enabled by default. This patch would like to override the TARGET_FUNCTION_VALUE_REGNO_P for vector register and then we will have hard_regno_nregs for copy_num, aka there is a return value copy. As a side-effect of allow vector in TARGET_FUNCTION_VALUE_REGNO_P, the TARGET_GET_RAW_RESULT_MODE will have vector mode and which is sizeless cannot be converted to fixed_size_mode. Thus override the hook TARGET_GET_RAW_RESULT_MODE and return VOIDmode when the regno is-not-a fixed_size_mode. The below tests are passed for this patch. * The fully riscv regression tests. * The reproducing test in bugzilla PR114639. PR target/114639 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_function_value_regno_p): New func impl for hook TARGET_FUNCTION_VALUE_REGNO_P. (riscv_get_raw_result_mode): New func imple for hook TARGET_GET_RAW_RESULT_MODE. (TARGET_FUNCTION_VALUE_REGNO_P): Impl the hook. (TARGET_GET_RAW_RESULT_MODE): Ditto. * config/riscv/riscv.h (V_RETURN): New macro for vector return. (GP_RETURN_FIRST): New macro for the first GPR in return. (GP_RETURN_LAST): New macro for the last GPR in return. (FP_RETURN_FIRST): Diito but for FPR. (FP_RETURN_LAST): Ditto. (FUNCTION_VALUE_REGNO_P): Remove as deprecated and replace by TARGET_FUNCTION_VALUE_REGNO_P. gcc/testsuite/ChangeLog: * g++.target/riscv/rvv/base/pr114639-1.C: New test. * gcc.target/riscv/rvv/base/pr114639-1.c: New test. Signed-off-by: Pan Li Diff: --- gcc/config/riscv/riscv.cc | 34 ++ gcc/config/riscv/riscv.h | 8 +++-- .../g++.target/riscv/rvv/base/pr114639-1.C | 25 .../gcc.target/riscv/rvv/base/pr114639-1.c | 14 + 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 00defa69fd8..91f017dd52a 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -10997,6 +10997,34 @@ riscv_vector_mode_supported_any_target_p (machine_mode) return true; } +/* Implements hook TARGET_FUNCTION_VALUE_REGNO_P. */ + +static bool +riscv_function_value_regno_p (const unsigned regno) +{ + if (GP_RETURN_FIRST <= regno && regno <= GP_RETURN_LAST) +return true; + + if (FP_RETURN_FIRST <= regno && regno <= FP_RETURN_LAST) +return true; + + if (regno == V_RETURN) +return true; + + return false; +} + +/* Implements hook TARGET_GET_RAW_RESULT_MODE. */ + +static fixed_size_mode +riscv_get_raw_result_mode (int regno) +{ + if (!is_a (reg_raw_mode[regno])) +return as_a (VOIDmode); + + return default_get_reg_raw_mode (regno); +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -11343,6 +11371,12 @@ riscv_vector_mode_supported_any_target_p (machine_mode) #undef TARGET_VECTOR_MODE_SUPPORTED_ANY_TARGET_P #define TARGET_VECTOR_MODE_SUPPORTED_ANY_TARGET_P riscv_vector_mode_supported_any_target_p +#undef TARGET_FUNCTION_VALUE_REGNO_P +#define TARGET_FUNCTION_VALUE_REGNO_P riscv_function_value_regno_p + +#undef TARGET_GET_RAW_RESULT_MODE +#define TARGET_GET_RAW_RESULT_MODE riscv_get_raw_result_mode + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-riscv.h" diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 269b8c1f076..7797e67317a 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -683,6 +683,12 @@ enum reg_class #define GP_RETURN GP_ARG_FIRST #define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST) +#def
[gcc r14-9909] RISC-V: Remove -Wno-psabi for test build option [NFC]
https://gcc.gnu.org/g:f3fdcf4a37a7be07f2acbf5c8ed5e3399440a0ef commit r14-9909-gf3fdcf4a37a7be07f2acbf5c8ed5e3399440a0ef Author: Pan Li Date: Thu Apr 11 11:42:40 2024 +0800 RISC-V: Remove -Wno-psabi for test build option [NFC] Just notice there are some test case still have -Wno-psabi option, which is deprecated now. Remove them all for riscv test cases. The below test are passed for this patch. * The riscv rvv regression test. gcc/testsuite/ChangeLog: * g++.target/riscv/rvv/base/pr109244.C: Remove deprecated -Wno-psabi option. * g++.target/riscv/rvv/base/pr109535.C: Ditto. * gcc.target/riscv/rvv/autovec/fixed-vlmax-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-5.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress-6.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-5.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/compress_run-6.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/consecutive-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/consecutive-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/consecutive_run-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/consecutive_run-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge-5.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge-6.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge-7.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge_run-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge_run-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge_run-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge_run-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge_run-5.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge_run-6.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/merge_run-7.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm-5.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm-6.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm-7.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm_run-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm_run-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm_run-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm_run-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm_run-5.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm_run-6.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/perm_run-7.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1u.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2u.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3u.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4u.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-run.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-runu.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-1.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-2.c: Ditto. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_set-3.c: Ditto.
[gcc r12-10319] RISC-V: Fix __atomic_compare_exchange with 32 bit value on RV64
https://gcc.gnu.org/g:d37be5c0413783c5459c5664b6ffb9f47acfca4e commit r12-10319-gd37be5c0413783c5459c5664b6ffb9f47acfca4e Author: Kito Cheng Date: Wed Feb 28 16:01:52 2024 +0800 RISC-V: Fix __atomic_compare_exchange with 32 bit value on RV64 atomic_compare_and_swapsi will use lr.w to do obtain the original value, which sign extends to DI. RV64 only has DI comparisons, so we also need to sign extend the expected value to DI as otherwise the comparison will fail when the expected value has the 32nd bit set. gcc/ChangeLog: PR target/114130 * config/riscv/sync.md (atomic_compare_and_swap): Sign extend the expected value if needed. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr114130.c: New. Reviewed-by: Palmer Dabbelt (cherry picked from commit fd07a29e39f5347d6cef3e7042a32306f97a1719) Diff: --- gcc/config/riscv/sync.md | 9 + gcc/testsuite/gcc.target/riscv/pr114130.c | 12 2 files changed, 21 insertions(+) diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md index 86b41e6b00a..9a9cb8be69a 100644 --- a/gcc/config/riscv/sync.md +++ b/gcc/config/riscv/sync.md @@ -129,6 +129,15 @@ (match_operand:SI 7 "const_int_operand" "")] ;; mod_f "TARGET_ATOMIC" { + if (word_mode != mode && operands[3] != const0_rtx) +{ + /* We don't have SI mode compare on RV64, so we need to make sure expected +value is sign-extended. */ + rtx tmp0 = gen_reg_rtx (word_mode); + emit_insn (gen_extend_insn (tmp0, operands[3], word_mode, mode, 0)); + operands[3] = simplify_gen_subreg (mode, tmp0, word_mode, 0); +} + emit_insn (gen_atomic_cas_value_strong (operands[1], operands[2], operands[3], operands[4], operands[6], operands[7])); diff --git a/gcc/testsuite/gcc.target/riscv/pr114130.c b/gcc/testsuite/gcc.target/riscv/pr114130.c new file mode 100644 index 000..cd0a4e8236c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr114130.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64 -O" } */ +#include + +void foo(uint32_t *p) { +uintptr_t x = *(uintptr_t *)p; +uint32_t e = !p ? 0 : (uintptr_t)p >> 1; +uint32_t d = (uintptr_t)x; +__atomic_compare_exchange(p, &e, &d, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); +} + +/* { dg-final { scan-assembler-times "sext.w\t" 1 } } */