Re: [PATCH] PR middle-end/88345: Honor -falign-functions=N even optimized for size.

2022-10-06 Thread Palmer Dabbelt

On Thu, 06 Oct 2022 21:03:25 PDT (-0700), kito.ch...@sifive.com wrote:

From: Monk Chiang 

Currnetly setting of -falign-functions=N will be ignored if the function
is optimized for size or marked as cold function.

However function alignment requirement is needed even optimized for
size in some situations, RISC-V target is an example, RISC-V kernel implement
patchable function that require function must be align to at least 4 bytes for
atomicly patch the function prologue.

Here is 4 way to fix that:
1. Fix -falign-functions=N, let it work as expect on -Os and all cold
functions, which is this patch.
2. Force align to 4 byte if -fpatchable-function-entry is given by adjust
RISC-V's FUNCTION_BOUNDARY.
3. Adjust RISC-V's FUNCTION_BOUNDARY to let it honor to -falign-functions=N.
4. Adding a -malign-functions=N for RISC-V...which x86 already deprecated that.

And this patch is the first approach.

gcc/ChangeLog:

PR middle-end/88345
* varasm.cc (assemble_start_function): Adjust function align
even optimized for size.
* doc/invoke.texi (Os): Remove -falign-functions= from the exclusion
list of -Os.

gcc/testsuite/ChangeLog:

PR middle-end/88345
* gcc.target/i386/pr88345-1.c: New.
* gcc.target/i386/pr88345-2.c: Ditto.
* gcc.target/riscv/pr88345-1.c: Ditto.
* gcc.target/riscv/pr88345-2.c: Ditto.
---
 gcc/doc/invoke.texi| 2 +-
 gcc/testsuite/gcc.target/i386/pr88345-1.c  | 5 +
 gcc/testsuite/gcc.target/i386/pr88345-2.c  | 5 +
 gcc/testsuite/gcc.target/riscv/pr88345-1.c | 5 +
 gcc/testsuite/gcc.target/riscv/pr88345-2.c | 5 +
 gcc/varasm.cc  | 3 +--
 6 files changed, 22 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr88345-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr88345-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr88345-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr88345-2.c

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a2b0b9636f0..acf98c68825 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -11381,7 +11381,7 @@ results.  This is the default.
 Optimize for size.  @option{-Os} enables all @option{-O2} optimizations
 except those that often increase code size:

-@gccoptlist{-falign-functions  -falign-jumps @gol
+@gccoptlist{-falign-jumps @gol
 -falign-labels  -falign-loops @gol
 -fprefetch-loop-arrays  -freorder-blocks-algorithm=stc}

diff --git a/gcc/testsuite/gcc.target/i386/pr88345-1.c 
b/gcc/testsuite/gcc.target/i386/pr88345-1.c
new file mode 100644
index 000..226bb9ffc82
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr88345-1.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-falign-functions=128" } */
+/* { dg-final { scan-assembler-times "\.p2align\t7" 1 } } */
+
+__attribute__((__cold__)) void a() {}
diff --git a/gcc/testsuite/gcc.target/i386/pr88345-2.c 
b/gcc/testsuite/gcc.target/i386/pr88345-2.c
new file mode 100644
index 000..a7fc3b162dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr88345-2.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-falign-functions=128 -Os" } */
+/* { dg-final { scan-assembler-times "\.p2align\t7" 1 } } */
+
+void a() {}
diff --git a/gcc/testsuite/gcc.target/riscv/pr88345-1.c 
b/gcc/testsuite/gcc.target/riscv/pr88345-1.c
new file mode 100644
index 000..7d5afe683eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr88345-1.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-falign-functions=128" } */
+/* { dg-final { scan-assembler-times "\.align\t7" 1 } } */
+
+__attribute__((__cold__)) void a() {}
diff --git a/gcc/testsuite/gcc.target/riscv/pr88345-2.c 
b/gcc/testsuite/gcc.target/riscv/pr88345-2.c
new file mode 100644
index 000..d4fc89d86d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr88345-2.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-falign-functions=128 -Os" } */
+/* { dg-final { scan-assembler-times "\.align\t7" 1 } } */
+
+void a() {}
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 423f3f91af8..4001648b214 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -1923,8 +1923,7 @@ assemble_start_function (tree decl, const char *fnname)
  Note that we still need to align to DECL_ALIGN, as above,
  because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all.  */
   if (! DECL_USER_ALIGN (decl)
-  && align_functions.levels[0].log > align
-  && optimize_function_for_speed_p (cfun))
+  && align_functions.levels[0].log > align)
 {
 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   int align_log = align_functions.levels[0].log;


Reviewed-by: Palmer Dabbelt 

Though I'm not a global reviewer, so not sure how much that helps...


Re: [PATCH] Set discriminators for call stmts on the same line within the same basic block

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/6/22 23:50, Eugene Rozenfeld wrote:

Thank you for the review Jason.

I fixed formatting and updated the commit description:


OK.




Call statements are possible split points of a basic block so they may end up
in different basic blocks by the time pass_ipa_auto_profile executes.

This change will also simplify call site lookups since now location with 
discriminator
will uniquely identify the call site (no callee function name is needed).

This change is based on commit 1e6c4a7a8fb8e20545bb9f9032d3854f3f794c18
by Dehao Chen in vendors/google/heads/gcc-4_8.

Tested on x86_64-pc-linux-gnu.

gcc/ChangeLog:
* tree-cfg.cc (assign_discriminators): Set discriminators for call stmts
on the same line within the same basic block.
---
  gcc/tree-cfg.cc | 32 
  1 file changed, 32 insertions(+)

diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index ade66c54499..f6a465f4c91 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -1203,8 +1203,40 @@ assign_discriminators (void)
  {
edge e;
edge_iterator ei;
+  gimple_stmt_iterator gsi;
gimple *last = last_stmt (bb);
location_t locus = last ? gimple_location (last) : UNKNOWN_LOCATION;
+  location_t curr_locus = UNKNOWN_LOCATION;
+  int curr_discr = 0;
+
+  /* Traverse the basic block, if two function calls within a basic block
+   are mapped to the same line, assign a new discriminator because a call
+   stmt could be a split point of a basic block.  */
+  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next ())
+   {
+ gimple *stmt = gsi_stmt (gsi);
+ expanded_location curr_locus_e;
+ if (curr_locus == UNKNOWN_LOCATION)
+   {
+ curr_locus = gimple_location (stmt);
+ curr_locus_e = expand_location (curr_locus);
+   }
+ else if (!same_line_p (curr_locus, _locus_e, gimple_location 
(stmt)))
+   {
+ curr_locus = gimple_location (stmt);
+ curr_locus_e = expand_location (curr_locus);
+ curr_discr = 0;
+   }
+ else if (curr_discr != 0)
+   {
+ location_t loc = gimple_location (stmt);
+ location_t dloc = location_with_discriminator (loc, curr_discr);
+ gimple_set_location (stmt, dloc);
+   }
+ /* Allocate a new discriminator for CALL stmt.  */
+ if (gimple_code (stmt) == GIMPLE_CALL)
+   curr_discr = next_discriminator_for_locus (curr_locus);
+   }
  
if (locus == UNKNOWN_LOCATION)

continue;




[PATCH] PR middle-end/88345: Honor -falign-functions=N even optimized for size.

2022-10-06 Thread Kito Cheng
From: Monk Chiang 

Currnetly setting of -falign-functions=N will be ignored if the function
is optimized for size or marked as cold function.

However function alignment requirement is needed even optimized for
size in some situations, RISC-V target is an example, RISC-V kernel implement
patchable function that require function must be align to at least 4 bytes for
atomicly patch the function prologue.

Here is 4 way to fix that:
1. Fix -falign-functions=N, let it work as expect on -Os and all cold
functions, which is this patch.
2. Force align to 4 byte if -fpatchable-function-entry is given by adjust
RISC-V's FUNCTION_BOUNDARY.
3. Adjust RISC-V's FUNCTION_BOUNDARY to let it honor to -falign-functions=N.
4. Adding a -malign-functions=N for RISC-V...which x86 already deprecated that.

And this patch is the first approach.

gcc/ChangeLog:

PR middle-end/88345
* varasm.cc (assemble_start_function): Adjust function align
even optimized for size.
* doc/invoke.texi (Os): Remove -falign-functions= from the exclusion
list of -Os.

gcc/testsuite/ChangeLog:

PR middle-end/88345
* gcc.target/i386/pr88345-1.c: New.
* gcc.target/i386/pr88345-2.c: Ditto.
* gcc.target/riscv/pr88345-1.c: Ditto.
* gcc.target/riscv/pr88345-2.c: Ditto.
---
 gcc/doc/invoke.texi| 2 +-
 gcc/testsuite/gcc.target/i386/pr88345-1.c  | 5 +
 gcc/testsuite/gcc.target/i386/pr88345-2.c  | 5 +
 gcc/testsuite/gcc.target/riscv/pr88345-1.c | 5 +
 gcc/testsuite/gcc.target/riscv/pr88345-2.c | 5 +
 gcc/varasm.cc  | 3 +--
 6 files changed, 22 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr88345-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr88345-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr88345-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr88345-2.c

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a2b0b9636f0..acf98c68825 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -11381,7 +11381,7 @@ results.  This is the default.
 Optimize for size.  @option{-Os} enables all @option{-O2} optimizations 
 except those that often increase code size:
 
-@gccoptlist{-falign-functions  -falign-jumps @gol
+@gccoptlist{-falign-jumps @gol
 -falign-labels  -falign-loops @gol
 -fprefetch-loop-arrays  -freorder-blocks-algorithm=stc}
 
diff --git a/gcc/testsuite/gcc.target/i386/pr88345-1.c 
b/gcc/testsuite/gcc.target/i386/pr88345-1.c
new file mode 100644
index 000..226bb9ffc82
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr88345-1.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-falign-functions=128" } */
+/* { dg-final { scan-assembler-times "\.p2align\t7" 1 } } */
+
+__attribute__((__cold__)) void a() {}
diff --git a/gcc/testsuite/gcc.target/i386/pr88345-2.c 
b/gcc/testsuite/gcc.target/i386/pr88345-2.c
new file mode 100644
index 000..a7fc3b162dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr88345-2.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-falign-functions=128 -Os" } */
+/* { dg-final { scan-assembler-times "\.p2align\t7" 1 } } */
+
+void a() {}
diff --git a/gcc/testsuite/gcc.target/riscv/pr88345-1.c 
b/gcc/testsuite/gcc.target/riscv/pr88345-1.c
new file mode 100644
index 000..7d5afe683eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr88345-1.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-falign-functions=128" } */
+/* { dg-final { scan-assembler-times "\.align\t7" 1 } } */
+
+__attribute__((__cold__)) void a() {}
diff --git a/gcc/testsuite/gcc.target/riscv/pr88345-2.c 
b/gcc/testsuite/gcc.target/riscv/pr88345-2.c
new file mode 100644
index 000..d4fc89d86d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr88345-2.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-falign-functions=128 -Os" } */
+/* { dg-final { scan-assembler-times "\.align\t7" 1 } } */
+
+void a() {}
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 423f3f91af8..4001648b214 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -1923,8 +1923,7 @@ assemble_start_function (tree decl, const char *fnname)
  Note that we still need to align to DECL_ALIGN, as above,
  because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all.  */
   if (! DECL_USER_ALIGN (decl)
-  && align_functions.levels[0].log > align
-  && optimize_function_for_speed_p (cfun))
+  && align_functions.levels[0].log > align)
 {
 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   int align_log = align_functions.levels[0].log;
-- 
2.37.2



Re: [PATCH] Set discriminators for call stmts on the same line within the same basic block

2022-10-06 Thread Eugene Rozenfeld via Gcc-patches
Thank you for the review Jason.

I fixed formatting and updated the commit description:


Call statements are possible split points of a basic block so they may end up
in different basic blocks by the time pass_ipa_auto_profile executes.

This change will also simplify call site lookups since now location with 
discriminator
will uniquely identify the call site (no callee function name is needed).

This change is based on commit 1e6c4a7a8fb8e20545bb9f9032d3854f3f794c18
by Dehao Chen in vendors/google/heads/gcc-4_8.

Tested on x86_64-pc-linux-gnu.

gcc/ChangeLog:
* tree-cfg.cc (assign_discriminators): Set discriminators for call stmts
on the same line within the same basic block.
---
 gcc/tree-cfg.cc | 32 
 1 file changed, 32 insertions(+)

diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index ade66c54499..f6a465f4c91 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -1203,8 +1203,40 @@ assign_discriminators (void)
 {
   edge e;
   edge_iterator ei;
+  gimple_stmt_iterator gsi;
   gimple *last = last_stmt (bb);
   location_t locus = last ? gimple_location (last) : UNKNOWN_LOCATION;
+  location_t curr_locus = UNKNOWN_LOCATION;
+  int curr_discr = 0;
+
+  /* Traverse the basic block, if two function calls within a basic block
+   are mapped to the same line, assign a new discriminator because a call
+   stmt could be a split point of a basic block.  */
+  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next ())
+   {
+ gimple *stmt = gsi_stmt (gsi);
+ expanded_location curr_locus_e;
+ if (curr_locus == UNKNOWN_LOCATION)
+   {
+ curr_locus = gimple_location (stmt);
+ curr_locus_e = expand_location (curr_locus);
+   }
+ else if (!same_line_p (curr_locus, _locus_e, gimple_location 
(stmt)))
+   {
+ curr_locus = gimple_location (stmt);
+ curr_locus_e = expand_location (curr_locus);
+ curr_discr = 0;
+   }
+ else if (curr_discr != 0)
+   {
+ location_t loc = gimple_location (stmt);
+ location_t dloc = location_with_discriminator (loc, curr_discr);
+ gimple_set_location (stmt, dloc);
+   }
+ /* Allocate a new discriminator for CALL stmt.  */
+ if (gimple_code (stmt) == GIMPLE_CALL)
+   curr_discr = next_discriminator_for_locus (curr_locus);
+   }
 
   if (locus == UNKNOWN_LOCATION)
continue;
-- 
2.25.1

-Original Message-
From: Jason Merrill  
Sent: Tuesday, October 04, 2022 3:21 PM
To: Eugene Rozenfeld ; gcc-patches@gcc.gnu.org
Subject: [EXTERNAL] Re: [PATCH] Set discriminators for call stmts on the same 
line within the same basic block

On 10/3/22 02:08, Eugene Rozenfeld wrote:
> This change is based on commit 
> 1e6c4a7a8fb8e20545bb9f9032d3854f3f794c18
> by Dehao Chen in vendors/google/heads/gcc-4_8.
> 
> Tested on x86_64-pc-linux-gnu.

Brief rationale for the change?

> gcc/ChangeLog:
>  * tree-cfg.cc (assign_discriminators): Set discriminators for call 
> stmts
>  on the same line within the same basic block.
> ---
>   gcc/tree-cfg.cc | 31 +++
>   1 file changed, 31 insertions(+)
> 
> diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 
> ade66c54499..8e2a3a5f6c6 100644
> --- a/gcc/tree-cfg.cc
> +++ b/gcc/tree-cfg.cc
> @@ -1203,8 +1203,39 @@ assign_discriminators (void)
>   {
> edge e;
> edge_iterator ei;
> +  gimple_stmt_iterator gsi;
> gimple *last = last_stmt (bb);
> location_t locus = last ? gimple_location (last) : 
> UNKNOWN_LOCATION;
> +  location_t curr_locus = UNKNOWN_LOCATION;
> +  int curr_discr = 0;
> +
> +  /* Traverse the basic block, if two function calls within a basic block
> +   are mapped to the same line, assign a new discriminator because a call
> +   stmt could be a split point of a basic block.  */
> +  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next ())
> +   {
> + gimple *stmt = gsi_stmt (gsi);
> + expanded_location curr_locus_e;
> + if (curr_locus == UNKNOWN_LOCATION)
> +   {
> + curr_locus = gimple_location (stmt);
> + curr_locus_e = expand_location (curr_locus);
> +   }
> + else if (!same_line_p (curr_locus, _locus_e, gimple_location 
> (stmt)))
> +   {
> + curr_locus = gimple_location (stmt);
> + curr_locus_e = expand_location (curr_locus);
> + curr_discr = 0;
> +   }
> + else if (curr_discr != 0)
> +   {
> + gimple_set_location (stmt, location_with_discriminator (
> + gimple_location (stmt), curr_discr));

This indentation is wonky, with an open paren at the end of the line; I'd 
suggest reformatting to

>  location_t dloc 

Go patch committed: better argument checking for builtins

2022-10-06 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend by Than McIntosh does some better
argument type checking for some builtin functions.  This avoids a
compiler crash on cases like panic(panic("bad")).  This fixes
https://go.dev/issue/56071.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
05c581aef882b3a6369acde2d37a437ef144705c
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 4793c821eba..10ed3fee67c 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-8f1a91aeff400d572857895b7f5e863ec5a4d93e
+50707b4b51266166ce9bcf9de187e35760ec50f9
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 2492d9fe735..247ae1bba34 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -10316,7 +10316,12 @@ Builtin_call_expression::do_check_types(Gogo*)
 case BUILTIN_PANIC:
 case BUILTIN_SIZEOF:
 case BUILTIN_ALIGNOF:
-  this->check_one_arg();
+  if (this->check_one_arg())
+{
+ Expression* arg = this->one_arg();
+ if (arg->type()->is_void_type())
+   this->report_error(_("argument to builtin has void type"));
+}
   break;
 
 case BUILTIN_RECOVER:


[PATCH v3] c-family: ICE with [[gnu::nocf_check]] [PR106937]

2022-10-06 Thread Marek Polacek via Gcc-patches
On Thu, Oct 06, 2022 at 05:42:41PM -0400, Jason Merrill wrote:
> On 10/4/22 19:06, Marek Polacek wrote:
> > On Fri, Sep 30, 2022 at 09:12:24AM -0400, Jason Merrill wrote:
> > > On 9/29/22 18:49, Marek Polacek wrote:
> > > > When getting the name of an attribute, we ought to use
> > > > get_attribute_name, which handles both [[ ]] and __attribute__(())
> > > > forms.  Failure to do so may result in an ICE, like here.
> > > > 
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > 
> > > How do we print the attributes with this patch?  Don't we also want to 
> > > print
> > > the namespace, and use [[]] in the output?
> > 
> > Good point, however: while the testcase indeed has an attribute
> > in the [[]] form in the typedef, here we're printing its "aka":
> > 
> > warning: initialization of 'FuncPointerWithNoCfCheck' {aka 'void 
> > (__attribute__((nocf_check)) *)(void)'} from incompatible pointer type 
> > 'FuncPointer' {aka 'void (*)(void)'}
> > 
> > c-pretty-print.cc doesn't seem to know how to print an [[]] attribute.
> > I could do that, but then we'd print
> > 
> >aka 'void ([[nocf_check]] *)(void)'
> > 
> > in the above, but that's invalid syntax!
> 
> Indeed, it should be
> 
> void (* [[gnu::nocf_check]])(void)

Ok, let me fix that too, then.  I've updated the description to show
what we print with the patch, and what was printed before.

And I also noticed another thing: type_hash_canon_hash hashes only
get_attribute_name, so build_type_attribute_qual_variant will use the
same function_type tree for these two pointers:

__attribute__((nocf_check)) typedef void (*fp1)();
[[gnu::nocf_check]] typedef void (*fp2)();

so if gcc prints a diagnostic with fp2, it will show the GNU form of
the attribute, because the already existing type of fp1 will be used!
I'm not addressing it here, just an oddity I discovered.


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

-- >8 --
When getting the name of an attribute, we ought to use
get_attribute_name, which handles both [[]] and __attribute__(())
forms.  Failure to do so may result in an ICE, like here.

pp_c_attributes_display wasn't able to print the [[]] form of
attributes, so this patch teaches it to.

When printing a pointer to function with an attribute, the attribute
should be printed after the *, because that's what it appertains to.
With this patch we print:

  aka 'void (*__attribute__((nocf_check)))()'
  aka 'void (*[[gnu::nocf_check]])()'

rather than

  aka 'void (__attribute__((nocf_check)) *)()

or crashing in the second case.

pp_c_attributes has been unused since its introduction in r56273 so
this patch removes it.

PR c++/106937

gcc/c-family/ChangeLog:

* c-pretty-print.cc (pp_c_specifier_qualifier_list): When
printing a pointer to function with an attribute, print the
attribute after the *.
(pp_c_attributes): Remove.
(pp_c_attributes_display): Print the [[]] form if appropriate.
Use get_attribute_name.  Don't print a trailing space.
* c-pretty-print.h (pp_c_attributes): Remove.

gcc/cp/ChangeLog:

* error.cc (dump_type_prefix): When printing a pointer/reference to
function with an attribute, print the attribute after the */&.

gcc/testsuite/ChangeLog:

* g++.dg/diagnostic/aka5a.C: Adjust.
* g++.dg/diagnostic/aka5b.C: Likewise.
* gcc.dg/diag-aka-5a.c: Likewise.
* gcc.dg/diag-aka-5b.c: Likewise.
* c-c++-common/pointer-to-fn1.c: New test.
---
 gcc/c-family/c-pretty-print.cc  | 92 +++--
 gcc/c-family/c-pretty-print.h   |  1 -
 gcc/cp/error.cc |  4 +-
 gcc/testsuite/c-c++-common/pointer-to-fn1.c | 18 
 gcc/testsuite/g++.dg/diagnostic/aka5a.C |  8 +-
 gcc/testsuite/g++.dg/diagnostic/aka5b.C |  9 +-
 gcc/testsuite/gcc.dg/diag-aka-5a.c  |  8 +-
 gcc/testsuite/gcc.dg/diag-aka-5b.c  |  8 +-
 8 files changed, 84 insertions(+), 64 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/pointer-to-fn1.c

diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc
index efa1768f4d6..2523939cffb 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -466,11 +466,16 @@ pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree 
t)
  {
pp_c_whitespace (pp);
pp_c_left_paren (pp);
+   pp_ptr_operator (pp, t);
pp_c_attributes_display (pp, TYPE_ATTRIBUTES (pointee));
  }
-   else if (!c_dialect_cxx ())
- pp_c_whitespace (pp);
-   pp_ptr_operator (pp, t);
+   else
+ {
+   /* Removing this WS inconsistency breaks too many tests.  */
+   if (!c_dialect_cxx ())
+ pp_c_whitespace (pp);
+   pp_ptr_operator (pp, t);
+ }
   }
   break;
 
@@ -850,32 +855,7 @@ c_pretty_printer::declaration (tree t)
   pp_c_init_declarator (this, t);
 }
 

Re: [PATCH RFC] c++: fix broken conversion in coroutines

2022-10-06 Thread Iain Sandoe



> On 6 Oct 2022, at 22:44, Jason Merrill  wrote:
> 
> On 10/3/22 23:53, Jason Merrill wrote:
>> On 9/30/22 18:50, Iain Sandoe wrote:
>>> Hi Jason,
>>> 
 On 30 Sep 2022, at 23:06, Jason Merrill  wrote:
 
 You can't use CONVERT_EXPR to convert between two class types, and it was
 breaking copy elision.
 
 Unfortunately, this patch breaks symmetric-transfer-00-basic.C, where
 susp_type is Loopy::handle_type.  How is this supposed to work?
>>> 
>>> We are trying to save a type-erased handle (which the symmetric transfer 
>>> makes
>>> and indirect call through, nothing else).
>> The problem is you're treating one class directly as another class here, 
>> without the indirection involved in usual type-erasure idioms.
>> It does seem that the gimplifier handles this fine, but it doesn't 
>> correspond to anything in the language and much of the front end assumes 
>> that CONVERT_EXPR is only used for scalars.  VIEW_CONVERT_EXPR would better 
>> express that we're not doing anything to the value, just cheating the type 
>> system.  That's still dodgy from a language perspective, but probably safe 
>> enough in this case.
> 
> So I'm applying this:<0001-c-fix-broken-conversion-in-coroutines.patch>

thanks, I have not had any cycles to look at this.

however, when I next do - was planning on looking at the:
cont = handle.from_address(await_suspend().address())
approach, since both .address() and .from_address() are constexpr, 
cp_fold_function should turn that into essentially a NOP.
Iain




[committed] libgcc, arc: Fix build

2022-10-06 Thread Jakub Jelinek via Gcc-patches
Hi!

On Thu, Oct 06, 2022 at 10:05:29PM +, Joseph Myers wrote:
> I'm seeing the following build failure for arc-linux-gnu after this 
> commit.  (Note that this is for building GCC *after* glibc, not for an 
> initial inhibit_libc bootstrap build of GCC.)
> 
> In file included from 
> /scratch/jmyers/glibc-bot/src/gcc/libgcc/unwind-dw2.c:413:
> ./md-unwind-support.h: In function 'arc_fallback_frame_state':
> ./md-unwind-support.h:103:10: warning: assignment to 'struct sigcontext *' 
> from incompatible pointer type 'mcontext_t *' [-Wincompatible-pointer-types]
>   103 |   sc = _->uc.uc_mcontext;
>   |  ^
> ./md-unwind-support.h:118:45: error: 'struct ' has no member named 
> 'how'
>   118 |   fs->regs.reg[register_id_for_index[i]].how = REG_SAVED_OFFSET;
>   | ^
> /scratch/jmyers/glibc-bot/src/gcc/libgcc/shared-object.mk:14: recipe for 
> target 'unwind-dw2.o' failed
> 
> https://sourceware.org/pipermail/libc-testresults/2022q4/010333.html

Oops, sorry.
Missed one spot in the r13-3108-g146e45914032 change (my sed script
didn't expect nested []s).

Committed to trunk as obvious.

2022-10-07  Jakub Jelinek  

* config/arc/linux-unwind.h (arc_fallback_frame_state): Use
fs->regs.how[X] instead of fs->regs.reg[X].how.

--- libgcc/config/arc/linux-unwind.h.jj 2022-10-06 11:04:33.254058274 +0200
+++ libgcc/config/arc/linux-unwind.h2022-10-07 00:10:24.353464043 +0200
@@ -115,7 +115,7 @@ arc_fallback_frame_state (struct _Unwind
 {
   if (register_id_for_index[i] == -1)
continue;
-  fs->regs.reg[register_id_for_index[i]].how = REG_SAVED_OFFSET;
+  fs->regs.how[register_id_for_index[i]] = REG_SAVED_OFFSET;
   fs->regs.reg[register_id_for_index[i]].loc.offset
= ((_Unwind_Ptr) &(regs[i])) - new_cfa;
 }


Jakub



Re: Patch ping (Re: [PATCH] libgcc: Decrease size of _Unwind_FrameState and even more size of cleared area in uw_frame_state_for)

2022-10-06 Thread Joseph Myers
I'm seeing the following build failure for arc-linux-gnu after this 
commit.  (Note that this is for building GCC *after* glibc, not for an 
initial inhibit_libc bootstrap build of GCC.)

In file included from 
/scratch/jmyers/glibc-bot/src/gcc/libgcc/unwind-dw2.c:413:
./md-unwind-support.h: In function 'arc_fallback_frame_state':
./md-unwind-support.h:103:10: warning: assignment to 'struct sigcontext *' from 
incompatible pointer type 'mcontext_t *' [-Wincompatible-pointer-types]
  103 |   sc = _->uc.uc_mcontext;
  |  ^
./md-unwind-support.h:118:45: error: 'struct ' has no member named 
'how'
  118 |   fs->regs.reg[register_id_for_index[i]].how = REG_SAVED_OFFSET;
  | ^
/scratch/jmyers/glibc-bot/src/gcc/libgcc/shared-object.mk:14: recipe for target 
'unwind-dw2.o' failed

https://sourceware.org/pipermail/libc-testresults/2022q4/010333.html

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH v3] c++: fixes for derived-to-base reference binding [PR107085]

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/6/22 17:43, Marek Polacek wrote:

On Thu, Oct 06, 2022 at 02:00:40PM -0400, Jason Merrill wrote:

On 10/6/22 13:51, Marek Polacek wrote:

On Thu, Oct 06, 2022 at 10:58:44AM -0400, Jason Merrill wrote:

On 10/6/22 10:49, Marek Polacek wrote:

On Wed, Oct 05, 2022 at 08:25:29PM -0400, Jason Merrill wrote:

On 10/5/22 17:27, Marek Polacek wrote:

This PR reports that

  struct Base {};
  struct Derived : Base {};
  static_assert(__reference_constructs_from_temporary(Base const&, 
Derived));

doesn't pass, which it should: it's just like

  const Base& b(Derived{});

where we bind 'b' to the Base subobject of a temporary object of type
Derived.  The ck_base conversion didn't have ->need_temporary_p set because
we didn't need to create a temporary object just for the base, but the whole
object is a temporary so we're still binding to a temporary.  Fixed by
the conv_is_prvalue hunk.

That broke a bunch of tests.  I've distilled the issue into a simple test
in elision4.C.  Essentially, we have

  struct B { /* ... */ };
  struct D : B { };
  B b = D();

and we set force_elide in build_over_call, but we're unable to actually
elide the B::B(B&&) call, and crash on gcc_assert (!force_elide);.

 says that copy
elision "can only apply when the object being initialized is known not to be
a potentially-overlapping subobject".  So I suppose we shouldn't force_elide
the B::B(B&&) call.  I don't belive the CWG 2327 code was added to handle
derived-to-base conversions, at that time conv_binds_ref_to_prvalue wasn't
checking ck_base at all.

Does that make sense?  If so...

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

PR c++/107085

gcc/cp/ChangeLog:

* call.cc (conv_is_prvalue): Return true if the base subobject is part
of a temporary object.


No, the base subobject of a prvalue is an xvalue.


Ah, so this is just like T().m where T() is a prvalue but the whole thing
is an xvalue.  Duly noted.


Exactly.


I think the problem is that an expression being a prvalue is a subset of
binding a reference to a temporary, and we shouldn't try to express both of
those using the same function: you need a separate
conv_binds_ref_to_temporary.


Ack, so how about this?  Thanks,

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

-- >8 --
This PR reports that

 struct Base {};
 struct Derived : Base {};
 static_assert(__reference_constructs_from_temporary(Base const&, Derived));

doesn't pass, which it should: it's just like

 const Base& b(Derived{});

where we bind 'b' to the Base subobject of a temporary object of type
Derived.  The ck_base conversion didn't have ->need_temporary_p set because
we didn't need to create a temporary object just for the base, but the whole
object is a temporary so we're still binding to a temporary.  Since the
Base subobject is an xvalue, a new function is introduced.

PR c++/107085

gcc/cp/ChangeLog:

* call.cc (conv_binds_ref_to_temporary): New.
(ref_conv_binds_directly): Use it.

gcc/testsuite/ChangeLog:

* g++.dg/ext/reference_constructs_from_temporary1.C: Adjust expected
result.
* g++.dg/ext/reference_converts_from_temporary1.C: Likewise.
* g++.dg/cpp0x/elision4.C: New test.
---
gcc/cp/call.cc| 23 ++-
gcc/testsuite/g++.dg/cpp0x/elision4.C | 15 
.../reference_constructs_from_temporary1.C|  2 +-
.../ext/reference_converts_from_temporary1.C  |  2 +-
4 files changed, 39 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision4.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index bd04a1d309a..715a83f5a69 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9210,6 +9210,27 @@ conv_binds_ref_to_prvalue (conversion *c)
  return conv_is_prvalue (next_conversion (c));
}
+/* True iff C is a conversion that binds a reference to a temporary.
+   This is a superset of conv_binds_ref_to_prvalue: here we're also
+   interested in xvalues.  */
+
+static bool
+conv_binds_ref_to_temporary (conversion *c)
+{
+  if (conv_binds_ref_to_prvalue (c))
+return true;
+  if (c->kind != ck_ref_bind)
+return false;
+  c = next_conversion (c);
+  /* This is the case for
+   struct Base {};
+   struct Derived : Base {};
+   const Base& b(Derived{});
+ where we bind 'b' to the Base subobject of a temporary object of type
+ Derived.  The subobject is an xvalue; the whole object is a prvalue.  */
+  return (c->kind == ck_base && conv_is_prvalue (next_conversion (c)));


I think you also want to check for the case of c->u.expr being a
COMPONENT_REF/ARRAY_REF around a TARGET_EXPR, as you mentioned.


I see.  So this would be achieved using e.g.

struct B { };
struct D : B { };
struct C {
D d;
};

const B& b = C{}.d;


Yes.


Except I'm not sure how to trigger this 

Re: [PATCH RFC] c++: fix broken conversion in coroutines

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/3/22 23:53, Jason Merrill wrote:

On 9/30/22 18:50, Iain Sandoe wrote:

Hi Jason,


On 30 Sep 2022, at 23:06, Jason Merrill  wrote:

You can't use CONVERT_EXPR to convert between two class types, and it 
was

breaking copy elision.

Unfortunately, this patch breaks symmetric-transfer-00-basic.C, where
susp_type is Loopy::handle_type.  How is this supposed to work?


We are trying to save a type-erased handle (which the symmetric 
transfer makes

and indirect call through, nothing else).


The problem is you're treating one class directly as another class here, 
without the indirection involved in usual type-erasure idioms.


It does seem that the gimplifier handles this fine, but it doesn't 
correspond to anything in the language and much of the front end assumes 
that CONVERT_EXPR is only used for scalars.  VIEW_CONVERT_EXPR would 
better express that we're not doing anything to the value, just cheating 
the type system.  That's still dodgy from a language perspective, but 
probably safe enough in this case.


So I'm applying this:From 0cd9dafcfa8cf69b3a1eae91bea82d388c5328d2 Mon Sep 17 00:00:00 2001
From: Jason Merrill 
Date: Fri, 30 Sep 2022 10:04:22 -0400
Subject: [PATCH] c++: fix broken conversion in coroutines
To: gcc-patches@gcc.gnu.org

You can't use CONVERT_EXPR to convert between two class types.

VIEW_CONVERT_EXPR takes liberties with the C++ type system, but is probably
safe in this context.  Let's also only use it when the type isn't already
what we want.

gcc/cp/ChangeLog:

	* coroutines.cc (expand_one_await_expression): Change conversion
	to VIEW_CONVERT_EXPR.
	* cp-gimplify.cc (cp_genericize_r) [CONVERT_EXPR]: Add assert.
---
 gcc/cp/coroutines.cc  | 5 -
 gcc/cp/cp-gimplify.cc | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index eca01abcb7a..60b846600b9 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1728,7 +1728,10 @@ expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
 }
   else
 {
-  r = build1_loc (loc, CONVERT_EXPR, void_coro_handle_type, suspend);
+  r = suspend;
+  if (!same_type_ignoring_top_level_qualifiers_p (susp_type,
+		  void_coro_handle_type))
+	r = build1_loc (loc, VIEW_CONVERT_EXPR, void_coro_handle_type, r);
   r = build2_loc (loc, INIT_EXPR, void_coro_handle_type, data->conthand, r);
   r = build1 (CONVERT_EXPR, void_type_node, r);
   append_to_statement_list (r, _list);
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index b4599fc34d8..5d26e59d098 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1589,6 +1589,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
   break;
 
 case CONVERT_EXPR:
+  gcc_checking_assert (!AGGREGATE_TYPE_P (TREE_TYPE (stmt)));
   gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
   break;
 
-- 
2.31.1



Re: [PATCH] Add __builtin_iseqsig()

2022-10-06 Thread Joseph Myers
My reading of the bug given as a reason for not testing that FE_INVALID is 
raised for (both quiet and signaling) NaN arguments is that it's 
specifically about constant arguments.  That is, it ought to be possible 
to have a testcase that verifies FE_INVALID is raised when appropriate 
(and not when inappropriate) provided the arguments come from volatile 
variables rather than directly from constants.  (There would still need to 
be a powerpc*-*-* XFAIL referencing bug 58684.)  Only a test for constant 
arguments would need to wait on a fix for bug 106805.

-- 
Joseph S. Myers
jos...@codesourcery.com


[PATCH v3] c++: fixes for derived-to-base reference binding [PR107085]

2022-10-06 Thread Marek Polacek via Gcc-patches
On Thu, Oct 06, 2022 at 02:00:40PM -0400, Jason Merrill wrote:
> On 10/6/22 13:51, Marek Polacek wrote:
> > On Thu, Oct 06, 2022 at 10:58:44AM -0400, Jason Merrill wrote:
> > > On 10/6/22 10:49, Marek Polacek wrote:
> > > > On Wed, Oct 05, 2022 at 08:25:29PM -0400, Jason Merrill wrote:
> > > > > On 10/5/22 17:27, Marek Polacek wrote:
> > > > > > This PR reports that
> > > > > > 
> > > > > >  struct Base {};
> > > > > >  struct Derived : Base {};
> > > > > >  static_assert(__reference_constructs_from_temporary(Base 
> > > > > > const&, Derived));
> > > > > > 
> > > > > > doesn't pass, which it should: it's just like
> > > > > > 
> > > > > >  const Base& b(Derived{});
> > > > > > 
> > > > > > where we bind 'b' to the Base subobject of a temporary object of 
> > > > > > type
> > > > > > Derived.  The ck_base conversion didn't have ->need_temporary_p set 
> > > > > > because
> > > > > > we didn't need to create a temporary object just for the base, but 
> > > > > > the whole
> > > > > > object is a temporary so we're still binding to a temporary.  Fixed 
> > > > > > by
> > > > > > the conv_is_prvalue hunk.
> > > > > > 
> > > > > > That broke a bunch of tests.  I've distilled the issue into a 
> > > > > > simple test
> > > > > > in elision4.C.  Essentially, we have
> > > > > > 
> > > > > >  struct B { /* ... */ };
> > > > > >  struct D : B { };
> > > > > >  B b = D();
> > > > > > 
> > > > > > and we set force_elide in build_over_call, but we're unable to 
> > > > > > actually
> > > > > > elide the B::B(B&&) call, and crash on gcc_assert (!force_elide);.
> > > > > > 
> > > > > >  says that 
> > > > > > copy
> > > > > > elision "can only apply when the object being initialized is known 
> > > > > > not to be
> > > > > > a potentially-overlapping subobject".  So I suppose we shouldn't 
> > > > > > force_elide
> > > > > > the B::B(B&&) call.  I don't belive the CWG 2327 code was added to 
> > > > > > handle
> > > > > > derived-to-base conversions, at that time conv_binds_ref_to_prvalue 
> > > > > > wasn't
> > > > > > checking ck_base at all.
> > > > > > 
> > > > > > Does that make sense?  If so...
> > > > > > 
> > > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > > > 
> > > > > > PR c++/107085
> > > > > > 
> > > > > > gcc/cp/ChangeLog:
> > > > > > 
> > > > > > * call.cc (conv_is_prvalue): Return true if the base subobject 
> > > > > > is part
> > > > > > of a temporary object.
> > > > > 
> > > > > No, the base subobject of a prvalue is an xvalue.
> > > > 
> > > > Ah, so this is just like T().m where T() is a prvalue but the whole 
> > > > thing
> > > > is an xvalue.  Duly noted.
> > > 
> > > Exactly.
> > > 
> > > > > I think the problem is that an expression being a prvalue is a subset 
> > > > > of
> > > > > binding a reference to a temporary, and we shouldn't try to express 
> > > > > both of
> > > > > those using the same function: you need a separate
> > > > > conv_binds_ref_to_temporary.
> > > > 
> > > > Ack, so how about this?  Thanks,
> > > > 
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > 
> > > > -- >8 --
> > > > This PR reports that
> > > > 
> > > > struct Base {};
> > > > struct Derived : Base {};
> > > > static_assert(__reference_constructs_from_temporary(Base const&, 
> > > > Derived));
> > > > 
> > > > doesn't pass, which it should: it's just like
> > > > 
> > > > const Base& b(Derived{});
> > > > 
> > > > where we bind 'b' to the Base subobject of a temporary object of type
> > > > Derived.  The ck_base conversion didn't have ->need_temporary_p set 
> > > > because
> > > > we didn't need to create a temporary object just for the base, but the 
> > > > whole
> > > > object is a temporary so we're still binding to a temporary.  Since the
> > > > Base subobject is an xvalue, a new function is introduced.
> > > > 
> > > > PR c++/107085
> > > > 
> > > > gcc/cp/ChangeLog:
> > > > 
> > > > * call.cc (conv_binds_ref_to_temporary): New.
> > > > (ref_conv_binds_directly): Use it.
> > > > 
> > > > gcc/testsuite/ChangeLog:
> > > > 
> > > > * g++.dg/ext/reference_constructs_from_temporary1.C: Adjust 
> > > > expected
> > > > result.
> > > > * g++.dg/ext/reference_converts_from_temporary1.C: Likewise.
> > > > * g++.dg/cpp0x/elision4.C: New test.
> > > > ---
> > > >gcc/cp/call.cc| 23 
> > > > ++-
> > > >gcc/testsuite/g++.dg/cpp0x/elision4.C | 15 
> > > >.../reference_constructs_from_temporary1.C|  2 +-
> > > >.../ext/reference_converts_from_temporary1.C  |  2 +-
> > > >4 files changed, 39 insertions(+), 3 deletions(-)
> > > >create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision4.C
> > > > 
> > > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
> > > > index bd04a1d309a..715a83f5a69 100644
> > > > --- 

Re: [PATCH v2] c-family: ICE with [[gnu::nocf_check]] [PR106937]

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/4/22 19:06, Marek Polacek wrote:

On Fri, Sep 30, 2022 at 09:12:24AM -0400, Jason Merrill wrote:

On 9/29/22 18:49, Marek Polacek wrote:

When getting the name of an attribute, we ought to use
get_attribute_name, which handles both [[ ]] and __attribute__(())
forms.  Failure to do so may result in an ICE, like here.

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


How do we print the attributes with this patch?  Don't we also want to print
the namespace, and use [[]] in the output?


Good point, however: while the testcase indeed has an attribute
in the [[]] form in the typedef, here we're printing its "aka":

warning: initialization of 'FuncPointerWithNoCfCheck' {aka 'void 
(__attribute__((nocf_check)) *)(void)'} from incompatible pointer type 
'FuncPointer' {aka 'void (*)(void)'}

c-pretty-print.cc doesn't seem to know how to print an [[]] attribute.
I could do that, but then we'd print

   aka 'void ([[nocf_check]] *)(void)'

in the above, but that's invalid syntax!


Indeed, it should be

void (* [[gnu::nocf_check]])(void)


pp_c_attributes_display appears
to be called for * and & only where you can't use an [[]] attribute.  So
perhaps we want to keep printing the GNU form here?

I noticed that pp_c_attributes has never been used, so we can just remove it.

I've also adjusted the test not to use "-w".

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

-- >8 --
When getting the name of an attribute, we ought to use
get_attribute_name, which handles both [[ ]] and __attribute__(())
forms.  Failure to do so may result in an ICE, like here.

pp_c_attributes has been unused since its introduction in r56273.

PR c++/106937

gcc/c-family/ChangeLog:

* c-pretty-print.cc (pp_c_attributes): Remove.
(pp_c_attributes_display): Use get_attribute_name.
* c-pretty-print.h (pp_c_attributes): Remove.

gcc/testsuite/ChangeLog:

* gcc.dg/fcf-protection-1.c: New test.
---
  gcc/c-family/c-pretty-print.cc  | 30 +++--
  gcc/c-family/c-pretty-print.h   |  1 -
  gcc/testsuite/gcc.dg/fcf-protection-1.c | 13 +++
  3 files changed, 16 insertions(+), 28 deletions(-)
  create mode 100644 gcc/testsuite/gcc.dg/fcf-protection-1.c

diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc
index efa1768f4d6..2419e149333 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -850,32 +850,8 @@ c_pretty_printer::declaration (tree t)
pp_c_init_declarator (this, t);
  }
  
-/* Pretty-print ATTRIBUTES using GNU C extension syntax.  */

-
-void
-pp_c_attributes (c_pretty_printer *pp, tree attributes)
-{
-  if (attributes == NULL_TREE)
-return;
-
-  pp_c_ws_string (pp, "__attribute__");
-  pp_c_left_paren (pp);
-  pp_c_left_paren (pp);
-  for (; attributes != NULL_TREE; attributes = TREE_CHAIN (attributes))
-{
-  pp_tree_identifier (pp, TREE_PURPOSE (attributes));
-  if (TREE_VALUE (attributes))
-   pp_c_call_argument_list (pp, TREE_VALUE (attributes));
-
-  if (TREE_CHAIN (attributes))
-   pp_separate_with (pp, ',');
-}
-  pp_c_right_paren (pp);
-  pp_c_right_paren (pp);
-}
-
  /* Pretty-print ATTRIBUTES using GNU C extension syntax for attributes
-   marked to be displayed on disgnostic.  */
+   marked to be displayed on diagnostic.  */
  
  void

  pp_c_attributes_display (c_pretty_printer *pp, tree a)
@@ -888,7 +864,7 @@ pp_c_attributes_display (c_pretty_printer *pp, tree a)
for (; a != NULL_TREE; a = TREE_CHAIN (a))
  {
const struct attribute_spec *as;
-  as = lookup_attribute_spec (TREE_PURPOSE (a));
+  as = lookup_attribute_spec (get_attribute_name (a));
if (!as || as->affects_type_identity == false)
  continue;
if (c_dialect_cxx ()
@@ -906,7 +882,7 @@ pp_c_attributes_display (c_pretty_printer *pp, tree a)
 {
   pp_separate_with (pp, ',');
 }
-  pp_tree_identifier (pp, TREE_PURPOSE (a));
+  pp_tree_identifier (pp, get_attribute_name (a));
if (TREE_VALUE (a))
 pp_c_call_argument_list (pp, TREE_VALUE (a));
  }
diff --git a/gcc/c-family/c-pretty-print.h b/gcc/c-family/c-pretty-print.h
index be86bed4fee..92674ab4d06 100644
--- a/gcc/c-family/c-pretty-print.h
+++ b/gcc/c-family/c-pretty-print.h
@@ -119,7 +119,6 @@ void pp_c_space_for_pointer_operator (c_pretty_printer *, 
tree);
  /* Declarations.  */
  void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
  void pp_c_function_definition (c_pretty_printer *, tree);
-void pp_c_attributes (c_pretty_printer *, tree);
  void pp_c_attributes_display (c_pretty_printer *, tree);
  void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool 
func_type);
  void pp_c_type_qualifier_list (c_pretty_printer *, tree);
diff --git a/gcc/testsuite/gcc.dg/fcf-protection-1.c 
b/gcc/testsuite/gcc.dg/fcf-protection-1.c
new file mode 100644
index 000..baad74cd86f
--- /dev/null
+++ 

Re: [PATCH, v2] Fortran: error recovery for invalid types in array constructors [PR107000]

2022-10-06 Thread Harald Anlauf via Gcc-patches
Hi Mikael,

> Gesendet: Donnerstag, 06. Oktober 2022 um 22:14 Uhr
> Von: "Mikael Morin" 
> An: "Harald Anlauf" 
> Cc: "fortran" , "gcc-patches" 
> Betreff: Re: [PATCH, v2] Fortran: error recovery for invalid types in array 
> constructors [PR107000]
>
> Le 05/10/2022 à 23:40, Harald Anlauf a écrit :
> > 
> >> There is one last thing that I'm dissatisfied with.
> >> The handling of unknown types should be moved to reduce_binary, because
> >> the dispatching in reduce_binary doesn't handle EXPR_OP, so even if
> >> either or both operands are scalar, they are handled by the (array vs
> >> array) reduce_binary_aa function.  That's confusing.
> 
> Thinking about it again, I'm not sure my suggestion is right here.
> > 
> > Do you have an example?
> > 
> No.  Actually, I think it works, but a weird way.
> 
> 
> For example, for this case:
> 
> [real :: 2] * [real :: +(.true.)]
> 
> First there is a "root" invocation of reduce binary with arguments [real 
> :: 2] and [real :: +(.true.)]
> The root invocation of reduce_binary will call reduce_binary_aa. This is 
> normal.
> 
> Then reduce_binary_aa calls reduce_binary again with arguments 2 and 
> +(.true.).  And reduce_binary calls again reduce_binary_aa with those 
> arguments.  This is weird, reduce_binary_aa is supposed to have arrays 
> for both arguments.

Am I seeing something different from you?  My gdb says
that one argument of reduce_binary is EXPR_CONSTANT,
the other EXPR_OP and BT_UNKNOWN.  Both rank 0.

> The same goes for the array vs constant case, reduce_binary_ca (or 
> reduce_binary_ac) is invoked with two scalars, while if you look at 
> reduce_binary, you would expect that we only get to reduce_binary_ca 
> with a scalar constant and an array as arguments.
> 
> 
> I think the checks in the three reduce_binary_* functions should be 
> moved into their respective loops, so that we detect the invalid type 
> just before these weird recursive calls instead of just after entering 
> into them.

I think I tried that before, and it didn't work.
There was always one weird case that lead to a bad or
invalid constructor for one of the arrays you want to
look at in the respective loop,  and this is why the
testcase tries to cover everything that I hit then and
there... (hopefully).  So I ended up with the check
before the loop.

What do we actually gain with your suggested change?
Moving the check into the loop does not really make
the code more readable to me.  And the recursion is
needed anyway.

Cheers,
Harald

> OK with that change.
>


[PATCH, rs6000] Fix addg6s builtin with long long parameters. (PR100693)

2022-10-06 Thread will schmidt via Gcc-patches
[PATCH, rs6000] Fix addg6s builtin with long long parameters. (PR100693)

Hi,
  As reported in PR 100693, attempts to use __builtin_addg6s
with long long arguments result in truncated results.

Since the int and long long types can be coerced into each other,
(documented further near the rs6000-c.cc change), this is handled
by adding a builtin overload (ADDG6S_OV), and the addition of some
special handling in altivec_resolve_overloaded_builtin() to map
the calls to addg6s_32 or addg6s_64; similar to how the SCAL_CMPB
builtins are currently handled.

This has sniff-tested cleanly.

I'm seeing a regression failure show up in
testsuite/g++.dg/modules/adl-3*.c; which seems entirely unrelated
to the content in this change.  I'm poking at that a bit more to
see if I can tell the what/why for that.

OK for trunk?

Thanks,
-Will

gcc/
PR target/100693

* config/rs6000/rs6000-builtins.def ([POWER7]): Replace bif-name
__builtin_addg6s with bif-name __builtin_addg6s_32.
([POWER7-64]): New bif-name __builtin_addg6s_64.
* config/rs6000/rs6000-c.cc (altivec_resolve_overloaded_builtin):
Add handler mapping RS6000_OVLD_ADDG6S_OV to RS6000_BIF_ADDG6S
and RS6000_BIF_ADDG6S_32.
* config/rs6000/rs6000-overload.def (ADDG6S_OV): Add overloaded
entry __builtin_addg6s mapped to ADDG6S_32 and ADDG6S.
* config/rs6000/rs6000.md ("addg6s", UNSPEC_ADDG6S): Replace with
("addg6s3") and rework.
* doc/extend.texi (__builtin_addg6s): Add documentation for
__builtin_addg6s with unsigned long long parameters.

gcc/testsuite/
* testsuite/gcc.target/powerpc/pr100693-compile.c: New.
* testsuite/gcc.target/powerpc/pr100693-run.c: New.

diff --git a/gcc/config/rs6000/rs6000-builtins.def 
b/gcc/config/rs6000/rs6000-builtins.def
index f76f54793d73..11050e4c26d5 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -2010,12 +2010,13 @@
 XXSPLTD_V2DI vsx_xxspltd_v2di {}
 
 
 ; Power7 builtins (ISA 2.06).
 [power7]
-  const unsigned int __builtin_addg6s (unsigned int, unsigned int);
-ADDG6S addg6s {}
+
+  const unsigned int __builtin_addg6s_32 (unsigned int, unsigned int);
+ADDG6S_32 addg6ssi3 {}
 
   const signed long __builtin_bpermd (signed long, signed long);
 BPERMD bpermd_di {32bit}
 
   const unsigned int __builtin_cbcdtd (unsigned int);
@@ -2041,10 +2042,14 @@
 UNPACK_V1TI unpackv1ti {}
 
 
 ; Power7 builtins requiring 64-bit GPRs (even with 32-bit addressing).
 [power7-64]
+
+  const unsigned long __builtin_addg6s_64 (unsigned long, unsigned long);
+ADDG6S addg6sdi3 {no32bit}
+
   const signed long long __builtin_divde (signed long long, signed long long);
 DIVDE dive_di {}
 
   const unsigned long long __builtin_divdeu (unsigned long long, \
  unsigned long long);
diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
index 566094626293..28e8b6761ce5 100644
--- a/gcc/config/rs6000/rs6000-c.cc
+++ b/gcc/config/rs6000/rs6000-c.cc
@@ -1919,10 +1919,35 @@ altivec_resolve_overloaded_builtin (location_t loc, 
tree fndecl,
   instance_code, fcode, types, args);
if (call != error_mark_node)
  return call;
break;
   }
+  /* We need to special case __builtin_addg6s because the overloaded
+forms of this function take (unsigned int, unsigned int) or
+(unsigned long long, unsigned long long).  Since C conventions
+allow the respective argument types to be implicitly coerced into
+each other, the default handling does not provide adequate
+discrimination between the desired forms of the function.  */
+case RS6000_OVLD_ADDG6S_OV:
+  {
+   machine_mode arg1_mode = TYPE_MODE (types[0]);
+   machine_mode arg2_mode = TYPE_MODE (types[1]);
+
+   /* If any supplied arguments are wider than 32 bits, resolve to
+  64-bit variant of built-in function.  */
+   if (GET_MODE_PRECISION (arg1_mode) > 32
+   || GET_MODE_PRECISION (arg2_mode) > 32)
+ instance_code = RS6000_BIF_ADDG6S;
+   else
+ instance_code = RS6000_BIF_ADDG6S_32;
+
+   tree call = find_instance (_builtin, ,
+  instance_code, fcode, types, args);
+   if (call != error_mark_node)
+ return call;
+   break;
+  }
 case RS6000_OVLD_VEC_VSIE:
   {
machine_mode arg1_mode = TYPE_MODE (types[0]);
 
/* If supplied first argument is wider than 64 bits, resolve to
diff --git a/gcc/config/rs6000/rs6000-overload.def 
b/gcc/config/rs6000/rs6000-overload.def
index 44e2945aaa0e..41b74c0c1500 100644
--- a/gcc/config/rs6000/rs6000-overload.def
+++ b/gcc/config/rs6000/rs6000-overload.def
@@ -193,10 +193,16 @@
   unsigned int __builtin_cmpb (unsigned int, unsigned int);
 CMPB_32
   unsigned long long __builtin_cmpb (unsigned 

Aw: Re: [PATCH, v2] Fortran: reject procedures and procedure pointers as IO element [PR107074]

2022-10-06 Thread Harald Anlauf via Gcc-patches
Hi Mikael,

I definitely agree that we need a temporary for the result of
MERGE(a,a,.true.), I just haven't found out how to do that.

The reason for the bad one-liner was that in gfc_simplify_merge

result = gfc_get_parentheses (result);

actually does have issues, in that the subsequent

  gfc_simplify_expr (result, 1);

seems to fail in interesting cases (as in PR105371).

So that is something to look into...

Cheers,
Harald

> Gesendet: Donnerstag, 06. Oktober 2022 um 22:32 Uhr
> Von: "Mikael Morin" 
> An: "Harald Anlauf" 
> Cc: "gcc-patches" , "fortran" 
> Betreff: Re: [PATCH, v2] Fortran: reject procedures and procedure pointers as 
> IO element [PR107074]
>
> Le 06/10/2022 à 10:37, Mikael Morin a écrit :
> > Le 05/10/2022 à 22:40, Harald Anlauf a écrit :
> >> Hi Mikael,
> >>
> >>> Gesendet: Mittwoch, 05. Oktober 2022 um 12:34 Uhr
> >>> Von: "Mikael Morin" 
> >>> Please move the check to resolve_transfer in resolve.cc.
> >>
> >> I have done this, see attached updated patch.
> >>
> >> Regtests cleanly on x86_64-pc-linux-gnu.
> >>
> >>> Strangely, the patch doesn't seem to fix the problem on the testcase
> >>> here.  There is an outer parenthese expression preventing the condition
> >>> you added from triggering.  Can you double check?
> >>
> >> You are right: I had a one-liner in my worktree from PR105371 that
> >> fixes an issue with gfc_simplify_merge and that seems to help here.
> >> It is now included.
> >>
> > The rest looks good, but I'm not sure about your one-liner.
> > I will try to come with a real test later, but in principle, if you have 
> > a call to FOO(MERGE(A,A,.TRUE.)) you can't simplify it to FOO(A) as 
> > writes to the argument in FOO should not overwrite the content of A. The 
> > dummy should be associated with a temporary value, not to A.
> > 
> Here is a test that your patch breaks.
> Admittedly it's rejected if A has the INTENT(INOUT) attribute, but 
> without it, I think it's allowed.
> 
> program p
>integer :: b
>b = 1
>call foo(merge(b,b,.true.))
>if (b /= 1) stop 1
> contains
>subroutine foo(a)
>  integer :: a
>  if (a == 1) a = 42
>end subroutine foo
> end program p
> 
>


[COMMITTED] [PR107170] Avoid copying incompatible types in legacy VRP.

2022-10-06 Thread Aldy Hernandez via Gcc-patches
Legacy VRP is calling ranger deep inside the bowels, and then trying to
copy an incompatible type.  My previous patch in this area assumed that
the only possibility out of vr_values::get_value_range for an
unsupported type was VARYING, but UNDEFINED can also be returned.

PR tree-optimization/107170

gcc/ChangeLog:

* vr-values.cc (vr_values::range_of_expr):  Do not die on
unsupported types.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/pr107170.c: New test.
---
 gcc/testsuite/gcc.dg/tree-ssa/pr107170.c |  8 
 gcc/vr-values.cc | 24 +---
 2 files changed, 21 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107170.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107170.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr107170.c
new file mode 100644
index 000..7a5a4a363f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107170.c
@@ -0,0 +1,8 @@
+// { dg-do compile }
+// { dg-options "-O2" }
+
+int main() {
+  double a;
+  if (__builtin_signbit(a))
+__builtin_abort();
+}
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 626a9189472..71fed1e6a7e 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -184,21 +184,23 @@ vr_values::range_of_expr (vrange , tree expr, gimple 
*stmt)
 
   if (const value_range *vr = get_value_range (expr, stmt))
 {
+  if (!vr->supports_type_p (TREE_TYPE (expr)))
+   {
+ // vr_values::extract_range_basic() use of ranger's
+ // fold_range() can create a situation where we are asked
+ // for the range of an unsupported legacy type.  Since
+ // get_value_range() above will return varying or undefined
+ // for such types, avoid copying incompatible range types.
+ if (vr->undefined_p ())
+   r.set_undefined ();
+ else
+   r.set_varying (TREE_TYPE (expr));
+ return true;
+   }
   if (vr->undefined_p () || vr->constant_p ())
r = *vr;
   else
{
- if (!vr->supports_type_p (TREE_TYPE (expr)))
-   {
- // vr_values::extract_range_basic() use of ranger's
- // fold_range() can create a situation where we are
- // asked for the range of an unsupported legacy type.
- // Since get_value_range() above will return varying for
- // such types, avoid copying incompatible range types.
- gcc_checking_assert (vr->varying_p ());
- r.set_varying (TREE_TYPE (expr));
- return true;
-   }
  value_range tmp = *vr;
  tmp.normalize_symbolics ();
  r = tmp;
-- 
2.37.1



Re: [PATCH, v2] Fortran: reject procedures and procedure pointers as IO element [PR107074]

2022-10-06 Thread Mikael Morin

Le 06/10/2022 à 10:37, Mikael Morin a écrit :

Le 05/10/2022 à 22:40, Harald Anlauf a écrit :

Hi Mikael,


Gesendet: Mittwoch, 05. Oktober 2022 um 12:34 Uhr
Von: "Mikael Morin" 
Please move the check to resolve_transfer in resolve.cc.


I have done this, see attached updated patch.

Regtests cleanly on x86_64-pc-linux-gnu.


Strangely, the patch doesn't seem to fix the problem on the testcase
here.  There is an outer parenthese expression preventing the condition
you added from triggering.  Can you double check?


You are right: I had a one-liner in my worktree from PR105371 that
fixes an issue with gfc_simplify_merge and that seems to help here.
It is now included.


The rest looks good, but I'm not sure about your one-liner.
I will try to come with a real test later, but in principle, if you have 
a call to FOO(MERGE(A,A,.TRUE.)) you can't simplify it to FOO(A) as 
writes to the argument in FOO should not overwrite the content of A. The 
dummy should be associated with a temporary value, not to A.



Here is a test that your patch breaks.
Admittedly it's rejected if A has the INTENT(INOUT) attribute, but 
without it, I think it's allowed.


program p
  integer :: b
  b = 1
  call foo(merge(b,b,.true.))
  if (b /= 1) stop 1
contains
  subroutine foo(a)
integer :: a
if (a == 1) a = 42
  end subroutine foo
end program p



Re: [PATCH, v2] Fortran: error recovery for invalid types in array constructors [PR107000]

2022-10-06 Thread Mikael Morin

Le 05/10/2022 à 23:40, Harald Anlauf a écrit :



There is one last thing that I'm dissatisfied with.
The handling of unknown types should be moved to reduce_binary, because
the dispatching in reduce_binary doesn't handle EXPR_OP, so even if
either or both operands are scalar, they are handled by the (array vs
array) reduce_binary_aa function.  That's confusing.


Thinking about it again, I'm not sure my suggestion is right here.


Do you have an example?


No.  Actually, I think it works, but a weird way.


For example, for this case:

[real :: 2] * [real :: +(.true.)]

First there is a "root" invocation of reduce binary with arguments [real 
:: 2] and [real :: +(.true.)]
The root invocation of reduce_binary will call reduce_binary_aa. This is 
normal.


Then reduce_binary_aa calls reduce_binary again with arguments 2 and 
+(.true.).  And reduce_binary calls again reduce_binary_aa with those 
arguments.  This is weird, reduce_binary_aa is supposed to have arrays 
for both arguments.



The same goes for the array vs constant case, reduce_binary_ca (or 
reduce_binary_ac) is invoked with two scalars, while if you look at 
reduce_binary, you would expect that we only get to reduce_binary_ca 
with a scalar constant and an array as arguments.



I think the checks in the three reduce_binary_* functions should be 
moved into their respective loops, so that we detect the invalid type 
just before these weird recursive calls instead of just after entering 
into them.


OK with that change.


[committed] analyzer: fixes to call_summary_replay::dump_to_pp

2022-10-06 Thread David Malcolm via Gcc-patches
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-3137-g30d6356773a838.

gcc/analyzer/ChangeLog:
* call-summary.cc (call_summary_replay::dump_to_pp): Bulletproof
against NULL caller regions/svalues.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/call-summary.cc | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/gcc/analyzer/call-summary.cc b/gcc/analyzer/call-summary.cc
index bc50562b5ec..12ef82d18d6 100644
--- a/gcc/analyzer/call-summary.cc
+++ b/gcc/analyzer/call-summary.cc
@@ -845,14 +845,20 @@ call_summary_replay::dump_to_pp (pretty_printer *pp, bool 
simple) const
   for (auto summary_reg : summary_regs)
 {
   pp_string (pp, "reg in summary: ");
-  summary_reg->dump_to_pp (pp, simple);
+  if (summary_reg)
+   summary_reg->dump_to_pp (pp, simple);
+  else
+   pp_string (pp, "(null)");
   pp_newline (pp);
 
   const region *caller_reg
= *((const_cast
 (m_map_region_from_summary_to_caller)).get (summary_reg));
   pp_string (pp, " reg in caller: ");
-  caller_reg->dump_to_pp (pp, simple);
+  if (caller_reg)
+   caller_reg->dump_to_pp (pp, simple);
+  else
+   pp_string (pp, "(null)");
   pp_newline (pp);
 }
 }
-- 
2.26.3



[committed] analyzer: fix another ICE in PR 107158

2022-10-06 Thread David Malcolm via Gcc-patches
I overreduced PR analyzer/107158 in r13-3096-gef878564140cbc, and there
was another ICE in the original reproducer, which this patch fixes.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-3138-g629b4813e91aba.

gcc/analyzer/ChangeLog:
PR analyzer/107158
* store.cc (store::replay_call_summary_cluster): Eliminate
special-casing of RK_HEAP_ALLOCATED in favor of sharing code with
RK_DECL, avoiding an ICE due to attempting to bind a
compound_svalue into a binding_cluster when an svalue in the
summary cluster converts to a compound_svalue in the caller.

gcc/testsuite/ChangeLog:
PR analyzer/107158
* gcc.dg/analyzer/call-summaries-pr107158-2.c: New test.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/store.cc |  34 +-
 .../analyzer/call-summaries-pr107158-2.c  | 108 ++
 2 files changed, 114 insertions(+), 28 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c

diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index d2279b53249..2631ea25559 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -3238,6 +3238,8 @@ store::replay_call_summary_cluster (call_summary_replay 
,
   caller_sval, NULL /* uncertainty_t * */);
   }
   break;
+
+case RK_HEAP_ALLOCATED:
 case RK_DECL:
   {
const region *caller_dest_reg
@@ -3246,6 +3248,10 @@ store::replay_call_summary_cluster (call_summary_replay 
,
  return;
const svalue *summary_sval
  = summary.get_any_binding (mgr, summary_base_reg);
+   if (!summary_sval)
+ summary_sval = reg_mgr->get_or_create_compound_svalue
+   (summary_base_reg->get_type (),
+summary_cluster->get_map ());
const svalue *caller_sval
  = r.convert_svalue_from_summary (summary_sval);
if (!caller_sval)
@@ -3255,34 +3261,6 @@ store::replay_call_summary_cluster (call_summary_replay 
,
   caller_sval, NULL /* uncertainty_t * */);
   }
   break;
-case RK_HEAP_ALLOCATED:
-  {
-   const region *caller_dest_reg
- = r.convert_region_from_summary (summary_base_reg);
-   gcc_assert (caller_dest_reg);
-   binding_cluster *caller_cluster
- = get_or_create_cluster (caller_dest_reg);
-   auto_vec  summary_keys;
-   for (auto kv : *summary_cluster)
- summary_keys.safe_push (kv.first);
-   summary_keys.qsort (binding_key::cmp_ptrs);
-   for (auto summary_key : summary_keys)
- {
-   const binding_key *caller_key
- = r.convert_key_from_summary (summary_key);
-   if (!caller_key)
- continue;
-   const svalue *summary_sval
- = summary_cluster->get_map ().get (summary_key);
-   const svalue *caller_sval
- = r.convert_svalue_from_summary (summary_sval);
-   if (!caller_sval)
- caller_sval = reg_mgr->get_or_create_unknown_svalue
-   (summary_sval->get_type ());
-   caller_cluster->bind_key (caller_key, caller_sval);
- }
-  }
-  break;
 
 case RK_ALLOCA:
   /* Ignore bindings of alloca regions in the summary.  */
diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c 
b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c
new file mode 100644
index 000..c2e9e2ba9f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c
@@ -0,0 +1,108 @@
+/* { dg-additional-options "-fanalyzer-call-summaries 
-Wno-analyzer-too-complex" } */
+
+typedef __SIZE_TYPE__ size_t;
+typedef struct _IO_FILE FILE;
+extern char *fgets(char *__restrict __s, int __n, FILE *__restrict __stream)
+__attribute__((__access__(__write_only__, 1, 2)));
+extern void perror(const char *__s);
+enum {
+  _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)),
+};
+extern const unsigned short int **__ctype_b_loc(void)
+__attribute__((__nothrow__, __leaf__)) __attribute__((__const__));
+extern void *malloc(size_t __size) __attribute__((__nothrow__, __leaf__))
+__attribute__((__malloc__)) __attribute__((__alloc_size__(1)));
+extern void exit(int __status) __attribute__((__nothrow__, __leaf__))
+__attribute__((__noreturn__));
+extern char *strcpy(char *__restrict __dest, const char *__restrict __src)
+__attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2)));
+extern size_t strlen(const char *__s) __attribute__((__nothrow__, __leaf__))
+__attribute__((__pure__)) __attribute__((__nonnull__(1)));
+
+struct mydata {
+  struct mydata *link;
+  char *name;
+  char *type;
+};
+
+static struct mydata *all_data;
+static int line_no;
+
+_Noreturn static void failed(const char *message) {
+  perror(message);
+  exit(1);
+}
+
+static char *string_dup(const char *string) {
+  char *buf;
+
+  if ((buf = malloc(strlen(string) + 1)) == ((void 

[PATCH v2] libstdc++: basic_filebuf: don't flush more often than necessary.

2022-10-06 Thread Charles-Francois Natali via Gcc-patches
`basic_filebuf::xsputn` would bypass the buffer when passed a chunk of
size 1024 and above, seemingly as an optimisation.

This can have a significant performance impact if the overhead of a
`write` syscall is non-negligible, e.g. on a slow disk, on network
filesystems, or simply during IO contention because instead of flushing
every `BUFSIZ` (by default), we can flush every 1024 char.
The impact is even greater with custom larger buffers, e.g. for network
filesystems, because the code could issue `write` for example 1000X more
often than necessary with respect to the buffer size.
It also introduces a significant discontinuity in performance when
writing chunks of size 1024 and above.

See this reproducer which writes down a fixed number of chunks to a file
open with `O_SYNC` - to replicate high-latency `write` - for varying
size of chunks:

```
$ cat test_fstream_flush.cpp

int
main(int argc, char* argv[])
{
  assert(argc == 3);

  const auto* path = argv[1];
  const auto chunk_size = std::stoul(argv[2]);

  const auto fd =
open(path, O_CREAT | O_TRUNC | O_WRONLY | O_SYNC | O_CLOEXEC, 0666);
  assert(fd >= 0);

  auto filebuf = __gnu_cxx::stdio_filebuf(fd, std::ios_base::out);
  auto stream = std::ostream();

  const auto chunk = std::vector(chunk_size);

  for (auto i = 0; i < 1'000; ++i) {
stream.write(chunk.data(), chunk.size());
  }

  return 0;
}
```

```
$ g++ -o /tmp/test_fstream_flush test_fstream_flush.cpp -std=c++17
$ for i in $(seq 1021 1025); do echo -e "\n$i"; time /tmp/test_fstream_flush 
/tmp/foo $i; done

1021

real0m0.997s
user0m0.000s
sys 0m0.038s

1022

real0m0.939s
user0m0.005s
sys 0m0.032s

1023

real0m0.954s
user0m0.005s
sys 0m0.034s

1024

real0m7.102s
user0m0.040s
sys 0m0.192s

1025

real0m7.204s
user0m0.025s
sys 0m0.209s
```

See the huge drop in performance at the 1024-boundary.

An `strace` confirms that from size 1024 we effectively defeat
buffering:
1023-sized writes
```
$ strace -P /tmp/foo -e openat,write,writev /tmp/test_fstream_flush /tmp/foo 
1023 2>&1 | head -n5
openat(AT_FDCWD, "/tmp/foo", O_WRONLY|O_CREAT|O_TRUNC|O_SYNC|O_CLOEXEC, 0666) = 
3
writev(3, 
[{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=8184}, 
{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=1023}], 2) = 9207
writev(3, 
[{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=8184}, 
{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=1023}], 2) = 9207
writev(3, 
[{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=8184}, 
{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=1023}], 2) = 9207
writev(3, 
[{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=8184}, 
{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=1023}], 2) = 9207
```

vs 1024-sized writes
```
$ strace -P /tmp/foo -e openat,write,writev /tmp/test_fstream_flush /tmp/foo 
1024 2>&1 | head -n5
openat(AT_FDCWD, "/tmp/foo", O_WRONLY|O_CREAT|O_TRUNC|O_SYNC|O_CLOEXEC, 0666) = 
3
writev(3, [{iov_base=NULL, iov_len=0}, 
{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=1024}], 2) = 1024
writev(3, [{iov_base="", iov_len=0}, 
{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=1024}], 2) = 1024
writev(3, [{iov_base="", iov_len=0}, 
{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=1024}], 2) = 1024
writev(3, [{iov_base="", iov_len=0}, 
{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 iov_len=1024}], 2) = 1024
```

Instead, it makes sense to only bypass the buffer if the amount of data
to be written is larger than the buffer capacity.

Closes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63746

Signed-off-by: Charles-Francois Natali 
---
 libstdc++-v3/include/bits/fstream.tcc |  9 ++---
 .../27_io/basic_filebuf/sputn/char/63746.cc   | 38 +++
 2 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/27_io/basic_filebuf/sputn/char/63746.cc

diff --git a/libstdc++-v3/include/bits/fstream.tcc 
b/libstdc++-v3/include/bits/fstream.tcc
index 7ccc887b8..2e9369628 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -757,23 +757,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   streamsize __ret = 0;
   // Optimization in the always_noconv() case, to be generalized in the
-  // future: when __n is sufficiently large we write directly instead of
-  // using the buffer.
+  // future: when __n is larger than the available capacity we write
+  // directly instead of using the buffer.
   const bool __testout = 

Re: [PATCH] c++, v3: Improve handling of foreigner namespace attributes

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/6/22 14:29, Jakub Jelinek wrote:

On Thu, Oct 06, 2022 at 01:30:18PM -0400, Jason Merrill wrote:

Yes, except I was thinking the new function would take the attribute
TREE_LIST as its parameter so that all the callers don't have to also call
get_attribute_namespace.


Ok, here it is in patch form.

2022-10-06  Jakub Jelinek  

gcc/
* attribs.h (is_attribute_namespace_p): New inline function.
(lookup_attribute): Document meaning of ATTR_NS equal to "".
* attribs.cc (remove_attribute): Use is_attribute_namespace_p.
(private_lookup_attribute): For ATTR_NS "" match either standard
attribute or "gnu" namespace one.
gcc/c-family/
* c-common.cc (attribute_fallthrough_p): Lookup fallthrough attribute
only in gnu namespace or as standard attribute, treat fallthrough
attributes in other namespaces like any other unknown attribute.
gcc/cp/
* parser.cc (cp_parser_check_std_attribute): Only do checks if
attribute is a standard attribute or in gnu namespace and only
lookup other attributes in those namespaces.
* cp-gimplify.cc (lookup_hotness_attribute): Adjust function comment.
Only return true for standard attribute or gnu namespace attribute.
(remove_hotness_attribute): Only remove hotness attributes when
they are standard or in gnu namespace, implement it in a single
loop rather than former 4 now 8 remove_attribute calls.
gcc/testsuite/
* g++.dg/cpp1z/fallthrough2.C: New test.
* g++.dg/cpp2a/attr-likely7.C: New test.

--- gcc/attribs.h.jj2022-10-05 16:15:29.834889059 +0200
+++ gcc/attribs.h   2022-10-06 20:22:37.946494304 +0200
@@ -188,6 +188,22 @@ is_attribute_p (const char *attr_name, c
  IDENTIFIER_POINTER (ident), IDENTIFIER_LENGTH (ident));
  }
  
+/* Given an attribute name ATTR and a string ATTR_NS, return true


The word "name" here is wrong now.  OK with that fixed, thanks.


+   if the identifier node is a valid attribute namespace for the string.
+   ATTR_NS "" stands for standard attribute (NULL IDENT) or "gnu"
+   namespace.  */
+
+static inline bool
+is_attribute_namespace_p (const char *attr_ns, const_tree attr)
+{
+  tree ident = get_attribute_namespace (attr);
+  if (attr_ns == NULL)
+return ident == NULL_TREE;
+  if (attr_ns[0])
+return ident && is_attribute_p (attr_ns, ident);
+  return ident == NULL_TREE || is_attribute_p ("gnu", ident);
+}
+
  /* Given an attribute name ATTR_NAME and a list of attributes LIST,
 return a pointer to the attribute's list element if the attribute
 is part of the list, or NULL_TREE if not found.  If the attribute
@@ -217,7 +233,8 @@ lookup_attribute (const char *attr_name,
  }
  }
  
-/* Similar to lookup_attribute, but also match the attribute namespace.  */

+/* Similar to lookup_attribute, but also match the attribute namespace.
+   ATTR_NS "" stands for either standard attribute or "gnu" namespace.  */
  
  static inline tree

  lookup_attribute (const char *attr_ns, const char *attr_name, tree list)
--- gcc/attribs.cc.jj   2022-10-04 23:13:10.289090796 +0200
+++ gcc/attribs.cc  2022-10-06 20:23:35.693713861 +0200
@@ -1645,7 +1645,8 @@ remove_attribute (const char *attr_name,
return list;
  }
  
-/* Similarly but also match namespace on the removed attributes.  */

+/* Similarly but also match namespace on the removed attributes.
+   ATTR_NS "" stands for NULL or "gnu" namespace.  */
  
  tree

  remove_attribute (const char *attr_ns, const char *attr_name, tree list)
@@ -1659,15 +1660,11 @@ remove_attribute (const char *attr_ns, c
tree l = *p;
  
tree attr = get_attribute_name (l);

-  if (is_attribute_p (attr_name, attr))
+  if (is_attribute_p (attr_name, attr)
+ && is_attribute_namespace_p (attr_ns, l))
{
- tree ns = get_attribute_namespace (l);
- if ((ns == NULL_TREE && attr_ns == NULL)
- || (ns && attr_ns && is_attribute_p (attr_ns, ns)))
-   {
- *p = TREE_CHAIN (l);
- continue;
-   }
+ *p = TREE_CHAIN (l);
+ continue;
}
p = _CHAIN (l);
  }
@@ -2088,14 +2085,20 @@ private_lookup_attribute (const char *at
  tree ns = get_attribute_namespace (list);
  if (ns == NULL_TREE)
{
- if (attr_ns == NULL)
+ if (attr_ns_len == 0)
break;
}
  else if (attr_ns)
{
  ident_len = IDENTIFIER_LENGTH (ns);
- if (cmp_attribs (attr_ns, attr_ns_len, IDENTIFIER_POINTER (ns),
-  ident_len))
+ if (attr_ns_len == 0)
+   {
+ if (cmp_attribs ("gnu", strlen ("gnu"),
+  IDENTIFIER_POINTER (ns), ident_len))
+   break;
+   }
+ else if (cmp_attribs (attr_ns, attr_ns_len,
+ 

[PATCH] c++, v3: Improve handling of foreigner namespace attributes

2022-10-06 Thread Jakub Jelinek via Gcc-patches
On Thu, Oct 06, 2022 at 01:30:18PM -0400, Jason Merrill wrote:
> Yes, except I was thinking the new function would take the attribute
> TREE_LIST as its parameter so that all the callers don't have to also call
> get_attribute_namespace.

Ok, here it is in patch form.

2022-10-06  Jakub Jelinek  

gcc/
* attribs.h (is_attribute_namespace_p): New inline function.
(lookup_attribute): Document meaning of ATTR_NS equal to "".
* attribs.cc (remove_attribute): Use is_attribute_namespace_p.
(private_lookup_attribute): For ATTR_NS "" match either standard
attribute or "gnu" namespace one.
gcc/c-family/
* c-common.cc (attribute_fallthrough_p): Lookup fallthrough attribute
only in gnu namespace or as standard attribute, treat fallthrough
attributes in other namespaces like any other unknown attribute.
gcc/cp/
* parser.cc (cp_parser_check_std_attribute): Only do checks if
attribute is a standard attribute or in gnu namespace and only
lookup other attributes in those namespaces.
* cp-gimplify.cc (lookup_hotness_attribute): Adjust function comment.
Only return true for standard attribute or gnu namespace attribute.
(remove_hotness_attribute): Only remove hotness attributes when
they are standard or in gnu namespace, implement it in a single
loop rather than former 4 now 8 remove_attribute calls.
gcc/testsuite/
* g++.dg/cpp1z/fallthrough2.C: New test.
* g++.dg/cpp2a/attr-likely7.C: New test.

--- gcc/attribs.h.jj2022-10-05 16:15:29.834889059 +0200
+++ gcc/attribs.h   2022-10-06 20:22:37.946494304 +0200
@@ -188,6 +188,22 @@ is_attribute_p (const char *attr_name, c
  IDENTIFIER_POINTER (ident), IDENTIFIER_LENGTH (ident));
 }
 
+/* Given an attribute name ATTR and a string ATTR_NS, return true
+   if the identifier node is a valid attribute namespace for the string.
+   ATTR_NS "" stands for standard attribute (NULL IDENT) or "gnu"
+   namespace.  */
+
+static inline bool
+is_attribute_namespace_p (const char *attr_ns, const_tree attr)
+{
+  tree ident = get_attribute_namespace (attr);
+  if (attr_ns == NULL)
+return ident == NULL_TREE;
+  if (attr_ns[0])
+return ident && is_attribute_p (attr_ns, ident);
+  return ident == NULL_TREE || is_attribute_p ("gnu", ident);
+}
+
 /* Given an attribute name ATTR_NAME and a list of attributes LIST,
return a pointer to the attribute's list element if the attribute
is part of the list, or NULL_TREE if not found.  If the attribute
@@ -217,7 +233,8 @@ lookup_attribute (const char *attr_name,
 }
 }
 
-/* Similar to lookup_attribute, but also match the attribute namespace.  */
+/* Similar to lookup_attribute, but also match the attribute namespace.
+   ATTR_NS "" stands for either standard attribute or "gnu" namespace.  */
 
 static inline tree
 lookup_attribute (const char *attr_ns, const char *attr_name, tree list)
--- gcc/attribs.cc.jj   2022-10-04 23:13:10.289090796 +0200
+++ gcc/attribs.cc  2022-10-06 20:23:35.693713861 +0200
@@ -1645,7 +1645,8 @@ remove_attribute (const char *attr_name,
   return list;
 }
 
-/* Similarly but also match namespace on the removed attributes.  */
+/* Similarly but also match namespace on the removed attributes.
+   ATTR_NS "" stands for NULL or "gnu" namespace.  */
 
 tree
 remove_attribute (const char *attr_ns, const char *attr_name, tree list)
@@ -1659,15 +1660,11 @@ remove_attribute (const char *attr_ns, c
   tree l = *p;
 
   tree attr = get_attribute_name (l);
-  if (is_attribute_p (attr_name, attr))
+  if (is_attribute_p (attr_name, attr)
+ && is_attribute_namespace_p (attr_ns, l))
{
- tree ns = get_attribute_namespace (l);
- if ((ns == NULL_TREE && attr_ns == NULL)
- || (ns && attr_ns && is_attribute_p (attr_ns, ns)))
-   {
- *p = TREE_CHAIN (l);
- continue;
-   }
+ *p = TREE_CHAIN (l);
+ continue;
}
   p = _CHAIN (l);
 }
@@ -2088,14 +2085,20 @@ private_lookup_attribute (const char *at
  tree ns = get_attribute_namespace (list);
  if (ns == NULL_TREE)
{
- if (attr_ns == NULL)
+ if (attr_ns_len == 0)
break;
}
  else if (attr_ns)
{
  ident_len = IDENTIFIER_LENGTH (ns);
- if (cmp_attribs (attr_ns, attr_ns_len, IDENTIFIER_POINTER (ns),
-  ident_len))
+ if (attr_ns_len == 0)
+   {
+ if (cmp_attribs ("gnu", strlen ("gnu"),
+  IDENTIFIER_POINTER (ns), ident_len))
+   break;
+   }
+ else if (cmp_attribs (attr_ns, attr_ns_len,
+   IDENTIFIER_POINTER (ns), ident_len))
break;
}
}
--- 

[PATCH RFA] gimplify: prevent some C++ temporary elision

2022-10-06 Thread Jason Merrill via Gcc-patches
Tested x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

In this testcase, we were optimizing away the temporary for f(), but
C++17 and above are clear that there is a temporary, and because its
destructor has visible side-effects we can't optimize it away under the
as-if rule.  So disable this optimization for TREE_ADDRESSABLE type.

I moved the declaration of volatile_p after the call to
gimple_fold_indirect_ref_rhs to minimize indentation changes; I don't see
any way the value of that flag could be affected by the call.

gcc/ChangeLog:

* gimplify.cc (gimplify_modify_expr_rhs): Don't optimize
x = *(A*)& to x =  for a TREE_ADDRESSABLE type.

gcc/testsuite/ChangeLog:

* g++.dg/init/elide9.C: New test.
---
 gcc/gimplify.cc| 15 ---
 gcc/testsuite/g++.dg/init/elide9.C | 25 +
 2 files changed, 33 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/init/elide9.C

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 9e0e3429958..07e63538e5b 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -5601,7 +5601,7 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, 
tree *to_p,
}
  break;
case INDIRECT_REF:
- {
+ if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
/* If we have code like
 
 *(const A*)(A*)
@@ -5610,11 +5610,13 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, 
tree *to_p,
 of "A"), treat the entire expression as identical to "x".
 This kind of code arises in C++ when an object is bound
 to a const reference, and if "x" is a TARGET_EXPR we want
-to take advantage of the optimization below.  */
-   bool volatile_p = TREE_THIS_VOLATILE (*from_p);
-   tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
-   if (t)
+to take advantage of the optimization below.  But not if
+the type is TREE_ADDRESSABLE; then C++17 says that the
+TARGET_EXPR needs to be a temporary.  */
+   if (tree t
+   = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)))
  {
+   bool volatile_p = TREE_THIS_VOLATILE (*from_p);
if (TREE_THIS_VOLATILE (t) != volatile_p)
  {
if (DECL_P (t))
@@ -5627,8 +5629,7 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, 
tree *to_p,
ret = GS_OK;
changed = true;
  }
-   break;
- }
+ break;
 
case TARGET_EXPR:
  {
diff --git a/gcc/testsuite/g++.dg/init/elide9.C 
b/gcc/testsuite/g++.dg/init/elide9.C
new file mode 100644
index 000..810d60a94a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/elide9.C
@@ -0,0 +1,25 @@
+// The static_cast should prevent temporary elision.
+// { dg-do run { target c++11 } }
+
+int d;
+struct A
+{
+  int i;
+  A() { }
+  ~A() { ++d; }
+};
+
+A f() { return A(); }
+
+struct B
+{
+  A a;
+  B(): a(static_cast(f())) {}
+};
+
+int main()
+{
+  { B b; }
+  if (d != 2)
+return -1;
+}

base-commit: 966010b2eb4a4c52f139b63548533e7bbd74ec9c
-- 
2.31.1



Re: [PATCH v2] c++: fixes for derived-to-base reference binding [PR107085]

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/6/22 13:51, Marek Polacek wrote:

On Thu, Oct 06, 2022 at 10:58:44AM -0400, Jason Merrill wrote:

On 10/6/22 10:49, Marek Polacek wrote:

On Wed, Oct 05, 2022 at 08:25:29PM -0400, Jason Merrill wrote:

On 10/5/22 17:27, Marek Polacek wrote:

This PR reports that

 struct Base {};
 struct Derived : Base {};
 static_assert(__reference_constructs_from_temporary(Base const&, Derived));

doesn't pass, which it should: it's just like

 const Base& b(Derived{});

where we bind 'b' to the Base subobject of a temporary object of type
Derived.  The ck_base conversion didn't have ->need_temporary_p set because
we didn't need to create a temporary object just for the base, but the whole
object is a temporary so we're still binding to a temporary.  Fixed by
the conv_is_prvalue hunk.

That broke a bunch of tests.  I've distilled the issue into a simple test
in elision4.C.  Essentially, we have

 struct B { /* ... */ };
 struct D : B { };
 B b = D();

and we set force_elide in build_over_call, but we're unable to actually
elide the B::B(B&&) call, and crash on gcc_assert (!force_elide);.

 says that copy
elision "can only apply when the object being initialized is known not to be
a potentially-overlapping subobject".  So I suppose we shouldn't force_elide
the B::B(B&&) call.  I don't belive the CWG 2327 code was added to handle
derived-to-base conversions, at that time conv_binds_ref_to_prvalue wasn't
checking ck_base at all.

Does that make sense?  If so...

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

PR c++/107085

gcc/cp/ChangeLog:

* call.cc (conv_is_prvalue): Return true if the base subobject is part
of a temporary object.


No, the base subobject of a prvalue is an xvalue.


Ah, so this is just like T().m where T() is a prvalue but the whole thing
is an xvalue.  Duly noted.


Exactly.


I think the problem is that an expression being a prvalue is a subset of
binding a reference to a temporary, and we shouldn't try to express both of
those using the same function: you need a separate
conv_binds_ref_to_temporary.


Ack, so how about this?  Thanks,

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

-- >8 --
This PR reports that

struct Base {};
struct Derived : Base {};
static_assert(__reference_constructs_from_temporary(Base const&, Derived));

doesn't pass, which it should: it's just like

const Base& b(Derived{});

where we bind 'b' to the Base subobject of a temporary object of type
Derived.  The ck_base conversion didn't have ->need_temporary_p set because
we didn't need to create a temporary object just for the base, but the whole
object is a temporary so we're still binding to a temporary.  Since the
Base subobject is an xvalue, a new function is introduced.

PR c++/107085

gcc/cp/ChangeLog:

* call.cc (conv_binds_ref_to_temporary): New.
(ref_conv_binds_directly): Use it.

gcc/testsuite/ChangeLog:

* g++.dg/ext/reference_constructs_from_temporary1.C: Adjust expected
result.
* g++.dg/ext/reference_converts_from_temporary1.C: Likewise.
* g++.dg/cpp0x/elision4.C: New test.
---
   gcc/cp/call.cc| 23 ++-
   gcc/testsuite/g++.dg/cpp0x/elision4.C | 15 
   .../reference_constructs_from_temporary1.C|  2 +-
   .../ext/reference_converts_from_temporary1.C  |  2 +-
   4 files changed, 39 insertions(+), 3 deletions(-)
   create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision4.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index bd04a1d309a..715a83f5a69 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9210,6 +9210,27 @@ conv_binds_ref_to_prvalue (conversion *c)
 return conv_is_prvalue (next_conversion (c));
   }
+/* True iff C is a conversion that binds a reference to a temporary.
+   This is a superset of conv_binds_ref_to_prvalue: here we're also
+   interested in xvalues.  */
+
+static bool
+conv_binds_ref_to_temporary (conversion *c)
+{
+  if (conv_binds_ref_to_prvalue (c))
+return true;
+  if (c->kind != ck_ref_bind)
+return false;
+  c = next_conversion (c);
+  /* This is the case for
+   struct Base {};
+   struct Derived : Base {};
+   const Base& b(Derived{});
+ where we bind 'b' to the Base subobject of a temporary object of type
+ Derived.  The subobject is an xvalue; the whole object is a prvalue.  */
+  return (c->kind == ck_base && conv_is_prvalue (next_conversion (c)));


I think you also want to check for the case of c->u.expr being a
COMPONENT_REF/ARRAY_REF around a TARGET_EXPR, as you mentioned.


I see.  So this would be achieved using e.g.

struct B { };
struct D : B { };
struct C {
   D d;
};

const B& b = C{}.d;


Yes.


Except I'm not sure how to trigger this via the built-in, which takes two types.
Am I missing something obvious?


Indeed, it can't be triggered by the built-in.  

Re: [PATCH v2] c++: fixes for derived-to-base reference binding [PR107085]

2022-10-06 Thread Marek Polacek via Gcc-patches
On Thu, Oct 06, 2022 at 10:58:44AM -0400, Jason Merrill wrote:
> On 10/6/22 10:49, Marek Polacek wrote:
> > On Wed, Oct 05, 2022 at 08:25:29PM -0400, Jason Merrill wrote:
> > > On 10/5/22 17:27, Marek Polacek wrote:
> > > > This PR reports that
> > > > 
> > > > struct Base {};
> > > > struct Derived : Base {};
> > > > static_assert(__reference_constructs_from_temporary(Base const&, 
> > > > Derived));
> > > > 
> > > > doesn't pass, which it should: it's just like
> > > > 
> > > > const Base& b(Derived{});
> > > > 
> > > > where we bind 'b' to the Base subobject of a temporary object of type
> > > > Derived.  The ck_base conversion didn't have ->need_temporary_p set 
> > > > because
> > > > we didn't need to create a temporary object just for the base, but the 
> > > > whole
> > > > object is a temporary so we're still binding to a temporary.  Fixed by
> > > > the conv_is_prvalue hunk.
> > > > 
> > > > That broke a bunch of tests.  I've distilled the issue into a simple 
> > > > test
> > > > in elision4.C.  Essentially, we have
> > > > 
> > > > struct B { /* ... */ };
> > > > struct D : B { };
> > > > B b = D();
> > > > 
> > > > and we set force_elide in build_over_call, but we're unable to actually
> > > > elide the B::B(B&&) call, and crash on gcc_assert (!force_elide);.
> > > > 
> > > >  says that copy
> > > > elision "can only apply when the object being initialized is known not 
> > > > to be
> > > > a potentially-overlapping subobject".  So I suppose we shouldn't 
> > > > force_elide
> > > > the B::B(B&&) call.  I don't belive the CWG 2327 code was added to 
> > > > handle
> > > > derived-to-base conversions, at that time conv_binds_ref_to_prvalue 
> > > > wasn't
> > > > checking ck_base at all.
> > > > 
> > > > Does that make sense?  If so...
> > > > 
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > 
> > > > PR c++/107085
> > > > 
> > > > gcc/cp/ChangeLog:
> > > > 
> > > > * call.cc (conv_is_prvalue): Return true if the base subobject 
> > > > is part
> > > > of a temporary object.
> > > 
> > > No, the base subobject of a prvalue is an xvalue.
> > 
> > Ah, so this is just like T().m where T() is a prvalue but the whole thing
> > is an xvalue.  Duly noted.
> 
> Exactly.
> 
> > > I think the problem is that an expression being a prvalue is a subset of
> > > binding a reference to a temporary, and we shouldn't try to express both 
> > > of
> > > those using the same function: you need a separate
> > > conv_binds_ref_to_temporary.
> > 
> > Ack, so how about this?  Thanks,
> > 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > -- >8 --
> > This PR reports that
> > 
> >struct Base {};
> >struct Derived : Base {};
> >static_assert(__reference_constructs_from_temporary(Base const&, 
> > Derived));
> > 
> > doesn't pass, which it should: it's just like
> > 
> >const Base& b(Derived{});
> > 
> > where we bind 'b' to the Base subobject of a temporary object of type
> > Derived.  The ck_base conversion didn't have ->need_temporary_p set because
> > we didn't need to create a temporary object just for the base, but the whole
> > object is a temporary so we're still binding to a temporary.  Since the
> > Base subobject is an xvalue, a new function is introduced.
> > 
> > PR c++/107085
> > 
> > gcc/cp/ChangeLog:
> > 
> > * call.cc (conv_binds_ref_to_temporary): New.
> > (ref_conv_binds_directly): Use it.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/ext/reference_constructs_from_temporary1.C: Adjust expected
> > result.
> > * g++.dg/ext/reference_converts_from_temporary1.C: Likewise.
> > * g++.dg/cpp0x/elision4.C: New test.
> > ---
> >   gcc/cp/call.cc| 23 ++-
> >   gcc/testsuite/g++.dg/cpp0x/elision4.C | 15 
> >   .../reference_constructs_from_temporary1.C|  2 +-
> >   .../ext/reference_converts_from_temporary1.C  |  2 +-
> >   4 files changed, 39 insertions(+), 3 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision4.C
> > 
> > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
> > index bd04a1d309a..715a83f5a69 100644
> > --- a/gcc/cp/call.cc
> > +++ b/gcc/cp/call.cc
> > @@ -9210,6 +9210,27 @@ conv_binds_ref_to_prvalue (conversion *c)
> > return conv_is_prvalue (next_conversion (c));
> >   }
> > +/* True iff C is a conversion that binds a reference to a temporary.
> > +   This is a superset of conv_binds_ref_to_prvalue: here we're also
> > +   interested in xvalues.  */
> > +
> > +static bool
> > +conv_binds_ref_to_temporary (conversion *c)
> > +{
> > +  if (conv_binds_ref_to_prvalue (c))
> > +return true;
> > +  if (c->kind != ck_ref_bind)
> > +return false;
> > +  c = next_conversion (c);
> > +  /* This is the case for
> > +   struct Base {};
> > +   struct Derived : Base {};
> > +   const Base& 

[PATCH] Fix gdb FilteringTypePrinter (again)

2022-10-06 Thread François Dumont via Gcc-patches

Hi

Looks like the previous patch was not enough. When using it in the 
context of a build without dual abi and versioned namespace I started 
having failures again. I guess I hadn't rebuild everything properly.


This time I think the problem was in those lines:

    if self.type_obj == type_obj:
    return strip_inline_namespaces(self.name)

I've added a call to gdb.types.get_basic_type so that we do not compare 
a type with its typedef.


Thanks for the pointer to the doc !

Doing so I eventually use your code Jonathan to make FilteringTypeFilter 
more specific to a given instantiation.


    libstdc++: Fix gdb FilteringTypePrinter

    Once we found a matching FilteringTypePrinter instance we look for 
the associated
    typedef and check that the returned Python Type is equal to the 
Type to recognize.
    But gdb Python Type includes properties to distinguish a typedef 
from the actual
    type. So use gdb.types.get_basic_type to check if we are indeed on 
the same type.


    Additionnaly enhance FilteringTypePrinter matching mecanism by 
introducing targ1 that,

    if not None, will be used as the 1st template parameter.

    libstdc++-v3/ChangeLog:

    * python/libstdcxx/v6/printers.py (FilteringTypePrinter): 
Rename 'match' field
    'template'. Add self.targ1 to specify the first template 
parameter of the instantiation

    to match.
    (add_one_type_printer): Add targ1 optional parameter, 
default to None.
    Use gdb.types.get_basic_type to compare the type to 
recognize and the type

    returned from the typedef lookup.
    (register_type_printers): Adapt calls to add_one_type_printers.

Tested under Linux x86_64 normal, version namespace with or without dual 
abi.


François

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 0fa7805183e..52339b247d8 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2040,62 +2040,72 @@ def add_one_template_type_printer(obj, name, defargs):
 
 class FilteringTypePrinter(object):
 r"""
-A type printer that uses typedef names for common template specializations.
+A type printer that uses typedef names for common template instantiations.
 
 Args:
-match (str): The class template to recognize.
+template (str): The class template to recognize.
 name (str): The typedef-name that will be used instead.
+targ1 (str): The first template argument.
+If arg1 is provided (not None), only template instantiations with this type
+as the first template argument, e.g. if template='basic_string is the same type as
+e.g. for template='basic_istream', name='istream', if any instantiation of
+std::basic_istream is the same type as std::istream then print it as
+std::istream.
+
+e.g. for template='basic_istream', name='istream', targ1='char', if any
+instantiation of std::basic_istream is the same type as
 std::istream then print it as std::istream.
 """
 
-def __init__(self, match, name):
-self.match = match
+def __init__(self, template, name, targ1):
+self.template = template
 self.name = name
+self.targ1 = targ1
 self.enabled = True
 
 class _recognizer(object):
 "The recognizer class for FilteringTypePrinter."
 
-def __init__(self, match, name):
-self.match = match
+def __init__(self, template, name, targ1):
+self.template = template
 self.name = name
+self.targ1 = targ1
 self.type_obj = None
 
 def recognize(self, type_obj):
 """
-If type_obj starts with self.match and is the same type as
+If type_obj starts with self.template and is the same type as
 self.name then return self.name, otherwise None.
 """
 if type_obj.tag is None:
 return None
 
 if self.type_obj is None:
-if not type_obj.tag.startswith(self.match):
+if self.targ1 is not None:
+if not type_obj.tag.startswith('{}<{}'.format(self.template, self.targ1)):
+# Filter didn't match.
+return None
+elif not type_obj.tag.startswith(self.template):
 # Filter didn't match.
 return None
+
 try:
 self.type_obj = gdb.lookup_type(self.name).strip_typedefs()
 except:
 pass
-if self.type_obj == type_obj:
-return strip_inline_namespaces(self.name)
 
 if self.type_obj is None:
 return None
 
-# Workaround ambiguous typedefs matching both std:: and std::__cxx11:: symbols.
-ambiguous = False
- 

Re: [RFC] c++: parser - Support for target address spaces in C++

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/6/22 10:34, Paul Iannetta wrote:

Hi,

Presently, GCC supports target address spaces as a GNU extension (cf.
`info -n "(gcc)Named Address Spaces"`).  This is however supported
only by the C frontend, which is a bit sad, since all the GIMPLE
machinery is readily available and, moreover, LLVM supports this GNU
extension both for C and C++.

Here is a first attempt at a patch to enable the support for target
address spaces in C++.  The basic idea is only to make the parser
recognize address spaces, and lower them into GIMPLE, in the same
fashion as the C parser.  This also makes it possible to merge the
function `c_register_addr_space` in one place which is better than
before.


Great.


The patch still has some drawbacks compared to its C counterpart.
Namely, much like the `__restrict__` keyword, it is always enabled and
-std=c++11 won't disable it (whereas -std=c11) would reject address
spaces.  Not also that the mangler ignores address spaces, much like
it ignores __restrict__.


Hmm?  We mangle __restrict:

void f(int *__restrict *p) { } // _Z1fPrPi

but cv-qualifiers (including restrict) are dropped on the top-level type 
of a parameter.


If address spaces should be mangled, it probably makes sense to use the 
same  mangling that we already use for attributes in 
write_CV_qualifiers_for_type.



Depending on the reception, I'll add further testcases and will update
the relevant part of the documentation.


Please.


Cheers,
Paul

Author: Paul Iannetta 
Date:   Wed Oct 5 16:44:36 2022 +0200

 Add support for custom address spaces in C++

gcc/
* tree.h (ENCODE_QUAL_ADDR_SPACE): Missing parentheses.

gcc/c/
* c-decl.c: Remove c_register_addr_space.

gcc/c-family/
* c-common.c (c_register_addr_space): Imported from c-decl.c
* c-common.h: Remove the FIXME.

gcc/cp/
* cp-tree.h (enum cp_decl_spec): Add addr_space support.
 (struct cp_decl_specifier_seq): Likewise.
* decl.c (get_type_quals): Likewise.
* parser.c (cp_parser_type_specifier): Likewise.
 (cp_parser_cv_qualifier_seq_opt): Likewise
* tree.c: Remove c_register_addr_space stub.

Signed-off-by: Paul Iannetta 

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 064c2f263f0..282ba54ab70 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2615,6 +2615,25 @@ c_build_bitfield_integer_type (unsigned HOST_WIDE_INT 
width, int unsignedp)
return build_nonstandard_integer_type (width, unsignedp);
  }
  
+/* Register reserved keyword WORD as qualifier for address space AS.  */

+
+void
+c_register_addr_space (const char *word, addr_space_t as)
+{
+  int rid = RID_FIRST_ADDR_SPACE + as;
+  tree id;
+
+  /* Address space qualifiers are only supported
+ in C with GNU extensions enabled.  */
+  if (c_dialect_objc () || flag_no_asm)
+return;
+
+  id = get_identifier (word);
+  C_SET_RID_CODE (id, rid);
+  TREE_LANG_FLAG_0 (id) = 1;
+  ridpointers[rid] = id;
+}
+
  /* The C version of the register_builtin_type langhook.  */
  
  void

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ed39b7764bf..f2c1df0c8de 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -808,9 +808,6 @@ extern const struct attribute_spec 
c_common_format_attribute_table[];
  
  extern tree (*make_fname_decl) (location_t, tree, int);
  
-/* In c-decl.c and cp/tree.c.  FIXME.  */

-extern void c_register_addr_space (const char *str, addr_space_t as);
-
  /* In c-common.c.  */
  extern bool in_late_binary_op;
  extern const char *c_addr_space_name (addr_space_t as);
@@ -926,6 +923,7 @@ extern void c_common_finish (void);
  extern void c_common_parse_file (void);
  extern FILE *get_dump_info (int, dump_flags_t *);
  extern alias_set_type c_common_get_alias_set (tree);
+extern void c_register_addr_space (const char *, addr_space_t);
  extern void c_register_builtin_type (tree, const char*);
  extern bool c_promoting_integer_type_p (const_tree);
  extern bool self_promoting_args_p (const_tree);
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 8e24b522ee4..278d1248d1c 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -11927,25 +11927,6 @@ c_parse_final_cleanups (void)
ext_block = NULL;
  }
  
-/* Register reserved keyword WORD as qualifier for address space AS.  */

-
-void
-c_register_addr_space (const char *word, addr_space_t as)
-{
-  int rid = RID_FIRST_ADDR_SPACE + as;
-  tree id;
-
-  /* Address space qualifiers are only supported
- in C with GNU extensions enabled.  */
-  if (c_dialect_objc () || flag_no_asm)
-return;
-
-  id = get_identifier (word);
-  C_SET_RID_CODE (id, rid);
-  C_IS_RESERVED_WORD (id) = 1;
-  ridpointers [rid] = id;
-}
-
  /* Return identifier to look up for omp declare reduction.  */
  
  tree

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 15ec4cd199f..4ae971ccb90 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5974,6 +5974,7 @@ enum cp_decl_spec {

Re: [PATCH] c++, v2: Improve handling of foreigner namespace attributes

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/6/22 13:20, Jakub Jelinek wrote:

On Thu, Oct 06, 2022 at 09:42:47AM -0400, Jason Merrill wrote:

-  tree t = lookup_attribute ("fallthrough", attr);
+  tree t = lookup_attribute (NULL, "fallthrough", attr);
+  if (t == NULL_TREE)
+t = lookup_attribute ("gnu", "fallthrough", attr);


Maybe lookup_attribute with a magic namespace argument that matches either
null or gnu?

And similarly, a new is_attribute_namespace (name, t) function with the same
behavior, to be used here and in all the below hunks?


So like this?


Yes, except I was thinking the new function would take the attribute 
TREE_LIST as its parameter so that all the callers don't have to also 
call get_attribute_namespace.



2022-10-05  Jakub Jelinek  

gcc/
* attribs.h (is_attribute_namespace_p): New inline function.
(lookup_attribute): Document meaning of ATTR_NS equal to "".
* attribs.cc (remove_attribute): Use is_attribute_namespace_p.
(private_lookup_attribute): For ATTR_NS "" match either standard
attribute or "gnu" namespace one.
gcc/c-family/
* c-common.cc (attribute_fallthrough_p): Lookup fallthrough attribute
only in gnu namespace or as standard attribute, treat fallthrough
attributes in other namespaces like any other unknown attribute.
gcc/cp/
* parser.cc (cp_parser_check_std_attribute): Only do checks if
attribute is a standard attribute or in gnu namespace and only
lookup other attributes in those namespaces.
* cp-gimplify.cc (lookup_hotness_attribute): Adjust function comment.
Only return true for standard attribute or gnu namespace attribute.
(remove_hotness_attribute): Only remove hotness attributes when
they are standard or in gnu namespace, implement it in a single
loop rather than former 4 now 8 remove_attribute calls.
gcc/testsuite/
* g++.dg/cpp1z/fallthrough2.C: New test.
* g++.dg/cpp2a/attr-likely7.C: New test.

--- gcc/attribs.h.jj2022-10-05 16:15:29.834889059 +0200
+++ gcc/attribs.h   2022-10-06 17:59:56.918430468 +0200
@@ -188,6 +188,21 @@ is_attribute_p (const char *attr_name, c
  IDENTIFIER_POINTER (ident), IDENTIFIER_LENGTH (ident));
  }
  
+/* Given an identifier node IDENT or NULL and a string ATTR_NS, return true

+   if the identifier node is a valid attribute namespace for the string.
+   ATTR_NS "" stands for standard attribute (NULL IDENT) or "gnu"
+   namespace.  */
+
+static inline bool
+is_attribute_namespace_p (const char *attr_ns, const_tree ident)
+{
+  if (attr_ns == NULL)
+return ident == NULL_TREE;
+  if (attr_ns[0])
+return ident && is_attribute_p (attr_ns, ident);
+  return ident == NULL_TREE || is_attribute_p ("gnu", ident);
+}
+
  /* Given an attribute name ATTR_NAME and a list of attributes LIST,
 return a pointer to the attribute's list element if the attribute
 is part of the list, or NULL_TREE if not found.  If the attribute
@@ -217,7 +232,8 @@ lookup_attribute (const char *attr_name,
  }
  }
  
-/* Similar to lookup_attribute, but also match the attribute namespace.  */

+/* Similar to lookup_attribute, but also match the attribute namespace.
+   ATTR_NS "" stands for either standard attribute or "gnu" namespace.  */
  
  static inline tree

  lookup_attribute (const char *attr_ns, const char *attr_name, tree list)
--- gcc/attribs.cc.jj   2022-10-04 23:13:10.289090796 +0200
+++ gcc/attribs.cc  2022-10-06 18:01:32.096146195 +0200
@@ -1645,7 +1645,8 @@ remove_attribute (const char *attr_name,
return list;
  }
  
-/* Similarly but also match namespace on the removed attributes.  */

+/* Similarly but also match namespace on the removed attributes.
+   ATTR_NS "" stands for NULL or "gnu" namespace.  */
  
  tree

  remove_attribute (const char *attr_ns, const char *attr_name, tree list)
@@ -1662,8 +1663,7 @@ remove_attribute (const char *attr_ns, c
if (is_attribute_p (attr_name, attr))
{
  tree ns = get_attribute_namespace (l);
- if ((ns == NULL_TREE && attr_ns == NULL)
- || (ns && attr_ns && is_attribute_p (attr_ns, ns)))
+ if (is_attribute_namespace_p (attr_ns, ns))
{
  *p = TREE_CHAIN (l);
  continue;
@@ -2088,14 +2088,20 @@ private_lookup_attribute (const char *at
  tree ns = get_attribute_namespace (list);
  if (ns == NULL_TREE)
{
- if (attr_ns == NULL)
+ if (attr_ns_len == 0)
break;
}
  else if (attr_ns)
{
  ident_len = IDENTIFIER_LENGTH (ns);
- if (cmp_attribs (attr_ns, attr_ns_len, IDENTIFIER_POINTER (ns),
-  ident_len))
+ if (attr_ns_len == 0)
+   {
+ if (cmp_attribs ("gnu", strlen ("gnu"),
+  IDENTIFIER_POINTER (ns), ident_len))
+   break;
+   

Re: [PATCH][AArch64] Improve immediate expansion [PR106583]

2022-10-06 Thread Wilco Dijkstra via Gcc-patches
Hi Richard,

> Did you consider handling the case where the movks aren't for
> consecutive bitranges?  E.g. the patch handles:

> but it looks like it would be fairly easy to extend it to:
>
>  0x12345678

Yes, with a more general search loop we can get that case too -
it doesn't trigger much though. The code that checks for this is
now refactored into a new function. Given there are now many
more calls to aarch64_bitmask_imm, I added a streamlined internal
entry point that assumes the input is 64-bit.

Cheers,
Wilco

[PATCH v2][AArch64] Improve immediate expansion [PR106583]

Improve immediate expansion of immediates which can be created from a
bitmask immediate and 2 MOVKs.  Simplify, refactor and improve 
efficiency of bitmask checks.  This reduces the number of 4-instruction
immediates in SPECINT/FP by 10-15%.

Passes regress, OK for commit?

gcc/ChangeLog:

PR target/106583
* config/aarch64/aarch64.cc (aarch64_internal_mov_immediate)
Add support for a bitmask immediate with 2 MOVKs.
(aarch64_check_bitmask): New function after refactorization.
(aarch64_replicate_bitmask_imm): Remove function, merge into...
(aarch64_bitmask_imm): Simplify replication of small modes.
Split function into 64-bit only version for efficiency. 

gcc/testsuite:
PR target/106583
* gcc.target/aarch64/pr106583.c: Add new test.

---

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 
926e81f028c82aac9a5fecc18f921f84399c24ae..b2d9c7380975028131d0fe731a97b3909874b87b
 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -306,6 +306,7 @@ static machine_mode aarch64_simd_container_mode 
(scalar_mode, poly_int64);
 static bool aarch64_print_address_internal (FILE*, machine_mode, rtx,
aarch64_addr_query_type);
 static HOST_WIDE_INT aarch64_clamp_to_uimm12_shift (HOST_WIDE_INT val);
+static bool aarch64_bitmask_imm (unsigned HOST_WIDE_INT);
 
 /* The processor for which instructions should be scheduled.  */
 enum aarch64_processor aarch64_tune = cortexa53;
@@ -5502,6 +5503,30 @@ aarch64_output_sve_vector_inc_dec (const char *operands, 
rtx x)
 factor, nelts_per_vq);
 }
 
+/* Return true if the immediate VAL can be a bitfield immediate
+   by changing the given MASK bits in VAL to zeroes, ones or bits
+   from the other half of VAL.  Return the new immediate in VAL2.  */
+static inline bool
+aarch64_check_bitmask (unsigned HOST_WIDE_INT val,
+  unsigned HOST_WIDE_INT ,
+  unsigned HOST_WIDE_INT mask)
+{
+  val2 = val & ~mask;
+  if (val2 != val && aarch64_bitmask_imm (val2))
+return true;
+  val2 = val | mask;
+  if (val2 != val && aarch64_bitmask_imm (val2))
+return true;
+  val = val & ~mask;
+  val2 = val | (((val >> 32) | (val << 32)) & mask);
+  if (val2 != val && aarch64_bitmask_imm (val2))
+return true;
+  val2 = val | (((val >> 16) | (val << 48)) & mask);
+  if (val2 != val && aarch64_bitmask_imm (val2))
+return true;
+  return false;
+}
+
 static int
 aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
scalar_int_mode mode)
@@ -5568,36 +5593,43 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool 
generate,
   one_match = ((~val & mask) == 0) + ((~val & (mask << 16)) == 0) +
 ((~val & (mask << 32)) == 0) + ((~val & (mask << 48)) == 0);
 
-  if (zero_match != 2 && one_match != 2)
+  if (zero_match < 2 && one_match < 2)
 {
   /* Try emitting a bitmask immediate with a movk replacing 16 bits.
 For a 64-bit bitmask try whether changing 16 bits to all ones or
 zeroes creates a valid bitmask.  To check any repeated bitmask,
 try using 16 bits from the other 32-bit half of val.  */
 
-  for (i = 0; i < 64; i += 16, mask <<= 16)
-   {
- val2 = val & ~mask;
- if (val2 != val && aarch64_bitmask_imm (val2, mode))
-   break;
- val2 = val | mask;
- if (val2 != val && aarch64_bitmask_imm (val2, mode))
-   break;
- val2 = val2 & ~mask;
- val2 = val2 | (((val2 >> 32) | (val2 << 32)) & mask);
- if (val2 != val && aarch64_bitmask_imm (val2, mode))
-   break;
-   }
-  if (i != 64)
-   {
- if (generate)
+  for (i = 0; i < 64; i += 16)
+   if (aarch64_check_bitmask (val, val2, mask << i))
+ {
+   if (generate)
+ {
+   emit_insn (gen_rtx_SET (dest, GEN_INT (val2)));
+   emit_insn (gen_insv_immdi (dest, GEN_INT (i),
+  GEN_INT ((val >> i) & 0x)));
+ }
+   return 2;
+ }
+}
+
+  /* Try a bitmask plus 2 movk to generate the immediate in 3 instructions.  */
+  if (zero_match + one_match == 0)
+{
+  for (i = 0; i < 48; i += 16)
+   for (int 

[PATCH] Reduce DF computation at -O0

2022-10-06 Thread Eric Botcazou via Gcc-patches
Hi,

even at -O0 there may be a fair amount of DF computation performed when
compiling large units and part of it appears to be useless.

Bootstrapped/regtested on x86-64/Linux, OK for the mainline?


2022-10-06  Eric Botcazou  

* function.cc (thread_prologue_and_epilogue_insns): Update only entry
and exit blocks when not optimizing.  Remove dead statement.

-- 
Eric Botcazoudiff --git a/gcc/function.cc b/gcc/function.cc
index 5498a712c4a..6474a663b30 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -6249,10 +6249,15 @@ thread_prologue_and_epilogue_insns (void)
 	}
 }
 
-  /* Threading the prologue and epilogue changes the artificial refs
- in the entry and exit blocks.  */
-  epilogue_completed = 1;
-  df_update_entry_exit_and_calls ();
+  /* Threading the prologue and epilogue changes the artificial refs in the
+ entry and exit blocks, and may invalidate DF info for tail calls.  */
+  if (optimize)
+df_update_entry_exit_and_calls ();
+  else
+{
+  df_update_entry_block_defs ();
+  df_update_exit_block_uses ();
+}
 }
 
 /* Reposition the prologue-end and epilogue-begin notes after


[PATCH] c++, v2: Improve handling of foreigner namespace attributes

2022-10-06 Thread Jakub Jelinek via Gcc-patches
On Thu, Oct 06, 2022 at 09:42:47AM -0400, Jason Merrill wrote:
> > -  tree t = lookup_attribute ("fallthrough", attr);
> > +  tree t = lookup_attribute (NULL, "fallthrough", attr);
> > +  if (t == NULL_TREE)
> > +t = lookup_attribute ("gnu", "fallthrough", attr);
> 
> Maybe lookup_attribute with a magic namespace argument that matches either
> null or gnu?
> 
> And similarly, a new is_attribute_namespace (name, t) function with the same
> behavior, to be used here and in all the below hunks?

So like this?

2022-10-05  Jakub Jelinek  

gcc/
* attribs.h (is_attribute_namespace_p): New inline function.
(lookup_attribute): Document meaning of ATTR_NS equal to "".
* attribs.cc (remove_attribute): Use is_attribute_namespace_p.
(private_lookup_attribute): For ATTR_NS "" match either standard
attribute or "gnu" namespace one.
gcc/c-family/
* c-common.cc (attribute_fallthrough_p): Lookup fallthrough attribute
only in gnu namespace or as standard attribute, treat fallthrough
attributes in other namespaces like any other unknown attribute.
gcc/cp/
* parser.cc (cp_parser_check_std_attribute): Only do checks if
attribute is a standard attribute or in gnu namespace and only
lookup other attributes in those namespaces.
* cp-gimplify.cc (lookup_hotness_attribute): Adjust function comment.
Only return true for standard attribute or gnu namespace attribute.
(remove_hotness_attribute): Only remove hotness attributes when
they are standard or in gnu namespace, implement it in a single
loop rather than former 4 now 8 remove_attribute calls.
gcc/testsuite/
* g++.dg/cpp1z/fallthrough2.C: New test.
* g++.dg/cpp2a/attr-likely7.C: New test.

--- gcc/attribs.h.jj2022-10-05 16:15:29.834889059 +0200
+++ gcc/attribs.h   2022-10-06 17:59:56.918430468 +0200
@@ -188,6 +188,21 @@ is_attribute_p (const char *attr_name, c
  IDENTIFIER_POINTER (ident), IDENTIFIER_LENGTH (ident));
 }
 
+/* Given an identifier node IDENT or NULL and a string ATTR_NS, return true
+   if the identifier node is a valid attribute namespace for the string.
+   ATTR_NS "" stands for standard attribute (NULL IDENT) or "gnu"
+   namespace.  */
+
+static inline bool
+is_attribute_namespace_p (const char *attr_ns, const_tree ident)
+{
+  if (attr_ns == NULL)
+return ident == NULL_TREE;
+  if (attr_ns[0])
+return ident && is_attribute_p (attr_ns, ident);
+  return ident == NULL_TREE || is_attribute_p ("gnu", ident);
+}
+
 /* Given an attribute name ATTR_NAME and a list of attributes LIST,
return a pointer to the attribute's list element if the attribute
is part of the list, or NULL_TREE if not found.  If the attribute
@@ -217,7 +232,8 @@ lookup_attribute (const char *attr_name,
 }
 }
 
-/* Similar to lookup_attribute, but also match the attribute namespace.  */
+/* Similar to lookup_attribute, but also match the attribute namespace.
+   ATTR_NS "" stands for either standard attribute or "gnu" namespace.  */
 
 static inline tree
 lookup_attribute (const char *attr_ns, const char *attr_name, tree list)
--- gcc/attribs.cc.jj   2022-10-04 23:13:10.289090796 +0200
+++ gcc/attribs.cc  2022-10-06 18:01:32.096146195 +0200
@@ -1645,7 +1645,8 @@ remove_attribute (const char *attr_name,
   return list;
 }
 
-/* Similarly but also match namespace on the removed attributes.  */
+/* Similarly but also match namespace on the removed attributes.
+   ATTR_NS "" stands for NULL or "gnu" namespace.  */
 
 tree
 remove_attribute (const char *attr_ns, const char *attr_name, tree list)
@@ -1662,8 +1663,7 @@ remove_attribute (const char *attr_ns, c
   if (is_attribute_p (attr_name, attr))
{
  tree ns = get_attribute_namespace (l);
- if ((ns == NULL_TREE && attr_ns == NULL)
- || (ns && attr_ns && is_attribute_p (attr_ns, ns)))
+ if (is_attribute_namespace_p (attr_ns, ns))
{
  *p = TREE_CHAIN (l);
  continue;
@@ -2088,14 +2088,20 @@ private_lookup_attribute (const char *at
  tree ns = get_attribute_namespace (list);
  if (ns == NULL_TREE)
{
- if (attr_ns == NULL)
+ if (attr_ns_len == 0)
break;
}
  else if (attr_ns)
{
  ident_len = IDENTIFIER_LENGTH (ns);
- if (cmp_attribs (attr_ns, attr_ns_len, IDENTIFIER_POINTER (ns),
-  ident_len))
+ if (attr_ns_len == 0)
+   {
+ if (cmp_attribs ("gnu", strlen ("gnu"),
+  IDENTIFIER_POINTER (ns), ident_len))
+   break;
+   }
+ else if (cmp_attribs (attr_ns, attr_ns_len,
+   IDENTIFIER_POINTER (ns), ident_len))
break;
}
}
--- gcc/c-family/c-common.cc.jj 

Re: [PING 2] [PATCH] libstdc++: basic_filebuf: don't flush more often than necessary.

2022-10-06 Thread Jonathan Wakely via Gcc-patches
On Thu, 6 Oct 2022 at 17:33, Charles-François Natali
 wrote:
>
> On Thu, Oct 6, 2022, 14:29 Jonathan Wakely  wrote:
>>
>> Sorry for the lack of review. I've been trying to remember (and find)
>> some previous discussions related to this topic, but haven't managed
>> to find it yet.
>
>
> No worries!
>
>
>>
>> The patch does look sensible (and is the same as the one attached to
>> PR 63746) so I'll make sure to review it in time for the GCC 13
>> cut-off.
>>
>> I noticed that you contributed your test case with a FSF copyright
>> assignment header. Do you actually have a copyright assignment for GCC
>> contributions? If not, you would either need to complete that
>> paperwork with the FSF, or alternatively just contribute under the DCO
>> terms instead: https://gcc.gnu.org/dco.html
>
>
>
> I actually just copy-pasted the header from another test, would it be simpler 
> if i just removed it?


Yes, that's probably the simplest solution, and then add a
Signed-off-by: tag in your patch email, to state you're contributing
it under the DCO terms (assuming of course that you are willing and
able to certify those terms).



Re: [PATCH] undef offsetof before defining it in stddef.h

2022-10-06 Thread Olivier Hainque via Gcc-patches



> On 6 Oct 2022, at 14:17, Richard Biener  wrote:
>> 
>> Ok to commit?
> 
> OK.

Thanks!



Re: [PATCH] Introduce DWARF_VERSION_DEFAULT (and redefine for VxWorks)

2022-10-06 Thread Olivier Hainque via Gcc-patches



> On 6 Oct 2022, at 14:15, Richard Biener  wrote:
> 
>> Is this ok to commit?
> 
> I think this is reasonable, thus OK.

Great, thanks Richard :-)




Re: [PING 2] [PATCH] libstdc++: basic_filebuf: don't flush more often than necessary.

2022-10-06 Thread Charles-François Natali via Gcc-patches
On Thu, Oct 6, 2022, 14:29 Jonathan Wakely  wrote:

> Sorry for the lack of review. I've been trying to remember (and find)
> some previous discussions related to this topic, but haven't managed
> to find it yet.
>

No worries!



> The patch does look sensible (and is the same as the one attached to
> PR 63746) so I'll make sure to review it in time for the GCC 13
> cut-off.
>
> I noticed that you contributed your test case with a FSF copyright
> assignment header. Do you actually have a copyright assignment for GCC
> contributions? If not, you would either need to complete that
> paperwork with the FSF, or alternatively just contribute under the DCO
> terms instead: https://gcc.gnu.org/dco.html



I actually just copy-pasted the header from another test, would it be
simpler if i just removed it?

Cheers,


Charles



>
>
> On Thu, 6 Oct 2022 at 14:24, Charles-François Natali via Libstdc++
>  wrote:
> >
> > On Thu, Sep 22, 2022, 17:51 Charles-François Natali  >
> > wrote:
> >
> > >
> > > On Mon, Sep 5, 2022, 23:51 Charles-Francois Natali <
> cf.nat...@gmail.com>
> > > wrote:
> > >
> > >> `basic_filebuf::xsputn` would bypass the buffer when passed a chunk of
> > >> size 1024 and above, seemingly as an optimisation.
> > >>
> > >> This can have a significant performance impact if the overhead of a
> > >> `write` syscall is non-negligible, e.g. on a slow disk, on network
> > >> filesystems, or simply during IO contention because instead of
> flushing
> > >> every `BUFSIZ` (by default), we can flush every 1024 char.
> > >> The impact is even greater with custom larger buffers, e.g. for
> network
> > >> filesystems, because the code could issue `write` for example 1000X
> more
> > >> often than necessary with respect to the buffer size.
> > >> It also introduces a significant discontinuity in performance when
> > >> writing chunks of size 1024 and above.
> > >>
> > >> See this reproducer which writes down a fixed number of chunks to a
> file
> > >> open with `O_SYNC` - to replicate high-latency `write` - for varying
> > >> size of chunks:
> > >>
> > >> ```
> > >> $ cat test_fstream_flush.cpp
> > >>
> > >> int
> > >> main(int argc, char* argv[])
> > >> {
> > >>   assert(argc == 3);
> > >>
> > >>   const auto* path = argv[1];
> > >>   const auto chunk_size = std::stoul(argv[2]);
> > >>
> > >>   const auto fd =
> > >> open(path, O_CREAT | O_TRUNC | O_WRONLY | O_SYNC | O_CLOEXEC,
> 0666);
> > >>   assert(fd >= 0);
> > >>
> > >>   auto filebuf = __gnu_cxx::stdio_filebuf(fd,
> std::ios_base::out);
> > >>   auto stream = std::ostream();
> > >>
> > >>   const auto chunk = std::vector(chunk_size);
> > >>
> > >>   for (auto i = 0; i < 1'000; ++i) {
> > >> stream.write(chunk.data(), chunk.size());
> > >>   }
> > >>
> > >>   return 0;
> > >> }
> > >> ```
> > >>
> > >> ```
> > >> $ g++ -o /tmp/test_fstream_flush test_fstream_flush.cpp -std=c++17
> > >> $ for i in $(seq 1021 1025); do echo -e "\n$i"; time
> > >> /tmp/test_fstream_flush /tmp/foo $i; done
> > >>
> > >> 1021
> > >>
> > >> real0m0.997s
> > >> user0m0.000s
> > >> sys 0m0.038s
> > >>
> > >> 1022
> > >>
> > >> real0m0.939s
> > >> user0m0.005s
> > >> sys 0m0.032s
> > >>
> > >> 1023
> > >>
> > >> real0m0.954s
> > >> user0m0.005s
> > >> sys 0m0.034s
> > >>
> > >> 1024
> > >>
> > >> real0m7.102s
> > >> user0m0.040s
> > >> sys 0m0.192s
> > >>
> > >> 1025
> > >>
> > >> real0m7.204s
> > >> user0m0.025s
> > >> sys 0m0.209s
> > >> ```
> > >>
> > >> See the huge drop in performance at the 1024-boundary.
> > >>
> > >> An `strace` confirms that from size 1024 we effectively defeat
> > >> buffering:
> > >> 1023-sized writes
> > >> ```
> > >> $ strace -P /tmp/foo -e openat,write,writev /tmp/test_fstream_flush
> > >> /tmp/foo 1023 2>&1 | head -n5
> > >> openat(AT_FDCWD, "/tmp/foo",
> O_WRONLY|O_CREAT|O_TRUNC|O_SYNC|O_CLOEXEC,
> > >> 0666) = 3
> > >> writev(3,
> > >>
> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> > >> iov_len=8184},
> > >>
> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> > >> iov_len=1023}], 2) = 9207
> > >> writev(3,
> > >>
> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> > >> iov_len=8184},
> > >>
> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> > >> iov_len=1023}], 2) = 9207
> > >> writev(3,
> > >>
> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> > >> iov_len=8184},
> > >>
> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> > >> iov_len=1023}], 2) = 9207
> > >> writev(3,
> > >>
> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> > >> iov_len=8184},
> > >>
> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> > >> iov_len=1023}], 2) = 9207
> > >> ```
> > >>
> > >> vs 1024-sized writes
> > >> ```
> > >> $ strace -P 

Re: [Patch] openmp: Map holds clause to IFN_ASSUME for Fortran

2022-10-06 Thread Jakub Jelinek via Gcc-patches
On Thu, Oct 06, 2022 at 06:15:52PM +0200, Tobias Burnus wrote:
> On 06.10.22 14:17, Jakub Jelinek wrote:
> > On Thu, Oct 06, 2022 at 12:55:01PM +0200, Tobias Burnus wrote:
> > > I don't know whether it makes sense to handle – in the long run – the
> > > case of se.pre/se.post being nonempty – and, if so, how.
> > I think it is essential not to throw those away,
> > if se.pre or se.post, you can e.g. expand it roughly as C/C++ ({ cond; }),
> > in GENERIC it can be say a TARGET_EXPR with a boolean
> > temporary as slot, where the the initializer will be the
> > se.pre part, followed by MODIFY_EXPR which sets the slot to se.expr
> > value and followed by se.post.
> 
> Like as attached? – It did survive regtesting.

LGTM, thanks.

> BTW: The assumption in assume-4.f90 does not help, but I think that's
> expected. I wonder whether it will work in both cases after your
> gimplify work.

Well, gimplify + gimple-lower but more importantly ranger work later on,
at least that's the hope...

Jakub



[PATCH] c++ modules: static var in inline function [PR104433]

2022-10-06 Thread Patrick Palka via Gcc-patches
The below testcase fails to link with the error

  undefined reference to `f()::y'

ultimately because during stream out for the static VAR_DECL y we
override DECL_EXTERNAL to true, which later during IPA confuses
symbol_table::remove_unreachable_nodes into thinking it's safe
to not emit the symbol.

The streaming code in question already avoids overriding DECL_EXTERNAL
here for DECL_VAR_DECLARED_INLINE_P vars, so it seems natural to do the
same for static vars from an DECL_DECLARED_INLINE_P function scope.

After this patch (and r13-3134-g09df0d8b14dda6), the following now
links:

  import ;
  int main() { std::make_shared(); }

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

PR c++/104433

gcc/cp/ChangeLog:

* module.cc (trees_out::core_bools): Don't override
DECL_EXTERNAL to true for static variables from an inline
function.

gcc/testsuite/ChangeLog:

* g++.dg/modules/static-2_a.H: New test.
* g++.dg/modules/static-2_b.C: New test.
---
 gcc/cp/module.cc  | 3 +++
 gcc/testsuite/g++.dg/modules/static-2_a.H | 8 
 gcc/testsuite/g++.dg/modules/static-2_b.C | 9 +
 3 files changed, 20 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/modules/static-2_a.H
 create mode 100644 gcc/testsuite/g++.dg/modules/static-2_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 79cbb346ffa..11f68794cd2 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -5397,6 +5397,9 @@ trees_out::core_bools (tree t)
 
case VAR_DECL:
  if (TREE_PUBLIC (t)
+ && !(TREE_STATIC (t)
+  && DECL_FUNCTION_SCOPE_P (t)
+  && DECL_DECLARED_INLINE_P (DECL_CONTEXT (t)))
  && !DECL_VAR_DECLARED_INLINE_P (t))
is_external = true;
  break;
diff --git a/gcc/testsuite/g++.dg/modules/static-2_a.H 
b/gcc/testsuite/g++.dg/modules/static-2_a.H
new file mode 100644
index 000..b4546932a12
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/static-2_a.H
@@ -0,0 +1,8 @@
+// PR c++/104433
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+inline int* f() {
+  static int y = 0;
+  return 
+}
diff --git a/gcc/testsuite/g++.dg/modules/static-2_b.C 
b/gcc/testsuite/g++.dg/modules/static-2_b.C
new file mode 100644
index 000..bfd35b0fc15
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/static-2_b.C
@@ -0,0 +1,9 @@
+// PR c++/104433
+// { dg-additional-options -fmodules-ts }
+// { dg-do link }
+
+import "static-2_a.H";
+
+int main() {
+  f();
+}
-- 
2.38.0.rc2



Re: [Patch] openmp: Map holds clause to IFN_ASSUME for Fortran

2022-10-06 Thread Tobias Burnus

On 06.10.22 14:17, Jakub Jelinek wrote:

On Thu, Oct 06, 2022 at 12:55:01PM +0200, Tobias Burnus wrote:

I don't know whether it makes sense to handle – in the long run – the
case of se.pre/se.post being nonempty – and, if so, how.

I think it is essential not to throw those away,
if se.pre or se.post, you can e.g. expand it roughly as C/C++ ({ cond; }),
in GENERIC it can be say a TARGET_EXPR with a boolean
temporary as slot, where the the initializer will be the
se.pre part, followed by MODIFY_EXPR which sets the slot to se.expr
value and followed by se.post.


Like as attached? – It did survive regtesting.

BTW: The assumption in assume-4.f90 does not help, but I think that's
expected. I wonder whether it will work in both cases after your
gimplify work.

Tobias
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
openmp: Map holds clause to IFN_ASSUME for Fortran

Same as r13-3107-g847f5addc4d07a2f3b95f5daa50ab4a64dfd957d did for C/C++.
Convert '!$omp assume holds(cond)' to IFN_ASSUME (cond).

gcc/fortran/
	* trans-openmp.cc (gfc_trans_omp_assume): New.
	(gfc_trans_omp_directive): Call it.

gcc/teststuite/
	* gfortran.dg/gomp/assume-3.f90: New test.
	* gfortran.dg/gomp/assume-4.f90: New test.

 gcc/fortran/trans-openmp.cc | 37 +-
 gcc/testsuite/gfortran.dg/gomp/assume-3.f90 | 46 +++
 gcc/testsuite/gfortran.dg/gomp/assume-4.f90 | 48 +
 3 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 21053694f81..8ea573f7d02 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -4570,6 +4570,41 @@ gfc_trans_oacc_wait_directive (gfc_code *code)
 static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
 static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
 
+static tree
+gfc_trans_omp_assume (gfc_code *code)
+{
+  stmtblock_t block;
+  gfc_init_block ();
+  gfc_omp_assumptions *assume = code->ext.omp_clauses->assume;
+  if (assume)
+for (gfc_expr_list *el = assume->holds; el; el = el->next)
+  {
+	location_t loc = gfc_get_location (>expr->where);
+	gfc_se se;
+	gfc_init_se (, NULL);
+	gfc_conv_expr (, el->expr);
+	tree t;
+	if (se.pre.head == NULL_TREE && se.post.head == NULL_TREE)
+	  t = se.expr;
+	else
+	  {
+	tree var = gfc_create_var (TREE_TYPE (se.expr), NULL);
+	stmtblock_t block2;
+	gfc_init_block ();
+	gfc_add_block_to_block (, );
+	gfc_add_modify_loc (loc, , var, se.expr);
+	gfc_add_block_to_block (, );
+	t = gfc_finish_block ();
+	t = build4 (TARGET_EXPR, boolean_type_node, var, t, NULL, NULL);
+	  }
+	t = build_call_expr_internal_loc (loc, IFN_ASSUME,
+	  void_type_node, 1, t);
+	gfc_add_expr_to_block (, t);
+  }
+  gfc_add_expr_to_block (, gfc_trans_omp_code (code->block->next, true));
+  return gfc_finish_block ();
+}
+
 static tree
 gfc_trans_omp_atomic (gfc_code *code)
 {
@@ -7488,7 +7523,7 @@ gfc_trans_omp_directive (gfc_code *code)
   switch (code->op)
 {
 case EXEC_OMP_ASSUME:
-  return gfc_trans_omp_code (code->block->next, true);
+  return gfc_trans_omp_assume (code);
 case EXEC_OMP_ATOMIC:
   return gfc_trans_omp_atomic (code);
 case EXEC_OMP_BARRIER:
diff --git a/gcc/testsuite/gfortran.dg/gomp/assume-3.f90 b/gcc/testsuite/gfortran.dg/gomp/assume-3.f90
new file mode 100644
index 000..e5deace306e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/assume-3.f90
@@ -0,0 +1,46 @@
+! { dg-do compile }
+! { dg-options "-fopenmp -O2 -fdump-tree-optimized -fdump-tree-original" }
+
+! { dg-final { scan-tree-dump-times ".ASSUME \\(x == 42\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times ".ASSUME \\(x <= 41\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times ".ASSUME \\(y <= 6\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times ".ASSUME \\(y > 5\\);" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "return 42;" 3 "optimized" } }
+! { dg-final { scan-tree-dump-not "return -1;" "optimized" } }
+
+integer function foo (x)
+  implicit none
+  integer, value :: x
+  integer :: y
+  !$omp assume holds (x == 42)
+y = x;
+  !$omp end assume
+  foo = y
+end
+
+integer function bar (x)
+  implicit none
+  integer, value :: x
+  !$omp assume holds (x < 42)
+  block
+  end block
+  if (x == 42) then
+bar = -1
+return
+  end if
+  bar = 42
+end
+
+integer function foobar (y)
+  implicit none
+  integer, value :: y
+  !$omp assume holds(y > 5) holds (y < 7)
+  block
+if (y == 6) then
+  foobar = 42
+  return
+end if
+  end block
+  foobar = -1
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/assume-4.f90 b/gcc/testsuite/gfortran.dg/gomp/assume-4.f90
new file 

gcc-12: FTBFS on hurd-i386

2022-10-06 Thread Svante Signell via Gcc-patches
Source: gcc-12
Version: 12_12.2.0-5
Severity: important
Tags: patch
User: debian-h...@lists.debian.org
Usertags: hurd
Affects: gcc-11, gcc-snapshot
X-Debbugs-CC: debian-h...@lists.debian.org

Hi,

gcc-12-12.2.0-4/5 in sid FTBFS on hurd-i386 due to failing linkage of
pthread_once (same error for gcc-11, gcc-12, gcc-snapshot):
/<>/build/i686-gnu/libstdc++-v3/include/i686-gnu/bits/gthr-
default.h:700: undefined reference to `pthread_once'

Patches have already submitted upstream by Samuel Thibault in August and
September, see
https://gcc.gnu.org/pipermail/gcc-patches/2022-August/600469.html
https://gcc.gnu.org/pipermail/gcc-patches/2022-September/601754.html

Unfortunately upstream is not very responsive. Therefore I have taken the time
to send these patches to Debian in the mean time.

Patches extracted and attached from that mail message are:
1.diff-6.diff. Note that 1.diff does not apply to gcc-12, it is related to the
git repo. This is reflected in attached debian_rules.patch by commenting out
1.diff.

Just a reflection: Matthias you are really doing a great job with the
gcc releases: Kudos!

Thanks!

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ba5939d9003..dd288cce2ca 100644
--- a/src/libstdc++-v3/ChangeLog
+++ b/src/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2022-08-28  Samuel Thibault  
+
+   * config/os/gnu/os_defines.h: New file.
+   * config/os/gnu/ctype_base.h: New file.
+   * config/os/gnu/ctype_configure_char.cc: New file.
+   * config/os/gnu/ctype_inline.h: New file.
+   * configure.host: On gnu* host, use os/gnu instead of os/gnu-linux.
+
 2022-08-27  Patrick Palka  
diff --git a/src/libstdc++-v3/config/os/gnu/ctype_base.h b/src/libstdc++-v3/config/os/gnu/ctype_base.h
new file mode 100644
index 000..955146543db
--- /dev/null
+++ b/src/libstdc++-v3/config/os/gnu/ctype_base.h
@@ -0,0 +1,66 @@
+// Locale support -*- C++ -*-
+
+// Copyright (C) 1997-2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// .
+
+/** @file bits/ctype_base.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{locale}
+ */
+
+//
+// ISO C++ 14882: 22.1  Locales
+//
+
+// Information as gleaned from /usr/include/ctype.h
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /// @brief  Base class for ctype.
+  struct ctype_base
+  {
+// Non-standard typedefs.
+typedef const int* 		__to_type;
+
+// NB: Offsets into ctype::_M_table force a particular size
+// on the mask type. Because of this, we don't use an enum.
+typedef unsigned short 	mask;
+static const mask upper	= _ISupper;
+static const mask lower 	= _ISlower;
+static const mask alpha 	= _ISalpha;
+static const mask digit 	= _ISdigit;
+static const mask xdigit 	= _ISxdigit;
+static const mask space 	= _ISspace;
+static const mask print 	= _ISprint;
+static const mask graph 	= _ISalpha | _ISdigit | _ISpunct;
+static const mask cntrl 	= _IScntrl;
+static const mask punct 	= _ISpunct;
+static const mask alnum 	= _ISalpha | _ISdigit;
+#if __cplusplus >= 201103L
+static const mask blank	= _ISblank;
+#endif
+  };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/src/libstdc++-v3/config/os/gnu/ctype_configure_char.cc b/src/libstdc++-v3/config/os/gnu/ctype_configure_char.cc
new file mode 100644
index 000..5a88fc11ab3
--- /dev/null
+++ b/src/libstdc++-v3/config/os/gnu/ctype_configure_char.cc
@@ -0,0 +1,196 @@
+// Locale support -*- C++ -*-
+
+// Copyright (C) 2011-2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but 

Re: [PATCH v2] c++: fixes for derived-to-base reference binding [PR107085]

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/6/22 10:49, Marek Polacek wrote:

On Wed, Oct 05, 2022 at 08:25:29PM -0400, Jason Merrill wrote:

On 10/5/22 17:27, Marek Polacek wrote:

This PR reports that

struct Base {};
struct Derived : Base {};
static_assert(__reference_constructs_from_temporary(Base const&, Derived));

doesn't pass, which it should: it's just like

const Base& b(Derived{});

where we bind 'b' to the Base subobject of a temporary object of type
Derived.  The ck_base conversion didn't have ->need_temporary_p set because
we didn't need to create a temporary object just for the base, but the whole
object is a temporary so we're still binding to a temporary.  Fixed by
the conv_is_prvalue hunk.

That broke a bunch of tests.  I've distilled the issue into a simple test
in elision4.C.  Essentially, we have

struct B { /* ... */ };
struct D : B { };
B b = D();

and we set force_elide in build_over_call, but we're unable to actually
elide the B::B(B&&) call, and crash on gcc_assert (!force_elide);.

 says that copy
elision "can only apply when the object being initialized is known not to be
a potentially-overlapping subobject".  So I suppose we shouldn't force_elide
the B::B(B&&) call.  I don't belive the CWG 2327 code was added to handle
derived-to-base conversions, at that time conv_binds_ref_to_prvalue wasn't
checking ck_base at all.

Does that make sense?  If so...

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

PR c++/107085

gcc/cp/ChangeLog:

* call.cc (conv_is_prvalue): Return true if the base subobject is part
of a temporary object.


No, the base subobject of a prvalue is an xvalue.


Ah, so this is just like T().m where T() is a prvalue but the whole thing
is an xvalue.  Duly noted.


Exactly.


I think the problem is that an expression being a prvalue is a subset of
binding a reference to a temporary, and we shouldn't try to express both of
those using the same function: you need a separate
conv_binds_ref_to_temporary.


Ack, so how about this?  Thanks,

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

-- >8 --
This PR reports that

   struct Base {};
   struct Derived : Base {};
   static_assert(__reference_constructs_from_temporary(Base const&, Derived));

doesn't pass, which it should: it's just like

   const Base& b(Derived{});

where we bind 'b' to the Base subobject of a temporary object of type
Derived.  The ck_base conversion didn't have ->need_temporary_p set because
we didn't need to create a temporary object just for the base, but the whole
object is a temporary so we're still binding to a temporary.  Since the
Base subobject is an xvalue, a new function is introduced.

PR c++/107085

gcc/cp/ChangeLog:

* call.cc (conv_binds_ref_to_temporary): New.
(ref_conv_binds_directly): Use it.

gcc/testsuite/ChangeLog:

* g++.dg/ext/reference_constructs_from_temporary1.C: Adjust expected
result.
* g++.dg/ext/reference_converts_from_temporary1.C: Likewise.
* g++.dg/cpp0x/elision4.C: New test.
---
  gcc/cp/call.cc| 23 ++-
  gcc/testsuite/g++.dg/cpp0x/elision4.C | 15 
  .../reference_constructs_from_temporary1.C|  2 +-
  .../ext/reference_converts_from_temporary1.C  |  2 +-
  4 files changed, 39 insertions(+), 3 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision4.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index bd04a1d309a..715a83f5a69 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9210,6 +9210,27 @@ conv_binds_ref_to_prvalue (conversion *c)
return conv_is_prvalue (next_conversion (c));
  }
  
+/* True iff C is a conversion that binds a reference to a temporary.

+   This is a superset of conv_binds_ref_to_prvalue: here we're also
+   interested in xvalues.  */
+
+static bool
+conv_binds_ref_to_temporary (conversion *c)
+{
+  if (conv_binds_ref_to_prvalue (c))
+return true;
+  if (c->kind != ck_ref_bind)
+return false;
+  c = next_conversion (c);
+  /* This is the case for
+   struct Base {};
+   struct Derived : Base {};
+   const Base& b(Derived{});
+ where we bind 'b' to the Base subobject of a temporary object of type
+ Derived.  The subobject is an xvalue; the whole object is a prvalue.  */
+  return (c->kind == ck_base && conv_is_prvalue (next_conversion (c)));


I think you also want to check for the case of c->u.expr being a 
COMPONENT_REF/ARRAY_REF around a TARGET_EXPR, as you mentioned.



+}
+
  /* Return tristate::TS_TRUE if converting EXPR to a reference type TYPE does
 not involve creating a temporary.  Return tristate::TS_FALSE if converting
 EXPR to a reference type TYPE binds the reference to a temporary.  If the
@@ -9230,7 +9251,7 @@ ref_conv_binds_directly (tree type, tree expr, bool 
direct_init_p /*= false*/)
  /*c_cast_p=*/false, 

[PATCH v2] c++: fixes for derived-to-base reference binding [PR107085]

2022-10-06 Thread Marek Polacek via Gcc-patches
On Wed, Oct 05, 2022 at 08:25:29PM -0400, Jason Merrill wrote:
> On 10/5/22 17:27, Marek Polacek wrote:
> > This PR reports that
> > 
> >struct Base {};
> >struct Derived : Base {};
> >static_assert(__reference_constructs_from_temporary(Base const&, 
> > Derived));
> > 
> > doesn't pass, which it should: it's just like
> > 
> >const Base& b(Derived{});
> > 
> > where we bind 'b' to the Base subobject of a temporary object of type
> > Derived.  The ck_base conversion didn't have ->need_temporary_p set because
> > we didn't need to create a temporary object just for the base, but the whole
> > object is a temporary so we're still binding to a temporary.  Fixed by
> > the conv_is_prvalue hunk.
> > 
> > That broke a bunch of tests.  I've distilled the issue into a simple test
> > in elision4.C.  Essentially, we have
> > 
> >struct B { /* ... */ };
> >struct D : B { };
> >B b = D();
> > 
> > and we set force_elide in build_over_call, but we're unable to actually
> > elide the B::B(B&&) call, and crash on gcc_assert (!force_elide);.
> > 
> >  says that copy
> > elision "can only apply when the object being initialized is known not to be
> > a potentially-overlapping subobject".  So I suppose we shouldn't force_elide
> > the B::B(B&&) call.  I don't belive the CWG 2327 code was added to handle
> > derived-to-base conversions, at that time conv_binds_ref_to_prvalue wasn't
> > checking ck_base at all.
> > 
> > Does that make sense?  If so...
> > 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > PR c++/107085
> > 
> > gcc/cp/ChangeLog:
> > 
> > * call.cc (conv_is_prvalue): Return true if the base subobject is part
> > of a temporary object.
> 
> No, the base subobject of a prvalue is an xvalue.

Ah, so this is just like T().m where T() is a prvalue but the whole thing
is an xvalue.  Duly noted.
 
> I think the problem is that an expression being a prvalue is a subset of
> binding a reference to a temporary, and we shouldn't try to express both of
> those using the same function: you need a separate
> conv_binds_ref_to_temporary.

Ack, so how about this?  Thanks,

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

-- >8 --
This PR reports that

  struct Base {};
  struct Derived : Base {};
  static_assert(__reference_constructs_from_temporary(Base const&, Derived));

doesn't pass, which it should: it's just like

  const Base& b(Derived{});

where we bind 'b' to the Base subobject of a temporary object of type
Derived.  The ck_base conversion didn't have ->need_temporary_p set because
we didn't need to create a temporary object just for the base, but the whole
object is a temporary so we're still binding to a temporary.  Since the
Base subobject is an xvalue, a new function is introduced.

PR c++/107085

gcc/cp/ChangeLog:

* call.cc (conv_binds_ref_to_temporary): New.
(ref_conv_binds_directly): Use it.

gcc/testsuite/ChangeLog:

* g++.dg/ext/reference_constructs_from_temporary1.C: Adjust expected
result.
* g++.dg/ext/reference_converts_from_temporary1.C: Likewise.
* g++.dg/cpp0x/elision4.C: New test.
---
 gcc/cp/call.cc| 23 ++-
 gcc/testsuite/g++.dg/cpp0x/elision4.C | 15 
 .../reference_constructs_from_temporary1.C|  2 +-
 .../ext/reference_converts_from_temporary1.C  |  2 +-
 4 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/elision4.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index bd04a1d309a..715a83f5a69 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9210,6 +9210,27 @@ conv_binds_ref_to_prvalue (conversion *c)
   return conv_is_prvalue (next_conversion (c));
 }
 
+/* True iff C is a conversion that binds a reference to a temporary.
+   This is a superset of conv_binds_ref_to_prvalue: here we're also
+   interested in xvalues.  */
+
+static bool
+conv_binds_ref_to_temporary (conversion *c)
+{
+  if (conv_binds_ref_to_prvalue (c))
+return true;
+  if (c->kind != ck_ref_bind)
+return false;
+  c = next_conversion (c);
+  /* This is the case for
+   struct Base {};
+   struct Derived : Base {};
+   const Base& b(Derived{});
+ where we bind 'b' to the Base subobject of a temporary object of type
+ Derived.  The subobject is an xvalue; the whole object is a prvalue.  */
+  return (c->kind == ck_base && conv_is_prvalue (next_conversion (c)));
+}
+
 /* Return tristate::TS_TRUE if converting EXPR to a reference type TYPE does
not involve creating a temporary.  Return tristate::TS_FALSE if converting
EXPR to a reference type TYPE binds the reference to a temporary.  If the
@@ -9230,7 +9251,7 @@ ref_conv_binds_directly (tree type, tree expr, bool 
direct_init_p /*= false*/)
  /*c_cast_p=*/false, flags, tf_none);
   tristate ret 

[RFC] c++: parser - Support for target address spaces in C++

2022-10-06 Thread Paul Iannetta via Gcc-patches
Hi,

Presently, GCC supports target address spaces as a GNU extension (cf.
`info -n "(gcc)Named Address Spaces"`).  This is however supported
only by the C frontend, which is a bit sad, since all the GIMPLE
machinery is readily available and, moreover, LLVM supports this GNU
extension both for C and C++.

Here is a first attempt at a patch to enable the support for target
address spaces in C++.  The basic idea is only to make the parser
recognize address spaces, and lower them into GIMPLE, in the same
fashion as the C parser.  This also makes it possible to merge the
function `c_register_addr_space` in one place which is better than
before.

The patch still has some drawbacks compared to its C counterpart.
Namely, much like the `__restrict__` keyword, it is always enabled and
-std=c++11 won't disable it (whereas -std=c11) would reject address
spaces.  Not also that the mangler ignores address spaces, much like
it ignores __restrict__.

Depending on the reception, I'll add further testcases and will update
the relevant part of the documentation.

Cheers,
Paul

Author: Paul Iannetta 
Date:   Wed Oct 5 16:44:36 2022 +0200

Add support for custom address spaces in C++

gcc/
* tree.h (ENCODE_QUAL_ADDR_SPACE): Missing parentheses.

gcc/c/
* c-decl.c: Remove c_register_addr_space.

gcc/c-family/
* c-common.c (c_register_addr_space): Imported from c-decl.c
* c-common.h: Remove the FIXME.

gcc/cp/
* cp-tree.h (enum cp_decl_spec): Add addr_space support.
(struct cp_decl_specifier_seq): Likewise.
* decl.c (get_type_quals): Likewise.
* parser.c (cp_parser_type_specifier): Likewise.
(cp_parser_cv_qualifier_seq_opt): Likewise
* tree.c: Remove c_register_addr_space stub.

Signed-off-by: Paul Iannetta 

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 064c2f263f0..282ba54ab70 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2615,6 +2615,25 @@ c_build_bitfield_integer_type (unsigned HOST_WIDE_INT 
width, int unsignedp)
   return build_nonstandard_integer_type (width, unsignedp);
 }
 
+/* Register reserved keyword WORD as qualifier for address space AS.  */
+
+void
+c_register_addr_space (const char *word, addr_space_t as)
+{
+  int rid = RID_FIRST_ADDR_SPACE + as;
+  tree id;
+
+  /* Address space qualifiers are only supported
+ in C with GNU extensions enabled.  */
+  if (c_dialect_objc () || flag_no_asm)
+return;
+
+  id = get_identifier (word);
+  C_SET_RID_CODE (id, rid);
+  TREE_LANG_FLAG_0 (id) = 1;
+  ridpointers[rid] = id;
+}
+
 /* The C version of the register_builtin_type langhook.  */
 
 void
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ed39b7764bf..f2c1df0c8de 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -808,9 +808,6 @@ extern const struct attribute_spec 
c_common_format_attribute_table[];
 
 extern tree (*make_fname_decl) (location_t, tree, int);
 
-/* In c-decl.c and cp/tree.c.  FIXME.  */
-extern void c_register_addr_space (const char *str, addr_space_t as);
-
 /* In c-common.c.  */
 extern bool in_late_binary_op;
 extern const char *c_addr_space_name (addr_space_t as);
@@ -926,6 +923,7 @@ extern void c_common_finish (void);
 extern void c_common_parse_file (void);
 extern FILE *get_dump_info (int, dump_flags_t *);
 extern alias_set_type c_common_get_alias_set (tree);
+extern void c_register_addr_space (const char *, addr_space_t);
 extern void c_register_builtin_type (tree, const char*);
 extern bool c_promoting_integer_type_p (const_tree);
 extern bool self_promoting_args_p (const_tree);
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 8e24b522ee4..278d1248d1c 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -11927,25 +11927,6 @@ c_parse_final_cleanups (void)
   ext_block = NULL;
 }
 
-/* Register reserved keyword WORD as qualifier for address space AS.  */
-
-void
-c_register_addr_space (const char *word, addr_space_t as)
-{
-  int rid = RID_FIRST_ADDR_SPACE + as;
-  tree id;
-
-  /* Address space qualifiers are only supported
- in C with GNU extensions enabled.  */
-  if (c_dialect_objc () || flag_no_asm)
-return;
-
-  id = get_identifier (word);
-  C_SET_RID_CODE (id, rid);
-  C_IS_RESERVED_WORD (id) = 1;
-  ridpointers [rid] = id;
-}
-
 /* Return identifier to look up for omp declare reduction.  */
 
 tree
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 15ec4cd199f..4ae971ccb90 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5974,6 +5974,7 @@ enum cp_decl_spec {
   ds_const,
   ds_volatile,
   ds_restrict,
+  ds_addr_space,
   ds_inline,
   ds_virtual,
   ds_explicit,
@@ -6046,6 +6047,8 @@ struct cp_decl_specifier_seq {
   /* True iff the alternate "__intN__" form of the __intN type has been
  used.  */
   BOOL_BITFIELD int_n_alt: 1;
+  /* The address space that the declaration belongs to.  */
+  addr_space_t address_space;
 };
 
 /* The various kinds of declarators.  */
diff 

Re: [PATCH 2/2] Split edge when edge locus and dest don't match

2022-10-06 Thread Jørgen Kvalsvik via Gcc-patches
On 06/10/2022 10:12, Richard Biener wrote:
> On Wed, Oct 5, 2022 at 2:49 PM Martin Liška  wrote:
>>
>> On 10/5/22 14:04, Jørgen Kvalsvik via Gcc-patches wrote:
>>> Edges with locus are candidates for splitting so that the edge with
>>> locus is the only edge out of a basic block, except when the locuses
>>> match. The test checks the last (non-debug) statement in a basic block,
>>> but this causes an unnecessary split when the edge locus go to a block
>>> which coincidentally has an unrelated label. Comparing the first
>>> statement of the destination block is the same check but does not get
>>> tripped up by labels.
>>>
>>> An example with source/edge/dest locus when an edge is split:
>>>
>>>   1  int fn (int a, int b, int c) {
>>>   2int x = 0;
>>>   3if (a && b) {
>>>   4x = a;
>>>   5} else {
>>>   6  a_:
>>>   7x = (a - b);
>>>   8}
>>>   9
>>>  10return x;
>>>  11  }
>>>
>>> block  file  line   col  stmt
>>>
>>> src t.c 310  if (a_3(D) != 0)
>>> edget.c 6 1
>>> destt.c 6 1  a_:
>>>
>>> src t.c 313  if (b_4(D) != 0)
>>> edget.c 6 1
>>> dst t.c 6 1  a_:
>>>
>>> With label removed:
>>>
>>>   1  int fn (int a, int b, int c) {
>>>   2int x = 0;
>>>   3if (a && b) {
>>>   4x = a;
>>>   5} else {
>>>   6  // a_: <- label removed
>>>   7x = (a - b);
>>>   8}
>>>   9
>>>  10return x;
>>>  11
>>>
>>> block  file  line   col  stmt
>>>
>>> src t.c 310  if (a_3(D) != 0)
>>> edge  (null)0 0
>>> destt.c 6 1  a_:
>>>
>>> src t.c 313  if (b_4(D) != 0)
>>> edge  (null)0 0
>>> dst t.c 6 1  a_:
>>>
>>> and this is extract from gcov-4b.c which *should* split:
>>>
>>> 205  int
>>> 206  test_switch (int i, int j)
>>> 207  {
>>> 208int result = 0;
>>> 209
>>> 210switch (i)/* branch(80 25) */
>>> 211  /* branch(end) */
>>> 212  {
>>> 213case 1:
>>> 214  result = do_something (2);
>>> 215  break;
>>> 216case 2:
>>> 217  result = do_something (1024);
>>> 218  break;
>>> 219case 3:
>>> 220case 4:
>>> 221  if (j == 2) /* branch(67) */
>>> 222  /* branch(end) */
>>> 223return do_something (4);
>>> 224  result = do_something (8);
>>> 225  break;
>>> 226default:
>>> 227  result = do_something (32);
>>> 228  switch_m++;
>>> 229  break;
>>> 230  }
>>> 231return result;
>>> 231  }
>>>
>>> block  file  line   col  stmt
>>>
>>> src4b.c   21418  result_18 = do_something (2);
>>> edge   4b.c   215 9
>>> dst4b.c   23110  _22 = result_3;
>>>
>>> src4b.c   21718  result_16 = do_something (1024);
>>> edge   4b.c   218 9
>>> dst4b.c   23110  _22 = result_3;
>>>
>>> src4b.c   22418  result_12 = do_something (8);
>>> edge   4b.c   225 9
>>> dst4b.c   23110  _22 = result_3;
>>>
>>> Note that the behaviour of comparison is preserved for the (switch) edge
>>> splitting case. The former case now fails the check (even though
>>> e->goto_locus is no longer a reserved location) because the dest matches
>>> the e->locus.
>>
>> It's fine, please install it.
>> I verified tramp3d coverage output is the same as before the patch.
>>
>> Martin
>>
>>>
>>> gcc/ChangeLog:
>>>
>>> * profile.cc (branch_prob): Compare edge locus to dest, not src.
>>> ---
>>>  gcc/profile.cc | 18 +-
>>>  1 file changed, 9 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/gcc/profile.cc b/gcc/profile.cc
>>> index 96121d60711..c13a79a84c2 100644
>>> --- a/gcc/profile.cc
>>> +++ b/gcc/profile.cc
>>> @@ -1208,17 +1208,17 @@ branch_prob (bool thunk)
>>> FOR_EACH_EDGE (e, ei, bb->succs)
>>>   {
>>> gimple_stmt_iterator gsi;
>>> -   gimple *last = NULL;
>>> +   gimple *dest = NULL;
>>>
>>> /* It may happen that there are compiler generated statements
>>>without a locus at all.  Go through the basic block from the
>>>last to the first statement looking for a locus.  */
> 
> The comment no longer matches the code.>
>>> -   for (gsi = gsi_last_nondebug_bb (bb);
>>> +   for (gsi = gsi_start_nondebug_bb (bb);
> 
> ^^^ and you are looking at the branch block stmts (bb), not the destination
> block stmts (e->dest)
> 
>>>  !gsi_end_p (gsi);
>>> -gsi_prev_nondebug ())
>>> +gsi_next_nondebug ())
>>>   {
>>> -

Re: [PATCH] c++: Improve handling of foreigner namespace attributes

2022-10-06 Thread Jason Merrill via Gcc-patches

On 10/5/22 08:04, Jakub Jelinek wrote:

Hi!

The following patch uses the new lookup_attribute overload and extra
tests to avoid emitting weird warnings on foreign namespace attributes
which we should just ignore (perhaps with a warning), but shouldn't
imply any meaning to them just because they have a name matching some
standard or gnu attribute name.

Lightly tested so far, ok for trunk if full bootstrap/regtest succeeds?

2022-10-05  Jakub Jelinek  

gcc/c-family/
* c-common.cc (attribute_fallthrough_p): Lookup fallthrough attribute
only in gnu namespace or as standard attribute, treat fallthrough
attributes in other namespaces like any other unknown attribute.
gcc/cp/
* parser.cc (cp_parser_check_std_attribute): Only do checks if
attribute is a standard attribute or in gnu namespace and only
lookup other attributes in those namespaces.
* cp-gimplify.cc (lookup_hotness_attribute): Adjust function comment.
Only return true for standard attribute or gnu namespace attribute.
(remove_hotness_attribute): Only remove hotness attributes when
they are standard or in gnu namespace, implement it in a single
loop rather than former 4 now 8 remove_attribute calls.
gcc/testsuite/
* g++.dg/cpp1z/fallthrough2.C: New test.
* g++.dg/cpp2a/attr-likely7.C: New test.

--- gcc/c-family/c-common.cc.jj 2022-10-03 18:00:58.548661062 +0200
+++ gcc/c-family/c-common.cc2022-10-05 12:58:08.396043609 +0200
@@ -6007,12 +6007,15 @@ attribute_fallthrough_p (tree attr)
  {
if (attr == error_mark_node)
 return false;
-  tree t = lookup_attribute ("fallthrough", attr);
+  tree t = lookup_attribute (NULL, "fallthrough", attr);
+  if (t == NULL_TREE)
+t = lookup_attribute ("gnu", "fallthrough", attr);


Maybe lookup_attribute with a magic namespace argument that matches 
either null or gnu?



if (t == NULL_TREE)
  return false;
/* It is no longer true that "this attribute shall appear at most once in
   each attribute-list", but we still give a warning.  */
-  if (lookup_attribute ("fallthrough", TREE_CHAIN (t)))
+  if (lookup_attribute (NULL, "fallthrough", TREE_CHAIN (t))
+  || lookup_attribute ("gnu", "fallthrough", TREE_CHAIN (t)))
  warning (OPT_Wattributes, "attribute % specified multiple "
 "times");
/* No attribute-argument-clause shall be present.  */
@@ -6023,9 +6026,11 @@ attribute_fallthrough_p (tree attr)
for (t = attr; t != NULL_TREE; t = TREE_CHAIN (t))
  {
tree name = get_attribute_name (t);
-  if (!is_attribute_p ("fallthrough", name))
+  tree ns = get_attribute_namespace (t);
+  if (!is_attribute_p ("fallthrough", name)
+ || (ns && !is_attribute_p ("gnu", ns)))


And similarly, a new is_attribute_namespace (name, t) function with the 
same behavior, to be used here and in all the below hunks?



{
- if (!c_dialect_cxx () && get_attribute_namespace (t) == NULL_TREE)
+ if (!c_dialect_cxx () && ns == NULL_TREE)
/* The specifications of standard attributes in C mean
   this is a constraint violation.  */
pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
--- gcc/cp/parser.cc.jj 2022-10-05 11:28:28.292141301 +0200
+++ gcc/cp/parser.cc2022-10-05 13:29:38.203433190 +0200
@@ -29265,7 +29265,10 @@ cp_parser_check_std_attribute (location_
if (attributes)
  for (const auto  : alist)
if (is_attribute_p (a, get_attribute_name (attribute))
- && lookup_attribute (a, attributes))
+ && (get_attribute_namespace (attribute) == NULL_TREE
+ || get_attribute_namespace (attribute) == gnu_identifier)
+ && (lookup_attribute (NULL, a, attributes)
+ || lookup_attribute ("gnu", a, attributes)))
{
  if (!from_macro_expansion_at (loc))
warning_at (loc, OPT_Wattributes, "attribute %qs specified "
--- gcc/cp/cp-gimplify.cc.jj2022-10-05 11:19:19.160573401 +0200
+++ gcc/cp/cp-gimplify.cc   2022-10-05 12:53:08.367115180 +0200
@@ -3027,7 +3027,7 @@ cp_fold (tree x)
return x;
  }
  
-/* Look up either "hot" or "cold" in attribute list LIST.  */

+/* Look up "hot", "cold", "likely" or "unlikely" in attribute list LIST.  */
  
  tree

  lookup_hotness_attribute (tree list)
@@ -3039,20 +3039,38 @@ lookup_hotness_attribute (tree list)
  || is_attribute_p ("cold", name)
  || is_attribute_p ("likely", name)
  || is_attribute_p ("unlikely", name))
-   break;
+   {
+ tree ns = get_attribute_namespace (list);
+ if (ns == NULL_TREE || ns == gnu_identifier)
+   break;
+   }
  }
return list;
  }
  
-/* Remove both "hot" and "cold" attributes from LIST.  */

+/* Remove "hot", "cold", "likely" and "unlikely" attributes from LIST.  */
  
  static tree

  remove_hotness_attribute (tree list)
  {
-  list = remove_attribute ("hot", 

Re: [PING 2] [PATCH] libstdc++: basic_filebuf: don't flush more often than necessary.

2022-10-06 Thread Jonathan Wakely via Gcc-patches
Sorry for the lack of review. I've been trying to remember (and find)
some previous discussions related to this topic, but haven't managed
to find it yet.

The patch does look sensible (and is the same as the one attached to
PR 63746) so I'll make sure to review it in time for the GCC 13
cut-off.

I noticed that you contributed your test case with a FSF copyright
assignment header. Do you actually have a copyright assignment for GCC
contributions? If not, you would either need to complete that
paperwork with the FSF, or alternatively just contribute under the DCO
terms instead: https://gcc.gnu.org/dco.html



On Thu, 6 Oct 2022 at 14:24, Charles-François Natali via Libstdc++
 wrote:
>
> On Thu, Sep 22, 2022, 17:51 Charles-François Natali 
> wrote:
>
> >
> > On Mon, Sep 5, 2022, 23:51 Charles-Francois Natali 
> > wrote:
> >
> >> `basic_filebuf::xsputn` would bypass the buffer when passed a chunk of
> >> size 1024 and above, seemingly as an optimisation.
> >>
> >> This can have a significant performance impact if the overhead of a
> >> `write` syscall is non-negligible, e.g. on a slow disk, on network
> >> filesystems, or simply during IO contention because instead of flushing
> >> every `BUFSIZ` (by default), we can flush every 1024 char.
> >> The impact is even greater with custom larger buffers, e.g. for network
> >> filesystems, because the code could issue `write` for example 1000X more
> >> often than necessary with respect to the buffer size.
> >> It also introduces a significant discontinuity in performance when
> >> writing chunks of size 1024 and above.
> >>
> >> See this reproducer which writes down a fixed number of chunks to a file
> >> open with `O_SYNC` - to replicate high-latency `write` - for varying
> >> size of chunks:
> >>
> >> ```
> >> $ cat test_fstream_flush.cpp
> >>
> >> int
> >> main(int argc, char* argv[])
> >> {
> >>   assert(argc == 3);
> >>
> >>   const auto* path = argv[1];
> >>   const auto chunk_size = std::stoul(argv[2]);
> >>
> >>   const auto fd =
> >> open(path, O_CREAT | O_TRUNC | O_WRONLY | O_SYNC | O_CLOEXEC, 0666);
> >>   assert(fd >= 0);
> >>
> >>   auto filebuf = __gnu_cxx::stdio_filebuf(fd, std::ios_base::out);
> >>   auto stream = std::ostream();
> >>
> >>   const auto chunk = std::vector(chunk_size);
> >>
> >>   for (auto i = 0; i < 1'000; ++i) {
> >> stream.write(chunk.data(), chunk.size());
> >>   }
> >>
> >>   return 0;
> >> }
> >> ```
> >>
> >> ```
> >> $ g++ -o /tmp/test_fstream_flush test_fstream_flush.cpp -std=c++17
> >> $ for i in $(seq 1021 1025); do echo -e "\n$i"; time
> >> /tmp/test_fstream_flush /tmp/foo $i; done
> >>
> >> 1021
> >>
> >> real0m0.997s
> >> user0m0.000s
> >> sys 0m0.038s
> >>
> >> 1022
> >>
> >> real0m0.939s
> >> user0m0.005s
> >> sys 0m0.032s
> >>
> >> 1023
> >>
> >> real0m0.954s
> >> user0m0.005s
> >> sys 0m0.034s
> >>
> >> 1024
> >>
> >> real0m7.102s
> >> user0m0.040s
> >> sys 0m0.192s
> >>
> >> 1025
> >>
> >> real0m7.204s
> >> user0m0.025s
> >> sys 0m0.209s
> >> ```
> >>
> >> See the huge drop in performance at the 1024-boundary.
> >>
> >> An `strace` confirms that from size 1024 we effectively defeat
> >> buffering:
> >> 1023-sized writes
> >> ```
> >> $ strace -P /tmp/foo -e openat,write,writev /tmp/test_fstream_flush
> >> /tmp/foo 1023 2>&1 | head -n5
> >> openat(AT_FDCWD, "/tmp/foo", O_WRONLY|O_CREAT|O_TRUNC|O_SYNC|O_CLOEXEC,
> >> 0666) = 3
> >> writev(3,
> >> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=8184},
> >> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=1023}], 2) = 9207
> >> writev(3,
> >> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=8184},
> >> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=1023}], 2) = 9207
> >> writev(3,
> >> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=8184},
> >> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=1023}], 2) = 9207
> >> writev(3,
> >> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=8184},
> >> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=1023}], 2) = 9207
> >> ```
> >>
> >> vs 1024-sized writes
> >> ```
> >> $ strace -P /tmp/foo -e openat,write,writev /tmp/test_fstream_flush
> >> /tmp/foo 1024 2>&1 | head -n5
> >> openat(AT_FDCWD, "/tmp/foo", O_WRONLY|O_CREAT|O_TRUNC|O_SYNC|O_CLOEXEC,
> >> 0666) = 3
> >> writev(3, [{iov_base=NULL, iov_len=0},
> >> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=1024}], 2) = 1024
> >> writev(3, [{iov_base="", iov_len=0},
> >> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> >> iov_len=1024}], 2) = 1024
> >> writev(3, 

Re: [PING 2] [PATCH] libstdc++: basic_filebuf: don't flush more often than necessary.

2022-10-06 Thread Charles-François Natali via Gcc-patches
On Thu, Sep 22, 2022, 17:51 Charles-François Natali 
wrote:

>
> On Mon, Sep 5, 2022, 23:51 Charles-Francois Natali 
> wrote:
>
>> `basic_filebuf::xsputn` would bypass the buffer when passed a chunk of
>> size 1024 and above, seemingly as an optimisation.
>>
>> This can have a significant performance impact if the overhead of a
>> `write` syscall is non-negligible, e.g. on a slow disk, on network
>> filesystems, or simply during IO contention because instead of flushing
>> every `BUFSIZ` (by default), we can flush every 1024 char.
>> The impact is even greater with custom larger buffers, e.g. for network
>> filesystems, because the code could issue `write` for example 1000X more
>> often than necessary with respect to the buffer size.
>> It also introduces a significant discontinuity in performance when
>> writing chunks of size 1024 and above.
>>
>> See this reproducer which writes down a fixed number of chunks to a file
>> open with `O_SYNC` - to replicate high-latency `write` - for varying
>> size of chunks:
>>
>> ```
>> $ cat test_fstream_flush.cpp
>>
>> int
>> main(int argc, char* argv[])
>> {
>>   assert(argc == 3);
>>
>>   const auto* path = argv[1];
>>   const auto chunk_size = std::stoul(argv[2]);
>>
>>   const auto fd =
>> open(path, O_CREAT | O_TRUNC | O_WRONLY | O_SYNC | O_CLOEXEC, 0666);
>>   assert(fd >= 0);
>>
>>   auto filebuf = __gnu_cxx::stdio_filebuf(fd, std::ios_base::out);
>>   auto stream = std::ostream();
>>
>>   const auto chunk = std::vector(chunk_size);
>>
>>   for (auto i = 0; i < 1'000; ++i) {
>> stream.write(chunk.data(), chunk.size());
>>   }
>>
>>   return 0;
>> }
>> ```
>>
>> ```
>> $ g++ -o /tmp/test_fstream_flush test_fstream_flush.cpp -std=c++17
>> $ for i in $(seq 1021 1025); do echo -e "\n$i"; time
>> /tmp/test_fstream_flush /tmp/foo $i; done
>>
>> 1021
>>
>> real0m0.997s
>> user0m0.000s
>> sys 0m0.038s
>>
>> 1022
>>
>> real0m0.939s
>> user0m0.005s
>> sys 0m0.032s
>>
>> 1023
>>
>> real0m0.954s
>> user0m0.005s
>> sys 0m0.034s
>>
>> 1024
>>
>> real0m7.102s
>> user0m0.040s
>> sys 0m0.192s
>>
>> 1025
>>
>> real0m7.204s
>> user0m0.025s
>> sys 0m0.209s
>> ```
>>
>> See the huge drop in performance at the 1024-boundary.
>>
>> An `strace` confirms that from size 1024 we effectively defeat
>> buffering:
>> 1023-sized writes
>> ```
>> $ strace -P /tmp/foo -e openat,write,writev /tmp/test_fstream_flush
>> /tmp/foo 1023 2>&1 | head -n5
>> openat(AT_FDCWD, "/tmp/foo", O_WRONLY|O_CREAT|O_TRUNC|O_SYNC|O_CLOEXEC,
>> 0666) = 3
>> writev(3,
>> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=8184},
>> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=1023}], 2) = 9207
>> writev(3,
>> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=8184},
>> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=1023}], 2) = 9207
>> writev(3,
>> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=8184},
>> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=1023}], 2) = 9207
>> writev(3,
>> [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=8184},
>> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=1023}], 2) = 9207
>> ```
>>
>> vs 1024-sized writes
>> ```
>> $ strace -P /tmp/foo -e openat,write,writev /tmp/test_fstream_flush
>> /tmp/foo 1024 2>&1 | head -n5
>> openat(AT_FDCWD, "/tmp/foo", O_WRONLY|O_CREAT|O_TRUNC|O_SYNC|O_CLOEXEC,
>> 0666) = 3
>> writev(3, [{iov_base=NULL, iov_len=0},
>> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=1024}], 2) = 1024
>> writev(3, [{iov_base="", iov_len=0},
>> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=1024}], 2) = 1024
>> writev(3, [{iov_base="", iov_len=0},
>> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=1024}], 2) = 1024
>> writev(3, [{iov_base="", iov_len=0},
>> {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
>> iov_len=1024}], 2) = 1024
>> ```
>>
>> Instead, it makes sense to only bypass the buffer if the amount of data
>> to be written is larger than the buffer capacity.
>>
>> Closes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63746
>> ---
>>  libstdc++-v3/include/bits/fstream.tcc |  9 +--
>>  .../27_io/basic_filebuf/sputn/char/63746.cc   | 55 +++
>>  2 files changed, 58 insertions(+), 6 deletions(-)
>>  create mode 100644
>> libstdc++-v3/testsuite/27_io/basic_filebuf/sputn/char/63746.cc
>>
>> diff --git a/libstdc++-v3/include/bits/fstream.tcc
>> b/libstdc++-v3/include/bits/fstream.tcc
>> index 7ccc887b8..2e9369628 100644
>> --- a/libstdc++-v3/include/bits/fstream.tcc
>> +++ 

Re: [PATCH] IPA: support -flto + -flive-patching=inline-clone

2022-10-06 Thread Qing Zhao via Gcc-patches


> On Oct 6, 2022, at 4:29 AM, Richard Biener  wrote:
> 
> On Wed, Oct 5, 2022 at 8:18 PM Qing Zhao via Gcc-patches
>  wrote:
>> 
>> 
>> 
>>> On Oct 5, 2022, at 1:36 PM, Martin Liška  wrote:
>>> 
>>> On 10/5/22 16:50, Qing Zhao wrote:
 I have two questions on this:
>>> 
>>> Hello.
>>> 
 
 1.  What’s the motivation to enable -flive-patching with -flto? Is there 
 any application that will try -flive-patching with -flto now?
>>> 
>>> We're planning supporting GCC LTO Linux kernel support, so that's one 
>>> motivation. And the second one is a possible
>>> use in user-space livepatching. Note majority of modern distros default to 
>>> -flto (openSUSE, Fedora, Debian, Ubuntu, ...).
>> 
>> Okay, I see. That’s reasonable.
>>> 
 
 2. Why only enable -flive-patching=inline-clone with -flto?
>>> 
>>> Because the inline-only-static level (which you added/requested) would have 
>>> to properly
>>> block inter-procedural inlining that happens in LTO 
>>> (can_inline_edge_by_limits_p) and
>>> I'm not sure it would be properly blocked. So, feel free to extend my patch 
>>> if you want?
>> 
>> -flive-patching=inline-only-static
>> 
>> Only enable static functions inlining,  all the inlining of external visible 
>> functions are blocked, So, LTO should be compatible with this naturally 
>> without any issue, I think.
>> 
>> i.e, when "-flive-patching=inline-only-static -flto"  present together, all 
>> the inter-procedural inlining should be automatically blocked by 
>> -flive-patching=inline-only-static already.
>> 
>> Do I miss anything here?
> 
> WPA will promote externally visible functions static when all accesses
> are from LTO IR, I don't think we preserve
> the "original" visibility for IPA inlining heuristics.

WPA is Whole Program Analysis?
Okay, then  It will promote all static function to extern functions. That’s 
reasonable.

Is it hard to preserve the original “static” visibility in the IR?
> 
> OTOH inline-only-static could disable WPA inlining and do all inlining early 
> ...

Inline-only-static ONLY inlines static functions, how can it disable WPA 
inlining? Don’t quite understand here.

thanks.

Qing
> 
> Richard,
> 
>> 
>> thanks.
>> 
>> Qing
>> 
>>> 
>>> Martin
>>> 
 
 thanks.



Re: [PATCH] Add first-order recurrence autovectorization

2022-10-06 Thread Richard Biener via Gcc-patches
On Thu, Oct 6, 2022 at 2:13 PM Richard Biener
 wrote:
>
> On Fri, Sep 30, 2022 at 10:00 AM  wrote:
> >
> > From: Ju-Zhe Zhong 
> >
> > Hi, After fixing previous ICE.
> > I add full implementation (insert permutation to get correct result.)
> >
> > The gimple IR is correct now I think:
> >   # t_21 = PHI <_4(6), t_12(9)>
> >   # i_22 = PHI 
> >   # vectp_a.6_26 = PHI 
> >   # vect_vec_recur_.9_9 = PHI 
> >   # vectp_b.11_7 = PHI 
> >   # curr_cnt_36 = PHI 
> >   # loop_len_20 = PHI 
> >   _38 = .WHILE_LEN (loop_len_20, 32, POLY_INT_CST [4, 4]);
> >   while_len_37 = _38;
> >   _1 = (long unsigned int) i_22;
> >   _2 = _1 * 4;
> >   _3 = a_14(D) + _2;
> >   vect__4.8_19 = .LEN_LOAD (vectp_a.6_26, 32B, loop_len_20, 0);
> >   _4 = *_3;
> >   _5 = b_15(D) + _2;
> >   vect_vec_recur_.9_9 = VEC_PERM_EXPR  > POLY_INT_CST [3, 4], POLY_INT_CST [4, 4], POLY_INT_CST [5, 4], ... }>;
> >
> > But I encounter another ICE:
> > 0x169e0e7 process_bb
> > ../../../riscv-gcc/gcc/tree-ssa-sccvn.cc:7498
> > 0x16a09af do_rpo_vn(function*, edge_def*, bitmap_head*, bool, bool, 
> > vn_lookup_kind)
> > ../../../riscv-gcc/gcc/tree-ssa-sccvn.cc:8109
> > 0x16a0fe7 do_rpo_vn(function*, edge_def*, bitmap_head*)
> > ../../../riscv-gcc/gcc/tree-ssa-sccvn.cc:8205
> > 0x179b7db execute
> > ../../../riscv-gcc/gcc/tree-vectorizer.cc:1365
> >
> > Could you help me with this? After fixing this ICE, I think the loop 
> > vectorizer
> > can run correctly. Maybe you can test is in X86 or ARM after fixing this 
> > ICE.
>
> Sorry for the late reply, the issue is that we have
>
> vect_vec_recur_.7_7 = VEC_PERM_EXPR  { 7, 8, 9, 10, 11, 12, 13, 14 }>;
>
> thus
>
> +  for (unsigned i = 0; i < ncopies; ++i)
> +   {
> + gphi *phi = as_a (STMT_VINFO_VEC_STMTS (def_stmt_info)[i]);
> + tree latch = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
> + tree recur = gimple_phi_result (phi);
> + gassign *assign
> +   = gimple_build_assign (recur, VEC_PERM_EXPR, recur, latch, perm);
> + gimple_assign_set_lhs (assign, recur);
>
> needs to create a new SSA name for each LHS.  You shouldn't create code in
> vect_get_vec_defs_for_operand either.
>
> Let me mangle the patch a bit.
>
> The attached is what I came up with, the permutes need to be generated when
> the backedge PHI values are filled in.  Missing are ncopies > 1 handling, we'd
> need to think of how the initial value and the permutes would work here, 
> missing
> is SLP support but more importantly handling in the epilogue (so on x86 
> requires
> constant loop bound)
> I've added a testcase that triggers on x86_64.

Actually I broke it, the following is more correct.

Richard.

> Richard.


p
Description: Binary data


Re: [GCC13][Patch][V6][PATCH 1/2] Add a new option -fstrict-flex-arrays[=n] and new attribute strict_flex_array

2022-10-06 Thread Qing Zhao via Gcc-patches



> On Oct 5, 2022, at 4:25 PM, Joseph Myers  wrote:
> 
> On Wed, 5 Oct 2022, Qing Zhao via Gcc-patches wrote:
> 
>> +  /* if not the last field, return false.  */
> 
> Comments should start with an uppercase letter.
> 
>> +  /* if not an array field, return false.  */
> 
>> +  /* if there is a strict_flex_array attribute attached to the field,
>> + override the flag_strict_flex_arrays.  */
> 
>> +  /* get the value of the level first from the attribute.  */
> 
>> +  /* the attribute has higher priority than flag_struct_flex_array.  */
> 
>> +/* default, all trailing arrays are flexiable array members.  */
> 
> Likewise, and "flexible" not "flexiable".
> 
>> +  /* whether this field is the last field of the structure or union.
>> + for UNION, any field is the last field of it.  */
> 
> Likewise.
> 
>> +field of a structure as a flexible array member for the purposesof accessing
> 
> Missing space, should be "purposes of".

Will fix all the above. 


> 
> The C front-end and docs changes are OK with the fixes above.

Thanks a lot.

So this patch is considered approved, I will commit it after the above fix and 
one more round of testing.

Let me know if you have more comment.

Qing

> 
> -- 
> Joseph S. Myers
> jos...@codesourcery.com



Re: [PATCH] Fix wrong code generated by unroll-and-jam pass

2022-10-06 Thread Richard Biener via Gcc-patches
On Thu, Oct 6, 2022 at 1:09 PM Eric Botcazou  wrote:
>
> > I'm wondering if testing DR_IS_WRITE (dra) is enough here and whether
> > the logic also applies to RAW and WAR.  So should it be either
> > (DR_IS_WRITE (dra) || DR_IS_WRITE (drb)) or DR_IS_WRITE (dra) &&
> > DR_IS_WRITE (drb) instead?
>
> It's a self-dependence, i.e. dra == drb in the block.  Or do you mean for
> other dependence pairs in general?  For them, I think that the code does the
> proper filtering in adjust_unroll_factor, but I may be wrong of course.

Ah, I see.

The original patch is OK.

thanks,
Richard.

> --
> Eric Botcazou
>
>


[PATCH] middle-end/107115 - avoid bogus redundant store removal during RTL expansion

2022-10-06 Thread Richard Biener via Gcc-patches
The following preserves the (premature) redundant store removal
done in store_expr by appropriately guarding it with
mems_same_for_tbaa_p.  The testcase added needs scheduling disabled
for now since there's a similar bug there still present.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

PR middle-end/107115
* expr.cc (store_expr): Check mems_same_for_tbaa_p before
eliding a seemingly redundant store.

* gcc.dg/torture/pr107115.c: New testcase.
---
 gcc/expr.cc |  4 ++-
 gcc/testsuite/gcc.dg/torture/pr107115.c | 37 +
 2 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr107115.c

diff --git a/gcc/expr.cc b/gcc/expr.cc
index 80bb1b8a4c5..ba627f176a7 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -6207,7 +6207,9 @@ store_expr (tree exp, rtx target, int call_param_p,
 
   if ((! rtx_equal_p (temp, target)
|| (temp != target && (side_effects_p (temp)
- || side_effects_p (target
+ || side_effects_p (target)
+ || (MEM_P (temp)
+ && !mems_same_for_tbaa_p (temp, target)
   && TREE_CODE (exp) != ERROR_MARK
   /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
 but TARGET is not valid memory reference, TEMP will differ
diff --git a/gcc/testsuite/gcc.dg/torture/pr107115.c 
b/gcc/testsuite/gcc.dg/torture/pr107115.c
new file mode 100644
index 000..5f7b6ff01e1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr107115.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* PR/107115 */
+/* { dg-additional-options "-fno-schedule-insns -fno-schedule-insns2" } */
+
+#include 
+
+void test1(long *p1)
+{
+  p1[0] = 1;
+}
+long test2(long long *p2, int index1, int index2)
+{
+  p2[index1] = 2;
+  return p2[index2];
+}
+long test3(long *p3, int index2, long value)
+{
+  p3[index2] = 3;
+  p3[index2] = value;
+  return p3[0];
+}
+long test4(void *p4, int index1, int index2)
+{
+  test1(p4);
+  long temp = test2(p4, index1, index2);
+  return test3(p4, index2, temp);
+}
+long (*volatile vtest)(void *, int, int) = test4;
+int main(void)
+{
+  void *pp = malloc(sizeof (long) + sizeof(long long));
+  if (!pp) abort();
+  long result = vtest(pp, 0, 0);
+  if (*(long *)pp != 2 || result != 2)
+__builtin_abort ();
+  return 0;
+}
-- 
2.35.3


Re: [PATCH] undef offsetof before defining it in stddef.h

2022-10-06 Thread Richard Biener via Gcc-patches
On Fri, Sep 30, 2022 at 6:35 PM Olivier Hainque via Gcc-patches
 wrote:
>
> Hello,
>
> The attached patch is a proposal to #undef offsetof before
> the #define we do in ginclude/stddef.h, which prevents redefinition
> warnings from dg tests passing -Wsystem-headers on systems which
> provide a definition in system headers, such as VxWorks.
>
> We have been using this for a while with gcc-11 based toolchains
> for a wide range of configurations (linux and windows hosts, native
> and cross, bare board or VxWorks for a range of CPUs).
>
> This also passes build + sanity test with gcc-12 for
> powerpc64-vxworks7r2, then full bootstrap + regression testing
> for mainline on x86_64-linux.
>
> Ok to commit?

OK.

> Thanks in advance!
>
> With Kind Regards,
>
> Olivier
>
> 2022-09-30  Olivier Hainque  
>
> gcc/
>* ginclude/stddef.h: #undef offsetof before #define.
>
>
>
>


Re: [Patch] openmp: Map holds clause to IFN_ASSUME for Fortran

2022-10-06 Thread Jakub Jelinek via Gcc-patches
On Thu, Oct 06, 2022 at 12:55:01PM +0200, Tobias Burnus wrote:
> Same as for C/C++, albeit a tiny bit longer patch.
> 
> I don't know whether it makes sense to handle – in the long run – the
> case of se.pre/se.post being nonempty – and, if so, how.

I think it is essential not to throw those away,
if se.pre or se.post, you can e.g. expand it roughly as C/C++ ({ cond; }),
in GENERIC it can be say a TARGET_EXPR with a boolean
temporary as slot, where the the initializer will be the
se.pre part, followed by MODIFY_EXPR which sets the slot to se.expr
value and followed by se.post.
I've only started playing with the middle-end changes now, here
is what I have and plan to at lower_cf time turn that into essentially
bool artificial (args...)
{
  return cond;
}
and
.ASSUME (, args...);

--- gcc/gimplify.cc.jj  2022-10-06 08:56:28.344131629 +0200
+++ gcc/gimplify.cc 2022-10-06 14:04:46.647204910 +0200
@@ -3569,7 +3569,45 @@ gimplify_call_expr (tree *expr_p, gimple
 fndecl, 0));
  return GS_OK;
}
- /* FIXME: Otherwise expand it specially.  */
+ /* Temporarily, until gimple lowering, transform
+.ASSUME (cond);
+into:
+guard = .ASSUME ();
+if (guard) goto label_true; else label_false;
+label_true:;
+{
+  guard = cond;
+}
+label_false:;
+.ASSUME (guard);
+such that gimple lowering can outline the condition into
+a separate function easily.  */
+ tree guard = create_tmp_var (boolean_type_node);
+ gcall *call = gimple_build_call_internal (ifn, 0);
+ gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
+ gimple_set_location (call, loc);
+ gimple_call_set_lhs (call, guard);
+ gimple_seq_add_stmt (pre_p, call);
+ *expr_p = build2 (MODIFY_EXPR, void_type_node, guard,
+   CALL_EXPR_ARG (*expr_p, 0));
+ *expr_p = build3 (BIND_EXPR, void_type_node, NULL, *expr_p, NULL);
+ tree label_false = create_artificial_label (UNKNOWN_LOCATION);
+ tree label_true = create_artificial_label (UNKNOWN_LOCATION);
+ gcond *cond_stmt = gimple_build_cond (NE_EXPR, guard,
+   boolean_false_node,
+   label_true, label_false);
+ gimplify_seq_add_stmt (pre_p, cond_stmt);
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (label_true));
+ push_gimplify_context ();
+ gimple_seq body = NULL;
+ gimple *g = gimplify_and_return_first (*expr_p, );
+ pop_gimplify_context (g);
+ gimplify_seq_add_seq (pre_p, body);
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (label_false));
+ call = gimple_build_call_internal (ifn, 1, guard);
+ gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
+ gimple_set_location (call, loc);
+ gimple_seq_add_stmt (pre_p, call);
  return GS_ALL_DONE;
}
 
--- gcc/cp/pt.cc.jj 2022-10-06 08:56:28.670127213 +0200
+++ gcc/cp/pt.cc2022-10-06 13:42:26.632351930 +0200
@@ -21182,6 +21182,8 @@ tsubst_copy_and_build (tree t,
  ret = error_mark_node;
  break;
}
+ if (!processing_template_decl)
+   arg = fold_build_cleanup_point_expr (TREE_TYPE (arg), arg);
  ret = build_call_expr_internal_loc (EXPR_LOCATION (t),
  IFN_ASSUME,
  void_type_node, 1,
--- gcc/cp/cp-gimplify.cc.jj2022-10-06 08:56:28.660127349 +0200
+++ gcc/cp/cp-gimplify.cc   2022-10-06 13:41:54.286789968 +0200
@@ -3117,6 +3117,8 @@ process_stmt_assume_attribute (tree std_
arg = contextual_conv_bool (arg, tf_warning_or_error);
  if (error_operand_p (arg))
continue;
+ if (!processing_template_decl)
+   arg = fold_build_cleanup_point_expr (TREE_TYPE (arg), arg);
  statement = build_call_expr_internal_loc (attrs_loc, IFN_ASSUME,
void_type_node, 1, arg);
  finish_expr_stmt (statement);
--- gcc/cp/parser.cc.jj 2022-10-06 10:39:31.989345921 +0200
+++ gcc/cp/parser.cc2022-10-06 13:41:28.001145938 +0200
@@ -46029,6 +46029,8 @@ cp_parser_omp_assumption_clauses (cp_par
t = contextual_conv_bool (t, tf_warning_or_error);
  if (is_assume && !error_operand_p (t))
{
+ if (!processing_template_decl)
+   t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
  t = build_call_expr_internal_loc (eloc, IFN_ASSUME,
void_type_node, 1, t);
  

Re: [PATCH] Introduce DWARF_VERSION_DEFAULT (and redefine for VxWorks)

2022-10-06 Thread Richard Biener via Gcc-patches
On Fri, Sep 30, 2022 at 6:18 PM Olivier Hainque via Gcc-patches
 wrote:
>
> Hello,
>
> This change is a proposal to introduce a target overridable macro
> to replace the hardcoded value used in common.opt to initialize
> dwarf_version.
>
> The main advantage compared to special code in a target
> override_options hook is that redefinitions by target config files
> are visible by both the compiler proper and by the driver, which
> might refer to dwarf_version in ASM_DEBUG_SPECs and friends.
>
> This is useful at least on VxWorks, where we usually need to
> default to dwarf 4 or even 2 to accommodate non-gdb debuggers
> provided by the environment, including for assembly sources
> used in libgcc for some ports (witnessed with lse.S on aarch64).
>
> We have been using this in a lot of gcc-11 based toolchains
> for various configurations for a while, cross and native.
>
> This is a noop for anything but VxWorks and helped cure crashes
> of target debuggers in VxWorks environments.
>
> Bootstrapped and regression tested for mainline on x86_64-linux.
>
> Is this ok to commit?

I think this is reasonable, thus OK.

Thanks,
Richard.

> Thanks in advance!
>
> Best Regards,
>
> Olivier
>
> 2022-09-30  Olivier Hainque  
>
> gcc/
> * defaults.h (DWARF_DEFAULT_VERSION): Define if not
> defined already.
> * common.opt (gdwarf-): Use it.
> * doc/tm.texi.in (DWARF_DEFAULT_VERSION): Document.
> * doc/tm.texi: Update accordingly.
>
> * config/vxworks.h (DWARF_DEFAULT_VERSION): Redefine.
> * config/vxworks.cc: Remove code setting dwarf_version, now
> handled by the DWARF_DEFAULT_VERSION redefinition.
>


Re: [PATCH] Add first-order recurrence autovectorization

2022-10-06 Thread Richard Biener via Gcc-patches
On Fri, Sep 30, 2022 at 10:00 AM  wrote:
>
> From: Ju-Zhe Zhong 
>
> Hi, After fixing previous ICE.
> I add full implementation (insert permutation to get correct result.)
>
> The gimple IR is correct now I think:
>   # t_21 = PHI <_4(6), t_12(9)>
>   # i_22 = PHI 
>   # vectp_a.6_26 = PHI 
>   # vect_vec_recur_.9_9 = PHI 
>   # vectp_b.11_7 = PHI 
>   # curr_cnt_36 = PHI 
>   # loop_len_20 = PHI 
>   _38 = .WHILE_LEN (loop_len_20, 32, POLY_INT_CST [4, 4]);
>   while_len_37 = _38;
>   _1 = (long unsigned int) i_22;
>   _2 = _1 * 4;
>   _3 = a_14(D) + _2;
>   vect__4.8_19 = .LEN_LOAD (vectp_a.6_26, 32B, loop_len_20, 0);
>   _4 = *_3;
>   _5 = b_15(D) + _2;
>   vect_vec_recur_.9_9 = VEC_PERM_EXPR  POLY_INT_CST [3, 4], POLY_INT_CST [4, 4], POLY_INT_CST [5, 4], ... }>;
>
> But I encounter another ICE:
> 0x169e0e7 process_bb
> ../../../riscv-gcc/gcc/tree-ssa-sccvn.cc:7498
> 0x16a09af do_rpo_vn(function*, edge_def*, bitmap_head*, bool, bool, 
> vn_lookup_kind)
> ../../../riscv-gcc/gcc/tree-ssa-sccvn.cc:8109
> 0x16a0fe7 do_rpo_vn(function*, edge_def*, bitmap_head*)
> ../../../riscv-gcc/gcc/tree-ssa-sccvn.cc:8205
> 0x179b7db execute
> ../../../riscv-gcc/gcc/tree-vectorizer.cc:1365
>
> Could you help me with this? After fixing this ICE, I think the loop 
> vectorizer
> can run correctly. Maybe you can test is in X86 or ARM after fixing this ICE.

Sorry for the late reply, the issue is that we have

vect_vec_recur_.7_7 = VEC_PERM_EXPR ;

thus

+  for (unsigned i = 0; i < ncopies; ++i)
+   {
+ gphi *phi = as_a (STMT_VINFO_VEC_STMTS (def_stmt_info)[i]);
+ tree latch = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
+ tree recur = gimple_phi_result (phi);
+ gassign *assign
+   = gimple_build_assign (recur, VEC_PERM_EXPR, recur, latch, perm);
+ gimple_assign_set_lhs (assign, recur);

needs to create a new SSA name for each LHS.  You shouldn't create code in
vect_get_vec_defs_for_operand either.

Let me mangle the patch a bit.

The attached is what I came up with, the permutes need to be generated when
the backedge PHI values are filled in.  Missing are ncopies > 1 handling, we'd
need to think of how the initial value and the permutes would work here, missing
is SLP support but more importantly handling in the epilogue (so on x86 requires
constant loop bound)
I've added a testcase that triggers on x86_64.

Richard.


p
Description: Binary data


[PATCH][committed] aarch64: Remove redundant zero-extends with LDAR

2022-10-06 Thread Kyrylo Tkachov via Gcc-patches
Hi all,

Like other loads in AArch64, the LDARB,LDARH,LDAR instructions clear out the 
top part of their
destination register and we can thus avoid having to explicitly zero-extend it.
We were missing a combine pattern that this patch adds.

For one of the examples in the testcase we generated:
load_uint8_t_ext_uint16_t:
adrpx0, .LANCHOR0
add x0, x0, :lo12:.LANCHOR0
ldarb   w0, [x0]
and w0, w0, 255
ret

but now generate:
load_uint8_t_ext_uint16_t:
adrpx0, .LANCHOR0
add x0, x0, :lo12:.LANCHOR0
ldarb   w0, [x0]
ret

Bootstrapped and tested on aarch64-none-linux-gnu.
Pushing to trunk.
Thanks,
Kyrill

gcc/ChangeLog:

* config/aarch64/atomics.md 
(*atomic_load_zext):
New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/ldar_2.c: New test.


ldar-ext.patch
Description: ldar-ext.patch


[PATCH][committed] aarch64: Add test for LDAR generation from __atomic_load_n

2022-10-06 Thread Kyrylo Tkachov via Gcc-patches
Hi all,

I'd like a test to check the generation of LDAR for atomic_load_n.
No new functionality added.
Pushing to trunk.
Thanks,
Kyrill

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/ldar_1.c: New test.


ldar-test.patch
Description: ldar-test.patch


Re: [PATCH] Fix wrong code generated by unroll-and-jam pass

2022-10-06 Thread Eric Botcazou via Gcc-patches
> I'm wondering if testing DR_IS_WRITE (dra) is enough here and whether
> the logic also applies to RAW and WAR.  So should it be either
> (DR_IS_WRITE (dra) || DR_IS_WRITE (drb)) or DR_IS_WRITE (dra) &&
> DR_IS_WRITE (drb) instead?

It's a self-dependence, i.e. dra == drb in the block.  Or do you mean for 
other dependence pairs in general?  For them, I think that the code does the 
proper filtering in adjust_unroll_factor, but I may be wrong of course.

-- 
Eric Botcazou




[Patch] openmp: Map holds clause to IFN_ASSUME for Fortran

2022-10-06 Thread Tobias Burnus

Same as for C/C++, albeit a tiny bit longer patch.

I don't know whether it makes sense to handle – in the long run – the
case of se.pre/se.post being nonempty – and, if so, how.

OK for mainline?

Tobias
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
openmp: Map holds clause to IFN_ASSUME for Fortran

Same as r13-3107-g847f5addc4d07a2f3b95f5daa50ab4a64dfd957d did for C/C++.
Convert '!$omp assume holds(cond)' to IFN_ASSUME (cond).

gcc/fortran/
	* trans-openmp.cc (gfc_trans_omp_assume): New.
	(gfc_trans_omp_directive): Call it.

gcc/teststuite/
	* gfortran.dg/gomp/assume-3.f90: New test.

 gcc/fortran/trans-openmp.cc | 27 -
 gcc/testsuite/gfortran.dg/gomp/assume-3.f90 | 46 +
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 21053694f81..b82257258a7 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -4570,6 +4570,31 @@ gfc_trans_oacc_wait_directive (gfc_code *code)
 static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
 static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
 
+static tree
+gfc_trans_omp_assume (gfc_code *code)
+{
+  stmtblock_t block;
+  gfc_init_block ();
+  gfc_omp_assumptions *assume = code->ext.omp_clauses->assume;
+  if (assume)
+for (gfc_expr_list *el = assume->holds; el; el = el->next)
+  {
+	tree t;
+	gfc_se se;
+	gfc_init_se (, NULL);
+	gfc_conv_expr (, el->expr);
+	/* Avoid side effects. */
+	if (se.pre.head || se.post.head)
+	  continue;
+	t = build_call_expr_internal_loc (gfc_get_location (>expr->where),
+	  IFN_ASSUME, void_type_node, 1,
+	  se.expr);
+	gfc_add_expr_to_block (, t);
+  }
+  gfc_add_expr_to_block (, gfc_trans_omp_code (code->block->next, true));
+  return gfc_finish_block ();
+}
+
 static tree
 gfc_trans_omp_atomic (gfc_code *code)
 {
@@ -7488,7 +7513,7 @@ gfc_trans_omp_directive (gfc_code *code)
   switch (code->op)
 {
 case EXEC_OMP_ASSUME:
-  return gfc_trans_omp_code (code->block->next, true);
+  return gfc_trans_omp_assume (code);
 case EXEC_OMP_ATOMIC:
   return gfc_trans_omp_atomic (code);
 case EXEC_OMP_BARRIER:
diff --git a/gcc/testsuite/gfortran.dg/gomp/assume-3.f90 b/gcc/testsuite/gfortran.dg/gomp/assume-3.f90
new file mode 100644
index 000..e5deace306e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/assume-3.f90
@@ -0,0 +1,46 @@
+! { dg-do compile }
+! { dg-options "-fopenmp -O2 -fdump-tree-optimized -fdump-tree-original" }
+
+! { dg-final { scan-tree-dump-times ".ASSUME \\(x == 42\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times ".ASSUME \\(x <= 41\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times ".ASSUME \\(y <= 6\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times ".ASSUME \\(y > 5\\);" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "return 42;" 3 "optimized" } }
+! { dg-final { scan-tree-dump-not "return -1;" "optimized" } }
+
+integer function foo (x)
+  implicit none
+  integer, value :: x
+  integer :: y
+  !$omp assume holds (x == 42)
+y = x;
+  !$omp end assume
+  foo = y
+end
+
+integer function bar (x)
+  implicit none
+  integer, value :: x
+  !$omp assume holds (x < 42)
+  block
+  end block
+  if (x == 42) then
+bar = -1
+return
+  end if
+  bar = 42
+end
+
+integer function foobar (y)
+  implicit none
+  integer, value :: y
+  !$omp assume holds(y > 5) holds (y < 7)
+  block
+if (y == 6) then
+  foobar = 42
+  return
+end if
+  end block
+  foobar = -1
+end


[RFC] Add op1_range for __builtin_signbit.

2022-10-06 Thread Aldy Hernandez via Gcc-patches
This is the op1_range range-op entry for __builtin_signbit.  It allows
us to wind back through a call to signbit.

For example, on the true side of if (__builtin_signbit(x_5) != 0) we
can crop down the range of x_5 to:

[frange] float [-Inf, -0.0 (-0x0.0p+0)] -NAN

Similarly on the false side, we can crop to:

[frange] float [0.0 (0x0.0p+0), +Inf] +NAN

This brings about an interesting question, can we fold the second
conditional here as always false?

void foo(float x)
{
  if (__builtin_signbit (x))
{
  if (x > 0.0)
link_error();
}
}

The only values for x at the second conditional are negative values,
or -NAN, so it will always evaluate to false.  ISTM that we
*shouldn't* fold this conditional as there is user observable behavior
if there is a signaling NAN.  For that matter, that is exactly what we
do in ranger-ops.  We leave the conditional in place, but ranger
is able to determine that "x" is UNDEFINED on the path leading up to
link_error:

=== BB 3 
Imports: x_3(D)
Exports: x_3(D)
x_3(D)  [frange] float [-Inf, -0.0 (-0x0.0p+0)] -NAN
 :
if (x_3(D) > 0.0)
  goto ; [INV]
else
  goto ; [INV]

3->4  (T) x_3(D) :  [frange] UNDEFINED
3->5  (F) x_3(D) :  [frange] float [-Inf, -0.0 (-0x0.0p+0)] -NAN

This would allow users of ranger to query x_3 on the 3->4 and notice
it's unreachable, without VRP removing the conditional.

I believe this is correct, but would like confirmation from the experts.

gcc/ChangeLog:

* gimple-range-op.cc: Add op1_range entry for __builtin_signbit.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/vrp-float-signbit-3.c: New test.
---
 gcc/gimple-range-op.cc| 20 +++
 .../gcc.dg/tree-ssa/vrp-float-signbit-3.c | 14 +
 2 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-signbit-3.c

diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index 42ebc7d6ce5..abc33e7af0c 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -306,6 +306,7 @@ class cfn_signbit : public range_operator_float
 {
 public:
   using range_operator_float::fold_range;
+  using range_operator_float::op1_range;
   virtual bool fold_range (irange , tree type, const frange ,
   const irange &, relation_kind) const
   {
@@ -320,6 +321,25 @@ public:
   }
return false;
   }
+  virtual bool op1_range (frange , tree type, const irange ,
+ const frange &, relation_kind) const override
+  {
+if (lhs.zero_p ())
+  {
+   r.set (type, dconst0, frange_val_max (type));
+   r.update_nan (false);
+   return true;
+  }
+if (!lhs.contains_p (build_zero_cst (lhs.type (
+  {
+   REAL_VALUE_TYPE dconstm0 = dconst0;
+   dconstm0.sign = 1;
+   r.set (type, frange_val_min (type), dconstm0);
+   r.update_nan (true);
+   return true;
+  }
+return false;
+  }
 } op_cfn_signbit;
 
 // Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-signbit-3.c 
b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-signbit-3.c
new file mode 100644
index 000..dd3090aeb10
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-signbit-3.c
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// { dg-options "-O2 -ffast-math -fdump-tree-evrp" }
+
+void link_error();
+
+void foo(float x)
+{
+  if (__builtin_signbit (x))
+{
+  if (x > 0.0)
+   link_error();
+}
+}
+// { dg-final { scan-tree-dump-not "link_error" "evrp" } }
-- 
2.37.1



Re: [PATCH v2] aarch64: update Ampere-1 core definition

2022-10-06 Thread Philipp Tomsich
Applied to master. Thanks!

Philipp.

On Thu, 6 Oct 2022 at 12:07, Richard Sandiford 
wrote:

> Philipp Tomsich  writes:
> > This brings the extensions detected by -mcpu=native on Ampere-1 systems
> > in sync with the defaults generated for -mcpu=ampere1.
> >
> > Note that some early kernel versions on Ampere1 may misreport the
> > presence of PAUTH and PREDRES (i.e., -mcpu=native will add 'nopauth'
> > and 'nopredres').
> >
> > gcc/ChangeLog:
> >
> >   * config/aarch64/aarch64-cores.def (AARCH64_CORE): Update
> >   Ampere-1 core entry.
> >
> > Signed-off-by: Philipp Tomsich 
>
> OK, thanks.
>
> > Ok for backport?
>
> Yeah.  I'll try to backport the RCPC change soon -- think it would
> be best to get that in first.
>
> Richard
>
> >
> > Changes in v2:
> > - Removed explicit RCPC, as the feature is now implicitly included
> >   in the 8.3 feature definition.
> >
> >  gcc/config/aarch64/aarch64-cores.def | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/gcc/config/aarch64/aarch64-cores.def
> b/gcc/config/aarch64/aarch64-cores.def
> > index b50628d6b51..e9a4b622be0 100644
> > --- a/gcc/config/aarch64/aarch64-cores.def
> > +++ b/gcc/config/aarch64/aarch64-cores.def
> > @@ -69,7 +69,7 @@ AARCH64_CORE("thunderxt81",   thunderxt81,
>  thunderx,  V8A,  (CRC, CRYPTO), thu
> >  AARCH64_CORE("thunderxt83",   thunderxt83,   thunderx,  V8A,  (CRC,
> CRYPTO), thunderx,  0x43, 0x0a3, -1)
> >
> >  /* Ampere Computing ('\xC0') cores. */
> > -AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (), ampere1, 0xC0,
> 0xac3, -1)
> > +AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (F16, RNG, AES,
> SHA3), ampere1, 0xC0, 0xac3, -1)
> >  /* Do not swap around "emag" and "xgene1",
> > this order is required to handle variant correctly. */
> >  AARCH64_CORE("emag",emag,  xgene1,V8A,  (CRC, CRYPTO),
> emag, 0x50, 0x000, 3)
>


Re: [PATCH v2] aarch64: fix off-by-one in reading cpuinfo

2022-10-06 Thread Philipp Tomsich
On Thu, 6 Oct 2022 at 12:06, Richard Sandiford 
wrote:

> Philipp Tomsich  writes:
> > Fixes: 341573406b39
> >
> > Don't subtract one from the result of strnlen() when trying to point
> > to the first character after the current string.  This issue would
> > cause individual characters (where the 128 byte buffers are stitched
> > together) to be lost.
> >
> > gcc/ChangeLog:
> >
> >   * config/aarch64/driver-aarch64.cc (readline): Fix off-by-one.
> >
> > gcc/testsuite/ChangeLog:
> >
> >   * gcc.target/aarch64/cpunative/info_18: New test.
> >   * gcc.target/aarch64/cpunative/native_cpu_18.c: New test.
> >
> > Signed-off-by: Philipp Tomsich 
> >
> > ---
> >
> > Changes in v2:
> > - Add a a regression test (as per review comment).
> >
> >  gcc/config/aarch64/driver-aarch64.cc  |  4 ++--
> >  .../gcc.target/aarch64/cpunative/info_18  |  8 
> >  .../gcc.target/aarch64/cpunative/native_cpu_18.c  | 15 +++
> >  3 files changed, 25 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/aarch64/cpunative/info_18
> >  create mode 100644
> gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
> >
> > diff --git a/gcc/config/aarch64/driver-aarch64.cc
> b/gcc/config/aarch64/driver-aarch64.cc
> > index 52ff537908e..48250e68034 100644
> > --- a/gcc/config/aarch64/driver-aarch64.cc
> > +++ b/gcc/config/aarch64/driver-aarch64.cc
> > @@ -203,9 +203,9 @@ readline (FILE *f)
> >   return std::string ();
> >/* If we're not at the end of the line then override the
> >\0 added by fgets.  */
> > -  last = strnlen (buf, size) - 1;
> > +  last = strnlen (buf, size);
> >  }
> > -  while (!feof (f) && buf[last] != '\n');
> > +  while (!feof (f) && (last > 0 && buf[last - 1] != '\n'));
>
> Very minor, but: I think the normal GCC style would be to avoid the
> extra (...).
>
> OK with that change, thanks.  OK for backports too after a settling period.
>

Applied to master (with that change). Thanks!

I'll backport around the end of this month, if no new issues are caused by
this change.

Philipp.


>
> Richard
>
> >
> >std::string result (buf);
> >free (buf);
> > diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_18
> b/gcc/testsuite/gcc.target/aarch64/cpunative/info_18
> > new file mode 100644
> > index 000..25061a4abe8
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_18
> > @@ -0,0 +1,8 @@
> > +processor: 0
> > +BogoMIPS : 2000.00
> > +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp
> asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm
> dit uscat ilrcpc flagm ssbs sb dcpodp flagm2 frint i8mm bf16 rng ecv
> > +CPU implementer  : 0xc0
> > +CPU architecture: 8
> > +CPU variant  : 0x0
> > +CPU part : 0xac3
> > +CPU revision : 0
> > diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
> b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
> > new file mode 100644
> > index 000..b5f0a3005f5
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
> > @@ -0,0 +1,15 @@
> > +/* { dg-do compile { target { { aarch64*-*-linux*} && native } } } */
> > +/* { dg-set-compiler-env-var GCC_CPUINFO
> "$srcdir/gcc.target/aarch64/cpunative/info_18" } */
> > +/* { dg-additional-options "-mcpu=native" } */
> > +
> > +int main()
> > +{
> > +  return 0;
> > +}
> > +
> > +/* { dg-final { scan-assembler {\.arch
> armv8.6-a\+crc\+fp16\+aes\+sha3\+rng} } } */
> > +
> > +/* Test one where the boundary of buffer size would overwrite the last
> > +   character read when stitching the fgets-calls together.  With the
> > +   test data provided, this would truncate the 'sha512' into 'ha512'
> > +   (dropping the 'sha3' feature). */
>


Re: [PATCH v2] aarch64: update Ampere-1 core definition

2022-10-06 Thread Richard Sandiford via Gcc-patches
Philipp Tomsich  writes:
> This brings the extensions detected by -mcpu=native on Ampere-1 systems
> in sync with the defaults generated for -mcpu=ampere1.
>
> Note that some early kernel versions on Ampere1 may misreport the
> presence of PAUTH and PREDRES (i.e., -mcpu=native will add 'nopauth'
> and 'nopredres').
>
> gcc/ChangeLog:
>
>   * config/aarch64/aarch64-cores.def (AARCH64_CORE): Update
>   Ampere-1 core entry.
>
> Signed-off-by: Philipp Tomsich 

OK, thanks.

> Ok for backport?

Yeah.  I'll try to backport the RCPC change soon -- think it would
be best to get that in first.

Richard

>
> Changes in v2:
> - Removed explicit RCPC, as the feature is now implicitly included
>   in the 8.3 feature definition.
>
>  gcc/config/aarch64/aarch64-cores.def | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/config/aarch64/aarch64-cores.def 
> b/gcc/config/aarch64/aarch64-cores.def
> index b50628d6b51..e9a4b622be0 100644
> --- a/gcc/config/aarch64/aarch64-cores.def
> +++ b/gcc/config/aarch64/aarch64-cores.def
> @@ -69,7 +69,7 @@ AARCH64_CORE("thunderxt81",   thunderxt81,   thunderx,  
> V8A,  (CRC, CRYPTO), thu
>  AARCH64_CORE("thunderxt83",   thunderxt83,   thunderx,  V8A,  (CRC, CRYPTO), 
> thunderx,  0x43, 0x0a3, -1)
>  
>  /* Ampere Computing ('\xC0') cores. */
> -AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (), ampere1, 0xC0, 0xac3, 
> -1)
> +AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (F16, RNG, AES, SHA3), 
> ampere1, 0xC0, 0xac3, -1)
>  /* Do not swap around "emag" and "xgene1",
> this order is required to handle variant correctly. */
>  AARCH64_CORE("emag",emag,  xgene1,V8A,  (CRC, CRYPTO), emag, 
> 0x50, 0x000, 3)


[PATCH] tree-optimization/107107 - tail-merging VN wrong-code

2022-10-06 Thread Richard Biener via Gcc-patches
The following fixes an unintended(?) side-effect of the special
MODIFY_EXPR expression entries we add for tail-merging during VN.
We shouldn't value-number the virtual operand differently here.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

PR tree-optimization/107107
* tree-ssa-sccvn.cc (visit_reference_op_store): Do not
affect value-numbering when doing the tail merging
MODIFY_EXPR lookup.

* gcc.dg/pr107107.c: New testcase.
---
 gcc/testsuite/gcc.dg/pr107107.c | 25 +
 gcc/tree-ssa-sccvn.cc   | 17 +++--
 2 files changed, 28 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr107107.c

diff --git a/gcc/testsuite/gcc.dg/pr107107.c b/gcc/testsuite/gcc.dg/pr107107.c
new file mode 100644
index 000..5ad6a63159e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr107107.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-tail-merge" } */
+
+static inline void set_longish(int is_long_long, void *p, long x)
+{
+  if (is_long_long)
+*(long long*)p = x;
+  else
+*(long*)p = x;
+}
+static long test(long long *p, int index, int mode)
+{
+  *p = 1;
+  set_longish(mode, p+index, 2);
+  return *p;
+}
+long (*volatile vtest)(long long*, int, int) = test;
+int main(void)
+{
+  long long x;
+  long result = vtest(, 0, 1);
+  if (result != 2 || x != 2)
+__builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 2cc2c0e1e34..37484403c56 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -5718,19 +5718,6 @@ visit_reference_op_store (tree lhs, tree op, gimple 
*stmt)
 
   if (!resultsame)
 {
-  /* Only perform the following when being called from PRE
-which embeds tail merging.  */
-  if (default_vn_walk_kind == VN_WALK)
-   {
- assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
- vn_reference_lookup (assign, vuse, VN_NOWALK, , false);
- if (vnresult)
-   {
- VN_INFO (vdef)->visited = true;
- return set_ssa_val_to (vdef, vnresult->result_vdef);
-   }
-   }
-
   if (dump_file && (dump_flags & TDF_DETAILS))
{
  fprintf (dump_file, "No store match\n");
@@ -5755,7 +5742,9 @@ visit_reference_op_store (tree lhs, tree op, gimple *stmt)
   if (default_vn_walk_kind == VN_WALK)
{
  assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
- vn_reference_insert (assign, lhs, vuse, vdef);
+ vn_reference_lookup (assign, vuse, VN_NOWALK, , false);
+ if (!vnresult)
+   vn_reference_insert (assign, lhs, vuse, vdef);
}
 }
   else
-- 
2.35.3


Re: [PATCH v2] aarch64: fix off-by-one in reading cpuinfo

2022-10-06 Thread Richard Sandiford via Gcc-patches
Philipp Tomsich  writes:
> Fixes: 341573406b39
>
> Don't subtract one from the result of strnlen() when trying to point
> to the first character after the current string.  This issue would
> cause individual characters (where the 128 byte buffers are stitched
> together) to be lost.
>
> gcc/ChangeLog:
>
>   * config/aarch64/driver-aarch64.cc (readline): Fix off-by-one.
>
> gcc/testsuite/ChangeLog:
>
>   * gcc.target/aarch64/cpunative/info_18: New test.
>   * gcc.target/aarch64/cpunative/native_cpu_18.c: New test.
>
> Signed-off-by: Philipp Tomsich 
>
> ---
>
> Changes in v2:
> - Add a a regression test (as per review comment).
>
>  gcc/config/aarch64/driver-aarch64.cc  |  4 ++--
>  .../gcc.target/aarch64/cpunative/info_18  |  8 
>  .../gcc.target/aarch64/cpunative/native_cpu_18.c  | 15 +++
>  3 files changed, 25 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/cpunative/info_18
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
>
> diff --git a/gcc/config/aarch64/driver-aarch64.cc 
> b/gcc/config/aarch64/driver-aarch64.cc
> index 52ff537908e..48250e68034 100644
> --- a/gcc/config/aarch64/driver-aarch64.cc
> +++ b/gcc/config/aarch64/driver-aarch64.cc
> @@ -203,9 +203,9 @@ readline (FILE *f)
>   return std::string ();
>/* If we're not at the end of the line then override the
>\0 added by fgets.  */
> -  last = strnlen (buf, size) - 1;
> +  last = strnlen (buf, size);
>  }
> -  while (!feof (f) && buf[last] != '\n');
> +  while (!feof (f) && (last > 0 && buf[last - 1] != '\n'));

Very minor, but: I think the normal GCC style would be to avoid the
extra (...).

OK with that change, thanks.  OK for backports too after a settling period.

Richard

>  
>std::string result (buf);
>free (buf);
> diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_18 
> b/gcc/testsuite/gcc.target/aarch64/cpunative/info_18
> new file mode 100644
> index 000..25061a4abe8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_18
> @@ -0,0 +1,8 @@
> +processor: 0
> +BogoMIPS : 2000.00
> +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp 
> asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm 
> dit uscat ilrcpc flagm ssbs sb dcpodp flagm2 frint i8mm bf16 rng ecv
> +CPU implementer  : 0xc0
> +CPU architecture: 8
> +CPU variant  : 0x0
> +CPU part : 0xac3
> +CPU revision : 0
> diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c 
> b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
> new file mode 100644
> index 000..b5f0a3005f5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile { target { { aarch64*-*-linux*} && native } } } */
> +/* { dg-set-compiler-env-var GCC_CPUINFO 
> "$srcdir/gcc.target/aarch64/cpunative/info_18" } */
> +/* { dg-additional-options "-mcpu=native" } */
> +
> +int main()
> +{
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler {\.arch armv8.6-a\+crc\+fp16\+aes\+sha3\+rng} 
> } } */
> +
> +/* Test one where the boundary of buffer size would overwrite the last
> +   character read when stitching the fgets-calls together.  With the
> +   test data provided, this would truncate the 'sha512' into 'ha512'
> +   (dropping the 'sha3' feature). */


[COMMITED] ada: Implementation of support for storage models in gigi

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Eric Botcazou 

It is based on a new LOAD_EXPR node in GENERIC that is later turned into
a bona-fide temporary during gimplification.

gcc/ada/

* gcc-interface/ada-tree.def (LOAD_EXPR): New expression code.
* gcc-interface/gigi.h (build_storage_model_load): Declare.
(build_storage_model_store): Likewise.
(instantiate_load_in_expr): Likewise.
(INSTANTIATE_LOAD_IN_EXPR): New macro.
(instantiate_load_in_array_ref): Declare.
* gcc-interface/decl.cc (gnat_to_gnu_entity) : Set a
fake discriminant number on the fields of the template type.
(gnat_to_gnu_field): Use integer for DECL_DISCRIMINANT_NUMBER.
* gcc-interface/misc.cc (gnat_init_ts): Mark LOAD_EXPR as typed.
* gcc-interface/trans.cc (fold_constant_decl_in_expr) :
Also preserve the 4th operand.
(Attribute_to_gnu): Deal with LOAD_EXPR of unconstrained array type.
: Call INSTANTIATE_LOAD_IN_EXPR for a storage model.
: Likewise.
: Likewise.
(get_storage_model): New function.
(get_storage_model_access): Likewise.
(storage_model_access_required_p): Likewise.
(Call_to_gnu): Add GNAT_STORAGE_MODEL parameter and deal with it.
Also deal with actual parameters that have a storage model.
(gnat_to_gnu) : Adjust call to Call_to_gnu.
: Deal with a storage model access.
: Likewise.
: Likewise.
: Likewise.
: Adjust call to Call_to_gnu.  Deal with a
storage model access either on the LHS, on the RHS or on both.
: Adjust call to Call_to_gnu.
: Deal with a pool that is a storage model.
Replace test for UNCONSTRAINED_ARRAY_REF with test on the type.
(gnat_gimplify_expr) : Tidy up.
: New case.
: Move down.
* gcc-interface/utils.cc (maybe_unconstrained_array): Deal with a
LOAD_EXPR by recursing on its first operand.
* gcc-interface/utils2.cc (build_allocator): Deal with a pool that
is a storage model.
(build_storage_model_copy): New function.
(build_storage_model_load): Likewise.
(build_storage_model_store): Likewise.
(instantiate_load_in_expr): Likewise.
(instantiate_load_in_array_ref): Likewise.
(gnat_rewrite_reference) : Also preserve the 4th operand.
(get_inner_constant_reference) : Remove useless test.
(gnat_invariant_expr) : Rewrite test.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/gcc-interface/ada-tree.def |   4 +
 gcc/ada/gcc-interface/decl.cc  |   6 +-
 gcc/ada/gcc-interface/gigi.h   |  28 +++
 gcc/ada/gcc-interface/misc.cc  |   1 +
 gcc/ada/gcc-interface/trans.cc | 326 +
 gcc/ada/gcc-interface/utils.cc |   7 +
 gcc/ada/gcc-interface/utils2.cc| 294 --
 7 files changed, 605 insertions(+), 61 deletions(-)

diff --git a/gcc/ada/gcc-interface/ada-tree.def 
b/gcc/ada/gcc-interface/ada-tree.def
index 8eb4688e749..7fc95cb74c5 100644
--- a/gcc/ada/gcc-interface/ada-tree.def
+++ b/gcc/ada/gcc-interface/ada-tree.def
@@ -35,6 +35,10 @@ DEFTREECODE (UNCONSTRAINED_ARRAY_TYPE, 
"unconstrained_array_type", tcc_type, 0)
 DEFTREECODE (UNCONSTRAINED_ARRAY_REF, "unconstrained_array_ref",
 tcc_reference, 1)
 
+/* Same as SAVE_EXPR, but operand 1 contains the statement used to initialize
+   the temporary instead of using the value of operand 0 directly.  */
+DEFTREECODE (LOAD_EXPR, "load_expr", tcc_expression, 2)
+
 /* An expression that returns an RTL suitable for its type.  Operand 0
is an expression to be evaluated for side effects only.  */
 DEFTREECODE (NULL_EXPR, "null_expr", tcc_expression, 1)
diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index c5a93fb3acd..f8c76982de5 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -2279,6 +2279,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, 
bool definition)
  gnu_index_type,
  gnu_template_type, NULL_TREE,
  NULL_TREE, 0, 0);
+   /* Mark the field specifically for INSTANTIATE_LOAD_IN_EXPR.  */
+   DECL_DISCRIMINANT_NUMBER (gnu_lb_field) = integer_minus_one_node;
Sloc_to_locus (Sloc (gnat_entity),
   _SOURCE_LOCATION (gnu_lb_field));
 
@@ -2287,6 +2289,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, 
bool definition)
  gnu_index_type,
  gnu_template_type, NULL_TREE,
  NULL_TREE, 0, 0);
+   /* Mark the field specifically for INSTANTIATE_LOAD_IN_EXPR.  */
+   DECL_DISCRIMINANT_NUMBER (gnu_hb_field) = integer_minus_one_node;
Sloc_to_locus 

[COMMITED] ada: Minor potential bug in sem_ch6.adb

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Steve Baird 

In sem_ch6.adb, the procedure Analyze_Procedure_Call is preceded with a
comment:
   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos that jump to the end of the routine and restore the
   --  Ghost mode.

Correct a violation of this comment. This is a one-line change.

gcc/ada/

* sem_ch6.adb
(Analyze_Procedure_Call): Replace "return;" with "goto Leave;", as
per comment preceding body of Analyze_Procedure_Call.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch6.adb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 7db0cb7c08f..7ad6408af81 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -2398,7 +2398,7 @@ package body Sem_Ch6 is
Class_Wide_Type (Etype (First_Formal (Subp))) = Typ)
  and then Try_Object_Operation (P)
then
-  return;
+  goto Leave;
 
else
   Analyze_Call_And_Resolve;
-- 
2.34.1



[COMMITED] ada: Reject conditional goto in lock-free protected subprograms

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Piotr Trojanek 

In lock-free protected subprograms we don't allow goto statements;
likewise, we now reject conditional goto statements.

This fix only affects semantic checking mode with switch -gnatc.
In ordinary compilation we already rejected conditional goto after
it was expanded into ordinary goto.

gcc/ada/

* sem_ch9.adb (Allows_Lock_Free_Implementation): Reject
conditional goto statements.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch9.adb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb
index 6506358a02b..f2a59017865 100644
--- a/gcc/ada/sem_ch9.adb
+++ b/gcc/ada/sem_ch9.adb
@@ -453,7 +453,7 @@ package body Sem_Ch9 is
 
   --  Goto statements restricted
 
-  elsif Kind = N_Goto_Statement then
+  elsif Kind in N_Goto_Statement | N_Goto_When_Statement then
  if Lock_Free_Given then
 Error_Msg_N ("goto statement not allowed", N);
 return Skip;
-- 
2.34.1



[COMMITED] ada: stack scrubbing: exemplify codegen changes

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Alexandre Oliva 

gcc/ada/

* doc/gnat_rm/security_hardening_features.rst: Add examples of
codegen changes in stack scrubbing.
* gnat_rm.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../gnat_rm/security_hardening_features.rst   | 52 ++
 gcc/ada/gnat_rm.texi  | 53 ++-
 2 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/doc/gnat_rm/security_hardening_features.rst 
b/gcc/ada/doc/gnat_rm/security_hardening_features.rst
index f5fdc8e46b4..e36d47517dc 100644
--- a/gcc/ada/doc/gnat_rm/security_hardening_features.rst
+++ b/gcc/ada/doc/gnat_rm/security_hardening_features.rst
@@ -74,6 +74,58 @@ or a variable.)
  --  scrubbing of the stack space used by that subprogram.
 
 
+Given these declarations, Foo has its type and body modified as
+follows:
+
+.. code-block:: ada
+
+ function Foo ( : in out System.Address) returns Integer
+ is
+   --  ...
+ begin
+   <__strub_update> ();  --  Updates the stack WaterMark.
+   --  ...
+ end;
+
+
+whereas its callers are modified from:
+
+.. code-block:: ada
+
+ X := Foo;
+
+to:
+
+.. code-block:: ada
+
+ declare
+: System.Address;
+ begin
+   <__strub_enter> ();  -- Initialize .
+   X := Foo ();
+   <__strub_leave> ();  -- Scrubs stack up to .
+ end;
+
+
+As for Bar, because it is strubbed in internal mode, its callers are
+not modified.  Its definition is modified roughly as follows:
+
+.. code-block:: ada
+
+ procedure Bar is
+: System.Address;
+   procedure Strubbed_Bar ( : in out System.Address) is
+   begin
+ <__strub_update> ();  --  Updates the stack WaterMark.
+ -- original Bar body.
+   end Strubbed_Bar;
+ begin
+   <__strub_enter> ();  -- Initialize .
+   Strubbed_Bar ();
+   <__strub_leave> ();  -- Scrubs stack up to .
+ end Bar;
+
+
 There are also :switch:`-fstrub={choice}` command-line options to
 control default settings.  For usage and more details on the
 command-line options, on the ``strub`` attribute, and their use with
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 64f2e796d8a..ff1845661a4 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -3,7 +3,7 @@
 @setfilename gnat_rm.info
 @documentencoding UTF-8
 @ifinfo
-@*Generated by Sphinx 5.1.1.@*
+@*Generated by Sphinx 5.2.3.@*
 @end ifinfo
 @settitle GNAT Reference Manual
 @defindex ge
@@ -19,7 +19,7 @@
 
 @copying
 @quotation
-GNAT Reference Manual , Sep 23, 2022
+GNAT Reference Manual , Oct 04, 2022
 
 AdaCore
 
@@ -28734,6 +28734,55 @@ pragma Machine_Attribute (Var, "strub");
 --  scrubbing of the stack space used by that subprogram.
 @end example
 
+Given these declarations, Foo has its type and body modified as
+follows:
+
+@example
+function Foo ( : in out System.Address) returns Integer
+is
+  --  ...
+begin
+  <__strub_update> ();  --  Updates the stack WaterMark.
+  --  ...
+end;
+@end example
+
+whereas its callers are modified from:
+
+@example
+X := Foo;
+@end example
+
+to:
+
+@example
+declare
+   : System.Address;
+begin
+  <__strub_enter> ();  -- Initialize .
+  X := Foo ();
+  <__strub_leave> ();  -- Scrubs stack up to .
+end;
+@end example
+
+As for Bar, because it is strubbed in internal mode, its callers are
+not modified.  Its definition is modified roughly as follows:
+
+@example
+procedure Bar is
+   : System.Address;
+  procedure Strubbed_Bar ( : in out System.Address) is
+  begin
+<__strub_update> ();  --  Updates the stack WaterMark.
+-- original Bar body.
+  end Strubbed_Bar;
+begin
+  <__strub_enter> ();  -- Initialize .
+  Strubbed_Bar ();
+  <__strub_leave> ();  -- Scrubs stack up to .
+end Bar;
+@end example
+
 There are also @code{-fstrub=`choice'} command-line options to
 control default settings.  For usage and more details on the
 command-line options, on the @code{strub} attribute, and their use with
-- 
2.34.1



[COMMITED] ada: Cleanup related to lock-free protected subprograms

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Piotr Trojanek 

Cleanup code and documentation; semantics is unaffected.

gcc/ada/

* doc/gnat_rm/implementation_defined_pragmas.rst
(Lock_Free): Remove inconsistent periods that end item
descriptions.
* sem_ch9.adb
(Allows_Lock_Free_Implementation): Remove unnecessary guard
against an empty list of parameters; replace low-level entity kind
membership test with a high-level query; refill error message.
* gnat_rm.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst | 6 +++---
 gcc/ada/gnat_rm.texi   | 6 +++---
 gcc/ada/sem_ch9.adb| 8 +++-
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst 
b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
index 53836c9fbcf..6752d48d159 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
@@ -3744,10 +3744,10 @@ In addition, each protected subprogram body must 
satisfy:
 
 * May reference only one protected component
 * May not reference nonconstant entities outside the protected subprogram
-  scope.
+  scope
 * May not contain address representation items, allocators, or quantified
-  expressions.
-* May not contain delay, goto, loop, or procedure-call statements.
+  expressions
+* May not contain delay, goto, loop, or procedure-call statements
 * May not contain exported and imported entities
 * May not dereferenced access values
 * Function calls and attribute references must be static
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index e13dba037ff..e79cdeeacfe 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -5243,14 +5243,14 @@ May reference only one protected component
 
 @item 
 May not reference nonconstant entities outside the protected subprogram
-scope.
+scope
 
 @item 
 May not contain address representation items, allocators, or quantified
-expressions.
+expressions
 
 @item 
-May not contain delay, goto, loop, or procedure-call statements.
+May not contain delay, goto, loop, or procedure-call statements
 
 @item 
 May not contain exported and imported entities
diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb
index cae0f233c52..6506358a02b 100644
--- a/gcc/ada/sem_ch9.adb
+++ b/gcc/ada/sem_ch9.adb
@@ -178,8 +178,6 @@ package body Sem_Ch9 is
elsif Nkind (Decl) = N_Subprogram_Declaration
  and then
Nkind (Specification (Decl)) = N_Procedure_Specification
- and then
-   Present (Parameter_Specifications (Specification (Decl)))
then
   declare
  Par_Specs : constant List_Id   :=
@@ -477,7 +475,7 @@ package body Sem_Ch9 is
 --  Prohibit references to non-constant entities
 --  outside the protected subprogram scope.
 
-if Ekind (Id) in Assignable_Kind
+if Is_Assignable (Id)
   and then not
 Scope_Within_Or_Same (Scope (Id), Sub_Id)
   and then not
@@ -487,8 +485,8 @@ package body Sem_Ch9 is
 then
if Lock_Free_Given then
   Error_Msg_NE
-("reference to global variable& not " &
- "allowed", N, Id);
+("reference to global variable& not allowed",
+ N, Id);
   return Skip;
end if;
 
-- 
2.34.1



[COMMITED] ada: hardened conditionals: exemplify codegen changes

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Alexandre Oliva 

gcc/ada/

* doc/gnat_rm/security_hardening_features.rst: Add examples of
codegen changes in hardened conditionals.
* gnat_rm.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../gnat_rm/security_hardening_features.rst   | 51 ++-
 gcc/ada/gnat_rm.texi  | 47 -
 2 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/gcc/ada/doc/gnat_rm/security_hardening_features.rst 
b/gcc/ada/doc/gnat_rm/security_hardening_features.rst
index d8ea849c032..d7c02b94f36 100644
--- a/gcc/ada/doc/gnat_rm/security_hardening_features.rst
+++ b/gcc/ada/doc/gnat_rm/security_hardening_features.rst
@@ -203,11 +203,58 @@ activated by a separate command-line option.
 
 The option :switch:`-fharden-compares` enables hardening of compares
 that compute results stored in variables, adding verification that the
-reversed compare yields the opposite result.
+reversed compare yields the opposite result, turning:
+
+.. code-block:: ada
+
+B := X = Y;
+
+
+into:
+
+.. code-block:: ada
+
+B := X = Y;
+declare
+  NotB : Boolean := X /= Y; -- Computed independently of B.
+begin
+  if B = NotB then
+<__builtin_trap>;
+  end if;
+end;
+
 
 The option :switch:`-fharden-conditional-branches` enables hardening
 of compares that guard conditional branches, adding verification of
-the reversed compare to both execution paths.
+the reversed compare to both execution paths, turning:
+
+.. code-block:: ada
+
+if X = Y then
+  X := Z + 1;
+else
+  Y := Z - 1;
+end if;
+
+
+into:
+
+.. code-block:: ada
+
+if X = Y then
+  if X /= Y then -- Computed independently of X = Y.
+<__builtin_trap>;
+  end if;
+  X := Z + 1;
+else
+  if X /= Y then -- Computed independently of X = Y.
+null;
+  else
+<__builtin_trap>;
+  end if;
+  Y := Z - 1;
+end if;
+
 
 These transformations are introduced late in the compilation pipeline,
 long after boolean expressions are decomposed into separate compares,
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index dad0092713e..e13dba037ff 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -28858,11 +28858,54 @@ activated by a separate command-line option.
 
 The option @code{-fharden-compares} enables hardening of compares
 that compute results stored in variables, adding verification that the
-reversed compare yields the opposite result.
+reversed compare yields the opposite result, turning:
+
+@example
+B := X = Y;
+@end example
+
+into:
+
+@example
+B := X = Y;
+declare
+  NotB : Boolean := X /= Y; -- Computed independently of B.
+begin
+  if B = NotB then
+<__builtin_trap>;
+  end if;
+end;
+@end example
 
 The option @code{-fharden-conditional-branches} enables hardening
 of compares that guard conditional branches, adding verification of
-the reversed compare to both execution paths.
+the reversed compare to both execution paths, turning:
+
+@example
+if X = Y then
+  X := Z + 1;
+else
+  Y := Z - 1;
+end if;
+@end example
+
+into:
+
+@example
+if X = Y then
+  if X /= Y then -- Computed independently of X = Y.
+<__builtin_trap>;
+  end if;
+  X := Z + 1;
+else
+  if X /= Y then -- Computed independently of X = Y.
+null;
+  else
+<__builtin_trap>;
+  end if;
+  Y := Z - 1;
+end if;
+@end example
 
 These transformations are introduced late in the compilation pipeline,
 long after boolean expressions are decomposed into separate compares,
-- 
2.34.1



[COMMITED] ada: hardened booleans: exemplify codegen changes

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Alexandre Oliva 

Show the sort of code that is to be expected from using hardened
booleans in Ada code.  Mention that C traps instead of raising
exceptions.

gcc/ada/

* doc/gnat_rm/security_hardening_features.rst: Add examples of
codegen changes in hardened booleans. Mention that C traps where
Ada raises exceptions.
* gnat_rm.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../gnat_rm/security_hardening_features.rst   | 29 ---
 gcc/ada/gnat_rm.texi  | 26 +++--
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/gcc/ada/doc/gnat_rm/security_hardening_features.rst 
b/gcc/ada/doc/gnat_rm/security_hardening_features.rst
index e36d47517dc..d8ea849c032 100644
--- a/gcc/ada/doc/gnat_rm/security_hardening_features.rst
+++ b/gcc/ada/doc/gnat_rm/security_hardening_features.rst
@@ -265,19 +265,40 @@ further remove checks found to be redundant.
 For additional hardening, the ``hardbool`` :samp:`Machine_Attribute`
 pragma can be used to annotate boolean types with representation
 clauses, so that expressions of such types used as conditions are
-checked even when compiling with :switch:`-gnatVT`.
+checked even when compiling with :switch:`-gnatVT`:
 
 .. code-block:: ada
 
pragma Machine_Attribute (HBool, "hardbool");
 
+   function To_Boolean (X : HBool) returns Boolean is (Boolean (X));
+
+
+is compiled roughly like:
+
+.. code-block:: ada
+
+   function To_Boolean (X : HBool) returns Boolean is
+   begin
+ if X not in True | False then
+   raise Constraint_Error;
+ elsif X in True then
+   return True;
+ else
+   return False;
+ end if;
+   end To_Boolean;
+
 
 Note that :switch:`-gnatVn` will disable even ``hardbool`` testing.
 
 Analogous behavior is available as a GCC extension to the C and
-Objective C programming languages, through the ``hardbool`` attribute.
-For usage and more details on that attribute, see :title:`Using the
-GNU Compiler Collection (GCC)`.
+Objective C programming languages, through the ``hardbool`` attribute,
+with the difference that, instead of raising a Constraint_Error
+exception, when a hardened boolean variable is found to hold a value
+that stands for neither True nor False, the program traps.  For usage
+and more details on that attribute, see :title:`Using the GNU Compiler
+Collection (GCC)`.
 
 
 .. Control Flow Redundancy:
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index ff1845661a4..dad0092713e 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -28920,17 +28920,37 @@ further remove checks found to be redundant.
 For additional hardening, the @code{hardbool} @code{Machine_Attribute}
 pragma can be used to annotate boolean types with representation
 clauses, so that expressions of such types used as conditions are
-checked even when compiling with @code{-gnatVT}.
+checked even when compiling with @code{-gnatVT}:
 
 @example
 pragma Machine_Attribute (HBool, "hardbool");
+
+function To_Boolean (X : HBool) returns Boolean is (Boolean (X));
+@end example
+
+is compiled roughly like:
+
+@example
+function To_Boolean (X : HBool) returns Boolean is
+begin
+  if X not in True | False then
+raise Constraint_Error;
+  elsif X in True then
+return True;
+  else
+return False;
+  end if;
+end To_Boolean;
 @end example
 
 Note that @code{-gnatVn} will disable even @code{hardbool} testing.
 
 Analogous behavior is available as a GCC extension to the C and
-Objective C programming languages, through the @code{hardbool} attribute.
-For usage and more details on that attribute, see @cite{Using the GNU Compiler 
Collection (GCC)}.
+Objective C programming languages, through the @code{hardbool} attribute,
+with the difference that, instead of raising a Constraint_Error
+exception, when a hardened boolean variable is found to hold a value
+that stands for neither True nor False, the program traps.  For usage
+and more details on that attribute, see @cite{Using the GNU Compiler 
Collection (GCC)}.
 
 @c Control Flow Redundancy:
 
-- 
2.34.1



[PATCH v2] aarch64: update Ampere-1 core definition

2022-10-06 Thread Philipp Tomsich
This brings the extensions detected by -mcpu=native on Ampere-1 systems
in sync with the defaults generated for -mcpu=ampere1.

Note that some early kernel versions on Ampere1 may misreport the
presence of PAUTH and PREDRES (i.e., -mcpu=native will add 'nopauth'
and 'nopredres').

gcc/ChangeLog:

* config/aarch64/aarch64-cores.def (AARCH64_CORE): Update
  Ampere-1 core entry.

Signed-off-by: Philipp Tomsich 

---
Ok for backport?

Changes in v2:
- Removed explicit RCPC, as the feature is now implicitly included
  in the 8.3 feature definition.

 gcc/config/aarch64/aarch64-cores.def | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/aarch64/aarch64-cores.def 
b/gcc/config/aarch64/aarch64-cores.def
index b50628d6b51..e9a4b622be0 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -69,7 +69,7 @@ AARCH64_CORE("thunderxt81",   thunderxt81,   thunderx,  V8A,  
(CRC, CRYPTO), thu
 AARCH64_CORE("thunderxt83",   thunderxt83,   thunderx,  V8A,  (CRC, CRYPTO), 
thunderx,  0x43, 0x0a3, -1)
 
 /* Ampere Computing ('\xC0') cores. */
-AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (), ampere1, 0xC0, 0xac3, 
-1)
+AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (F16, RNG, AES, SHA3), 
ampere1, 0xC0, 0xac3, -1)
 /* Do not swap around "emag" and "xgene1",
this order is required to handle variant correctly. */
 AARCH64_CORE("emag",emag,  xgene1,V8A,  (CRC, CRYPTO), emag, 
0x50, 0x000, 3)
-- 
2.34.1



[COMMITED] ada: Add C declarations for Storage Model support

2022-10-06 Thread Marc Poulhiès via Gcc-patches
Add needed C declarations for Storage Model support in gigi.

gcc/ada/

* fe.h (Has_Storage_Model_Type_Aspect)
(Has_Designated_Storage_Model_Aspect, Storage_Model_Object)
(Storage_Model_Copy_From, Storage_Model_Copy_To): Add
declarations.
* sem_util.ads: Add WARNING markers for functions for which a new
C declaration has been added in fe.h

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/fe.h | 10 ++
 gcc/ada/sem_util.ads | 10 ++
 2 files changed, 20 insertions(+)

diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h
index 02cf105d5e1..79a1b58836e 100644
--- a/gcc/ada/fe.h
+++ b/gcc/ada/fe.h
@@ -304,17 +304,27 @@ extern Boolean Compile_Time_Known_Value   (Node_Id);
 
 #define Defining_Entitysem_util__defining_entity
 #define First_Actual   sem_util__first_actual
+#define Has_Storage_Model_Type_Aspect  
sem_util__storage_model_support__has_storage_model_type_aspect
+#define Has_Designated_Storage_Model_Aspect 
sem_util__storage_model_support__has_designated_storage_model_aspect
 #define Is_Expression_Function sem_util__is_expression_function
 #define Is_Variable_Size_Recordsem_util__is_variable_size_record
 #define Needs_Secondary_Stack  sem_util__needs_secondary_stack
 #define Next_Actualsem_util__next_actual
+#define Storage_Model_Object   
sem_util__storage_model_support__storage_model_object
+#define Storage_Model_Copy_From
sem_util__storage_model_support__storage_model_copy_from
+#define Storage_Model_Copy_To  
sem_util__storage_model_support__storage_model_copy_to
 
 extern Entity_Id Defining_Entity   (Node_Id);
 extern Node_Id First_Actual(Node_Id);
+extern Boolean Has_Storage_Model_Type_Aspect   (Entity_Id);
+extern Boolean Has_Designated_Storage_Model_Aspect (Entity_Id);
 extern Boolean Is_Expression_Function  (Entity_Id);
 extern Boolean Is_Variable_Size_Record (Entity_Id);
 extern Boolean Needs_Secondary_Stack   (Entity_Id);
 extern Node_Id Next_Actual (Node_Id);
+extern Entity_Id Storage_Model_Object  (Entity_Id);
+extern Entity_Id Storage_Model_Copy_From   (Entity_Id);
+extern Entity_Id Storage_Model_Copy_To (Entity_Id);
 
 /* sinfo: */
 
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 132c2b8cddf..c23d358e2fb 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -3655,10 +3655,14 @@ package Sem_Util is
   function Has_Storage_Model_Type_Aspect (Typ : Entity_Id) return Boolean;
   --  Returns True iff Typ specifies aspect Storage_Model_Type
 
+  --  WARNING: There is a matching C declaration of this subprogram in fe.h
+
   function Has_Designated_Storage_Model_Aspect
 (Typ : Entity_Id) return Boolean;
   --  Returns True iff Typ specifies aspect Designated_Storage_Model
 
+  --  WARNING: There is a matching C declaration of this subprogram in fe.h
+
   function Storage_Model_Object (Typ : Entity_Id) return Entity_Id;
   --  Given an access type Typ with aspect Designated_Storage_Model,
   --  returns the storage-model object associated with that type.
@@ -3666,6 +3670,8 @@ package Sem_Util is
   --  other functions declared in this interface to retrieve operations
   --  associated with Storage_Model_Type aspect of the object's type.
 
+  --  WARNING: There is a matching C declaration of this subprogram in fe.h
+
   function Storage_Model_Type (Obj : Entity_Id) return Entity_Id;
   --  Given an object Obj of a type specifying aspect Storage_Model_Type,
   --  returns that type.
@@ -3715,12 +3721,16 @@ package Sem_Util is
   --  type, returns the procedure specified for the Copy_From choice in
   --  that aspect; returns Empty if the procedure isn't specified.
 
+  --  WARNING: There is a matching C declaration of this subprogram in fe.h
+
   function Storage_Model_Copy_To
 (SM_Obj_Or_Type : Entity_Id) return Entity_Id;
   --  Given a type with aspect Storage_Model_Type or an object of such a
   --  type, returns the procedure specified for the Copy_To choice in that
   --  aspect; returns Empty if the procedure isn't specified.
 
+  --  WARNING: There is a matching C declaration of this subprogram in fe.h
+
   function Storage_Model_Storage_Size
 (SM_Obj_Or_Type : Entity_Id) return Entity_Id;
   --  Given a type with aspect Storage_Model_Type or an object of such a
-- 
2.34.1



[COMMITED] ada: Fix inserting of validity checks in lock-free protected subprograms

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Piotr Trojanek 

Validity checks for statements in a lock-free implementation of
protected subprogram were wrongly inserted in front of the original
statements. This happened because the lock-free implementation was
created as a shallow copy, where only the protected body statements were
copied while its children still had the Parent pointing to the original
statements.

gcc/ada/

* exp_ch9.adb (Build_Lock_Free_Protected_Subprogram_Body): Replace
shallow copy of protected statements with a deep copy.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_ch9.adb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 8abff55110d..decf61782af 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -2797,7 +2797,7 @@ package body Exp_Ch9 is
 Expected_Comp : Entity_Id;
 Stmt  : Node_Id;
 Stmts : List_Id :=
-  New_Copy_List (Statements (Hand_Stmt_Seq));
+  New_Copy_List_Tree (Statements (Hand_Stmt_Seq));
 Typ_Size  : Int;
 Unsigned  : Entity_Id;
 
-- 
2.34.1



[COMMITED] ada: Incorrect inferences drawn from if/elsif/while conditions with -gnatVo

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Steve Baird 

Within the first (respectively, second) statement list of this if statement
  declare
 X : constant Integer := ... ;
  begin
 if X > 0 then
   ...;
 else
   ...;
 end if;
  end;
we can safely assume that X is greater (respectively, not greater) than 0.

Fix a bug that incorrectly computed the region in which such assumptions
can be made to include the condition of the if-statement. This bug usually
had no effect because semantic analysis/simplification of the condition was
already complete before the code containing the bug was executed.
Unfortunately, this is not true in some cases involving -gnatVo validity
checking. In these cases, the bug could result in incorrect simplification
of the condition at compile time. This, in turn, could lead to incorrect
unconditional execution of one arm of the if-statement at run time. Similar
errors appear to be possible for the conditions of an elsif or a while loop;
the fix addresses these cases as well, although corresponding problems with
these constructs have not been demonstrated.

gcc/ada/

* exp_util.adb
(Get_Current_Value_Condition): Treat references occurring within
the condition of an if statement, an elsif, or a while loop in the
same way as references that occur before the start of that
enclosing construct.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_util.adb | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 61395adf195..f569d2ef583 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -6923,6 +6923,11 @@ package body Exp_Util is
 if Loc < Sloc (CV) then
return;
 
+--  In condition of IF statement
+
+elsif In_Subtree (N => Var, Root => Condition (CV)) then
+   return;
+
 --  After end of IF statement
 
 elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
@@ -7009,7 +7014,12 @@ package body Exp_Util is
 if Loc < Sloc (CV) then
return;
 
-   --  After end of IF statement
+--  In condition of ELSIF part
+
+elsif In_Subtree (N => Var, Root => Condition (CV)) then
+   return;
+
+--  After end of IF statement
 
 elsif Loc >= Sloc (Stm) +
   Text_Ptr (UI_To_Int (End_Span (Stm)))
@@ -7066,6 +7076,11 @@ package body Exp_Util is
if Loc < Sloc (Loop_Stmt) then
   return;
 
+   --  In condition of while loop
+
+   elsif In_Subtree (N => Var, Root => Condition (CV)) then
+  return;
+
--  After end of LOOP statement
 
elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
-- 
2.34.1



[COMMITED] ada: Accessibility error incorrectly flagged on call within Pre'Class expression

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Gary Dismukes 

The compiler was wrongly reporting an error on a function call within
a Pre'Class expression when a formal of the aspect's subprogram was
passed to an aliased formal. This occurred due to the call appearing
with the return statement of the wrapper function created for the
precondition, but the accessibility error check should only be done
for return statements that appear in the source program.

gcc/ada/

* sem_ch4.adb (Analyze_Call): Add test of Comes_From_Source on the
enclosing subprogram's Entity_Id for determining whether to
perform the compile-time accessibility check on actuals passed to
aliased formals in a function call occurring within a return
statement. That test excludes cases where the call occurs within
the return statement of a Pre'Class wrapper function.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch4.adb | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index ceaf66bd3e2..6824941fa34 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -1467,12 +1467,17 @@ package body Sem_Ch4 is
   end if;
 
   --  Check the accessibility level for actuals for explicitly aliased
-  --  formals.
+  --  formals when a function call appears within a return statement.
+  --  This is only checked if the enclosing subprogram Comes_From_Source,
+  --  to avoid issuing errors on calls occurring in wrapper subprograms
+  --  (for example, where the call is part of an expression of an aspect
+  --  associated with a wrapper, such as Pre'Class).
 
   if Nkind (N) = N_Function_Call
 and then Comes_From_Source (N)
 and then Present (Nam_Ent)
 and then In_Return_Value (N)
+and then Comes_From_Source (Current_Subprogram)
   then
  declare
 Form : Node_Id;
-- 
2.34.1



[PATCH v2] aarch64: fix off-by-one in reading cpuinfo

2022-10-06 Thread Philipp Tomsich
Fixes: 341573406b39

Don't subtract one from the result of strnlen() when trying to point
to the first character after the current string.  This issue would
cause individual characters (where the 128 byte buffers are stitched
together) to be lost.

gcc/ChangeLog:

* config/aarch64/driver-aarch64.cc (readline): Fix off-by-one.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/cpunative/info_18: New test.
* gcc.target/aarch64/cpunative/native_cpu_18.c: New test.

Signed-off-by: Philipp Tomsich 

---

Changes in v2:
- Add a a regression test (as per review comment).

 gcc/config/aarch64/driver-aarch64.cc  |  4 ++--
 .../gcc.target/aarch64/cpunative/info_18  |  8 
 .../gcc.target/aarch64/cpunative/native_cpu_18.c  | 15 +++
 3 files changed, 25 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/cpunative/info_18
 create mode 100644 gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c

diff --git a/gcc/config/aarch64/driver-aarch64.cc 
b/gcc/config/aarch64/driver-aarch64.cc
index 52ff537908e..48250e68034 100644
--- a/gcc/config/aarch64/driver-aarch64.cc
+++ b/gcc/config/aarch64/driver-aarch64.cc
@@ -203,9 +203,9 @@ readline (FILE *f)
return std::string ();
   /* If we're not at the end of the line then override the
 \0 added by fgets.  */
-  last = strnlen (buf, size) - 1;
+  last = strnlen (buf, size);
 }
-  while (!feof (f) && buf[last] != '\n');
+  while (!feof (f) && (last > 0 && buf[last - 1] != '\n'));
 
   std::string result (buf);
   free (buf);
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_18 
b/gcc/testsuite/gcc.target/aarch64/cpunative/info_18
new file mode 100644
index 000..25061a4abe8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_18
@@ -0,0 +1,8 @@
+processor  : 0
+BogoMIPS   : 2000.00
+Features   : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp 
asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm dit 
uscat ilrcpc flagm ssbs sb dcpodp flagm2 frint i8mm bf16 rng ecv
+CPU implementer: 0xc0
+CPU architecture: 8
+CPU variant: 0x0
+CPU part   : 0xac3
+CPU revision   : 0
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
new file mode 100644
index 000..b5f0a3005f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_18.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { { aarch64*-*-linux*} && native } } } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/aarch64/cpunative/info_18" } */
+/* { dg-additional-options "-mcpu=native" } */
+
+int main()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.arch armv8.6-a\+crc\+fp16\+aes\+sha3\+rng} } 
} */
+
+/* Test one where the boundary of buffer size would overwrite the last
+   character read when stitching the fgets-calls together.  With the
+   test data provided, this would truncate the 'sha512' into 'ha512'
+   (dropping the 'sha3' feature). */
-- 
2.34.1



[COMMITED] ada: Clean up slice-of-component optimization

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Bob Duff 

In the recursive case of Volatile_Or_Independent = False for array
types, fall through into later checks, so for example we check
the type of the prefix of a slice. The pattern here is "return True
in certain cases, otherwise fall through into the final 'return False'".

Remove check for "Ndim = 1"; if Slices is True, then the number of
dimensions is necessarily 1, because Ada doesn't have multi-dimensional
slices.

gcc/ada/

* exp_ch5.adb
(Expand_Assign_Array_Loop_Or_Bitfield): Minor cleanups.

Tested on x86_64-pc-linux-gnu, committed on master.
---
 gcc/ada/exp_ch5.adb | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 9669737a79b..d5d66d961de 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -1632,7 +1632,10 @@ package body Exp_Ch5 is
  end if;
 
  if Is_Array_Type (Typ) then
-return Volatile_Or_Independent (Empty, Component_Type (Typ));
+if Volatile_Or_Independent (Empty, Component_Type (Typ)) then
+   return True;
+end if;
+
  elsif Is_Record_Type (Typ) then
 declare
Comp : Entity_Id := First_Component (Typ);
@@ -1688,7 +1691,6 @@ package body Exp_Ch5 is
 and then Is_Bit_Packed_Array (R_Type)
 and then not Reverse_Storage_Order (L_Type)
 and then not Reverse_Storage_Order (R_Type)
-and then Ndim = 1
 and then Slices
 and then not Slice_Of_Packed_Component (L)
 and then not Volatile_Or_Independent (L, L_Type)
-- 
2.34.1



[COMMITED] ada: Do not issue compiler warnings in GNATprove mode

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Yannick Moy 

Use of pragma Warning with a string literal to set warning
switches, should not impact GNATprove which is not subject
to these switches.

gcc/ada/

* sem_prag.adb (Analyze_Pragma): Ignore one variant of pragma
Warnings in GNATprove mode.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_prag.adb | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 0c3dd815263..f85d0919e7b 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -25731,6 +25731,13 @@ package body Sem_Prag is
("argument of pragma% must be On/Off or static string "
 & "expression", Arg1);
 
+  --  Use of pragma Warnings to set warning switches is
+  --  ignored in GNATprove mode, as these switches apply to
+  --  the compiler only.
+
+  elsif GNATprove_Mode then
+ null;
+
   --  One argument string expression case
 
   else
-- 
2.34.1



[COMMITED] ada: Disable slice-of-component optimization in some cases

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Bob Duff 

This patch disables the Fast_Copy_Bitfield optimization in certain rare
cases that currently do not work (crash in gigi). We could improve
Expand_Assign_Array_Bitfield_Fast to handle these cases properly, but
that change is delicate, so for now, we simply disable the optimization.

gcc/ada/

* exp_ch5.adb
(Expand_Assign_Array_Loop_Or_Bitfield): Disable the
Fast_Copy_Bitfield optimization in certain cases.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_ch5.adb | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 209741c82cf..9669737a79b 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -1660,6 +1660,15 @@ package body Exp_Ch5 is
  return False;
   end Volatile_Or_Independent;
 
+  function Slice_Of_Packed_Component (L : Node_Id) return Boolean is
+(Nkind (L) = N_Slice
+ and then Nkind (Prefix (L)) = N_Indexed_Component
+ and then Is_Bit_Packed_Array (Etype (Prefix (Prefix (L);
+  --  L is the left-hand side Name. Returns True if L is a slice of a
+  --  component of a bit-packed array. The optimization is disabled in
+  --  that case, because Expand_Assign_Array_Bitfield_Fast cannot
+  --  currently handle that case correctly.
+
   L : constant Node_Id := Name (N);
   R : constant Node_Id := Expression (N);
   --  Left- and right-hand sides of the assignment statement
@@ -1681,6 +1690,7 @@ package body Exp_Ch5 is
 and then not Reverse_Storage_Order (R_Type)
 and then Ndim = 1
 and then Slices
+and then not Slice_Of_Packed_Component (L)
 and then not Volatile_Or_Independent (L, L_Type)
 and then not Volatile_Or_Independent (R, R_Type)
   then
-- 
2.34.1



[COMMITED] ada: Fix spurious warning on unreferenced refinement constituents

2022-10-06 Thread Marc Poulhiès via Gcc-patches
From: Piotr Trojanek 

Listing an object as a state refinement constituent shouldn't be
considered to be a reference, at least from the point of view of the
machinery for detecting objects that are never referenced or written
without being referenced.

This patch fixes a spurious warning that rarely occurred in practice but
was annoyingly emitted for minimal reproducers for issues related to
state abstractions.

Note: there are other pragmas that should be similarly recognized (e.g.
Depends, Global and their refined variants), but recognizing them
efficiently probably requires a dedicated utility routine (i.e. to avoid
traversal of the parent chain for every kind of pragma).

gcc/ada/

* sem_prag.adb
(Sig_Pragma): Change flag for pragma Refined_State to mean "not
significant"; this is primarily for documentation, because the
exact value of the flag is not really taken into account for
Refined_State.
(Is_Non_Significant_Pragma_Reference): Add special handling for
pragma Refined_State.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_prag.adb | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 77ff68e23cb..0c3dd815263 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -31608,7 +31608,7 @@ package body Sem_Prag is
   Pragma_Refined_Depends=> -1,
   Pragma_Refined_Global => -1,
   Pragma_Refined_Post   => -1,
-  Pragma_Refined_State  => -1,
+  Pragma_Refined_State  =>  0,
   Pragma_Relative_Deadline  =>  0,
   Pragma_Remote_Access_Type => -1,
   Pragma_Remote_Call_Interface  => -1,
@@ -31713,6 +31713,15 @@ package body Sem_Prag is
   P := Parent (N);
 
   if Nkind (P) /= N_Pragma_Argument_Association then
+
+ --  References within pragma Refined_State are not significant. They
+ --  can't be recognized using pragma argument number, because they
+ --  appear inside refinement clauses that rely on aggregate syntax.
+
+ if In_Pragma_Expression (N, Name_Refined_State) then
+return True;
+ end if;
+
  return False;
 
   else
-- 
2.34.1



Re: [PATCH] aarch64: update Ampere-1 core definition

2022-10-06 Thread Philipp Tomsich
On Tue, 4 Oct 2022 at 18:43, Richard Sandiford
 wrote:
>
> Philipp Tomsich  writes:
> > This brings the extensions detected by -mcpu=native on Ampere-1 systems
> > in sync with the defaults generated for -mcpu=ampere1.
> >
> > Note that some kernel versions may misreport the presence of PAUTH and
> > PREDRES (i.e., -mcpu=native will add 'nopauth' and 'nopredres').
> >
> > gcc/ChangeLog:
> >
> >   * config/aarch64/aarch64-cores.def (AARCH64_CORE): Update
> >   Ampere-1 core entry.
> >
> > Signed-off-by: Philipp Tomsich 
> >
> > ---
> > Ok for backport?
> >
> >  gcc/config/aarch64/aarch64-cores.def | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/gcc/config/aarch64/aarch64-cores.def 
> > b/gcc/config/aarch64/aarch64-cores.def
> > index 60299160bb6..9090f80b4b7 100644
> > --- a/gcc/config/aarch64/aarch64-cores.def
> > +++ b/gcc/config/aarch64/aarch64-cores.def
> > @@ -69,7 +69,7 @@ AARCH64_CORE("thunderxt81",   thunderxt81,   thunderx,  
> > V8A,  (CRC, CRYPTO), thu
> >  AARCH64_CORE("thunderxt83",   thunderxt83,   thunderx,  V8A,  (CRC, 
> > CRYPTO), thunderx,  0x43, 0x0a3, -1)
> >
> >  /* Ampere Computing ('\xC0') cores. */
> > -AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (), ampere1, 0xC0, 
> > 0xac3, -1)
> > +AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (F16, RCPC, RNG, AES, 
> > SHA3), ampere1, 0xC0, 0xac3, -1)
>
> The fact that you had include RCPC here shows that there was a bug
> in the definition of Armv8.3-A.  I've just pushed a fix for that.
>
> Otherwise, this seems to line up with the LLVM definition, except
> that this definition enables RNG/AEK_RAND whereas the LLVM one doesn't
> seem to.  Which one's right (or is it me that's wrong)?

I just rechecked, and the latest documents (in correspondence to the
/proc/cpuinfo-output) confirm that FEAT_RNG is implemented.

LLVM needs to be updated to reflect that RNG is implemented.

>
> Thanks,
> Richard
>
>
> >  /* Do not swap around "emag" and "xgene1",
> > this order is required to handle variant correctly. */
> >  AARCH64_CORE("emag",emag,  xgene1,V8A,  (CRC, CRYPTO), 
> > emag, 0x50, 0x000, 3)


Re: [PATCH][pushed] contrib: run fetch before pushing Daily bump

2022-10-06 Thread Martin Liška
On 10/5/22 22:09, Tobias Burnus wrote:
> On 05.10.22 20:41, Martin Liška wrote:
>> +++ b/contrib/gcc-changelog/git_update_version.py
>> @@ -127,6 +127,7 @@ def update_current_branch(ref_name):
>>   repo.git.add(datestamp_path)
>>   if not args.current:
>>   repo.index.commit('Daily bump.')
>> +    origin.fetch()
>>   if args.push:
>>   repo.git.push('origin', branch)
>>   print('branch is pushed')
> 
> Don't you need a 'rebase' in addition?

Well, no, because that would mean the script won't generate a ChangeLog entry 
for some commits.

> Or alternately – putting 'fetch'
> before 'commit' and then 'merge' would be alternately possible.

Well, the window is pretty small, in between 'git pull' and processing the 
ChangeLog entries
it should take only a few seconds before a push is done.

Anyway, it failed today again, let me add more robust logging.

Martin

> 
> Tobias
> 
> -
> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
> München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
> Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
> München, HRB 106955



[committed] arc: Remove max-page-size and common-page-size forced setting

2022-10-06 Thread Claudiu Zissulescu via Gcc-patches
Max page size is defined in the ARC's BFD file, and the common page
size is also set by the appropriate binutils macros. Remove them from
LINK_SPEC.

2022-10-06  Claudiu Zissulescu  

* config/arc/linux.h (LINK_SPEC): Remove max-page-size and
common-pave-size.

Signed-off-by: Claudiu Zissulescu 
---
 gcc/config/arc/linux.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/config/arc/linux.h b/gcc/config/arc/linux.h
index 0f1ff055be7..6ebbb143895 100644
--- a/gcc/config/arc/linux.h
+++ b/gcc/config/arc/linux.h
@@ -45,7 +45,6 @@ along with GCC; see the file COPYING3.  If not see
 %{!shared:-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}} \
   -X \
   %{mbig-endian:-EB} %{EB} %{EL} \
-  %{!z:-z max-page-size=0x2000 -z common-page-size=0x2000} \
   %{mcpu=nps400:-marclinux_nps; :-marclinux}"
 
 #undef STARTFILE_SPEC
-- 
2.30.2



[committed] openmp: Map holds clause to IFN_ASSUME for C/C++

2022-10-06 Thread Jakub Jelinek via Gcc-patches
Hi!

Now that [[assume (cond)]] support is in, this simple patch makes
  #pragma omp assume holds(cond)
use it.

Committed to trunk.

2022-10-06  Jakub Jelinek  

* c-parser.cc (c_parser_omp_assumption_clauses): Emit IFN_ASSUME
call for holds clause on assume construct.

* parser.cc (cp_parser_omp_assumption_clauses): Emit IFN_ASSUME
call for holds clause on assume construct.

* c-c++-common/gomp/assume-4.c: New test.

--- gcc/c/c-parser.cc.jj2022-10-06 08:56:28.570128568 +0200
+++ gcc/c/c-parser.cc   2022-10-06 10:07:25.596420330 +0200
@@ -23571,10 +23571,12 @@ c_parser_omp_assumption_clauses (c_parse
  tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
  t = c_objc_common_truthvalue_conversion (eloc, t);
  t = c_fully_fold (t, false, NULL);
- if (is_assume)
+ if (is_assume && t != error_mark_node)
{
- /* FIXME: Emit .ASSUME (t) call here.  */
- (void) t;
+ tree fn = build_call_expr_internal_loc (eloc, IFN_ASSUME,
+ void_type_node, 1,
+ t);
+ add_stmt (fn);
}
  parens.skip_until_found_close (parser);
}
--- gcc/cp/parser.cc.jj 2022-10-06 08:56:28.625127823 +0200
+++ gcc/cp/parser.cc2022-10-06 10:20:35.452732109 +0200
@@ -46023,13 +46023,15 @@ cp_parser_omp_assumption_clauses (cp_par
  matching_parens parens;
  if (parens.require_open (parser))
{
+ location_t eloc = cp_lexer_peek_token (parser->lexer)->location;
  tree t = cp_parser_assignment_expression (parser);
  if (!type_dependent_expression_p (t))
t = contextual_conv_bool (t, tf_warning_or_error);
- if (is_assume)
+ if (is_assume && !error_operand_p (t))
{
- /* FIXME: Emit .ASSUME (t) call here.  */
- (void) t;
+ t = build_call_expr_internal_loc (eloc, IFN_ASSUME,
+   void_type_node, 1, t);
+ finish_expr_stmt (t);
}
  if (!parens.require_close (parser))
cp_parser_skip_to_closing_parenthesis (parser,
--- gcc/testsuite/c-c++-common/gomp/assume-4.c.jj   2022-10-06 
10:17:58.028862432 +0200
+++ gcc/testsuite/c-c++-common/gomp/assume-4.c  2022-10-06 10:23:41.011221059 
+0200
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "return 42;" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "return -1;" "optimized" } } */
+
+int
+foo (int x)
+{
+  int y;
+  #pragma omp assume holds (x == 42)
+  y = x;
+  return y;
+}
+
+int
+bar (int x)
+{
+  #pragma omp assume holds (x < 42)
+  ;
+  if (x == 42)
+return -1;
+  return 42;
+}

Jakub



Re: [PATCH] Add __builtin_iseqsig()

2022-10-06 Thread FX via Gcc-patches
ping*3
please?


> Le 21 sept. 2022 à 11:40, FX  a écrit :
> 
> ping*2
> 
> <0001-Add-__builtin_iseqsig.patch>
> 
>> Le 9 sept. 2022 à 19:55, FX  a écrit :
>> 
>> ping
>> 
>> 
>>> Le 1 sept. 2022 à 23:02, FX  a écrit :
>>> 
>>> Attached patch adds __builtin_iseqsig() to the middle-end and C family 
>>> front-ends.
>>> Testing does not currently check whether the signaling part works, because 
>>> with optimisation is actually does not (preexisting compiler bug: 
>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106805)
>>> 
>>> Bootstrapped and regtested on x86_64-linux.
>>> OK to commit?
>>> 
>>> (I’m not very skilled for middle-end hacking, so I’m sure there will be 
>>> modifications to make.)
>>> 
>>> FX
>>> <0001-Add-__builtin_iseqsig.patch>
>> 
> 



Re: [PATCH] IPA: support -flto + -flive-patching=inline-clone

2022-10-06 Thread Martin Liška
On 10/6/22 10:29, Richard Biener wrote:
> On Wed, Oct 5, 2022 at 8:18 PM Qing Zhao via Gcc-patches
>  wrote:
>>
>>
>>
>>> On Oct 5, 2022, at 1:36 PM, Martin Liška  wrote:
>>>
>>> On 10/5/22 16:50, Qing Zhao wrote:
 I have two questions on this:
>>>
>>> Hello.
>>>

 1.  What’s the motivation to enable -flive-patching with -flto? Is there 
 any application that will try -flive-patching with -flto now?
>>>
>>> We're planning supporting GCC LTO Linux kernel support, so that's one 
>>> motivation. And the second one is a possible
>>> use in user-space livepatching. Note majority of modern distros default to 
>>> -flto (openSUSE, Fedora, Debian, Ubuntu, ...).
>>
>> Okay, I see. That’s reasonable.
>>>

 2. Why only enable -flive-patching=inline-clone with -flto?
>>>
>>> Because the inline-only-static level (which you added/requested) would have 
>>> to properly
>>> block inter-procedural inlining that happens in LTO 
>>> (can_inline_edge_by_limits_p) and
>>> I'm not sure it would be properly blocked. So, feel free to extend my patch 
>>> if you want?
>>
>> -flive-patching=inline-only-static
>>
>> Only enable static functions inlining,  all the inlining of external visible 
>> functions are blocked, So, LTO should be compatible with this naturally 
>> without any issue, I think.
>>
>> i.e, when "-flive-patching=inline-only-static -flto"  present together, all 
>> the inter-procedural inlining should be automatically blocked by 
>> -flive-patching=inline-only-static already.
>>
>> Do I miss anything here?
> 
> WPA will promote externally visible functions static when all accesses
> are from LTO IR, I don't think we preserve
> the "original" visibility for IPA inlining heuristics.

That said, can we go with my original patch?

> 
> OTOH inline-only-static could disable WPA inlining and do all inlining early 
> ...

And this can be extended by Oracle folks if they are interested in 
-flive-patching=inline-only-static
combined with LTO.

Martin

> 
> Richard,
> 
>>
>> thanks.
>>
>> Qing
>>
>>>
>>> Martin
>>>

 thanks.
>>>
>>



Re: [PATCH, v2] Fortran: reject procedures and procedure pointers as IO element [PR107074]

2022-10-06 Thread Mikael Morin

Le 05/10/2022 à 22:40, Harald Anlauf a écrit :

Hi Mikael,


Gesendet: Mittwoch, 05. Oktober 2022 um 12:34 Uhr
Von: "Mikael Morin" 
Please move the check to resolve_transfer in resolve.cc.


I have done this, see attached updated patch.

Regtests cleanly on x86_64-pc-linux-gnu.


Strangely, the patch doesn't seem to fix the problem on the testcase
here.  There is an outer parenthese expression preventing the condition
you added from triggering.  Can you double check?


You are right: I had a one-liner in my worktree from PR105371 that
fixes an issue with gfc_simplify_merge and that seems to help here.
It is now included.


The rest looks good, but I'm not sure about your one-liner.
I will try to come with a real test later, but in principle, if you have 
a call to FOO(MERGE(A,A,.TRUE.)) you can't simplify it to FOO(A) as 
writes to the argument in FOO should not overwrite the content of A. 
The dummy should be associated with a temporary value, not to A.






Re: c: C2x typeof

2022-10-06 Thread Richard Biener via Gcc-patches
On Thu, Oct 6, 2022 at 3:22 AM Joseph Myers  wrote:
>
> [C++ maintainers / global reviewers, note that there is a C++
> front-end change here needing review.]
>
> C2x adds typeof as a standard feature.  In general this follows
> existing GNU C semantics very closely, but there are various ways in
> which the implementation involves more than simply enabling the
> keyword for C2x:
>
> * As well as typeof, there is a typeof_unqual variant, which removes
>   all qualifiers and _Atomic from the resulting type (whereas typeof
>   preserves qualifiers and _Atomic on qualified or atomic (lvalue or
>   type name) operands).
>
> * The typeof keyword is disabled by -fno-asm, so enabling it for C2x
>   needs to be implemented in a way that preserves the disabling by
>   -fno-asm for older standard versions (which having -fno-asm having
>   no effect on it in C2x mode).  This is done via adding a new D_EXT11
>   mask (which is also where the C++ front-end change comes from, to
>   handle D_EXT11 appropriately there for -fno-asm and
>   -fno-gnu-keywords).
>
> * GNU typeof treats the noreturn property of a function (as specified
>   in standard C with _Noreturn or [[noreturn]]) as being part of the
>   type of a pointer to function, but it is not part of the type in
>   standard terms.  Thus a special case is needed in the typeof
>   implementation, just like in the _Generic implementation, to avoid
>   treating it as a type for standard typeof.  It seems plausible this
>   is being used when copying the type of one object to another using
>   typeof, so the existing semantics are preserved for __typeof__, and
>   for typeof in pre-C2x modes, while typeof for C2x or later has the
>   standard semantics.
>
> * It turns out that, even after Martin Uecker's changes in this area,
>   there were still cases where rvalues could wrongly have a qualified
>   or atomic type in GCC.  This applied to ++ and -- increment and
>   decrement expressions, and also to calls to functions returning an
>   atomic type.  (For the latter, the working draft doesn't actually
>   explicitly exclude the function call expression having an atomic
>   type, but given all the changes that have gone into C17 and C2x to
>   avoid rvalues ever having qualified types, and given that
>   lvalue-to-rvalue conversion removes both qualifiers and _Atomic, it
>   seems unlikely that this (or casts, where GCC already removes
>   _Atomic) is actually intended as a route to allow an
>   _Atomic-qualified rvalue; I've noted this to raise as an NB comment
>   on the CD ballot.)
>
> Bootstrapped with no regressions for x86_64-pc-linux-gnu.  OK to
> commit (C++ front-end changes)?

I think those are obvious, but OK.

Thanks,
Richard.

>
> gcc/
> * doc/invoke.texi (-fno-asm): Update description of effects on
> typeof keyword.
>
> gcc/c-family/
> * c-common.cc (c_common_reswords): Mark typeof as D_EXT11.  Add
> typeof_unqual.
> * c-common.h (enum rid): Add RID_TYPEOF_UNQUAL.
> (D_EXT11): New macro.  Values of subsequent macros updated.
>
> gcc/c/
> * c-parser.cc (c_parse_init): Add D_EXT11 to mask if flag_no_asm
> and not C2x.
> (c_keyword_starts_typename, c_token_starts_declspecs)
> (c_parser_declspecs, c_parser_objc_selector): Handle
> RID_TYPEOF_UNQUAL.
> (c_parser_typeof_specifier): Handle RID_TYPEOF_UNQUAL.
> Distinguish typeof for C2x from __typeof__ for all standard
> versions and typeof before C2x.
> * c-typeck.cc (build_function_call_vec): Use unqualified version
> of non-void return type.
> (build_unary_op): Use unqualified type for increment and
> decrement.
>
> gcc/cp/
> * lex.cc (init_reswords): Handle D_EXT11.
>
> gcc/testsuite/
> * gcc.dg/c11-typeof-1.c, gcc.dg/c2x-typeof-1.c,
> gcc.dg/c2x-typeof-2.c, gcc.dg/c2x-typeof-3.c,
> gcc.dg/gnu11-typeof-1.c, gcc.dg/gnu11-typeof-2.c,
> gcc.dg/gnu2x-typeof-1.c: New tests.
>
> diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> index 4f9878d2695..ffe17eaa9d9 100644
> --- a/gcc/c-family/c-common.cc
> +++ b/gcc/c-family/c-common.cc
> @@ -494,7 +494,8 @@ const struct c_common_resword c_common_reswords[] =
>{ "typedef", RID_TYPEDEF,0 },
>{ "typename",RID_TYPENAME,   D_CXXONLY | D_CXXWARN },
>{ "typeid",  RID_TYPEID, D_CXXONLY | D_CXXWARN },
> -  { "typeof",  RID_TYPEOF, D_ASM | D_EXT },
> +  { "typeof",  RID_TYPEOF, D_EXT11 },
> +  { "typeof_unqual",   RID_TYPEOF_UNQUAL,  D_CONLY | D_C2X },
>{ "union",   RID_UNION,  0 },
>{ "unsigned",RID_UNSIGNED,   0 },
>{ "using",   RID_USING,  D_CXXONLY | D_CXXWARN },
> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
> index 5f470d94f4a..62ab4ba437b 100644
> --- a/gcc/c-family/c-common.h
> +++ b/gcc/c-family/c-common.h
> @@ -104,7 +104,8 

Re: [PATCH] IPA: support -flto + -flive-patching=inline-clone

2022-10-06 Thread Richard Biener via Gcc-patches
On Wed, Oct 5, 2022 at 8:18 PM Qing Zhao via Gcc-patches
 wrote:
>
>
>
> > On Oct 5, 2022, at 1:36 PM, Martin Liška  wrote:
> >
> > On 10/5/22 16:50, Qing Zhao wrote:
> >> I have two questions on this:
> >
> > Hello.
> >
> >>
> >> 1.  What’s the motivation to enable -flive-patching with -flto? Is there 
> >> any application that will try -flive-patching with -flto now?
> >
> > We're planning supporting GCC LTO Linux kernel support, so that's one 
> > motivation. And the second one is a possible
> > use in user-space livepatching. Note majority of modern distros default to 
> > -flto (openSUSE, Fedora, Debian, Ubuntu, ...).
>
> Okay, I see. That’s reasonable.
> >
> >>
> >> 2. Why only enable -flive-patching=inline-clone with -flto?
> >
> > Because the inline-only-static level (which you added/requested) would have 
> > to properly
> > block inter-procedural inlining that happens in LTO 
> > (can_inline_edge_by_limits_p) and
> > I'm not sure it would be properly blocked. So, feel free to extend my patch 
> > if you want?
>
> -flive-patching=inline-only-static
>
> Only enable static functions inlining,  all the inlining of external visible 
> functions are blocked, So, LTO should be compatible with this naturally 
> without any issue, I think.
>
> i.e, when "-flive-patching=inline-only-static -flto"  present together, all 
> the inter-procedural inlining should be automatically blocked by 
> -flive-patching=inline-only-static already.
>
> Do I miss anything here?

WPA will promote externally visible functions static when all accesses
are from LTO IR, I don't think we preserve
the "original" visibility for IPA inlining heuristics.

OTOH inline-only-static could disable WPA inlining and do all inlining early ...

Richard,

>
> thanks.
>
> Qing
>
> >
> > Martin
> >
> >>
> >> thanks.
> >
>


Re: [PATCH] Support multilib-aware target lib flags self-specs overriding

2022-10-06 Thread Alexandre Oliva via Gcc-patches
On Jun 28, 2022, Alexandre Oliva  wrote:

> Support multilib-aware target lib flags self-specs overriding

> This patch introduces -fmultiflags, short for multilib TFLAGS, as an
> option that does nothing by default, but that can be added to TFLAGS
> and mapped to useful options by driver self-specs.

> Regstrapped on x86_64-linux-gnu.  Posted mainly FTR, but...  I wouldn't
> mind putting it in, so...  Ok to install?  ;-)

Since this patch didn't seem to gain much traction towards acceptance,
I've been thinking of other ways to accomplish its goal, namely, to
enable target libs to be built with additional flags, like setting
TFLAGS, but enabling different multilibs to be built with different
flags.

The other way that came to mind was to add settings to the multilib
target fragment configurations, say MULTILIB_TFLAGS, to map multilibs to
extra flags to use, and then adjust the target lib multilib flag build
machinery to extract and add these flags when configuring and building
each library.  Yuck.

I'd much rather we could use -fmultiflags, a far more elegant
arrangement IMHO, so...

Ping?  https://gcc.gnu.org/pipermail/gcc-patches/2022-June/597419.html

> for  gcc/ChangeLog

>   * common.opt (fmultiflags): New.
>   * doc/invoke.texi: Document it.
>   * gcc.cc (driver_self_specs): Discard it.
>   * opts.cc (common_handle_option): Ignore it in the driver.


Since this is kind of a build machinery feature, would anyone mind if I
self-approved this with my build machinery maintainer hat on?

Please raise your objection within one week if you do.

Thanks,

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Fix wrong code generated by unroll-and-jam pass

2022-10-06 Thread Richard Biener via Gcc-patches
On Wed, Oct 5, 2022 at 5:39 PM Eric Botcazou via Gcc-patches
 wrote:
>
> Hi,
>
> as shown by the attached testcase, there is a loophole in the unroll-and-jam
> pass that can quickly result in wrong code generation.  The code reads:
>
> if (!compute_data_dependences_for_loop (outer, true, _nest,
> , ))
> {
>   if (dump_file && (dump_flags & TDF_DETAILS))
> fprintf (dump_file, "Cannot analyze data dependencies\n");
>   free_data_refs (datarefs);
>   free_dependence_relations (dependences);
>   continue;
> }
>
> but compute_data_dependences_for_loop may return true even if the analysis is
> reported as failing by compute_affine_dependence for some dependence pair:
>
> (compute_affine_dependence
>   ref_a: data[_14], stmt_a: data[_14] = i_59;
>   ref_b: data[_14], stmt_b: data[_14] = i_59;
> Data ref a:
> #(Data Ref:
> #  bb: 12
> #  stmt: data[_14] = i_59;
> #  ref: data[_14];
> #  base_object: data;
> #  Access function 0: scev_not_known;
> #)
> Data ref b:
> #(Data Ref:
> #  bb: 12
> #  stmt: data[_14] = i_59;
> #  ref: data[_14];
> #  base_object: data;
> #  Access function 0: scev_not_known;
> #)
> affine dependence test not usable: access function not affine or constant.
> ) -> dependence analysis failed
>
> Note that this is a self-dependence pair and the code for them reads:
>
>   /* Nothing interesting for the self dependencies.  */
>   if (dra == drb)
> continue;
>
> This means that the pass may reorder "complex" accesses to the same memory
> location in successive iterations, which is OK for reads but not for writes.
>
> Proposed fix attached, tested on x86-64/Linux, OK for all active branches?

+ if (DR_IS_WRITE (dra)
+ && !DR_ACCESS_FNS (dra).is_empty ()
+ && DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
+   {

I'm wondering if testing DR_IS_WRITE (dra) is enough here and whether
the logic also applies to RAW and WAR.  So should it be either
(DR_IS_WRITE (dra) || DR_IS_WRITE (drb)) or DR_IS_WRITE (dra) &&
DR_IS_WRITE (drb)
instead?

Otherwise thanks for catching.

Richard.

>
> 2022-10-05  Eric Botcazou  
>
> * gimple-loop-jam.cc (tree_loop_unroll_and_jam): Bail out for a self
> dependency that is a write-after-write if the access function is not
> affine or constant.
>
>
> 2022-10-05  Eric Botcazou  
>
> * gcc.c-torture/execute/20221005-1.c: New test.
>
> --
> Eric Botcazou


Re: [PATCH 2/2] Split edge when edge locus and dest don't match

2022-10-06 Thread Richard Biener via Gcc-patches
On Wed, Oct 5, 2022 at 2:49 PM Martin Liška  wrote:
>
> On 10/5/22 14:04, Jørgen Kvalsvik via Gcc-patches wrote:
> > Edges with locus are candidates for splitting so that the edge with
> > locus is the only edge out of a basic block, except when the locuses
> > match. The test checks the last (non-debug) statement in a basic block,
> > but this causes an unnecessary split when the edge locus go to a block
> > which coincidentally has an unrelated label. Comparing the first
> > statement of the destination block is the same check but does not get
> > tripped up by labels.
> >
> > An example with source/edge/dest locus when an edge is split:
> >
> >   1  int fn (int a, int b, int c) {
> >   2int x = 0;
> >   3if (a && b) {
> >   4x = a;
> >   5} else {
> >   6  a_:
> >   7x = (a - b);
> >   8}
> >   9
> >  10return x;
> >  11  }
> >
> > block  file  line   col  stmt
> >
> > src t.c 310  if (a_3(D) != 0)
> > edget.c 6 1
> > destt.c 6 1  a_:
> >
> > src t.c 313  if (b_4(D) != 0)
> > edget.c 6 1
> > dst t.c 6 1  a_:
> >
> > With label removed:
> >
> >   1  int fn (int a, int b, int c) {
> >   2int x = 0;
> >   3if (a && b) {
> >   4x = a;
> >   5} else {
> >   6  // a_: <- label removed
> >   7x = (a - b);
> >   8}
> >   9
> >  10return x;
> >  11
> >
> > block  file  line   col  stmt
> >
> > src t.c 310  if (a_3(D) != 0)
> > edge  (null)0 0
> > destt.c 6 1  a_:
> >
> > src t.c 313  if (b_4(D) != 0)
> > edge  (null)0 0
> > dst t.c 6 1  a_:
> >
> > and this is extract from gcov-4b.c which *should* split:
> >
> > 205  int
> > 206  test_switch (int i, int j)
> > 207  {
> > 208int result = 0;
> > 209
> > 210switch (i)/* branch(80 25) */
> > 211  /* branch(end) */
> > 212  {
> > 213case 1:
> > 214  result = do_something (2);
> > 215  break;
> > 216case 2:
> > 217  result = do_something (1024);
> > 218  break;
> > 219case 3:
> > 220case 4:
> > 221  if (j == 2) /* branch(67) */
> > 222  /* branch(end) */
> > 223return do_something (4);
> > 224  result = do_something (8);
> > 225  break;
> > 226default:
> > 227  result = do_something (32);
> > 228  switch_m++;
> > 229  break;
> > 230  }
> > 231return result;
> > 231  }
> >
> > block  file  line   col  stmt
> >
> > src4b.c   21418  result_18 = do_something (2);
> > edge   4b.c   215 9
> > dst4b.c   23110  _22 = result_3;
> >
> > src4b.c   21718  result_16 = do_something (1024);
> > edge   4b.c   218 9
> > dst4b.c   23110  _22 = result_3;
> >
> > src4b.c   22418  result_12 = do_something (8);
> > edge   4b.c   225 9
> > dst4b.c   23110  _22 = result_3;
> >
> > Note that the behaviour of comparison is preserved for the (switch) edge
> > splitting case. The former case now fails the check (even though
> > e->goto_locus is no longer a reserved location) because the dest matches
> > the e->locus.
>
> It's fine, please install it.
> I verified tramp3d coverage output is the same as before the patch.
>
> Martin
>
> >
> > gcc/ChangeLog:
> >
> > * profile.cc (branch_prob): Compare edge locus to dest, not src.
> > ---
> >  gcc/profile.cc | 18 +-
> >  1 file changed, 9 insertions(+), 9 deletions(-)
> >
> > diff --git a/gcc/profile.cc b/gcc/profile.cc
> > index 96121d60711..c13a79a84c2 100644
> > --- a/gcc/profile.cc
> > +++ b/gcc/profile.cc
> > @@ -1208,17 +1208,17 @@ branch_prob (bool thunk)
> > FOR_EACH_EDGE (e, ei, bb->succs)
> >   {
> > gimple_stmt_iterator gsi;
> > -   gimple *last = NULL;
> > +   gimple *dest = NULL;
> >
> > /* It may happen that there are compiler generated statements
> >without a locus at all.  Go through the basic block from the
> >last to the first statement looking for a locus.  */

The comment no longer matches the code.

> > -   for (gsi = gsi_last_nondebug_bb (bb);
> > +   for (gsi = gsi_start_nondebug_bb (bb);

^^^ and you are looking at the branch block stmts (bb), not the destination
block stmts (e->dest)

> >  !gsi_end_p (gsi);
> > -gsi_prev_nondebug ())
> > +gsi_next_nondebug ())
> >   {
> > -   last = gsi_stmt (gsi);
> > -   if 

Re: Patch ping (Re: [PATCH] libgcc: Decrease size of _Unwind_FrameState and even more size of cleared area in uw_frame_state_for)

2022-10-06 Thread Richard Biener via Gcc-patches
On Wed, Oct 5, 2022 at 12:34 PM Jakub Jelinek via Gcc-patches
 wrote:
>
> Hi!
>
> I'd like to ping this patch.

The patch is OK.

Richard.

> Thanks.
>
> > 2022-09-19  Jakub Jelinek  
> >
> >   * unwind-dw2.h (REG_UNSAVED, REG_SAVED_OFFSET, REG_SAVED_REG,
> >   REG_SAVED_EXP, REG_SAVED_VAL_OFFSET, REG_SAVED_VAL_EXP,
> >   REG_UNDEFINED): New anonymous enum, moved from inside of
> >   struct frame_state_reg_info.
> >   (struct frame_state_reg_info): Remove reg[].how element and the
> >   anonymous enum there.  Add how element.
> >   * unwind-dw2.c: Include stddef.h.
> >   (uw_frame_state_for): Don't clear first
> >   offsetof (_Unwind_FrameState, regs.how[0]) bytes of *fs.
> >   (execute_cfa_program, __frame_state_for, uw_update_context_1,
> >   uw_update_context): Use fs->regs.how[X] instead of fs->regs.reg[X].how
> >   or fs.regs.how[X] instead of fs.regs.reg[X].how.
> >   * config/sh/linux-unwind.h (sh_fallback_frame_state): Likewise.
> >   * config/bfin/linux-unwind.h (bfin_fallback_frame_state): Likewise.
> >   * config/pa/linux-unwind.h (pa32_fallback_frame_state): Likewise.
> >   * config/pa/hpux-unwind.h (UPDATE_FS_FOR_SAR, UPDATE_FS_FOR_GR,
> >   UPDATE_FS_FOR_FR, UPDATE_FS_FOR_PC, pa_fallback_frame_state):
> >   Likewise.
> >   * config/alpha/vms-unwind.h (alpha_vms_fallback_frame_state):
> >   Likewise.
> >   * config/alpha/linux-unwind.h (alpha_fallback_frame_state): Likewise.
> >   * config/arc/linux-unwind.h (arc_fallback_frame_state,
> >   arc_frob_update_context): Likewise.
> >   * config/riscv/linux-unwind.h (riscv_fallback_frame_state): Likewise.
> >   * config/nios2/linux-unwind.h (NIOS2_REG): Likewise.
> >   * config/nds32/linux-unwind.h (NDS32_PUT_FS_REG): Likewise.
> >   * config/s390/tpf-unwind.h (s390_fallback_frame_state): Likewise.
> >   * config/s390/linux-unwind.h (s390_fallback_frame_state): Likewise.
> >   * config/sparc/sol2-unwind.h (sparc64_frob_update_context,
> >   MD_FALLBACK_FRAME_STATE_FOR): Likewise.
> >   * config/sparc/linux-unwind.h (sparc64_fallback_frame_state,
> >   sparc64_frob_update_context, sparc_fallback_frame_state): Likewise.
> >   * config/i386/sol2-unwind.h (x86_64_fallback_frame_state,
> >   x86_fallback_frame_state): Likewise.
> >   * config/i386/w32-unwind.h (i386_w32_fallback_frame_state): Likewise.
> >   * config/i386/linux-unwind.h (x86_64_fallback_frame_state,
> >   x86_fallback_frame_state): Likewise.
> >   * config/i386/freebsd-unwind.h (x86_64_freebsd_fallback_frame_state):
> >   Likewise.
> >   * config/i386/dragonfly-unwind.h
> >   (x86_64_dragonfly_fallback_frame_state): Likewise.
> >   * config/i386/gnu-unwind.h (x86_gnu_fallback_frame_state): Likewise.
> >   * config/csky/linux-unwind.h (csky_fallback_frame_state): Likewise.
> >   * config/aarch64/linux-unwind.h (aarch64_fallback_frame_state):
> >   Likewise.
> >   * config/aarch64/freebsd-unwind.h
> >   (aarch64_freebsd_fallback_frame_state): Likewise.
> >   * config/aarch64/aarch64-unwind.h (aarch64_frob_update_context):
> >   Likewise.
> >   * config/or1k/linux-unwind.h (or1k_fallback_frame_state): Likewise.
> >   * config/mips/linux-unwind.h (mips_fallback_frame_state): Likewise.
> >   * config/loongarch/linux-unwind.h (loongarch_fallback_frame_state):
> >   Likewise.
> >   * config/m68k/linux-unwind.h (m68k_fallback_frame_state): Likewise.
> >   * config/xtensa/linux-unwind.h (xtensa_fallback_frame_state):
> >   Likewise.
> >   * config/rs6000/darwin-fallback.c (set_offset): Likewise.
> >   * config/rs6000/aix-unwind.h (MD_FROB_UPDATE_CONTEXT): Likewise.
> >   * config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Likewise.
> >   * config/rs6000/freebsd-unwind.h (frob_update_context): Likewise.
>
> Jakub
>


RE: [PATCH][AArch64] Implement ACLE Data Intrinsics

2022-10-06 Thread Richard Biener via Gcc-patches
On Wed, 5 Oct 2022, Kyrylo Tkachov wrote:

> 
> 
> > -Original Message-
> > From: Andre Vieira (lists) 
> > Sent: Tuesday, October 4, 2022 11:34 AM
> > To: Kyrylo Tkachov ; gcc-patches@gcc.gnu.org;
> > Richard Sandiford ; Richard Biener
> > 
> > Subject: Re: [PATCH][AArch64] Implement ACLE Data Intrinsics
> > 
> > Hi all,
> > 
> > Can I backport this to gcc-11 branch? Also applies cleanly (with the
> > exception of the file extensions being different: 'aarch64-builtins.cc
> > vs aarch64-builtins.c').
> > 
> 
> Ok by me if testing is clean.

Target patches like this are really up to the maintainers to decide
for backporting.

Richard.


Re: [PATCH] cselib: Skip BImode while keeping track of subvalue relations [PR107088]

2022-10-06 Thread Stefan Schulze Frielinghaus via Gcc-patches
On Wed, Oct 05, 2022 at 08:48:13PM -0600, Jeff Law via Gcc-patches wrote:
> 
> On 10/4/22 05:28, Stefan Schulze Frielinghaus via Gcc-patches wrote:
> > For BImode get_narrowest_mode evaluates to QImode but BImode < QImode.
> > Thus FOR_EACH_MODE_UNTIL never reaches BImode and iterates until OImode
> > for which no wider mode exists so we end up with VOIDmode and fail.
> > Fixed by adding a size guard so we effectively skip BImode.
> > 
> > Bootstrap and regtest are currently running on x64.  Assuming they pass
> > ok for mainline?
> > 
> > gcc/ChangeLog:
> > 
> > PR rtl-optimization/107088
> > * cselib.cc (new_cselib_val): Skip BImode while keeping track of
> > subvalue relations.
> 
> OK.  And FWIW, this fixes the various failures I saw in my tester due to the
> cselib patches.

Thanks for testing, too!  Out of curiosity which target is your tester?
I gave it a try on x64 and AArch64 for which bootstrap went fine and
regtest showed no difference, and of course, for s390x regtest went for
the better.


  1   2   >