[gcc r15-2843] c-family: Add some more ARRAY_SIZE uses
https://gcc.gnu.org/g:723e0f724e0c884a31ddf4a688604e7163ed31f2 commit r15-2843-g723e0f724e0c884a31ddf4a688604e7163ed31f2 Author: Jakub Jelinek Date: Fri Aug 9 09:34:50 2024 +0200 c-family: Add some more ARRAY_SIZE uses These two spots were just non-standard, because they divided sizeof (omp_pragmas_simd) by sizeof (*omp_pragmas) and not the expected sizeof (*omp_pragmas_simd) and so weren't converted into ARRAY_SIZE. Both of the latter sizes are the same though, as both arrays have the same type, so this patch doesn't change anything but readability. 2024-08-09 Jakub Jelinek * c-pragma.cc (c_pp_lookup_pragma): Use ARRAY_SIZE in n_omp_pragmas_simd initializer. (init_pragmas): Likewise. Diff: --- gcc/c-family/c-pragma.cc | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc index 25251c2b69f9..ed2a7a00e9eb 100644 --- a/gcc/c-family/c-pragma.cc +++ b/gcc/c-family/c-pragma.cc @@ -1565,8 +1565,7 @@ c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) { const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas); const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas); - const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd) -/ sizeof (*omp_pragmas); + const int n_omp_pragmas_simd = ARRAY_SIZE (omp_pragmas_simd); int i; for (i = 0; i < n_oacc_pragmas; ++i) @@ -1807,8 +1806,7 @@ init_pragma (void) } if (flag_openmp || flag_openmp_simd) { - const int n_omp_pragmas_simd - = sizeof (omp_pragmas_simd) / sizeof (*omp_pragmas); + const int n_omp_pragmas_simd = ARRAY_SIZE (omp_pragmas_simd); int i; for (i = 0; i < n_omp_pragmas_simd; ++i)
[gcc r15-2844] AVR: Tidy up code for __[x]load insns.
https://gcc.gnu.org/g:a90c74ab161eab09802920fbd894bf55bc4fa797 commit r15-2844-ga90c74ab161eab09802920fbd894bf55bc4fa797 Author: Georg-Johann Lay Date: Fri Aug 9 12:15:28 2024 +0200 AVR: Tidy up code for __[x]load insns. gcc/ * config/avr/avr.md (*load__libgcc, *xload__libgcc): Tidy up code. Diff: --- gcc/config/avr/avr.md | 30 +- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index fce5349bbe5f..84dfe4c40ecf 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -536,7 +536,7 @@ ;; "load_sf_libgcc" (define_insn_and_split "load__libgcc" [(set (reg:MOVMODE 22) -(match_operand:MOVMODE 0 "memory_operand" "m,m"))] +(match_operand:MOVMODE 0 "memory_operand" "m"))] "avr_load_libgcc_p (operands[0]) && REG_P (XEXP (operands[0], 0)) && REG_Z == REGNO (XEXP (operands[0], 0))" @@ -544,24 +544,18 @@ "&& reload_completed" [(parallel [(set (reg:MOVMODE 22) (match_dup 0)) - (clobber (reg:CC REG_CC))])] - "" - [(set_attr "isa" "rjmp,jmp")]) + (clobber (reg:CC REG_CC))])]) (define_insn "*load__libgcc" [(set (reg:MOVMODE 22) -(match_operand:MOVMODE 0 "memory_operand" "m,m")) +(match_operand:MOVMODE 0 "memory_operand" "m")) (clobber (reg:CC REG_CC))] "avr_load_libgcc_p (operands[0]) && REG_P (XEXP (operands[0], 0)) && REG_Z == REGNO (XEXP (operands[0], 0)) && reload_completed" - { -operands[0] = GEN_INT (); -return "%~call __load_%0"; - } - [(set_attr "length" "1,2") - (set_attr "isa" "rjmp,jmp")]) + "%~call __load_" + [(set_attr "type" "xcall")]) ;; "xload8qi_A" @@ -657,7 +651,6 @@ ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc" ;; "xload_sf_libgcc" ;; "xload_psi_libgcc" - (define_insn_and_split "xload__libgcc" [(set (reg:MOVMODE 22) (mem:MOVMODE (lo_sum:PSI (reg:QI 21) @@ -668,8 +661,8 @@ "#" "&& reload_completed" [(parallel [(set (reg:MOVMODE 22) - (mem:MOVMODE (lo_sum:PSI (reg:QI 21) - (reg:HI REG_Z + (mem:MOVMODE (lo_sum:PSI (reg:QI 21) +(reg:HI REG_Z (clobber (reg:CC REG_CC))])]) (define_insn "*xload__libgcc" @@ -679,12 +672,7 @@ (clobber (reg:CC REG_CC))] "avr_xload_libgcc_p (mode) && reload_completed" - { -rtx x_bytes = GEN_INT (); - -output_asm_insn ("%~call __xload_%0", &x_bytes); -return ""; - } + "%~call __xload_" [(set_attr "type" "xcall")]) @@ -2278,7 +2266,7 @@ [(set (match_operand:PSI 0 "register_operand" "=r") (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r") (const_int 23)) - (match_operand:PSI 2 "register_operand" "0")))] + (match_operand:PSI 2 "register_operand" "0")))] "" "#" "&& reload_completed"
[gcc r15-2845] OpenMP: Constructors and destructors for "declare target" static aggregates: Fix effective-target ke
https://gcc.gnu.org/g:9f5d22e3e2b8e4532896a4f3837cb86006d5930c commit r15-2845-g9f5d22e3e2b8e4532896a4f3837cb86006d5930c Author: Thomas Schwinge Date: Fri Aug 9 11:23:15 2024 +0200 OpenMP: Constructors and destructors for "declare target" static aggregates: Fix effective-target keyword in test cases (Most of) the tests added in commit f1bfba3a9b3f31e3e06bfd1911c9f223869ea03f "OpenMP: Constructors and destructors for "declare target" static aggregates" had a mismatch between dump file production and its scanning; the former needs to use 'offload_target_nvptx' (like 'offload_target_amdgcn'), not 'offload_device_nvptx'. libgomp/ * testsuite/libgomp.c++/static-aggr-constructor-destructor-1.C: Fix effective-target keyword. * testsuite/libgomp.c++/static-aggr-constructor-destructor-2.C: Likewise. * testsuite/libgomp.c-c++-common/target-is-initial-host-2.c: Likewise. * testsuite/libgomp.c-c++-common/target-is-initial-host.c: Likewise. * testsuite/libgomp.fortran/target-is-initial-host-2.f90: Likewise. * testsuite/libgomp.fortran/target-is-initial-host.f: Likewise. * testsuite/libgomp.fortran/target-is-initial-host.f90: Likewise. Diff: --- libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-1.C | 2 +- libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-2.C | 2 +- libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host-2.c| 2 +- libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host.c | 2 +- libgomp/testsuite/libgomp.fortran/target-is-initial-host-2.f90 | 2 +- libgomp/testsuite/libgomp.fortran/target-is-initial-host.f | 2 +- libgomp/testsuite/libgomp.fortran/target-is-initial-host.f90 | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-1.C b/libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-1.C index b5aafc8cabc2..a704e39411da 100644 --- a/libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-1.C +++ b/libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-1.C @@ -1,6 +1,6 @@ // { dg-do run } // { dg-additional-options "-fdump-tree-gimple -fdump-tree-optimized" } -// { dg-additional-options -foffload-options=-fdump-tree-optimized { target { offload_device_nvptx || offload_target_amdgcn } } } +// { dg-additional-options -foffload-options=-fdump-tree-optimized { target { offload_target_nvptx || offload_target_amdgcn } } } // { dg-final { scan-tree-dump-times "omp_is_initial_device" 1 "gimple" } } // { dg-final { scan-tree-dump-times "_GLOBAL__off_I_v1" 1 "gimple" } } diff --git a/libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-2.C b/libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-2.C index 9652a721bbe2..de481aadd34e 100644 --- a/libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-2.C +++ b/libgomp/testsuite/libgomp.c++/static-aggr-constructor-destructor-2.C @@ -1,6 +1,6 @@ // { dg-do run } // { dg-additional-options "-fdump-tree-gimple -fdump-tree-optimized" } -// { dg-additional-options -foffload-options=-fdump-tree-optimized { target { offload_device_nvptx || offload_target_amdgcn } } } +// { dg-additional-options -foffload-options=-fdump-tree-optimized { target { offload_target_nvptx || offload_target_amdgcn } } } // { dg-final { scan-tree-dump-times "omp_is_initial_device" 1 "gimple" } } // { dg-final { scan-tree-dump-times "_GLOBAL__off_I_v1" 1 "gimple" } } diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host-2.c b/libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host-2.c index 313d188a871a..eabc394c8cf8 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host-2.c +++ b/libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host-2.c @@ -4,7 +4,7 @@ /* Check whether 'omp_is_initial_device()' is NOT compile-time optimized. */ /* { dg-additional-options "-fdump-tree-gimple -fdump-tree-optimized" } */ -/* { dg-additional-options -foffload-options=-fdump-tree-optimized { target { offload_device_nvptx || offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload-options=-fdump-tree-optimized { target { offload_target_nvptx || offload_target_amdgcn } } } */ /* { dg-final { scan-tree-dump-times "omp_is_initial_device" 1 "gimple" } } */ diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host.c b/libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host.c index 423727ce55f0..3b1283a59798 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host.c +++ b/libgomp/testsuite/libgomp.c-c++-common/target-is-initial-host.c @@ -3,7 +3,7 @@ /* Check whether 'omp_is_initial_device()' is properly compile-time optimized. */ /* { dg-additional-options "-fdump-
[gcc r15-2846] amdgcn: Add padding to trampoline
https://gcc.gnu.org/g:b5a09a68bf0feaf0b0678d8f3433f776238d3896 commit r15-2846-gb5a09a68bf0feaf0b0678d8f3433f776238d3896 Author: Andrew Stubbs Date: Fri Aug 9 11:45:42 2024 + amdgcn: Add padding to trampoline This avoids a -Wpadded warning (testcase gcc.dg/20050607-1.c). gcc/ChangeLog: * config/gcn/gcn.cc (gcn_asm_trampoline_template): Add .align. * config/gcn/gcn.h (TRAMPOLINE_SIZE): Increase to 40. Diff: --- gcc/config/gcn/gcn.cc | 1 + gcc/config/gcn/gcn.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc index 0725d15c8ed0..17316a7ddb84 100644 --- a/gcc/config/gcn/gcn.cc +++ b/gcc/config/gcn/gcn.cc @@ -3794,6 +3794,7 @@ gcn_asm_trampoline_template (FILE *f) asm_fprintf (f, "\ts_mov_b32\ts%i, 0x\n", CC_SAVE_REG); asm_fprintf (f, "\ts_mov_b32\ts%i, 0x\n", CC_SAVE_REG + 1); asm_fprintf (f, "\ts_setpc_b64\ts[%i:%i]\n", CC_SAVE_REG, CC_SAVE_REG + 1); + asm_fprintf (f, "\t.align 8\n"); } /* Implement TARGET_TRAMPOLINE_INIT. diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h index e3bfd29c17d2..bd2afa61c10b 100644 --- a/gcc/config/gcn/gcn.h +++ b/gcc/config/gcn/gcn.h @@ -831,7 +831,7 @@ enum gcn_builtin_codes #define PROFILE_BEFORE_PROLOGUE 0 /* Trampolines */ -#define TRAMPOLINE_SIZE 36 +#define TRAMPOLINE_SIZE 40 /* 36 + 4 padding for alignment. */ #define TRAMPOLINE_ALIGNMENT 64 /* MD Optimization.
[gcc r15-2847] i386: Fix up __builtin_ia32_b{extr{, i}_u{32, 64}, zhi_{s, d}i} folding [PR116287]
https://gcc.gnu.org/g:6e7088dbe3bf87108a89558ffb7df36df3469206 commit r15-2847-g6e7088dbe3bf87108a89558ffb7df36df3469206 Author: Jakub Jelinek Date: Fri Aug 9 14:32:51 2024 +0200 i386: Fix up __builtin_ia32_b{extr{,i}_u{32,64},zhi_{s,d}i} folding [PR116287] The GENERIC folding of these builtins have cases where it folds to a constant regardless of the value of the first operand. If so, we need to use omit_one_operand to avoid throwing away side-effects in the first operand if any. The cases which verify the first argument is INTEGER_CST don't need that, INTEGER_CST doesn't have side-effects. 2024-08-09 Jakub Jelinek PR target/116287 * config/i386/i386.cc (ix86_fold_builtin) : When folding into zero without checking whether first argument is constant, use omit_one_operand. (ix86_fold_builtin) : Likewise. * gcc.target/i386/bmi-pr116287.c: New test. * gcc.target/i386/bmi2-pr116287.c: New test. * gcc.target/i386/tbm-pr116287.c: New test. Diff: --- gcc/config/i386/i386.cc | 12 +++ gcc/testsuite/gcc.target/i386/bmi-pr116287.c | 28 ++ gcc/testsuite/gcc.target/i386/bmi2-pr116287.c | 24 ++ gcc/testsuite/gcc.target/i386/tbm-pr116287.c | 29 +++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 02e282904410..f044826269ca 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -18549,9 +18549,11 @@ ix86_fold_builtin (tree fndecl, int n_args, unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0])); unsigned int start = tree_to_uhwi (args[1]); unsigned int len = (start & 0xff00) >> 8; + tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl)); start &= 0xff; if (start >= prec || len == 0) - res = 0; + return omit_one_operand (lhs_type, build_zero_cst (lhs_type), +args[0]); else if (!tree_fits_uhwi_p (args[0])) break; else @@ -18560,7 +18562,7 @@ ix86_fold_builtin (tree fndecl, int n_args, len = prec; if (len < HOST_BITS_PER_WIDE_INT) res &= (HOST_WIDE_INT_1U << len) - 1; - return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res); + return build_int_cstu (lhs_type, res); } break; @@ -18570,15 +18572,17 @@ ix86_fold_builtin (tree fndecl, int n_args, if (tree_fits_uhwi_p (args[1])) { unsigned int idx = tree_to_uhwi (args[1]) & 0xff; + tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl)); if (idx >= TYPE_PRECISION (TREE_TYPE (args[0]))) return args[0]; if (idx == 0) - return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); + return omit_one_operand (lhs_type, build_zero_cst (lhs_type), +args[0]); if (!tree_fits_uhwi_p (args[0])) break; unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]); res &= ~(HOST_WIDE_INT_M1U << idx); - return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res); + return build_int_cstu (lhs_type, res); } break; diff --git a/gcc/testsuite/gcc.target/i386/bmi-pr116287.c b/gcc/testsuite/gcc.target/i386/bmi-pr116287.c new file mode 100644 index ..2212cb458d26 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bmi-pr116287.c @@ -0,0 +1,28 @@ +/* PR target/116287 */ +/* { dg-do run { target bmi } } */ +/* { dg-options "-O2 -mbmi" } */ + +#include + +#include "bmi-check.h" + +static void +bmi_test () +{ + unsigned int a = 0; + if (__builtin_ia32_bextr_u32 (a++, 0) != 0) +abort (); + if (__builtin_ia32_bextr_u32 (a++, 0x120) != 0) +abort (); + if (a != 2) +abort (); +#ifdef __x86_64__ + unsigned long long b = 0; + if (__builtin_ia32_bextr_u64 (b++, 0) != 0) +abort (); + if (__builtin_ia32_bextr_u64 (b++, 0x140) != 0) +abort (); + if (b != 2) +abort (); +#endif +} diff --git a/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c b/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c new file mode 100644 index ..51c939c39f62 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c @@ -0,0 +1,24 @@ +/* PR target/116287 */ +/* { dg-do run { target bmi2 } } */ +/* { dg-options "-O2 -mbmi2" } */ + +#include + +#include "bmi2-check.h" + +static void +bmi2_test () +{ + unsigned int a = 0; + if (__builtin_ia32_bzhi_si (a++, 0) != 0) +abort (); + if (a != 1) +abort (); +#ifdef __x86_64__ + unsigned long long b = 0; + if (__builtin_ia32_bzhi_di (b++, 0) != 0) +abort (); + if (b
[gcc r14-10575] i386: Fix up __builtin_ia32_b{extr{, i}_u{32, 64}, zhi_{s, d}i} folding [PR116287]
https://gcc.gnu.org/g:b0dd13efca673355dd2a0c5646452c2f23f86029 commit r14-10575-gb0dd13efca673355dd2a0c5646452c2f23f86029 Author: Jakub Jelinek Date: Fri Aug 9 14:32:51 2024 +0200 i386: Fix up __builtin_ia32_b{extr{,i}_u{32,64},zhi_{s,d}i} folding [PR116287] The GENERIC folding of these builtins have cases where it folds to a constant regardless of the value of the first operand. If so, we need to use omit_one_operand to avoid throwing away side-effects in the first operand if any. The cases which verify the first argument is INTEGER_CST don't need that, INTEGER_CST doesn't have side-effects. 2024-08-09 Jakub Jelinek PR target/116287 * config/i386/i386.cc (ix86_fold_builtin) : When folding into zero without checking whether first argument is constant, use omit_one_operand. (ix86_fold_builtin) : Likewise. * gcc.target/i386/bmi-pr116287.c: New test. * gcc.target/i386/bmi2-pr116287.c: New test. * gcc.target/i386/tbm-pr116287.c: New test. (cherry picked from commit 6e7088dbe3bf87108a89558ffb7df36df3469206) Diff: --- gcc/config/i386/i386.cc | 12 +++ gcc/testsuite/gcc.target/i386/bmi-pr116287.c | 28 ++ gcc/testsuite/gcc.target/i386/bmi2-pr116287.c | 24 ++ gcc/testsuite/gcc.target/i386/tbm-pr116287.c | 29 +++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 35a282433892..6f89891d3cb5 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -18671,9 +18671,11 @@ ix86_fold_builtin (tree fndecl, int n_args, unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0])); unsigned int start = tree_to_uhwi (args[1]); unsigned int len = (start & 0xff00) >> 8; + tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl)); start &= 0xff; if (start >= prec || len == 0) - res = 0; + return omit_one_operand (lhs_type, build_zero_cst (lhs_type), +args[0]); else if (!tree_fits_uhwi_p (args[0])) break; else @@ -18682,7 +18684,7 @@ ix86_fold_builtin (tree fndecl, int n_args, len = prec; if (len < HOST_BITS_PER_WIDE_INT) res &= (HOST_WIDE_INT_1U << len) - 1; - return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res); + return build_int_cstu (lhs_type, res); } break; @@ -18692,15 +18694,17 @@ ix86_fold_builtin (tree fndecl, int n_args, if (tree_fits_uhwi_p (args[1])) { unsigned int idx = tree_to_uhwi (args[1]) & 0xff; + tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl)); if (idx >= TYPE_PRECISION (TREE_TYPE (args[0]))) return args[0]; if (idx == 0) - return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); + return omit_one_operand (lhs_type, build_zero_cst (lhs_type), +args[0]); if (!tree_fits_uhwi_p (args[0])) break; unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]); res &= ~(HOST_WIDE_INT_M1U << idx); - return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res); + return build_int_cstu (lhs_type, res); } break; diff --git a/gcc/testsuite/gcc.target/i386/bmi-pr116287.c b/gcc/testsuite/gcc.target/i386/bmi-pr116287.c new file mode 100644 index ..2212cb458d26 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bmi-pr116287.c @@ -0,0 +1,28 @@ +/* PR target/116287 */ +/* { dg-do run { target bmi } } */ +/* { dg-options "-O2 -mbmi" } */ + +#include + +#include "bmi-check.h" + +static void +bmi_test () +{ + unsigned int a = 0; + if (__builtin_ia32_bextr_u32 (a++, 0) != 0) +abort (); + if (__builtin_ia32_bextr_u32 (a++, 0x120) != 0) +abort (); + if (a != 2) +abort (); +#ifdef __x86_64__ + unsigned long long b = 0; + if (__builtin_ia32_bextr_u64 (b++, 0) != 0) +abort (); + if (__builtin_ia32_bextr_u64 (b++, 0x140) != 0) +abort (); + if (b != 2) +abort (); +#endif +} diff --git a/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c b/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c new file mode 100644 index ..51c939c39f62 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c @@ -0,0 +1,24 @@ +/* PR target/116287 */ +/* { dg-do run { target bmi2 } } */ +/* { dg-options "-O2 -mbmi2" } */ + +#include + +#include "bmi2-check.h" + +static void +bmi2_test () +{ + unsigned int a = 0; + if (__builtin_ia32_bzhi_si (a++, 0) != 0) +abort (); + if (a != 1) +abort (); +#ifdef __x86_64__ + unsigned long lo
[gcc r13-8967] c++: local class memfn synth from uneval context [PR113063]
https://gcc.gnu.org/g:12ba140ee93adc56a3426f0c6c05f4d6c6a3d08e commit r13-8967-g12ba140ee93adc56a3426f0c6c05f4d6c6a3d08e Author: Patrick Palka Date: Fri Aug 9 09:03:14 2024 -0400 c++: local class memfn synth from uneval context [PR113063] This is essentially a narrow backport of r14-6724-gfced59166f95e9 that instead uses cp_evaluated instead of maybe_push_to_top_level to clear cp_unevaluated_operand within synthesize_method, which turns out is sufficient to also fix the 13.3 regression PR116289 (whose immediate trigger is a change backport r13-7739-gd919309679334a). PR c++/113063 PR c++/116289 gcc/cp/ChangeLog: * method.cc (synthesize_method): Use cp_evaluated. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/spaceship-synth16.C: New test. * g++.dg/cpp2a/spaceship-synth16a.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/method.cc| 1 + gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C | 13 + gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C | 16 3 files changed, 30 insertions(+) diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 9fd5567e97fd..09ea6d732dfc 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -1797,6 +1797,7 @@ synthesize_method (tree fndecl) it now. */ push_deferring_access_checks (dk_no_deferred); + cp_evaluated ev; if (! context) push_to_top_level (); else if (nested) diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C new file mode 100644 index ..37a183de0f5b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C @@ -0,0 +1,13 @@ +// PR c++/113063 +// { dg-do link { target c++20 } } + +#include + +int main() { + struct X { +auto operator<=>(const X&) const = default; + }; + X x; + static_assert(noexcept(x <=> x)); + x <=> x; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C new file mode 100644 index ..68388a680b20 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C @@ -0,0 +1,16 @@ +// PR c++/116289 +// PR c++/113063 +// { dg-do link { target c++20 } } +// A version of spaceship-synth16.C where the local class isn't empty. + +#include + +int main() { + struct X { +int m = 0; +auto operator<=>(const X&) const = default; + }; + X x; + static_assert(noexcept(x <=> x)); + x <=> x; +}
[gcc r15-2848] c++: add fixed testcase [PR116289]
https://gcc.gnu.org/g:4aa89badc8c16637e0d9a39a08da7d18e209631b commit r15-2848-g4aa89badc8c16637e0d9a39a08da7d18e209631b Author: Patrick Palka Date: Fri Aug 9 09:16:45 2024 -0400 c++: add fixed testcase [PR116289] Fully fixed since r14-6724-gfced59166f95e9. PR c++/116289 PR c++/113063 gcc/testsuite/ChangeLog: * g++.dg/cpp2a/spaceship-synth16a.C: New test. Diff: --- gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C | 16 1 file changed, 16 insertions(+) diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C new file mode 100644 index ..68388a680b20 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C @@ -0,0 +1,16 @@ +// PR c++/116289 +// PR c++/113063 +// { dg-do link { target c++20 } } +// A version of spaceship-synth16.C where the local class isn't empty. + +#include + +int main() { + struct X { +int m = 0; +auto operator<=>(const X&) const = default; + }; + X x; + static_assert(noexcept(x <=> x)); + x <=> x; +}
[gcc r15-2849] c-family: regenerate c.opt.urls
https://gcc.gnu.org/g:f91f7201ac0ab6805b517341c0ba7a0c48b7971c commit r15-2849-gf91f7201ac0ab6805b517341c0ba7a0c48b7971c Author: Patrick Palka Date: Fri Aug 9 09:35:17 2024 -0400 c-family: regenerate c.opt.urls The addition of -Wtemplate-body in r15-2774-g596d1ed9d40b10 means we need to regenerate c.opt.urls. gcc/c-family/ChangeLog: * c.opt.urls: Regenerate. Diff: --- gcc/c-family/c.opt.urls | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls index df5f58a1eeed..e40b8e5c3a0d 100644 --- a/gcc/c-family/c.opt.urls +++ b/gcc/c-family/c.opt.urls @@ -837,6 +837,9 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-templates) Wtautological-compare UrlSuffix(gcc/Warning-Options.html#index-Wno-tautological-compare) +Wtemplate-body +UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-template-body) + Wtemplate-id-cdtor UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-template-id-cdtor)
[gcc r15-2850] RISC-V: Small stack tie changes
https://gcc.gnu.org/g:0e604d0ef6dcac8ee4cdc62902f2a2708ef7b040 commit r15-2850-g0e604d0ef6dcac8ee4cdc62902f2a2708ef7b040 Author: Raphael Moreira Zinsly Date: Mon Jul 22 11:23:12 2024 -0300 RISC-V: Small stack tie changes Enable the register used by riscv_emit_stack_tie () to be passed as an argument so we can tie the stack with other registers besides hard_frame_pointer_rtx. Also don't allow operand 1 of stack_tie to be optimized to sp in preparation for the stack clash protection support. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_emit_stack_tie): Pass the register to be tied to the stack pointer as argument. * config/riscv/riscv.md (stack_tie): Don't match equal operands. Diff: --- gcc/config/riscv/riscv.cc | 18 +- gcc/config/riscv/riscv.md | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 3d0a1d12b146..6981ec42af4e 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7894,12 +7894,12 @@ riscv_adjust_multi_push_cfi_prologue (int saved_size) } static void -riscv_emit_stack_tie (void) +riscv_emit_stack_tie (rtx reg) { if (Pmode == SImode) -emit_insn (gen_stack_tiesi (stack_pointer_rtx, hard_frame_pointer_rtx)); +emit_insn (gen_stack_tiesi (stack_pointer_rtx, reg)); else -emit_insn (gen_stack_tiedi (stack_pointer_rtx, hard_frame_pointer_rtx)); +emit_insn (gen_stack_tiedi (stack_pointer_rtx, reg)); } /*zcmp multi push and pop code_for_push_pop function ptr array */ @@ -8080,7 +8080,7 @@ riscv_expand_prologue (void) GEN_INT ((frame->hard_frame_pointer_offset - remaining_size).to_constant ())); RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); } /* Save the V registers. */ @@ -8111,7 +8111,7 @@ riscv_expand_prologue (void) allocation is ordered WRT fp setup and subsequent writes into the frame. */ if (frame_pointer_needed) - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); return; } @@ -8150,7 +8150,7 @@ riscv_expand_prologue (void) allocation is ordered WRT fp setup and subsequent writes into the frame. */ if (frame_pointer_needed) - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); } } @@ -8285,7 +8285,7 @@ riscv_expand_epilogue (int style) if (cfun->calls_alloca) { /* Emit a barrier to prevent loads from a deallocated stack. */ - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); need_barrier_p = false; poly_int64 adjust_offset = -frame->hard_frame_pointer_offset; @@ -8379,7 +8379,7 @@ riscv_expand_epilogue (int style) if (known_gt (step1, 0)) { /* Emit a barrier to prevent loads from a deallocated stack. */ - riscv_emit_stack_tie (); + riscv_emit_stack_tie (hard_frame_pointer_rtx); need_barrier_p = false; /* Restore the scalable frame which is assigned in prologue. */ @@ -8479,7 +8479,7 @@ riscv_expand_epilogue (int style) frame->mask = mask; /* Undo the above fib. */ if (need_barrier_p) -riscv_emit_stack_tie (); +riscv_emit_stack_tie (hard_frame_pointer_rtx); /* Deallocate the final bit of the frame. */ if (step2.to_constant () > 0) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index f46851dd4717..5e3ef789e42e 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3969,7 +3969,7 @@ (unspec:BLK [(match_operand:X 0 "register_operand" "r") (match_operand:X 1 "register_operand" "r")] UNSPEC_TIE))] - "" + "!rtx_equal_p (operands[0], operands[1])" "" [(set_attr "type" "ghost") (set_attr "length" "0")]
[gcc r15-2851] RISC-V: Move riscv_v_adjust_scalable_frame
https://gcc.gnu.org/g:5694fcf75b65bea5d3eb42e5d28d7f3e5ee7cfd7 commit r15-2851-g5694fcf75b65bea5d3eb42e5d28d7f3e5ee7cfd7 Author: Raphael Moreira Zinsly Date: Mon Jul 22 11:23:17 2024 -0300 RISC-V: Move riscv_v_adjust_scalable_frame Move riscv_v_adjust_scalable_frame () in preparation for the stack clash protection support. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_v_adjust_scalable_frame): Move closer to riscv_expand_prologue. Diff: --- gcc/config/riscv/riscv.cc | 62 +++ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 6981ec42af4e..eb32520b36cc 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3122,37 +3122,6 @@ riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src) } } -/* Adjust scalable frame of vector for prologue && epilogue. */ - -static void -riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue) -{ - rtx tmp = RISCV_PROLOGUE_TEMP (Pmode); - rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode); - rtx insn, dwarf, adjust_frame_rtx; - - riscv_legitimize_poly_move (Pmode, adjust_size, tmp, - gen_int_mode (offset, Pmode)); - - if (epilogue) -insn = gen_add3_insn (target, target, adjust_size); - else -insn = gen_sub3_insn (target, target, adjust_size); - - insn = emit_insn (insn); - - RTX_FRAME_RELATED_P (insn) = 1; - - adjust_frame_rtx -= gen_rtx_SET (target, - plus_constant (Pmode, target, epilogue ? offset : -offset)); - - dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx), - NULL_RTX); - - REG_NOTES (insn) = dwarf; -} - /* Take care below subreg const_poly_int move: 1. (set (subreg:DI (reg:TI 237) 8) @@ -7931,6 +7900,37 @@ static const code_for_push_pop_t code_for_push_pop[ZCMP_MAX_GRP_SLOTS][ZCMP_OP_N code_for_gpr_multi_popret_up_to_s11, code_for_gpr_multi_popretz_up_to_s11}}; +/* Adjust scalable frame of vector for prologue && epilogue. */ + +static void +riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue) +{ + rtx tmp = RISCV_PROLOGUE_TEMP (Pmode); + rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode); + rtx insn, dwarf, adjust_frame_rtx; + + riscv_legitimize_poly_move (Pmode, adjust_size, tmp, + gen_int_mode (offset, Pmode)); + + if (epilogue) +insn = gen_add3_insn (target, target, adjust_size); + else +insn = gen_sub3_insn (target, target, adjust_size); + + insn = emit_insn (insn); + + RTX_FRAME_RELATED_P (insn) = 1; + + adjust_frame_rtx += gen_rtx_SET (target, + plus_constant (Pmode, target, epilogue ? offset : -offset)); + + dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx), + NULL_RTX); + + REG_NOTES (insn) = dwarf; +} + static rtx riscv_gen_multi_push_pop_insn (riscv_zcmp_op_t op, HOST_WIDE_INT adj_size, unsigned int regs_num)
[gcc r15-2852] RISC-V: Stack-clash protection implemention
https://gcc.gnu.org/g:b82d173dac33d9e2f7d31bf84eb0d9f0c21d0240 commit r15-2852-gb82d173dac33d9e2f7d31bf84eb0d9f0c21d0240 Author: Raphael Moreira Zinsly Date: Mon Jul 22 11:23:20 2024 -0300 RISC-V: Stack-clash protection implemention This implements stack-clash protection for riscv, with riscv_allocate_and_probe_stack_space being based of aarch64_allocate_and_probe_stack_space from aarch64's implementation. We enforce the probing interval and the guard size to always be equal, their default value is 4Kb which is riscv page size. We also probe up by 1024 bytes in the general case when a probe is required. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_option_override): Enforce that interval is the same size as guard size. (riscv_allocate_and_probe_stack_space): New function. (riscv_expand_prologue): Call riscv_allocate_and_probe_stack_space to the final allocation of the stack and add stack-clash dump information. * config/riscv/riscv.h: Define STACK_CLASH_CALLER_GUARD and STACK_CLASH_MAX_UNROLL_PAGES. gcc/testsuite/ChangeLog: * gcc.dg/params/blocksort-part.c: Skip riscv for stack-clash protection intervals. * gcc.dg/pr82788.c: Skip riscv. * gcc.dg/stack-check-6.c: Skip residual check for riscv. * gcc.dg/stack-check-6a.c: Skip riscv. * gcc.target/riscv/stack-check-12.c: New test. * gcc.target/riscv/stack-check-13.c: New test. * gcc.target/riscv/stack-check-cfa-1.c: New test. * gcc.target/riscv/stack-check-cfa-2.c: New test. * gcc.target/riscv/stack-check-prologue-1.c: New test. * gcc.target/riscv/stack-check-prologue-10.c: New test. * gcc.target/riscv/stack-check-prologue-11.c: New test. * gcc.target/riscv/stack-check-prologue-12.c: New test. * gcc.target/riscv/stack-check-prologue-13.c: New test. * gcc.target/riscv/stack-check-prologue-14.c: New test. * gcc.target/riscv/stack-check-prologue-15.c: New test. * gcc.target/riscv/stack-check-prologue-2.c: New test. * gcc.target/riscv/stack-check-prologue-3.c: New test. * gcc.target/riscv/stack-check-prologue-4.c: New test. * gcc.target/riscv/stack-check-prologue-5.c: New test. * gcc.target/riscv/stack-check-prologue-6.c: New test. * gcc.target/riscv/stack-check-prologue-7.c: New test. * gcc.target/riscv/stack-check-prologue-8.c: New test. * gcc.target/riscv/stack-check-prologue-9.c: New test. * gcc.target/riscv/stack-check-prologue.h: New file. * lib/target-supports.exp (check_effective_target_supports_stack_clash_protection): Add riscv. (check_effective_target_caller_implicit_probes): Likewise. Diff: --- gcc/config/riscv/riscv.cc | 244 ++--- gcc/config/riscv/riscv.h | 8 + gcc/testsuite/gcc.dg/params/blocksort-part.c | 2 +- gcc/testsuite/gcc.dg/pr82788.c | 2 +- gcc/testsuite/gcc.dg/stack-check-6.c | 2 +- gcc/testsuite/gcc.dg/stack-check-6a.c | 2 +- gcc/testsuite/gcc.target/riscv/stack-check-12.c| 23 ++ gcc/testsuite/gcc.target/riscv/stack-check-13.c| 26 +++ gcc/testsuite/gcc.target/riscv/stack-check-cfa-1.c | 12 + gcc/testsuite/gcc.target/riscv/stack-check-cfa-2.c | 13 ++ .../gcc.target/riscv/stack-check-prologue-1.c | 9 + .../gcc.target/riscv/stack-check-prologue-10.c | 11 + .../gcc.target/riscv/stack-check-prologue-11.c | 11 + .../gcc.target/riscv/stack-check-prologue-12.c | 15 ++ .../gcc.target/riscv/stack-check-prologue-13.c | 20 ++ .../gcc.target/riscv/stack-check-prologue-14.c | 24 ++ .../gcc.target/riscv/stack-check-prologue-15.c | 23 ++ .../gcc.target/riscv/stack-check-prologue-2.c | 10 + .../gcc.target/riscv/stack-check-prologue-3.c | 11 + .../gcc.target/riscv/stack-check-prologue-4.c | 11 + .../gcc.target/riscv/stack-check-prologue-5.c | 11 + .../gcc.target/riscv/stack-check-prologue-6.c | 11 + .../gcc.target/riscv/stack-check-prologue-7.c | 11 + .../gcc.target/riscv/stack-check-prologue-8.c | 10 + .../gcc.target/riscv/stack-check-prologue-9.c | 11 + .../gcc.target/riscv/stack-check-prologue.h| 5 + gcc/testsuite/lib/target-supports.exp | 6 +- 27 files changed, 504 insertions(+), 40 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index eb32520b36cc..63139afd3e36 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7953,6 +7953,191 @@ get_multi_push_fpr_mask (unsigned max_fprs_push) return mask_fprs_push; } +/* A
[gcc r15-2853] RISC-V: Add support to vector stack-clash protection
https://gcc.gnu.org/g:2862d99bfdae96a1d4b275fa3f3daad6206ff761 commit r15-2853-g2862d99bfdae96a1d4b275fa3f3daad6206ff761 Author: Raphael Moreira Zinsly Date: Mon Jul 22 11:23:23 2024 -0300 RISC-V: Add support to vector stack-clash protection Adds basic support to vector stack-clash protection using a loop to do the probing and stack adjustments. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_allocate_and_probe_stack_loop): New function. (riscv_v_adjust_scalable_frame): Add stack-clash protection support. (riscv_allocate_and_probe_stack_space): Move the probe loop implementation to riscv_allocate_and_probe_stack_loop. * config/riscv/riscv.h: Define RISCV_STACK_CLASH_VECTOR_CFA_REGNUM. gcc/testsuite/ChangeLog: * gcc.target/riscv/stack-check-cfa-3.c: New test. * gcc.target/riscv/stack-check-prologue-16.c: New test. * gcc.target/riscv/struct_vect_24.c: New test. Diff: --- gcc/config/riscv/riscv.cc | 99 +- gcc/config/riscv/riscv.h | 5 ++ gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c | 13 +++ .../gcc.target/riscv/stack-check-prologue-16.c | 30 +++ gcc/testsuite/gcc.target/riscv/struct_vect_24.c| 47 ++ 5 files changed, 173 insertions(+), 21 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 63139afd3e36..034290617624 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7900,6 +7900,35 @@ static const code_for_push_pop_t code_for_push_pop[ZCMP_MAX_GRP_SLOTS][ZCMP_OP_N code_for_gpr_multi_popret_up_to_s11, code_for_gpr_multi_popretz_up_to_s11}}; +/* Set a probe loop for stack clash protection. */ +static void +riscv_allocate_and_probe_stack_loop (rtx tmp, enum rtx_code code, +rtx op0, rtx op1, bool vector, +HOST_WIDE_INT offset) +{ + tmp = riscv_force_temporary (tmp, gen_int_mode (offset, Pmode)); + + /* Loop. */ + rtx label = gen_label_rtx (); + emit_label (label); + + /* Allocate and probe stack. */ + emit_insn (gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, tmp)); + emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, + STACK_CLASH_CALLER_GUARD)); + emit_insn (gen_blockage ()); + + /* Adjust the remaining vector length. */ + if (vector) +emit_insn (gen_sub3_insn (op0, op0, tmp)); + + /* Branch if there's still more bytes to probe. */ + riscv_expand_conditional_branch (label, code, op0, op1); + JUMP_LABEL (get_last_insn ()) = label; + + emit_insn (gen_blockage ()); +} + /* Adjust scalable frame of vector for prologue && epilogue. */ static void @@ -7912,6 +7941,49 @@ riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue) riscv_legitimize_poly_move (Pmode, adjust_size, tmp, gen_int_mode (offset, Pmode)); + /* If doing stack clash protection then we use a loop to allocate and probe + the stack. */ + if (flag_stack_clash_protection && !epilogue) +{ + HOST_WIDE_INT min_probe_threshold + = (1 << param_stack_clash_protection_guard_size) - STACK_CLASH_CALLER_GUARD; + + if (!frame_pointer_needed) + { + /* This is done to provide unwinding information for the stack +adjustments we're about to do, however to prevent the optimizers +from removing the T3 move and leaving the CFA note (which would be +very wrong) we tie the old and new stack pointer together. +The tie will expand to nothing but the optimizers will not touch +the instruction. */ + insn = get_last_insn (); + rtx stack_ptr_copy = gen_rtx_REG (Pmode, RISCV_STACK_CLASH_VECTOR_CFA_REGNUM); + emit_move_insn (stack_ptr_copy, stack_pointer_rtx); + riscv_emit_stack_tie (stack_ptr_copy); + + /* We want the CFA independent of the stack pointer for the +duration of the loop. */ + add_reg_note (insn, REG_CFA_DEF_CFA, stack_ptr_copy); + RTX_FRAME_RELATED_P (insn) = 1; + } + + riscv_allocate_and_probe_stack_loop (tmp, GE, adjust_size, tmp, true, + min_probe_threshold); + + /* Allocate the residual. */ + insn = emit_insn (gen_sub3_insn (target, target, adjust_size)); + + /* Now reset the CFA register if needed. */ + if (!frame_pointer_needed) + { + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (Pmode, stack_pointer_rtx, -offset)); + RTX_FRAME_RELATED_P (insn) = 1; + } + + return; +} + if (epilogue) insn = gen_add3_insn (target, target, adjust_size); else @@ -8059,8 +8131,9 @@ riscv_allocate_and_probe_stack_space (rtx temp1, HOST_WIDE_INT size
[gcc r15-2854] RISC-V: Enable stack clash in alloca
https://gcc.gnu.org/g:180ede3543e98ade8f809afe8be5af0eeaeff7bb commit r15-2854-g180ede3543e98ade8f809afe8be5af0eeaeff7bb Author: Raphael Moreira Zinsly Date: Mon Jul 22 11:23:27 2024 -0300 RISC-V: Enable stack clash in alloca Add the TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE to riscv in order to enable stack clash protection when using alloca. The code and tests are the same used by aarch64. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_compute_frame_info): Update outgoing args size. (riscv_stack_clash_protection_alloca_probe_range): New. (TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE): New. * config/riscv/riscv.h (STACK_CLASH_MIN_BYTES_OUTGOING_ARGS): New. (STACK_DYNAMIC_OFFSET): New. gcc/testsuite/ChangeLog: * gcc.target/riscv/stack-check-14.c: New test. * gcc.target/riscv/stack-check-15.c: New test. * gcc.target/riscv/stack-check-alloca-1.c: New test. * gcc.target/riscv/stack-check-alloca-2.c: New test. * gcc.target/riscv/stack-check-alloca-3.c: New test. * gcc.target/riscv/stack-check-alloca-4.c: New test. * gcc.target/riscv/stack-check-alloca-5.c: New test. * gcc.target/riscv/stack-check-alloca-6.c: New test. * gcc.target/riscv/stack-check-alloca-7.c: New test. * gcc.target/riscv/stack-check-alloca-8.c: New test. * gcc.target/riscv/stack-check-alloca-9.c: New test. * gcc.target/riscv/stack-check-alloca-10.c: New test. * gcc.target/riscv/stack-check-alloca.h: New. Diff: --- gcc/config/riscv/riscv.cc | 17 +++ gcc/config/riscv/riscv.h | 17 +++ gcc/testsuite/gcc.target/riscv/stack-check-14.c| 24 ++ gcc/testsuite/gcc.target/riscv/stack-check-15.c| 21 +++ .../gcc.target/riscv/stack-check-alloca-1.c| 15 ++ .../gcc.target/riscv/stack-check-alloca-10.c | 13 .../gcc.target/riscv/stack-check-alloca-2.c| 11 ++ .../gcc.target/riscv/stack-check-alloca-3.c| 11 ++ .../gcc.target/riscv/stack-check-alloca-4.c| 12 +++ .../gcc.target/riscv/stack-check-alloca-5.c| 12 +++ .../gcc.target/riscv/stack-check-alloca-6.c| 12 +++ .../gcc.target/riscv/stack-check-alloca-7.c| 12 +++ .../gcc.target/riscv/stack-check-alloca-8.c| 14 + .../gcc.target/riscv/stack-check-alloca-9.c| 13 .../gcc.target/riscv/stack-check-alloca.h | 15 ++ 15 files changed, 219 insertions(+) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 034290617624..a1b09e865ea7 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7248,6 +7248,10 @@ riscv_compute_frame_info (void) frame = &cfun->machine->frame; + /* Adjust the outgoing arguments size if required. Keep it in sync with what + the mid-end is doing. */ + crtl->outgoing_args_size = STACK_DYNAMIC_OFFSET (cfun); + /* In an interrupt function, there are two cases in which t0 needs to be used: 1, If we have a large frame, then we need to save/restore t0. We check for this before clearing the frame struct. @@ -11939,6 +11943,15 @@ riscv_c_mode_for_floating_type (enum tree_index ti) return default_mode_for_floating_type (ti); } +/* On riscv we have an ABI defined safe buffer. This constant is used to + determining the probe offset for alloca. */ + +static HOST_WIDE_INT +riscv_stack_clash_protection_alloca_probe_range (void) +{ + return STACK_CLASH_CALLER_GUARD; +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -12247,6 +12260,10 @@ riscv_c_mode_for_floating_type (enum tree_index ti) #define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \ riscv_vectorize_preferred_vector_alignment +#undef TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE +#define TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE \ + riscv_stack_clash_protection_alloca_probe_range + /* Mode switching hooks. */ #undef TARGET_MODE_EMIT diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 58e17178212b..ead97867eb8e 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -1271,4 +1271,21 @@ extern void riscv_remove_unneeded_save_restore_calls (void); generating stack clash probes. */ #define STACK_CLASH_MAX_UNROLL_PAGES 4 +/* This value represents the minimum amount of bytes we expect the function's + outgoing arguments to be when stack-clash is enabled. */ +#define STACK_CLASH_MIN_BYTES_OUTGOING_ARGS 8 + +/* Allocate a minimum of STACK_CLASH_MIN_BYTES_OUTGOING_ARGS bytes for the + outgoing arguments if stack clash p
[gcc r15-2855] c++: Don't accept multiple enum definitions within template class [PR115806]
https://gcc.gnu.org/g:786ebbd6058540b2110da16a693f0c582c11413c commit r15-2855-g786ebbd6058540b2110da16a693f0c582c11413c Author: Simon Martin Date: Thu Aug 8 14:59:49 2024 +0200 c++: Don't accept multiple enum definitions within template class [PR115806] We have been accepting the following invalid code since revision 557831a91df === cut here === template struct S { enum E { a }; enum E { b }; }; S s; === cut here === The problem is that start_enum will set OPAQUE_ENUM_P to true even if it retrieves an existing definition for the enum, which causes the redefinition check in cp_parser_enum_specifier to be bypassed. This patch only sets OPAQUE_ENUM_P and ENUM_FIXED_UNDERLYING_TYPE_P when actually pushing a new tag for the enum. PR c++/115806 gcc/cp/ChangeLog: * decl.cc (start_enum): Only set OPAQUE_ENUM_P and ENUM_FIXED_UNDERLYING_TYPE_P when pushing a new tag. gcc/testsuite/ChangeLog: * g++.dg/parse/enum15.C: New test. Diff: --- gcc/cp/decl.cc | 22 -- gcc/testsuite/g++.dg/parse/enum15.C | 9 + 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index a468bfdb7b67..f23b635aec9f 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -17059,22 +17059,24 @@ start_enum (tree name, tree enumtype, tree underlying_type, enumtype = cxx_make_type (ENUMERAL_TYPE); enumtype = pushtag (name, enumtype); - /* std::byte aliases anything. */ - if (enumtype != error_mark_node - && TYPE_CONTEXT (enumtype) == std_node - && !strcmp ("byte", TYPE_NAME_STRING (enumtype))) - TYPE_ALIAS_SET (enumtype) = 0; + if (enumtype != error_mark_node) + { + /* The enum is considered opaque until the opening '{' of the +enumerator list. */ + SET_OPAQUE_ENUM_P (enumtype, true); + ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) = !! underlying_type; + + /* std::byte aliases anything. */ + if (TYPE_CONTEXT (enumtype) == std_node + && !strcmp ("byte", TYPE_NAME_STRING (enumtype))) + TYPE_ALIAS_SET (enumtype) = 0; + } } else enumtype = xref_tag (enum_type, name); if (enumtype == error_mark_node) return error_mark_node; - - /* The enum is considered opaque until the opening '{' of the -enumerator list. */ - SET_OPAQUE_ENUM_P (enumtype, true); - ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) = !! underlying_type; } SET_SCOPED_ENUM_P (enumtype, scoped_enum_p); diff --git a/gcc/testsuite/g++.dg/parse/enum15.C b/gcc/testsuite/g++.dg/parse/enum15.C new file mode 100644 index ..d19262156b91 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/enum15.C @@ -0,0 +1,9 @@ +// PR c++/115806 +// { dg-do compile } + +template +struct S { + enum E { a }; // { dg-note "previous definition" } + enum E { b }; // { dg-error "multiple definition" } +}; +S s;
[gcc r15-2856] btf: Protect BTF_KIND_INFO against invalid kind
https://gcc.gnu.org/g:d0bc1cbf6a8938220f42d8102031fd6f6644e171 commit r15-2856-gd0bc1cbf6a8938220f42d8102031fd6f6644e171 Author: Will Hawkins Date: Mon Jul 29 10:42:48 2024 -0400 btf: Protect BTF_KIND_INFO against invalid kind If the user provides a kind value that is more than 5 bits, the BTF_KIND_INFO macro would emit incorrect values for info (by clobbering values of the kind flag). Tested on x86_64-redhat-linux. include/ChangeLog: * btf.h (BTF_TYPE_INFO): Protect against user providing invalid kind. Signed-off-by: Will Hawkins Diff: --- include/btf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/btf.h b/include/btf.h index 3f45ffb0b6bb..0c3e1a1cf518 100644 --- a/include/btf.h +++ b/include/btf.h @@ -82,7 +82,7 @@ struct btf_type }; }; -/* The folloing macros access the information encoded in btf_type.info. */ +/* The following macros access the information encoded in btf_type.info. */ /* Type kind. See below. */ #define BTF_INFO_KIND(info)(((info) >> 24) & 0x1f) /* Number of entries of variable length data following certain type kinds. @@ -95,7 +95,7 @@ struct btf_type /* Encoding for struct btf_type.info. */ #define BTF_TYPE_INFO(kind, kflag, vlen) \ - kflag) ? 1 : 0 ) << 31) | ((kind) << 24) | ((vlen) & 0x)) + kflag) ? 1 : 0 ) << 31) | ((kind & 0x1f) << 24) | ((vlen) & 0x)) #define BTF_KIND_UNKN 0 /* Unknown or invalid. */ #define BTF_KIND_INT 1 /* Integer. */
[gcc r15-2858] Adjust rangers recomputation depth based on the number of BBs.
https://gcc.gnu.org/g:9e4da946c4263a4c89d5fc365b3c97ae244c5018 commit r15-2858-g9e4da946c4263a4c89d5fc365b3c97ae244c5018 Author: Andrew MacLeod Date: Thu Aug 8 16:37:28 2024 -0400 Adjust rangers recomputation depth based on the number of BBs. As the number of block increase, recomputations can become more expensive. Adjust the depth limit to avoid excessive compile time. PR tree-optimization/114855 * gimple-range-gori.cc (gori_compute::gori_compute): Adjust ranger_recompute_depth limit based on the number of BBs. (gori_compute::may_recompute_p): Use previosuly calculated value. * gimple-range-gori.h (gori_compute::m_recompute_depth): New. Diff: --- gcc/gimple-range-gori.cc | 12 gcc/gimple-range-gori.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index a31e3be65f79..f2e2b5049aaa 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -567,6 +567,13 @@ gori_compute::gori_compute (gori_map &map, int not_executable_flag, m_bool_one = range_true (); if (dump_file && (param_ranger_debug & RANGER_DEBUG_GORI)) tracer.enable_trace (); + + // Reduce maximum recompute depth based on the size of the CFG to avoid + // excessive compuations in large CFGs. + m_recompute_depth = (int) param_ranger_recompute_depth + - (int) last_basic_block_for_fn (cfun) / 4096; + if (m_recompute_depth < 1) +m_recompute_depth = 1; } gori_compute::~gori_compute () @@ -1327,10 +1334,7 @@ gori_compute::may_recompute_p (tree name, basic_block bb, int depth) { // -1 indicates a default param, convert it to the real default. if (depth == -1) - { - depth = (int)param_ranger_recompute_depth; - gcc_checking_assert (depth >= 1); - } + depth = m_recompute_depth; bool res = m_map.is_export_p (dep1, bb); if (res || depth <= 1) diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index 11019e38471e..97e051cd3170 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -206,6 +206,7 @@ private: range_tracer tracer; int m_not_executable_flag; + int m_recompute_depth; }; // These APIs are used to query GORI if there are ranges generated on an edge.
[gcc r15-2857] Limit equivalency processing in rangers cache.
https://gcc.gnu.org/g:5ce3874b3c2fdd76f506005cb1171a732af7c807 commit r15-2857-g5ce3874b3c2fdd76f506005cb1171a732af7c807 Author: Andrew MacLeod Date: Thu Aug 8 16:34:15 2024 -0400 Limit equivalency processing in rangers cache. When the number of block exceed VRP's sparse threshold, do not query all equivalencies during cache filling. This can be expensive for unknown benefit. PR tree-optimization/114855 * gimple-range-cache.cc (ranger_cache::fill_block_cache): Do not process equivalencies if the number of blocks is too high. Diff: --- gcc/gimple-range-cache.cc | 8 1 file changed, 8 insertions(+) diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 0fffd7c16a1c..43949894cbed 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -1486,6 +1486,14 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb) tree equiv_name; relation_kind rel; int prec = TYPE_PRECISION (type); + // If there are too many basic blocks, do not attempt to process + // equivalencies. + if (last_basic_block_for_fn (cfun) > param_vrp_sparse_threshold) + { + m_on_entry.set_bb_range (name, bb, block_result); + gcc_checking_assert (m_workback.length () == start_length); + return; + } FOR_EACH_PARTIAL_AND_FULL_EQUIV (m_relation, bb, name, equiv_name, rel) { basic_block equiv_bb = gimple_bb (SSA_NAME_DEF_STMT (equiv_name));
[gcc r15-2859] Revert "lra: emit caller-save register spills before call insn [PR116028]"
https://gcc.gnu.org/g:4734c1bfe837b3e70bc783dafc442de3bca43d88 commit r15-2859-g4734c1bfe837b3e70bc783dafc442de3bca43d88 Author: Kyrylo Tkachov Date: Fri Aug 9 21:16:56 2024 +0200 Revert "lra: emit caller-save register spills before call insn [PR116028]" This reverts commit 3c67a0fa1dd39a3378deb854a7fef0ff7fe38004. Diff: --- gcc/lra-constraints.cc | 28 gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c | 2 +- gcc/testsuite/gcc.dg/pr10474.c | 2 +- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 28c1a877c003..92b343fa99a0 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -152,9 +152,6 @@ static machine_mode curr_operand_mode[MAX_RECOG_OPERANDS]; (e.g. constant) and whose subreg is given operand of the current insn. VOIDmode in all other cases. */ static machine_mode original_subreg_reg_mode[MAX_RECOG_OPERANDS]; -/* The nearest call insn for an insn on which split transformation - will be done. The call insn is in the same EBB as the insn. */ -static rtx_insn *latest_call_insn; @@ -6289,25 +6286,10 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn, after_p ? restore : NULL, call_save_p ? "Add reg<-save" : "Add reg<-split"); - if (call_save_p && latest_call_insn != NULL) -/* PR116028: If original_regno is a pseudo that has been assigned a - call-save hard register, then emit the spill insn before the call - insn 'latest_call_insn' instead of adjacent to 'insn'. If 'insn' - and 'latest_call_insn' belong to the same EBB but to two separate - BBs, and if 'insn' is present in the entry BB, then generating the - spill insn in the entry BB can prevent shrink wrap from happening. - This is because the spill insn references the stack pointer and - hence the prolog gets generated in the entry BB itself. It is - also more efficient to generate the spill before - 'latest_call_insn' as the spill now occurs only in the path - containing the call. */ -lra_process_new_insns (PREV_INSN (latest_call_insn), NULL, save, - "Add save<-reg"); - else -lra_process_new_insns (insn, before_p ? save : NULL, - before_p ? NULL : save, - call_save_p - ? "Add save<-reg" : "Add split<-reg"); + lra_process_new_insns (insn, before_p ? save : NULL, +before_p ? NULL : save, +call_save_p +? "Add save<-reg" : "Add split<-reg"); if (nregs > 1 || original_regno < FIRST_PSEUDO_REGISTER) /* If we are trying to split multi-register. We should check conflicts on the next assignment sub-pass. IRA can allocate on @@ -6791,7 +6773,6 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) last_processed_bb = NULL; CLEAR_HARD_REG_SET (potential_reload_hard_regs); live_hard_regs = eliminable_regset | lra_no_alloc_regs; - latest_call_insn = NULL; /* We don't process new insns generated in the loop. */ for (curr_insn = tail; curr_insn != PREV_INSN (head); curr_insn = prev_insn) { @@ -7004,7 +6985,6 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) last_call_for_abi[callee_abi.id ()] = calls_num; full_and_partial_call_clobbers |= callee_abi.full_and_partial_reg_clobbers (); - latest_call_insn = curr_insn; if ((cheap = find_reg_note (curr_insn, REG_RETURNED, NULL_RTX)) != NULL_RTX && ((cheap = XEXP (cheap, 0)), true) diff --git a/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c index 8c150972f952..a95637abbe54 100644 --- a/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c +++ b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c @@ -26,4 +26,4 @@ bar (long a) /* { dg-final { scan-rtl-dump "Will split live ranges of parameters" "ira" } } */ /* { dg-final { scan-rtl-dump "Split live-range of register" "ira" { xfail { ! aarch64*-*-* } } } } */ -/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" } } */ +/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" { xfail powerpc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/pr10474.c b/gcc/testsuite/gcc.dg/pr10474.c index b5393d5b6e3e..a4af536ec284 100644 --- a/gcc/testsuite/gcc.dg/pr10474.c +++ b/gcc/testsuite/gcc.dg/pr10474.c @@ -13,4 +13,4 @@ void f(int *i) } /* XFAIL due to PR70681. */ -/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" { xfail arm*-*-* } } } */ +/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" { xfail arm*-*-* powerpc*-*-* } } } */
[gcc r15-2860] [RISC-V][PR target/116283] Fix split code for recent Zbs improvements with masked bit positions
https://gcc.gnu.org/g:d4e1290e5d603984e9b410c7d4cf21a9ffbd68fd commit r15-2860-gd4e1290e5d603984e9b410c7d4cf21a9ffbd68fd Author: Jeff Law Date: Fri Aug 9 17:46:01 2024 -0600 [RISC-V][PR target/116283] Fix split code for recent Zbs improvements with masked bit positions So Patrick's fuzzer found an interesting little buglet in the Zbs improvements I added a couple months back. Specifically when we have masked bit position for a Zbs instruction. If the mask has extraneous bits set we'll generate an unrecognizable insn due to an invalid constant. More concretely, let's take this pattern: > (define_insn_and_split "" > [(set (match_operand:DI 0 "register_operand" "=r") > (any_extend:DI > (ashift:SI (const_int 1) > (subreg:QI(and:DI (match_operand:DI 1 "register_operand" "r") > (match_operand 2 "const_int_operand")) 0] What we need to know to transform this into bset for rv64. After masking the shift count we want to know the low 5 bits aren't 0x1f. If they were 0x1f, then the constant generated would be 0x8000 which would then need sign extension out to 64bits, which the bset instruction will not do for us. We can ignore anything outside the low 5 bits. The mode of the shift is SI, so shifting by 32+ bits is undefined behavior. It's also worth explicitly mentioning that the hardware is going to mask the count against 0x3f. The net is if (operands[2] & 0x1f) != 0x1f, then this transformation is safe. So onto the generated split code... > [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 2))) >(set (match_dup 0) (zero_extend:DI (ashift:SI > (const_int 1) > (subreg:QI (match_dup 0) 0] Which would seemingly do exactly what we want. The problem is the first split insn. If the constant does not fit into a simm12, that insn won't be recognized resulting in the ICE. The fix is simple, we just need to mask the constant before generating RTL. We can just mask it against 0x1f since we only care about the low 5 bits. This affects multiple patterns. I've added the appropriate fix to all of them. Tested in my tester. Waiting for the pre-commit bits to run before pushing. PR target/116283 gcc/ * config/riscv/bitmanip.md (Zbs combiner patterns/splitters): Mask the bit position in the split code appropriately. gcc/testsuite/ * gcc.target/riscv/pr116283.c: New test Diff: --- gcc/config/riscv/bitmanip.md | 24 ++-- gcc/testsuite/gcc.target/riscv/pr116283.c | 15 +++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index b19295cd9424..6872ee56022c 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -643,7 +643,10 @@ (set (match_dup 3) (and:DI (not:DI (match_dup 1)) (match_dup 3))) (set (match_dup 0) (zero_extend:DI (ashift:SI (const_int 1) (match_dup 4] - { operands[4] = gen_lowpart (QImode, operands[3]); } +{ + operands[4] = gen_lowpart (QImode, operands[3]); + operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); +} [(set_attr "type" "bitmanip")]) (define_insn_and_split "" @@ -662,7 +665,7 @@ (set (match_dup 0) (zero_extend:DI (ashift:SI (const_int 1) (subreg:QI (match_dup 0) 0] - { } + { operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); } [(set_attr "type" "bitmanip")]) ;; Similarly two patterns for IOR/XOR generating bset/binv to @@ -687,7 +690,10 @@ [(set (match_dup 4) (match_dup 2)) (set (match_dup 4) (and:DI (not:DI (match_dup 1)) (match_dup 4))) (set (match_dup 0) (any_or:DI (ashift:DI (const_int 1) (match_dup 5)) (match_dup 3)))] - { operands[5] = gen_lowpart (QImode, operands[4]); } +{ + operands[5] = gen_lowpart (QImode, operands[4]); + operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); +} [(set_attr "type" "bitmanip")]) (define_insn_and_split "" @@ -708,7 +714,7 @@ "&& reload_completed" [(set (match_dup 4) (and:DI (match_dup 1) (match_dup 2))) (set (match_dup 0) (any_or:DI (ashift:DI (const_int 1) (subreg:QI (match_dup 4) 0)) (match_dup 3)))] - { } + { operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); } [(set_attr "type" "bitmanip")]) ;; Similarly two patterns for AND generating bclr to @@ -734,7 +740,10 @@ [(set (match_dup 4) (match_dup 2)) (set (match_dup 4) (and:DI (not:DI (match_dup 1)) (match_dup 4))) (set (match_dup 0) (and:DI (rotate:DI (const_int -2) (match_dup 5)) (match_dup 3)))]
[gcc r15-2862] c++: clean up cp_identifier_kind checks
https://gcc.gnu.org/g:cf7feae517d4819cd33ef6bb123217ea39845fd1 commit r15-2862-gcf7feae517d4819cd33ef6bb123217ea39845fd1 Author: Patrick Palka Date: Fri Aug 9 21:13:03 2024 -0400 c++: clean up cp_identifier_kind checks The predicates for checking an IDENTIFIER node's cp_identifier_kind currently directly test the three flag bits that encode the kind. This patch instead makes the checks first reconstruct the cp_identifier_kind in its entirety and then compare that. gcc/cp/ChangeLog: * cp-tree.h (get_identifier_kind): Define. (IDENTIFIER_KEYWORD_P): Redefine in terms of get_identifier_kind. (IDENTIFIER_CDTOR_P): Likewise. (IDENTIFIER_CTOR_P): Likewise. (IDENTIFIER_DTOR_P): Likewise. (IDENTIFIER_ANY_OP_P): Likewise. (IDENTIFIER_OVL_OP_P): Likewise. (IDENTIFIER_ASSIGN_OP_P): Likewise. (IDENTIFIER_CONV_OP_P): Likewise. (IDENTIFIER_TRAIT_P): Likewise. * parser.cc (cp_lexer_peek_trait): Mark IDENTIFIER_TRAIT_P check UNLIKELY. Reviewed-by: Jason Merrill Diff: --- gcc/cp/cp-tree.h | 41 + gcc/cp/parser.cc | 3 ++- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b1693051231b..5807f4e0edb3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1255,56 +1255,57 @@ enum cp_identifier_kind { #define IDENTIFIER_VIRTUAL_P(NODE) \ TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (NODE)) +/* Return the cp_identifier_kind of the given IDENTIFIER node ID. */ + +ATTRIBUTE_PURE inline cp_identifier_kind +get_identifier_kind (tree id) +{ + unsigned bit0 = IDENTIFIER_KIND_BIT_0 (id); + unsigned bit1 = IDENTIFIER_KIND_BIT_1 (id); + unsigned bit2 = IDENTIFIER_KIND_BIT_2 (id); + return cp_identifier_kind ((bit2 << 2) | (bit1 << 1) | bit0); +} + /* True if this identifier is a reserved word. C_RID_CODE (node) is then the RID_* value of the keyword. Value 1. */ #define IDENTIFIER_KEYWORD_P(NODE) \ - ((!IDENTIFIER_KIND_BIT_2 (NODE)) \ - & (!IDENTIFIER_KIND_BIT_1 (NODE)) \ - & IDENTIFIER_KIND_BIT_0 (NODE)) + (get_identifier_kind (NODE) == cik_keyword) /* True if this identifier is the name of a constructor or destructor. Value 2 or 3. */ #define IDENTIFIER_CDTOR_P(NODE) \ - ((!IDENTIFIER_KIND_BIT_2 (NODE)) \ - & IDENTIFIER_KIND_BIT_1 (NODE)) + (IDENTIFIER_CTOR_P (NODE) || IDENTIFIER_DTOR_P (NODE)) /* True if this identifier is the name of a constructor. Value 2. */ #define IDENTIFIER_CTOR_P(NODE)\ - (IDENTIFIER_CDTOR_P(NODE)\ -& (!IDENTIFIER_KIND_BIT_0 (NODE))) + (get_identifier_kind (NODE) == cik_ctor) /* True if this identifier is the name of a destructor. Value 3. */ #define IDENTIFIER_DTOR_P(NODE)\ - (IDENTIFIER_CDTOR_P(NODE)\ -& IDENTIFIER_KIND_BIT_0 (NODE)) + (get_identifier_kind (NODE) == cik_dtor) /* True if this identifier is for any operator name (including conversions). Value 4, 5, or 6. */ #define IDENTIFIER_ANY_OP_P(NODE) \ - (IDENTIFIER_KIND_BIT_2 (NODE) && !IDENTIFIER_TRAIT_P (NODE)) + (IDENTIFIER_OVL_OP_P (NODE) || IDENTIFIER_CONV_OP_P (NODE)) /* True if this identifier is for an overloaded operator. Values 4, 5. */ #define IDENTIFIER_OVL_OP_P(NODE) \ - (IDENTIFIER_ANY_OP_P (NODE) \ - & (!IDENTIFIER_KIND_BIT_1 (NODE))) + (get_identifier_kind (NODE) == cik_simple_op \ + || get_identifier_kind (NODE) == cik_assign_op) /* True if this identifier is for any assignment. Values 5. */ #define IDENTIFIER_ASSIGN_OP_P(NODE) \ - (IDENTIFIER_OVL_OP_P (NODE) \ - & IDENTIFIER_KIND_BIT_0 (NODE)) + (get_identifier_kind (NODE) == cik_assign_op) /* True if this identifier is the name of a type-conversion operator. Value 6. */ #define IDENTIFIER_CONV_OP_P(NODE) \ - (IDENTIFIER_ANY_OP_P (NODE) \ - & IDENTIFIER_KIND_BIT_1 (NODE) \ - & (!IDENTIFIER_KIND_BIT_0 (NODE))) + (get_identifier_kind (NODE) == cik_conv_op) /* True if this identifier is the name of a built-in trait. */ #define IDENTIFIER_TRAIT_P(NODE) \ - (IDENTIFIER_KIND_BIT_0 (NODE)\ - & IDENTIFIER_KIND_BIT_1 (NODE) \ - & IDENTIFIER_KIND_BIT_2 (NODE)) + (get_identifier_kind (NODE) == cik_trait) /* True if this identifier is a new or delete operator. */ #define IDENTIFIER_NEWDEL_OP_P(NODE) \ diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 82f3903838e2..852efe45076f 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -1198,7 +1198,8 @@ static const cp_trait * cp_lexer_peek_trait (cp_lexer *lexer) { const cp_token *token1 = cp_lexer_peek_toke
[gcc r15-2863] c++: DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P tweaks
https://gcc.gnu.org/g:70da0ca1239faefa6dec0494a85e998eae34beff commit r15-2863-g70da0ca1239faefa6dec0494a85e998eae34beff Author: Patrick Palka Date: Fri Aug 9 21:13:05 2024 -0400 c++: DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P tweaks DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P templates can only appear as part of a template friend declaration, and in turn get partially instantiated only from tsubst_friend_function or tsubst_friend_class. So rather than having tsubst_template_decl clear the flag, let's leave it up to the tsubst friend routines to clear it so that template friend handling stays localized (note that tsubst_friend_function was already clearing it). Also the template depth comparison test within tsubst_friend_function is equivalent to DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P since such templates belong to the class context (and so always have more levels than the context), and conversely and it isn't possible to directly refer to an existing template that has more levels than the class context. gcc/cp/ChangeLog: * pt.cc (tsubst_friend_class): Simplify depth comparison test in the redeclaration code path to DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P. Clear the flag after partial instantiation here ... (tsubst_template_decl): ... instead of here. Reviewed-by: Jason Merrill Diff: --- gcc/cp/pt.cc | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 1dde7d167fd6..c1d4cdc7e259 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -11772,8 +11772,7 @@ tsubst_friend_class (tree friend_tmpl, tree args) compatible with the attachment of the friend template. */ module_may_redeclare (tmpl, friend_tmpl); - if (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (friend_tmpl)) - > TMPL_ARGS_DEPTH (args)) + if (DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (friend_tmpl)) { tree parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl), args, tf_warning_or_error); @@ -11815,6 +11814,7 @@ tsubst_friend_class (tree friend_tmpl, tree args) CLASSTYPE_USE_TEMPLATE (TREE_TYPE (tmpl)) = 0; CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)) = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl))); + DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (tmpl) = false; /* Substitute into and set the constraints on the new declaration. */ if (tree ci = get_constraints (friend_tmpl)) @@ -15044,8 +15044,6 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, if (PRIMARY_TEMPLATE_P (t)) DECL_PRIMARY_TEMPLATE (r) = r; - DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (r) = false; - if (!lambda_fntype && !class_p) { /* Record this non-type partial instantiation. */
[gcc r15-2864] c++: inherited CTAD fixes [PR116276]
https://gcc.gnu.org/g:8cc67b520968ca9a13fd96896522aa66e39a99e2 commit r15-2864-g8cc67b520968ca9a13fd96896522aa66e39a99e2 Author: Patrick Palka Date: Fri Aug 9 21:15:25 2024 -0400 c++: inherited CTAD fixes [PR116276] This implements the overlooked inherited vs non-inherited guide tiebreaker from P2582R1. This requires tracking inherited-ness of a guide, for which it seems natural to reuse the lang_decl_fn::context field which for a constructor tracks its inherited-ness. This patch also works around CLASSTYPE_CONSTRUCTORS not reliably returning all inherited constructors (due to some using-decl handling quirks in in push_class_level_binding) by iterating over TYPE_FIELDS instead. This patch also makes us recognize another written form of inherited constructor, 'using Base::Base::Base' whose USING_DECL_SCOPE is a TYPENAME_TYPE. PR c++/116276 gcc/cp/ChangeLog: * call.cc (joust): Implement P2582R1 inherited vs non-inherited guide tiebreaker. * cp-tree.h (lang_decl_fn::context): Document usage in deduction_guide_p FUNCTION_DECLs. (inherited_guide_p): Declare. * pt.cc (inherited_guide_p): Define. (set_inherited_guide_context): Define. (alias_ctad_tweaks): Use set_inherited_guide_context. (inherited_ctad_tweaks): Recognize some inherited constructors whose scope is a TYPENAME_TYPE. (ctor_deduction_guides_for): For C++23 inherited CTAD, iterate over TYPE_FIELDS instead of CLASSTYPE_CONSTRUCTORS to recognize all inherited constructors. gcc/testsuite/ChangeLog: * g++.dg/cpp23/class-deduction-inherited4.C: Remove an xfail. * g++.dg/cpp23/class-deduction-inherited5.C: New test. * g++.dg/cpp23/class-deduction-inherited6.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/call.cc | 27 - gcc/cp/cp-tree.h | 8 ++-- gcc/cp/pt.cc | 43 .../g++.dg/cpp23/class-deduction-inherited4.C | 4 +- .../g++.dg/cpp23/class-deduction-inherited5.C | 25 .../g++.dg/cpp23/class-deduction-inherited6.C | 46 ++ 6 files changed, 139 insertions(+), 14 deletions(-) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 67d38e2a78a7..94015db4e650 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -13262,10 +13262,35 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn, else if (cand2->rewritten ()) return 1; - /* F1 is generated from a deduction-guide (13.3.1.8) and F2 is not */ if (deduction_guide_p (cand1->fn)) { gcc_assert (deduction_guide_p (cand2->fn)); + + /* F1 and F2 are generated from class template argument deduction for a +class D, and F2 is generated from inheriting constructors from a base +class of D while F1 is not, and for each explicit function argument, +the corresponding parameters of F1 and F2 are either both ellipses or +have the same type. */ + bool inherited1 = inherited_guide_p (cand1->fn); + bool inherited2 = inherited_guide_p (cand2->fn); + if (int diff = inherited2 - inherited1) + { + for (i = 0; i < len; ++i) + { + conversion *t1 = cand1->convs[i + off1]; + conversion *t2 = cand2->convs[i + off2]; + /* ??? It seems the ellipses part of this tiebreaker isn't +needed since a mismatch should have broken the tie earlier +during ICS comparison. */ + gcc_checking_assert (t1->ellipsis_p == t2->ellipsis_p); + if (!same_type_p (t1->type, t2->type)) + break; + } + if (i == len) + return diff; + } + + /* F1 is generated from a deduction-guide (13.3.1.8) and F2 is not */ /* We distinguish between candidates from an explicit deduction guide and candidates built from a constructor based on DECL_ARTIFICIAL. */ int art1 = DECL_ARTIFICIAL (cand1->fn); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5807f4e0edb3..a53fbcb43ec4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2972,9 +2972,10 @@ struct GTY(()) lang_decl_fn { this pointer and result pointer adjusting thunks are chained here. This pointer thunks to return pointer thunks will be chained on the return pointer thunk. - For a DECL_CONSTUCTOR_P FUNCTION_DECL, this is the base from - whence we inherit. Otherwise, it is the class in which a - (namespace-scope) friend is defined (if any). */ + For a DECL_CONSTRUCTOR_P or deduction_guide_p FUNCTION_DECL, + this is the base from whence we inherit. + Otherwise, it is the class in whi