[to-be-committed][RISC-V] Improve (x << C1) + C2 split code

2025-05-21 Thread Jeff Law
I wrote this a couple months ago to fix an instruction count regression 
in 505.mcf on risc-v, but I don't have a trivial little testcase to add 
to the suite.


There were two problems with the pattern.

First, the code was generating a shift followed by an add after reload. 
Naturally combine doesn't run after reload and the code stayed in that 
form rather than using shadd when available.


Second the splitter was just over-active.  We need to make sure that the 
shifted form of the constant operand has a cost > 1 to synthesize.  It's 
useless to split if the shifted constant can be synthesized in a single 
instruction.


This has been in my tester since March.  So it's been through numerous 
riscv64-elf and riscv32-elf test cycles as well as multiple rv64 
bootstrap tests.  Waiting on the upstream CI system to render a verdict 
before moving forward.


Looking further out I'm hoping this pattern will transform into a 
simpler and always active define_split.


Jeff

gcc/
* config/riscv/riscv.md ((x << C1) + C2): Tighten split condition
and generate more efficient code when splitting.

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index e48d78a899e..5eb35d2fa64 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4864,23 +4864,38 @@ (define_insn_and_split ""
(match_operand 2 "const_int_operand" "n"))
 (match_operand 3 "const_int_operand" "n")))
(clobber (match_scratch:DI 4 "=&r"))]
-  "(TARGET_64BIT && riscv_const_insns (operands[3], false) == 1)"
+  "(TARGET_64BIT
+&& riscv_const_insns (operands[3], false) == 1
+&& riscv_const_insns (GEN_INT (INTVAL (operands[3])
+ << INTVAL (operands[2])), false) != 1)"
   "#"
   "&& reload_completed"
   [(const_int 0)]
   "{
- rtx x = gen_rtx_ASHIFT (DImode, operands[1], operands[2]);
- emit_insn (gen_rtx_SET (operands[0], x));
-
- /* If the constant fits in a simm12, use it directly as we do not
-   get another good chance to optimize things again.  */
- if (!SMALL_OPERAND (INTVAL (operands[3])))
+ /* Prefer to generate shNadd when we can, even over using an
+   immediate form.  If we're not going to be able to generate
+   a shNadd, then use the constant directly if it fits in a
+   simm12 field since we won't get another chance to optimize this.  */
+ if ((TARGET_ZBA && imm123_operand (operands[2], word_mode))
+|| !SMALL_OPERAND (INTVAL (operands[3])))
emit_move_insn (operands[4], operands[3]);
  else
operands[4] = operands[3];
 
- x = gen_rtx_PLUS (DImode, operands[0], operands[4]);
- emit_insn (gen_rtx_SET (operands[0], x));
+ if (TARGET_ZBA && imm123_operand (operands[2], word_mode))
+   {
+rtx x = gen_rtx_ASHIFT (DImode, operands[1], operands[2]);
+x = gen_rtx_PLUS (DImode, x, operands[4]);
+emit_insn (gen_rtx_SET (operands[0], x));
+   }
+ else
+   {
+rtx x = gen_rtx_ASHIFT (DImode, operands[1], operands[2]);
+emit_insn (gen_rtx_SET (operands[0], x));
+x = gen_rtx_PLUS (DImode, operands[0], operands[4]);
+emit_insn (gen_rtx_SET (operands[0], x));
+   }
+
  DONE;
}"
   [(set_attr "type" "arith")])


Re: [PATCH v24 2/3] c: Add

2025-05-21 Thread Jakub Jelinek
On Wed, May 21, 2025 at 11:01:35PM +0200, Alejandro Colomar wrote:
> gcc/ChangeLog:
> 
>   * Makefile.in (USER_H): Add .
>   * ginclude/stdcountof.h: Add countof macro.

This one is actually : New file.
If the header existed before and you've just added countof macro
definition, it would be (countof): Define.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/countof-stdcountof.c: Add tests for .

This is a new test, so you just say : New test.

Jakub



Re: [PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Jakub Jelinek
On Wed, May 21, 2025 at 11:01:31PM +0200, Alejandro Colomar wrote:
> This operator is similar to sizeof but can only be applied to an array,
> and returns its number of elements.
> 
> FUTURE DIRECTIONS:
> 
> -  We should make it work with array parameters to functions,
>and somehow magically return the number of elements of the array,
>regardless of it being really a pointer.
> 
> Link: 
> Link: 
> Link: 
> Link: 
> 
> Link: 
> Link: 
> Link: 
> Link: 
> Link: 
> Link: 
> Link: 
> Link: 
> 
> gcc/ChangeLog:
> 
>   * doc/extend.texi: Document _Countof operator.
> 
> gcc/c-family/ChangeLog:
> 
>   * c-common.h: Add RID_COUNTOF.

(enum rid): Add RID_COUNTOF.

>   (c_countof_type): New function prototype.
>   * c-common.def (COUNTOF_EXPR): New tree.
>   * c-common.cc
>   (c_common_reswords): Add RID_COUNTOF entry.

No newline in between the line with file and (c_common_reswords).
* c-common.cc (c_common_reswords): Add RID_COUNTOF entry.
fits just fine.  And even if the description wouldn't fit completely,
you'd wrap on the first word that doesn't fit.

>   (c_countof_type): New function.
> 
> gcc/c/ChangeLog:
> 
>   * c-tree.h
>   (in_countof): Add global variable declaration.

Ditto.
>   (c_expr_countof_expr): Add function prototype.
>   (c_expr_countof_type): Add function prototype.
>   * c-decl.cc
>   (start_struct, finish_struct): Add support for _Countof.

Ditto.

>   (start_enum, finish_enum): Add support for _Countof.
>   * c-parser.cc
>   (c_parser_sizeof_expression): New macro.

Ditto.
>   (c_parser_countof_expression): New macro.
>   (c_parser_sizeof_or_countof_expression):
>   Rename function and add support for _Countof.
>   (c_parser_unary_expression): Add RID_COUNTOF entry.
>   * c-typeck.cc
>   (in_countof): Add global variable.

Ditto.
>   (build_external_ref): Add support for _Countof.
>   (record_maybe_used_decl): Add support for _Countof.
>   (pop_maybe_used): Add support for _Countof.
>   (is_top_array_vla): New function.
>   (c_expr_countof_expr, c_expr_countof_type): New functions.
>   Add _Countof operator.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/countof-compile.c: Compile-time tests for _Countof.
>   * gcc.dg/countof-vla.c: Tests for _Countof with VLAs.
>   * gcc.dg/countof-vmt.c: Tests for _Countof with other VMTs.
>   * gcc.dg/countof-zero-compile.c:
>   Compile-time tests for _Countof with zero-sized arrays.
>   * gcc.dg/countof-zero.c:
>   Tests for _Countof with zero-sized arrays.
>   * gcc.dg/countof.c: Tests for _Countof.
> 
> Suggested-by: Xavier Del Campo Romero 
> Co-authored-by: Martin Uecker 
> Acked-by: "James K. Lowden" 
> Signed-off-by: Alejandro Colomar 
> ---
>  gcc/c-family/c-common.cc|  26 
>  gcc/c-family/c-common.def   |   3 +
>  gcc/c-family/c-common.h |   2 +
>  gcc/c/c-decl.cc |  22 +++-
>  gcc/c/c-parser.cc   |  63 +++---
>  gcc/c/c-tree.h  |   4 +
>  gcc/c/c-typeck.cc   | 115 +-
>  gcc/doc/extend.texi |  30 +
>  gcc/testsuite/gcc.dg/countof-compile.c  | 124 
>  gcc/testsuite/gcc.dg/countof-vla.c  |  35 ++
>  gcc/testsuite/gcc.dg/countof-vmt.c  |  20 
>  gcc/testsuite/gcc.dg/countof-zero-compile.c |  38 ++
>  gcc/testsuite/gcc.dg/countof-zero.c |  31 +
>  gcc/testsuite/gcc.dg/countof.c  | 120 +++
>  14 files changed, 609 insertions(+), 24 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/countof-compile.c
>  create mode 100644 gcc/testsuite/gcc.dg/countof-vla.c
>  create mode 100644 gcc/testsuite/gcc.dg/countof-vmt.c
>  create mode 100644 gcc/testsuite/gcc.dg/countof-zero-compile.c
>  create mode 100644 gcc/testsuite/gcc.dg/countof-zero.c
>  create mode 100644 gcc/testsuite/gcc.dg/countof.c
> 
> diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> index 587d76461e9e..f71cb2652d5a 100644
> --- a/gcc/c-family/c-common.cc
> +++ b/gcc/c-family/c-common.cc
> @@ -394,6 +394,7 @@ con

Re: [PATCH v24 3/3] c: Add -Wpedantic diagnostic for _Countof

2025-05-21 Thread Jakub Jelinek
On Wed, May 21, 2025 at 11:01:38PM +0200, Alejandro Colomar wrote:
> It has been standardized in C2y.
> 
> gcc/c/ChangeLog:
> 
>   * c-parser.cc (c_parser_sizeof_or_countof_expression):
>   Add -Wpedantic diagnostic for _Countof in <= C23 mode.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/countof-compat.c:
>   Test _Countof diagnostics with -Wc23-c2y-compat on C2y.
>   * gcc.dg/countof-no-compat.c:
>   Test _Countof diagnostics with -Wno-c23-c2y-compat on C23.
>   * gcc.dg/countof-pedantic.c:
>   Test _Countof diagnostics with -pedantic on C23.
>   * gcc.dg/countof-pedantic-errors.c:
>   Test _Countof diagnostics with -pedantic-errors on C23.

For new test files, just say : New test.

Jakub



Re: [PATCH] configure: Always add pre-installed header directories to search path

2025-05-21 Thread Jeff Law




On 9/25/24 9:22 PM, Stephanos Ioannidis wrote:

configure script was adding the target directory flags, including the
'-B' flags for the executable prefix and the '-isystem' flags for the
pre-installed header directories, to the target flags only for
non-Canadian builds under the premise that the host binaries under the
executable prefix will not be able to execute on the build system for
Canadian builds.

While that is true for the '-B' flags specifying the executable prefix,
the '-isystem' flags specifying the pre-installed header directories are
not affected by this and do not need special handling.

This patch updates the configure script to always add the 'include' and
'sys-include' pre-installed header directories to the target search
path, in order to ensure that the availability of the pre-installed
header directories in the search path is consistent across non-Canadian
and Canadian builds.

When '--with-headers' flag is specified, this effectively ensures that
the libc headers, that are copied from the specified header directory to
the sys-include directory, are used by libstdc++.

ChangeLog:

 * configure.ac: Always add pre-installed heades to search path.
 * configure: Regenerate.

Thanks.  I've pushed this to the trunk.

FTR, this has been in my tester for quite a while, so it's been 
bootstrapped on aarch64, riscv64, ppc64 etc etc.  I don't do any 
canadian crosses, so the primary purpose of the patch is not getting 
tested.  But it shouldn't cause any problems for natives or traditional 
crosses.


jeff



Re: [AUTOFDO] Merge profiles of clones before annotating

2025-05-21 Thread Kugan Vivekanandarajah
Ping?

Thanks,
Kugan



> On 9 May 2025, at 11:54 am, Kugan Vivekanandarajah  
> wrote:
>
> External email: Use caution opening links or attachments
>
>
> This patch add support for merging profiles from multiple clones.
> That is, when optimized binaries have clones such as IPA-CP clone or SRA
> clones, genarted gcov will have profiled them spereately.
> Currently we pick one and ignore the rest. This patch fixes this by
> merging the profiles.
>
>
> Regression tested on aarch64-linux-gnu with no new regression.
> Also successfully  done autoprofiledbootstrap with the relevant patch.
>
> Is this OK for trunk?
> Thanks,
> Kugan
>



0002-AUTOFDO-Merge-profiles-of-clones-before-annotating.patch
Description: 0002-AUTOFDO-Merge-profiles-of-clones-before-annotating.patch


0002-AUTOFDO-Merge-profiles-of-clones-before-annotating.patch
Description: 0002-AUTOFDO-Merge-profiles-of-clones-before-annotating.patch


Re: [AUTOFDO] Fix annotated profile for de-duplicated call

2025-05-21 Thread Kugan Vivekanandarajah
Ping?

Thanks,
Kugan



> On 9 May 2025, at 11:51 am, Kugan Vivekanandarajah  
> wrote:
>
> External email: Use caution opening links or attachments
>
>
> This patch fixes wrong annotation of profiles when call statement is
> de-duplicated. i.e., when we may have same stmt executing from
> more than one path (by jumping to same statment). Thus, the
> profile we get will be for multiple paths and would make the annotated
> profile wrong. As a fix, we dont annotate profile for GIMPLE_CALL stmt
> and extract BB counts from edge counts.
>
> Regression tested on aarch64-linux-gnu with no new regression.
> Also successfully  done autoprofiledbootstrap with the relevant patch.
>
> Is this OK for trunk?
> Thanks,
> Kugan
>



0001-AUTOFDO-Fix-annotated-profile-for-de-duplicated-call.patch
Description: 0001-AUTOFDO-Fix-annotated-profile-for-de-duplicated-call.patch


0001-AUTOFDO-Fix-annotated-profile-for-de-duplicated-call.patch
Description: 0001-AUTOFDO-Fix-annotated-profile-for-de-duplicated-call.patch


Re: [AUTOFDO] Enable ipa-split for auto-profile

2025-05-21 Thread Kugan Vivekanandarajah
Ping?

Thanks,
Kugan


> On 9 May 2025, at 11:55 am, Kugan Vivekanandarajah  
> wrote:
>
> ipa-split is not now run for auto-profile. IMO this was an oversight.
> This patch enables it similar to PGO runs.
>
> gcc/ChangeLog:
>
>* ipa-split.cc pass_feedback_split_functions::clone (): New.
>* passes.def: Enable pass_feedback_split_functions for
>pass_ipa_auto_profile.
>
>
> Regression tested on aarch64-linux-gnu with no new regression.
> Also successfully  done autoprofiledbootstrap with the relevant patch.
>
> Is this OK for trunk?
> Thanks,
> Kugan
>
> <0003-AUTOFDO-Enable-ips-split-for-auto-profile.patch>



0003-AUTOFDO-Enable-ips-split-for-auto-profile.patch
Description: 0003-AUTOFDO-Enable-ips-split-for-auto-profile.patch


Re: [PATCH 1/2] expand: Use rtx_cost directly instead of gen_move_insn for canonicalize_comparison.

2025-05-21 Thread Jeff Law




On 5/20/25 9:12 PM, Andrew Pinski wrote:

This is the first part in fixing PR target/120372.
The current code for canonicalize_comparison, uses gen_move_insn and rtx_cost 
to find
out the cost of generating a constant. This is ok in most cases except sometimes
the comparison instruction can handle different constants than a simple set
intruction can do. This changes to use rtx_cost directly with the outer being 
COMPARE
just like how prepare_cmp_insn handles that.

Note this is also a small speedup and small memory improvement because we are 
not creating
a move for the constant any more. Since we are not creating a psedu-register 
any more, this
also removes the check on that.

Also adds a dump so we can see why one choice was chosen over the other.

Build and tested for aarch64-linux-gnu.

gcc/ChangeLog:

* expmed.cc (canonicalize_comparison): Use rtx_cost directly
instead of gen_move_insn. Print out the choice if dump is enabled.

OK.  Someone else needs to ACK the 2nd patch though.

Jeff



[PATCH v2] libstdc++: implement Philox Engine [PR119794]

2025-05-21 Thread 1nfocalypse
Implements Philox Engine (P2075R6) and associated tests.

v2 corrects a multiline comment left in error in serialize.cc, and additionally 
corrects a bug hidden by said comment, where the stream was given the output of 
'y()' instead of 'y', causing state to be incorrectly passed. Lastly, it fixes 
numerous whitespace issues found in the original patch. My apologies for not 
noticing prior to the submission of the original patch, which can now be 
disregarded.

To reiterate from the original email, the template unpacking functions are 
placed in a private classifier prior to the public one due to an ordering bug, 
where in order to function correctly, they must be placed prior to the bulk of 
the header. This is counter to the style recommendations, but I was unable to 
obtain functionality any other way. Additionally, while SIMD instructions are 
not utilized, and I do not think that they would integrate well with how the 
generator's state is currently handled, some structure choices could be made 
that may make them of interest.

Lastly, since word width can be specified, and thus atypical, maximum value is 
calculated via some bit manipulation rather than numeric_limits, since the 
specified width may differ from the width of the type used.

Built/tested on x86_64-linux-gnu.

- 1nfocalypseFrom 8fca3ac477c18fc988bd8148e1bc97fef0f3ff0c Mon Sep 17 00:00:00 2001
From: 1nfocalypse <1nfocaly...@protonmail.com>
Date: Wed, 21 May 2025 13:04:46 +
Subject: [PATCH] [PATCH v2] libstdc++: implement Philox Engine [PR119794]

The template unpacking functions, while private, are placed prior
to the public access specifier due to issues where the template
pack could not be unpacked and used to populate the public member
arrays without being declared beforehand.

Additionally, the tests implemented attempt to mirror the tests
for other engines, when they apply. Changes to random
provided cause for changing 'pr60037-neg.cc' because it suppresses
an error by explicit line number. It should still be correctly
suppressed in this patch. Lastly, v2 fixes an issue in
'serialize.cc' for Philox, where a portion of the test was
commented out, hiding a bug where 'y()' was passed to the
stream instead of 'y'. Both have been remedied in this patch.

Plus some whitespace fixes.

	PR libstdc++/119794

libstdc++-v3/ChangeLog:

	* include/bits/random.h: Add Philox Engine components.
	* include/bits/random.tcc: Implement Philox Engine components.
	* testsuite/26_numerics/random/pr60037-neg.cc: Alter line #.
	* testsuite/26_numerics/random/inequal.cc: New test.
	* testsuite/26_numerics/random/philox4x32.cc: New test.
	* testsuite/26_numerics/random/philox4x64.cc: New test.
	* testsuite/26_numerics/random/philox_engine/cons/
	119794.cc: New test.
	* testsuite/26_numerics/random/philox_engine/cons/
	copy.cc: New test.
	* testsuite/26_numerics/random/philox_engine/cons/
	default.cc: New test.
	* testsuite/26_numerics/random/philox_engine/cons/
	seed.cc: New test.
	* testsuite/26_numerics/random/philox_engine/cons/
	seed_seq.cc: New test.
	* testsuite/26_numerics/random/philox_engine/operators/
	equal.cc: New test.
	* testsuite/26_numerics/random/philox_engine/operators/
	inequal.cc: New test.
	* testsuite/26_numerics/random/philox_engine/operators/
	serialize.cc: New test.
	* testsuite/26_numerics/random/philox_engine/requirements/
	constants.cc: New test.
	* testsuite/26_numerics/random/philox_engine/requirements/
	constexpr_data.cc: New test.
	* testsuite/26_numerics/random/philox_engine/requirements/
	constexpr_functions.cc: New test.
	* testsuite/26_numerics/random/philox_engine/requirements/
	typedefs.cc: New test.
---
 libstdc++-v3/include/bits/random.h| 340 ++
 libstdc++-v3/include/bits/random.tcc  | 201 +++
 .../testsuite/26_numerics/random/inequal.cc   |  49 +++
 .../26_numerics/random/philox4x32.cc  |  42 +++
 .../26_numerics/random/philox4x64.cc  |  42 +++
 .../random/philox_engine/cons/119794.cc   |  57 +++
 .../random/philox_engine/cons/copy.cc |  44 +++
 .../random/philox_engine/cons/default.cc  |  46 +++
 .../random/philox_engine/cons/seed.cc |  39 ++
 .../random/philox_engine/cons/seed_seq.cc |  41 +++
 .../random/philox_engine/operators/equal.cc   |  49 +++
 .../random/philox_engine/operators/inequal.cc |  49 +++
 .../philox_engine/operators/serialize.cc  |  68 
 .../philox_engine/requirements/constants.cc   |  45 +++
 .../requirements/constexpr_data.cc|  69 
 .../requirements/constexpr_functions.cc   |  60 
 .../philox_engine/requirements/typedefs.cc|  45 +++
 .../26_numerics/random/pr60037-neg.cc |   2 +-
 18 files changed, 1287 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/testsuite/26_numerics/random/inequal.cc
 create mode 100644 libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
 create mode 100644 libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc
 create mod

RE: [PATCH] aarch64: Carry over zeroness in aarch64_evpc_reencode

2025-05-21 Thread quic_pzheng
> Pengxuan Zheng  writes:
> > There was a bug in aarch64_evpc_reencode which could leave zero_op0_p
> > and zero_op1_p of the struct "newd" uninitialized.
> > r16-701-gd77c3bc1c35e303 fixed the issue by zero initializing "newd."
> > This patch provides an alternative fix as suggested by Richard
> > Sandiford based on the fact that the zeroness is preserved by
> aarch64_evpc_reencode.
> >
> > gcc/ChangeLog:
> >
> > * config/aarch64/aarch64.cc (aarch64_evpc_reencode): Copy
> zero_op0_p and
> > zero_op1_p from d to newd.
> >
> > Signed-off-by: Pengxuan Zheng 
> 
> OK, thanks.
> 
> Richard
Thanks, pushed as r16-811-g84c6988c026114.

Pengxuan
> 
> > ---
> >  gcc/config/aarch64/aarch64.cc | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/gcc/config/aarch64/aarch64.cc
> > b/gcc/config/aarch64/aarch64.cc index 1da615c8955..2b837ec8e67
> 100644
> > --- a/gcc/config/aarch64/aarch64.cc
> > +++ b/gcc/config/aarch64/aarch64.cc
> > @@ -26327,7 +26327,7 @@ aarch64_evpc_trn (struct expand_vec_perm_d
> *d)
> > static bool  aarch64_evpc_reencode (struct expand_vec_perm_d *d)  {
> > -  expand_vec_perm_d newd = {};
> > +  expand_vec_perm_d newd;
> >
> >/* The subregs that we'd create are not supported for big-endian SVE;
> >   see aarch64_modes_compatible_p for details.  */ @@ -26353,6
> > +26353,8 @@ aarch64_evpc_reencode (struct expand_vec_perm_d *d)
> >newd.op1 = d->op1 ? gen_lowpart (new_mode, d->op1) : NULL;
> >newd.testing_p = d->testing_p;
> >newd.one_vector_p = d->one_vector_p;
> > +  newd.zero_op0_p = d->zero_op0_p;
> > +  newd.zero_op1_p = d->zero_op1_p;
> >
> >newd.perm.new_vector (newpermindices.encoding (),
> newd.one_vector_p ? 1 : 2,
> > newpermindices.nelts_per_input ());



[PATCH 1/2] Support picolibc targets

2025-05-21 Thread Keith Packard
Match *-picolibc-* and select picolibc as the default C library, plus
continuing to use the newlib-based logic for other configuration
items.

Add custom spec file fragments for use with picolibc:

 * '--oslib='. Allows targets to insert an OS library after the C
   library in the LIB_PATH spec file fragment. This library maps a few
   POSIX APIs used by picolibc to underlying system capabilities.

 * '--crt0='. Allows targets to use an alternate crt0 in place of the
   usual one as provided by Picolibc.

 * '--printf='. Allows targets to customize the version of printf linked
   from the C library.

Signed-off-by: Keith Packard 
---
 gcc/config.gcc   |  9 ++
 gcc/config/picolibc-spec.h   | 57 
 gcc/config/picolibc.opt  | 47 +
 gcc/config/picolibc.opt.urls |  2 ++
 gcc/gcc.cc   | 17 +--
 5 files changed, 130 insertions(+), 2 deletions(-)
 create mode 100644 gcc/config/picolibc-spec.h
 create mode 100644 gcc/config/picolibc.opt
 create mode 100644 gcc/config/picolibc.opt.urls

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 1e386a469e0..b20545da649 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1161,6 +1161,15 @@ case ${target} in
   ;;
   esac
   ;;
+*-picolibc-*)
+  # picolibc provides __cxa_atexit
+  default_use_cxa_atexit=yes
+  # picolibc provides stdint.h
+  use_gcc_stdint=none
+  tm_file="${tm_file} picolibc-spec.h"
+  extra_options="${extra_options} picolibc.opt"
+  ;;
+
 *-*-elf|arc*-*-elf*)
   # Assume that newlib is being used and so __cxa_atexit is provided.
   default_use_cxa_atexit=yes
diff --git a/gcc/config/picolibc-spec.h b/gcc/config/picolibc-spec.h
new file mode 100644
index 000..40a55c056f4
--- /dev/null
+++ b/gcc/config/picolibc-spec.h
@@ -0,0 +1,57 @@
+/* Configuration common to all targets running Picolibc.
+   Copyright (C) 2023 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
+   .  */
+
+#define PICOLIBC_LD "picolibc.ld"
+
+/* Default to local-exec TLS model.  */
+#undef OS_CC1_SPEC
+#define OS_CC1_SPEC " %{!ftls-model=*:-ftls-model=local-exec}"
+
+/* Pass along preprocessor definitions when --printf or --scanf are specified 
*/
+#define LIBC_CPP_SPEC  \
+  " %{-printf=*: -D_PICOLIBC_PRINTF='%*'}" \
+  " %{-scanf=*: -D_PICOLIBC_SCANF='%*'}"
+
+/*
+ * Add picolibc.ld if not using -shared, -r or -T and we can find it.
+ * Define vfprintf if --printf is set
+ * Define vfscanf if --scanf is set
+ */
+#define LIBC_LINK_SPEC \
+  " %{!shared:%{!r:%{!T*: %:if-exists-then-else(%:find-file(" PICOLIBC_LD ") 
-T" PICOLIBC_LD ")}}}" \
+  " %{-printf=*:--defsym=" USER_LABEL_PREFIX "vfprintf=" USER_LABEL_PREFIX 
"__%*_vfprintf}" \
+  " %{-scanf=*:--defsym=" USER_LABEL_PREFIX "vfscanf=" USER_LABEL_PREFIX 
"__%*_vfscanf}"
+
+/*
+ * Place the C library, libgcc and any oslib in a link group to resolve
+ * interdependencies
+ */
+#undef  LIB_SPEC
+#define LIB_SPEC "--start-group -lc %{-oslib=*:-l%*} %(libgcc) --end-group"
+
+/* Select alternate crt0 version if --crt0 is specified */
+#undef  STARTFILE_SPEC
+#define STARTFILE_SPEC "%{-crt0=*:crt0-%*%O%s; :crt0%O%s}"
+
+#define EH_TABLES_CAN_BE_READ_ONLY 1
diff --git a/gcc/config/picolibc.opt b/gcc/config/picolibc.opt
new file mode 100644
index 000..c5192fd6378
--- /dev/null
+++ b/gcc/config/picolibc.opt
@@ -0,0 +1,47 @@
+; Processor-independent options for picolibc.
+;
+; 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.
+;
+; Yo

Re: [RFC PATCH 0/3] _BitInt(N) support for LoongArch

2025-05-21 Thread Yang Yujie
On Wed, May 21, 2025 at 11:48:08AM GMT, Jakub Jelinek wrote:
> In gimple-lower-bitint.cc I'd strongly prefer to differentiate between
> changes required to get info->extended working correctly (that is what
> should be committed first, and right now should include the LSHIFT_EXPR in
> lower_shift_stmt) from just optimizations where you want to avoid some
> extensions that might not be strictly necessary and where those
> optimizations can cause further needs to extend at some other places.

Ok. I will rebase the LoongArch support patch (and possibly other changes
that falls into the optimization category) on your new changes and post
a v2.



[PATCH 0/4] c++: Support modules streaming some internal structures with no DECL_CONTEXT

2025-05-21 Thread Nathaniel Shead
This patch series adds support for streaming some internal declarations
in C++20 modules that we previously would ICE on.  

The series has been successfully bootstrapped and regtested on
x86_64-pc-linux-gnu.  Additionally, modules.exp now passes with
'--target_board=unix/-fsanitize=undefined'.

Nathaniel Shead (4):
  c++: Add flag to detect underlying representative of bitfield decls
  c++/modules: Implement streaming of uncontexted TYPE_DECLs [PR98735]
  c++/modules: Support streaming new size cookie for constexpr
[PR120040]
  c++/modules: Avoid name clashes when streaming internal labels
[PR98375,PR118904]

 gcc/cp/constexpr.cc|   2 +-
 gcc/cp/cp-gimplify.cc  |   5 +-
 gcc/cp/init.cc |  10 +-
 gcc/cp/module.cc   | 170 +++--
 gcc/stor-layout.cc |   1 +
 gcc/testsuite/g++.dg/modules/pr120040_a.C  |  19 +++
 gcc/testsuite/g++.dg/modules/pr120040_b.C  |  15 ++
 gcc/testsuite/g++.dg/modules/src-loc-1.h   |   6 +
 gcc/testsuite/g++.dg/modules/src-loc-1_a.H |   7 +
 gcc/testsuite/g++.dg/modules/src-loc-1_b.C |   5 +
 gcc/testsuite/g++.dg/modules/src-loc-1_c.C |  16 ++
 gcc/testsuite/g++.dg/modules/ubsan-1_a.C   |  10 ++
 gcc/testsuite/g++.dg/modules/ubsan-1_b.C   |  14 ++
 gcc/testsuite/g++.dg/ubsan/module-1-aux.cc |  12 ++
 gcc/testsuite/g++.dg/ubsan/module-1.C  |  11 ++
 gcc/tree-core.h|   1 +
 gcc/tree.cc|  51 +++
 gcc/tree.h |  12 ++
 gcc/ubsan.cc   |  16 +-
 19 files changed, 350 insertions(+), 33 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/pr120040_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/pr120040_b.C
 create mode 100644 gcc/testsuite/g++.dg/modules/src-loc-1.h
 create mode 100644 gcc/testsuite/g++.dg/modules/src-loc-1_a.H
 create mode 100644 gcc/testsuite/g++.dg/modules/src-loc-1_b.C
 create mode 100644 gcc/testsuite/g++.dg/modules/src-loc-1_c.C
 create mode 100644 gcc/testsuite/g++.dg/modules/ubsan-1_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/ubsan-1_b.C
 create mode 100644 gcc/testsuite/g++.dg/ubsan/module-1-aux.cc
 create mode 100644 gcc/testsuite/g++.dg/ubsan/module-1.C

-- 
2.47.0



[PATCH 1/4] c++: Add flag to detect underlying representative of bitfield decls

2025-05-21 Thread Nathaniel Shead
This patch isn't currently necessary with how I've currently done the
follow-up patches, but is needed for avoiding any potential issues in
the future with DECL_CONTEXT'ful types getting created in the compiler
with no names on the fields.  (For instance, this change would make much
of r15-7342-gd3627c78be116e unnecessary.)

It does take up another flag though in the frontend though.  Another
possible approach would be to instead do a walk through all the fields
first to see if this is the target of a DECL_BIT_FIELD_REPRESENTATIVE;
thoughts?  Or would you prefer to skip this patch entirely?

-- >8 --

Modules streaming needs to handle these differently from other unnamed
FIELD_DECLs that are streamed for internal RECORD_DECLs, and there
doesn't seem to be a good way to detect this case otherwise.

gcc/cp/ChangeLog:

* module.cc (trees_out::get_merge_kind): Use new flag.

gcc/ChangeLog:

* stor-layout.cc (start_bitfield_representative): Mark with
DECL_BIT_FIELD_UNDERLYING_REPR_P.
* tree-core.h (struct tree_decl_common): Add comment.
* tree.h (DECL_BIT_FIELD_UNDERLYING_REPR_P): New accessor.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/module.cc   | 4 +---
 gcc/stor-layout.cc | 1 +
 gcc/tree-core.h| 1 +
 gcc/tree.h | 5 +
 4 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 13f8770b7bd..99cbfdbf01d 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -11131,9 +11131,7 @@ trees_out::get_merge_kind (tree decl, depset *dep)
  return MK_named;
}
 
- if (!DECL_NAME (decl)
- && !RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
- && !DECL_BIT_FIELD_REPRESENTATIVE (decl))
+ if (!DECL_NAME (decl) && DECL_BIT_FIELD_UNDERLYING_REPR_P (decl))
{
  /* The underlying storage unit for a bitfield.  We do not
 need to dedup it, because it's only reachable through
diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc
index 12071c96ca7..1f37a130e24 100644
--- a/gcc/stor-layout.cc
+++ b/gcc/stor-layout.cc
@@ -2067,6 +2067,7 @@ static tree
 start_bitfield_representative (tree field)
 {
   tree repr = make_node (FIELD_DECL);
+  DECL_BIT_FIELD_UNDERLYING_REPR_P (repr) = 1;
   DECL_FIELD_OFFSET (repr) = DECL_FIELD_OFFSET (field);
   /* Force the representative to begin at a BITS_PER_UNIT aligned
  boundary - C++ may use tail-padding of a base object to
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index bd19c99d326..2e773d7bf83 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1911,6 +1911,7 @@ struct GTY(()) tree_decl_common {
   unsigned decl_read_flag : 1;
   /* In a VAR_DECL or RESULT_DECL, this is DECL_NONSHAREABLE.  */
   /* In a PARM_DECL, this is DECL_HIDDEN_STRING_LENGTH.  */
+  /* In a FIELD_DECL, this is DECL_BIT_FIELD_UNDERLYING_REPR_P.  */
   unsigned decl_nonshareable_flag : 1;
 
   /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs.  */
diff --git a/gcc/tree.h b/gcc/tree.h
index 99f26177628..0d876234824 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3085,6 +3085,11 @@ extern void decl_value_expr_insert (tree, tree);
 #define DECL_BIT_FIELD_REPRESENTATIVE(NODE) \
   (FIELD_DECL_CHECK (NODE)->field_decl.qualifier)
 
+/* In a FIELD_DECL of a RECORD_TYPE, this indicates whether the field
+   is used as the underlying storage unit for a bitfield.  */
+#define DECL_BIT_FIELD_UNDERLYING_REPR_P(NODE) \
+  (FIELD_DECL_CHECK (NODE)->decl_common.decl_nonshareable_flag)
+
 /* For a FIELD_DECL in a QUAL_UNION_TYPE, records the expression, which
if nonzero, indicates that the field occupies the type.  */
 #define DECL_QUALIFIER(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.qualifier)
-- 
2.47.0



[PATCH 2/4] c++/modules: Implement streaming of uncontexted TYPE_DECLs [PR98735]

2025-05-21 Thread Nathaniel Shead
Another approach would be to fix 'write_class_def' to handle these
declarations better, but that ended up being more work and felt fragile.
It also meant streaming a lot more information that we don't need.

Long term I had been playing around with reworking ubsan.cc entirely to
have a fixed set of types it would use we that we could merge with, but
given that there seems to be at least one other place we are creating
ad-hoc types (the struct for constexpr new allocations), and I couldn't
see an easy way of reworking that, I thought we should support this.

Finally, I'm not 100% certain about the hard-coding MK_unique for fields
of contextless types, but given that we've given up merging the owning
TYPE_DECL with anything anyway I think it should be OK.

-- >8 --

Currently, most declarations must have a DECL_CONTEXT for modules
streaming to behave correctly, so that they can have an appropriate
merge key generated and be correctly deduplicated on import.

There are a few exceptions, however, for internally generated
declarations that will never be merged and don't necessarily have an
appropriate parent to key off for the context.  One case that's come up
a few times is TYPE_DECLs, especially temporary RECORD_TYPEs used as
intermediaries within expressions.

Previously I've tried to give all such types a DECL_CONTEXT, but in some
cases that has ended up being infeasible, such as with the types
generated by UBSan (which are shared with the C frontend and don't know
their context, especially when created at global scope).  Additionally,
these types often don't have many of the parts that a normal struct
declaration created via parsing user code would have, which confuses
module streaming.

Given that these types are typically intended to be one-off and unique
anyway, this patch instead adds support for by-value streaming of
uncontexted TYPE_DECLs.  The patch only support streaming the bare
minimum amount of fields needed for the cases I've come across so far;
in general the preference should still be to ensure that DECL_CONTEXT is
set where possible.

PR c++/98735
PR c++/120040

gcc/cp/ChangeLog:

* module.cc (trees_out::tree_value): Write TYPE_DECLs.
(trees_in::tree_value): Read TYPE_DECLs.
(trees_out::tree_node): Support uncontexted TYPE_DECLs, and
ensure that all parts of a by-value decl are marked for
streaming.
(trees_out::get_merge_kind): Treat members of uncontexted types
as always unique.

gcc/testsuite/ChangeLog:

* g++.dg/modules/pr120040_a.C: New test.
* g++.dg/modules/pr120040_b.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/module.cc | 112 ---
 1 file changed, 107 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 99cbfdbf01d..ddb5299b244 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -9654,9 +9654,10 @@ trees_out::tree_value (tree t)
 
   if (DECL_P (t))
 /* No template, type, var or function, except anonymous
-   non-context vars.  */
+   non-context vars and types.  */
 gcc_checking_assert ((TREE_CODE (t) != TEMPLATE_DECL
- && TREE_CODE (t) != TYPE_DECL
+ && (TREE_CODE (t) != TYPE_DECL
+ || (DECL_ARTIFICIAL (t) && !DECL_CONTEXT (t)))
  && (TREE_CODE (t) != VAR_DECL
  || (!DECL_NAME (t) && !DECL_CONTEXT (t)))
  && TREE_CODE (t) != FUNCTION_DECL));
@@ -9670,7 +9671,7 @@ trees_out::tree_value (tree t)
   tree_node_bools (t);
 }
 
-  if  (TREE_CODE (t) == TREE_BINFO)
+  if (TREE_CODE (t) == TREE_BINFO)
 /* Binfos are decl-like and need merging information.  */
 binfo_mergeable (t);
 
@@ -9679,8 +9680,51 @@ trees_out::tree_value (tree t)
 dump (dumper::TREE)
   && dump ("Writing tree:%d %C:%N", tag, TREE_CODE (t), t);
 
+  int type_tag = 0;
+  tree type = NULL_TREE;
+  if (TREE_CODE (t) == TYPE_DECL)
+{
+  type = TREE_TYPE (t);
+
+  /* We only support a limited set of features for uncontexted types;
+these are typically types created in the language-independent
+parts of the frontend (such as ubsan).  */
+  gcc_checking_assert (RECORD_OR_UNION_TYPE_P (type)
+  && TYPE_MAIN_VARIANT (type) == type
+  && TYPE_NAME (type) == t
+  && TYPE_STUB_DECL (type) == t
+  && !TYPE_VFIELD (type)
+  && !TYPE_BINFO (type));
+  gcc_checking_assert (!TYPE_LANG_SPECIFIC (type)
+  || (!TYPE_CONTAINS_VPTR_P (type)
+  && !CLASSTYPE_MEMBER_VEC (type)));
+
+  if (streaming_p ())
+   {
+ start (type);
+ tree_node_bools (type);
+   }
+
+  type_tag = insert (type, WK_value);
+  if (streaming_p ())
+   dump (du

[PATCH 4/4] c++/modules: Avoid name clashes when streaming internal labels [PR98375,PR118904]

2025-05-21 Thread Nathaniel Shead
I'm not sure if there might be a better way to retrieve the prefix back
off an IDENTIFIER_NODE?  I'm also not sure if IDENTIFIER_INTERNAL_P
could ever clash with IDENTIFIER_TRANSPARENT_ALIAS; I'm pretty sure not
(and it looks like nothing ever sets that flag anyway, that I could
find?) but would appreciate any other thoughts.

I also wanted a run test (or at least a link test) using
-fsanitize=undefined, but I couldn't work out how to do so under
modules.exp, so I instead placed one under ubsan.exp.

-- >8 --

The frontend creates some variables that need to be given unique names
for the TU so that they can unambiguously be accessed.  Historically
this has been done with a global counter local to each place that needs
an internal label, but this doesn't work with modules as depending on
what declarations have been imported, some counter values may have
already been used.

This patch reworks the situation to instead have a single collection of
counters for the TU, and a new function 'generate_internal_label' that
gets the next label with given prefix using that counter.  Modules
streaming can then use this function to regenerate new names on
stream-in for any such decls, guaranteeing uniqueness within the TU.

These labels should only be used for internal entities so there should
be no issues with the names differing from TU to TU; we will need to
handle this if we ever start checking ODR of definitions we're merging
but that's an issue for later.

For proof of concept, this patch makes use of the new API for
__builtin_source_location and ubsan; there are probably other places
in the frontend where this change will need to be made as well.
One other change this exposes is that both of these components rely
on the definition of the VAR_DECLs they create, so stream that too
for uncontexted variables.

PR c++/98735
PR c++/118904

gcc/cp/ChangeLog:

* cp-gimplify.cc (source_location_id): Remove.
(fold_builtin_source_location): Use generate_internal_label.
* module.cc (enum tree_tag): Add 'tt_internal_id' enumerator.
(trees_out::tree_value): Adjust assertion, write definitions
of uncontexted VAR_DECLs.
(trees_in::tree_value): Read variable definitions.
(trees_out::tree_node): Write internal labels, adjust assert.
(trees_in::tree_node): Read internal labels.

gcc/ChangeLog:

* tree.cc (struct identifier_hash): New type.
(struct identifier_count_traits): New traits.
(internal_label_nums): New hash map.
(generate_internal_label): New function.
(prefix_for_internal_label): New function.
* tree.h (IDENTIFIER_INTERNAL_P): New macro.
(generate_internal_label): Declare.
(prefix_for_internal_label): Declare.
* ubsan.cc (ubsan_ids): Remove.
(ubsan_type_descriptor): Use generate_internal_label.
(ubsan_create_data): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/modules/src-loc-1.h: New test.
* g++.dg/modules/src-loc-1_a.H: New test.
* g++.dg/modules/src-loc-1_b.C: New test.
* g++.dg/modules/src-loc-1_c.C: New test.
* g++.dg/modules/ubsan-1_a.C: New test.
* g++.dg/modules/ubsan-1_b.C: New test.
* g++.dg/ubsan/module-1-aux.cc: New test.
* g++.dg/ubsan/module-1.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/cp-gimplify.cc  |  5 +--
 gcc/cp/module.cc   | 51 +++---
 gcc/testsuite/g++.dg/modules/src-loc-1.h   |  6 +++
 gcc/testsuite/g++.dg/modules/src-loc-1_a.H |  7 +++
 gcc/testsuite/g++.dg/modules/src-loc-1_b.C |  5 +++
 gcc/testsuite/g++.dg/modules/src-loc-1_c.C | 16 +++
 gcc/testsuite/g++.dg/modules/ubsan-1_a.C   | 10 +
 gcc/testsuite/g++.dg/modules/ubsan-1_b.C   | 14 ++
 gcc/testsuite/g++.dg/ubsan/module-1-aux.cc | 12 +
 gcc/testsuite/g++.dg/ubsan/module-1.C  | 11 +
 gcc/tree.cc| 51 ++
 gcc/tree.h |  7 +++
 gcc/ubsan.cc   | 16 ++-
 13 files changed, 188 insertions(+), 23 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/src-loc-1.h
 create mode 100644 gcc/testsuite/g++.dg/modules/src-loc-1_a.H
 create mode 100644 gcc/testsuite/g++.dg/modules/src-loc-1_b.C
 create mode 100644 gcc/testsuite/g++.dg/modules/src-loc-1_c.C
 create mode 100644 gcc/testsuite/g++.dg/modules/ubsan-1_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/ubsan-1_b.C
 create mode 100644 gcc/testsuite/g++.dg/ubsan/module-1-aux.cc
 create mode 100644 gcc/testsuite/g++.dg/ubsan/module-1.C

diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index f7bd453bc5e..7414064c68a 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -3874,7 +3874,6 @@ struct source_location_table_entry_hash
 
 static GTY(()) hash_table 
   *source_location_table;
-static GTY(()) unsigned int source_location_id;
 
 /* F

[PATCH 3/4] c++/modules: Support streaming new size cookie for constexpr [PR120040]

2025-05-21 Thread Nathaniel Shead
This type currently has a DECL_NAME of an IDENTIFIER_DECL.  Although the
documentation indicates this is legal, this confuses modules streaming
which expects all RECORD_TYPEs to have a TYPE_DECL, which is used to
determine the context and merge key, etc.

PR c++/120040

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_constant_expression): Handle TYPE_NAME
now being a TYPE_DECL rather than just an IDENTIFIER_NODE.
* init.cc (build_new_constexpr_heap_type): Build a TYPE_DECL for
the returned type; mark the type as artificial.
* module.cc (trees_out::type_node): Add some assertions.

gcc/testsuite/ChangeLog:

* g++.dg/modules/pr120040_a.C: New test.
* g++.dg/modules/pr120040_b.C: New test.

Signed-off-by: Nathaniel Shead 
---
 gcc/cp/constexpr.cc   |  2 +-
 gcc/cp/init.cc| 10 +-
 gcc/cp/module.cc  |  3 +++
 gcc/testsuite/g++.dg/modules/pr120040_a.C | 19 +++
 gcc/testsuite/g++.dg/modules/pr120040_b.C | 15 +++
 5 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/pr120040_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/pr120040_b.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index fa754b9a176..ceb8f04fab4 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8613,7 +8613,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
tree cookie_size = NULL_TREE;
tree arg_size = NULL_TREE;
if (TREE_CODE (elt_type) == RECORD_TYPE
-   && TYPE_NAME (elt_type) == heap_identifier)
+   && DECL_NAME (TYPE_NAME (elt_type)) == heap_identifier)
  {
tree fld1 = TYPE_FIELDS (elt_type);
tree fld2 = DECL_CHAIN (fld1);
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 80a37a14a80..0a389fb6ecd 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -3010,7 +3010,6 @@ build_new_constexpr_heap_type (tree elt_type, tree 
cookie_size, tree itype2)
   tree atype1 = build_cplus_array_type (sizetype, itype1);
   tree atype2 = build_cplus_array_type (elt_type, itype2);
   tree rtype = cxx_make_type (RECORD_TYPE);
-  TYPE_NAME (rtype) = heap_identifier;
   tree fld1 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, atype1);
   tree fld2 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, atype2);
   DECL_FIELD_CONTEXT (fld1) = rtype;
@@ -3019,7 +3018,16 @@ build_new_constexpr_heap_type (tree elt_type, tree 
cookie_size, tree itype2)
   DECL_ARTIFICIAL (fld2) = true;
   TYPE_FIELDS (rtype) = fld1;
   DECL_CHAIN (fld1) = fld2;
+  TYPE_ARTIFICIAL (rtype) = true;
   layout_type (rtype);
+
+  tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL, heap_identifier, rtype);
+  TYPE_NAME (rtype) = decl;
+  TYPE_STUB_DECL (rtype) = decl;
+  DECL_CONTEXT (decl) = NULL_TREE;
+  DECL_ARTIFICIAL (decl) = true;
+  layout_decl (decl, 0);
+
   return rtype;
 }
 
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ddb5299b244..765d17935c5 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -9362,6 +9362,7 @@ trees_out::type_node (tree type)
 
   tree root = (TYPE_NAME (type)
   ? TREE_TYPE (TYPE_NAME (type)) : TYPE_MAIN_VARIANT (type));
+  gcc_checking_assert (root);
 
   if (type != root)
 {
@@ -9440,6 +9441,8 @@ trees_out::type_node (tree type)
|| TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == ENUMERAL_TYPE)
   {
+   gcc_checking_assert (DECL_P (name));
+
/* We can meet template parms that we didn't meet in the
   tpl_parms walk, because we're referring to a derived type
   that was previously constructed from equivalent template
diff --git a/gcc/testsuite/g++.dg/modules/pr120040_a.C 
b/gcc/testsuite/g++.dg/modules/pr120040_a.C
new file mode 100644
index 000..77e16892f4e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr120040_a.C
@@ -0,0 +1,19 @@
+// PR c++/120040
+// { dg-additional-options "-fmodules -std=c++20" }
+// { dg-module-cmi M }
+
+export module M;
+
+struct S {
+  constexpr ~S() {}
+};
+
+export constexpr bool foo() {
+  S* a = new S[3];
+  delete[] a;
+  return true;
+}
+
+export constexpr S* bar() {
+  return new S[3];
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr120040_b.C 
b/gcc/testsuite/g++.dg/modules/pr120040_b.C
new file mode 100644
index 000..e4610b07eaf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr120040_b.C
@@ -0,0 +1,15 @@
+// PR c++/120040
+// { dg-additional-options "-fmodules -std=c++20" }
+
+import M;
+
+constexpr bool qux() {
+  auto* s = bar();
+  delete[] s;
+  return true;
+}
+
+int main() {
+  static_assert(foo());
+  static_assert(qux());
+}
-- 
2.47.0



Re: [PATCH 2/4] c++/modules: Implement streaming of uncontexted TYPE_DECLs [PR98735]

2025-05-21 Thread Nathaniel Shead
On Thu, May 22, 2025 at 12:15:02PM +1000, Nathaniel Shead wrote:
> Another approach would be to fix 'write_class_def' to handle these
> declarations better, but that ended up being more work and felt fragile.
> It also meant streaming a lot more information that we don't need.
> 
> Long term I had been playing around with reworking ubsan.cc entirely to
> have a fixed set of types it would use we that we could merge with, but
> given that there seems to be at least one other place we are creating
> ad-hoc types (the struct for constexpr new allocations), and I couldn't
> see an easy way of reworking that, I thought we should support this.
> 
> Finally, I'm not 100% certain about the hard-coding MK_unique for fields
> of contextless types, but given that we've given up merging the owning
> TYPE_DECL with anything anyway I think it should be OK.
> 
> -- >8 --
> 
> Currently, most declarations must have a DECL_CONTEXT for modules
> streaming to behave correctly, so that they can have an appropriate
> merge key generated and be correctly deduplicated on import.
> 
> There are a few exceptions, however, for internally generated
> declarations that will never be merged and don't necessarily have an
> appropriate parent to key off for the context.  One case that's come up
> a few times is TYPE_DECLs, especially temporary RECORD_TYPEs used as
> intermediaries within expressions.
> 
> Previously I've tried to give all such types a DECL_CONTEXT, but in some
> cases that has ended up being infeasible, such as with the types
> generated by UBSan (which are shared with the C frontend and don't know
> their context, especially when created at global scope).  Additionally,
> these types often don't have many of the parts that a normal struct
> declaration created via parsing user code would have, which confuses
> module streaming.
> 
> Given that these types are typically intended to be one-off and unique
> anyway, this patch instead adds support for by-value streaming of
> uncontexted TYPE_DECLs.  The patch only support streaming the bare
> minimum amount of fields needed for the cases I've come across so far;
> in general the preference should still be to ensure that DECL_CONTEXT is
> set where possible.
> 
>   PR c++/98735
>   PR c++/120040
> 
> gcc/cp/ChangeLog:
> 
>   * module.cc (trees_out::tree_value): Write TYPE_DECLs.
>   (trees_in::tree_value): Read TYPE_DECLs.
>   (trees_out::tree_node): Support uncontexted TYPE_DECLs, and
>   ensure that all parts of a by-value decl are marked for
>   streaming.
>   (trees_out::get_merge_kind): Treat members of uncontexted types
>   as always unique.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/modules/pr120040_a.C: New test.
>   * g++.dg/modules/pr120040_b.C: New test.
> 
> Signed-off-by: Nathaniel Shead 
> ---
>  gcc/cp/module.cc | 112 ---
>  1 file changed, 107 insertions(+), 5 deletions(-)
> 
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index 99cbfdbf01d..ddb5299b244 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -9654,9 +9654,10 @@ trees_out::tree_value (tree t)
>  
>if (DECL_P (t))
>  /* No template, type, var or function, except anonymous
> -   non-context vars.  */
> +   non-context vars and types.  */
>  gcc_checking_assert ((TREE_CODE (t) != TEMPLATE_DECL
> -   && TREE_CODE (t) != TYPE_DECL
> +   && (TREE_CODE (t) != TYPE_DECL
> +   || (DECL_ARTIFICIAL (t) && !DECL_CONTEXT (t)))
> && (TREE_CODE (t) != VAR_DECL
> || (!DECL_NAME (t) && !DECL_CONTEXT (t)))
> && TREE_CODE (t) != FUNCTION_DECL));
> @@ -9670,7 +9671,7 @@ trees_out::tree_value (tree t)
>tree_node_bools (t);
>  }
>  
> -  if  (TREE_CODE (t) == TREE_BINFO)
> +  if (TREE_CODE (t) == TREE_BINFO)
>  /* Binfos are decl-like and need merging information.  */
>  binfo_mergeable (t);
>  
> @@ -9679,8 +9680,51 @@ trees_out::tree_value (tree t)
>  dump (dumper::TREE)
>&& dump ("Writing tree:%d %C:%N", tag, TREE_CODE (t), t);
>  
> +  int type_tag = 0;
> +  tree type = NULL_TREE;
> +  if (TREE_CODE (t) == TYPE_DECL)
> +{
> +  type = TREE_TYPE (t);
> +
> +  /* We only support a limited set of features for uncontexted types;
> +  these are typically types created in the language-independent
> +  parts of the frontend (such as ubsan).  */
> +  gcc_checking_assert (RECORD_OR_UNION_TYPE_P (type)
> +&& TYPE_MAIN_VARIANT (type) == type
> +&& TYPE_NAME (type) == t
> +&& TYPE_STUB_DECL (type) == t
> +&& !TYPE_VFIELD (type)
> +&& !TYPE_BINFO (type));
> +  gcc_checking_assert (!TYPE_LANG_SPECIFIC (type)
> +|| (!TYPE_CONTAINS_VPTR_P (type)
> + 

Re: [PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Alejandro Colomar
Hi Jakub,

On Wed, May 21, 2025 at 11:12:07PM +0200, Jakub Jelinek wrote:
> > * c-common.h: Add RID_COUNTOF.
> 
> (enum rid): Add RID_COUNTOF.

Okay.

> 
> > (c_countof_type): New function prototype.
> > * c-common.def (COUNTOF_EXPR): New tree.
> > * c-common.cc
> > (c_common_reswords): Add RID_COUNTOF entry.
> 
> No newline in between the line with file and (c_common_reswords).
>   * c-common.cc (c_common_reswords): Add RID_COUNTOF entry.
> fits just fine.  And even if the description wouldn't fit completely,
> you'd wrap on the first word that doesn't fit.

Okay.

> >  warning_at (loc, OPT_Wc___compat,
> > "defining type in %qs expression is invalid in C++",
> > (in_sizeof
> >  ? "sizeof"
> > -: (in_typeof ? "typeof" : "alignof")));
> > +: (in_typeof
> > +   ? "typeof"
> > +   : (in_alignof
> > +  ? "alignof"
> > +  : "_Countof";
> 
> Why so many lines?  Plus no idea why there are the ()s around, I see it is
> preexisting for the outermost where it can help emacs formatting, but the
> rest doesn't need that.

The preexisting ones are not just the outermost ones.  The preexisting
code was 

(in_sizeof
 ? "sizeof"
 : (in_typeof ? "typeof" : "alignof")));

The only pattern I can find in that code is wrapping every ?:
subexpression in ().  I would find not doing so for the last one I'm
adding inconsistent with it.  On the other hand, I would agree that
limiting it to just the outermost ones would be more readable, but that
would mean removing existing ()s.  So can you please confirm that I
should remove the existing inner ()?

> > +#define c_parser_sizeof_expression(parser) 
> >\
> > +(  
> >\
> > +  c_parser_sizeof_or_countof_expression (parser, RID_SIZEOF)   
> >\
> > +)
> >  
> > +#define c_parser_countof_expression(parser)
> >\
> > +(  
> >\
> > +  c_parser_sizeof_or_countof_expression (parser, RID_COUNTOF)  
> >\
> > +)
> 
> Up to Joseph, but I'd say these should just be inline functions, not macros,
> and defined after the declarations.

I don't mind, so yeah, I'm okay with changing these to be inline.


Have a lovely night!
Alex

-- 



signature.asc
Description: PGP signature


[PATCH 0/2] Add picolibc support

2025-05-21 Thread Keith Packard
The first patch in this series selects picolibc as the default C
library when the target is *-picolibc-*. This configures the default
compiler specs for picolibc usage, including the addition of three
picolic-specific options.

The section patch in this series allows the default C library to be
selected separately from the target name. This allows toolchains for
targets like Zephyr to use picolibc without needing to include
'picolibc' in the target name.

Since January, this series has been tested with 11 different targets
as a part of the Zephyr 0.18 SDK development work. This uncovered
issues with the generated specs which were fixed by adding
libc-specific spec fragment defines. The C library selection mechanism
has been simplified to only select between newlib and picolibc to
avoid any potential impact on other toolchains.

Keith Packard (2):
  Support picolibc targets
  Allow default libc (either newlib or picolibc) to be specified to
configure

 gcc/config.gcc   | 51 +++-
 gcc/config/picolibc-spec.h   | 57 
 gcc/config/picolibc.opt  | 47 +
 gcc/config/picolibc.opt.urls |  2 ++
 gcc/configure.ac |  4 +++
 gcc/gcc.cc   | 17 +--
 6 files changed, 168 insertions(+), 10 deletions(-)
 create mode 100644 gcc/config/picolibc-spec.h
 create mode 100644 gcc/config/picolibc.opt
 create mode 100644 gcc/config/picolibc.opt.urls

-- 
2.49.0



[PATCH 2/2] Allow default libc (either newlib or picolibc) to be specified to configure

2025-05-21 Thread Keith Packard
The default C library is normally computed based on the target
triplet. However, for embedded systems, it can be useful to leave the
triplet alone while changing which C library is used by default. Other
C libraries may still be available on the system so the compiler and
can be used by specifying suitable include and library paths at build
time.

This patch only allows selecting between newlib and picolibc as those
are typically used in embedded systems. Other targets continue to
select their default C library through the existing mechanism.

If something other than picolibc or newlib is specified using
--with-default-libc= emit an error and stop.

Signed-off-by: Keith Packard 
---
 gcc/config.gcc   | 54 +++-
 gcc/configure.ac |  4 
 2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index b20545da649..052c69db028 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -720,6 +720,9 @@ arrowlake arrowlake-s clearwaterforest pantherlake 
diamondrapids native"
 # MUST be separated by exactly one space.
 x86_cpus="generic intel"
 
+# Inferred target C library (either newlib or picolibc)
+target_libc=
+
 # Common parts for widely ported systems.
 case ${target} in
 *-*-darwin*)
@@ -1162,23 +1165,11 @@ case ${target} in
   esac
   ;;
 *-picolibc-*)
-  # picolibc provides __cxa_atexit
-  default_use_cxa_atexit=yes
-  # picolibc provides stdint.h
-  use_gcc_stdint=none
-  tm_file="${tm_file} picolibc-spec.h"
-  extra_options="${extra_options} picolibc.opt"
+  target_libc=picolibc
   ;;
 
 *-*-elf|arc*-*-elf*)
-  # Assume that newlib is being used and so __cxa_atexit is provided.
-  default_use_cxa_atexit=yes
-  use_gcc_stdint=wrap
-
-  case "${with_newlib}-${with_headers}" in
-  no-no) use_gcc_stdint=provide ;;
-  *) ;;
-  esac
+  target_libc=newlib
   ;;
 esac
 
@@ -6135,6 +6126,41 @@ case ${target} in
;;
 esac
 
+# Override target_libc using --with-default-libc option
+case "${with_default_libc}" in
+newlib|picolibc)
+  target_libc="${with_default_libc}"
+  ;;
+"")
+  ;;
+*)
+  echo "Unknown libc in --with-default-libc=$with_default_libc" 1>&2
+  exit 1
+  ;;
+esac
+
+# Set up newlib or picolibc
+case "${target_libc}" in
+newlib)
+  # Assume that newlib is being used and so __cxa_atexit is provided.
+  default_use_cxa_atexit=yes
+  use_gcc_stdint=wrap
+  case "${with_newlib}-${with_headers}" in
+  no-no) use_gcc_stdint=provide ;;
+  *) ;;
+  esac
+  ;;
+picolibc)
+  # picolibc provides __cxa_atexit
+  default_use_cxa_atexit=yes
+  # picolibc provides stdint.h
+  use_gcc_stdint=none
+  tm_file="${tm_file} picolibc-spec.h"
+  extra_options="${extra_options} picolibc.opt"
+   ;;
+*) ;;
+esac
+
 t=
 all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 
schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls 
lxc1-sxc1 madd4 isa_spec compact-branches msa cmodel"
 for option in $all_defaults
diff --git a/gcc/configure.ac b/gcc/configure.ac
index b6db9edfc83..9c5a4de6181 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2582,6 +2582,10 @@ if { { test x$host != x$target && test "x$with_sysroot" 
= x ; } ||
 fi
 AC_SUBST(inhibit_libc)
 
+AC_ARG_WITH(default-libc,
+   [AS_HELP_STRING([--with-default-libc],
+   [Use specified default C library])])
+
 # When building gcc with a cross-compiler, we need to adjust things so
 # that the generator programs are still built with the native compiler.
 # Also, we cannot run fixincludes.
-- 
2.49.0



Re: [PATCH][RISC-V][PR target/70557] Improve storing 0 to memory on rv32

2025-05-21 Thread Jeff Law




On 5/21/25 12:20 PM, Shreya Munnangi wrote:
Patch is originally from Siarhei Volkau >.


RISC-V has a zero register (x0) which we can use to store zero into memory
without loading the constant into a distinct register. Adjust the 
constraints

of the 32-bit movdi_32bit pattern to recognize that we can store 0.0 into
memory using x0 as the source register.

This patch only affects RISC-V. It has been regression tested on 
riscv64-elf.
Jeff has also tested this in his tester (riscv64-elf and riscv32-elf) 
with no

regressions.

         PR target/70557
gcc/
         * config/riscv/riscv.md (movdi_32bit): Add "J" constraint to 
allow storing 0

         directly to memory.
So you forgot to attach the patch.  Usually when you do this you'll get 
the response "ENOPATCH" from someone which means "error, no patch".


Can you resend with the patch attached ;-)
jeff



[PATCH v25 0/3] c: Add _Countof and

2025-05-21 Thread Alejandro Colomar
Hi!

Here's v25.  Changes compared to v24 (see range-diff below):

-  Small fixes to the change logs.
-  Rewrap and remove parentheses in chains of ?: .
-  Implement c_parser_{sizeof,countof}_expression() as static inline.

Tests still pass:

$ grep countof ./gcc/testsuite/gcc/gcc.sum
PASS: gcc.dg/countof-compat.c  (test for warnings, line 8)
PASS: gcc.dg/countof-compat.c (test for excess errors)
PASS: gcc.dg/countof-compile.c  (test for errors, line 114)
PASS: gcc.dg/countof-compile.c  (test for errors, line 123)
PASS: gcc.dg/countof-compile.c  (test for errors, line 23)
PASS: gcc.dg/countof-compile.c  (test for errors, line 27)
PASS: gcc.dg/countof-compile.c  (test for errors, line 38)
PASS: gcc.dg/countof-compile.c  (test for errors, line 46)
PASS: gcc.dg/countof-compile.c  (test for errors, line 64)
PASS: gcc.dg/countof-compile.c  (test for errors, line 67)
PASS: gcc.dg/countof-compile.c  (test for errors, line 70)
PASS: gcc.dg/countof-compile.c  (test for errors, line 82)
PASS: gcc.dg/countof-compile.c  (test for errors, line 83)
PASS: gcc.dg/countof-compile.c  (test for errors, line 84)
PASS: gcc.dg/countof-compile.c  (test for errors, line 85)
PASS: gcc.dg/countof-compile.c  (test for errors, line 86)
PASS: gcc.dg/countof-compile.c  (test for errors, line 87)
PASS: gcc.dg/countof-compile.c  (test for errors, line 88)
PASS: gcc.dg/countof-compile.c  (test for errors, line 89)
PASS: gcc.dg/countof-compile.c  (test for errors, line 90)
PASS: gcc.dg/countof-compile.c  (test for errors, line 94)
PASS: gcc.dg/countof-compile.c (test for excess errors)
PASS: gcc.dg/countof-no-compat.c (test for excess errors)
PASS: gcc.dg/countof-pedantic-errors.c  (test for errors, line 8)
PASS: gcc.dg/countof-pedantic-errors.c (test for excess errors)
PASS: gcc.dg/countof-pedantic.c  (test for warnings, line 8)
PASS: gcc.dg/countof-pedantic.c (test for excess errors)
PASS: gcc.dg/countof-stdcountof.c (test for excess errors)
PASS: gcc.dg/countof-stdcountof.c execution test
PASS: gcc.dg/countof-vla.c (test for excess errors)
PASS: gcc.dg/countof-vmt.c (test for excess errors)
PASS: gcc.dg/countof-vmt.c execution test
PASS: gcc.dg/countof-zero-compile.c (test for excess errors)
PASS: gcc.dg/countof-zero.c (test for excess errors)
PASS: gcc.dg/countof-zero.c execution test
PASS: gcc.dg/countof.c (test for excess errors)
PASS: gcc.dg/countof.c execution test


Have a lovely night!
Alex


Alejandro Colomar (3):
  c: Add _Countof operator
  c: Add 
  c: Add -Wpedantic diagnostic for _Countof

 gcc/Makefile.in   |   1 +
 gcc/c-family/c-common.cc  |  26 
 gcc/c-family/c-common.def |   3 +
 gcc/c-family/c-common.h   |   2 +
 gcc/c/c-decl.cc   |  24 ++--
 gcc/c/c-parser.cc |  77 ---
 gcc/c/c-tree.h|   4 +
 gcc/c/c-typeck.cc | 115 +++-
 gcc/doc/extend.texi   |  30 +
 gcc/ginclude/stdcountof.h |  31 +
 gcc/testsuite/gcc.dg/countof-compat.c |   8 ++
 gcc/testsuite/gcc.dg/countof-compile.c| 124 ++
 gcc/testsuite/gcc.dg/countof-no-compat.c  |   5 +
 .../gcc.dg/countof-pedantic-errors.c  |   8 ++
 gcc/testsuite/gcc.dg/countof-pedantic.c   |   8 ++
 gcc/testsuite/gcc.dg/countof-stdcountof.c |  24 
 gcc/testsuite/gcc.dg/countof-vla.c|  35 +
 gcc/testsuite/gcc.dg/countof-vmt.c|  20 +++
 gcc/testsuite/gcc.dg/countof-zero-compile.c   |  38 ++
 gcc/testsuite/gcc.dg/countof-zero.c   |  31 +
 gcc/testsuite/gcc.dg/countof.c| 120 +
 21 files changed, 705 insertions(+), 29 deletions(-)
 create mode 100644 gcc/ginclude/stdcountof.h
 create mode 100644 gcc/testsuite/gcc.dg/countof-compat.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-no-compat.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic-errors.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-stdcountof.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-vmt.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-zero-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-zero.c
 create mode 100644 gcc/testsuite/gcc.dg/countof.c

Range-diff against v24:
1:  1ac81ab0d3dc ! 1:  a3fb6089a388 c: Add _Countof operator
@@ Commit message
 
 gcc/c-family/ChangeLog:
 
-* c-common.h

[PATCH v25 2/3] c: Add

2025-05-21 Thread Alejandro Colomar
gcc/ChangeLog:

* Makefile.in (USER_H): Add .
* ginclude/stdcountof.h: New file.

gcc/testsuite/ChangeLog:

* gcc.dg/countof-stdcountof.c: New test.

Signed-off-by: Alejandro Colomar 
---
 gcc/Makefile.in   |  1 +
 gcc/ginclude/stdcountof.h | 31 +++
 gcc/testsuite/gcc.dg/countof-stdcountof.c | 24 ++
 3 files changed, 56 insertions(+)
 create mode 100644 gcc/ginclude/stdcountof.h
 create mode 100644 gcc/testsuite/gcc.dg/countof-stdcountof.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 72d132207c0d..fc8a7e532b97 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -481,6 +481,7 @@ USER_H = $(srcdir)/ginclude/float.h \
 $(srcdir)/ginclude/stdalign.h \
 $(srcdir)/ginclude/stdatomic.h \
 $(srcdir)/ginclude/stdckdint.h \
+$(srcdir)/ginclude/stdcountof.h \
 $(EXTRA_HEADERS)
 
 USER_H_INC_NEXT_PRE = @user_headers_inc_next_pre@
diff --git a/gcc/ginclude/stdcountof.h b/gcc/ginclude/stdcountof.h
new file mode 100644
index ..1d914f40e5db
--- /dev/null
+++ b/gcc/ginclude/stdcountof.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2025 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
+.  */
+
+/* ISO C2Y: 7.21 Array count .  */
+
+#ifndef _STDCOUNTOF_H
+#define _STDCOUNTOF_H
+
+#define countof  _Countof
+
+#endif /* stdcountof.h */
diff --git a/gcc/testsuite/gcc.dg/countof-stdcountof.c 
b/gcc/testsuite/gcc.dg/countof-stdcountof.c
new file mode 100644
index ..2fb0c6306ef0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-stdcountof.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+#include 
+
+#define assert(e)  ((e) ? (void) 0 : __builtin_abort ())
+
+extern int strcmp (const char *, const char *);
+
+#ifndef countof
+#error "countof not defined"
+#endif
+
+int a[3];
+int b[countof a];
+
+#define str(x) #x
+#define xstr(x) str(x)
+
+int
+main (void)
+{
+  assert (strcmp (xstr(countof), "_Countof") == 0);
+}
-- 
2.49.0



[PATCH v25 3/3] c: Add -Wpedantic diagnostic for _Countof

2025-05-21 Thread Alejandro Colomar
It has been standardized in C2y.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_sizeof_or_countof_expression):
Add -Wpedantic diagnostic for _Countof in <= C23 mode.

gcc/testsuite/ChangeLog:

* gcc.dg/countof-compat.c: New test.
* gcc.dg/countof-no-compat.c: New test.
* gcc.dg/countof-pedantic.c: New test.
* gcc.dg/countof-pedantic-errors.c: New test.

Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-parser.cc  | 4 
 gcc/testsuite/gcc.dg/countof-compat.c  | 8 
 gcc/testsuite/gcc.dg/countof-no-compat.c   | 5 +
 gcc/testsuite/gcc.dg/countof-pedantic-errors.c | 8 
 gcc/testsuite/gcc.dg/countof-pedantic.c| 8 
 5 files changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/countof-compat.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-no-compat.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic-errors.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic.c

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 733cb312341e..98a0c5632805 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -10649,6 +10649,10 @@ c_parser_sizeof_or_countof_expression (c_parser 
*parser, enum rid rid)
 
   start = c_parser_peek_token (parser)->location;
 
+  if (rid == RID_COUNTOF)
+pedwarn_c23 (start, OPT_Wpedantic,
+"ISO C does not support %qs before C23", op_name);
+
   c_parser_consume_token (parser);
   c_inhibit_evaluation_warnings++;
   if (rid == RID_COUNTOF)
diff --git a/gcc/testsuite/gcc.dg/countof-compat.c 
b/gcc/testsuite/gcc.dg/countof-compat.c
new file mode 100644
index ..ab5b4ae6219c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-compat.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors -Wc23-c2y-compat" } */
+
+#include 
+
+int a[1];
+int b[countof(a)];
+int c[_Countof(a)];  /* { dg-warning "ISO C does not support" } */
diff --git a/gcc/testsuite/gcc.dg/countof-no-compat.c 
b/gcc/testsuite/gcc.dg/countof-no-compat.c
new file mode 100644
index ..4a244cf222f6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-no-compat.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors -Wno-c23-c2y-compat" } */
+
+int a[1];
+int b[_Countof(a)];
diff --git a/gcc/testsuite/gcc.dg/countof-pedantic-errors.c 
b/gcc/testsuite/gcc.dg/countof-pedantic-errors.c
new file mode 100644
index ..5d5bedbe1f7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-pedantic-errors.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+#include 
+
+int a[1];
+int b[countof(a)];
+int c[_Countof(a)];  /* { dg-error "ISO C does not support" } */
diff --git a/gcc/testsuite/gcc.dg/countof-pedantic.c 
b/gcc/testsuite/gcc.dg/countof-pedantic.c
new file mode 100644
index ..408dc6f93667
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-pedantic.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic" } */
+
+#include 
+
+int a[1];
+int b[countof(a)];
+int c[_Countof(a)];  /* { dg-warning "ISO C does not support" } */
-- 
2.49.0



[PATCH v25 1/3] c: Add _Countof operator

2025-05-21 Thread Alejandro Colomar
This operator is similar to sizeof but can only be applied to an array,
and returns its number of elements.

FUTURE DIRECTIONS:

-  We should make it work with array parameters to functions,
   and somehow magically return the number of elements of the array,
   regardless of it being really a pointer.

Link: 
Link: 
Link: 
Link: 

Link: 
Link: 
Link: 
Link: 
Link: 
Link: 
Link: 
Link: 

gcc/ChangeLog:

* doc/extend.texi: Document _Countof operator.

gcc/c-family/ChangeLog:

* c-common.h (enum rid): Add RID_COUNTOF.
(c_countof_type): New function prototype.
* c-common.def (COUNTOF_EXPR): New tree.
* c-common.cc (c_common_reswords): Add RID_COUNTOF entry.
(c_countof_type): New function.

gcc/c/ChangeLog:

* c-tree.h (in_countof): Add global variable declaration.
(c_expr_countof_expr): Add function prototype.
(c_expr_countof_type): Add function prototype.
* c-decl.cc (start_struct, finish_struct): Add support for
_Countof.
(start_enum, finish_enum): Add support for _Countof.
* c-parser.cc (c_parser_sizeof_expression): New macro.
(c_parser_countof_expression): New macro.
(c_parser_sizeof_or_countof_expression): Rename function and add
support for _Countof.
(c_parser_unary_expression): Add RID_COUNTOF entry.
* c-typeck.cc (in_countof): Add global variable.
(build_external_ref): Add support for _Countof.
(record_maybe_used_decl): Add support for _Countof.
(pop_maybe_used): Add support for _Countof.
(is_top_array_vla): New function.
(c_expr_countof_expr, c_expr_countof_type): New functions.

gcc/testsuite/ChangeLog:

* gcc.dg/countof-compile.c: New test.
* gcc.dg/countof-vla.c: New test.
* gcc.dg/countof-vmt.c: New test.
* gcc.dg/countof-zero-compile.c: New test.
* gcc.dg/countof-zero.c: New test.
* gcc.dg/countof.c: New test.

Suggested-by: Xavier Del Campo Romero 
Co-authored-by: Martin Uecker 
Acked-by: "James K. Lowden" 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc|  26 
 gcc/c-family/c-common.def   |   3 +
 gcc/c-family/c-common.h |   2 +
 gcc/c/c-decl.cc |  24 ++--
 gcc/c/c-parser.cc   |  73 +---
 gcc/c/c-tree.h  |   4 +
 gcc/c/c-typeck.cc   | 115 +-
 gcc/doc/extend.texi |  30 +
 gcc/testsuite/gcc.dg/countof-compile.c  | 124 
 gcc/testsuite/gcc.dg/countof-vla.c  |  35 ++
 gcc/testsuite/gcc.dg/countof-vmt.c  |  20 
 gcc/testsuite/gcc.dg/countof-zero-compile.c |  38 ++
 gcc/testsuite/gcc.dg/countof-zero.c |  31 +
 gcc/testsuite/gcc.dg/countof.c  | 120 +++
 14 files changed, 616 insertions(+), 29 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/countof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-vmt.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-zero-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-zero.c
 create mode 100644 gcc/testsuite/gcc.dg/countof.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 587d76461e9e..f71cb2652d5a 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -394,6 +394,7 @@ const struct c_common_resword c_common_reswords[] =
 {
   { "_Alignas",RID_ALIGNAS,   D_CONLY },
   { "_Alignof",RID_ALIGNOF,   D_CONLY },
+  { "_Countof",RID_COUNTOF,   D_CONLY },
   { "_Atomic", RID_ATOMIC,D_CONLY },
   { "_BitInt", RID_BITINT,D_CONLY },
   { "_Bool",   RID_BOOL,  D_CONLY },
@@ -4080,6 +4081,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement the _Countof keyword:
+   Return the number of elements of an array.  */
+
+tree
+c_countof_type (location_t loc, tree type)
+{
+  enum tree_code type_code;
+
+  type_code = TREE_CODE (type);
+  if (type_code != ARRAY_TYPE)

[PATCH] testsuite: RISC-V: Update the cset-sext-sfb/zba-slliuw test optimization level.

2025-05-21 Thread Dongyan Chen
Failed testcases occurred in the regression test of gcc: cset-sext-sfb.c failed
the -Oz test, and zba-slliuw.c failed the -Og test.
This patch solves the problem by skipping the optimization.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/cset-sext-sfb.c: Skip for -Oz.
* gcc.target/riscv/zba-slliuw.c: Skip for -Og.

---
 gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c | 2 +-
 gcc/testsuite/gcc.target/riscv/zba-slliuw.c| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c 
b/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c
index 4a8477e81621..3d46306f1e19 100644
--- a/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c
+++ b/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c
@@ -1,5 +1,5 @@
 /* { dg-do compile { target { ! riscv_abi_e } } } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" "-Os" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" "-Os" "-Oz" } } */
 /* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 
-fno-ssa-phiopt -fdump-rtl-ce1" { target { rv32 } } } */
 /* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 
-fno-ssa-phiopt -fdump-rtl-ce1" { target { rv64 } } } */

diff --git a/gcc/testsuite/gcc.target/riscv/zba-slliuw.c 
b/gcc/testsuite/gcc.target/riscv/zba-slliuw.c
index c123bb5ece0f..69914db95a2c 100644
--- a/gcc/testsuite/gcc.target/riscv/zba-slliuw.c
+++ b/gcc/testsuite/gcc.target/riscv/zba-slliuw.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-march=rv64gc_zba_zbs -mabi=lp64" } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */

 long
 foo (long i)
--
2.43.0



Re: [PATCH] RISC-V: Default-initialize variable.

2025-05-21 Thread Kito Cheng
LGTM

On Wed, May 21, 2025 at 9:49 PM Robin Dapp  wrote:
>
> Hi,
>
> this patch initializes saved_vxrm_mode to VXRM_MODE_NONE.  This is a
> warning (but no error) when building the compiler so better fix it.
>
> Regtested on rv64gcv_zvl512b.  Going to commit as obvious if the CI
> is happy.
>
> Regards
>  Robin
>
> gcc/ChangeLog:
>
> * config/riscv/riscv.cc (singleton_vxrm_need): Init
> saved_vxrm_mode.
> ---
>  gcc/config/riscv/riscv.cc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 0b10842d176..8849b2c05c1 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -12298,7 +12298,7 @@ singleton_vxrm_need (void)
>/* Walk the IL noting if VXRM is needed and if there's more than one
>   mode needed.  */
>bool found = false;
> -  int saved_vxrm_mode;
> +  int saved_vxrm_mode = VXRM_MODE_NONE;
>for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
>  {
>if (!INSN_P (insn) || DEBUG_INSN_P (insn))
> --
> 2.49.0
>


Re: [PATCH] RISC-V: Support CPUs in -march.

2025-05-21 Thread Kito Cheng
I could imagine that is a simpler way to set the march since the march
string becomes terribly long - we have an arch string more than 300
char...so I support this, although I think this should be discuss with
LLVM community, but I think it's fine to accept as a GCC extension.

So LGTM, go ahead to the trunk, and I will raise this topic in the
next LLVM sync up meeting.

On Wed, May 21, 2025 at 9:51 PM Robin Dapp  wrote:
>
> Hi,
>
> This patch allows an -march string like
>
>   -march=sifive-p670
>
> in order to allow overriding a previous -march in a simple way.
>
> Suppose we have a Makefile that specifies -march=rv64gc by default.
> A user-specified -mcpu=sifive-p670 would be after the -march in the
> options string and thus only set -mtune=sifive-p670 (as -mcpu does not
> override a previously specified -march or -mtune).
>
> So if we wanted to override we would need to specify the full, lengthy
> -march=rv64gcv_... string instead of a simple -mcpu=...
>
> Therefore this patch always first tries to interpret -march= as CPU
> string.  If it is a supported CPU we use its march properties and let it
> override previously specified options.  Otherwise the behavior is as
> before.  This enables the "last-specified option wins" behavior GCC
> normally employs.
>
> Note that -march does not imply -mtune like on x86 or other targets.
> So an -march=CPU won't override a previously specified -mtune=other-CPU.
>
> I haven't spent a lot of time on this (basically stopped once it looked
> like it's working) and was hoping somebody who touched these riscv parts
> will notice glaring holes :)
>
> Regtested on rv64gcv_zvl512b.
>
> Regards
>  Robin
>
> gcc/ChangeLog:
>
> * common/config/riscv/riscv-common.cc 
> (riscv_subset_list::parse_base_ext):
> Adjust error message.
> (riscv_handle_option): Parse as CPU string first.
> (riscv_expand_arch): Ditto.
> * doc/invoke.texi: Document.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/arch-56.c: New test.
> ---
>  gcc/common/config/riscv/riscv-common.cc  | 19 ---
>  gcc/doc/invoke.texi  |  2 +-
>  gcc/testsuite/gcc.target/riscv/arch-56.c | 13 +
>  3 files changed, 26 insertions(+), 8 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/arch-56.c
>
> diff --git a/gcc/common/config/riscv/riscv-common.cc 
> b/gcc/common/config/riscv/riscv-common.cc
> index c843393998c..a6d8763f032 100644
> --- a/gcc/common/config/riscv/riscv-common.cc
> +++ b/gcc/common/config/riscv/riscv-common.cc
> @@ -980,8 +980,9 @@ riscv_subset_list::parse_base_ext (const char *p)
>  }
>else
>  {
> -  error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, rv64 
> "
> -   "or Profiles", m_arch);
> +  error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, 
> rv64,"
> +   " a supported RVA profile or refer to a supported CPU",
> +   m_arch);
>return NULL;
>  }
>
> @@ -1708,7 +1709,8 @@ riscv_handle_option (struct gcc_options *opts,
>switch (decoded->opt_index)
>  {
>  case OPT_march_:
> -  riscv_parse_arch_string (decoded->arg, opts, loc);
> +  if (riscv_find_cpu (decoded->arg) == NULL)
> +   riscv_parse_arch_string (decoded->arg, opts, loc);
>return true;
>
>  case OPT_mcpu_:
> @@ -1725,15 +1727,18 @@ riscv_handle_option (struct gcc_options *opts,
>  /* Expand arch string with implied extensions.  */
>
>  const char *
> -riscv_expand_arch (int argc ATTRIBUTE_UNUSED,
> +riscv_expand_arch (int argc,
>const char **argv)
>  {
>gcc_assert (argc == 1);
>location_t loc = UNKNOWN_LOCATION;
> -  riscv_parse_arch_string (argv[0], NULL, loc);
> +  /* Try to interpret the arch as CPU first.  */
> +  const char *arch_str = riscv_expand_arch_from_cpu (argc, argv);
> +  if (!strlen (arch_str))
> +riscv_parse_arch_string (argv[0], NULL, loc);
>const std::string arch = riscv_arch_str (false);
> -  if (arch.length())
> -return xasprintf ("-march=%s", arch.c_str());
> +  if (arch.length ())
> +return xasprintf ("-march=%s", arch.c_str ());
>else
>  return "";
>  }
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 52cfdb99871..2368509034f 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -1268,7 +1268,7 @@ See RS/6000 and PowerPC Options.
>  -mfence-tso  -mno-fence-tso
>  -mdiv  -mno-div
>  -misa-spec=@var{ISA-spec-string}
> --march=@var{ISA-string|Profiles|Profiles_ISA-string}
> +-march=@var{ISA-string|Profiles|Profiles_ISA-string|CPU/processor string}
>  -mtune=@var{processor-string}
>  -mpreferred-stack-boundary=@var{num}
>  -msmall-data-limit=@var{N-bytes}
> diff --git a/gcc/testsuite/gcc.target/riscv/arch-56.c 
> b/gcc/testsuite/gcc.target/riscv/arch-56.c
> new file mode 100644
> index 000..c0b43b74a49
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/arch-56.c
> @@ -0,0 +1,13 @@
> +/* Check 

[PATCH v4 1/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Christopher Bazley
Commit 0547dbb725b reduced the number of cases in which
union padding bits are zeroed when the relevant language
standard does not strictly require it, unless gcc was
invoked with -fzero-init-padding-bits=unions or
-fzero-init-padding-bits=all in order to explicitly
request zeroing of padding bits.

This commit adds a closely related warning,
-Wzero-init-padding-bits=, which is intended to help
programmers to find code that might now need to be
rewritten or recompiled with
-fzero-init-padding-bits=unions or
-fzero-init-padding-bits=all in order to replicate
the behaviour that it had when compiled by older
versions of GCC. It can also be used to find struct
padding that was never previously guaranteed to be
zero initialized and still isn't unless GCC is
invoked with -fzero-init-padding-bits=all.

The new warning can be set to the same three states
as -fzero-init-padding-bits ('standard', 'unions'
or 'all') and has the same default value ('standard').

The two options interact as follows:

 f: standard  f: unions   f: all
w: standard X X X
w: unions   U X X
w: all  A S X

X = No warnings about padding
U = Warnings about padding of unions.
S = Warnings about padding of structs.
A = Warnings about padding of structs and unions.

The level of optimisation and whether or not the
entire initializer is dropped to memory can both
affect whether warnings are produced when compiling
a given program. This is intentional, since tying
the warnings more closely to the relevant language
standard would require a very different approach
that would still be target-dependent, might impose
an unacceptable burden on programmers, and would
risk not satisfying the intended use-case (which
is closely tied to a specific optimisation).

gcc/ChangeLog:

* common.opt: Add Wzero-init-padding-bits=.
* doc/invoke.texi: Document Wzero-init-padding-bits=.
* expr.cc (categorize_ctor_elements_1): Update new struct type
ctor_completeness instead of an integer to indicate presence of
padding or missing fields in a constructor. Instead of setting -1
upon discovery of padding bits in both structs and unions,
set separate flags to indicate the type of padding bits.
(categorize_ctor_elements): Update the type and documentation of
the p_complete parameter.
(mostly_zeros_p): Use new struct type ctor_completeness when
calling categorize_ctor_elements.
(all_zeros_p): Use new struct type ctor_completeness when
calling categorize_ctor_elements.
* expr.h (struct ctor_completeness): New struct type to replace an
an integer that could take the value -1 ('all fields are
initialized, but there's padding'), 0 ('fields are missing') or
1 ('all fields are initialized, and there's no padding'). Named
bool members make the code easier to understand and make room to
disambiguate struct padding bits from union padding bits.
(categorize_ctor_elements): Update the function declaration to use
the new struct type in the last parameter declaration.
* gimplify.cc (gimplify_init_constructor): Replace use of
complete_p != 0 ('all fields are initialized') with !sparse,
replace use of complete == 0 ('fields are missing') with sparse, and
replace use of complete <= 0 ('fields are missing' or 'all fields are
initialized, but there's padding') with sparse || padded_union or
padded_non_union. Trigger new warnings if storage for the object
is not zeroed but padded_union or padded_non_union is set
(because this combination implies possible non-zero padding bits).

gcc/testsuite/ChangeLog:

* gcc.dg/c23-empty-init-warn-1.c: New test.
* gcc.dg/c23-empty-init-warn-10.c: New test.
* gcc.dg/c23-empty-init-warn-11.c: New test.
* gcc.dg/c23-empty-init-warn-12.c: New test.
* gcc.dg/c23-empty-init-warn-13.c: New test.
* gcc.dg/c23-empty-init-warn-14.c: New test.
* gcc.dg/c23-empty-init-warn-15.c: New test.
* gcc.dg/c23-empty-init-warn-16.c: New test.
* gcc.dg/c23-empty-init-warn-17.c: New test.
* gcc.dg/c23-empty-init-warn-2.c: New test.
* gcc.dg/c23-empty-init-warn-3.c: New test.
* gcc.dg/c23-empty-init-warn-4.c: New test.
* gcc.dg/c23-empty-init-warn-5.c: New test.
* gcc.dg/c23-empty-init-warn-6.c: New test.
* gcc.dg/c23-empty-init-warn-7.c: New test.
* gcc.dg/c23-empty-init-warn-8.c: New test.
* gcc.dg/c23-empty-init-warn-9.c: New test.
* gcc.dg/gnu11-empty-init-warn-1.c: New test.
* gcc.dg/gnu11-empty-init-warn-10.c: New test.
* gcc.dg/gnu11-empty-init-warn-11.c: New test.

[PATCH] libstdc++: Fix vector(from_range_t, R&&) for exceptions [PR120367]

2025-05-21 Thread Jonathan Wakely
Because this constructor delegates to vector(a) the object has been
fully constructed and the destructor will run if an exception happens.
That means we need to set _M_finish == _M_start so that the destructor
doesn't try to destroy any elements.

libstdc++-v3/ChangeLog:

PR libstdc++/120367
* include/bits/stl_vector.h (_M_range_initialize): Initialize
_M_impl._M_finish.
* testsuite/23_containers/vector/cons/from_range.cc: Check with
a type that throws on construction.
exceptions during construction.
---

Tested x86_64-linux.

 libstdc++-v3/include/bits/stl_vector.h|  1 +
 .../23_containers/vector/cons/from_range.cc   | 22 +++
 2 files changed, 23 insertions(+)

diff --git a/libstdc++-v3/include/bits/stl_vector.h 
b/libstdc++-v3/include/bits/stl_vector.h
index 57680b7bbcf3..43b913da778d 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1971,6 +1971,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
  pointer __start = this->_M_impl._M_start =
this->_M_allocate(_S_check_init_len(__n, _M_get_Tp_allocator()));
+ this->_M_impl._M_finish = __start;
  this->_M_impl._M_end_of_storage = __start + __n;
  this->_M_impl._M_finish
  = std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last,
diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc 
b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
index 7a62645283d2..3784b9cd66ad 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
@@ -106,8 +106,30 @@ test_constexpr()
   return true;
 }
 
+void
+test_pr120367()
+{
+#ifdef __cpp_exceptions
+  struct X
+  {
+X(int) { throw 1; } // Cannot successfully construct an X.
+~X() { VERIFY(false); } // So should never need to destroy one.
+  };
+
+  try
+  {
+int i[1]{};
+std::vector v(std::from_range, i);
+  }
+  catch (int)
+  {
+  }
+#endif
+}
+
 int main()
 {
   test_ranges();
   static_assert( test_constexpr() );
+  test_pr120367();
 }
-- 
2.49.0



Re: [PATCH 2/2] RISC-V:Add testcases for signed .SAT_ADD IMM form 1 with IMM = -1.

2025-05-21 Thread Jeff Law




On 5/20/25 8:39 PM, Li, Pan2 wrote:

Thanks Jeff.


So for the tests, why are we forcing matching of the assembly code for
the entire function?  That must makes for a fragile test as we may
change various aspects of code generation over time.



If the point of the patch is to detect SAT_ADD in more cases, then the
better and more stable test is to verify the existence of SAT_ADD the
appropriate number of times in the .optimized dump.



IMHO we really don't want this kind of whole function assembly matching.



Pan, do you have any further comments here?  Do you have strong opinions
on whether or not we want to be doing this kind of assembly output
testing or not?


Unlike vector we have vsadd for asm check, the scalar SAT_* will expand to 
sorts of branchless codes.
So I add the function body check with no-schedule-insns. However, we have run 
test for the same
scenarios which may also indicates the code-gen for SAT_ADD is correct.

Given that it is totally OK to drop that whole function check. How about keep 
this series as is and I
can help to drop all the similar check of scalar in another thread?

Sure.  I can live with that.

One of the things we probably want to do (but probably not that high 
priority) is see how those sequences behave when zicond is turned on, 
particularly since zicond got included in rva23.

Jeff


Re: [PATCH V4] RISC-V: Prevent speculative vsetvl insn scheduling

2025-05-21 Thread Jeff Law




On 5/20/25 4:05 PM, Edwin Lu wrote:

The instruction scheduler appears to be speculatively hoisting vsetvl
insns outside of their basic block without checking for data
dependencies. This resulted in a situation where the following occurs

 vsetvli a5,a1,e32,m1,tu,ma
 vle32.v v2,0(a0)
 sub a1,a1,a5 <-- a1 potentially set to 0
 sh2add  a0,a5,a0
 vfmacc.vv   v1,v2,v2
 vsetvli a5,a1,e32,m1,tu,ma <-- incompatible vinfo. update vl to 0
 beq a1,zero,.L12 <-- check if avl is 0

This patch would essentially delay the vsetvl update to after the branch
to prevent unnecessarily updating the vinfo at the end of a basic block.

PR 117974

gcc/ChangeLog:

* config/riscv/riscv.cc (struct riscv_tune_param): Add tune
  param.
(riscv_sched_can_speculate_insn): Implement.
(TARGET_SCHED_CAN_SPECULATE_INSN): Implement.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/vsetvl/pr117974.c: New test.
LGTM.  If you could do a quick sentence or two in invoke.texi it'd be 
helpful.  There's probably already examples of other params in there.


jeff



Re: [PATCH V4] RISC-V: Prevent speculative vsetvl insn scheduling

2025-05-21 Thread Jeff Law




On 5/20/25 4:05 PM, Edwin Lu wrote:

The instruction scheduler appears to be speculatively hoisting vsetvl
insns outside of their basic block without checking for data
dependencies. This resulted in a situation where the following occurs

 vsetvli a5,a1,e32,m1,tu,ma
 vle32.v v2,0(a0)
 sub a1,a1,a5 <-- a1 potentially set to 0
 sh2add  a0,a5,a0
 vfmacc.vv   v1,v2,v2
 vsetvli a5,a1,e32,m1,tu,ma <-- incompatible vinfo. update vl to 0
 beq a1,zero,.L12 <-- check if avl is 0

This patch would essentially delay the vsetvl update to after the branch
to prevent unnecessarily updating the vinfo at the end of a basic block.

PR 117974

gcc/ChangeLog:

* config/riscv/riscv.cc (struct riscv_tune_param): Add tune
  param.
(riscv_sched_can_speculate_insn): Implement.
(TARGET_SCHED_CAN_SPECULATE_INSN): Implement.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/vsetvl/pr117974.c: New test.

Though note it failed CI on the new test:


FAIL: gcc.target/riscv/rvv/vsetvl/pr117974.c   -O3 -fomit-frame-pointer 
-funroll-loops -fpeel-loops -ftracer -finline-functions   scan-assembler-times 
beq\\s+[a-x0-9]+,zero,.L12\\s+vsetvli 3


So something probably needs a minor adjustment.


Jeff


Re: [PATCH 0/3] Redirect to specific target based on TARGET_VERSION_COMPATIBLE

2025-05-21 Thread Jeff Law




On 4/14/25 5:34 AM, Yangyu Chen wrote:




On 14 Apr 2025, at 19:06, Alfie Richards  wrote:

Hi Yangyu,

This looks great with what we discussed previously.

I have a very similar patch that implements a slightly stronger optimisation 
that I was about to send. It makes use of information if the caller is 
versioned. I will share this with you shortly and we can work out what we wish 
to use?


Sure! Thank you!
So do we have a sense of which of the two approaches we want to try and 
move forward?   Or to put it another way, are your patches still useful 
and if so, do we have the most recent versions posted for review?


Jeff



Re: Fix PR 118541, do not generate unordered fp cmoves for IEEE compares

2025-05-21 Thread Michael Meissner
I have posted a new version of the patch at:
https://gcc.gnu.org/pipermail/gcc-patches/2025-May/684473.html

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meiss...@linux.ibm.com


Re: [PATCH 2/2] aarch64: Fold lsl+lsr+orr to rev for half-width shifts

2025-05-21 Thread Dhruv Chawla

On 20/05/25 16:35, Richard Sandiford wrote:

External email: Use caution opening links or attachments


Dhruv Chawla  writes:

On 06/05/25 21:57, Richard Sandiford wrote:

External email: Use caution opening links or attachments


Dhruv Chawla  writes:

This patch modifies the intrinsic expanders to expand svlsl and svlsr to
unpredicated forms when the predicate is a ptrue. It also folds the
following pattern:

lsl , , 
lsr , , 
orr , , 

to:

revb/h/w , 

when the shift amount is equal to half the bitwidth of the 
register.

Bootstrapped and regtested on aarch64-linux-gnu.

Signed-off-by: Dhruv Chawla 

gcc/ChangeLog:

* config/aarch64/aarch64-sve-builtins-base.cc
(svlsl_impl::expand): Define.
(svlsr_impl): New class.
(svlsr_impl::fold): Define.
(svlsr_impl::expand): Likewise.
* config/aarch64/aarch64-sve.md
(*v_rev): New pattern.
(*v_revvnx8hi): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/sve/shift_rev_1.c: New test.
* gcc.target/aarch64/sve/shift_rev_2.c: Likewise.
---
   .../aarch64/aarch64-sve-builtins-base.cc  | 33 +++-
   gcc/config/aarch64/aarch64-sve.md | 49 +++
   .../gcc.target/aarch64/sve/shift_rev_1.c  | 83 +++
   .../gcc.target/aarch64/sve/shift_rev_2.c  | 63 ++
   4 files changed, 227 insertions(+), 1 deletion(-)
   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/shift_rev_1.c
   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/shift_rev_2.c

diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc 
b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 927c5bbae21..938d010e11b 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -2086,6 +2086,37 @@ public:
 {
   return f.fold_const_binary (LSHIFT_EXPR);
 }
+
+  rtx expand (function_expander &e) const override
+  {
+tree pred = TREE_OPERAND (e.call_expr, 3);
+tree shift = TREE_OPERAND (e.call_expr, 5);
+if (is_ptrue (pred, GET_MODE_UNIT_SIZE (e.result_mode ()))
+ && uniform_integer_cst_p (shift))
+  return e.use_unpred_insn (e.direct_optab_handler (ashl_optab));
+return rtx_code_function::expand (e);
+  }
+};
+
+class svlsr_impl : public rtx_code_function
+{
+public:
+  CONSTEXPR svlsr_impl () : rtx_code_function (LSHIFTRT, LSHIFTRT) {}
+
+  gimple *fold (gimple_folder &f) const override
+  {
+return f.fold_const_binary (RSHIFT_EXPR);
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+tree pred = TREE_OPERAND (e.call_expr, 3);
+tree shift = TREE_OPERAND (e.call_expr, 5);
+if (is_ptrue (pred, GET_MODE_UNIT_SIZE (e.result_mode ()))
+ && uniform_integer_cst_p (shift))
+  return e.use_unpred_insn (e.direct_optab_handler (lshr_optab));
+return rtx_code_function::expand (e);
+  }
   };

   class svmad_impl : public function_base
@@ -3572,7 +3603,7 @@ FUNCTION (svldnt1, svldnt1_impl,)
   FUNCTION (svlen, svlen_impl,)
   FUNCTION (svlsl, svlsl_impl,)
   FUNCTION (svlsl_wide, shift_wide, (ASHIFT, UNSPEC_ASHIFT_WIDE))
-FUNCTION (svlsr, rtx_code_function, (LSHIFTRT, LSHIFTRT))
+FUNCTION (svlsr, svlsr_impl, )
   FUNCTION (svlsr_wide, shift_wide, (LSHIFTRT, UNSPEC_LSHIFTRT_WIDE))
   FUNCTION (svmad, svmad_impl,)
   FUNCTION (svmax, rtx_code_function, (SMAX, UMAX, UNSPEC_COND_FMAX,


I'm hoping that this won't be necessary after the changes I mentioned
in patch 1.  The expander should handle everything itself.


Hi,

Unfortunately this still turned out to be required - removing the changes to the expander would cause a 
call to @aarch64_pred_ which would bypass the whole 
v3 pattern.


I think we should make @aarch64_pred_ drop the predicate
for constant shifts, just like v3 avoids creating a predicate
for constant shifts.  Also, since the idea of patch 1 is to "lower" constant
shifts to the unpredicated form as soon as possible, rather than after
reload, the split in @aarch64_pred_ should no longer depend
on reload_completed.

And: my bad, but I realised after sending the review for the first patch
that v3 can just test CONSTANT_P, since the predicate
already enforces the range.

Putting that together, the tests seem to work for me with the patch below,
where the aarch64-sve.md change would be part of patch 1.



Nice, thanks a lot! I've applied the patches and it seems to work well :)


[...]

I can't remember if we discussed this before, but I think we could extend
this to partial vector modes (rather than SVE_FULL...) by using the
GET_MODE_UNIT_SIZE of the container mode.


Hmm, I am not sure how this would work. This could be a follow-up patch.


Sure, that's fine.


[...]

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/shift_rev_1.c 
b/gcc/testsuite/gcc.target/aarch64/sve/shift_rev_1.c
new file mode 100644
index 000..3a30f80d152
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/shift_rev_1.c
@@ -0,0 

[PATCH v4 1/2] aarch64: Match unpredicated shift patterns for ADR, SRA and ADDHNB instructions

2025-05-21 Thread dhruvc
From: Dhruv Chawla 

This patch modifies the shift expander to immediately lower constant
shifts without unspec. It also modifies the ADR, SRA and ADDHNB patterns
to match the lowered forms of the shifts, as the predicate register is
not required for these instructions.

Bootstrapped and regtested on aarch64-linux-gnu.

Signed-off-by: Dhruv Chawla 
Co-authored-by: Richard Sandiford 

gcc/ChangeLog:

* gcc/config/aarch64/aarch64-sve.md (@aarch64_adr_shift):
Match lowered form of ashift.
(*aarch64_adr_shift): Likewise.
(*aarch64_adr_shift_sxtw): Likewise.
(*aarch64_adr_shift_uxtw): Likewise.
(3): Check amount instead of operands[2] in
aarch64_sve_shift_operand.
(v3): Generate unpredicated shifts for constant
operands.
(@aarch64_pred_): Convert to a define_expand.
(*aarch64_pred_): Create define_insn_and_split pattern
from @aarch64_pred_.
(*post_ra_v_ashl3): Rename to ...
(aarch64_vashl3_const): ... this and remove reload requirement.
(*post_ra_v_3): Rename to ...
(aarch64_v3_const): ... this and remove reload
requirement.
* gcc/config/aarch64/aarch64-sve2.md
(@aarch64_sve_add_): Match lowered form of
SHIFTRT.
(*aarch64_sve2_sra): Likewise.
(*bitmask_shift_plus): Match lowered form of lshiftrt.
---
 gcc/config/aarch64/aarch64-sve.md  | 119 +++--
 gcc/config/aarch64/aarch64-sve2.md |  46 ---
 2 files changed, 75 insertions(+), 90 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index bf7569f932b..e1ec778b10d 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -4234,80 +4234,57 @@
 (define_expand "@aarch64_adr_shift"
   [(set (match_operand:SVE_FULL_SDI 0 "register_operand")
(plus:SVE_FULL_SDI
- (unspec:SVE_FULL_SDI
-   [(match_dup 4)
-(ashift:SVE_FULL_SDI
-  (match_operand:SVE_FULL_SDI 2 "register_operand")
-  (match_operand:SVE_FULL_SDI 3 "const_1_to_3_operand"))]
-   UNSPEC_PRED_X)
+ (ashift:SVE_FULL_SDI
+   (match_operand:SVE_FULL_SDI 2 "register_operand")
+   (match_operand:SVE_FULL_SDI 3 "const_1_to_3_operand"))
  (match_operand:SVE_FULL_SDI 1 "register_operand")))]
   "TARGET_SVE && TARGET_NON_STREAMING"
-  {
-operands[4] = CONSTM1_RTX (mode);
-  }
 )
 
-(define_insn_and_rewrite "*aarch64_adr_shift"
+(define_insn "*aarch64_adr_shift"
   [(set (match_operand:SVE_24I 0 "register_operand" "=w")
(plus:SVE_24I
- (unspec:SVE_24I
-   [(match_operand 4)
-(ashift:SVE_24I
-  (match_operand:SVE_24I 2 "register_operand" "w")
-  (match_operand:SVE_24I 3 "const_1_to_3_operand"))]
-   UNSPEC_PRED_X)
+ (ashift:SVE_24I
+   (match_operand:SVE_24I 2 "register_operand" "w")
+   (match_operand:SVE_24I 3 "const_1_to_3_operand"))
  (match_operand:SVE_24I 1 "register_operand" "w")))]
   "TARGET_SVE && TARGET_NON_STREAMING"
   "adr\t%0., [%1., %2., lsl %3]"
-  "&& !CONSTANT_P (operands[4])"
-  {
-operands[4] = CONSTM1_RTX (mode);
-  }
 )
 
 ;; Same, but with the index being sign-extended from the low 32 bits.
 (define_insn_and_rewrite "*aarch64_adr_shift_sxtw"
   [(set (match_operand:VNx2DI 0 "register_operand" "=w")
(plus:VNx2DI
- (unspec:VNx2DI
-   [(match_operand 4)
-(ashift:VNx2DI
-  (unspec:VNx2DI
-[(match_operand 5)
- (sign_extend:VNx2DI
-   (truncate:VNx2SI
- (match_operand:VNx2DI 2 "register_operand" "w")))]
-UNSPEC_PRED_X)
-  (match_operand:VNx2DI 3 "const_1_to_3_operand"))]
-   UNSPEC_PRED_X)
+ (ashift:VNx2DI
+   (unspec:VNx2DI
+ [(match_operand 4)
+  (sign_extend:VNx2DI
+(truncate:VNx2SI
+  (match_operand:VNx2DI 2 "register_operand" "w")))]
+UNSPEC_PRED_X)
+   (match_operand:VNx2DI 3 "const_1_to_3_operand"))
  (match_operand:VNx2DI 1 "register_operand" "w")))]
   "TARGET_SVE && TARGET_NON_STREAMING"
   "adr\t%0.d, [%1.d, %2.d, sxtw %3]"
-  "&& (!CONSTANT_P (operands[4]) || !CONSTANT_P (operands[5]))"
+  "&& !CONSTANT_P (operands[4])"
   {
-operands[5] = operands[4] = CONSTM1_RTX (VNx2BImode);
+operands[4] = CONSTM1_RTX (VNx2BImode);
   }
 )
 
 ;; Same, but with the index being zero-extended from the low 32 bits.
-(define_insn_and_rewrite "*aarch64_adr_shift_uxtw"
+(define_insn "*aarch64_adr_shift_uxtw"
   [(set (match_operand:VNx2DI 0 "register_operand" "=w")
(plus:VNx2DI
- (unspec:VNx2DI
-   [(match_operand 5)
-(ashift:VNx2DI
-  (and:VNx2DI
-(match_operand:VNx2DI 2 "register_operand" "w")
-

Re: [PATCH] testsuite: RISC-V: Update the cset-sext-sfb/zba-slliuw test optimization level.

2025-05-21 Thread Dongyan Chen

Thanks. I will pay attention to this.

Dongyan Chen

在 2025/5/22 11:49, Jeff Law 写道:



On 5/21/25 9:16 PM, Dongyan Chen wrote:
Failed testcases occurred in the regression test of gcc: 
cset-sext-sfb.c failed

the -Oz test, and zba-slliuw.c failed the -Og test.
This patch solves the problem by skipping the optimization.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/cset-sext-sfb.c: Skip for -Oz.
* gcc.target/riscv/zba-slliuw.c: Skip for -Og.

THanks.  I've pushed this to the trunk.

Note when disabling tests for particular options it's often helpful to 
indicate why the test doesn't work in a particular configuration.  
It's not strictly necessary, but can simplify the review process if we 
know why something isn't expected to work.


jeff




[PATCH v4 2/2] aarch64: Fold lsl+lsr+orr to rev for half-width shifts

2025-05-21 Thread dhruvc
From: Dhruv Chawla 

This patch folds the following pattern:

  lsl , , 
  lsr , , 
  orr , , 

to:

  revb/h/w , 

when the shift amount is equal to half the bitwidth of the 
register.

Bootstrapped and regtested on aarch64-linux-gnu.

Signed-off-by: Dhruv Chawla 
Co-authored-by: Richard Sandiford 

gcc/ChangeLog:

* expmed.cc (expand_rotate_as_vec_perm): Avoid a no-op move if the
target already provided the result in the expected register.
* config/aarch64/aarch64.cc (aarch64_vectorize_vec_perm_const):
Avoid forcing subregs into fresh registers unnecessarily.
* config/aarch64/aarch64-sve.md: Add define_split for rotate.
(*v_revvnx8hi): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/sve/shift_rev_1.c: New test.
* gcc.target/aarch64/sve/shift_rev_2.c: Likewise.
* gcc.target/aarch64/sve/shift_rev_3.c: Likewise.
---
 gcc/config/aarch64/aarch64-sve.md | 55 
 gcc/config/aarch64/aarch64.cc | 10 ++-
 gcc/expmed.cc |  3 +-
 .../gcc.target/aarch64/sve/shift_rev_1.c  | 83 +++
 .../gcc.target/aarch64/sve/shift_rev_2.c  | 63 ++
 .../gcc.target/aarch64/sve/shift_rev_3.c  | 83 +++
 6 files changed, 294 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/shift_rev_1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/shift_rev_2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/shift_rev_3.c

diff --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index e1ec778b10d..fa431c9c060 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -3317,6 +3317,61 @@
 ;; - REVW
 ;; -
 
+(define_split
+  [(set (match_operand:SVE_FULL_HSDI 0 "register_operand")
+   (rotate:SVE_FULL_HSDI
+ (match_operand:SVE_FULL_HSDI 1 "register_operand")
+ (match_operand:SVE_FULL_HSDI 2 "aarch64_constant_vector_operand")))]
+  "TARGET_SVE && can_create_pseudo_p ()"
+  [(set (match_dup 3)
+   (ashift:SVE_FULL_HSDI (match_dup 1)
+ (match_dup 2)))
+   (set (match_dup 0)
+   (plus:SVE_FULL_HSDI
+ (lshiftrt:SVE_FULL_HSDI (match_dup 1)
+ (match_dup 4))
+ (match_dup 3)))]
+  {
+if (aarch64_emit_opt_vec_rotate (operands[0], operands[1], operands[2]))
+  DONE;
+
+if (!TARGET_SVE2)
+  FAIL;
+
+operands[3] = gen_reg_rtx (mode);
+HOST_WIDE_INT shift_amount =
+  INTVAL (unwrap_const_vec_duplicate (operands[2]));
+int bitwidth = GET_MODE_UNIT_BITSIZE (mode);
+operands[4] = aarch64_simd_gen_const_vector_dup (mode,
+bitwidth - shift_amount);
+  }
+)
+
+;; The RTL combiners are able to combine "ior (ashift, ashiftrt)" to a "bswap".
+;; Match that as well.
+(define_insn_and_split "*v_revvnx8hi"
+  [(parallel
+[(set (match_operand:VNx8HI 0 "register_operand")
+ (bswap:VNx8HI (match_operand 1 "register_operand")))
+ (clobber (match_scratch:VNx8BI 2))])]
+  "TARGET_SVE"
+  "#"
+  ""
+  [(set (match_dup 0)
+   (unspec:VNx8HI
+ [(match_dup 2)
+  (unspec:VNx8HI
+[(match_dup 1)]
+UNSPEC_REVB)]
+ UNSPEC_PRED_X))]
+  {
+if (!can_create_pseudo_p ())
+  operands[2] = CONSTM1_RTX (VNx8BImode);
+else
+  operands[2] = aarch64_ptrue_reg (VNx8BImode);
+  }
+)
+
 ;; Predicated integer unary operations.
 (define_insn "@aarch64_pred_"
   [(set (match_operand:SVE_FULL_I 0 "register_operand")
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 1da615c8955..7cdd5fda903 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -27067,11 +27067,17 @@ aarch64_vectorize_vec_perm_const (machine_mode vmode, 
machine_mode op_mode,
   d.op_mode = op_mode;
   d.op_vec_flags = aarch64_classify_vector_mode (d.op_mode);
   d.target = target;
-  d.op0 = op0 ? force_reg (op_mode, op0) : NULL_RTX;
+  d.op0 = op0;
+  if (d.op0 && !register_operand (d.op0, op_mode))
+d.op0 = force_reg (op_mode, d.op0);
   if (op0 && d.one_vector_p)
 d.op1 = copy_rtx (d.op0);
   else
-d.op1 = op1 ? force_reg (op_mode, op1) : NULL_RTX;
+{
+  d.op1 = op1;
+  if (d.op1 && !register_operand (d.op1, op_mode))
+   d.op1 = force_reg (op_mode, d.op1);
+}
   d.testing_p = !target;
 
   if (!d.testing_p)
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 72dbafe5d9f..deb4e48d14f 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -6324,7 +6324,8 @@ expand_rotate_as_vec_perm (machine_mode mode, rtx dst, 
rtx x, rtx amt)
 qimode, perm_dst);
   if (!res)
 return NULL_RTX;
-  emit_move_insn (dst, lowpart_subreg (mode, res, qimode));
+  if (!rtx_equal_p (res, perm_dst

Fix PR 118541 (V3), do not generate unordered fp cmoves for IEEE compares

2025-05-21 Thread Michael Meissner
Fix PR 118541, do not generate unordered fp cmoves for IEEE compares.

This is version 3 of patch.  I re-implemented the patch to just focus on the
generation of the XSCMP{EQ,GT,GE}{DP,QP} instructions.

In bug PR target/118541 on power9, power10, and power11 systems, for the
function:

extern double __ieee754_acos (double);

double
__acospi (double x)
{
  double ret = __ieee754_acos (x) / 3.14;
  return __builtin_isgreater (ret, 1.0) ? 1.0 : ret;
}

GCC currently generates the following code:

Power9  Power10 and Power11
==  ===
bl __ieee754_acos   bl __ieee754_acos@notoc
nop plfd 0,.LC0@pcrel
addis 9,2,.LC2@toc@ha   xxspltidp 12,1065353216
addi 1,1,32 addi 1,1,32
lfd 0,.LC2@toc@l(9) ld 0,16(1)
addis 9,2,.LC0@toc@ha   fdiv 0,1,0
ld 0,16(1)  mtlr 0
lfd 12,.LC0@toc@l(9)xscmpgtdp 1,0,12
fdiv 0,1,0  xxsel 1,0,12,1
mtlr 0  blr
xscmpgtdp 1,0,12
xxsel 1,0,12,1
blr

This is because ifcvt.c optimizes the conditional floating point move to use the
XSCMPGTDP instruction.

However, the XSCMPGTDP instruction will generate an interrupt if one of the
arguments is a signalling NaN and signalling NaNs can generate an interrupt.
The IEEE comparison functions (isgreater, etc.) require that the comparison not
raise an interrupt.

The root cause of this is we allow floating point comparisons to be reversed
(i.e. LT will be reversed to UNGE).  Before power9, this was ok because we only
generated the FCMPU or XSCMPUDP instructions.

But with power9, we can generate the XSCMPEQDP, XSCMPGTDP, or XSCMPGEDP
instructions.  This code now does not convert an unordered compare into an
ordered compare.  Instead, it does the opposite comparison and swaps the
arguments.  I.e. it converts:

r = (a < b) ? c : d;

into:

r = (b >= a) ? c : d;

For the following code:

double
ordered_compare (double a, double b, double c, double d)
{
  return __builtin_isgreater (a, b) ? c : d;
}

/* Verify normal > does generate xscmpgtdp.  */

double
normal_compare (double a, double b, double c, double d)
{
  return a > b ? c : d;
}

with the following patch, GCC generates the following for power9, power10, and
power11:

ordered_compare:
fcmpu 0,1,2
fmr 1,4
bnglr 0
fmr 1,3
blr

normal_compare:
xscmpgtdp 1,1,2
xxsel 1,4,3,1
blr

I have built bootstrap compilers on big endian power9 systems and little endian
power9/power10 systems and there were no regressions.  Can I check this patch
into the GCC trunk, and after a waiting period, can I check this into the active
older branches?

2025-05-21  Michael Meissner  

gcc/

PR target/118541
* config/rs6000/predicates.md (invert_fpmask_comparison_operator):
Delete.
(fpmask_reverse_args_comparison_operator): New predicate.
* config/rs6000/rs6000-proto.h (rs6000_fpmask_reverse_args): New
declaration.
* config/rs6000/rs6000.cc (rs6000_fpmask_reverse_args): New function.
* config/rs6000/rs6000.h (REVERSIBLE_CC_MODE): Do not allow floating
point comparisons to be reversed unless -ffinite-math-only is used.
* config/rs6000/rs6000.md (movcc_p9): Add
comment.
(movcc_invert_p9): Reverse the argument order for
the comparison, and use an unordered comparison, instead of ordered
comparison.
(movcc_invert_p10): Likewise.

gcc/testsuite/

PR target/118541
* gcc.target/powerpc/pr118541.c: New test.

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meiss...@linux.ibm.com


Re: Fix PR 118541 (V6 not V3), do not generate unordered fp cmoves for IEEE compares

2025-05-21 Thread Michael Meissner
I got the version number of the patch wrong.  This patch is something like V6
of the patch, not V3.

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meiss...@linux.ibm.com


[PATCH][RISC-V][PR target/70557] Improve storing 0 to memory on rv32

2025-05-21 Thread Shreya Munnangi
Patch is originally from Siarhei Volkau .

RISC-V has a zero register (x0) which we can use to store zero into memory
without loading the constant into a distinct register. Adjust the
constraints
of the 32-bit movdi_32bit pattern to recognize that we can store 0.0 into
memory using x0 as the source register.

This patch only affects RISC-V. It has been regression tested on
riscv64-elf.
Jeff has also tested this in his tester (riscv64-elf and riscv32-elf) with
no
regressions.

PR target/70557
gcc/
* config/riscv/riscv.md (movdi_32bit): Add "J" constraint to allow
storing 0
directly to memory.
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 0a5899a0f72..ef13a1c7e26 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2573,8 +2573,8 @@
 })
 
 (define_insn "*movdi_32bit"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,  
*f,*f,*r,*f,*m,r")
-   (match_operand:DI 1 "move_operand" " 
r,i,m,r,*J*r,*m,*f,*f,*f,vp"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,  
*f,*f,*r,*f,*m,r")
+   (match_operand:DI 1 "move_operand" " 
r,i,m,rJ,*J*r,*m,*f,*f,*f,vp"))]
   "!TARGET_64BIT
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"


Re: [PATCH] testsuite: RISC-V: Update the cset-sext-sfb/zba-slliuw test optimization level.

2025-05-21 Thread Jeff Law




On 5/21/25 9:16 PM, Dongyan Chen wrote:

Failed testcases occurred in the regression test of gcc: cset-sext-sfb.c failed
the -Oz test, and zba-slliuw.c failed the -Og test.
This patch solves the problem by skipping the optimization.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/cset-sext-sfb.c: Skip for -Oz.
* gcc.target/riscv/zba-slliuw.c: Skip for -Og.

THanks.  I've pushed this to the trunk.

Note when disabling tests for particular options it's often helpful to 
indicate why the test doesn't work in a particular configuration.  It's 
not strictly necessary, but can simplify the review process if we know 
why something isn't expected to work.


jeff



Re: [PATCH v2 1/6] libstdc++: Implement layout_left from mdspan.

2025-05-21 Thread Tomasz Kaminski
On Wed, May 21, 2025 at 10:20 AM Luc Grosheintz 
wrote:

>
>
> On 5/21/25 08:29, Tomasz Kaminski wrote:
> > On Tue, May 20, 2025 at 3:16 PM Luc Grosheintz  >
> > wrote:
> >
> >> Implements the parts of layout_left that don't depend on any of the
> >> other layouts.
> >>
> >> libstdc++-v3/ChangeLog:
> >>
> >>  * include/std/mdspan (layout_left): New class.
> >>
> >> Signed-off-by: Luc Grosheintz 
> >> ---
> >>   libstdc++-v3/include/std/mdspan | 309 +++-
> >>   1 file changed, 308 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/libstdc++-v3/include/std/mdspan
> >> b/libstdc++-v3/include/std/mdspan
> >> index 47cfa405e44..d90fed57a19 100644
> >> --- a/libstdc++-v3/include/std/mdspan
> >> +++ b/libstdc++-v3/include/std/mdspan
> >> @@ -144,6 +144,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>{ return __exts[__i]; });
> >>}
> >>
> >> +   static constexpr span
> >> +   _S_static_subextents(size_t __begin, size_t __end) noexcept
> >> +   {
> >> + return {_Extents.data() + __begin, _Extents.data() + __end};
> >> +   }
> >> +
> >> +   constexpr span
> >> +   _M_dynamic_subextents(size_t __begin, size_t __end) const
> noexcept
> >> +   requires (_Extents.size() > 0)
> >> +   {
> >> + return {_M_dynamic_extents + _S_dynamic_index[__begin],
> >> + _M_dynamic_extents + _S_dynamic_index[__end]};
> >> +   }
> >> +
> >> private:
> >>  using _S_storage = __array_traits<_IndexType,
> >> _S_rank_dynamic>::_Type;
> >>  [[no_unique_address]] _S_storage _M_dynamic_extents;
> >> @@ -160,6 +174,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>  || _Extent <= numeric_limits<_IndexType>::max();
> >> }
> >>
> >> +  namespace __mdspan
> >> +  {
> >> +template
> >> +  constexpr span
> >> +  __static_subextents(size_t __begin, size_t __end)
> >> +  { return _Extents::_S_storage::_S_static_subextents(__begin,
> >> __end); }
> >> +
> >> +template
> >> +  constexpr span
> >> +  __dynamic_subextents(const _Extents& __exts, size_t __begin,
> size_t
> >> __end)
> >> +  {
> >> +   return __exts._M_dynamic_extents._M_dynamic_subextents(__begin,
> >> __end);
> >> +  }
> >> +  }
> >> +
> >> template
> >>   class extents
> >>   {
> >> @@ -251,7 +280,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>  : _M_dynamic_extents(span(__exts))
> >>  { }
> >>
> >> -
> >> template<__mdspan::__valid_index_type _OIndexType,
> >> size_t _Nm>
> >>  requires (_Nm == rank() || _Nm == rank_dynamic())
> >>  constexpr explicit(_Nm != rank_dynamic())
> >> @@ -276,6 +304,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>  }
> >>
> >>   private:
> >> +  friend span
> >> +  __mdspan::__static_subextents(size_t, size_t);
> >> +
> >> +  friend span
> >> +  __mdspan::__dynamic_subextents(const extents&, size_t,
> >> size_t);
> >> +
> >> using _S_storage = __mdspan::_ExtentsStorage<
> >>  _IndexType, array{_Extents...}>;
> >> [[no_unique_address]] _S_storage _M_dynamic_extents;
> >> @@ -286,6 +320,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>
> >> namespace __mdspan
> >> {
> >> +template
> >> +  constexpr size_t
> >> +  __static_extents_prod(size_t __begin, size_t __end)
> >> +  {
> >> +   auto __sta_exts = __static_subextents<_Extents>(__begin, __end);
> >> +   size_t __ret = 1;
> >> +   for(size_t __i = 0; __i < __sta_exts.size(); ++__i)
> >> + if (__sta_exts[__i] != dynamic_extent)
> >> +   __ret *= __sta_exts[__i];
> >> +   return __ret;
> >>
> > I wonder if we could perform some compile time caching of result here,
> like:
> > size_t __ret = 1;
> > switch (__end - __begin)
> > {
> > default:
> > break;
> > case 3:
> > if (__sta_exts[__begin + 2] != dynamic_extent)
> >   _ret *= __sta_exts[__begin + 2];
> > [[ fallthrou ]];
> > case 2:
> > if (__sta_exts[__begin + 1] != dynamic_extent)
> >   _ret *= __sta_exts[__begin + 1];
> > [[ fallthrou ]];
> > case 1:
> > if (__sta_exts[__begin] != dynamic_extent)
> >   _ret *= __sta_exts[__begin];
> > [[ fallthrou ]];
> >case 0:
> > return __ret;
> > }
> > if constexpr ( _Extents::rank() >= 4 )
> > {
> >   static constexpr std::array
> __partial_prods
> >= [] { return partial sums ;}
> >return __partial_prods[__end - 1] / __partial_prods[__begin];
> > }
> > return __ret;
> >
>
> Nice idea to trade N >= 4 multiplications for 1 division. Without
> measuring how do we know that N >= 4 is the optimal choice?
>
> Since we only ever need __exts_prod to compute __{fwd,rev}_prod, we
> can instead cache __static_{fwd,rev}_prod(__r) separately and can skip
> the divison entirely. Note that no layout uses both __fwd_prod and
> __rev_prod with arguments that are not know at com

Re: [PATCH] libstdc++: Fix vector(from_range_t, R&&) for exceptions [PR120367]

2025-05-21 Thread Tomasz Kaminski
On Wed, May 21, 2025 at 5:41 PM Jonathan Wakely  wrote:

> Because this constructor delegates to vector(a) the object has been
> fully constructed and the destructor will run if an exception happens.
> That means we need to set _M_finish == _M_start so that the destructor
> doesn't try to destroy any elements.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/120367
> * include/bits/stl_vector.h (_M_range_initialize): Initialize
> _M_impl._M_finish.
> * testsuite/23_containers/vector/cons/from_range.cc: Check with
> a type that throws on construction.
> exceptions during construction.
> ---
>
> Tested x86_64-linux.
>
>  libstdc++-v3/include/bits/stl_vector.h|  1 +
>  .../23_containers/vector/cons/from_range.cc   | 22 +++
>  2 files changed, 23 insertions(+)
>
> diff --git a/libstdc++-v3/include/bits/stl_vector.h
> b/libstdc++-v3/include/bits/stl_vector.h
> index 57680b7bbcf3..43b913da778d 100644
> --- a/libstdc++-v3/include/bits/stl_vector.h
> +++ b/libstdc++-v3/include/bits/stl_vector.h
> @@ -1971,6 +1971,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> {
>   pointer __start = this->_M_impl._M_start =
>
Not required change, but I was a bit confused where _M_start is set.
Maybe assign all pointers here?
  pointer __start = this->_M_impl._M_start =
this->_M_impl._M_finish =

> this->_M_allocate(_S_check_init_len(__n,
> _M_get_Tp_allocator()));
> + this->_M_impl._M_finish = __start;
>   this->_M_impl._M_end_of_storage = __start + __n;
>   this->_M_impl._M_finish
>   = std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last,
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
> b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
> index 7a62645283d2..3784b9cd66ad 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
> @@ -106,8 +106,30 @@ test_constexpr()
>return true;
>  }
>
> +void
> +test_pr120367()
> +{
> +#ifdef __cpp_exceptions
> +  struct X
> +  {
> +X(int) { throw 1; } // Cannot successfully construct an X.
> +~X() { VERIFY(false); } // So should never need to destroy one.
> +  };
> +
> +  try
> +  {
> +int i[1]{};
> +std::vector v(std::from_range, i);
> +  }
> +  catch (int)
> +  {
> +  }
> +#endif
> +}
> +
>  int main()
>  {
>test_ranges();
>static_assert( test_constexpr() );
> +  test_pr120367();
>  }
> --
> 2.49.0
>
>


[PATCH] RISC-V: Add minimal support of double trap extension 1.0

2025-05-21 Thread Jerry Zhang Jian
Add support of double trap extension [1], enabling GCC
to recognize the following extensions at compile time.

New extensions:
- ssdbltrp
- smdbltrp

[1] 
https://github.com/riscv/riscv-double-trap/releases/download/v1.0/riscv-double-trap.pdf

gcc/ChangeLog:
* config/riscv/riscv-ext.def: New extensions

gcc/testsuite/ChangeLog:
* gcc/testsuite/gcc.target/riscv/arch-56.c: New test
* gcc/testsuite/gcc.target/riscv/arch-57.c: New test

Signed-off-by: Jerry Zhang Jian 
---
 gcc/config/riscv/riscv-ext.def   | 26 
 gcc/testsuite/gcc.target/riscv/arch-56.c |  6 ++
 gcc/testsuite/gcc.target/riscv/arch-57.c |  6 ++
 3 files changed, 38 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-56.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-57.c

diff --git a/gcc/config/riscv/riscv-ext.def b/gcc/config/riscv/riscv-ext.def
index 97b576617ad..dbda8ded397 100644
--- a/gcc/config/riscv/riscv-ext.def
+++ b/gcc/config/riscv/riscv-ext.def
@@ -1727,6 +1727,19 @@ DEFINE_RISCV_EXT(
   /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED,
   /* EXTRA_EXTENSION_FLAGS */ 0)
 
+DEFINE_RISCV_EXT(
+  /* NAME */ smdbltrp,
+  /* UPPERCAE_NAME */ SMDBLTRP,
+  /* FULL_NAME */ "Double Trap Extensions",
+  /* DESC */ "",
+  /* URL */ ,
+  /* DEP_EXTS */ ({"zicsr"}),
+  /* SUPPORTED_VERSIONS */ ({{1, 0}}),
+  /* FLAG_GROUP */ sm,
+  /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED,
+  /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED,
+  /* EXTRA_EXTENSION_FLAGS */ 0)
+
 DEFINE_RISCV_EXT(
   /* NAME */ ssaia,
   /* UPPERCAE_NAME */ SSAIA,
@@ -1818,6 +1831,19 @@ DEFINE_RISCV_EXT(
   /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED,
   /* EXTRA_EXTENSION_FLAGS */ 0)
 
+DEFINE_RISCV_EXT(
+  /* NAME */ ssdbltrp,
+  /* UPPERCAE_NAME */ SSDBLTRP,
+  /* FULL_NAME */ "Double Trap Extensions",
+  /* DESC */ "",
+  /* URL */ ,
+  /* DEP_EXTS */ ({"zicsr"}),
+  /* SUPPORTED_VERSIONS */ ({{1, 0}}),
+  /* FLAG_GROUP */ ss,
+  /* BITMASK_GROUP_ID */ BITMASK_NOT_YET_ALLOCATED,
+  /* BITMASK_BIT_POSITION*/ BITMASK_NOT_YET_ALLOCATED,
+  /* EXTRA_EXTENSION_FLAGS */ 0)
+
 DEFINE_RISCV_EXT(
   /* NAME */ supm,
   /* UPPERCAE_NAME */ SUPM,
diff --git a/gcc/testsuite/gcc.target/riscv/arch-56.c 
b/gcc/testsuite/gcc.target/riscv/arch-56.c
new file mode 100644
index 000..88b20dfb6c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-56.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64i_ssdbltrp -mabi=lp64d" } */
+
+void foo(){}
+
+/* { dg-final { scan-assembler ".attribute arch, 
\"rv64i2p1_zicsr2p0_ssdbltrp1p0\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/arch-57.c 
b/gcc/testsuite/gcc.target/riscv/arch-57.c
new file mode 100644
index 000..42cf30a3171
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-57.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64i_smdbltrp -mabi=lp64d" } */
+
+void foo(){}
+
+/* { dg-final { scan-assembler ".attribute arch, 
\"rv64i2p1_zicsr2p0_smdbltrp1p0\"" } } */
-- 
2.49.0



Re: [PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Alejandro Colomar
Hi Jakub,

On Wed, May 21, 2025 at 11:12:07PM +0200, Jakub Jelinek wrote:
> >  warning_at (loc, OPT_Wc___compat,
> > "defining type in %qs expression is invalid in C++",
> > (in_sizeof
> >  ? "sizeof"
> > -: (in_typeof ? "typeof" : "alignof")));
> > +: (in_typeof
> > +   ? "typeof"
> > +   : (in_alignof
> > +  ? "alignof"
> > +  : "_Countof";
> 
> Why so many lines?

Because IMO using two lines and breaking at a random point would make it
less readable.  Which style do you prefer?  If you send me an exact way
I should use, I'll paste it.


Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: [PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Alejandro Colomar
On Wed, May 21, 2025 at 11:36:56PM +0200, Alejandro Colomar wrote:
> Hi Jakub,
> 
> On Wed, May 21, 2025 at 11:12:07PM +0200, Jakub Jelinek wrote:
> > >  warning_at (loc, OPT_Wc___compat,
> > >   "defining type in %qs expression is invalid in C++",
> > >   (in_sizeof
> > >? "sizeof"
> > > -  : (in_typeof ? "typeof" : "alignof")));
> > > +  : (in_typeof
> > > + ? "typeof"
> > > + : (in_alignof
> > > +? "alignof"
> > > +: "_Countof";
> > 
> > Why so many lines?
> 
> Because IMO using two lines and breaking at a random point would make it
> less readable.  Which style do you prefer?  If you send me an exact way
> I should use, I'll paste it.

I propose:

diff --git i/gcc/c/c-decl.cc w/gcc/c/c-decl.cc
index 5bf638bfbd81..e6b8a84e50b1 100644
--- i/gcc/c/c-decl.cc
+++ w/gcc/c/c-decl.cc
@@ -8949,11 +8949,11 @@ start_struct (location_t loc, enum tree_code code, tree 
name,
"defining type in %qs expression is invalid in C++",
(in_sizeof
 ? "sizeof"
-: (in_typeof
-   ? "typeof"
-   : (in_alignof
-  ? "alignof"
-  : "_Countof";
+: in_typeof
+  ? "typeof"
+  : in_alignof
+? "alignof"
+: "_Countof"));
 
   if (in_underspecified_init)
 error_at (loc, "%qT defined in underspecified object initializer", ref);



-- 



signature.asc
Description: PGP signature


Re: [PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Jakub Jelinek
On Wed, May 21, 2025 at 11:31:01PM +0200, Alejandro Colomar wrote:
> The preexisting ones are not just the outermost ones.  The preexisting
> code was 
> 
>   (in_sizeof
>? "sizeof"
>: (in_typeof ? "typeof" : "alignof")));
> 
> The only pattern I can find in that code is wrapping every ?:
> subexpression in ().  I would find not doing so for the last one I'm
> adding inconsistent with it.  On the other hand, I would agree that
> limiting it to just the outermost ones would be more readable, but that
> would mean removing existing ()s.  So can you please confirm that I
> should remove the existing inner ()?

I think
warning_at (loc, OPT_Wc___compat,
"defining type in %qs expression is invalid in C++",
in_sizeof ? "sizeof" : in_typeof ? "typeof"
: in_alignof ? "alignof" : "_Countof");
or say
(in_sizeof ? "sizeof"
 : in_typeof ? "typeof"
 : in_alignof ? "alignof"
 : "_Countof"));
or that without the extra () would look better.
Those are the styles used elsewhere, e.g.
alias.cc-  sizey = (!MEM_P (rtly) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtly)))
alias.cc:  : MEM_SIZE_KNOWN_P (rtly) ? MEM_SIZE (rtly)
alias.cc-  : -1);
or
cfgexpand.cc-   allows_reg ? EXPAND_NORMAL
cfgexpand.cc:   : allows_mem ? EXPAND_MEMORY
cfgexpand.cc-   : EXPAND_INITIALIZER);
or
combine.cc-   inner = simplify_binary_operation (code == MINUS ? PLUS
combine.cc:  : code == DIV ? MULT
combine.cc-  : code,
combine.cc-  mode, inner_op0, 
inner_op1);
etc.

Jakub



Re: [PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Alejandro Colomar
Hi Jakub,

On Wed, May 21, 2025 at 11:31:05PM +0200, Alejandro Colomar wrote:
> > > +#define c_parser_sizeof_expression(parser)   
> > >  \
> > > +(
> > >  \
> > > +  c_parser_sizeof_or_countof_expression (parser, RID_SIZEOF) 
> > >  \
> > > +)
> > >  
> > > +#define c_parser_countof_expression(parser)  
> > >  \
> > > +(
> > >  \
> > > +  c_parser_sizeof_or_countof_expression (parser, RID_COUNTOF)
> > >  \
> > > +)
> > 
> > Up to Joseph, but I'd say these should just be inline functions, not macros,
> > and defined after the declarations.
> 
> I don't mind, so yeah, I'm okay with changing these to be inline.

Does this sound good?

diff --git i/gcc/c/c-parser.cc w/gcc/c/c-parser.cc
index faa03c4903a2..733cb312341e 100644
--- i/gcc/c/c-parser.cc
+++ w/gcc/c/c-parser.cc
@@ -78,16 +78,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-ubsan.h"
 #include "gcc-urlifier.h"
 ^L
-#define c_parser_sizeof_expression(parser) 
   \
-(  
   \
-  c_parser_sizeof_or_countof_expression (parser, RID_SIZEOF)   
   \
-)
-
-#define c_parser_countof_expression(parser)
   \
-(  
   \
-  c_parser_sizeof_or_countof_expression (parser, RID_COUNTOF)  
   \
-)
-^L
 /* We need to walk over decls with incomplete struct/union/enum types
after parsing the whole translation unit.
In finish_decl(), if the decl is static, has incomplete
@@ -1747,6 +1737,8 @@ static struct c_expr c_parser_binary_expression 
(c_parser *, struct c_expr *,
 tree);
 static struct c_expr c_parser_cast_expression (c_parser *, struct 
c_expr *);
 static struct c_expr c_parser_unary_expression (c_parser *);
+static inline struct c_expr c_parser_sizeof_expression (c_parser *);
+static inline struct c_expr c_parser_countof_expression (c_parser *);
 static struct c_expr c_parser_sizeof_or_countof_expression (c_parser *,
enum rid);
 static struct c_expr c_parser_alignof_expression (c_parser *);
@@ -10627,6 +10619,22 @@ c_parser_unary_expression (c_parser *parser)
 
 /* Parse a sizeof expression.  */
 
+static inline struct c_expr
+c_parser_sizeof_expression (c_parser *parser)
+{
+  return c_parser_sizeof_or_countof_expression (parser, RID_SIZEOF);
+}
+
+/* Parse a _Countof expression.  */
+
+static inline struct c_expr
+c_parser_countof_expression (c_parser *parser)
+{
+  return c_parser_sizeof_or_countof_expression (parser, RID_COUNTOF);
+}
+
+/* Parse a sizeof or _Countof expression.  */
+
 static struct c_expr
 c_parser_sizeof_or_countof_expression (c_parser *parser, enum rid rid)
 {


Cheers,
Alex

-- 



signature.asc
Description: PGP signature


Re: [PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Alejandro Colomar
Hi Jakub,

On Wed, May 21, 2025 at 11:47:30PM +0200, Jakub Jelinek wrote:
> > @@ -1747,6 +1737,8 @@ static struct c_expr c_parser_binary_expression 
> > (c_parser *, struct c_expr *,
> >  tree);
> >  static struct c_expr c_parser_cast_expression (c_parser *, struct 
> > c_expr *);
> >  static struct c_expr c_parser_unary_expression (c_parser *);
> > +static inline struct c_expr c_parser_sizeof_expression (c_parser *);
> > +static inline struct c_expr c_parser_countof_expression (c_parser *);
> 
> I don't see the point of the above (unless they are defined after first
> use,

They are indeed defined after first use.

> but then it would be better to define them before the first use).

Moving them before the first use would separate them from
c_parser_sizeof_or_countof_expression(), which is their closest
relative.  I find them more organized this way.  Please confirm what I
should do.


Cheers,
Alex

> 
> >  static struct c_expr c_parser_sizeof_or_countof_expression (c_parser *,
> > enum rid);
> >  static struct c_expr c_parser_alignof_expression (c_parser *);
> > @@ -10627,6 +10619,22 @@ c_parser_unary_expression (c_parser *parser)
> >  
> >  /* Parse a sizeof expression.  */
> >  
> > +static inline struct c_expr
> > +c_parser_sizeof_expression (c_parser *parser)
> > +{
> > +  return c_parser_sizeof_or_countof_expression (parser, RID_SIZEOF);
> > +}
> > +
> > +/* Parse a _Countof expression.  */
> > +
> > +static inline struct c_expr
> > +c_parser_countof_expression (c_parser *parser)
> > +{
> > +  return c_parser_sizeof_or_countof_expression (parser, RID_COUNTOF);
> > +}
> > +
> > +/* Parse a sizeof or _Countof expression.  */
> > +
> 
> This looks good to me (but Joseph or Marek should have the final say in C
> FE).
> 
>   Jakub
> 

-- 



signature.asc
Description: PGP signature


Re: [PATCH 3/6] RISC-V: frm/mode-switch: remove dubious frm edge insertion before call_insn

2025-05-21 Thread Jeff Law




On 5/20/25 1:56 PM, Robin Dapp wrote:
Maybe I'm missing something there.  Particularly whether or not you 
can know anything about frm's value after a call has returned.  
Normally the answer to this kind of question is a hard no.


AFAICT the main difference to standard mode switching is that we (ab)use 
it to set the rounding mode to the value it had initially, either at 
function entry or after a call.  That's different to regular mode 
switching which assumes "static" rounding modes for different instructions.


Standard could e.g. be:
- insn1 demands frm1
- call1 demands frm4
- call2 demands frm5

Whereas we have:
- insn1 demands frm1
- call1 demands "frm at the start of the function"
- call2 demands "frm after call1 that could have called fesetround"
Weird, call2 can demand the frm as it existed after call1?!?  I'm going 
to try not to cry and return to my bubble :-)


Jeff




Re: [PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Jakub Jelinek
On Wed, May 21, 2025 at 11:44:42PM +0200, Alejandro Colomar wrote:
> Does this sound good?
> 
>   diff --git i/gcc/c/c-parser.cc w/gcc/c/c-parser.cc
>   index faa03c4903a2..733cb312341e 100644
>   --- i/gcc/c/c-parser.cc
>   +++ w/gcc/c/c-parser.cc
>   @@ -78,16 +78,6 @@ along with GCC; see the file COPYING3.  If not see
>#include "c-family/c-ubsan.h"
>#include "gcc-urlifier.h"
>^L
>   -#define c_parser_sizeof_expression(parser) 
>\
>   -(  
>\
>   -  c_parser_sizeof_or_countof_expression (parser, RID_SIZEOF)   
>\
>   -)
>   -
>   -#define c_parser_countof_expression(parser)
>\
>   -(  
>\
>   -  c_parser_sizeof_or_countof_expression (parser, RID_COUNTOF)  
>\
>   -)
>   -^L
>/* We need to walk over decls with incomplete struct/union/enum types
>   after parsing the whole translation unit.
>   In finish_decl(), if the decl is static, has incomplete
>   @@ -1747,6 +1737,8 @@ static struct c_expr c_parser_binary_expression 
> (c_parser *, struct c_expr *,
>tree);
>static struct c_expr c_parser_cast_expression (c_parser *, struct 
> c_expr *);
>static struct c_expr c_parser_unary_expression (c_parser *);
>   +static inline struct c_expr c_parser_sizeof_expression (c_parser *);
>   +static inline struct c_expr c_parser_countof_expression (c_parser *);

I don't see the point of the above (unless they are defined after first
use, but then it would be better to define them before the first use).

>static struct c_expr c_parser_sizeof_or_countof_expression (c_parser *,
>   enum rid);
>static struct c_expr c_parser_alignof_expression (c_parser *);
>   @@ -10627,6 +10619,22 @@ c_parser_unary_expression (c_parser *parser)
>
>/* Parse a sizeof expression.  */
>
>   +static inline struct c_expr
>   +c_parser_sizeof_expression (c_parser *parser)
>   +{
>   +  return c_parser_sizeof_or_countof_expression (parser, RID_SIZEOF);
>   +}
>   +
>   +/* Parse a _Countof expression.  */
>   +
>   +static inline struct c_expr
>   +c_parser_countof_expression (c_parser *parser)
>   +{
>   +  return c_parser_sizeof_or_countof_expression (parser, RID_COUNTOF);
>   +}
>   +
>   +/* Parse a sizeof or _Countof expression.  */
>   +

This looks good to me (but Joseph or Marek should have the final say in C
FE).

Jakub



[to-be-committed][RISC-V] Clear high or low bits using shift pairs

2025-05-21 Thread Jeff Law


So the first special case of clearing bits from Shreya's work.  We can 
clear an arbitrary number of high bits by shifting left by the number of 
bits to clear, then logically shifting right to put everything in place. 
  Similarly we can clear an arbitrary number of low bits with a right 
logical shift followed by a left shift.  Naturally this only applies 
when the constant synthesis budget is 2+ insns.


Even with mvconst_internal still enabled this does consistently show 
various small code generation improvements.


I have seen a notable regression.  The two shift form to wipe out high 
bits isn't handled well by ext-dce.  Essentially it looks like we don't 
recognize the sequence as wiping upper bits, instead it makes bits live 
and as a result we're unable to remove a prior zero extension.  I've 
opened a bug for this issue.


The other case I've seen is CSE related.  If we had a number of masking 
operations with the same mask, we might have previously CSE'd the 
constant.  In that scenario each instance of masking would be a single 
AND using the CSE'd register holding the constant, whereas with this 
patch it'll be a pair of shifts.  But on a good uarch design the pair of 
shifts would be fused into a single op.  Given this is relatively rare 
and on the margins from a performance standpoint I'm not going to worry 
about it.


This has spun in my tester for riscv32-elf and riscv64-elf.  Bootstrap 
and regression test is in flight and due in an hour or so.   Waiting on 
the upstream pre-commit tester and the bootstrap test before moving forward.



jeff
gcc/
* config/riscv/riscv.cc (synthesize_and): When profitable, use two
shift combinations to clear high or low bits rather than synthsizing
the constant.

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 1a88e96d8c6..5842a08fcb0 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -14524,6 +14524,43 @@ synthesize_and (rtx operands[3])
}
 }
 
+  /* The number of instructions to synthesize the constant is a good
+ estimate of the budget.  That does not account for out of order
+ execution an fusion in the constant synthesis those would naturally
+ decrease the budget.  It also does not account for the AND at
+ the end of the sequence which would increase the budget. */
+  int budget = riscv_const_insns (operands[2], true);
+  rtx input = NULL_RTX;
+  rtx output = NULL_RTX;
+
+  /* Left shift + right shift to clear high bits.  */
+  if (budget >= 2 && p2m1_shift_operand (operands[2], word_mode))
+{
+  int count = (GET_MODE_BITSIZE (GET_MODE (operands[1])).to_constant ()
+  - exact_log2 (INTVAL (operands[2]) + 1));
+  rtx x = gen_rtx_ASHIFT (word_mode, operands[1], GEN_INT (count));
+  output = gen_reg_rtx (word_mode);
+  emit_insn (gen_rtx_SET (output, x));
+  input = output;
+  x = gen_rtx_LSHIFTRT (word_mode, input, GEN_INT (count));
+  emit_insn (gen_rtx_SET (operands[0], x));
+  return true;
+}
+
+  /* Clears a bunch of low bits with only high bits set.  */
+  unsigned HOST_WIDE_INT t = ~INTVAL (operands[2]);
+  if (budget >= 2 && exact_log2 (t + 1) >= 0)
+{
+  int count = ctz_hwi (INTVAL (operands[2]));
+  rtx x = gen_rtx_LSHIFTRT (word_mode, operands[1], GEN_INT (count));
+  output = gen_reg_rtx (word_mode);
+  emit_insn (gen_rtx_SET (output, x));
+  input = output;
+  x = gen_rtx_ASHIFT (word_mode, input, GEN_INT (count));
+  emit_insn (gen_rtx_SET (operands[0], x));
+  return true;
+}
+
   /* If the remaining budget has gone to less than zero, it
  forces the value into a register and performs the AND
  operation.  It returns TRUE to the caller so the caller


Re: [PATCH] combine: gen_lowpart_no_emit vs CLOBBER [PR120090]

2025-05-21 Thread Andrew Pinski
On Wed, May 21, 2025 at 3:21 PM Jeff Law  wrote:
>
>
>
> On 5/5/25 3:27 PM, Andrew Pinski wrote:
> > The problem here is simplify-rtx.cc expects gen_lowpart_no_emit
> > to return NULL on failure but combine's hook was returning CLOBBER.
> > After r16-160-ge6f89d78c1a7528e93458278, 
> > gcc.target/i386/avx512bw-pr103750-2.c
> > started to fail at -m32 due to this as new simplify code would return
> > a RTL with a clobber in it rather than returning NULL.
> > To fix this gen_lowpart_no_emit should return NULL when there was an failure
> > instead of a clobber. This only changes the gen_lowpart_no_emit hook and 
> > not the
> > generic gen_lowpart hook as parts of combine just pass gen_lowpart result 
> > directly
> > without checking the return value.
> >
> > Bootstrapped and tested on x86_64-linux-gnu.
> >
> >   PR rtl-optimization/120090
> > gcc/ChangeLog:
> >
> >   * combine.cc (gen_lowpart_for_combine_no_emit): New function.
> >   (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Set to 
> > gen_lowpart_for_combine_no_emit.
> So that's standard combine behavior from as long as I can remember.  So
> I'm naturally worried about the various chunks of combine that are
> expecting to see valid RTL objects (the CLOBBER) now getting pass a
> NULL.  If we substitute that value into an insn and try to recognize it
> we could well run into a ICE or segfault.

Yes I had worry too which is why I didn't change
gen_lowpart_for_combine. and only changed the no_emit hook.
Combine itself does not call the no_emit hook directly but rather than
the full gen_lowpart which then calls the non no_emit hook version.
And it is why I wrote:
```
This only changes the gen_lowpart_no_emit hook and not the
generic gen_lowpart hook as parts of combine just pass gen_lowpart
result directly
without checking the return value.
```
In my original commit message of why we can't just change gen_lowpart hook.

Thanks,
Andrew

>
> Jeff
>
>


Re: [PATCH] combine: gen_lowpart_no_emit vs CLOBBER [PR120090]

2025-05-21 Thread Jeff Law




On 5/5/25 3:27 PM, Andrew Pinski wrote:

The problem here is simplify-rtx.cc expects gen_lowpart_no_emit
to return NULL on failure but combine's hook was returning CLOBBER.
After r16-160-ge6f89d78c1a7528e93458278, gcc.target/i386/avx512bw-pr103750-2.c
started to fail at -m32 due to this as new simplify code would return
a RTL with a clobber in it rather than returning NULL.
To fix this gen_lowpart_no_emit should return NULL when there was an failure
instead of a clobber. This only changes the gen_lowpart_no_emit hook and not the
generic gen_lowpart hook as parts of combine just pass gen_lowpart result 
directly
without checking the return value.

Bootstrapped and tested on x86_64-linux-gnu.

PR rtl-optimization/120090
gcc/ChangeLog:

* combine.cc (gen_lowpart_for_combine_no_emit): New function.
(RTL_HOOKS_GEN_LOWPART_NO_EMIT): Set to gen_lowpart_for_combine_no_emit.
So that's standard combine behavior from as long as I can remember.  So 
I'm naturally worried about the various chunks of combine that are 
expecting to see valid RTL objects (the CLOBBER) now getting pass a 
NULL.  If we substitute that value into an insn and try to recognize it 
we could well run into a ICE or segfault.


Jeff




Re: [PATCH] combine: gen_lowpart_no_emit vs CLOBBER [PR120090]

2025-05-21 Thread Jeff Law




On 5/21/25 4:29 PM, Andrew Pinski wrote:

On Wed, May 21, 2025 at 3:21 PM Jeff Law  wrote:




On 5/5/25 3:27 PM, Andrew Pinski wrote:

The problem here is simplify-rtx.cc expects gen_lowpart_no_emit
to return NULL on failure but combine's hook was returning CLOBBER.
After r16-160-ge6f89d78c1a7528e93458278, gcc.target/i386/avx512bw-pr103750-2.c
started to fail at -m32 due to this as new simplify code would return
a RTL with a clobber in it rather than returning NULL.
To fix this gen_lowpart_no_emit should return NULL when there was an failure
instead of a clobber. This only changes the gen_lowpart_no_emit hook and not the
generic gen_lowpart hook as parts of combine just pass gen_lowpart result 
directly
without checking the return value.

Bootstrapped and tested on x86_64-linux-gnu.

   PR rtl-optimization/120090
gcc/ChangeLog:

   * combine.cc (gen_lowpart_for_combine_no_emit): New function.
   (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Set to gen_lowpart_for_combine_no_emit.

So that's standard combine behavior from as long as I can remember.  So
I'm naturally worried about the various chunks of combine that are
expecting to see valid RTL objects (the CLOBBER) now getting pass a
NULL.  If we substitute that value into an insn and try to recognize it
we could well run into a ICE or segfault.


Yes I had worry too which is why I didn't change
gen_lowpart_for_combine. and only changed the no_emit hook.
Combine itself does not call the no_emit hook directly but rather than
the full gen_lowpart which then calls the non no_emit hook version.
And it is why I wrote:
```
This only changes the gen_lowpart_no_emit hook and not the
generic gen_lowpart hook as parts of combine just pass gen_lowpart
result directly
without checking the return value.
```
In my original commit message of why we can't just change gen_lowpart hook.
I clearly missed the significance of that comment.  THanks for 
clarifying.  Ok for the trunk.


jeff



[PATCH v24 1/3] c: Add _Countof operator

2025-05-21 Thread Alejandro Colomar
This operator is similar to sizeof but can only be applied to an array,
and returns its number of elements.

FUTURE DIRECTIONS:

-  We should make it work with array parameters to functions,
   and somehow magically return the number of elements of the array,
   regardless of it being really a pointer.

Link: 
Link: 
Link: 
Link: 

Link: 
Link: 
Link: 
Link: 
Link: 
Link: 
Link: 
Link: 

gcc/ChangeLog:

* doc/extend.texi: Document _Countof operator.

gcc/c-family/ChangeLog:

* c-common.h: Add RID_COUNTOF.
(c_countof_type): New function prototype.
* c-common.def (COUNTOF_EXPR): New tree.
* c-common.cc
(c_common_reswords): Add RID_COUNTOF entry.
(c_countof_type): New function.

gcc/c/ChangeLog:

* c-tree.h
(in_countof): Add global variable declaration.
(c_expr_countof_expr): Add function prototype.
(c_expr_countof_type): Add function prototype.
* c-decl.cc
(start_struct, finish_struct): Add support for _Countof.
(start_enum, finish_enum): Add support for _Countof.
* c-parser.cc
(c_parser_sizeof_expression): New macro.
(c_parser_countof_expression): New macro.
(c_parser_sizeof_or_countof_expression):
Rename function and add support for _Countof.
(c_parser_unary_expression): Add RID_COUNTOF entry.
* c-typeck.cc
(in_countof): Add global variable.
(build_external_ref): Add support for _Countof.
(record_maybe_used_decl): Add support for _Countof.
(pop_maybe_used): Add support for _Countof.
(is_top_array_vla): New function.
(c_expr_countof_expr, c_expr_countof_type): New functions.
Add _Countof operator.

gcc/testsuite/ChangeLog:

* gcc.dg/countof-compile.c: Compile-time tests for _Countof.
* gcc.dg/countof-vla.c: Tests for _Countof with VLAs.
* gcc.dg/countof-vmt.c: Tests for _Countof with other VMTs.
* gcc.dg/countof-zero-compile.c:
Compile-time tests for _Countof with zero-sized arrays.
* gcc.dg/countof-zero.c:
Tests for _Countof with zero-sized arrays.
* gcc.dg/countof.c: Tests for _Countof.

Suggested-by: Xavier Del Campo Romero 
Co-authored-by: Martin Uecker 
Acked-by: "James K. Lowden" 
Signed-off-by: Alejandro Colomar 
---
 gcc/c-family/c-common.cc|  26 
 gcc/c-family/c-common.def   |   3 +
 gcc/c-family/c-common.h |   2 +
 gcc/c/c-decl.cc |  22 +++-
 gcc/c/c-parser.cc   |  63 +++---
 gcc/c/c-tree.h  |   4 +
 gcc/c/c-typeck.cc   | 115 +-
 gcc/doc/extend.texi |  30 +
 gcc/testsuite/gcc.dg/countof-compile.c  | 124 
 gcc/testsuite/gcc.dg/countof-vla.c  |  35 ++
 gcc/testsuite/gcc.dg/countof-vmt.c  |  20 
 gcc/testsuite/gcc.dg/countof-zero-compile.c |  38 ++
 gcc/testsuite/gcc.dg/countof-zero.c |  31 +
 gcc/testsuite/gcc.dg/countof.c  | 120 +++
 14 files changed, 609 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/countof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-vmt.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-zero-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-zero.c
 create mode 100644 gcc/testsuite/gcc.dg/countof.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 587d76461e9e..f71cb2652d5a 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -394,6 +394,7 @@ const struct c_common_resword c_common_reswords[] =
 {
   { "_Alignas",RID_ALIGNAS,   D_CONLY },
   { "_Alignof",RID_ALIGNOF,   D_CONLY },
+  { "_Countof",RID_COUNTOF,   D_CONLY },
   { "_Atomic", RID_ATOMIC,D_CONLY },
   { "_BitInt", RID_BITINT,D_CONLY },
   { "_Bool",   RID_BOOL,  D_CONLY },
@@ -4080,6 +4081,31 @@ c_alignof_expr (location_t loc, tree expr)
 
   return fold_convert_loc (loc, size_type_node, t);
 }
+
+/* Implement 

[PATCH v24 3/3] c: Add -Wpedantic diagnostic for _Countof

2025-05-21 Thread Alejandro Colomar
It has been standardized in C2y.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_sizeof_or_countof_expression):
Add -Wpedantic diagnostic for _Countof in <= C23 mode.

gcc/testsuite/ChangeLog:

* gcc.dg/countof-compat.c:
Test _Countof diagnostics with -Wc23-c2y-compat on C2y.
* gcc.dg/countof-no-compat.c:
Test _Countof diagnostics with -Wno-c23-c2y-compat on C23.
* gcc.dg/countof-pedantic.c:
Test _Countof diagnostics with -pedantic on C23.
* gcc.dg/countof-pedantic-errors.c:
Test _Countof diagnostics with -pedantic-errors on C23.

Signed-off-by: Alejandro Colomar 
---
 gcc/c/c-parser.cc  | 4 
 gcc/testsuite/gcc.dg/countof-compat.c  | 8 
 gcc/testsuite/gcc.dg/countof-no-compat.c   | 5 +
 gcc/testsuite/gcc.dg/countof-pedantic-errors.c | 8 
 gcc/testsuite/gcc.dg/countof-pedantic.c| 8 
 5 files changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/countof-compat.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-no-compat.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic-errors.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic.c

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index faa03c4903a2..de48a016dcdb 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -10641,6 +10641,10 @@ c_parser_sizeof_or_countof_expression (c_parser 
*parser, enum rid rid)
 
   start = c_parser_peek_token (parser)->location;
 
+  if (rid == RID_COUNTOF)
+pedwarn_c23 (start, OPT_Wpedantic,
+"ISO C does not support %qs before C23", op_name);
+
   c_parser_consume_token (parser);
   c_inhibit_evaluation_warnings++;
   if (rid == RID_COUNTOF)
diff --git a/gcc/testsuite/gcc.dg/countof-compat.c 
b/gcc/testsuite/gcc.dg/countof-compat.c
new file mode 100644
index ..ab5b4ae6219c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-compat.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors -Wc23-c2y-compat" } */
+
+#include 
+
+int a[1];
+int b[countof(a)];
+int c[_Countof(a)];  /* { dg-warning "ISO C does not support" } */
diff --git a/gcc/testsuite/gcc.dg/countof-no-compat.c 
b/gcc/testsuite/gcc.dg/countof-no-compat.c
new file mode 100644
index ..4a244cf222f6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-no-compat.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors -Wno-c23-c2y-compat" } */
+
+int a[1];
+int b[_Countof(a)];
diff --git a/gcc/testsuite/gcc.dg/countof-pedantic-errors.c 
b/gcc/testsuite/gcc.dg/countof-pedantic-errors.c
new file mode 100644
index ..5d5bedbe1f7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-pedantic-errors.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+#include 
+
+int a[1];
+int b[countof(a)];
+int c[_Countof(a)];  /* { dg-error "ISO C does not support" } */
diff --git a/gcc/testsuite/gcc.dg/countof-pedantic.c 
b/gcc/testsuite/gcc.dg/countof-pedantic.c
new file mode 100644
index ..408dc6f93667
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-pedantic.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic" } */
+
+#include 
+
+int a[1];
+int b[countof(a)];
+int c[_Countof(a)];  /* { dg-warning "ISO C does not support" } */
-- 
2.49.0



[PATCH v24 0/3] c: Add _Countof and

2025-05-21 Thread Alejandro Colomar
Hi!

Here's v24.  Changes compared to v23 (see range-diff below):

-  Use a GNU dialect in tests that use GNU extensions.
-  Add comment about the syntax of _Countof.

Tests still pass:

$ grep countof ./gcc/testsuite/gcc/gcc.sum
PASS: gcc.dg/countof-compat.c  (test for warnings, line 8)
PASS: gcc.dg/countof-compat.c (test for excess errors)
PASS: gcc.dg/countof-compile.c  (test for errors, line 114)
PASS: gcc.dg/countof-compile.c  (test for errors, line 123)
PASS: gcc.dg/countof-compile.c  (test for errors, line 23)
PASS: gcc.dg/countof-compile.c  (test for errors, line 27)
PASS: gcc.dg/countof-compile.c  (test for errors, line 38)
PASS: gcc.dg/countof-compile.c  (test for errors, line 46)
PASS: gcc.dg/countof-compile.c  (test for errors, line 64)
PASS: gcc.dg/countof-compile.c  (test for errors, line 67)
PASS: gcc.dg/countof-compile.c  (test for errors, line 70)
PASS: gcc.dg/countof-compile.c  (test for errors, line 82)
PASS: gcc.dg/countof-compile.c  (test for errors, line 83)
PASS: gcc.dg/countof-compile.c  (test for errors, line 84)
PASS: gcc.dg/countof-compile.c  (test for errors, line 85)
PASS: gcc.dg/countof-compile.c  (test for errors, line 86)
PASS: gcc.dg/countof-compile.c  (test for errors, line 87)
PASS: gcc.dg/countof-compile.c  (test for errors, line 88)
PASS: gcc.dg/countof-compile.c  (test for errors, line 89)
PASS: gcc.dg/countof-compile.c  (test for errors, line 90)
PASS: gcc.dg/countof-compile.c  (test for errors, line 94)
PASS: gcc.dg/countof-compile.c (test for excess errors)
PASS: gcc.dg/countof-no-compat.c (test for excess errors)
PASS: gcc.dg/countof-pedantic-errors.c  (test for errors, line 8)
PASS: gcc.dg/countof-pedantic-errors.c (test for excess errors)
PASS: gcc.dg/countof-pedantic.c  (test for warnings, line 8)
PASS: gcc.dg/countof-pedantic.c (test for excess errors)
PASS: gcc.dg/countof-stdcountof.c (test for excess errors)
PASS: gcc.dg/countof-stdcountof.c execution test
PASS: gcc.dg/countof-vla.c (test for excess errors)
PASS: gcc.dg/countof-vmt.c (test for excess errors)
PASS: gcc.dg/countof-vmt.c execution test
PASS: gcc.dg/countof-zero-compile.c (test for excess errors)
PASS: gcc.dg/countof-zero.c (test for excess errors)
PASS: gcc.dg/countof-zero.c execution test
PASS: gcc.dg/countof.c (test for excess errors)
PASS: gcc.dg/countof.c execution test


Have a lovely day!
Alex


Alejandro Colomar (3):
  c: Add _Countof operator
  c: Add 
  c: Add -Wpedantic diagnostic for _Countof

 gcc/Makefile.in   |   1 +
 gcc/c-family/c-common.cc  |  26 
 gcc/c-family/c-common.def |   3 +
 gcc/c-family/c-common.h   |   2 +
 gcc/c/c-decl.cc   |  22 +++-
 gcc/c/c-parser.cc |  67 --
 gcc/c/c-tree.h|   4 +
 gcc/c/c-typeck.cc | 115 +++-
 gcc/doc/extend.texi   |  30 +
 gcc/ginclude/stdcountof.h |  31 +
 gcc/testsuite/gcc.dg/countof-compat.c |   8 ++
 gcc/testsuite/gcc.dg/countof-compile.c| 124 ++
 gcc/testsuite/gcc.dg/countof-no-compat.c  |   5 +
 .../gcc.dg/countof-pedantic-errors.c  |   8 ++
 gcc/testsuite/gcc.dg/countof-pedantic.c   |   8 ++
 gcc/testsuite/gcc.dg/countof-stdcountof.c |  24 
 gcc/testsuite/gcc.dg/countof-vla.c|  35 +
 gcc/testsuite/gcc.dg/countof-vmt.c|  20 +++
 gcc/testsuite/gcc.dg/countof-zero-compile.c   |  38 ++
 gcc/testsuite/gcc.dg/countof-zero.c   |  31 +
 gcc/testsuite/gcc.dg/countof.c| 120 +
 21 files changed, 698 insertions(+), 24 deletions(-)
 create mode 100644 gcc/ginclude/stdcountof.h
 create mode 100644 gcc/testsuite/gcc.dg/countof-compat.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-no-compat.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic-errors.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-stdcountof.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-vla.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-vmt.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-zero-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-zero.c
 create mode 100644 gcc/testsuite/gcc.dg/countof.c

Range-diff against v23:
1:  5040a7d25a96 ! 1:  1ac81ab0d3dc c: Add _Countof operator
@@ gcc/c/c-parser.cc: static struct c_expr c_parser_binary_expression 
(c_parser *,
  static struct c_expr c_parser_alignof_expression (c_parser *)

[PATCH v24 2/3] c: Add

2025-05-21 Thread Alejandro Colomar
gcc/ChangeLog:

* Makefile.in (USER_H): Add .
* ginclude/stdcountof.h: Add countof macro.

gcc/testsuite/ChangeLog:

* gcc.dg/countof-stdcountof.c: Add tests for .

Signed-off-by: Alejandro Colomar 
---
 gcc/Makefile.in   |  1 +
 gcc/ginclude/stdcountof.h | 31 +++
 gcc/testsuite/gcc.dg/countof-stdcountof.c | 24 ++
 3 files changed, 56 insertions(+)
 create mode 100644 gcc/ginclude/stdcountof.h
 create mode 100644 gcc/testsuite/gcc.dg/countof-stdcountof.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 72d132207c0d..fc8a7e532b97 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -481,6 +481,7 @@ USER_H = $(srcdir)/ginclude/float.h \
 $(srcdir)/ginclude/stdalign.h \
 $(srcdir)/ginclude/stdatomic.h \
 $(srcdir)/ginclude/stdckdint.h \
+$(srcdir)/ginclude/stdcountof.h \
 $(EXTRA_HEADERS)
 
 USER_H_INC_NEXT_PRE = @user_headers_inc_next_pre@
diff --git a/gcc/ginclude/stdcountof.h b/gcc/ginclude/stdcountof.h
new file mode 100644
index ..1d914f40e5db
--- /dev/null
+++ b/gcc/ginclude/stdcountof.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2025 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
+.  */
+
+/* ISO C2Y: 7.21 Array count .  */
+
+#ifndef _STDCOUNTOF_H
+#define _STDCOUNTOF_H
+
+#define countof  _Countof
+
+#endif /* stdcountof.h */
diff --git a/gcc/testsuite/gcc.dg/countof-stdcountof.c 
b/gcc/testsuite/gcc.dg/countof-stdcountof.c
new file mode 100644
index ..2fb0c6306ef0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/countof-stdcountof.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+#include 
+
+#define assert(e)  ((e) ? (void) 0 : __builtin_abort ())
+
+extern int strcmp (const char *, const char *);
+
+#ifndef countof
+#error "countof not defined"
+#endif
+
+int a[3];
+int b[countof a];
+
+#define str(x) #x
+#define xstr(x) str(x)
+
+int
+main (void)
+{
+  assert (strcmp (xstr(countof), "_Countof") == 0);
+}
-- 
2.49.0



[PATCH] configury: replace autoconf obsolete macros [PR/103459]

2025-05-21 Thread Pietro Monteiro
Autoreconf -Wall complains about obsolete macros, so replace them according to
the autoconf documentation[0].

This patch doesn't fully fix all warnings because I focused on doing simple
fixes and keeping the changes to the generated files to a minimum.

Bootstrapped and retested on x86_64-linux-gnu.

[0]: 
https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Obsolete-Macros.html

PR bootstrap/103459

ChangeLog:

* configure: Regenerate.
* configure.ac: Replace AC_CANONICAL_SYSTEM with AC_CANONICAL_TARGET.
Replace AC_TRY_COMPILE with AC_COMPILE_IFELSE.  Replace AC_TRY_LINK with
AC_LINK_IFELSE.

c++tools/ChangeLog:

* configure: Regenerate.
* configure.ac: Replace AC_CANONICAL_SYSTEM with AC_CANONICAL_TARGET.

config/ChangeLog:

* acx.m4: Remove uses of AC_CHECK_TOOL_PREFIX.  Replace AC_TRY_COMPILE
with AC_COMPILE_IFELSE.
* asmcfi.m4: Replace AC_TRY_COMPILE with AC_COMPILE_IFELSE.
* bitfields.m4: Likewise.
* cet.m4: Replace AC_TRY_LINK with AC_LINK_IFELSE.  Replace AC_TRY_RUN
with AC_RUN_IFELSE.
* codeset.m4: Replace AC_TRY_LINK with AC_LINK_IFELSE.
* enable.m4: Replace AC_HELP_STRING with AS_HELP_STRING.
* gcc-plugin.m4: Replace AC_TRY_LINK with AC_LINK_IFELSE.
* hwcaps.m4: Replace AC_TRY_COMPILE with AC_COMPILE_IFELSE.  Replace
AC_TRY_LINK with AC_LINK_IFELSE.
* isl.m4: Replace AC_TRY_LINK with AC_LINK_IFELSE.
* lcmessage.m4:Replace AC_TRY_LINK with AC_LINK_IFELSE.
* lthostflags.m4: Replace AC_CANONICAL_SYSTEM with AC_CANONICAL_HOST.
* no-executables.m4: Replace AC_TRY_COMPILE with AC_COMPILE_IFELSE.
Replace AC_TRY_LINK with AC_LINK_IFELSE.
* po.m4: Replace AC_OUTPUT_COMMANDS with AC_CONFIG_COMMANDS.
* tls.m4: Add explicit 4th argument to AC_LINK_IFELSE.

fixincludes/ChangeLog:

* configure: Regenerate.
* configure.ac: Replace AC_CANONICAL_SYSTEM with AC_CANONICAL_TARGET.

gcc/ChangeLog:

* acinclude.m4: Replace AC_FOREACH with m4_foreach_w.  Replace
AC_TRY_LINK with AC_LINK_IFELSE.
* configure: Regenerate.
* configure.ac: Replace AC_HELP_STRING with AS_HELP_STRING.  Replace
AC_PROG_LIBTOOL with LT_INIT.

gnattools/ChangeLog:

* configure.ac: Replace AC_HELP_STRING with AS_HELP_STRING.

gotools/ChangeLog:

* configure: Regenerate.
* configure.ac: Replace AC_CANONICAL_SYSTEM with AC_CANONICAL_TARGET.

libada/ChangeLog:

* configure.ac: Replace AC_HELP_STRING with AS_HELP_STRING.

libatomic/ChangeLog:

* acinclude.m4: Replace AC_ERROR with AS_MSG_ERROR.  Replace AC_TRY_LINK
with AC_LINK_IFELSE.  Replace AC_TRY_COMPILE with AC_COMPILE_IFELSE.
Replace AC_TRY_RUN with AC_RUN_IFELSE.
* configure.ac: Replace AM_PROG_LIBTOOL with LT_INIT.  Replace
AC_STDC_HEADERS with AC_HEADER_STDC.

libbacktrace/ChangeLog:

* configure: Regenerate.
* configure.ac: Replace AC_CANONICAL_SYSTEM with AC_CANONICAL_TARGET.
Remove redundant AM_PROG_LIBTOOL.

libcc1/ChangeLog:

* configure: Regenerate.
* configure.ac: Replace AC_CANONICAL_SYSTEM with AC_CANONICAL_TARGET.
Remove redundant AM_PROG_LIBTOOL.

libcpp/ChangeLog:

* configure: Regenerate.
* configure.ac: Replace AC_CANONICAL_SYSTEM with AC_CANONICAL_TARGET.
Replace AC_TRY_COMPILE with AC_COMPILE_IFELSE.

libgcc/ChangeLog:

* configure: Regenerate.
* configure.ac: Replace AC_HELP_STRING with AS_HELP_STRING.  Replace
AC_TRY_COMPILE with AC_COMPILE_IFELSE.

libgcobol/ChangeLog:

* configure: Regenerate.
* configure.ac: Remove redundant AM_PROG_LIBTOOL.

libgfortran/ChangeLog:

* acinclude.m4: Replace AC_TRY_COMPILE with AC_COMPILE_IFELSE.
* configure.ac: Replace AC_LANG_C with AC_LANG([C]).  Replace
AM_PROG_LIBTOOL with LT_INIT.

libgm2/ChangeLog:

* acinclude.m4: Replace AC_HELP_STRING with AS_HELP_STRING.  Replace
AC_LANG_SAVE AC_LANG_CPLUSPLUS (...) AC_LANG_RESTORE with
AC_LANG_PUSH([C++]) (...) AC_LANG_POP([C++]).  Replace AC_TRY_LINK with
AC_LINK_IFELSE.  Replace AC_TRY_COMPILE with AC_COMPILE_IFELSE.
* configure: Regenerate.
* configure.ac: Replace AC_HELP_STRING AS_HELP_STRING.  Remove redundant
AM_PROG_LIBTOOL.  Replace AC_LANG_C with AC_LANG([C]).  Replace
AC_FOREACH with m4_foreach_w.

libgomp/ChangeLog:

* acinclude.m4: Replace AC_TRY_LINK with AC_LINK_IFELSE.  Replace
AC_TRY_COMPILE with AC_COMPILE_IFELSE.  Replace AC_HELP_STRING with
AS_HELP_STRING.  Replace AC_TRY_RUN with AC_RUN_IFELSE.
* configure: Regenerate.
* configure.ac: Replace AM_PROG_LIBTOOL with LT_INIT.  Replace
AC_STDC_HEADERS with AC_HEADER_STDC.  Replace _AC_COMPUTE_INT with
AC_COMPUTE_INT.

libgrust/ChangeLog:

[to-be-committed][RISC-V] Clear both upper and lower bits using 3 shifts

2025-05-21 Thread Jeff Law
So the next step in Shreya's work.  In the prior patch we used two 
shifts to clear bits at the high or low end of an object.  In this patch 
we use 3 shifts to clear bits on both ends.


Nothing really special here.  With mvconst_internal still in the tree 
it's of marginal value, though Shreya and I have confirmed the code 
coming out of expand looks good.  It's just that combine reconstitutes 
the operation via mvconst_internal+and which looks cheaper.


When I was playing in this space earlier I definitely saw testsuite 
cases that need this case handled to not regress with mvconst_internal 
removed.


This has spun in my tester on rv32 and rv64 and it's bootstrap + testing 
on my BPI with a mere 23 hours to go.  Waiting on pre-commit testing to 
render a verdict before moving forward.


Jeff



gcc/
* config/riscv/riscv.cc (synthesize_and): When profitable, use a three
shift sequence to clear bits at both upper and lower bits rather than
synthesizing the constant mask.

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 41a164bc778..358d1ec5d32 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -14562,6 +14562,34 @@ synthesize_and (rtx operands[3])
   return true;
 }
 
+  /* If there are all zeros, except for a run of 1s somewhere in the middle
+ of the constant, then this is at worst 3 shifts.  */
+  t = INTVAL (operands[2]);
+  if (budget >= 3
+  && consecutive_bits_operand (GEN_INT (t), word_mode)
+  && popcount_hwi (t) > 3)
+{
+  /* Shift right to clear the low order bits.  */
+  int count = ctz_hwi (INTVAL (operands[2]));
+  rtx x = gen_rtx_LSHIFTRT (word_mode, operands[1], GEN_INT (count));
+  output = gen_reg_rtx (word_mode);
+  emit_insn (gen_rtx_SET (output, x));
+  input = output;
+
+  /* Shift left to clear the high order bits.  */
+  count += clz_hwi (INTVAL (operands[2])) % BITS_PER_WORD;
+  x = gen_rtx_ASHIFT (word_mode, input, GEN_INT (count));
+  output = gen_reg_rtx (word_mode);
+  emit_insn (gen_rtx_SET (output, x));
+  input = output;
+
+  /* And shift back right to put the bits into position.  */
+  count = clz_hwi (INTVAL (operands[2])) % BITS_PER_WORD;
+  x = gen_rtx_LSHIFTRT (word_mode, input, GEN_INT (count));
+  emit_insn (gen_rtx_SET (operands[0], x));
+  return true;
+}
+
   /* If the remaining budget has gone to less than zero, it
  forces the value into a register and performs the AND
  operation.  It returns TRUE to the caller so the caller


Re: [PATCH] match: Undo maybe_push_res_to_seq in some cases [PR120331]

2025-05-21 Thread Jeff Law




On 5/18/25 10:38 AM, Andrew Pinski wrote:

While working on improving forwprop and removal of
forward_propagate_into_gimple_cond/forward_propagate_into_comparison,
I came cross a case where we end up with SSA_NAME in the resulting
gimple_match_op and one statement in the sequence.  This was the result
of simplification of:
```
_3 = MIN_EXPR  > 16
if (_3 > 16) ...
```

Which simplifies down to:
(maxlen_2(D) > 16) & (264 > 16)
into
(maxlen_2(D) > 16) & 1

Which `maxlen_2(D) > 16` gets pushed onto the sequence
and then the & 1 is removed via the match pattern:
```
/* x & ~0 -> x  */
(simplify
  (bit_and @0 integer_all_onesp)
   (non_lvalue @0))
```

So what this patch does is to undo the push extracting the new op
from the pushed statement and remove the sequence as it is not used
any more.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/ChangeLog:

PR tree-optimization/120331
* gimple-match-exports.cc (maybe_undo_push): New function.
(gimple_simplify): Call maybe_undo_push if resimplify was successfull.
OK, but this isn't my strongest area.  So give Richi until Monday AM to 
chime in if he's got concerns.


Thanks,
jeff



[PATCH] i386, v2: Extend *cmp_minus_1 optimizations also to plus with CONST_INT [PR120360]

2025-05-21 Thread Jakub Jelinek
On Wed, May 21, 2025 at 11:48:34AM +0200, Uros Bizjak wrote:
> Please introduce "x86_64_neg_const_int_operand" predicate that will
> allow only const_int operands, and will reject negative endbr (and
> wide DImode) const_ints. You don't need a constraint if the predicate
> allows only const_ints (the const_int won't be reloaded).
> 
> > + (const_int 0)))]
> > +  "CONST_INT_P (operands[1])
> > +   && ix86_match_ccmode (insn, CCGOCmode)
> > +   && (mode != DImode || !mode_signbit_p (SImode, operands[1]))
> > +   && ((flag_cf_protection & CF_BRANCH) == 0
> > +   || ((-INTVAL (operands[1]) & 0xUL)
> > +  != (TARGET_64BIT ? 0xfa1e0ff3UL : 0xfb1e0ff3UL)))"
> 
> New predicate will also avoid the above horrible insn condition.

So like this (if it passes bootstrap/regtest)?
Note, I'm using "n" rather than "" constraints, because with "e" we could
get into trouble when the non-negated value would match endbr{64,32} - the
predicate only checks (I think that is desirable) that the negation isn't
endbr{64,32}.

2025-05-21  Jakub Jelinek  

PR target/120360
* config/i386/predicates.md (x86_64_neg_const_int_operand): New
predicate.
* config/i386/i386.md (*cmp_plus_1): New pattern.

* gcc.target/i386/pr120360.c: New test.

--- gcc/config/i386/predicates.md.jj2025-05-20 08:14:05.053424802 +0200
+++ gcc/config/i386/predicates.md   2025-05-21 13:10:09.94528 +0200
@@ -393,6 +393,23 @@ (define_predicate "x86_64_zext_immediate
   return false;
 })
 
+;; Return true if VALUE is a constant integer whose negation satisfies
+;; x86_64_immediate_operand.
+(define_predicate "x86_64_neg_const_int_operand"
+  (match_code "const_int")
+{
+  HOST_WIDE_INT val = -UINTVAL (op);
+  if (mode == DImode && trunc_int_for_mode (val, SImode) != val)
+return false;
+  if (flag_cf_protection & CF_BRANCH)
+{
+  unsigned HOST_WIDE_INT endbr = TARGET_64BIT ? 0xfa1e0ff3 : 0xfb1e0ff3;
+  if ((val & HOST_WIDE_INT_C (0x)) == endbr)
+   return false;
+}
+  return true;
+})
+
 ;; Return true if VALUE is a constant integer whose low and high words satisfy
 ;; x86_64_immediate_operand.
 (define_predicate "x86_64_hilo_int_operand"
--- gcc/config/i386/i386.md.jj  2025-05-20 08:14:05.036425035 +0200
+++ gcc/config/i386/i386.md 2025-05-21 13:04:12.441142398 +0200
@@ -1599,6 +1599,20 @@ (define_insn "*cmp_minus_1"
   [(set_attr "type" "icmp")
(set_attr "mode" "")])
 
+(define_insn "*cmp_plus_1"
+  [(set (reg FLAGS_REG)
+   (compare
+ (plus:SWI (match_operand:SWI 0 "nonimmediate_operand" "m")
+   (match_operand:SWI 1 "x86_64_neg_const_int_operand" "n"))
+ (const_int 0)))]
+  "ix86_match_ccmode (insn, CCGOCmode)"
+{
+  operands[1] = gen_int_mode (-INTVAL (operands[1]), mode);
+  return "cmp{}\t{%1, %0|%0, %1}";
+}
+  [(set_attr "type" "icmp")
+   (set_attr "mode" "")])
+
 (define_insn "*cmpqi_ext_1"
   [(set (reg FLAGS_REG)
(compare
--- gcc/testsuite/gcc.target/i386/pr120360.c.jj 2025-05-20 20:40:32.194962716 
+0200
+++ gcc/testsuite/gcc.target/i386/pr120360.c2025-05-20 20:43:03.910930990 
+0200
@@ -0,0 +1,36 @@
+/* PR target/120360 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-stack-protector -masm=att" } */
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
+/* { dg-final { scan-assembler-times "\tjn*s\t" 3 } } */
+/* { dg-final { scan-assembler-times "\tcmp\[lq]\t%" 1 } } */
+/* { dg-final { scan-assembler-times "\tcmp\[lq]\t\\\$-1234," 1 } } */
+/* { dg-final { scan-assembler-times "\tcmp\[lq]\t\\\$2345," 1 } } */
+/* { dg-final { scan-assembler-not "\tadd\[lq]\t" { target { ! *-*-darwin* } } 
} } */
+/* { dg-final { scan-assembler-not "\tsub\[lq]\t" { target { ! *-*-darwin* } } 
} } */
+
+void qux (unsigned long);
+
+void
+foo (unsigned long x, unsigned long y)
+{
+  unsigned long z = x - y;
+  if ((long) z < 0)
+qux (x);
+}
+
+void
+bar (unsigned long x)
+{
+  unsigned long z = x + 1234;
+  if ((long) z < 0)
+qux (x);
+}
+
+void
+baz (unsigned long x)
+{
+  unsigned long z = x - 2345;
+  if ((long) z < 0)
+qux (x);
+}


Jakub



Re: [PATCH v2 1/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Christopher Bazley

On 21/05/2025 12:26, Christopher Bazley wrote:

Hi Joseph,

Thanks for reviewing my patch.

On 20/05/2025 18:02, Joseph Myers wrote:

On Tue, 20 May 2025, Christopher Bazley wrote:


+    if (!cleared)
+  {
+    if (complete_p.padded_non_union
+    && warn_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_ALL)
+  {
+    warning (OPT_Wzero_init_padding_bits_,
+ "Padding bits might not be initialized to zero; "
+ "consider using %<-fzero-init-padding-bits=all%>");
+  }
+    else if (complete_p.padded_union
+ && warn_zero_init_padding_bits
+    >= ZERO_INIT_PADDING_BITS_UNIONS)
+  {
+    warning (OPT_Wzero_init_padding_bits_,
+ "Padding bits might not be initialized to zero; "
+ "consider using %<-fzero-init-padding-bits=unions%> "
+ "or %<-fzero-init-padding-bits=all%>");

Diagnostics should start with a lowercase letter.


I'll change it to "padding might not be initialized to zero..." OK?

("padding" seems to be more common than "padding bits" in existing 
messages.)


Is there anything I need to do for initialization?


Sorry, I meant "internationalisation" (i.e. to support translation), not 
"initialization"!


--
Christopher Bazley
Staff Software Engineer, GNU Tools Team.
Arm Ltd, 110 Fulbourn Road, Cambridge, CB1 9NJ, UK.
http://www.arm.com/



Re: [PATCH v23 1/3] c: Add _Countof operator

2025-05-21 Thread Joseph Myers
On Wed, 21 May 2025, Alejandro Colomar wrote:

> @@ -10572,6 +10583,8 @@ c_parser_unary_expression (c_parser *parser)
>  case CPP_KEYWORD:
>switch (c_parser_peek_token (parser)->keyword)
>   {
> + case RID_COUNTOF:
> +   return c_parser_countof_expression (parser);
>   case RID_SIZEOF:
> return c_parser_sizeof_expression (parser);
>   case RID_ALIGNOF:

The comment above this function should be updated to include the _Countof 
syntax for C2Y.

> diff --git a/gcc/testsuite/gcc.dg/countof-vmt.c 
> b/gcc/testsuite/gcc.dg/countof-vmt.c
> new file mode 100644
> index ..cf4bfd1aa74e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/countof-vmt.c
> @@ -0,0 +1,20 @@
> +/* { dg-do run } */
> +/* { dg-options "-std=c2y" } */

I think -std=gnu2y is more appropriate for tests such as this that are 
concerned with GNU extensions (VLAs in structures, in this case).

> diff --git a/gcc/testsuite/gcc.dg/countof-zero-compile.c 
> b/gcc/testsuite/gcc.dg/countof-zero-compile.c
> new file mode 100644
> index ..3dc60ce293bd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/countof-zero-compile.c
> @@ -0,0 +1,38 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=c2y" } */

Likewise for this one using the extension of arrays with zero elements.

> diff --git a/gcc/testsuite/gcc.dg/countof-zero.c 
> b/gcc/testsuite/gcc.dg/countof-zero.c
> new file mode 100644
> index ..678a08148a5c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/countof-zero.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run } */
> +/* { dg-options "-std=c2y" } */

Likewise for this one as well.

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



[PATCH] RISC-V: Default-initialize variable.

2025-05-21 Thread Robin Dapp

Hi,

this patch initializes saved_vxrm_mode to VXRM_MODE_NONE.  This is a
warning (but no error) when building the compiler so better fix it.

Regtested on rv64gcv_zvl512b.  Going to commit as obvious if the CI
is happy.

Regards
Robin

gcc/ChangeLog:

* config/riscv/riscv.cc (singleton_vxrm_need): Init
saved_vxrm_mode.
---
gcc/config/riscv/riscv.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 0b10842d176..8849b2c05c1 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12298,7 +12298,7 @@ singleton_vxrm_need (void)
  /* Walk the IL noting if VXRM is needed and if there's more than one
 mode needed.  */
  bool found = false;
-  int saved_vxrm_mode;
+  int saved_vxrm_mode = VXRM_MODE_NONE;
  for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
  if (!INSN_P (insn) || DEBUG_INSN_P (insn))
--
2.49.0



[PATCH] RISC-V: Add autovec mode param.

2025-05-21 Thread Robin Dapp

Hi,

This patch adds a --param=autovec-mode=.  When the param is
specified we make autovectorize_vector_modes return exactly this mode if
it is available.  This helps when testing different vectorizer settings.

Regtested on rv64gcv_zvl512b.

Regards
Robin

gcc/ChangeLog:

* config/riscv/riscv-v.cc (autovectorize_vector_modes): Return
user-specified mode if available.
* config/riscv/riscv.opt: New param.
---
gcc/config/riscv/riscv-v.cc | 20 
gcc/config/riscv/riscv.opt  |  4 
2 files changed, 24 insertions(+)

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 1b5ef51886e..a7f2f0a4abe 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -2821,6 +2821,26 @@ autovectorize_vector_modes (vector_modes *modes, bool)
i++;
size = base_size / (1U << i);
 }
+
+  /* If the user specified the exact mode to use look if it is available and
+ remove all other ones before returning.  */
+  if (riscv_autovec_mode)
+{
+  auto_vector_modes ms;
+  ms.safe_splice (*modes);
+  modes->truncate (0);
+
+  for (machine_mode mode : ms)
+   {
+ if (!strcmp (GET_MODE_NAME (mode), riscv_autovec_mode))
+   {
+ modes->safe_push (mode);
+ return 0;
+   }
+   }
+  return 0;
+}
+
  /* Enable LOOP_VINFO comparison in COST model.  */
  return VECT_COMPARE_COSTS;
}
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 527e09549a8..5b6dbc6bb4e 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -286,6 +286,10 @@ Max number of bytes to compare as part of inlined 
strcmp/strncmp routines (defau
Target RejectNegative Joined UInteger Var(gpr2vr_cost) 
Init(GPR2VR_COST_UNPROVIDED)
Set the cost value of the rvv instruction when operate from GPR to VR.

+-param=autovec-mode=
+Target Undocumented RejectNegative Joined Var(riscv_autovec_mode) Save
+Set the only autovec mode to try.
+
Enum
Name(rvv_max_lmul) Type(enum rvv_max_lmul_enum)
The RVV possible LMUL (-mrvv-max-lmul=):
--
2.49.0



[PATCH v4 0/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Christopher Bazley
Commit 0547dbb725b reduced the number of cases in which
union padding bits are zeroed when the relevant language
standard does not strictly require it, unless gcc was
invoked with -fzero-init-padding-bits=unions or
-fzero-init-padding-bits=all in order to explicitly
request zeroing of padding bits.

This commit adds a closely related warning,
-Wzero-init-padding-bits=, which is intended to help
programmers to find code that might now need to be
rewritten or recompiled with
-fzero-init-padding-bits=unions or
-fzero-init-padding-bits=all in order to replicate
the behaviour that it had when compiled by older
versions of GCC. It can also be used to find struct
padding that was never previously guaranteed to be
zero initialized and still isn't unless GCC is
invoked with -fzero-init-padding-bits=all option.

The new warning can be set to the same three states
as -fzero-init-padding-bits ('standard', 'unions'
or 'all') and has the same default value ('standard').

The two options interact as follows:

  f: standard  f: unions   f: all
w: standard X X X
w: unions   U X X
w: all  A S X

X = No warnings about padding
U = Warnings about padding of unions.
S = Warnings about padding of structs.
A = Warnings about padding of structs and unions.

The level of optimisation and whether or not the
entire initializer is dropped to memory can both
affect whether warnings are produced when compiling
a given program. This is intentional, since tying
the warnings more closely to the relevant language
standard would require a very different approach
that would still be target-dependent, might impose
an unacceptable burden on programmers, and would
risk not satisfying the intended use-case (which
is closely tied to a specific optimisation).

Bootstrapped the compiler and tested on AArch64
and x86-64 using some new tests for
-Wzero-init-padding-bits and the existing tests
for -fzero-init-padding-bits
(check-gcc RUNTESTFLAGS="dg.exp=*-empty-init-*.c").

Base commit is a470433732e77ae29a717cf79049ceeea3cbe979

Changes in v2:
 - Added missing changelog entry.

Changes in v3:
 - Modified two tests in which I had neglected to
   ensure that initializers were not compile time
   constants. This policy prevents the entire
   initializer being dropped to memory, which
   would otherwise prevent the expected diagnostic
   message from being produced.
 - Amended the diagnostic message from "Padding bits
   might not.." to "padding might not..."

Changes in v4:
- Removed redundant braces.
- Added "if code relies on it being zero," to the
  diagnostic message.

Link to v1:
https://inbox.sourceware.org/gcc-patches/20250520104940.3546-1-chris.baz...@arm.com/

Link to v2:
https://inbox.sourceware.org/gcc-patches/20250520144524.5968-1-chris.baz...@arm.com/

Link to v3:
https://inbox.sourceware.org/gcc-patches/20250521124745.24592-1-chris.baz...@arm.com/

Christopher Bazley (1):
  Add warnings of potentially-uninitialized padding bits

 gcc/common.opt|  4 +
 gcc/doc/invoke.texi   | 85 ++-
 gcc/expr.cc   | 41 -
 gcc/expr.h|  7 +-
 gcc/gimplify.cc   | 27 +-
 gcc/testsuite/gcc.dg/c23-empty-init-warn-1.c  | 68 +++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-10.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-11.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-12.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-13.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-14.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-15.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-16.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-17.c | 51 +++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-2.c  | 69 +++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-3.c  |  7 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-4.c  | 69 +++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-5.c  |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-6.c  |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-7.c  |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-8.c  |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-9.c  | 69 +++
 .../gcc.dg/gnu11-empty-init-warn-1.c  | 52 
 .../gcc.dg/gnu11-empty-init-warn-10.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-11.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-12.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-13.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-14.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-15.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-16.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-17.c | 51 +++
 .../gcc.dg/gnu11-empty-init-warn-2.c  | 59 +
 .../gcc.dg/gnu11-empty-init-warn-3.c  |  7 ++
 .../gcc.dg/gnu11-empty-init-warn-4.c 

Re: [PATCH v23 1/3] c: Add _Countof operator

2025-05-21 Thread Alejandro Colomar
Hi Joseph,

On Wed, May 21, 2025 at 04:26:46PM +, Joseph Myers wrote:
> On Wed, 21 May 2025, Alejandro Colomar wrote:
> 
> > @@ -10572,6 +10583,8 @@ c_parser_unary_expression (c_parser *parser)
> >  case CPP_KEYWORD:
> >switch (c_parser_peek_token (parser)->keyword)
> > {
> > +   case RID_COUNTOF:
> > + return c_parser_countof_expression (parser);
> > case RID_SIZEOF:
> >   return c_parser_sizeof_expression (parser);
> > case RID_ALIGNOF:
> 
> The comment above this function should be updated to include the _Countof 
> syntax for C2Y.

Makes sense.  I'm unsure where exactly I should put it.  Is this okay?

diff --git i/gcc/c/c-parser.cc w/gcc/c/c-parser.cc
index 87700339394b..08350a216dd8 100644
--- i/gcc/c/c-parser.cc
+++ w/gcc/c/c-parser.cc
@@ -10456,20 +10456,22 @@ c_parser_cast_expression (c_parser *parser, 
struct c_expr *after)
 return c_parser_unary_expression (parser);
 }
 
 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
 
unary-expression:
  postfix-expression
  ++ unary-expression
  -- unary-expression
  unary-operator cast-expression
+ _Countof unary-expression
+ _Countof ( type-name )
  sizeof unary-expression
  sizeof ( type-name )
 
unary-operator: one of
  & * + - ~ !
 
GNU extensions:
 
unary-expression:
  __alignof__ unary-expression

> > diff --git a/gcc/testsuite/gcc.dg/countof-vmt.c 
> > b/gcc/testsuite/gcc.dg/countof-vmt.c
> > new file mode 100644
> > index ..cf4bfd1aa74e
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/countof-vmt.c
> > @@ -0,0 +1,20 @@
> > +/* { dg-do run } */
> > +/* { dg-options "-std=c2y" } */
> 
> I think -std=gnu2y is more appropriate for tests such as this that are 
> concerned with GNU extensions (VLAs in structures, in this case).

Makes sense (and likewise for the below).  When you confirm the above,
I'll send v24 your way.  Thanks for the review!


Have a lovely day!
Alex

> 
> > diff --git a/gcc/testsuite/gcc.dg/countof-zero-compile.c 
> > b/gcc/testsuite/gcc.dg/countof-zero-compile.c
> > new file mode 100644
> > index ..3dc60ce293bd
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/countof-zero-compile.c
> > @@ -0,0 +1,38 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-std=c2y" } */
> 
> Likewise for this one using the extension of arrays with zero elements.
> 
> > diff --git a/gcc/testsuite/gcc.dg/countof-zero.c 
> > b/gcc/testsuite/gcc.dg/countof-zero.c
> > new file mode 100644
> > index ..678a08148a5c
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/countof-zero.c
> > @@ -0,0 +1,31 @@
> > +/* { dg-do run } */
> > +/* { dg-options "-std=c2y" } */
> 
> Likewise for this one as well.
> 
> -- 
> Joseph S. Myers
> josmy...@redhat.com
> 

-- 



signature.asc
Description: PGP signature


Re: [PATCH] libstdc++: Make debug iterator pointer sequence const [PR116369]

2025-05-21 Thread François Dumont
Sending again because my previous reply got a weird 'Got' word as its 
header that might be making it looks like a mistake.


On 14/05/2025 18:46, Jonathan Wakely wrote:

On Wed, 14 May 2025 at 17:31, François Dumont  wrote:

On 12/05/2025 23:03, Jonathan Wakely wrote:

On 31/03/25 22:20 +0200, François Dumont wrote:

Hi

Following this previous patch
https://gcc.gnu.org/pipermail/libstdc++/2024-August/059418.html I've
completed it for the _Safe_unordered_container_base type and
implemented the rest of the change to store the safe iterator
sequence as a pointer-to-const.

 libstdc++: Make debug iterator pointer sequence const [PR116369]

 In revision a35dd276cbf6236e08bcf6e56e62c2be41cf6e3c the debug
sequence
 have been made mutable to allow attach iterators to const
containers.
 This change completes this fix by also declaring debug unordered
container
 members mutable.

 Additionally the debug iterator sequence is now a
pointer-to-const and so
 _Safe_sequence_base _M_attach and all other methods are const
qualified.
 Symbols export are maintained thanks to __asm directives.


I can't compile this, it seems to be missing changes to
safe_local_iterator.tcc:

In file included from
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_local_iterator.h:444,
  from
/home/jwakely/src/gcc/gcc/libstdc++-v3/src/c++11/debug.cc:33:
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_local_iterator.tcc:
In member function ‘typename
__gnu_debug::_Distance_traits<_Iterator>::__type
__gnu_debug::_Safe_local_iterator<_Iterator,
_Sequence>::_M_get_distance_to(const
__gnu_debug::_Safe_local_iterator<_Iterator, _Sequence>&) const’:
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_local_iterator.tcc:47:17:
error: there are no arguments to ‘_M_get_sequence’ that depend on a
template parameter, so a declaration of ‘_M_get_sequence’ must be
available [-Wtemplate-body]
47 | _M_get_sequence()->bucket_size(bucket()),
   | ^~~
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_local_iterator.tcc:47:17:
note: (if you use ‘-fpermissive’, G++ will accept your code, but
allowing the use of an undeclared name is deprecated)
/home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_local_iterator.tcc:59:18:
error: there are no arguments to ‘_M_get_sequence’ that depend on a
template parameter, so a declaration of ‘_M_get_sequence’ must be
available [-Wtemplate-body]
59 | -_M_get_sequence()->bucket_size(bucket()),
   |  ^~~


Yes, sorry, I had already spotted this problem, but only updated the PR
and not re-sending patch here.



Also available as a PR

https://forge.sourceware.org/gcc/gcc-TEST/pulls/47

 /** Detach all singular iterators.
  *  @post for all iterators i attached to this sequence,
  *   i->_M_version == _M_version.
  */
 void
-_M_detach_singular();
+_M_detach_singular() const
+ __asm("_ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv");

Does this work on all targets?

No idea ! I thought the symbol name used here just had to match the
entries in config/abi/pre/gnu.ver.

That linker script is not used for all targets.

Ok, got it, I only need to use this when symbol versioning is activated.

I think this new patch should do it then.
diff --git a/libstdc++-v3/include/debug/formatter.h 
b/libstdc++-v3/include/debug/formatter.h
index d80e8a78dcb..8aa84adec77 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -96,7 +96,7 @@ namespace __gnu_debug
   template
 class _Safe_iterator;
 
-  template
+  template
 class _Safe_local_iterator;
 
   template
@@ -316,8 +316,8 @@ namespace __gnu_debug
}
}
 
-  template
-   _Parameter(_Safe_local_iterator<_Iterator, _Sequence> const& __it,
+  template
+   _Parameter(_Safe_local_iterator<_Iterator, _UContainer> const& __it,
   const char* __name, _Is_iterator)
: _M_kind(__iterator),  _M_variant()
{
@@ -326,8 +326,8 @@ namespace __gnu_debug
  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(_Iterator);
  _M_variant._M_iterator._M_constness =
__it._S_constant() ? __const_iterator : __mutable_iterator;
- _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
- _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
+ _M_variant._M_iterator._M_sequence = __it._M_get_ucontainer();
+ _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_UContainer);
 
  if (__it._M_singular())
{
diff --git a/libstdc++-v3/include/debug/safe_base.h 
b/libstdc++-v3/include/debug/safe_base.h
index cf3f1708ad2..7f7876e4017 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_bas

Re: [PATCH] libstdc++: Fix vector(from_range_t, R&&) for exceptions [PR120367]

2025-05-21 Thread Patrick Palka
On Wed, 21 May 2025, Jonathan Wakely wrote:

> Because this constructor delegates to vector(a) the object has been
> fully constructed and the destructor will run if an exception happens.
> That means we need to set _M_finish == _M_start so that the destructor
> doesn't try to destroy any elements.

LGTM (and TIL!)

> 
> libstdc++-v3/ChangeLog:
> 
>   PR libstdc++/120367
>   * include/bits/stl_vector.h (_M_range_initialize): Initialize
>   _M_impl._M_finish.
>   * testsuite/23_containers/vector/cons/from_range.cc: Check with
>   a type that throws on construction.
>   exceptions during construction.
> ---
> 
> Tested x86_64-linux.
> 
>  libstdc++-v3/include/bits/stl_vector.h|  1 +
>  .../23_containers/vector/cons/from_range.cc   | 22 +++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/libstdc++-v3/include/bits/stl_vector.h 
> b/libstdc++-v3/include/bits/stl_vector.h
> index 57680b7bbcf3..43b913da778d 100644
> --- a/libstdc++-v3/include/bits/stl_vector.h
> +++ b/libstdc++-v3/include/bits/stl_vector.h
> @@ -1971,6 +1971,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>   {
> pointer __start = this->_M_impl._M_start =
>   this->_M_allocate(_S_check_init_len(__n, _M_get_Tp_allocator()));
> +   this->_M_impl._M_finish = __start;
> this->_M_impl._M_end_of_storage = __start + __n;
> this->_M_impl._M_finish
> = std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last,
> diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc 
> b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
> index 7a62645283d2..3784b9cd66ad 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
> @@ -106,8 +106,30 @@ test_constexpr()
>return true;
>  }
>  
> +void
> +test_pr120367()
> +{
> +#ifdef __cpp_exceptions
> +  struct X
> +  {
> +X(int) { throw 1; } // Cannot successfully construct an X.
> +~X() { VERIFY(false); } // So should never need to destroy one.
> +  };
> +
> +  try
> +  {
> +int i[1]{};
> +std::vector v(std::from_range, i);
> +  }
> +  catch (int)
> +  {
> +  }
> +#endif
> +}
> +
>  int main()
>  {
>test_ranges();
>static_assert( test_constexpr() );
> +  test_pr120367();
>  }
> -- 
> 2.49.0
> 
> 



Re: [PATCH] c++: substituting fn parm redeclared with dep alias tmpl [PR120224]

2025-05-21 Thread Jason Merrill

On 5/20/25 11:28 AM, Patrick Palka wrote:

On Mon, 19 May 2025, Patrick Palka wrote:


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


Whoops, CI reports I missed a testsuite adjustment expecting an
additional error in other/default13.C, which seems reasonable.  Here's
an updated patch.


OK.


-- >8 --

Here we declare f twice, first ordinarily and then using a dependent
alias template.  Due to alias template transparency these logically
declare the same overload.  But now the function type of f, which was
produced from the first declaration, diverges from the type of its
formal parameter, which is produced from the subsequent redefinition,
in that substituting T=int succeeds for the function type but not for
the formal parameter type.  This eventually causes us to produce an
undiagnosed error_mark_node in the AST of function call, leading to
a sanity check failure added in r14-6343-g0c018a74eb1aff.

Before r14-6343, we would later reject the testcase albeit from
regenerate_decl_from_template when instantiating the definition of f,
making this a regression.

To fix this, it seems we just need to check for errors when substituting
the type of a PARM_DECL, since that could still fail despite substitution
into the function type succeeding.

PR c++/120224

gcc/cp/ChangeLog:

* pt.cc (tsubst_function_decl): Return error_mark_node if any
of the substituted function parameters are erroneous.
(tsubst_decl) : Return error_mark_node if
the substituted function parameter type is erroneous.

gcc/testsuite/ChangeLog:

* g++.dg/other/default13.C: Expect additional overload
resolution failure diagnostic.
* g++.dg/cpp0x/alias-decl-80.C: New test.
---
  gcc/cp/pt.cc   |  9 -
  gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C | 14 ++
  gcc/testsuite/g++.dg/other/default13.C |  2 +-
  3 files changed, 23 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1973d25b61a0..df6d7bb136ea 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -14903,7 +14903,11 @@ tsubst_function_decl (tree t, tree args, 
tsubst_flags_t complain,
  parms = DECL_CHAIN (parms);
parms = tsubst (parms, args, complain, t);
for (tree parm = parms; parm; parm = DECL_CHAIN (parm))
-DECL_CONTEXT (parm) = r;
+{
+  if (parm == error_mark_node)
+   return error_mark_node;
+  DECL_CONTEXT (parm) = r;
+}
if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t))
  {
tree tparm = build_this_parm (r, closure, type_memfn_quals (type));
@@ -15474,6 +15478,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain,
/* We're dealing with a normal parameter.  */
type = tsubst (TREE_TYPE (t), args, complain, in_decl);
  
+	if (type == error_mark_node)

+ RETURN (error_mark_node);
+
  type = type_decays_to (type);
  TREE_TYPE (r) = type;
  cp_apply_type_quals_to_decl (cp_type_quals (type), r);
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C 
b/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C
new file mode 100644
index ..e2ff663843de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C
@@ -0,0 +1,14 @@
+// PR c++/120224
+// { dg-do compile { target c++11 } }
+
+template using void_t = void;
+
+template
+void f(void*); // #1
+
+template
+void f(void_t*) { } // { dg-error "not a class" } #2
+
+int main() {
+  f(0); // { dg-error "no match" }
+}
diff --git a/gcc/testsuite/g++.dg/other/default13.C 
b/gcc/testsuite/g++.dg/other/default13.C
index eae23ffdf2d1..381aee78ea2c 100644
--- a/gcc/testsuite/g++.dg/other/default13.C
+++ b/gcc/testsuite/g++.dg/other/default13.C
@@ -8,4 +8,4 @@ template < typename > struct B
int f;
  };
  
-B < int > b (0);

+B < int > b (0); // { dg-error "no match" }




[PATCH v3 1/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Christopher Bazley
Commit 0547dbb725b reduced the number of cases in which
union padding bits are zeroed when the relevant language
standard does not strictly require it, unless gcc was
invoked with -fzero-init-padding-bits=unions or
-fzero-init-padding-bits=all in order to explicitly
request zeroing of padding bits.

This commit adds a closely related warning,
-Wzero-init-padding-bits=, which is intended to help
programmers to find code that might now need to be
rewritten or recompiled with
-fzero-init-padding-bits=unions or
-fzero-init-padding-bits=all in order to replicate
the behaviour that it had when compiled by older
versions of GCC. It can also be used to find struct
padding that was never previously guaranteed to be
zero initialized and still isn't unless GCC is
invoked with -fzero-init-padding-bits=all.

The new warning can be set to the same three states
as -fzero-init-padding-bits ('standard', 'unions'
or 'all') and has the same default value ('standard').

The two options interact as follows:

 f: standard  f: unions   f: all
w: standard X X X
w: unions   U X X
w: all  A S X

X = No warnings about padding
U = Warnings about padding of unions.
S = Warnings about padding of structs.
A = Warnings about padding of structs and unions.

The level of optimisation and whether or not the
entire initializer is dropped to memory can both
affect whether warnings are produced when compiling
a given program. This is intentional, since tying
the warnings more closely to the relevant language
standard would require a very different approach
that would still be target-dependent, might impose
an unacceptable burden on programmers, and would
risk not satisfying the intended use-case (which
is closely tied to a specific optimisation).

gcc/ChangeLog:

* common.opt: Add Wzero-init-padding-bits=.
* doc/invoke.texi: Document Wzero-init-padding-bits=.
* expr.cc (categorize_ctor_elements_1): Update new struct type
ctor_completeness instead of an integer to indicate presence of
padding or missing fields in a constructor. Instead of setting -1
upon discovery of padding bits in both structs and unions,
set separate flags to indicate the type of padding bits.
(categorize_ctor_elements): Update the type and documentation of
the p_complete parameter.
(mostly_zeros_p): Use new struct type ctor_completeness when
calling categorize_ctor_elements.
(all_zeros_p): Use new struct type ctor_completeness when
calling categorize_ctor_elements.
* expr.h (struct ctor_completeness): New struct type to replace an
an integer that could take the value -1 ('all fields are
initialized, but there's padding'), 0 ('fields are missing') or
1 ('all fields are initialized, and there's no padding'). Named
bool members make the code easier to understand and make room to
disambiguate struct padding bits from union padding bits.
(categorize_ctor_elements): Update the function declaration to use
the new struct type in the last parameter declaration.
* gimplify.cc (gimplify_init_constructor): Replace use of
complete_p != 0 ('all fields are initialized') with !sparse,
replace use of complete == 0 ('fields are missing') with sparse, and
replace use of complete <= 0 ('fields are missing' or 'all fields are
initialized, but there's padding') with sparse || padded_union or
padded_non_union. Trigger new warnings if storage for the object
is not zeroed but padded_union or padded_non_union is set
(because this combination implies possible non-zero padding bits).

gcc/testsuite/ChangeLog:

* gcc.dg/c23-empty-init-warn-1.c: New test.
* gcc.dg/c23-empty-init-warn-10.c: New test.
* gcc.dg/c23-empty-init-warn-11.c: New test.
* gcc.dg/c23-empty-init-warn-12.c: New test.
* gcc.dg/c23-empty-init-warn-13.c: New test.
* gcc.dg/c23-empty-init-warn-14.c: New test.
* gcc.dg/c23-empty-init-warn-15.c: New test.
* gcc.dg/c23-empty-init-warn-16.c: New test.
* gcc.dg/c23-empty-init-warn-17.c: New test.
* gcc.dg/c23-empty-init-warn-2.c: New test.
* gcc.dg/c23-empty-init-warn-3.c: New test.
* gcc.dg/c23-empty-init-warn-4.c: New test.
* gcc.dg/c23-empty-init-warn-5.c: New test.
* gcc.dg/c23-empty-init-warn-6.c: New test.
* gcc.dg/c23-empty-init-warn-7.c: New test.
* gcc.dg/c23-empty-init-warn-8.c: New test.
* gcc.dg/c23-empty-init-warn-9.c: New test.
* gcc.dg/gnu11-empty-init-warn-1.c: New test.
* gcc.dg/gnu11-empty-init-warn-10.c: New test.
* gcc.dg/gnu11-empty-init-warn-11.c: New test.

[PATCH v3 0/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Christopher Bazley
Commit 0547dbb725b reduced the number of cases in which
union padding bits are zeroed when the relevant language
standard does not strictly require it, unless gcc was
invoked with -fzero-init-padding-bits=unions or
-fzero-init-padding-bits=all in order to explicitly
request zeroing of padding bits.

This commit adds a closely related warning,
-Wzero-init-padding-bits=, which is intended to help
programmers to find code that might now need to be
rewritten or recompiled with
-fzero-init-padding-bits=unions or
-fzero-init-padding-bits=all in order to replicate
the behaviour that it had when compiled by older
versions of GCC. It can also be used to find struct
padding that was never previously guaranteed to be
zero initialized and still isn't unless GCC is
invoked with -fzero-init-padding-bits=all option.

The new warning can be set to the same three states
as -fzero-init-padding-bits ('standard', 'unions'
or 'all') and has the same default value ('standard').

The two options interact as follows:

  f: standard  f: unions   f: all
w: standard X X X
w: unions   U X X
w: all  A S X

X = No warnings about padding
U = Warnings about padding of unions.
S = Warnings about padding of structs.
A = Warnings about padding of structs and unions.

The level of optimisation and whether or not the
entire initializer is dropped to memory can both
affect whether warnings are produced when compiling
a given program. This is intentional, since tying
the warnings more closely to the relevant language
standard would require a very different approach
that would still be target-dependent, might impose
an unacceptable burden on programmers, and would
risk not satisfying the intended use-case (which
is closely tied to a specific optimisation).

Bootstrapped the compiler and tested on AArch64
and x86-64 using some new tests for
-Wzero-init-padding-bits and the existing tests
for -fzero-init-padding-bits
(check-gcc RUNTESTFLAGS="dg.exp=*-empty-init-*.c").

Base commit is a470433732e77ae29a717cf79049ceeea3cbe979

Changes in v2:
 - Added missing changelog entry.

Changes in v3:
 - Modified two tests in which I had neglected to
   ensure that initializers were not compile time
   constants. This policy prevents the entire
   initializer being dropped to memory, which
   would otherwise prevent the expected diagnostic
   message from being produced.
 - Amended the diagnostic message from "Padding bits
   might not.." to "padding might not..."

Link to v1:
https://inbox.sourceware.org/gcc-patches/20250520104940.3546-1-chris.baz...@arm.com/

Link to v2:
https://inbox.sourceware.org/gcc-patches/20250520144524.5968-2-chris.baz...@arm.com/

Christopher Bazley (1):
  Add warnings of potentially-uninitialized padding bits

 gcc/common.opt|  4 +
 gcc/doc/invoke.texi   | 85 ++-
 gcc/expr.cc   | 41 -
 gcc/expr.h|  7 +-
 gcc/gimplify.cc   | 29 ++-
 gcc/testsuite/gcc.dg/c23-empty-init-warn-1.c  | 68 +++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-10.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-11.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-12.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-13.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-14.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-15.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-16.c |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-17.c | 51 +++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-2.c  | 69 +++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-3.c  |  7 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-4.c  | 69 +++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-5.c  |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-6.c  |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-7.c  |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-8.c  |  8 ++
 gcc/testsuite/gcc.dg/c23-empty-init-warn-9.c  | 69 +++
 .../gcc.dg/gnu11-empty-init-warn-1.c  | 52 
 .../gcc.dg/gnu11-empty-init-warn-10.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-11.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-12.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-13.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-14.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-15.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-16.c |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-17.c | 51 +++
 .../gcc.dg/gnu11-empty-init-warn-2.c  | 59 +
 .../gcc.dg/gnu11-empty-init-warn-3.c  |  7 ++
 .../gcc.dg/gnu11-empty-init-warn-4.c  | 63 ++
 .../gcc.dg/gnu11-empty-init-warn-5.c  |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-6.c  |  8 ++
 .../gcc.dg/gnu11-empty-init-warn-7.c  |  8 ++
 .../gcc.dg/gnu11-empty-init

Re: [PATCH] RISC-V: Support CPUs in -march.

2025-05-21 Thread Kito Cheng
On Wed, May 21, 2025 at 10:19 PM Robin Dapp  wrote:
>
> > I could imagine that is a simpler way to set the march since the march
> > string becomes terribly long - we have an arch string more than 300
> > char...so I support this, although I think this should be discuss with
> > LLVM community, but I think it's fine to accept as a GCC extension.
> >
> > So LGTM, go ahead to the trunk, and I will raise this topic in the
> > next LLVM sync up meeting.
>
> That would be great, thanks.
>
> Another related issue.  i386 and other targets, but not aarch64,
> make -march imply -mtune.  Was it a deliberate decision to _not_ do this?
> Could we even add it still? ;)  That might help simplify things a bit
> further even.

That sounds make sense to me, but let me think about it a few more
(let me sleep first and think more tomorrow :P)
also discuss with a few more people, let's step by step...I don't want
to change too much at one time without sync with the LLVM community :)

>
> --
> Regards
>  Robin
>


[to-be-committed][RISC-V][PR target/120368] Fix 32bit shift on rv64

2025-05-21 Thread Jeff Law
So a followup to last week's bugfix.  In last week's change we we 
stopped using define_insn_and_split to rewrite instructions.  That 
change was done to avoid dropping a masking instruction out of the RTL.


As a result the pattern(s) were changed into simple define_insns, which 
is good.  One of them uses the GPR iterator since it's supposed to work 
for both 32bit and 64bit shifts on rv64.


But we failed to emit the right opcode for a 32bit shift on rv64. 
Thankfully the fix is trivial.  If the mode is anything but word_mode, 
then we must be doing a 32-bit shift on rv64, ie the various "w" shift 
instructions.


It's run through my tester.  Just waiting on the upstream CI system to 
spin it.


Jeff


diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 7f6d0bbab3e..7e35d7877ed 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2938,7 +2938,14 @@ (define_insn "*3_mask_1"
   (match_operand:GPR2 2 "register_operand"  "r")
   (match_operand 3 ""))])))]
   ""
-  "\t%0,%1,%2"
+{
+  /* If the shift mode is not word mode, then it must be the
+ case that we're generating rv64 code, but this is a 32-bit
+ operation.  Thus we need to use the "w" variant.  */
+  if (E_mode != word_mode)
+return "w\t%0,%1,%2";
+  return "\t%0,%1,%2";
+}
   [(set_attr "type" "shift")
(set_attr "mode" "")])
 
diff --git a/gcc/testsuite/gcc.target/riscv/pr120368.c 
b/gcc/testsuite/gcc.target/riscv/pr120368.c
new file mode 100644
index 000..4fea8e6fe7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr120368.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+
+int g;
+
+int
+foo (int s, int v)
+{
+  __builtin_memset (&g, v >> (s & 31), sizeof(g));
+  return g;
+}
+
+int
+main ()
+{
+  int x = foo (-16, 0xd);
+  if (x != 0x0d0d0d0d)
+__builtin_abort();
+  __builtin_exit (0);
+}


[PATCH] testsuite: Fix typo in parse_ctx.cc

2025-05-21 Thread Stefan Schulze Frielinghaus
libstdc++-v3/ChangeLog:

* testsuite/std/format/parse_ctx.cc: Fix typo for bfloat16 guard.
---
 Ok for mainline?

 libstdc++-v3/testsuite/std/format/parse_ctx.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/std/format/parse_ctx.cc 
b/libstdc++-v3/testsuite/std/format/parse_ctx.cc
index adafc58c183..6294dcf43f5 100644
--- a/libstdc++-v3/testsuite/std/format/parse_ctx.cc
+++ b/libstdc++-v3/testsuite/std/format/parse_ctx.cc
@@ -539,7 +539,7 @@ test_dynamic_type_check()
   (void) std::format("{:str}", X{}, "H2G2");
   (void) std::format("{:float}", X{}, 10.0);
 
-#ifdef __STDCPP_FLOAT16_T__
+#ifdef __STDCPP_BFLOAT16_T__
   if constexpr (std::formattable)
 (void) std::format("{:other}", X{}, 10.0bf16);
 #endif
-- 
2.49.0



Re: [PATCH v23 1/3] c: Add _Countof operator

2025-05-21 Thread Joseph Myers
On Wed, 21 May 2025, Alejandro Colomar wrote:

> Makes sense.  I'm unsure where exactly I should put it.  Is this okay?
> 
>   diff --git i/gcc/c/c-parser.cc w/gcc/c/c-parser.cc
>   index 87700339394b..08350a216dd8 100644
>   --- i/gcc/c/c-parser.cc
>   +++ w/gcc/c/c-parser.cc
>   @@ -10456,20 +10456,22 @@ c_parser_cast_expression (c_parser *parser, 
> struct c_expr *after)
>return c_parser_unary_expression (parser);
>}
>
>/* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
>
>   unary-expression:
> postfix-expression
> ++ unary-expression
> -- unary-expression
> unary-operator cast-expression
>   + _Countof unary-expression
>   + _Countof ( type-name )

With some kind of remark to indicate it's new in C2Y, yes.  E.g. 
c_parser_generic_selection's comment says "(The use of a type-name is new 
in C2Y.)".

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



Re: [PATCH v2 1/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Christopher Bazley

Hi Joseph,

Thanks for reviewing my patch.

On 20/05/2025 18:02, Joseph Myers wrote:

On Tue, 20 May 2025, Christopher Bazley wrote:


+   if (!cleared)
+ {
+   if (complete_p.padded_non_union
+   && warn_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_ALL)
+ {
+   warning (OPT_Wzero_init_padding_bits_,
+"Padding bits might not be initialized to zero; "
+"consider using %<-fzero-init-padding-bits=all%>");
+ }
+   else if (complete_p.padded_union
+&& warn_zero_init_padding_bits
+   >= ZERO_INIT_PADDING_BITS_UNIONS)
+ {
+   warning (OPT_Wzero_init_padding_bits_,
+"Padding bits might not be initialized to zero; "
+"consider using %<-fzero-init-padding-bits=unions%> "
+"or %<-fzero-init-padding-bits=all%>");

Diagnostics should start with a lowercase letter.


I'll change it to "padding might not be initialized to zero..." OK?

("padding" seems to be more common than "padding bits" in existing 
messages.)


Is there anything I need to do for initialization?


If there's a meaningful location available for the initialization, then
warning_at (passing an explicit location) is preferred to warning.


I originally intended to use warning_at, but I never found the right way 
of getting a source code location. It wasn't obvious to me what that 
location should be either, since whether or not padding bits are 
initialized may depend on more than one initializer (or the absence of 
an initializer).


Then, I found that the generated warnings seem adequate without using 
warning_at:


/work/gcc/gcc/testsuite/gcc.dg/gnu11-empty-init-warn-1.c:49:12: error: 
padding might not be initialized to zero; consider using 
‘-fzero-init-padding-bits=unions’ or ‘-fzero-init-padding-bits=all’ 
[-Werror=zero-init-padding-bits=]
   49 |   struct F t = { argc, {}, .b = {.a = 2} }; /* { dg-warning 
"padding might not be initialized to zero" } */

  |    ^

The opening brace is highlighted when diagnosing an issue within a 
compound literal:


/work/gcc/gcc/testsuite/gcc.dg/gnu11-empty-init-warn-1.c:55:16: error: 
padding might not be initialized to zero; consider using 
‘-fzero-init-padding-bits=unions’ or ‘-fzero-init-padding-bits=all’ 
[-Werror=zero-init-padding-bits=]
   55 |   aa((struct F){ argc, {}, .b = {.a = 2} }); /* { dg-warning 
"padding might not be initialized to zero" } */

  |    ^

Would you agree this is adequate? If anyone wants different source code 
locations to be highlighted then a future commit could change that.


--
Christopher Bazley
Staff Software Engineer, GNU Tools Team.
Arm Ltd, 110 Fulbourn Road, Cambridge, CB1 9NJ, UK.
http://www.arm.com/



Re: [PATCH v2 1/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Jakub Jelinek
On Wed, May 21, 2025 at 01:42:01PM +0100, Christopher Bazley wrote:
> On 21/05/2025 12:26, Christopher Bazley wrote:
> > Hi Joseph,
> > 
> > Thanks for reviewing my patch.
> > 
> > On 20/05/2025 18:02, Joseph Myers wrote:
> > > On Tue, 20 May 2025, Christopher Bazley wrote:
> > > 
> > > > +    if (!cleared)
> > > > +  {
> > > > +    if (complete_p.padded_non_union
> > > > +    && warn_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_ALL)
> > > > +  {
> > > > +    warning (OPT_Wzero_init_padding_bits_,
> > > > + "Padding bits might not be initialized to zero; "
> > > > + "consider using %<-fzero-init-padding-bits=all%>");
> > > > +  }
> > > > +    else if (complete_p.padded_union
> > > > + && warn_zero_init_padding_bits
> > > > +    >= ZERO_INIT_PADDING_BITS_UNIONS)
> > > > +  {
> > > > +    warning (OPT_Wzero_init_padding_bits_,
> > > > + "Padding bits might not be initialized to zero; "
> > > > + "consider using %<-fzero-init-padding-bits=unions%> "
> > > > + "or %<-fzero-init-padding-bits=all%>");
> > > Diagnostics should start with a lowercase letter.
> > 
> > I'll change it to "padding might not be initialized to zero..." OK?
> > 
> > ("padding" seems to be more common than "padding bits" in existing
> > messages.)
> > 
> > Is there anything I need to do for initialization?
> 
> Sorry, I meant "internationalisation" (i.e. to support translation), not
> "initialization"!

For translations I think it is fine as is.
Please avoid {}s around single statements (e.g. the warning call above).
And, I think the warnings should include text like
"if code relies on it being zero, consider"
because telling people to use those options mindlessly is undesirable.
Having uninitialized padding bits is most of the time just fine, only if
code accesses it (whether writing it to disk, or say computing checksum
of all the bytes in it etc.), it is problematic.
And there are many other cases where nothing warns about those.
struct S { char a; long long b; };
void bar (struct S *);
void foo ()
{
  struct S a = { 1, 2 }; // Here you'd warn?
  struct S b; // Here I'm sure you wouldn't.
  b.a = 1; b.b = 2;
  bar (&a, &b);
}

Jakub



Re: [PATCH v3 0/9] Implement layouts from mdspan.

2025-05-21 Thread Luc Grosheintz

It's missing the "registration" of the three new classes in
std.cc.in.

On 5/21/25 11:40, Luc Grosheintz wrote:

Follows up on:
https://gcc.gnu.org/pipermail/libstdc++/2025-May/061535.html

To improve naming conventions, this series includes three new commits:
   * Two commits to rename  _ExtentsStorage::_M_dynamic_extents, and
 extents::_M_dynamic_extents.
   * One commit to cleanup whitespace errors in extents.

The changes to the existing commits are:
   * Fix division by zero bug.
   * Rename subextents -> extents.
   * Default arguments for __{static,dynamic}_extents.
   * Default argument for __static_quotient.
   * Four times: use range-based for.
   * Eliminate __has_static_zero
   * Short-circuit in __static_quotient.
   * Optimize __exts_prod for rank == rank_dynamic.

This review suggestion was intentionally skipped:
   * Inline helper of __exts_prod, because with the additional
   optimization for rank == rank_dynamic, having two separate
   functions makes the highlevel structure a little bit more
   obvious. Additionally, there's numerous changes planned that
   might make one of the two functions much more verbose.

Luc Grosheintz (9):
   libstdc++: Rename _ExtentsStorage::_M_dynamic_extents.
   libstdc++: Rename extents::_M_dynamic_extents.
   libstdc++: Cleanup formatting in mdspan.
   libstdc++: Implement layout_left from mdspan.
   libstdc++: Add tests for layout_left.
   libstdc++: Implement layout_right from mdspan.
   libstdc++: Add tests for layout_right.
   libstdc++: Implement layout_stride from mdspan.
   libstdc++: Add tests for layout_stride.

  libstdc++-v3/include/std/mdspan   | 692 +-
  .../mdspan/layouts/class_mandate_neg.cc   |  42 ++
  .../23_containers/mdspan/layouts/ctors.cc | 401 ++
  .../23_containers/mdspan/layouts/mapping.cc   | 569 ++
  .../23_containers/mdspan/layouts/stride.cc| 494 +
  5 files changed, 2185 insertions(+), 13 deletions(-)
  create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/layouts/class_mandate_neg.cc
  create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
  create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
  create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc





Re: [PATCH 3/3] genemit: Use a byte encoding to generate insns

2025-05-21 Thread Jeff Law




On 5/21/25 5:06 AM, Richard Sandiford wrote:

Jeff Law  writes:

Given you know the RTL gen* related thingies better than anyone, I'd say
go forward and if there's any fallout, we can certainly cope with it.


Thanks.  I've now pushed the series and the earlier genemit tweaks,
with the discussed change to mark the operandN arguments as const.
Thanks.  I'll keep an eye on the riscv64 bootstrap, it'll be interesting 
to see how the changes impact the timing.  It won't kick off until COB 
my time, so data COB tomorrow my time.


jeff


Re: [PATCH] RISC-V: Add autovec mode param.

2025-05-21 Thread Kito Cheng
Could you make a simple testcase that could vectorize two loops in
different modes (e.g one SI and one SF) and with this param will only
auto vec on loop?

On Wed, May 21, 2025 at 9:47 PM Robin Dapp  wrote:
>
> Hi,
>
> This patch adds a --param=autovec-mode=.  When the param is
> specified we make autovectorize_vector_modes return exactly this mode if
> it is available.  This helps when testing different vectorizer settings.
>
> Regtested on rv64gcv_zvl512b.
>
> Regards
>  Robin
>
> gcc/ChangeLog:
>
> * config/riscv/riscv-v.cc (autovectorize_vector_modes): Return
> user-specified mode if available.
> * config/riscv/riscv.opt: New param.
> ---
>  gcc/config/riscv/riscv-v.cc | 20 
>  gcc/config/riscv/riscv.opt  |  4 
>  2 files changed, 24 insertions(+)
>
> diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
> index 1b5ef51886e..a7f2f0a4abe 100644
> --- a/gcc/config/riscv/riscv-v.cc
> +++ b/gcc/config/riscv/riscv-v.cc
> @@ -2821,6 +2821,26 @@ autovectorize_vector_modes (vector_modes *modes, bool)
> i++;
> size = base_size / (1U << i);
>   }
> +
> +  /* If the user specified the exact mode to use look if it is available and
> + remove all other ones before returning.  */
> +  if (riscv_autovec_mode)
> +{
> +  auto_vector_modes ms;
> +  ms.safe_splice (*modes);
> +  modes->truncate (0);
> +
> +  for (machine_mode mode : ms)
> +   {
> + if (!strcmp (GET_MODE_NAME (mode), riscv_autovec_mode))
> +   {
> + modes->safe_push (mode);
> + return 0;
> +   }
> +   }
> +  return 0;
> +}
> +
>/* Enable LOOP_VINFO comparison in COST model.  */
>return VECT_COMPARE_COSTS;
>  }
> diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
> index 527e09549a8..5b6dbc6bb4e 100644
> --- a/gcc/config/riscv/riscv.opt
> +++ b/gcc/config/riscv/riscv.opt
> @@ -286,6 +286,10 @@ Max number of bytes to compare as part of inlined 
> strcmp/strncmp routines (defau
>  Target RejectNegative Joined UInteger Var(gpr2vr_cost) 
> Init(GPR2VR_COST_UNPROVIDED)
>  Set the cost value of the rvv instruction when operate from GPR to VR.
>
> +-param=autovec-mode=
> +Target Undocumented RejectNegative Joined Var(riscv_autovec_mode) Save
> +Set the only autovec mode to try.
> +
>  Enum
>  Name(rvv_max_lmul) Type(enum rvv_max_lmul_enum)
>  The RVV possible LMUL (-mrvv-max-lmul=):
> --
> 2.49.0
>


Re: [PATCH] RISC-V: Support CPUs in -march.

2025-05-21 Thread Robin Dapp

I could imagine that is a simpler way to set the march since the march
string becomes terribly long - we have an arch string more than 300
char...so I support this, although I think this should be discuss with
LLVM community, but I think it's fine to accept as a GCC extension.

So LGTM, go ahead to the trunk, and I will raise this topic in the
next LLVM sync up meeting.


That would be great, thanks.

Another related issue.  i386 and other targets, but not aarch64,
make -march imply -mtune.  Was it a deliberate decision to _not_ do this?
Could we even add it still? ;)  That might help simplify things a bit
further even.

--
Regards
Robin



Re: [PATCH v2 1/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Joseph Myers
On Wed, 21 May 2025, Christopher Bazley wrote:

> Would you agree this is adequate? If anyone wants different source code
> locations to be highlighted then a future commit could change that.

In this case the locations seem reasonable.

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



Re: [PATCH] Match: Handle commonly used unsigned modulo counters

2025-05-21 Thread MCC CS
Dear Richard,

Thank you so much for your reply. I submitted the patch for the third case to
LLVM before I've received your reply, and they said the same thing,
that it would probably be used outside of loops as well and it would inflict
a branch misprediction, so it should be implemented at the level
of loop code generation only (because branch predictor could handle it
inside loops).

I didn't know that the second pattern would cause disassociation
from division. Unexpectedly LLVM has that pattern in their match.pd
equivalent but what you've said makes more sense.

For the first pattern, I verified that trunk GCC, for:

void d(unsigned x)
{
 if (x >= 5) __builtin_unreachable();
 x %= 5;
 g(x);
}

optimizes away the "%=", as you've said. However,
for the code:

void a(void)
{
 unsigned m = 0;
 for(int i = 0; i < 300; i++)
 {
 m++;
 m %= 600;
 g(m);
 }
}

it gets optimized only with the patch, which is surprising.

Thanks
MCCCS


Re: [PATCH] i386, v2: Extend *cmp_minus_1 optimizations also to plus with CONST_INT [PR120360]

2025-05-21 Thread Uros Bizjak
On Wed, May 21, 2025 at 1:20 PM Jakub Jelinek  wrote:
>
> On Wed, May 21, 2025 at 11:48:34AM +0200, Uros Bizjak wrote:
> > Please introduce "x86_64_neg_const_int_operand" predicate that will
> > allow only const_int operands, and will reject negative endbr (and
> > wide DImode) const_ints. You don't need a constraint if the predicate
> > allows only const_ints (the const_int won't be reloaded).
> >
> > > + (const_int 0)))]
> > > +  "CONST_INT_P (operands[1])
> > > +   && ix86_match_ccmode (insn, CCGOCmode)
> > > +   && (mode != DImode || !mode_signbit_p (SImode, operands[1]))
> > > +   && ((flag_cf_protection & CF_BRANCH) == 0
> > > +   || ((-INTVAL (operands[1]) & 0xUL)
> > > +  != (TARGET_64BIT ? 0xfa1e0ff3UL : 0xfb1e0ff3UL)))"
> >
> > New predicate will also avoid the above horrible insn condition.
>
> So like this (if it passes bootstrap/regtest)?
> Note, I'm using "n" rather than "" constraints, because with "e" we could
> get into trouble when the non-negated value would match endbr{64,32} - the
> predicate only checks (I think that is desirable) that the negation isn't
> endbr{64,32}.

IIRC, constraint is not needed when only CONST_INT is allowed. See
quite some examples in i386.md.

>
> 2025-05-21  Jakub Jelinek  
>
> PR target/120360
> * config/i386/predicates.md (x86_64_neg_const_int_operand): New
> predicate.
> * config/i386/i386.md (*cmp_plus_1): New pattern.
>
> * gcc.target/i386/pr120360.c: New test.

OK.

Thanks,
Uros.

>
> --- gcc/config/i386/predicates.md.jj2025-05-20 08:14:05.053424802 +0200
> +++ gcc/config/i386/predicates.md   2025-05-21 13:10:09.94528 +0200
> @@ -393,6 +393,23 @@ (define_predicate "x86_64_zext_immediate
>return false;
>  })
>
> +;; Return true if VALUE is a constant integer whose negation satisfies
> +;; x86_64_immediate_operand.
> +(define_predicate "x86_64_neg_const_int_operand"
> +  (match_code "const_int")
> +{
> +  HOST_WIDE_INT val = -UINTVAL (op);
> +  if (mode == DImode && trunc_int_for_mode (val, SImode) != val)
> +return false;
> +  if (flag_cf_protection & CF_BRANCH)
> +{
> +  unsigned HOST_WIDE_INT endbr = TARGET_64BIT ? 0xfa1e0ff3 : 0xfb1e0ff3;
> +  if ((val & HOST_WIDE_INT_C (0x)) == endbr)
> +   return false;
> +}
> +  return true;
> +})
> +
>  ;; Return true if VALUE is a constant integer whose low and high words 
> satisfy
>  ;; x86_64_immediate_operand.
>  (define_predicate "x86_64_hilo_int_operand"
> --- gcc/config/i386/i386.md.jj  2025-05-20 08:14:05.036425035 +0200
> +++ gcc/config/i386/i386.md 2025-05-21 13:04:12.441142398 +0200
> @@ -1599,6 +1599,20 @@ (define_insn "*cmp_minus_1"
>[(set_attr "type" "icmp")
> (set_attr "mode" "")])
>
> +(define_insn "*cmp_plus_1"
> +  [(set (reg FLAGS_REG)
> +   (compare
> + (plus:SWI (match_operand:SWI 0 "nonimmediate_operand" "m")
> +   (match_operand:SWI 1 "x86_64_neg_const_int_operand" "n"))
> + (const_int 0)))]
> +  "ix86_match_ccmode (insn, CCGOCmode)"
> +{
> +  operands[1] = gen_int_mode (-INTVAL (operands[1]), mode);
> +  return "cmp{}\t{%1, %0|%0, %1}";
> +}
> +  [(set_attr "type" "icmp")
> +   (set_attr "mode" "")])
> +
>  (define_insn "*cmpqi_ext_1"
>[(set (reg FLAGS_REG)
> (compare
> --- gcc/testsuite/gcc.target/i386/pr120360.c.jj 2025-05-20 20:40:32.194962716 
> +0200
> +++ gcc/testsuite/gcc.target/i386/pr120360.c2025-05-20 20:43:03.910930990 
> +0200
> @@ -0,0 +1,36 @@
> +/* PR target/120360 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fno-stack-protector -masm=att" } */
> +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
> +/* { dg-final { scan-assembler-times "\tjn*s\t" 3 } } */
> +/* { dg-final { scan-assembler-times "\tcmp\[lq]\t%" 1 } } */
> +/* { dg-final { scan-assembler-times "\tcmp\[lq]\t\\\$-1234," 1 } } */
> +/* { dg-final { scan-assembler-times "\tcmp\[lq]\t\\\$2345," 1 } } */
> +/* { dg-final { scan-assembler-not "\tadd\[lq]\t" { target { ! *-*-darwin* } 
> } } } */
> +/* { dg-final { scan-assembler-not "\tsub\[lq]\t" { target { ! *-*-darwin* } 
> } } } */
> +
> +void qux (unsigned long);
> +
> +void
> +foo (unsigned long x, unsigned long y)
> +{
> +  unsigned long z = x - y;
> +  if ((long) z < 0)
> +qux (x);
> +}
> +
> +void
> +bar (unsigned long x)
> +{
> +  unsigned long z = x + 1234;
> +  if ((long) z < 0)
> +qux (x);
> +}
> +
> +void
> +baz (unsigned long x)
> +{
> +  unsigned long z = x - 2345;
> +  if ((long) z < 0)
> +qux (x);
> +}
>
>
> Jakub
>


Re: [PATCH v2 1/1] Add warnings of potentially-uninitialized padding bits

2025-05-21 Thread Christopher Bazley

Hi Jakub,

Thanks for your review.

On 21/05/2025 13:51, Jakub Jelinek wrote:

On Wed, May 21, 2025 at 01:42:01PM +0100, Christopher Bazley wrote:

On 21/05/2025 12:26, Christopher Bazley wrote:

Hi Joseph,

Thanks for reviewing my patch.

On 20/05/2025 18:02, Joseph Myers wrote:

On Tue, 20 May 2025, Christopher Bazley wrote:


+    if (!cleared)
+  {
+    if (complete_p.padded_non_union
+    && warn_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_ALL)
+  {
+    warning (OPT_Wzero_init_padding_bits_,
+ "Padding bits might not be initialized to zero; "
+ "consider using %<-fzero-init-padding-bits=all%>");
+  }
+    else if (complete_p.padded_union
+ && warn_zero_init_padding_bits
+    >= ZERO_INIT_PADDING_BITS_UNIONS)
+  {
+    warning (OPT_Wzero_init_padding_bits_,
+ "Padding bits might not be initialized to zero; "
+ "consider using %<-fzero-init-padding-bits=unions%> "
+ "or %<-fzero-init-padding-bits=all%>");

Diagnostics should start with a lowercase letter.

I'll change it to "padding might not be initialized to zero..." OK?

("padding" seems to be more common than "padding bits" in existing
messages.)

Is there anything I need to do for initialization?

Sorry, I meant "internationalisation" (i.e. to support translation), not
"initialization"!

For translations I think it is fine as is.
Please avoid {}s around single statements (e.g. the warning call above).


Originally, it was more than one statement to produce information on how 
to initialise padding bits. That information was language (and dialect) 
specific, which wasn't acceptable in the Gimplifier. I'll remove the 
redundant braces.



And, I think the warnings should include text like
"if code relies on it being zero, consider"
because telling people to use those options mindlessly is undesirable.


Nobody is going to see these warnings unless they explicitly enable 
them, in which case I hope they would have read the documentation first.


The current text is:

+               warning (OPT_Wzero_init_padding_bits_,
+                        "padding might not be initialized to zero; "
+                        "consider using 
%<-fzero-init-padding-bits=unions%> "

+                        "or %<-fzero-init-padding-bits=all%>");

I can add "if code relies on it being zero," although I don't think 
"consider" is a very strong prescription and I highly doubt whether the 
people reading these warnings will know whether the code they are 
compiling relies on padding being zeroed or not. My presumption was that 
programmers who know their own code intimately won't enable the warnings 
in the first place.



Having uninitialized padding bits is most of the time just fine, only if
code accesses it (whether writing it to disk, or say computing checksum
of all the bytes in it etc.), it is problematic.


I'm well aware of that. You can see what I wrote in the documentation:

"It does not follow that all source code which causes warnings about
uninitialized padding bits has undefined behaviour: usually, the values
of padding bits have no effect on execution of a program."

--
Christopher Bazley
Staff Software Engineer, GNU Tools Team.
Arm Ltd, 110 Fulbourn Road, Cambridge, CB1 9NJ, UK.
http://www.arm.com/



[PATCH] RISC-V: Support CPUs in -march.

2025-05-21 Thread Robin Dapp

Hi,

This patch allows an -march string like

 -march=sifive-p670

in order to allow overriding a previous -march in a simple way.

Suppose we have a Makefile that specifies -march=rv64gc by default.
A user-specified -mcpu=sifive-p670 would be after the -march in the
options string and thus only set -mtune=sifive-p670 (as -mcpu does not
override a previously specified -march or -mtune).

So if we wanted to override we would need to specify the full, lengthy
-march=rv64gcv_... string instead of a simple -mcpu=...

Therefore this patch always first tries to interpret -march= as CPU
string.  If it is a supported CPU we use its march properties and let it
override previously specified options.  Otherwise the behavior is as
before.  This enables the "last-specified option wins" behavior GCC
normally employs.

Note that -march does not imply -mtune like on x86 or other targets.
So an -march=CPU won't override a previously specified -mtune=other-CPU.

I haven't spent a lot of time on this (basically stopped once it looked
like it's working) and was hoping somebody who touched these riscv parts
will notice glaring holes :)

Regtested on rv64gcv_zvl512b.

Regards
Robin

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc 
(riscv_subset_list::parse_base_ext):
Adjust error message.
(riscv_handle_option): Parse as CPU string first.
(riscv_expand_arch): Ditto.
* doc/invoke.texi: Document.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/arch-56.c: New test.
---
gcc/common/config/riscv/riscv-common.cc  | 19 ---
gcc/doc/invoke.texi  |  2 +-
gcc/testsuite/gcc.target/riscv/arch-56.c | 13 +
3 files changed, 26 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/arch-56.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index c843393998c..a6d8763f032 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -980,8 +980,9 @@ riscv_subset_list::parse_base_ext (const char *p)
}
  else
{
-  error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, rv64 "
-   "or Profiles", m_arch);
+  error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, rv64,"
+   " a supported RVA profile or refer to a supported CPU",
+   m_arch);
  return NULL;
}

@@ -1708,7 +1709,8 @@ riscv_handle_option (struct gcc_options *opts,
  switch (decoded->opt_index)
{
case OPT_march_:
-  riscv_parse_arch_string (decoded->arg, opts, loc);
+  if (riscv_find_cpu (decoded->arg) == NULL)
+   riscv_parse_arch_string (decoded->arg, opts, loc);
  return true;

case OPT_mcpu_:
@@ -1725,15 +1727,18 @@ riscv_handle_option (struct gcc_options *opts,
/* Expand arch string with implied extensions.  */

const char *
-riscv_expand_arch (int argc ATTRIBUTE_UNUSED,
+riscv_expand_arch (int argc,
   const char **argv)
{
  gcc_assert (argc == 1);
  location_t loc = UNKNOWN_LOCATION;
-  riscv_parse_arch_string (argv[0], NULL, loc);
+  /* Try to interpret the arch as CPU first.  */
+  const char *arch_str = riscv_expand_arch_from_cpu (argc, argv);
+  if (!strlen (arch_str))
+riscv_parse_arch_string (argv[0], NULL, loc);
  const std::string arch = riscv_arch_str (false);
-  if (arch.length())
-return xasprintf ("-march=%s", arch.c_str());
+  if (arch.length ())
+return xasprintf ("-march=%s", arch.c_str ());
  else
return "";
}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 52cfdb99871..2368509034f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1268,7 +1268,7 @@ See RS/6000 and PowerPC Options.
-mfence-tso  -mno-fence-tso
-mdiv  -mno-div
-misa-spec=@var{ISA-spec-string}
--march=@var{ISA-string|Profiles|Profiles_ISA-string}
+-march=@var{ISA-string|Profiles|Profiles_ISA-string|CPU/processor string}
-mtune=@var{processor-string}
-mpreferred-stack-boundary=@var{num}
-msmall-data-limit=@var{N-bytes}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-56.c 
b/gcc/testsuite/gcc.target/riscv/arch-56.c
new file mode 100644
index 000..c0b43b74a49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-56.c
@@ -0,0 +1,13 @@
+/* Check whether the second -march overrides the first.  */
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gc -march=sifive-p670" } */
+
+void
+foo (char *a, char *b, int n)
+{
+  for (int i = 0; i < n; i++)
+a[i] = b[i] + 1;
+}
+
+/* { dg-final { scan-assembler "vset" } } */
+/* { dg-final { scan-assembler "zvl128b" } } */
--
2.49.0




Re: [PATCH] RISC-V: Add autovec mode param.

2025-05-21 Thread Robin Dapp

Could you make a simple testcase that could vectorize two loops in
different modes (e.g one SI and one SF) and with this param will only
auto vec on loop?


I added a test now in the attached v2 that checks that we vectorize with the 
requested mode.  Right now the patch only takes away "additional" vector modes 
(like V4QI) and not the first vector mode that we always have (e.g. RVVM1SF).


Maybe I should change the doc string still?  But technically, it's undocumented 
;)


Regards
Robin

This patch adds a --param=autovec-mode=.  When the param is
specified we make autovectorize_vector_modes return exactly this mode if
it is available.  This helps when testing different vectorizer settings.

gcc/ChangeLog:

* config/riscv/riscv-v.cc (autovectorize_vector_modes): Return
user-specified mode if available.
* config/riscv/riscv.opt: New param.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/param-autovec-mode.c: New test.
---
gcc/config/riscv/riscv-v.cc   | 22 +++
gcc/config/riscv/riscv.opt|  4 
.../riscv/rvv/autovec/param-autovec-mode.c| 16 ++
3 files changed, 42 insertions(+)
create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/param-autovec-mode.c

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 1b5ef51886e..cb643389bb9 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -2821,6 +2821,28 @@ autovectorize_vector_modes (vector_modes *modes, bool)
i++;
size = base_size / (1U << i);
 }
+
+  /* If the user specified the exact mode to use look if it is available and
+ remove all other ones before returning.  */
+  if (riscv_autovec_mode)
+{
+  auto_vector_modes ms;
+  ms.safe_splice (*modes);
+  modes->truncate (0);
+
+  for (machine_mode mode : ms)
+   {
+ if (!strcmp (GET_MODE_NAME (mode), riscv_autovec_mode))
+   {
+ modes->safe_push (mode);
+ return 0;
+   }
+   }
+
+  /* Nothing found, fall back to regular handling.  */
+  modes->safe_splice (ms);
+}
+
  /* Enable LOOP_VINFO comparison in COST model.  */
  return VECT_COMPARE_COSTS;
}
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 527e09549a8..5b6dbc6bb4e 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -286,6 +286,10 @@ Max number of bytes to compare as part of inlined 
strcmp/strncmp routines (defau
Target RejectNegative Joined UInteger Var(gpr2vr_cost) 
Init(GPR2VR_COST_UNPROVIDED)
Set the cost value of the rvv instruction when operate from GPR to VR.

+-param=autovec-mode=
+Target Undocumented RejectNegative Joined Var(riscv_autovec_mode) Save
+Set the only autovec mode to try.
+
Enum
Name(rvv_max_lmul) Type(enum rvv_max_lmul_enum)
The RVV possible LMUL (-mrvv-max-lmul=):
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/param-autovec-mode.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/param-autovec-mode.c
new file mode 100644
index 000..b2ec8f9dc77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/param-autovec-mode.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d --param=autovec-mode=V4QI 
-fdump-tree-vect-details" } */
+
+/* By default we will use RVVM1SI mode for vectorization because N is not
+   known.  Check that we use V4QI and create an epilogue when the autovec-mode
+   param is specified.  */
+
+void
+foo (int *a, int *b, int n)
+{
+  for (int i = 0; i < n; i++)
+a[i] = b[i] + 1;
+}
+
+/* { dg-final { scan-tree-dump "Choosing vector mode V4QI" "vect" } } */
+/* { dg-final { scan-tree-dump "Choosing epilogue vector mode RVVM1SI" "vect" 
} } */
--
2.49.0




[PATCH][RISC-V][PR target/70557] Improve storing 0 to memory on rv32

2025-05-21 Thread Shreya Munnangi
Patch is originally from Siarhei Volkau .

RISC-V has a zero register (x0) which we can use to store zero into memory
without loading the constant into a distinct register. Adjust the
constraints
of the 32-bit movdi_32bit pattern to recognize that we can store 0.0 into
memory using x0 as the source register.

This patch only affects RISC-V. It has been regression tested on
riscv64-elf.
Jeff has also tested this in his tester (riscv64-elf and riscv32-elf) with
no
regressions.

PR target/70557
gcc/
* config/riscv/riscv.md (movdi_32bit): Add "J" constraint to allow
storing 0
directly to memory.


Re: Fix PR 118541, do not generate unordered fp cmoves for IEEE compares

2025-05-21 Thread Segher Boessenkool
Hi!

On Wed, May 21, 2025 at 06:27:38AM +0200, Richard Biener wrote:
> On Wed, May 21, 2025 at 12:30 AM Segher Boessenkool
>  wrote:
> >
> > On Mon, May 12, 2025 at 06:35:15PM -0400, Michael Meissner wrote:
> > > On Mon, May 12, 2025 at 01:24:04PM +0530, Surya Kumari Jangala wrote:
> > > > Hi Mike,
> > > > Irrespective of whether -Ofast is used or not, should’nt we generate 
> > > > XSCMPUDP instruction for ‘isgreater()’ operation? This is because 
> > > > XSCMPGTDP insn will generate a trap if either operand is an SNaN or a 
> > > > QNaN. Whereas, XSCMPUDP insn will generate a trap only if either 
> > > > operand is an SNaN. The issue with the failing glibc tests is that an 
> > > > “Invalid operation” exception is being thrown due to qNaNs.
> > >
> > > But -Ofast says not to worry about Nans (signalling or otherwise).  But if
> > > Segher desires, I remove the test for Ofast.
> >
> > That is not what -Ofast means at all.  It means "-O3, but also
> > -ffast-math, and some other not recommendable things".  Its name is a
> > total misnomer: it often is not faster than even -O2 (the baseline
> > here), but it also is very non-standard-compliant and similar things.
> 
> -ffinite-math-only is a promise to the compiler that no NaNs (quiet or
> signalling)
> or Infs exist as inputs to or produced by any expression in the program.

Yes.  So for most programs / by most programmers this is very much not
recommendable, since infinities and NaNs will almost certainly happen
for some real executions of the program, for some inputs.

> Mostly
> helpful with arithmetic simplifications done as-if-it-were-math-and-not-FP.
> Without -fsignalling-nans sNaNs are assumed to not exist (that's the default
> btw).

Yup.

> > "-Ofast-and-loose" might be a name that does make sense.  As the
> > dictionary says:
> >"If you say that someone is playing fast and loose, you are
> > expressing disapproval of them for behaving in a deceitful, immoral,
> > or irresponsible way."
> >
> > And yeah, xscmpgtdp is plain wrong no matter what flags are used, unless
> > we adopt a -fuck-up flag :-(
> 
> The interesting question of course is why the instruction exists in
> the first place?

xscmpgtdp is a variant of xscmpodp, which is like the traditional fcmpo
but works on all 64 VSRs, not just the higher numbered half of the
registers (the traditional FPRs).  (And it returns integer -1 or 0,
instead of a CR field with the four possible FP result bits).

We never do fcmpo for fp compares, we always do fcmpu.  fcmpo raises the
invalid comparison exception if it gets a NaN as input, which is hardly
ever useful.

The insn was generated here because of a simple bug in the machine
description.


Segher


[PATCH] doc: Document the 'q' constraint for LoongArch

2025-05-21 Thread Xi Ruoyao
The kernel developers have requested such a constraint to use csrxchg
in inline assembly.

gcc/ChangeLog:

* doc/md.texi: Document the 'q' constraint for LoongArch.
---

Ok for trunk?

 gcc/doc/md.texi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 1a1c1b73089..2a1f9919c5b 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -2918,6 +2918,9 @@ A signed 16-bit constant.
 A memory operand whose address is formed by a base register and offset
 that is suitable for use in instructions with the same addressing mode
 as @code{st.w} and @code{ld.w}.
+@item q
+A general-purpose register except for $r0 and $r1 (for the csrxchg
+instruction)
 @item I
 A signed 12-bit constant (for arithmetic instructions).
 @item K
-- 
2.49.0



Avoid double indirection in function_ref

2025-05-21 Thread Tomasz Kamiński
This commit series implements double indirection avoidance for the
function_ref and it is based on my patch for function_ref implementation.

This patch is send as RFC instead of PATCH ready for review, as I have
noticed that performing this implementation is user-observable and not
allowed in the standard even with changes suggested in LWG4264 [1].

To avoidance of double indirection requires that constructed function_ref,
refers directly to the target function of the source, instead of source,
and this is visible after the assigment:

```
void foo() noexcept;
void bar() noexcept;

std::function_ref sr(&foo);
std::function_ref dr(sr);
dr(); // calls `foo` regardless of implementation

sr = &bar;
sr(); // calls `bar`
dr(); // still calls `foo` if we avoid indirection,
  // calls `bar` if we do not
```

Similary for move_only_function/copyable_function source:

```
std::move_only_function sm;
std::function_ref dm(sm);

dm(); // UB because `sm` is empty

sm = &foo;

dm(); // remains UB if we avoid indirection,
  // calls `bar` if we do not.

```

While we may want to allow skipping indirection for function_ref,
as this produces same behavior as in case for copy constructor (matching
signatures):
```
void foo() noexcept;
void bar() noexcept;

std::function_ref sr(&foo);
std::function_ref dr(sr); // copy-cosntructor
dr(); // calls `foo` regardless of implementation

sr = &bar;
sr(); // calls `bar`
dr(); // still calls `foo` if we avoid indirection
```,
I do not think this is acceptable for `move_only_function. So most
likely we will and only first commit. 
 
Note that for the same reason, implementations are not free to avoid
dangling when constructing function_ref from reference_wrapper:
---
auto srw = std::ref(&foo);
std::function_ref drw(srw);
drw(); // calls `foo`

srw = std::ref(&bar);
drw(); // calls `foo` if we unwrap referenc wrapper,
   // calls `bar` otherwise.
--

Note that this is limited to function_ref due reference nature of this
wrapper.

[1] https://cplusplus.github.io/LWG/issue4264



[RFC 2/2] libstdc++: Avoid double indirection when cosntructing function_ref owning wrappers [PR119126]

2025-05-21 Thread Tomasz Kamiński
This patch uses the additional provisions from LWG 4264, to avoid double
indirection when function_ref is constructed from move_only_function or
copyable_function with compatible signature. The details of compatible
signatures follows the move_only_function as described in
r16-617-g708d40ff109c6e49d02b684a368571722a160af8.

This requires ability to retrive an invoker accepting an _Ptrs, from the owning
wrappers that use const _Storage&. This is achieved by additional 
_Op::_PtrInvoker
operation that stores the invoker into __target._M_ptrs._M_func. In consequence
the _M_init for _Mo_base and _Cpy_base now accepts additional template parameter
designating ptr invoker.

The conversion is performed by _Ref_base::_M_adapt function, to uses
_Op::_Address to retrive pointer to stored object, and then returns pointer to
ptr invoker retrived using _Op::_PtrInvoke.

As constructing function_ref from empty move_only_function/copyable_function
is well-defined, but produces functor for wich any invocation is UB, we need
to thread this case specially, and _M_manage is not usable for such object.
When source is empty owning wrapper, we instad set the _M_invoke to nullptr
direclty, which gives the same effects.

As retriving the invoker requires reintepret_cast from void(*) to appropariate
function type, the undesirable consequence of this patch is that constructing
function_ref from usable in constant expression reference to non-empty
move_only_function or copyable_function is not constant expression. The 
constructor
is marked constexpr, but we do not specify when invocation is compile time,
at move_only_function/copyable_function cannot be cosntructed at compile time.

PR libstdc++/119126

libstdc++-v3/ChangeLog:

* include/bits/funcwrap.h (_Op::_PtrInvoke, _Manager::_S_create)
(_Manager::_S_with_invoker, _Ref_base::_M_adapt): Define.
(_Manager::_S_select): Make private.
(_Manager::_S_func, _Manager::_S_trivial, _Manger::_S_local)
(_Manager::_S_ptr): Add unreachable case _Op::_PtrInvoke.
(_Mo_base::_M_init, _Cpy_base::_M_init): Accept ptr invoke as
template paramter.
(_Mo_base::_Ref_base) [__glibcxx_function_ref]: Declare as friend.
* include/bits/funcref_impl.h:
* include/bits/mofunc_impl.h (move_only_function::_M_init): Define.
(move_only_function::move_only_function): Adjust to use _M_init.
* include/bits/cpyfunc_impl.h (coyable_function::_M_init): Define.
(coyable_function::coyable_function): Adjust to use _M_init.
* testsuite/20_util/function_ref/conv.cc: Adjust test to reflect
lack of double indirection. Test to check if right object is
referenced.
---
 libstdc++-v3/include/bits/cpyfunc_impl.h  | 20 +++---
 libstdc++-v3/include/bits/funcref_impl.h  | 16 +
 libstdc++-v3/include/bits/funcwrap.h  | 59 --
 libstdc++-v3/include/bits/mofunc_impl.h   | 20 +++---
 .../testsuite/20_util/function_ref/conv.cc| 62 +--
 5 files changed, 151 insertions(+), 26 deletions(-)

diff --git a/libstdc++-v3/include/bits/cpyfunc_impl.h 
b/libstdc++-v3/include/bits/cpyfunc_impl.h
index 7ba74ed8a8d..5a802310cdd 100644
--- a/libstdc++-v3/include/bits/cpyfunc_impl.h
+++ b/libstdc++-v3/include/bits/cpyfunc_impl.h
@@ -117,11 +117,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
 
  if constexpr (!__is_polymorphic_function_v<_Vt>
- || !__polyfunc::__is_invoker_convertible<_Vt, 
copyable_function>())
-   {
- _M_init<_Vt>(std::forward<_Fn>(__f));
- _M_invoke = _Invoker::template _S_storage<_Vt 
_GLIBCXX_MOF_INV_QUALS>();
-   }
+  || !__polyfunc::__is_invoker_convertible<_Vt, 
copyable_function>())
+   _M_init<_Vt>(std::forward<_Fn>(__f));
  else if constexpr (is_lvalue_reference_v<_Fn>)
{
  _M_copy(__polyfunc::__base_of(__f));
@@ -141,7 +138,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit
copyable_function(in_place_type_t<_Tp>, _Args&&... __args)
noexcept(_S_nothrow_init<_Tp, _Args...>())
-   : _M_invoke(_Invoker::template _S_storage<_Tp _GLIBCXX_MOF_INV_QUALS>())
{
  static_assert(is_same_v, _Tp>);
  static_assert(is_copy_constructible_v<_Tp>);
@@ -156,7 +152,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
copyable_function(in_place_type_t<_Tp>, initializer_list<_Up> __il,
   _Args&&... __args)
noexcept(_S_nothrow_init<_Tp, initializer_list<_Up>&, _Args...>())
-   : _M_invoke(_Invoker::template _S_storage<_Tp _GLIBCXX_MOF_INV_QUALS>())
{
  static_assert(is_same_v, _Tp>);
  static_assert(is_copy_constructible_v<_Tp>);
@@ -245,6 +240,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { return __x._M_invoke == nullptr; }
 
 private:
+  template
+   void
+   _M_init(_Args&&... __args)
+   noexcept(_S_nothrow_

Re: [RFC PATCH 0/3] _BitInt(N) support for LoongArch

2025-05-21 Thread Jakub Jelinek
On Wed, May 21, 2025 at 10:13:27AM +0800, Yang Yujie wrote:
> On Tue, May 20, 2025 at 03:44:09PM GMT, Jakub Jelinek wrote:
> > I'd suggest working on it incrementally rather than with a full patch set.
> > In one or multiple patches handle the promote_mode stuff, the atomic
> > extension and expr.cc changes with the feedback incorporated.
> 
> Ok.
> 
> > For gimple-lower-bitint.cc I'd really like to see what testing you've done
> > to decide on a case by case basis.
> > 
> > > > Are you sure all those changes were really necessary (rather than doing 
> > > > them
> > > > just in case)?  I believe most of gimple-lower-bitint.cc already should 
> > > > be
> > > > sign or zero extending the partial limbs when storing stuff, there can 
> > > > be
> > > > some corner cases (I think one of the shift directions at least).
> > > 
> > > The modifications to gimple-lower-bitint.cc are based on testing, 
> > 
> > The tests weren't included :(.
> 
> "The tests" refer to the existing regression tests in testsuite/gcc.dg and
> testsuite/gcc.dg/torture, specifically bitint-*.c.

The existing testsuite never tests whether the padding bits are sign or zero
extended or contain unknown values.
In the s390x patch, info->extended is set to true, yet all bitint tests but
bitint-64.c at -O3 pass.

So, I'm really interested to know in which cases you found the existing code
not doing the extensions, ideally simple {,un}signed _BitInt(N) with values
X and Y doing arithmetic or logical operation OP.
And put that into the new test(s), so that we can ensure that the extensions
are performed correctly.

Jakub



  1   2   >