[gcc r14-11807] gimple-fold: Avoid ICEs with bogus declarations like const attribute no snprintf [PR117358]
https://gcc.gnu.org/g:e326152845584d78410963e5c3d31cdbdf8f50fe commit r14-11807-ge326152845584d78410963e5c3d31cdbdf8f50fe Author: Jakub Jelinek Date: Thu Nov 28 10:51:16 2024 +0100 gimple-fold: Avoid ICEs with bogus declarations like const attribute no snprintf [PR117358] When one puts incorrect const or pure attributes on declarations of various C APIs which have corresponding builtins (vs. what they actually do), we can get tons of ICEs in gimple-fold.cc. The following patch fixes it by giving up gimple_fold_builtin_* folding if the functions don't have gimple_vdef (or for pure functions like bcmp/strchr/strstr gimple_vuse) when in SSA form (during gimplification they will surely have both of those NULL even when declared correctly, yet it is highly desirable to fold them). Or shall I replace !gimple_vdef (stmt) && gimple_in_ssa_p (cfun) tests with (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE | ECF_NOVOPS)) != 0 and !gimple_vuse (stmt) && gimple_in_ssa_p (cfun) with (gimple_call_flags (stmt) & (ECF_CONST | ECF_NOVOPS)) != 0 ? 2024-11-28 Jakub Jelinek PR tree-optimization/117358 * gimple-fold.cc (gimple_fold_builtin_memory_op): Punt if stmt has no vdef in ssa form. (gimple_fold_builtin_bcmp): Punt if stmt has no vuse in ssa form. (gimple_fold_builtin_bcopy): Punt if stmt has no vdef in ssa form. (gimple_fold_builtin_bzero): Likewise. (gimple_fold_builtin_memset): Likewise. Use return false instead of return NULL_TREE. (gimple_fold_builtin_strcpy): Punt if stmt has no vdef in ssa form. (gimple_fold_builtin_strncpy): Likewise. (gimple_fold_builtin_strchr): Punt if stmt has no vuse in ssa form. (gimple_fold_builtin_strstr): Likewise. (gimple_fold_builtin_strcat): Punt if stmt has no vdef in ssa form. (gimple_fold_builtin_strcat_chk): Likewise. (gimple_fold_builtin_strncat): Likewise. (gimple_fold_builtin_strncat_chk): Likewise. (gimple_fold_builtin_string_compare): Likewise. (gimple_fold_builtin_fputs): Likewise. (gimple_fold_builtin_memory_chk): Likewise. (gimple_fold_builtin_stxcpy_chk): Likewise. (gimple_fold_builtin_stxncpy_chk): Likewise. (gimple_fold_builtin_stpcpy): Likewise. (gimple_fold_builtin_snprintf_chk): Likewise. (gimple_fold_builtin_sprintf_chk): Likewise. (gimple_fold_builtin_sprintf): Likewise. (gimple_fold_builtin_snprintf): Likewise. (gimple_fold_builtin_fprintf): Likewise. (gimple_fold_builtin_printf): Likewise. (gimple_fold_builtin_realloc): Likewise. * gcc.c-torture/compile/pr117358.c: New test. (cherry picked from commit 29032dfa57629d1713a97b17a785273823993a91) Diff: --- gcc/gimple-fold.cc | 76 -- gcc/testsuite/gcc.c-torture/compile/pr117358.c | 17 ++ 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 3548c9144829..0d90bab595fc 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -936,6 +936,8 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, } goto done; } + else if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)) +return false; else { /* We cannot (easily) change the type of the copy if it is a storage @@ -1377,6 +1379,8 @@ gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi) /* Transform bcmp (a, b, len) into memcmp (a, b, len). */ gimple *stmt = gsi_stmt (*gsi); + if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun)) +return false; tree a = gimple_call_arg (stmt, 0); tree b = gimple_call_arg (stmt, 1); tree len = gimple_call_arg (stmt, 2); @@ -1403,6 +1407,8 @@ gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi) len) into memmove (dest, src, len). */ gimple *stmt = gsi_stmt (*gsi); + if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)) +return false; tree src = gimple_call_arg (stmt, 0); tree dest = gimple_call_arg (stmt, 1); tree len = gimple_call_arg (stmt, 2); @@ -1428,6 +1434,8 @@ gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi) /* Transform bzero (dest, len) into memset (dest, 0, len). */ gimple *stmt = gsi_stmt (*gsi); + if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)) +return false; tree dest = gimple_call_arg (stmt, 0); tree len = gimple_call_arg (stmt, 1); @@ -1457,6 +1465,9 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len) return true; } + if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)) +return false; + if (! tree_fits_uhwi_p (len)) return false; @@ -1479,20 +1490,20 @@ gimple_fold_b
[gcc r16-876] Fixup gcc.target/i386/vect-epilogues-5.c
https://gcc.gnu.org/g:c61743a186cfecd646334817f356f799502ee71a commit r16-876-gc61743a186cfecd646334817f356f799502ee71a Author: Richard Biener Date: Mon May 26 11:21:19 2025 +0200 Fixup gcc.target/i386/vect-epilogues-5.c The following adjusts the expected messages after -fopt-info-vec was improved for (masked) epilogues. * gcc.target/i386/vect-epilogues-5.c: Adjust. Diff: --- gcc/testsuite/gcc.target/i386/vect-epilogues-5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.target/i386/vect-epilogues-5.c b/gcc/testsuite/gcc.target/i386/vect-epilogues-5.c index 6772cabeb4a4..d7c75dfe5cc9 100644 --- a/gcc/testsuite/gcc.target/i386/vect-epilogues-5.c +++ b/gcc/testsuite/gcc.target/i386/vect-epilogues-5.c @@ -9,5 +9,6 @@ int test (signed char *data, int n) return sum; } -/* { dg-final { scan-tree-dump-times "loop vectorized using 64 byte vectors" 2 "vect" } } */ +/* { dg-final { scan-tree-dump-times "loop vectorized using 64 byte vectors" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "epilogue loop vectorized using masked 64 byte vectors" 1 "vect" } } */ /* { dg-final { scan-tree-dump-not "loop vectorized using 32 byte vectors" "vect" } } */
[gcc r16-877] libstdc++: Implement C++26 function_ref [PR119126]
https://gcc.gnu.org/g:545433e9bd32e965726956cb238d53b39844b85c commit r16-877-g545433e9bd32e965726956cb238d53b39844b85c Author: Tomasz Kamiński Date: Wed May 14 12:04:24 2025 +0200 libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely Signed-off-by: Tomasz Kamiński Diff: --- libstdc++-v3/doc/doxygen/stdheader.cc | 1 + libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/bits/funcref_impl.h | 198 libstdc++-v3/include/bits/funcwrap.h | 188 +++ libstdc++-v3/include/bits/utility.h| 17 ++ libstdc++-v3/include/bits/version.def | 8 + libstdc++-v3/include/bits/version.h| 10 + libstdc++-v3/include/std/functional| 3 +- libstdc++-v3/src/c++23/std.cc.in | 7 + .../testsuite/20_util/function_ref/assign.cc | 108 + .../testsuite/20_util/function_ref/call.cc | 186 +++ .../testsuite/20_util/function_ref/cons.cc | 218 + .../testsuite/20_util/function_ref/cons_neg.cc | 30 +++ .../testsuite/20_util/function_ref/conv.cc | 259 + .../testsuite/20_util/function_ref/deduction.cc| 103 .../testsuite/20_util/function_ref/mutation.cc | 85 +++ 17 files changed, 1376 insertions(+), 47 deletions(-) diff --git a/libstdc++-v3/doc/doxygen/stdheader.cc b/libstdc++-v3/doc/doxygen/stdheader.cc index 839bfc81bc02..938b2b04a262 100644 --- a/libstdc++-v3/doc/doxygen/stdheader.cc +++ b/libstdc++-v3/doc/dox
[gcc r14-11809] cselib: Fix up previous patch for SPARC [PR117239]
https://gcc.gnu.org/g:5499c332a60a6928274796af0667d40719bf0715 commit r14-11809-g5499c332a60a6928274796af0667d40719bf0715 Author: Jakub Jelinek Date: Wed Feb 5 14:06:42 2025 +0100 cselib: Fix up previous patch for SPARC [PR117239] Sorry, our CI bot just notified me I broke SPARC build. There are two #ifdef STACK_ADDRESS_OFFSET guarded snippets and the macro is only defined on SPARC target, so I didn't notice there was a syntax error. Fixed thusly. 2025-02-05 Jakub Jelinek PR rtl-optimization/117239 * cselib.cc (cselib_init): Remove spurious closing paren in the #ifdef STACK_ADDRESS_OFFSET specific code. (cherry picked from commit 6094801d6fd7849d2d95ce78f7c6ef01686b9f63) Diff: --- gcc/cselib.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cselib.cc b/gcc/cselib.cc index 2382e994ebc2..f0a8f2c7f8fb 100644 --- a/gcc/cselib.cc +++ b/gcc/cselib.cc @@ -3364,7 +3364,7 @@ cselib_init (int record_what) #ifdef STACK_ADDRESS_OFFSET /* On SPARC take stack pointer bias into account as well. */ off += (STACK_ADDRESS_OFFSET - - FIRST_PARM_OFFSET (current_function_decl))); + - FIRST_PARM_OFFSET (current_function_decl)); #endif callmem[1] = plus_constant (Pmode, stack_pointer_rtx, off); }
[gcc r14-11810] alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 [PR118819]
https://gcc.gnu.org/g:4b9f2877e334b4108c33259753acfdd27820b4f5 commit r14-11810-g4b9f2877e334b4108c33259753acfdd27820b4f5 Author: Jakub Jelinek Date: Thu Feb 27 08:48:18 2025 +0100 alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 [PR118819] This PR is about ubsan error on the c - cx1 + cy1 evaluation in the first hunk. The following patch hopefully fixes that by doing the additions/subtractions in poly_offset_int rather than poly_int64 and then converting back to poly_int64. If it doesn't fit, -1 is returned (which means it is unknown if there is a conflict or not). 2025-02-27 Jakub Jelinek PR middle-end/118819 * alias.cc (memrefs_conflict_p): Perform arithmetics on c, xsize and ysize in poly_offset_int and return -1 if it is not representable in poly_int64. (cherry picked from commit b570f48c3dfb9ca3d640467cff67e569904009d4) Diff: --- gcc/alias.cc | 68 ++-- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/gcc/alias.cc b/gcc/alias.cc index 808e2095d9b4..fab7161f6941 100644 --- a/gcc/alias.cc +++ b/gcc/alias.cc @@ -2533,19 +2533,39 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, return memrefs_conflict_p (xsize, x1, ysize, y1, c); if (poly_int_rtx_p (x1, &cx1)) { + poly_offset_int co = c; + co -= cx1; if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x0, ysize, y0, - c - cx1 + cy1); + { + co += cy1; + if (!co.to_shwi (&c)) + return -1; + return memrefs_conflict_p (xsize, x0, ysize, y0, c); + } + else if (!co.to_shwi (&c)) + return -1; else - return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); + return memrefs_conflict_p (xsize, x0, ysize, y, c); } else if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); + { + poly_offset_int co = c; + co += cy1; + if (!co.to_shwi (&c)) + return -1; + return memrefs_conflict_p (xsize, x, ysize, y0, c); + } return -1; } else if (poly_int_rtx_p (x1, &cx1)) - return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); + { + poly_offset_int co = c; + co -= cx1; + if (!co.to_shwi (&c)) + return -1; + return memrefs_conflict_p (xsize, x0, ysize, y, c); + } } else if (GET_CODE (y) == PLUS) { @@ -2561,7 +2581,13 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, poly_int64 cy1; if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); + { + poly_offset_int co = c; + co += cy1; + if (!co.to_shwi (&c)) + return -1; + return memrefs_conflict_p (xsize, x, ysize, y0, c); + } else return -1; } @@ -2614,8 +2640,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, if (maybe_gt (xsize, 0)) xsize = -xsize; if (maybe_ne (xsize, 0)) - xsize += sc + 1; - c -= sc + 1; + { + poly_offset_int xsizeo = xsize; + xsizeo += sc + 1; + if (!xsizeo.to_shwi (&xsize)) + return -1; + } + poly_offset_int co = c; + co -= sc + 1; + if (!co.to_shwi (&c)) + return -1; return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ysize, y, c); } @@ -2629,8 +2663,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, if (maybe_gt (ysize, 0)) ysize = -ysize; if (maybe_ne (ysize, 0)) - ysize += sc + 1; - c += sc + 1; + { + poly_offset_int ysizeo = ysize; + ysizeo += sc + 1; + if (!ysizeo.to_shwi (&ysize)) + return -1; + } + poly_offset_int co = c; + co += sc + 1; + if (!co.to_shwi (&c)) + return -1; return memrefs_conflict_p (xsize, x, ysize, canon_rtx (XEXP (y, 0)), c); } @@ -2641,7 +2683,11 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, poly_int64 cx, cy; if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy)) { - c += cy - cx; + poly_offset_int co = c; + co += cy; + co -= cx; + if (!co.to_shwi (&c)) + return -1;
[gcc r16-888] RISC-V: Add testcases for signed vector SAT_ADD IMM form 1
https://gcc.gnu.org/g:a91679a3d9f7cbc079880f201fd8292c1d54baa7 commit r16-888-ga91679a3d9f7cbc079880f201fd8292c1d54baa7 Author: xuli Date: Thu Dec 26 09:39:08 2024 + RISC-V: Add testcases for signed vector SAT_ADD IMM form 1 This patch adds testcase for form1, as shown below: void __attribute__((noinline)) \ vec_sat_s_add_imm_##T##_fmt_1##_##INDEX (T *out, T *op_1, unsigned limit) \ {\ unsigned i;\ for (i = 0; i < limit; i++)\ {\ T x = op_1[i]; \ T sum = (UT)x + (UT)IMM; \ out[i] = (x ^ IMM) < 0 \ ? sum\ : (sum ^ x) >= 0 \ ? sum \ : x < 0 ? MIN : MAX; \ }\ } Passed the rv64gcv regression test. Signed-off-by: Li Xu gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h: add signed vec SAT_ADD IMM form1. * gcc.target/riscv/rvv/autovec/sat/vec_sat_data.h: add sat_s_add_imm data. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i16.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i32.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i64.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i8.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-run-1-i16.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-run-1-i32.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-run-1-i64.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm-run-1-i8.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm_type_check-1-i16.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm_type_check-1-i32.c: New test. * gcc.target/riscv/rvv/autovec/sat/vec_sat_s_add_imm_type_check-1-i8.c: New test. Diff: --- .../riscv/rvv/autovec/sat/vec_sat_arith.h | 25 +++ .../riscv/rvv/autovec/sat/vec_sat_data.h | 240 + .../rvv/autovec/sat/vec_sat_s_add_imm-1-i16.c | 10 + .../rvv/autovec/sat/vec_sat_s_add_imm-1-i32.c | 10 + .../rvv/autovec/sat/vec_sat_s_add_imm-1-i64.c | 10 + .../riscv/rvv/autovec/sat/vec_sat_s_add_imm-1-i8.c | 10 + .../rvv/autovec/sat/vec_sat_s_add_imm-run-1-i16.c | 28 +++ .../rvv/autovec/sat/vec_sat_s_add_imm-run-1-i32.c | 28 +++ .../rvv/autovec/sat/vec_sat_s_add_imm-run-1-i64.c | 28 +++ .../rvv/autovec/sat/vec_sat_s_add_imm-run-1-i8.c | 28 +++ .../sat/vec_sat_s_add_imm_type_check-1-i16.c | 9 + .../sat/vec_sat_s_add_imm_type_check-1-i32.c | 9 + .../sat/vec_sat_s_add_imm_type_check-1-i8.c| 10 + 13 files changed, 445 insertions(+) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h index 983c9b440abc..f78bdc047ca1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/sat/vec_sat_arith.h @@ -345,6 +345,31 @@ vec_sat_s_add_##T##_fmt_4 (T *out, T *op_1, T *op_2, unsigned limit) \ #define RUN_VEC_SAT_S_ADD_FMT_4_WRAP(T, out, op_1, op_2, N) \ RUN_VEC_SAT_S_ADD_FMT_4(T, out, op_1, op_2, N) +#define DEF_VEC_SAT_S_ADD_IMM_FMT_1(INDEX, T, UT, IMM, MIN, MAX) \ +void __attribute__((noinline)) \ +vec_sat_s_add_imm_##T##_fmt_1##_##INDEX (T *out, T *op_1, unsigned limit) \ +{\ + unsigned i;\ + for (i = 0; i < limit; i++)\ +{\ + T x = op_1[i]; \ + T sum = (UT)x + (UT)IMM; \ + out[i] = (x ^ IMM) < 0 \ +? sum\ +: (sum ^ x) >= 0 \ + ? sum \ + : x < 0 ? MIN : M
[gcc r16-887] Match:Support signed vector SAT_ADD IMM form 1
https://gcc.gnu.org/g:70fdc02b60935bf8de886795dda13924b0c08cad commit r16-887-g70fdc02b60935bf8de886795dda13924b0c08cad Author: xuli Date: Thu Dec 26 09:06:57 2024 + Match:Support signed vector SAT_ADD IMM form 1 This patch would like to support vector SAT_ADD when one of the op is singed IMM. void __attribute__((noinline)) \ vec_sat_s_add_imm_##T##_fmt_1##_##INDEX (T *out, T *op_1, unsigned limit) \ {\ unsigned i;\ for (i = 0; i < limit; i++)\ {\ T x = op_1[i]; \ T sum = (UT)x + (UT)IMM; \ out[i] = (x ^ IMM) < 0 \ ? sum\ : (sum ^ x) >= 0 \ ? sum \ : x < 0 ? MIN : MAX; \ }\ } Take below form1 as example: DEF_VEC_SAT_S_ADD_IMM_FMT_1(0, int8_t, uint8_t, 9, INT8_MIN, INT8_MAX) Before this patch: __attribute__((noinline)) void vec_sat_s_add_imm_int8_t_fmt_1_0 (int8_t * restrict out, int8_t * restrict op_1, unsigned int limit) { vector([16,16]) signed char * vectp_out.28; vector([16,16]) signed char vect_iftmp.27; vector([16,16]) mask__28.26; vector([16,16]) mask__29.25; vector([16,16]) mask__19.19; vector([16,16]) mask__31.18; vector([16,16]) signed char vect__6.17; vector([16,16]) signed char vect__5.16; vector([16,16]) signed char vect_sum_15.15; vector([16,16]) unsigned char vect__4.14; vector([16,16]) unsigned char vect_x.13; vector([16,16]) signed char vect_x_14.12; vector([16,16]) signed char * vectp_op_1.10; vector([16,16]) _78; vector([16,16]) unsigned char _79; vector([16,16]) unsigned char _80; unsigned long _92; unsigned long ivtmp_93; unsigned long ivtmp_94; unsigned long _95; [local count: 118111598]: if (limit_12(D) != 0) goto ; [89.00%] else goto ; [11.00%] [local count: 105119322]: _92 = (unsigned long) limit_12(D); [local count: 955630226]: # vectp_op_1.10_62 = PHI # vectp_out.28_89 = PHI # ivtmp_93 = PHI _95 = .SELECT_VL (ivtmp_93, POLY_INT_CST [16, 16]); vect_x_14.12_64 = .MASK_LEN_LOAD (vectp_op_1.10_62, 8B, { -1, ... }, _95, 0); vect_x.13_65 = VIEW_CONVERT_EXPR(vect_x_14.12_64); vect__4.14_67 = vect_x.13_65 + { 9, ... }; vect_sum_15.15_68 = VIEW_CONVERT_EXPR(vect__4.14_67); vect__5.16_70 = vect_x_14.12_64 ^ { 9, ... }; vect__6.17_71 = vect_x_14.12_64 ^ vect_sum_15.15_68; mask__31.18_73 = vect__5.16_70 >= { 0, ... }; mask__19.19_75 = vect_x_14.12_64 < { 0, ... }; mask__29.25_85 = vect__6.17_71 < { 0, ... }; mask__28.26_86 = mask__31.18_73 & mask__29.25_85; _78 = ~mask__28.26_86; _79 = .VCOND_MASK (mask__19.19_75, { 128, ... }, { 127, ... }); _80 = .COND_ADD (_78, vect_x.13_65, { 9, ... }, _79); vect_iftmp.27_87 = VIEW_CONVERT_EXPR(_80); .MASK_LEN_STORE (vectp_out.28_89, 8B, { -1, ... }, _95, 0, vect_iftmp.27_87); vectp_op_1.10_63 = vectp_op_1.10_62 + _95; vectp_out.28_90 = vectp_out.28_89 + _95; ivtmp_94 = ivtmp_93 - _95; if (ivtmp_94 != 0) goto ; [89.00%] else goto ; [11.00%] [local count: 118111600]: return; } After this patch: __attribute__((noinline)) void vec_sat_s_add_imm_int8_t_fmt_1_0 (int8_t * restrict out, int8_t * restrict op_1, unsigned int limit) { vector([16,16]) signed char * vectp_out.12; vector([16,16]) signed char vect_patt_10.11; vector([16,16]) signed char vect_x_14.10; vector([16,16]) signed char D.2852; vector([16,16]) signed char * vectp_op_1.8; vector([16,16]) signed char _73(D); unsigned long _80; unsigned long ivtmp_81; unsigned long ivtmp_82; unsigned long _83; [local count: 118111598]: if (limit_12(D) != 0) goto ; [89.00%] else goto ; [11.00%] [local count: 105119322]: _80 = (unsigned long) limit_12(D); [local count: 955630226]: # vectp_op_1.8_71 = PHI # vectp_out.12_77 = PHI # ivtmp_81 = PHI _83 = .SELECT_VL (ivtmp_81, POLY_INT_CST [16, 16]); vect_x_14.10_74 = .MASK_LEN_LOAD (ve
[gcc r16-886] RISC-V:Add testcases for signed .SAT_ADD IMM form 1 with IMM = -1.
https://gcc.gnu.org/g:4962e6d0810823d68349cd019f5dd53524a62ac5 commit r16-886-g4962e6d0810823d68349cd019f5dd53524a62ac5 Author: xuli Date: Fri Dec 27 07:59:31 2024 + RISC-V:Add testcases for signed .SAT_ADD IMM form 1 with IMM = -1. This patch adds testcase for form1, as shown below: T __attribute__((noinline)) \ sat_s_add_imm_##T##_fmt_1##_##INDEX (T x) \ {\ T sum = (UT)x + (UT)IMM; \ return (x ^ IMM) < 0 \ ? sum\ : (sum ^ x) >= 0 \ ? sum \ : x < 0 ? MIN : MAX; \ } Passed the rv64gcv regression test. Signed-off-by: Li Xu gcc/testsuite/ChangeLog: * gcc.target/riscv/sat/sat_s_add_imm-2.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm-1-i16.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-3.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm-1-i32.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-4.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm-1-i64.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-1.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm-1-i8.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-run-2.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm-run-1-i16.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-run-3.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm-run-1-i32.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-run-4.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm-run-1-i64.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-run-1.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm-run-1-i8.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-2-1.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm_type_check-1-i16.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-3-1.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm_type_check-1-i32.c: ...here. * gcc.target/riscv/sat/sat_s_add_imm-1-1.c: Move to... * gcc.target/riscv/sat/sat_s_add_imm_type_check-1-i8.c: ...here. Diff: --- .../{sat_s_add_imm-2.c => sat_s_add_imm-1-i16.c} | 27 +- .../{sat_s_add_imm-3.c => sat_s_add_imm-1-i32.c} | 26 - .../{sat_s_add_imm-4.c => sat_s_add_imm-1-i64.c} | 22 +- .../{sat_s_add_imm-1.c => sat_s_add_imm-1-i8.c}| 22 +- ...s_add_imm-run-2.c => sat_s_add_imm-run-1-i16.c} | 6 + ...s_add_imm-run-3.c => sat_s_add_imm-run-1-i32.c} | 6 + ...s_add_imm-run-4.c => sat_s_add_imm-run-1-i64.c} | 6 + ..._s_add_imm-run-1.c => sat_s_add_imm-run-1-i8.c} | 6 + ..._imm-2-1.c => sat_s_add_imm_type_check-1-i16.c} | 0 ..._imm-3-1.c => sat_s_add_imm_type_check-1-i32.c} | 0 ...d_imm-1-1.c => sat_s_add_imm_type_check-1-i8.c} | 0 11 files changed, 117 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c similarity index 53% rename from gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2.c rename to gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c index 3878286d207b..2e23af5d86b7 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-2.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i16.c @@ -29,4 +29,29 @@ */ DEF_SAT_S_ADD_IMM_FMT_1(0, int16_t, uint16_t, -7, INT16_MIN, INT16_MAX) -/* { dg-final { scan-tree-dump-times ".SAT_ADD " 1 "optimized" } } */ +/* +** sat_s_add_imm_int16_t_fmt_1_1: +** addi\s+[atx][0-9]+,\s*a0,\s*-1 +** not\s+[atx][0-9]+,\s*a0 +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** srai\s+a0,\s*a0,\s*63 +** li\s+[atx][0-9]+,\s*32768 +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 +** neg\s+a0,\s*[atx][0-9]+ +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*a0 +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ +** or\s+a0,\s*a0,\s*[atx][0-9]+ +** slliw\s+a0,\s*a0,\s*16 +** sraiw\s+a0,\s*a0,\s*16 +** ret +*/ +DEF_SAT_S_ADD_IMM_FMT_1(1, int16_t, uint16_t, -1, INT16_MIN, INT16_MAX) + +/* { dg-final { scan-tree-dump-times ".SAT_ADD " 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-3.c b/gcc/testsuite/gcc.target/riscv/sat/sat_s_add_imm-1-i32.c similarity index 53% rename from gcc/tests
[gcc r16-885] Match:Support IMM=-1 for signed scalar SAT_ADD IMM form1
https://gcc.gnu.org/g:7cf7149ec8303d0ed828fb7629417b28e6565d32 commit r16-885-g7cf7149ec8303d0ed828fb7629417b28e6565d32 Author: xuli Date: Fri Dec 27 07:03:14 2024 + Match:Support IMM=-1 for signed scalar SAT_ADD IMM form1 This patch would like to support .SAT_ADD when IMM=-1. Form1: T __attribute__((noinline)) \ sat_s_add_imm_##T##_fmt_1##_##INDEX (T x) \ {\ T sum = (UT)x + (UT)IMM; \ return (x ^ IMM) < 0 \ ? sum\ : (sum ^ x) >= 0 \ ? sum \ : x < 0 ? MIN : MAX; \ } Take below form1 as example: DEF_SAT_S_ADD_IMM_FMT_1(0, int8_t, uint8_t, -1, INT8_MIN, INT8_MAX) Before this patch: __attribute__((noinline)) int8_t sat_s_add_imm_int8_t_fmt_1_0 (int8_t x) { unsigned char x.0_1; unsigned char _2; unsigned char _3; int8_t iftmp.1_4; signed char _8; unsigned char _9; signed char _10; [local count: 1073741824]: x.0_1 = (unsigned char) x_5(D); _3 = -x.0_1; _10 = (signed char) _3; _8 = x_5(D) & _10; if (_8 < 0) goto ; [1.40%] else goto ; [98.60%] [local count: 434070867]: _2 = x.0_1 + 255; [local count: 1073741824]: # _9 = PHI <_2(3), 128(2)> iftmp.1_4 = (int8_t) _9; return iftmp.1_4; } After this patch: __attribute__((noinline)) int8_t sat_s_add_imm_int8_t_fmt_1_0 (int8_t x) { int8_t _4; [local count: 1073741824]: gimple_call <.SAT_ADD, _4, x_5(D), 255> [tail call] gimple_return <_4> } The below test suites are passed for this patch: 1. The rv64gcv fully regression tests. 2. The x86 bootstrap tests. 3. The x86 fully regression tests. Signed-off-by: Li Xu gcc/ChangeLog: * match.pd: Add signed scalar SAT_ADD IMM form1 with IMM=-1 matching. * tree-ssa-math-opts.cc (match_unsigned_saturation_add): Adapt function name. (match_saturation_add_with_assign): Match signed and unsigned SAT_ADD with assign. (math_opts_dom_walker::after_dom_children): Match imm=-1 signed SAT_ADD with NOP_EXPR case. Diff: --- gcc/match.pd | 19 ++- gcc/tree-ssa-math-opts.cc | 30 +- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index 27f662f9714b..50bd853b39a8 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3461,7 +3461,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_xor:c @0 INTEGER_CST@3)) integer_zerop) (signed_integer_sat_val @0) @2) - (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0 + (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0))) + +(match (signed_integer_sat_add @0 @1) + /* T SUM = (T)((UT)X + (UT)-1); + SAT_S_ADD = (X ^ -1) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM + : (x < 0) ? MIN : MAX */ + (convert (cond^ (lt (bit_and:c @0 (nop_convert (negate (nop_convert @0 + integer_zerop) +INTEGER_CST@2 +(plus (nop_convert @0) integer_all_onesp@1))) + (with +{ + unsigned precision = TYPE_PRECISION (type); + wide_int c1 = wi::to_wide (@1); + wide_int c2 = wi::to_wide (@2); + wide_int sum = wi::add (c1, c2); +} +(if (wi::eq_p (sum, wi::max_value (precision, SIGNED))) /* Saturation sub for signed integer. */ (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type)) diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index eb03ebe102ad..7e819f37446c 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -4104,15 +4104,34 @@ build_saturation_binary_arith_call_and_insert (gimple_stmt_iterator *gsi, * _10 = -_9; * _12 = _7 | _10; * => - * _12 = .SAT_ADD (_4, _6); */ + * _12 = .SAT_ADD (_4, _6); + * + * Try to match IMM=-1 saturation signed add with assign. + * [local count: 1073741824]: + * x.0_1 = (unsigned char) x_5(D); + * _3 = -x.0_1; + * _10 = (signed char) _3; + * _8 = x_5(D) & _10; + * if (_8 < 0) + * goto ; [1.40%] + * else + * goto ; [98.60%] + * [local count: 434070867]: + * _2 = x.0_1 + 255; + * [local count: 1073741824]: + * # _9 = PHI <_2(3), 128(2)> + * _4 = (int8_t) _9; + * => + * _4 = .SAT_ADD (x_5, -1); */ static void -match_unsigned_saturation_add (gimple_stmt_iterator *gsi, gassign *stmt) +match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt) { tree ops[2]; tree lhs = gimple_assign_lhs (stmt); - if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)) + if (gimple_unsigned_integer_sat_add
[gcc r16-889] driver: Fix multilib_os_dir and multiarch_dir for those target use TARGET_COMPUTE_MULTILIB
https://gcc.gnu.org/g:447156e4d143d7f513c488dd0b44037524a01fba commit r16-889-g447156e4d143d7f513c488dd0b44037524a01fba Author: Kito Cheng Date: Mon Mar 10 16:26:04 2025 +0800 driver: Fix multilib_os_dir and multiarch_dir for those target use TARGET_COMPUTE_MULTILIB This patch fixes the multilib_os_dir and multiarch_dir for those targets that use TARGET_COMPUTE_MULTILIB, since the TARGET_COMPUTE_MULTILIB hook only update/fix the multilib_dir but not the multilib_os_dir and multiarch_dir, so the multilib_os_dir and multiarch_dir are not set correctly for those targets. Use RISC-V linux target (riscv64-unknown-linux-gnu) as an example: ``` $ riscv64-unknown-linux-gnu-gcc -print-multi-lib .; lib32/ilp32;@march=rv32imac@mabi=ilp32 lib32/ilp32d;@march=rv32imafdc@mabi=ilp32d lib64/lp64;@march=rv64imac@mabi=lp64 lib64/lp64d;@march=rv64imafdc@mabi=lp64d ``` If we use the exactly same -march and -mabi options to compile a source file, the multilib_os_dir and multiarch_dir are set correctly: ``` $ riscv64-unknown-linux-gnu-gcc -print-multi-os-directory -march=rv64imafdc -mabi=lp64d ../lib64/lp64d $ riscv64-unknown-linux-gnu-gcc -print-multi-directory -march=rv64imafdc -mabi=lp64d lib64/lp64d ``` However if we use the -march=rv64imafdcv -mabi=lp64d option to compile a source file, the multilib_os_dir and multiarch_dir are not set correctly: ``` $ riscv64-unknown-linux-gnu-gcc -print-multi-os-directory -march=rv64imafdc -mabi=lp64d lib64/lp64d $ riscv64-unknown-linux-gnu-gcc -print-multi-directory -march=rv64imafdc -mabi=lp64d lib64/lp64d ``` That's because the TARGET_COMPUTE_MULTILIB hook only update/fix the multilib_dir but not the multilib_os_dir, so the multilib_os_dir is blank and will use same value as multilib_dir, but that is not correct. So we introduce second chance to fix the multilib_os_dir if it's not set, we do also try to fix the multiarch_dir, because it may also not set correctly if multilib_os_dir is not set. Changes since v1: - Fix non-multilib build. - Fix fix indentation. gcc/ChangeLog: * gcc.cc (find_multilib_os_dir_by_multilib_dir): New. (set_multilib_dir): Fix multilib_os_dir and multiarch_dir if multilib_os_dir is not set. Diff: --- gcc/gcc.cc | 108 - 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/gcc/gcc.cc b/gcc/gcc.cc index 4fd87f2c4a13..4e61de2a47c3 100644 --- a/gcc/gcc.cc +++ b/gcc/gcc.cc @@ -9747,6 +9747,103 @@ default_arg (const char *p, int len) return 0; } +/* Use multilib_dir as key to find corresponding multilib_os_dir and + multiarch_dir. */ + +static void +find_multilib_os_dir_by_multilib_dir (const char *multilib_dir, + const char **p_multilib_os_dir, + const char **p_multiarch_dir) +{ + const char *p = multilib_select; + unsigned int this_path_len; + const char *this_path; + int ok = 0; + + while (*p != '\0') +{ + /* Ignore newlines. */ + if (*p == '\n') + { + ++p; + continue; + } + + /* Get the initial path. */ + this_path = p; + while (*p != ' ') + { + if (*p == '\0') + { + fatal_error (input_location, "multilib select %qs %qs is invalid", + multilib_select, multilib_reuse); + } + ++p; + } + this_path_len = p - this_path; + + ok = 0; + + /* Skip any arguments, we don't care at this stage. */ + while (*++p != ';'); + + if (this_path_len != 1 + || this_path[0] != '.') + { + char *new_multilib_dir = XNEWVEC (char, this_path_len + 1); + char *q; + + strncpy (new_multilib_dir, this_path, this_path_len); + new_multilib_dir[this_path_len] = '\0'; + q = strchr (new_multilib_dir, ':'); + if (q != NULL) + *q = '\0'; + + if (strcmp (new_multilib_dir, multilib_dir) == 0) + ok = 1; + } + + /* Found matched multilib_dir, update multilib_os_dir and +multiarch_dir. */ + if (ok) + { + const char *q = this_path, *end = this_path + this_path_len; + + while (q < end && *q != ':') + q++; + if (q < end) + { + const char *q2 = q + 1, *ml_end = end; + char *new_multilib_os_dir; + + while (q2 < end && *q2 != ':') + q2++; + if (*q2 == ':') + ml_end = q2; + if (ml_end - q == 1) + *p_multilib_os_dir = xstrdup ("."); + else + { + new_multilib_os_dir = XNEWVEC (char, ml_end - q); + memcpy (new_mu
[gcc r13-9689] asan: Don't fold some strlens with -fsanitize=address [PR110676]
https://gcc.gnu.org/g:c884148d3cb440fca6692452aabb42c340b987a9 commit r13-9689-gc884148d3cb440fca6692452aabb42c340b987a9 Author: Jakub Jelinek Date: Tue Feb 6 13:00:04 2024 +0100 asan: Don't fold some strlens with -fsanitize=address [PR110676] The UB on the following testcase isn't diagnosed by -fsanitize=address, because we see that the array has a single element and optimize the strlen to 0. I think it is fine to assume e.g. for range purposes the lower bound for the strlen as long as we don't try to optimize strlen (str) where we know that it returns [26, 42] to 26 + strlen (str + 26), but for the upper bound we really want to punt on optimizing that for -fsanitize=address to read all the bytes of the string and diagnose if we run to object end etc. 2024-02-06 Jakub Jelinek PR sanitizer/110676 * gimple-fold.cc (gimple_fold_builtin_strlen): For -fsanitize=address reset maxlen to sizetype maximum. * gcc.dg/asan/pr110676.c: New test. (cherry picked from commit d3eac7d96de790df51859f63c13838f153b416de) Diff: --- gcc/gimple-fold.cc | 5 + gcc/testsuite/gcc.dg/asan/pr110676.c | 14 ++ 2 files changed, 19 insertions(+) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 5bdd1d08a265..b5f4a9ec0a1c 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -4020,6 +4020,11 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi) maxlen = wi::to_wide (max_object_size (), prec) - 2; } + /* For -fsanitize=address, don't optimize the upper bound of the + length to be able to diagnose UB on non-zero terminated arrays. */ + if (sanitize_flags_p (SANITIZE_ADDRESS)) +maxlen = wi::max_value (TYPE_PRECISION (sizetype), UNSIGNED); + if (minlen == maxlen) { /* Fold the strlen call to a constant. */ diff --git a/gcc/testsuite/gcc.dg/asan/pr110676.c b/gcc/testsuite/gcc.dg/asan/pr110676.c new file mode 100644 index ..0ae6fdd67b59 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/pr110676.c @@ -0,0 +1,14 @@ +/* PR sanitizer/110676 */ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ +/* { dg-shouldfail "asan" } */ + +int +main () +{ + char s[1] = "A"; + return __builtin_strlen (s); +} + +/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow on address.*(\n|\r\n|\r)" } */ +/* { dg-output "READ of size.*" } */
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] gimple-exec: correction prise en charge offset adresse MEM_REF
https://gcc.gnu.org/g:947a0417737071a7fbc10a826a3bff75e252b660 commit 947a0417737071a7fbc10a826a3bff75e252b660 Author: Mikael Morin Date: Mon May 26 10:47:41 2025 +0200 gimple-exec: correction prise en charge offset adresse MEM_REF Diff: --- gcc/cgraphunit.cc | 251 ++ 1 file changed, 161 insertions(+), 90 deletions(-) diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index 62fb874dbdba..97013daa9fbd 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -3880,14 +3880,13 @@ exec_context::evaluate (tree expr) const storage_address *address = val_ptr.get_address (); gcc_assert (address != nullptr); data_value storage_value = address->storage.get ().get_value (); - unsigned ptr_offset = address->offset; + wide_int ptr_off = wi::uhwi (address->offset, +HOST_BITS_PER_WIDE_INT); tree offset_bytes = TREE_OPERAND (expr, 1); data_value val_off = evaluate (offset_bytes); gcc_assert (val_off.classify () == VAL_CONSTANT); wide_int wi_off = val_off.get_cst (); - gcc_assert (wi::fits_uhwi_p (wi_off)); - unsigned offset = wi_off.to_uhwi (); unsigned bit_width; if (!get_constant_type_size (TREE_TYPE (expr), bit_width)) @@ -3909,13 +3908,14 @@ exec_context::evaluate (tree expr) const gcc_assert (val_step.classify () == VAL_CONSTANT); wide_int wi_step = val_step.get_cst (); - wide_int additional_off = wi_idx * wi_step; - gcc_assert (wi::fits_uhwi_p (additional_off)); - offset += additional_off.to_uhwi (); + wi_off += wi_idx * wi_step; } } - return storage_value.get_at (offset * CHAR_BIT + ptr_offset, bit_width); + wi_off = wi_off * CHAR_BIT + ptr_off; + gcc_assert (wi::fits_uhwi_p (wi_off)); + + return storage_value.get_at (wi_off.to_shwi (), bit_width); } break; @@ -4206,105 +4206,130 @@ exec_context::evaluate_binary (enum tree_code code, tree type, tree lhs, tree rh gcc_unreachable (); } -void -exec_context::decompose_ref (tree data_ref, data_storage * & storage, int & offset) const + +static bool +is_zero_offset_data_ref (enum tree_code code) { - offset = -1; - enum tree_code code = TREE_CODE (data_ref); switch (code) { case VAR_DECL: case SSA_NAME: - { - tree var = data_ref; - offset = 0; - storage = find_reachable_var (var); - } - break; + return true; -case ARRAY_REF: - { - data_storage *parent_storage = nullptr; - int parent_offset = -1; - tree parent_ref = TREE_OPERAND (data_ref, 0); - decompose_ref (parent_ref, parent_storage, parent_offset); - gcc_assert (parent_offset >= 0); - gcc_assert (parent_storage != nullptr); - - tree idx = TREE_OPERAND (data_ref, 1); - data_value val = evaluate (idx); - gcc_assert (val.classify () == VAL_CONSTANT); - wide_int wi_idx = val.get_cst (); - gcc_assert (wi::fits_uhwi_p (wi_idx)); - unsigned HOST_WIDE_INT hw_idx = wi_idx.to_uhwi (); - - gcc_assert (TREE_OPERAND (data_ref, 3) == NULL_TREE); - tree elt_type = TREE_TYPE (TREE_TYPE (parent_ref)); - unsigned size_bits; - bool found_size = get_constant_type_size (elt_type, size_bits); - gcc_assert (found_size); - unsigned this_offset = hw_idx * size_bits; +default: + return false; +} +} - storage = parent_storage; - offset = parent_offset + this_offset; - } - break; -case COMPONENT_REF: - { - data_storage *parent_storage = nullptr; - int parent_offset = -1; - decompose_ref (TREE_OPERAND (data_ref, 0), parent_storage, parent_offset); - gcc_assert (parent_offset >= 0); - gcc_assert (parent_storage != nullptr); +void +exec_context::decompose_ref (tree data_ref, data_storage * & storage, int & offset) const +{ + offset = -1; + enum tree_code code = TREE_CODE (data_ref); + if (is_zero_offset_data_ref (code)) +{ + offset = 0; + storage = find_reachable_var (data_ref); +} + else +{ + tree parent_data_ref = nullptr; + wide_int add_offset = wi::zero (HOST_BITS_PER_WIDE_INT); + wide_int add_index = wi::zero (HOST_BITS_PER_WIDE_INT); + wide_int add_multiplier = wi::zero (HOST_BITS_PER_WIDE_INT); + switch (code) + { + case ARRAY_REF: + { + parent_data_ref = TREE_OPERAND (data_ref, 0); + + tree idx = TREE_OPERAND (data_ref, 1); + data_value val = evaluate (idx); + gcc_assert (val.classify () == VAL_CONSTANT); + add_index = val.get_cst (); + + gcc_assert (TREE_OPERAND (data_ref, 3) == NULL_TREE); + tree elt_type = TREE_TYPE (TREE_TYPE (parent_data_ref)); + unsigned size_bits; +
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Revert modifs finalization
https://gcc.gnu.org/g:c28356e40bd6ed46c8bd259215351a4ac65372cd commit c28356e40bd6ed46c8bd259215351a4ac65372cd Author: Mikael Morin Date: Mon May 26 17:22:25 2025 +0200 Revert modifs finalization Diff: --- gcc/fortran/class.cc | 369 -- gcc/fortran/trans-expr.cc | 9 +- 2 files changed, 324 insertions(+), 54 deletions(-) diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc index e6a99be93210..41be63bf768f 100644 --- a/gcc/fortran/class.cc +++ b/gcc/fortran/class.cc @@ -1343,12 +1343,14 @@ finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr, offset = 0 do idx2 = 1, rank offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2) - end do */ + end do + offset = offset * byte_stride. */ static gfc_code* finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, gfc_symbol *strides, gfc_symbol *sizes, -gfc_expr *rank, gfc_code *block, gfc_namespace *sub_ns) +gfc_symbol *byte_stride, gfc_expr *rank, +gfc_code *block, gfc_namespace *sub_ns) { gfc_iterator *iter; gfc_expr *expr, *expr2; @@ -1441,6 +1443,17 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, block->block->next->expr2->ts = idx->ts; block->block->next->expr2->where = gfc_current_locus; + /* After the loop: offset = offset * byte_stride. */ + block->next = gfc_get_code (EXEC_ASSIGN); + block = block->next; + block->expr1 = gfc_lval_expr_from_sym (offset); + block->expr2 = gfc_get_expr (); + block->expr2->expr_type = EXPR_OP; + block->expr2->value.op.op = INTRINSIC_TIMES; + block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset); + block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride); + block->expr2->ts = block->expr2->value.op.op1->ts; + block->expr2->where = gfc_current_locus; return block; } @@ -1477,18 +1490,247 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, static void finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini, - gfc_symbol *array, gfc_symbol *byte_stride ATTRIBUTE_UNUSED, - gfc_symbol *nelem ATTRIBUTE_UNUSED, gfc_symbol *is_contiguous ATTRIBUTE_UNUSED, - gfc_namespace *sub_ns ATTRIBUTE_UNUSED) + gfc_symbol *array, gfc_symbol *byte_stride, + gfc_symbol *idx, gfc_symbol *ptr, + gfc_symbol *nelem, + gfc_symbol *strides, gfc_symbol *sizes, + gfc_symbol *idx2, gfc_symbol *offset, + gfc_symbol *is_contiguous, gfc_expr *rank, + gfc_namespace *sub_ns) { + gfc_symbol *tmp_array, *ptr2; + gfc_expr *size_expr, *offset2, *expr; + gfc_namespace *ns; + gfc_iterator *iter; + gfc_code *block2; + int i; + + block->next = gfc_get_code (EXEC_IF); + block = block->next; + + block->block = gfc_get_code (EXEC_IF); + block = block->block; + + /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */ + size_expr = gfc_get_expr (); + size_expr->where = gfc_current_locus; + size_expr->expr_type = EXPR_OP; + size_expr->value.op.op = INTRINSIC_DIVIDE; + + /* STORAGE_SIZE (array,kind=c_intptr_t). */ + size_expr->value.op.op1 + = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE, + "storage_size", gfc_current_locus, 2, + gfc_lval_expr_from_sym (array), + gfc_get_int_expr (gfc_index_integer_kind, + NULL, 0)); + + /* NUMERIC_STORAGE_SIZE. */ + size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, + gfc_character_storage_size); + size_expr->value.op.op1->ts = size_expr->value.op.op2->ts; + size_expr->ts = size_expr->value.op.op1->ts; + + /* IF condition: (stride == size_expr + && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous) + || is_contiguous) + || 0 == size_expr. */ + block->expr1 = gfc_get_expr (); + block->expr1->ts.type = BT_LOGICAL; + block->expr1->ts.kind = gfc_default_logical_kind; + block->expr1->expr_type = EXPR_OP; + block->expr1->where = gfc_current_locus; + + block->expr1->value.op.op = INTRINSIC_OR; + + /* byte_stride == size_expr */ + expr = gfc_get_expr (); + expr->ts.type = BT_LOGICAL; + expr->ts.kind = gfc_default_logical_kind; + expr->expr_type = EXPR_OP; + expr->where = gfc_current_locus; + expr->value.op.op = INTRINSIC_EQ; + expr->value.op.op1 + = gfc_lval_expr_from_sym (byte_stride); + expr->value.op.op2 = size_expr; + + /* If strides aren't allowed (
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régressions finalization
https://gcc.gnu.org/g:fe8c567d6554f6e47fbea88be57450584442f6ed commit fe8c567d6554f6e47fbea88be57450584442f6ed Author: Mikael Morin Date: Mon May 26 17:26:44 2025 +0200 Correction régressions finalization Diff: --- gcc/fortran/class.cc | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc index 41be63bf768f..aee7f2ce8f5e 100644 --- a/gcc/fortran/class.cc +++ b/gcc/fortran/class.cc @@ -1349,7 +1349,7 @@ finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr, static gfc_code* finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, gfc_symbol *strides, gfc_symbol *sizes, -gfc_symbol *byte_stride, gfc_expr *rank, +gfc_symbol *byte_stride ATTRIBUTE_UNUSED, gfc_expr *rank, gfc_code *block, gfc_namespace *sub_ns) { gfc_iterator *iter; @@ -1443,17 +1443,6 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, block->block->next->expr2->ts = idx->ts; block->block->next->expr2->where = gfc_current_locus; - /* After the loop: offset = offset * byte_stride. */ - block->next = gfc_get_code (EXEC_ASSIGN); - block = block->next; - block->expr1 = gfc_lval_expr_from_sym (offset); - block->expr2 = gfc_get_expr (); - block->expr2->expr_type = EXPR_OP; - block->expr2->value.op.op = INTRINSIC_TIMES; - block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset); - block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride); - block->expr2->ts = block->expr2->value.op.op1->ts; - block->expr2->where = gfc_current_locus; return block; }
[gcc r13-9695] cselib: Fix up previous patch for SPARC [PR117239]
https://gcc.gnu.org/g:ffac0a49a88e0e366d35739d97fced2b01bfcf89 commit r13-9695-gffac0a49a88e0e366d35739d97fced2b01bfcf89 Author: Jakub Jelinek Date: Wed Feb 5 14:06:42 2025 +0100 cselib: Fix up previous patch for SPARC [PR117239] Sorry, our CI bot just notified me I broke SPARC build. There are two #ifdef STACK_ADDRESS_OFFSET guarded snippets and the macro is only defined on SPARC target, so I didn't notice there was a syntax error. Fixed thusly. 2025-02-05 Jakub Jelinek PR rtl-optimization/117239 * cselib.cc (cselib_init): Remove spurious closing paren in the #ifdef STACK_ADDRESS_OFFSET specific code. (cherry picked from commit 6094801d6fd7849d2d95ce78f7c6ef01686b9f63) Diff: --- gcc/cselib.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cselib.cc b/gcc/cselib.cc index fba96d5a8e30..476a94b08f2a 100644 --- a/gcc/cselib.cc +++ b/gcc/cselib.cc @@ -3359,7 +3359,7 @@ cselib_init (int record_what) #ifdef STACK_ADDRESS_OFFSET /* On SPARC take stack pointer bias into account as well. */ off += (STACK_ADDRESS_OFFSET - - FIRST_PARM_OFFSET (current_function_decl))); + - FIRST_PARM_OFFSET (current_function_decl)); #endif callmem[1] = plus_constant (Pmode, stack_pointer_rtx, off); }
[gcc r13-9697] i386: Change RTL representation of bt[lq] [PR118623]
https://gcc.gnu.org/g:b70fba168fb3b11998a80e21cec0eb7fa7a42da7 commit r13-9697-gb70fba168fb3b11998a80e21cec0eb7fa7a42da7 Author: Jakub Jelinek Date: Mon Feb 10 10:40:22 2025 +0100 i386: Change RTL representation of bt[lq] [PR118623] The following testcase is miscompiled because of RTL represententation of bt{l,q} insn followed by e.g. j{c,nc} being misleading to what it actually does. Let's look e.g. at (define_insn_and_split "*jcc_bt" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" [(zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") (const_int 1) (match_operand:QI 2 "nonmemory_operand")) (const_int 0)]) (label_ref (match_operand 3)) (pc))) (clobber (reg:CC FLAGS_REG))] "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) && (CONST_INT_P (operands[2]) ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (mode) && INTVAL (operands[2]) >= (optimize_function_for_size_p (cfun) ? 8 : 32)) : !memory_operand (operands[1], mode)) && ix86_pre_reload_split ()" "#" "&& 1" [(set (reg:CCC FLAGS_REG) (compare:CCC (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (pc) (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) (label_ref (match_dup 3)) (pc)))] { operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) The define_insn part in RTL describes exactly what it does, jumps to op3 if bit op2 in op1 is set (for op0 NE) or not set (for op0 EQ). The problem is with what it splits into. put_condition_code %C1 for CCCmode comparisons emits c for EQ and LTU, nc for NE and GEU and ICEs otherwise. CCCmode is used mainly for carry out of add/adc, borrow out of sub/sbb, in those cases e.g. for add we have (set (reg:CCC flags) (compare:CCC (plus:M x y) x)) and use (ltu (reg:CCC flags) (const_int 0)) for carry set and (geu (reg:CCC flags) (const_int 0)) for carry not set. These cases model in RTL what is actually happening, compare in infinite precision x from the result of finite precision addition in M mode and if it is less than unsigned (i.e. overflow happened), carry is set. Another use of CCCmode is in UNSPEC_* patterns, those are used with (eq (reg:CCC flags) (const_int 0)) for carry set and ne for unset, given the UNSPEC no big deal, the middle-end doesn't know what means set or unset. But for the bt{l,q}; j{c,nc} case the above splits it into (set (reg:CCC flags) (compare:CCC (zero_extract) (const_int 0))) for bt and (set (pc) (if_then_else (eq (reg:CCC flags) (const_int 0)) (label_ref) (pc))) for the bit set case (so that the jump expands to jc) and ne for the bit not set case (so that the jump expands to jnc). Similarly for the different splitters for cmov and set{c,nc} etc. The problem is that when the middle-end reads this RTL, it feels the exact opposite to it. If zero_extract is 1, flags is set to comparison of 1 and 0 and that would mean using ne ne in the if_then_else, and vice versa. So, in order to better describe in RTL what is actually happening, one possibility would be to swap the behavior of put_condition_code and use NE + LTU -> c and EQ + GEU -> nc rather than the current EQ + LTU -> c and NE + GEU -> nc; and adjust everything. The following patch uses a more limited approach, instead of representing bt{l,q}; j{c,nc} case as written above it uses (set (reg:CCC flags) (compare:CCC (const_int 0) (zero_extract))) and (set (pc) (if_then_else (ltu (reg:CCC flags) (const_int 0)) (label_ref) (pc))) which uses the existing put_condition_code but describes what the insns actually do in RTL clearly. If zero_extract is 1, then flags are LTU, 0U < 1U, if zero_extract is 0, then flags are GEU, 0U >= 0U. The patch adjusts the *bt define_insn and all the splitters to it and its comparisons/conditional moves/setXX. 2025-02-10 Jakub Jelinek PR target/118623 * config/i386/i386.md (*bt): Represent bt as compare:CCC of const0_rtx and zero_extract rather than zero_extract and const0_rtx. (*jcc_bt): Likewise. Use LTU and GEU as flags test instead of EQ and NE. (*jcc_bt_1): Likewise. (*jcc_bt_mask): Likewise. (*jcc_bt_mask_1): Likewise. (Help combine recogniz
[gcc r13-9696] alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 [PR118819]
https://gcc.gnu.org/g:b0502fbcee2a4eaf070f26201829478d8df51423 commit r13-9696-gb0502fbcee2a4eaf070f26201829478d8df51423 Author: Jakub Jelinek Date: Thu Feb 27 08:48:18 2025 +0100 alias: Perform offset arithmetics in poly_offset_int rather than poly_int64 [PR118819] This PR is about ubsan error on the c - cx1 + cy1 evaluation in the first hunk. The following patch hopefully fixes that by doing the additions/subtractions in poly_offset_int rather than poly_int64 and then converting back to poly_int64. If it doesn't fit, -1 is returned (which means it is unknown if there is a conflict or not). 2025-02-27 Jakub Jelinek PR middle-end/118819 * alias.cc (memrefs_conflict_p): Perform arithmetics on c, xsize and ysize in poly_offset_int and return -1 if it is not representable in poly_int64. (cherry picked from commit b570f48c3dfb9ca3d640467cff67e569904009d4) Diff: --- gcc/alias.cc | 68 ++-- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/gcc/alias.cc b/gcc/alias.cc index 3672bf277b95..2ac46d207a58 100644 --- a/gcc/alias.cc +++ b/gcc/alias.cc @@ -2603,19 +2603,39 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, return memrefs_conflict_p (xsize, x1, ysize, y1, c); if (poly_int_rtx_p (x1, &cx1)) { + poly_offset_int co = c; + co -= cx1; if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x0, ysize, y0, - c - cx1 + cy1); + { + co += cy1; + if (!co.to_shwi (&c)) + return -1; + return memrefs_conflict_p (xsize, x0, ysize, y0, c); + } + else if (!co.to_shwi (&c)) + return -1; else - return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); + return memrefs_conflict_p (xsize, x0, ysize, y, c); } else if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); + { + poly_offset_int co = c; + co += cy1; + if (!co.to_shwi (&c)) + return -1; + return memrefs_conflict_p (xsize, x, ysize, y0, c); + } return -1; } else if (poly_int_rtx_p (x1, &cx1)) - return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); + { + poly_offset_int co = c; + co -= cx1; + if (!co.to_shwi (&c)) + return -1; + return memrefs_conflict_p (xsize, x0, ysize, y, c); + } } else if (GET_CODE (y) == PLUS) { @@ -2631,7 +2651,13 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, poly_int64 cy1; if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); + { + poly_offset_int co = c; + co += cy1; + if (!co.to_shwi (&c)) + return -1; + return memrefs_conflict_p (xsize, x, ysize, y0, c); + } else return -1; } @@ -2684,8 +2710,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, if (maybe_gt (xsize, 0)) xsize = -xsize; if (maybe_ne (xsize, 0)) - xsize += sc + 1; - c -= sc + 1; + { + poly_offset_int xsizeo = xsize; + xsizeo += sc + 1; + if (!xsizeo.to_shwi (&xsize)) + return -1; + } + poly_offset_int co = c; + co -= sc + 1; + if (!co.to_shwi (&c)) + return -1; return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ysize, y, c); } @@ -2699,8 +2733,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, if (maybe_gt (ysize, 0)) ysize = -ysize; if (maybe_ne (ysize, 0)) - ysize += sc + 1; - c += sc + 1; + { + poly_offset_int ysizeo = ysize; + ysizeo += sc + 1; + if (!ysizeo.to_shwi (&ysize)) + return -1; + } + poly_offset_int co = c; + co += sc + 1; + if (!co.to_shwi (&c)) + return -1; return memrefs_conflict_p (xsize, x, ysize, canon_rtx (XEXP (y, 0)), c); } @@ -2711,7 +2753,11 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, poly_int64 cx, cy; if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy)) { - c += cy - cx; + poly_offset_int co = c; + co += cy; + co -= cx; + if (!co.to_shwi (&c)) + return -1; r
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Sauvegarde code finalization
https://gcc.gnu.org/g:acc34b33d1968cd74927f63a0103a07e5c980c8a commit acc34b33d1968cd74927f63a0103a07e5c980c8a Author: Mikael Morin Date: Mon May 26 16:32:36 2025 +0200 Sauvegarde code finalization Diff: --- gcc/fortran/class.cc | 10 -- gcc/fortran/trans-expr.cc | 9 +++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc index f9a2c96f77d8..e6a99be93210 100644 --- a/gcc/fortran/class.cc +++ b/gcc/fortran/class.cc @@ -1622,7 +1622,6 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns, array->ts.u.derived = derived; array->attr.flavor = FL_VARIABLE; array->attr.dummy = 1; - array->attr.contiguous = 1; array->attr.dimension = 1; array->attr.artificial = 1; array->as = gfc_get_array_spec(); @@ -2125,8 +2124,15 @@ finish_assumed_rank: last_code->symtree = ancestor_wrapper->symtree; last_code->resolved_sym = ancestor_wrapper->symtree->n.sym; + gfc_expr *parent_type_array = gfc_lval_expr_from_sym (array); + gfc_ref **subref = &parent_type_array->ref; + if (*subref) + subref = &(*subref)->next; + insert_component_ref (&parent_type_array->ts, subref, + derived->components->name); + last_code->ext.actual = gfc_get_actual_arglist (); - last_code->ext.actual->expr = gfc_lval_expr_from_sym (array); + last_code->ext.actual->expr = parent_type_array; last_code->ext.actual->next = gfc_get_actual_arglist (); last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride); last_code->ext.actual->next->next = gfc_get_actual_arglist (); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 9845f7fe71d6..bd3f35245050 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -7546,7 +7546,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, else if (e->expr_type == EXPR_VARIABLE && is_subref_array (e) - && !(fsym && fsym->attr.pointer)) + && !(fsym && fsym->attr.pointer) + && !(e->symtree->n.sym +&& e->symtree->n.sym->as +&& e->symtree->n.sym->as->type == AS_ASSUMED_RANK)) /* The actual argument is a component reference to an array of derived types. In this case, the argument is converted to a temporary, which is passed and then @@ -7591,7 +7594,9 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && (fsym->attr.target ? gfc_is_not_contiguous (e) : !gfc_is_simply_contiguous (e, false, true)) - && gfc_expr_is_variable (e)) + && gfc_expr_is_variable (e) + && !(e->symtree->n.sym->as + && e->symtree->n.sym->as->type == AS_ASSUMED_RANK)) { gfc_conv_subref_array_arg (&parmse, e, nodesc_arg, fsym->attr.intent,
[gcc r13-9692] doloop: Fix up doloop df use [PR116799]
https://gcc.gnu.org/g:c1e55bcc1075aa74bebd7e1bb87d3939da2e498b commit r13-9692-gc1e55bcc1075aa74bebd7e1bb87d3939da2e498b Author: Jakub Jelinek Date: Thu Dec 5 13:01:21 2024 +0100 doloop: Fix up doloop df use [PR116799] The following testcases are miscompiled on s390x-linux, because the doloop_optimize /* Ensure that the new sequence doesn't clobber a register that is live at the end of the block. */ { bitmap modified = BITMAP_ALLOC (NULL); for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i)) note_stores (i, record_reg_sets, modified); basic_block loop_end = desc->out_edge->src; bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified); check doesn't work as intended. The problem is that it uses df, but the df analysis was only done using iv_analysis_loop_init (loop); -> df_analyze_loop (loop); which computes df inside on the bbs of the loop. While loop_end bb is inside of the loop, df_get_live_out computed that way includes registers set in the loop and used at the start of the next iteration, but doesn't include registers set in the loop (or before the loop) and used after the loop. The following patch fixes that by doing whole function df_analyze first, changes the loop iteration mode from 0 to LI_ONLY_INNERMOST (on many targets which use can_use_doloop_if_innermost target hook a so are known to only handle innermost loops) or LI_FROM_INNERMOST (I think only bfin actually allows non-innermost loops) and checking not just df_get_live_out (loop_end) (that is needed for something used by the next iteration), but also df_get_live_in (desc->out_edge->dest), i.e. what will be used after the loop. df of such a bb shouldn't be affected by the df_analyze_loop and so should be from df_analyze of the whole function. 2024-12-05 Jakub Jelinek PR rtl-optimization/113994 PR rtl-optimization/116799 * loop-doloop.cc: Include targhooks.h. (doloop_optimize): Also punt on intersection of modified with df_get_live_in (desc->out_edge->dest). (doloop_optimize_loops): Call df_analyze. Use LI_ONLY_INNERMOST or LI_FROM_INNERMOST instead of 0 as second loops_list argument. * gcc.c-torture/execute/pr116799.c: New test. * g++.dg/torture/pr113994.C: New test. (cherry picked from commit 0eed81612ad6eac2bec60286348a103d4dc02a5a) Diff: --- gcc/loop-doloop.cc | 20 - gcc/testsuite/g++.dg/torture/pr113994.C| 31 +++ gcc/testsuite/gcc.c-torture/execute/pr116799.c | 41 ++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/gcc/loop-doloop.cc b/gcc/loop-doloop.cc index 4feb0a25ab93..d8a665fad7da 100644 --- a/gcc/loop-doloop.cc +++ b/gcc/loop-doloop.cc @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "loop-unroll.h" #include "regs.h" #include "df.h" +#include "targhooks.h" /* This module is used to modify loops with a determinable number of iterations to use special low-overhead looping instructions. @@ -770,6 +771,18 @@ doloop_optimize (class loop *loop) basic_block loop_end = desc->out_edge->src; bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified); +/* iv_analysis_loop_init calls df_analyze_loop, which computes just + partial df for blocks of the loop only. The above will catch if + any of the modified registers are use inside of the loop body, but + it will most likely not have accurate info on registers used + at the destination of the out_edge. We call df_analyze on the + whole function at the start of the pass though and iterate only + on innermost loops or from innermost loops, so + live in on desc->out_edge->dest should be still unmodified from + the initial df_analyze. */ +if (!fail) + fail = bitmap_intersect_p (df_get_live_in (desc->out_edge->dest), +modified); BITMAP_FREE (modified); if (fail) @@ -795,7 +808,12 @@ doloop_optimize_loops (void) df_live_set_all_dirty (); } - for (auto loop : loops_list (cfun, 0)) + df_analyze (); + + for (auto loop : loops_list (cfun, + targetm.can_use_doloop_p + == can_use_doloop_if_innermost + ? LI_ONLY_INNERMOST : LI_FROM_INNERMOST)) doloop_optimize (loop); if (optimize == 1) diff --git a/gcc/testsuite/g++.dg/torture/pr113994.C b/gcc/testsuite/g++.dg/torture/pr113994.C new file mode 100644 index ..c9c186d45ee7 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr113994.C @@ -0,0 +1,31 @@ +// PR rtl-optimization/113994 +// { dg-do run } + +#include +
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Simplification code finalization
https://gcc.gnu.org/g:66e5dcba5f8713fa57e5857c079348379c6eff29 commit 66e5dcba5f8713fa57e5857c079348379c6eff29 Author: Mikael Morin Date: Mon May 26 13:28:57 2025 +0200 Simplification code finalization Diff: --- gcc/fortran/class.cc | 138 ++- 1 file changed, 4 insertions(+), 134 deletions(-) diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc index e92760db51dd..f9a2c96f77d8 100644 --- a/gcc/fortran/class.cc +++ b/gcc/fortran/class.cc @@ -1477,148 +1477,18 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset, static void finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini, - gfc_symbol *array, gfc_symbol *byte_stride, - gfc_symbol *nelem, gfc_symbol *is_contiguous, - gfc_namespace *sub_ns) + gfc_symbol *array, gfc_symbol *byte_stride ATTRIBUTE_UNUSED, + gfc_symbol *nelem ATTRIBUTE_UNUSED, gfc_symbol *is_contiguous ATTRIBUTE_UNUSED, + gfc_namespace *sub_ns ATTRIBUTE_UNUSED) { - gfc_symbol *ptr2; - gfc_expr *size_expr, *expr; - gfc_namespace *ns; - - block->next = gfc_get_code (EXEC_IF); - block = block->next; - - block->block = gfc_get_code (EXEC_IF); - block = block->block; - - /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */ - size_expr = gfc_get_expr (); - size_expr->where = gfc_current_locus; - size_expr->expr_type = EXPR_OP; - size_expr->value.op.op = INTRINSIC_DIVIDE; - - /* STORAGE_SIZE (array,kind=c_intptr_t). */ - size_expr->value.op.op1 - = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE, - "storage_size", gfc_current_locus, 2, - gfc_lval_expr_from_sym (array), - gfc_get_int_expr (gfc_index_integer_kind, - NULL, 0)); - - /* NUMERIC_STORAGE_SIZE. */ - size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, - gfc_character_storage_size); - size_expr->value.op.op1->ts = size_expr->value.op.op2->ts; - size_expr->ts = size_expr->value.op.op1->ts; - - /* IF condition: (stride == size_expr - && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous) - || is_contiguous) - || 0 == size_expr. */ - block->expr1 = gfc_get_expr (); - block->expr1->ts.type = BT_LOGICAL; - block->expr1->ts.kind = gfc_default_logical_kind; - block->expr1->expr_type = EXPR_OP; - block->expr1->where = gfc_current_locus; - - block->expr1->value.op.op = INTRINSIC_OR; - - /* byte_stride == size_expr */ - expr = gfc_get_expr (); - expr->ts.type = BT_LOGICAL; - expr->ts.kind = gfc_default_logical_kind; - expr->expr_type = EXPR_OP; - expr->where = gfc_current_locus; - expr->value.op.op = INTRINSIC_EQ; - expr->value.op.op1 - = gfc_lval_expr_from_sym (byte_stride); - expr->value.op.op2 = size_expr; - - /* If strides aren't allowed (not assumed shape or CONTIGUOUS), - add is_contiguous check. */ - - if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE - || fini->proc_tree->n.sym->formal->sym->attr.contiguous) -{ - gfc_expr *expr2; - expr2 = gfc_get_expr (); - expr2->ts.type = BT_LOGICAL; - expr2->ts.kind = gfc_default_logical_kind; - expr2->expr_type = EXPR_OP; - expr2->where = gfc_current_locus; - expr2->value.op.op = INTRINSIC_AND; - expr2->value.op.op1 = expr; - expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous); - expr = expr2; -} - - block->expr1->value.op.op1 = expr; - - /* 0 == size_expr */ - block->expr1->value.op.op2 = gfc_get_expr (); - block->expr1->value.op.op2->ts.type = BT_LOGICAL; - block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind; - block->expr1->value.op.op2->expr_type = EXPR_OP; - block->expr1->value.op.op2->where = gfc_current_locus; - block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ; - block->expr1->value.op.op2->value.op.op1 = - gfc_get_int_expr (gfc_index_integer_kind, NULL, 0); - block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr); - /* IF body: call final subroutine. */ block->next = gfc_get_code (EXEC_CALL); - block->next->symtree = fini->proc_tree; - block->next->resolved_sym = fini->proc_tree->n.sym; - block->next->ext.actual = gfc_get_actual_arglist (); - block->next->ext.actual->expr = gfc_lval_expr_from_sym (array); - - /* ELSE. */ - - block->block = gfc_get_code (EXEC_IF); - block = block->block; - - /* BLOCK ... END BLOCK. */ - block->next = gfc_get_code (EXEC_BLOCK); block = block->next; - ns = gfc_build_block_ns (sub_ns); - block->ext.block.ns = ns; - block->ext.block.assoc = NULL; - - gfc_get_symbol ("
[gcc r13-9698] c++: Fix explicit instantiation of const variable templates after earlier implicit instantation [PR1
https://gcc.gnu.org/g:5e72938390fb49549a38e5800b2c635c061b07d8 commit r13-9698-g5e72938390fb49549a38e5800b2c635c061b07d8 Author: Jakub Jelinek Date: Wed Feb 28 23:20:13 2024 +0100 c++: Fix explicit instantiation of const variable templates after earlier implicit instantation [PR113976] Already previously instantiated const variable templates had cp_apply_type_quals_to_decl called when they were instantiated, but if they need runtime initialization, their TREE_READONLY flag has been subsequently cleared. Explicit variable template instantiation calls grokdeclarator which calls cp_apply_type_quals_to_decl on them again, setting TREE_READONLY flag again, but nothing clears it afterwards, so we emit such instantiations into rodata sections and segfault when the dynamic initialization attempts to initialize them. The following patch fixes that by not calling cp_apply_type_quals_to_decl on already instantiated variable declarations. 2024-02-28 Jakub Jelinek Patrick Palka PR c++/113976 * decl.cc (grokdeclarator): Don't call cp_apply_type_quals_to_decl on DECL_TEMPLATE_INSTANTIATED VAR_DECLs. * g++.dg/cpp1y/var-templ87.C: New test. (cherry picked from commit 29ac92436aa5c702e9e02c206e7590ebd806398e) Diff: --- gcc/cp/decl.cc | 7 +- gcc/testsuite/g++.dg/cpp1y/var-templ87.C | 43 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index e49641680231..9a5f2ee87421 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -14858,7 +14858,12 @@ grokdeclarator (const cp_declarator *declarator, /* Record constancy and volatility on the DECL itself . There's no need to do this when processing a template; we'll do this for the instantiated declaration based on the type of DECL. */ -if (!processing_template_decl) +if (!processing_template_decl + /* Don't do it for instantiated variable templates either, + cp_apply_type_quals_to_decl should have been called on it + already and might have been overridden in cp_finish_decl + if initializer needs runtime initialization. */ + && (!VAR_P (decl) || !DECL_TEMPLATE_INSTANTIATED (decl))) cp_apply_type_quals_to_decl (type_quals, decl); return decl; diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ87.C b/gcc/testsuite/g++.dg/cpp1y/var-templ87.C new file mode 100644 index ..e62d06d172c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ87.C @@ -0,0 +1,43 @@ +// PR c++/113976 +// { dg-do run { target c++14 } } + +int +foo () +{ + return 42; +} + +template +const int a = foo (); +const int *b = &a <0>; +template +const int c = foo (); +template const int c <0>; +template +const int d = foo (); +const int *e = &d <0>; +template const int d <0>; +template +const int f = foo (); +template const int f <0>; +const int *g = &f <0>; +struct S { int a, b; }; +template +const S h = { 42, foo () }; +const S *i = &h <0>; +template +const S j = { 42, foo () }; +template const S j <0>; +template +const S k = { 42, foo () }; +const S *l = &k <0>; +template const S k <0>; +template +const S m = { 42, foo () }; +template const S m <0>; +const S *n = &m <0>; + +int +main () +{ +}
[gcc r13-9690] c++: vtable referring to "unavailable" virtual fn [PR116606]
https://gcc.gnu.org/g:d0f2b0711f24238c5daefc97448d2f1b3a856359 commit r13-9690-gd0f2b0711f24238c5daefc97448d2f1b3a856359 Author: Marek Polacek Date: Thu Sep 5 13:01:59 2024 -0400 c++: vtable referring to "unavailable" virtual fn [PR116606] mark_vtable_entries already has /* It's OK for the vtable to refer to deprecated virtual functions. */ warning_sentinel w(warn_deprecated_decl); but that doesn't cover __attribute__((unavailable)). We can use the following override to cover both. PR c++/116606 gcc/cp/ChangeLog: * decl2.cc (mark_vtable_entries): Temporarily override deprecated_state to UNAVAILABLE_DEPRECATED_SUPPRESS. Remove a warning_sentinel. gcc/testsuite/ChangeLog: * g++.dg/ext/attr-unavailable-13.C: New test. (cherry picked from commit d9d34f9a91371dea4bab0b54b2d7f762a6cc23e0) Diff: --- gcc/cp/decl2.cc| 3 ++- gcc/testsuite/g++.dg/ext/attr-unavailable-13.C | 8 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 89c64277b5d6..fb2241b48133 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -2075,7 +2075,8 @@ static void mark_vtable_entries (tree decl, vec &consteval_vtables) { /* It's OK for the vtable to refer to deprecated virtual functions. */ - warning_sentinel w(warn_deprecated_decl); + auto du = make_temp_override (deprecated_state, + UNAVAILABLE_DEPRECATED_SUPPRESS); bool consteval_seen = false; diff --git a/gcc/testsuite/g++.dg/ext/attr-unavailable-13.C b/gcc/testsuite/g++.dg/ext/attr-unavailable-13.C new file mode 100644 index ..9ca400054190 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-unavailable-13.C @@ -0,0 +1,8 @@ +// PR c++/116606 +// { dg-do compile } + +struct C { +__attribute__((unavailable)) virtual void f() {} +}; + +C c;
[gcc r16-881] OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BLOCK [PR120413]
https://gcc.gnu.org/g:45b849d05b733a25ec7ce612229084b8f4b86d3d commit r16-881-g45b849d05b733a25ec7ce612229084b8f4b86d3d Author: Tobias Burnus Date: Mon May 26 17:58:07 2025 +0200 OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BLOCK [PR120413] PR c++/120413 gcc/cp/ChangeLog: * semantics.cc (finish_omp_target_clauses_r): Handle BIND_EXPR with empty BIND_EXPR_BLOCK. gcc/testsuite/ChangeLog: * g++.dg/gomp/target-4.C: New test. Diff: --- gcc/cp/semantics.cc | 8 gcc/testsuite/g++.dg/gomp/target-4.C | 22 ++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 43a0eabfa127..ef4a668a4e4d 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -10565,10 +10565,10 @@ finish_omp_target_clauses_r (tree *tp, int *walk_subtrees, void *ptr) if (TREE_CODE (t) == BIND_EXPR) { - tree block = BIND_EXPR_BLOCK (t); - for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) - if (!data->local_decls.contains (var)) - data->local_decls.add (var); + if (tree block = BIND_EXPR_BLOCK (t)) + for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) + if (!data->local_decls.contains (var)) + data->local_decls.add (var); return NULL_TREE; } diff --git a/gcc/testsuite/g++.dg/gomp/target-4.C b/gcc/testsuite/g++.dg/gomp/target-4.C new file mode 100644 index ..80fc9dfe9365 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/target-4.C @@ -0,0 +1,22 @@ +// { dg-do compile { target c++11 } } +// PR c++/120413 + +struct S +{ + S() {} + ~S() {} +}; + +struct array +{ + S _arr[1]; +}; + +int main() +{ +#pragma omp target + { +array arr{}; + } + return 0; +}
[gcc r16-882] libstdc++: Run in_place constructor test for std::indirect [PR119152]
https://gcc.gnu.org/g:97e8cd9295dadad32fb5866e96cb7e403c1d993d commit r16-882-g97e8cd9295dadad32fb5866e96cb7e403c1d993d Author: Tomasz Kamiński Date: Mon May 26 17:35:08 2025 +0200 libstdc++: Run in_place constructor test for std::indirect [PR119152] In indirect/ctor.cc test_inplace_ctor function was defined, but never called. PR libstdc++/119152 libstdc++-v3/ChangeLog: * testsuite/std/memory/indirect/ctor.cc: Run test_inplace_ctor. Diff: --- libstdc++-v3/testsuite/std/memory/indirect/ctor.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc b/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc index 67e7a8aba037..124874d02fe6 100644 --- a/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc +++ b/libstdc++-v3/testsuite/std/memory/indirect/ctor.cc @@ -139,7 +139,6 @@ test_inplace_ctor() std::indirect> i5(std::in_place); VERIFY( i5->size() == 0 ); - VERIFY( i5->at(0) == 13 ); std::indirect> i6(std::in_place, 5, 13); VERIFY( i6->size() == 5 ); @@ -194,10 +193,12 @@ int main() { test_default_ctor(); test_forwarding_ctor(); + test_inplace_ctor(); static_assert([] { test_default_ctor(); test_forwarding_ctor(); +test_inplace_ctor(); return true; }); }
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] gimple-exec: réutilisation decompose_ref
https://gcc.gnu.org/g:630d555a49b2b503b7cfb5c3bcdcd374d9cacf14 commit 630d555a49b2b503b7cfb5c3bcdcd374d9cacf14 Author: Mikael Morin Date: Mon May 26 11:13:56 2025 +0200 gimple-exec: réutilisation decompose_ref Diff: --- gcc/cgraphunit.cc | 71 --- 1 file changed, 15 insertions(+), 56 deletions(-) diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index 97013daa9fbd..40b1af804be9 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -3850,6 +3850,8 @@ exec_context::evaluate (tree expr) const { case ARRAY_REF: case COMPONENT_REF: +case MEM_REF: +case TARGET_MEM_REF: { data_storage *storage = nullptr; int offset = -1; @@ -3871,54 +3873,6 @@ exec_context::evaluate (tree expr) const } break; -case MEM_REF: -case TARGET_MEM_REF: - { - tree ptr = TREE_OPERAND (expr, 0); - data_value val_ptr = evaluate (ptr); - gcc_assert (val_ptr.classify () == VAL_ADDRESS); - storage_address *address = val_ptr.get_address (); - gcc_assert (address != nullptr); - data_value storage_value = address->storage.get ().get_value (); - wide_int ptr_off = wi::uhwi (address->offset, -HOST_BITS_PER_WIDE_INT); - - tree offset_bytes = TREE_OPERAND (expr, 1); - data_value val_off = evaluate (offset_bytes); - gcc_assert (val_off.classify () == VAL_CONSTANT); - wide_int wi_off = val_off.get_cst (); - - unsigned bit_width; - if (!get_constant_type_size (TREE_TYPE (expr), bit_width)) - gcc_unreachable (); - - if (code == TARGET_MEM_REF) - { - tree index = TREE_OPERAND (expr, 2); - tree step = TREE_OPERAND (expr, 3); - if (index || step) - { - gcc_assert (index && step); - - data_value val_idx = evaluate (index); - gcc_assert (val_idx.classify () == VAL_CONSTANT); - wide_int wi_idx = val_idx.get_cst (); - - data_value val_step = evaluate (step); - gcc_assert (val_step.classify () == VAL_CONSTANT); - wide_int wi_step = val_step.get_cst (); - - wi_off += wi_idx * wi_step; - } - } - - wi_off = wi_off * CHAR_BIT + ptr_off; - gcc_assert (wi::fits_uhwi_p (wi_off)); - - return storage_value.get_at (wi_off.to_shwi (), bit_width); - } - break; - case INTEGER_CST: { data_value result (TREE_TYPE (expr)); @@ -4288,15 +4242,20 @@ exec_context::decompose_ref (tree data_ref, data_storage * & storage, int & offs if (code == TARGET_MEM_REF) { tree index = TREE_OPERAND (data_ref, 2); - data_value idx_val = evaluate (index); - gcc_assert (idx_val.classify () == VAL_CONSTANT); - add_index = idx_val.get_cst (); - tree step = TREE_OPERAND (data_ref, 3); - data_value step_val = evaluate (step); - gcc_assert (step_val.classify () == VAL_CONSTANT); - add_multiplier = step_val.get_cst (); - add_multiplier *= CHAR_BIT; + if (index || step) + { + gcc_assert (index && step); + + data_value idx_val = evaluate (index); + gcc_assert (idx_val.classify () == VAL_CONSTANT); + add_index = idx_val.get_cst (); + + data_value step_val = evaluate (step); + gcc_assert (step_val.classify () == VAL_CONSTANT); + add_multiplier = step_val.get_cst (); + add_multiplier *= CHAR_BIT; + } } } break;
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression assign_10
https://gcc.gnu.org/g:f3275b34704c8463bdfeecc0f0dffa838d8db986 commit f3275b34704c8463bdfeecc0f0dffa838d8db986 Author: Mikael Morin Date: Mon May 26 18:52:29 2025 +0200 Correction régression assign_10 Diff: --- gcc/fortran/trans-array.cc | 2 +- gcc/testsuite/gfortran.dg/assign_10.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 264abd407b46..11a203e474b8 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -3518,7 +3518,7 @@ conv_array_index (gfc_se * se, gfc_ss * ss, int dim, int i, gfc_array_ref * ar) index = gfc_build_array_ref (data, index, non_negative_strides_array_p (desc), se->loop->from[i], - gfc_conv_array_spacing (desc, 0)); + info->subscript[dim]->info->data.array.spacing[0]); index = gfc_evaluate_now (index, &se->pre); index = fold_convert (gfc_array_index_type, index); diff --git a/gcc/testsuite/gfortran.dg/assign_10.f90 b/gcc/testsuite/gfortran.dg/assign_10.f90 index c207f9e5e2b4..965e91c66bb2 100644 --- a/gcc/testsuite/gfortran.dg/assign_10.f90 +++ b/gcc/testsuite/gfortran.dg/assign_10.f90 @@ -23,5 +23,5 @@ end ! cases will all yield a temporary, so that atmp appears 18 times. ! Note that it is the kind conversion that generates the temp. ! -! { dg-final { scan-tree-dump-times "parm" 20 "original" } } +! { dg-final { scan-tree-dump-times "parm" 18 "original" } } ! { dg-final { scan-tree-dump-times "atmp" 20 "original" } }
[gcc r15-9729] OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BLOCK [PR120413]
https://gcc.gnu.org/g:9c8e20a8425f123abd54261d03af5a956d4d01c6 commit r15-9729-g9c8e20a8425f123abd54261d03af5a956d4d01c6 Author: Tobias Burnus Date: Mon May 26 17:58:07 2025 +0200 OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BLOCK [PR120413] PR c++/120413 gcc/cp/ChangeLog: * semantics.cc (finish_omp_target_clauses_r): Handle BIND_EXPR with empty BIND_EXPR_BLOCK. gcc/testsuite/ChangeLog: * g++.dg/gomp/target-4.C: New test. (cherry picked from commit 45b849d05b733a25ec7ce612229084b8f4b86d3d) Diff: --- gcc/cp/semantics.cc | 8 gcc/testsuite/g++.dg/gomp/target-4.C | 22 ++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index a10ef34383c2..804c22d4661a 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -10543,10 +10543,10 @@ finish_omp_target_clauses_r (tree *tp, int *walk_subtrees, void *ptr) if (TREE_CODE (t) == BIND_EXPR) { - tree block = BIND_EXPR_BLOCK (t); - for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) - if (!data->local_decls.contains (var)) - data->local_decls.add (var); + if (tree block = BIND_EXPR_BLOCK (t)) + for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) + if (!data->local_decls.contains (var)) + data->local_decls.add (var); return NULL_TREE; } diff --git a/gcc/testsuite/g++.dg/gomp/target-4.C b/gcc/testsuite/g++.dg/gomp/target-4.C new file mode 100644 index ..80fc9dfe9365 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/target-4.C @@ -0,0 +1,22 @@ +// { dg-do compile { target c++11 } } +// PR c++/120413 + +struct S +{ + S() {} + ~S() {} +}; + +struct array +{ + S _arr[1]; +}; + +int main() +{ +#pragma omp target + { +array arr{}; + } + return 0; +}
[gcc r15-9730] libgomp.c-c++-common/metadirective-1.c: Expect 'error:' for nvptx compile [PR118694]
https://gcc.gnu.org/g:cf619d4a366ad428421fdb7ad617b4749799cf93 commit r15-9730-gcf619d4a366ad428421fdb7ad617b4749799cf93 Author: Tobias Burnus Date: Fri May 23 11:30:48 2025 +0200 libgomp.c-c++-common/metadirective-1.c: Expect 'error:' for nvptx compile [PR118694] OpenMP's 'target teams' is strictly coupled with 'teams'; if the latter exists, the kernel is launched in directly with multiple teams. Thus, the host has to know whether the teams construct exists or not. For #pragma omp target #pragma omp metadirective when (device={arch("nvptx")}: teams loop) it is simple when 'nvptx' offloading is not supported, otherwise it depends on the default device at runtime as the user code asks for a single team for host fallback and gcn offload and multiple for nvptx offload. In any case, this commit ensures that no FAIL is printed, whatever a future solution might look like. Instead of a dg-bogus combined with an 'xfail offload_target_nvptx', one an also argue that a dg-error for 'target offload_target_nvptx' would be more appropriate. libgomp/ChangeLog: PR middle-end/118694 * testsuite/libgomp.c-c++-common/metadirective-1.c: xfail when compiling (also) for nvptx offloading as an error is then expected. (cherry picked from commit b3d07ec7ac2ccd935a79b29e1a0e2eb16225286a) Diff: --- libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c b/libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c index a57d6fd56714..fbe4ac3a954e 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c +++ b/libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c @@ -1,4 +1,5 @@ -/* { dg-do run } */ +/* { dg-do run { target { ! offload_target_nvptx } } } */ +/* { dg-do compile { target offload_target_nvptx } } */ #define N 100 @@ -7,12 +8,17 @@ f (int x[], int y[], int z[]) { int i; + // The following fails as on the host the target side cannot be + // resolved - and the 'teams' or not status affects how 'target' + // is called. + // Note also the dg-do compile above for offload_target_nvptx #pragma omp target map(to: x[0:N], y[0:N]) map(from: z[0:N]) #pragma omp metadirective \ when (device={arch("nvptx")}: teams loop) \ default (parallel loop) for (i = 0; i < N; i++) z[i] = x[i] * y[i]; + /* { dg-bogus "'target' construct with nested 'teams' construct contains directives outside of the 'teams' construct" "PR118694" { xfail offload_target_nvptx } .-6 } */ } int
[gcc r13-9693] gimple-fold: Avoid ICEs with bogus declarations like const attribute no snprintf [PR117358]
https://gcc.gnu.org/g:65724317b26eb16a3cd7279aacd68f4c85b355c0 commit r13-9693-g65724317b26eb16a3cd7279aacd68f4c85b355c0 Author: Jakub Jelinek Date: Thu Nov 28 10:51:16 2024 +0100 gimple-fold: Avoid ICEs with bogus declarations like const attribute no snprintf [PR117358] When one puts incorrect const or pure attributes on declarations of various C APIs which have corresponding builtins (vs. what they actually do), we can get tons of ICEs in gimple-fold.cc. The following patch fixes it by giving up gimple_fold_builtin_* folding if the functions don't have gimple_vdef (or for pure functions like bcmp/strchr/strstr gimple_vuse) when in SSA form (during gimplification they will surely have both of those NULL even when declared correctly, yet it is highly desirable to fold them). Or shall I replace !gimple_vdef (stmt) && gimple_in_ssa_p (cfun) tests with (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE | ECF_NOVOPS)) != 0 and !gimple_vuse (stmt) && gimple_in_ssa_p (cfun) with (gimple_call_flags (stmt) & (ECF_CONST | ECF_NOVOPS)) != 0 ? 2024-11-28 Jakub Jelinek PR tree-optimization/117358 * gimple-fold.cc (gimple_fold_builtin_memory_op): Punt if stmt has no vdef in ssa form. (gimple_fold_builtin_bcmp): Punt if stmt has no vuse in ssa form. (gimple_fold_builtin_bcopy): Punt if stmt has no vdef in ssa form. (gimple_fold_builtin_bzero): Likewise. (gimple_fold_builtin_memset): Likewise. Use return false instead of return NULL_TREE. (gimple_fold_builtin_strcpy): Punt if stmt has no vdef in ssa form. (gimple_fold_builtin_strncpy): Likewise. (gimple_fold_builtin_strchr): Punt if stmt has no vuse in ssa form. (gimple_fold_builtin_strstr): Likewise. (gimple_fold_builtin_strcat): Punt if stmt has no vdef in ssa form. (gimple_fold_builtin_strcat_chk): Likewise. (gimple_fold_builtin_strncat): Likewise. (gimple_fold_builtin_strncat_chk): Likewise. (gimple_fold_builtin_string_compare): Likewise. (gimple_fold_builtin_fputs): Likewise. (gimple_fold_builtin_memory_chk): Likewise. (gimple_fold_builtin_stxcpy_chk): Likewise. (gimple_fold_builtin_stxncpy_chk): Likewise. (gimple_fold_builtin_stpcpy): Likewise. (gimple_fold_builtin_snprintf_chk): Likewise. (gimple_fold_builtin_sprintf_chk): Likewise. (gimple_fold_builtin_sprintf): Likewise. (gimple_fold_builtin_snprintf): Likewise. (gimple_fold_builtin_fprintf): Likewise. (gimple_fold_builtin_printf): Likewise. (gimple_fold_builtin_realloc): Likewise. * gcc.c-torture/compile/pr117358.c: New test. (cherry picked from commit 29032dfa57629d1713a97b17a785273823993a91) Diff: --- gcc/gimple-fold.cc | 76 -- gcc/testsuite/gcc.c-torture/compile/pr117358.c | 17 ++ 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index b5f4a9ec0a1c..180817cc8680 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -938,6 +938,8 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, } goto done; } + else if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)) +return false; else { /* We cannot (easily) change the type of the copy if it is a storage @@ -1376,6 +1378,8 @@ gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi) /* Transform bcmp (a, b, len) into memcmp (a, b, len). */ gimple *stmt = gsi_stmt (*gsi); + if (!gimple_vuse (stmt) && gimple_in_ssa_p (cfun)) +return false; tree a = gimple_call_arg (stmt, 0); tree b = gimple_call_arg (stmt, 1); tree len = gimple_call_arg (stmt, 2); @@ -1402,6 +1406,8 @@ gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi) len) into memmove (dest, src, len). */ gimple *stmt = gsi_stmt (*gsi); + if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)) +return false; tree src = gimple_call_arg (stmt, 0); tree dest = gimple_call_arg (stmt, 1); tree len = gimple_call_arg (stmt, 2); @@ -1427,6 +1433,8 @@ gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi) /* Transform bzero (dest, len) into memset (dest, 0, len). */ gimple *stmt = gsi_stmt (*gsi); + if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)) +return false; tree dest = gimple_call_arg (stmt, 0); tree len = gimple_call_arg (stmt, 1); @@ -1456,6 +1464,9 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len) return true; } + if (!gimple_vdef (stmt) && gimple_in_ssa_p (cfun)) +return false; + if (! tree_fits_uhwi_p (len)) return false; @@ -1477,20 +1488,20 @@ gimple_fold_bu
[gcc r16-883] c-c++-common/gomp/{attrs-, }metadirective-3.c: Fix expected result [PR118694]
https://gcc.gnu.org/g:5d6ed6d604ff949b650e48fa4eaed3ec8b6489c1 commit r16-883-g5d6ed6d604ff949b650e48fa4eaed3ec8b6489c1 Author: Tobias Burnus Date: Mon May 26 19:50:40 2025 +0200 c-c++-common/gomp/{attrs-,}metadirective-3.c: Fix expected result [PR118694] With compilation for nvptx enabled, two issues showed up: (a) "error: 'target' construct with nested 'teams' construct contains directives outside of the 'teams' construct" See PR comment 9 why this is difficult to fix. Solution: Add dg-bogus and accept/expect the error for 'target offload_nvptx'. (b) The assumptions about the dump for 'target offload_nvptx' were wrong as the metadirective was already expanded to a OMP_NEXT_VARIANT construct such that no 'omp metadirective' was left in either case. Solution: Check that no 'omp metadirective' is left; additionally, expect either OMP_NEXT_VARIANT (when offload_nvptx is available) or no 'teams' directive at all (if not). gcc/testsuite/ChangeLog: PR middle-end/118694 * c-c++-common/gomp/attrs-metadirective-3.c: Change to never expect 'omp metadirective' in the dump. If !offload_nvptx, check that no 'teams' shows up in the dump; for offload_nvptx, expect OMP_NEXT_VARIANT and an error about directive between 'target' and 'teams'. * c-c++-common/gomp/metadirective-3.c: Likewise. Diff: --- gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c | 7 --- gcc/testsuite/c-c++-common/gomp/metadirective-3.c | 7 --- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c b/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c index 31dd054922fc..803bf0ad1ebf 100644 --- a/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c +++ b/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c @@ -9,7 +9,7 @@ f (int x[], int y[], int z[]) { int i; - [[omp::sequence (directive (target map(to: x, y) map(from: z)), + [[omp::sequence (directive (target map(to: x, y) map(from: z)), /* { dg-bogus "'target' construct with nested 'teams' construct contains directives outside of the 'teams' construct" "PR118694" { xfail offload_nvptx } } */ directive (metadirective when (device={arch("nvptx")}: teams loop) default (parallel loop)))]] @@ -20,5 +20,6 @@ f (int x[], int y[], int z[]) /* If offload device "nvptx" isn't supported, the front end can eliminate that alternative and not produce a metadirective at all. Otherwise this won't be resolved until late. */ -/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" { target { ! offload_nvptx } } } } */ -/* { dg-final { scan-tree-dump "#pragma omp metadirective" "gimple" { target { offload_nvptx } } } } */ +/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" } } */ +/* { dg-final { scan-tree-dump-not " teams" "gimple" { target { ! offload_nvptx } } } } */ +/* { dg-final { scan-tree-dump "variant.\[0-9\]+ = \\\[omp_next_variant\\\] OMP_NEXT_VARIANT <0,\[\r\n \]+construct context = 14\[\r\n \]+1: device = \\{arch \\(.nvptx.\\)\\}\[\r\n \]+2: >;" "gimple" { target { offload_nvptx } } } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/metadirective-3.c b/gcc/testsuite/c-c++-common/gomp/metadirective-3.c index 0ac0d1d329d8..b6c1601f7b10 100644 --- a/gcc/testsuite/c-c++-common/gomp/metadirective-3.c +++ b/gcc/testsuite/c-c++-common/gomp/metadirective-3.c @@ -8,7 +8,7 @@ f (int x[], int y[], int z[]) { int i; - #pragma omp target map(to: x, y) map(from: z) + #pragma omp target map(to: x, y) map(from: z) /* { dg-bogus "'target' construct with nested 'teams' construct contains directives outside of the 'teams' construct" "PR118694" { xfail offload_nvptx } } */ #pragma omp metadirective \ when (device={arch("nvptx")}: teams loop) \ default (parallel loop) @@ -19,5 +19,6 @@ f (int x[], int y[], int z[]) /* If offload device "nvptx" isn't supported, the front end can eliminate that alternative and not produce a metadirective at all. Otherwise this won't be resolved until late. */ -/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" { target { ! offload_nvptx } } } } */ -/* { dg-final { scan-tree-dump "#pragma omp metadirective" "gimple" { target { offload_nvptx } } } } */ +/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" } } */ +/* { dg-final { scan-tree-dump-not " teams" "gimple" { target { ! offload_nvptx } } } } */ +/* { dg-final { scan-tree-dump "variant.\[0-9\]+ = \\\[omp_next_variant\\\] OMP_NEXT_VARIANT <0,\[\r\n \]+construct context = 14\[\r\n \]+1: device = \\{arch \\(.nvptx.\\)\\}\[\r\n \]+2: >;" "gimple" { target { offload_nvptx } } } } */
[gcc/devel/omp/gcc-15] Merge branch 'releases/gcc-15' into devel/omp/gcc-15
https://gcc.gnu.org/g:499d610ac358f9b8dd3f788c6728f05ecea7c3e3 commit 499d610ac358f9b8dd3f788c6728f05ecea7c3e3 Merge: e841798c07dc d390c7e5bd03 Author: Tobias Burnus Date: Mon May 26 19:59:34 2025 +0200 Merge branch 'releases/gcc-15' into devel/omp/gcc-15 Merge up to r15-9731-gd390c7e5bd0349 (26th May 2025) Diff: gcc/ChangeLog | 32 ++ gcc/DATESTAMP | 2 +- gcc/cgraph.cc | 2 +- gcc/cgraph.h | 2 +- gcc/cgraphclones.cc| 4 +- gcc/config/microblaze/microblaze.cc| 4 + gcc/cp/ChangeLog | 35 ++ gcc/cp/decl2.cc| 3 +- gcc/cp/module.cc | 3 +- gcc/cp/semantics.cc| 8 +- gcc/fortran/ChangeLog | 19 gcc/fortran/dependency.cc | 6 +- gcc/fortran/resolve.cc | 8 +- gcc/ipa-cp.cc | 2 +- gcc/ipa-sra.cc | 2 +- gcc/symtab.cc | 4 +- gcc/testsuite/ChangeLog| 79 + .../c-c++-common/gomp/attrs-metadirective-3.c | 7 +- gcc/testsuite/c-c++-common/gomp/metadirective-3.c | 7 +- gcc/testsuite/g++.dg/gomp/target-4.C | 22 .../g++.dg/modules/{pr113292_a.H => tls-1_a.H} | 0 .../g++.dg/modules/{pr113292_b.C => tls-1_b.C} | 2 +- .../g++.dg/modules/{pr113292_c.C => tls-1_c.C} | 2 +- gcc/testsuite/g++.dg/modules/tls-2_a.C | 12 ++ gcc/testsuite/g++.dg/modules/tls-2_b.C | 5 + gcc/testsuite/g++.dg/modules/tls-2_c.C | 11 ++ gcc/testsuite/g++.dg/modules/tls-3.h | 42 +++ gcc/testsuite/g++.dg/modules/tls-3_a.H | 4 + gcc/testsuite/g++.dg/modules/tls-3_b.C | 4 + gcc/testsuite/g++.dg/modules/using-31_a.C | 18 +++ gcc/testsuite/g++.dg/modules/using-31_b.C | 5 + gcc/testsuite/gcc.dg/ipa/pr120044-1.c | 17 +++ gcc/testsuite/gcc.dg/ipa/pr120044-2.c | 17 +++ gcc/testsuite/gcc.dg/tree-ssa/pr114864.c | 15 +++ .../gfortran.dg/alloc_comp_auto_array_3.f90| 4 +- gcc/testsuite/gfortran.dg/alloc_comp_class_3.f03 | 3 +- gcc/testsuite/gfortran.dg/alloc_comp_class_4.f03 | 5 +- .../gfortran.dg/allocate_with_source_14.f03| 2 +- .../gfortran.dg/derived_constructor_comps_6.f90| 2 +- gcc/testsuite/gfortran.dg/derived_result_5.f90 | 123 + .../gfortran.dg/transfer_array_subref.f90 | 48 gcc/tree-sra.cc| 4 +- .../libgomp.c-c++-common/metadirective-1.c | 8 +- libstdc++-v3/ChangeLog | 12 ++ 44 files changed, 577 insertions(+), 39 deletions(-)
[gcc/devel/omp/gcc-15] (17 commits) Merge branch 'releases/gcc-15' into devel/omp/gcc-15
The branch 'devel/omp/gcc-15' was updated to point to: 499d610ac358... Merge branch 'releases/gcc-15' into devel/omp/gcc-15 It previously pointed to: e841798c07dc... ChangeLog.omp bump Diff: Summary of changes (added commits): --- 499d610... Merge branch 'releases/gcc-15' into devel/omp/gcc-15 d390c7e... c-c++-common/gomp/{attrs-,}metadirective-3.c: Fix expected (*) cf619d4... libgomp.c-c++-common/metadirective-1.c: Expect 'error:' for (*) 9c8e20a... OpenMP/C++: Avoid ICE for BIND_EXPR with empty BIND_EXPR_BL (*) afa69f8... Daily bump. (*) 4ac1fb5... MicroBlaze does not support speculative execution (CVE-2017 (*) 65c2baf... Daily bump. (*) 18f937f... Daily bump. (*) a8f62a9... c++/modules: Fix merge of TLS init functions [PR120363] (*) 2486d94... c++/modules: Fix stream-in of member using-decls [PR120414] (*) fd2a11e... Daily bump. (*) 6fb3dd1... Fortran: default-initialization and functions returning der (*) 8c4b236... Daily bump. (*) 7e58022... Daily bump. (*) 6683c72... Fortran: fix passing of inquiry ref of complex array to TRA (*) c1db46f... tree-sra: Do not create stores into const aggregates (PR111 (*) 76d16fb... ipa: Dump cgraph_node UID instead of order into ipa-clones (*) (*) This commit already exists in another branch. Because the reference `refs/heads/devel/omp/gcc-15' matches your hooks.email-new-commits-only configuration, no separate email is sent for this commit.
[gcc r13-9688] s390: Fix tf_to_fprx2
https://gcc.gnu.org/g:a0fe50437ec2e207876a489ce0fdd4d35aeeebb0 commit r13-9688-ga0fe50437ec2e207876a489ce0fdd4d35aeeebb0 Author: Stefan Schulze Frielinghaus Date: Wed May 14 09:22:00 2025 +0200 s390: Fix tf_to_fprx2 Insn tf_to_fprx2 moves a TF value into a floating-point register pair. For alternative 0, the input is a vector register, however, in the else case instruction ldr is emitted which expects floating-point register operands only. Thus, this works only for vector registers which overlap with floating-point registers. Replace ldr with vlr so that the remaining vector registers are dealt with, too. Emitting a vlr instead of a ldr is fine since the destination register %v0 is part of a floating-point register pair which means that the low half of %v0 is ignored in the end anyway and therefore may be clobbered. gcc/ChangeLog: * config/s390/vector.md: Fix tf_to_fprx2 by using vlr instead of ldr. (cherry picked from commit 8519b8ba9dd9567a5f90966351c1e758dbf511a4) Diff: --- gcc/config/s390/vector.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md index 8cf39e0cd4b6..b65b3ee88d14 100644 --- a/gcc/config/s390/vector.md +++ b/gcc/config/s390/vector.md @@ -936,7 +936,7 @@ else { reg_pair += 2; // get rid of prefix %f - snprintf (buf, sizeof (buf), "ldr\t%%f0,%%f1;vpdi\tv%s,%%v1,v%s,5", reg_pair, reg_pair); + snprintf (buf, sizeof (buf), "vlr\t%%v0,%%v1;vpdi\tv%s,%%v1,v%s,5", reg_pair, reg_pair); output_asm_insn (buf, operands); return ""; }
[gcc r13-9694] cselib: For CALL_INSNs to const/pure fns invalidate memory below sp [PR117239]
https://gcc.gnu.org/g:af5d43648bd942a9c273218432b2cd0c446a9f04 commit r13-9694-gaf5d43648bd942a9c273218432b2cd0c446a9f04 Author: Jakub Jelinek Date: Wed Feb 5 13:16:17 2025 +0100 cselib: For CALL_INSNs to const/pure fns invalidate memory below sp [PR117239] The following testcase is miscompiled on x86_64 during postreload. After reload (with IPA-RA figuring out the calls don't modify any registers but %rax for return value) postreload sees (insn 14 12 15 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp) (const_int 16 [0x10])) [0 S8 A64]) (reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":18:7 95 {*movdi_internal} (nil)) (call_insn/i 15 14 16 2 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:DI ("baz") [flags 0x3] ) [0 baz S1 A8]) (const_int 24 [0x18]))) "pr117239.c":18:7 1476 {*call_value} (expr_list:REG_CALL_DECL (symbol_ref:DI ("baz") [flags 0x3] ) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil))) (nil)) (insn 16 15 18 2 (parallel [ (set (reg/f:DI 7 sp) (plus:DI (reg/f:DI 7 sp) (const_int 24 [0x18]))) (clobber (reg:CC 17 flags)) ]) "pr117239.c":18:7 285 {*adddi_1} (expr_list:REG_ARGS_SIZE (const_int 0 [0]) (nil))) ... (call_insn/i 19 18 21 2 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:DI ("foo") [flags 0x3] ) [0 foo S1 A8]) (const_int 0 [0]))) "pr117239.c":19:3 1476 {*call_value} (expr_list:REG_CALL_DECL (symbol_ref:DI ("foo") [flags 0x3] ) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil))) (nil)) (insn 21 19 26 2 (parallel [ (set (reg/f:DI 7 sp) (plus:DI (reg/f:DI 7 sp) (const_int -24 [0xffe8]))) (clobber (reg:CC 17 flags)) ]) "pr117239.c":19:3 discrim 1 285 {*adddi_1} (expr_list:REG_ARGS_SIZE (const_int 24 [0x18]) (nil))) (insn 26 21 24 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp) (const_int 16 [0x10])) [0 S8 A64]) (reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":19:3 discrim 1 95 {*movdi_internal} (nil)) i.e. movq%rdx, 16(%rsp) callbaz addq$24, %rsp ... callfoo subq$24, %rsp movq%rdx, 16(%rsp) Now, postreload uses cselib and cselib remembered that %rdx value has been stored into 16(%rsp). Both baz and foo are pure calls. If they weren't, when processing those CALL_INSNs cselib would invalidate all MEMs if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn) || !(RTL_CONST_OR_PURE_CALL_P (insn))) cselib_invalidate_mem (callmem); where callmem is (mem:BLK (scratch)). But they are pure, so instead the code just invalidates the argument slots from CALL_INSN_FUNCTION_USAGE. The calls actually clobber more than that, even const/pure calls clobber all memory below the stack pointer. And that is something that hasn't been invalidated. In this failing testcase, the call to baz is not a big deal, we don't have anything remembered in memory below %rsp at that call. But then we increment %rsp by 24, so the %rsp+16 is now 8 bytes below stack and do the call to foo. And that call now actually, not just in theory, clobbers the memory below the stack pointer (in particular overwrites it with the return value). But cselib does not invalidate. Then %rsp is decremented again (in preparation for another call, to bar) and cselib is processing store of %rdx (which IPA-RA says has not been modified by either baz or foo calls) to %rsp + 16, and it sees the memory already has that value, so the store is useless, let's remove it. But it is not, the call to foo has changed it, so it needs to be stored again. The following patch adds targetted invalidation of memory below stack pointer (or on SPARC memory below stack pointer + 2047 when stack bias is used, or on PA memory above stack pointer instead). It does so only in !ACCUMULATE_OUTGOING_ARGS or cfun->calls_alloca functions, because in other functions the stack pointer should be constant from the end of prologue till start of epilogue and so nothing should be stored within the function below the stack pointer. Now, memory below stack pointer is special, except for functions using alloca/VLAs I believe no addressable memory should be there, it should be purely outgoing function argument area, if we take address of some automatic variable, it should live all the time above the outgoing function argument area. So on top of just trying to flush memory below stack pointer (represented by %rsp - PTRDIFF_MAX with
[gcc r15-9731] c-c++-common/gomp/{attrs-, }metadirective-3.c: Fix expected result [PR118694]
https://gcc.gnu.org/g:d390c7e5bd03490485a0b036add096e2e8b811b9 commit r15-9731-gd390c7e5bd03490485a0b036add096e2e8b811b9 Author: Tobias Burnus Date: Mon May 26 19:50:40 2025 +0200 c-c++-common/gomp/{attrs-,}metadirective-3.c: Fix expected result [PR118694] With compilation for nvptx enabled, two issues showed up: (a) "error: 'target' construct with nested 'teams' construct contains directives outside of the 'teams' construct" See PR comment 9 why this is difficult to fix. Solution: Add dg-bogus and accept/expect the error for 'target offload_nvptx'. (b) The assumptions about the dump for 'target offload_nvptx' were wrong as the metadirective was already expanded to a OMP_NEXT_VARIANT construct such that no 'omp metadirective' was left in either case. Solution: Check that no 'omp metadirective' is left; additionally, expect either OMP_NEXT_VARIANT (when offload_nvptx is available) or no 'teams' directive at all (if not). gcc/testsuite/ChangeLog: PR middle-end/118694 * c-c++-common/gomp/attrs-metadirective-3.c: Change to never expect 'omp metadirective' in the dump. If !offload_nvptx, check that no 'teams' shows up in the dump; for offload_nvptx, expect OMP_NEXT_VARIANT and an error about directive between 'target' and 'teams'. * c-c++-common/gomp/metadirective-3.c: Likewise. (cherry picked from commit 5d6ed6d604ff949b650e48fa4eaed3ec8b6489c1) Diff: --- gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c | 7 --- gcc/testsuite/c-c++-common/gomp/metadirective-3.c | 7 --- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c b/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c index 31dd054922fc..803bf0ad1ebf 100644 --- a/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c +++ b/gcc/testsuite/c-c++-common/gomp/attrs-metadirective-3.c @@ -9,7 +9,7 @@ f (int x[], int y[], int z[]) { int i; - [[omp::sequence (directive (target map(to: x, y) map(from: z)), + [[omp::sequence (directive (target map(to: x, y) map(from: z)), /* { dg-bogus "'target' construct with nested 'teams' construct contains directives outside of the 'teams' construct" "PR118694" { xfail offload_nvptx } } */ directive (metadirective when (device={arch("nvptx")}: teams loop) default (parallel loop)))]] @@ -20,5 +20,6 @@ f (int x[], int y[], int z[]) /* If offload device "nvptx" isn't supported, the front end can eliminate that alternative and not produce a metadirective at all. Otherwise this won't be resolved until late. */ -/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" { target { ! offload_nvptx } } } } */ -/* { dg-final { scan-tree-dump "#pragma omp metadirective" "gimple" { target { offload_nvptx } } } } */ +/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" } } */ +/* { dg-final { scan-tree-dump-not " teams" "gimple" { target { ! offload_nvptx } } } } */ +/* { dg-final { scan-tree-dump "variant.\[0-9\]+ = \\\[omp_next_variant\\\] OMP_NEXT_VARIANT <0,\[\r\n \]+construct context = 14\[\r\n \]+1: device = \\{arch \\(.nvptx.\\)\\}\[\r\n \]+2: >;" "gimple" { target { offload_nvptx } } } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/metadirective-3.c b/gcc/testsuite/c-c++-common/gomp/metadirective-3.c index 0ac0d1d329d8..b6c1601f7b10 100644 --- a/gcc/testsuite/c-c++-common/gomp/metadirective-3.c +++ b/gcc/testsuite/c-c++-common/gomp/metadirective-3.c @@ -8,7 +8,7 @@ f (int x[], int y[], int z[]) { int i; - #pragma omp target map(to: x, y) map(from: z) + #pragma omp target map(to: x, y) map(from: z) /* { dg-bogus "'target' construct with nested 'teams' construct contains directives outside of the 'teams' construct" "PR118694" { xfail offload_nvptx } } */ #pragma omp metadirective \ when (device={arch("nvptx")}: teams loop) \ default (parallel loop) @@ -19,5 +19,6 @@ f (int x[], int y[], int z[]) /* If offload device "nvptx" isn't supported, the front end can eliminate that alternative and not produce a metadirective at all. Otherwise this won't be resolved until late. */ -/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" { target { ! offload_nvptx } } } } */ -/* { dg-final { scan-tree-dump "#pragma omp metadirective" "gimple" { target { offload_nvptx } } } } */ +/* { dg-final { scan-tree-dump-not "#pragma omp metadirective" "gimple" } } */ +/* { dg-final { scan-tree-dump-not " teams" "gimple" { target { ! offload_nvptx } } } } */ +/* { dg-final { scan-tree-dump "variant.\[0-9\]+ = \\\[omp_next_variant\\\] OMP_NEXT_VARIANT <0,\[\r\n \]+construct context = 14\[\r\n \]+1: device = \\{arch \\(.nvptx.\\)\\}\[\r\n \]+2: >;" "gimple" { target { offl
[gcc r13-9691] c++: Disable deprecated/unavailable diagnostics when creating thunks for methods with such attribute
https://gcc.gnu.org/g:17dcde03ec2fcc1856b9026f8479f57495c949ae commit r13-9691-g17dcde03ec2fcc1856b9026f8479f57495c949ae Author: Jakub Jelinek Date: Thu Sep 12 18:22:21 2024 +0200 c++: Disable deprecated/unavailable diagnostics when creating thunks for methods with such attributes [PR116636] On the following testcase, we emit false positive warnings/errors about using the deprecated or unavailable methods when creating thunks for them, even when nothing (in the testcase so far) actually used those. The following patch temporarily disables that diagnostics when creating the thunks. 2024-09-12 Jakub Jelinek PR c++/116636 * method.cc: Include decl.h. (use_thunk): Temporarily change deprecated_state to UNAVAILABLE_DEPRECATED_SUPPRESS. * g++.dg/warn/deprecated-19.C: New test. (cherry picked from commit 4026d89d623e322920b052f7ac0d940ef267dc0f) Diff: --- gcc/cp/method.cc | 6 ++ gcc/testsuite/g++.dg/warn/deprecated-19.C | 22 ++ 2 files changed, 28 insertions(+) diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index c9d9e3516f3b..0e701d64b130 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "target.h" #include "cp-tree.h" +#include "decl.h" #include "stringpool.h" #include "cgraph.h" #include "varasm.h" @@ -283,6 +284,11 @@ use_thunk (tree thunk_fndecl, bool emit_p) /* Thunks are always addressable; they only appear in vtables. */ TREE_ADDRESSABLE (thunk_fndecl) = 1; + /* Don't diagnose deprecated or unavailable functions just because they + have thunks emitted for them. */ + auto du = make_temp_override (deprecated_state, +UNAVAILABLE_DEPRECATED_SUPPRESS); + /* Figure out what function is being thunked to. It's referenced in this translation unit. */ TREE_ADDRESSABLE (function) = 1; diff --git a/gcc/testsuite/g++.dg/warn/deprecated-19.C b/gcc/testsuite/g++.dg/warn/deprecated-19.C new file mode 100644 index ..e49af4f74d0d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/deprecated-19.C @@ -0,0 +1,22 @@ +// PR c++/116636 +// { dg-do compile { target c++11 } } +// { dg-options "-pedantic -Wdeprecated" } + +struct A { + virtual int foo () = 0; +}; +struct B : virtual A { + [[deprecated]] int foo () { return 0; } // { dg-message "declared here" } +}; +struct C : virtual A { + [[gnu::unavailable]] int foo () { return 0; }// { dg-message "declared here" } +}; + +void +bar () +{ + B b; + b.foo ();// { dg-warning "'virtual int B::foo\\\(\\\)' is deprecated" } + C c; + c.foo ();// { dg-error "'virtual int C::foo\\\(\\\)' is unavailable" } +}
[gcc r14-11811] s390: Fix tf_to_fprx2
https://gcc.gnu.org/g:1dd54c5ad3930e27c4206ec3c08f4baecd9b4543 commit r14-11811-g1dd54c5ad3930e27c4206ec3c08f4baecd9b4543 Author: Stefan Schulze Frielinghaus Date: Wed May 14 09:22:00 2025 +0200 s390: Fix tf_to_fprx2 Insn tf_to_fprx2 moves a TF value into a floating-point register pair. For alternative 0, the input is a vector register, however, in the else case instruction ldr is emitted which expects floating-point register operands only. Thus, this works only for vector registers which overlap with floating-point registers. Replace ldr with vlr so that the remaining vector registers are dealt with, too. Emitting a vlr instead of a ldr is fine since the destination register %v0 is part of a floating-point register pair which means that the low half of %v0 is ignored in the end anyway and therefore may be clobbered. gcc/ChangeLog: * config/s390/vector.md: Fix tf_to_fprx2 by using vlr instead of ldr. (cherry picked from commit 8519b8ba9dd9567a5f90966351c1e758dbf511a4) Diff: --- gcc/config/s390/vector.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md index 35defb7043a4..a79f21b05c73 100644 --- a/gcc/config/s390/vector.md +++ b/gcc/config/s390/vector.md @@ -938,7 +938,7 @@ else { reg_pair += 2; // get rid of prefix %f - snprintf (buf, sizeof (buf), "ldr\t%%f0,%%f1;vpdi\tv%s,%%v1,v%s,5", reg_pair, reg_pair); + snprintf (buf, sizeof (buf), "vlr\t%%v0,%%v1;vpdi\tv%s,%%v1,v%s,5", reg_pair, reg_pair); output_asm_insn (buf, operands); return ""; }
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régressions vector_subscript*
https://gcc.gnu.org/g:57a48a2b589ccf9ec3457825cc487b15674e835e commit 57a48a2b589ccf9ec3457825cc487b15674e835e Author: Mikael Morin Date: Mon May 26 21:52:17 2025 +0200 Correction régressions vector_subscript* Diff: --- gcc/fortran/trans-array.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 11a203e474b8..27d8dda70573 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -2780,6 +2780,7 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript, gfc_add_block_to_block (&outer_loop->pre, &se.pre); gfc_add_block_to_block (&outer_loop->post, &se.post); info->descriptor = se.expr; + gfc_conv_array_lbound_spacing (&outer_loop->pre, ss, 0); break; case GFC_SS_INTRINSIC: @@ -4308,7 +4309,8 @@ gfc_conv_array_lbound_spacing (stmtblock_t * block, gfc_ss * ss, int dim) gfc_array_info *info; gcc_assert (ss->info->type == GFC_SS_SECTION - || ss->info->type == GFC_SS_COMPONENT); + || ss->info->type == GFC_SS_COMPONENT + || ss->info->type == GFC_SS_VECTOR); info = &ss->info->data.array; tree desc = info->descriptor;
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression assign_10
https://gcc.gnu.org/g:c9be2ad052f90cdc55f7a28f55f8f574fc17dc49 commit c9be2ad052f90cdc55f7a28f55f8f574fc17dc49 Author: Mikael Morin Date: Mon May 26 22:49:46 2025 +0200 Correction régression assign_10 Diff: --- gcc/fortran/trans-array.cc | 2 +- gcc/fortran/trans-descriptor.cc | 10 +- gcc/fortran/trans-descriptor.h | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 27d8dda70573..dc4c0399cb2f 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -7825,7 +7825,7 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) gfc_set_descriptor (&loop.pre, parm, desc, expr, loop.dimen, codim, ss, info, loop.from, loop.to, !se->data_not_needed, - subref_array_target); + subref_array_target, !se->direct_byref); desc = parm; } diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index e41809f0037a..600c1bd43a5a 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -2955,6 +2955,9 @@ gfc_set_temporary_descriptor (stmtblock_t *block, tree desc, tree class_src, tree this_lbound = shift_bounds ? gfc_index_zero_node : lbound[n]; set_descriptor_dimension (block, desc, n, this_lbound, ubound[n], spacing[n], &offset, nullptr); + if (TREE_CODE (spacing[n]) == INTEGER_CST + && GFC_TYPE_ARRAY_SPACING (TREE_TYPE (desc), n) == NULL_TREE) + GFC_TYPE_ARRAY_SPACING (TREE_TYPE (desc), n) = spacing[n]; } } @@ -3024,7 +3027,7 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree src, gfc_expr *src_expr, int rank, int corank, gfc_ss *ss, gfc_array_info *info, tree lowers[GFC_MAX_DIMENSIONS], tree uppers[GFC_MAX_DIMENSIONS], bool data_needed, - bool subref) + bool subref, bool update_spacing_in_type) { int ndim = info->ref ? info->ref->u.ar.dimen : rank; @@ -3138,6 +3141,11 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree src, gfc_expr *src_expr, offset = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (offset), offset, tmp); + if (update_spacing_in_type + && TREE_CODE (spacing) == INTEGER_CST + && GFC_TYPE_ARRAY_SPACING (TREE_TYPE (dest), dim) == NULL_TREE) + GFC_TYPE_ARRAY_SPACING (TREE_TYPE (dest), dim) = spacing; + /* Store the new spacing. */ gfc_conv_descriptor_spacing_set (block, dest, gfc_rank_cst[dim], spacing); } diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index e431aeb9a7a3..4c4c82d227ab 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -91,7 +91,7 @@ void gfc_set_temporary_descriptor (stmtblock_t *, tree, tree, tree, tree, void gfc_set_descriptor (stmtblock_t *, tree, tree, gfc_expr *, int, int, gfc_ss *, gfc_array_info *, tree [GFC_MAX_DIMENSIONS], -tree [GFC_MAX_DIMENSIONS], bool, bool); +tree [GFC_MAX_DIMENSIONS], bool, bool, bool); tree gfc_descr_init_count (tree, int, int, gfc_expr **, gfc_expr **, stmtblock_t *, stmtblock_t *, tree *, tree,
[gcc r13-9675] dwarf2out: Propagate dtprel into the .debug_addr table in resolve_addr_in_expr
https://gcc.gnu.org/g:95e204dbc28f479b6b4116e5efacacde6c81ad75 commit r13-9675-g95e204dbc28f479b6b4116e5efacacde6c81ad75 Author: Kyle Huey Date: Tue May 13 20:26:26 2025 -0700 dwarf2out: Propagate dtprel into the .debug_addr table in resolve_addr_in_expr For a debugger to display statically-allocated[0] TLS variables the compiler must communicate information[1] that can be used in conjunction with knowledge of the runtime enviroment[2] to calculate a location for the variable for each thread. That need gives rise to dw_loc_dtprel in dwarf2out, a flag tracking whether the location description is dtprel, or relative to the "dynamic thread pointer". Location descriptions in the .debug_info section for TLS variables need to be relocated by the static linker accordingly, and dw_loc_dtprel controls emission of the needed relocations. This is further complicated by -gsplit-dwarf. -gsplit-dwarf is designed to allow as much debugging information as possible to bypass the static linker to improve linking performance. One of the ways that is done is by introducing a layer of indirection for relocatable values[3]. That gives rise to addr_index_table which ultimately results in the .debug_addr section. While the code handling addr_index_table clearly contemplates the existence of dtprel entries[4] resolve_addr_in_expr does not, and the result is that when using -gsplit-dwarf the DWARF for TLS variables contains an address[5] rather than an offset, and debuggers can't work with that. This is visible on a trivial example. Compile ``` static __thread int tls_var; int main(void) { tls_var = 42; return 0; } ``` with -g and -g -gsplit-dwarf. Run the program under gdb. When examining the value of tls_var before and after the assignment, -g behaves as one would expect but -g -gsplit-dwarf does not. If the user is lucky and the miscalculated address is not mapped, gdb will print "Cannot access memory at address ...". If the user is unlucky and the miscalculated address is mapped, gdb will simply give the wrong value. You can further confirm that the issue is the address calculation by asking gdb for the address of tls_var and comparing that to what one would expect.[6] Thankfully this is trivial to fix by modifying resolve_addr_in_expr to propagate the dtprel character of the location where necessary. gdb begins working as expected and the diff in the generated assembly is clear. ``` .section.debug_addr,"",@progbits .long 0x14 .value 0x5 .byte 0x8 .byte 0 .Ldebug_addr0: - .quad tls_var + .long tls_var@dtpoff, 0 .quad .LFB0 ``` [0] Referring to e.g. __thread as statically-allocated vs. e.g. a dynamically-allocated pthread_key_create() call. [1] Generally an offset in a TLS block. [2] With glibc, provided by libthread_db.so. [3] Relocatable values are moved to a table in the .debug_addr section, those values in .debug_info are replaced with special values that look up indexes in that table, and then the static linker elsewhere assigns a single per-CU starting index in the .debug_addr section, allowing those special values to remain permanently fixed and the resulting data to be ignored by the linker. [4] ate_kind_rtx_dtprel exists, after all, and new_addr_loc_descr does produce it where appropriate. [5] e.g. an address in the .tbss/.tdata section. [6] e.g. on x86-64 by examining %fsbase and the offset in the assembly 2025-05-01 Kyle Huey * dwarf2out.cc (resolve_addr_in_expr): Propagate dtprel into the address table when appropriate. (cherry picked from commit 02e95abdde9742cecd7d1211e572549c1e56b8b1) Diff: --- gcc/dwarf2out.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index b1a846c55a3e..5d1f75c6d0f6 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -30797,7 +30797,8 @@ resolve_addr_in_expr (dw_attr_node *a, dw_loc_descr_ref loc) return false; remove_addr_table_entry (loc->dw_loc_oprnd1.val_entry); loc->dw_loc_oprnd1.val_entry - = add_addr_table_entry (rtl, ate_kind_rtx); + = add_addr_table_entry (rtl, loc->dtprel + ? ate_kind_rtx_dtprel : ate_kind_rtx); } break; case DW_OP_const4u:
[gcc r13-9676] middle-end/119706 - allow POLY_INT_CST as is_gimple_mem_ref_addr
https://gcc.gnu.org/g:fa2089e8dd1632e4597d61230e33375628368fc1 commit r13-9676-gfa2089e8dd1632e4597d61230e33375628368fc1 Author: Richard Biener Date: Thu Apr 10 13:30:42 2025 +0200 middle-end/119706 - allow POLY_INT_CST as is_gimple_mem_ref_addr We currently only INTEGER_CST, but not POLY_INT_CST, which leads to the situation that when the POLY_INT_CST is only indrectly present via a SSA def the IL is valid but when propagated it's not. That's unsustainable. PR middle-end/119706 * gimple-expr.cc (is_gimple_mem_ref_addr): Also allow POLY_INT_CST. (cherry picked from commit bf812c6ad83ec0b241bb3fecc7e68f883b6083df) Diff: --- gcc/gimple-expr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/gimple-expr.cc b/gcc/gimple-expr.cc index 83dc340a35df..5cd5dd5e48fe 100644 --- a/gcc/gimple-expr.cc +++ b/gcc/gimple-expr.cc @@ -877,7 +877,7 @@ bool is_gimple_mem_ref_addr (tree t) { return (is_gimple_reg (t) - || TREE_CODE (t) == INTEGER_CST + || poly_int_tree_p (t) || (TREE_CODE (t) == ADDR_EXPR && (CONSTANT_CLASS_P (TREE_OPERAND (t, 0)) || decl_address_invariant_p (TREE_OPERAND (t, 0);
[gcc r13-9677] aarch64: Add test case.
https://gcc.gnu.org/g:b73dffc733524f05634ab0321a6978fc798d1384 commit r13-9677-gb73dffc733524f05634ab0321a6978fc798d1384 Author: Jennifer Schmitz Date: Thu Apr 10 06:46:15 2025 -0700 aarch64: Add test case. This patch adds a test case to the testsuite for PR119706. The bug was already fixed by https://gcc.gnu.org/pipermail/gcc-patches/2025-April/680573.html. OK for mainline? Signed-off-by: Jennifer Schmitz gcc/testsuite/ PR tree-optimization/119706 * g++.target/aarch64/sve/pr119706.C: New test. (cherry picked from commit f6e6e6d9ba1d71fdd02a2c570d60217db6c5a31b) Diff: --- gcc/testsuite/g++.target/aarch64/sve/pr119706.C | 178 1 file changed, 178 insertions(+) diff --git a/gcc/testsuite/g++.target/aarch64/sve/pr119706.C b/gcc/testsuite/g++.target/aarch64/sve/pr119706.C new file mode 100644 index ..40fefe5f4fb2 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve/pr119706.C @@ -0,0 +1,178 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mcpu=neoverse-v2 --param=aarch64-autovec-preference=sve-only -w" } */ + +namespace a { +typedef long unsigned b; +typedef int c; +template struct e { using f = d; }; +template using h = typename e::f; +template class> struct i { + using f = aa; +}; +template class j> using k = i; +template class j> +using l = typename k::f; +} // namespace a +inline void *operator new(a::b, void *ab) { return ab; } +namespace a { +template class ac { +public: + typedef b m; + template void ae(ad *ab, n... w) { +new (ab) ad(w...); + } +}; +template using x = ac; +template class af : public x { +public: + typedef d o; + template struct ag { typedef af ah; }; +}; +struct ai {}; +struct aj : ai {}; +struct ak : aj {}; +template struct al; +template struct al { + typedef ak an; + typedef c ao; + typedef d ap; +}; +template typename aq ::an ar(aq) { return typename aq ::an(); } +template typename as ::ao at(as au, as av, ak) { return av - au; } +template typename aw ::ao ax(aw au, aw av) { + return at(au, av, ar(au)); +} +template struct ay { typedef c ao; }; +} // namespace a +namespace az { +template class ba { + am bb; + typedef a::al bc; + +public: + typedef typename bc::an an; + typedef typename bc::ao ao; + typedef typename bc::ap ap; + ba(am bd) : bb(bd) {} + ap operator*() { return *bb; } + ba operator++() { +++bb; +return *this; + } + am base() { return bb; } +}; +template +bool operator!=(ba bh, ba p) { + return bh.base() != p.base(); +} +template +auto operator-(ba bh, ba p) { + return bh.base() - p.base(); +} +} // namespace az +namespace a { +struct bi { + template struct bj { +using f = typename d::ag::ah; + }; + template using bk = b; + template static constexpr bool bl = false; + template static constexpr bool bm = bl<>; + template static constexpr bool bn = bm; +}; +template using bp = typename bi::bj::f; +template struct bq : bi { + typedef typename bo::o o; + using br = l; + template struct bt { using f = typename ay::ao; }; + template struct bv { using f = typename bu::m; }; + using ao = typename bt::f; + using m = typename bv::f; + template using bw = bp; + static br allocate(bo, m); + template + static h> ae(bo ci, d ab, n... w) { +ci.ae(ab, w...); + } +}; +template struct bx { + static bool by(d &bz) try { d(bz.begin(), bz.ca(), bz.cb()); } catch (...) { + } +}; +} // namespace a +namespace az { +template struct cc : a::bq { + typedef a::bq q; + template struct ag { typedef typename q::bw ah; }; +}; +} // namespace az +enum cd {}; +using ce = double; +namespace a { +template +cg cj(aw au, cf av, cg ck, ch cl) { + typedef az::cc cx; + for (; au != av; ++au, ++ck) +cx::ae(cl, ck, *au); +} +template struct cm { + typedef typename az::cc::ag::ah cn; + typedef typename az::cc::br br; + struct co { +br db; +br cp; + }; + struct cq : cn, co { +cq(cn) {} + } typedef cr; + cn cs(); + cr cb() noexcept; + cm(cr ci) : ct(ci) {} + cq ct; + br cu(b cv) { +typedef az::cc cw; +return cv ? cw::allocate(ct, cv) : c(); + } +}; +template > class cy : cm { + typedef cm cz; + +public: + typedef typename cz::br br; + typedef az::ba da; + typedef b m; + typedef bo cr; + cz::cs; + template cy(aw au, aw av, cr ci) : cz(ci) { +dg(au, av, ar(au)); + } + cz::cb; + da begin() { return this->ct.db; } + da ca() { return this->ct.cp; } + void r() { s(); } + void clear() { t(this->ct.db); } + template void dg(cg au, cg av, ai) { y(au, av, ax(au, av)); } + template void y(am au, cf av, m cv) { +br z = this->cu(dc(cv, cs())); +cj(au, av, z, cs()); + } + bool s(); + m dc(m cv, cr) { return cv; } + void t(br dd) { +if (this->ct.cp - dd) + this->ct.cp = dd; + } +}; +template bool cy::s() { bx::by(*this); } +namespace basic { +class u { + using de = ce; + void v(cd, b); + cy df; +}; +void u::v(cd, b)
[gcc r13-9678] [14] Use --param=aarch64-autovec-preference=2 instead of =sve-only
https://gcc.gnu.org/g:d02be6073d902925510736855e7f044eb8755aa4 commit r13-9678-gd02be6073d902925510736855e7f044eb8755aa4 Author: Richard Biener Date: Tue Apr 22 16:40:42 2025 +0200 [14] Use --param=aarch64-autovec-preference=2 instead of =sve-only This updates the backported test. PR tree-optimization/119706 * g++.target/aarch64/sve/pr119706.C: Adjust --param aarch64-autovec-preference. (cherry picked from commit d7b5fe3400cf15150ae18d522859cafcdd6a9315) Diff: --- gcc/testsuite/g++.target/aarch64/sve/pr119706.C | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/g++.target/aarch64/sve/pr119706.C b/gcc/testsuite/g++.target/aarch64/sve/pr119706.C index 40fefe5f4fb2..b185c12496f0 100644 --- a/gcc/testsuite/g++.target/aarch64/sve/pr119706.C +++ b/gcc/testsuite/g++.target/aarch64/sve/pr119706.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -mcpu=neoverse-v2 --param=aarch64-autovec-preference=sve-only -w" } */ +/* { dg-options "-O3 -mcpu=neoverse-v2 --param=aarch64-autovec-preference=2 -w" } */ namespace a { typedef long unsigned b; @@ -175,4 +175,4 @@ void u::v(cd, b) { df.r(); } } // namespace basic -} // namespace a \ No newline at end of file +} // namespace a
[gcc r13-9680] tree-optimization/117979 - failed irreducible loop update from DCE
https://gcc.gnu.org/g:6e6b9bbe9aadbfec4130c442ace9cabab50400c2 commit r13-9680-g6e6b9bbe9aadbfec4130c442ace9cabab50400c2 Author: Richard Biener Date: Wed Jan 8 09:25:52 2025 +0100 tree-optimization/117979 - failed irreducible loop update from DCE When CD-DCE creates forwarders to reduce false control dependences it fails to update the irreducible state of edge and the forwarder block in case the fowarder groups both normal (entry) and edges from an irreducible region (necessarily backedges). This is because when we split the first edge, if that's a normal edge, the forwarder and its edge to the original block will not be marked as part of the irreducible region but when we then redirect an edge from within the region it becomes so. The following fixes this up. Note I think creating a forwarder that includes backedges is likely not going to help, but at this stage I don't want to change the CFG going into DCE. For regular loops we'll have a single entry and a single backedge by means of loop init and will never create a forwarder - so this is solely happening for irreducible regions where it's harder to prove that such forwarder doesn't help. PR tree-optimization/117979 * tree-ssa-dce.cc (make_forwarders_with_degenerate_phis): Properly update the irreducible region state. * gcc.dg/torture/pr117979.c: New testcase. (cherry picked from commit eca04660a2c9546c8ecefc5288395eb8a9fdc168) Diff: --- gcc/testsuite/gcc.dg/torture/pr117979.c | 21 + gcc/tree-ssa-dce.cc | 10 ++ 2 files changed, 31 insertions(+) diff --git a/gcc/testsuite/gcc.dg/torture/pr117979.c b/gcc/testsuite/gcc.dg/torture/pr117979.c new file mode 100644 index ..646cd70776b6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr117979.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +int a, b; +void foo (void); +int __attribute__((returns_twice)) bar (int); + +int __attribute__((const)) +baz (int f) +{ + if (f) +{ + l:; + for (f = 0; f < 6; ++f) +if (bar (b)) + goto l; + for (;; a--) +; +} + foo (); + return 0; +} diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc index 0ae998f86f98..8de1a276288d 100644 --- a/gcc/tree-ssa-dce.cc +++ b/gcc/tree-ssa-dce.cc @@ -1857,12 +1857,22 @@ make_forwarders_with_degenerate_phis (function *fn) } free_dominance_info (fn, CDI_DOMINATORS); basic_block forwarder = split_edge (args[start].first); + bool irr = false; for (unsigned j = start + 1; j < i; ++j) { edge e = args[j].first; + if (e->flags & EDGE_IRREDUCIBLE_LOOP) + irr = true; redirect_edge_and_branch_force (e, forwarder); redirect_edge_var_map_clear (e); } + if (irr) + { + forwarder->flags |= BB_IRREDUCIBLE_LOOP; + single_succ_edge (forwarder)->flags + |= EDGE_IRREDUCIBLE_LOOP; + } + if (vphi) { tree def = copy_ssa_name (vphi_args[0]);
[gcc r13-9684] tree-optimization/119534 - reject bogus emulated vectorized gather
https://gcc.gnu.org/g:cdc47838cba79380bb5caa8f3934aabf2b44a7d5 commit r13-9684-gcdc47838cba79380bb5caa8f3934aabf2b44a7d5 Author: Richard Biener Date: Tue Apr 1 14:13:03 2025 +0200 tree-optimization/119534 - reject bogus emulated vectorized gather The following makes sure to reject the attempts to emulate a vector gather when the discovered index vector type is a vector mask. PR tree-optimization/119534 * tree-vect-stmts.cc (get_load_store_type): Reject VECTOR_BOOLEAN_TYPE_P offset vector type for emulated gathers. * gcc.dg/vect/pr119534.c: New testcase. (cherry picked from commit d0cc14c62ad7403afcab3c2e38851d3ab179352f) Diff: --- gcc/testsuite/gcc.dg/vect/pr119534.c | 11 +++ gcc/tree-vect-stmts.cc | 1 + 2 files changed, 12 insertions(+) diff --git a/gcc/testsuite/gcc.dg/vect/pr119534.c b/gcc/testsuite/gcc.dg/vect/pr119534.c new file mode 100644 index ..0b4130b7cfaa --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr119534.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mavx512bw" { target { x86_64-*-* i?86-*-* } } } */ + +void f(int w, int *out, double *d) +{ + for (int j = 0; j < w; j++) +{ + const int i = (j >= w / 2); + out[j] += d[i]; +} +} diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 98cf3f2bfc07..52face23c10c 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -2513,6 +2513,7 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, else if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant () || !TYPE_VECTOR_SUBPARTS (gs_info->offset_vectype).is_constant () + || VECTOR_BOOLEAN_TYPE_P (gs_info->offset_vectype) || !constant_multiple_p (TYPE_VECTOR_SUBPARTS (gs_info->offset_vectype), TYPE_VECTOR_SUBPARTS (vectype)))
[gcc r13-9683] tree-optimization/98845 - ICE with tail-merging and DCE/DSE disabled
https://gcc.gnu.org/g:9e7c7e567704bd12d65b01246a655d8628bb521d commit r13-9683-g9e7c7e567704bd12d65b01246a655d8628bb521d Author: Richard Biener Date: Mon Feb 17 15:53:11 2025 +0100 tree-optimization/98845 - ICE with tail-merging and DCE/DSE disabled The following shows that tail-merging will make dead SSA defs live in paths where it wasn't before, possibly introducing UB or as in this case, uses of abnormals that eventually fail coalescing later. The fix is to register such defs for stmt comparison. PR tree-optimization/98845 * tree-ssa-tail-merge.cc (stmt_local_def): Consider a def with no uses not local. * gcc.dg/pr98845.c: New testcase. * gcc.dg/pr81192.c: Adjust. (cherry picked from commit 6b8a8c9fd68c5dabaec5ddbc25efeade44f37a14) Diff: --- gcc/testsuite/gcc.dg/pr81192.c | 68 -- gcc/testsuite/gcc.dg/pr98845.c | 33 gcc/tree-ssa-tail-merge.cc | 8 + 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr81192.c b/gcc/testsuite/gcc.dg/pr81192.c index 6cab60565585..87a7a7a19c80 100644 --- a/gcc/testsuite/gcc.dg/pr81192.c +++ b/gcc/testsuite/gcc.dg/pr81192.c @@ -1,5 +1,62 @@ -/* { dg-options "-Os -fdump-tree-pre-details -fdisable-tree-evrp -fno-tree-dse" } */ +/* { dg-options "-Os -fgimple -fdump-tree-pre-details -fdisable-tree-evrp -fno-tree-dse" } */ +#if __SIZEOF_INT__ == 2 +#define unsigned __UINT32_TYPE__ +#define int __INT32_TYPE__ +#endif + +unsigned a; +int b, c; + +void __GIMPLE(ssa, startwith("pre")) fn2 () +{ + int b_lsm6; + int j; + int c0_1; + int iftmp2_8; + + __BB(2): + a = _Literal (unsigned)30; + c0_1 = c; + b_lsm6_9 = b; + goto __BB7; + + __BB(3): + if (j_6(D) != _Literal (int)2147483647) +goto __BB4; + else +goto __BB9; + + __BB(4): + iftmp2_8 = j_6(D) + _Literal (int)1; + goto __BB5; + + __BB(9): + iftmp2_8 = j_6(D) + _Literal (int)1; + goto __BB5; + + __BB(5): + b_lsm6_10 = _Literal (int)2147483647; + goto __BB6; + + __BB(6): + if (c0_1 != _Literal (int) 0) +goto __BB3; + else +goto __BB8; + + __BB(8): + goto __BB7; + + __BB(7): + goto __BB6; + +} + +#if 0 +/* This used to be a C based testcase but ccp3 would now would remove + the setting of iftmp2_8 (in the above gimple) which would cause PRE + not to test what PRE was doing incorrectly. The original code is below. */ /* Disable tree-evrp because the new version of evrp sees : if (j_8(D) != 2147483647) @@ -18,14 +75,6 @@ which causes the situation being tested to dissapear before we get to PRE. */ /* Likewise disable DSE which also elides the tail merging "opportunity". */ -#if __SIZEOF_INT__ == 2 -#define unsigned __UINT32_TYPE__ -#define int __INT32_TYPE__ -#endif - -unsigned a; -int b, c; - static int fn1 (int p1, int p2) { @@ -41,5 +90,6 @@ fn2 (void) for (; c; b = fn1 (j, 1)) ; } +#endif /* { dg-final { scan-tree-dump-times "(?n)find_duplicates: duplicate of " 1 "pre" } } */ diff --git a/gcc/testsuite/gcc.dg/pr98845.c b/gcc/testsuite/gcc.dg/pr98845.c new file mode 100644 index ..074c979678f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr98845.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-dce -fno-tree-dse" } */ + +int n; + +__attribute__ ((returns_twice)) void +foo (void); + +void +bar (void); + +void +quux (int x) +{ + if (x) +++x; + else +{ + if (n) +{ + x = 1; + foo (); +} + else +bar (); + + if (n) +{ + ++x; + ++n; +} +} +} diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc index 33acb649d5d6..a94108da9f48 100644 --- a/gcc/tree-ssa-tail-merge.cc +++ b/gcc/tree-ssa-tail-merge.cc @@ -336,10 +336,13 @@ stmt_local_def (gimple *stmt) def_bb = gimple_bb (stmt); + bool any_use = false; FOR_EACH_IMM_USE_FAST (use_p, iter, val) { if (is_gimple_debug (USE_STMT (use_p))) continue; + + any_use = true; bb = gimple_bb (USE_STMT (use_p)); if (bb == def_bb) continue; @@ -351,6 +354,11 @@ stmt_local_def (gimple *stmt) return false; } + /* When there is no use avoid making the stmt live on other paths. + This can happen with DCE disabled or not done as seen in PR98845. */ + if (!any_use) +return false; + return true; }
[gcc r13-9682] middle-end/119119 - re-gimplification of empty CTOR assignments
https://gcc.gnu.org/g:5a855127604e4df40afb25326a449b066c4a3527 commit r13-9682-g5a855127604e4df40afb25326a449b066c4a3527 Author: Richard Biener Date: Thu Mar 6 09:08:07 2025 +0100 middle-end/119119 - re-gimplification of empty CTOR assignments The following testcase runs into a re-gimplification issue during inlining when processing MEM[(struct e *)this_2(D)].a = {}; where re-gimplification does not handle assignments in the same way than the gimplifier but instead relies on rhs_predicate_for and gimplifying the RHS standalone. This fails to handle special-casing of CTORs. The is_gimple_mem_rhs_or_call predicate already handles clobbers but not empty CTORs so we end up in the fallback code trying to force the CTOR into a separate stmt using a temporary - but as we have a non-copyable type here that ICEs. The following generalizes empty CTORs in is_gimple_mem_rhs_or_call since those need no additional re-gimplification. PR middle-end/119119 * gimplify.cc (is_gimple_mem_rhs_or_call): All empty CTORs are OK when not a register type. * g++.dg/torture/pr11911.C: New testcase. (cherry picked from commit 3bd61c1dfaa2d7153eb4be82f423533ea937d0f9) Diff: --- gcc/gimplify.cc| 2 +- gcc/testsuite/g++.dg/torture/pr11911.C | 21 + 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 9c22139bd990..99e30a09f238 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -552,7 +552,7 @@ is_gimple_mem_rhs_or_call (tree t) else return (is_gimple_val (t) || is_gimple_lvalue (t) - || TREE_CLOBBER_P (t) + || (TREE_CODE (t) == CONSTRUCTOR && CONSTRUCTOR_NELTS (t) == 0) || TREE_CODE (t) == CALL_EXPR); } diff --git a/gcc/testsuite/g++.dg/torture/pr11911.C b/gcc/testsuite/g++.dg/torture/pr11911.C new file mode 100644 index ..7dc836ff9b53 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr11911.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// { dg-require-effective-target c++17 } + +struct b { + int a; +}; +struct c { + b d{}; + c() = default; + c(c &) = delete; +}; +struct e { + c a{}; + e() {} +}; +inline e f() { return {}; } +struct g { + e cx; + g() : cx{f()} {} +}; +void h() { g i; }
[gcc r13-9685] Fix ICE with -fdump-tree-moref
https://gcc.gnu.org/g:1067dd74239aa3efd3489cf8c6216fb9787031ca commit r13-9685-g1067dd74239aa3efd3489cf8c6216fb9787031ca Author: Jan Hubicka Date: Mon Jul 29 10:48:34 2024 +0200 Fix ICE with -fdump-tree-moref gcc/ChangeLog: PR ipa/116055 * ipa-modref.cc (analyze_function): Do not ICE when flags regress. (cherry picked from commit 98baaa17561ca299eefc98f469f4326e551604c9) Diff: --- gcc/ipa-modref.cc | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc index d633c8331956..0fa381488e7e 100644 --- a/gcc/ipa-modref.cc +++ b/gcc/ipa-modref.cc @@ -3295,7 +3295,8 @@ analyze_function (bool ipa) fprintf (dump_file, " Flags for param %i improved:", (int)i); else - gcc_unreachable (); + fprintf (dump_file, " Flags for param %i changed:", +(int)i); dump_eaf_flags (dump_file, old_flags, false); fprintf (dump_file, " -> "); dump_eaf_flags (dump_file, new_flags, true); @@ -3311,7 +3312,7 @@ analyze_function (bool ipa) || (summary->retslot_flags & EAF_UNUSED)) fprintf (dump_file, " Flags for retslot improved:"); else - gcc_unreachable (); + fprintf (dump_file, " Flags for retslot changed:"); dump_eaf_flags (dump_file, past_retslot_flags, false); fprintf (dump_file, " -> "); dump_eaf_flags (dump_file, summary->retslot_flags, true); @@ -3326,7 +3327,7 @@ analyze_function (bool ipa) || (summary->static_chain_flags & EAF_UNUSED)) fprintf (dump_file, " Flags for static chain improved:"); else - gcc_unreachable (); + fprintf (dump_file, " Flags for static chain changed:"); dump_eaf_flags (dump_file, past_static_chain_flags, false); fprintf (dump_file, " -> "); dump_eaf_flags (dump_file, summary->static_chain_flags, true);
[gcc r13-9686] PR tree-optimization/113673: Avoid load merging when potentially trapping.
https://gcc.gnu.org/g:d034c8d5c31811b0c12a4c1ffad89f8f8b086053 commit r13-9686-gd034c8d5c31811b0c12a4c1ffad89f8f8b086053 Author: Roger Sayle Date: Mon Jun 24 15:34:03 2024 +0100 PR tree-optimization/113673: Avoid load merging when potentially trapping. This patch fixes PR tree-optimization/113673, a P2 ice-on-valid regression caused by load merging of (ptr[0]<<8)+ptr[1] when -ftrapv has been specified. When the operator is | or ^ this is safe, but for addition of signed integer types, a trap may be generated/required, so merging this idiom into a single non-trapping instruction is inappropriate, confusing the compiler by transforming a basic block with an exception edge into one without. This revision implements Richard Biener's feedback to add an early check for stmt_can_throw_internal (cfun, stmt) to prevent transforming in the presence of any statement that could trap, not just overflow on addition. The one other tweak included in this patch is to mark the local function find_bswap_or_nop_load as static ensuring that it isn't called from outside this file, and guaranteeing that it is dominated by stmt_can_throw_internal checking. 2024-06-24 Roger Sayle Richard Biener gcc/ChangeLog PR tree-optimization/113673 * gimple-ssa-store-merging.cc (find_bswap_or_nop_load): Make static. (find_bswap_or_nop_1): Avoid transformations (load merging) when stmt_can_throw_internal indicates that a statement can trap. gcc/testsuite/ChangeLog PR tree-optimization/113673 * g++.dg/pr113673.C: New test case. (cherry picked from commit d8b05aef77443e1d3d8f3f5d2c56ac49a503fee3) Diff: --- gcc/gimple-ssa-store-merging.cc | 6 -- gcc/testsuite/g++.dg/pr113673.C | 14 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc index 4898f48ec523..decccef25dae 100644 --- a/gcc/gimple-ssa-store-merging.cc +++ b/gcc/gimple-ssa-store-merging.cc @@ -363,7 +363,7 @@ init_symbolic_number (struct symbolic_number *n, tree src) the answer. If so, REF is that memory source and the base of the memory area accessed and the offset of the access from that base are recorded in N. */ -bool +static bool find_bswap_or_nop_load (gimple *stmt, tree ref, struct symbolic_number *n) { /* Leaf node is an array or component ref. Memorize its base and @@ -610,7 +610,9 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit) gimple *rhs1_stmt, *rhs2_stmt, *source_stmt1; enum gimple_rhs_class rhs_class; - if (!limit || !is_gimple_assign (stmt)) + if (!limit + || !is_gimple_assign (stmt) + || stmt_can_throw_internal (cfun, stmt)) return NULL; rhs1 = gimple_assign_rhs1 (stmt); diff --git a/gcc/testsuite/g++.dg/pr113673.C b/gcc/testsuite/g++.dg/pr113673.C new file mode 100644 index ..11489777f5b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr113673.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fnon-call-exceptions -ftrapv" } */ + +struct s { ~s(); }; +void +h (unsigned char *data, int c) +{ + s a1; + while (c) +{ + int m = *data++ << 8; + m += *data++; +} +}
[gcc r14-11808] cselib: For CALL_INSNs to const/pure fns invalidate memory below sp [PR117239]
https://gcc.gnu.org/g:cfd7c674139097d12546d034f7869e272457aa56 commit r14-11808-gcfd7c674139097d12546d034f7869e272457aa56 Author: Jakub Jelinek Date: Wed Feb 5 13:16:17 2025 +0100 cselib: For CALL_INSNs to const/pure fns invalidate memory below sp [PR117239] The following testcase is miscompiled on x86_64 during postreload. After reload (with IPA-RA figuring out the calls don't modify any registers but %rax for return value) postreload sees (insn 14 12 15 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp) (const_int 16 [0x10])) [0 S8 A64]) (reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":18:7 95 {*movdi_internal} (nil)) (call_insn/i 15 14 16 2 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:DI ("baz") [flags 0x3] ) [0 baz S1 A8]) (const_int 24 [0x18]))) "pr117239.c":18:7 1476 {*call_value} (expr_list:REG_CALL_DECL (symbol_ref:DI ("baz") [flags 0x3] ) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil))) (nil)) (insn 16 15 18 2 (parallel [ (set (reg/f:DI 7 sp) (plus:DI (reg/f:DI 7 sp) (const_int 24 [0x18]))) (clobber (reg:CC 17 flags)) ]) "pr117239.c":18:7 285 {*adddi_1} (expr_list:REG_ARGS_SIZE (const_int 0 [0]) (nil))) ... (call_insn/i 19 18 21 2 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:DI ("foo") [flags 0x3] ) [0 foo S1 A8]) (const_int 0 [0]))) "pr117239.c":19:3 1476 {*call_value} (expr_list:REG_CALL_DECL (symbol_ref:DI ("foo") [flags 0x3] ) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil))) (nil)) (insn 21 19 26 2 (parallel [ (set (reg/f:DI 7 sp) (plus:DI (reg/f:DI 7 sp) (const_int -24 [0xffe8]))) (clobber (reg:CC 17 flags)) ]) "pr117239.c":19:3 discrim 1 285 {*adddi_1} (expr_list:REG_ARGS_SIZE (const_int 24 [0x18]) (nil))) (insn 26 21 24 2 (set (mem:DI (plus:DI (reg/f:DI 7 sp) (const_int 16 [0x10])) [0 S8 A64]) (reg:DI 1 dx [orig:105 q+16 ] [105])) "pr117239.c":19:3 discrim 1 95 {*movdi_internal} (nil)) i.e. movq%rdx, 16(%rsp) callbaz addq$24, %rsp ... callfoo subq$24, %rsp movq%rdx, 16(%rsp) Now, postreload uses cselib and cselib remembered that %rdx value has been stored into 16(%rsp). Both baz and foo are pure calls. If they weren't, when processing those CALL_INSNs cselib would invalidate all MEMs if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn) || !(RTL_CONST_OR_PURE_CALL_P (insn))) cselib_invalidate_mem (callmem); where callmem is (mem:BLK (scratch)). But they are pure, so instead the code just invalidates the argument slots from CALL_INSN_FUNCTION_USAGE. The calls actually clobber more than that, even const/pure calls clobber all memory below the stack pointer. And that is something that hasn't been invalidated. In this failing testcase, the call to baz is not a big deal, we don't have anything remembered in memory below %rsp at that call. But then we increment %rsp by 24, so the %rsp+16 is now 8 bytes below stack and do the call to foo. And that call now actually, not just in theory, clobbers the memory below the stack pointer (in particular overwrites it with the return value). But cselib does not invalidate. Then %rsp is decremented again (in preparation for another call, to bar) and cselib is processing store of %rdx (which IPA-RA says has not been modified by either baz or foo calls) to %rsp + 16, and it sees the memory already has that value, so the store is useless, let's remove it. But it is not, the call to foo has changed it, so it needs to be stored again. The following patch adds targetted invalidation of memory below stack pointer (or on SPARC memory below stack pointer + 2047 when stack bias is used, or on PA memory above stack pointer instead). It does so only in !ACCUMULATE_OUTGOING_ARGS or cfun->calls_alloca functions, because in other functions the stack pointer should be constant from the end of prologue till start of epilogue and so nothing should be stored within the function below the stack pointer. Now, memory below stack pointer is special, except for functions using alloca/VLAs I believe no addressable memory should be there, it should be purely outgoing function argument area, if we take address of some automatic variable, it should live all the time above the outgoing function argument area. So on top of just trying to flush memory below stack pointer (represented by %rsp - PTRDIFF_MAX wit
[gcc r13-9679] tree-optimization/119778 - properly mark abnormal edge sources during inlining
https://gcc.gnu.org/g:b98de795c7f57ad15155ed1223c25c094ff27d16 commit r13-9679-gb98de795c7f57ad15155ed1223c25c094ff27d16 Author: Richard Biener Date: Mon Apr 14 11:42:18 2025 +0200 tree-optimization/119778 - properly mark abnormal edge sources during inlining When inlining a call that abnormally transfers control-flow we make all inlined calls that can possibly transfer abnormal control-flow do so as well. But we failed to mark the calls as altering control-flow. This results in inconsistent behavior later and possibly wrong-code (we'd eventually prune those edges). PR tree-optimization/119778 * tree-inline.cc (copy_edges_for_bb): Mark calls that are source of abnormal edges as altering control-flow. * g++.dg/torture/pr119778.C: New testcase. (cherry picked from commit a48f934211434cac1be951c207ee76e4b4340fac) Diff: --- gcc/testsuite/g++.dg/torture/pr119778.C | 20 gcc/tree-inline.cc | 7 +-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/g++.dg/torture/pr119778.C b/gcc/testsuite/g++.dg/torture/pr119778.C new file mode 100644 index ..494805619282 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr119778.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-additional-options "-Wall" } + +struct jmp_buf { long l[16]; }; +extern "C" int setjmp (jmp_buf *); +struct S { + void foo () { bar (); } + virtual char bar () { return 0; } +}; +void baz (); +jmp_buf *a; + +void +qux (bool x, S *y) +{ + if (x) +setjmp (a); + y->foo (); + baz (); +} diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index 73d5a9fadef3..c17b3432d1b0 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -2679,8 +2679,11 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den, && gimple_call_arg (copy_stmt, 0) == boolean_true_node) nonlocal_goto = false; else - make_single_succ_edge (copy_stmt_bb, abnormal_goto_dest, - EDGE_ABNORMAL); + { + make_single_succ_edge (copy_stmt_bb, abnormal_goto_dest, +EDGE_ABNORMAL); + gimple_call_set_ctrl_altering (copy_stmt, true); + } } if ((can_throw || nonlocal_goto)
[gcc r13-9681] tree-optimization/119057 - bogus double reduction detection
https://gcc.gnu.org/g:876083c5e7a8863ce87d8da9e3a43927aee7e02b commit r13-9681-g876083c5e7a8863ce87d8da9e3a43927aee7e02b Author: Richard Biener Date: Mon Mar 3 13:21:53 2025 +0100 tree-optimization/119057 - bogus double reduction detection We are detecting a cycle as double reduction where the inner loop cycle has extra out-of-loop uses. This clashes at least with assumptions from the SLP discovery code which says the cycle isn't reachable from another SLP instance. It also was not intended to support this case, in fact with GCC 14 we seem to generate wrong code here. PR tree-optimization/119057 * tree-vect-loop.cc (check_reduction_path): Add argument specifying whether we're analyzing the inner loop of a double reduction. Do not allow extra uses outside of the double reduction cycle in this case. (vect_is_simple_reduction): Adjust. * gcc.dg/vect/pr119057.c: New testcase. (cherry picked from commit 758de6263dfc7ba8701965fa468691ac23cb7eb5) Diff: --- gcc/testsuite/gcc.dg/vect/pr119057.c | 19 +++ gcc/tree-vect-loop.cc| 12 +++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/pr119057.c b/gcc/testsuite/gcc.dg/vect/pr119057.c new file mode 100644 index ..582bb8ff86c3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr119057.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fno-tree-vrp -fno-tree-forwprop" } */ + +int a, b, c, d; +unsigned e; +static void f(void) +{ + unsigned h; + for (d = 0; d < 2; d++) +b |= e; + h = b; + c |= h; +} +int main() +{ + for (; a; a++) +f(); + return 0; +} diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 7a319e7f98ef..9672dc7f8a35 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -3552,7 +3552,8 @@ needs_fold_left_reduction_p (tree type, code_helper code) static bool check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi, tree loop_arg, code_helper *code, - vec > &path) + vec > &path, + bool inner_loop_of_double_reduc) { auto_bitmap visited; tree lookfor = PHI_RESULT (phi); @@ -3682,7 +3683,8 @@ pop: break; } /* Check there's only a single stmt the op is used on. For the -not value-changing tail and the last stmt allow out-of-loop uses. +not value-changing tail and the last stmt allow out-of-loop uses, +but not when this is the inner loop of a double reduction. ??? We could relax this and handle arbitrary live stmts by forcing a scalar epilogue for example. */ imm_use_iterator imm_iter; @@ -3691,7 +3693,7 @@ pop: unsigned cnt = 0; FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op.ops[opi]) if (!is_gimple_debug (op_use_stmt) - && (*code != ERROR_MARK + && ((*code != ERROR_MARK || inner_loop_of_double_reduc) || flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) cnt++; @@ -3710,7 +3712,7 @@ check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi, { auto_vec > path; code_helper code_; - return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path) + return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path, false) && code_ == code); } @@ -3914,7 +3916,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info, auto_vec > path; code_helper code; if (check_reduction_path (vect_location, loop, phi, latch_def, &code, - path)) + path, inner_loop_of_double_reduc)) { STMT_VINFO_REDUC_CODE (phi_info) = code; if (code == COND_EXPR && !nested_in_vect_loop)
[gcc r16-878] libstdc++: Implement C++26 std::indirect [PR119152]
https://gcc.gnu.org/g:caf804b1795575d7714c62dd45b649831598055e commit r16-878-gcaf804b1795575d7714c62dd45b649831598055e Author: Jonathan Wakely Date: Thu Mar 21 23:07:56 2024 + libstdc++: Implement C++26 std::indirect [PR119152] This patch implements C++26 std::indirect as specified in P3019 with amendment to move assignment from LWG 4251. PR libstdc++/119152 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added indirect.h file. * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/bits/indirect.h: New file. * include/bits/version.def (indirect): Define. * include/bits/version.h: Regenerate. * include/std/memory: Include new header. * testsuite/std/memory/indirect/copy.cc * testsuite/std/memory/indirect/copy_alloc.cc * testsuite/std/memory/indirect/ctor.cc * testsuite/std/memory/indirect/incomplete.cc * testsuite/std/memory/indirect/invalid_neg.cc * testsuite/std/memory/indirect/move.cc * testsuite/std/memory/indirect/move_alloc.cc * testsuite/std/memory/indirect/relops.cc Co-authored-by: Tomasz Kamiński Signed-off-by: Tomasz Kamiński Diff: --- libstdc++-v3/doc/doxygen/stdheader.cc | 1 + libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/bits/indirect.h | 459 + libstdc++-v3/include/bits/version.def | 9 + libstdc++-v3/include/bits/version.h| 10 + libstdc++-v3/include/std/memory| 5 + libstdc++-v3/testsuite/std/memory/indirect/copy.cc | 121 ++ .../testsuite/std/memory/indirect/copy_alloc.cc| 228 ++ libstdc++-v3/testsuite/std/memory/indirect/ctor.cc | 203 + .../testsuite/std/memory/indirect/incomplete.cc| 38 ++ .../testsuite/std/memory/indirect/invalid_neg.cc | 28 ++ libstdc++-v3/testsuite/std/memory/indirect/move.cc | 144 +++ .../testsuite/std/memory/indirect/move_alloc.cc| 296 + .../testsuite/std/memory/indirect/relops.cc| 82 15 files changed, 1626 insertions(+) diff --git a/libstdc++-v3/doc/doxygen/stdheader.cc b/libstdc++-v3/doc/doxygen/stdheader.cc index 938b2b04a262..cb5d17a4f1f7 100644 --- a/libstdc++-v3/doc/doxygen/stdheader.cc +++ b/libstdc++-v3/doc/doxygen/stdheader.cc @@ -106,6 +106,7 @@ void init_map() headers["uses_allocator.h"] = "memory"; headers["uses_allocator_args.h"]= "memory"; headers["out_ptr.h"]= "memory"; +headers["indirect.h"] = "memory"; headers["memory_resource.h"]= "memory_resource"; headers["unique_lock.h"]= "mutex"; headers["sat_arith.h"] = "numeric"; diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index baf0290d6559..cc402f0648f4 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -211,6 +211,7 @@ bits_headers = \ ${bits_srcdir}/gslice_array.h \ ${bits_srcdir}/hashtable.h \ ${bits_srcdir}/hashtable_policy.h \ + ${bits_srcdir}/indirect.h \ ${bits_srcdir}/indirect_array.h \ ${bits_srcdir}/ios_base.h \ ${bits_srcdir}/istream.tcc \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index e4e1079d8bdb..a6e602327b6e 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -564,6 +564,7 @@ bits_freestanding = \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/gslice_array.h \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/hashtable.h \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/hashtable_policy.h \ +@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/indirect.h \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/indirect_array.h \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/ios_base.h \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/istream.tcc \ diff --git a/libstdc++-v3/include/bits/indirect.h b/libstdc++-v3/include/bits/indirect.h new file mode 100644 index ..85908e219b77 --- /dev/null +++ b/libstdc++-v3/include/bits/indirect.h @@ -0,0 +1,459 @@ +// Vocabulary Types for Composite Class Design -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Un
[gcc r16-875] [AUTOFDO][AARCH64] Add support for profilebootstrap
https://gcc.gnu.org/g:86dc974cf30f926a014438a5fccdc9d41e26282b commit r16-875-g86dc974cf30f926a014438a5fccdc9d41e26282b Author: Kugan Vivekanandarajah Date: Mon May 26 11:41:59 2025 +1000 [AUTOFDO][AARCH64] Add support for profilebootstrap Add support for autoprofiledbootstrap in aarch64. This is similar to what is done for i386. Added gcc/config/aarch64/gcc-auto-profile for aarch64 profile creation. How to run: configure --with-build-config=bootstrap-lto make autoprofiledbootstrap ChangeLog: * Makefile.def: AUTO_PROFILE based on cpu_type. * Makefile.in: Likewise. * configure: Regenerate. * configure.ac: Set autofdo_target. gcc/ChangeLog: * config/aarch64/gcc-auto-profile: New file. Signed-off-by: Kugan Vivekanandarajah Diff: --- Makefile.def| 2 +- Makefile.in | 69 +++-- configure | 4 +++ configure.ac| 3 ++ gcc/config/aarch64/gcc-auto-profile | 53 5 files changed, 96 insertions(+), 35 deletions(-) diff --git a/Makefile.def b/Makefile.def index 3f980bce8c05..b0382713609a 100644 --- a/Makefile.def +++ b/Makefile.def @@ -758,7 +758,7 @@ bootstrap_stage = { bootstrap_target=profiledbootstrap ; }; bootstrap_stage = { id=autoprofile ; prev=1 ; -autoprofile="$$s/gcc/config/i386/$(AUTO_PROFILE)" ; }; +autoprofile="$$s/gcc/config/@cpu_typet@/$(AUTO_PROFILE)" ; }; bootstrap_stage = { id=autofeedback ; prev=autoprofile ; bootstrap_target=autoprofiledbootstrap ; diff --git a/Makefile.in b/Makefile.in index b1ed67d3d4f1..931507c32703 100644 --- a/Makefile.in +++ b/Makefile.in @@ -38,6 +38,7 @@ build_alias=@build_noncanonical@ build_vendor=@build_vendor@ build_os=@build_os@ build=@build@ +cpu_type=@cpu_type@ host_alias=@host_noncanonical@ host_vendor=@host_vendor@ host_os=@host_os@ @@ -4271,7 +4272,7 @@ all-stageautoprofile-bfd: configure-stageautoprofile-bfd $(HOST_EXPORTS) \ $(POSTSTAGE1_HOST_EXPORTS) \ cd $(HOST_SUBDIR)/bfd && \ - $$s/gcc/config/i386/$(AUTO_PROFILE) \ + $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \ $(MAKE) $(BASE_FLAGS_TO_PASS) \ CFLAGS="$(STAGEautoprofile_CFLAGS)" \ GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \ @@ -5411,7 +5412,7 @@ all-stageautoprofile-opcodes: configure-stageautoprofile-opcodes $(HOST_EXPORTS) \ $(POSTSTAGE1_HOST_EXPORTS) \ cd $(HOST_SUBDIR)/opcodes && \ - $$s/gcc/config/i386/$(AUTO_PROFILE) \ + $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \ $(MAKE) $(BASE_FLAGS_TO_PASS) \ CFLAGS="$(STAGEautoprofile_CFLAGS)" \ GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \ @@ -6551,7 +6552,7 @@ all-stageautoprofile-binutils: configure-stageautoprofile-binutils $(HOST_EXPORTS) \ $(POSTSTAGE1_HOST_EXPORTS) \ cd $(HOST_SUBDIR)/binutils && \ - $$s/gcc/config/i386/$(AUTO_PROFILE) \ + $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \ $(MAKE) $(BASE_FLAGS_TO_PASS) \ CFLAGS="$(STAGEautoprofile_CFLAGS)" \ GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \ @@ -10037,7 +10038,7 @@ all-stageautoprofile-fixincludes: configure-stageautoprofile-fixincludes $(HOST_EXPORTS) \ $(POSTSTAGE1_HOST_EXPORTS) \ cd $(HOST_SUBDIR)/fixincludes && \ - $$s/gcc/config/i386/$(AUTO_PROFILE) \ + $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \ $(MAKE) $(BASE_FLAGS_TO_PASS) \ CFLAGS="$(STAGEautoprofile_CFLAGS)" \ GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \ @@ -11617,7 +11618,7 @@ all-stageautoprofile-gas: configure-stageautoprofile-gas $(HOST_EXPORTS) \ $(POSTSTAGE1_HOST_EXPORTS) \ cd $(HOST_SUBDIR)/gas && \ - $$s/gcc/config/i386/$(AUTO_PROFILE) \ + $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \ $(MAKE) $(BASE_FLAGS_TO_PASS) \ CFLAGS="$(STAGEautoprofile_CFLAGS)" \ GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \ @@ -12766,7 +12767,7 @@ all-stageautoprofile-gcc: configure-stageautoprofile-gcc $(HOST_EXPORTS) \ $(POSTSTAGE1_HOST_EXPORTS) \ cd $(HOST_SUBDIR)/gcc && \ - $$s/gcc/config/i386/$(AUTO_PROFILE) \ + $$s/gcc/config/$(cpu_type)/$(AUTO_PROFILE) \ $(MAKE) $(BASE_FLAGS_TO_PASS) \ CFLAGS="$(STAGEautoprofile_CFLAGS)" \ GENERATOR_CFLAGS="$(STAGEautoprofile_GENERATOR_CFLAGS)" \ @@ -13915,7 +13916,7 @@ all-stageautoprofile-gmp: configure-stageautoprofile-gmp $(HOST_EXPORTS) \ $(POSTSTAGE1_HOST_EXPORTS) \ cd $(HOST_SUBDIR)/gmp && \ - $$s/gcc/confi
[gcc r16-880] c++: add -fdump-lang-tinst
https://gcc.gnu.org/g:f59ff19bc3d37f4dd159db541ed4f07efb10fcc8 commit r16-880-gf59ff19bc3d37f4dd159db541ed4f07efb10fcc8 Author: Jason Merrill Date: Fri Apr 18 09:50:04 2025 -0400 c++: add -fdump-lang-tinst This patch adds a dump with a trace of template instantiations, indented based on the depth of recursive instantiation. -lineno adds the location that triggered the instantiation, -details adds non-instantiation sbustitutions. The instantiate_pending_templates change is to avoid a bunch of entries for reopening tinst scopes that we then don't instantiate anything with; it also seems a bit cleaner this way. gcc/cp/ChangeLog: * cp-tree.h: Declare tinst_dump_id. * cp-objcp-common.cc (cp_register_dumps): Set it. * pt.cc (push_tinst_level_loc): Dump it. (reopen_tinst_level): Here too. (tinst_complete_p): New. (instantiate_pending_templates): Don't reopen_tinst_level for already-complete instantiations. gcc/ChangeLog: * doc/invoke.texi: Move C++ -fdump-lang to C++ section. Add -fdump-lang-tinst. Diff: --- gcc/doc/invoke.texi | 72 -- gcc/cp/cp-tree.h | 1 + gcc/cp/cp-objcp-common.cc | 2 + gcc/cp/pt.cc | 111 +++--- 4 files changed, 145 insertions(+), 41 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index fe47ce564873..e3bc833c59bd 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3297,6 +3297,50 @@ Enable support for the C++ coroutines extension (experimental). Permit the C++ front end to note all candidates during overload resolution failure, including when a deleted function is selected. +@item -fdump-lang- +@itemx -fdump-lang-@var{switch} +@itemx -fdump-lang-@var{switch}-@var{options} +@itemx -fdump-lang-@var{switch}-@var{options}=@var{filename} +Control the dumping of C++-specific information. The @var{options} +and @var{filename} portions behave as described in the +@option{-fdump-tree} option. The following @var{switch} values are +accepted: + +@table @samp +@item all +Enable all of the below. + +@opindex fdump-lang-class +@item class +Dump class hierarchy information. Virtual table information is emitted +unless '@option{slim}' is specified. + +@opindex fdump-lang-module +@item module +Dump module information. Options @option{lineno} (locations), +@option{graph} (reachability), @option{blocks} (clusters), +@option{uid} (serialization), @option{alias} (mergeable), +@option{asmname} (Elrond), @option{eh} (mapper) & @option{vops} +(macros) may provide additional information. + +@opindex fdump-lang-raw +@item raw +Dump the raw internal tree data. + +@opindex fdump-lang-tinst +@item tinst +Dump the sequence of template instantiations, indented to show the +depth of recursion. The @option{lineno} option adds the source +location where the instantiation was triggered, and the +@option{details} option also dumps pre-instantiation substitutions +such as those performed during template argument deduction. + +Lines in the .tinst dump start with @samp{I} for an instantiation, +@samp{S} for another substitution, and @samp{R[IS]} for the reopened +context of a deferred instantiation. + +@end table + @opindex fno-elide-constructors @opindex felide-constructors @item -fno-elide-constructors @@ -20891,30 +20935,10 @@ Dump language-specific information. The file name is made by appending @itemx -fdump-lang-@var{switch}-@var{options}=@var{filename} Control the dumping of language-specific information. The @var{options} and @var{filename} portions behave as described in the -@option{-fdump-tree} option. The following @var{switch} values are -accepted: - -@table @samp -@item all - -Enable all language-specific dumps. - -@item class -Dump class hierarchy information. Virtual table information is emitted -unless '@option{slim}' is specified. This option is applicable to C++ only. - -@item module -Dump module information. Options @option{lineno} (locations), -@option{graph} (reachability), @option{blocks} (clusters), -@option{uid} (serialization), @option{alias} (mergeable), -@option{asmname} (Elrond), @option{eh} (mapper) & @option{vops} -(macros) may provide additional information. This option is -applicable to C++ only. - -@item raw -Dump the raw internal tree data. This option is applicable to C++ only. - -@end table +@option{-fdump-tree} option. @option{-fdump-tree-all} enables all +language-specific dumps; other options vary with the language. For +instance, see @xref{C++ Dialect Options} for the @option{-fdump-lang} +flags supported by the C++ front-end. @opindex fdump-passes @item -fdump-passes diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7433b8962199..19c0b452d868 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6822,6 +6822,7 @@ extern int class_dump_i
[gcc r16-879] c++: add cxx_dump_pretty_printer
https://gcc.gnu.org/g:d424245c7abb2871b977ddc5c1e73b827a78ad07 commit r16-879-gd424245c7abb2871b977ddc5c1e73b827a78ad07 Author: Jason Merrill Date: Thu Apr 17 16:29:49 2025 -0400 c++: add cxx_dump_pretty_printer A class to simplify implementation of -fdump-lang-foo with support for pp_printf using %D and such. gcc/cp/ChangeLog: * cp-tree.h (class cxx_dump_pretty_printer): New. * error.cc (cxx_dump_pretty_printer): Ctor/dtor definitions. Diff: --- gcc/cp/cp-tree.h | 23 +++ gcc/cp/error.cc | 27 +++ 2 files changed, 50 insertions(+) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 175ab2874903..7433b8962199 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7322,6 +7322,29 @@ extern void cp_check_const_attributes (tree); extern void maybe_propagate_warmth_attributes (tree, tree); /* in error.cc */ +/* A class for pretty-printing to -flang-dump-XXX files. Used like + + if (cxx_dump_pretty_printer pp {foo_dump_id}) + { + pp_printf (&pp, ...); + } + + If the dump is enabled, the pretty printer will open the dump file and + attach to it, and flush and close the file on destruction. */ + +class cxx_dump_pretty_printer: public pretty_printer +{ + int phase; + FILE *outf; + dump_flags_t flags; + +public: + cxx_dump_pretty_printer (int phase); + operator bool() { return outf != nullptr; } + bool has_flag (dump_flags_t f) { return (flags & f); } + ~cxx_dump_pretty_printer (); +}; + extern const char *type_as_string (tree, int); extern const char *type_as_string_translate(tree, int); extern const char *decl_as_string (tree, int); diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 305064d476c4..d52dad3db293 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -193,6 +193,33 @@ class cxx_format_postprocessor : public format_postprocessor deferred_printed_type m_type_b; }; +/* Constructor and destructor for cxx_dump_pretty_printer, defined here to + avoid needing to move cxx_format_postprocessor into the header as well. */ + +cxx_dump_pretty_printer:: +cxx_dump_pretty_printer (int phase) + : phase (phase) +{ + outf = dump_begin (phase, &flags); + if (outf) +{ + pp_format_decoder (this) = cp_printer; + /* This gets deleted in ~pretty_printer. */ + pp_format_postprocessor (this) = new cxx_format_postprocessor (); + set_output_stream (outf); +} +} + +cxx_dump_pretty_printer:: +~cxx_dump_pretty_printer () +{ + if (outf) +{ + pp_flush (this); + dump_end (phase, outf); +} +} + /* Return the in-scope template that's currently being parsed, or NULL_TREE otherwise. */
[gcc r13-9687] c++: format attribute redeclaration [PR116954]
https://gcc.gnu.org/g:bde3ca83ffe99088718198ea643bed7c4b22bbf1 commit r13-9687-gbde3ca83ffe99088718198ea643bed7c4b22bbf1 Author: Jason Merrill Date: Wed Apr 16 11:15:14 2025 -0400 c++: format attribute redeclaration [PR116954] Here when merging the two decls, remove_contract_attributes loses ATTR_IS_DEPENDENT on the format attribute, so apply_late_template_attributes just returns, so the attribute doesn't get propagated to the type where the warning looks for it. Fixed by using copy_node instead of tree_cons to preserve flags. PR c++/116954 gcc/cp/ChangeLog: * contracts.cc (remove_contract_attributes): Preserve flags on the attribute list. gcc/testsuite/ChangeLog: * g++.dg/warn/Wformat-3.C: New test. (cherry picked from commit b0d7d644f3c25af9bf60c948ab26aa7b09a68787) Diff: --- gcc/cp/contracts.cc | 9 - gcc/testsuite/g++.dg/warn/Wformat-3.C | 19 +++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc index 18482e5c4c85..d3ac71570a3b 100644 --- a/gcc/cp/contracts.cc +++ b/gcc/cp/contracts.cc @@ -869,10 +869,17 @@ cp_contract_assertion_p (const_tree attr) void remove_contract_attributes (tree fndecl) { + if (!flag_contracts) +return; + tree list = NULL_TREE; for (tree p = DECL_ATTRIBUTES (fndecl); p; p = TREE_CHAIN (p)) if (!cxx_contract_attribute_p (p)) - list = tree_cons (TREE_PURPOSE (p), TREE_VALUE (p), list); + { + tree nl = copy_node (p); + TREE_CHAIN (nl) = list; + list = nl; + } DECL_ATTRIBUTES (fndecl) = nreverse (list); } diff --git a/gcc/testsuite/g++.dg/warn/Wformat-3.C b/gcc/testsuite/g++.dg/warn/Wformat-3.C new file mode 100644 index ..e308530761c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wformat-3.C @@ -0,0 +1,19 @@ +// PR c++/116954 +// { dg-additional-options -Wformat } + +#ifndef WORKS +template +int fn(char (&buf)[N], const char fmt[], ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +#endif + +template +__attribute__ ((__format__ (__printf__, 2, 3))) +int fn(char (&)[N], const char [], ...) +{ return 0; } + +int main() +{ + char buf[20]; + return fn(buf, "%s", 42); /* { dg-warning "Wformat" } */ +}