Re: [PATCH] testsuite: Fix up strub-internal-pr112938.C test for C++2{0,3,6}

2025-03-27 Thread Mike Stump
On Mar 27, 2025, at 12:29 PM, Jakub Jelinek  wrote:
> 
> On Thu, Mar 27, 2025 at 12:05:21AM +, Sam James wrote:
>> The test was being ignored because dg.exp looks for .C in g++.dg/.
>> 
>> gcc/testsuite/ChangeLog:
>>  PR middle-end/112938
>> 
>>  * g++.dg/strub-internal-pr112938.cc: Move to...
>>  * g++.dg/strub-internal-pr112938.C: ...here.
>> ---
>> .../{strub-internal-pr112938.cc => strub-internal-pr112938.C} | 0
>> 1 file changed, 0 insertions(+), 0 deletions(-)
>> rename gcc/testsuite/g++.dg/{strub-internal-pr112938.cc => 
>> strub-internal-pr112938.C} (100%)
>> 
>> diff --git a/gcc/testsuite/g++.dg/strub-internal-pr112938.cc 
>> b/gcc/testsuite/g++.dg/strub-internal-pr112938.C
>> similarity index 100%
>> rename from gcc/testsuite/g++.dg/strub-internal-pr112938.cc
>> rename to gcc/testsuite/g++.dg/strub-internal-pr112938.C
> 
> This regressed the test for C++20 and higher:
> FAIL: g++.dg/strub-internal-pr112938.C  -std=gnu++20 (test for excess errors)
> FAIL: g++.dg/strub-internal-pr112938.C  -std=gnu++23 (test for excess errors)
> FAIL: g++.dg/strub-internal-pr112938.C  -std=gnu++26 (test for excess errors)
> 
> Here is a fix, tested on x86_64-linux, ok for trunk?

Ok.

[committed] i386: Fix offset calculation in ix86_redzone_clobber

2025-03-27 Thread Uros Bizjak
plus_constant expects integer as its third argument, not rtx.

gcc/ChangeLog:

* config/i386/i386.cc (ix86_redzone_clobber): Use integer, not rtx
as the third argument of plus_constant.

Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}.

Uros.
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 18127bcada8..f38e3db41fa 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -26465,8 +26465,7 @@ ix86_redzone_clobber ()
   cfun->machine->asm_redzone_clobber_seen = true;
   if (ix86_using_red_zone ())
 {
-  rtx base = plus_constant (Pmode, stack_pointer_rtx,
-   GEN_INT (-RED_ZONE_SIZE));
+  rtx base = plus_constant (Pmode, stack_pointer_rtx, -RED_ZONE_SIZE);
   rtx mem = gen_rtx_MEM (BLKmode, base);
   set_mem_size (mem, RED_ZONE_SIZE);
   return mem;


[PATCH v2] c++: fix reporting routines re-entered [PR119303]

2025-03-27 Thread Marek Polacek
On Wed, Mar 19, 2025 at 12:00:00PM -0400, Jason Merrill wrote:
> On 3/17/25 6:55 PM, Marek Polacek wrote:
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > -- >8 --
> > We crash while we call warning_at ("inline function used but never defined")
> > since it invokes dump_template_bindings -> tsubst -> ... -> convert_like ->
> > ... -> c_common_truthvalue_conversion -> warning_at ("enum constant in 
> > boolean
> >  context")
> > 
> > cp_truthvalue_conversion correctly gets complain=0 but it calls
> > c_common_truthvalue_conversion from c-family which doesn't have
> > a similar parameter.
> 
> It seems that we try to prevent this in cp_convert_and_check with
> 
>   warning_sentinel c (warn_int_in_bool_context);
> 
> which is why we don't get a warning when we first instantiate the template.
> 
> But that doesn't help when we rebuild the expression for
> dump_template_bindings because the recursion check in report_diagnostic
> comes before the check whether the diagnostic is actually enabled.
> 
> I think rather than adding another mechanism for suppressing warnings, I'd
> like to make the existing ones work better by moving the recursion check
> after the checks for disabled diagnostics.

Fair enough.  That happens to fix c++/116960 et al too.  Note that my
adding a complain parameter into c-family isn't entirely novel:
c_sizeof_or_alignof_type also has one.


Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
We crash while we call warning_at ("inline function used but never defined")
since it invokes dump_template_bindings -> tsubst -> ... -> convert_like ->
... -> c_common_truthvalue_conversion -> warning_at ("enum constant in boolean
 context")

cp_truthvalue_conversion correctly gets complain=0 but it calls
c_common_truthvalue_conversion from c-family which doesn't have
a similar parameter.

We can fix this by tweaking diagnostic_context::report_diagnostic to
check for recursion after checking if the diagnostic was enabled.

PR c++/116960
PR c++/119303

gcc/ChangeLog:

* diagnostic.cc (diagnostic_context::report_diagnostic): Check for
non-zero m_lock only after diagnostic_enabled.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/lambda-uneval26.C: New test.
* g++.dg/warn/undefined2.C: New test.
---
 gcc/diagnostic.cc| 24 ++--
 gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C | 10 
 gcc/testsuite/g++.dg/warn/undefined2.C   | 14 
 3 files changed, 36 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C
 create mode 100644 gcc/testsuite/g++.dg/warn/undefined2.C

diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 82d7f946818..425477ea5b2 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -1398,18 +1398,6 @@ diagnostic_context::report_diagnostic (diagnostic_info 
*diagnostic)
   if (diagnostic->kind == DK_NOTE && m_inhibit_notes_p)
 return false;
 
-  if (m_lock > 0)
-{
-  /* If we're reporting an ICE in the middle of some other error,
-try to flush out the previous error, then let this one
-through.  Don't do this more than once.  */
-  if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
- && m_lock == 1)
-   pp_newline_and_flush (m_reference_printer);
-  else
-   error_recursion ();
-}
-
   /* If the user requested that warnings be treated as errors, so be
  it.  Note that we do this before the next block so that
  individual warnings can be overridden back to warnings with
@@ -1426,6 +1414,18 @@ diagnostic_context::report_diagnostic (diagnostic_info 
*diagnostic)
   if (!diagnostic_enabled (diagnostic))
 return false;
 
+  if (m_lock > 0)
+{
+  /* If we're reporting an ICE in the middle of some other error,
+try to flush out the previous error, then let this one
+through.  Don't do this more than once.  */
+  if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
+ && m_lock == 1)
+   pp_newline_and_flush (m_reference_printer);
+  else
+   error_recursion ();
+}
+
   if ((was_warning || diagnostic->kind == DK_WARNING)
   && ((!m_warn_system_headers
   && diagnostic->m_iinfo.m_allsyslocs)
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C 
b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C
new file mode 100644
index 000..3e3097bedcb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C
@@ -0,0 +1,10 @@
+// PR c++/116960
+// { dg-do compile { target c++20 } }
+
+template
+using Foo = decltype([](auto) { return 0; }(0));
+
+template
+Foo<[] {}> foo() {}   // { dg-warning "no return statement" }
+
+auto t = foo();
diff --git a/gcc/testsuite/g++.dg/warn/undefined2.C 
b/gcc/testsuite/g++.dg/warn/undefined2.C
new file mode 1

Re: [PATCH] libcpp: Add missing configure check for setlocale.

2025-03-27 Thread Roland McGrath
I've spent more than my fair share of my life fiddling with autoconf
installations, so I just hand-editted the patches to elide the
unwanted changes.
Now committed on both trunk and releases/14.

Thanks,
Roland


[COMMITTED 071/146] gccrs: derive(Copy): Use new LangItemPath

2025-03-27 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-copy.cc: Use new LangItemPath for derive(Copy).
---
 gcc/rust/expand/rust-derive-copy.cc | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-copy.cc 
b/gcc/rust/expand/rust-derive-copy.cc
index 1de72900d04..02817250db1 100644
--- a/gcc/rust/expand/rust-derive-copy.cc
+++ b/gcc/rust/expand/rust-derive-copy.cc
@@ -18,6 +18,8 @@
 
 #include "rust-derive-copy.h"
 #include "rust-ast-full.h"
+#include "rust-mapping-common.h"
+#include "rust-path.h"
 
 namespace Rust {
 namespace AST {
@@ -44,7 +46,7 @@ DeriveCopy::copy_impl (
   // `$crate::core::marker::Copy` instead
   auto segments = std::vector> ();
   segments.emplace_back (builder.type_path_segment ("Copy"));
-  auto copy = TypePath (std::move (segments), loc);
+  auto copy = Rust::make_unique (LangItem::Kind::COPY, loc);
 
   // we need to build up the generics for this impl block which will be just a
   // clone of the types specified ones
@@ -116,7 +118,7 @@ DeriveCopy::copy_impl (
: builder.single_generic_type_path (name, generic_args_for_self);
 
   return std::unique_ptr (
-new TraitImpl (copy, /* unsafe */ false,
+new TraitImpl (std::move (copy), /* unsafe */ false,
   /* exclam */ false, /* trait items */ {},
   std::move (impl_generics), std::move (self_type_path),
   WhereClause::create_empty (), Visibility::create_private (),
-- 
2.45.2



[pushed: r15-8992] v2: contrib: add dg-lint and libgdiagnostics.py [PR116163]

2025-03-27 Thread David Malcolm
Given that this is all below "contrib", I've taken the liberty of
pushing this updated version to trunk, as r15-8992-g8d6de758cca6d1.

Changed in v2:
- eliminated COMMON_MISSPELLINGS in favor of retesting with a regexp
  that adds underscores
- add a list of KNOWN_DIRECTIVES, and complain if we see a directive
  that isn't in the list
- various refactorings to reduce the nesting within the script
- skip more kinds of file ('README', 'Makefile.am', 'Makefile.in',
  'gen_directive_tests')
- keep track of the number of files scanned and report it and the end
  with a note

This patch adds a new dg-lint subdirectory below contrib, containing
a "dg-lint" script for detecting common mistakes made in our DejaGnu
tests.

Specifically, DejaGnu's dg.exp's dg-get-options has a regexp for
detecting dg- directives
  https://git.savannah.gnu.org/gitweb/?p=dejagnu.git;a=blob;f=lib/dg.exp
here's the current:

set tmp [grep $prog "{\[ \t\]\+dg-\[-a-z\]\+\[ \t\]\+.*\[ \t\]\+}" line]

which if I'm reading it right requires a "{", then one or more tab/space
chars, then a "dg-" directive name, then one of more tab/space
characters, then anything (for arguments to the directive), then one of
more tab/space character, then a "}".

There are numerous places in our testsuite which look like attempts to
use a directive, but which don't match this regexp.

The script warns about such places, along with a list of misspelled
directives (currently just "dg_options" for "dg-options"), and a warning
if a dg-do appears after a dg-require-* (as per
https://gcc.gnu.org/onlinedocs/gccint/Directives.html
"This directive must appear after any dg-do directive in the test
and before any dg-additional-sources directive." for
dg-require-effective-target.

dg-lint uses libgdiagnostics to report its results; the patch adds a
new libgdiagnostics.py script below contrib/dg-lint.  This uses Python's
ctypes module to expose libgdianostics.so to Python via FFI.  Hence
the warnings have colorization, quote the pertinent parts of the tested
file, can have fix-it hints, etc.  Here's the output from the tests, run
from the top-level directory:

$ LD_LIBRARY_PATH=../build/gcc/ ./contrib/dg-lint/dg-lint 
contrib/dg-lint/test-*.c
contrib/dg-lint/test-1.c:6:6: warning: misspelled directive: 'dg_final'; did 
you mean 'dg-final'?
6 | /* { dg_final { scan_assembler_times "vmsumudm" 2 } } */
  |  ^~~~
  |  dg-final
contrib/dg-lint/test-1.c:15:4: warning: directive 'dg-output-file' appears not 
to match dg.exp's regexp
   15 |dg-output-file "m4.out"
  |^~
contrib/dg-lint/test-1.c:18:4: warning: directive 'dg-output-file' appears not 
to match dg.exp's regexp
   18 |dg-output-file "m4.out" }
  |^~
contrib/dg-lint/test-1.c:21:6: warning: directive 'dg-output-file' appears not 
to match dg.exp's regexp
   21 |{ dg-output-file "m4.out"
  |  ^~
contrib/dg-lint/test-1.c:24:5: warning: directive 'dg-output-file' appears not 
to match dg.exp's regexp
   24 |{dg-output-file "m4.out"}
  | ^~
contrib/dg-lint/test-1.c:27:6: warning: directive 'dg-output-file' appears not 
to match dg.exp's regexp
   27 |{ dg-output-file, "m4.out" }
  |  ^~
contrib/dg-lint/test-2.c:4:6: warning: 'dg-do' after 
'dg-require-effective-target'
4 | /* { dg-do compile } */
  |  ^
contrib/dg-lint/test-2.c:3:6: note: 'dg-require-effective-target' was here
3 | /* { dg-require-effective-target c++11 } */
  |  ^~~

I don't yet have a way to verify these tests (clearly we can't use
DejaGnu for this).

These Python bindings could be used by other projects, but so far I only
implemented what I needed for dg-lint.

Running the test on the GCC source tree finds dozens of issues, which
followup patches address.

Tested with Python 3.8

contrib/ChangeLog:
PR testsuite/116163
* dg-lint/dg-lint: New file.
* dg-lint/libgdiagnostics.py: New file.
* dg-lint/test-1.c: New file.
* dg-lint/test-2.c: New file.

FIXME: updates to dg-lint
---
 contrib/dg-lint/dg-lint| 404 +
 contrib/dg-lint/libgdiagnostics.py | 250 ++
 contrib/dg-lint/test-1.c   |  41 +++
 contrib/dg-lint/test-2.c   |   8 +
 4 files changed, 703 insertions(+)
 create mode 100755 contrib/dg-lint/dg-lint
 create mode 100644 contrib/dg-lint/libgdiagnostics.py
 create mode 100644 contrib/dg-lint/test-1.c
 create mode 100644 contrib/dg-lint/test-2.c

diff --git a/contrib/dg-lint/dg-lint b/contrib/dg-lint/dg-lint
new file mode 100755
index ..01d58d7a3e95
--- /dev/null
+++ b/contrib/dg-lint/dg-lint
@@ -0,0 +1,404 @@
+#!/usr/bin/env python3
+
+# Script to detect common mistakes in DejaGnu tests.
+
+# Contributed by David Malcolm 
+#
+# Copyright (C) 2024-2025 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software;

[COMMITTED 131/144] gccrs: Improve handling of InlineAsm in DefaultASTVisitor

2025-03-27 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit): Visit fields of InlineAsm.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove
inline_asm_parse_output_operand.rs.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-ast-visitor.cc   | 41 +-
 gcc/testsuite/rust/compile/nr2/exclude |  1 -
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index b124531b09c..8f53e528131 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -675,7 +675,46 @@ DefaultASTVisitor::visit (AST::AsyncBlockExpr &expr)
 
 void
 DefaultASTVisitor::visit (AST::InlineAsm &expr)
-{}
+{
+  visit_outer_attrs (expr);
+  using RegisterType = AST::InlineAsmOperand::RegisterType;
+  for (auto &operand : expr.get_operands ())
+{
+  switch (operand.get_register_type ())
+   {
+ case RegisterType::In: {
+   visit (operand.get_in ().expr);
+   break;
+ }
+ case RegisterType::Out: {
+   visit (operand.get_out ().expr);
+   break;
+ }
+ case RegisterType::InOut: {
+   visit (operand.get_in_out ().expr);
+   break;
+ }
+ case RegisterType::SplitInOut: {
+   auto split = operand.get_split_in_out ();
+   visit (split.in_expr);
+   visit (split.out_expr);
+   break;
+ }
+ case RegisterType::Const: {
+   visit (operand.get_const ().anon_const.expr);
+   break;
+ }
+ case RegisterType::Sym: {
+   visit (operand.get_sym ().expr);
+   break;
+ }
+ case RegisterType::Label: {
+   visit (operand.get_label ().expr);
+   break;
+ }
+   }
+}
+}
 
 void
 DefaultASTVisitor::visit (AST::TypeParam ¶m)
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 166977e7bac..6c7d5041291 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -233,7 +233,6 @@ issue-3045-1.rs
 issue-3045-2.rs
 issue-3046.rs
 unknown-associated-item.rs
-inline_asm_parse_output_operand.rs
 issue-3030.rs
 issue-3035.rs
 issue-3082.rs
-- 
2.45.2



[COMMITTED 077/146] gccrs: fix bad not expression in rust

2025-03-27 Thread arthur . cohen
From: Philip Herron 

Fixes Rust-GCC#3229

gcc/rust/ChangeLog:

* rust-gcc.cc (operator_to_tree_code): ! expressions are BIT_NOT_EXPR

Signed-off-by: Philip Herron 
---
 gcc/rust/rust-gcc.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 7da5e2c5637..37d51e58c08 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -942,7 +942,7 @@ operator_to_tree_code (NegationOperator op)
 case NegationOperator::NEGATE:
   return NEGATE_EXPR;
 case NegationOperator::NOT:
-  return TRUTH_NOT_EXPR;
+  return BIT_NOT_EXPR;
 default:
   rust_unreachable ();
 }
-- 
2.45.2



Re: [Fortran, Patch, PR119349, v1] Fix regression of polymorphic dummy sourced from array constructors.

2025-03-27 Thread Jerry D

On 3/20/25 9:20 AM, Andre Vehreschild wrote:

Hi all,

attached patch fixes a 15-regression where an element of an actual
temporary array, i.e., elemental([ e1, e2...]) passed to the formal polymorphic
dummy leads to a double free of the derived types components. This patch
prevents this by preventing the deallocation of the array constructors
temporary, when the formal is polymorphic. ...

Folks its so hard to explain this in prose. I rewrote above paragraph the third
time now. And I still don't understand on re-reading. So here is some pseudo
code:

struct derived {
   char *c; // This is the component suffering from double-free
};

derived[2] atmp = [ derived(""), derived("")]

forall a in atmp
   derived t_a = a; // <- Copy of a, but no deep copy, i.e. t_a.c == a.c
   class_temp = class_derived(a); // set _vtype left out for brevity
   call elemental_function(class_temp);
   if (class_temp._data.c != NULL)
 free(class_temp._data.c); // and set it to NULL
   if (t_a.c != NULL)
 free(t_a.c); // BOOM, this is freeing the same c
end

Generating the last if-block and the free is what this patch prevents for
polymorphic dummys that stem from an array construction. And only for those.

Sorry, I am having a hard time explaining things today. So I hope the code
above will do.

Regtested ok on x86_64-pc-linux-gnu / F41. Ok for mainline?


OK and thanks for the fix. Your prose is fine and your comment in the 
code suffices.


Thanks for the patch.

Jerry


Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de




[pushed: r15-8993] testsuite: fix some malformed dg-require-* directives

2025-03-27 Thread David Malcolm
Pushed to trunk as r15-8993-gc88abca94a6abb.

gcc/testsuite/ChangeLog:
* g++.dg/abi/pure-virtual1.C: Fix dg-require-weak directive.
* g++.target/i386/mangling-alias1.C: Fix dg-require-ifunc
directive.
---
 gcc/testsuite/g++.dg/abi/pure-virtual1.C| 2 +-
 gcc/testsuite/g++.target/i386/mangling-alias1.C | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/g++.dg/abi/pure-virtual1.C 
b/gcc/testsuite/g++.dg/abi/pure-virtual1.C
index 59eaf2256204..ce7cd70810b9 100644
--- a/gcc/testsuite/g++.dg/abi/pure-virtual1.C
+++ b/gcc/testsuite/g++.dg/abi/pure-virtual1.C
@@ -1,6 +1,6 @@
 // Test that we don't need libsupc++ just for __cxa_pure_virtual.
 // { dg-do link }
-// { dg-require-weak }
+// { dg-require-weak "" }
 // { dg-additional-options "-fno-rtti -nostdlib++" }
 // { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target 
*-*-darwin* } }
 // { dg-xfail-if "AIX weak" { powerpc-ibm-aix* } }
diff --git a/gcc/testsuite/g++.target/i386/mangling-alias1.C 
b/gcc/testsuite/g++.target/i386/mangling-alias1.C
index 70264e2b64e6..2d7a25ab709d 100644
--- a/gcc/testsuite/g++.target/i386/mangling-alias1.C
+++ b/gcc/testsuite/g++.target/i386/mangling-alias1.C
@@ -1,6 +1,6 @@
 // PR c++/114992
 // { dg-do compile { target { c++11 && x86_64-*-* } } }
-// { dg-require-ifunc }
+// { dg-require-ifunc "" }
 
 template 
 __attribute__((target_clones("avx2", "default")))
-- 
2.26.3



[pushed: r15-8994-g1ee9caf2f84832] libstdc++-v3 testsuite: fix malformed dg-require-static-libstdcxx directives

2025-03-27 Thread David Malcolm
I believe these don't get detected by DejaGnu's regexp.

Found by dg-lint.

Pushed to trunk as r15-8994-g1ee9caf2f84832.

libstdc++-v3/ChangeLog:
* testsuite/17_intro/shared_with_static_deps.cc: Fix malformed
dg-require-static-libstdcxx directive.
* testsuite/17_intro/static.cc: Likewise.
* testsuite/18_support/type_info/110572.cc: Likewise.
* testsuite/20_util/to_chars/4.cc: Likewise.
* testsuite/std/time/tzdb_list/pr118811.cc: Likewise.
---
 libstdc++-v3/testsuite/17_intro/shared_with_static_deps.cc | 2 +-
 libstdc++-v3/testsuite/17_intro/static.cc  | 2 +-
 libstdc++-v3/testsuite/18_support/type_info/110572.cc  | 2 +-
 libstdc++-v3/testsuite/20_util/to_chars/4.cc   | 2 +-
 libstdc++-v3/testsuite/std/time/tzdb_list/pr118811.cc  | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/testsuite/17_intro/shared_with_static_deps.cc 
b/libstdc++-v3/testsuite/17_intro/shared_with_static_deps.cc
index 9491bbcd5741..a84c110ab52c 100644
--- a/libstdc++-v3/testsuite/17_intro/shared_with_static_deps.cc
+++ b/libstdc++-v3/testsuite/17_intro/shared_with_static_deps.cc
@@ -1,5 +1,5 @@
 // { dg-do link }
-// { dg-require-static-libstdcxx }
+// { dg-require-static-libstdcxx "" }
 // { dg-require-sharedlib "" }
 // { dg-require-effective-target fpic }
 // { dg-options "-shared -fPIC -static-libgcc -static-libstdc++" }
diff --git a/libstdc++-v3/testsuite/17_intro/static.cc 
b/libstdc++-v3/testsuite/17_intro/static.cc
index ab0cf279d994..26b34c819d52 100644
--- a/libstdc++-v3/testsuite/17_intro/static.cc
+++ b/libstdc++-v3/testsuite/17_intro/static.cc
@@ -1,5 +1,5 @@
 // { dg-do run { target c++11 } }
-// { dg-require-static-libstdcxx }
+// { dg-require-static-libstdcxx "" }
 // { dg-options "-static-libstdc++" }
 
 // Copyright (C) 2012-2025 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/18_support/type_info/110572.cc 
b/libstdc++-v3/testsuite/18_support/type_info/110572.cc
index f727653adfb1..5a05078510fe 100644
--- a/libstdc++-v3/testsuite/18_support/type_info/110572.cc
+++ b/libstdc++-v3/testsuite/18_support/type_info/110572.cc
@@ -1,6 +1,6 @@
 // { dg-options "-static-libstdc++" }
 // { dg-do link }
-// { dg-require-static-libstdcxx }
+// { dg-require-static-libstdcxx "" }
 // { dg-require-cpp-feature-test __cpp_rtti }
 
 #include 
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/4.cc 
b/libstdc++-v3/testsuite/20_util/to_chars/4.cc
index 3d76d5691287..65abfaaff952 100644
--- a/libstdc++-v3/testsuite/20_util/to_chars/4.cc
+++ b/libstdc++-v3/testsuite/20_util/to_chars/4.cc
@@ -17,7 +17,7 @@
 
 // { dg-do link { target c++17 } }
 // { dg-require-effective-target ieee_floats }
-// { dg-require-static-libstdcxx }
+// { dg-require-static-libstdcxx "" }
 // { dg-additional-options "-static-libstdc++" }
 
 // Verify the Ryu symbol generic_to_chars doesn't inadvertently leak into
diff --git a/libstdc++-v3/testsuite/std/time/tzdb_list/pr118811.cc 
b/libstdc++-v3/testsuite/std/time/tzdb_list/pr118811.cc
index 3968be3f0eca..fe86602ecce9 100644
--- a/libstdc++-v3/testsuite/std/time/tzdb_list/pr118811.cc
+++ b/libstdc++-v3/testsuite/std/time/tzdb_list/pr118811.cc
@@ -1,7 +1,7 @@
 // { dg-do run { target c++20 } }
 // { dg-require-effective-target tzdb }
 // { dg-require-effective-target cxx11_abi }
-// { dg-require-static-libstdcxx }
+// { dg-require-static-libstdcxx "" }
 // { dg-additional-options "-static-libstdc++" }
 
 #include 
-- 
2.26.3



Re: [PATCH] cobol: Do not include (no longer needed).

2025-03-27 Thread James K. Lowden
On Thu, 27 Mar 2025 09:33:40 +
Iain Sandoe  wrote:

> As noted in the commit log, the macOS version of cmath (at least) has
> conflicts with parse.y.  Tested on x86_64,aarch64 linux,
> x86_64-darwin. OK for trunk?
> thanks,
> Iain

LGTM, Iain.  Any header file that isn't needed, isn't needed.  

If in the future we decide to use , we'll rename any conflicting
names in parse.y.  

--jkl


> --- 8< ---
> 
> Several of enumerators in parse.y conflict with ones declared in at
> least some versions of  .. e.g. "OVERFLOW".  The header is no
> longer needed since the FE is not trying to do host arithmetic.
> 
> gcc/cobol/ChangeLog:
> 
>   * cobol-system.h: Remove .
> 
> Signed-off-by: Iain Sandoe 
> ---
>  gcc/cobol/cobol-system.h | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/gcc/cobol/cobol-system.h b/gcc/cobol/cobol-system.h
> index 81529bd3a67..ff9583530e2 100644
> --- a/gcc/cobol/cobol-system.h
> +++ b/gcc/cobol/cobol-system.h
> @@ -53,7 +53,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  
>  #include 
>  #include 
> -- 
> 2.39.2 (Apple Git-143)
> 


[wwwdocs] cxx-dr-status: Update from C++ Core Language Issue TOC, Revision 116

2025-03-27 Thread Marek Polacek
~90 new DRs.  More updates tomorrow.

Pushed.

-- >8 --
commit eabbf82b95871f4cc1561b9d5bd9ba88a849a61f
Author: Marek Polacek 
Date:   Thu Mar 27 19:08:35 2025 -0400

cxx-dr-status: Update from C++ Core Language Issue TOC, Revision 116

diff --git a/htdocs/projects/cxx-dr-status.html 
b/htdocs/projects/cxx-dr-status.html
index c0715865..6ff9497c 100644
--- a/htdocs/projects/cxx-dr-status.html
+++ b/htdocs/projects/cxx-dr-status.html
@@ -15,7 +15,7 @@
 
   This table tracks the implementation status of C++ defect reports in GCC.
   It is based on C++ Standard Core Language Issue Table of Contents, Revision
-  114 (https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_toc.html";>here).
+  116 (https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_toc.html";>here).
 
   
 
@@ -1652,7 +1652,7 @@
 
 
   https://wg21.link/cwg233";>233
-  review
+  DRWP
   References vs pointers in UDC overload resolution
   No
   https://gcc.gnu.org/PR114697";>PR114697
@@ -2742,8 +2742,8 @@
   https://wg21.link/cwg388";>388
   CD3
   Catching base*& from a throw of 
derived*
-  ?
-  
+  No
+  https://gcc.gnu.org/PR23257";>PR23257
 
 
   https://wg21.link/cwg389";>389
@@ -3196,7 +3196,7 @@
 
 
   https://wg21.link/cwg453";>453
-  DR
+  DRWP
   References may only bind to "valid" objects
   ?
   
@@ -8585,11 +8585,11 @@
   ?
   
 
-
+
   https://wg21.link/cwg1223";>1223
-  drafting
+  DRWP
   Syntactic disambiguation and trailing-return-types
-  -
+  ?
   
 
 
@@ -8764,7 +8764,7 @@
 
   https://wg21.link/cwg1248";>1248
   open
-  Updating Annex C to C99
+  Updating Annex C to C99 and C23
   -
   
 
@@ -8796,11 +8796,11 @@
   ?
   
 
-
+
   https://wg21.link/cwg1253";>1253
-  open
+  C++17
   Generic non-template members
-  -
+  ?
   
 
 
@@ -10521,11 +10521,11 @@
   ?
   
 
-
+
   https://wg21.link/cwg1499";>1499
-  drafting
+  DRWP
   Missing case for deleted move assignment operator
-  -
+  ?
   
 
 
@@ -10675,11 +10675,11 @@
   ?
   
 
-
+
   https://wg21.link/cwg1521";>1521
-  drafting
+  dup
   T{expr} with reference types
-  -
+  ?
   https://gcc.gnu.org/PR115085";>PR115085
 
 
@@ -11411,11 +11411,11 @@
   -
   
 
-
+
   https://wg21.link/cwg1626";>1626
-  open
+  dup
   constexpr member functions in 
brace-or-equal-initializers
-  -
+  ?
   
 
 
@@ -13701,16 +13701,16 @@
   ?
   
 
-
+
   https://wg21.link/cwg1953";>1953
-  open
+  DR
   Data races and common initial sequence
-  -
+  ?
   
 
 
   https://wg21.link/cwg1954";>1954
-  DR
+  DRWP
   typeid null dereference check in subexpressions
   ?
   
@@ -13787,7 +13787,7 @@
 
 
   https://wg21.link/cwg1965";>1965
-  drafting
+  open
   Explicit casts to reference types
   -
   
@@ -14010,11 +14010,11 @@
   https://gcc.gnu.org/PR90390";>PR90390,
  https://gcc.gnu.org/PR113141";>PR113141
 
-
+
   https://wg21.link/cwg1997";>1997
-  drafting
+  DRWP
   Placement new and previous initialization
-  -
+  ?
   
 
 
@@ -15040,11 +15040,11 @@
   ?
   
 
-
+
   https://wg21.link/cwg2144";>2144
-  drafting
+  DRWP
   Function/variable declaration ambiguity
-  -
+  ?
   
 
 
@@ -15075,11 +15075,11 @@
   -
   
 
-
+
   https://wg21.link/cwg2149";>2149
-  drafting
+  DRWP
   Brace elision and array length deduction
-  -
+  ?
   
 
 
@@ -15299,11 +15299,11 @@
   ?
   
 
-
+
   https://wg21.link/cwg2181";>2181
-  drafting
+  C++20
   Normative requirements in an informative Annex
-  -
+  ?
   
 
 
@@ -15334,11 +15334,11 @@
   ?
   
 
-
+
   https://wg21.link/cwg2186";>2186
-  drafting
+  C++20
   Unclear point that "preceding initialization" must precede
-  -
+  ?
   
 
 
@@ -16013,11 +16013,11 @@
   ?
   
 
-
+
   https://wg21.link/cwg2283";>2283
-  drafting
+  DR
   Missing complete type requirements
-  -
+  ?
   
 
 
@@ -17366,7 +17366,7 @@
 
 
   https://wg21.link/cwg2476";>2476
-  DR
+  DRWP
   placeholder-type-specifiers and function declarators
   ?
   
@@ -17765,7 +17765,7 @@
 
 
   https://wg21.link/cwg2533";>2533
-  DR
+  DRWP
   Storage duration of implicitly created objects
   ?
   
@@ -17856,14 +17856,14 @@
 
 
   https://wg21.link/cwg2546";>2546
-

[PATCH] PR tree-optimization/119471 - If the LHS does not contain zero, neither do multiply operands.

2025-03-27 Thread Andrew MacLeod

This patch fixes both 119471 and the remainder of 110992.

At issue is we do not recognize that if

  "a * b != 0" , then neither "a" nor "b" can be zero.

This is fairly trivial with range-ops.   op1_range and op2_range for 
operator_mult are taught that if the LHS does not contain zero, than 
neither does either operand.


Included are patches for trunk (gcc15), gcc14, and gcc13.  All are 
basically the same few lines.


I presume we want to wait for stage 1 to check this into trunk .

Bootstraps with no regressions on x86_64-pc-linux-gnu on all 3 
branches.  OK for gcc13 and gcc14 branches?


Andrew

From 74edd2831affac005d2d5bf0170668188aa1a091 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Thu, 27 Mar 2025 13:44:00 -0400
Subject: [PATCH] If the LHS does not contain zero, neither do multiply
 operands.

Given ~[0,0] = op1 * op2, range-ops should determine that neither op1 nor
op2 is zero.  Add this to the operator_mult for op1_range.  op2_range
simply invokes op1_range, so both will be covered.

	PR tree-optimzation/110992.c
	PR tree-optimzation/119471.c
	gcc/
	* range-op.cc (operator_mult::op1_range): If the LHS does not
	contain zero, return non-zero.

	gcc/testsuite/
	* gcc.dg/pr110992.c: New.
	* gcc.dg/pr119471.c: New.
---
 gcc/range-op.cc |  7 +++
 gcc/testsuite/gcc.dg/pr110992.c | 18 ++
 gcc/testsuite/gcc.dg/pr119471.c | 19 +++
 3 files changed, 44 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr110992.c
 create mode 100644 gcc/testsuite/gcc.dg/pr119471.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index d1a1cd73687..6ea0d9935eb 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2140,6 +2140,13 @@ operator_mult::op1_range (irange &r, tree type,
   wide_int offset;
   if (op2.singleton_p (offset) && offset != 0)
 return range_op_handler (TRUNC_DIV_EXPR).fold_range (r, type, lhs, op2);
+
+  //  ~[0, 0] = op1 * op2  defines op1 and op2 as non-zero.
+  if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ()
+{
+  r.set_nonzero (type);
+  return true;
+}
   return false;
 }
 
diff --git a/gcc/testsuite/gcc.dg/pr110992.c b/gcc/testsuite/gcc.dg/pr110992.c
new file mode 100644
index 000..05e9b9267e6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110992.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void foo (int);
+
+int f(unsigned b, short c)
+{
+  int bt = b;
+  int bt1 = bt;
+  int t = bt1 & -(c!=0);
+ // int t = bt1 * (c!=0);
+
+  if (!t) return 0;
+  foo(bt == 0);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "foo \\(0\\)" 1 "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr119471.c b/gcc/testsuite/gcc.dg/pr119471.c
new file mode 100644
index 000..4c55d85f77c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119471.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+int fa(int a, int b)
+{
+  int c = a * b;
+  if (c != 0)
+return (a != 0);
+  return 0;
+}
+int fb(int a, int b)
+{
+  int c = a * b;
+  if (c != 0)
+return (b != 0);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "PHI <1" 2 "evrp" } } */
-- 
2.45.0

From 68f8db2c13df7acee838ba1503d97f9e7f18ecea Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Thu, 27 Mar 2025 13:50:16 -0400
Subject: [PATCH 2/2] If the LHS does not contain zero, neither do multiply
 operands.

Given ~[0,0] = op1 * op2, range-ops should determine that neither op1 nor
op2 is zero.  Add this to the operator_mult for op1_range.  op2_range
simply invokes op1_range, so both will be covered.

	PR tree-optimzation/110992.c
	PR tree-optimzation/119471.c
	gcc/
	* range-op.cc (operator_mult::op1_range): If the LHS does not
	contain zero, return non-zero.

	gcc/testsuite/
	* gcc.dg/pr110992.c: New.
	* gcc.dg/pr119471.c: New.
---
 gcc/range-op.cc |  8 
 gcc/testsuite/gcc.dg/pr110992.c | 18 ++
 gcc/testsuite/gcc.dg/pr119471.c | 19 +++
 3 files changed, 45 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr110992.c
 create mode 100644 gcc/testsuite/gcc.dg/pr119471.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 97a88dc7efa..275b3ae6891 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1976,6 +1976,14 @@ operator_mult::op1_range (irange &r, tree type,
   if (op2.singleton_p (&offset) && !integer_zerop (offset))
 return range_op_handler (TRUNC_DIV_EXPR, type).fold_range (r, type,
 			   lhs, op2);
+
+  //  ~[0, 0] = op1 * op2  defines op1 and op2 as non-zero.
+  if (!contains_zero_p ((lhs)))
+   {
+ r.set_nonzero (type);
+ return true;
+   }
+
   return false;
 }
 
diff --git a/gcc/testsuite/gcc.dg/pr110992.c b/gcc/testsuite/gcc.dg/pr110992.c
new file mode 100644
index 000..05e9b9267e6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110992.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void foo (int);
+
+int f(unsigned b, short

[PATCH v3 08/19] Add get_clone_versions and get_version functions.

2025-03-27 Thread Alfie Richards

This is a reimplementation of get_target_clone_attr_len,
get_attr_str, and separate_attrs using string_slice and auto_vec to make
memory management and use simpler.

This also adds get_version which is a helper function to get the version
string from a decl.

gcc/c-family/ChangeLog:

* c-attribs.cc (handle_target_clones_attribute): Change to use
get_clone_versions.

gcc/ChangeLog:

* tree.cc (get_clone_versions): New function.
(get_clone_attr_versions): New function.
(get_version): New function.
* tree.h (get_clone_versions): New function.
(get_clone_attr_versions): New function.
(get_version): New function.
---
 gcc/c-family/c-attribs.cc |  4 ++-
 gcc/tree.cc   | 57 +++
 gcc/tree.h| 11 
 3 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5a0e3d328ba..5dff489fcca 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -6132,7 +6132,9 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
 	}
 	}
 
-  if (get_target_clone_attr_len (args) == -1)
+  auto_vec versions= get_clone_attr_versions (args, NULL);
+
+  if (versions.length () == 1)
 	{
 	  warning (OPT_Wattributes,
 		   "single % attribute is ignored");
diff --git a/gcc/tree.cc b/gcc/tree.cc
index eccfcc89da4..ddbe98e1a74 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -15372,6 +15372,63 @@ get_target_clone_attr_len (tree arglist)
   return str_len_sum;
 }
 
+/* Returns an auto_vec of string_slices containing the version strings from
+   ARGLIST.  DEFAULT_COUNT is incremented for each default version found.  */
+
+auto_vec
+get_clone_attr_versions (const tree arglist, int *default_count)
+{
+  gcc_assert (TREE_CODE (arglist) == TREE_LIST);
+  auto_vec versions;
+
+  static const char separator_str[] = {TARGET_CLONES_ATTR_SEPARATOR, 0};
+  string_slice separators = string_slice (separator_str);
+
+  for (tree arg = arglist; arg; arg = TREE_CHAIN (arg))
+{
+  string_slice str = string_slice (TREE_STRING_POINTER (TREE_VALUE (arg)));
+  while (str.is_valid ())
+	{
+	  string_slice attr = string_slice::tokenize (&str, separators);
+	  attr = attr.strip ();
+
+	  if (attr == "default" && default_count)
+	(*default_count)++;
+	  versions.safe_push (attr);
+	}
+}
+  return versions;
+}
+
+/* Returns an auto_vec of string_slices containing the version strings from
+   the target_clone attribute from DECL.  DEFAULT_COUNT is incremented for each
+   default version found.  */
+auto_vec
+get_clone_versions (const tree decl, int *default_count)
+{
+  tree attr = lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl));
+  if (!attr)
+return auto_vec ();
+  tree arglist = TREE_VALUE (attr);
+  return get_clone_attr_versions (arglist, default_count);
+}
+
+/* Only works for target_version due to target attributes allowing multiple
+   string arguments to specify one target.  */
+string_slice
+get_target_version (const tree decl)
+{
+  gcc_assert (!TARGET_HAS_FMV_TARGET_ATTRIBUTE);
+
+  tree attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl));
+
+  if (!attr)
+return string_slice::invalid ();
+
+  return string_slice (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr
+	   .strip ();
+}
+
 void
 tree_cc_finalize (void)
 {
diff --git a/gcc/tree.h b/gcc/tree.h
index 55f97f9f999..e34a49a9ed9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "tree-core.h"
 #include "options.h"
+#include "vec.h"
 
 /* Convert a target-independent built-in function code to a combined_fn.  */
 
@@ -7041,4 +7042,14 @@ extern tree get_attr_nonstring_decl (tree, tree * = NULL);
 
 extern int get_target_clone_attr_len (tree);
 
+/* Returns the version string for a decl with target_version attribute.
+   Returns an invalid string_slice if no attribute is present.  */
+extern string_slice get_target_version (const tree);
+/* Returns a vector of the version strings from a target_clones attribute on
+   a decl.  Can also record the number of default versions found.  */
+extern auto_vec get_clone_versions (const tree, int * = NULL);
+/* Returns a vector of the version strings from a target_clones attribute
+   directly.  */
+extern auto_vec get_clone_attr_versions (const tree, int *);
+
 #endif  /* GCC_TREE_H  */


[PATCH v3 16/19] Refactor FMV frontend hooks and logic.

2025-03-27 Thread Alfie Richards

This change refactors FMV handling in the frontend to allows greater
reasoning about versions in shared code.

This is needed for target_version semantics and allowing target_clones
and target_versions to both be used for the declaration there are now
two questions that need to be answered for the front end.

1. Are these two declarations completely distinct FMV declarations
(ie. the versions they define have no overlap). If so, they don't match.
2. Are these two declarations matching and therefore mergeable.
(ie. two target_clone decls that define the same set of versions, or
an un-annotated declaration, and a target_clones definition containing the
default version). If so, the existing merging logic should be used to
try to merge these and diagnose if it's not possible. If not, then this
needs to be diagnosed.

To do this the common_function_versions function has been renamed
distinct_function_versions (meaning, are the versions defined by these
two functions completely distinct from eachother).

The common function version hook was changed to instead take two
string_slice's and determine if they define the same version.

There is a new function, called mergeable_version_decls which checks
if two decls (which define overlapping versions) can be merged.
For example, if they are two target_clone decls which define the exact
same set of versions.

This change also records the conflicting version so that it can be
included in diagnostics.

gcc/ChangeLog:

* attribs.cc (attr_strcmp): Moved to target specific code.
(sorted_attr_string): Moved to target specific code.
(common_function_versions): New function.
* attribs.h (sorted_attr_string): Removed.
(common_function_versions): New function.
* config/aarch64/aarch64.cc (aarch64_common_function_versions):
New function.
* config/riscv/riscv.cc (riscv_common_function_versions): New function.
* doc/tm.texi: Regenerated.
* target.def: Change common_function_versions hook.
* tree.cc (distinct_version_decls): New function.
(mergeable_version_decls): Ditto.
* tree.h (distinct_version_decls): New function.
(mergeable_version_decls): Ditto.

gcc/cp/ChangeLog:

* class.cc (resolve_address_of_overloaded_function): Updated to use
distinct_version_decls instead of common_function_version hook.
* cp-tree.h (decls_match): Updated to use
distinct_version_decls instead of common_function_version hook.
* decl.cc (decls_match): Refacture to use distinct_version_decls and
to pass through conflicting_version argument.
(maybe_version_functions): Updated to use
distinct_version_decls instead of common_function_version hook.
(duplicate_decls): Add logic to handle conflicting unmergable decls
and improve diagnostics for conflicting versions.
* decl2.cc (check_classfn): Updated to use
distinct_version_decls instead of common_function_version hook.
---
 gcc/attribs.cc|  75 ++---
 gcc/attribs.h |   3 +-
 gcc/config/aarch64/aarch64.cc |  16 ++-
 gcc/config/riscv/riscv.cc |  32 +++---
 gcc/cp/class.cc   |   4 +-
 gcc/cp/cp-tree.h  |   2 +-
 gcc/cp/decl.cc|  43 +--
 gcc/cp/decl2.cc   |   2 +-
 gcc/doc/tm.texi   |   4 +-
 gcc/target.def|   6 +-
 gcc/tree.cc   | 204 ++
 gcc/tree.h|   6 +
 12 files changed, 293 insertions(+), 104 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 80833388ff2..13ddee3376b 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1086,7 +1086,14 @@ make_attribute (string_slice name, string_slice arg_name, tree chain)
   return attr;
 }
 
-/* Common functions used for target clone support.  */
+/* Used for targets with target_version semantics.  */
+
+bool
+common_function_versions (string_slice fn1 ATTRIBUTE_UNUSED,
+			  string_slice fn2 ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable();
+}
 
 /* Comparator function to be used in qsort routine to sort attribute
specification strings to "target".  */
@@ -1176,72 +1183,6 @@ sorted_attr_string (tree arglist)
   XDELETEVEC (attr_str);
   return ret_str;
 }
-
-
-/* This function returns true if FN1 and FN2 are versions of the same function,
-   that is, the target strings of the function decls are different.  This assumes
-   that FN1 and FN2 have the same signature.  */
-
-bool
-common_function_versions (tree fn1, tree fn2)
-{
-  tree attr1, attr2;
-  char *target1, *target2;
-  bool result;
-
-  if (TREE_CODE (fn1) != FUNCTION_DECL
-  || TREE_CODE (fn2) != FUNCTION_DECL)
-return false;
-
-  attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1));
-  attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2));
-
-  /* At least one function decl should have the target attribute specified.  */
-  if (attr1

[PATCH v3 02/19] Add x86 FMV symbol tests

2025-03-27 Thread Alfie Richards

This is for testing the x86 mangling of FMV versioned function
assembly names.

gcc/testsuite/ChangeLog:

* g++.target/i386/mv-symbols1.C: New test.
* g++.target/i386/mv-symbols2.C: New test.
* g++.target/i386/mv-symbols3.C: New test.
* g++.target/i386/mv-symbols4.C: New test.
* g++.target/i386/mv-symbols5.C: New test.
* g++.target/i386/mvc-symbols1.C: New test.
* g++.target/i386/mvc-symbols2.C: New test.
* g++.target/i386/mvc-symbols3.C: New test.
* g++.target/i386/mvc-symbols4.C: New test.

Co-authored-by: Alfie Richards 
---
 gcc/testsuite/g++.target/i386/mv-symbols1.C  | 68 
 gcc/testsuite/g++.target/i386/mv-symbols2.C  | 56 
 gcc/testsuite/g++.target/i386/mv-symbols3.C  | 44 +
 gcc/testsuite/g++.target/i386/mv-symbols4.C  | 50 ++
 gcc/testsuite/g++.target/i386/mv-symbols5.C  | 56 
 gcc/testsuite/g++.target/i386/mvc-symbols1.C | 44 +
 gcc/testsuite/g++.target/i386/mvc-symbols2.C | 29 +
 gcc/testsuite/g++.target/i386/mvc-symbols3.C | 35 ++
 gcc/testsuite/g++.target/i386/mvc-symbols4.C | 23 +++
 9 files changed, 405 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/i386/mv-symbols1.C
 create mode 100644 gcc/testsuite/g++.target/i386/mv-symbols2.C
 create mode 100644 gcc/testsuite/g++.target/i386/mv-symbols3.C
 create mode 100644 gcc/testsuite/g++.target/i386/mv-symbols4.C
 create mode 100644 gcc/testsuite/g++.target/i386/mv-symbols5.C
 create mode 100644 gcc/testsuite/g++.target/i386/mvc-symbols1.C
 create mode 100644 gcc/testsuite/g++.target/i386/mvc-symbols2.C
 create mode 100644 gcc/testsuite/g++.target/i386/mvc-symbols3.C
 create mode 100644 gcc/testsuite/g++.target/i386/mvc-symbols4.C

diff --git a/gcc/testsuite/g++.target/i386/mv-symbols1.C b/gcc/testsuite/g++.target/i386/mv-symbols1.C
new file mode 100644
index 000..1290299aea5
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/mv-symbols1.C
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target("default")))
+int foo ()
+{
+  return 1;
+}
+
+__attribute__((target("arch=slm")))
+int foo ()
+{
+  return 3;
+}
+
+__attribute__((target("sse4.2")))
+int foo ()
+{
+  return 5;
+}
+
+__attribute__((target("sse4.2")))
+int foo (int)
+{
+  return 6;
+}
+
+__attribute__((target("arch=slm")))
+int foo (int)
+{
+  return 4;
+}
+
+__attribute__((target("default")))
+int foo (int)
+{
+  return 2;
+}
+
+int bar()
+{
+  return foo ();
+}
+
+int bar(int x)
+{
+  return foo (x);
+}
+
+/* When updating any of the symbol names in these tests, make sure to also
+   update any tests for their absence in mvc-symbolsN.C */
+
+/* { dg-final { scan-assembler-times "\n_Z3foov:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.arch_slm:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.sse4.2:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3foovv\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3foovv, @gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3foovv,_Z3foov\.resolver\n" 1 } } */
+
+/* { dg-final { scan-assembler-times "\n_Z3fooi:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.arch_slm:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.sse4.2:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3fooii\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3fooii, @gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3fooii,_Z3fooi\.resolver\n" 1 } } */
diff --git a/gcc/testsuite/g++.target/i386/mv-symbols2.C b/gcc/testsuite/g++.target/i386/mv-symbols2.C
new file mode 100644
index 000..8b75565d78d
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/mv-symbols2.C
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target("default")))
+int foo ()
+{
+  return 1;
+}
+
+__attribute__((target("arch=slm")))
+int foo ()
+{
+  return 3;
+}
+
+__attribute__((target("sse4.2")))
+int foo ()
+{
+  return 5;
+}
+
+__attribute__((target("sse4.2")))
+int foo (int)
+{
+  return 6;
+}
+
+__attribute__((target("arch=slm")))
+int foo (int)
+{
+  return 4;
+}
+
+__attribute__((target("default")))
+int foo (int)
+{
+  return 2;
+}
+
+/* When updating any of the symbol names in these tests, make sure to also
+   update any tests for their absence in mvc-symbolsN.C */
+
+/* { dg-final { scan-assembler-times "\n_Z3foov:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.arch_slm:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.sse4.2:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.resolve

Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-27 Thread Paul-Antoine Arras

On 25/03/2025 18:55, Sandra Loosemore wrote:

On 3/25/25 09:25, Paul-Antoine Arras wrote:

On 24/03/2025 21:17, Sandra Loosemore wrote:
[snip]
Besides, I am not sure how to encode complex types like (**const *). 
Does that require creating new definitions in gcc/builtin-types.def 
and gcc/fortran/types.def?


I don't understand what the Fortran front end has to do with this, 
BUILT_IN_GOMP_INTEROP is only referenced from gimplify.cc and omp-low.cc.


DEF_GOMP_BUILTIN defines builtins for both C/C++ and Fortran. If a type 
definition is missing in gcc/fortran/types.def, you get an error, e.g.:


gcc/fortran/../omp-builtins.def: In function 'void 
gfc_init_builtin_functions()':
gcc/fortran/../omp-builtins.def:406:19: error: 
'BT_FN_VOID_INT_INT_PTRPTRCONSTPTR_CONSTPTR_PTRCONSTSTRING_INT_PTRPTR_INT_PTRPTRCONSTPTR_UINT_PTRPTR' 
was not declared in this scope
  406 | 
BT_FN_VOID_INT_INT_PTRPTRCONSTPTR_CONSTPTR_PTRCONSTSTRING_INT_PTRPTR_INT_PTRPTRCONSTPTR_UINT_PTRPTR,
  | 
^~~
gcc/fortran/f95-lang.cc:1291:60: note: in definition of macro 
'DEF_GOMP_BUILTIN'

 1291 |   gfc_define_builtin ("__builtin_" name, builtin_types[type], \
  |^~~~

And what difference does it make to have an argument declared as 
BT_PTR instead of, say, BT_PTR_CONST_PTR_PTR? Is is just a matter of 
optimisation?

If someone could shed some light...


Well, the declaration used by GCC for code generation should match the 
definition in the library, right?


Mainly, I got to thinking about this because the "declare variant" 
interop creation/destruction code that Tobias had sketched out before 
handing it over to me included a bunch of explicit clobbers that 
confused the heck out of me.  AFAICT, the only thing that GOMP_interop 
needs to modify is the actual interop objects whose pointers are in the 
init/destroy arrays, so in my final version of the code those are the 
only things clobbered after the interop objects are destroyed.  If GCC 
knows the arrays themselves are const, that potentially also enables 
optimizations like hoisting the code to set up the argument arrays out a 
loop containing a variant call.


I updated the patch (see attachment) with that in mind. Let me know what 
you think.

--
PAcommit c379d33e55fb7af4d560ae912b9395e33b723b9f
Author: Paul-Antoine Arras 
Date:   Thu Mar 27 17:01:41 2025 +0100

OpenMP: interop - make arrays const

Treat arrays passed to GOMP_interop as const.

gcc/ChangeLog:

* builtin-types.def (BT_PTR_CONST_PTR_PTR): Define.
(BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR): Define.
* omp-builtins.def (BUILT_IN_GOMP_INTEROP): Update.

gcc/fortran/ChangeLog:

* types.def (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR):
Define.
(BT_FN_VOID_INT_INT_PTRCONSTPTRPTR_CONSTPTR_PTRCONSTSTRING_INT_PTRPTR_INT_PTRCONSTPTRPTR_UINT_PTRPTR):
Define.

libgomp/ChangeLog:

* libgomp_g.h (GOMP_interop): Make arrays const.
* target.c (struct interop_data_t): Likewise.
(GOMP_interop): Likewise.

diff --git gcc/builtin-types.def gcc/builtin-types.def
index 9583d30dfc0..c7b2e1619d1 100644
--- gcc/builtin-types.def
+++ gcc/builtin-types.def
@@ -221,6 +221,11 @@ DEF_PRIMITIVE_TYPE (BT_PTR_CONST_STRING,
 		 (build_qualified_type (string_type_node,
 	TYPE_QUAL_CONST)))
 
+/* The C type `void **const *'.  */
+DEF_PRIMITIVE_TYPE (BT_PTR_CONST_PTR_PTR,
+		build_pointer_type (build_qualified_type (
+		  build_pointer_type (ptr_type_node), TYPE_QUAL_CONST)))
+
 DEF_POINTER_TYPE (BT_PTR_UINT, BT_UINT)
 DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
 DEF_POINTER_TYPE (BT_PTR_ULONG, BT_ULONG)
@@ -1015,9 +1020,11 @@ DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_UINT_LONG_INT_ULL_
 		  BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
 		  BT_UINT, BT_LONG, BT_INT,
 		  BT_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
-DEF_FUNCTION_TYPE_11 (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR,
-		  BT_VOID, BT_INT, BT_INT, BT_PTR, BT_PTR, BT_PTR, BT_INT,
-		  BT_PTR, BT_INT, BT_PTR, BT_UINT, BT_PTR)
+DEF_FUNCTION_TYPE_11 (
+  BT_FN_VOID_INT_INT_PTRCONSTPTRPTR_CONSTPTR_PTRCONSTSTRING_INT_PTRPTR_INT_PTRCONSTPTRPTR_UINT_PTRPTR,
+  BT_VOID, BT_INT, BT_INT, BT_PTR_CONST_PTR_PTR, BT_CONST_PTR,
+  BT_PTR_CONST_STRING, BT_INT, BT_PTR_PTR, BT_INT, BT_PTR_CONST_PTR_PTR,
+  BT_UINT, BT_PTR_PTR)
 
 DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
 DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
diff --git gcc/fortran/types.def gcc/fortran/types.def
index dd9b8df59be..d68d02e819d 100644
--- gcc/fortran/types.def
+++ gcc/fortran/types.def
@@ -266,7 +266,7 @@ DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_UINT_LONG_INT_ULL_
 		  BT_PTR_FN_VOID_P

[PATCH v3 17/19] Support mixing of target_clones and target_version.

2025-03-27 Thread Alfie Richards

This patch adds support for the combination of target_clones and
target_version in the definition of a versioned function.

This patch changes is_function_default_version to consider a function
declaration annotated with target_clones containing default to be a
default version.

This takes advantage of refactoring done in previous patches changing
how target_clones are expanded and how conflicting decls are handled.

gcc/ChangeLog:

* attribs.cc (is_function_default_version): Update to handle
target_clones.
* cgraph.h (FOR_EACH_FUNCTION_REMOVABLE): New macro.
* multiple_target.cc (expand_target_clones): Update logic to delete
empty target_clones and modify diagnostic.
(ipa_target_clone): Update to use
FOR_EACH_FUNCTION_REMOVABLE.

gcc/c-family/ChangeLog:

* c-attribs.cc: Add support for target_version and target_clone mixing.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/mv-and-mvc1.C: New test.
* g++.target/aarch64/mv-and-mvc2.C: New test.
* g++.target/aarch64/mv-and-mvc3.C: New test.
* g++.target/aarch64/mv-and-mvc4.C: New test.
---
 gcc/attribs.cc| 10 -
 gcc/c-family/c-attribs.cc |  9 +---
 gcc/cgraph.h  |  7 
 gcc/multiple_target.cc| 24 +--
 .../g++.target/aarch64/mv-and-mvc1.C  | 38 +
 .../g++.target/aarch64/mv-and-mvc2.C  | 29 +
 .../g++.target/aarch64/mv-and-mvc3.C  | 41 +++
 .../g++.target/aarch64/mv-and-mvc4.C  | 38 +
 8 files changed, 183 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-and-mvc1.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-and-mvc2.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-and-mvc3.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-and-mvc4.C

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 13ddee3376b..d0127029d8e 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1247,7 +1247,8 @@ make_dispatcher_decl (const tree decl)
With the target attribute semantics, returns true if the function is marked
as default with the target version.
With the target_version attribute semantics, returns true if the function
-   is either not annotated, or annotated as default.  */
+   is either not annotated, annotated as default, or is a target_clone
+   containing the default declaration.  */
 
 bool
 is_function_default_version (const tree decl)
@@ -1264,6 +1265,13 @@ is_function_default_version (const tree decl)
 }
   else
 {
+  if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl)))
+	{
+	  int num_defaults = 0;
+	  get_clone_versions (decl, &num_defaults);
+	  return num_defaults > 0;
+	}
+
   attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl));
   if (!attr)
 	return true;
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index b5287f0da06..a4e657d9ffd 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -249,13 +249,6 @@ static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
   ATTR_EXCL ("always_inline", true, true, true),
   ATTR_EXCL ("target", TARGET_HAS_FMV_TARGET_ATTRIBUTE,
 	 TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE),
-  ATTR_EXCL ("target_version", true, true, true),
-  ATTR_EXCL (NULL, false, false, false),
-};
-
-static const struct attribute_spec::exclusions attr_target_version_exclusions[] =
-{
-  ATTR_EXCL ("target_clones", true, true, true),
   ATTR_EXCL (NULL, false, false, false),
 };
 
@@ -543,7 +536,7 @@ const struct attribute_spec c_common_gnu_attributes[] =
 			  attr_target_exclusions },
   { "target_version", 1, 1, true, false, false, false,
 			  handle_target_version_attribute,
-			  attr_target_version_exclusions },
+			  NULL },
   { "target_clones",  1, -1, true, false, false, false,
 			  handle_target_clones_attribute,
 			  attr_target_clones_exclusions },
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 8dcc9315a51..5a8ccb8042b 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -3090,6 +3090,13 @@ symbol_table::next_function_with_gimple_body (cgraph_node *node)
for ((node) = symtab->first_function (); (node); \
 	(node) = symtab->next_function ((node)))
 
+/* Walk all functions but precompute so a node can be deleted if needed.  */
+#define FOR_EACH_FUNCTION_REMOVABLE(node) \
+   cgraph_node *next; \
+   for ((node) = symtab->first_function (), \
+	next = (node) ? symtab->next_function ((node)) : NULL; (node); \
+	(node) = next, next = (node) ? symtab->next_function ((node)) : NULL)
+
 /* Return true when callgraph node is a function with Gimple body defined
in current unit.  Functions can also be define externally or they
can be thunks with no Gimple representation.
diff --git a/gcc/m

[PATCH v3 10/19] Add dispatcher_resolver_function and is_target_clone to cgraph_node.

2025-03-27 Thread Alfie Richards

These flags are used to make sure mangling is done correctly.

gcc/ChangeLog:

* cgraph.h (struct cgraph_node): Add dispatcher_resolver_function and
is_target_clone.
---
 gcc/cgraph.h | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 4a4fb7302b1..91e5de30f98 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -907,7 +907,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
   used_as_abstract_origin (false),
   lowered (false), process (false), frequency (NODE_FREQUENCY_NORMAL),
   only_called_at_startup (false), only_called_at_exit (false),
-  tm_clone (false), dispatcher_function (false), calls_comdat_local (false),
+  tm_clone (false), dispatcher_function (false),
+  dispatcher_resolver_function (false), is_target_clone (false),
+  calls_comdat_local (false),
   icf_merged (false), nonfreeing_fn (false), merged_comdat (false),
   merged_extern_inline (false), parallelized_function (false),
   split_part (false), indirect_call_target (false), local (false),
@@ -1465,6 +1467,11 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
   unsigned tm_clone : 1;
   /* True if this decl is a dispatcher for function versions.  */
   unsigned dispatcher_function : 1;
+  /* True if this decl is a resolver for function versions.  */
+  unsigned dispatcher_resolver_function : 1;
+  /* True this is part of a multiversioned set and the default version
+ comes from a target_clone attribute.  */
+  unsigned is_target_clone : 1;
   /* True if this decl calls a COMDAT-local function.  This is set up in
  compute_fn_summary and inline_call.  */
   unsigned calls_comdat_local : 1;


[PATCH v3 14/19] Add reject_target_clone hook in order to filter target_clone versions.

2025-03-27 Thread Alfie Richards

This patch introduces the TARGET_REJECT_FUNCTION_CLONE_VERSION hook
which is used to determine if a target_clones version string parses.

If true is returned, a warning is emitted and from then on the version
is ignored.

This is as specified in the Arm C Language Extension. The purpose of this
is to allow some portability of code using target_clones attributes.

Currently this is only properly implemented for the Aarch64 backend.

For riscv which is the only other backend which uses target_version
semantics a partial implementation is present, where this hook is used
to check parsing, in which errors will be emitted on a failed parse
rather than warnings. A refactor of the riscv parsing logic would be
required to enable this functionality fully.

Additionally, after refactoring the riscv logic, the location argument
to the hook would be unnecessary.

This also fixes PR 118339 where parse failures could cause ICE in Aarch64.

gcc/ChangeLog:

PR target/118339
* attribs.cc (reject_target_clone_version): New function.
* target.def: Add reject_target_clone_version hook.
* tree.cc (get_clone_attr_versions): Add filter and location argument.
(get_clone_versions): Update call to get_clone_attr_versions.
* tree.h (get_clone_attr_versions): Add filter and location argument.
* config/aarch64/aarch64.cc (aarch64_reject_target_clone_version):
New function
(TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/i386/i386.cc (TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/riscv/riscv.cc (riscv_reject_target_clone_version):
New function.
(TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/rs6000/rs6000.cc (TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* doc/tm.texi: Regenerated.
* doc/tm.texi.in: Add documentation for new hook.

gcc/c-family/ChangeLog:

* c-attribs.cc (handle_target_clones_attribute): Update to emit warnings
for rejected versions.
---
 gcc/attribs.cc|  7 +++
 gcc/c-family/c-attribs.cc | 24 
 gcc/config/aarch64/aarch64.cc | 20 
 gcc/config/i386/i386.cc   |  3 +++
 gcc/config/riscv/riscv.cc | 18 ++
 gcc/config/rs6000/rs6000.cc   |  3 +++
 gcc/doc/tm.texi   |  5 +
 gcc/doc/tm.texi.in|  2 ++
 gcc/target.def|  8 
 gcc/tree.cc   | 12 ++--
 gcc/tree.h|  8 ++--
 11 files changed, 102 insertions(+), 8 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 09c4db96531..80833388ff2 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1242,6 +1242,13 @@ common_function_versions (tree fn1, tree fn2)
   return result;
 }
 
+bool
+reject_target_clone_version (string_slice str ATTRIBUTE_UNUSED,
+			 location_t loc ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
 /* Make a dispatcher declaration for the multi-versioned function DECL.
Calls to DECL function will be replaced with calls to the dispatcher
by the front-end.  Return the decl created.  */
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5dff489fcca..b5287f0da06 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -6132,12 +6132,28 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
 	}
 	}
 
-  auto_vec versions= get_clone_attr_versions (args, NULL);
+  int num_defaults = 0;
+  auto_vec versions= get_clone_attr_versions (args,
+  &num_defaults,
+  DECL_SOURCE_LOCATION (*node),
+  false);
 
-  if (versions.length () == 1)
-	{
+  for (auto v : versions)
+	if (targetm.reject_function_clone_version
+	  (v, DECL_SOURCE_LOCATION (*node)))
 	  warning (OPT_Wattributes,
-		   "single % attribute is ignored");
+		   "invalid % version %qB ignored",
+		   &v);
+
+  /* Lone target_clones version is always ignored for target attr semantics.
+	 Only ignore under target_version semantics if it is a default
+	 version.  */
+  if (versions.length () == 1 && (TARGET_HAS_FMV_TARGET_ATTRIBUTE
+  || num_defaults == 1))
+	{
+	  if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+	warning (OPT_Wattributes,
+		 "single % attribute is ignored");
 	  *no_add_attrs = true;
 	}
   else
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index fe46e569afe..1b9d91d268a 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -31224,6 +31224,23 @@ aarch64_expand_reversed_crc_using_pmull (scalar_mode crc_mode,
 }
 }
 
+bool
+aarch64_reject_target_clone_version (string_slice str,
+ location_t loc ATTRIBUTE_UNUSED)
+{
+  str = str.strip ();
+
+  if (str == "default")
+return false;
+
+  enum aarch_parse_opt_result parse_res;
+  auto isa_flags = aarch64_asm_isa_flags;
+  parse_res = 

[PATCH v3 05/19] Update is_function_default_version to work with target_version.

2025-03-27 Thread Alfie Richards

Notably this respects target_version semantics where an unannotated
function can be the default version.

gcc/ChangeLog:

* attribs.cc (is_function_default_version): Add target_version logic.
---
 gcc/attribs.cc | 27 ---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 56dd18c2fa8..f6667839c01 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1279,18 +1279,31 @@ make_dispatcher_decl (const tree decl)
   return func_decl;
 }
 
-/* Returns true if DECL is multi-versioned using the target attribute, and this
-   is the default version.  This function can only be used for targets that do
-   not support the "target_version" attribute.  */
+/* Returns true if DECL a multiversioned default.
+   With the target attribute semantics, returns true if the function is marked
+   as default with the target version.
+   With the target_version attribute semantics, returns true if the function
+   is either not annotated, or annotated as default.  */
 
 bool
 is_function_default_version (const tree decl)
 {
-  if (TREE_CODE (decl) != FUNCTION_DECL
-  || !DECL_FUNCTION_VERSIONED (decl))
+  tree attr;
+  if (TREE_CODE (decl) != FUNCTION_DECL)
 return false;
-  tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
-  gcc_assert (attr);
+  if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+{
+  if (!DECL_FUNCTION_VERSIONED (decl))
+	return false;
+  attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
+  gcc_assert (attr);
+}
+  else
+{
+  attr = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl));
+  if (!attr)
+	return true;
+}
   attr = TREE_VALUE (TREE_VALUE (attr));
   return (TREE_CODE (attr) == STRING_CST
 	  && strcmp (TREE_STRING_POINTER (attr), "default") == 0);


Re: [PATCH][PUSHED] hwasan: support new dg-output format.

2025-03-27 Thread Mike Stump
On Mar 20, 2025, at 8:11 AM, Alex Coplan  wrote:
> On 09/02/2024 15:32, Alex Coplan wrote:
>> On 04/05/2022 09:59, Martin Liška wrote:
>>> Supports change in libsanitizer where it newly reports:
>>> READ of size 4 at 0xc3d4 tags: 02/01(00) (ptr/mem) in thread T0
>>> 
>>> So the 'tags' contains now 3 entries compared to 2 entries.
>>> 
>>> gcc/testsuite/ChangeLog:
>>> 
>>> * c-c++-common/hwasan/alloca-outside-caught.c: Update dg-output.
>>> * c-c++-common/hwasan/heap-overflow.c: Likewise.
>>> * c-c++-common/hwasan/hwasan-thread-access-parent.c: Likewise.
>>> * c-c++-common/hwasan/large-aligned-1.c: Likewise.
>> 
>> I noticed the above test (large-aligned-1.c) failing on the GCC 12
>> branch due to the change in output format mentioned above.  This patch
>> (committed as r13-100-g3771486daa1e904ceae6f3e135b28e58af33849f) seems
>> to apply cleanly on the GCC 12 branch too, is it OK to backport to GCC 12?
> 
> Ping.

Ok.


[PATCH] tailc: Handle musttail noreturn calls [PR119483]

2025-03-27 Thread Jakub Jelinek
Hi!

The following (first) testcase is accepted by clang (if clang::musttail)
and rejected by gcc, because we discover the call is noreturn and then bail
out because we don't want noreturn tailcalls.
The general reason not to support noreturn tail calls is for cases like
abort where we want nicer backtrace, but if user asks explicitly to
musttail a call which either is explicitly noreturn or is implicitly
determined to be noreturn, I don't see a reason why we couldn't do that.
Both for tail calls and tail recursions.

An alternative would be to keep rejecting musttail to explicit noreturn,
but not actually implicitly mark anything as noreturn if it has any musttail
calls.  But it is unclear how we could do that, such marking is I think done
typically before IPA and e.g. for LTO we won't know whether some other TU
could have musttail calls to it.  And keeping around both explicit and
implicit noreturn bits would be ugly.  Well, I guess we could differentiate
between presence of noreturn/_Noreturn attributes and just ECF_NORETURN
without those, but then tailc would still need to support it, just error out
if it was explicit.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-03-27  Jakub Jelinek  

PR tree-optimization/119483
* tree-tailcall.cc (find_tail_calls): Handle noreturn musttail
calls.
(eliminate_tail_call): Likewise.
(tree_optimize_tail_calls_1): If cfun->has_musttail and
diag_musttail, handle also basic blocks with no successors
with noreturn musttail calls.
* calls.cc (can_implement_as_sibling_call_p): Allow ECF_NORETURN
calls if they are musttail calls.

* c-c++-common/pr119483-1.c: New test.
* c-c++-common/pr119483-2.c: New test.

--- gcc/tree-tailcall.cc.jj 2025-03-25 09:36:31.502487137 +0100
+++ gcc/tree-tailcall.cc2025-03-27 16:18:30.017898249 +0100
@@ -484,7 +484,8 @@ find_tail_calls (basic_block bb, struct
   size_t idx;
   tree var;
 
-  if (!single_succ_p (bb))
+  if (!single_succ_p (bb)
+  && (EDGE_COUNT (bb->succs) || !cfun->has_musttail || !diag_musttail))
 {
   /* If there is an abnormal edge assume it's the only extra one.
 Tolerate that case so that we can give better error messages
@@ -605,7 +606,7 @@ find_tail_calls (basic_block bb, struct
   /* If the call might throw an exception that wouldn't propagate out of
  cfun, we can't transform to a tail or sibling call (82081).  */
   if ((stmt_could_throw_p (cfun, stmt)
-   && !stmt_can_throw_external (cfun, stmt)) || !single_succ_p (bb))
+   && !stmt_can_throw_external (cfun, stmt)) || EDGE_COUNT (bb->succs) > 1)
   {
 if (stmt == last_stmt)
   maybe_error_musttail (call,
@@ -760,10 +761,12 @@ find_tail_calls (basic_block bb, struct
   a = NULL_TREE;
   auto_bitmap to_move_defs;
   auto_vec to_move_stmts;
+  bool is_noreturn
+= EDGE_COUNT (bb->succs) == 0 && gimple_call_noreturn_p (call);
 
   abb = bb;
   agsi = gsi;
-  while (1)
+  while (!is_noreturn)
 {
   tree tmp_a = NULL_TREE;
   tree tmp_m = NULL_TREE;
@@ -844,7 +847,22 @@ find_tail_calls (basic_block bb, struct
 }
 
   /* See if this is a tail call we can handle.  */
-  ret_var = gimple_return_retval (as_a  (stmt));
+  if (is_noreturn)
+{
+  tree rettype = TREE_TYPE (TREE_TYPE (current_function_decl));
+  tree calltype = TREE_TYPE (gimple_call_fntype (call));
+  if (!VOID_TYPE_P (rettype)
+ && !useless_type_conversion_p (rettype, calltype))
+   {
+ maybe_error_musttail (call,
+   _("call and return value are different"),
+   diag_musttail);
+ return;
+   }
+  ret_var = NULL_TREE;
+}
+  else
+ret_var = gimple_return_retval (as_a  (stmt));
 
   /* We may proceed if there either is no return value, or the return value
  is identical to the call's return or if the return decl is an empty type
@@ -1153,24 +1171,32 @@ eliminate_tail_call (struct tailcall *t,
gsi_prev (&gsi2);
 }
 
-  /* Number of executions of function has reduced by the tailcall.  */
-  e = single_succ_edge (gsi_bb (t->call_gsi));
+  if (gimple_call_noreturn_p (as_a  (stmt)))
+{
+  e = make_edge (gsi_bb (t->call_gsi), first, EDGE_FALLTHRU);
+  e->probability = profile_probability::always ();
+}
+  else
+{
+  /* Number of executions of function has reduced by the tailcall.  */
+  e = single_succ_edge (gsi_bb (t->call_gsi));
 
-  profile_count count = e->count ();
+  profile_count count = e->count ();
 
-  /* When profile is inconsistent and the recursion edge is more frequent
- than number of executions of functions, scale it down, so we do not end
- up with 0 executions of entry block.  */
-  if (count >= ENTRY_BLOCK_PTR_FOR_FN (cfun)->count)
-count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.apply_scale (7, 8);
-  decrease_profile (EXIT_BLOCK_PTR_FOR_FN (cfun), 

Re: [PATCH 00/12] Implement a new dg-lint tool and use on our testsuite

2025-03-27 Thread Mike Stump
On Mar 26, 2025, at 11:34 AM, David Malcolm  wrote:
> 
> This patch kit:
>  * adds minimal Python bindings for libgdiagnostics.so (below contrib)
>  * implements a new dg-lint tool (below contrib) to detect for
>common mistakes in our testsuite, using Python 3 (and the above
>bindings)
>  * fixes a bunch of issues reported by the tool
> 
> I've only tested the testsuite fixes on x86_64-pc-linux-gnu; there
> were some new PASSes and no regressions, but I haven't tested the
> tests on non-x86 archs.
> 
> Thoughts?

Thanks.  :-)

A quick glance through the patches, seems fine, seems obvious. The obvious can 
go in, feel free to ask again for anything tricky.



Fix too late initialization of tasking runtime with standalone library

2025-03-27 Thread Eric Botcazou
The Tasking_Runtime_Initialize routine installs the tasking version of the 
RTS_Lock manipulation routines and thus needs to be called very early before 
the elaboration of all the Ada units of the program, including those of the 
runtime itself.

This is guaranteed by the binder when the tasking runtime is explicitly 
dragged into the link.  However, for a standalone dynamic library that does 
not depend on the tasking runtime and is auto-initialized, no such guarantee 
holds, even though the library might be later dragged into a link that 
contains the tasking runtime.

This change causes the routine to be called even earlier, in particular at 
load time when a (standalone) dynamic library is involved in the link, so as 
to meet the requirements.  It will cause the routine to be called twice if the 
main subprogram is generated by the binder, but this is harmless since the 
routine is idempotent.

Tested on x86-64/Linux, applied on the mainline (branches are not affected).


2025-03-27  Eric Botcazou  

ada/
* libgnarl/s-tasini.adb (Tasking_Runtime_Initialize): Add pragma
Linker_Constructor for the procedure.

-- 
Eric Botcazoudiff --git a/gcc/ada/libgnarl/s-tasini.adb b/gcc/ada/libgnarl/s-tasini.adb
index 144ac7c1c4e..ae0826590c8 100644
--- a/gcc/ada/libgnarl/s-tasini.adb
+++ b/gcc/ada/libgnarl/s-tasini.adb
@@ -115,11 +115,13 @@ package body System.Tasking.Initialization is
procedure Tasking_Runtime_Initialize;
pragma Export (Ada, Tasking_Runtime_Initialize,
   "__gnat_tasking_runtime_initialize");
+   pragma Linker_Constructor (Tasking_Runtime_Initialize);
--  This procedure starts the initialization of the GNARL. It installs the
-   --  tasking versions of the RTS_Lock manipulation routines. It is called
+   --  tasking version of the RTS_Lock manipulation routines. It is called
--  very early before the elaboration of all the Ada units of the program,
--  including those of the runtime, because this elaboration may require
-   --  the initialization of RTS_Lock objects.
+   --  the initialization of RTS_Lock objects, which means that it must only
+   --  contain code to which pragma Restrictions (No_Elaboration_Code) applies.
 
--
-- Change_Base_Priority --


Re: [libstdc++] Optimize string constructors

2025-03-27 Thread Bernhard Reutner-Fischer


>> > diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr80331.C 
>> > b/gcc/testsuite/g++.dg/tree-ssa/pr80331.C
>> > new file mode 100644
>> > index 000..85034504f2f
>> > --- /dev/null
>> > +++ b/gcc/testsuite/g++.dg/tree-ssa/pr80331.C
>> > @@ -0,0 +1,8 @@
>> > +// { dg-do compile }
>> > +// { dg-additional-options "-O2 -fdump-tree-optimized" }
>> > +#include
>> > +int sain() {
>> > +  const std::string remove_me("remove_me");
>> > +  return 0;
>> > +}
>> > +// { dg-final { scan-tree-dump-not "remove_me" "optimized" } }
>> > diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr87502.C 
>> > b/gcc/testsuite/g++.dg/tree-ssa/pr87502.C
>> > new file mode 100644
>> > index 000..7975432597d
>> > --- /dev/null
>> > +++ b/gcc/testsuite/g++.dg/tree-ssa/pr87502.C
>> > @@ -0,0 +1,16 @@
>> > +// { dg-do compile }
>> > +// { dg-additional-options "-O2 -fdump-tree-optimized" }
>> > +#include 
>> > +
>> > +
>> > +__attribute__ ((pure))
>> > +extern int foo (const std::string &);
>> > +
>> > +int
>> > +bar ()
>> > +{
>> > +  return foo ("abc") + foo (std::string("abc"));
>> > +}
>> > +// We used to add terminating zero explicitely instead of using fact
>> > +// that memcpy source is already 0 terminated.
>> > +// { dg-final { scan-tree-dump-not "remove_me" "= 0;" } }

Copy'n paste error



Re: [PATCH] change cbl_field_data_t::etc_t::value from _Float128 to tree

2025-03-27 Thread Jakub Jelinek
On Fri, Mar 21, 2025 at 08:25:10PM +0100, Richard Biener wrote:
> > --- gcc/cobol/parse.y.jj2025-03-21 17:49:43.571440176 +0100
> > +++ gcc/cobol/parse.y   2025-03-21 20:15:24.852414777 +0100
> > @@ -4331,7 +4331,8 @@ value_clause:   VALUE all LITERAL[lit] {
> >cbl_field_t *field = current_field();
> >auto orig_str = original_number();
> >   REAL_VALUE_TYPE orig_val;
> > - real_from_string (&orig_val, orig_str);
> > + real_from_string3 (&orig_val, orig_str,
> > +TYPE_MODE (float128_type_node));
> >char *initial = NULL;
> >  
> >if( real_identical (&orig_val, &$value) ) {
> > @@ -6922,7 +6923,8 @@ cce_expr:   cce_factor
> >  cce_factor: NUMSTR {
> >/* ???  real_from_string does not allow arbitrary radix. 
> >  */
> >// $$ = numstr2i($1.string, $1.radix);
> > - real_from_string (&$$, $1.string);
> > + real_from_string3 (&$$, $1.string,
> > +TYPE_MODE (float128_type_node));
> >  }
> >  ;
> >  
> > 
> > The old code was just using _Float128 which has the IEEE quad precision,
> > but REAL_VALUE_TYPE in GCC actually has larger internal precision than that,
> > so if it isn't rounded to the IEEE quad precision first and builds REAL_CST,
> > it isn't the expected 0.01002 but
> > 0.0099...

Without real_from_string3 (or real_from_string + real_convert, the former is
just a shorthand for that) you can have excess precision in the stored
REAL_VALUE_TYPE, which certainly can't then match what happens when the FE
uses _Float128 directly.

> we've come from initial_from_float128 which does
> 
>   REAL_VALUE_TYPE pow10
> = real_powi10 (field->data.digits + field->data.rdigits);
>   real_arithmetic (&value, MULT_EXPR, &value, &pow10);
> 
> which produces the 1.0e+0 - do I need to process this to be "normal"?

That real_arithmetic is also supposed to be followed by real_convert,
otherwise again there is an excess precision.  That could be desirable at
times but certainly not if it attempts to work the same as former
_Float128 *= __int128.
Because that computation also rounds.

When fold-const.cc calls real_arithmetic, it does that as well:
  inexact = real_arithmetic (&value, code, &d1, &d2);
  real_convert (&result, mode, &value);

Jakub



[COMMITTED 135/146] gccrs: derive(Clone): Mark PhantomData as a lang item

2025-03-27 Thread arthur . cohen
From: Arthur Cohen 

gcc/testsuite/ChangeLog:

* rust/compile/derive_macro4.rs: Make PhantomData a lang item.
---
 gcc/testsuite/rust/compile/derive_macro4.rs | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/gcc/testsuite/rust/compile/derive_macro4.rs 
b/gcc/testsuite/rust/compile/derive_macro4.rs
index 7802e8fd800..b20043ba927 100644
--- a/gcc/testsuite/rust/compile/derive_macro4.rs
+++ b/gcc/testsuite/rust/compile/derive_macro4.rs
@@ -6,12 +6,9 @@ pub trait Clone {
 fn clone(&self) -> Self;
 }
 
+#[lang = "phantom_data"]
 struct PhantomData;
 
-pub struct AssertParamIsCopy {
-_field: PhantomData,
-}
-
 #[derive(Clone)] // { dg-error "bounds not satisfied for U .Copy. is not 
satisfied" }
 union U {
 i: i32,
-- 
2.45.2



[COMMITTED 082/146] gccrs: parser: Add testcases for multiline strings

2025-03-27 Thread arthur . cohen
From: Arthur Cohen 

Regression checks for Rust-GCC#1399

gcc/testsuite/ChangeLog:

* rust/compile/multiline-string.rs: New test.
* rust/execute/torture/multiline-string.rs: New test.
---
 gcc/testsuite/rust/compile/multiline-string.rs| 14 ++
 .../rust/execute/torture/multiline-string.rs  | 15 +++
 2 files changed, 29 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/multiline-string.rs
 create mode 100644 gcc/testsuite/rust/execute/torture/multiline-string.rs

diff --git a/gcc/testsuite/rust/compile/multiline-string.rs 
b/gcc/testsuite/rust/compile/multiline-string.rs
new file mode 100644
index 000..fcd6fa812ed
--- /dev/null
+++ b/gcc/testsuite/rust/compile/multiline-string.rs
@@ -0,0 +1,14 @@
+fn main() {
+let _a = "gcc
+
+rs";
+
+let _b = "rust
+
+c
+gcc
+
+
+
+rs";
+}
diff --git a/gcc/testsuite/rust/execute/torture/multiline-string.rs 
b/gcc/testsuite/rust/execute/torture/multiline-string.rs
new file mode 100644
index 000..4d22f991ad3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/multiline-string.rs
@@ -0,0 +1,15 @@
+// { dg-output "gcc\n\nrs\n" }
+
+extern "C" {
+fn printf(fmt: *const i8, ...);
+}
+
+fn main() -> i32 {
+let a = "gcc
+
+rs\0";
+
+unsafe { printf("%s\n\0" as *const str as *const i8, a as *const str as 
*const i8); }
+
+0
+}
-- 
2.45.2



Re: [PATCH] libstdc++: Fix std::ranges::iter_move for function references [PR119469]

2025-03-27 Thread Tomasz Kaminski
On Wed, Mar 26, 2025 at 12:29 PM Jonathan Wakely  wrote:

> The result of std::move (or a cast to an rvalue reference) on a function
> reference is always an lvalue. Because std::ranges::iter_move was using
> the type std::remove_reference_t&& as the result of std::move, it was
> giving the wrong type for function references. Use a decltype-specifier
> with declval>() instead of just using the
> remove_reference_t&& type directly. This gives the right result,
> while still avoiding the cost of doing overload resolution for
> std::move.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/119469
> * include/bits/iterator_concepts.h (_IterMove::__result): Use
> decltype-specifier instead of an explicit type.
> * testsuite/24_iterators/customization_points/iter_move.cc:
> Check results for function references.
> ---
>
> This one is weird, but I think the fix is right.
>
Interesting, for T being a function type, T&& is forming rvalue reference
to function type,
but we only yield values of function type, so decltype would give T&.

LGTM.
I am not sold on why I would care about the result of calling iter_move on
function reference
(not iterator returning function reference), but standard seem to require
that we support it,
because * works on them due decay to pointer.


> Testing x86_64-linux.
>
>  libstdc++-v3/include/bits/iterator_concepts.h | 11 +--
>  .../24_iterators/customization_points/iter_move.cc| 11 +++
>  2 files changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/iterator_concepts.h
> b/libstdc++-v3/include/bits/iterator_concepts.h
> index a201e24d2e2..e36556dc512 100644
> --- a/libstdc++-v3/include/bits/iterator_concepts.h
> +++ b/libstdc++-v3/include/bits/iterator_concepts.h
> @@ -133,12 +133,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   struct __result<_Tp>
>   { using type = decltype(iter_move(std::declval<_Tp>())); };
>
> -   // Otherwise, if *E if an lvalue, use std::move(*E).
> +   // Otherwise, if *E is an lvalue, use std::move(*E).
> template
>   requires (!__adl_imove<_Tp>)
> && is_lvalue_reference_v<__iter_ref_t<_Tp>>
>   struct __result<_Tp>
> - { using type = remove_reference_t<__iter_ref_t<_Tp>>&&; };
> + {
> +   // Instead of decltype(std::move(*E)) we define the type as the
> +   // return type of std::move, i.e.
> remove_reference_t&&.
> +   // N.B. the use of decltype(declval()) instead of just X&&
> is
> +   // needed for function reference types, see PR
> libstdc++/119469.
> +   using type
> + =
> decltype(std::declval>>());
> + };
>
> template
>   static constexpr bool
> diff --git
> a/libstdc++-v3/testsuite/24_iterators/customization_points/iter_move.cc
> b/libstdc++-v3/testsuite/24_iterators/customization_points/iter_move.cc
> index 341bd5b98d7..87375746dfd 100644
> --- a/libstdc++-v3/testsuite/24_iterators/customization_points/iter_move.cc
> +++ b/libstdc++-v3/testsuite/24_iterators/customization_points/iter_move.cc
> @@ -157,9 +157,20 @@ test_pr106612()
>static_assert( std::same_as
> );
>  }
>
> +void
> +test_pr119469()
> +{
> +  // rvalue references to function types are weird.
> +  using F = int();
> +  static_assert( std::same_as, F&> );
> +  static_assert( std::same_as, F&> );
> +  static_assert( std::same_as, F&> );
>
+}
> +
>  int
>  main()
>  {
>test01();
>test_adl();
> +  test_pr119469();
>  }
> --
> 2.49.0
>
>


[ping] [PATCH] libiberty, gcc: Add memrchr to libiberty and use it [PR119283].

2025-03-27 Thread Iain Sandoe
this (or an alternate implementation) is needed for the cobol FE to build on 
darwin,

> On 21 Mar 2025, at 10:00, Iain Sandoe  wrote:
> 
> It seems that libiberty already has replacements for most of the
> mem* functions, but they are not published via include/libiberty.h.
> 
> Tested on x86_64 Linux, Darwin aarch64 Linux, OK for trunk?
> thanks,
> Iain
> 
> --- 8< ---
> 
> This adds an implementation of memrchr to libiberty and arranges
> to configure gcc to use it, if the host does not have it.
> 
> gcc/ChangeLog:
> 
>   * config.in: Regenerate.
>   * configure: Regenerate.
>   * configure.ac: Check for host memrchr.
> 
> include/ChangeLog:
> 
>   * libiberty.h (memrchr): New.
> 
> libiberty/ChangeLog:
> 
>   * Makefile.in: Add memrchr build rules.
>   * config.in: Regenerate.
>   * configure: Regenerate.
>   * configure.ac: Check for memrchr.
>   * functions.texi: Document memrchr.
>   * memrchr.c: New file.
> 
> Signed-off-by: Iain Sandoe 
> ---
> gcc/config.in|  6 ++
> gcc/configure|  2 +-
> gcc/configure.ac |  2 +-
> include/libiberty.h  | 10 ++
> libiberty/Makefile.in| 17 +
> libiberty/config.in  |  3 +++
> libiberty/configure  |  5 +++--
> libiberty/configure.ac   |  5 +++--
> libiberty/functions.texi | 14 ++
> libiberty/memrchr.c  | 33 +
> 10 files changed, 87 insertions(+), 10 deletions(-)
> create mode 100644 libiberty/memrchr.c
> 
> diff --git a/gcc/config.in b/gcc/config.in
> index 0d8a6ba1808..7c89cab7717 100644
> --- a/gcc/config.in
> +++ b/gcc/config.in
> @@ -1960,6 +1960,12 @@
> #endif
> 
> 
> +/* Define to 1 if you have the `memrchr' function. */
> +#ifndef USED_FOR_TARGET
> +#undef HAVE_MEMRCHR
> +#endif
> +
> +
> /* Define to 1 if you have the `mmap' function. */
> #ifndef USED_FOR_TARGET
> #undef HAVE_MMAP
> diff --git a/gcc/configure b/gcc/configure
> index 063b9ce6701..ab6bec1f0ae 100755
> --- a/gcc/configure
> +++ b/gcc/configure
> @@ -10640,7 +10640,7 @@ for ac_func in times clock kill getrlimit setrlimit 
> atoq \
>   popen sysconf strsignal getrusage nl_langinfo \
>   gettimeofday mbstowcs wcswidth mmap posix_fallocate setlocale \
>   clearerr_unlocked feof_unlocked   ferror_unlocked fflush_unlocked 
> fgetc_unlocked fgets_unlocked   fileno_unlocked fprintf_unlocked 
> fputc_unlocked fputs_unlocked   fread_unlocked fwrite_unlocked 
> getchar_unlocked getc_unlocked   putchar_unlocked putc_unlocked madvise 
> mallinfo mallinfo2 fstatat getauxval \
> - clock_gettime munmap msync get_current_dir_name
> + clock_gettime munmap msync get_current_dir_name memrchr
> do :
>   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
> ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index 3243472680c..fca0579574f 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -1574,7 +1574,7 @@ AC_CHECK_FUNCS(times clock kill getrlimit setrlimit 
> atoq \
>   popen sysconf strsignal getrusage nl_langinfo \
>   gettimeofday mbstowcs wcswidth mmap posix_fallocate setlocale \
>   gcc_UNLOCKED_FUNCS madvise mallinfo mallinfo2 fstatat getauxval \
> - clock_gettime munmap msync get_current_dir_name)
> + clock_gettime munmap msync get_current_dir_name memrchr)
> 
> # At least for glibc, clock_gettime is in librt.  But don't pull that
> # in if it still doesn't give us the function we want.
> diff --git a/include/libiberty.h b/include/libiberty.h
> index f2e763a306a..d4e8791b14b 100644
> --- a/include/libiberty.h
> +++ b/include/libiberty.h
> @@ -215,6 +215,16 @@ extern int ffs(int);
> extern int mkstemps(char *, int);
> #endif
> 
> +#if defined (HAVE_DECL_MKSTEMPS) && !HAVE_DECL_MKSTEMPS
> +extern int mkstemps(char *, int);
> +#endif
> +
> +/* Make memrchr available on systems that do not have it.  */
> +#if !defined (__GNU_LIBRARY__ ) && !defined (__linux__) && \
> +!defined (HAVE_MEMRCHR)
> +extern void *memrchr(const void *, int, size_t);
> +#endif
> +
> /* Get the working directory.  The result is cached, so don't call
>chdir() between calls to getpwd().  */
> 
> diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
> index 4870fa95f2f..ce54d88278d 100644
> --- a/libiberty/Makefile.in
> +++ b/libiberty/Makefile.in
> @@ -139,8 +139,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c  
> \
>   ldirname.c  \
>   lrealpath.c \
>   make-relative-prefix.c  \
> - make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmem.c  \
> -  memmove.c mempcpy.c memset.c mkstemps.c\
> + make-temp-file.c md5.c memchr.c memrchr.c memcmp.c memcpy.c \
> + memmem.c memmove.c mempcpy.c memset.c mkstemps.c\
>   

[PATCH] cobol: Do not include (no longer needed).

2025-03-27 Thread Iain Sandoe
As noted in the commit log, the macOS version of cmath (at least) has
conflicts with parse.y.  Tested on x86_64,aarch64 linux, x86_64-darwin.
OK for trunk?
thanks,
Iain

--- 8< ---

Several of enumerators in parse.y conflict with ones declared in at
least some versions of  .. e.g. "OVERFLOW".  The header is no
longer needed since the FE is not trying to do host arithmetic.

gcc/cobol/ChangeLog:

* cobol-system.h: Remove .

Signed-off-by: Iain Sandoe 
---
 gcc/cobol/cobol-system.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/cobol/cobol-system.h b/gcc/cobol/cobol-system.h
index 81529bd3a67..ff9583530e2 100644
--- a/gcc/cobol/cobol-system.h
+++ b/gcc/cobol/cobol-system.h
@@ -53,7 +53,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
-- 
2.39.2 (Apple Git-143)



[PATCH] target/119010 - add missing DF load/store reservations for znver4 and znver5

2025-03-27 Thread Richard Biener
The following resolves missing reservations for DFmode *movdf_internal
loads and stores, visible as 'nothing' in -fsched-verbose=2 dumps.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

PR target/119010
* config/i386/zn4zn5.md (znver4_sse_mov_fp, znver4_sse_mov_fp_load,
znver5_sse_mov_fp_load, znver4_sse_mov_fp_store,
znver5_sse_mov_fp_store): Also match V1SF and DF.
---
 gcc/config/i386/zn4zn5.md | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/config/i386/zn4zn5.md b/gcc/config/i386/zn4zn5.md
index ae188a1201e..f8772fed620 100644
--- a/gcc/config/i386/zn4zn5.md
+++ b/gcc/config/i386/zn4zn5.md
@@ -986,35 +986,35 @@
 (define_insn_reservation "znver4_sse_mov_fp" 1
 (and (eq_attr "cpu" "znver4,znver5")
  (and (eq_attr "type" "ssemov")
-  (and (eq_attr "mode" 
"V16SF,V8DF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V16SF,V8DF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "none"
 "znver4-direct,znver4-fpu")
 
 (define_insn_reservation "znver4_sse_mov_fp_load" 6
 (and (eq_attr "cpu" "znver4")
  (and (eq_attr "type" "ssemov")
-  (and (eq_attr "mode" 
"V16SF,V8DF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V16SF,V8DF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "load"
 "znver4-direct,znver4-load,znver4-fpu")
 
 (define_insn_reservation "znver5_sse_mov_fp_load" 6
 (and (eq_attr "cpu" "znver5")
  (and (eq_attr "type" "ssemov")
-  (and (eq_attr "mode" 
"V16SF,V8DF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V16SF,V8DF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "load"
 "znver4-direct,znver5-load,znver4-fpu")
 
 (define_insn_reservation "znver4_sse_mov_fp_store" 1
 (and (eq_attr "cpu" "znver4")
  (and (eq_attr "type" "ssemov")
-  (and (eq_attr "mode" 
"V16SF,V8DF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V16SF,V8DF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "store"
 "znver4-direct,znver4-fp-store")
 
 (define_insn_reservation "znver5_sse_mov_fp_store" 1
 (and (eq_attr "cpu" "znver5")
  (and (eq_attr "type" "ssemov")
-  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "store"
 "znver4-direct,znver5-fp-store256")
 
-- 
2.43.0


[PATCH] target/119474 - more DFmode handling in zn4zn5 reservations

2025-03-27 Thread Richard Biener
The following adds DFmode where V1DFmode and SFmode were handled.
This resolves missing reservations for adds, subs [with memory]
and for FMAs for the testcase I'm looking at.  Resolved cases are

-;;  16--> b  0: i 237 xmm3=xmm3+[r9*0x8+si]   :nothing
-;;  29--> b  0: i 246 xmm3=xmm3+xmm1  :nothing
-;;  46--> b  0: i 296 xmm1=xmm1-xmm3  :nothing

I've done search-and-replace for this, the catched cases look reasonable
though I'm of course not sure all of them can actually happen.

This also fixes the matched type for the znver{4,5}_sse_muladd_load
reservations from sseshuf to ssemuladd, resolving

-;;   1--> b  0: i 161 xmm0={-xmm0*xmm27+[cx+ax]}  :nothing
-;;  22--> b  0: i 229 xmm11={-xmm11*xmm7+[di*0x8+dx]} :nothing

Bootstrap and regtest running on x86_64-unknown-linux-gnu.  OK?

PR target/119474
* config/i386/zn4zn5.md (znver4_sse_add, znver4_sse_add_load,
znver5_sse_add_load, znver4_sse_add1, znver4_sse_add1_load,
znver5_sse_add1_load, znver4_sse_mul, znver4_sse_mul_load,
znver5_sse_mul_load, znver4_sse_cvt, znver4_sse_cvt_load,
znver5_sse_cvt_load, znver4_sse_shuf, znver5_sse_shuf,
znver4_sse_shuf_load, znver5_sse_shuf_load,
znver4_sse_cmp_avx128, znver5_sse_cmp_avx128,
znver4_sse_cmp_avx128_load, znver5_sse_cmp_avx128_load):
Also handle DFmode.
(znver4_sse_muladd_load, znver5_sse_muladd_load): Use
ssemuladd type.
---
 gcc/config/i386/zn4zn5.md | 44 +++
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/gcc/config/i386/zn4zn5.md b/gcc/config/i386/zn4zn5.md
index 954cdc528d6..5a3960e9d01 100644
--- a/gcc/config/i386/zn4zn5.md
+++ b/gcc/config/i386/zn4zn5.md
@@ -1054,42 +1054,42 @@
 (define_insn_reservation "znver4_sse_add" 3
 (and (eq_attr "cpu" "znver4,znver5")
  (and (eq_attr "type" "sseadd")
-  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "none"
 "znver4-direct,znver4-fpu2|znver4-fpu3")
 
 (define_insn_reservation "znver4_sse_add_load" 8
 (and (eq_attr "cpu" "znver4")
  (and (eq_attr "type" "sseadd")
-  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "load"
 "znver4-direct,znver4-load,znver4-fpu2|znver4-fpu3")
 
 (define_insn_reservation "znver5_sse_add_load" 8
 (and (eq_attr "cpu" "znver5")
  (and (eq_attr "type" "sseadd")
-  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "load"
 "znver4-direct,znver5-load,znver4-fpu2|znver4-fpu3")
 
 (define_insn_reservation "znver4_sse_add1" 4
 (and (eq_attr "cpu" "znver4,znver5")
  (and (eq_attr "type" "sseadd1")
-  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "none"
 "znver4-vector,znver4-fvector*2")
 
 (define_insn_reservation "znver4_sse_add1_load" 9
 (and (eq_attr "cpu" "znver4")
  (and (eq_attr "type" "sseadd1")
-  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "load"
 "znver4-vector,znver4-load,znver4-fvector*2")
 
 (define_insn_reservation "znver5_sse_add1_load" 9
 (and (eq_attr "cpu" "znver5")
  (and (eq_attr "type" "sseadd1")
-  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF")
+  (and (eq_attr "mode" 
"V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,DF,SF")
(eq_attr "memory" "load"
 "znver4-vector,znver5-load,znver4-fvector*2")
 
@@ -1117,21 +1117,21 @@
 (define_insn_reservation "znver4_sse_mul" 3
 (and (eq_attr "cpu" "znver4,znver5")
  (and (eq

[PATCH] target/119010 - add znver{4,5}_insn_both to resolve missing reservations

2025-03-27 Thread Richard Biener
I still was seeing

;;0--> b  0: i 101 {[sp-0x3c]=[sp-0x3c]+0x1;clobber flags;}:nothing

so the following adds a standard alu insn reservation mimicing that
from the znver.md description allowing both load and store.

Bootstrap and regtest running on x86_64-unknown-linux-gnu, OK?

PR target/119010
* config/i386/zn4zn5.md (znver4_insn_both, znver5_insn_both):
New reservation for ALU ops with load and store.
---
 gcc/config/i386/zn4zn5.md | 12 
 1 file changed, 12 insertions(+)

diff --git a/gcc/config/i386/zn4zn5.md b/gcc/config/i386/zn4zn5.md
index 5a3960e9d01..75e31020215 100644
--- a/gcc/config/i386/zn4zn5.md
+++ b/gcc/config/i386/zn4zn5.md
@@ -421,6 +421,18 @@
   (eq_attr "memory" "store")))
 "znver4-direct,znver4-ieu,znver5-store")
 
+(define_insn_reservation "znver4_insn_both" 5
+(and (eq_attr "cpu" "znver4")
+ (and (eq_attr "type" 
"alu,alu1,negnot,rotate1,ishift1,test,incdec,icmp")
+  (eq_attr "memory" "both")))
+"znver4-direct,znver4-load,znver4-ieu,znver4-store")
+
+(define_insn_reservation "znver5_insn_both" 5
+(and (eq_attr "cpu" "znver5")
+ (and (eq_attr "type" 
"alu,alu1,negnot,rotate1,ishift1,test,incdec,icmp")
+  (eq_attr "memory" "both")))
+"znver4-direct,znver5-load,znver4-ieu,znver5-store")
+
 (define_insn_reservation "znver4_insn2_store" 1
 (and (eq_attr "cpu" "znver4")
  (and (eq_attr "type" "icmov,setcc")
-- 
2.43.0


Re: [PATCH, V3] PR target/118541 - Do not generate unordered fp cmoves for IEEE compares on PowerPC

2025-03-27 Thread Florian Weimer
* Michael Meissner:

> On Mon, Mar 24, 2025 at 09:15:26PM +0100, Florian Weimer wrote:
>> * Michael Meissner:
>> 
>> > +enum reverse_cond_t {
>> > +  REVERSE_COND_ORDERED_OK,
>> > +  REVERSE_COND_NO_ORDERED
>> > +};
>> 
>> This should probably be something 
>> like
>> 
>> enum reverse_cond_t {
>>   ordered_ok,
>>   no_ordered,
>> };
>> 
>> to inhibit implicit conversion to integer types and bool.
>
> Thanks.  At heart I am still a C programmer, so I missed this.  I wrote 
> version
> 4 of the patch that hopefully codes this correctly.
>
> https://gcc.gnu.org/pipermail/gcc-patches/2025-March/679428.html

Unfortunately I totally botched my advice and dropped a critical
keyword.

To get scoped enum, you have to write:

enum class reverse_cond_t {
  ordered_ok,
  no_ordered,
};

Sorry!


[PATCH] target/119010 - fixup zn4zn5 reservation for move from const_vector

2025-03-27 Thread Richard Biener
movv8si_internal uses sselog1 and V4SFmode for an instruction like

(insn 363 2437 371 97 (set (reg:V8SI 46 xmm10 [1125])
(const_vector:V8SI [
(const_int 0 [0]) repeated x8
])) "ComputeNonbondedUtil.C":185:21 2402 {movv8si_internal}

this wasn't catched by the existing znver4_sse_log1 reservation,
I think the znver automaton catches this with the generic

(define_insn_reservation "znver1_sse_log1" 1
 (and (eq_attr "cpu" "znver1,znver2,znver3")
  (and (eq_attr "type" "sselog1")
   (eq_attr "memory" "none")))
 "znver1-direct,znver1-fp1|znver1-fp2")

which does not look at the mode at all.  The zn4zn5 automaton lacks
this and instead has separated store and load-store reservations
in odd ways.  The following renames the store one and introduces
a none variant.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.  OK?

PR target/119010
* config/i386/zn4zn5.md (znver4_sse_log1): Rename to
znver4_sse_log1_store.
(znver5_sse_log1): Rename to znver5_sse_log1_store.
(znver4_sse_log1): New memory-less variant.
---
 gcc/config/i386/zn4zn5.md | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/gcc/config/i386/zn4zn5.md b/gcc/config/i386/zn4zn5.md
index 75e31020215..fb856e9dc98 100644
--- a/gcc/config/i386/zn4zn5.md
+++ b/gcc/config/i386/zn4zn5.md
@@ -893,13 +893,20 @@
 "znver4-direct,znver5-load,znver4-fpu")
 
 (define_insn_reservation "znver4_sse_log1" 1
+(and (eq_attr "cpu" "znver4,znver5")
+ (and (eq_attr "type" "sselog1")
+  (and (eq_attr "mode" 
"V4SF,V8SF,V2DF,V4DF,QI,HI,SI,DI,TI,OI")
+   (eq_attr "memory" "none"
+"znver4-direct,znver4-fpu1|znver4-fpu2")
+
+(define_insn_reservation "znver4_sse_log1_store" 1
 (and (eq_attr "cpu" "znver4")
  (and (eq_attr "type" "sselog1")
   (and (eq_attr "mode" 
"V4SF,V8SF,V2DF,V4DF,QI,HI,SI,DI,TI,OI")
(eq_attr "memory" "store"
 
"znver4-direct,znver4-fpu1|znver4-fpu2,znver4-fp-store")
 
-(define_insn_reservation "znver5_sse_log1" 1
+(define_insn_reservation "znver5_sse_log1_store" 1
 (and (eq_attr "cpu" "znver5")
  (and (eq_attr "type" "sselog1")
   (and (eq_attr "mode" 
"V4SF,V8SF,V2DF,V4DF,QI,HI,SI,DI,TI,OI")
-- 
2.43.0


Re:[pushed] [PATCH] LoongArch: Support Q suffix for __float128.

2025-03-27 Thread Lulu Cheng

Pushed to r15-8962.

在 2025/3/22 下午4:35, Lulu Cheng 写道:

In r14-3635 supports `__float128`, but does not support the 'q/Q' suffix.

PR target/119408

gcc/ChangeLog:

* config/loongarch/loongarch.cc
(loongarch_c_mode_for_suffix): New.
(TARGET_C_MODE_FOR_SUFFIX): Define.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/pr119408.c: New test.

---
  gcc/config/loongarch/loongarch.cc | 13 +
  gcc/testsuite/gcc.target/loongarch/pr119408.c | 12 
  2 files changed, 25 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/loongarch/pr119408.c

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 01f048664b5..7533e53839f 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -11206,6 +11206,16 @@ loongarch_asm_code_end (void)
  #undef DUMP_FEATURE
  }
  
+/* Target hook for c_mode_for_suffix.  */

+static machine_mode
+loongarch_c_mode_for_suffix (char suffix)
+{
+  if (suffix == 'q')
+return TFmode;
+
+  return VOIDmode;
+}
+
  /* Initialize the GCC target structure.  */
  #undef TARGET_ASM_ALIGNED_HI_OP
  #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -11477,6 +11487,9 @@ loongarch_asm_code_end (void)
  #undef TARGET_OPTION_VALID_ATTRIBUTE_P
  #define TARGET_OPTION_VALID_ATTRIBUTE_P loongarch_option_valid_attribute_p
  
+#undef TARGET_C_MODE_FOR_SUFFIX

+#define TARGET_C_MODE_FOR_SUFFIX loongarch_c_mode_for_suffix
+
  struct gcc_target targetm = TARGET_INITIALIZER;
  
  #include "gt-loongarch.h"

diff --git a/gcc/testsuite/gcc.target/loongarch/pr119408.c 
b/gcc/testsuite/gcc.target/loongarch/pr119408.c
new file mode 100644
index 000..f46399aa0b5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr119408.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-pedantic" } */
+
+__float128 a;
+__float128 b;
+void
+test (void)
+{
+  a = 1.Q;
+  b = 1.434345q;   
+}
+




Re: [PATCH 1/2] c++/modules: Fix tsubst of global module friend classes [PR118920]

2025-03-27 Thread Nathaniel Shead
On Wed, Mar 26, 2025 at 11:40:16PM -0400, Jason Merrill wrote:
> On 3/26/25 9:23 AM, Nathaniel Shead wrote:
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> > 
> > -- >8 --
> > 
> > When doing tsubst_friend_class, we need to first check if any imported
> > module has already created a (hidden) declaration for the class so that
> > we don't end up with conflicting declarations.  Currently we do this
> > using DECL_MODULE_IMPORT_P, but this is not set in cases where the class
> > is in the global module and matches an existing GM declaration we've
> > seen (via an include, for example).
> > 
> > This patch fixes this by checking DECL_MODULE_ENTITY_P instead, which is
> > set on all entities that have been seen from a module import.  We also
> > use the 'for_mangle' version of get_originating_module so that we don't
> > treat imported GM entities as attached to the module we imported them
> > from.
> 
> I had actually made the same change on my branch to get the libstdc++
> testsuite running with modules, I just haven't gotten around to merging it
> because I hadn't come up with a reduced testcase.  Here's a patch that
> merges mine with yours, does it work for you?

Yes, it works for me; thanks.


[PATCH] c++/modules: Fix modules and LTO with header units [PR118961]

2025-03-27 Thread Nathaniel Shead
Bootstrapped and regtested (so far just dg.exp and modules.exp) on
x86_64-pc-linux-gnu, OK for trunk if full regtest succeeds?

Rather than updating copy_fndecl_with_name, we could also just fix
modules specifically by overwriting DECL_ABSTRACT_P before calling
build_cdtor_clones in trees_in::decl_value, or by forcing it to 0 for
DECL_MAYBE_IN_CHARGE_CDTOR during tree streaming, if you prefer, since
it'll always be set again by expand_or_defer_fn anyway.

-- >8 --

This patch makes some adjustments required to get a simple modules
testcase working with LTO.  There are two main issues fixed.

Firstly, modules only streams the maybe-in-charge constructor, and any
clones are recreated on stream-in.  These clones are copied from the
existing function decl and then adjusted.  This caused issues because
the clones were getting incorrectly marked as abstract, since after
clones have been created (in the imported file) the maybe-in-charge decl
gets marked as abstract.  So this patch just ensures that clones are
always created as non-abstract.

The second issue is that we need to explicitly tell cgraph that explicit
instantiations need to be emitted, otherwise LTO will elide them (as
they don't necessarily appear to be used directly) and cause link
errors.  Additionally, expand_or_defer_fn doesn't setup comdat groups
for explicit instantiations, so we need to do that here as well.

PR c++/118961

gcc/cp/ChangeLog:

* class.cc (copy_fndecl_with_name): Mark clones as non-abstract.
* module.cc (trees_in::read_var_def): Explicit instantiation
definitions of variables must be emitted, and are COMDAT.
(module_state::read_cluster): Likewise for functions.

gcc/testsuite/ChangeLog:

* g++.dg/modules/lto-1_a.H: New test.
* g++.dg/modules/lto-1_b.C: New test.
* g++.dg/modules/lto-2_a.H: New test.
* g++.dg/modules/lto-2_b.C: New test.
* g++.dg/modules/lto-3_a.H: New test.
* g++.dg/modules/lto-3_b.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/class.cc|  1 +
 gcc/cp/module.cc   | 17 +
 gcc/testsuite/g++.dg/modules/lto-1_a.H |  9 +
 gcc/testsuite/g++.dg/modules/lto-1_b.C |  9 +
 gcc/testsuite/g++.dg/modules/lto-2_a.H | 11 +++
 gcc/testsuite/g++.dg/modules/lto-2_b.C |  9 +
 gcc/testsuite/g++.dg/modules/lto-3_a.H |  6 ++
 gcc/testsuite/g++.dg/modules/lto-3_b.C | 10 ++
 8 files changed, 72 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/modules/lto-1_a.H
 create mode 100644 gcc/testsuite/g++.dg/modules/lto-1_b.C
 create mode 100644 gcc/testsuite/g++.dg/modules/lto-2_a.H
 create mode 100644 gcc/testsuite/g++.dg/modules/lto-2_b.C
 create mode 100644 gcc/testsuite/g++.dg/modules/lto-3_a.H
 create mode 100644 gcc/testsuite/g++.dg/modules/lto-3_b.C

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index d5ae69b0fdf..2b694b98e56 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -5169,6 +5169,7 @@ copy_fndecl_with_name (tree fn, tree name, tree_code code,
   set_constraints (clone, copy_node (ci));
 
   SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
+  DECL_ABSTRACT_P (clone) = false;
   /* There's no pending inline data for this function.  */
   DECL_PENDING_INLINE_INFO (clone) = NULL;
   DECL_PENDING_INLINE_P (clone) = 0;
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 2cded878c64..f9f48bb2421 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12684,6 +12684,13 @@ trees_in::read_var_def (tree decl, tree maybe_template)
  if (maybe_dup && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P 
(maybe_dup))
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
  tentative_decl_linkage (decl);
+ if (DECL_EXPLICIT_INSTANTIATION (decl)
+ && !DECL_EXTERNAL (decl))
+   {
+ mark_needed (decl);
+ if (TREE_PUBLIC (decl))
+   maybe_make_one_only (decl);
+   }
  if (DECL_IMPLICIT_INSTANTIATION (decl)
  || (DECL_EXPLICIT_INSTANTIATION (decl)
  && !DECL_EXTERNAL (decl))
@@ -16604,6 +16611,16 @@ module_state::read_cluster (unsigned snum)
   cfun->language->returns_abnormally = pdata.returns_abnormally;
   cfun->language->infinite_loop = pdata.infinite_loop;
 
+  /* Make sure we emit explicit instantiations.  */
+  if (!abstract
+ && DECL_EXPLICIT_INSTANTIATION (decl)
+ && !DECL_EXTERNAL (decl))
+   {
+ mark_needed (decl);
+ if (TREE_PUBLIC (decl))
+   maybe_make_one_only (decl);
+   }
+
   if (abstract)
;
   else if (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
diff --git a/gcc/testsuite/g++.dg/modules/lto-1_a.H 
b/gcc/testsuite/g++.dg/modules/lto-1_a.H
new file mode 100644
index 000..f28e1fdce03
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lto-1_a.H
@@ -0,0 +1,9 @@
+// PR c++/118961
+// { dg-additional-options "-fmodule-h

COBOL: why not getting UAT/NIST "temporarily" to trunk (was: [PATCH] cobol, v2: Get rid of __int128 uses in the COBOL FE [PR119242])

2025-03-27 Thread Simon Sobisch

> > Implicit criticism about tests accepted.  I have 679 UAT tests, and
> > now I've got the bit in my teeth, and I am creating a process that
> > will convert as many as I can to DejaGnu.  However: the autom4te and
> > DejaGnu principles, practices, and philosophies are almost, but not
> > quite, completely unlike each other.
>
> Didn't mean to criticize in any way, just mention that because we have
> just 23 tests so far, the UAT/NIST testing you are doing is a
> precondition for any non-trivial FE changes and that testing wasn't
> done on my side.

While I'm feeling like the old grumpy man I possibly am sometimes by 
asking the same question over and over again... let me make this 
explicit one time to this list (as I've not seen a response on-list to 
that, sorry if I missed it):




Is there any reason at all why the UAT should not be added to trunk, 
like immediately, even if it is only temporary?


I totally see the point that sticking with what the project *mostly* 
uses (not all frontends do use DejaGnu!) is reasonable. I also see that 
the way it is setup (running the same tests multiple times with 
different options) is better than what the UAT currently does (I can 
offer help to do something similar with autotest generated testsuite as 
we did do that in GnuCOBOL in the past), but I mostly see:


* there are very reasonable testcases

* there are a lot testcases

* again and again contributors don't know if their changes are fine,
  because the DejaGnu part doesn't cover them; and patches sent in
  need to be tested by COBOLworx

* UAT doesn't need any additional software - it is just autoconf, make,
  shell and is portable in general (cross-compiling without executing
  would need adjustments "AT_SKIP" or assigning a shell script that
  exits with 77 instead of running the program)

* the whole testsuite is either already copyrighted by the FSF (the
  parts that were taken from GnuCOBOL) or COBOLworx (changes and new
  tests) - and the tests converted to DejaGnu are also contributed by
  COBOLworx so there should be no problem in contributing UAT directly

* converting tests to DejaGnu takes time from Bob, and there's only a
  single Bob available - while bugzilla gets new entries that would also
  need his focus

Overall my conclusion is: Time seems to be spent MUCH more useful for 
everyone if UAT would just be added as-is for now. I should be able to 
provide some patches to run it multiple times with different options 
(like DejaGnu does), if wanted, as well.


GCC-15 could ship with the generated testsuites, so the user does not 
need any additional tools as well, and if really wanted all of UAT could 
be converted to DejaGnu for GCC-16.



Plain question again:
Is there any reason at all why the UAT should not be added to trunk, 
like immediately and *potentially* the move to DejaGnu be postponed?



A _separate_ issue is the question if NIST could be checked in as well, 
configured to not run automatically (so independent from users or build 
recipes) but this way being possible to be executed on the contributor 
side easily?
If not: what about making the "nist" sub-folder a tarball that can just 
be extracted to gcc/cobol and then be used on the contributor side 
(there's no autotools stuff in there, so that would be possible)?




Kind regards and thanks for your work on COBOL,
Simon


Re: [PATCH] libstdc++: Fix std::ranges::iter_move for function references [PR119469]

2025-03-27 Thread Jonathan Wakely
On Thu, 27 Mar 2025 at 08:38, Tomasz Kaminski  wrote:
>
>
>
> On Wed, Mar 26, 2025 at 12:29 PM Jonathan Wakely  wrote:
>>
>> The result of std::move (or a cast to an rvalue reference) on a function
>> reference is always an lvalue. Because std::ranges::iter_move was using
>> the type std::remove_reference_t&& as the result of std::move, it was
>> giving the wrong type for function references. Use a decltype-specifier
>> with declval>() instead of just using the
>> remove_reference_t&& type directly. This gives the right result,
>> while still avoiding the cost of doing overload resolution for
>> std::move.
>>
>> libstdc++-v3/ChangeLog:
>>
>> PR libstdc++/119469
>> * include/bits/iterator_concepts.h (_IterMove::__result): Use
>> decltype-specifier instead of an explicit type.
>> * testsuite/24_iterators/customization_points/iter_move.cc:
>> Check results for function references.
>> ---
>>
>> This one is weird, but I think the fix is right.
>
> Interesting, for T being a function type, T&& is forming rvalue reference to 
> function type,
> but we only yield values of function type, so decltype would give T&.

Yes, it's a very strange corner of the language.

[basic.lval] p4 is a note which includes "rvalue references to
functions are treated as lvalues whether named or not".
[expr.static.cast] and [expr.reinterpret.cast] and [expr.type.conv]
all have wording like "the result is an lvalue if T is an lvalue
reference type or an rvalue reference to function type and an xvalue
otherwise."
And the final piece of the puzzle is that [dcl.init.ref] (5.3.1)
allows rvalue references to bind to lvalues of function type, which is
what allows std::move to compile, even though the return type is an
rvalue reference and the return statement produces an lvalue.

So although the return type of std::move(*funref) is
remove_reference_t&&, the actual result of
std::move(*funref) is not that type!
Using decltype(std::move(*funref)) gets the core language "it's always
an lvalue even when it's not" behaviour that we want.

An alternative would be something like:
conditional_t>, T, remove_reference_t&&>
but it seems simpler and cheaper to just use
decltype(declval>()), as this is equivalent to
the decltype(std::move(*funref)) type.

> LGTM.
> I am not sold on why I would care about the result of calling iter_move on 
> function reference
> (not iterator returning function reference), but standard seem to require 
> that we support it,

Yes, it seems completely useless, but because I was fixing
ranges::iter_move recently I decided to deal with this right away.

> because * works on them due decay to pointer.

Yes, that's the other weird part of this. *funref decays the function
reference to a function pointer, which is then dereferenced to get the
original function reference back. So std::move(funref) and
std::move(*funref) are identical.



Re: [PATCH] c++: fix missing lifetime extension [PR119383]

2025-03-27 Thread Jason Merrill

On 3/25/25 3:37 PM, Marek Polacek wrote:

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14?

-- >8 --
Since r15-8011 cp_build_indirect_ref_1 won't do the *&TARGET_EXPR ->
TARGET_EXPR folding not to change its value category.  That fix is
correct but it made us stop extending the lifetime in this testcase,
causing a wrong-code issue -- extend_ref_init_temps_1 did not see
through the extra *& because it doesn't use a tree walk.  It is not
hard to fix that, but there may be other places that need this
adjustment.  :/


Hmm, this suggests to me that we should revert the 117512 patch and 
instead fix it in build_over_call, perhaps by forcing 'val' to be an 
lvalue after it's built rather than relying on 'to' being an lvalue already.



PR c++/119383

gcc/cp/ChangeLog:

* call.cc (extend_ref_init_temps_1): Handle *&TARGET_EXPR the same as
TARGET_EXPR.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/temp-extend3.C: New test.
---
  gcc/cp/call.cc|  6 +
  gcc/testsuite/g++.dg/cpp0x/temp-extend3.C | 32 +++
  2 files changed, 38 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/temp-extend3.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index c1c8987ec8b..ed2bdc85d87 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -14835,6 +14835,12 @@ extend_ref_init_temps_1 (tree decl, tree init, vec **cleanups,
for (p = &TREE_OPERAND (sub, 0);
 TREE_CODE (*p) == COMPONENT_REF || TREE_CODE (*p) == ARRAY_REF; )
  p = &TREE_OPERAND (*p, 0);
+  /* cp_build_indirect_ref_1 leaves *&TARGET_EXPR intact, handle it here.  */
+  if (INDIRECT_REF_P (*p)
+  && TREE_CODE (TREE_OPERAND (*p, 0)) == ADDR_EXPR
+  && same_type_p (TREE_TYPE (*p),
+ TREE_TYPE (TREE_TYPE (TREE_OPERAND (*p, 0)
+p = &TREE_OPERAND (TREE_OPERAND (*p, 0), 0);
if (TREE_CODE (*p) == TARGET_EXPR)
  {
tree subinit = NULL_TREE;
diff --git a/gcc/testsuite/g++.dg/cpp0x/temp-extend3.C 
b/gcc/testsuite/g++.dg/cpp0x/temp-extend3.C
new file mode 100644
index 000..3eab88d0076
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/temp-extend3.C
@@ -0,0 +1,32 @@
+// PR c++/119383
+// { dg-do run { target c++11 } }
+
+int g;
+
+struct base {
+  virtual base *clone() const = 0;
+  ~base() { }
+};
+
+struct impl : virtual base {
+  base *clone() const { return new impl; }  // #1
+  impl() { ++g; }
+  ~impl() { --g; }
+};
+
+const base *
+make_a_clone ()
+{
+  const base &base = impl{}; // #2
+  return base.clone();
+}
+
+int
+main ()
+{
+  make_a_clone ();
+  // impl::impl() is called twice (#1 and #2), impl::~impl() once,
+  // at the end of make_a_clone.
+  if (g != 1)
+__builtin_abort ();
+}

base-commit: 927cfea902c330092848bd7a228b714b07d08f6b




[committed v2] libstdc++: Replace use of std::min in ranges::uninitialized_xxx algos [PR101587]

2025-03-27 Thread Jonathan Wakely
Because ranges can have any signed integer-like type as difference_type,
it's not valid to use std::min(diff1, diff2). Instead of calling
std::min with an explicit template argument, this adds a new __mindist
helper that determines the common type and uses that with std::min.

libstdc++-v3/ChangeLog:

PR libstdc++/101587
* include/bits/ranges_uninitialized.h (__detail::__mindist):
New function object.
(ranges::uninitialized_copy, ranges::uninitialized_copy_n)
(ranges::uninitialized_move, ranges::uninitialized_move_n): Use
__mindist instead of std::min.
* 
testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc:
Check ranges with difference difference types.
* 
testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc:
Likewise.
---

Here's what I've pushed, after changing the name to mindist and adding
the missing 'constexpr'.

Tested x86_64-linux.

 .../include/bits/ranges_uninitialized.h   | 32 +++
 .../uninitialized_copy/constrained.cc | 13 
 .../uninitialized_move/constrained.cc | 13 
 3 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h 
b/libstdc++-v3/include/bits/ranges_uninitialized.h
index 990929efaa9..b5580073a6a 100644
--- a/libstdc++-v3/include/bits/ranges_uninitialized.h
+++ b/libstdc++-v3/include/bits/ranges_uninitialized.h
@@ -263,6 +263,26 @@ namespace ranges
   inline constexpr __uninitialized_value_construct_n_fn
 uninitialized_value_construct_n;
 
+  namespace __detail
+  {
+// This is only intended for finding smaller iterator differences below,
+// not as a general purpose replacement for std::min.
+struct __mindist_fn
+{
+  template
+   constexpr common_type_t<_Dp1, _Dp2>
+   operator()(_Dp1 __d1, _Dp2 __d2) const noexcept
+   {
+ // Every C++20 iterator I satisfies weakly_incrementable which
+ // requires signed-integer-like>.
+ static_assert(std::__detail::__is_signed_integer_like<_Dp1>);
+ static_assert(std::__detail::__is_signed_integer_like<_Dp2>);
+ return std::min>(__d1, __d2);
+   }
+};
+inline constexpr __mindist_fn __mindist{};
+  }
+
   template
 using uninitialized_copy_result = in_out_result<_Iter, _Out>;
 
@@ -287,8 +307,8 @@ namespace ranges
  {
auto __d1 = __ilast - __ifirst;
auto __d2 = __olast - __ofirst;
-   return ranges::copy_n(std::move(__ifirst), std::min(__d1, __d2),
- __ofirst);
+   return ranges::copy_n(std::move(__ifirst),
+ __detail::__mindist(__d1, __d2), __ofirst);
  }
else
  {
@@ -337,8 +357,8 @@ namespace ranges
 iter_reference_t<_Iter>>)
  {
auto __d = __olast - __ofirst;
-   return ranges::copy_n(std::move(__ifirst), std::min(__n, __d),
- __ofirst);
+   return ranges::copy_n(std::move(__ifirst),
+ __detail::__mindist(__n, __d), __ofirst);
  }
else
  {
@@ -381,7 +401,7 @@ namespace ranges
auto __d2 = __olast - __ofirst;
auto [__in, __out]
  = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
-  std::min(__d1, __d2), __ofirst);
+  __detail::__mindist(__d1, __d2), __ofirst);
return {std::move(__in).base(), __out};
  }
else
@@ -435,7 +455,7 @@ namespace ranges
auto __d = __olast - __ofirst;
auto [__in, __out]
  = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
-  std::min(__n, __d), __ofirst);
+  __detail::__mindist(__n, __d), __ofirst);
return {std::move(__in).base(), __out};
  }
else
diff --git 
a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
 
b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
index e0589e33f3d..af3b73364ec 100644
--- 
a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
+++ 
b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
@@ -175,6 +175,17 @@ test03()
 }
 }
 
+void
+test_pr101587()
+{
+  short in[1];
+  __gnu_test::test_contiguous_range r(in); // difference_type is integer-like
+  long out[1];
+  std::span o(out); // difference_type is ptrdiff_t
+  ranges::uninitialized_copy(r, o);
+  ranges::uninitialized_copy_n(ranges::begin(r), 0, o.begin(), o.end());
+}
+
 int
 main()
 {
@@ -188,4 +199,6 @@ main()
 
   test02();
   test02();
+
+  test_pr101587();
 }
diff --git 
a/libstdc++-v3/testsuite/20_util/s

[COMMITTED 085/144] rust: negative polarity removes restrictions on validation of impl blocks

2025-03-27 Thread arthur . cohen
From: Philip Herron 

Negative polarity means we can just ignore if any trait items are not
implemented.

Fxies #3030

gcc/rust/ChangeLog:

* hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): the polarity was 
reversed
* typecheck/rust-hir-type-check-item.cc: check the polarity

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 cant handle this
* rust/compile/issue-3030.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-ast-lower-item.cc|  4 ++--
 gcc/rust/typecheck/rust-hir-type-check-item.cc |  3 ++-
 gcc/testsuite/rust/compile/issue-3030.rs   | 16 
 gcc/testsuite/rust/compile/nr2/exclude |  1 +
 4 files changed, 21 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3030.rs

diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index 0ef4f357c8e..171737ab029 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -690,8 +690,8 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block)
 }
 
   BoundPolarity polarity = impl_block.is_exclam ()
-? BoundPolarity::RegularBound
-: BoundPolarity::NegativeBound;
+? BoundPolarity::NegativeBound
+: BoundPolarity::RegularBound;
   HIR::ImplBlock *hir_impl_block = new HIR::ImplBlock (
 mapping, std::move (impl_items), std::move (generic_params),
 std::unique_ptr (impl_type),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 68e206924bb..d707e3458f1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -734,7 +734,8 @@ TypeCheckItem::validate_trait_impl_block (
   bool impl_block_missing_trait_items
 = !specified_bound.is_error ()
   && trait_reference->size () != trait_item_refs.size ();
-  if (impl_block_missing_trait_items)
+  if (impl_block_missing_trait_items
+  && impl_block.get_polarity () == BoundPolarity::RegularBound)
 {
   // filter the missing impl_items
   std::vector>
diff --git a/gcc/testsuite/rust/compile/issue-3030.rs 
b/gcc/testsuite/rust/compile/issue-3030.rs
new file mode 100644
index 000..0a1866d9a6b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3030.rs
@@ -0,0 +1,16 @@
+#![feature(negative_impls)]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+pub trait Deref {}
+
+pub trait DerefMut: Deref {
+type Target;
+
+/// Mutably dereferences the value.
+#[stable(feature = "rust1", since = "1.0.0")]
+fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+impl !DerefMut for &T {}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index ca07ed6ecd2..3251921acd4 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -291,3 +291,4 @@ unknown-associated-item.rs
 box_syntax_feature_gate.rs
 dropck_eyepatch_feature_gate.rs
 inline_asm_parse_output_operand.rs
+issue-3030.rs
\ No newline at end of file
-- 
2.45.2



[PATCH v3 19/19] Remove FMV beta warning.

2025-03-27 Thread Alfie Richards

This patch removes the warning for target_version and target_clones
in aarch64 as it is now spec compliant.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_process_target_version_attr):
Remove warning.
* config/aarch64/aarch64.opt: Mark -Wno-experimental-fmv-target
deprecated.
* doc/invoke.texi: Ditto.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/mv-1.C: Remove option.
* g++.target/aarch64/mv-and-mvc-error1.C: Ditto.
* g++.target/aarch64/mv-and-mvc-error2.C: Ditto.
* g++.target/aarch64/mv-and-mvc-error3.C: Ditto.
* g++.target/aarch64/mv-and-mvc1.C: Ditto.
* g++.target/aarch64/mv-and-mvc2.C: Ditto.
* g++.target/aarch64/mv-and-mvc3.C: Ditto.
* g++.target/aarch64/mv-and-mvc4.C: Ditto.
* g++.target/aarch64/mv-error1.C: Ditto.
* g++.target/aarch64/mv-error2.C: Ditto.
* g++.target/aarch64/mv-error3.C: Ditto.
* g++.target/aarch64/mv-error4.C: Ditto.
* g++.target/aarch64/mv-error5.C: Ditto.
* g++.target/aarch64/mv-error6.C: Ditto.
* g++.target/aarch64/mv-error7.C: Ditto.
* g++.target/aarch64/mv-error8.C: Ditto.
* g++.target/aarch64/mv-pragma.C: Ditto.
* g++.target/aarch64/mv-symbols1.C: Ditto.
* g++.target/aarch64/mv-symbols10.C: Ditto.
* g++.target/aarch64/mv-symbols11.C: Ditto.
* g++.target/aarch64/mv-symbols12.C: Ditto.
* g++.target/aarch64/mv-symbols13.C: Ditto.
* g++.target/aarch64/mv-symbols2.C: Ditto.
* g++.target/aarch64/mv-symbols3.C: Ditto.
* g++.target/aarch64/mv-symbols4.C: Ditto.
* g++.target/aarch64/mv-symbols5.C: Ditto.
* g++.target/aarch64/mv-symbols6.C: Ditto.
* g++.target/aarch64/mv-symbols7.C: Ditto.
* g++.target/aarch64/mv-symbols8.C: Ditto.
* g++.target/aarch64/mv-symbols9.C: Ditto.
* g++.target/aarch64/mvc-error1.C: Ditto.
* g++.target/aarch64/mvc-error2.C: Ditto.
* g++.target/aarch64/mvc-symbols1.C: Ditto.
* g++.target/aarch64/mvc-symbols2.C: Ditto.
* g++.target/aarch64/mvc-symbols3.C: Ditto.
* g++.target/aarch64/mvc-symbols4.C: Ditto.
* g++.target/aarch64/mv-warning1.C: Removed.
* g++.target/aarch64/mvc-warning1.C: Removed.
---
 gcc/config/aarch64/aarch64.cc| 9 -
 gcc/config/aarch64/aarch64.opt   | 2 +-
 gcc/doc/invoke.texi  | 5 +
 gcc/testsuite/g++.target/aarch64/mv-1.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error3.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc1.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc2.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc3.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-and-mvc4.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error1.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error2.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error3.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error4.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error5.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error6.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error7.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-error8.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-pragma.C | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols1.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols10.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols11.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols12.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols13.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols2.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols3.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols4.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols5.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols6.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols7.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols8.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-symbols9.C   | 1 -
 gcc/testsuite/g++.target/aarch64/mv-warning1.C   | 9 -
 gcc/testsuite/g++.target/aarch64/mvc-error1.C| 1 -
 gcc/testsuite/g++.target/aarch64/mvc-error2.C| 1 -
 gcc/testsuite/g++.target/aarch64/mvc-symbols1.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mvc-symbols2.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mvc-symbols3.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mvc-symbols4.C  | 1 -
 gcc/testsuite/g++.target/aarch64/mvc-warning1.C  | 1 -
 41 files changed, 2 insertions(+), 60 deletions(-)
 delete mode 100644 gcc/testsuite/g++.target/aarch64/mv-warning1.C

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aa

[PATCH v3 15/19] Change target_version semantics to follow ACLE specification.

2025-03-27 Thread Alfie Richards

This changes behavior of target_clones and target_version attributes
to be inline with what is specified in the Arm C Language Extension.

Notably this changes the scope and signature of multiversioned functions
to that of the default version, and changes the resolver to be
created at the implementation of the default version.

This is achieved by changing the C++ front end to no longer resolve any
non-default version decls in lookup, and by moving dipatching
for default_target sets to reuse the dispatching logic for target_clones
in multiple_target.cc.

The dispatching in create_dispatcher_calls is changed for the case of
a lone annotated default function to change the dispatched symbol to
be an alias for the mangled default function.

gcc/ChangeLog:

* cgraphunit.cc (analyze_functions): Add logic for target version
dependencies.
* ipa.cc (symbol_table::remove_unreachable_nodes): Ditto.
* multiple_target.cc (create_dispatcher_calls): Change to support
target version semantics.
(ipa_target_clone): Change to dispatch all function sets in
target_version semantics.

gcc/cp/ChangeLog:

* call.cc (add_candidates): Change to not resolve non-default versions 
in
target_version semantics.
* class.cc (resolve_address_of_overloaded_function): Ditto.
* cp-gimplify.cc (cp_genericize_r): Change logic to not apply for
target_version semantics.
* decl.cc (start_decl): Change to mark and therefore mangle all
target_version decls.
(start_preparsed_function): Ditto.
* typeck.cc (cp_build_function_call_vec): Add error for calling 
unresolvable
non-default node in target_version semantics.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/mv-1.C: Change for target_version semantics.
* g++.target/aarch64/mv-symbols2.C: Ditto.
* g++.target/aarch64/mv-symbols3.C: Ditto.
* g++.target/aarch64/mv-symbols4.C: Ditto.
* g++.target/aarch64/mv-symbols5.C: Ditto.
* g++.target/aarch64/mvc-symbols3.C: Ditto.
* g++.target/riscv/mv-symbols2.C: Ditto.
* g++.target/riscv/mv-symbols3.C: Ditto.
* g++.target/riscv/mv-symbols4.C: Ditto.
* g++.target/riscv/mv-symbols5.C: Ditto.
* g++.target/riscv/mvc-symbols3.C: Ditto.
* g++.target/aarch64/mv-symbols10.C: New test.
* g++.target/aarch64/mv-symbols11.C: New test.
* g++.target/aarch64/mv-symbols12.C: New test.
* g++.target/aarch64/mv-symbols13.C: New test.
* g++.target/aarch64/mv-symbols6.C: New test.
* g++.target/aarch64/mv-symbols7.C: New test.
* g++.target/aarch64/mv-symbols8.C: New test.
* g++.target/aarch64/mv-symbols9.C: New test.
---
 gcc/cgraphunit.cc |  9 +++
 gcc/cp/call.cc| 10 +++
 gcc/cp/class.cc   | 13 +++-
 gcc/cp/cp-gimplify.cc | 11 +--
 gcc/cp/decl.cc| 14 
 gcc/cp/typeck.cc  | 10 +++
 gcc/ipa.cc| 11 +++
 gcc/multiple_target.cc| 71 ---
 gcc/testsuite/g++.target/aarch64/mv-1.C   |  4 ++
 .../g++.target/aarch64/mv-symbols10.C | 27 +++
 .../g++.target/aarch64/mv-symbols11.C | 30 
 .../g++.target/aarch64/mv-symbols12.C | 28 
 .../g++.target/aarch64/mv-symbols13.C | 28 
 .../g++.target/aarch64/mv-symbols2.C  | 12 ++--
 .../g++.target/aarch64/mv-symbols3.C  |  6 +-
 .../g++.target/aarch64/mv-symbols4.C  |  6 +-
 .../g++.target/aarch64/mv-symbols5.C  |  6 +-
 .../g++.target/aarch64/mv-symbols6.C  | 25 +++
 .../g++.target/aarch64/mv-symbols7.C  | 48 +
 .../g++.target/aarch64/mv-symbols8.C  | 46 
 .../g++.target/aarch64/mv-symbols9.C  | 43 +++
 .../g++.target/aarch64/mvc-symbols3.C | 12 ++--
 gcc/testsuite/g++.target/riscv/mv-symbols2.C  | 12 ++--
 gcc/testsuite/g++.target/riscv/mv-symbols3.C  |  6 +-
 gcc/testsuite/g++.target/riscv/mv-symbols4.C  |  6 +-
 gcc/testsuite/g++.target/riscv/mv-symbols5.C  |  6 +-
 gcc/testsuite/g++.target/riscv/mvc-symbols3.C | 12 ++--
 27 files changed, 455 insertions(+), 57 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols10.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols11.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols12.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols13.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols6.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols7.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols8.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols9.C

diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc

[PATCH v3 18/19] Add error cases and tests for Aarch64 FMV.

2025-03-27 Thread Alfie Richards

This changes the ambiguation error for C++ to cover cases of differently
annotated FMV function sets whose signatures only differ by their return
type.

It also adds tests covering many FMV errors for Aarch64, including
redeclaration, and mixing target_clones and target_versions.

gcc/cp/ChangeLog:
PR c++/119498
* decl.cc (duplicate_decls): Change logic to not always exclude FMV
annotated functions in cases of return type non-ambiguation.

gcc/testsuite/ChangeLog:

* g++.target/aarch64/mv-and-mvc-error1.C: New test.
* g++.target/aarch64/mv-and-mvc-error2.C: New test.
* g++.target/aarch64/mv-and-mvc-error3.C: New test.
* g++.target/aarch64/mv-error1.C: New test.
* g++.target/aarch64/mv-error2.C: New test.
* g++.target/aarch64/mv-error3.C: New test.
* g++.target/aarch64/mv-error4.C: New test.
* g++.target/aarch64/mv-error5.C: New test.
* g++.target/aarch64/mv-error6.C: New test.
* g++.target/aarch64/mv-error7.C: New test.
* g++.target/aarch64/mv-error8.C: New test.
* g++.target/aarch64/mvc-error1.C: New test.
* g++.target/aarch64/mvc-error2.C: New test.
* g++.target/aarch64/mvc-warning1.C: Modified test.
---
 gcc/cp/decl.cc|  7 +--
 .../g++.target/aarch64/mv-and-mvc-error1.C| 10 +
 .../g++.target/aarch64/mv-and-mvc-error2.C| 10 +
 .../g++.target/aarch64/mv-and-mvc-error3.C|  9 
 gcc/testsuite/g++.target/aarch64/mv-error1.C  | 19 +
 gcc/testsuite/g++.target/aarch64/mv-error2.C  | 10 +
 gcc/testsuite/g++.target/aarch64/mv-error3.C  | 13 
 gcc/testsuite/g++.target/aarch64/mv-error4.C  | 10 +
 gcc/testsuite/g++.target/aarch64/mv-error5.C  |  9 
 gcc/testsuite/g++.target/aarch64/mv-error6.C  | 21 +++
 gcc/testsuite/g++.target/aarch64/mv-error7.C  | 12 +++
 gcc/testsuite/g++.target/aarch64/mv-error8.C  | 13 
 gcc/testsuite/g++.target/aarch64/mvc-error1.C | 10 +
 gcc/testsuite/g++.target/aarch64/mvc-error2.C | 10 +
 .../g++.target/aarch64/mvc-warning1.C | 12 +--
 15 files changed, 171 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-and-mvc-error3.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-error1.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-error2.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-error3.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-error4.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-error5.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-error6.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-error7.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mv-error8.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mvc-error1.C
 create mode 100644 gcc/testsuite/g++.target/aarch64/mvc-error2.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 83f24b1ddb2..10e5ce82313 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2022,8 +2022,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
 	}
 	  /* For function versions, params and types match, but they
 	 are not ambiguous.  */
-	  else if ((!DECL_FUNCTION_VERSIONED (newdecl)
-		&& !DECL_FUNCTION_VERSIONED (olddecl))
+	  else if (((!DECL_FUNCTION_VERSIONED (newdecl)
+		 && !DECL_FUNCTION_VERSIONED (olddecl))
+		|| !comptypes (TREE_TYPE (TREE_TYPE (newdecl)),
+   TREE_TYPE (TREE_TYPE (olddecl)),
+   COMPARE_STRICT))
 		   /* Let constrained hidden friends coexist for now, we'll
 		  check satisfaction later.  */
 		   && !member_like_constrained_friend_p (newdecl)
diff --git a/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C
new file mode 100644
index 000..00d3826f757
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error1.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+/* { dg-additional-options "-Wno-experimental-fmv-target" } */
+
+__attribute__ ((target_version ("dotprod"))) int
+foo () { return 3; } /* { dg-message "previous definition" } */
+
+__attribute__ ((target_clones ("dotprod", "sve"))) int
+foo () { return 1; } /* { dg-error "conflicting .dotprod. versions" } */
diff --git a/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C
new file mode 100644
index 000..bf8a4112a21
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/mv-and-mvc-error2.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+/* { dg-additional-options "-Wno-experimental-fmv-target" }

[PATCH v3 09/19] Add assembler_name to cgraph_function_version_info.

2025-03-27 Thread Alfie Richards

This adds the assembler_name member to cgraph_function_version_info
to store the base assembler name for the function to be mangled. This is
used in later patches for refactoring FMV mangling.

gcc/ChangeLog:

* cgraph.cc (cgraph_node::insert_new_function_version): Record
assembler_name.
* cgraph.h (struct cgraph_function_version_info): Add assembler_name.
---
 gcc/cgraph.cc | 1 +
 gcc/cgraph.h  | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index a2ad2516c12..e81c7262d36 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -187,6 +187,7 @@ cgraph_node::insert_new_function_version (void)
   version_info_node = NULL;
   version_info_node = ggc_cleared_alloc ();
   version_info_node->this_node = this;
+  version_info_node->assembler_name = DECL_ASSEMBLER_NAME (this->decl);
 
   if (cgraph_fnver_htab == NULL)
 cgraph_fnver_htab = hash_table::create_ggc (2);
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 6759505bf33..4a4fb7302b1 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -856,6 +856,9 @@ struct GTY((for_user)) cgraph_function_version_info {
  dispatcher. The dispatcher decl is an alias to the resolver
  function decl.  */
   tree dispatcher_resolver;
+
+  /* The assmbly name of the function set before version mangling.  */
+  tree assembler_name;
 };
 
 #define DEFCIFCODE(code, type, string)	CIF_ ## code,


Re: [COMMITTED,wwwdocs] Mention Incremental LTO in GCC15

2025-03-27 Thread Michal Jires
(already Ok-ed off-list, since I forgot to Cc: )

On Thu, 2025-03-27 at 14:40:57 +0100, Gerald Pfeifer wrote:
> On Thu, 27 Mar 2025, Michal Jires wrote:
> > +  Introduced incremental Link-Time Optimizations to significantly 
> > reduce
> > +average recompilation time with small code changes while using LTO.
> 
> How about rephrasing this to "Incremental Link-Time Optimizations 
> significantly reduce average recompilation time with only small changes to 
> generated code..."?
> 
> Go ahead with this or variation if you agree with the general idea; if I 
> misunderstood the intent, please push back and let me know. :-)

Thanks a lot, you probably misunderstood. The generated code should be
identical for identical source code with or without Incremental LTO,
which your phrasing seems to heavily imply is not the case (and mine
could be interpreted that way). I will have to make it clearer.


Maybe:
```
Incremental Link-Time Optimizations significantly reduce average
recompilation time of LTO when doing small code edits
(e.g. editing a single function).
```
explains it better?

Michal

> 
> Gerald

---
 htdocs/gcc-15/changes.html | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/htdocs/gcc-15/changes.html b/htdocs/gcc-15/changes.html
index dbc82be2..5c802a6b 100644
--- a/htdocs/gcc-15/changes.html
+++ b/htdocs/gcc-15/changes.html
@@ -59,6 +59,13 @@ a work-in-progress.
 system and user time. This reduces the overhead of the option 
significantly,
 making it possible to use in standard build systems.
   
+  Incremental Link-Time Optimizations significantly reduce average
+recompilation time of LTO when doing small code edits
+(e.g. editing a single function).
+Enable with https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-flto-incremental";
+>-flto-incremental=.
+  
 
 
 
-- 
2.48.1



Re: [PATCH 5/6] testsuite: fix more dg-* whitespace issues

2025-03-27 Thread Marek Polacek
On Thu, Mar 27, 2025 at 12:38:55AM +, Sam James wrote:
> A handful of cosmetic ones in here but most meant the directive wasn't
> doing anything.

This patch breaks g++.dg/template/explicit-args6.C for me.
 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/cpp0x/udlit-namespace-ambiguous.C: Fix whitespace.
>   * g++.dg/cpp2a/constexpr-init21.C: Ditto.
>   * g++.dg/diagnostic/wrong-tag-1.C: Ditto.
>   * g++.dg/init/self1.C: Ditto.
>   * g++.dg/opt/pr98743.C: Add missing '}' to terminate dg directive.
>   * g++.dg/parse/error8.C: Fix whitespace.
>   * g++.dg/template/explicit-args6.C: Add missing '{' to begin dg 
> directive.
>   * g++.dg/template/unify9.C: Fix whitespace.
>   * g++.dg/tree-ssa/pr105820.C: Ditto.
>   * g++.dg/warn/Wmismatched-tags-8.C: Add missing braces.
>   * gcc.dg/cpp/cmdlne-dM-M.c: Ditto.
>   * gcc.dg/tree-ssa/reassoc-32.c: Ditto.
>   * gcc.dg/tree-ssa/reassoc-33.c: Ditto.
>   * gcc.dg/tree-ssa/reassoc-34.c: Ditto.
>   * gcc.dg/tree-ssa/reassoc-35.c: Ditto.
>   * gcc.dg/tree-ssa/reassoc-36.c: Ditto.
>   * gcc.dg/tree-ssa/reassoc-39.c: Ditto.
>   * gcc.dg/tree-ssa/reassoc-41.c: Ditto.

Marek



Re: [PATCH 5/6] testsuite: fix more dg-* whitespace issues

2025-03-27 Thread Sam James
Marek Polacek  writes:

> On Thu, Mar 27, 2025 at 12:38:55AM +, Sam James wrote:
>> A handful of cosmetic ones in here but most meant the directive wasn't
>> doing anything.
>
> This patch breaks g++.dg/template/explicit-args6.C for me.

See PR119490. I can XFAIL it, but I think it may be a real bug (and
simply exposed by the change).


Re: [PATCH 1/3] testsuite: harmless dg-* whitespace fixes

2025-03-27 Thread Sam James
Harald Anlauf  writes:

> Sam,
>
> who approved the fortran testsuite changes?

We've been doing them as obvious by consensus since last year. I'm sorry
for the error.

>
> Am 27.03.25 um 14:28 schrieb Sam James:
>> These just fix inconsistent/unusual style to avoid noise when grepping
>> and also people picking up bad habits when they see it (as similar
>> mistakes can be harmful).
>
> This one should be reverted.  The reason for the two spaces is actually
> explained in the testcase:

Yes, you're quite right (and done). I had it in a branch where I'd left
a poor comment for myself, even though I'd already handled other Fortran
cases like this specially. Apologies agian.

>
>> diff --git a/gcc/testsuite/gfortran.dg/cray_pointers_2.f90 
>> b/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
>> index 4351874825ed..a7e15bad850a 100644
>> --- a/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
>> +++ b/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
>> @@ -1,6 +1,6 @@
>>   ! Using two spaces between dg-do and run is a hack to keep 
>> gfortran-dg-runtest
>>   ! from cycling through optimization options for this expensive test.
>> -! { dg-do  run }
>> +! { dg-do run }
>>   ! { dg-options "-O3 -fcray-pointer -fbounds-check -fno-inline" }
>>   ! { dg-timeout-factor 4 }
>>   !
>
> There was an attempt by Jerry some time ago to have a directive
> for not cycling through options, but this is not yet available.

Ah, PR28032.

>
> Thanks,
> Harald

thanks,
sam


Re: [PATCH v2] c++: Fix FAIL: g++.dg/tree-ssa/initlist-opt1.C

2025-03-27 Thread Marek Polacek
On Wed, Mar 26, 2025 at 05:57:51PM +, Jonathan Wakely wrote:
> On Wed, 26 Mar 2025 at 17:42, Jason Merrill  wrote:
> >
> > On 3/26/25 6:14 AM, Jonathan Wakely wrote:
> > > My r15-8904-ge200f53a555651 changed the std::vector initializer-list
> > > constructor so that it calls a new _M_range_initialize_n function
> > > instead of _M_range_initialize. Change the scan-tree-dump pattern in
> > > this g++.dg test to match the new gimple output.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >   * g++.dg/tree-ssa/initlist-opt1.C: Match _M_range_initialize_n
> > >   instead of _M_range_initialize.
> > > ---
> > >
> > > Would anybody prefer a different pattern?
> > >
> > > e.g. just {_M_range_initialize_n > > the second template argument and '>' would work, and would be correct
> > > for the gcc-14 backport where the new function only has one template
> > > parameter.
> >
> > That sounds most convenient to me.  I don't think the specific signature
> > is important, as long as it checks that we use range-initialization from
> > const char *.
> 
> Agreed - so I've pushed the attached patch to trunk now, thanks.

> commit 101f302363e8773958887e00750098b760a5b6bd
> Author: Jonathan Wakely 
> AuthorDate: Wed Mar 26 10:10:19 2025
> Commit: Jonathan Wakely 
> CommitDate: Wed Mar 26 17:53:34 2025
> 
> c++: Fix FAIL: g++.dg/tree-ssa/initlist-opt1.C
> 
> My r15-8904-ge200f53a555651 changed the std::vector initializer-list
> constructor so that it calls a new _M_range_initialize_n function
> instead of _M_range_initialize. Change the scan-tree-dump pattern in
> this g++.dg test to match the new gimple output.
> 
> gcc/testsuite/ChangeLog:
> 
> * g++.dg/tree-ssa/initlist-opt1.C: Match _M_range_initialize_n
> instead of _M_range_initialize.
> 
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C 
> b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C
> index 89abdd90a82..976c3f30b16 100644
> --- a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C
> +++ b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt1.C
> @@ -4,7 +4,7 @@
>  // { dg-skip-if "requires hosted libstdc++ for string" { ! hostedlib } }
>  
>  // Test that we do range-initialization from const char *.
> -// { dg-final { scan-tree-dump {_M_range_initialize} 
> "gimple" } }
> +// { dg-final { scan-tree-dump {_M_range_initialize_n "gimple" } }
>  // { dg-final { scan-tree-dump {static const char.*72} "gimple" } }
>  
>  #include 

Looks like g++.dg/tree-ssa/initlist-opt2.C needs the same fix.

Tested x86_64-pc-linux-gnu, applying to trunk.

-- >8 --
This test needs the same fix as g++.dg/tree-ssa/initlist-opt1.C in
r15-8934.

gcc/testsuite/ChangeLog:

* g++.dg/tree-ssa/initlist-opt2.C: Match _M_range_initialize_n
instead of _M_range_initialize.
---
 gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C 
b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C
index 8080e9fbfbd..bc9b6cf3867 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/initlist-opt2.C
@@ -4,7 +4,7 @@
 // { dg-skip-if "requires hosted libstdc++ for string" { ! hostedlib } }
 
 // Test that we do range-initialization from const char *.
-// { dg-final { scan-tree-dump {_M_range_initialize} 
"gimple" } }
+// { dg-final { scan-tree-dump {_M_range_initialize_n

Re: [PATCH] libcpp: Add missing configure check for setlocale.

2025-03-27 Thread Joseph Myers
On Wed, 26 Mar 2025, Roland McGrath wrote:

> The libcpp code uses `#ifdef HAVE_SETLOCALE` but its configure doesn't
> have the corresponding check.
> 
> Ok for trunk and 14 branch?

OK, but watch out for what look like spurious changes in the generated 
configure (maybe resulting from a patched autoconf?); CI will complain if 
the committed configure doesn't match what you get with unmodified 
autoconf 2.69.

-- 
Joseph S. Myers
josmy...@redhat.com



[committed] testsuite: Require effective target sigsetjmp for gcov-31/32

2025-03-27 Thread Dimitar Dimitrov
The tests call sigsetjmp and use sigjmp_buf type.  Thus the tests
cannot be compiled on baremetal newlib targets which do not have
sigsetjmp.

Pushed to trunk as obvious.

gcc/testsuite/ChangeLog:

* gcc.misc-tests/gcov-31.c: Require effective target sigsetjmp.
* gcc.misc-tests/gcov-32.c: Ditto.

Signed-off-by: Dimitar Dimitrov 
---
 gcc/testsuite/gcc.misc-tests/gcov-31.c | 1 +
 gcc/testsuite/gcc.misc-tests/gcov-32.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/gcc/testsuite/gcc.misc-tests/gcov-31.c 
b/gcc/testsuite/gcc.misc-tests/gcov-31.c
index fff08825ff9..6c42d345abf 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-31.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-31.c
@@ -1,5 +1,6 @@
 /* { dg-options "--coverage -fpath-coverage" } */
 /* { dg-do compile } */
+/* { dg-require-effective-target sigsetjmp } */
 
 /* A collection of odd crashes and regressions observed when building arbitrary
programs.  */
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-32.c 
b/gcc/testsuite/gcc.misc-tests/gcov-32.c
index a1e453c0e93..cb8da01b7d5 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-32.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-32.c
@@ -1,5 +1,6 @@
 /* { dg-options "--coverage -fpath-coverage -g -O2" } */
 /* { dg-do compile } */
+/* { dg-require-effective-target sigsetjmp } */
 
 #include 
 
-- 
2.48.1



[COMMITTED 131/146] gccrs: ast-collector: Fix tuple struct pattern collection

2025-03-27 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Visit tuple 
pattern items as
separated by commas.
---
 gcc/rust/ast/rust-ast-collector.cc | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 4c9c360c04d..978de648a58 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2470,10 +2470,7 @@ TokenCollector::visit (StructPattern &pattern)
 void
 TokenCollector::visit (TupleStructItemsNoRange &pattern)
 {
-  for (auto &pat : pattern.get_patterns ())
-{
-  visit (pat);
-}
+  visit_items_joined_by_separator (pattern.get_patterns ());
 }
 
 void
-- 
2.45.2



[PATCH] testsuite: Replace the cray_pointers_2.f90 no cycling hack with dg-skip-if

2025-03-27 Thread Jakub Jelinek
On Thu, Mar 27, 2025 at 06:11:25PM +, Sam James wrote:
> >> diff --git a/gcc/testsuite/gfortran.dg/cray_pointers_2.f90 
> >> b/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
> >> index 4351874825ed..a7e15bad850a 100644
> >> --- a/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
> >> +++ b/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
> >> @@ -1,6 +1,6 @@
> >>   ! Using two spaces between dg-do and run is a hack to keep 
> >> gfortran-dg-runtest
> >>   ! from cycling through optimization options for this expensive test.
> >> -! { dg-do  run }
> >> +! { dg-do run }
> >>   ! { dg-options "-O3 -fcray-pointer -fbounds-check -fno-inline" }
> >>   ! { dg-timeout-factor 4 }
> >>   !
> >
> > There was an attempt by Jerry some time ago to have a directive
> > for not cycling through options, but this is not yet available.
> 
> Ah, PR28032.

There already is a documented directive which can do that.

As documented, dg-skip-if allows to skip a test if some option appears in
the list (e.g. cycle through everything but skip the test with -O2) or skip
unless all the options from a string are included.

The following patch runs the test only in the -O3 -g case (just using -O3
there would run it twice, once with
-O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions
and once with
-O3 -g

The -O3 from dg-options can be dropped too.

Some tests (e.g. in testsuite/gcc.dg/torture/) use e.g.
/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */
so the test is run just with -O2 by default, but when testing with
GCC_TEST_RUN_EXPENSIVE=1 it cycles through everything.  Note, you'd need
to drop the -O3 from dg-options in that case for sure, because with explicit
-O3 option in there it cycles through -O0 -O3, -O1 -O3, -O2 -O3,
-O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
-finline-functions -O3,
-O3 -g -O3, -Os -O3.

Ok for trunk?

Or do you want the ! run_expensive_tests version?

2025-03-27  Jakub Jelinek  

* gfortran.dg/cray_pointers_2.f90: Replace { dg-do  run } hack with
dg-skip-if directive.

--- gcc/testsuite/gfortran.dg/cray_pointers_2.f90.jj2020-01-12 
11:54:38.207386342 +0100
+++ gcc/testsuite/gfortran.dg/cray_pointers_2.f90   2025-03-27 
19:23:29.237873386 +0100
@@ -1,6 +1,5 @@
-! Using two spaces between dg-do and run is a hack to keep gfortran-dg-runtest
-! from cycling through optimization options for this expensive test.
-! { dg-do  run }
+! { dg-do run }
+! { dg-skip-if "Don't cycle through options" { *-*-* }  { "*" } { "-O3 -g" } }
 ! { dg-options "-O3 -fcray-pointer -fbounds-check -fno-inline" }
 ! { dg-timeout-factor 4 }
 !


Jakub



[PATCH] testsuite: Add options for float16 for test [PR119133]

2025-03-27 Thread Christophe Lyon
Some targets (like arm) need some flags to enable _Float16 support.

gcc/testsuite/ChangeLog:

PR target/119133
* gcc.dg/torture/pr119133.c: Add options for float16.
---
 gcc/testsuite/gcc.dg/torture/pr119133.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.dg/torture/pr119133.c 
b/gcc/testsuite/gcc.dg/torture/pr119133.c
index 5369becd350..f0c8f734c86 100644
--- a/gcc/testsuite/gcc.dg/torture/pr119133.c
+++ b/gcc/testsuite/gcc.dg/torture/pr119133.c
@@ -1,5 +1,6 @@
 /* { dg-additional-options "-fno-tree-ter" } */
 /* { dg-require-effective-target float16 } */
+/* { dg-add-options float16 } */
 
 int
 foo(_Float16 f, int i)
-- 
2.34.1



[PATCH] testsuite: aarch64: fix another unbalanced }

2025-03-27 Thread Sam James
In r15-8956-ge90d6c2639c392, I missed one, so while it did fix a problem,
it also exposed another because the braces were now unbalanced.

There's IMO more to do here with ideally whitespace before the } when
using scan-assembler-times but let's do that later.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/atomic-inst-ldlogic.c: Add another closing brace.
---
Pushed.

 gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c 
b/gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c
index 1927ebc10e28..11f9bfe7194b 100644
--- a/gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c
+++ b/gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c
@@ -145,7 +145,7 @@ TEST (xor_load_notreturn, XOR_LOAD_NORETURN)
 /* { dg-final { scan-assembler-times "ldeorlh\t" 8} } */
 /* { dg-final { scan-assembler-times "ldeoralh\t" 16} } */
 
-/* { dg-final { scan-assembler-times "ldeor\t" 16} */
+/* { dg-final { scan-assembler-times "ldeor\t" 16} } */
 /* { dg-final { scan-assembler-times "ldeora\t" 32} } */
 /* { dg-final { scan-assembler-times "ldeorl\t" 16} } */
 /* { dg-final { scan-assembler-times "ldeoral\t" 32} } */
-- 
2.49.0



[PATCH v3 12/19] Refactor FMV name mangling.

2025-03-27 Thread Alfie Richards

This patch is an overhaul of how FMV name mangling works. Previously
mangling logic was duplicated in several places across both target
specific and independent code. This patch changes this such that all
mangling is done in targetm.mangle_decl_assembler_name (including for the
dispatched symbol and dispatcher resolver).

This allows for the removing of previous hacks, such as where the default
mangled decl's assembler name was unmangled to then remangle all versions
and the resolver and dispatched symbol.

This does introduce a change though (shown in test changes) where
previously x86 for target annotated FMV sets set the function name to
the assembler name and remangled this. This was hard to reproduce without
resorting to hacks I wasn't comfortable with so the mangling is changed
to append ".ifunc" which matches clang.

This change also refactors expand_target_clone using
targetm.mangle_decl_assembler_name for mangling and get_clone_versions.

gcc/ChangeLog:

* attribs.cc (make_dispatcher_decl): Move duplicated cgraph logic into
this function and change to use targetm.mangle_decl_assembler_name for
mangling.
* config/aarch64/aarch64.cc (aarch64_parse_fmv_features): Change to
support string_slice.
(aarch64_process_target_version_attr): Ditto.
(get_feature_mask_for_version): Ditto.
(aarch64_mangle_decl_assembler_name): Add logic for mangling dispatched
symbol and resolver.
(get_suffixed_assembler_name): Removed.
(make_resolver_func): Refactor to use
aarch64_mangle_decl_assembler_name for mangling.
(aarch64_generate_version_dispatcher_body): Remove remangling.
(aarch64_get_function_versions_dispatcher): Refactor to remove
duplicated cgraph logic.
* config/i386/i386-features.cc (is_valid_asm_symbol): Moved from
multiple_target.cc.
(create_new_asm_name): Ditto.
(ix86_mangle_function_version_assembler_name): Refactor to use
clone_identifier and to mangle default.
(ix86_mangle_decl_assembler_name): Add logic for mangling dispatched
symbol and resolver.
(ix86_get_function_versions_dispatcher): Remove duplicated cgraph
logic.
(make_resolver_func): Refactor to use ix86_mangle_decl_assembler_name
for mangling.
* config/riscv/riscv.cc (riscv_mangle_decl_assembler_name): Add logic
for FMV mangling.
(get_suffixed_assembler_name): Removed.
(make_resolver_func): Refactor to use riscv_mangle_decl_assembler_name
for mangling.
(riscv_generate_version_dispatcher_body): Remove unnecessary remangling.
(riscv_get_function_versions_dispatcher): Remove duplicated cgraph
logic.
* config/rs6000/rs6000.cc (rs6000_mangle_decl_assembler_name): New
function.
(rs6000_get_function_versions_dispatcher): Remove duplicated cgraph
logic.
(make_resolver_func): Refactor to use rs6000_mangle_decl_assembler_name
for mangling.
(is_valid_asm_symbol): Move from multiple_target.cc.
(create_new_asm_name): Ditto.
(rs6000_mangle_function_version_assembler_name): New function.
* multiple_target.cc (create_dispatcher_calls): Remove mangling code.
(get_attr_str): Removed.
(separate_attrs): Ditto.
(is_valid_asm_symbol): Moved to target specific.
(create_new_asm_name): Ditto.
(expand_target_clones): Refactor to use
targetm.mangle_decl_assembler_name for mangling and be more general.
* tree.cc (get_target_clone_attr_len): Removed.
* tree.h (get_target_clone_attr_len): Removed.

gcc/cp/ChangeLog:

* decl.cc (maybe_mark_function_versioned): Change to insert function 
version
and therefore record assembler name.

gcc/testsuite/ChangeLog:

* g++.target/i386/mv-symbols1.C: Update x86 FMV mangling.
* g++.target/i386/mv-symbols3.C: Ditto.
* g++.target/i386/mv-symbols4.C: Ditto.
* g++.target/i386/mv-symbols5.C: Ditto.
---
 gcc/attribs.cc  |  44 +++-
 gcc/config/aarch64/aarch64.cc   | 166 ++-
 gcc/config/i386/i386-features.cc| 108 +++---
 gcc/config/riscv/riscv.cc   | 107 --
 gcc/config/rs6000/rs6000.cc | 115 +--
 gcc/cp/decl.cc  |   7 +
 gcc/multiple_target.cc  | 211 +++-
 gcc/testsuite/g++.target/i386/mv-symbols1.C |  12 +-
 gcc/testsuite/g++.target/i386/mv-symbols3.C |  10 +-
 gcc/testsuite/g++.target/i386/mv-symbols4.C |  10 +-
 gcc/testsuite/g++.target/i386/mv-symbols5.C |  10 +-
 gcc/tree.cc |  26 ---
 gcc/tree.h  |   2 -
 13 files changed, 400 insertions(+), 428 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 37d6ce0f916..09c4db96531 100644
--- 

Re: [PATCH] c++/modules: Fix modules and LTO with header units [PR118961]

2025-03-27 Thread Jason Merrill

On 3/27/25 3:35 AM, Nathaniel Shead wrote:

Bootstrapped and regtested (so far just dg.exp and modules.exp) on
x86_64-pc-linux-gnu, OK for trunk if full regtest succeeds?

Rather than updating copy_fndecl_with_name, we could also just fix
modules specifically by overwriting DECL_ABSTRACT_P before calling
build_cdtor_clones in trees_in::decl_value, or by forcing it to 0 for
DECL_MAYBE_IN_CHARGE_CDTOR during tree streaming, if you prefer, since
it'll always be set again by expand_or_defer_fn anyway.

-- >8 --

This patch makes some adjustments required to get a simple modules
testcase working with LTO.  There are two main issues fixed.

Firstly, modules only streams the maybe-in-charge constructor, and any
clones are recreated on stream-in.  These clones are copied from the
existing function decl and then adjusted.  This caused issues because
the clones were getting incorrectly marked as abstract, since after
clones have been created (in the imported file) the maybe-in-charge decl
gets marked as abstract.  So this patch just ensures that clones are
always created as non-abstract.


Sounds good.


The second issue is that we need to explicitly tell cgraph that explicit
instantiations need to be emitted, otherwise LTO will elide them (as
they don't necessarily appear to be used directly) and cause link
errors.


Makes sense.  Maybe you want to check get_importer_interface == 
always_emit instead of specifically for explicit inst?


...except I see that it returns that value for internal decls, which 
don't actually always need to be emitted; there seems to be a missing 
distinction between "considered to be defined in this TU" and actually 
"always emit".



Additionally, expand_or_defer_fn doesn't setup comdat groups
for explicit instantiations, so we need to do that here as well.


Hmm, that inconsistency seems worth fixing in expand_or_defer_fn, though 
it's fine to leave that for later and just add a FIXME comment to your 
change.



PR c++/118961

gcc/cp/ChangeLog:

* class.cc (copy_fndecl_with_name): Mark clones as non-abstract.
* module.cc (trees_in::read_var_def): Explicit instantiation
definitions of variables must be emitted, and are COMDAT.
(module_state::read_cluster): Likewise for functions.

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 2cded878c64..f9f48bb2421 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12684,6 +12684,13 @@ trees_in::read_var_def (tree decl, tree maybe_template)
  if (maybe_dup && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P 
(maybe_dup))
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
  tentative_decl_linkage (decl);


Doesn't this handle the comdat for variables?


+ if (DECL_EXPLICIT_INSTANTIATION (decl)
+ && !DECL_EXTERNAL (decl))
+   {
+ mark_needed (decl);
+ if (TREE_PUBLIC (decl))
+   maybe_make_one_only (decl);
+   }
  if (DECL_IMPLICIT_INSTANTIATION (decl)
  || (DECL_EXPLICIT_INSTANTIATION (decl)
  && !DECL_EXTERNAL (decl))


Jason



[PATCH v3 07/19] Change make_attribute to take string_slice.

2025-03-27 Thread Alfie Richards

gcc/ChangeLog:

* attribs.cc (make_attribute): Change arguments.
* attribs.h (make_attribute): Change arguments.
---
 gcc/attribs.cc | 18 ++
 gcc/attribs.h  |  2 +-
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index f6667839c01..37d6ce0f916 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1072,25 +1072,19 @@ apply_tm_attr (tree fndecl, tree attr)
   decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
 }
 
-/* Makes a function attribute of the form NAME(ARG_NAME) and chains
+/* Makes a function attribute of the form NAME (ARG_NAME) and chains
it to CHAIN.  */
 
 tree
-make_attribute (const char *name, const char *arg_name, tree chain)
+make_attribute (string_slice name, string_slice arg_name, tree chain)
 {
-  tree attr_name;
-  tree attr_arg_name;
-  tree attr_args;
-  tree attr;
-
-  attr_name = get_identifier (name);
-  attr_arg_name = build_string (strlen (arg_name), arg_name);
-  attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
-  attr = tree_cons (attr_name, attr_args, chain);
+  tree attr_name = get_identifier_with_length (name.begin (), name.size ());
+  tree attr_arg_name = build_string (arg_name.size (), arg_name.begin ());
+  tree attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
+  tree attr = tree_cons (attr_name, attr_args, chain);
   return attr;
 }
 
-
 /* Common functions used for target clone support.  */
 
 /* Comparator function to be used in qsort routine to sort attribute
diff --git a/gcc/attribs.h b/gcc/attribs.h
index 4b946390f76..b8b6838599c 100644
--- a/gcc/attribs.h
+++ b/gcc/attribs.h
@@ -45,7 +45,7 @@ extern bool cxx11_attribute_p (const_tree);
 extern tree get_attribute_name (const_tree);
 extern tree get_attribute_namespace (const_tree);
 extern void apply_tm_attr (tree, tree);
-extern tree make_attribute (const char *, const char *, tree);
+extern tree make_attribute (string_slice, string_slice, tree);
 extern bool attribute_ignored_p (tree);
 extern bool attribute_ignored_p (const attribute_spec *const);
 extern bool any_nonignored_attribute_p (tree);


[PATCH v3 06/19] Change function versions to be implicitly ordered.

2025-03-27 Thread Alfie Richards

This changes function version structures to maintain the default version
as the first declaration in the linked data structures by giving priority
to the set containing the default when constructing the structure.

This allows for removing logic for moving the default to the first
position which was duplicated across target specific code and enables
easier reasoning about function sets when checking for a default.

gcc/ChangeLog:

* cgraph.cc (cgraph_node::record_function_versions): Refactor and
rename to...
(cgraph_node::add_function_version): new function.
* cgraph.h (cgraph_node::record_function_versions): Refactor and
rename to...
(cgraph_node::add_function_version): new function.
* config/aarch64/aarch64.cc (aarch64_get_function_versions_dispatcher):
Remove reordering.
* config/i386/i386-features.cc (ix86_get_function_versions_dispatcher):
Remove reordering.
* config/riscv/riscv.cc (riscv_get_function_versions_dispatcher):
Remove reordering.
* config/rs6000/rs6000.cc (rs6000_get_function_versions_dispatcher):
Remove reordering.

gcc/cp/ChangeLog:

* decl.cc (maybe_version_functions): Change record_function_versions
call to add_function_version.
---
 gcc/cgraph.cc| 50 ++--
 gcc/cgraph.h |  6 ++--
 gcc/config/aarch64/aarch64.cc| 37 +--
 gcc/config/i386/i386-features.cc | 33 -
 gcc/config/riscv/riscv.cc| 38 
 gcc/config/rs6000/rs6000.cc  | 35 --
 gcc/cp/decl.cc   |  8 -
 7 files changed, 63 insertions(+), 144 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 6ae6a97f6f5..a2ad2516c12 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -231,43 +231,49 @@ cgraph_node::delete_function_version_by_decl (tree decl)
   decl_node->remove ();
 }
 
-/* Record that DECL1 and DECL2 are semantically identical function
-   versions.  */
+/* Add decl to the structure of semantically identical function versions..  */
 void
-cgraph_node::record_function_versions (tree decl1, tree decl2)
+cgraph_node::add_function_version (cgraph_function_version_info *fn_v,
+   tree decl)
 {
-  cgraph_node *decl1_node = cgraph_node::get_create (decl1);
-  cgraph_node *decl2_node = cgraph_node::get_create (decl2);
-  cgraph_function_version_info *decl1_v = NULL;
-  cgraph_function_version_info *decl2_v = NULL;
+  cgraph_node *decl_node = cgraph_node::get_create (decl);
+  cgraph_function_version_info *decl_v = NULL;
+
   cgraph_function_version_info *before;
   cgraph_function_version_info *after;
 
-  gcc_assert (decl1_node != NULL && decl2_node != NULL);
-  decl1_v = decl1_node->function_version ();
-  decl2_v = decl2_node->function_version ();
+  gcc_assert (decl_node != NULL);
 
-  if (decl1_v != NULL && decl2_v != NULL)
+  decl_v = decl_node->function_version ();
+
+  /* If the nodes are already linked, skip.  */
+  if (decl_v != NULL && (decl_v->next || decl_v->prev))
 return;
 
-  if (decl1_v == NULL)
-decl1_v = decl1_node->insert_new_function_version ();
+  if (decl_v == NULL)
+decl_v = decl_node->insert_new_function_version ();
 
-  if (decl2_v == NULL)
-decl2_v = decl2_node->insert_new_function_version ();
+  gcc_assert (decl_v);
+  gcc_assert (fn_v);
 
-  /* Chain decl2_v and decl1_v.  All semantically identical versions
- will be chained together.  */
+  before = fn_v;
+  after = decl_v;
 
-  before = decl1_v;
-  after = decl2_v;
+  /* Go to the beginning of both nodes (as after is on its own we just need to
+ this for before).  */
+  while (before->prev != NULL)
+before = before->prev;
 
+  /* Potentially swap the nodes to maintain the default always being in the
+ first position.  */
+  if (is_function_default_version (decl))
+std::swap (before, after);
+
+  /* Go to last node of before.  */
   while (before->next != NULL)
 before = before->next;
 
-  while (after->prev != NULL)
-after= after->prev;
-
+  /* Chain decl2_v and decl1_v.  */
   before->next = after;
   after->prev = before;
 }
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 065fcc742e8..6759505bf33 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1319,9 +1319,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
 return m_summary_id;
   }
 
-  /* Record that DECL1 and DECL2 are semantically identical function
- versions.  */
-  static void record_function_versions (tree decl1, tree decl2);
+  /* Adds DECL to the FN_V structure of semantically identical functions.  */
+  static void add_function_version (cgraph_function_version_info *fn_v,
+tree decl);
 
   /* Remove the cgraph_function_version_info and cgraph_node for DECL.  This
  DECL is a duplicate declaration.  */
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 25963c

Re: [RFC] [C]New syntax for the argument of counted_by attribute for C language

2025-03-27 Thread Qing Zhao
Yeoul,

Thanks for the writeup.

So, basically, This writeup insisted on introducing a new “structure scope” 
(similar as the instance scope in C++) into C language ONLY for counted_by 
attribute:

1. Inside counted_by attribute, the name lookup starts:

A. Inside the current structure first (the NEW structure scope added to C);
B. Then outside the structure; (other current C scopes, local scope or 
global scope)

2. When trying to reference a variable outside of the structure scope that 
name_conflicts with
a structure member, a new builtin function “__builtin_global_ref” is 
introduced for such 
purpose. 

   ( I think that __builtin_global_ref might not accurate, because the outer 
scope might be either global scope or local scope)

3. Where there is confliction between counted_by and VLA such as:

constexpr int len = 10;

struct s {
  int len;
  int *__counted_by(len) buf; // refers to struct member `len`.
  int arr[len]; // refers to global constexpr `len`
};

Issue compiler warning to user to ask the user to use __builtin_global_ref to 
distinguish. 

Are the above the correct understanding of your writeup?


From my understanding:

1. This design started from the C++’s point of view by adding a new “structure 
scope” to C;
2. This design conflicts with the current VLA default scope rule (which based 
on the default C scopes) in C.
 In the above example that mixes counted_by and VLA, it’s so weird that  
there are two difference name
 lookup rules inside the same structure. 
 It’s clearly a design bug. Either VLA or counted_by need to be fixed to 
make them consistent. 


I personally do not completely object to introduce a new “structure scope” into 
C, but it’s so hard for me to accept
that there are two different name lookup rules inside the same structure: one 
rule for VLA, another rule for counted_by
attribute.  (If introducing a new “structure scope” to C,  I think it’s better 
to change VLA to “structure scope” too, not sure
whether this is feasible or not)

I still think that introduce a new keyword “__self” for referring member 
variable inside structure without adding 
a new “structure scope" should be the best approach to resolve this issue in C. 

However, I am really hoping that the discussion can be converged soon. So, I am 
okay with adding a new “structure scope”
If most of people agreed on that approach. 

Qing


> On Mar 26, 2025, at 12:59, Yeoul Na  wrote:
> 
> Hi all,
> 
> Thanks for all the discussions.
> 
> I posted the design rationale for our current approach in 
> https://discourse.llvm.org/t/rfc-forward-referencing-a-struct-member-within-bounds-annotations/85510.
>  This clarifies some of the questions that are asked in this thread. The 
> document also proposes diagnostics to mitigate potential ambiguity, and 
> propose new builtins that can be used as a suppression and disambiguation 
> mechanism.
> 
> Best regards,
> Yeoul
> 
>> On Mar 26, 2025, at 9:11 AM, Yeoul Na  wrote:
>> 
>> Sorry for the delay.
>> 
>> I’m planning on sending out our design rationale of the current approach 
>> without the new syntax today.
>> 
>> - Yeoul
>> 
>>> On Mar 14, 2025, at 9:22 PM, John McCall  wrote:
>>> 
>>> On 14 Mar 2025, at 15:18, Martin Uecker wrote:
>>> Am Freitag, dem 14.03.2025 um 14:42 -0400 schrieb John McCall:
>>> On 14 Mar 2025, at 14:13, Martin Uecker wrote:
>>> Am Freitag, dem 14.03.2025 um 10:11 -0700 schrieb David Tarditi:
>>> Hi Martin,
>>> The C design of VLAs misunderstood dependent typing.
>>> They probably did not care about theory, but the design is 
>>> not inconsistent with theory.
>>> This is almost true, but for bad reasons. The theory of dependent types is 
>>> heavily concerned with deciding whether two types are the same, and C 
>>> simply sidesteps this question because type identity is largely meaningless 
>>> in C. Every value of variably-modified type is (or decays to) a pointer, 
>>> and all pointers in C freely convert to one another (within the 
>>> object/function categories). _Generic is based on type compatibility, not 
>>> equality. So in that sense, the standard doesn’t say anything inconsistent 
>>> with theory because it doesn’t even try to say anything.
>>> The reason it is not quite true is that C does have rules for compatible 
>>> and composite types, and alas, those rules for variably-modified types are 
>>> not consistent with theory. Two VLA types of compatible element type are 
>>> always statically considered compatible, and it’s simply UB if the sizes 
>>> aren’t the same. The composite type of a VLA and a fixed-size array type is 
>>> always the fixed-size array type. The standard is literally incomplete 
>>> about the composite type of two VLAs; if you use a ternary operator where 
>>> both operands are casts to VLA types, the standard just says it’s 
>>> straight-up just undefined behavior (because one of the types has a bound 
>>> that’s unevaluated) and doesn’t even bother telling us what the static typ

[COMMITTED 045/144] gccrs: Successfully produce pseudo-nop

2025-03-27 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* backend/rust-compile-asm.cc (CompileAsm::add_stmt):
Deleted
(CompileAsm::CompileAsm):
Successfully produce pseudo-nop
(CompileAsm::visit): Likewise
(CompileAsm::asm_build_asm_stmt): Likewise
(CompileAsm::asm_construct_string_tree): Likewise
(CompileAsm::asm_is_inline): Likewise
* backend/rust-compile-asm.h (class CompileAsm): Likewise
* backend/rust-compile-expr.cc (CompileExpr::visit): Likewise
---
 gcc/rust/backend/rust-compile-asm.cc  | 178 ++
 gcc/rust/backend/rust-compile-asm.h   |  73 ++-
 gcc/rust/backend/rust-compile-expr.cc |   3 +-
 3 files changed, 224 insertions(+), 30 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index bc11696ed10..fe080f6aa6b 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -2,34 +2,17 @@
 
 #include "rust-tree.h"
 #include "rust-system.h"
+#include 
 namespace Rust {
 namespace Compile {
 
-tree
-CompileAsm::add_stmt (tree t)
+CompileAsm::CompileAsm (Context *ctx)
+  : HIRCompileBase (ctx), translated (error_mark_node)
+{}
+void
+CompileAsm::visit (HIR::InlineAsm &expr)
 {
-  enum tree_code code = TREE_CODE (t);
-
-  if (EXPR_P (t) && code != LABEL_EXPR)
-{
-  if (!EXPR_HAS_LOCATION (t))
-   SET_EXPR_LOCATION (t, input_location);
-
-  /* When we expand a statement-tree, we must know whether or not the
-statements are full-expressions.  We record that fact here.  */
-  if (STATEMENT_CODE_P (TREE_CODE (t)))
-   STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
-}
-
-  if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
-STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1;
-
-  /* Add T to the statement-tree.  Non-side-effect statements need to be
- recorded during statement expressions.  */
-  gcc_checking_assert (!stmt_list_stack->is_empty ());
-  append_to_statement_list_force (t, &cur_stmt_list);
-
-  return t;
+  return ctx->add_statement (asm_build_expr (expr));
 }
 tree
 CompileAsm::asm_build_asm_stmt (HIR::InlineAsm &expr)
@@ -43,7 +26,7 @@ CompileAsm::asm_build_asm_stmt (HIR::InlineAsm &expr)
   //   return add_stmt (args);
   // }
   //
-  return add_stmt (asm_build_expr (expr));
+  return NULL_TREE;
 }
 tree
 CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
@@ -116,6 +99,8 @@ CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
 {
   if (expr.template_strs.empty ())
 return build_string (1, "");
+  else
+return build_string (4, "nop");
   // Initialize to NULL_TREE
   tree string_chain = NULL_TREE;
 
@@ -168,3 +153,146 @@ CompileAsm::asm_is_inline (HIR::InlineAsm &expr)
 }
 } // namespace Compile
 } // namespace Rust
+  //
+  //
+  // The following section serves as documentation for PR revieweres and future
+  // asm developers. It documents the inspriation for the implementation of the
+  // CompileAsm class
+
+// From the implementation of c-typeck.cc
+// tree
+// build_asm_stmt (bool is_volatile, tree args)
+//{
+//   if (is_volatile)
+// ASM_VOLATILE_P (args) = 1;
+//   return add_stmt (args);
+// }
+//
+///* Build an asm-expr, whose components are a STRING, some OUTPUTS,
+//   some INPUTS, and some CLOBBERS.  The latter three may be NULL.
+//   SIMPLE indicates whether there was anything at all after the
+//   string in the asm expression -- asm("blah") and asm("blah" : )
+//   are subtly different.  We use a ASM_EXPR node to represent this.
+//   LOC is the location of the asm, and IS_INLINE says whether this
+//   is asm inline.  */
+// tree
+// build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
+// tree clobbers, tree labels, bool simple, bool is_inline)
+//{
+//  tree tail;
+//  tree args;
+//  int i;
+//  const char *constraint;
+//  const char **oconstraints;
+//  bool allows_mem, allows_reg, is_inout;
+//  int ninputs, noutputs;
+//
+//  ninputs = list_length (inputs);
+//  noutputs = list_length (outputs);
+//  oconstraints = (const char **) alloca (noutputs * sizeof (const char *));
+//
+//  string = resolve_asm_operand_names (string, outputs, inputs, labels);
+//
+//  /* Remove output conversions that change the type but not the mode.  */
+//  for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
+//{
+//  tree output = TREE_VALUE (tail);
+//
+//  output = c_fully_fold (output, false, NULL, true);
+//
+//  /* ??? Really, this should not be here.  Users should be using a
+//  proper lvalue, dammit.  But there's a long history of using casts
+//  in the output operands.  In cases like longlong.h, this becomes a
+//  primitive form of typechecking -- if the cast can be removed, then
+//  the output operand had a type of the proper width; otherwise we'll
+//  get an error.  Gross, but ...  */
+//  STRIP_NOPS (output);
+//
+//  if (!lvalue_or_else (loc, ou

Re: [PATCH 1/3] testsuite: harmless dg-* whitespace fixes

2025-03-27 Thread Harald Anlauf

Sam,

who approved the fortran testsuite changes?

Am 27.03.25 um 14:28 schrieb Sam James:

These just fix inconsistent/unusual style to avoid noise when grepping
and also people picking up bad habits when they see it (as similar
mistakes can be harmful).


This one should be reverted.  The reason for the two spaces is actually
explained in the testcase:


diff --git a/gcc/testsuite/gfortran.dg/cray_pointers_2.f90 
b/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
index 4351874825ed..a7e15bad850a 100644
--- a/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
+++ b/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
@@ -1,6 +1,6 @@
  ! Using two spaces between dg-do and run is a hack to keep gfortran-dg-runtest
  ! from cycling through optimization options for this expensive test.
-! { dg-do  run }
+! { dg-do run }
  ! { dg-options "-O3 -fcray-pointer -fbounds-check -fno-inline" }
  ! { dg-timeout-factor 4 }
  !


There was an attempt by Jerry some time ago to have a directive
for not cycling through options, but this is not yet available.

Thanks,
Harald




[PATCH] testsuite: revert Fortran change

2025-03-27 Thread Sam James
Revert part of my change from r15-8973-g1307de1b4e7d5e; as Harald points
out, the comment explains why this is there. It's a hack but it needs to
stay for now. (I did have this marked as a TODO in my branch and didn't
leave a proper note as to why, so it's my fault.)

gcc/testsuite/ChangeLog:

* gfortran.dg/cray_pointers_2.f90: Restore whitespace.
---

 gcc/testsuite/gfortran.dg/cray_pointers_2.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gfortran.dg/cray_pointers_2.f90 
b/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
index a7e15bad850a..4351874825ed 100644
--- a/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
+++ b/gcc/testsuite/gfortran.dg/cray_pointers_2.f90
@@ -1,6 +1,6 @@
 ! Using two spaces between dg-do and run is a hack to keep gfortran-dg-runtest
 ! from cycling through optimization options for this expensive test.
-! { dg-do run }
+! { dg-do  run }
 ! { dg-options "-O3 -fcray-pointer -fbounds-check -fno-inline" }
 ! { dg-timeout-factor 4 }
 !

base-commit: 176c7a2f751e0487c500c2a83bd44ebad89df958
-- 
2.49.0



[Committed] RISC-V: testsuite: fix syntax error for assembler scan

2025-03-27 Thread Edwin Lu
When the dg brackets were added, they forgot to add the brackets for the
scan-assembler-times directive.

Committed as obvious.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vls/merge-4.c: Fix typo

Signed-off-by: Edwin Lu 
---
 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-4.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-4.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-4.c
index 30ef22f9f9e..4ae341a091e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-4.c
@@ -3,6 +3,6 @@

 #include "../vls-vlmax/merge-4.c"

-/* { dg-final scan-assembler-times {\tvmerge.vvm} 11 } */
+/* { dg-final { scan-assembler-times {\tvmerge.vvm} 11 } } */
 /* { dg-final { scan-assembler-not {\tvms} } } */
 /* { dg-final { scan-assembler-times {\tvlm.v} 11 } } */
--
2.43.0



[PATCH v3 14/19] Add reject_target_clone hook and filter target_clone versions.

2025-03-27 Thread Alfie Richards

This patch introduces the TARGET_REJECT_FUNCTION_CLONE_VERSION hook
which is used to determine if a target_clones version string parses.

If true is returned, a warning is emitted and from then on the version
is ignored.

This is as specified in the Arm C Language Extension. The purpose of this
is to allow some portability of code using target_clones attributes.

Currently this is only properly implemented for the Aarch64 backend.

For riscv which is the only other backend which uses target_version
semantics a partial implementation is present, where this hook is used
to check parsing, in which errors will be emitted on a failed parse
rather than warnings. A refactor of the riscv parsing logic would be
required to enable this functionality fully.

Additionally, after refactoring the riscv logic, the location argument
to the hook would be unnecessary.

This also fixes PR 118339 where parse failures could cause ICE in Aarch64.

gcc/ChangeLog:

PR target/118339
* attribs.cc (reject_target_clone_version): New function.
* target.def: Add reject_target_clone_version hook.
* tree.cc (get_clone_attr_versions): Add filter and location argument.
(get_clone_versions): Update call to get_clone_attr_versions.
* tree.h (get_clone_attr_versions): Add filter and location argument.
* config/aarch64/aarch64.cc (aarch64_reject_target_clone_version):
New function
(TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/i386/i386.cc (TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/riscv/riscv.cc (riscv_reject_target_clone_version):
New function.
(TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* config/rs6000/rs6000.cc (TARGET_REJECT_FUNCTION_CLONE_VERSION):
New define.
* doc/tm.texi: Regenerated.
* doc/tm.texi.in: Add documentation for new hook.

gcc/c-family/ChangeLog:

* c-attribs.cc (handle_target_clones_attribute): Update to emit warnings
for rejected versions.
---
 gcc/attribs.cc|  7 +++
 gcc/c-family/c-attribs.cc | 24 
 gcc/config/aarch64/aarch64.cc | 20 
 gcc/config/i386/i386.cc   |  3 +++
 gcc/config/riscv/riscv.cc | 18 ++
 gcc/config/rs6000/rs6000.cc   |  3 +++
 gcc/doc/tm.texi   |  5 +
 gcc/doc/tm.texi.in|  2 ++
 gcc/target.def|  8 
 gcc/tree.cc   | 12 ++--
 gcc/tree.h|  8 ++--
 11 files changed, 102 insertions(+), 8 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 09c4db96531..80833388ff2 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -1242,6 +1242,13 @@ common_function_versions (tree fn1, tree fn2)
   return result;
 }
 
+bool
+reject_target_clone_version (string_slice str ATTRIBUTE_UNUSED,
+			 location_t loc ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
 /* Make a dispatcher declaration for the multi-versioned function DECL.
Calls to DECL function will be replaced with calls to the dispatcher
by the front-end.  Return the decl created.  */
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5dff489fcca..b5287f0da06 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -6132,12 +6132,28 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
 	}
 	}
 
-  auto_vec versions= get_clone_attr_versions (args, NULL);
+  int num_defaults = 0;
+  auto_vec versions= get_clone_attr_versions (args,
+  &num_defaults,
+  DECL_SOURCE_LOCATION (*node),
+  false);
 
-  if (versions.length () == 1)
-	{
+  for (auto v : versions)
+	if (targetm.reject_function_clone_version
+	  (v, DECL_SOURCE_LOCATION (*node)))
 	  warning (OPT_Wattributes,
-		   "single % attribute is ignored");
+		   "invalid % version %qB ignored",
+		   &v);
+
+  /* Lone target_clones version is always ignored for target attr semantics.
+	 Only ignore under target_version semantics if it is a default
+	 version.  */
+  if (versions.length () == 1 && (TARGET_HAS_FMV_TARGET_ATTRIBUTE
+  || num_defaults == 1))
+	{
+	  if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+	warning (OPT_Wattributes,
+		 "single % attribute is ignored");
 	  *no_add_attrs = true;
 	}
   else
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index fe46e569afe..1b9d91d268a 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -31224,6 +31224,23 @@ aarch64_expand_reversed_crc_using_pmull (scalar_mode crc_mode,
 }
 }
 
+bool
+aarch64_reject_target_clone_version (string_slice str,
+ location_t loc ATTRIBUTE_UNUSED)
+{
+  str = str.strip ();
+
+  if (str == "default")
+return false;
+
+  enum aarch_parse_opt_result parse_res;
+  auto isa_flags = aarch64_asm_isa_flags;
+  parse_res = 

Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-27 Thread Sandra Loosemore

On 3/27/25 10:11, Paul-Antoine Arras wrote:
I updated the patch (see attachment) with that in mind. Let me know what 
you think.


I know that very long 
"BT_FN_VOID_INT_INT_PTRCONSTPTRPTR_CONSTPTR_PTRCONSTSTRING..." 
identifier follows the conventions used elsewhere, but it's not very 
readable, and this function signature is unlikely to ever be used for 
anything other than BUILT_IN_GOMP_INTEROP.  What do other folks think 
about using a name like "BT_FN_GOMP_INTEROP" or 
"BT_FN_GOMP_INTEROP_11ARGS" or something like that?


Somebody else will have to approve the patch, anyway, since this is out 
of my league


-Sandra


[PATCH] RISC-V: Add pattern for vector-scalar multiply-add/sub [PR119100]

2025-03-27 Thread Paul-Antoine Arras
This pattern enables the combine pass to merge a vec_duplicate into a plus-mult
or minus-mult RTL instruction.

Before this patch, we have two instructions, e.g.:
  vfmv.v.fv6,fa0
  vfmadd.vv   v9,v6,v7

After, we get only one:
  vfmadd.vf   v9,fa0,v7

On SPEC2017's 503.bwaves_r, depending on the workload, the reduction in dynamic
instruction count varies from -4.66% to -4.75%.

gcc/ChangeLog:

PR target/119100
* config/riscv/vector.md (*pred__scalar): Define.
---
 gcc/config/riscv/vector.md | 23 +++
 1 file changed, 23 insertions(+)

diff --git gcc/config/riscv/vector.md gcc/config/riscv/vector.md
index 8ee43cf0ce1..6f538eeefda 100644
--- gcc/config/riscv/vector.md
+++ gcc/config/riscv/vector.md
@@ -6633,6 +6633,29 @@
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
 
+(define_insn_and_split "*pred__scalar"
+  [(set (match_operand:V_VLSF 0 "register_operand""=vd, vr")
+(plus_minus:V_VLSF
+   (mult:V_VLSF
+ (vec_duplicate:V_VLSF
+   (match_operand: 1 "register_operand" "  f,f"))
+ (match_operand:V_VLSF 2 "register_operand"  "  0,0"))
+   (match_operand:V_VLSF 3 "register_operand"" vr,   vr")))]
+  "TARGET_VECTOR"
+  "#"
+  "!reload_completed"
+  [(const_int 0)]
+  {
+rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+ operands[2]};
+riscv_vector::emit_vlmax_insn (code_for_pred_mul_scalar (, 
mode),
+riscv_vector::TERNARY_OP_FRM_DYN, ops);
+DONE;
+  }
+  [(set_attr "type" "vfmuladd")
+   (set_attr "mode" "")]
+)
+
 (define_insn "*pred__scalar"
   [(set (match_operand:V_VLSF 0 "register_operand""=vd, vr")
(if_then_else:V_VLSF
-- 
2.34.1



[Fortran, Patch, PR119380, v1] Fix freeing procedure pointers in components

2025-03-27 Thread Andre Vehreschild
Hi all,

attached patch fixes freeing of procedure pointers that are stored in a derived
type's component. GFortran did that already for polymorphic types but missed
out on the others.

Regtested ok on x86_64-pc-linux-gnu / F41. Ok for mainline?

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
From 9a77974f8120564846f672f28650100d158f365d Mon Sep 17 00:00:00 2001
From: Andre Vehreschild 
Date: Fri, 21 Mar 2025 09:13:29 +0100
Subject: [PATCH] Fortran: Fix freeing procedure pointer components [PR119380]

	PR fortran/119380

gcc/fortran/ChangeLog:

	* trans-array.cc (structure_alloc_comps): Prevent freeing of
	procedure pointer components.

gcc/testsuite/ChangeLog:

	* gfortran.dg/proc_ptr_comp_54.f90: New test.
---
 gcc/fortran/trans-array.cc|  2 +-
 .../gfortran.dg/proc_ptr_comp_54.f90  | 30 +++
 2 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/proc_ptr_comp_54.f90

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index e9eacf20128..960613167f7 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10109,7 +10109,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest,
 	  else
 	{
 	  attr = &c->attr;
-	  if (attr->pointer)
+	  if (attr->pointer || attr->proc_pointer)
 		continue;
 	}

diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_54.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_54.f90
new file mode 100644
index 000..73abc590e9e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_54.f90
@@ -0,0 +1,30 @@
+!{ dg-do run }
+
+! Check that components of procedure pointer aren't freeed.
+! Contributed by Damian Rouson  
+
+  implicit none
+
+  type foo_t
+integer, allocatable :: i_
+procedure(f), pointer, nopass :: f_
+procedure(c), pointer, nopass :: c_
+  end type
+
+  class(foo_t), allocatable :: ff
+
+  associate(foo => foo_t(1,f))
+  end associate
+
+contains
+
+  function f()
+logical, allocatable :: f
+f = .true.
+  end function
+
+  function c()
+class(foo_t), allocatable :: c
+allocate(c)
+  end function
+end
--
2.49.0



[PATCH] testsuite: Fix up strub-internal-pr112938.C test for C++2{0,3,6}

2025-03-27 Thread Jakub Jelinek
On Thu, Mar 27, 2025 at 12:05:21AM +, Sam James wrote:
> The test was being ignored because dg.exp looks for .C in g++.dg/.
> 
> gcc/testsuite/ChangeLog:
>   PR middle-end/112938
> 
>   * g++.dg/strub-internal-pr112938.cc: Move to...
>   * g++.dg/strub-internal-pr112938.C: ...here.
> ---
>  .../{strub-internal-pr112938.cc => strub-internal-pr112938.C} | 0
>  1 file changed, 0 insertions(+), 0 deletions(-)
>  rename gcc/testsuite/g++.dg/{strub-internal-pr112938.cc => 
> strub-internal-pr112938.C} (100%)
> 
> diff --git a/gcc/testsuite/g++.dg/strub-internal-pr112938.cc 
> b/gcc/testsuite/g++.dg/strub-internal-pr112938.C
> similarity index 100%
> rename from gcc/testsuite/g++.dg/strub-internal-pr112938.cc
> rename to gcc/testsuite/g++.dg/strub-internal-pr112938.C

This regressed the test for C++20 and higher:
FAIL: g++.dg/strub-internal-pr112938.C  -std=gnu++20 (test for excess errors)
FAIL: g++.dg/strub-internal-pr112938.C  -std=gnu++23 (test for excess errors)
FAIL: g++.dg/strub-internal-pr112938.C  -std=gnu++26 (test for excess errors)

Here is a fix, tested on x86_64-linux, ok for trunk?

2025-03-27  Jakub Jelinek  

* g++.dg/strub-internal-pr112938.C: Add dg-warning for c++20.

--- gcc/testsuite/g++.dg/strub-internal-pr112938.C.jj   2025-03-27 
17:17:35.837752377 +0100
+++ gcc/testsuite/g++.dg/strub-internal-pr112938.C  2025-03-27 
20:25:49.13565 +0100
@@ -3,7 +3,7 @@
 /* { dg-require-effective-target strub } */
 
 bool __attribute__ ((__strub__ ("internal")))
-f(bool i, volatile bool j)
+f(bool i, volatile bool j) /* { dg-warning "'volatile'-qualified parameter 
is deprecated" "" { target c++20 } } */
 {
   return (i ^ j) == j;
 }


Jakub



RE: [PATCH] i386: Add attr_isa for vaes patterns to sync with attr gpr16. [pr119473]

2025-03-27 Thread Hu, Lin1
Bootstrapped and Regtested on x86_64-linux-gnu{-m32,-m64}, OK for trunk?

BRs,
Lin

> -Original Message-
> From: Hu, Lin1 
> Sent: Friday, March 28, 2025 1:55 PM
> To: gcc-patches@gcc.gnu.org
> Cc: Liu, Hongtao ; ubiz...@gmail.com; Wang, Hongyu
> 
> Subject: [PATCH] i386: Add attr_isa for vaes patterns to sync with attr gpr16.
> [pr119473]
> 
> For vaes patterns with jm constraint and gpr16 attr, it requires "isa"
> attr to distinct avx/avx512 alternatives in ix86_memory_address_reg_class.
> Also adds missing type and mode attributes for those vaes patterns.
> 
> gcc/ChangeLog:
> 
>   PR target/119473
>   * config/i386/sse.md
>   (vaesdec_): Set attr "isa" as "avx,vaes_avx512vl", "type" as
>   "sselog1", "mode" as "TI".
>   (vaesdeclast_): Ditto.
>   (vaesenc_): Ditto.
>   (vaesenclast_): Ditto.
> 
> gcc/testsuite/ChangeLog:
> 
>   PR target/119473
>   * gcc.target/i386/pr119473.c: New test.
> 
> Co-authored-by: Hongyu Wang 
> ---
>  gcc/config/i386/sse.md   | 20 +++
>  gcc/testsuite/gcc.target/i386/pr119473.c | 25 
>  2 files changed, 41 insertions(+), 4 deletions(-)  create mode 100644
> gcc/testsuite/gcc.target/i386/pr119473.c
> 
> diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index
> ed5ac1abe80..538a7f7bdd5 100644
> --- a/gcc/config/i386/sse.md
> +++ b/gcc/config/i386/sse.md
> @@ -30845,7 +30845,10 @@ (define_insn "vaesdec_"
>else
>  return "vaesdec\t{%2, %1, %0|%0, %1, %2}";  } -[(set_attr "addr" 
> "gpr16,*")])
> +[(set_attr "isa" "avx,vaes_avx512vl")
> + (set_attr "type" "sselog1")
> + (set_attr "addr" "gpr16,*")
> + (set_attr "mode" "TI")])
> 
>  (define_insn "vaesdeclast_"
>[(set (match_operand:VI1_AVX512VL_F 0 "register_operand" "=x,v") @@ -
> 30860,7 +30863,10 @@ (define_insn "vaesdeclast_"
>else
>  return "vaesdeclast\t{%2, %1, %0|%0, %1, %2}";  } -[(set_attr "addr"
> "gpr16,*")])
> +[(set_attr "isa" "avx,vaes_avx512vl")
> + (set_attr "type" "sselog1")
> + (set_attr "addr" "gpr16,*")
> + (set_attr "mode" "TI")])
> 
>  (define_insn "vaesenc_"
>[(set (match_operand:VI1_AVX512VL_F 0 "register_operand" "=x,v") @@ -
> 30875,7 +30881,10 @@ (define_insn "vaesenc_"
>else
>  return "vaesenc\t{%2, %1, %0|%0, %1, %2}";  } -[(set_attr "addr" 
> "gpr16,*")])
> +[(set_attr "isa" "avx,vaes_avx512vl")
> + (set_attr "type" "sselog1")
> + (set_attr "addr" "gpr16,*")
> + (set_attr "mode" "TI")])
> 
>  (define_insn "vaesenclast_"
>[(set (match_operand:VI1_AVX512VL_F 0 "register_operand" "=x,v") @@ -
> 30890,7 +30899,10 @@ (define_insn "vaesenclast_"
>else
>  return "vaesenclast\t{%2, %1, %0|%0, %1, %2}";  } -[(set_attr "addr"
> "gpr16,*")])
> +[(set_attr "isa" "avx,vaes_avx512vl")
> + (set_attr "type" "sselog1")
> + (set_attr "addr" "gpr16,*")
> + (set_attr "mode" "TI")])
> 
>  (define_insn "vpclmulqdq_"
>[(set (match_operand:VI8_FVL 0 "register_operand" "=v") diff --git
> a/gcc/testsuite/gcc.target/i386/pr119473.c
> b/gcc/testsuite/gcc.target/i386/pr119473.c
> new file mode 100644
> index 000..62287c5c3b3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr119473.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-options "-O2 -mapxf -m64 -mvaes" } */
> +
> +typedef char __v32qi __attribute__ ((__vector_size__(32))); typedef
> +long long __m256i __attribute__((__vector_size__(32),
> +__aligned__(32)));
> +
> +typedef union
> +{
> +  __v32qi qi[8];
> +} tmp_u;
> +
> +
> +void foo ()
> +{
> +  register tmp_u *tdst __asm__("%rdx");
> +  register tmp_u *src1 __asm__("%rcx");
> +  register tmp_u *src2 __asm__("%r26");
> +
> +  tdst->qi[0] = __builtin_ia32_vaesdec_v32qi(src1->qi[0], src2->qi[0]);
> +  tdst->qi[0] = __builtin_ia32_vaesdeclast_v32qi(src1->qi[0],
> +src2->qi[0]);
> +  tdst->qi[0] = __builtin_ia32_vaesenc_v32qi(src1->qi[0], src2->qi[0]);
> +  tdst->qi[0] = __builtin_ia32_vaesenclast_v32qi(src1->qi[0],
> +src2->qi[0]); }
> +
> +/* { dg-final { scan-assembler-not "\\\(%r26\\\), " } } */
> --
> 2.31.1



[PATCH] i386: Add attr_isa for vaes patterns to sync with attr gpr16. [pr119473]

2025-03-27 Thread Hu, Lin1
For vaes patterns with jm constraint and gpr16 attr, it requires "isa"
attr to distinct avx/avx512 alternatives in ix86_memory_address_reg_class.
Also adds missing type and mode attributes for those vaes patterns.

gcc/ChangeLog:

PR target/119473
* config/i386/sse.md
(vaesdec_): Set attr "isa" as "avx,vaes_avx512vl", "type" as
"sselog1", "mode" as "TI".
(vaesdeclast_): Ditto.
(vaesenc_): Ditto.
(vaesenclast_): Ditto.

gcc/testsuite/ChangeLog:

PR target/119473
* gcc.target/i386/pr119473.c: New test.

Co-authored-by: Hongyu Wang 
---
 gcc/config/i386/sse.md   | 20 +++
 gcc/testsuite/gcc.target/i386/pr119473.c | 25 
 2 files changed, 41 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr119473.c

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index ed5ac1abe80..538a7f7bdd5 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -30845,7 +30845,10 @@ (define_insn "vaesdec_"
   else
 return "vaesdec\t{%2, %1, %0|%0, %1, %2}";
 }
-[(set_attr "addr" "gpr16,*")])
+[(set_attr "isa" "avx,vaes_avx512vl")
+ (set_attr "type" "sselog1")
+ (set_attr "addr" "gpr16,*")
+ (set_attr "mode" "TI")])
 
 (define_insn "vaesdeclast_"
   [(set (match_operand:VI1_AVX512VL_F 0 "register_operand" "=x,v")
@@ -30860,7 +30863,10 @@ (define_insn "vaesdeclast_"
   else
 return "vaesdeclast\t{%2, %1, %0|%0, %1, %2}";
 }
-[(set_attr "addr" "gpr16,*")])
+[(set_attr "isa" "avx,vaes_avx512vl")
+ (set_attr "type" "sselog1")
+ (set_attr "addr" "gpr16,*")
+ (set_attr "mode" "TI")])
 
 (define_insn "vaesenc_"
   [(set (match_operand:VI1_AVX512VL_F 0 "register_operand" "=x,v")
@@ -30875,7 +30881,10 @@ (define_insn "vaesenc_"
   else
 return "vaesenc\t{%2, %1, %0|%0, %1, %2}";
 }
-[(set_attr "addr" "gpr16,*")])
+[(set_attr "isa" "avx,vaes_avx512vl")
+ (set_attr "type" "sselog1")
+ (set_attr "addr" "gpr16,*")
+ (set_attr "mode" "TI")])
 
 (define_insn "vaesenclast_"
   [(set (match_operand:VI1_AVX512VL_F 0 "register_operand" "=x,v")
@@ -30890,7 +30899,10 @@ (define_insn "vaesenclast_"
   else
 return "vaesenclast\t{%2, %1, %0|%0, %1, %2}";
 }
-[(set_attr "addr" "gpr16,*")])
+[(set_attr "isa" "avx,vaes_avx512vl")
+ (set_attr "type" "sselog1")
+ (set_attr "addr" "gpr16,*")
+ (set_attr "mode" "TI")])
 
 (define_insn "vpclmulqdq_"
   [(set (match_operand:VI8_FVL 0 "register_operand" "=v")
diff --git a/gcc/testsuite/gcc.target/i386/pr119473.c 
b/gcc/testsuite/gcc.target/i386/pr119473.c
new file mode 100644
index 000..62287c5c3b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr119473.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mapxf -m64 -mvaes" } */
+
+typedef char __v32qi __attribute__ ((__vector_size__(32)));
+typedef long long __m256i __attribute__((__vector_size__(32), 
__aligned__(32)));
+
+typedef union
+{
+  __v32qi qi[8];
+} tmp_u;
+
+
+void foo ()
+{
+  register tmp_u *tdst __asm__("%rdx");
+  register tmp_u *src1 __asm__("%rcx");
+  register tmp_u *src2 __asm__("%r26");
+
+  tdst->qi[0] = __builtin_ia32_vaesdec_v32qi(src1->qi[0], src2->qi[0]);
+  tdst->qi[0] = __builtin_ia32_vaesdeclast_v32qi(src1->qi[0], src2->qi[0]);
+  tdst->qi[0] = __builtin_ia32_vaesenc_v32qi(src1->qi[0], src2->qi[0]);
+  tdst->qi[0] = __builtin_ia32_vaesenclast_v32qi(src1->qi[0], src2->qi[0]);
+}
+
+/* { dg-final { scan-assembler-not "\\\(%r26\\\), " } } */
-- 
2.31.1



[committed] cobol: Incorporate new testcases from the cobolworx UAT tests.

2025-03-27 Thread Robert Dubner
This is the initial group of testcases programmatically converted from the
autom4te UAT tests in the cobolworx repository.

These tests behave as intended on an x86_64-linux platform.

>From c8d32f79a27e034979f838e7f611cb4ea049639f Mon Sep 17 00:00:00 2001
From: Bob Dubner 
Date: Thu, 27 Mar 2025 17:55:53 -0400
Subject: [PATCH] cobol: Incorporate new testcases from the cobolworx UAT
 tests.

The author notes that some of the file names are regrettably lengthy,
which is because they are derived from the descriptive names of the
autom4te tests.

gcc/testsuite

*
cobol.dg/group2/ACCEPT_DATE___DAY_and_intrinsic_functions__1_.cob: New
testcase.
*
cobol.dg/group2/ACCEPT_DATE___DAY_and_intrinsic_functions__2_.cob:
Likewise.
*
cobol.dg/group2/ACCEPT_FROM_TIME___DATE___DAY___DAY-OF-WEEK__1_.cob:
Likewise.
*
cobol.dg/group2/ACCEPT_FROM_TIME___DATE___DAY___DAY-OF-WEEK__2_.cob:
Likewise.
* cobol.dg/group2/COMP-6_arithmetic.cob: Likewise.
* cobol.dg/group2/COMP-6_numeric_test.cob: Likewise.
* cobol.dg/group2/COMP-6_used_with_DISPLAY.cob: Likewise.
* cobol.dg/group2/COMP-6_used_with_MOVE.cob: Likewise.
* cobol.dg/group2/COMPUTE_multiplication_to_FIX4.cob: Likewise.
* cobol.dg/group2/DISPLAY__Sign_ASCII__2_.cob: Likewise.
* cobol.dg/group2/DISPLAY__Sign_ASCII.cob: Likewise.
* cobol.dg/group2/Floating_continuation_indicator__1_.cob:
Likewise.
* cobol.dg/group2/floating-point_ADD_FORMAT_1.cob: Likewise.
* cobol.dg/group2/floating-point_ADD_FORMAT_2.cob: Likewise.
* cobol.dg/group2/floating-point_DIVIDE_FORMAT_1.cob: Likewise.
* cobol.dg/group2/floating-point_DIVIDE_FORMAT_2.cob: Likewise.
* cobol.dg/group2/floating-point_literals.cob: Likewise.
* cobol.dg/group2/floating-point_MULTIPLY_FORMAT_1.cob: Likewise.
* cobol.dg/group2/floating-point_MULTIPLY_FORMAT_2.cob: Likewise.
* cobol.dg/group2/floating-point_SUBTRACT_FORMAT_1.cob: Likewise.
* cobol.dg/group2/floating-point_SUBTRACT_FORMAT_2.cob: Likewise.
*
cobol.dg/group2/IBM_dialect_COMP_redefined_by_POINTER_as_64-bit.cob:
Likewise.
* cobol.dg/group2/Indicators___-D__.cob: Likewise.
* cobol.dg/group2/MULTIPLY_to_FIX4.cob: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_arithmetic.cob: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_basic_comp-3_comp-6__1_.cob:
Likewise.
* cobol.dg/group2/PACKED-DECIMAL_basic_comp-3_comp-6__2_.cob:
Likewise.
* cobol.dg/group2/PACKED-DECIMAL_dump.cob: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_numeric_test__1_.cob: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_numeric_test__2_.cob: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_used_with_DISPLAY.cob: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_used_with_INITIALIZE.cob:
Likewise.
* cobol.dg/group2/PACKED-DECIMAL_used_with_MOVE.cob: Likewise.
* cobol.dg/group2/POINTER__display.cob: Likewise.
* cobol.dg/group2/Simple_floating-point_MOVE.cob: Likewise.
* cobol.dg/group2/Simple_floating-point_VALUE_and_MOVE.cob:
Likewise.
*
cobol.dg/group2/ACCEPT_FROM_TIME___DATE___DAY___DAY-OF-WEEK__2_.out:
Known-good result.
* cobol.dg/group2/COMP-6_arithmetic.out: Likewise.
* cobol.dg/group2/COMP-6_numeric_test.out: Likewise.
* cobol.dg/group2/COMP-6_used_with_DISPLAY.out: Likewise.
* cobol.dg/group2/COMP-6_used_with_MOVE.out: Likewise.
* cobol.dg/group2/COMPUTE_multiplication_to_FIX4.out: Likewise.
* cobol.dg/group2/DISPLAY__Sign_ASCII__2_.out: Likewise.
* cobol.dg/group2/DISPLAY__Sign_ASCII.out: Likewise.
* cobol.dg/group2/Floating_continuation_indicator__1_.out:
Likewise.
* cobol.dg/group2/floating-point_ADD_FORMAT_1.out: Likewise.
* cobol.dg/group2/floating-point_ADD_FORMAT_2.out: Likewise.
* cobol.dg/group2/floating-point_DIVIDE_FORMAT_1.out: Likewise.
* cobol.dg/group2/floating-point_DIVIDE_FORMAT_2.out: Likewise.
* cobol.dg/group2/floating-point_literals.out: Likewise.
* cobol.dg/group2/floating-point_MULTIPLY_FORMAT_1.out: Likewise.
* cobol.dg/group2/floating-point_MULTIPLY_FORMAT_2.out: Likewise.
* cobol.dg/group2/floating-point_SUBTRACT_FORMAT_1.out: Likewise.
* cobol.dg/group2/floating-point_SUBTRACT_FORMAT_2.out: Likewise.
*
cobol.dg/group2/IBM_dialect_COMP_redefined_by_POINTER_as_64-bit.out:
Likewise.
* cobol.dg/group2/Indicators___-D__.out: Likewise.
* cobol.dg/group2/MULTIPLY_to_FIX4.out: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_arithmetic.out: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_basic_comp-3_comp-6__1_.out:
Likewise.
* cobol.dg/group2/PACKED-DECIMAL_basic_comp-3_comp-6__2_.out:
Likewise.
* cobol.dg/group2/PACKED-DECIMAL_dump.out: Likewise.
* cobol.dg/group2/PACKED-DECIMAL_numeric_test_

Re: [committed] i386: Fix offset calculation in ix86_redzone_clobber

2025-03-27 Thread Jakub Jelinek
On Thu, Mar 27, 2025 at 09:28:31PM +0100, Uros Bizjak wrote:
> plus_constant expects integer as its third argument, not rtx.
> 
> gcc/ChangeLog:
> 
> * config/i386/i386.cc (ix86_redzone_clobber): Use integer, not rtx
> as the third argument of plus_constant.

Oops, thanks for catching this.

And guess we should improve the poly-int.h ctors so that it rejects mistakes
like this, rather than doing something really weird.

If I read it right, I think it was just casting the rtx (i.e. a pointer)
to HOST_WIDE_INT:

void poly_int<1, long int>::poly_int (struct poly_int * const this, 
struct rtx_def * const & cs#0)
{
  struct poly_int_full D.324089;
  
  [../../gcc/poly-int.h:455:1] [../../gcc/poly-int.h:455:1] *this = 
{CLOBBER(bob)};
  [../../gcc/poly-int.h:457:16] {
[../../gcc/poly-int.h:457:13] poly_int<1, long int>::poly_int 
(this, D.324089, cs#0);
  }
}
  
  
void poly_int<1, long int>::poly_int (struct poly_int * const this, 
struct poly_int_full D.289987, struct rtx_def * const & cs#0)
{
  [../../gcc/poly-int.h:470:1] [../../gcc/poly-int.h:470:1] *this = 
{CLOBBER(bob)};
  [../../gcc/poly-int.h:472:49] {
[../../gcc/poly-int.h:471:5] _1 = [../../gcc/poly-int.h:471:5] *cs#0;
[../../gcc/poly-int.h:471:5] _2 = (long int) _1;
[../../gcc/poly-int.h:471:5] [../../gcc/poly-int.h:471:5] this->coeffs[0] = 
_2;
  }
}

/* Initialize with cs... directly, casting where necessary.  */
template
template
inline constexpr
poly_int::poly_int (poly_int_full, const Cs &... cs)
  : coeffs { (typename poly_coeff_traits::
  template init_cast::type (cs))... } {}

Wonder if we shouldn't static_assert that Cs is not a pointer
somewhere or something like that (or floating point type).
I bet the intent is to support there integral types and the various
wide_int flavors.

Jakub



Re: [PATCH] RISC-V: Add pattern for vector-scalar multiply-add/sub [PR119100]

2025-03-27 Thread Robin Dapp

Hi Paul-Antoine,


This pattern enables the combine pass to merge a vec_duplicate into a plus-mult
or minus-mult RTL instruction.

Before this patch, we have two instructions, e.g.:
  vfmv.v.fv6,fa0
  vfmadd.vv   v9,v6,v7

After, we get only one:
  vfmadd.vf   v9,fa0,v7

On SPEC2017's 503.bwaves_r, depending on the workload, the reduction in dynamic
instruction count varies from -4.66% to -4.75%.


The general issue with this kind of optimization (we have discussed it a few 
times already) is that, depending on the uarch, we want the local combine 
optimization that you show but not the fwprop/late-combine one where we 
propagate a vector broadcast into a loop.


So IMHO in order to continue with this and similar patterns we need at least 
accompanying rtx_cost handling that would allow us to tune per uarch.


Pan Li sent a similar patch for vadd.vv/vadd.vx I think in November and I 
believe he intended to continue when stage 1 opens.


An outstanding question is how to distinguish the combine case from the 
late-combine case.  I haven't yet thought about that in detail.


--
Regards
Robin



Re: [PATCH] doc: document incremental LTO flags

2025-03-27 Thread Sam James
Michal Jires  writes:

> This adds missing documentation for LTO flags.
>
> Ok?
>
> gcc/ChangeLog:
>
>   * doc/invoke.texi: (Optimize Options):
>   Add incremental LTO flags.
> ---
>  gcc/doc/invoke.texi | 26 +++---
>  1 file changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 4fbb4cda101..3efc6602898 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -601,7 +601,8 @@ Objective-C and Objective-C++ Dialects}.
>  -floop-block  -floop-interchange  -floop-strip-mine
>  -floop-unroll-and-jam  -floop-nest-optimize
>  -floop-parallelize-all  -flra-remat  -flto  -flto-compression-level
> --flto-partition=@var{alg}  -fmalloc-dce -fmerge-all-constants
> +-flto-partition=@var{alg} -flto-incremental=@var{path}
> +-flto-incremental-cache-size=@var{n} -fmalloc-dce -fmerge-all-constants
>  -fmerge-constants  -fmodulo-sched  -fmodulo-sched-allow-regmoves
>  -fmove-loop-invariants  -fmove-loop-stores  -fno-branch-count-reg
>  -fno-defer-pop  -fno-fp-int-builtin-inexact  -fno-function-cse
> @@ -15086,8 +15087,10 @@ Specify the partitioning algorithm used by the 
> link-time optimizer.
>  The value is either @samp{1to1} to specify a partitioning mirroring
>  the original source files or @samp{balanced} to specify partitioning
>  into equally sized chunks (whenever possible) or @samp{max} to create
> -new partition for every symbol where possible.  Specifying @samp{none}
> -as an algorithm disables partitioning and streaming completely.
> +new partition for every symbol where possible or @samp{cache} to
> +balance chunk sizes while keeping related symbols together for better
> +caching in incremental LTO.  Specifying @samp{none} as an algorithm
> +disables partitioning and streaming completely.
>  The default value is @samp{balanced}. While @samp{1to1} can be used
>  as an workaround for various code ordering issues, the @samp{max}
>  partitioning is intended for internal testing only.
> @@ -15095,6 +15098,23 @@ The value @samp{one} specifies that exactly one 
> partition should be
>  used while the value @samp{none} bypasses partitioning and executes
>  the link-time optimization step directly from the WPA phase.
>  
> +@opindex flto-incremental
> +@item -flto-incremental=@var{path}
> +Enable incremental LTO, with its cache in given existing directory.
> +Can significantly shorten edit-compile cycles with LTO.

One thing I wasn't quite sure on yet: is -flto-partition=cache automatic
with -flto-incremental? Or is it just an optional flag I can pass for
more effective incremental LTO?

If it's the latter, should we mention that in the -flto-incremental
documentation?

> [...]

Thanks for working on incremental LTO. I had the opportunity to use it
for a bug for the first time last weekend and enjoyed it.


[PATCH v3 03/19] Add string_slice class.

2025-03-27 Thread Alfie Richards

The string_slice inherits from array_slice and is used to refer to a
substring of an array that is memory managed elsewhere without modifying
the underlying array.

For example, this is useful in cases such as when needing to refer to a
substring of an attribute in the syntax tree.

This commit also adds some minimal helper functions for string_slice,
such as a strtok alternative, equality operators, strcmp, and a function
to strip whitespace from the beginning and end of a string_slice.

gcc/c-family/ChangeLog:

* c-format.cc (local_string_slice_node): New node type.
(asm_fprintf_char_table): New entry.
(init_dynamic_diag_info): Add support for string_slice.
* c-format.h (T_STRING_SLICE): New node type.

gcc/ChangeLog:

* pretty-print.cc (format_phase_2): Add support for string_slice.
* vec.cc (string_slice::tokenize): New method.
(strcmp): New implementation for string_slice.
(string_slice::strip): New method.
(test_string_slice_initializers): New test.
(test_string_slice_tokenize): Ditto.
(test_string_slice_strcmp): Ditto.
(test_string_slice_equality): Ditto.
(test_string_slice_inequality): Ditto.
(test_string_slice_invalid): Ditto.
(test_string_slice_strip): Ditto.
(vec_cc_tests): Add new tests.
* vec.h (class string_slice): New class.
(strcmp): New implementation for string_slice.
---
 gcc/c-family/c-format.cc |   9 ++
 gcc/c-family/c-format.h  |   1 +
 gcc/pretty-print.cc  |  10 ++
 gcc/vec.cc   | 207 +++
 gcc/vec.h|  45 +
 5 files changed, 272 insertions(+)

diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 211d20dd25b..8b4447f9fdc 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -70,6 +70,7 @@ static GTY(()) tree local_event_ptr_node;
 static GTY(()) tree local_pp_element_ptr_node;
 static GTY(()) tree local_gimple_ptr_node;
 static GTY(()) tree local_cgraph_node_ptr_node;
+static GTY(()) tree local_string_slice_node;
 static GTY(()) tree locus;
 
 static bool decode_format_attr (const_tree, tree, tree, function_format_info *,
@@ -770,6 +771,7 @@ static const format_char_info asm_fprintf_char_table[] =
   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c",  NULL }, \
   { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "","//cR",   NULL }, \
   { "@",   1, STD_C89, { T_EVENT_PTR,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL }, \
+  { "B",   1, STD_C89, { T_STRING_SLICE,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q", "",   NULL }, \
   { "e",   1, STD_C89, { T_PP_ELEMENT_PTR,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"", NULL }, \
   { "<",   0, STD_C89, NOARGUMENTS, "",  "<",   NULL }, \
   { ">",   0, STD_C89, NOARGUMENTS, "",  ">",   NULL }, \
@@ -5211,6 +5213,13 @@ init_dynamic_diag_info (void)
   || local_cgraph_node_ptr_node == void_type_node)
 local_cgraph_node_ptr_node = get_named_type ("cgraph_node");
 
+  /* Similar to the above but for string_slice*.  */
+  if (!local_string_slice_node
+  || local_string_slice_node == void_type_node)
+{
+  local_string_slice_node = get_named_type ("string_slice");
+}
+
   /* Similar to the above but for diagnostic_event_id_t*.  */
   if (!local_event_ptr_node
   || local_event_ptr_node == void_type_node)
diff --git a/gcc/c-family/c-format.h b/gcc/c-family/c-format.h
index 323338cb8e7..d44d3862d83 100644
--- a/gcc/c-family/c-format.h
+++ b/gcc/c-family/c-format.h
@@ -317,6 +317,7 @@ struct format_kind_info
 #define T89_G   { STD_C89, NULL, &local_gimple_ptr_node }
 #define T_CGRAPH_NODE   { STD_C89, NULL, &local_cgraph_node_ptr_node }
 #define T_EVENT_PTR{ STD_C89, NULL, &local_event_ptr_node }
+#define T_STRING_SLICE{ STD_C89, NULL, &local_string_slice_node }
 #define T_PP_ELEMENT_PTR{ STD_C89, NULL, &local_pp_element_ptr_node }
 #define T89_T   { STD_C89, NULL, &local_tree_type_node }
 #define T89_V	{ STD_C89, NULL, T_V }
diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc
index 79c7bc2b662..280cde30adc 100644
--- a/gcc/pretty-print.cc
+++ b/gcc/pretty-print.cc
@@ -2035,6 +2035,16 @@ format_phase_2 (pretty_printer *pp,
 	pp_string (pp, va_arg (*text.m_args_ptr, const char *));
 	  break;
 
+	case 'B':
+	  {
+	string_slice s = *va_arg (*text.m_args_ptr, string_slice *);
+	if (quote)
+	  pp_quoted_string (pp, s.begin (), s.size ());
+	else
+	  pp_string_n (pp, s.begin (), s.size ());
+	break;
+	  }
+
 	case 'p':
 	  pp_pointer (pp, va_arg (*text.m_args_ptr, void *));
 	  break;
diff --git a/gcc/vec.cc b/gcc/vec.cc
index 55f

[PATCH v3 00/19] FMV refactor and ACLE compliance.

2025-03-27 Thread Alfie Richards
Hi All,

This is an update on the patch series enabling ACLE compliant FMV
behaviour for targets supporting target_version and a refactor of FMV
in the front end.

This patch series leaves much of the logic that enables FMV for x86
in place, often gated behind TARGET_HAS_FMV_TARGET_ATTRIBUTE.
I would like to refactor more of the x86/PPC logic. Possibly even
making it match ACLE behaviour/semantics in places. but want to avoid
breaking changes and regressions, and as I could not find any x86/PPC 
spec I thought best left alone for now.

The main changes between last patch series and this one are:

* Added pretty-print formatting support for string_slice.
  (I'm not sure I did this completely correctly though in
  the c-family front end?)
* Large refactor to the merging/conflicting logic in the
  C++ front end. This is because I found flaws in the previous version
  which could merge target_version decls that weren't distinct, but
  weren't mergaeble.
  * This involved a large refactor of the common_function_version
hook to take string_slices instead of decls, and moving
the target_version/target_clone distinctness/mergability
logic into shared code.
  * This has the added benefit of enabling riscv target_version/
target_clones automatically as it now uses the same shared code
which wasn't possible before the hook refactor.
  * This did also require some hacks to the riscv target parsing code
which would benefit from a more careful refactor.
* Added warning and skipping for unparsable target_clones values
  * This is part of the ACLE that I missed last time.
  * It only works properly for Aarch64 at the moment. Though I use
the hook to check parsing and emit errors for riscv as otherwise
I was breaking a lot of things.
  * Ideally this would be implemented by other targets (especially riscv
with the shared target_clones semantics) to enable some portability.

I am also working on a patch to add target_version support to the C frontend
while making it ACLE compliant, and a patch to update the
redirect_to_specific_clone logic to work properly with ACLE semantics which
will both use the work in this patch.

Reg tested and bootstrapped on x86-linux-gnu and aarch64-linux-gnu.
FMV tests ran for PowerPC and RiscV.

Kind regards,
Alfie Richards

Alfie Richards (17):
  Add string_slice class.
  Remove unnecessary `record` argument from maybe_version_functions.
  Update is_function_default_version to work with target_version.
  Change function versions to be implicitly ordered.
  Change make_attribute to take string_slice.
  Add get_clone_versions and get_version functions.
  Add assembler_name to cgraph_function_version_info.
  Add dispatcher_resolver_function and is_target_clone to cgraph_node.
  Add clone_identifier function.
  Refactor FMV name mangling.
  Refactor riscv target parsing to take string_slice.
  Add regect_target_clone hook and filter target_clone versions.
  Change target_version semantics to follow ACLE specification.
  Refactor FMV frontend hooks and logic.
  Support mixing of target_clones and target_version.
  Add error cases and tests for Aarch64 FMV.
  Remove FMV beta warning.

Andrew Carlotti (2):
  Add PowerPC FMV symbol tests.
  Add x86 FMV symbol tests

 gcc/attribs.cc| 252 +--
 gcc/attribs.h |   6 +-
 gcc/c-family/c-attribs.cc |  29 +-
 gcc/c-family/c-format.cc  |   9 +
 gcc/c-family/c-format.h   |   1 +
 gcc/cgraph.cc |  28 +-
 gcc/cgraph.h  |  20 +-
 gcc/cgraphclones.cc   |  16 +-
 gcc/cgraphunit.cc |   9 +
 gcc/config/aarch64/aarch64.cc | 247 ++
 gcc/config/aarch64/aarch64.opt|   2 +-
 gcc/config/i386/i386-features.cc  | 141 
 gcc/config/i386/i386.cc   |   3 +
 gcc/config/riscv/riscv-protos.h   |   2 +
 gcc/config/riscv/riscv-target-attr.cc |  14 +-
 gcc/config/riscv/riscv.cc | 231 ++---
 gcc/config/rs6000/rs6000.cc   | 153 ++---
 gcc/cp/call.cc|  10 +
 gcc/cp/class.cc   |  19 +-
 gcc/cp/cp-gimplify.cc |  11 +-
 gcc/cp/cp-tree.h  |   4 +-
 gcc/cp/decl.cc|  79 -
 gcc/cp/decl2.cc   |   2 +-
 gcc/cp/typeck.cc  |  10 +
 gcc/doc/invoke.texi   |   5 +-
 gcc/doc/tm.texi   |   9 +-
 gcc/doc/tm.texi.in|   2 +
 gcc/ipa.cc|  11 +
 gcc/multiple_target.cc| 304 +-
 gcc/pretty-print.cc   |  1

[PATCH v3 04/19] Remove unnecessary `record` argument from maybe_version_functions.

2025-03-27 Thread Alfie Richards

Previously, the `record` argument in maybe_version_function allowed the
call to cgraph_node::record_function_versions to be skipped.  However,
this was only skipped when both decls were already marked as versioned,
in which case we trigger the early exit in record_function_versions
instead. Therefore, the argument is unnecessary.

gcc/cp/ChangeLog:

* class.cc (add_method): Remove argument.
* cp-tree.h (maybe_version_functions): Ditto.
* decl.cc (decls_match): Ditto.
(maybe_version_functions): Ditto.
---
 gcc/cp/class.cc  | 2 +-
 gcc/cp/cp-tree.h | 2 +-
 gcc/cp/decl.cc   | 9 +++--
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index d5ae69b0fdf..df67ec34273 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -1402,7 +1402,7 @@ add_method (tree type, tree method, bool via_using)
   /* If these are versions of the same function, process and
 	 move on.  */
   if (TREE_CODE (fn) == FUNCTION_DECL
-	  && maybe_version_functions (method, fn, true))
+	  && maybe_version_functions (method, fn))
 	continue;
 
   if (DECL_INHERITED_CTOR (method))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 07500fa2b21..51fda134403 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7121,7 +7121,7 @@ extern void determine_local_discriminator	(tree, tree = NULL_TREE);
 extern bool member_like_constrained_friend_p	(tree);
 extern bool fns_correspond			(tree, tree);
 extern int decls_match(tree, tree, bool = true);
-extern bool maybe_version_functions		(tree, tree, bool);
+extern bool maybe_version_functions		(tree, tree);
 extern bool validate_constexpr_redeclaration	(tree, tree);
 extern bool merge_default_template_args		(tree, tree, bool);
 extern tree duplicate_decls			(tree, tree,
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 337ee65752e..697096f84a4 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -1216,9 +1216,7 @@ decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */)
 	  && targetm.target_option.function_versions (newdecl, olddecl))
 	{
 	  if (record_versions)
-	maybe_version_functions (newdecl, olddecl,
- (!DECL_FUNCTION_VERSIONED (newdecl)
-  || !DECL_FUNCTION_VERSIONED (olddecl)));
+	maybe_version_functions (newdecl, olddecl);
 	  return 0;
 	}
 }
@@ -1289,7 +1287,7 @@ maybe_mark_function_versioned (tree decl)
If RECORD is set to true, record function versions.  */
 
 bool
-maybe_version_functions (tree newdecl, tree olddecl, bool record)
+maybe_version_functions (tree newdecl, tree olddecl)
 {
   if (!targetm.target_option.function_versions (newdecl, olddecl))
 return false;
@@ -1312,8 +1310,7 @@ maybe_version_functions (tree newdecl, tree olddecl, bool record)
   maybe_mark_function_versioned (newdecl);
 }
 
-  if (record)
-cgraph_node::record_function_versions (olddecl, newdecl);
+  cgraph_node::record_function_versions (olddecl, newdecl);
 
   return true;
 }


[PATCH v3 11/19] Add clone_identifier function.

2025-03-27 Thread Alfie Richards

This is similar to clone_function_name and its siblings but takes an
identifier tree node rather than a function declaration.

This is to be used in conjunction with the identifier node stored in
cgraph_function_version_info::assembler_name to mangle FMV functions in
later patches.

gcc/ChangeLog:

* cgraph.h (clone_identifier): New function.
* cgraphclones.cc (clone_identifier): New function.
clone_function_name: Refactored to use clone_identifier.
---
 gcc/cgraph.h|  1 +
 gcc/cgraphclones.cc | 16 ++--
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 91e5de30f98..8dcc9315a51 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -2629,6 +2629,7 @@ tree clone_function_name (const char *name, const char *suffix,
 tree clone_function_name (tree decl, const char *suffix,
 			  unsigned long number);
 tree clone_function_name (tree decl, const char *suffix);
+tree clone_identifier (tree decl, const char *suffix);
 
 void tree_function_versioning (tree, tree, vec *,
 			   ipa_param_adjustments *,
diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 5332a433317..6b650849a63 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -557,6 +557,14 @@ clone_function_name (tree decl, const char *suffix)
   /* For consistency this needs to behave the same way as
  ASM_FORMAT_PRIVATE_NAME does, but without the final number
  suffix.  */
+  return clone_identifier (identifier, suffix);
+}
+
+/* Return a new clone of ID ending with the string SUFFIX.  */
+
+tree
+clone_identifier (tree id, const char *suffix)
+{
   char *separator = XALLOCAVEC (char, 2);
   separator[0] = symbol_table::symbol_suffix_separator ();
   separator[1] = 0;
@@ -565,15 +573,11 @@ clone_function_name (tree decl, const char *suffix)
 #else
   const char *prefix = "";
 #endif
-  char *result = ACONCAT ((prefix,
-			   IDENTIFIER_POINTER (identifier),
-			   separator,
-			   suffix,
-			   (char*)0));
+  char *result = ACONCAT (
+(prefix, IDENTIFIER_POINTER (id), separator, suffix, (char *) 0));
   return get_identifier (result);
 }
 
-
 /* Create callgraph node clone with new declaration.  The actual body will be
copied later at compilation stage.  The name of the new clone will be
constructed from the name of the original node, SUFFIX and NUM_SUFFIX.


[PATCH v3 13/19] Refactor riscv target parsing to take string_slice.

2025-03-27 Thread Alfie Richards

This is a quick refactor of the riscv target processing code
to take a string_slice rather than a decl.

The reason for this is to enable it to work with target_clones
where merging logic requires reasoning about each version string
individually in the front end.

This refactor primarily serves just to get this working. Ideally the
logic here would be further refactored as currenly there is no way to
check if a parse fails or not without emitting an error.
This makes things difficult for later patches which intends to emit a
warning and ignoring unrecognised/not parsed target_clone values rather
than erroring which can't currenly be achieved with the current riscv
code.

gcc/ChangeLog:

* config/riscv/riscv-protos.h (riscv_process_target_version_str): New 
function..
* config/riscv/riscv-target-attr.cc (riscv_process_target_attr): 
Refactor to take
string_slice.
(riscv_process_target_version_str): Ditto.
* config/riscv/riscv.cc (parse_features_for_version): Refactor to take
string_slice.
(riscv_compare_version_priority): Ditto.
(dispatch_function_versions): Change to pass location.
---
 gcc/config/riscv/riscv-protos.h   |  2 ++
 gcc/config/riscv/riscv-target-attr.cc | 14 +---
 gcc/config/riscv/riscv.cc | 50 ++-
 3 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 2bedd878a04..1efe45d63e6 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -813,6 +813,8 @@ riscv_option_valid_attribute_p (tree, tree, tree, int);
 extern bool
 riscv_option_valid_version_attribute_p (tree, tree, tree, int);
 extern bool
+riscv_process_target_version_str (string_slice, location_t);
+extern bool
 riscv_process_target_version_attr (tree, location_t);
 extern void
 riscv_override_options_internal (struct gcc_options *);
diff --git a/gcc/config/riscv/riscv-target-attr.cc b/gcc/config/riscv/riscv-target-attr.cc
index 1d968655f95..d3f06fb15d4 100644
--- a/gcc/config/riscv/riscv-target-attr.cc
+++ b/gcc/config/riscv/riscv-target-attr.cc
@@ -354,11 +354,11 @@ num_occurrences_in_str (char c, char *str)
and update the global target options space.  */
 
 bool
-riscv_process_target_attr (const char *args,
+riscv_process_target_attr (string_slice args,
 			   location_t loc,
 			   const struct riscv_attribute_info *attrs)
 {
-  size_t len = strlen (args);
+  size_t len = args.size ();
 
   /* No need to emit warning or error on empty string here, generic code already
  handle this case.  */
@@ -369,7 +369,7 @@ riscv_process_target_attr (const char *args,
 
   std::unique_ptr buf (new char[len+1]);
   char *str_to_check = buf.get ();
-  strcpy (str_to_check, args);
+  strncpy (str_to_check, args.begin (), args.size ());
 
   /* Used to catch empty spaces between semi-colons i.e.
  attribute ((target ("attr1;;attr2"))).  */
@@ -391,8 +391,7 @@ riscv_process_target_attr (const char *args,
 
   if (num_attrs != num_semicolons + 1)
 {
-  error_at (loc, "malformed % attribute",
-		args);
+  error_at (loc, "malformed % attribute", &args);
   return false;
 }
 
@@ -513,6 +512,11 @@ riscv_process_target_version_attr (tree args, location_t loc)
   return riscv_process_target_attr (str, loc, riscv_target_version_attrs);
 }
 
+bool
+riscv_process_target_version_str (string_slice str, location_t loc)
+{
+  return riscv_process_target_attr (str, loc, riscv_target_version_attrs);
+}
 
 /* Implement TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P.  This is used to
process attribute ((target_version ("..."))).  */
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index baf2ea77821..723f8c1ebce 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -13092,31 +13092,22 @@ riscv_c_mode_for_floating_type (enum tree_index ti)
   return default_mode_for_floating_type (ti);
 }
 
-/* This parses the attribute arguments to target_version in DECL and modifies
-   the feature mask and priority required to select those targets.  */
-static void
-parse_features_for_version (tree decl,
+/* This parses STR and modifies the feature mask and priority required to
+   select those targets.  */
+static bool
+parse_features_for_version (string_slice version_str,
+			location_t loc,
 			struct riscv_feature_bits &res,
 			int &priority)
 {
-  tree version_attr = lookup_attribute ("target_version",
-	DECL_ATTRIBUTES (decl));
-  if (version_attr == NULL_TREE)
+  gcc_assert (version_str.is_valid ());
+  if (version_str == "default")
 {
   res.length = 0;
   priority = 0;
-  return;
+  return true;
 }
 
-  const char *version_string = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE
-		(version_attr)));
-  gcc_assert (version_string != NULL);
-  if (strcmp (version_string, "default") == 0)
-{
-  res.length = 0;
-  priority = 0;
-  return

[PATCH v3 01/19] Add PowerPC FMV symbol tests.

2025-03-27 Thread Alfie Richards

This tests the mangling of function assembly names when annotated with
target_clones attributes.

gcc/testsuite/ChangeLog:

* g++.target/powerpc/mvc-symbols1.C: New test.
* g++.target/powerpc/mvc-symbols2.C: New test.
* g++.target/powerpc/mvc-symbols3.C: New test.
* g++.target/powerpc/mvc-symbols4.C: New test.

Co-authored-by: Alfie Richards 
---
 .../g++.target/powerpc/mvc-symbols1.C | 47 +++
 .../g++.target/powerpc/mvc-symbols2.C | 35 ++
 .../g++.target/powerpc/mvc-symbols3.C | 41 
 .../g++.target/powerpc/mvc-symbols4.C | 29 
 4 files changed, 152 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/powerpc/mvc-symbols1.C
 create mode 100644 gcc/testsuite/g++.target/powerpc/mvc-symbols2.C
 create mode 100644 gcc/testsuite/g++.target/powerpc/mvc-symbols3.C
 create mode 100644 gcc/testsuite/g++.target/powerpc/mvc-symbols4.C

diff --git a/gcc/testsuite/g++.target/powerpc/mvc-symbols1.C b/gcc/testsuite/g++.target/powerpc/mvc-symbols1.C
new file mode 100644
index 000..9424382bf14
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/mvc-symbols1.C
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target_clones("default", "cpu=power6", "cpu=power6x")))
+int foo ()
+{
+  return 1;
+}
+
+__attribute__((target_clones("cpu=power6x", "cpu=power6", "default")))
+int foo (int)
+{
+  return 2;
+}
+
+int bar()
+{
+  return foo ();
+}
+
+int bar(int x)
+{
+  return foo (x);
+}
+
+/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.cpu_power6:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.cpu_power6x:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\tbl _Z3foov\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, @gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.default\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.cpu_power6\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.cpu_power6x\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.cpu_power6:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.cpu_power6x:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\tbl _Z3fooi\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, @gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3fooi\.default\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3fooi\.cpu_power6\n" 0 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3fooi\.cpu_power6x\n" 1 } } */
diff --git a/gcc/testsuite/g++.target/powerpc/mvc-symbols2.C b/gcc/testsuite/g++.target/powerpc/mvc-symbols2.C
new file mode 100644
index 000..edf54480efd
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/mvc-symbols2.C
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target_clones("default", "cpu=power6", "cpu=power6x")))
+int foo ()
+{
+  return 1;
+}
+
+__attribute__((target_clones("cpu=power6x", "cpu=power6", "default")))
+int foo (int)
+{
+  return 2;
+}
+
+/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.cpu_power6:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.cpu_power6x:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, @gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.default\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.cpu_power6\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3foov\.cpu_power6x\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.cpu_power6:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.cpu_power6x:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, @gnu_indirect_function\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n\t\.quad\t_Z3fooi\.default\n" 1 } } */
+/* 

Re: [PATCH] Further use of mod_scope in modified_type_die

2025-03-27 Thread Tom Tromey
> "Richard" == Richard Biener  writes:

Sorry about the delay on this.

>> -  mod_type_die = subrange_type_die (type, low, high, bias, context_die);
>> +  mod_type_die = subrange_type_die (type, low, high, bias, mod_scope);

Richard> that looks good.  But why not for the ARRAY_TYPE case dircetly
Richard> above?

I think I just didn't happen to need it.

I can make this change if you think it's desirable.

>> - add_child_die_after (comp_unit_die (), mod_type_die, after_die);
>> + add_child_die_after (mod_scope, mod_type_die, after_die);

Richard> For the next DW_AT_endianity there's an assert for the correct
Richard> placement but not here So I'm not positive this change is
Richard> according to the comment.  In fact we're realing with base-type
Richard> DIEs here, and those are usually directly at comp_unit_die (),
Richard> no?

In C/C++, I think base types are normally only emitted at comp-unit
scope.

Ada (with my patches that are still in progress) may emit base types
that have a different scope.  For a type like:

package body Pck is
   type My_Other_Int is mod 2**8;

 <1><9a>: Abbrev Number: 1 (DW_TAG_base_type)
<9b>   DW_AT_byte_size   : 1
<9c>   DW_AT_encoding: 7(unsigned)
<9d>   DW_AT_name: (indirect string, offset: 0xf): pck__my_other_int

This is the "encoded" (non-hierarchical) form, which is why it's
currently a child of the CU DIE and why that "pkg__" prefix is in there.

My patches will change this to emit a DW_TAG_module named "pck" that
contains a base type named "my_other_int".

thanks,
Tom


Re: [PATCH] libstdc++: Update tzdata to 2025b

2025-03-27 Thread Tomasz Kaminski
On Thu, Mar 27, 2025 at 12:20 PM Jonathan Wakely  wrote:

> Import the new 2025b tzdata.zi file.
>
> libstdc++-v3/ChangeLog:
>
> * src/c++20/tzdata.zi: Import new file from 2025b release.
> ---
>
> A much smaller change for 2025b, and no update to the leapseconds file.
>
LGTM

>
> Tested x86-64-linux with this file installed via RPM to
> /usr/share/zoneinfo/ so that the tests use it (it's harder to test the
> embedded static data because you need to configure with a missing system
> zoneinfo config).
>
>  libstdc++-v3/src/c++20/tzdata.zi | 18 --
>  1 file changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/src/c++20/tzdata.zi
> b/libstdc++-v3/src/c++20/tzdata.zi
> index db6ba4af2b0..a7fb52f1968 100644
> --- a/libstdc++-v3/src/c++20/tzdata.zi
> +++ b/libstdc++-v3/src/c++20/tzdata.zi
> @@ -1,4 +1,4 @@
> -# version 2025a
> +# version 2025b
>  # This zic input file is in the public domain.
>  R d 1916 o - Jun 14 23s 1 S
>  R d 1916 1919 - O Su>=1 23s 0 -
> @@ -2432,6 +2432,20 @@ Z America/Ciudad_Juarez -7:5:56 - LMT 1922 Ja 1 7u
>  Z America/Costa_Rica -5:36:13 - LMT 1890
>  -5:36:13 - SJMT 1921 Ja 15
>  -6 CR C%sT
> +Z America/Coyhaique -4:48:16 - LMT 1890
> +-4:42:45 - SMT 1910 Ja 10
> +-5 - %z 1916 Jul
> +-4:42:45 - SMT 1918 S 10
> +-4 - %z 1919 Jul
> +-4:42:45 - SMT 1927 S
> +-5 x %z 1932 S
> +-4 - %z 1942 Jun
> +-5 - %z 1942 Au
> +-4 - %z 1946 Au 28 24
> +-5 1 %z 1947 Mar 31 24
> +-5 - %z 1947 May 21 23
> +-4 x %z 2025 Mar 20
> +-3 - %z
>  Z America/Cuiaba -3:44:20 - LMT 1914
>  -4 B %z 2003 S 24
>  -4 - %z 2004 O
> @@ -3420,7 +3434,7 @@ Z Asia/Tbilisi 2:59:11 - LMT 1880
>  Z Asia/Tehran 3:25:44 - LMT 1916
>  3:25:44 - TMT 1935 Jun 13
>  3:30 i %z 1977 O 20 24
> -4 i %z 1979
> +4 i %z 1978 N 10 24
>  3:30 i %z
>  Z Asia/Thimphu 5:58:36 - LMT 1947 Au 15
>  5:30 - %z 1987 O
> --
> 2.49.0
>
>


[pushed] testsuite: fix g++.dg/template/explicit-args6.C

2025-03-27 Thread Marek Polacek
Tested x86_64-pc-linux-gnu, applying to trunk.

-- >8 --
gcc/testsuite/ChangeLog:

* g++.dg/template/explicit-args6.C: Remove an extra set of {} in
a dg-message.
---
 gcc/testsuite/g++.dg/template/explicit-args6.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/template/explicit-args6.C 
b/gcc/testsuite/g++.dg/template/explicit-args6.C
index 6e8ec38d13f..18663d7bcf9 100644
--- a/gcc/testsuite/g++.dg/template/explicit-args6.C
+++ b/gcc/testsuite/g++.dg/template/explicit-args6.C
@@ -20,7 +20,7 @@ constexpr unsigned
 frob()
 {
   static_assert(N == 1, "user-friendly diagnostic"); // { dg-error 
"user-friendly" }
-  // { dg-message { "-1 == 1" "" { target *-*-* } .-1 } }
+  // { dg-message "-1 == 1" "" { target *-*-* } .-1 }
 
   // narrowing check, reject negative values
   return unsigned{N};  // { dg-prune-output "narrowing" }

base-commit: 1c5c57092cf23ac6eae139627d2406f67fe3303b
-- 
2.49.0



Re: [PATCH] testsuite: Replace the cray_pointers_2.f90 no cycling hack with dg-skip-if

2025-03-27 Thread Jakub Jelinek
On Thu, Mar 27, 2025 at 07:34:14PM +0100, Jakub Jelinek wrote:
> The following patch runs the test only in the -O3 -g case (just using -O3
> there would run it twice, once with
> -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
> -finline-functions
> and once with
> -O3 -g
> 
> The -O3 from dg-options can be dropped too.
> 
> Some tests (e.g. in testsuite/gcc.dg/torture/) use e.g.
> /* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */
> so the test is run just with -O2 by default, but when testing with
> GCC_TEST_RUN_EXPENSIVE=1 it cycles through everything.  Note, you'd need
> to drop the -O3 from dg-options in that case for sure, because with explicit
> -O3 option in there it cycles through -O0 -O3, -O1 -O3, -O2 -O3,
> -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
> -finline-functions -O3,
> -O3 -g -O3, -Os -O3.

Though, seeing 395 gfortran.dg/*.f90 tests with dg-options or
dg-additional-options including -O, perhaps better might be to hack up
the gfortran.dg/dg.exp and libgomp.fortran/fortran.exp drivers so that
they actually don't cycle through options if -O appears anywhere in
dg-options/dg-additional-options.

What do you think about that?

For gcc.dg/torture/ and g++.dg/torture/, IMHO explicit -O in
dg-options/dg-additional-options is always a bug, either the test shouldn't
be in torture subdirectory and have the explicit -O, or it shouldn't have
them and cycle through everything.

But in gfortran.dg case when the default is to cycle for all tests...

Jakub



[PATCH][gcc13] PR tree-optimization/117287 - Backport new assume implementation

2025-03-27 Thread Andrew MacLeod

This patch backports the ASSUME support that was rewritten in GCC 15.

Its slightly more complicated than the port to GCC 14 was in that a few 
classes have been rewritten. I've isolated them all to tree-assume.cc 
which contains the pass.


It has to also bring in the ssa_cache and lazy_ssa_cache from gcc14, 
along with some tweaks to those classes to deal with changes in the way 
range_allocators worked started in GCC14. Those changes are are all the 
top of the tree-assume.cc file. The rest of the file is a carbon copy of 
the GCC14 version. (well, what should be... there is an outstanding 
debug output support that was never submitted I discovered)


I'm not sure if its worth putting this in GCC13 or not, but I will 
submit it and leave it to the release managers :-)  It should be low 
risk, especially since assume was experimental support?


Bootstraps on x86_64-pc-linux-gnu with no regressions.


Andrew
From e39271c8c13b8fd5a49349000bfe8639c25cf470 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod 
Date: Thu, 27 Mar 2025 10:51:16 -0400
Subject: [PATCH 1/2] backport new assume implementation and cache.

---
 gcc/Makefile.in|   1 +
 gcc/gimple-range-fold.cc   |  13 -
 gcc/gimple-range-fold.h|  12 +
 gcc/gimple-range.cc| 189 --
 gcc/gimple-range.h |  19 -
 gcc/testsuite/g++.dg/cpp23/pr117287-attr.C |  38 ++
 gcc/tree-assume.cc | 650 +
 gcc/tree-vrp.cc|  68 ---
 8 files changed, 701 insertions(+), 289 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp23/pr117287-attr.C
 create mode 100644 gcc/tree-assume.cc

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 775aaa1b3c4..1d9e10127ca 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1633,6 +1633,7 @@ OBJS = \
ubsan.o \
sanopt.o \
sancov.o \
+   tree-assume.o \
tree-call-cdce.o \
tree-cfg.o \
tree-cfgcleanup.o \
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 180f349eda9..e2bb294624f 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -103,21 +103,8 @@ fur_source::register_relation (edge e ATTRIBUTE_UNUSED,
 {
 }
 
-// This version of fur_source will pick a range up off an edge.
-
-class fur_edge : public fur_source
-{
-public:
-  fur_edge (edge e, range_query *q = NULL);
-  virtual bool get_operand (vrange &r, tree expr) override;
-  virtual bool get_phi_operand (vrange &r, tree expr, edge e) override;
-private:
-  edge m_edge;
-};
-
 // Instantiate an edge based fur_source.
 
-inline
 fur_edge::fur_edge (edge e, range_query *q) : fur_source (q)
 {
   m_edge = e;
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index 68c6d7743e9..0a028e31be0 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -149,6 +149,18 @@ protected:
   relation_oracle *m_oracle;
 };
 
+// This version of fur_source will pick a range up off an edge.
+
+class fur_edge : public fur_source
+{
+public:
+  fur_edge (edge e, range_query *q = NULL);
+  virtual bool get_operand (vrange &r, tree expr) override;
+  virtual bool get_phi_operand (vrange &r, tree expr, edge e) override;
+private:
+  edge m_edge;
+};
+
 // This class uses ranges to fold a gimple statement producing a range for
 // the LHS.  The source of all operands is supplied via the fur_source class
 // which provides a range_query as well as a source location and any other
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index b4de8dd4ef9..e1f283c774c 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -729,192 +729,3 @@ disable_ranger (struct function *fun)
   fun->x_range_query = NULL;
 }
 
-// 
-
-// If there is a non-varying value associated with NAME, return true and the
-// range in R.
-
-bool
-assume_query::assume_range_p (vrange &r, tree name)
-{
-  if (global.get_global_range (r, name))
-return !r.varying_p ();
-  return false;
-}
-
-// Query used by GORI to pick up any known value on entry to a block.
-
-bool
-assume_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
-{
-  if (!gimple_range_ssa_p (expr))
-return get_tree_range (r, expr, stmt);
-
-  if (!global.get_global_range (r, expr))
-r.set_varying (TREE_TYPE (expr));
-  return true;
-}
-
-// If the current function returns an integral value, and has a single return
-// statement, it will calculate any SSA_NAMES it can determine ranges for
-// assuming the function returns 1.
-
-assume_query::assume_query ()
-{
-  basic_block exit_bb = EXIT_BLOCK_PTR_FOR_FN (cfun);
-  if (single_pred_p (exit_bb))
-{
-  basic_block bb = single_pred (exit_bb);
-  gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
-  if (gsi_end_p (gsi))
-   return;
-  gimple *s = gsi_stmt (gsi);
-  if (!is_a (s))
-   return;
-  greturn

[PATCH] ipa-sra: Don't change return type to void if there are musttail calls [PR119484]

2025-03-27 Thread Jakub Jelinek
Hi!

The following testcase is rejected, because IPA-SRA decides to
turn bar.constprop call into bar.constprop.isra which returns void.
While there is no explicit lhs on the call, as it is a musttail call
the tailc pass checks if IPA-VRP returns singleton from that function
and the function returns the same value and in that case it still turns
it into a tail call.  This can't work with IPA-SRA changing it into
void returning function though.

The following patch fixes this by forcing returning the original type
if there are musttail calls.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-03-27  Jakub Jelinek  

PR ipa/119484
* ipa-sra.cc (isra_analyze_call): Don't set m_return_ignored if
gimple_call_must_tail_p even if it doesn't have lhs.

* c-c++-common/pr119484.c: New test.

--- gcc/ipa-sra.cc.jj   2025-03-01 09:13:17.736075042 +0100
+++ gcc/ipa-sra.cc  2025-03-27 14:23:43.884552767 +0100
@@ -2242,7 +2242,11 @@ isra_analyze_call (cgraph_edge *cs)
  BITMAP_FREE (analyzed);
}
 }
-  else
+  /* Don't set m_return_ignored for musttail calls.  The tailc/musttail passes
+ compare the returned value against the IPA-VRP return value range if
+ it is a singleton, but if the call is changed to something which doesn't
+ return anything, it will always fail.  */
+  else if (!gimple_call_must_tail_p (call_stmt))
 csum->m_return_ignored = true;
 }
 
--- gcc/testsuite/c-c++-common/pr119484.c.jj2025-03-27 14:30:32.988976396 
+0100
+++ gcc/testsuite/c-c++-common/pr119484.c   2025-03-27 14:31:17.074375485 
+0100
@@ -0,0 +1,21 @@
+/* PR ipa/119484 */
+/* { dg-do compile { target musttail } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "bar\[.a-z0-9]* \\\(\[^\n\r]*\\\); 
\\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */
+
+void foo (int);
+
+[[gnu::noinline]] static int
+bar (int x)
+{
+  foo (x);
+  return 0;
+}
+
+int
+baz (int x)
+{
+  if (x == 1)
+[[gnu::musttail]] return bar (x);
+  return 0;
+}

Jakub



Re: [PATCH] testsuite: Replace the cray_pointers_2.f90 no cycling hack with dg-skip-if

2025-03-27 Thread Harald Anlauf

Hi Jakub, all,

Am 27.03.25 um 20:04 schrieb Jakub Jelinek:

On Thu, Mar 27, 2025 at 07:34:14PM +0100, Jakub Jelinek wrote:

The following patch runs the test only in the -O3 -g case (just using -O3
there would run it twice, once with
-O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions
and once with
-O3 -g

The -O3 from dg-options can be dropped too.

Some tests (e.g. in testsuite/gcc.dg/torture/) use e.g.
/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */
so the test is run just with -O2 by default, but when testing with
GCC_TEST_RUN_EXPENSIVE=1 it cycles through everything.  Note, you'd need
to drop the -O3 from dg-options in that case for sure, because with explicit
-O3 option in there it cycles through -O0 -O3, -O1 -O3, -O2 -O3,
-O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
-finline-functions -O3,
-O3 -g -O3, -Os -O3.


Though, seeing 395 gfortran.dg/*.f90 tests with dg-options or
dg-additional-options including -O, perhaps better might be to hack up
the gfortran.dg/dg.exp and libgomp.fortran/fortran.exp drivers so that
they actually don't cycle through options if -O appears anywhere in
dg-options/dg-additional-options.

What do you think about that?

For gcc.dg/torture/ and g++.dg/torture/, IMHO explicit -O in
dg-options/dg-additional-options is always a bug, either the test shouldn't
be in torture subdirectory and have the explicit -O, or it shouldn't have
them and cycle through everything.

But in gfortran.dg case when the default is to cycle for all tests...


I don't think we want to change the default for gfortran.dg,
at least not now.  And not in any of the subdirectories, which
I normally do not touch.

It would be great to have an easy-to-use way to run selected tests
only once, for the following reasons (just my opinion):

(1) A certain runtime test is expensive.  Here I did not know that there
is a variable GCC_TEST_RUN_EXPENSIVE, but this seems to suppress
running a certain test completely.  This may be too much, and it
appears that gfortran.dg does not yet support this.

(2) A certain runtime test actually tests the runtime *library*.
Cycling through options then provides no insight and is just a
waste of my time as voluntary developer.  The only way to cycle
here I can imagine would involve e.g. lto.

(3) ...

I like the idea of having a way to control how expensive tests
can be.  For example, several of the tests that check inline code
generation in the Fortran FE would need only a small subset of
the options being tested in regtesting, unless one really works
on that particular Frontend code in question.

It would be really helpful to have an easy-to-use way to specify
if a test should cycle over options, or just one, (or a list?).
Given that it is apparently difficult to write a simple dg-directive
correctly, more is likely less... ;-)  The dg-skip-if seems to be
very non-intuitive for the current purpose.

(And I did stumple over the two spaces in { dg-do  run } myself before.)

Cheers,
Harald


Jakub







Re: [PATCH] testsuite: Fix up strub-internal-pr112938.C test for C++2{0,3,6}

2025-03-27 Thread Alexandre Oliva
On Mar 27, 2025, Jakub Jelinek  wrote:

> Here is a fix, tested on x86_64-linux, ok for trunk?

> 2025-03-27  Jakub Jelinek  

>   * g++.dg/strub-internal-pr112938.C: Add dg-warning for c++20.

LGTM, thanks

-- 
Alexandre Oliva, happy hackerhttps://blog.lx.oliva.nom.br/
Free Software Activist FSFLA co-founder GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!


[PATCH 1/2] LoongArch: Set default alignment for functions jumps loops and labels.

2025-03-27 Thread Lulu Cheng
Based on r15-7624, a set of align combinations with better performance
was tested through spec2006.

LA464: -falign-loops=8 -falign-functions=32 -falign-jumps=32 -falign-labels=8
LA664: -falign-loops=16 -falign-functions=16 -falign-jumps=32 -falign-labels=8

gcc/ChangeLog:

* config/loongarch/loongarch-def.cc
(la464_align): Add settings for labels.
(la664_align): Likewise.
* config/loongarch/loongarch-opts.cc
(loongarch_target_option_override): Likewise.
* config/loongarch/loongarch-tune.h
(struct loongarch_align): Implement the function `label_`.

---
 gcc/config/loongarch/loongarch-def.cc  | 4 ++--
 gcc/config/loongarch/loongarch-opts.cc | 3 +++
 gcc/config/loongarch/loongarch-tune.h  | 9 -
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/gcc/config/loongarch/loongarch-def.cc 
b/gcc/config/loongarch/loongarch-def.cc
index 5f235a04ef2..04b277eb742 100644
--- a/gcc/config/loongarch/loongarch-def.cc
+++ b/gcc/config/loongarch/loongarch-def.cc
@@ -107,12 +107,12 @@ array_tune loongarch_cpu_cache =
 
 static inline loongarch_align la464_align ()
 {
-  return loongarch_align ().function_ ("32").loop_ ("16").jump_ ("16");
+  return loongarch_align ().function_ ("32").loop_ ("8").jump_ ("32").label_ 
("8");
 }
 
 static inline loongarch_align la664_align ()
 {
-  return loongarch_align ().function_ ("8").loop_ ("8").jump_ ("32");
+  return loongarch_align ().function_ ("16").loop_ ("16").jump_ ("32").label_ 
("8");
 }
 
 array_tune loongarch_cpu_align =
diff --git a/gcc/config/loongarch/loongarch-opts.cc 
b/gcc/config/loongarch/loongarch-opts.cc
index c2a63f75fc2..6e72084b9be 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -965,6 +965,9 @@ loongarch_target_option_override (struct loongarch_target 
*target,
 
   if (opts->x_flag_align_jumps && !opts->x_str_align_jumps)
opts->x_str_align_jumps = loongarch_cpu_align[target->cpu_tune].jump;
+
+  if (opts->x_flag_align_labels && !opts->x_str_align_labels)
+   opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label;
 }
 
   /* Set up parameters to be used in prefetching algorithm.  */
diff --git a/gcc/config/loongarch/loongarch-tune.h 
b/gcc/config/loongarch/loongarch-tune.h
index f7819fe7678..0ae74e77f99 100644
--- a/gcc/config/loongarch/loongarch-tune.h
+++ b/gcc/config/loongarch/loongarch-tune.h
@@ -177,8 +177,9 @@ struct loongarch_align {
   const char *function;/* default value for -falign-functions */
   const char *loop;/* default value for -falign-loops */
   const char *jump;/* default value for -falign-jumps */
+  const char *label;   /* default value for -falign-labels */
 
-  loongarch_align () : function (nullptr), loop (nullptr), jump (nullptr) {}
+  loongarch_align () : function (nullptr), loop (nullptr), jump (nullptr), 
label (nullptr) {}
 
   loongarch_align function_ (const char *_function)
   {
@@ -197,6 +198,12 @@ struct loongarch_align {
 jump = _jump;
 return *this;
   }
+
+  loongarch_align label_ (const char *_label)
+  {
+label = _label;
+return *this;
+  }
 };
 
 #endif /* LOONGARCH_TUNE_H */
-- 
2.34.1



[PATCH 2/2] LoongArch: doc: Add same-address constraint to the description of '-mld-seq-sa'.

2025-03-27 Thread Lulu Cheng
gcc/ChangeLog:

* doc/invoke.texi: Modify the description of '-mld-seq-sa'.

---
 gcc/doc/invoke.texi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b3f7f0479cc..4cdef8938dd 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -27963,8 +27963,8 @@ Use (do not use) @code{amcas[_db].@{b/h/w/d@}} 
instructions.  When build with
 @opindex mno-ld-seq-sa
 @item -mld-seq-sa
 @itemx -mno-ld-seq-sa
-Whether a load-load barrier (@code{dbar 0x700}) is needed.  When build with
-@option{-march=la664}, it is enabled by default.  The default is
+Whether a same-address load-load barrier (@code{dbar 0x700}) is needed.  When
+build with @option{-march=la664}, it is enabled by default.  The default is
 @option{-mno-ld-seq-sa}, the load-load barrier is needed.
 
 @opindex mtls-dialect
-- 
2.34.1



Re: [PATCH 1/2] libstdc++: add constexpr inplace_merge

2025-03-27 Thread Jonathan Wakely
On Sat, 15 Mar 2025 at 20:11, Giuseppe D'Angelo
 wrote:
>
> Hello,
>
> These two patches complete the implementation of P2562R1 for C++26 (the
> paper is called "constexpr Stable Sorting", but these other permutation
> algorithms are also included).
>
> You can also find them on Forgejo here:
>
> https://forge.sourceware.org/gcc/gcc-TEST/pulls/44
>
> with some additional comments/questions.

I agree that the 1-element buffer is fine for GCC 15.

> This first patch adds support for constexpr inplace_merge, which is
> relatively easy -- use if consteval to dispatch to a constexpr-friendly
> implementation.

OK for trunk, thanks.



Re: [PATCH 04/12] testsuite, aarch64: fix broken dg directives

2025-03-27 Thread Richard Earnshaw (lists)
On 26/03/2025 18:34, David Malcolm wrote:
> Found by dg-lint.
> 
> gcc/testsuite/ChangeLog:
>   * gcc.target/aarch64/atomic-inst-ldlogic.c: Add missing trailing
>   " }" for 2 dg-final directives.
>   * gcc.target/aarch64/saturating_arithmetic_1.c: Fix dg-do compile.
>   * gcc.target/aarch64/saturating_arithmetic_2.c: Likewise.
> ---
>  gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c | 4 ++--
>  gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c | 4 ++--
>  gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c | 4 ++--
>  3 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c 
> b/gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c
> index 4879d52b9b4f..ef79396151c6 100644
> --- a/gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c
> +++ b/gcc/testsuite/gcc.target/aarch64/atomic-inst-ldlogic.c
> @@ -128,7 +128,7 @@ TEST (xor_load_notreturn, XOR_LOAD_NORETURN)
>  /* { dg-final { scan-assembler-times "ldclrlh\t" 8} } */
 ^

Shouldn't there also be a space here (and all the other instances)?

But this is OK as far as it goes.

R.

>  /* { dg-final { scan-assembler-times "ldclralh\t" 16} } */
>  
> -/* { dg-final { scan-assembler-times "ldclr\t" 16} */
> +/* { dg-final { scan-assembler-times "ldclr\t" 16} } */
>  /* { dg-final { scan-assembler-times "ldclra\t" 32} } */
>  /* { dg-final { scan-assembler-times "ldclrl\t" 16} } */
>  /* { dg-final { scan-assembler-times "ldclral\t" 32} } */
> @@ -145,7 +145,7 @@ TEST (xor_load_notreturn, XOR_LOAD_NORETURN)
>  /* { dg-final { scan-assembler-times "ldeorlh\t" 8} } */
>  /* { dg-final { scan-assembler-times "ldeoralh\t" 16} } */
>  
> -/* { dg-final { scan-assembler-times "ldeor\t" 16} */
> +/* { dg-final { scan-assembler-times "ldeor\t" 16} } */
>  /* { dg-final { scan-assembler-times "ldeora\t" 32} } */
>  /* { dg-final { scan-assembler-times "ldeorl\t" 16} } */
>  /* { dg-final { scan-assembler-times "ldeoral\t" 32} } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c 
> b/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c
> index 2ac0c376d126..acd2e11f41d3 100644
> --- a/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c
> +++ b/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c
> @@ -1,4 +1,4 @@
> -/* { dg-do-compile } */
> +/* { dg-do compile } */
>  /* { dg-options "-O2 --save-temps -fno-schedule-insns2" } */
>  /* { dg-final { check-function-bodies "**" "" "" } } */
>  
> @@ -33,4 +33,4 @@
>  #define UMAX UCHAR_MAX
>  #define UMIN 0
>  
> -#include "saturating_arithmetic.inc"
> \ No newline at end of file
> +#include "saturating_arithmetic.inc"
> diff --git a/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c 
> b/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c
> index 2a55aa9f2218..86c88f8447c3 100644
> --- a/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c
> @@ -1,4 +1,4 @@
> -/* { dg-do-compile } */
> +/* { dg-do compile } */
>  /* { dg-options "-O2 --save-temps -fno-schedule-insns2" } */
>  /* { dg-final { check-function-bodies "**" "" "" } } */
>  
> @@ -33,4 +33,4 @@
>  #define UMAX USHRT_MAX
>  #define UMIN 0
>  
> -#include "saturating_arithmetic.inc"
> \ No newline at end of file
> +#include "saturating_arithmetic.inc"



Re: [PATCH 2/2] c++/modules: Handle conflicting ABI tags [PR118920]

2025-03-27 Thread Nathaniel Shead
On Thu, Mar 27, 2025 at 08:02:20AM -0400, Jason Merrill wrote:
> On 3/26/25 9:24 AM, Nathaniel Shead wrote:
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> > 
> > -- >8 --
> > 
> > The ICE in the linked PR is caused because out_ptr_t inherits an ABI tag
> > in a module that it does not in the importing module.  When we try to
> > build a qualified 'const out_ptr_t' during stream-in, we find the
> > existing 'const out_ptr_t' variant type that has been built, but discard
> > it due to having a mismatching attribute list.  This causes us to build
> > a new copy of this variant, and ultimately fail a checking assertion due
> > to this being an identical type with different TYPE_CANONICAL.
> > 
> > This patch adds checking that ABI tags between an imported and existing
> > declaration match, and errors if they are incompatible.  We make use of
> > 'equal_abi_tags' from mangle.cc to determine if we should error; in the
> > case in the PR, because the ABI tag was an implicit tag that doesn't
> > affect name mangling, we don't need to error.  To fix the ICE we ensure
> > that (regardless of whether we errored or not) later processing
> > considers the ABI tags as equivalent.
> > 
> > PR c++/118920
> > 
> > gcc/cp/ChangeLog:
> > 
> > * cp-tree.h (equal_abi_tags): Declare.
> > * mangle.cc (equal_abi_tags): Make external, fix comparison.
> > (tree_string_cmp): Make internal.
> > * module.cc (trees_in::check_abi_tags): New function.
> > (trees_in::decl_value): Use it.
> > (trees_in::is_matching_decl): Likewise.
> > 
> > @@ -1738,7 +1737,8 @@ equal_abi_tags (tree t1, tree t2)
> > if (len1 != v2->length())
> >   return false;
> > for (unsigned i = 0; i < len1; ++i)
> > -if (tree_string_cmp (v1[i], v2[i]) != 0)
> > +if (strcmp (TREE_STRING_POINTER (v1[i]),
> > +   TREE_STRING_POINTER (v2[i])) != 0)
> 
> How does this "fix" the comparison?  It looks equivalent to me.
> 
> Jason
> 

I was getting segfaults in my testcases; I think this was unfortunate
conversions to void*, and intended was 'tree_string_cmp(&v1[i], &v2[i])'.
But rather than messing around with that I elected to go with the more
obviously correct approach.

Nathaniel


  1   2   >