[gcc r16-1710] rust: Silence a clang warning in borrow-checker-diagnostics

2025-06-26 Thread Martin Jambor via Gcc-cvs
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]

2025-06-26 Thread Paul-Antoine Arras via Gcc-cvs
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

2025-06-26 Thread Alex Coplan via Gcc-cvs
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]

2025-06-26 Thread Tomasz Kaminski via Gcc-cvs
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]

2025-06-26 Thread Tomasz Kaminski via Gcc-cvs
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]

2025-06-26 Thread Uros Bizjak via Gcc-cvs
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]

2025-06-26 Thread Harald Anlauf via Gcc-cvs
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]

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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]

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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]

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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]

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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]

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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]

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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]

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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

2025-06-26 Thread Martin Jambor via Gcc-cvs
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

2025-06-26 Thread Martin Jambor via Gcc-cvs
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

2025-06-26 Thread Martin Jambor via Gcc-cvs
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]

2025-06-26 Thread Kito Cheng via Gcc-cvs
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

2025-06-26 Thread Martin Jambor via Gcc-cvs
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

2025-06-26 Thread Kito Cheng via Gcc-cvs
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]

2025-06-26 Thread Andre Vehreschild via Gcc-cvs
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.

2025-06-26 Thread Andre Vehreschild via Gcc-cvs
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.

2025-06-26 Thread Andre Vehreschild via Gcc-cvs
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

2025-06-26 Thread Jan Hubicka via Gcc-cvs
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

2025-06-26 Thread Mikael Morin via Gcc-cvs
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'

2025-06-26 Thread Mikael Morin via Gcc-cvs
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

2025-06-26 Thread Richard Biener via Gcc-cvs
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

2025-06-26 Thread Jan Hubicka via Gcc-cvs
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

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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

2025-06-26 Thread Alexandre Oliva via Gcc-cvs
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

2025-06-26 Thread Dimitar Dimitrov via Gcc-cvs
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

2025-06-26 Thread H.J. Lu via Gcc-cvs
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

2025-06-26 Thread Jakub Jelinek via Libstdc++-cvs
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

2025-06-26 Thread Jakub Jelinek via Gcc-cvs
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

2025-06-26 Thread David Malcolm via Gcc-cvs
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]

2025-06-26 Thread David Malcolm via Gcc-cvs
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

2025-06-26 Thread David Malcolm via Gcc-cvs
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.  */