[gcc r16-1710] rust: Silence a clang warning in borrow-checker-diagnostics
https://gcc.gnu.org/g:1e69c5655894ab3cbeb4431a5b3daff211d3c4e1 commit r16-1710-g1e69c5655894ab3cbeb4431a5b3daff211d3c4e1 Author: Martin Jambor Date: Mon Jun 23 23:52:20 2025 +0200 rust: Silence a clang warning in borrow-checker-diagnostics When compiling gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc with clang, it emits the following warning: gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc:145:46: warning: non-constant-expression cannot be narrowed from type 'Polonius::Loan' (aka 'unsigned long') to 'uint32_t' (aka 'unsigned int') in initializer list [-Wc++11-narrowing] I'd hope that for indexing that is never really a problem, nevertheless if narrowing is taking place, I guess it can be argued it should be made explicit. gcc/rust/ChangeLog: 2025-06-23 Martin Jambor * checks/errors/borrowck/rust-borrow-checker-diagnostics.cc (BorrowCheckerDiagnostics::get_loan): Type cast loan to uint32_t. Diff: --- gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc index 6c67706780bf..adf1448791e1 100644 --- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc +++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc @@ -142,7 +142,7 @@ BorrowCheckerDiagnostics::get_statement (Polonius::Point point) const BIR::Loan & BorrowCheckerDiagnostics::get_loan (Polonius::Loan loan) { - return bir_function.place_db.get_loans ()[{loan}]; + return bir_function.place_db.get_loans ()[{(uint32_t) loan}]; } const HIR::LifetimeParam *
[gcc r16-1713] RISC-V: update prepare_ternary_operands to handle vector-scalar case [PR120828]
https://gcc.gnu.org/g:181cb2943d53862aa41eab49a042dff991a3d94f commit r16-1713-g181cb2943d53862aa41eab49a042dff991a3d94f Author: Paul-Antoine Arras Date: Wed Jun 25 16:42:00 2025 + RISC-V: update prepare_ternary_operands to handle vector-scalar case [PR120828] This is a followup to 92e1893e0 "RISC-V: Add patterns for vector-scalar multiply-(subtract-)accumulate" that caused an ICE in some cases where the mult operands were wrongly swapped. This patch ensures that operands are not swapped in the vector-scalar case. PR target/120828 gcc/ChangeLog: * config/riscv/riscv-v.cc (prepare_ternary_operands): Handle the vector-scalar case. Diff: --- gcc/config/riscv/riscv-v.cc | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 45dd9256d020..a3d704e81cc4 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -4723,7 +4723,7 @@ prepare_ternary_operands (rtx *ops) ops[4], ops[1], ops[6], ops[7], ops[9])); ops[5] = ops[4] = ops[0]; } - else + else if (VECTOR_MODE_P (GET_MODE (ops[2]))) { /* Swap the multiplication ops if the fallback value is the second of the two. */ @@ -4733,8 +4733,10 @@ prepare_ternary_operands (rtx *ops) /* TODO: ??? Maybe we could support splitting FMA (a, 4, b) into PLUS (ASHIFT (a, 2), b) according to uarchs. */ } - gcc_assert (rtx_equal_p (ops[5], RVV_VUNDEF (mode)) - || rtx_equal_p (ops[5], ops[2]) || rtx_equal_p (ops[5], ops[4])); + gcc_assert ( +rtx_equal_p (ops[5], RVV_VUNDEF (mode)) || rtx_equal_p (ops[5], ops[2]) +|| (!VECTOR_MODE_P (GET_MODE (ops[2])) && rtx_equal_p (ops[5], ops[3])) +|| rtx_equal_p (ops[5], ops[4])); } /* Expand VEC_MASK_LEN_{LOAD_LANES,STORE_LANES}. */
[gcc r16-1711] contrib/mklog.py: Add main function
https://gcc.gnu.org/g:ca8ea1d23e8b6798b6eb8c018957b25aa6f0db95 commit r16-1711-gca8ea1d23e8b6798b6eb8c018957b25aa6f0db95 Author: Alex Coplan Date: Thu Jun 19 14:44:06 2025 +0100 contrib/mklog.py: Add main function This adds a main() function to mklog.py (like e.g. check_GNU_style.py has), which makes it easier to import and invoke from another python script. This is useful when using a wrapper script to set up the python environment. Smoke tested by using the modified mklog.py to generate the ChangeLog for this patch. contrib/ChangeLog: * mklog.py (main): New. Diff: --- contrib/mklog.py | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/mklog.py b/contrib/mklog.py index dcf7dde63336..26d4156b0340 100755 --- a/contrib/mklog.py +++ b/contrib/mklog.py @@ -360,7 +360,7 @@ def skip_line_in_changelog(line): return FIRST_LINE_OF_END_RE.match(line) is None -if __name__ == '__main__': +def main(): extra_args = os.getenv('GCC_MKLOG_ARGS') if extra_args: sys.argv += json.loads(extra_args) @@ -447,3 +447,6 @@ if __name__ == '__main__': f.write('\n'.join(end)) else: print(output, end='') + +if __name__ == '__main__': +main()
[gcc r16-1712] libstdc++: Lift chrono localized formatting to main chrono format loop [PR110739]
https://gcc.gnu.org/g:caac9489f62221da083684456c7c7ceca7425493 commit r16-1712-gcaac9489f62221da083684456c7c7ceca7425493 Author: Tomasz Kamiński Date: Wed Jun 25 16:58:31 2025 +0200 libstdc++: Lift chrono localized formatting to main chrono format loop [PR110739] This patch extract calls to _M_locale_fmt and construction of the struct tm, from the functions dedicated to each specifier, to main format loop in _M_format_to functions. This removes duplicated code repeated for specifiers. To allow _M_locale_fmt to only be called if localized formatting is enabled ('L' is present in chrono-format-spec), we provide a implementations for locale specific specifiers (%c, %r, %x, %X) that produces the same result as locale::classic(): * %c is implemented as separate _M_c method * %r is implemented as separate _M_r method * %x is implemented together with %D, as they provide same behavior, * %X is implemented together with %R as _M_R_X, as both of them do not include subseconds. The handling of subseconds was also extracted to _M_subsecs function that is used by _M_S and _M_T specifier. The _M_T is now implemented in terms of _M_R_X (printing time without subseconds) and _M_subs. The __mod parameter responsible for triggering localized formatting was removed from methods handling most of specifiers, except: * _M_S (for %S) for which it determines if subseconds should be included, * _M_z (for %z) for which it determines if ':' is used as separator. PR libstdc++/110739 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_use_locale_fmt): Define. (__formatter_chrono::_M_locale_fmt): Moved to front of the class. (__formatter_chrono::_M_format_to): Construct and initialize struct tm and call _M_locale_fmt if needed. (__formatter_chrono::_M_c_r_x_X): Split into separate methods. (__formatter_chrono::_M_c, __formatter_chrono::_M_r): Define. (__formatter_chrono::_M_D): Renamed to _M_D_x. (__formatter_chrono::_M_D_x): Renamed from _M_D. (__formatter_chrono::_M_R_T): Split into _M_R_X and _M_T. (__formatter_chrono::_M_R_X): Extracted from _M_R_T. (__formatter_chrono::_M_T): Define in terms of _M_R_X and _M_subsecs. (__formatter_chrono::_M_subsecs): Extracted from _M_S. (__formatter_chrono::_M_S): Replaced __mod with __subs argument, removed _M_locale_fmt call, and delegate to _M_subsecs. (__formatter_chrono::_M_C_y_Y, __formatter_chrono::_M_d_e) (__formatter_chrono::_M_H_I, __formatter_chrono::_M_m) (__formatter_chrono::_M_u_w, __formatter_chrono::_M_U_V_W): Remove __mod argument and call to _M_locale_fmt. Reviewed-by: Jonathan Wakely Signed-off-by: Tomasz Kamiński Diff: --- libstdc++-v3/include/bits/chrono_io.h | 338 +- 1 file changed, 171 insertions(+), 167 deletions(-) diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 2041f8535f66..bcfd51b98665 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -908,6 +908,40 @@ namespace __format return __format::__write(std::move(__out), __s); } + [[__gnu__::__always_inline__]] + static bool + _S_localized_spec(_CharT __conv, _CharT __mod) + { + switch (__conv) + { + case 'c': + case 'r': + case 'x': + case 'X': + return true; + case 'z': + return false; + default: + return (bool)__mod; + }; + } + + // Use the formatting locale's std::time_put facet to produce + // a locale-specific representation. + template + _Iter + _M_locale_fmt(_Iter __out, const locale& __loc, const struct tm& __tm, + char __fmt, char __mod) const + { + basic_ostringstream<_CharT> __os; + __os.imbue(__loc); + const auto& __tp = use_facet>(__loc); + __tp.put(__os, __os, _S_space, &__tm, __fmt, __mod); + if (__os) + __out = _M_write(std::move(__out), __loc, __os.view()); + return __out; + } + template _Out _M_format_to(const _ChronoData<_CharT>& __t, _Out __out, @@ -925,6 +959,36 @@ namespace __format return std::move(__out); }; + struct tm __tm{}; + bool __use_locale_fmt = false; + if (_M_spec._M_localized && _M_spec._M_locale_specific) + if (__fc.locale() != locale::classic()) + { + __use_locale_fmt = true; + + __tm.tm_year = (int)__t._M_year - 1900; + __tm.tm_yday = __t._M_day_of_year.count
[gcc r16-1709] libstdc++: Type-erase chrono-data for formatting [PR110739]
https://gcc.gnu.org/g:4b3cefed1a08344495fedec4982d85168bd8173f commit r16-1709-g4b3cefed1a08344495fedec4982d85168bd8173f Author: Tomasz Kamiński Date: Tue Jun 24 14:07:46 2025 +0200 libstdc++: Type-erase chrono-data for formatting [PR110739] This patch reworks the formatting for the chrono types, such that they are all formatted in terms of _ChronoData class, that includes all required fields. Populating each required field is performed in formatter for specific type, based on the chrono-spec used. To facilitate above, the _ChronoSpec now includes additional _M_needed field, that represnts the chrono data that is referenced by format spec (this value is also configured for __defSpec). This value differs from the value of __parts passed to _M_parse, which does include all fields that can be computed from input (e.g. weekday_indexed can be computed for year_month_day). Later it is used to fill _ChronoData, in particular _M_fill_* family of functions, to determine if given field needs to be set, and thus its value needs to be computed. In consequence _ChronoParts enum was extended with additional values, that allows more fine grained identification: * _TimeOfDay is separated into _HoursMinutesSeconds and _Subseconds, * _TimeZone is separated into _ZoneAbbrev and _ZoneOffset, * _LocalDays, _WeekdayIndex are defined and in included in _Date, * _Duration is removed, and instead _EpochUnits and _UnitSuffix are introduced. Furthermore, to avoid name conflicts _ChonoParts is now defined as enum class, with additional operators that simplify uses. In addition to fields that can be printed using chrono-spec, _ChronoData stores: * Total days in wall time (_M_ldays), day of year (_M_day_of_year) - used by struct tm construction, and for ISO calendar computation. * Total seconds in wall time (_M_lseconds) - this value may be different from sum of days, hours, minutes, seconds (e.g. see utc_time below). Included to allow future extension, like printing total minutes. * Total seconds since epoch - due offset different from above. Again to be used with future extension (e.g. %s as proposed in P2945R1). * Subseconds - count of attoseconds (10^(-18)), in addition to printing can be used to compute fractional hours, minutes. The both total seconds fields use single _TotalSeconds enumerator in _ChronoParts, that when present in combination with _EpochUnits or _LocalDays indicates that _M_eseconds (_EpochSeconds) or _M_lseconds (_LocalSeconds) are provided/required. To handle type formatting of time since epoch ('%Q'|_EpochUnits), we use the format_args mechanism, where the result of +d.count() (see LWG4118) is erased into make_format_args to local __arg_store, that is later referenced by _M_ereps (_M_ereps.get(0)). To handle precision values, and in prepartion to allow user to configure ones, we store the precision as third element of _M_ereps (_M_ereps.get(2)), this allows duration with precision to be printed using "{0:{2}}". For subseconds the precision is handled differently depending on the representation: * for integral reps, _M_subseconds value is used to determine fractional value, precision is trimmed to 18 digits; * for floating-points, _M_ereps stores duration initialized with only fractional seconds, that is later formatted with precision. Always using _M_subseconds fields for integral duration, means that we do not use formattter for user-defined durations that are considered to be integral (see empty_spec.cc file change). To avoid potentially expensive computation of _M_subseconds, we make sure that _ChronoParts::_Subseconds is set only if _Subseconds are needed. In particular we remove this flag for localized ouput in _M_parse. Construction of the _M_ereps as described above is handled by __formatter_duration, that is then used to format duration, hh_mm_ss and time_points specializations. This class also handles _UnitSuffix, the _M_units_suffix field is populated either with predefined suffix (chrono::__detail::__units_suffix) or one produced locally. Finally, formatters for types listed below contains type specific logic: * hh_mm_ss - we do not compute total duration and seconds, unless explicitly requested, as such computation may overflow; * utc_time - for time during leap second insertion, the _M_seconds field is increased to 60; * __local_time_fmt - exception is thrown if zone offset (_ZoneOffset) or abbrevation (_ZoneAbbrev) is requsted, but corresponding pointer is null, futhermore conversion from `char` to `wchar_t` for abbreviation is performed if needed. PR libstdc++/110739 libstdc++-v3/ChangeLo
[gcc r16-1706] i386: Introduce crc_revsi4 expanders [PR120719]
https://gcc.gnu.org/g:f8f7ace4f20829f2fad87662f5163c9b13427e39 commit r16-1706-gf8f7ace4f20829f2fad87662f5163c9b13427e39 Author: Uros Bizjak Date: Thu Jun 26 14:13:01 2025 +0200 i386: Introduce crc_revsi4 expanders [PR120719] Introduce crc_revsi4 expanders to generate CRC32 instruction when using __builtin_rev_crc32_data* builtins with 0x1EDC6F41 poylnomial and -mcrc32. PR target/120719 gcc/ChangeLog: * config/i386/i386.md (crc_revsi4): New expander. gcc/testsuite/ChangeLog: * gcc.target/i386/crc-builtin-crc32.c: New test. Diff: --- gcc/config/i386/i386.md | 17 + gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c | 22 ++ 2 files changed, 39 insertions(+) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 41a86544bbf7..adff2af45631 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -29523,6 +29523,23 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_expand "crc_revsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SWI124 2 "nonimmediate_operand") + (match_operand:SI 3)] + "TARGET_CRC32" +{ + /* crc32 uses iSCSI polynomial */ + if (INTVAL (operands[3]) == 0x1EDC6F41) +emit_insn (gen_sse4_2_crc32 (operands[0], operands[1], operands[2])); + else +expand_reversed_crc_table_based (operands[0], operands[1], operands[2], +operands[3], mode, +generate_reflecting_code_standard); + DONE; +}) + (define_insn "rdpmc" [(set (match_operand:DI 0 "register_operand" "=A") (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] diff --git a/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c b/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c new file mode 100644 index ..0b4ff978817d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c @@ -0,0 +1,22 @@ +/* PR target/120719 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcrc32" } */ + +#include + +int32_t rev_crc32_data8 (int8_t v) +{ + return __builtin_rev_crc32_data8 (0x, v, 0x1EDC6F41); +} + +int32_t rev_crc32_data16 (int16_t v) +{ + return __builtin_rev_crc32_data16 (0x, v, 0x1EDC6F41); +} + +int32_t rev_crc32_data32 (int32_t v) +{ + return __builtin_rev_crc32_data32 (0x, v, 0x1EDC6F41); +} + +/* { dg-final { scan-assembler-times "\tcrc32" 3 } } */
[gcc r15-9867] Fortran: fix checking of renamed-on-use interface name [PR120784]
https://gcc.gnu.org/g:58323d4a03274114a09e75d7aad6d766aceff256 commit r15-9867-g58323d4a03274114a09e75d7aad6d766aceff256 Author: Harald Anlauf Date: Mon Jun 23 21:33:40 2025 +0200 Fortran: fix checking of renamed-on-use interface name [PR120784] PR fortran/120784 gcc/fortran/ChangeLog: * interface.cc (gfc_match_end_interface): If a use-associated symbol is renamed, use the local_name for checking. gcc/testsuite/ChangeLog: * gfortran.dg/interface_63.f90: New test. (cherry picked from commit 6dd1659cf10a7ad51576f902ef3bc007db30c990) Diff: --- gcc/fortran/interface.cc | 13 +-- gcc/testsuite/gfortran.dg/interface_63.f90 | 62 ++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc index b8542920ce79..cdb838d83368 100644 --- a/gcc/fortran/interface.cc +++ b/gcc/fortran/interface.cc @@ -452,11 +452,18 @@ gfc_match_end_interface (void) case INTERFACE_DTIO: case INTERFACE_GENERIC: + /* If a use-associated symbol is renamed, check the local_name. */ + const char *local_name = current_interface.sym->name; + + if (current_interface.sym->attr.use_assoc + && current_interface.sym->attr.use_rename + && current_interface.sym->ns->use_stmts->rename) + local_name = current_interface.sym->ns->use_stmts->rename->local_name; + if (type != current_interface.type - || strcmp (current_interface.sym->name, name) != 0) + || strcmp (local_name, name) != 0) { - gfc_error ("Expecting % at %C", -current_interface.sym->name); + gfc_error ("Expecting % at %C", local_name); m = MATCH_ERROR; } diff --git a/gcc/testsuite/gfortran.dg/interface_63.f90 b/gcc/testsuite/gfortran.dg/interface_63.f90 new file mode 100644 index ..a55e8ab431b1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/interface_63.f90 @@ -0,0 +1,62 @@ +! { dg-do compile } +! PR fortran/120784 - fix checking of renamed-on-use interface name +! +! Contributed by Matt Thompson + +module A_mod + implicit none + + interface Get + procedure :: get_1 + procedure :: get_2 + end interface Get + +contains + + subroutine get_1(i) +integer :: i +i = 5 + end subroutine get_1 + + subroutine get_2(x) +real :: x +x = 4 + end subroutine get_2 +end module A_mod + +module B_mod + use A_mod, only : MyGet => Get + implicit none + + interface MyGet + procedure :: other_get + end interface MyGet + +contains + + subroutine other_get(c) +character(1) :: c +c = 'a' + end subroutine other_get + + subroutine check_get () +character :: c +integer :: i +real :: r +call myget (c) +call myget (i) +call myget (r) + end subroutine check_get + +end module B_MOD + +program p + use b_mod, only: myget + implicit none + character :: c + integer :: i + real :: r + call myget (c) + call myget (i) + call myget (r) +end
[gcc r16-1719] [genoutput] mark scratch outputs as eliminable [PR120424]
https://gcc.gnu.org/g:6c554467623ec53ae228d127cbec9c4ba3cdc027 commit r16-1719-g6c554467623ec53ae228d127cbec9c4ba3cdc027 Author: Alexandre Oliva Date: Thu Jun 26 21:01:21 2025 -0300 [genoutput] mark scratch outputs as eliminable [PR120424] acats' fdd2a00.read is miscompiled on arm-linux-gnu with -O2 -fstack-clash-protection -march=armv7-a -marm: a clobbered scratch register in a *iorsi3_compare0_scratch pattern gets initially assigned to the frame pointer register, but at some point during lra the frame size grows to nonzero, arm_frame_pointer_required flips to true, and the fp2sp elimination has to be disabled, so the scratch register gets spilled to a stack slot. It needs to get the sfp elimination at that point, because later rounds of elimination will assume the previous round's offset has already been applied. But since scratch matches are not regarded as eliminable by genoutput, we don't attempt elimination in the clobbered stack slot MEM rtx. Later on, lra issues a reload for that slot, using a new pseudo allocated to a hardware register, that gets stored in the stack slot after the original insn. Elimination in that reload store insn eventually updates the elimination offset, but it's an incremental update, assuming that the offset so far has already been applied. Without applying the initial offset, the store ends up overlapping with the function's register save area, corrupting a caller's call-saved register. AFAICT the old reload's elimination wouldn't be harmed by allowing elimination in scratch operands, so I'm enabling eliminable for them regardless. Should it be found to make a difference, we could presumably set a different bit in eliminable to enable reload and lra to tell them apart and behave accordingly. for gcc/ChangeLog PR rtl-optimization/120424 * genoutput.cc (scan_operands): Make MATCH_SCRATCHes eliminable. Diff: --- gcc/genoutput.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/genoutput.cc b/gcc/genoutput.cc index dd4e7b80c2a9..25d0b8b86467 100644 --- a/gcc/genoutput.cc +++ b/gcc/genoutput.cc @@ -478,7 +478,7 @@ scan_operands (class data *d, rtx part, int this_address_p, d->operand[opno].n_alternatives = n_occurrences (',', d->operand[opno].constraint) + 1; d->operand[opno].address_p = 0; - d->operand[opno].eliminable = 0; + d->operand[opno].eliminable = 1; return; case MATCH_OPERATOR:
[gcc r16-1720] [lra] recompute ranges upon disabling fp2sp elimination [PR120424]
https://gcc.gnu.org/g:be547188b632d8c1072341c431af339b7384c4a6 commit r16-1720-gbe547188b632d8c1072341c431af339b7384c4a6 Author: Alexandre Oliva Date: Thu Jun 26 21:01:22 2025 -0300 [lra] recompute ranges upon disabling fp2sp elimination [PR120424] If the frame size grows to nonzero, arm_frame_pointer_required may flip to true under -fstack-clash-protection -fnon-call-exceptions, and that may disable the fp2sp elimination part-way through lra. If pseudos had got assigned to the frame pointer register before that, they have to be spilled, and that requires complete live range information. If !lra_reg_spill_p, lra_spill won't have live ranges for such pseudos, and they could end up sharing spill slots with other pseudos whose live ranges actually overlap. This affects at least Ada.Strings.Wide_Superbounded.Super_Insert and .Super_Replace_Slice in libgnat/a-stwisu.adb, when compiled with -O2 -fstack-clash-protection -march=armv7 (implied Thumb2), causing acats-4's cdd2a01 to fail. Recomputing live ranges including registers may renumber and compress points, so we have to recompute the aggregated live ranges for already-assigned spill slots as well. As a safety net, reject empty live ranges when computing slot sharing. for gcc/ChangeLog PR rtl-optimization/120424 * lra-eliminations.cc (lra_update_fp2sp_elimination): Compute complete live ranges and recompute slots' live ranges if needed. * lra-lives.cc (lra_reset_live_range_list): New. (lra_complete_live_ranges): New. * lra-spills.cc (assign_spill_hard_regs): Reject empty live ranges. (add_pseudo_to_slot): Likewise. (lra_recompute_slots_live_ranges): New. * lra-int.h (lra_reset_live_range_list): Declare. (lra_complete_live_ranges): Declare. (lra_recompute_slots_live_ranges): Declare. Diff: --- gcc/lra-eliminations.cc | 8 gcc/lra-int.h | 3 +++ gcc/lra-lives.cc| 22 ++ gcc/lra-spills.cc | 37 + 4 files changed, 70 insertions(+) diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index ff05501dbbbd..6663d1c37e8b 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -1429,6 +1429,14 @@ lra_update_fp2sp_elimination (int *spilled_pseudos) frame_pointer_needed = true; CLEAR_HARD_REG_SET (set); add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM); + /* If !lra_reg_spill_p, we likely have incomplete range information + for pseudos assigned to the frame pointer that will have to be + spilled, and so we may end up incorrectly sharing them unless we + get live range information for them. */ + if (lra_complete_live_ranges ()) +/* If lives ranges changed, update the aggregate live ranges in + slots as well before spilling any further pseudos. */ +lra_recompute_slots_live_ranges (); n = spill_pseudos (set, spilled_pseudos); if (!ep) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) diff --git a/gcc/lra-int.h b/gcc/lra-int.h index ad42f48cc822..0cf7266ce646 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -381,7 +381,9 @@ extern int *lra_point_freq; extern int lra_hard_reg_usage[FIRST_PSEUDO_REGISTER]; extern int lra_live_range_iter; +extern void lra_reset_live_range_list (lra_live_range_t &); extern void lra_create_live_ranges (bool, bool); +extern bool lra_complete_live_ranges (void); extern lra_live_range_t lra_copy_live_range_list (lra_live_range_t); extern lra_live_range_t lra_merge_live_ranges (lra_live_range_t, lra_live_range_t); @@ -417,6 +419,7 @@ extern bool lra_need_for_scratch_reg_p (void); extern bool lra_need_for_spills_p (void); extern void lra_spill (void); extern void lra_final_code_change (void); +extern void lra_recompute_slots_live_ranges (void); /* lra-remat.cc: */ diff --git a/gcc/lra-lives.cc b/gcc/lra-lives.cc index ffce162907e9..3b1d7a97caf9 100644 --- a/gcc/lra-lives.cc +++ b/gcc/lra-lives.cc @@ -113,6 +113,15 @@ free_live_range_list (lra_live_range_t lr) } } +/* Reset and release live range list LR. */ +void +lra_reset_live_range_list (lra_live_range_t &lr) +{ + lra_live_range_t first = lr; + lr = NULL; + free_live_range_list (first); +} + /* Create and return pseudo live range with given attributes. */ static lra_live_range_t create_live_range (int regno, int start, int finish, lra_live_range_t next) @@ -1524,6 +1533,19 @@ lra_create_live_ranges (bool all_p, bool dead_insn_p) lra_assert (! res); } +/* Run lra_create_live_ranges if !complete_info_p. Return FALSE iff + live ranges are known to have remained unchanged. */ + +bool +lra_complete_live_ranges (void) +{ + if (complete_info_p) +re
[gcc r16-1718] [lra] inactivate disabled fp2sp elimination [PR120424]
https://gcc.gnu.org/g:7ce8a87f78122509334c5cfeebb624f634ccf96e commit r16-1718-g7ce8a87f78122509334c5cfeebb624f634ccf96e Author: Alexandre Oliva Date: Thu Jun 26 21:01:19 2025 -0300 [lra] inactivate disabled fp2sp elimination [PR120424] Even after we disable the fp2sp elimination when it is the active elimination for the fp, spilling might use it before update_reg_eliminate runs and inactivates it for good. If it is used, update_reg_eliminate will fail the check that fp2sp was not used. Since we keep track of uses of this specific elimination, and lra_update_fp2sp_elimination checks it before disabling it, we know it hasn't been used, so we can inactivate it without any ill effects. This fixes the pr118591-1.c avr-none regression exposed by the PR120424 fix. for gcc/ChangeLog PR rtl-optimization/120424 * lra-eliminations.cc (lra_update_fp2sp_elimination): Inactivate the unused fp2sp elimination right away. Diff: --- gcc/lra-eliminations.cc | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index bb708b007a4e..ff05501dbbbd 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -1415,6 +1415,14 @@ lra_update_fp2sp_elimination (int *spilled_pseudos) if (frame_pointer_needed || !targetm.frame_pointer_required ()) return 0; gcc_assert (!elimination_fp2sp_occured_p); + ep = elimination_map[FRAME_POINTER_REGNUM]; + if (ep->to == STACK_POINTER_REGNUM) +{ + elimination_map[FRAME_POINTER_REGNUM] = NULL; + setup_can_eliminate (ep, false); +} + else +ep = NULL; if (lra_dump_file != NULL) fprintf (lra_dump_file, " Frame pointer can not be eliminated anymore\n"); @@ -1422,9 +1430,10 @@ lra_update_fp2sp_elimination (int *spilled_pseudos) CLEAR_HARD_REG_SET (set); add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM); n = spill_pseudos (set, spilled_pseudos); - for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) -if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) - setup_can_eliminate (ep, false); + if (!ep) +for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) + if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) + setup_can_eliminate (ep, false); return n; }
[gcc r16-1721] [lra] rework deactivation of fp2sp elimination [PR120424]
https://gcc.gnu.org/g:b49473448966b045460a23794ed9a309e503fa3b commit r16-1721-gb49473448966b045460a23794ed9a309e503fa3b Author: Alexandre Oliva Date: Thu Jun 26 21:01:24 2025 -0300 [lra] rework deactivation of fp2sp elimination [PR120424] Deactivating the fp2sp elimination in lra_update_fp2sp_elimination prevents update_reg_eliminate from propagating the fp2sp elimination offset to the next chosen elimination, so it may retain -1 as the prev_offset, and prev_offset will be taken as an already-applied offset that needs to be compensated in the next round of spilling and reloading. This affects, for example, crtbegin.o's __do_global_dtors_aux on arm-linux-gnueabihf in a {BOOT_C,T}FLAGS='-O2 -g -fnon-call-exceptions -fstack-clash-protection' bootstrap. Alas, just retaining that elimination causes spills to use the fp2sp elimination, including applying sp offsets, which breaks e.g. an x86_64-linux-gnu native bootstrap with ix86_frame_pointer_required modified to return true on nonzero frame size. The middle-ground solution is to keep the elimination active, so that its offsets are applied and propagated on to the subsequent fp elimination, but without introducing sp offsets, so that e.g. pr103973-18.c on the modified x86_64-linux-gnu doesn't get adjacent argument pushes of two adjacent on-stack temporaries ending up pushing the same temporary because of undesired adjustments. for gcc/ChangeLog PR rtl-optimization/120424 * lra-eliminations.cc (lra_update_fp2sp_elimination): Avoid sp offsets in further fp2sp eliminations... (update_reg_eliminate): ... and restore to_rtx before assert checking. Diff: --- gcc/lra-eliminations.cc | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index 6663d1c37e8b..0a702a43a5a1 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -1172,7 +1172,16 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) /* If it is a currently used elimination: update the previous offset. */ if (elimination_map[ep->from] == ep) - ep->previous_offset = ep->offset; + { + ep->previous_offset = ep->offset; + /* Restore the stack_pointer_rtx into to_rtx, that +lra_update_fp2sp_elimination set to from_rtx, so that the assert +below still checks what it was supposed to check. */ + if (ep->from_rtx == ep->to_rtx + && ep->from != ep->to + && ep->from == FRAME_POINTER_REGNUM) + ep->to_rtx = stack_pointer_rtx; + } prev = ep->prev_can_eliminate; setup_can_eliminate (ep, targetm.can_eliminate (ep->from, ep->to)); @@ -1418,7 +1427,12 @@ lra_update_fp2sp_elimination (int *spilled_pseudos) ep = elimination_map[FRAME_POINTER_REGNUM]; if (ep->to == STACK_POINTER_REGNUM) { - elimination_map[FRAME_POINTER_REGNUM] = NULL; + /* Prevent any further uses of fp, say in spill addresses, from being +eliminated to sp and affected by sp offsets. Alas, deactivating the +elimination altogether causes the next chosen fp elimination to miss +the offset propagation, so it may keep -1 as its prev_offset, and that +will make subsequent offsets incorrect. */ + ep->to_rtx = ep->from_rtx; setup_can_eliminate (ep, false); } else
[gcc r16-1724] [lra] catch all to-sp eliminations with nonzero offsets [PR120424]
https://gcc.gnu.org/g:f9a6efa7a71e80a0989ac91fb7f282468471bb46 commit r16-1724-gf9a6efa7a71e80a0989ac91fb7f282468471bb46 Author: Alexandre Oliva Date: Thu Jun 26 21:01:29 2025 -0300 [lra] catch all to-sp eliminations with nonzero offsets [PR120424] An x86_64-linux-gnu native with ix86_frame_pointer_required modified to return true for nonzero frames, to exercize lra_update_fp2sp_elimination, reveals in stage1 testing that wrong code is generated for gcc.c-torture/execute/ieee/fp-cmp-8l.c: argp-to-sp eliminations are used for one_test to pass its arguments on to *pos, and the sp offsets survive the disabling of that elimination. We didn't really have to disable that elimination, but the x86 backend disables eliminations to sp if frame_pointer_needed. This change extends the catching of fp2sp eliminations to all (?) eliminations to sp with nonzero offsets, since none of them can be properly reversed and would silently lead to wrong code. By accepting nonzero offsets, we bootstrap with -maccumulate-outgoing-args on x86_64-linux-gnu (with ix86_frame_pointer_required modified to return true on nonzero frame size). for gcc/ChangeLog PR rtl-optimization/120424 * lra-eliminations.cc (elimination_2sp_occurred_p): Rename from... (elimination_fp2sp_occured_p): ... this. Adjust all uses. (lra_eliminate_regs_1): Don't require a from-frame-pointer elimination to set it. (update_reg_eliminate): Likewise to test it. Diff: --- gcc/lra-eliminations.cc | 46 +- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index 9cdd0c5ff53a..045f2dcf23ef 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -309,8 +309,18 @@ move_plus_up (rtx x) return x; } -/* Flag that we already did frame pointer to stack pointer elimination. */ -static bool elimination_fp2sp_occured_p = false; +/* Flag that we already applied nonzero stack pointer elimination + offset; such sp updates cannot currently be undone. */ +static bool elimination_2sp_occurred_p = false; + +/* Take note of any nonzero sp-OFFSET used in eliminations to sp. */ +static inline poly_int64 +note_spoff (poly_int64 offset) +{ + if (maybe_ne (offset, 0)) +elimination_2sp_occurred_p = true; + return offset; +} /* Scan X and replace any eliminable registers (such as fp) with a replacement (such as sp) if SUBST_P, plus an offset. The offset is @@ -369,13 +379,10 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, { rtx to = subst_p ? ep->to_rtx : ep->from_rtx; - if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM) - elimination_fp2sp_occured_p = true; - if (maybe_ne (update_sp_offset, 0)) { if (ep->to_rtx == stack_pointer_rtx) - return plus_constant (Pmode, to, update_sp_offset); + return plus_constant (Pmode, to, note_spoff (update_sp_offset)); return to; } else if (update_p) @@ -385,7 +392,8 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, ep->offset - (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx -? lra_get_insn_recog_data (insn)->sp_offset +? note_spoff (lra_get_insn_recog_data + (insn)->sp_offset) : 0)); else return to; @@ -402,19 +410,18 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, poly_int64 offset, curr_offset; rtx to = subst_p ? ep->to_rtx : ep->from_rtx; - if (ep->to_rtx == stack_pointer_rtx && ep->from == FRAME_POINTER_REGNUM) - elimination_fp2sp_occured_p = true; - if (! update_p && ! full_p) return simplify_gen_binary (PLUS, Pmode, to, XEXP (x, 1)); if (maybe_ne (update_sp_offset, 0)) - offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0; + offset = (ep->to_rtx == stack_pointer_rtx + ? note_spoff (update_sp_offset) + : 0); else offset = (update_p ? ep->offset - ep->previous_offset : ep->offset); if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) - offset -= lra_get_insn_recog_data (insn)->sp_offset; + offset -= note_spoff (lra_get_insn_recog_data (insn)->sp_offset); if (poly_int_rtx_p (XEXP (x, 1), &curr_offse
[gcc r16-1722] [lra] reorder operations in lra_update_fp2sp_elimination [PR120424]
https://gcc.gnu.org/g:66b6da3b66ed0fe79e5db79b41eabe82952d1a9b commit r16-1722-g66b6da3b66ed0fe79e5db79b41eabe82952d1a9b Author: Alexandre Oliva Date: Thu Jun 26 21:01:26 2025 -0300 [lra] reorder operations in lra_update_fp2sp_elimination [PR120424] The various recent additions to lra_update_fp2sp_elimination rendered it somewhat confusing, with intermixed groups of statements pertaining to three different major actions: disabling the elimination, recomputing live ranges, and spilling uses of the frame pointer. Reorder them for readability. for gcc/ChangeLog PR rtl-optimization/120424 * lra-eliminations.cc (lra_update_fp2sp_elimination): Reorder and regroup related statements. Diff: --- gcc/lra-eliminations.cc | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index 0a702a43a5a1..5713a9680523 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -1436,13 +1436,13 @@ lra_update_fp2sp_elimination (int *spilled_pseudos) setup_can_eliminate (ep, false); } else -ep = NULL; +for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) + if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) + setup_can_eliminate (ep, false); if (lra_dump_file != NULL) fprintf (lra_dump_file, " Frame pointer can not be eliminated anymore\n"); frame_pointer_needed = true; - CLEAR_HARD_REG_SET (set); - add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM); /* If !lra_reg_spill_p, we likely have incomplete range information for pseudos assigned to the frame pointer that will have to be spilled, and so we may end up incorrectly sharing them unless we @@ -1451,11 +1451,9 @@ lra_update_fp2sp_elimination (int *spilled_pseudos) /* If lives ranges changed, update the aggregate live ranges in slots as well before spilling any further pseudos. */ lra_recompute_slots_live_ranges (); + CLEAR_HARD_REG_SET (set); + add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM); n = spill_pseudos (set, spilled_pseudos); - if (!ep) -for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) - if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) - setup_can_eliminate (ep, false); return n; }
[gcc r16-1723] [lra] apply elimination offsets to MEM in autoinc address [PR120424]
https://gcc.gnu.org/g:ccef9e5dd9ffde563f415f0b7117b48537c8e57d commit r16-1723-gccef9e5dd9ffde563f415f0b7117b48537c8e57d Author: Alexandre Oliva Date: Thu Jun 26 21:01:27 2025 -0300 [lra] apply elimination offsets to MEM in autoinc address [PR120424] When attempting to bootstrap arm-linux-gnueabihf with {BOOT_C,T}FLAGS='-g -O2 -fnon-call-exceptions -fstack-clash-protection', gmp fails to build in stage2: gen-fac's mpz_and gets miscompiled. A pseudo is initialized before a loop and used in a PRE_INC load inside a loop. It gets spilled just as the fp2sp elimination is disabled, and only the initialization gets adjusted with elimination offsets. The unadjusted stack slot within the PRE_INC load ends up reloaded later, but only when the FP offset has already missed its chance to be adjusted. Arrange for lra_eliminate_regs_1 to adjust autoinc addresses that are MEMs themselves. for gcc/ChangeLog PR rtl-optimization/120424 * lra-eliminations.cc (lra_eliminate_regs_1): Adjust autoinc addresses that are MEMs. Diff: --- gcc/lra-eliminations.cc | 6 ++ 1 file changed, 6 insertions(+) diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc index 5713a9680523..9cdd0c5ff53a 100644 --- a/gcc/lra-eliminations.cc +++ b/gcc/lra-eliminations.cc @@ -571,6 +571,9 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, case POST_INC: case PRE_DEC: case POST_DEC: + /* Recurse to adjust elimination offsets in a spilled pseudo. */ + if (GET_CODE (XEXP (x, 0)) == MEM) + break; /* We do not support elimination of a register that is modified. elimination_effects has already make sure that this does not happen. */ @@ -578,6 +581,9 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, case PRE_MODIFY: case POST_MODIFY: + /* Recurse to adjust elimination offsets in a spilled pseudo. */ + if (GET_CODE (XEXP (x, 0)) == MEM) + break; /* We do not support elimination of a hard register that is modified. LRA has already make sure that this does not happen. The only remaining case we need to consider here is
[gcc r16-1700] fortran: Avoid freeing uninitialized value
https://gcc.gnu.org/g:bf6078d2aaee8b240b7425b9788d8038cd45c8f3 commit r16-1700-gbf6078d2aaee8b240b7425b9788d8038cd45c8f3 Author: Martin Jambor Date: Thu Jun 26 11:25:20 2025 +0200 fortran: Avoid freeing uninitialized value When compiling fortran/match.cc, clang emits a warning fortran/match.cc:5301:7: warning: variable 'p' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized] which looks accurate, so this patch adds an initialization of p to avoid the use. gcc/fortran/ChangeLog: 2025-06-23 Martin Jambor * match.cc (gfc_match_nullify): Initialize p to NULL; Diff: --- gcc/fortran/match.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc index aa0b04afd563..8355a390ee08 100644 --- a/gcc/fortran/match.cc +++ b/gcc/fortran/match.cc @@ -5293,7 +5293,7 @@ match gfc_match_nullify (void) { gfc_code *tail; - gfc_expr *e, *p; + gfc_expr *e, *p = NULL; match m; tail = NULL;
[gcc r16-1701] Silence a clang warning in tree-vect-slp.cc about an unused variable
https://gcc.gnu.org/g:b4d6292373b2d50e9f15b2e82ad61abf64105f7b commit r16-1701-gb4d6292373b2d50e9f15b2e82ad61abf64105f7b Author: Martin Jambor Date: Tue Jun 24 11:22:19 2025 +0200 Silence a clang warning in tree-vect-slp.cc about an unused variable Since r15-4695-gd17e672ce82e69 (Richard Biener: Assert finished vectorizer pattern COND_EXPR transition), the static const array cond_expr_maps is unused and when GCC is compiled with clang, it warns about that. This patch simply removes the variable. gcc/ChangeLog: 2025-06-24 Martin Jambor * tree-vect-slp.cc (cond_expr_maps): Remove. Diff: --- gcc/tree-vect-slp.cc | 5 - 1 file changed, 5 deletions(-) diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 603dfc0d4b2d..1a703a9bae4a 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -507,11 +507,6 @@ vect_def_types_match (enum vect_def_type dta, enum vect_def_type dtb) && (dtb == vect_external_def || dtb == vect_constant_def))); } -static const int cond_expr_maps[3][5] = { - { 4, -1, -2, 1, 2 }, - { 4, -2, -1, 1, 2 }, - { 4, -1, -2, 2, 1 } -}; static const int no_arg_map[] = { 0 }; static const int arg0_map[] = { 1, 0 }; static const int arg1_map[] = { 1, 1 };
[gcc r16-1702] tree-vect-stmts.cc: Remove an unused shadowed variable
https://gcc.gnu.org/g:64310ae3ccebc8cfe6edf32d3c2ddfdfb02411a6 commit r16-1702-g64310ae3ccebc8cfe6edf32d3c2ddfdfb02411a6 Author: Martin Jambor Date: Tue Jun 24 00:08:39 2025 +0200 tree-vect-stmts.cc: Remove an unused shadowed variable When compiling tree-vect-stmts.cc with clang, it emits a warning: gcc/tree-vect-stmts.cc:14930:19: warning: unused variable 'mode_iter' [-Wunused-variable] And indeed, there are two mode_iter local variables in function supportable_indirect_convert_operation and the first one is not used at all. This patch removes it. gcc/ChangeLog: 2025-06-24 Martin Jambor * tree-vect-stmts.cc (supportable_indirect_convert_operation): Remove an unused shadowed variable. Diff: --- gcc/tree-vect-stmts.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index db1b539b6c74..1adc23c403fe 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -14744,7 +14744,6 @@ supportable_indirect_convert_operation (code_helper code, bool found_mode = false; scalar_mode lhs_mode = GET_MODE_INNER (TYPE_MODE (vectype_out)); scalar_mode rhs_mode = GET_MODE_INNER (TYPE_MODE (vectype_in)); - opt_scalar_mode mode_iter; tree_code tc1, tc2, code1, code2; tree cvt_type = NULL_TREE;
[gcc r16-1703] RISC-V: Add comment and reorder the the include files in riscv.md [NFC]
https://gcc.gnu.org/g:14035a14aac24fb60bf7bbc803d7275fc32fdcae commit r16-1703-g14035a14aac24fb60bf7bbc803d7275fc32fdcae Author: Kito Cheng Date: Thu Jun 26 14:26:57 2025 +0800 RISC-V: Add comment and reorder the the include files in riscv.md [NFC] This patch adds a comment to the riscv.md file to clarify the purpose of the file and reorders the include files for better organization. gcc/ChangeLog: * config/riscv/riscv.md: Add comment and reorder include files. Diff: --- gcc/config/riscv/riscv.md | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 3406b50518ed..04b8cc92cd60 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4860,6 +4860,7 @@ { operands[3] = GEN_INT (BITS_PER_WORD - exact_log2 (INTVAL (operands[3]) + 1)); }) +;; Standard extensions and pattern for optimization (include "bitmanip.md") (include "crypto.md") (include "sync.md") @@ -4867,19 +4868,21 @@ (include "sync-ztso.md") (include "peephole.md") (include "pic.md") -(include "generic.md") -(include "sifive-7.md") -(include "sifive-p400.md") -(include "sifive-p600.md") -(include "thead.md") -(include "generic-vector-ooo.md") -(include "generic-ooo.md") -(include "vector.md") (include "vector-crypto.md") (include "vector-bfloat16.md") (include "zicond.md") (include "sfb.md") (include "zc.md") +(include "vector.md") +;; Vendor extensions +(include "thead.md") (include "corev.md") +;; Pipeline models +(include "generic.md") (include "xiangshan.md") (include "mips-p8700.md") +(include "sifive-7.md") +(include "sifive-p400.md") +(include "sifive-p600.md") +(include "generic-vector-ooo.md") +(include "generic-ooo.md")
[gcc r16-1704] lto-ltrans-cache: Remove unused private member
https://gcc.gnu.org/g:9a402db6ed749dc14429e2598ab586074f1796c6 commit r16-1704-g9a402db6ed749dc14429e2598ab586074f1796c6 Author: Martin Jambor Date: Thu Jun 26 11:34:46 2025 +0200 lto-ltrans-cache: Remove unused private member When building GCC with clang, it warns that the private member suffix in class ltrans_file_cache (defined in lto-ltrans-cache.h) is not used which indeed looks like it is the case. This patch therefore removes it along with its initialization in the constructor. gcc/ChangeLog: 2025-06-24 Martin Jambor * lto-ltrans-cache.h (class ltrans_file_cache): Remove member prefix. * lto-ltrans-cache.cc (ltrans_file_cache::ltrans_file_cache): Do not initialize member prefix. Diff: --- gcc/lto-ltrans-cache.cc | 3 +-- gcc/lto-ltrans-cache.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/gcc/lto-ltrans-cache.cc b/gcc/lto-ltrans-cache.cc index c57775fae851..91af6ed6f823 100644 --- a/gcc/lto-ltrans-cache.cc +++ b/gcc/lto-ltrans-cache.cc @@ -210,8 +210,7 @@ write_cache_item (FILE* f, ltrans_file_cache::item *item, const char* dir) ltrans_file_cache::ltrans_file_cache (const char* dir, const char* prefix, const char* suffix, size_t soft_cache_size): - dir (dir), prefix (prefix), suffix (suffix), - soft_cache_size (soft_cache_size) + dir (dir), suffix (suffix), soft_cache_size (soft_cache_size) { if (!dir) return; diff --git a/gcc/lto-ltrans-cache.h b/gcc/lto-ltrans-cache.h index 5fef44bae538..fdb7a3894359 100644 --- a/gcc/lto-ltrans-cache.h +++ b/gcc/lto-ltrans-cache.h @@ -122,8 +122,7 @@ private: std::map map_checksum; std::map map_input; - /* Cached filenames are in format "prefix%d[.ltrans]suffix". */ - const char* prefix; + /* Cached filenames are in format "cache_prefix%d[.ltrans]suffix". */ const char* suffix; /* If cache items count is larger, prune deletes old items. */
[gcc r16-1705] RISC-V: Fix build issue
https://gcc.gnu.org/g:7c67f7f8d4c8aadbe8efd733c29d13bfcbb0f50f commit r16-1705-g7c67f7f8d4c8aadbe8efd733c29d13bfcbb0f50f Author: Kito Cheng Date: Thu Jun 26 14:35:47 2025 +0800 RISC-V: Fix build issue Apparently I forgot to squash this fix into the previous commit before I push... gcc/ChangeLog: * config/riscv/riscv.md: Fix build issue. Diff: --- gcc/config/riscv/riscv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 04b8cc92cd60..893c925b6b94 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4868,12 +4868,12 @@ (include "sync-ztso.md") (include "peephole.md") (include "pic.md") +(include "vector.md") (include "vector-crypto.md") (include "vector-bfloat16.md") (include "zicond.md") (include "sfb.md") (include "zc.md") -(include "vector.md") ;; Vendor extensions (include "thead.md") (include "corev.md")
[gcc r16-1696] Fortran: Fix out of bounds access in structure constructor's clean up [PR120711]
https://gcc.gnu.org/g:dff66a690f6d47963e5cb96677d0e194b85948fa commit r16-1696-gdff66a690f6d47963e5cb96677d0e194b85948fa Author: Andre Vehreschild Date: Wed Jun 25 09:12:35 2025 +0200 Fortran: Fix out of bounds access in structure constructor's clean up [PR120711] A structure constructor's generated clean up code was using an offset variable, which was manipulated before the clean up was run leading to an out of bounds access. PR fortran/120711 gcc/fortran/ChangeLog: * trans-array.cc (gfc_trans_array_ctor_element): Store the value of the offset for reuse. gcc/testsuite/ChangeLog: * gfortran.dg/asan/array_constructor_1.f90: New test. Diff: --- gcc/fortran/trans-array.cc | 10 ++ .../gfortran.dg/asan/array_constructor_1.f90 | 23 ++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 3d274439895d..7be2d7b11a62 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -1991,14 +1991,17 @@ static void gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc, tree offset, gfc_se * se, gfc_expr * expr) { - tree tmp; + tree tmp, offset_eval; gfc_conv_expr (se, expr); /* Store the value. */ tmp = build_fold_indirect_ref_loc (input_location, gfc_conv_descriptor_data_get (desc)); - tmp = gfc_build_array_ref (tmp, offset, NULL); + /* The offset may change, so get its value now and use that to free memory. + */ + offset_eval = gfc_evaluate_now (offset, &se->pre); + tmp = gfc_build_array_ref (tmp, offset_eval, NULL); if (expr->expr_type == EXPR_FUNCTION && expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp) @@ -3150,8 +3153,7 @@ finish: the reference. */ if ((expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS) && finalblock.head != NULL_TREE) -gfc_add_block_to_block (&loop->post, &finalblock); - +gfc_prepend_expr_to_block (&loop->post, finalblock.head); } diff --git a/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 b/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 new file mode 100644 index ..45eafacd5a67 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/asan/array_constructor_1.f90 @@ -0,0 +1,23 @@ +!{ dg-do run } + +! Contributed by Christopher Albert + +program grow_type_array +type :: container +integer, allocatable :: arr(:) +end type container + +type(container), allocatable :: list(:) + +list = [list, new_elem(5)] + +deallocate(list) + +contains + +type(container) function new_elem(s) result(out) +integer :: s +allocate(out%arr(s)) +end function new_elem + +end program grow_type_array
[gcc r16-1697] Fortran: Fix wasting memory in coarray single mode.
https://gcc.gnu.org/g:84947575bd0281cd4d99f1a31029ca4da11fc997 commit r16-1697-g84947575bd0281cd4d99f1a31029ca4da11fc997 Author: Andre Vehreschild Date: Wed Jun 25 12:27:04 2025 +0200 Fortran: Fix wasting memory in coarray single mode. gcc/fortran/ChangeLog: * resolve.cc (resolve_fl_derived0): Do not create the token component when not in coarray lib mode. * trans-types.cc: Do not access the token when not in coarray lib mode. Diff: --- gcc/fortran/resolve.cc | 4 ++-- gcc/fortran/trans-types.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 7089e4f171d1..58f7aee29c35 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -16841,8 +16841,8 @@ resolve_fl_derived0 (gfc_symbol *sym) return false; /* Now add the caf token field, where needed. */ - if (flag_coarray != GFC_FCOARRAY_NONE - && !sym->attr.is_class && !sym->attr.vtype) + if (flag_coarray == GFC_FCOARRAY_LIB && !sym->attr.is_class + && !sym->attr.vtype) { for (c = sym->components; c; c = c->next) if (!c->attr.dimension && !c->attr.codimension diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index e15b1bb89f01..1754d9821532 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -3187,7 +3187,7 @@ copy_derived_types: for (c = derived->components; c; c = c->next) { /* Do not add a caf_token field for class container components. */ - if ((codimen || coarray_flag) && !c->attr.dimension + if (codimen && coarray_flag && !c->attr.dimension && !c->attr.codimension && (c->attr.allocatable || c->attr.pointer) && !derived->attr.is_class) {
[gcc r16-1698] Fortran: Prevent creation of unused tree.
https://gcc.gnu.org/g:24940ad1534aa71ed74cf059982446c6df1f3f74 commit r16-1698-g24940ad1534aa71ed74cf059982446c6df1f3f74 Author: Andre Vehreschild Date: Wed Jun 25 12:27:35 2025 +0200 Fortran: Prevent creation of unused tree. gcc/fortran/ChangeLog: * trans.cc (gfc_allocate_using_malloc): Prevent possible memory leak when allocation was already done. Diff: --- gcc/fortran/trans.cc | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index fdeb1e89a765..13fd5ad498da 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -822,6 +822,7 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree pointer, tree tmp, error_cond; stmtblock_t on_error; tree status_type = status ? TREE_TYPE (status) : NULL_TREE; + bool cond_is_true = cond == boolean_true_node; /* If successful and stat= is given, set status to 0. */ if (status != NULL_TREE) @@ -834,11 +835,13 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree pointer, tmp = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size, build_int_cst (size_type_node, 1)); - tmp = build_call_expr_loc (input_location, -builtin_decl_explicit (BUILT_IN_MALLOC), 1, tmp); - if (cond == boolean_true_node) + if (!cond_is_true) +tmp = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_MALLOC), 1, tmp); + else tmp = alt_alloc; - else if (cond) + + if (!cond_is_true && cond) tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond, alt_alloc, tmp);
[gcc r16-1699] Add testcase for afdo offlining and fix two bugs
https://gcc.gnu.org/g:7b28a7dc9dfb277ef1f053dda84899837f8ed0c1 commit r16-1699-g7b28a7dc9dfb277ef1f053dda84899837f8ed0c1 Author: Jan Hubicka Date: Thu Jun 26 10:48:20 2025 +0200 Add testcase for afdo offlining and fix two bugs This patch adds a testcase that offlining works and profile info is not lost. While doing it I noticed a pasto that made the dump to be "afdo" and not "afdo_offline" and also that not all functions are processed as the range for does not expect new values to be put to the vector. Fixed thus. gcc/ChangeLog: * auto-profile.cc (function_instance::merge): Add TODO. (autofdo_source_profile::offline_external_functions): Do not use range for on the worklist. * timevar.def (TV_IPA_AUTOFDO_OFFLINE): New timevar. gcc/testsuite/ChangeLog: * gcc.dg/tree-prof/afdo-crossmodule-1.c: New test. * gcc.dg/tree-prof/afdo-crossmodule-1b.c: New test. Diff: --- gcc/auto-profile.cc| 93 -- .../gcc.dg/tree-prof/afdo-crossmodule-1.c | 29 +++ .../gcc.dg/tree-prof/afdo-crossmodule-1b.c | 10 +++ gcc/timevar.def| 1 + 4 files changed, 90 insertions(+), 43 deletions(-) diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc index 3e0505ecd78e..d19afd73fae7 100644 --- a/gcc/auto-profile.cc +++ b/gcc/auto-profile.cc @@ -800,7 +800,11 @@ function_instance::merge (function_instance *other, Otherwise turn FN toplevel. Return true if new toplevel function was introduced. If new toplevel functions are created and NEW_FUNCTIONS != NULL, - add them to NEW_FUNCTIONS. */ + add them to NEW_FUNCTIONS. + + TODO: When offlining indirect call we lose information about the + call target. It should be possible to add it into + targets histogram. */ bool function_instance::offline (function_instance *fn, @@ -1118,46 +1122,49 @@ autofdo_source_profile::offline_external_functions () may introduce new functions by offlining. */ for (auto const &iter : map_) fns.safe_push (iter.second); - for (function_instance *f : fns) -if (!seen.contains (afdo_string_table->get_index - (afdo_string_table->get_name (f->name () - { - f->offline_if_in_set (seen, fns); - if (dump_file) - fprintf (dump_file, "Removing external %s\n", - afdo_string_table->get_name (f->name ())); - map_.erase (afdo_string_table->get_index - (afdo_string_table->get_name (f->name (; - delete f; - } -else - { - f->remove_external_functions (seen, to_symbol_name, fns); - int index = afdo_string_table->get_index - (afdo_string_table->get_name (f->name ())); - int *newn = to_symbol_name.get (index); - if (newn) - { - if (map_.count (*newn)) - { - if (dump_file) - fprintf (dump_file, "Merging duplicate symbol %s\n", - afdo_string_table->get_name (f->name ())); - function_instance *to = map_[index]; - if (to != f) - { - map_[index]->merge (f); - delete f; - } - } - else - { - auto iter = map_.find (index); - map_[*newn] = iter->second; - map_.erase (iter); - } - } - } + for (unsigned int i = 0; i < fns.length (); i++) +{ + function_instance *f = fns[i]; + if (!seen.contains (afdo_string_table->get_index + (afdo_string_table->get_name (f->name () + { + f->offline_if_in_set (seen, fns); + if (dump_file) + fprintf (dump_file, "Removing external %s\n", +afdo_string_table->get_name (f->name ())); + map_.erase (afdo_string_table->get_index + (afdo_string_table->get_name (f->name (; + delete f; + } + else + { + f->remove_external_functions (seen, to_symbol_name, fns); + int index = afdo_string_table->get_index + (afdo_string_table->get_name (f->name ())); + int *newn = to_symbol_name.get (index); + if (newn) + { + if (map_.count (*newn)) + { + if (dump_file) + fprintf (dump_file, "Merging duplicate symbol %s\n", +afdo_string_table->get_name (f->name ())); + function_instance *to = map_[index]; + if (to != f) + { + map_[index]->merge (f); + delete f; + } + } + else + { + auto iter = map_.find (index); +
[gcc(refs/users/mikael/heads/unwrap_non_lvalue_v08)] match: Unwrap non-lvalue as unary or binary operand
https://gcc.gnu.org/g:96a657775713c5f99ed5fbdfd240b66797dc0c6e commit 96a657775713c5f99ed5fbdfd240b66797dc0c6e Author: Mikael Morin Date: Thu Jul 4 15:24:36 2024 +0200 match: Unwrap non-lvalue as unary or binary operand This change makes the binary and unary folding functions return a tree whose operands have their non-lvalue wrapper stripped (if they had one). It only makes a difference if the function hasn't found any simplification and would return NULL_TREE. It moves all early NULL_TREE return to the end of the function where a last resort common simplification attempt is made. That attempt checks whether the implicit simplifications contained in the stripped operands are worth keeping, and returns a new tree based on the stripped operands in that case. This requires the original tree code to remain unmodified until the end of the function, so the code variable is renamed to a new variable in an area where a modified value was used. The testcases are best effort; for some operators the fortran frontend generates a temporary variable, so the simplification doesn't happen. Those cases are not tested. gcc/ChangeLog: * fold-const.cc (stripped_converted_equals_original): New. (fold_binary_loc): Check whether the initial stripping of operands was a simplification worth keeping before returning NULL_TREE, and rebuild a new tree based on the stripped operands in that case. (fold_unary_loc): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/non_lvalue_2.f90: New test. * gfortran.dg/non_lvalue_3.f90: New test. Diff: --- gcc/fold-const.cc | 139 +++ gcc/testsuite/gfortran.dg/non_lvalue_2.f90 | 58 ++ gcc/testsuite/gfortran.dg/non_lvalue_3.f90 | 172 + 3 files changed, 326 insertions(+), 43 deletions(-) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 014f42187932..db0fc0ae3efe 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -9181,6 +9181,21 @@ build_fold_addr_expr_loc (location_t loc, tree t) return build_fold_addr_expr_with_type_loc (loc, t, ptrtype); } +/* Tells whether tree ORIGINAL is equal to what would be produced if + converting its nop-stripped subtree STRIPPED to its type. */ + +static inline bool +stripped_converted_equals_original (const_tree stripped, const_tree original) +{ + if (stripped == original) +return true; + + if (TREE_TYPE (stripped) == TREE_TYPE (original)) +return false; + + return TREE_OPERAND (original, 0) == stripped; +} + /* Fold a unary expression of code CODE and type TYPE with operand OP0. Return the folded expression if folding is successful. Otherwise, return NULL_TREE. */ @@ -9299,7 +9314,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) case NON_LVALUE_EXPR: if (!maybe_lvalue_p (op0)) return fold_convert_loc (loc, type, op0); - return NULL_TREE; + break; CASE_CONVERT: case FLOAT_EXPR: @@ -9437,7 +9452,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) && sanitize_flags_p (SANITIZE_ALIGNMENT) && (min_align_of_type (TREE_TYPE (type)) > min_align_of_type (TREE_TYPE (TREE_TYPE (arg00) - return NULL_TREE; + break; /* Similarly, avoid this optimization in GENERIC for -fsanitize=null when type is a reference type and arg00's type is not, @@ -9447,7 +9462,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) && !in_gimple_form && sanitize_flags_p (SANITIZE_NULL) && TREE_CODE (TREE_TYPE (arg00)) != REFERENCE_TYPE) - return NULL_TREE; + break; arg00 = fold_convert_loc (loc, type, arg00); return fold_build_pointer_plus_loc (loc, arg00, arg01); @@ -9496,7 +9511,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) } } - return NULL_TREE; + break; case VIEW_CONVERT_EXPR: if (TREE_CODE (op0) == MEM_REF) @@ -9509,13 +9524,13 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) return tem; } - return NULL_TREE; + break; case NEGATE_EXPR: tem = fold_negate_expr (loc, arg0); if (tem) return fold_convert_loc (loc, type, tem); - return NULL_TREE; + break; case ABS_EXPR: /* Convert fabs((double)float) into (double)fabsf(float). */ @@ -9529,7 +9544,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) TREE_TYPE (targ0), targ0)); } - return NULL_TREE; +
[gcc] Created branch 'mikael/heads/unwrap_non_lvalue_v08' in namespace 'refs/users'
The branch 'mikael/heads/unwrap_non_lvalue_v08' was created in namespace 'refs/users' pointing to: 96a657775713... match: Unwrap non-lvalue as unary or binary operand
[gcc r15-9866] Bump LTO_minor_version
https://gcc.gnu.org/g:8d600e98004b63e788614fc8958cbafbc1bb52c0 commit r15-9866-g8d600e98004b63e788614fc8958cbafbc1bb52c0 Author: Richard Biener Date: Thu Jun 26 08:53:01 2025 +0200 Bump LTO_minor_version At least my introduction of a new --param made raising the LTO IL minor necessary, so do it now, also in preparation for GCC 15.2. * lto-streamer.h (LTO_minor_version): Bump to 1. Diff: --- gcc/lto-streamer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 4b7209e3d82d..8c1d2d4947d6 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -122,7 +122,7 @@ along with GCC; see the file COPYING3. If not see form followed by the data for the string. */ #define LTO_major_version GCC_major_version -#define LTO_minor_version 0 +#define LTO_minor_version 1 typedef unsigned char lto_decl_flags_t;
[gcc r16-1695] Avoid some lost AFDO profiles with LTO
https://gcc.gnu.org/g:884030d2de767c491223c9cfcf2dd14fdfa93df4 commit r16-1695-g884030d2de767c491223c9cfcf2dd14fdfa93df4 Author: Jan Hubicka Date: Thu Jun 26 09:06:52 2025 +0200 Avoid some lost AFDO profiles with LTO This patch fixes some of cases where we lose profile info because we do not perform inlining that happened at train run before AFDO annotation is done. This is a common problem with LTO in the case cross-module inlining happened. I added afdo_offline pass that does two things: 1) collect set of all functions defined in current unit 2) walk all toplevel function instances. If function instance correspond to a defined symbol, walk everything inlined to it. If crossmodule inlining is seen, remove the inline instances and recursively look into inline instnaces that go back to the current unit and turn them to offline ones If function instance corresponds to external symbol, remove it but also look for functions inlined to it that belong to current module. When merging profile we also need to recursively merge profiles of inlined functions and if the inlining decisins does not match, offline the bodies. This is somewhat fragile since recursive calls may trigger modifications of functions currently being merged, but I hope I chased away problems with that - will give it a second tought to see if this can be reorganized into a worklist fashion that is more safe. I noticed that functions may appear in the afdo data either as their symbol name or dwarf name (since inline functions may not have known symbol name). There is already some logic to handle that but it is broken in the case both names are used. To mitigate the problem I also added logic to translate dwarf names to symbol names in case both are used. This prevents profile loss i.e. in exchange2. Here digits_2 function appears by its dwarf name (digits_2) but also is clonned which makes it to appear by its symbol name (__*digits_2) All profile massaging is done before early optimization so the VPT targets of offline bodies are correct. We still will lose profile if early inlining fails. I will add second pass to afdo to offline these. Last problem is that in case we early inlined more than expected (which now happens more often due to offlining) the profile will be lost and filled by static profile. Problem here is that we need to somehow scale the profile of inline instance but I do not see how to determine invocation counts. Will try to look into that incrementally - perhaps we can keep some info from offlining. There is also now a dump infrastructure that prints the proflie in a the same format as dump_gcov tool. autoprofiledbootstraped, regsted x86_64-linux, will commit it shortly. Honza gcc/ChangeLog: * auto-profile.cc (name_index_set, name_index_map): New types. (dump_afdo_loc): New function. (dump_inline_stack): Simplify. (function_instance::merge): Merge recursively inlined functions; offline if necessary; collect new fnctions. (function_instance::offline): New member function. (function_instance::offline_if_in_set): New member function. (function_instance::remove_external_functions): New member function. (function_instance::dump): New member function. (function_instance::debug): New member function. (function_instance::dump_inline_stack): New member function. (function_instance::find_icall_target_map): Use removed_icall_target. (function_instance::remove_icall_target): Only mark icall target removed. (autofdo_source_profile::offline_external_functions): New function. (function_instance::read_function_instance): Record inlined_to pointers; use -1 for unknown head counts. (autofdo_source_profile::get_function_instance_by_name_index): New function. (autofdo_source_profile::add_function_instance): New member function. (autofdo_source_profile::read): Do not leak memory; fix formatting. (read_profile): Fix formatting. (afdo_annotate_cfg): LIkewise. (class pass_ipa_auto_profile_offline): New pass. (make_pass_ipa_auto_profile_offline): New function. * passes.def (pass_ipa_auto_profile_offline): Add * tree-pass.h (make_pass_ipa_auto_profile): Declare gcc/testsuite/ChangeLog: * gcc.dg/tree-prof/indir-call-prof-2.c: Update template. Diff: --- gcc/auto-profile.cc| 611 - gcc/passes.def | 1 + gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-2.c | 6 +-
[gcc/aoliva/heads/lra-elim-fp2sp] (634 commits) [lra] catch all to-sp eliminations with nonzero offsets [PR
The branch 'aoliva/heads/lra-elim-fp2sp' was updated to point to: 6d0055d14fc6... [lra] catch all to-sp eliminations with nonzero offsets [PR It previously pointed to: efab6fca... [lra] catch all to-sp eliminations Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- efa... [lra] catch all to-sp eliminations f879601... [lra] apply elimination offsets to MEM in autoinc address [ f93660a... [lra] reorder operations in lra_update_fp2sp_elimination [P 7057f17... [lra] rework deactivation of fp2sp elimination [PR120424] ed2c07a... [lra] recompute ranges upon disabling fp2sp elimination [PR 89620fe... [genoutput] mark scratch outputs as eliminable [PR120424] 440d462... [lra] inactivate disabled fp2sp elimination [PR120424] 026509b... [arm] require armv7 support for [PR120424] Summary of changes (added commits): --- 6d0055d... [lra] catch all to-sp eliminations with nonzero offsets [PR (*) d2127e0... [lra] apply elimination offsets to MEM in autoinc address [ (*) 2b80b7c... [lra] reorder operations in lra_update_fp2sp_elimination [P (*) f650e38... [lra] rework deactivation of fp2sp elimination [PR120424] (*) baeb74e... [lra] recompute ranges upon disabling fp2sp elimination [PR (*) 7bba784... [genoutput] mark scratch outputs as eliminable [PR120424] (*) 686ffe5... [lra] inactivate disabled fp2sp elimination [PR120424] (*) 0bd63f1... [arm] require armv7 support for [PR120424] (*) 407ae3a... Daily bump. (*) b8b08a8... x86: Add debug dump for the remove_redundant_vector pass (*) 5fd8f33... arc: Use intrinsics for __builtin_mul_overflow () (*) 49943c2... arc: Add commutative multiplication patterns (*) 913d8cb... arc: testsuite: Scan rlc instead of mov.hs (*) b9361e5... ARC: Use intrinsics for __builtin_sub_overflow*() (*) 467fa6d... ARC: Use intrinsics for __builtin_add_overflow*() (*) 6af1e74... diagnostics: Mark path_label::get_effects as final override (*) a73cb70... ranger-op: Use CFN_ constant instead of plain BUILTIN_ one (*) 00712ae... value-relation.h: Mark dom_oracle::next_relation as overrid (*) 2670d11... tree-ssa-propagate.h: Mark two functions as override (*) 85f0620... ranger: Mark several member functions as final override (*) 8b4b0f7... coroutines: Remove unused private member in cp_coroutine_tr (*) db5cda8... Mark pass_sccopy gate and execute functions as final overri (*) fb1ba48... Mark rtl_avoid_store_forwarding functions final override (*) c08d6d9... Remove unused vector in value-relation.cc. (*) ec44df7... Promote verify_range to vrange. (*) 3b84d18... get_bitmask is sometimes less refined. (*) 5aca851... tree-optimization/109892 - SLP reduction of fma (*) 143e50f... tree-optimization/120808 - SLP build with mixed .FMA/.FMS (*) e7ff8e8... ivopts: Change constant_multiple_of to expand aff nodes. (*) 1bac0fc... libstdc++: Test for %S precision for durations with integra (*) 76f7f91... rtl-ssa: Rewrite process_uses_of_deleted_def [PR120745] (*) 190... libstdc++: Report compilation error on formatting "%d" from (*) 7fd6cb3... x86: Update -mtune=intel for Diamond Rapids/Clearwater Fore (*) 0c701c7... i386: Remove CLDEMOTE for clients (*) e858dc7... RISC-V: Add Profiles RVA/B23S64 support. (*) aaf55e0... Add -fauto-profile-inlining (*) 3fde750... Remove early inlining from afdo pass (*) 3924740... Daily bump. (*) 750bc28... gcn: Fix glc vs. sc0 handling for scalar memory access (*) 1e35a51... Fortran/OpenACC: Add Fortran support for acc_attach/acc_det (*) 92e1893... RISC-V: Add patterns for vector-scalar multiply-(subtract-) (*) 5bc9271... Fortran: fix ICE in verify_gimple_in_seq with substrings [P (*) ed7fc2b... c++: Implement C++26 P3618R0 - Allow attaching main to the (*) 8f5fac5... i386: Convert LEA stack adjust insn to SUB when FLAGS_REG i (*) 63076db... Remove non-SLP path from vectorizable_load (*) 3f19867... diagnostic: fix for older version of GCC (*) bc8f542... libstdc++: Unnecessary type completion in __is_complete_or_ (*) 0606d2b... gcc: remove atan from edom_only_function (*) bd9cac1... s390: Fix float vector extract for pre-z13 (*) f60d3f5... AArch64: promote aarch64-autovec-peference to mautovec-pref (*) 8e80287... AArch64: propose -mmax-vectorization as an option to overri (*) 3f88230... fortran: Mention user variable in SELECT TYPE temporary var (*) c06979f... Don't duplicate setup code cost when do group-candidate cos (*) 7f87bfa... middle-end: Apply loop->unroll directly in vectorizer (*) 309dbce... middle-end: replace log_vf usages with vf to allow support (*) aba3b9d... x86: Extend the remove_redundant_vector pass (*) d073bb6... x86: Update memcpy/memset inline strategies for -mtune=gene (*) 0235b6d... Copy discriminators when inlining (*) c24eb5e... Fix AFDO zero profile handling (*) 4b739c0... Fix shri
[gcc/aoliva/heads/testme] (8 commits) [lra] catch all to-sp eliminations with nonzero offsets [PR
The branch 'aoliva/heads/testme' was updated to point to: 6d0055d14fc6... [lra] catch all to-sp eliminations with nonzero offsets [PR It previously pointed to: b7cc7ea036b6... [testsuite] restore default action from dfp.exp [PR120631] Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- b7cc7ea... [testsuite] restore default action from dfp.exp [PR120631] Summary of changes (added commits): --- 6d0055d... [lra] catch all to-sp eliminations with nonzero offsets [PR (*) d2127e0... [lra] apply elimination offsets to MEM in autoinc address [ (*) 2b80b7c... [lra] reorder operations in lra_update_fp2sp_elimination [P (*) f650e38... [lra] rework deactivation of fp2sp elimination [PR120424] (*) baeb74e... [lra] recompute ranges upon disabling fp2sp elimination [PR (*) 7bba784... [genoutput] mark scratch outputs as eliminable [PR120424] (*) 686ffe5... [lra] inactivate disabled fp2sp elimination [PR120424] (*) 0bd63f1... [arm] require armv7 support for [PR120424] (*) (*) This commit already exists in another branch. Because the reference `refs/users/aoliva/heads/testme' matches your hooks.email-new-commits-only configuration, no separate email is sent for this commit.
[gcc r16-1717] pru: Split 64-bit moves into a sequence of 32-bit moves
https://gcc.gnu.org/g:a1c592be501b12942181391cb6a7e3cca54e4e45 commit r16-1717-ga1c592be501b12942181391cb6a7e3cca54e4e45 Author: Dimitar Dimitrov Date: Sun Feb 9 17:55:03 2025 +0200 pru: Split 64-bit moves into a sequence of 32-bit moves The 64-bit register-to-register moves on PRU are implemented with two instructions moving 32-bit registers. Defining a split for the 64-bit moves allows this to be described in RTL, and thus one of the 32-bit moves to be eliminated if the destination register is dead. Also, split the loading of non-trivial 64-bit integer constants. The resulting 32-bit integer constants have better chance to be loaded with something more optimal than an "ldi32". For now do the splits only after register allocation, because LRA does not yet efficiently handle subregs. See https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651366.html This patch shows slight improvement for wikisort benchmark from embench-iot: Benchmark size-before size-after difference - --- -- -- aha-mont64 1,648 1,648 0 crc32 104 104 0 depthconv 1,172 1,172 0 edn 3,040 3,040 0 huffbench 1,616 1,616 0 matmult-int 748 748 0 md5sum700 700 0 nettle-aes 2,664 2,664 0 nettle-sha256 5,732 5,732 0 nsichneu 21,372 21,372 0 picojpeg9,716 9,716 0 qrduino 8,556 8,556 0 sglib-combined 3,724 3,724 0 slre3,488 3,488 0 statemate 1,132 1,132 0 tarfind 652 652 0 ud 1,004 1,004 0 wikisort 18,120 18,092 -28 xgboost 300 300 0 gcc/ChangeLog: * config/pru/pru.md (reg move splitter): New splitter for 64-bit register moves into two 32-bit moves. (const_int move splitter): New splitter for 64-bit constant integer moves into two 32-bit moves. gcc/testsuite/ChangeLog: * gcc.target/pru/mov64-subreg-1.c: New test. * gcc.target/pru/mov64-subreg-2.c: New test. Signed-off-by: Dimitar Dimitrov Diff: --- gcc/config/pru/pru.md | 77 +++ gcc/testsuite/gcc.target/pru/mov64-subreg-1.c | 9 gcc/testsuite/gcc.target/pru/mov64-subreg-2.c | 8 +++ 3 files changed, 94 insertions(+) diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md index fcd310613f50..3504e42e9002 100644 --- a/gcc/config/pru/pru.md +++ b/gcc/config/pru/pru.md @@ -283,6 +283,83 @@ [(set_attr "type" "st,ld,alu,alu,alu,alu,alu,alu") (set_attr "length" "4,4,4,4,8,8,8,16")]) +; Break 64-bit register-to-register moves into 32-bit moves. +; If only a subreg of the destination is used, this split would allow +; for the other 32-bit subreg of the DI register to be eliminated. +(define_split + [(set (match_operand:DI 0 "register_operand") + (match_operand:DI 1 "register_operand"))] + " + /* TODO - LRA does not yet handle subregs efficiently. + So it is profitable to split only after register allocation is + complete. + Once https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651366.html + is merged, this condition should be removed to allow splitting + before LRA. */ + reload_completed + /* Sign-extended paradoxical registers require expansion + of the proper pattern. We can do only zero extension here. */ + && (SUBREG_P (operands[1]) && paradoxical_subreg_p (operands[1]) + ? SUBREG_PROMOTED_VAR_P (operands[1]) + && SUBREG_PROMOTED_UNSIGNED_P (operands[1]) > 0 + : true)" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + " + rtx dst_lo = simplify_gen_subreg (SImode, operands[0], DImode, 0); + rtx dst_hi = simplify_gen_subreg (SImode, operands[0], DImode, 4); + rtx src_lo = simplify_gen_subreg (SImode, operands[1], DImode, 0); + rtx src_hi = simplify_gen_subreg (SImode, operands[1], DImode, 4); + + if (SUBREG_P (operands[1]) && paradoxical_subreg_p (operands[1])) +{ + gcc_assert (SUBREG_PROMOTED_VAR_P (operands[1])); + gcc_assert (SUBREG_PROMOTED_UNSIGNED_P (operands[1]) > 0); + + operands[0] = dst_lo; + operands[1] = src_lo; + operands[2] = dst_hi; + operands[3] = const0_rtx; +} + else if (!reg_overlap_mentioned_p (dst_lo, src_hi)) +{ + operands[0] = dst_lo; + operands[1] = src_lo; + operands[2] = dst_hi; + operands[3] = src_hi; +} + else +{ + operands[0] = dst_hi; + operands[1]
[gcc r16-1725] x86: Handle vector broadcast source
https://gcc.gnu.org/g:64c55a99746ef8efa37937ee0fef29de4f081f25 commit r16-1725-g64c55a99746ef8efa37937ee0fef29de4f081f25 Author: H.J. Lu Date: Thu Jun 26 10:05:30 2025 +0800 x86: Handle vector broadcast source Use the inner scalar mode of vector broadcast source in: (set (reg:V8DF 394) (vec_duplicate:V8DF (reg:V2DF 190 [ alpha ]))) to compute the vector mode for broadcast from vector source. gcc/ PR target/120830 * config/i386/i386-features.cc (ix86_get_vector_cse_mode): Handle vector broadcast source. gcc/testsuite/ PR target/120830 * g++.target/i386/pr120830.C: New test. Signed-off-by: H.J. Lu Diff: --- gcc/config/i386/i386-features.cc | 9 ++ gcc/testsuite/g++.target/i386/pr120830.C | 211 +++ 2 files changed, 220 insertions(+) diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index fb4a9ec9903b..054f8d5ddc82 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -3395,6 +3395,15 @@ make_pass_remove_partial_avx_dependency (gcc::context *ctxt) static machine_mode ix86_get_vector_cse_mode (unsigned int size, machine_mode smode) { + /* Use the inner scalar mode of vector broadcast source in: + + (set (reg:V8DF 394) + (vec_duplicate:V8DF (reg:V2DF 190 [ alpha ]))) + + to compute the vector mode for broadcast from vector source. + */ + if (VECTOR_MODE_P (smode)) +smode = GET_MODE_INNER (smode); scalar_mode s_mode = as_a (smode); poly_uint64 nunits = size / GET_MODE_SIZE (smode); machine_mode mode = mode_for_vector (s_mode, nunits).require (); diff --git a/gcc/testsuite/g++.target/i386/pr120830.C b/gcc/testsuite/g++.target/i386/pr120830.C new file mode 100644 index ..56e41e99e019 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr120830.C @@ -0,0 +1,211 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=znver4 -std=gnu++17" } */ + +typedef double __m128d __attribute__ ((__vector_size__ (16))); +typedef double __m512d __attribute__ ((__vector_size__ (64))); +enum +{ + ColMajor +}; +enum +{ + DefaultProduct +}; +template struct EigenBase +{ +}; +struct +{ + template + void + operator= (OtherDerived other) + { +call_assignment_no_alias (other); + } +} __trans_tmp_6; +template struct Product +{ +}; +template struct unpacket_traits; +template +Packet ploadu (const typename unpacket_traits::type *); +template +Packet pset1 (const typename unpacket_traits::type &); +struct Packet1cd +{ + Packet1cd (__m128d a) : v (a) {} + __m128d v; +}; +template <> struct unpacket_traits +{ + typedef int type; +}; +template <> +Packet1cd +ploadu (const int *from) +{ + return *( + __attribute__ ((__vector_size__ (2 * sizeof (double double *)from; +} +template <> +Packet1cd +pset1 (const int &from) +{ + return ploadu (&from); +} +struct Packet4cd +{ + Packet4cd (__m512d); +}; +template <> struct unpacket_traits +{ + typedef int type; +}; +__m512d pset1___trans_tmp_3; +template <> +Packet4cd +pset1 (const int &from) +{ + Packet1cd __trans_tmp_1 = pset1 (from); + __m512d __trans_tmp_2; + pset1___trans_tmp_3 = __builtin_ia32_broadcastf64x2_512_mask ( + __trans_tmp_1.v, __trans_tmp_2, -1); + return pset1___trans_tmp_3; +} +template struct assign_op +{ +}; +template struct Assignment; +assign_op call_assignment_no_alias_func; +EigenBase call_assignment_no_alias_dst; +template +void +call_assignment_no_alias (Src src) +{ + Assignment, Src, assign_op>::run ( + call_assignment_no_alias_dst, src, call_assignment_no_alias_func); +} +template +struct general_matrix_matrix_product; +struct blas_data_mapper +{ + blas_data_mapper (int *, int); +}; +template +struct gebp_kernel +{ + typedef LhsScalar ResScalar; + void operator() (const DataMapper &, const LhsScalar *, const RhsScalar *, + Index, Index, Index, ResScalar, Index = 1, Index = 1, + Index = 0, Index = 0); +}; +struct lhs_process_one_packet +{ + void + operator() (blas_data_mapper, const int *, const int *, int alpha, long, + long peelEnd, long, long, long, long, int, long, long, long, + long, long) + { +for (; peelEnd;) + pset1 (alpha); +pset1 (alpha); + } +}; +template +__attribute__ ((noinline)) void +gebp_kernel::operator() ( +const DataMapper &res, const LhsScalar *blockA, const RhsScalar *blockB, +Index rows, Index depth, Index cols, ResScalar alpha, Index, Index, Index, +Index) +{ + Index packet_cols4, peeled_mc2; + enum + { +pk + } peeled_kc; + int prefetch_res_offset; + lhs_process_one_packet p; + p (res, blockA, blockB, alpha, peeled_mc2, rows, 1, 1, 0, 0, + prefetch_res_offset, peeled_kc, pk, cols, depth, packet_cols4); +} +long parallelize_gemm_rows; +template +void +parallelize_gemm (Functor func) +{ + long ac
[gcc r16-1707] c++, libstdc++: Implement C++26 P2830R10 - Constexpr Type Ordering
https://gcc.gnu.org/g:29c7661c6f92d80f63a9a3cc37f3dc790a161f3f commit r16-1707-g29c7661c6f92d80f63a9a3cc37f3dc790a161f3f Author: Jakub Jelinek Date: Thu Jun 26 16:15:20 2025 +0200 c++, libstdc++: Implement C++26 P2830R10 - Constexpr Type Ordering The following patch attempts to implement the C++26 P2830R10 - Constexpr Type Ordering paper, with a minor change that std::type_order class template doesn't derive from integer_constant, because std::strong_ordering is not a structural type (except in MSVC), so instead it is just a class template with static constexpr strong_ordering value member and also value_type, type and 2 operators. The paper mostly talks about using something other than mangled names for the ordering, but given that the mangler is part of the GCC C++ FE, using the mangler seems to be the best ordering choice to me. 2025-06-26 Jakub Jelinek gcc/cp/ * cp-trait.def: Implement C++26 P2830R10 - Constexpr Type Ordering. (TYPE_ORDER): New. * method.cc (type_order_value): Define. * cp-tree.h (type_order_value): Declare. * semantics.cc (trait_expr_value): Use gcc_unreachable also for CPTK_TYPE_ORDER, adjust comment. (finish_trait_expr): Handle CPTK_TYPE_ORDER. * constraint.cc (diagnose_trait_expr): Likewise. gcc/testsuite/ * g++.dg/cpp26/type-order1.C: New test. * g++.dg/cpp26/type-order2.C: New test. * g++.dg/cpp26/type-order3.C: New test. libstdc++-v3/ * include/bits/version.def (type_order): New. * include/bits/version.h: Regenerate. * libsupc++/compare: Define __glibcxx_want_type_order before including bits/version.h. (std::type_order, std::type_order_v): New trait and template variable. * src/c++23/std.cc.in (std::type_order, std::type_order_v): Export. * testsuite/18_support/comparisons/type_order/1.cc: New test. Diff: --- gcc/cp/constraint.cc | 3 + gcc/cp/cp-trait.def| 1 + gcc/cp/cp-tree.h | 2 + gcc/cp/method.cc | 21 + gcc/cp/semantics.cc| 13 ++- gcc/testsuite/g++.dg/cpp26/type-order1.C | 94 + gcc/testsuite/g++.dg/cpp26/type-order2.C | 4 + gcc/testsuite/g++.dg/cpp26/type-order3.C | 8 ++ libstdc++-v3/include/bits/version.def | 10 +++ libstdc++-v3/include/bits/version.h| 10 +++ libstdc++-v3/libsupc++/compare | 23 ++ libstdc++-v3/src/c++23/std.cc.in | 4 + .../18_support/comparisons/type_order/1.cc | 95 ++ 13 files changed, 287 insertions(+), 1 deletion(-) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 17d20696e874..c8eef24d585c 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3266,6 +3266,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_RANK: inform (loc, " %qT cannot yield a rank", t1); break; +case CPTK_TYPE_ORDER: + inform (loc, " %qT and %qT cannot be ordered", t1, t2); + break; case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY: inform (loc, " %qT is not a reference that binds to a temporary " "object of type %qT (direct-initialization)", t1, t2); diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 2e3b4ca2892d..e71b28cb0a62 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -114,6 +114,7 @@ DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1) DEFTRAIT_TYPE (REMOVE_EXTENT, "__remove_extent", 1) DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1) DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1) +DEFTRAIT_EXPR (TYPE_ORDER, "__builtin_type_order", 2) DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1) DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4bf02a1890f7..8f81fe034e96 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7557,6 +7557,8 @@ extern bool ctor_omit_inherited_parms (tree); extern tree locate_ctor(tree); extern tree implicitly_declare_fn (special_function_kind, tree, bool, tree, tree); +extern tree type_order_value (tree, tree); + /* In module.cc */ class module_state; /* Forward declare. */ inline bool modules_p () { return flag_modules != 0; } diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 67a80a387ba7..1b9a1c8c9b1d 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -3951,5 +3951,26 @@ num_artificial_parms_for (const_tree fn) return count; } +/* Return value of the __builtin_type_order trait. */ + +
[gcc r16-1708] libstdc++: Implement C++26 P2927R3 - Inspecting exception_ptr
https://gcc.gnu.org/g:af5b72cf9f5640d24f28398b37c7208d6b2439ab commit r16-1708-gaf5b72cf9f5640d24f28398b37c7208d6b2439ab Author: Jakub Jelinek Date: Thu Jun 26 16:18:38 2025 +0200 libstdc++: Implement C++26 P2927R3 - Inspecting exception_ptr The following patch attempts to implement the C++26 P2927R3 - Inspecting exception_ptr paper (but not including P3748R0, I plan to play with it incrementally and it will really depend on the Constexpr exceptions patch). The function template is implemented using an out of line private method of exception_ptr, so that P3748R0 then can use if consteval and provide a constant evaluation variant of it. 2025-06-26 Jakub Jelinek * include/bits/version.def (exception_ptr_cast): Add. * include/bits/version.h: Regenerate. * libsupc++/exception: Define __glibcxx_want_exception_ptr_cast before including bits/version.h. * libsupc++/exception_ptr.h (std::exception_ptr_cast): Define. (std::__exception_ptr::exception_ptr::_M_exception_ptr_cast): Declare. * libsupc++/eh_ptr.cc (std::__exception_ptr::exception_ptr::_M_exception_ptr_cast): Define. * src/c++23/std.cc.in (std::exception_ptr_cast): Export. * config/abi/pre/gnu.ver: Export _ZNKSt15__exception_ptr13exception_ptr21_M_exception_ptr_castERKSt9type_info at CXXABI_1.3.17. * testsuite/util/testsuite_abi.cc (check_version): Allow CXXABI_1.3.17. * testsuite/18_support/exception_ptr/exception_ptr_cast.cc: New test. Diff: --- libstdc++-v3/config/abi/pre/gnu.ver| 10 +++ libstdc++-v3/include/bits/version.def | 8 +++ libstdc++-v3/include/bits/version.h| 10 +++ libstdc++-v3/libsupc++/eh_ptr.cc | 16 + libstdc++-v3/libsupc++/exception | 1 + libstdc++-v3/libsupc++/exception_ptr.h | 28 libstdc++-v3/src/c++23/std.cc.in | 3 + .../18_support/exception_ptr/exception_ptr_cast.cc | 81 ++ libstdc++-v3/testsuite/util/testsuite_abi.cc | 1 + 9 files changed, 158 insertions(+) diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index c36f1c347675..bba5705509c6 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -2899,6 +2899,16 @@ CXXABI_1.3.16 { } CXXABI_1.3.15; #endif +CXXABI_1.3.17 { +# std::exception_ptr::_M_exception_ptr_cast + _ZNKSt15__exception_ptr13exception_ptr21_M_exception_ptr_castERKSt9type_info; +} +#ifdef __riscv +CXXABI_1.3.16; +#else +CXXABI_1.3.15; +#endif + # Symbols in the support library (libsupc++) supporting transactional memory. CXXABI_TM_1 { diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index caec5d114479..f4ba501c403f 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -2022,6 +2022,14 @@ ftms = { }; }; +ftms = { + name = exception_ptr_cast; + values = { +v = 202506; +cxxmin = 26; + }; +}; + // Standard test specifications. stds[97] = ">= 199711L"; stds[03] = ">= 199711L"; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 2dc21b693656..dc8ac07be166 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -2263,4 +2263,14 @@ #endif /* !defined(__cpp_lib_type_order) && defined(__glibcxx_want_type_order) */ #undef __glibcxx_want_type_order +#if !defined(__cpp_lib_exception_ptr_cast) +# if (__cplusplus > 202302L) +# define __glibcxx_exception_ptr_cast 202506L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_exception_ptr_cast) +# define __cpp_lib_exception_ptr_cast 202506L +# endif +# endif +#endif /* !defined(__cpp_lib_exception_ptr_cast) && defined(__glibcxx_want_exception_ptr_cast) */ +#undef __glibcxx_want_exception_ptr_cast + #undef __glibcxx_want_all diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index 6512449a32cc..1fb35d82f539 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -220,4 +220,20 @@ std::rethrow_exception(std::exception_ptr ep) std::terminate(); } +const void* +std::__exception_ptr::exception_ptr::_M_exception_ptr_cast(const type_info& t) + const noexcept +{ + void *ptr = _M_exception_object; + if (__builtin_expect(ptr == nullptr, false)) +return nullptr; + __cxa_refcounted_exception *eh += __get_refcounted_exception_header_from_obj (_M_exception_object); + const type_info* __thr_type = eh->exc.exceptionType; + if (t.__do_catch(__thr_type, &ptr, 1)) +return ptr; + return nullptr; +} + + #undef _GLIBCXX_EH_PTR_COMPAT diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception index 8c3bb33c831b..61d
[gcc r16-1716] diagnostics: make 5 more fields of diagnostic_context private
https://gcc.gnu.org/g:c4d211bba2a86b90ee20a4f6f2cd1af1a036ee26 commit r16-1716-gc4d211bba2a86b90ee20a4f6f2cd1af1a036ee26 Author: David Malcolm Date: Thu Jun 26 13:29:36 2025 -0400 diagnostics: make 5 more fields of diagnostic_context private No functional change intended. gcc/ada/ChangeLog: * gcc-interface/misc.cc (gnat_init): Use diagnostic_context::set_internal_error_callback. gcc/c-family/ChangeLog: * c-opts.cc (c_common_diagnostics_set_defaults): Use diagnostic_context::set_permissive_option. gcc/cp/ChangeLog: * error.cc (cxx_initialize_diagnostics): Use diagnostic_context::set_adjust_diagnostic_info_callback. gcc/ChangeLog: * diagnostic.h (diagnostic_context::set_permissive_option): New. (diagnostic_context::set_fatal_errors): New. (diagnostic_context::set_internal_error_callback): New. (diagnostic_context::set_adjust_diagnostic_info_callback): New. (diagnostic_context::inhibit_notes): New. (diagnostic_context::m_opt_permissive): Make private. (diagnostic_context::m_fatal_errors): Likewise. (diagnostic_context::m_internal_error): Likewise. (diagnostic_context::m_adjust_diagnostic_info): Likewise. (diagnostic_context::m_inhibit_notes_p): Likewise. (diagnostic_inhibit_notes): Delete. * opts.cc (common_handle_option): Use diagnostic_context::set_fatal_errors. * toplev.cc (internal_error_function): Use diagnostic_context::set_internal_error_callback. (general_init): Likewise. (process_options): Use diagnostic_context::inhibit_notes. Signed-off-by: David Malcolm Diff: --- gcc/ada/gcc-interface/misc.cc | 2 +- gcc/c-family/c-opts.cc| 2 +- gcc/cp/error.cc | 2 +- gcc/diagnostic.h | 43 +-- gcc/opts.cc | 2 +- gcc/toplev.cc | 6 +++--- 6 files changed, 40 insertions(+), 17 deletions(-) diff --git a/gcc/ada/gcc-interface/misc.cc b/gcc/ada/gcc-interface/misc.cc index ca5c9a2163ee..128040e4d90d 100644 --- a/gcc/ada/gcc-interface/misc.cc +++ b/gcc/ada/gcc-interface/misc.cc @@ -377,7 +377,7 @@ gnat_init (void) line_table->default_range_bits = 0; /* Register our internal error function. */ - global_dc->m_internal_error = &internal_error_function; + global_dc->set_internal_error_callback (&internal_error_function); return true; } diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index 697518637df3..3ee9444cbefe 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -192,7 +192,7 @@ void c_common_diagnostics_set_defaults (diagnostic_context *context) { diagnostic_text_finalizer (context) = c_diagnostic_text_finalizer; - context->m_opt_permissive = OPT_fpermissive; + context->set_permissive_option (OPT_fpermissive); } /* Input charset configuration for diagnostics. */ diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 69da381a355b..abeb0285eec6 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -308,7 +308,7 @@ cxx_initialize_diagnostics (diagnostic_context *context) diagnostic_text_starter (context) = cp_diagnostic_text_starter; /* diagnostic_finalizer is already c_diagnostic_text_finalizer. */ context->set_format_decoder (cp_printer); - context->m_adjust_diagnostic_info = cp_adjust_diagnostic_info; + context->set_adjust_diagnostic_info_callback (cp_adjust_diagnostic_info); } /* Dump an '@module' name suffix for DECL, if it's attached to an import. */ diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index f9c8253395b9..9df429275f0b 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -842,6 +842,36 @@ public: void set_main_input_filename (const char *filename); + void + set_permissive_option (diagnostic_option_id opt_permissive) + { +m_opt_permissive = opt_permissive; + } + + void + set_fatal_errors (bool fatal_errors) + { +m_fatal_errors = fatal_errors; + } + + void + set_internal_error_callback (void (*cb) (diagnostic_context *, + const char *, + va_list *)) + { +m_internal_error = cb; + } + + void + set_adjust_diagnostic_info_callback (void (*cb) (diagnostic_context *, + diagnostic_info *)) + { +m_adjust_diagnostic_info = cb; + } + + void + inhibit_notes () { m_inhibit_notes_p = true; } + private: void error_recursion () ATTRIBUTE_NORETURN; @@ -911,6 +941,7 @@ public: /* True if permerrors are warnings. */ bool m_permissive; +private: /* The option to associate with turning permerrors into warnings, if any. */ diagnostic_option_id m_opt_permissive; @@ -918,6 +949,7 @@ public: /* True if er
[gcc r16-1715] diagnostics, testsuite: don't assume host has "dot" [PR120809]
https://gcc.gnu.org/g:0e7296540be35831e791ffe9f419cd6107831fc9 commit r16-1715-g0e7296540be35831e791ffe9f419cd6107831fc9 Author: David Malcolm Date: Thu Jun 26 13:28:50 2025 -0400 diagnostics, testsuite: don't assume host has "dot" [PR120809] gcc/ChangeLog: PR analyzer/120809 * diagnostic-format-html.cc (html_builder::maybe_make_state_diagram): Bulletproof against the SVG generation failing. * xml.cc (xml::printer::push_element): Assert that the ptr is nonnull. (xml::printer::append): Likewise. gcc/testsuite/ChangeLog: PR analyzer/120809 * gcc.dg/analyzer/state-diagram-5.c: Split out into... * gcc.dg/analyzer/state-diagram-5-html.c: ...this, adding dg-require-dot... * gcc.dg/analyzer/state-diagram-5-sarif.c: ...and this. Signed-off-by: David Malcolm Diff: --- gcc/diagnostic-format-html.cc | 3 +- .../{state-diagram-5.c => state-diagram-5-html.c} | 11 ++- .../gcc.dg/analyzer/state-diagram-5-sarif.c| 35 ++ gcc/xml.cc | 2 ++ 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/gcc/diagnostic-format-html.cc b/gcc/diagnostic-format-html.cc index 1f5c138bcd08..473880fce245 100644 --- a/gcc/diagnostic-format-html.cc +++ b/gcc/diagnostic-format-html.cc @@ -632,7 +632,8 @@ html_builder::maybe_make_state_diagram (const diagnostic_event &event) // Turn the .dot into SVG and splice into place auto svg = dot::make_svg_from_graph (*graph); - xp.append (std::move (svg)); + if (svg) +xp.append (std::move (svg)); return wrapper; } diff --git a/gcc/testsuite/gcc.dg/analyzer/state-diagram-5.c b/gcc/testsuite/gcc.dg/analyzer/state-diagram-5-html.c similarity index 64% rename from gcc/testsuite/gcc.dg/analyzer/state-diagram-5.c rename to gcc/testsuite/gcc.dg/analyzer/state-diagram-5-html.c index 8e00cac06863..274a951769e9 100644 --- a/gcc/testsuite/gcc.dg/analyzer/state-diagram-5.c +++ b/gcc/testsuite/gcc.dg/analyzer/state-diagram-5-html.c @@ -1,4 +1,4 @@ -/* { dg-additional-options "-fdiagnostics-add-output=sarif:xml-state=yes" } */ +/* { dg-require-dot "" } */ /* { dg-additional-options "-fdiagnostics-add-output=experimental-html:javascript=no,show-state-diagrams=yes" } */ /* { dg-additional-options "-fdiagnostics-show-caret" } */ @@ -36,13 +36,6 @@ void test (void) __analyzer_dump_path (); { dg-end-multiline-output "" } */ -/* Verify that some JSON was written to a file with the expected name. */ -/* { dg-final { verify-sarif-file } } */ - -/* Use a Python script to verify various properties about the generated - .sarif file: - { dg-final { run-sarif-pytest state-diagram-5.c "state-diagram-5-sarif.py" } } */ - /* Use a Python script to verify various properties about the generated .html file: - { dg-final { run-html-pytest state-diagram-5.c "state-diagram-5-html.py" } } */ + { dg-final { run-html-pytest state-diagram-5-html.c "state-diagram-5-html.py" } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/state-diagram-5-sarif.c b/gcc/testsuite/gcc.dg/analyzer/state-diagram-5-sarif.c new file mode 100644 index ..28cf58042306 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/state-diagram-5-sarif.c @@ -0,0 +1,35 @@ +/* { dg-additional-options "-fdiagnostics-add-output=sarif:xml-state=yes" } */ + +#include "analyzer-decls.h" + +struct foo +{ + int m_ints[4]; +}; + +struct bar +{ + struct foo m_foos[3]; + int m_int; + char m_ch; +}; + +struct baz +{ + struct bar m_bars[2]; + struct foo m_foos[5]; +}; + +void test (void) +{ + struct baz baz_arr[2]; + baz_arr[1].m_bars[1].m_foos[2].m_ints[1] = 42; + __analyzer_dump_path (); /* { dg-message "path" } */ +} + +/* Verify that some JSON was written to a file with the expected name. */ +/* { dg-final { verify-sarif-file } } */ + +/* Use a Python script to verify various properties about the generated + .sarif file: + { dg-final { run-sarif-pytest state-diagram-5-sarif.c "state-diagram-5-sarif.py" } } */ diff --git a/gcc/xml.cc b/gcc/xml.cc index 6bb269a2a19e..8e11c6783425 100644 --- a/gcc/xml.cc +++ b/gcc/xml.cc @@ -317,6 +317,7 @@ printer::add_raw (std::string text) void printer::push_element (std::unique_ptr new_element) { + gcc_assert (new_element.get ()); element *parent = m_open_tags.back (); m_open_tags.push_back (new_element.get ()); parent->add_child (std::move (new_element)); @@ -325,6 +326,7 @@ printer::push_element (std::unique_ptr new_element) void printer::append (std::unique_ptr new_node) { + gcc_assert (new_node.get ()); element *parent = m_open_tags.back (); parent->add_child (std::move (new_node)); }
[gcc r16-1714] diagnostics: refactor sarif_scheme_handler::make_sink
https://gcc.gnu.org/g:5bf213d4ad648fb6761e6143883ceca68c9342e7 commit r16-1714-g5bf213d4ad648fb6761e6143883ceca68c9342e7 Author: David Malcolm Date: Thu Jun 26 13:28:44 2025 -0400 diagnostics: refactor sarif_scheme_handler::make_sink No functional change intended. gcc/ChangeLog: * diagnostic-output-spec.cc (sarif_scheme_handler::make_sink): Split out creation of sarif_generation_options and sarif_serialization_format into... (sarif_scheme_handler::make_sarif_gen_opts): ...this... (sarif_scheme_handler::make_sarif_serialization_object): ...and this. Signed-off-by: David Malcolm Diff: --- gcc/diagnostic-output-spec.cc | 43 --- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/gcc/diagnostic-output-spec.cc b/gcc/diagnostic-output-spec.cc index e58f0c40fc01..25ef86f5f224 100644 --- a/gcc/diagnostic-output-spec.cc +++ b/gcc/diagnostic-output-spec.cc @@ -179,6 +179,14 @@ public: diagnostic_context &dc, const char *unparsed_arg, const scheme_name_and_params &parsed_arg) const final override; + +private: + static sarif_generation_options + make_sarif_gen_opts (enum sarif_version version, + bool xml_state); + + static std::unique_ptr + make_sarif_serialization_object (enum sarif_serialization_kind); }; class html_scheme_handler : public output_factory::scheme_handler @@ -505,27 +513,40 @@ sarif_scheme_handler::make_sink (const context &ctxt, if (!output_file) return nullptr; + auto sarif_gen_opts = make_sarif_gen_opts (version, xml_state); + + auto serialization_obj = make_sarif_serialization_object (serialization_kind); + + auto sink = make_sarif_sink (dc, + *ctxt.get_affected_location_mgr (), + std::move (serialization_obj), + sarif_gen_opts, + std::move (output_file)); + return sink; +} + +sarif_generation_options +sarif_scheme_handler::make_sarif_gen_opts (enum sarif_version version, + bool xml_state) +{ sarif_generation_options sarif_gen_opts; sarif_gen_opts.m_version = version; sarif_gen_opts.m_xml_state = xml_state; + return sarif_gen_opts; +} - std::unique_ptr serialization_obj; - switch (serialization_kind) +std::unique_ptr +sarif_scheme_handler:: +make_sarif_serialization_object (enum sarif_serialization_kind kind) +{ + switch (kind) { default: gcc_unreachable (); case sarif_serialization_kind::json: - serialization_obj - = std::make_unique (true); + return std::make_unique (true); break; } - - auto sink = make_sarif_sink (dc, - *ctxt.get_affected_location_mgr (), - std::move (serialization_obj), - sarif_gen_opts, - std::move (output_file)); - return sink; } /* class html_scheme_handler : public output_factory::scheme_handler. */