Re: try multi dest registers in default_zero_call_used_regs

2022-03-31 Thread Alexandre Oliva via Gcc-patches
Hello, Richard,

Thanks for the review!

On Mar 31, 2022, Richard Sandiford  wrote:

>> +/* If the natural mode doesn't work, try some wider mode.  */
>> +if (!targetm.hard_regno_mode_ok (regno, mode))
>> +  {
>> +for (int nregs = 2;
>> + regno + nregs <= FIRST_PSEUDO_REGISTER
>> +   && TEST_HARD_REG_BIT (need_zeroed_hardregs,
>> + regno + nregs - 1);
>> + nregs++)
>> +  {
>> +mode = choose_hard_reg_mode (regno, nregs, 0);

> I like the idea, but it would be good to avoid the large:

>   FIRST_PSEUDO_REGISTER * FIRST_PSEUDO_REGISTER * NUM_MACHINE_MODES

> constant factor.

Enteringf the nregs loop, because the register can't be used in its
natural mode, is supposed to be an unusual case, not worth optimizing
much under Amdahl's law.  I gather the aggregate trip counts are
unlikely to hit the theoretical O(n^2) because registers that would take
the loop are rare and expected to be paired/grouped up.  If that
assumption doesn't hold, then a cap would indeed be desirable.

> How about if init_reg_modes_target recorded the maximum value of
> x_hard_regno_nregs?

I had thought of a cap but couldn't find one I was happy with, and in
the end I thought we didn't need one.  But this is indeed a good one to
use.  Thanks, I'm implementing it.

> This seems big enough to be worth splitting out into a helper, rather
> than repeating.

I had considered that, but it didn't seem to me it would bring an
improvement.  As it turns out, it does.  Thanks.

>> -rtx zsrc = gen_rtx_REG (mode, src);
>> +rtx src_rtx = (mode == GET_MODE (regno_reg_rtx[src])
>> +   ? regno_reg_rtx[src]
>> +   : gen_rtx_REG (mode, src));

> Is this needed?  The original gen_rtx_REG (mode, src) seems OK.

No, it's not needed, it's just an attempt to avoid allocating RTL that
we have handy.  This function could in theory make several attempts at
allocating rtl for each register in the shrinking pending set.  I
thought every saved bit could help.


Here's what I'm regstrapping on x86_64-linux-gnu, after verifying that
it does the job on the affected arm variant.  Ok to install, assuming no
surprises in the testing?


try multi-reg dest in default_zero_call_used_regs

From: Alexandre Oliva 

When the mode of regno_reg_rtx is not hard_regno_mode_ok for the
target, try grouping the register with subsequent ones.  This enables
s16 to s31 and their hidden pairs to be zeroed with the default logic
on some arm variants.


for  gcc/ChangeLog

* targhooks.c (default_zero_call_used_regs): Attempt to group
regs that the target refuses to use in their natural modes.
(zcur_select_mode_rtx): New.
* regs.h (struct target_regs): Add x_hard_regno_max_nregs.
(hard_regno_max_nregs): Define.
* reginfo.c (init_reg_modes_target): Set hard_regno_max_nregs.
---
 gcc/reginfo.cc   |9 --
 gcc/regs.h   |5 +++
 gcc/targhooks.cc |   86 --
 3 files changed, 89 insertions(+), 11 deletions(-)

diff --git a/gcc/reginfo.cc b/gcc/reginfo.cc
index 234f72eceeb25..67e30cab42855 100644
--- a/gcc/reginfo.cc
+++ b/gcc/reginfo.cc
@@ -441,10 +441,15 @@ init_reg_modes_target (void)
 {
   int i, j;
 
+  this_target_regs->x_hard_regno_max_nregs = 1;
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
 for (j = 0; j < MAX_MACHINE_MODE; j++)
-  this_target_regs->x_hard_regno_nregs[i][j]
-   = targetm.hard_regno_nregs (i, (machine_mode) j);
+  {
+   unsigned char nregs = targetm.hard_regno_nregs (i, (machine_mode) j);
+   this_target_regs->x_hard_regno_nregs[i][j] = nregs;
+   if (nregs > this_target_regs->x_hard_regno_max_nregs)
+ this_target_regs->x_hard_regno_max_nregs = nregs;
+  }
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
 {
diff --git a/gcc/regs.h b/gcc/regs.h
index 74f1f63770322..f72b06fb56508 100644
--- a/gcc/regs.h
+++ b/gcc/regs.h
@@ -202,6 +202,9 @@ struct target_regs {
  registers that a given machine mode occupies.  */
   unsigned char x_hard_regno_nregs[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
 
+  /* The max value found in x_hard_regno_nregs.  */
+  unsigned char x_hard_regno_max_nregs;
+
   /* For each hard register, the widest mode object that it can contain.
  This will be a MODE_INT mode if the register can hold integers.  Otherwise
  it will be a MODE_FLOAT or a MODE_CC mode, whichever is valid for the
@@ -235,6 +238,8 @@ extern struct target_regs *this_target_regs;
 #else
 #define this_target_regs (_target_regs)
 #endif
+#define hard_regno_max_nregs \
+  (this_target_regs->x_hard_regno_max_nregs)
 #define reg_raw_mode \
   (this_target_regs->x_reg_raw_mode)
 #define have_regs_of_mode \
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index fc49235eb38ee..2681833e2ce79 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ 

[Bug c++/100052] [11/12 regression] ICE in compiling g++.dg/modules/xtreme-header-3_b.C after r11-8118

2022-03-31 Thread guojiufu at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100052

Jiu Fu Guo  changed:

   What|Removed |Added

 CC||guojiufu at gcc dot gnu.org

--- Comment #9 from Jiu Fu Guo  ---
On the latest trunk, these failures seems to disappear again.

./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-3_b.C -std=c++17
(test for excess errors)
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-3_b.C -std=c++2a
(test for excess errors)
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-3_b.C -std=c++2b
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-3_b.C -std=c++17
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-3_b.C -std=c++2a
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-3_b.C -std=c++2b
(test for excess errors)

[Bug c++/99910] [11/12 Regression] g++.dg/modules/xtreme-header-2_b.C ICE

2022-03-31 Thread guojiufu at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99910

Jiu Fu Guo  changed:

   What|Removed |Added

 CC||guojiufu at gcc dot gnu.org

--- Comment #10 from Jiu Fu Guo  ---
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-2_b.C -std=c++17
(test for excess errors)
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-2_b.C -std=c++2a
(test for excess errors)
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-2_b.C -std=c++2b
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-2_b.C -std=c++17
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-2_b.C -std=c++2a
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-2_b.C -std=c++2b
(test for excess errors)
.
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-tr1_b.C -std=c++17
(test for excess errors)
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-tr1_b.C -std=c++2a
(test for excess errors)
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-tr1_b.C -std=c++2b
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-tr1_b.C -std=c++17
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-tr1_b.C -std=c++2a
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-tr1_b.C -std=c++2b
(test for excess errors)

It would pass with the latest trunk. (I tested on ppc64le)

[Bug c++/101853] [12 Regression] g++.dg/modules/xtreme-header-5_b.C ICE

2022-03-31 Thread guojiufu at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101853

Jiu Fu Guo  changed:

   What|Removed |Added

 CC||guojiufu at gcc dot gnu.org

--- Comment #10 from Jiu Fu Guo  ---
On the trunk, this would be fixed:
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-5_b.C -std=c++17
(test for excess errors)
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-5_b.C -std=c++2a
(test for excess errors)
./gcc/testsuite/g++/g++.sum:PASS: g++.dg/modules/xtreme-header-5_b.C -std=c++2b
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-5_b.C -std=c++17
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-5_b.C -std=c++2a
(test for excess errors)
./gcc/testsuite/g++/g++.log:PASS: g++.dg/modules/xtreme-header-5_b.C -std=c++2b
(test for excess errors)

> grep -r xtreme-. > ~/22.4.1aaf3a5993ae.log
grep -i FAIL ~/22.4.1aaf3a5993ae.log |wc
  0   0   0
grep -i PASS ~/22.4.1aaf3a5993ae.log |wc
3602232   41904

[COMMITTED] MAINTAINERS: Update my email address

2022-03-31 Thread Qian Jianhua via Gcc-patches
Update my email address in the MAINTAINERS file.

2022-04-01  Qian Jianhua  

ChangeLog:

* MAINTAINERS: Update my email address.
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f388bdaf4f1..30f81b3dd52 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -463,7 +463,7 @@ Daniel Jacobowitz   
 Andreas Jaeger 
 Harsha Jagasia 
 Fariborz Jahanian  
-Qian Jianhua   
+Qian Jianhua   
 Janis Johnson  
 Teresa Johnson 
 Kean Johnston  
-- 
2.18.1





Re: [PATCH] libgcc, riscv: Add restore libcalls to be used by tail calling functions

2022-03-31 Thread Palmer Dabbelt

On Tue, 29 Mar 2022 07:08:35 PDT (-0700), lewis.rev...@embecosm.com wrote:

Currently the existing libcalls for restoring registers have the
requirement that they must be tail called by the parent function, so
that they can safely return through the restored return address
register. This does impose the restriction that the libcalls cannot be
used if there already exists a tail call at the end of the parent
function in question, and as such this patch forms part of an effort to
rectify this situation.

There already exists patches to LLVM and Compiler-RT to add the libcalls
and the capability for the compiler to generate them
(https://reviews.llvm.org/D91720 and https://reviews.llvm.org/D91719),
and the behaviour that we want to standardize across the compilers is
documented in the following pull request to the RISC-V toolchain
conventions repository:
https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/10


This generally looks good to me, but the timing is awkward: we're in 
stage 4 (so features need an exception), but my bigger worry is that 
taking support for a draft spec so late in the cycle puts us at serious 
risk of shipping the draft and being stuck with it (which is bad for 
everyone).  It looks like the spec is just waiting on GCC, though, so 
maybe we're in that chicken-and-egg stage -- a bit of a headache for 
that to show up in stage 4 as there's no room for error, but this one 
seems manageable.


If this is aimed at GCC-13, then I think it's best to make sure we also 
have the GCC support for emitting calls to those routines -- otherwise 
it'll be very hard to test this.  The good news is that in that case 
there's time, it's just a chunk of extra work to do.  That should also 
make alignment with the spec timeline easy, as we'll have many months of 
slack.


Regardless, it seems like this is mostly Jim's code so I'll defer to him 
here.


Thanks!


The libcalls added in this patch follow that documented behaviour and
are based off a suggested implementation provided by Jim Wilson in the
thread of that pull request. Similar to the existing restore libcalls,
restores are grouped according to the expected stack alignment, and the
'upper' libcalls fall through to the lower libcalls, finally ending in
return through the temporary register t1.

libgcc/

* config/riscv/restore-tail.S: Add restore libcalls compatible
with use from functions ending in tail calls.
* config/riscv/t-elf: Add file restore-tail.S.
---
 libgcc/config/riscv/restore-tail.S | 279 +
 libgcc/config/riscv/t-elf  |   1 +
 2 files changed, 280 insertions(+)
 create mode 100644 libgcc/config/riscv/restore-tail.S

diff --git a/libgcc/config/riscv/restore-tail.S
b/libgcc/config/riscv/restore-tail.S
new file mode 100644
index 000..54116beff17
--- /dev/null
+++ b/libgcc/config/riscv/restore-tail.S
@@ -0,0 +1,279 @@
+/* Tail-call compatible callee-saved register restore routines for RISC-V.
+
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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
+.  */
+
+#include "riscv-asm.h"
+
+  .text
+
+#if __riscv_xlen == 64
+
+FUNC_BEGIN (__riscv_restore_tailcall_12)
+  .cfi_startproc
+  .cfi_def_cfa_offset 112
+  .cfi_offset 27, -104
+  .cfi_offset 26, -96
+  .cfi_offset 25, -88
+  .cfi_offset 24, -80
+  .cfi_offset 23, -72
+  .cfi_offset 22, -64
+  .cfi_offset 21, -56
+  .cfi_offset 20, -48
+  .cfi_offset 19, -40
+  .cfi_offset 18, -32
+  .cfi_offset 9, -24
+  .cfi_offset 8, -16
+  .cfi_offset 1, -8
+  ld s11, 8(sp)
+  .cfi_restore 27
+  addi sp, sp, 16
+
+FUNC_BEGIN (__riscv_restore_tailcall_11)
+FUNC_BEGIN (__riscv_restore_tailcall_10)
+  .cfi_restore 27
+  .cfi_def_cfa_offset 96
+  ld s10, 0(sp)
+  .cfi_restore 26
+  ld s9, 8(sp)
+  .cfi_restore 25
+  addi sp, sp, 16
+
+FUNC_BEGIN (__riscv_restore_tailcall_9)
+FUNC_BEGIN (__riscv_restore_tailcall_8)
+  .cfi_restore 25
+  .cfi_restore 26
+  .cfi_restore 27
+  .cfi_def_cfa_offset 80
+  ld s8, 0(sp)
+  .cfi_restore 24
+  ld s7, 8(sp)
+  .cfi_restore 23
+  addi sp, sp, 16
+
+FUNC_BEGIN (__riscv_restore_tailcall_7)
+FUNC_BEGIN 

fixed-point/composite-type: add -Wno-array-parameter

2022-03-31 Thread Alexandre Oliva via Gcc-patches


On machines that support fixed-point and the test runs, it's failing
because of warnings issued by -Warray-parameter=[12], enabled by
-Wall.

The warnings state "mismatch in bound 1 of argument 1 declared as...",
referring to the redeclaration of f2_##NAME.  The purpose of the
redeclaration is not clear to me.

It doesn't look like the test intends to catch mismatches between
parameter's array lengths, despite the explicit array bound and the
incompatible calls, so I'm adding -Wno-array-parameter to avoid this
distraction and enable the test to pass.

Tested on arm-eabi, where the patch removes the excess errors fail.  Ok
to install?


for gcc/testsuite/ChangeLog

* gcc.dg/fixed-point/composite-type.c: Add -Wno-array-parameter.
---
 gcc/testsuite/gcc.dg/fixed-point/composite-type.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/fixed-point/composite-type.c 
b/gcc/testsuite/gcc.dg/fixed-point/composite-type.c
index 026bdaf564420..59351ff09b390 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/composite-type.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/composite-type.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-std=gnu99 -O -Wall -Wno-unused -ftrack-macro-expansion=0" } 
*/
+/* { dg-options "-std=gnu99 -O -Wall -Wno-unused -ftrack-macro-expansion=0 
-Wno-array-parameter" } */
 
 /* C99 6.2.7: Compatible type and composite type.  */
 


-- 
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 


New Croatian PO file for 'gcc' (version 12.1-b20220213)

2022-03-31 Thread Translation Project Robot
Hello, gentle maintainer.

This is a message from the Translation Project robot.

A revised PO file for textual domain 'gcc' has been submitted
by the Croatian team of translators.  The file is available at:

https://translationproject.org/latest/gcc/hr.po

(This file, 'gcc-12.1-b20220213.hr.po', has just now been sent to you in
a separate email.)

All other PO files for your package are available in:

https://translationproject.org/latest/gcc/

Please consider including all of these in your next release, whether
official or a pretest.

Whenever you have a new distribution with a new version number ready,
containing a newer POT file, please send the URL of that distribution
tarball to the address below.  The tarball may be just a pretest or a
snapshot, it does not even have to compile.  It is just used by the
translators when they need some extra translation context.

The following HTML page has been updated:

https://translationproject.org/domain/gcc.html

If any question arises, please contact the translation coordinator.

Thank you for all your work,

The Translation Project robot, in the
name of your translation coordinator.




[Bug c++/105104] [coroutines] ICE during GIMPLE pass: coro-early-expand-ifns

2022-03-31 Thread jehelset at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105104

--- Comment #5 from John Eivind Helset  ---
Created attachment 52729
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52729=edit
Patch with testcase.

Tried adding a testcase to the g++.dg/coroutines testsuite. Used dg-ice, but it
seems to complain about excess errors anyways:

FAIL: g++.dg/coroutines/pr105104.C (test for excess errors)
Excess errors:
during GIMPLE pass: coro-early-expand-ifns

[Bug c++/47634] Incorrect checking of attribute format printf on constructor of derived class with virtual base

2022-03-31 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47634

Marek Polacek  changed:

   What|Removed |Added

 CC||mpolacek at gcc dot gnu.org
 Ever confirmed|0   |1
   Assignee|unassigned at gcc dot gnu.org  |mpolacek at gcc dot 
gnu.org
 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2022-03-31

gcc-9-20220331 is now available

2022-03-31 Thread GCC Administrator via Gcc
Snapshot gcc-9-20220331 is now available on
  https://gcc.gnu.org/pub/gcc/snapshots/9-20220331/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 9 git branch
with the following options: git://gcc.gnu.org/git/gcc.git branch releases/gcc-9 
revision eeb08803c0f17d20389d8ea9d67fd45d742adbca

You'll find:

 gcc-9-20220331.tar.xzComplete GCC

  SHA256=25ec240c4ff3bbdde2cc7d32f8630a46d9b241f1ce9690046913895893362d43
  SHA1=48063628e629c8ee2e73a8e3f71a6f4183068c2e

Diffs from 9-20220324 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-9
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


Re: rs6000 patch ping: [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004]

2022-03-31 Thread Segher Boessenkool
On Wed, Mar 30, 2022 at 06:07:26PM -0500, Segher Boessenkool wrote:
> On Tue, Mar 15, 2022 at 02:18:00PM +0100, Jakub Jelinek wrote:
> > On Fri, Jan 28, 2022 at 11:50:26AM -0600, Bill Schmidt via Gcc-patches 
> > wrote:
> > > PR104004 caught some misses on my part in converting to the new built-in
> > > function infrastructure.  In particular, I forgot to mark all of the 
> > > "nosoft"
> > > built-ins, and one of those should also have been marked "no32bit".
> 
> > This patch fixes a P1 regression and from my (limited) understanding
> > doesn't depend on any other patch in the series.
> 
> It depends on 3/8 which was only partially applied (or not at all even?)
> It is a mess :-(
> 
> I'll look into it tomorrow.

3/8 wasn't applied at all.  I did some surgery to apply this 8/8 though.


Segher


[Bug target/104004] [12 Regression] ICE: in extract_insn, at recog.c:2769 (error: unrecognizable insn)

2022-03-31 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104004

Segher Boessenkool  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 CC||segher at gcc dot gnu.org
 Resolution|--- |FIXED

--- Comment #4 from Segher Boessenkool  ---
Fixed now.

[Bug target/104004] [12 Regression] ICE: in extract_insn, at recog.c:2769 (error: unrecognizable insn)

2022-03-31 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104004

--- Comment #3 from CVS Commits  ---
The master branch has been updated by Segher Boessenkool :

https://gcc.gnu.org/g:aaf3a5993ae49f1ae6792800e5161a1d51436ed3

commit r12-7945-gaaf3a5993ae49f1ae6792800e5161a1d51436ed3
Author: Bill Schmidt 
Date:   Fri Jan 28 11:50:26 2022 -0600

rs6000: Fix some missing built-in attributes [PR104004]

PR104004 caught some misses on my part in converting to the new built-in
function infrastructure.  In particular, I forgot to mark all of the
"nosoft"
built-ins, and one of those should also have been marked "no32bit".

2022-01-27  Bill Schmidt  

gcc/
PR target/104004
* config/rs6000/rs6000-builtins.def (MFFSL): Mark nosoft.
(MTFSB0): Likewise.
(MTFSB1): Likewise.
(SET_FPSCR_RN): Likewise.
(SET_FPSCR_DRN): Mark nosoft and no32bit.

[Bug c++/101833] [9/10/11/12 Regression] ICE with -Wformat on a constructor with a virtual base

2022-03-31 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101833

Marek Polacek  changed:

   What|Removed |Added

 CC||mpolacek at gcc dot gnu.org
 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |mpolacek at gcc dot 
gnu.org

[Bug c++/105104] [coroutines] ICE during GIMPLE pass: coro-early-expand-ifns

2022-03-31 Thread jehelset at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105104

--- Comment #4 from John Eivind Helset  ---
It seems a non-void return-type from await-resume of a final awaitable,
combined with at least -O1 causes a segfault: https://godbolt.org/z/rzq8dM7Pr

Not sure if it's the same as the one I initially encountered yet.

Re: [PATCH v4] libgo: Don't use pt_regs member in mcontext_t

2022-03-31 Thread Ian Lance Taylor via Gcc-patches
On Thu, Mar 31, 2022 at 9:41 AM Sören Tempel  wrote:
>
> Ping.
>
> Would be nice to get this integrated since this one of the changes needed to
> make gccgo work with musl libc. Let me know if the patch needs to be revised
> further.

I went with a simpler solution, more verbose but easier to read.  Now
committed to mainline.  Please let me know if you have any problems
with this.  Thanks.

Ian
fad0ecb68c08512ac24852b6d5264cdb9809dc6d
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index afaccb0e9e6..f93eaf48e28 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-7f33baa09a8172bb2c5f1ca0435d9efe3e194c9b
+45108f37070afb696b069768700e39a269f1fecb
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index 0cb90304730..9c919e1568a 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -231,7 +231,14 @@ getSiginfo(siginfo_t *info, void *context 
__attribute__((unused)))
 #elif defined(__alpha__) && defined(__linux__)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc;
 #elif defined(__PPC__) && defined(__linux__)
+   // For some reason different libc implementations use
+   // different names.
+#if defined(__PPC64__) || defined(__GLIBC__)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.regs->nip;
+#else
+   // Assumed to be ppc32 musl.
+   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[32];
+#endif
 #elif defined(__PPC__) && defined(_AIX)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.jmp_context.iar;
 #elif defined(__aarch64__) && defined(__linux__)
@@ -347,6 +354,7 @@ dumpregs(siginfo_t *info __attribute__((unused)), void 
*context __attribute__((u
mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
int i;
 
+#if defined(__PPC64__) || defined(__GLIBC__)
for (i = 0; i < 32; i++)
runtime_printf("r%d %X\n", i, m->regs->gpr[i]);
runtime_printf("pc  %X\n", m->regs->nip);
@@ -355,6 +363,16 @@ dumpregs(siginfo_t *info __attribute__((unused)), void 
*context __attribute__((u
runtime_printf("lr  %X\n", m->regs->link);
runtime_printf("ctr %X\n", m->regs->ctr);
runtime_printf("xer %X\n", m->regs->xer);
+#else
+   for (i = 0; i < 32; i++)
+   runtime_printf("r%d %X\n", i, m->gregs[i]);
+   runtime_printf("pc  %X\n", m->gregs[32]);
+   runtime_printf("msr %X\n", m->gregs[33]);
+   runtime_printf("cr  %X\n", m->gregs[38]);
+   runtime_printf("lr  %X\n", m->gregs[36]);
+   runtime_printf("ctr %X\n", m->gregs[35]);
+   runtime_printf("xer %X\n", m->gregs[37]);
+#endif
  }
 #elif defined(__PPC__) && defined(_AIX)
  {


Re: [patch]update the documentation for TARGET_ZERO_CALL_USED_REGS hook and add an assertion

2022-03-31 Thread Uros Bizjak via Gcc-patches
On Mon, Mar 21, 2022 at 10:28 PM Qing Zhao via Gcc-patches
 wrote:
>
> Hi,
>
> Per our discussion on: 
> https://gcc.gnu.org/pipermail/gcc-patches/2022-March/592002.html
>
> I come up with the following patch to:
>
> 1. Update the documentation for TARGET_ZERO_CALL_USED_REGS hook;
> 2. Add an assertion in function.cc to make sure the actually zeroed_regs is a 
> subset of all call used regs;
>(The reason I didn’t add a new parameter to TARGET_ZERO_CALL_USED_REGS is, 
> I think adding the
> assertion in the common place function.cc is simpler to be implemented).
> 3. This new assertion identified a bug in i386 implementation. Fix this bug 
> in i386.
>
> This patch is bootstrapped on both x86 and aarch64, no regression.
>
> Okay for commit?
>
> thanks.
>
> Qing
>
> ===
> From 2e5bc1b25a707c6a17afbf03da2a8bec5b03454d Mon Sep 17 00:00:00 2001
> From: Qing Zhao 
> Date: Fri, 18 Mar 2022 20:49:56 +
> Subject: [PATCH] Add an assertion: the zeroed_hardregs set is a subset of all
>  call used regs.
>
> We should make sure that the hard register set that is actually cleared by
> the target hook zero_call_used_regs should be a subset of all call used
> registers.
>
> At the same time, update documentation for the target hook
> TARGET_ZERO_CALL_USED_REGS.
>
> This new assertion identified a bug in the i386 implemenation, which
> incorrectly set the zeroed_hardregs for stack registers. Fixed this bug
> in i386 implementation.
>
> gcc/ChangeLog:
>
> 2022-03-21  Qing Zhao  
>
> * config/i386/i386.cc (zero_all_st_registers): Return the value of
> num_of_st.
> (ix86_zero_call_used_regs): Update zeroed_hardregs set according to
> the return value of zero_all_st_registers.
> * doc/tm.texi: Update the documentation of TARGET_ZERO_CALL_USED_REGS.
> * function.cc (gen_call_used_regs_seq): Add an assertion.
> * target.def: Update the documentation of TARGET_ZERO_CALL_USED_REGS.

OK for the i386 part.

Thanks,
Uros.

> ---
>  gcc/config/i386/i386.cc | 27 ++-
>  gcc/doc/tm.texi |  7 +++
>  gcc/function.cc | 22 ++
>  gcc/target.def  |  7 +++
>  4 files changed, 50 insertions(+), 13 deletions(-)
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index 5a561966eb44..d84047a4bc1b 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -3753,16 +3753,17 @@ zero_all_vector_registers (HARD_REG_SET 
> need_zeroed_hardregs)
> needs to be cleared, the whole stack should be cleared.  However,
> x87 stack registers that hold the return value should be excluded.
> x87 returns in the top (two for complex values) register, so
> -   num_of_st should be 7/6 when x87 returns, otherwise it will be 8.  */
> +   num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
> +   return the value of num_of_st.  */
>
>
> -static bool
> +static int
>  zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
>  {
>
>/* If the FPU is disabled, no need to zero all st registers.  */
>if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
> -return false;
> +return 0;
>
>unsigned int num_of_st = 0;
>for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
> @@ -3774,7 +3775,7 @@ zero_all_st_registers (HARD_REG_SET 
> need_zeroed_hardregs)
>}
>
>if (num_of_st == 0)
> -return false;
> +return 0;
>
>bool return_with_x87 = false;
>return_with_x87 = (crtl->return_rtx
> @@ -3802,7 +3803,7 @@ zero_all_st_registers (HARD_REG_SET 
> need_zeroed_hardregs)
>insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
>add_reg_note (insn, REG_DEAD, st_reg);
>  }
> -  return true;
> +  return num_of_st;
>  }
>
>
> @@ -3851,7 +3852,7 @@ ix86_zero_call_used_regs (HARD_REG_SET 
> need_zeroed_hardregs)
>  {
>HARD_REG_SET zeroed_hardregs;
>bool all_sse_zeroed = false;
> -  bool all_st_zeroed = false;
> +  int all_st_zeroed_num = 0;
>bool all_mm_zeroed = false;
>
>CLEAR_HARD_REG_SET (zeroed_hardregs);
> @@ -3881,9 +3882,17 @@ ix86_zero_call_used_regs (HARD_REG_SET 
> need_zeroed_hardregs)
>if (!exit_with_mmx_mode)
>  /* x87 exit mode, we should zero all st registers together.  */
>  {
> -  all_st_zeroed = zero_all_st_registers (need_zeroed_hardregs);
> -  if (all_st_zeroed)
> -   SET_HARD_REG_BIT (zeroed_hardregs, FIRST_STACK_REG);
> +  all_st_zeroed_num = zero_all_st_registers (need_zeroed_hardregs);
> +
> +  if (all_st_zeroed_num > 0)
> +   for (unsigned int regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; 
> regno++)
> + /* x87 stack registers that hold the return value should be 
> excluded.
> +x87 returns in the top (two for complex values) register.  */
> + if (all_st_zeroed_num == 8
> + || !((all_st_zeroed_num >= 6 && regno == REGNO 
> (crtl->return_rtx))
> +  || 

[Bug fortran/102312] [9/10/11 Regression] ICE in gfc_get_dtype_rank_type, at fortran/trans-types.c:1558 since r9-5424-g92f3a180aaf6f3cd

2022-03-31 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102312

anlauf at gcc dot gnu.org changed:

   What|Removed |Added

  Known to work||12.0
Summary|[9/10/11/12 Regression] ICE |[9/10/11 Regression] ICE in
   |in gfc_get_dtype_rank_type, |gfc_get_dtype_rank_type, at
   |at  |fortran/trans-types.c:1558
   |fortran/trans-types.c:1558  |since
   |since   |r9-5424-g92f3a180aaf6f3cd
   |r9-5424-g92f3a180aaf6f3cd   |

--- Comment #2 from anlauf at gcc dot gnu.org ---
Works for me on mainline (gcc-12).
Example z1 prints 0.

[Bug rtl-optimization/105091] RTL dse1 remove stack mem storing incorrectly

2022-03-31 Thread ian at airs dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105091

--- Comment #17 from Ian Lance Taylor  ---
Thanks.

[Bug fortran/105117] automatic deallocation of objects in procedures with heap arrays

2022-03-31 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105117

--- Comment #2 from anlauf at gcc dot gnu.org ---
(In reply to anlauf from comment #1)
> There seems to be a threshold at -fmax-stack-var-size=64.

The threshold is 64 for -m64, and 36 for -m32.
Could it be that the limit applies to the array descriptor instead of the
array?

Re: [PATCH] libstdc++: Implement std::unreachable() for C++23 (P0627R6)

2022-03-31 Thread Marc Glisse via Gcc-patches

On Thu, 31 Mar 2022, Jonathan Wakely wrote:


On Thu, 31 Mar 2022 at 17:03, Marc Glisse via Libstdc++
 wrote:


On Thu, 31 Mar 2022, Matthias Kretz via Gcc-patches wrote:


I like it. But I'd like it even more if we could have

#elif defined _UBSAN
   __ubsan_invoke_ub("reached std::unreachable()");

But to my knowledge UBSAN has no hooks for the library like this (yet).


-fsanitize=undefined already replaces __builtin_unreachable with its own
thing, so I was indeed going to ask if the assertion / trap provide a
better debugging experience compared to plain __builtin_unreachable, with
the possibility to get a stack trace (UBSAN_OPTIONS=print_stacktrace=1),
etc? Detecting if (the right subset of) ubsan is enabled sounds like a
good idea.


Does UBsan define a macro that we can use to detect it?


https://github.com/google/sanitizers/issues/765 seems to say no (it could 
be outdated though), but they were asking for use cases to motivate adding 
one. Apparently there is a macro for clang, although I don't think it is 
fine-grained.


Adding one to cppbuiltin.cc testing SANITIZE_UNREACHABLE looks easy, maybe 
we can do just this one, we don't need to go overboard and define macros 
for all possible suboptions of ubsan right now.


I don't think any of that prevents from pushing your patch as is for 
gcc-12.


--
Marc Glisse


[Bug fortran/104949] [OpenMP] omp target: firstprivate of allocatable array – only descriptor firstprivatized

2022-03-31 Thread burnus at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104949

--- Comment #1 from Tobias Burnus  ---
The following addition to testcase is needed.

! ---

!$omp parallel default(A)
!$omp master
  if (any (A /= [1,2,3,4,5])) error stop
  A(:) = [99,88,77,66,55]
!$omp end master
!$omp end parallel
if (any (A /= [1,2,3,4,5])) error stop

!$omp target defaultmap(firstprivate)
  if (any (A /= [1,2,3,4,5])) error stop
  A(:) = [99,88,77,66,55]
!$omp end target
if (any (A /= [1,2,3,4,5])) error stop

! ---

Reason: A different code path for
(a) defaultmap(firstprivate)  and  default(firstprivate)
For them gfc_omp_finish_clause is invoked
(b) explicit firstprivate(a)
Handled via gfc_trans_omp_clauses -> gfc_trans_omp_variable_list.
but gfc_omp_finish_clause is not called (should it?)

The 'parallel' variant works – and for both variants the
gfc_omp_clause_copy_ctor is invoked for both via lower_rec_input_clauses()'s
the block which follows the 'do_firstprivate:' label.

Both 'target' variants only create 'firstprivate(a)' - but additionally
'firstprivate(a.data)' is needed, including doing a pointer attach.

  *  *  * 

Currently, we support either code using attach like:

  map(force_to:var) map(force_to:*var.data [len...]) map(attach_detach:var.data
[bias: 0])

or pointer-set/pointer assign like for

  map(to:var.data [len:...])
  map(to:var [pointer set, len: 64])
  map(alloc: var.data [pointer assign, bias: 0])

In my understanding, either code requires that 'var.data' can be found as
host->device lookup, which does not work for firstprivate. And just internally
adding 'a' to the host->device mapping for firstprivate purpose internally does
not handle the following.

a = 5
!$omp target enter data map(to: a)
a = 7

! adding internally 'a' (host)->'a'(firstprivate) mapping to find the 'a.var'
! for the usage in attach/pointer assign does not work as 'a' already exists.

!$omp target firstprivate(a) 
  ! a should be now 7
!$omp end firstprivate
!$omp target
   ! a is 5
!$omp end target


For the usage in
  type t
integer, allocatable :: a, b
  end type t
  type(t) :: var
  !$omp target firstprivate(var)
...
multiple attachments are needed, i.e. just using firstprivate(a)
firstprivate(b) pointer_attach (a.data) and working with index i, i+1, i+2 does
not work.

[Bug rtl-optimization/105119] New: the division in x / (1 << y) is optimized away when x has unsigned type, but not when it's signed

2022-03-31 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105119

Bug ID: 105119
   Summary: the division in x / (1 << y) is optimized away when x
has unsigned type, but not when it's signed
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: rtl-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ppalka at gcc dot gnu.org
  Target Milestone: ---

For the following on x86_64 with -O2

int f(int x, int y) {
  return x / (1 << y);
}

GCC generates an idiv instruction:

movl%esi, %ecx
movl$1, %edx
movl%edi, %eax
sall%cl, %edx
movl%edx, %ecx
cltd
idivl   %ecx
ret

But I believe this is equivalent to the division-less

int g(int x, int y) {
  return (x + (x < 0) * ((1 << y) - 1)) >> y;
}

(which basically generalizes the existing x / (1 << y) -> x >> y transformation
that we perform for unsigned x).  For this latter function, we generate

movl%esi, %ecx
movl$1, %eax
xorl%edx, %edx
sall%cl, %eax
subl$1, %eax
testl   %edi, %edi
cmovns  %edx, %eax
addl%edi, %eax
sarl%cl, %eax
ret

which seems to be significantly faster according to some rough benchmarks.

[Bug libstdc++/105118] New: Why is unexpected::value() named error() in libstdc++?

2022-03-31 Thread hewillk at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105118

Bug ID: 105118
   Summary: Why is unexpected::value() named error() in libstdc++?
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: hewillk at gmail dot com
  Target Milestone: ---

In libstdc++'s implementation of std::expected, std::unexpected gets the _M_val
through error(), but in [expected.un.object.general], unexpected uses value()
to access val.
In my opinion, error() should be a better member function name, but the
standard currently uses value(). So I wonder why libstdc++ uses error()? Is
there any information about this?

[Bug fortran/105117] automatic deallocation of objects in procedures with heap arrays

2022-03-31 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105117

anlauf at gcc dot gnu.org changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
 Ever confirmed|0   |1
   Last reconfirmed||2022-03-31

--- Comment #1 from anlauf at gcc dot gnu.org ---
There seems to be a threshold at -fmax-stack-var-size=64.

[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

Jakub Jelinek  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|REOPENED|RESOLVED

--- Comment #12 from Jakub Jelinek  ---
Now fixed, thanks Joseph.

[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

--- Comment #11 from CVS Commits  ---
The master branch has been updated by Jakub Jelinek :

https://gcc.gnu.org/g:562d014efadfef6628ae670049c2d92ff6b166f0

commit r12-7941-g562d014efadfef6628ae670049c2d92ff6b166f0
Author: Jakub Jelinek 
Date:   Thu Mar 31 19:21:00 2022 +0200

contrib: Fix up spelling of loongarch-str.h dependency [PR105114]

As found by Joseph, the dependency of
gcc/config/loongarch/loongarch-str.h is spelled incorrectly,
it should be
gcc/config/loongarch/genopts/loongarch-strings
but was using
gcc/config/loongarch/genopts/loongarch-string

2022-03-31  Jakub Jelinek  
Joseph Myers  

PR other/105114
* gcc_update: Fix up spelling of
gcc/config/loongarch/genopts/loongarch-strings dependency.

[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

Jakub Jelinek  changed:

   What|Removed |Added

 Ever confirmed|0   |1
   Last reconfirmed||2022-03-31
 Resolution|FIXED   |---
 Status|RESOLVED|REOPENED

--- Comment #10 from Jakub Jelinek  ---
Sharp eyes...

Re: options: Clarifications around option definition records' help texts (was: make conflicting help text an error)

2022-03-31 Thread Joseph Myers
On Wed, 30 Mar 2022, Thomas Schwinge wrote:

> > I don't think we want to support different help strings for
> > different languages; if an option is supported for multiple languages, we
> > should have a generic description of that option that is correct for all
> > of them.
> 
> To not just bury that in the email archives: OK to push the attached
> "options: Clarifications around option definition records' help texts"?

OK.

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


Re: options: Fix "Multiple different help strings" error diagnostic (was: make conflicting help text an error)

2022-03-31 Thread Joseph Myers
On Wed, 30 Mar 2022, Thomas Schwinge wrote:

> > --- gcc/optc-gen.awk  (revision 187427)
> > +++ gcc/optc-gen.awk  (working copy)
> 
> >   else if (help[i] != "" && help[i + 1] != help[i])
> > - print "warning: multiple different help strings for " 
> > \
> > - opts[i] ":\n\t" help[i] "\n\t" help[i + 1] \
> > - | "cat 1>&2"
> > + print "#error Multiple different help strings for " \
> > + opts[i] ":\n\t" help[i] "\n\t" help[i + 1]
> > +
> 
> OK to push the attached 'options: Fix "Multiple different help strings"
> error diagnostic'?

OK.

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


[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread joseph at codesourcery dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

--- Comment #9 from joseph at codesourcery dot com  ---
The dependencies in gcc_update refer to 
gcc/config/loongarch/genopts/loongarch-string which doesn't exist (should 
be loongarch-strings not loongarch-string, I suppose).  Maybe that's 
causing the problem?

[Bug debug/105108] incomplete/incorrect DWARF information at -O1 and -Og after inlining a function returning a constant

2022-03-31 Thread assaiante at diag dot uniroma1.it via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105108

--- Comment #9 from Cristian Assaiante  ---
Created attachment 52728
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52728=edit
Executable file at -Og with l_144 = 8

[Bug debug/105108] incomplete/incorrect DWARF information at -O1 and -Og after inlining a function returning a constant

2022-03-31 Thread assaiante at diag dot uniroma1.it via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105108

--- Comment #8 from Cristian Assaiante  ---
(In reply to Jakub Jelinek from comment #3)
> And I certainly can't reproduce the wrong-debug issue you're talking about.
> If I change it to char l_144 = 8;
> then optimized dump has:
>[local count: 1073741824]:
>   # DEBUG BEGIN_STMT
>   # DEBUG l_144 => 8
>   # DEBUG BEGIN_STMT
>   # DEBUG l_165 => 128
>   # DEBUG BEGIN_STMT
>   # DEBUG l_144 => NULL
>   # DEBUG BEGIN_STMT
>   a = 1;
>   return 0;
> and in the debugger it correctly says that
> (gdb) p l_144
> $1 = 
> because at the a = 1 store the value is unknown.

I have tested again the C example with l_144 = 8 and in gdb l_144 is not marked
as optimized out, instead it has 8 as value:

$ cat a.c
int a;
char b() { return 0; }
int main() {
 char l_144 = 8;
 short l_165 = 128;
 l_144 = b();
 a = l_144 != l_165;
}

$ gcc -Og -g a.c -o opt

DWARF info for l_144:
0x006b: DW_TAG_variable
  DW_AT_name("l_144")
  DW_AT_decl_file   ("/home/stepping/a.c")
  DW_AT_decl_line   (4)
  DW_AT_decl_column (0x07)
  DW_AT_type(0x008d "char")
  DW_AT_location(0x000e: 
 [0x0040048c, 0x0040048c): DW_OP_lit8,
DW_OP_stack_value)
  DW_AT_GNU_locviews(0x000c)

GDB trace:
Reading symbols from opt...
(gdb) b 6
Breakpoint 1 at 0x40048c: file a.c, line 6.
(gdb) r
Starting program: /home/stepping/opt 

Breakpoint 1, main () at a.c:7
7a = l_144 != l_165;
(gdb) p l_144
$1 = 8 '\b'


I will add the executable file as an attachment.

[Bug c++/102629] [10/11/12 Regression] ICE: tree check in lookup_base, at cp/search.c:233 since r10-2194-g10acaf4db9f8b54b

2022-03-31 Thread mpolacek at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102629

Marek Polacek  changed:

   What|Removed |Added

 CC||mpolacek at gcc dot gnu.org
   Last reconfirmed||2022-03-31
   Priority|P3  |P2
 Status|UNCONFIRMED |NEW
 Ever confirmed|0   |1

--- Comment #2 from Marek Polacek  ---
Confirmed, but even GCC 9 ICEs for me.

Re: [PATCH v4] libgo: Don't use pt_regs member in mcontext_t

2022-03-31 Thread Sören Tempel via Gcc-patches
Ping.

Would be nice to get this integrated since this one of the changes needed to
make gccgo work with musl libc. Let me know if the patch needs to be revised
further.

Sören Tempel  wrote:
> The .regs member is primarily intended to be used in conjunction with
> ptrace. Since this code is not using ptrace, using .regs is a bad idea.
> Furthermore, the code currently fails to compile on musl since the
> pt_regs type (used by .regs) is in an incomplete type which has to be
> completed by inclusion of the asm/ptrace.h Kernel header. Contrary to
> glibc, this header is not indirectly included by musl through other
> header files.
> 
> This patch fixes compilation of this code with musl libc by accessing
> the register values via .gp_regs/.gregs (depending on 32-bit or 64-bit
> PowerPC) instead of using .regs. For more details, see
> https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591261.html
> 
> For the offsets in gp_regs refer to the Kernel asm/ptrace.h header.
> 
> This patch has been tested on Alpine Linux ppc64le (uses musl libc).
> 
> Signed-off-by: Sören Tempel 
> 
> ChangeLog:
> 
>   * libgo/runtime/go-signal.c (defined): Use .gp_regs/.gregs
> to access ppc64/ppc32 registers.
>   (dumpregs): Ditto.
> ---
> Changes since v3: Add special handling for 32-bit PowerPC with glibc,
> also avoid use of gregs_t type since glibc does not seem to define
> it on PowerPC.
> 
> This version of the patch introduces a new macro (PPC_GPREGS) to access
> these registers to special case musl/glibc handling in a central place
> once instead of duplicating it twice.
> 
>  libgo/runtime/go-signal.c | 32 
>  1 file changed, 24 insertions(+), 8 deletions(-)
> 
> diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
> index d30d1603adc..3255046260d 100644
> --- a/libgo/runtime/go-signal.c
> +++ b/libgo/runtime/go-signal.c
> @@ -16,6 +16,21 @@
>#define SA_RESTART 0
>  #endif
>  
> +// The PowerPC API for accessing gregs/gp_regs differs greatly across
> +// different libc implementations (musl and glibc).  To workaround that,
> +// define the canonical way to access these registers once here.
> +//
> +// See https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591360.html
> +#ifdef __PPC__
> +#if defined(__PPC64__)   /* ppc64 glibc & musl */
> +#define PPC_GPREGS(MCTX) (MCTX)->gp_regs
> +#elif defined(__GLIBC__) /* ppc32 glibc */
> +#define PPC_GPREGS(MCTX) (MCTX)->uc_regs->gregs
> +#else/* ppc32 musl */
> +#define PPC_GPREGS(MCTX) (MCTX)->gregs
> +#endif /* __PPC64__ */
> +#endif /* __PPC__ */
> +
>  #ifdef USING_SPLIT_STACK
>  
>  extern void __splitstack_getcontext(void *context[10]);
> @@ -224,7 +239,8 @@ getSiginfo(siginfo_t *info, void *context 
> __attribute__((unused)))
>  #elif defined(__alpha__) && defined(__linux__)
>   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc;
>  #elif defined(__PPC__) && defined(__linux__)
> - ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.regs->nip;
> + mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
> + ret.sigpc = PPC_GPREGS(m)[32];
>  #elif defined(__PPC__) && defined(_AIX)
>   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.jmp_context.iar;
>  #elif defined(__aarch64__) && defined(__linux__)
> @@ -341,13 +357,13 @@ dumpregs(siginfo_t *info __attribute__((unused)), void 
> *context __attribute__((u
>   int i;
>  
>   for (i = 0; i < 32; i++)
> - runtime_printf("r%d %X\n", i, m->regs->gpr[i]);
> - runtime_printf("pc  %X\n", m->regs->nip);
> - runtime_printf("msr %X\n", m->regs->msr);
> - runtime_printf("cr  %X\n", m->regs->ccr);
> - runtime_printf("lr  %X\n", m->regs->link);
> - runtime_printf("ctr %X\n", m->regs->ctr);
> - runtime_printf("xer %X\n", m->regs->xer);
> + runtime_printf("r%d %X\n", i, PPC_GPREGS(m)[i]);
> + runtime_printf("pc  %X\n", PPC_GPREGS(m)[32]);
> + runtime_printf("msr %X\n", PPC_GPREGS(m)[33]);
> + runtime_printf("cr  %X\n", PPC_GPREGS(m)[38]);
> + runtime_printf("lr  %X\n", PPC_GPREGS(m)[36]);
> + runtime_printf("ctr %X\n", PPC_GPREGS(m)[35]);
> + runtime_printf("xer %X\n", PPC_GPREGS(m)[37]);
> }
>  #elif defined(__PPC__) && defined(_AIX)
> {
> 


[Bug ipa/102513] [10/11/12 Regression] Many false positive warnings with recursive function

2022-03-31 Thread jamborm at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102513

Martin Jambor  changed:

   What|Removed |Added

   Assignee|jamborm at gcc dot gnu.org |unassigned at gcc dot 
gnu.org
 Status|ASSIGNED|NEW

--- Comment #13 from Martin Jambor  ---
Mitigated using value-range on master (soon to be GCC 12).  On 11 and earlier,
the determined IPA value-range is "variable" - I have not looked at why - so
the same approach cannot be taken there.

I am un-assigning myself so that whoever wants to explore other options how to
prevent/mitigate this issue does not feel hindered.  (But I'll keep the issue
on my list to ponder about.)

[PATCH] mips: Ignore zero width bitfields in arguments and issue -Wpsabi warning about C zero-width bit-field ABI changes [PR102024]

2022-03-31 Thread Xi Ruoyao via Gcc-patches
Part 2/2 of PR 102024 fix for MIPS.

The ABI says:

"Regardless of the struct field structure, it is treated as a sequence
of 64-bit chunks. If a chunk consists solely of a double float field
(but not a double, which is part of a union), it is passed in a floating
point register. Any other chunk is passed in an integer register."

It's not clear that if a zero-width field is a part of any 64-bit chunk,
and which 64-bit chunk it shall belong to when its on the boundary of
two chunks.  In previous GCC releases, the C++ FE removes all zero-width
bit-fields but otherwise a zero-width field is considered a part of the
next 64-bit chunk:

struct A
{
  /* first chunk */
  double a;  /* into FPR */
  /* second chunk */
  int : 0;
  double b;  /* into GPR with current GCC trunk because "the chunk
contains a bit-field" */
};

But clang does not account a zero-width bit-field on the boundary into
any "64-bit chunk", so its behavior is same as the C++ FE of previous
GCC releases.

I think we should not make an arbitary assumption like "a zero-width
bit-field is a part of the next chunk, but not a part of the previous
chunk".  So a consistent behavior is either consider it a part of both
chunks, or consider it not a part of any chunks.  As we are changing
psABI anyway, it seems OK to be compatible with clang.

gcc/
PR target/102024
* mips.cc (mips_function_arg): Ignore zero-width bit-fields, and
inform if it causes a psABI change.

gcc/testsuite/
PR target/102024
* gcc.target/mips/pr102024.c: New test.
---
 gcc/config/mips/mips.cc  | 45 +---
 gcc/testsuite/gcc.target/mips/pr102024.c | 20 +++
 2 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/pr102024.c

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 3284cf71f6f..5d1637e7b2f 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -6042,11 +6042,26 @@ mips_function_arg (cumulative_args_t cum_v, const 
function_arg_info )
  for (i = 0; i < info.reg_words; i++)
{
  rtx reg;
+ int has_zero_width_bf_abi_change = 0;
 
  for (; field; field = DECL_CHAIN (field))
-   if (TREE_CODE (field) == FIELD_DECL
-   && int_bit_position (field) >= bitpos)
- break;
+   {
+ if (TREE_CODE (field) != FIELD_DECL)
+   continue;
+
+ /* Ignore zero-width bit-fields.  And, if the ignored
+field is not from C++, it may be an ABI change.  */
+ if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
+   continue;
+ if (integer_zerop (DECL_SIZE (field)))
+   {
+ has_zero_width_bf_abi_change = 1;
+ continue;
+   }
+
+ if (int_bit_position (field) >= bitpos)
+   break;
+   }
 
  if (field
  && int_bit_position (field) == bitpos
@@ -6054,7 +6069,29 @@ mips_function_arg (cumulative_args_t cum_v, const 
function_arg_info )
  && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
reg = gen_rtx_REG (DFmode, FP_ARG_FIRST + info.reg_offset + i);
  else
-   reg = gen_rtx_REG (DImode, GP_ARG_FIRST + info.reg_offset + i);
+   {
+ reg = gen_rtx_REG (DImode,
+GP_ARG_FIRST + info.reg_offset + i);
+ has_zero_width_bf_abi_change = 0;
+   }
+
+ if (has_zero_width_bf_abi_change && warn_psabi)
+   {
+ static unsigned last_reported_type_uid;
+ unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (arg.type));
+ if (uid != last_reported_type_uid)
+   {
+ static const char *url =
+   CHANGES_ROOT_URL
+   "gcc-12/changes.html#zero_width_bitfields";
+ inform (input_location,
+ "the ABI for passing a value containing "
+ "zero-width bit-fields before an adjacent "
+ "64-bit floating-point field was retconned "
+ "in GCC %{12.1%}", url);
+ last_reported_type_uid = uid;
+   }
+   }
 
  XVECEXP (ret, 0, i)
= gen_rtx_EXPR_LIST (VOIDmode, reg,
diff --git a/gcc/testsuite/gcc.target/mips/pr102024.c 
b/gcc/testsuite/gcc.target/mips/pr102024.c
new file mode 100644
index 000..c45d01315d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr102024.c
@@ -0,0 +1,20 @@
+// PR target/102024
+// { dg-do compile }
+// { dg-options "-mabi=64 -mhard-float" }
+// { dg-final { scan-assembler "\\\$f12" } }
+
+struct 

[PATCH][GCC 9] arm: Fix ICEs with compare-and-swap and -march=armv8-m.base [PR99977]

2022-03-31 Thread Alex Coplan via Gcc-patches
Hi,

This is a backport of the fix for PR99977 to the GCC 9 branch. The only
case where the GCC 10 patch did not apply cleanly was on sync.md, where
some of the context has changed, but the substance of the patch has not
changed, it simply required applying by hand.

Tested as follows:
 - Bootstrap/regtest on arm-linux-gnueabihf.
 - Regression tested a cross compiler configured with
   --with-arch=armv8-m.base.

OK for the GCC 9 branch?

Thanks,
Alex

---

The PR shows two ICEs with __sync_bool_compare_and_swap and
-mcpu=cortex-m23 (equivalently, -march=armv8-m.base): one in LRA and one
later on, after the CAS insn is split.

The LRA ICE occurs because the
@atomic_compare_and_swap_1 pattern attempts to tie
two output operands together (operands 0 and 1 in the third
alternative). LRA can't handle this, since it doesn't make sense for an
insn to assign to the same operand twice.

The later (post-splitting) ICE occurs because the expansion of the
cbranchsi4_scratch insn doesn't quite go according to plan. As it
stands, arm_split_compare_and_swap calls gen_cbranchsi4_scratch,
attempting to pass a register (neg_bval) to use as a scratch register.
However, since the RTL template has a match_scratch here,
gen_cbranchsi4_scratch ignores this argument and produces a scratch rtx.
Since this is all happening after RA, this is doomed to fail (and we get
an ICE about the insn not matching its constraints).

It seems that the motivation for the choice of constraints in the
atomic_compare_and_swap pattern comes from an attempt to satisfy the
constraints of the cbranchsi4_scratch insn. This insn requires the
scratch register to be the same as the input register in the case that
we use a larger negative immediate (one that satisfies J, but not L).

Of course, as noted above, LRA refuses to assign two output operands to
the same register, so this was never going to work.

The solution I'm proposing here is to collapse the alternatives to the
CAS insn (allowing the two output register operands to be matched to
different registers) and to ensure that the constraints for
cbranchsi4_scratch are met in arm_split_compare_and_swap. We do this by
inserting a move to ensure the source and destination registers match if
necessary (i.e. in the case of large negative immediates).

Another notable change here is that we only do:

  emit_move_insn (neg_bval, const1_rtx);

for non-negative immediates. This is because the ADDS instruction used in
the negative case suffices to leave a suitable value in neg_bval: if the
operands compare equal, we don't take the branch (so neg_bval will be
set by the load exclusive). Otherwise, the ADDS will leave a nonzero
value in neg_bval, which will correctly signal that the CAS has failed
when it is later negated.

gcc/ChangeLog:

PR target/99977
* config/arm/arm.c (arm_split_compare_and_swap): Fix up codegen
with negative immediates: ensure we expand cbranchsi4_scratch
correctly and ensure we satisfy its constraints.
* config/arm/sync.md
(@atomic_compare_and_swap_1): Don't
attempt to tie two output operands together with constraints;
collapse two alternatives.
(@atomic_compare_and_swap_1): Likewise.
* config/arm/thumb1.md (cbranchsi4_neg_late): New.

gcc/testsuite/ChangeLog:

PR target/99977
* gcc.target/arm/pr99977.c: New test.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 58afc4a2647..8cbdb9a44e5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -29053,13 +29053,31 @@ arm_split_compare_and_swap (rtx operands[])
 }
   else
 {
-  emit_move_insn (neg_bval, const1_rtx);
   cond = gen_rtx_NE (VOIDmode, rval, oldval);
   if (thumb1_cmpneg_operand (oldval, SImode))
-   emit_unlikely_jump (gen_cbranchsi4_scratch (neg_bval, rval, oldval,
-   label2, cond));
+   {
+ rtx src = rval;
+ if (!satisfies_constraint_L (oldval))
+   {
+ gcc_assert (satisfies_constraint_J (oldval));
+
+ /* For such immediates, ADDS needs the source and destination regs
+to be the same.
+
+Normally this would be handled by RA, but this is all happening
+after RA.  */
+ emit_move_insn (neg_bval, rval);
+ src = neg_bval;
+   }
+
+ emit_unlikely_jump (gen_cbranchsi4_neg_late (neg_bval, src, oldval,
+  label2, cond));
+   }
   else
-   emit_unlikely_jump (gen_cbranchsi4_insn (cond, rval, oldval, label2));
+   {
+ emit_move_insn (neg_bval, const1_rtx);
+ emit_unlikely_jump (gen_cbranchsi4_insn (cond, rval, oldval, label2));
+   }
 }
 
   arm_emit_store_exclusive (mode, neg_bval, mem, newval, use_release);
diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md
index 0e777a92bb4..693a802c292 100644
--- 

[Bug gcov-profile/105063] [GCOV] Ability to map .gcda paths

2022-03-31 Thread vit9696 at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105063

--- Comment #14 from vit9696  ---
I have just tested this patch after rebasing it on 10.3.x branch, and can
confirm it works as intended. Thank you!

Re: [aarch64] Implement determine_suggested_unroll_factor

2022-03-31 Thread Andre Vieira (lists) via Gcc-patches


On 28/03/2022 15:59, Richard Sandiford wrote:

"Andre Vieira (lists)"  writes:

Hi,

Addressed all of your comments bar the pred ops one.

Is this OK?


gcc/ChangeLog:

      * config/aarch64/aarch64.cc (aarch64_vector_costs): Define
determine_suggested_unroll_factor and m_nosve_pattern.
      (determine_suggested_unroll_factor): New function.
      (aarch64_vector_costs::add_stmt_cost): Check for a qualifying
pattern
      to set m_nosve_pattern.
      (aarch64_vector_costs::finish_costs): Use
determine_suggested_unroll_factor.
      * config/aarch64/aarch64.opt (aarch64-vect-unroll-limit): New.

On 16/03/2022 18:01, Richard Sandiford wrote:

"Andre Vieira (lists)"  writes:

Hi,

This patch implements the costing function
determine_suggested_unroll_factor for aarch64.
It determines the unrolling factor by dividing the number of X
operations we can do per cycle by the number of X operations in the loop
body, taking this information from the vec_ops analysis during vector
costing and the available issue_info information.
We multiply the dividend by a potential reduction_latency, to improve
our pipeline utilization if we are stalled waiting on a particular
reduction operation.

Right now we also have a work around for vectorization choices where the
main loop uses a NEON mode and predication is available, such that if
the main loop makes use of a NEON pattern that is not directly supported
by SVE we do not unroll, as that might cause performance regressions in
cases where we would enter the original main loop's VF. As an example if
you have a loop where you could use AVG_CEIL with a V8HI mode, you would
originally get 8x NEON using AVG_CEIL followed by a 8x SVE predicated
epilogue, using other instructions. Whereas with the unrolling you would
end up with 16x AVG_CEIL NEON + 8x SVE predicated loop, thus skipping
the original 8x NEON. In the future, we could handle this differently,
by either using a different costing model for epilogues, or potentially
vectorizing more than one single epilogue.

gcc/ChangeLog:

       * config/aarch64/aarch64.cc (aarch64_vector_costs): Define
determine_suggested_unroll_factor.
       (determine_suggested_unroll_factor): New function.
       (aarch64_vector_costs::finish_costs): Use
determine_suggested_unroll_factor.

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 
b5687aab59f630920e51b742b80a540c3a56c6c8..9d3a607d378d6a2792efa7c6dece2a65c24e4521
 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -15680,6 +15680,7 @@ private:
 unsigned int adjust_body_cost (loop_vec_info, const aarch64_vector_costs *,
 unsigned int);
 bool prefer_unrolled_loop () const;
+  unsigned int determine_suggested_unroll_factor ();
   
 /* True if we have performed one-time initialization based on the

vec_info.  */
@@ -16768,6 +16769,105 @@ adjust_body_cost_sve (const aarch64_vec_op_count *ops,
 return sve_cycles_per_iter;
   }
   
+unsigned int

+aarch64_vector_costs::determine_suggested_unroll_factor ()
+{
+  auto *issue_info = aarch64_tune_params.vec_costs->issue_info;
+  if (!issue_info)
+return 1;
+  bool sve = false;
+  if (aarch64_sve_mode_p (m_vinfo->vector_mode))

Other code uses m_vec_flags & VEC_ANY_SVE for this.


+{
+  if (!issue_info->sve)
+   return 1;
+  sve = true;
+}
+  else
+{
+  if (!issue_info->advsimd)
+   return 1;

The issue info should instead be taken from vec_ops.simd_issue_info ()
in the loop below.  It can vary for each entry.


+  /* If we are trying to unroll a NEON main loop that contains patterns

s/a NEON/an Advanced SIMD/


+that we do not support with SVE and we might use a predicated
+epilogue, we need to be conservative and block unrolling as this might
+lead to a less optimal loop for the first and only epilogue using the
+original loop's vectorization factor.
+TODO: Remove this constraint when we add support for multiple epilogue
+vectorization.  */
+  if (partial_vectors_supported_p ()
+ && param_vect_partial_vector_usage != 0
+ && !TARGET_SVE2)
+   {
+ unsigned int i;
+ stmt_vec_info stmt_vinfo;
+ FOR_EACH_VEC_ELT (m_vinfo->stmt_vec_infos, i, stmt_vinfo)
+   {
+ if (is_pattern_stmt_p (stmt_vinfo))
+   {
+ gimple *stmt = stmt_vinfo->stmt;
+ if (is_gimple_call (stmt)
+ && gimple_call_internal_p (stmt))
+   {
+ enum internal_fn ifn
+   = gimple_call_internal_fn (stmt);
+ switch (ifn)
+   {
+   case IFN_AVG_FLOOR:
+   case IFN_AVG_CEIL:
+ return 1;
+   default:
+ break;
+   

[PATCH] mips: Emit psabi diagnostic for return values affected by C++ zero-width bit-field ABI change [PR 102024]

2022-03-31 Thread Xi Ruoyao via Gcc-patches
Part 1/2 of PR 102024 fix for MIPS.

No change for code generation.  It only adds a -Wpsabi inform for return
values affected by the change in C++ FE.

The ABI is clear that any zero-width bit-field in a return value will
disallow using FPRs for it, so the behavior of GCC trunk is correct
(it's also same as clang).

gcc/
PR target/102024
* mips.cc (mips_fpr_return_fields): Detect C++ zero-width
bit-fields and set up an indicator.
(mips_return_in_msb): Adapt for mips_fpr_return_fields change.
(mips_function_value_1): Diagnose when the presense of a C++
zero-width bit-field changes function returning in GCC 12.

gcc/testsuite/
PR target/102024
* g++.target/mips/mips.exp: New test supporting file.
* g++.target/mips/pr102024-1.C: New test.
---
 gcc/config/mips/mips.cc  | 51 ++--
 gcc/testsuite/g++.target/mips/mips.exp   | 34 
 gcc/testsuite/g++.target/mips/pr102024.C | 20 ++
 3 files changed, 101 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/mips/mips.exp
 create mode 100644 gcc/testsuite/g++.target/mips/pr102024.C

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index a1c4b437cd4..3284cf71f6f 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -6274,10 +6274,17 @@ mips_callee_copies (cumulative_args_t, const 
function_arg_info )
 
For n32 & n64, a structure with one or two fields is returned in
floating-point registers as long as every field has a floating-point
-   type.  */
+   type.
+
+   The C++ FE used to remove zero-width bit-fields in GCC 11 and earlier.
+   To make a proper diagnostic, this function will set HAS_ZERO_WIDTH_BF
+   to 1 once a C++ zero-width bit-field shows up, and then ignore it.
+   Then the caller can determine if this zero-width bit-field will make a
+   difference and emit a -Wpsabi inform.  */
 
 static int
-mips_fpr_return_fields (const_tree valtype, tree *fields)
+mips_fpr_return_fields (const_tree valtype, tree *fields,
+   int *has_zero_width_bf)
 {
   tree field;
   int i;
@@ -6294,6 +6301,12 @@ mips_fpr_return_fields (const_tree valtype, tree *fields)
   if (TREE_CODE (field) != FIELD_DECL)
continue;
 
+  if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
+   {
+ *has_zero_width_bf = 1;
+ continue;
+   }
+
   if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (field)))
return 0;
 
@@ -6319,11 +6332,14 @@ static bool
 mips_return_in_msb (const_tree valtype)
 {
   tree fields[2];
+  int has_zero_width_bf = 0;
+  int use_fpr = mips_fpr_return_fields (valtype, fields,
+   _zero_width_bf);
 
   return (TARGET_NEWABI
  && TARGET_BIG_ENDIAN
  && AGGREGATE_TYPE_P (valtype)
- && mips_fpr_return_fields (valtype, fields) == 0);
+ && (use_fpr == 0 || has_zero_width_bf));
 }
 
 /* Return true if the function return value MODE will get returned in a
@@ -6418,8 +6434,35 @@ mips_function_value_1 (const_tree valtype, const_tree 
fn_decl_or_type,
 return values, promote the mode here too.  */
   mode = promote_function_mode (valtype, mode, _p, func, 1);
 
+  int has_zero_width_bf = 0;
+  int use_fpr = mips_fpr_return_fields (valtype, fields,
+   _zero_width_bf);
+  if (TARGET_HARD_FLOAT &&
+ warn_psabi &&
+ has_zero_width_bf &&
+ use_fpr != 0)
+   {
+ static unsigned last_reported_type_uid;
+ unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (valtype));
+ if (uid != last_reported_type_uid)
+   {
+ static const char *url =
+   CHANGES_ROOT_URL
+   "gcc-12/changes.html#zero_width_bitfields";
+ inform (input_location,
+ "the ABI for returning a value containing "
+ "zero-width bit-fields but otherwise an aggregate "
+ "with only one or two floating-point fields was "
+ "retconned in GCC %{12.1%}", url);
+ last_reported_type_uid = uid;
+   }
+   }
+
+  if (has_zero_width_bf)
+   use_fpr = 0;
+
   /* Handle structures whose fields are returned in $f0/$f2.  */
-  switch (mips_fpr_return_fields (valtype, fields))
+  switch (use_fpr)
{
case 1:
  return mips_return_fpr_single (mode,
diff --git a/gcc/testsuite/g++.target/mips/mips.exp 
b/gcc/testsuite/g++.target/mips/mips.exp
new file mode 100644
index 000..9fa7e771b4d
--- /dev/null
+++ b/gcc/testsuite/g++.target/mips/mips.exp
@@ -0,0 +1,34 @@
+# Copyright (C) 2019-2022 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at 

Re: [PATCH] libstdc++: Implement std::unreachable() for C++23 (P0627R6)

2022-03-31 Thread Jonathan Wakely via Gcc-patches
On Thu, 31 Mar 2022 at 17:03, Marc Glisse via Libstdc++
 wrote:
>
> On Thu, 31 Mar 2022, Matthias Kretz via Gcc-patches wrote:
>
> > I like it. But I'd like it even more if we could have
> >
> > #elif defined _UBSAN
> >__ubsan_invoke_ub("reached std::unreachable()");
> >
> > But to my knowledge UBSAN has no hooks for the library like this (yet).
>
> -fsanitize=undefined already replaces __builtin_unreachable with its own
> thing, so I was indeed going to ask if the assertion / trap provide a
> better debugging experience compared to plain __builtin_unreachable, with
> the possibility to get a stack trace (UBSAN_OPTIONS=print_stacktrace=1),
> etc? Detecting if (the right subset of) ubsan is enabled sounds like a
> good idea.

Does UBsan define a macro that we can use to detect it?



Re: [PATCH] libstdc++: Implement std::unreachable() for C++23 (P0627R6)

2022-03-31 Thread Jonathan Wakely via Gcc-patches
On Thu, 31 Mar 2022 at 16:51, Matthias Kretz via Libstdc++
 wrote:
>
> I like it. But I'd like it even more if we could have
>
> #elif defined _UBSAN
> __ubsan_invoke_ub("reached std::unreachable()");
>
> But to my knowledge UBSAN has no hooks for the library like this (yet).

As far as I know, that's correct.


> > +#ifdef _GLIBCXX_DEBUG
> > +std::__glibcxx_assert_fail("", 0, "std::unreachable()",
> > +  "inconceivable!");
>
> Funny message, but it should be more helpful, IMHO. :)

We're currently limited to some string that can go inside "Assertion
'...' failed."

I also considered changing __glibcxx_assert_fail like so:

--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -55,6 +55,8 @@ namespace std
if (file && function && condition)
  fprintf(stderr, "%s:%d: %s: Assertion '%s' failed.\n",
 file, line, function, condition);
+else if (function)
+  fprintf(stderr, "%s called.\n", function);
abort();
  }
}

And then making std::unreachable() call __glibcxx_assert_fail(0, 0,
"std::unreachable()", 0).



Re: [PATCH] libstdc++: Implement std::unreachable() for C++23 (P0627R6)

2022-03-31 Thread Marc Glisse via Gcc-patches

On Thu, 31 Mar 2022, Matthias Kretz via Gcc-patches wrote:


I like it. But I'd like it even more if we could have

#elif defined _UBSAN
   __ubsan_invoke_ub("reached std::unreachable()");

But to my knowledge UBSAN has no hooks for the library like this (yet).


-fsanitize=undefined already replaces __builtin_unreachable with its own 
thing, so I was indeed going to ask if the assertion / trap provide a 
better debugging experience compared to plain __builtin_unreachable, with 
the possibility to get a stack trace (UBSAN_OPTIONS=print_stacktrace=1), 
etc? Detecting if (the right subset of) ubsan is enabled sounds like a 
good idea.


--
Marc Glisse


Re: [PATCH] libstdc++: Implement std::unreachable() for C++23 (P0627R6)

2022-03-31 Thread Xi Ruoyao via Gcc-patches
On Thu, 2022-03-31 at 17:50 +0200, Matthias Kretz via Gcc-patches wrote:
> I like it. But I'd like it even more if we could have
> 
> #elif defined _UBSAN
>     __ubsan_invoke_ub("reached std::unreachable()");
> 
> But to my knowledge UBSAN has no hooks for the library like this
> (yet).

UBSAN can catch __builtin_unreachable() and print a message "execution
reached an unreachable program point".
-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


[Bug ipa/103171] [12 Regression] ICE Segmentation fault since r12-2523-g13586172d0b70c9d

2022-03-31 Thread jamborm at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103171

Martin Jambor  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|ASSIGNED|RESOLVED

--- Comment #7 from Martin Jambor  ---
Fixed.

Re: [PATCH] libstdc++: Implement std::unreachable() for C++23 (P0627R6)

2022-03-31 Thread Matthias Kretz via Gcc-patches
I like it. But I'd like it even more if we could have

#elif defined _UBSAN
__ubsan_invoke_ub("reached std::unreachable()");

But to my knowledge UBSAN has no hooks for the library like this (yet).

and...

On Thursday, 31 March 2022 17:30:29 CEST Jonathan Wakely via Gcc-patches 
wrote:
> diff --git a/libstdc++-v3/include/std/utility
> b/libstdc++-v3/include/std/utility index 0d7f8954c5a..e5b5212381d 100644
> --- a/libstdc++-v3/include/std/utility
> +++ b/libstdc++-v3/include/std/utility
> @@ -186,6 +186,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  constexpr underlying_type_t<_Tp>
>  to_underlying(_Tp __value) noexcept
>  { return static_cast>(__value); }
> +
> +#define __cpp_lib_unreachable 202202L
> +  [[noreturn,__gnu__::__always_inline__]]
> +  void
> +  unreachable()
> +  {
> +#ifdef _GLIBCXX_DEBUG
> +std::__glibcxx_assert_fail("", 0, "std::unreachable()",
> +  "inconceivable!");

Funny message, but it should be more helpful, IMHO. :)

-Matthias

> +#elif defined _GLIBCXX_ASSERTIONS
> +__builtin_trap();
> +#else
> +__builtin_unreachable();
> +#endif
> +  }


-- 
──
 Dr. Matthias Kretz   https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research   https://gsi.de
 stdₓ::simd
──


[Bug target/102772] [12 regression] g++.dg/torture/pr80334.C FAILs

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102772

--- Comment #43 from Jakub Jelinek  ---
Created attachment 52727
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52727=edit
gcc12-pr102772.patch

Another patch.  This one changes (for now on 32-bit x86 solaris only)
malloc_alignment () value, which is used in 2 places, to initialize
aligned_new_threshold value if user used -falignment-new or -falignment-new=1
or -std=c++17 or later and -falignment-new=SOMETHING_BIGGER_THAN_ONE wasn't
used,
and for -Waligned-new= warning (we warn when non-align_t operator new is used
on types that need bigger alignment than malloc_alignment ()).

[PATCH] libstdc++: Implement std::unreachable() for C++23 (P0627R6)

2022-03-31 Thread Jonathan Wakely via Gcc-patches
This is a tiny C++23 feature that I plan to add for GCC 12. Does anybody
have any comments on the choices below in terms of when to make reaching
std::unreachable do an assert/trap/unreachable?

My thoughts on avoiding the overhead in the _GLIBCXX_ASSERTIONS case is
that this differs from e.g. assertions in operator[] where we want to
catch accidental bad indices. A std::unreachable() call should not be
reached accidentally. I hope it will only be used for conditions that
really are unreachable, and probably quite often where performance
matters. If using std::unreachable() increased code size significantly
then it would make it much less useful for guiding optimizations.


-- >8 --

This defines std::unreachable as an assertion for debug mode, a trap
when _GLIBCXX_ASSERTIONS is defined, and __builtin_unreachable()
otherwise.

The reason for only using __builtin_trap() in the second case is to
avoid the overhead of setting up a call to __glibcxx_assert_fail that
should never happen.

While thinking about what the debug assertion failure should print, I
noticed that the __glibcxx_assert_fail function doesn't check for null
pointers. This adds a check so we don't try to print them if null.

libstdc++-v3/ChangeLog:

* include/std/utility (unreachable): Define for C++23.
* include/std/version (__cpp_lib_unreachable): Define.
* src/c++11/debug.cc (__glibcxx_assert_fail): Check for valid
arguments.
* testsuite/20_util/unreachable/1.cc: New test.
* testsuite/20_util/unreachable/version.cc: New test.
---
 libstdc++-v3/include/std/utility| 15 +++
 libstdc++-v3/include/std/version|  1 +
 libstdc++-v3/src/c++11/debug.cc |  5 +++--
 libstdc++-v3/testsuite/20_util/unreachable/1.cc | 17 +
 .../testsuite/20_util/unreachable/version.cc| 10 ++
 5 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/20_util/unreachable/1.cc
 create mode 100644 libstdc++-v3/testsuite/20_util/unreachable/version.cc

diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 0d7f8954c5a..e5b5212381d 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -186,6 +186,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 constexpr underlying_type_t<_Tp>
 to_underlying(_Tp __value) noexcept
 { return static_cast>(__value); }
+
+#define __cpp_lib_unreachable 202202L
+  [[noreturn,__gnu__::__always_inline__]]
+  void
+  unreachable()
+  {
+#ifdef _GLIBCXX_DEBUG
+std::__glibcxx_assert_fail("", 0, "std::unreachable()",
+  "inconceivable!");
+#elif defined _GLIBCXX_ASSERTIONS
+__builtin_trap();
+#else
+__builtin_unreachable();
+#endif
+  }
 #endif // C++23
 #endif // C++20
 #endif // C++17
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 44b8a9f88b5..51f2110b68e 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -326,6 +326,7 @@
 # define __cpp_lib_string_resize_and_overwrite 202110L
 #endif
 #define __cpp_lib_to_underlying 202102L
+#define __cpp_lib_unreachable 202202L
 #endif
 #endif // C++2b
 #endif // C++20
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index 98fe2dcc153..ff3723eb93b 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -52,8 +52,9 @@ namespace std
   __glibcxx_assert_fail(const char* file, int line,
const char* function, const char* condition) noexcept
   {
-fprintf(stderr, "%s:%d: %s: Assertion '%s' failed.\n",
- file, line, function, condition);
+if (file && function && condition)
+  fprintf(stderr, "%s:%d: %s: Assertion '%s' failed.\n",
+ file, line, function, condition);
 abort();
   }
 }
diff --git a/libstdc++-v3/testsuite/20_util/unreachable/1.cc 
b/libstdc++-v3/testsuite/20_util/unreachable/1.cc
new file mode 100644
index 000..0c463d52a48
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unreachable/1.cc
@@ -0,0 +1,17 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do compile { target c++23 } }
+
+#include 
+
+#ifndef __cpp_lib_unreachable
+# error "Feature-test macro for unreachable missing in "
+#elif __cpp_lib_unreachable != 202202L
+# error "Feature-test macro for unreachable has wrong value in "
+#endif
+
+bool test01(int i)
+{
+  if (i == 4)
+return true;
+  std::unreachable();
+} // { dg-bogus "control reaches end of non-void function" }
diff --git a/libstdc++-v3/testsuite/20_util/unreachable/version.cc 
b/libstdc++-v3/testsuite/20_util/unreachable/version.cc
new file mode 100644
index 000..c7795900c30
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unreachable/version.cc
@@ -0,0 +1,10 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do preprocess { target c++23 } }
+
+#include 
+
+#ifndef __cpp_lib_unreachable
+# error 

[Bug ipa/103083] [10/11/12 Regression] Wrong code due to ipa-cp's bits value propagation since r10-5538-gc7ac9a0c7e3916f1

2022-03-31 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103083

--- Comment #6 from CVS Commits  ---
The master branch has been updated by Martin Jambor :

https://gcc.gnu.org/g:7ea3a73c195a79e6740ae594ee1a14c8bf7a938d

commit r12-7939-g7ea3a73c195a79e6740ae594ee1a14c8bf7a938d
Author: Martin Jambor 
Date:   Thu Mar 31 17:22:34 2022 +0200

ipa: Careful processing ANCESTOR jump functions and NULL pointers (PR
103083)

IPA_JF_ANCESTOR jump functions are constructed also when the formal
parameter of the caller is first checked whether it is NULL and left
as it is if it is NULL, to accommodate C++ casts to an ancestor class.

The jump function type was invented for devirtualization and IPA-CP
propagation of tree constants is also careful to apply it only to
existing DECLs(*) but as PR 103083 shows, the part propagating "known
bits" was not careful about this, which can lead to miscompilations.

This patch introduces a flag to the ancestor jump functions which
tells whether a NULL-check was elided when creating it and makes the
bits propagation behave accordingly, masking any bits otherwise would
be known to be one.  This should safely preserve alignment info, which
is the primary ifnormation that we keep in bits for pointers.

(*) There still may remain problems when a DECL resides on address
zero (with -fno-delete-null-pointer-checks ...I hope it cannot happen
otherwise).  I am looking into that now but I think it will be easier
for everyone if I do so in a follow-up patch.

gcc/ChangeLog:

2022-02-11  Martin Jambor  

PR ipa/103083
* ipa-prop.h (ipa_ancestor_jf_data): New flag keep_null;
(ipa_get_jf_ancestor_keep_null): New function.
* ipa-prop.cc (ipa_set_ancestor_jf): Initialize keep_null field of
the
ancestor function.
(compute_complex_assign_jump_func): Pass false to keep_null
parameter of ipa_set_ancestor_jf.
(compute_complex_ancestor_jump_func): Pass true to keep_null
parameter of ipa_set_ancestor_jf.
(update_jump_functions_after_inlining): Carry over keep_null from
the
original ancestor jump-function or merge them.
(ipa_write_jump_function): Stream keep_null flag.
(ipa_read_jump_function): Likewise.
(ipa_print_node_jump_functions_for_edge): Print the new flag.
* ipa-cp.cc (class ipcp_bits_lattice): Make various getters const. 
New
member function known_nonzero_p.
(ipcp_bits_lattice::known_nonzero_p): New.
(ipcp_bits_lattice::meet_with_1): New parameter drop_all_ones,
observe it.
(ipcp_bits_lattice::meet_with): Likewise.
(propagate_bits_across_jump_function): Simplify.  Pass true in
drop_all_ones when it is necessary.
(propagate_aggs_across_jump_function): Take care of keep_null
flag.
(ipa_get_jf_ancestor_result): Propagate NULL accross keep_null
jump functions.

gcc/testsuite/ChangeLog:

2021-11-25  Martin Jambor  

* gcc.dg/ipa/pr103083-1.c: New test.
* gcc.dg/ipa/pr103083-2.c: Likewise.

[committed] libstdc++: Add comment about memalign requirements

2022-03-31 Thread Jonathan Wakely via Gcc-patches
Pushed to trunk.

-- >8 --

The memalign man page on Solaris and QNX lists an additional requirement
for the alignment value that is not present in all implementation of
that non-standard function. For both those targets we should actually be
using posix_memalign anyway, so it doesn't matter. This just adds a
comment making note of that fact.

libstdc++-v3/ChangeLog:

* libsupc++/new_opa.cc (aligned_alloc): Add comment.
---
 libstdc++-v3/libsupc++/new_opa.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libstdc++-v3/libsupc++/new_opa.cc 
b/libstdc++-v3/libsupc++/new_opa.cc
index 5f24737de1c..411cd8d98b2 100644
--- a/libstdc++-v3/libsupc++/new_opa.cc
+++ b/libstdc++-v3/libsupc++/new_opa.cc
@@ -87,6 +87,8 @@ aligned_alloc (std::size_t al, std::size_t sz)
 static inline void*
 aligned_alloc (std::size_t al, std::size_t sz)
 {
+  // Solaris requires al >= sizeof a word and QNX requires >= sizeof(void*)
+  // but they both provide posix_memalign, so will use the definition above.
   return memalign (al, sz);
 }
 #else // !HAVE__ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN
-- 
2.34.1



[Bug ipa/102513] [10/11/12 Regression] Many false positive warnings with recursive function

2022-03-31 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102513

--- Comment #12 from CVS Commits  ---
The master branch has been updated by Martin Jambor :

https://gcc.gnu.org/g:cf68f5a6d20db2aee2f3e674ad3f10e1c458edf9

commit r12-7937-gcf68f5a6d20db2aee2f3e674ad3f10e1c458edf9
Author: Martin Jambor 
Date:   Thu Mar 31 17:14:42 2022 +0200

ipa-cp: Do not create clones for values outside known value range (PR
102513)

PR 102513 shows we emit bogus array access warnings when IPA-CP
creates clones specialized for values which it deduces from arithmetic
jump functions describing self-recursive calls.  Those can however be
avoided if we consult the IPA-VR information that the same pass also
has.

The patch below does that at the stage when normally values are only
examined for profitability.  It would be better not to create lattices
describing such bogus values in the first place, however that presents
an ordering problem, the pass currently propagates all information,
and so both constants and VR, in no particular order when processing
SCCs, and so this approach seemed much simpler.

I plan to rearrange the pass so that it clones in multiple passes over
the call graph (or rather the lattice dependence graph) and it feels
natural to only do propagation for these kinds of recursion in the
second or later passes, which would fix the issue more elegantly.

gcc/ChangeLog:

2022-02-14  Martin Jambor  

PR ipa/102513
* ipa-cp.cc (decide_whether_version_node): Skip scalar values
which do not fit the known value_range.

gcc/testsuite/ChangeLog:

2022-02-14  Martin Jambor  

PR ipa/102513
* gcc.dg/ipa/pr102513.c: New test.

[Bug target/102772] [12 regression] g++.dg/torture/pr80334.C FAILs

2022-03-31 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102772

--- Comment #42 from Jonathan Wakely  ---
It should really depend on -faligned-new which can be set for C++14 and C++11
too (and I guess C++98 in theory, but that would break when you include 
because you can't have 'enum class align_val_t' in C++98). So cxx_dialect isn't
right.

Does -faligned-new get processed already before the hook? If so, can you just
check if the threadshold is already non-zero and change if so? If it's zero,
leave it as zero.

[Bug target/102024] [12 Regression] zero width bitfields and ABIs

2022-03-31 Thread xry111 at mengyan1223 dot wang via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102024

--- Comment #34 from Xi Ruoyao  ---
(In reply to Xi Ruoyao from comment #33)

> > So in struct B { int : 0; double a, b; }; it will go into GPR and FPR
> 
> GCC trunk puts "a" into FPR, not GPR!  So the "leading" zero-width
> bit-fields are ignored (GCC does not think it's a part of any "64-bit
> chunk"), but other zero-width bit-fields are accounted...  This is just
> puzzling to me.

Remove this: I just forgot to rename ".C" to ".c" when I tested this with GCC
11.  But still I think clang's behavior is better.

> I'll make a patch to match the behavior of clang.

[Bug target/102024] [12 Regression] zero width bitfields and ABIs

2022-03-31 Thread xry111 at mengyan1223 dot wang via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102024

--- Comment #33 from Xi Ruoyao  ---
(In reply to Segher Boessenkool from comment #31)
> Well, what do other compilers do?  It's not such a good idea to break ABI
> compatibility with the 1990's compilers ;-)

Does someone have access to a Greenhills compiler here?

(In reply to Jakub Jelinek from comment #32)

> I think best would be to ignore them altogether, especially if other
> compilers do that too.

I agree the behavior of clang (or previous G++) is more "rational".  To make
things more "interesting":

> So in struct B { int : 0; double a, b; }; it will go into GPR and FPR

GCC trunk puts "a" into FPR, not GPR!  So the "leading" zero-width bit-fields
are ignored (GCC does not think it's a part of any "64-bit chunk"), but other
zero-width bit-fields are accounted...  This is just puzzling to me.

I'll make a patch to match the behavior of clang.

[Bug analyzer/105112] Speed up -fanalyzer on big-code.c

2022-03-31 Thread dmalcolm at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105112

--- Comment #3 from David Malcolm  ---
Possible simplification: don't try to model floating-point operations e.g. any
binop on a floating point value has unknown_svalue as the result, so that
complicated floating-point computations can be quickly handled with a "we don't
care" value.   (though do we care about tainted divisors for floating-point?)

[Bug ipa/103171] [12 Regression] ICE Segmentation fault since r12-2523-g13586172d0b70c9d

2022-03-31 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103171

--- Comment #6 from CVS Commits  ---
The master branch has been updated by Martin Jambor :

https://gcc.gnu.org/g:f6d65e803623c7ba6c8eb92ce5975fc1b90cd91e

commit r12-7936-gf6d65e803623c7ba6c8eb92ce5975fc1b90cd91e
Author: Martin Jambor 
Date:   Thu Mar 31 16:50:24 2022 +0200

ipa: Create LOAD references when necessary during inlining (PR 103171)

in r12-2523-g13586172d0b70c ipa-prop tracking of jump functions during
inlining got the ability to remove ADDR references when inlining
discovered that they were not necessary or turn them into LOAD
references when we know that what was a function call argument passed
by reference will end up as a load (one or more).

Unfortunately, the code only creates the LOAD references when
replacing removed ADDR references and PR 103171 showed that with some
ordering of inlining, we need to add the LOAD reference before we know
we can remove the ADDR one - or the reference will be lost, leading to
link errors or even ICEs.

Specifically in testcase gcc.dg/lto/pr103171_1.c added in this patch,
if foo() is inlined to entry(), we need to create the LOAD reference
so that when later bar() is inlined into foo() and we discover that
the paameter is unused, we can remove the ADDR reference and still
keep the varaible around for the load.

Martin

gcc/ChangeLog:

2022-01-28  Martin Jambor  

PR ipa/103171
* ipa-prop.cc (propagate_controlled_uses): Add a LOAD reference
always when an ADDR_EXPR constant is known to reach a load because
of inlining, not just when removing an ADDR reference.

gcc/testsuite/ChangeLog:

2022-01-28  Martin Jambor  

PR ipa/103171
* gcc.dg/ipa/remref-6.c: Adjust dump scan string.
* gcc.dg/ipa/remref-7.c: New test.
* gcc.dg/lto/pr103171_0.c: New test.
* gcc.dg/lto/pr103171_1.c: Likewise.

MC/DC support for gcov?

2022-03-31 Thread Sebastian Huber

Hello,

gcov supports currently branch coverage. Some projects require modified 
condition/decision coverage (MC/DC):


https://en.wikipedia.org/wiki/Modified_condition/decision_coverage

In general, 100% branch coverage does not imply 100% MC/DC coverage:

https://www.adacore.com/uploads_gems/Couverture_ERTS-2012.pdf

The paper contains a criterion under which 100% branch coverage implies 
100% MC/DC coverage:


"Theorem 1 If the BDD of a decision D is a tree (with
only one path from the root to any condition node),
then BDD edge coverage implies MCDC"

The BDD is the Binary Decision Diagram. I have no idea how the compiler 
and the coverage supports works in GCC. Is this BDD available for the 
coverage support and could the coverage support check for this property 
and then for example add it to the gcov information? If the BDD of a 
decision is not a tree, then we would have to record which paths through 
the BDD are covered to get the MC/DC coverage. This would require extra 
storage and instrumentation. According to the paper, the BDD is usually 
a tree in real world applications. Does this sound like feasible feature 
for GCC? Could it be even a GSoC project?


Kind regards,
Sebastian

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[Bug target/102772] [12 regression] g++.dg/torture/pr80334.C FAILs

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102772

--- Comment #41 from Jakub Jelinek  ---
(In reply to Jonathan Wakely from comment #39)
> (In reply to r...@cebitec.uni-bielefeld.de from comment #37)
> >   AFAICS, alignof is C++ >= 11 only.  I've used the attached patch to
> >   use __alignof__ instead, although I don't know if that's the best fix.
> 
> Yes, alignof is C++11 only, but the reason it's OK to use there is that
> __STDCPP_DEFAULT_NEW_ALIGNMENT__ is C++17 only, and alignof is guarded by:
> 
> #if __cpp_aligned_new
> if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
> 
> Strictly speaking, this code is enabled when -faligned-new is active, which
> is true for C++17 by default.
> 
> It appears that Jakub's patch makes -faligned-new always active for Solaris
> x86, which we don't want.

Ah, indeed, I thought the threshold is separate from it being enabled, but it
is not.
So, we want to change it in the option override handling only if cxx_dialect >=
cxx17, but that is something only defined in c-family, while the backend option
overriding is in code linked with all FEs.
Thus, we'd need to override it instead somewhere in i386-c.cc.
But nothing in that file is called early enough, from what I can see, the
sequence of initialization is:
cxx_dialect set to the default (cxx17 now)
possibly cxx_dialect changed if -std= used on command line
SUBTARGET_OVERRIDE_OPTIONS invoked
cxx_init_decl_processing
4645  if (aligned_new_threshold == -1)
4646aligned_new_threshold = (cxx_dialect >= cxx17) ? 1 : 0;
4647  if (aligned_new_threshold == 1)
4648aligned_new_threshold = malloc_alignment () / BITS_PER_UNIT;
code invoked
ix86_register_pragmas from i386-c.cc called
ix86_target_macros from i386-c.cc called

Also, the -Waligned-new= warning uses malloc_alignment () rather than
aligned_new_threshold, so if we want to override something for 32-bit x86
solaris, mingw and vxworks, we probably need something to hook into
malloc_alignment rather than to tweak aligned_new_threshold.

I think we need a target macro for it though rather than target hook, because
it needs to be invoked from the C++ FE and implemented in config/*-c.cc

[PATCH] testsuite: add missing dg-require-effective-target fpic

2022-03-31 Thread Marc Poulhiès via Gcc-patches
Require effective target fpic for newly added test.

gcc/testsuite/
* g++.dg/ext/visibility/visibility-local-extern1.C: Add missing
dg-require-effective-target fpic.

Tested on x86_64-linux. Ok for master?

---
 gcc/testsuite/g++.dg/ext/visibility/visibility-local-extern1.C | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-local-extern1.C 
b/gcc/testsuite/g++.dg/ext/visibility/visibility-local-extern1.C
index 40c20199d0c..6fb1cc7f381 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/visibility-local-extern1.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-local-extern1.C
@@ -1,6 +1,7 @@
 // PR c++/103291
 // { dg-additional-options -fpic }
 // { dg-final { scan-assembler-not "@GOTPCREL" } }
+// { dg-require-effective-target fpic }
 
 #pragma GCC visibility push(hidden)
 
-- 
2.25.1



[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

--- Comment #8 from Jakub Jelinek  ---
One possibility would be 32-bit make binary using 32-bit stat syscalls and the
new files having non-representable ino_t values, so stat on those would appear
to fail.  But that is just a wild guess...

[Bug target/102772] [12 regression] g++.dg/torture/pr80334.C FAILs

2022-03-31 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102772

--- Comment #40 from Jonathan Wakely  ---
N.B. I don't think we want to replace alignof with __alignof__ because they're
not identical. For x86 alignof(long long) != __alignof__(long long).

[Bug target/102772] [12 regression] g++.dg/torture/pr80334.C FAILs

2022-03-31 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102772

--- Comment #39 from Jonathan Wakely  ---
(In reply to r...@cebitec.uni-bielefeld.de from comment #37)
>   AFAICS, alignof is C++ >= 11 only.  I've used the attached patch to
>   use __alignof__ instead, although I don't know if that's the best fix.

Yes, alignof is C++11 only, but the reason it's OK to use there is that
__STDCPP_DEFAULT_NEW_ALIGNMENT__ is C++17 only, and alignof is guarded by:

#if __cpp_aligned_new
if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)

Strictly speaking, this code is enabled when -faligned-new is active, which is
true for C++17 by default.

It appears that Jakub's patch makes -faligned-new always active for Solaris
x86, which we don't want.

[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread schwab--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

--- Comment #7 from Andreas Schwab  ---
contrib/gcc_update is supposed to work with any make, even non-GNU ones,
though.

[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread seurer at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

seurer at gcc dot gnu.org changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|UNCONFIRMED |RESOLVED

--- Comment #6 from seurer at gcc dot gnu.org ---
On a system where things were working I built and installed make 3.81.  Using
that I now get the same failure.

I will just use the newer make on the old system where things were failing.

Re: [patch]update the documentation for TARGET_ZERO_CALL_USED_REGS hook and add an assertion

2022-03-31 Thread Qing Zhao via Gcc-patches
Hi, Richard,

Thanks a lot for your reviewing on the non-x86 part. 

Uros, could you please review the x86 part of the change?

thanks.

Qing

> On Mar 31, 2022, at 8:10 AM, Richard Sandiford  
> wrote:
> 
> Qing Zhao  writes:
>> Hi, 
>> 
>> Per our discussion on: 
>> https://gcc.gnu.org/pipermail/gcc-patches/2022-March/592002.html
>> 
>> I come up with the following patch to:
>> 
>> 1. Update the documentation for TARGET_ZERO_CALL_USED_REGS hook;
>> 2. Add an assertion in function.cc to make sure the actually zeroed_regs is 
>> a subset of all call used regs;
>>   (The reason I didn’t add a new parameter to TARGET_ZERO_CALL_USED_REGS is, 
>> I think adding the 
>>assertion in the common place function.cc is simpler to be implemented).
> 
> Yeah, that's fair.  I guess in theory, passing the parameter would allow
> targets to choose between two versions of zeroing the register, one with
> a temporary and one without.  But that's a purely hypothetical situation
> and we could always add a parameter later if that turns out to be useful.
> 
> Perhaps more realistically, there might be other uses of the hook in
> future that want to zero registers for different reasons, with their
> own rules about which registers can be zeroed.  In other words, the
> hook is providing a general facility that happens to be useful for
> -fzero-call-used-regs.  But again, we can deal with that if it ever
> happens.
> 
> So I agree this is the right call, especially for stage 4.
> 
>> 3. This new assertion identified a bug in i386 implementation. Fix this bug 
>> in i386.
>> 
>> This patch is bootstrapped on both x86 and aarch64, no regression.
>> 
>> Okay for commit?
> 
> OK for the non-x86 bits.
> 
> Thanks,
> Richard
> 
>> thanks.
>> 
>> Qing
>> 
>> ===
>> From 2e5bc1b25a707c6a17afbf03da2a8bec5b03454d Mon Sep 17 00:00:00 2001
>> From: Qing Zhao 
>> Date: Fri, 18 Mar 2022 20:49:56 +
>> Subject: [PATCH] Add an assertion: the zeroed_hardregs set is a subset of all
>> call used regs.
>> 
>> We should make sure that the hard register set that is actually cleared by
>> the target hook zero_call_used_regs should be a subset of all call used
>> registers.
>> 
>> At the same time, update documentation for the target hook
>> TARGET_ZERO_CALL_USED_REGS.
>> 
>> This new assertion identified a bug in the i386 implemenation, which
>> incorrectly set the zeroed_hardregs for stack registers. Fixed this bug
>> in i386 implementation.
>> 
>> gcc/ChangeLog:
>> 
>> 2022-03-21  Qing Zhao  
>> 
>>  * config/i386/i386.cc (zero_all_st_registers): Return the value of
>>  num_of_st.
>>  (ix86_zero_call_used_regs): Update zeroed_hardregs set according to
>>  the return value of zero_all_st_registers.
>>  * doc/tm.texi: Update the documentation of TARGET_ZERO_CALL_USED_REGS.
>>  * function.cc (gen_call_used_regs_seq): Add an assertion.
>>  * target.def: Update the documentation of TARGET_ZERO_CALL_USED_REGS.
>> ---
>> gcc/config/i386/i386.cc | 27 ++-
>> gcc/doc/tm.texi |  7 +++
>> gcc/function.cc | 22 ++
>> gcc/target.def  |  7 +++
>> 4 files changed, 50 insertions(+), 13 deletions(-)
>> 
>> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
>> index 5a561966eb44..d84047a4bc1b 100644
>> --- a/gcc/config/i386/i386.cc
>> +++ b/gcc/config/i386/i386.cc
>> @@ -3753,16 +3753,17 @@ zero_all_vector_registers (HARD_REG_SET 
>> need_zeroed_hardregs)
>>needs to be cleared, the whole stack should be cleared.  However,
>>x87 stack registers that hold the return value should be excluded.
>>x87 returns in the top (two for complex values) register, so
>> -   num_of_st should be 7/6 when x87 returns, otherwise it will be 8.  */
>> +   num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
>> +   return the value of num_of_st.  */
>> 
>> 
>> -static bool
>> +static int
>> zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
>> {
>> 
>>   /* If the FPU is disabled, no need to zero all st registers.  */
>>   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
>> -return false;
>> +return 0;
>> 
>>   unsigned int num_of_st = 0;
>>   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
>> @@ -3774,7 +3775,7 @@ zero_all_st_registers (HARD_REG_SET 
>> need_zeroed_hardregs)
>>   }
>> 
>>   if (num_of_st == 0)
>> -return false;
>> +return 0;
>> 
>>   bool return_with_x87 = false;
>>   return_with_x87 = (crtl->return_rtx
>> @@ -3802,7 +3803,7 @@ zero_all_st_registers (HARD_REG_SET 
>> need_zeroed_hardregs)
>>   insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
>>   add_reg_note (insn, REG_DEAD, st_reg);
>> }
>> -  return true;
>> +  return num_of_st;
>> }
>> 
>> 
>> @@ -3851,7 +3852,7 @@ ix86_zero_call_used_regs (HARD_REG_SET 
>> need_zeroed_hardregs)
>> {
>>   HARD_REG_SET zeroed_hardregs;
>>   bool all_sse_zeroed = false;
>> -  bool all_st_zeroed = 

[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread seurer at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

--- Comment #5 from seurer at gcc dot gnu.org ---
The makefiles between systems were the same.

One thing that is different is make itself.  On another system where this was
working make was a later release.  So I grabbed the latest release of make on
the failing system, built and installed it, and the problem went away.

The failing make was 3.81.  I am going to try make 3.81 on a working system to
see if it then fails.

[Bug target/102772] [12 regression] g++.dg/torture/pr80334.C FAILs

2022-03-31 Thread ro at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102772

--- Comment #38 from Rainer Orth  ---
Created attachment 52726
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52726=edit
Use __alignof__ in several allocator headers.

[Bug target/102772] [12 regression] g++.dg/torture/pr80334.C FAILs

2022-03-31 Thread ro at CeBiTec dot Uni-Bielefeld.DE via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102772

--- Comment #37 from ro at CeBiTec dot Uni-Bielefeld.DE  ---
> --- Comment #36 from Jakub Jelinek  ---
> Created attachment 52719
>   --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52719=edit
> gcc12-pr102772.patch
>
> So like this?

Mostly.  There were some issues, though:

* Initially, the patch caused the bootstrap to fail:

In file included from
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/i386-pc-solaris2.11/bits/c++allocator.h:33,
 from
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/bits/allocator.h:46,
 from
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/memory:64,
 from
/vol/gcc/src/hg/master/local/libstdc++-v3/src/c++98/allocator-inst.cc:29:
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/bits/new_allocator.h:
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*)':
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/bits/new_allocator.h:130:24:
error: expected primary-expression before ')' token
  130 | if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
  |^
  | ^~~
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/bits/new_allocator.h:130:13:
note: (if you use '-fpermissive', G++ will accept your code, but allowing the
use of an undeclared name is deprecated)
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/bits/new_allocator.h:132:54:
error: there are no arguments to 'alignof' that depend on a template parameter,
so a declaration of 'alignof' must be available [-fpermissive]
  132 | std::align_val_t __al = std::align_val_t(alignof(_Tp));
  |  ^~~
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/bits/new_allocator.h:132:53:
error: expected primary-expression before '(' token
  132 | std::align_val_t __al = std::align_val_t(alignof(_Tp));
  | ^
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/bits/new_allocator.h:132:65:
error: expected primary-expression before ')' token
  132 | std::align_val_t __al = std::align_val_t(alignof(_Tp));
  | ^

  and several more, affecting

  include/ext/bitmap_allocator.h
  include/ext/mt_allocator.h
  include/ext/pool_allocator.h

  AFAICS, alignof is C++ >= 11 only.  I've used the attached patch to
  use __alignof__ instead, although I don't know if that's the best fix.

* With that, the build completed and g++.dg/torture/pr80334.C PASSes.

  And yes, my tree did include

changeset:   259338:c7f332059508
bookmark:trunk
tag: qparent
user:Jakub Jelinek 
date:Wed Mar 30 16:47:10 2022 +0200
summary: Revert "testsuite: Change pr80334.C testcase to dg-do compile
[PR102772]"

* However, there were quite a number of 32-bit regressions:

+FAIL: g++.dg/cpp1z/aligned-new4.C(test for warnings, line 11)
+FAIL: g++.dg/cpp1z/aligned-new4a.C(test for warnings, line 11)
+FAIL: g++.dg/diagnostic/recur-align.C  -std=gnu++14  (test for warnings, line
13)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 132)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 136)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 140)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 155)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 180)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 210)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 233)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings,
 line 241)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 41)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14  (test for
warnings, line 43)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14 (test for excess
errors)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14 note (test for
warnings, line 178)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14 note (test for
warnings, line 208)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14 note (test for
warnings, line 231)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++14 note (test for
warnings, line 238)
+FAIL: g++.dg/warn/Wmismatched-new-delete-2.C  -std=gnu++98  (test for
warnings, line 132)
+FAIL: 

Re: [PATCH] tree-optimization/104912 - ensure cost model is checked first

2022-03-31 Thread Richard Biener via Gcc-patches
On Thu, 31 Mar 2022, Richard Sandiford wrote:

> Richard Biener  writes:
> > The following makes sure that when we build the versioning condition
> > for vectorization including the cost model check, we check for the
> > cost model and branch over other versioning checks.  That is what
> > the cost modeling assumes, since the cost model check is the only
> > one accounted for in the scalar outside cost.  Currently we emit
> > all checks as straight-line code combined with bitwise ops which
> > can result in surprising ordering of checks in the final assembly.
> 
> Yeah, this had bugged me too, and meant that we made some bad
> decisions in some of the local benchmarks we use.  Was just afraid
> to poke at it, since it seemed like a deliberate decision. :-)

I guess it was rather giving up because of the way our loop-versioning
infrastructure works ...

> > Since loop_version accepts only a single versioning condition
> > the splitting is done after the fact.
> >
> > The result is a 1.5% speedup of 416.gamess on x86_64 when compiling
> > with -Ofast and tuning for generic or skylake.  That's not enough
> > to recover from the slowdown when vectorizing but it now cuts off
> > the expensive alias versioning test.
> >
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> >
> > OK for trunk?
> >
> > For the rest of the regression my plan is to somehow factor in
> > the evolution of the number of iterations in the outer loop
> > (which is {1, +, 1}) to somehow bump the static profitability
> > estimate and together with the "cheap" cost model check never
> > execute the vectorized version (well, it is actually never executed,
> > but only because the alias check fails).
> >
> > Thanks,
> > Richard.
> >
> > 2022-03-21  Richard Biener  
> >
> > PR tree-optimization/104912
> > * tree-vect-loop-manip.cc (vect_loop_versioning): Split
> > the cost model check to a separate BB to make sure it is
> > checked first and not combined with other version checks.
> > ---
> >  gcc/tree-vect-loop-manip.cc | 53 ++---
> >  1 file changed, 50 insertions(+), 3 deletions(-)
> >
> > diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
> > index a7bbc916bbc..8ef333eb31b 100644
> > --- a/gcc/tree-vect-loop-manip.cc
> > +++ b/gcc/tree-vect-loop-manip.cc
> > @@ -3445,13 +3445,28 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
> > cond_expr = expr;
> >  }
> >  
> > +  tree cost_name = NULL_TREE;
> > +  if (cond_expr
> > +  && !integer_truep (cond_expr)
> > +  && (version_niter
> > + || version_align
> > + || version_alias
> > + || version_simd_if_cond))
> > +cost_name = cond_expr = force_gimple_operand_1 (unshare_expr 
> > (cond_expr),
> > +   _expr_stmt_list,
> > +   is_gimple_val, NULL_TREE);
> > +
> >if (version_niter)
> >  vect_create_cond_for_niters_checks (loop_vinfo, _expr);
> >  
> >if (cond_expr)
> > -cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
> > -   _expr_stmt_list,
> > -   is_gimple_condexpr, NULL_TREE);
> > +{
> > +  gimple_seq tem = NULL;
> > +  cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
> > + ,
> > + is_gimple_condexpr, NULL_TREE);
> > +  gimple_seq_add_seq (_expr_stmt_list, tem);
> > +}
> >  
> >if (version_align)
> >  vect_create_cond_for_align_checks (loop_vinfo, _expr,
> > @@ -3654,6 +3669,38 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
> >update_ssa (TODO_update_ssa);
> >  }
> >  
> > +  /* Split the cost model check off to a separate BB.  Costing assumes
> > + this is the only thing we perform when we enter the scalar loop.  */
> 
> Maybe “…from a failed cost decision” or something?  Might sounds out
> of context like it applied more generally.

Fixed.

> > +  if (cost_name)
> > +{
> > +  gimple *def = SSA_NAME_DEF_STMT (cost_name);
> 
> I realise it should only happen very rarely if at all, but is it
> absolutely guaranteed that the cost condition doesn't fold to a
> constant?

OK, better be safe than sorry - I added a SSA_NAME check.

> > +  /* All uses of the cost check are 'true' after the check we
> > +are going to insert.  */
> > +  replace_uses_by (cost_name, boolean_true_node);
> > +  /* And we're going to build the new single use of it.  */
> > +  gcond *cond = gimple_build_cond (NE_EXPR, cost_name, 
> > boolean_false_node,
> > +  NULL_TREE, NULL_TREE);
> > +  edge e = split_block (gimple_bb (def), def);
> > +  gimple_stmt_iterator gsi = gsi_for_stmt (def);
> > +  gsi_insert_after (, cond, GSI_NEW_STMT);
> > +  edge true_e, false_e;
> > +  extract_true_false_edges_from_block (e->dest, _e, _e);
> > +  

options: Clarify 'Init' option property usage for streaming optimization (was: [PATCH] options, lto: Optimize streaming of optimization nodes)

2022-03-31 Thread Thomas Schwinge
Hi!

On 2020-11-18T10:36:35+0100, Jakub Jelinek via Gcc-patches 
 wrote:
> Honza mentioned that especially for the new param machinery, most of
> streamed values are probably going to be the default values.  Perhaps
> somehow we could stream them more effectively.
>
> This patch implements it and brings further savings, the size
> goes down from 574 bytes to 273 bytes, i.e. less than half.

Neat idea about the XOR-encoding!

> Not trying to handle enums because the code doesn't know if (enum ...) 10
> is even valid, similarly non-parameters because those really generally
> don't have large initializers, and params without Init (those are 0
> initialized and thus don't need to be handled).

Given this only looks at 'Init', I understand this may actually
mis-optimize in the case that there is an 'Init' present, but that value
is then "by default" overridden via 'LANG_HOOKS_INIT_OPTIONS_STRUCT', or
'TARGET_OPTION_OVERRIDE', for example.  (I'm however not claiming that's
an actual problem to be worried about -- just for my understanding.)

Either way:

>   * optc-save-gen.awk: Initialize var_opt_init.  In
>   cl_optimization_stream_out for params with default values larger than
>   10, xor the default value with the actual parameter value.  In
>   cl_optimization_stream_in repeat the above xor.

> --- gcc/optc-save-gen.awk.jj  2020-09-14 10:51:54.493740942 +0200
> +++ gcc/optc-save-gen.awk 2020-09-14 11:39:39.441602594 +0200
> @@ -1186,6 +1186,7 @@ for (i = 0; i < n_opts; i++) {
>   var_opt_val_type[n_opt_val] = otype;
>   var_opt_val[n_opt_val] = "x_" name;
>   var_opt_hash[n_opt_val] = flag_set_p("Optimization", flags[i]);
> + var_opt_init[n_opt_val] = opt_args("Init", flags[i]);
>   n_opt_val++;
>   }
>  }

Reading through the options handling, I was confused why 'Init' needs to
be handled in 'gcc/optc-save-gen.awk'.  To help the next person -- like,
me in a few weeks ;-) -- wondering about this, OK to push the attached
"options: Clarify 'Init' option property usage for streaming
optimization"?


Grüße
 Thomas


> @@ -1257,10 +1258,21 @@ for (i = 0; i < n_opt_val; i++) {
>   otype = var_opt_val_type[i];
>   if (otype ~ "^const char \\**$")
>   print "  bp_pack_string (ob, bp, ptr->" name", true);";
> - else if (otype ~ "^unsigned")
> - print "  bp_pack_var_len_unsigned (bp, ptr->" name");";
> - else
> - print "  bp_pack_var_len_int (bp, ptr->" name");";
> + else {
> + if (otype ~ "^unsigned") {
> + sgn = "unsigned";
> + } else {
> + sgn = "int";
> + }
> + if (name ~ "^x_param" && !(otype ~ "^enum ") && 
> var_opt_init[i]) {
> + print "  if (" var_opt_init[i] " > (" 
> var_opt_val_type[i] ") 10)";
> + print "bp_pack_var_len_" sgn " (bp, ptr->" name" ^ 
> " var_opt_init[i] ");";
> + print "  else";
> + print "bp_pack_var_len_" sgn " (bp, ptr->" name");";
> + } else {
> + print "  bp_pack_var_len_" sgn " (bp, ptr->" name");";
> + }
> + }
>  }
>  print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof 
> (ptr->explicit_mask[0]); i++)";
>  print "bp_pack_value (bp, ptr->explicit_mask[i], 64);";
> @@ -1281,10 +1293,18 @@ for (i = 0; i < n_opt_val; i++) {
>   print "  if (ptr->" name")";
>   print "ptr->" name" = xstrdup (ptr->" name");";
>   }
> - else if (otype ~ "^unsigned")
> - print "  ptr->" name" = (" var_opt_val_type[i] ") 
> bp_unpack_var_len_unsigned (bp);";
> - else
> - print "  ptr->" name" = (" var_opt_val_type[i] ") 
> bp_unpack_var_len_int (bp);";
> + else {
> + if (otype ~ "^unsigned") {
> + sgn = "unsigned";
> + } else {
> + sgn = "int";
> + }
> + print "  ptr->" name" = (" var_opt_val_type[i] ") 
> bp_unpack_var_len_" sgn " (bp);";
> + if (name ~ "^x_param" && !(otype ~ "^enum ") && 
> var_opt_init[i]) {
> + print "  if (" var_opt_init[i] " > (" 
> var_opt_val_type[i] ") 10)";
> + print "ptr->" name" ^= " var_opt_init[i] ";";
> + }
> + }
>  }
>  print "  for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof 
> (ptr->explicit_mask[0]); i++)";
>  print "ptr->explicit_mask[i] = bp_unpack_value (bp, 64);";


-
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
>From c7968fa44b1073dfa7da3a11470a9e76b6faafaf Mon Sep 17 00:00:00 2001
From: Thomas Schwinge 
Date: Thu, 31 Mar 2022 12:06:29 

[Bug ipa/104303] [12 regression] gnatmake is miscompiled by IPA/modref

2022-03-31 Thread hubicka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104303

--- Comment #4 from Jan Hubicka  ---
What happens to the by-value parameter should get merged from  
concat5_pkg2.compare (s);
I will take a look now - sorry for not handling this bug earlier.

Honza

Re: [patch]update the documentation for TARGET_ZERO_CALL_USED_REGS hook and add an assertion

2022-03-31 Thread Richard Sandiford via Gcc-patches
Qing Zhao  writes:
> Hi, 
>
> Per our discussion on: 
> https://gcc.gnu.org/pipermail/gcc-patches/2022-March/592002.html
>
> I come up with the following patch to:
>
> 1. Update the documentation for TARGET_ZERO_CALL_USED_REGS hook;
> 2. Add an assertion in function.cc to make sure the actually zeroed_regs is a 
> subset of all call used regs;
>(The reason I didn’t add a new parameter to TARGET_ZERO_CALL_USED_REGS is, 
> I think adding the 
> assertion in the common place function.cc is simpler to be implemented).

Yeah, that's fair.  I guess in theory, passing the parameter would allow
targets to choose between two versions of zeroing the register, one with
a temporary and one without.  But that's a purely hypothetical situation
and we could always add a parameter later if that turns out to be useful.

Perhaps more realistically, there might be other uses of the hook in
future that want to zero registers for different reasons, with their
own rules about which registers can be zeroed.  In other words, the
hook is providing a general facility that happens to be useful for
-fzero-call-used-regs.  But again, we can deal with that if it ever
happens.

So I agree this is the right call, especially for stage 4.

> 3. This new assertion identified a bug in i386 implementation. Fix this bug 
> in i386.
>
> This patch is bootstrapped on both x86 and aarch64, no regression.
>
> Okay for commit?

OK for the non-x86 bits.

Thanks,
Richard

> thanks.
>
> Qing
>
> ===
> From 2e5bc1b25a707c6a17afbf03da2a8bec5b03454d Mon Sep 17 00:00:00 2001
> From: Qing Zhao 
> Date: Fri, 18 Mar 2022 20:49:56 +
> Subject: [PATCH] Add an assertion: the zeroed_hardregs set is a subset of all
>  call used regs.
>
> We should make sure that the hard register set that is actually cleared by
> the target hook zero_call_used_regs should be a subset of all call used
> registers.
>
> At the same time, update documentation for the target hook
> TARGET_ZERO_CALL_USED_REGS.
>
> This new assertion identified a bug in the i386 implemenation, which
> incorrectly set the zeroed_hardregs for stack registers. Fixed this bug
> in i386 implementation.
>
> gcc/ChangeLog:
>
> 2022-03-21  Qing Zhao  
>
>   * config/i386/i386.cc (zero_all_st_registers): Return the value of
>   num_of_st.
>   (ix86_zero_call_used_regs): Update zeroed_hardregs set according to
>   the return value of zero_all_st_registers.
>   * doc/tm.texi: Update the documentation of TARGET_ZERO_CALL_USED_REGS.
>   * function.cc (gen_call_used_regs_seq): Add an assertion.
>   * target.def: Update the documentation of TARGET_ZERO_CALL_USED_REGS.
> ---
>  gcc/config/i386/i386.cc | 27 ++-
>  gcc/doc/tm.texi |  7 +++
>  gcc/function.cc | 22 ++
>  gcc/target.def  |  7 +++
>  4 files changed, 50 insertions(+), 13 deletions(-)
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index 5a561966eb44..d84047a4bc1b 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -3753,16 +3753,17 @@ zero_all_vector_registers (HARD_REG_SET 
> need_zeroed_hardregs)
> needs to be cleared, the whole stack should be cleared.  However,
> x87 stack registers that hold the return value should be excluded.
> x87 returns in the top (two for complex values) register, so
> -   num_of_st should be 7/6 when x87 returns, otherwise it will be 8.  */
> +   num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
> +   return the value of num_of_st.  */
>  
>  
> -static bool
> +static int
>  zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
>  {
>  
>/* If the FPU is disabled, no need to zero all st registers.  */
>if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
> -return false;
> +return 0;
>  
>unsigned int num_of_st = 0;
>for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
> @@ -3774,7 +3775,7 @@ zero_all_st_registers (HARD_REG_SET 
> need_zeroed_hardregs)
>}
>  
>if (num_of_st == 0)
> -return false;
> +return 0;
>  
>bool return_with_x87 = false;
>return_with_x87 = (crtl->return_rtx
> @@ -3802,7 +3803,7 @@ zero_all_st_registers (HARD_REG_SET 
> need_zeroed_hardregs)
>insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
>add_reg_note (insn, REG_DEAD, st_reg);
>  }
> -  return true;
> +  return num_of_st;
>  }
>  
>  
> @@ -3851,7 +3852,7 @@ ix86_zero_call_used_regs (HARD_REG_SET 
> need_zeroed_hardregs)
>  {
>HARD_REG_SET zeroed_hardregs;
>bool all_sse_zeroed = false;
> -  bool all_st_zeroed = false;
> +  int all_st_zeroed_num = 0;
>bool all_mm_zeroed = false;
>  
>CLEAR_HARD_REG_SET (zeroed_hardregs);
> @@ -3881,9 +3882,17 @@ ix86_zero_call_used_regs (HARD_REG_SET 
> need_zeroed_hardregs)
>if (!exit_with_mmx_mode)
>  /* x87 exit mode, we should zero all st registers together.  */
>  {
> -  

[Bug tree-optimization/104645] [12 Regression] i ? i % 2 : 0 not optimized anymore

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104645

--- Comment #4 from Jakub Jelinek  ---
The first GCC 13 should have been GCC 12 of course.

[Bug tree-optimization/104645] [12 Regression] i ? i % 2 : 0 not optimized anymore

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104645

--- Comment #3 from Jakub Jelinek  ---
Created attachment 52725
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52725=edit
gcc12-pr104645.patch

I wonder if at least for GCC 13 we just can't treat even that cast stmt as a
preparation statement.
This won't handle say shifts etc. with casts after them, but will at least fix
this regression.
And for GCC 13 perhaps we can throw away all the separation of "preparation"
and assign statements and natural_element_p and absorbing_element_p and instead
just try to constant evaluate all the middle_bb statements and see if that
doesn't trigger traps/overflows/other UB and yields the expected PHI arg
constant from the original comparison constant.

Re: [PATCH] tree-optimization/104912 - ensure cost model is checked first

2022-03-31 Thread Richard Sandiford via Gcc-patches
Richard Biener  writes:
> The following makes sure that when we build the versioning condition
> for vectorization including the cost model check, we check for the
> cost model and branch over other versioning checks.  That is what
> the cost modeling assumes, since the cost model check is the only
> one accounted for in the scalar outside cost.  Currently we emit
> all checks as straight-line code combined with bitwise ops which
> can result in surprising ordering of checks in the final assembly.

Yeah, this had bugged me too, and meant that we made some bad
decisions in some of the local benchmarks we use.  Was just afraid
to poke at it, since it seemed like a deliberate decision. :-)

> Since loop_version accepts only a single versioning condition
> the splitting is done after the fact.
>
> The result is a 1.5% speedup of 416.gamess on x86_64 when compiling
> with -Ofast and tuning for generic or skylake.  That's not enough
> to recover from the slowdown when vectorizing but it now cuts off
> the expensive alias versioning test.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
>
> OK for trunk?
>
> For the rest of the regression my plan is to somehow factor in
> the evolution of the number of iterations in the outer loop
> (which is {1, +, 1}) to somehow bump the static profitability
> estimate and together with the "cheap" cost model check never
> execute the vectorized version (well, it is actually never executed,
> but only because the alias check fails).
>
> Thanks,
> Richard.
>
> 2022-03-21  Richard Biener  
>
>   PR tree-optimization/104912
>   * tree-vect-loop-manip.cc (vect_loop_versioning): Split
>   the cost model check to a separate BB to make sure it is
>   checked first and not combined with other version checks.
> ---
>  gcc/tree-vect-loop-manip.cc | 53 ++---
>  1 file changed, 50 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
> index a7bbc916bbc..8ef333eb31b 100644
> --- a/gcc/tree-vect-loop-manip.cc
> +++ b/gcc/tree-vect-loop-manip.cc
> @@ -3445,13 +3445,28 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
>   cond_expr = expr;
>  }
>  
> +  tree cost_name = NULL_TREE;
> +  if (cond_expr
> +  && !integer_truep (cond_expr)
> +  && (version_niter
> +   || version_align
> +   || version_alias
> +   || version_simd_if_cond))
> +cost_name = cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
> + _expr_stmt_list,
> + is_gimple_val, NULL_TREE);
> +
>if (version_niter)
>  vect_create_cond_for_niters_checks (loop_vinfo, _expr);
>  
>if (cond_expr)
> -cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
> - _expr_stmt_list,
> - is_gimple_condexpr, NULL_TREE);
> +{
> +  gimple_seq tem = NULL;
> +  cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
> +   ,
> +   is_gimple_condexpr, NULL_TREE);
> +  gimple_seq_add_seq (_expr_stmt_list, tem);
> +}
>  
>if (version_align)
>  vect_create_cond_for_align_checks (loop_vinfo, _expr,
> @@ -3654,6 +3669,38 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
>update_ssa (TODO_update_ssa);
>  }
>  
> +  /* Split the cost model check off to a separate BB.  Costing assumes
> + this is the only thing we perform when we enter the scalar loop.  */

Maybe “…from a failed cost decision” or something?  Might sounds out
of context like it applied more generally.

> +  if (cost_name)
> +{
> +  gimple *def = SSA_NAME_DEF_STMT (cost_name);

I realise it should only happen very rarely if at all, but is it
absolutely guaranteed that the cost condition doesn't fold to a
constant?

> +  /* All uses of the cost check are 'true' after the check we
> +  are going to insert.  */
> +  replace_uses_by (cost_name, boolean_true_node);
> +  /* And we're going to build the new single use of it.  */
> +  gcond *cond = gimple_build_cond (NE_EXPR, cost_name, 
> boolean_false_node,
> +NULL_TREE, NULL_TREE);
> +  edge e = split_block (gimple_bb (def), def);
> +  gimple_stmt_iterator gsi = gsi_for_stmt (def);
> +  gsi_insert_after (, cond, GSI_NEW_STMT);
> +  edge true_e, false_e;
> +  extract_true_false_edges_from_block (e->dest, _e, _e);
> +  e->flags &= ~EDGE_FALLTHRU;
> +  e->flags |= EDGE_TRUE_VALUE;
> +  edge e2 = make_edge (e->src, false_e->dest, EDGE_FALSE_VALUE);
> +  e->probability = prob;
> +  e2->probability = prob.invert ();

Is reusing prob the right thing to do?  Wouldn't the path to the vector
loop end up with a probability of PROB^2?

> +  set_immediate_dominator (CDI_DOMINATORS, false_e->dest, 

[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

--- Comment #4 from Jakub Jelinek  ---
Mar 30 15:14 is certainly much newer than Mar 30 10:16.
Perhaps try make -d -f Makefile.28475 all
?

[Bug ipa/104303] [12 regression] gnatmake is miscompiled by IPA/modref

2022-03-31 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104303

--- Comment #3 from Richard Biener  ---
The store

D.5010.P_BOUNDS = 

is

 
unit-size 
align:32 warn_if_not_align:0 symtab:0 alias-set 9 canonical-type
0x7653bf18 fields  Ada size 
pointer_to_this  chain >
public unsigned DI size  unit-size

align:64 warn_if_not_align:0 symtab:0 alias-set 4 canonical-type
0x7653b150>

arg:0 
unit-size 
align:64 warn_if_not_align:0 symtab:0 alias-set 2 canonical-type
0x7653b348 fields  context
 unconstrained array

pointer_to_this  chain >
used ignored TI concat5_pkg1.adb:15:5 size  unit-size 
align:128 warn_if_not_align:0 context 
chain 
addressable used ignored DI concat5_pkg1.adb:15:5 size  unit-size 
align:32 warn_if_not_align:0 context  chain >>
arg:1 
visited unsigned DI :0:0 size 
unit-size 
align:64 warn_if_not_align:0 offset_align 128
offset  bit-offset  context >>

and the issue is that somehow the summary for

concat5_pkg1.make_failed (D.5010);

only has an base/ref/access node for MODREF_GLOBAL_MEMORY_PARM and
nothing else.  In .modref2 this function is just

void concat5_pkg1.make_failed (struct  s)
{
  struct string___XUB * s$P_BOUNDS;

   [local count: 1073741824]:
  concat5_pkg2.compare (s);
  return;

but we do

modref analyzing 'Concat5_Pkg1.Make_Failed/0' (ipa=0)
Past summary:
  loads:
Every base
  stores:
Every base
  Side effects
  Nondeterministic
  Global memory read
  Global memory written
 - Analyzing load: s
   - Read-only or local, ignoring.
 - Analyzing call:concat5_pkg2.compare (s);
 - Function availability <= AVAIL_INTERPOSABLE.
 - modref done with result: tracked.
  loads:
  Base 0: alias set 0
Ref 0: alias set 0
  access: Base in global memory
  stores:
  Base 0: alias set 0
Ref 0: alias set 0
  access: Base in global memory
  Side effects
  Nondeterministic
  Global memory read
  Global memory written

so it seems we fail to consider by-value escaping parameters.  Something
like the following, but it does not reproduce with that, so there must
be sth special with the Ada testcase.

struct X { int i; };

void foo (struct X);

static void __attribute__((noinline))
bar (struct X x)
{
  foo (x);
}

void baz ()
{
  struct X x;
  x.i = 1;
  bar (x);
}

Btw, if we disable modref2 the testcase works - so somehow dropping that we
load/store all bases wrecks things.

Honza?

Re: [pushed] c++: parse trivial DMI immediately [PR96645]

2022-03-31 Thread Patrick Palka via Gcc-patches
On Wed, 30 Mar 2022, Jason Merrill via Gcc-patches wrote:

> The recent change to reject __is_constructible for nested classes with DMI
> is breaking some code loudly that was previously only silently broken.
> Let's allow simple cases by immediately parsing DMI that do no name lookup;
> then being in complete class scope makes no difference.

Not sure if this is a problem in practice but it seems the initializer
processing step of cp_parser_late_parse_one_default_arg may involve name
lookup even if the parse itself didn't:

  struct A {
struct B {
  const A  = {};
};
  };

We used to accept this (very contrived example), but now reject with

  error: invalid use of incomplete type ‘const struct A’

> 
> Tested x86_64-pc-linux-gnu, applying to trunk.
> 
>   PR c++/96645
> 
> gcc/cp/ChangeLog:
> 
>   * parser.cc (cp_parser_early_parsing_nsdmi): New.
>   (cp_parser_member_declaration): Call it.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/cpp0x/nsdmi10.C: Now OK.
>   * g++.dg/ext/is_constructible3.C: Likewise.
>   * g++.dg/ext/is_constructible7.C: Likewise.
> ---
>  gcc/cp/parser.cc | 28 +++-
>  gcc/testsuite/g++.dg/cpp0x/nsdmi10.C |  4 +--
>  gcc/testsuite/g++.dg/ext/is_constructible3.C |  2 +-
>  gcc/testsuite/g++.dg/ext/is_constructible7.C |  3 +--
>  4 files changed, 31 insertions(+), 6 deletions(-)
> 
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index 7e1c777364e..63c8af1c722 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -2701,6 +2701,8 @@ static tree cp_parser_late_parse_one_default_arg
>(cp_parser *, tree, tree, tree);
>  static void cp_parser_late_parsing_nsdmi
>(cp_parser *, tree);
> +static bool cp_parser_early_parsing_nsdmi
> +  (cp_parser *, tree);
>  static void cp_parser_late_parsing_default_args
>(cp_parser *, tree);
>  static tree cp_parser_sizeof_operand
> @@ -27478,7 +27480,8 @@ cp_parser_member_declaration (cp_parser* parser)
> if (DECL_DECLARES_FUNCTION_P (decl))
>   cp_parser_save_default_args (parser, STRIP_TEMPLATE (decl));
> else if (TREE_CODE (decl) == FIELD_DECL
> -&& DECL_INITIAL (decl))
> +&& DECL_INITIAL (decl)
> +&& !cp_parser_early_parsing_nsdmi (parser, decl))
>   /* Add DECL to the queue of NSDMI to be parsed later.  */
>   vec_safe_push (unparsed_nsdmis, decl);
>   }
> @@ -32292,6 +32295,29 @@ cp_parser_late_parsing_nsdmi (cp_parser *parser, 
> tree field)
>DECL_INITIAL (field) = def;
>  }
>  
> +/* If the DEFERRED_PARSE for FIELD is safe to parse immediately, do so.
> +   Returns true if deferred parsing is no longer needed.  */
> +
> +static bool
> +cp_parser_early_parsing_nsdmi (cp_parser *parser, tree field)
> +{
> +  tree init = DECL_INITIAL (field);
> +  if (TREE_CODE (init) != DEFERRED_PARSE)
> +return true;
> +
> +  cp_token_cache *tokens = DEFPARSE_TOKENS (init);
> +  for (cp_token *p = tokens->first; p != tokens->last; ++p)
> +if (p->type == CPP_NAME
> + || p->keyword == RID_THIS
> + || p->keyword == RID_OPERATOR)
> +  /* There's a name to look up or 'this', give up.  */
> +  return false;
> +
> +  /* It's trivial, parse now.  */
> +  cp_parser_late_parsing_nsdmi (parser, field);
> +  return true;
> +}
> +
>  /* FN is a FUNCTION_DECL which may contains a parameter with an
> unparsed DEFERRED_PARSE.  Parse the default args now.  This function
> assumes that the current scope is the scope in which the default
> diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi10.C 
> b/gcc/testsuite/g++.dg/cpp0x/nsdmi10.C
> index d8588b7f29e..a965f7bc333 100644
> --- a/gcc/testsuite/g++.dg/cpp0x/nsdmi10.C
> +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi10.C
> @@ -6,7 +6,7 @@ struct A1 {
>  int y1 = 1;
>};
>  
> -  A1(const B1& opts = B1()) {}  // { dg-error "default member initializer" }
> +  A1(const B1& opts = B1()) {}
>  };
>  
>  struct A2 {
> @@ -14,5 +14,5 @@ struct A2 {
>  int x2, y2 = 1;
>};
>  
> -  A2(const B2& opts = B2()) {}  // { dg-error "default member initializer" }
> +  A2(const B2& opts = B2()) {}
>  };
> diff --git a/gcc/testsuite/g++.dg/ext/is_constructible3.C 
> b/gcc/testsuite/g++.dg/ext/is_constructible3.C
> index 305751d28e2..c7c58746cd0 100644
> --- a/gcc/testsuite/g++.dg/ext/is_constructible3.C
> +++ b/gcc/testsuite/g++.dg/ext/is_constructible3.C
> @@ -8,7 +8,7 @@ struct A {
>  B() = default;
>};
>  
> -  static constexpr bool v = __is_constructible (B); // { dg-error "member 
> initializer" }
> +  static constexpr bool v = __is_constructible (B);
>  
>  };
>  
> diff --git a/gcc/testsuite/g++.dg/ext/is_constructible7.C 
> b/gcc/testsuite/g++.dg/ext/is_constructible7.C
> index 76a63bba5d0..013a1df03c6 100644
> --- a/gcc/testsuite/g++.dg/ext/is_constructible7.C
> +++ b/gcc/testsuite/g++.dg/ext/is_constructible7.C
> @@ -12,7 +12,7 @@ using true_type = 

[Bug target/102024] [12 Regression] zero width bitfields and ABIs

2022-03-31 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102024

--- Comment #32 from Jakub Jelinek  ---
One of the reasons we changed the ABI on various arches one way or another is
that we had this ABI incompatibility between C and C++, that just can't be
right.
At that time we can and should decide if we go for compatibility with C or C++.
The MIPS n64 wording I could find:
"Regardless of the struct field structure, it is treated as a sequence of
64-bit chunks. If a chunk consists solely of a double float field (but not a
double, which is part of a union), it is passed in a floating point register.
Any other chunk is passed in an integer register."
is unclear for both the zero width bitfields and empty structure/union C
members,
members that have zero size and are on the 64-bit chunk boundaries can belong
to either previous or next chunk or can be ignored altogether.

I think best would be to ignore them altogether, especially if other compilers
do that too.
Also consider:
struct T {};
struct S { struct T t; double a; struct T u; double b; };
struct U { int a[0]; double b; int c[0]; double d; };
argument passing in C (etc.) - in C++ struct T will have size 1 and therefore
will be passed differently between C (which pedantically disallows empty
structures or zero length arrays) and C++.

Re: [PATCH] ipa-cp: Do not create clones for values outside known value range (PR 102513)

2022-03-31 Thread Jan Hubicka via Gcc-patches
> Hi,
> 
> PR 102513 shows we emit bogus array access warnings when IPA-CP
> creates clones specialized for values which it deduces from arithmetic
> jump functions describing self-recursive calls.  Those can however be
> avoided if we consult the IPA-VR information that the same pass also
> has.
> 
> The patch below does that at the stage when normally values are only
> examined for profitability.  It would be better not to create lattices
> describing such bogus values in the first place, however that presents
> an ordering problem, the pass currently propagates all information,
> and so both constants and VR, in no particular order when processing
> SCCs, and so this approach seemed much simpler.
> 
> I plan to rearrange the pass so that it clones in multiple passes over
> the call graph (or rather the lattice dependence graph) and it feels
> natural to only do propagation for these kinds of recursion in the
> second or later passes, which would fix the issue more elegantly.
> 
> Bootstrapped and tested on x86_64, OK for trunk (and perhaps also for
> GCC 11)?

Looks OK.  I wonder if we can do that more genrally to avoid inlining in
such cases as well?

Honza
> 
> Thanks,
> 
> Martin
> 
> 
> gcc/ChangeLog:
> 
> 2022-02-14  Martin Jambor  
> 
>   PR ipa/102513
>   * ipa-cp.cc (decide_whether_version_node): Skip scalar values
>   which do not fit the known value_range.
> 
> gcc/testsuite/ChangeLog:
> 
> 2022-02-14  Martin Jambor  
> 
>   PR ipa/102513
>   * gcc.dg/ipa/pr102513.c: New test.
> ---
>  gcc/ipa-cp.cc   | 28 ++--
>  gcc/testsuite/gcc.dg/ipa/pr102513.c | 33 +
>  2 files changed, 59 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/ipa/pr102513.c
> 
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index 453e9c93cc3..ec37632d487 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -6154,8 +6154,32 @@ decide_whether_version_node (struct cgraph_node *node)
>   {
> ipcp_value *val;
> for (val = lat->values; val; val = val->next)
> - ret |= decide_about_value (node, i, -1, val, ,
> -_gen_clones);
> + {
> +   /* If some values generated for self-recursive calls with
> +  arithmetic jump functions fall outside of the known
> +  value_range for the parameter, we can skip them.  VR interface
> +  supports this only for integers now.  */
> +   if (TREE_CODE (val->value) == INTEGER_CST
> +   && !plats->m_value_range.bottom_p ()
> +   && !plats->m_value_range.m_vr.contains_p (val->value))
> + {
> +   /* This can happen also if a constant present in the source
> +  code falls outside of the range of parameter's type, so we
> +  cannot assert.  */
> +   if (dump_file && (dump_flags & TDF_DETAILS))
> + {
> +   fprintf (dump_file, " - skipping%s value ",
> +val->self_recursion_generated_p ()
> +? " self_recursion_generated" : "");
> +   print_ipcp_constant_value (dump_file, val->value);
> +   fprintf (dump_file, " because it is outside known "
> +"value range.\n");
> + }
> +   continue;
> + }
> +   ret |= decide_about_value (node, i, -1, val, ,
> +  _gen_clones);
> + }
>   }
>  
>if (!plats->aggs_bottom)
> diff --git a/gcc/testsuite/gcc.dg/ipa/pr102513.c 
> b/gcc/testsuite/gcc.dg/ipa/pr102513.c
> new file mode 100644
> index 000..9ee5431b730
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/ipa/pr102513.c
> @@ -0,0 +1,33 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -Warray-bounds" } */
> +
> +extern int block2[7][256];
> +
> +static int encode_block(int block2[7][256], unsigned level)
> +{
> +int best_score = 0;
> +
> +for (unsigned x = 0; x < level; x++) {
> +int v = block2[1][x];
> +block2[level][x] = 0;
> +best_score += v * v;
> +}
> +
> +if (level > 0 && best_score > 64) {
> +int score = 0;
> +
> +score += encode_block(block2, level - 1);
> +score += encode_block(block2, level - 1);
> +
> +if (score < best_score) {
> +best_score = score;
> +}
> +}
> +
> +return best_score;
> +}
> +
> +int foo(void)
> +{
> +return encode_block(block2, 5);
> +}
> -- 
> 2.34.1
> 


Re: [PATCH] ipa: Create LOAD references when necessary during inlining (PR 103171)

2022-03-31 Thread Jan Hubicka via Gcc-patches
> Hi,
> 
> in r12-2523-g13586172d0b70c ipa-prop tracking of jump functions during
> inlining got the ability to remove ADDR references when inlining
> discovered that they were not necessary or turn them into LOAD
> references when we know that what was a function call argument passed
> by reference will end up as a load (one or more).
> 
> Unfortunately, the code only creates the LOAD references when
> replacing removed ADDR references and PR 103171 showed that with some
> ordering of inlining, we need to add the LOAD reference before we know
> we can remove the ADDR one - or the reference will be lost, leading to
> link errors or even ICEs.
> 
> Specifically in testcase gcc.dg/lto/pr103171_1.c added in this patch,
> if foo() is inlined to entry(), we need to create the LOAD reference
> so that when later bar() is inlined into foo() and we discover that
> the paameter is unused, we can remove the ADDR reference and still
> keep the varaible around for the load.
> 
> Bootstrapped, LTO bootstrapped and tested on x86_64-linux.  OK for
> trunk?

OK,
Thanks!
Honza
> 
> Thanks,
> 
> Martin
> 
> 
> 
> gcc/ChangeLog:
> 
> 2022-01-28  Martin Jambor  
> 
>   PR ipa/103171
>   * ipa-prop.cc (propagate_controlled_uses): Add a LOAD reference
>   always when an ADDR_EXPR constant is known to reach a load because
>   of inlining, not just when removing an ADDR reference.
> 
> gcc/testsuite/ChangeLog:
> 
> 2022-01-28  Martin Jambor  
> 
>   PR ipa/103171
>   * gcc.dg/ipa/remref-6.c: Adjust dump scan string.
>   * gcc.dg/ipa/remref-7.c: New test.
>   * gcc.dg/lto/pr103171_0.c: New test.
>   * gcc.dg/lto/pr103171_1.c: Likewise.
> ---
>  gcc/ipa-prop.cc   | 30 ---
>  gcc/testsuite/gcc.dg/ipa/remref-6.c   |  2 +-
>  gcc/testsuite/gcc.dg/ipa/remref-7.c   | 33 +
>  gcc/testsuite/gcc.dg/lto/pr103171_0.c | 11 +
>  gcc/testsuite/gcc.dg/lto/pr103171_1.c | 35 +++
>  5 files changed, 96 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/ipa/remref-7.c
>  create mode 100644 gcc/testsuite/gcc.dg/lto/pr103171_0.c
>  create mode 100644 gcc/testsuite/gcc.dg/lto/pr103171_1.c
> 
> diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
> index e55fe2776f2..72aa3e2f60d 100644
> --- a/gcc/ipa-prop.cc
> +++ b/gcc/ipa-prop.cc
> @@ -4181,6 +4181,20 @@ propagate_controlled_uses (struct cgraph_edge *cs)
> int d = ipa_get_controlled_uses (old_root_info, i);
> int c = rdesc->refcount;
> rdesc->refcount = combine_controlled_uses_counters (c, d);
> +   if (rdesc->refcount != IPA_UNDESCRIBED_USE
> +   && ipa_get_param_load_dereferenced (old_root_info, i))
> + {
> +   tree cst = ipa_get_jf_constant (jf);
> +   gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
> +&& (TREE_CODE (TREE_OPERAND (cst, 0))
> +== VAR_DECL));
> +   symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
> +   new_root->create_reference (n, IPA_REF_LOAD, NULL);
> +   if (dump_file)
> + fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
> +  "a load so adding LOAD reference from %s to %s.\n",
> +  new_root->dump_name (), n->dump_name ());
> + }
> if (rdesc->refcount == 0)
>   {
> tree cst = ipa_get_jf_constant (jf);
> @@ -4193,20 +4207,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
> symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
> if (n)
>   {
> -   struct cgraph_node *clone;
> -   bool removed = remove_described_reference (n, rdesc);
> -   /* The reference might have been removed by IPA-CP.  */
> -   if (removed
> -   && ipa_get_param_load_dereferenced (old_root_info, i))
> - {
> -   new_root->create_reference (n, IPA_REF_LOAD, NULL);
> -   if (dump_file)
> - fprintf (dump_file, "ipa-prop: ...replaced it with "
> -  "LOAD one from %s to %s.\n",
> -  new_root->dump_name (), n->dump_name ());
> - }
> -
> -   clone = cs->caller;
> +   remove_described_reference (n, rdesc);
> +   cgraph_node *clone = cs->caller;
> while (clone->inlined_to
>&& clone->ipcp_clone
>&& clone != rdesc->cs->caller)
> diff --git a/gcc/testsuite/gcc.dg/ipa/remref-6.c 
> b/gcc/testsuite/gcc.dg/ipa/remref-6.c
> index 7deae3114a4..f31f4c14319 100644
> --- a/gcc/testsuite/gcc.dg/ipa/remref-6.c
> +++ b/gcc/testsuite/gcc.dg/ipa/remref-6.c
> @@ -20,5 +20,5 @@ void entry()
>  }
>  
>  /* { dg-final { scan-ipa-dump "Removed a reference"  "inline" } }  */
> -/* { 

[Bug target/102024] [12 Regression] zero width bitfields and ABIs

2022-03-31 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102024

--- Comment #31 from Segher Boessenkool  ---
Well, what do other compilers do?  It's not such a good idea to break ABI
compatibility with the 1990's compilers ;-)

Re: [PATCH] ipa: Careful processing ANCESTOR jump functions and NULL pointers (PR 103083)

2022-03-31 Thread Jan Hubicka via Gcc-patches
> IPA_JF_ANCESTOR jump functions are constructed also when the formal
> parameter of the caller is first checked whether it is NULL and left
> as it is if it is NULL, to accommodate C++ casts to an ancestor class.
> 
> The jump function type was invented for devirtualization and IPA-CP
> propagation of tree constants is also careful to apply it only to
> existing DECLs(*) but as PR 103083 shows, the part propagating "known
> bits" was not careful about this, which can lead to miscompilations.
> 
> This patch introduces a flag to the ancestor jump functions which
> tells whether a NULL-check was elided when creating it and makes the
> bits propagation behave accordingly, masking any bits otherwise would
> be known to be one.  This should safely preserve alignment info, which
> is the primary ifnormation that we keep in bits for pointers.
> 
> (*) There still may remain problems when a DECL resides on address
> zero (with -fno-delete-null-pointer-checks ...I hope it cannot happen
> otherwise).  I am looking into that now but I think it will be easier
> for everyone if I do so in a follow-up patch.
> 
> gcc/ChangeLog:
> 
> 2022-02-11  Martin Jambor  
> 
>   PR ipa/103083
>   * ipa-prop.h (ipa_ancestor_jf_data): New flag keep_null;
>   (ipa_get_jf_ancestor_keep_null): New function.
>   * ipa-prop.c (ipa_set_ancestor_jf): Initialize keep_null field of the
>   ancestor function.
>   (compute_complex_assign_jump_func): Pass false to keep_null
>   parameter of ipa_set_ancestor_jf.
>   (compute_complex_ancestor_jump_func): Pass true to keep_null
>   parameter of ipa_set_ancestor_jf.
>   (update_jump_functions_after_inlining): Carry over keep_null from the
>   original ancestor jump-function or merge them.
>   (ipa_write_jump_function): Stream keep_null flag.
>   (ipa_read_jump_function): Likewise.
>   (ipa_print_node_jump_functions_for_edge): Print the new flag.
>   * ipa-cp.c (class ipcp_bits_lattice): Make various getters const.  New
>   member function known_nonzero_p.
>   (ipcp_bits_lattice::known_nonzero_p): New.
>   (ipcp_bits_lattice::meet_with_1): New parameter drop_all_ones,
>   observe it.
>   (ipcp_bits_lattice::meet_with): Likewise.
>   (propagate_bits_across_jump_function): Simplify.  Pass true in
>   drop_all_ones when it is necessary.
>   (propagate_aggs_across_jump_function): Take care of keep_null
>   flag.
>   (ipa_get_jf_ancestor_result): Propagate NULL accross keep_null
>   jump functions.
> 
> gcc/testsuite/ChangeLog:
> 
> 2021-11-25  Martin Jambor  
> 
>   * gcc.dg/ipa/pr103083-1.c: New test.
>   * gcc.dg/ipa/pr103083-2.c: Likewise.

OK,
thanks!
Honza


[Bug other/105114] [12 regression] contrib/gcc_update hangs

2022-03-31 Thread seurer at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105114

--- Comment #3 from seurer at gcc dot gnu.org ---
I did look at the Makefile and didn't see anything that jumped out as weird.  I
will try comparing it to one that works.


Those files all exist.

-rwxr-xr-x 1 seurer users 2954 Mar 30 10:16
gcc/config/loongarch/genopts/genstr.sh
-rw-r--r-- 1 seurer users 5231 Mar 30 10:16
gcc/config/loongarch/genopts/loongarch.opt.in
-rw-r--r-- 1 seurer users 1756 Mar 30 15:14
gcc/config/loongarch/loongarch-str.h
-rw-r--r-- 1 seurer users 5011 Mar 30 10:16 gcc/config/loongarch/loongarch.opt

[Bug gcov-profile/105063] [GCOV] Ability to map .gcda paths

2022-03-31 Thread marxin at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105063

--- Comment #13 from Martin Liška  ---
Created attachment 52724
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52724=edit
Tentative patch

Can you please experiment with the following patch?

Re: try multi dest registers in default_zero_call_used_regs

2022-03-31 Thread Richard Sandiford via Gcc-patches
Alexandre Oliva via Gcc-patches  writes:
> When the mode of regno_reg_rtx is not hard_regno_mode_ok for the
> target, try grouping the register with subsequent ones.  This enables
> s16 to s31 and their hidden pairs to be zeroed with the default logic
> on some arm variants.
>
> Regstrapped on x86_64-linux-gnu, also tested on an affected arm
> configuration.  Ok to install?
>
>
> for  gcc/ChangeLog
>
>   * targhooks.c (default_zero_call_used_regs): Attempt to group
>   regs that the target refuses to use in their natural modes.

Thanks for doing this.  Some comments below…

> ---
>  gcc/targhooks.cc |   79 
> --
>  1 file changed, 70 insertions(+), 9 deletions(-)
>
> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> index fc49235eb38ee..bdaab9c63c7ee 100644
> --- a/gcc/targhooks.cc
> +++ b/gcc/targhooks.cc
> @@ -1035,16 +1035,45 @@ default_zero_call_used_regs (HARD_REG_SET 
> need_zeroed_hardregs)
>  if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
>{
>   rtx_insn *last_insn = get_last_insn ();
> - machine_mode mode = GET_MODE (regno_reg_rtx[regno]);
> + rtx regno_rtx = regno_reg_rtx[regno];
> + machine_mode mode = GET_MODE (regno_rtx);
> +
> + /* If the natural mode doesn't work, try some wider mode.  */
> + if (!targetm.hard_regno_mode_ok (regno, mode))
> +   {
> + for (int nregs = 2;
> +  regno + nregs <= FIRST_PSEUDO_REGISTER
> +&& TEST_HARD_REG_BIT (need_zeroed_hardregs,
> +  regno + nregs - 1);
> +  nregs++)
> +   {
> + mode = choose_hard_reg_mode (regno, nregs, 0);

I like the idea, but it would be good to avoid the large:

  FIRST_PSEUDO_REGISTER * FIRST_PSEUDO_REGISTER * NUM_MACHINE_MODES

constant factor.  How about if init_reg_modes_target recorded the
maximum value of x_hard_regno_nregs?

> + if (mode == E_VOIDmode)
> +   continue;
> + gcc_checking_assert (targetm.hard_regno_mode_ok (regno, mode));
> + regno_rtx = gen_rtx_REG (mode, regno);
> + break;
> +   }
> + if (mode != GET_MODE (regno_rtx)
> + || regno_rtx == regno_reg_rtx[regno])
> +   {
> + SET_HARD_REG_BIT (failed, regno);
> + continue;
> +   }
> +   }
> +
>   rtx zero = CONST0_RTX (mode);
> - rtx_insn *insn = emit_move_insn (regno_reg_rtx[regno], zero);
> + rtx_insn *insn = emit_move_insn (regno_rtx, zero);
>   if (!valid_insn_p (insn))
> {
>   SET_HARD_REG_BIT (failed, regno);
>   delete_insns_since (last_insn);
> }
>   else
> -   progress = true;
> +   {
> + progress = true;
> + regno += hard_regno_nregs (regno, mode) - 1;
> +   }
>}
>  
>/* Now retry with copies from zeroed registers, as long as we've
> @@ -1060,7 +1089,34 @@ default_zero_call_used_regs (HARD_REG_SET 
> need_zeroed_hardregs)
>for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
>   if (TEST_HARD_REG_BIT (retrying, regno))
> {
> - machine_mode mode = GET_MODE (regno_reg_rtx[regno]);
> + rtx regno_rtx = regno_reg_rtx[regno];
> + machine_mode mode = GET_MODE (regno_rtx);
> +
> + /* If the natural mode doesn't work, try some wider mode.  */
> + if (!targetm.hard_regno_mode_ok (regno, mode))
> +   {
> + for (int nregs = 2;
> +  regno + nregs <= FIRST_PSEUDO_REGISTER
> +&& TEST_HARD_REG_BIT (need_zeroed_hardregs,
> +  regno + nregs - 1);
> +  nregs++)
> +   {
> + mode = choose_hard_reg_mode (regno, nregs, 0);
> + if (mode == E_VOIDmode)
> +   continue;
> + gcc_checking_assert (targetm.hard_regno_mode_ok (regno,
> +  mode));
> + regno_rtx = gen_rtx_REG (mode, regno);
> + break;
> +   }
> + if (mode != GET_MODE (regno_rtx)
> + || regno_rtx == regno_reg_rtx[regno])
> +   {
> + SET_HARD_REG_BIT (failed, regno);
> + continue;
> +   }
> +   }
> + 

This seems big enough to be worth splitting out into a helper, rather
than repeating.  That should also simplify the failure detection:
the helper can return nonnull on success and null on failure.

>   bool success = false;
>   /* Look for a source.  */
>   for (unsigned int src = 0; src < FIRST_PSEUDO_REGISTER; src++)
> @@ -1086,8 +1142,10 @@ default_zero_call_used_regs (HARD_REG_SET 
> need_zeroed_hardregs)
>  
>   /* SRC is usable, try to copy from it.  */
>   rtx_insn *last_insn = 

[Bug gcov-profile/105063] [GCOV] Ability to map .gcda paths

2022-03-31 Thread vit9696 at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105063

--- Comment #12 from vit9696  ---
It is an in-house airborne RTOS we develop in ISP RAS. There is a legacy paper
in English telling a bit more about the project
(https://www.ispras.ru/proceedings/docs/2016/28/2/isp_28_2016_2_181.pdf).

[RFC/gcov 10/12] gcov: Fix integer types in ftw_read_file()

2022-03-31 Thread Sebastian Huber
libgcc/

* libgcov-util.c (ftw_read_file): Use size_t for strlen() variables.
---
 libgcc/libgcov-util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 03902ed10b1..622d5a9dc71 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -384,8 +384,8 @@ ftw_read_file (const char *filename,
const struct stat *status ATTRIBUTE_UNUSED,
int type)
 {
-  int filename_len;
-  int suffix_len;
+  size_t filename_len;
+  size_t suffix_len;
 
   /* Only read regular files.  */
   if (type != FTW_F)
-- 
2.34.1



[RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-tool.cc (gcov_profile_merge_stream): Declare.
(print_merge_stream_usage_message): New.
(merge_stream_usage): Likewise.
(do_merge_stream): Likewise.
(print_usage): Call print_merge_stream_usage_message().
(main): Call do_merge_stream() to execute merge-stream subcommand.

libgcc/

* libgcov-util.c (consume_stream): New.
(get_target_profiles_for_merge): Likewise.
(gcov_profile_merge_stream): Likewise.
---
 gcc/gcov-tool.cc  | 76 
 libgcc/libgcov-util.c | 80 +++
 2 files changed, 156 insertions(+)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index d712715cf7e..d8572b184e9 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
 extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
 struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge_stream (const char *, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -229,6 +230,78 @@ do_merge (int argc, char **argv)
   return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
 }
 
+/* Usage message for profile merge-stream.  */
+
+static void
+print_merge_stream_usage_message (int error_p)
+{
+  FILE *file = error_p ? stderr : stdout;
+
+  fnotice (file, "  merge-stream [options] [stream-file]  Merge coverage 
stream file (or stdin)\n"
+"and coverage file 
contents\n");
+  fnotice (file, "-v, --verbose   Verbose mode\n");
+  fnotice (file, "-w, --weight Set weights (float 
point values)\n");
+}
+
+static const struct option merge_stream_options[] =
+{
+  { "verbose",no_argument,   NULL, 'v' },
+  { "weight", required_argument, NULL, 'w' },
+  { 0, 0, 0, 0 }
+};
+
+/* Print merge-stream usage and exit.  */
+
+static void ATTRIBUTE_NORETURN
+merge_stream_usage (void)
+{
+  fnotice (stderr, "Merge-stream subcomand usage:");
+  print_merge_stream_usage_message (true);
+  exit (FATAL_EXIT_CODE);
+}
+
+/* Driver for profile merge-stream sub-command.  */
+
+static int
+do_merge_stream (int argc, char **argv)
+{
+  int opt;
+  int w1 = 1, w2 = 1;
+  struct gcov_info *merged_profile;
+
+  optind = 0;
+  while ((opt = getopt_long (argc, argv, "vw:",
+merge_stream_options, NULL)) != -1)
+{
+  switch (opt)
+   {
+   case 'v':
+ verbose = true;
+ gcov_set_verbose ();
+ break;
+   case 'w':
+ sscanf (optarg, "%d,%d", , );
+ if (w1 < 0 || w2 < 0)
+   fatal_error (input_location, "weights need to be non-negative");
+ break;
+   default:
+ merge_stream_usage ();
+   }
+}
+
+  if (argc - optind > 1)
+merge_stream_usage ();
+
+  merged_profile = gcov_profile_merge_stream (argv[optind], w1, w2);
+
+  if (merged_profile)
+gcov_do_dump (merged_profile, 0, -1);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
+
+  return 0;
+}
+
 /* If N_VAL is no-zero, normalize the profile by setting the largest counter
counter value to N_VAL and scale others counters proportionally.
Otherwise, multiply the all counters by SCALE.  */
@@ -505,6 +578,7 @@ print_usage (int error_p)
   fnotice (file, "  -h, --helpPrint this help, 
then exit\n");
   fnotice (file, "  -v, --version Print version 
number, then exit\n");
   print_merge_usage_message (error_p);
+  print_merge_stream_usage_message (error_p);
   print_rewrite_usage_message (error_p);
   print_overlap_usage_message (error_p);
   fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
@@ -594,6 +668,8 @@ main (int argc, char **argv)
 
   if (!strcmp (sub_command, "merge"))
 return do_merge (argc - optind, argv + optind);
+  else if (!strcmp (sub_command, "merge-stream"))
+return do_merge_stream (argc - optind, argv + optind);
   else if (!strcmp (sub_command, "rewrite"))
 return do_rewrite (argc - optind, argv + optind);
   else if (!strcmp (sub_command, "overlap"))
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 622d5a9dc71..0fe60528b48 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -735,6 +735,86 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   return tgt_profile;
 }
 
+struct gcov_info *
+consume_stream (const char *filename)
+{
+  read_profile_dir_init ();
+
+  while (true)
+{
+  unsigned version;
+  const char *filename_of_info;
+  struct gcov_info *obj_info;
+
+ 

[RFC/gcov 11/12] gcov: Record EOF error during read

2022-03-31 Thread Sebastian Huber
Use an enum for file error codes.

gcc/

* gcov-io.cc (gcov_file_error): New enum.
(gcov_var): Use gcov_file_error enum for the error member.
(gcov_open): Use GCOV_FILE_NO_ERROR.
(gcov_close): Use GCOV_FILE_WRITE_ERROR.
(gcov_write): Likewise.
(gcov_write_unsigned): Likewise.
(gcov_write_string): Likewise.
(gcov_read_bytes): Set error code if EOF is reached.
(gcov_read_counter): Use GCOV_FILE_COUNTER_OVERFLOW.
---
 gcc/gcov-io.cc | 27 +++
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 177f81166a6..60c762bf3a3 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -29,10 +29,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
 static gcov_unsigned_t *gcov_read_words (void *buffer, unsigned);
 
+enum gcov_file_error {
+  GCOV_FILE_COUNTER_OVERFLOW = -1,
+  GCOV_FILE_NO_ERROR = 0,
+  GCOV_FILE_WRITE_ERROR = 1,
+  GCOV_FILE_EOF = 2
+};
+
 struct gcov_var
 {
   FILE *file;
-  int error;   /* < 0 overflow, > 0 disk error.  */
+  enum gcov_file_error error;
   int mode;/* < 0 writing, > 0 reading.  */
   int endian;  /* Swap endianness.  */
 #ifdef IN_GCOV_TOOL
@@ -113,7 +120,7 @@ gcov_open (const char *name, int mode)
 #endif
 
   gcov_nonruntime_assert (!gcov_var.file);
-  gcov_var.error = 0;
+  gcov_var.error = GCOV_FILE_NO_ERROR;
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
@@ -217,7 +224,7 @@ gcov_close (void)
   if (gcov_var.file)
 {
   if (fclose (gcov_var.file))
-   gcov_var.error = 1;
+   gcov_var.error = GCOV_FILE_WRITE_ERROR;
 
   gcov_var.file = 0;
 }
@@ -253,7 +260,7 @@ gcov_write (const void *data, unsigned length)
 {
   gcov_unsigned_t r = fwrite (data, length, 1, gcov_var.file);
   if (r != 1)
-gcov_var.error = 1;
+gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 /* Write unsigned VALUE to coverage file.  */
@@ -263,7 +270,7 @@ gcov_write_unsigned (gcov_unsigned_t value)
 {
   gcov_unsigned_t r = fwrite (, sizeof (value), 1, gcov_var.file);
   if (r != 1)
-gcov_var.error = 1;
+gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 #if !IN_LIBGCOV
@@ -283,7 +290,7 @@ gcov_write_string (const char *string)
 {
   gcov_unsigned_t r = fwrite (string, length, 1, gcov_var.file);
   if (r != 1)
-   gcov_var.error = 1;
+   gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 }
 #endif
@@ -385,7 +392,11 @@ gcov_read_bytes (void *buffer, unsigned count)
 
   unsigned read = fread (buffer, count, 1, gcov_var.file);
   if (read != 1)
-return NULL;
+{
+  if (feof (gcov_var.file))
+   gcov_var.error = GCOV_FILE_EOF;
+  return NULL;
+}
 
 #ifdef IN_GCOV_TOOL
   gcov_var.pos += count;
@@ -434,7 +445,7 @@ gcov_read_counter (void)
   if (sizeof (value) > sizeof (gcov_unsigned_t))
 value |= ((gcov_type) from_file (buffer[1])) << 32;
   else if (buffer[1])
-gcov_var.error = -1;
+gcov_var.error = GCOV_FILE_COUNTER_OVERFLOW;
 
   return value;
 }
-- 
2.34.1



[RFC/gcov 05/12] gcov: Add __gcov_filename_to_gcfn()

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-io.h (GCOV_FILENAME_MAGIC): Define and document.

libgcc/

* gcov.h (__gcov_info_to_gcda): Mention __gcov_filename_to_gcfn().
(__gcov_filename_to_gcfn): Declare and document.
* libgcov-driver.c (dump_string): New.
(__gcov_filename_to_gcfn): Likewise.
---
 gcc/gcov-io.h   | 24 
 libgcc/gcov.h   | 17 -
 libgcc/libgcov-driver.c | 30 ++
 3 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 204ae0ccf7f..30947634d73 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -60,14 +60,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
file : int32:magic int32:version int32:stamp record*
 
-   The magic ident is different for the notes and the data files.  The
-   magic ident is used to determine the endianness of the file, when
-   reading.  The version is the same for both files and is derived
-   from gcc's version number. The stamp value is used to synchronize
-   note and data files and to synchronize merging within a data
-   file. It need not be an absolute time stamp, merely a ticker that
-   increments fast enough and cycles slow enough to distinguish
-   different compile/run/compile cycles.
+   A filename header may be used to provide a filename for the data in
+   a stream of data to support gcov in freestanding environments.  This
+   header is used by the merge-stream subcommand of the gcov-tool.  The
+   format of the filename header is
+
+   filename-header : int32:magic int32:version string
+
+   The magic ident is different for the notes and the data files as
+   well as the filename header.  The magic ident is used to determine
+   the endianness of the file, when reading.  The version is the same
+   for both files and is derived from gcc's version number. The stamp
+   value is used to synchronize note and data files and to synchronize
+   merging within a data file. It need not be an absolute time stamp,
+   merely a ticker that increments fast enough and cycles slow enough
+   to distinguish different compile/run/compile cycles.
 
Although the ident and version are formally 32 bit numbers, they
are derived from 4 character ASCII strings.  The version number
@@ -228,6 +235,7 @@ typedef uint64_t gcov_type_unsigned;
 /* File magic. Must not be palindromes.  */
 #define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */
 #define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f) /* "gcno" */
+#define GCOV_FILENAME_MAGIC ((gcov_unsigned_t)0x6763666e) /* "gcfn" */
 
 #include "version.h"
 
diff --git a/libgcc/gcov.h b/libgcc/gcov.h
index cea93023920..cdd4206f625 100644
--- a/libgcc/gcov.h
+++ b/libgcc/gcov.h
@@ -43,7 +43,8 @@ extern void __gcov_dump (void);
stream.  The ALLOCATE_FN callback shall allocate memory with a size in
characters specified by the first callback parameter.  The ARG parameter is
a user-provided argument passed as the last argument to the callback
-   functions.  */
+   functions.  It is recommended to use the __gcov_filename_to_gcfn()
+   in the filename callback function.  */
 
 extern void
 __gcov_info_to_gcda (const struct gcov_info *__info,
@@ -52,4 +53,18 @@ __gcov_info_to_gcda (const struct gcov_info *__info,
 void *(*__allocate_fn) (unsigned, void *),
 void *__arg);
 
+/* Convert the FILENAME to a gcfn data stream.  The DUMP_FN callback is
+   subsequently called with chunks (the begin and length of the chunk are
+   passed as the first two callback parameters) of the gcfn data stream.
+   The ARG parameter is a user-provided argument passed as the last
+   argument to the DUMP_FN callback function.  This function is intended
+   to be used by the filename callback of __gcov_info_to_gcda().  The gcfn
+   data stream is used by the merge-stream subcommand of the gcov-tool to
+   get the filename associated with a gcda data stream.  */
+
+extern void
+__gcov_filename_to_gcfn (const char *__filename,
+void (*__dump_fn) (const void *, unsigned, void *),
+void *__arg);
+
 #endif /* GCC_GCOV_H */
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 10831e84b61..a44054a3cb3 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -410,6 +410,23 @@ dump_counter (gcov_type counter,
 dump_unsigned (0, dump_fn, arg);
 }
 
+/* Dump the STRING using the DUMP handler called with ARG.  */
+
+static inline void
+dump_string (const char *string,
+void (*dump_fn) (const void *, unsigned, void *),
+void *arg)
+{
+  unsigned length = 0;
+
+  if (string)
+length = strlen (string) + 1;
+
+  dump_unsigned (length, dump_fn, arg);
+  if (string)
+(*dump_fn) (string, length, arg);
+}
+
 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
 
 /* Store all TOP N counters where each has a dynamic length.  */
@@ -780,4 

[RFC/gcov 09/12] gcov: Move gcov_open() to caller of read_gcda_file()

2022-03-31 Thread Sebastian Huber
This allows to reuse read_gcda_file() to read multiple objects from a single
file.

libgcc/

* libgcov-util.c (read_gcda_file): Do not open file.
(ftw_read_file): Open file here.
---
 libgcc/libgcov-util.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index d628c71479e..03902ed10b1 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,17 +268,10 @@ read_gcda_file (const char *filename)
 k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename, 1))
-{
-  fnotice (stderr, "%s:cannot open\n", filename);
-  return NULL;
-}
-
   /* Read magic.  */
   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
 {
   fnotice (stderr, "%s:not a gcov data file\n", filename);
-  gcov_close ();
   return NULL;
 }
 
@@ -287,7 +280,6 @@ read_gcda_file (const char *filename)
   if (version != GCOV_VERSION)
 {
   fnotice (stderr, "%s:incorrect gcov version %d vs %d \n", filename, 
version, GCOV_VERSION);
-  gcov_close ();
   return NULL;
 }
 
@@ -379,7 +371,6 @@ read_gcda_file (const char *filename)
 }
 
   read_gcda_finalize (obj_info);
-  gcov_close ();
 
   return obj_info;
 }
@@ -412,7 +403,14 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
+  if (!gcov_open (filename, 1))
+{
+  fnotice (stderr, "%s:cannot open\n", filename);
+  return 0;
+}
+
   (void)read_gcda_file (xstrdup (filename));
+  gcov_close ();
 
   return 0;
 }
-- 
2.34.1



[RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file()

2022-03-31 Thread Sebastian Huber
This helps to reuse read_gcda_file().

libgcc/

* libgcov-util.c (read_gcda_file): Prepend new info object to global
list.
(ftw_read_file): Remove list append here.
---
 libgcc/libgcov-util.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ae5712c0138..d628c71479e 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -301,6 +301,9 @@ read_gcda_file (const char *filename)
   num_fn_info = 0;
   curr_fn_info = 0;
 
+  /* Prepend to gcov info list */
+  obj_info->next = gcov_info_head;
+  gcov_info_head = obj_info;
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -392,7 +395,6 @@ ftw_read_file (const char *filename,
 {
   int filename_len;
   int suffix_len;
-  struct gcov_info *obj_info;
 
   /* Only read regular files.  */
   if (type != FTW_F)
@@ -410,12 +412,7 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (xstrdup (filename));
-  if (!obj_info)
-return 0;
-
-  obj_info->next = gcov_info_head;
-  gcov_info_head = obj_info;
+  (void)read_gcda_file (xstrdup (filename));
 
   return 0;
 }
-- 
2.34.1



[RFC/gcov 07/12] gcov: Use xstrdup()

2022-03-31 Thread Sebastian Huber
Move duplication of filename to caller and use xstrdup() instead of custom
code.  This helps to reuse read_gcda_file() for other purposes.

libgcc/

* libgcov-util.c (read_gcda_file): Do not duplicate filename.
(ftw_read_file): Duplicate filename for read_gcda_file().
---
 libgcc/libgcov-util.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index db157220c9d..ae5712c0138 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -296,16 +296,11 @@ read_gcda_file (const char *filename)
  sizeof (struct gcov_ctr_info) * GCOV_COUNTERS, 1);
 
   obj_info->version = version;
+  obj_info->filename = filename;
   obstack_init (_info);
   num_fn_info = 0;
   curr_fn_info = 0;
-  {
-size_t len = strlen (filename) + 1;
-char *str_dup = (char*) xmalloc (len);
 
-memcpy (str_dup, filename, len);
-obj_info->filename = str_dup;
-  }
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -415,7 +410,7 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (filename);
+  obj_info = read_gcda_file (xstrdup (filename));
   if (!obj_info)
 return 0;
 
-- 
2.34.1



[RFC/gcov 04/12] gcov: Make gcov_seek() static

2022-03-31 Thread Sebastian Huber
This function is only used by gcov_write_length() in the gcov-io.cc file.

gcc/

* gcov-io.cc (gcov_seek): Make it static.
* gcov-io.h (struct gcov_summary): Do not mention gcov_seek().

libgcc/

* libgcov.h (gcov_seek): Remove define and declaration.
---
 gcc/gcov-io.cc   | 4 +---
 gcc/gcov-io.h| 6 +++---
 libgcc/libgcov.h | 2 --
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 017a6e32a5d..fee3130f94a 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -294,17 +294,15 @@ gcov_write_filename (const char *filename)
 
   gcov_write_string (filename);
 }
-#endif
 
 /* Move to a given position in a gcov file.  */
 
-GCOV_LINKAGE void
+static void
 gcov_seek (gcov_position_t base)
 {
   fseek (gcov_var.file, base, SEEK_SET);
 }
 
-#if !IN_LIBGCOV
 /* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length.  */
 
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index afe74b002f1..204ae0ccf7f 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -340,9 +340,9 @@ struct gcov_summary
 /* Functions for reading and writing gcov files. In libgcov you can
open the file for reading then writing. Elsewhere you can open the
file either for reading or for writing. When reading a file you may
-   use the gcov_read_* functions, gcov_sync, gcov_position, &
-   gcov_error. When writing a file you may use the gcov_write
-   functions, gcov_seek & gcov_error. When a file is to be rewritten
+   use the gcov_read_* functions, gcov_sync, gcov_position, and
+   gcov_error. When writing a file you may use the gcov_write*
+   functions and gcov_error. When a file is to be rewritten
you use the functions for reading, then gcov_rewrite then the
functions for writing.  Your file may become corrupted if you break
these invariants.  */
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index f190547e819..487bd1464cd 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -115,7 +115,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode 
(QI)));
 #define gcov_open __gcov_open
 #define gcov_close __gcov_close
 #define gcov_position __gcov_position
-#define gcov_seek __gcov_seek
 #define gcov_rewrite __gcov_rewrite
 #define gcov_is_error __gcov_is_error
 #define gcov_write_unsigned __gcov_write_unsigned
@@ -346,7 +345,6 @@ extern int __gcov_execve (const char *, char  *const [], 
char *const [])
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
   const struct gcov_summary *)
 ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_rewrite (void) ATTRIBUTE_HIDDEN;
 
 /* "Counts" stored in gcda files can be a real counter value, or
-- 
2.34.1



[RFC/gcov 06/12] gcov-tool: Support file input from stdin

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-io.cc (GCOV_MODE_STDIN): Define.
(gcov_position): For gcov-tool, return calculated position if file is
stdin.
(gcov_open):  For gcov-tool, use stdin if filename is NULL.
(gcov_close): For gcov-tool, do not close stdin.
(gcov_read_bytes): For gcov-tool, update position if file is stdin.
(gcov_sync): For gcov-tool, discard input if file is stdin.
---
 gcc/gcov-io.cc | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index fee3130f94a..177f81166a6 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -35,8 +35,13 @@ struct gcov_var
   int error;   /* < 0 overflow, > 0 disk error.  */
   int mode;/* < 0 writing, > 0 reading.  */
   int endian;  /* Swap endianness.  */
+#ifdef IN_GCOV_TOOL
+  gcov_position_t pos; /* File position for stdin support. */
+#endif
 } gcov_var;
 
+#define GCOV_MODE_STDIN 2
+
 /* Save the current position in the gcov file.  */
 /* We need to expose this function when compiling for gcov-tool.  */
 #ifndef IN_GCOV_TOOL
@@ -45,6 +50,10 @@ static inline
 gcov_position_t
 gcov_position (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+return gcov_var.pos;
+#endif
   return ftell (gcov_var.file);
 }
 
@@ -108,6 +117,16 @@ gcov_open (const char *name, int mode)
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos = 0;
+  if (!name)
+{
+  gcov_nonruntime_assert (gcov_var.mode > 0);
+  gcov_var.file = stdin;
+  gcov_var.mode = GCOV_MODE_STDIN;
+  return 1;
+}
+#endif
 #if GCOV_LOCKED
   if (mode > 0)
 {
@@ -190,6 +209,11 @@ gcov_open (const char *name, int mode)
 GCOV_LINKAGE int
 gcov_close (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.file == stdin)
+gcov_var.file = 0;
+  else
+#endif
   if (gcov_var.file)
 {
   if (fclose (gcov_var.file))
@@ -363,6 +387,9 @@ gcov_read_bytes (void *buffer, unsigned count)
   if (read != 1)
 return NULL;
 
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos += count;
+#endif
   return buffer;
 }
 
@@ -499,6 +526,17 @@ gcov_sync (gcov_position_t base, gcov_unsigned_t length)
 {
   gcov_nonruntime_assert (gcov_var.mode > 0);
   base += length;
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+{
+  while (gcov_var.pos < base)
+   {
+ ++gcov_var.pos;
+ (void)fgetc(gcov_var.file);
+   }
+  return;
+}
+#endif
   fseek (gcov_var.file, base, SEEK_SET);
 }
 #endif
-- 
2.34.1



[RFC/gcov 03/12] gcov: Add open mode parameter to gcov_do_dump()

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-tool.cc (gcov_do_dump): Add mode parameter.
(gcov_output_files): Open files for reading and writing.

libgcc/

* libgcov-driver-system.c (gcov_exit_open_gcda_file): Add mode
parameter.  Pass mode to gcov_open() calls.
* libgcov-driver.c (dump_one_gcov):  Add mode parameter.  Pass mode to
gcov_exit_open_gcda_file() call.
(gcov_do_dump): Add mode parameter.  Pass mode to dump_one_gcov()
calls.
(__gcov_dump_one):  Open file for reading and writing.
---
 gcc/gcov-tool.cc   |  4 ++--
 libgcc/libgcov-driver-system.c |  7 ---
 libgcc/libgcov-driver.c| 12 ++--
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index 2e4083a664d..d712715cf7e 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -46,7 +46,7 @@ extern int gcov_profile_overlap (struct gcov_info*, struct 
gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
 extern struct gcov_info* gcov_read_profile_dir (const char*, int);
-extern void gcov_do_dump (struct gcov_info *, int);
+extern void gcov_do_dump (struct gcov_info *, int, int);
 extern const char *gcov_get_filename (struct gcov_info *list);
 extern void gcov_set_verbose (void);
 
@@ -124,7 +124,7 @@ gcov_output_files (const char *out, struct gcov_info 
*profile)
 fatal_error (input_location, "output file %s already exists in folder %s",
 filename, out);
 
-  gcov_do_dump (profile, 0);
+  gcov_do_dump (profile, 0, 0);
 
   ret = chdir (pwd);
   if (ret)
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 9abb2fe7f74..ac405c38e3a 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -261,7 +261,8 @@ allocate_filename_struct (struct gcov_filename *gf)
 
 static int
 gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
- struct gcov_filename *gf)
+ struct gcov_filename *gf,
+ int mode)
 {
   int append_slash = 0;
   const char *fname = gi_ptr->filename;
@@ -309,7 +310,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
 {
   /* Open failed likely due to missed directory.
  Create directory and retry to open file. */
@@ -318,7 +319,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
   fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
   return -1;
 }
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
 {
   fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
   return -1;
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 7e52c5676e5..10831e84b61 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -595,14 +595,14 @@ write_one_data (const struct gcov_info *gi_ptr,
 static void
 dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
   unsigned run_counted ATTRIBUTE_UNUSED,
-  gcov_type run_max ATTRIBUTE_UNUSED)
+  gcov_type run_max ATTRIBUTE_UNUSED, int mode)
 {
   struct gcov_summary summary = {};
   int error;
   gcov_unsigned_t tag;
   fn_buffer = 0;
 
-  error = gcov_exit_open_gcda_file (gi_ptr, gf);
+  error = gcov_exit_open_gcda_file (gi_ptr, gf, mode);
   if (error == -1)
 return;
 
@@ -649,13 +649,13 @@ read_fatal:;
 
 /* Dump all the coverage counts for the program. It first computes program
summary and then traverses gcov_list list and dumps the gcov_info
-   objects one by one.  */
+   objects one by one.  Use MODE to open files.  */
 
 #if !IN_GCOV_TOOL
 static
 #endif
 void
-gcov_do_dump (struct gcov_info *list, int run_counted)
+gcov_do_dump (struct gcov_info *list, int run_counted, int mode)
 {
   struct gcov_info *gi_ptr;
   struct gcov_filename gf;
@@ -678,7 +678,7 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
   /* Now merge each file.  */
   for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
 {
-  dump_one_gcov (gi_ptr, , run_counted, run_max);
+  dump_one_gcov (gi_ptr, , run_counted, run_max, mode);
   free (gf.filename);
 }
 
@@ -701,7 +701,7 @@ __gcov_dump_one (struct gcov_root *root)
   if (root->dumped)
 return;
 
-  gcov_do_dump (root->list, root->run_counted);
+  gcov_do_dump (root->list, root->run_counted, 0);
   
   root->dumped = 1;
   root->run_counted = 1;
-- 
2.34.1



[RFC/gcov 02/12] gcov: Add mode to all gcov_open()

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-io.cc (gcov_open): Always use the mode parameter.
* gcov-io.h (gcov_open): Declare it unconditionally.

libgcc/

* libgcov-driver-system.c (gcov_exit_open_gcda_file): Open file for
reading and writing.
* libgcov-util.c (read_gcda_file): Open file for reading.
* libgcov.h (gcov_open): Delete declaration.
---
 gcc/gcov-io.cc | 7 ---
 gcc/gcov-io.h  | 5 +
 libgcc/libgcov-driver-system.c | 4 ++--
 libgcc/libgcov-util.c  | 2 +-
 libgcc/libgcov.h   | 1 -
 5 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 72c40f8eaa0..017a6e32a5d 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -89,15 +89,8 @@ from_file (gcov_unsigned_t value)
Return zero on failure, non-zero on success.  */
 
 GCOV_LINKAGE int
-#if IN_LIBGCOV
-gcov_open (const char *name)
-#else
 gcov_open (const char *name, int mode)
-#endif
 {
-#if IN_LIBGCOV
-  int mode = 0;
-#endif
 #if GCOV_LOCKED
   struct flock s_flock;
   int fd;
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 99ce7dbccc8..afe74b002f1 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -347,15 +347,12 @@ struct gcov_summary
functions for writing.  Your file may become corrupted if you break
these invariants.  */
 
-#if !IN_LIBGCOV
-GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
-#endif
-
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
 GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
 #endif
 
 /* Available everywhere.  */
+GCOV_LINKAGE int gcov_open (const char *, int) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index eef6e3cbda1..9abb2fe7f74 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -309,7 +309,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
 {
   /* Open failed likely due to missed directory.
  Create directory and retry to open file. */
@@ -318,7 +318,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
   fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
   return -1;
 }
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
 {
   fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
   return -1;
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 100f1b19f1a..db157220c9d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,7 +268,7 @@ read_gcda_file (const char *filename)
 k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename))
+  if (!gcov_open (filename, 1))
 {
   fnotice (stderr, "%s:cannot open\n", filename);
   return NULL;
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 40e845ce3ea..f190547e819 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -343,7 +343,6 @@ extern int __gcov_execve (const char *, char  *const [], 
char *const [])
   ATTRIBUTE_HIDDEN;
 
 /* Functions that only available in libgcov.  */
-GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
   const struct gcov_summary *)
 ATTRIBUTE_HIDDEN;
-- 
2.34.1



  1   2   >