[ARC PATCH] Split asl dst, 1, src into bset dst, 0, src to implement 1<

2023-10-15 Thread Roger Sayle
 

This patch adds a pre-reload splitter to arc.md, to use the bset (set

specific bit instruction) to implement 1<

 

gcc/ChangeLog

* config/arc/arc.md (*ashlsi3_1): New pre-reload splitter to

use bset dst,0,src to implement 1<

RE: [ARC PATCH] Split asl dst, 1, src into bset dst, 0, src to implement 1<

2023-10-15 Thread Roger Sayle
I've done it again. ENOPATCH.

 

From: Roger Sayle  
Sent: 15 October 2023 09:13
To: 'gcc-patches@gcc.gnu.org' 
Cc: 'Claudiu Zissulescu' 
Subject: [ARC PATCH] Split asl dst,1,src into bset dst,0,src to implement
1 >

 

gcc/ChangeLog

* config/arc/arc.md (*ashlsi3_1): New pre-reload splitter to

use bset dst,0,src to implement 1

RE: [PATCH] PR 91865: Avoid ZERO_EXTEND of ZERO_EXTEND in make_compound_operation.

2023-10-15 Thread Roger Sayle


Hi Jeff,
Thanks for the speedy review(s).

> From: Jeff Law 
> Sent: 15 October 2023 00:03
> To: Roger Sayle ; gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH] PR 91865: Avoid ZERO_EXTEND of ZERO_EXTEND in
> make_compound_operation.
> 
> On 10/14/23 16:14, Roger Sayle wrote:
> >
> > This patch is my proposed solution to PR rtl-optimization/91865.
> > Normally RTX simplification canonicalizes a ZERO_EXTEND of a
> > ZERO_EXTEND to a single ZERO_EXTEND, but as shown in this PR it is
> > possible for combine's make_compound_operation to unintentionally
> > generate a non-canonical ZERO_EXTEND of a ZERO_EXTEND, which is
> > unlikely to be matched by the backend.
> >
> > For the new test case:
> >
> > const int table[2] = {1, 2};
> > int foo (char i) { return table[i]; }
> >
> > compiling with -O2 -mlarge on msp430 we currently see:
> >
> > Trying 2 -> 7:
> >  2: r25:HI=zero_extend(R12:QI)
> >REG_DEAD R12:QI
> >  7: r28:PSI=sign_extend(r25:HI)#0
> >REG_DEAD r25:HI
> > Failed to match this instruction:
> > (set (reg:PSI 28 [ iD.1772 ])
> >  (zero_extend:PSI (zero_extend:HI (reg:QI 12 R12 [ iD.1772 ]
> >
> > which results in the following code:
> >
> > foo:AND #0xff, R12
> >  RLAM.A #4, R12 { RRAM.A #4, R12
> >  RLAM.A  #1, R12
> >  MOVX.W  table(R12), R12
> >  RETA
> >
> > With this patch, we now see:
> >
> > Trying 2 -> 7:
> >  2: r25:HI=zero_extend(R12:QI)
> >REG_DEAD R12:QI
> >  7: r28:PSI=sign_extend(r25:HI)#0
> >REG_DEAD r25:HI
> > Successfully matched this instruction:
> > (set (reg:PSI 28 [ iD.1772 ])
> >  (zero_extend:PSI (reg:QI 12 R12 [ iD.1772 ]))) allowing
> > combination of insns 2 and 7 original costs 4 + 8 = 12 replacement
> > cost 8
> >
> > foo:MOV.B   R12, R12
> >  RLAM.A  #1, R12
> >  MOVX.W  table(R12), R12
> >  RETA
> >
> >
> > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> > and make -k check, both with and without --target_board=unix{-m32}
> > with no new failures.  Ok for mainline?
> >
> > 2023-10-14  Roger Sayle  
> >
> > gcc/ChangeLog
> >  PR rtl-optimization/91865
> >  * combine.cc (make_compound_operation): Avoid creating a
> >  ZERO_EXTEND of a ZERO_EXTEND.
> >
> > gcc/testsuite/ChangeLog
> >  PR rtl-optimization/91865
> >  * gcc.target/msp430/pr91865.c: New test case.
> Neither an ACK or NAK at this point.
> 
> The bug report includes a patch from Segher which purports to fix this in 
> simplify-
> rtx.  Any thoughts on Segher's approach and whether or not it should be
> considered?
> 
> The BZ also indicates that removal of 2 patterns from msp430.md would solve 
> this
> too (though it may cause regressions elsewhere?).  Any thoughts on that 
> approach
> as well?
> 

Great questions.  I believe Segher's proposed patch (in comment #4) was an
msp430-specific proof-of-concept workaround rather than intended to be fix.
Eliminating a ZERO_EXTEND simply by changing the mode of a hard register
is not a solution that'll work on many platforms (and therefore not really 
suitable
for target-independent middle-end code in the RTL optimizers).

For example, zero_extend:TI (and:QI (reg:QI hard_r1) (const_int 0x0f)) can't
universally be reduced to (and:TI (reg:TI hard_r1) (const_int 0x0f)).  Notice 
that
Segher's code doesn't check TARGET_HARD_REGNO_MODE_OK or 
TARGET_MODES_TIEABLE_P or any of the other backend hooks necessary
to confirm such a transformation is safe/possible.

Secondly, the hard register aspect is a bit of a red herring.  This work-around
fixes the issue in the original BZ description, but not the slightly modified 
test
case in comment #2 (with a global variable).  This doesn't have a hard register,
but does have the dubious ZERO_EXTEND/SIGN_EXTEND of a ZERO_EXTEND.

The underlying issue, which is applicable to all targets, is that combine.cc's
make_compound_operation is expected to reverse the local transformations
made by expand_compound_operation.  Hence, if an RTL expression is
canonical going into expand_compound_operation, it is expected (hoped)
to be canonical (and equivalent) coming out of make_compound_operation.

Hence, rather than be a MSP430 specific issue, no target should expect (or
be expected to see) a ZERO_EXTEND of a ZERO_EXTEND, or a SIGN_EXTEND
of a ZERO_EXTEND in the RTL stream.  Much like a binary operator with two
CONST_INT operands, or a shift by zero, it's something the middle-end might
reasonably be expected to clean-up. [Yeah, I know... 😊]

However, if it isn't considered a problem that make_compound_operand and
simplify_rtx generate different forms of the same expression, requiring the
backend to match multiple patterns (some for the combine pass, and others
for other RTL passes), there is a simple fix for MSP430; Just add a pattern 
that matches (the slightly odd):

> > (set (reg:PSI 28 [ iD.1772 ])
> >  (zero_extend:PSI (zero_extend:HI (reg:QI 12 R12 [ iD

[patch] libgomp.texi: Use present not future tense (was: [Patch] libgomp.texi: Clarify OMP_TARGET_OFFLOAD=mandatory)

2023-10-15 Thread Tobias Burnus

On 14.10.23 22:08, Sandra Loosemore wrote:

Can we please rewrite this whole section in the present tense?


How about the following patch?

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

libgomp/ChangeLog:

	* libgomp.texi: Replace most future tense by present tense.

diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 526d1be2955..ee22b6c5cb4 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -794,9 +794,9 @@ are allowed to create new teams.  The function takes the language-specific
 equivalent of @code{true} and @code{false}, where @code{true} enables 
 dynamic adjustment of team sizes and @code{false} disables it.
 
-Enabling nested parallel regions will also set the maximum number of
+Enabling nested parallel regions also sets the maximum number of
 active nested regions to the maximum supported.  Disabling nested parallel
-regions will set the maximum number of active nested regions to one.
+regions sets the maximum number of active nested regions to one.
 
 Note that the @code{omp_set_nested} API routine was deprecated
 in the OpenMP specification 5.2 in favor of @code{omp_set_max_active_levels}.
@@ -905,8 +905,8 @@ For @code{omp_sched_auto} the @var{chunk_size} argument is ignored.
 @subsection @code{omp_get_schedule} -- Obtain the runtime scheduling method
 @table @asis
 @item @emph{Description}:
-Obtain the runtime scheduling method.  The @var{kind} argument will be
-set to the value @code{omp_sched_static}, @code{omp_sched_dynamic},
+Obtain the runtime scheduling method.  The @var{kind} argument is set to
+to @code{omp_sched_static}, @code{omp_sched_dynamic},
 @code{omp_sched_guided} or @code{omp_sched_auto}.  The second argument,
 @var{chunk_size}, is set to the chunk size.
 
@@ -934,7 +934,7 @@ set to the value @code{omp_sched_static}, @code{omp_sched_dynamic},
 @subsection @code{omp_get_teams_thread_limit} -- Maximum number of threads imposed by teams
 @table @asis
 @item @emph{Description}:
-Return the maximum number of threads that will be able to participate in
+Return the maximum number of threads that are able to participate in
 each team created by a teams construct.
 
 @item @emph{C/C++}:
@@ -1316,7 +1316,7 @@ that does not use the clause @code{num_teams}.
 @subsection @code{omp_set_teams_thread_limit} -- Set upper thread limit for teams construct
 @table @asis
 @item @emph{Description}:
-Specifies the upper bound for number of threads that will be available
+Specifies the upper bound for number of threads that are available
 for each team created by the teams construct which does not specify a
 @code{thread_limit} clause.  The argument of
 @code{omp_set_teams_thread_limit} shall be a positive integer.
@@ -2456,7 +2456,7 @@ may be used as trait value to specify that the default value should be used.
 Releases all resources used by a memory allocator, which must not represent
 a predefined memory allocator.  Accessing memory after its allocator has been
 destroyed has unspecified behavior.  Passing @code{omp_null_allocator} to the
-routine is permitted but will have no effect.
+routine is permitted but has no effect.
 
 
 @item @emph{C/C++}:
@@ -3029,7 +3029,7 @@ OMP_ALLOCATOR=omp_low_lat_mem_space:pinned=true,partition=nearest
 Sets the format string used when displaying OpenMP thread affinity information.
 Special values are output using @code{%} followed by an optional size
 specification and then either the single-character field type or its long
-name enclosed in curly braces; using @code{%%} will display a literal percent.
+name enclosed in curly braces; using @code{%%} displays a literal percent.
 The size specification consists of an optional @code{0.} or @code{.} followed
 by a positive integer, specifying the minimal width of the output.  With
 @code{0.} and numerical values, the output is padded with zeros on the left;
@@ -3110,7 +3110,7 @@ if unset, cancellation is disabled and the @code{cancel} construct is ignored.
 @item @emph{Scope:} global
 @item @emph{Description}:
 If set to @code{FALSE} or if unset, affinity displaying is disabled.
-If set to @code{TRUE}, the runtime will display affinity information about
+If set to @code{TRUE}, the runtime displays affinity information about
 OpenMP threads in a parallel region upon entering the region and every time
 any change occurs.
 
@@ -3135,7 +3135,7 @@ If set to @code{TRUE}, the OpenMP version number and the values
 associated with the OpenMP environment variables are printed to @code{stderr}.
 If set to @code{VERBOSE}, it additionally shows the value of the environment
 variables which are GNU extensions.  If undefined or set to @code{FALSE},
-this information will not be shown.
+this information is not shown.
 
 
 @item @emph{Reference

Re: [patch] libgomp.texi: Improve "OpenACC Environment Variables"

2023-10-15 Thread Tobias Burnus

Hi Sandra,

thanks for the comments.

On 15.10.23 00:46, Sandra Loosemore wrote:

+Semicolon separated list of dynamic libraries to be loaded as
profiling library.


s/Semicolon separated/Semicolon-separated/

There's also a semantic issue with "list of dynamic libraries"
(plural) and "profiling library" (singular).  Are they all separately
profiling libraries, or does the entire list constitute a single
logical profiling library and its dependencies?


No, each library works as separate "profiling library", everything else
does not make much sense.

Updated patch attached - I hope it is now clearer.

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

None of the ACC_* env vars was documented; in particular, the valid valids
for ACC_DEVICE_TYPE found to be lacking as those are not document in the
OpenACC spec.
GCC_ACC_NOTIFY was removed as I find any traces of it but the addition
to the documentation in commit r6-6185-gcdf6119dad04dd ("libgomp.texi:
Updates for OpenACC.").  It seems to be planned as GCC version of
the ACC_NOTIFY env var used by another compiler for offloading debugging.

libgomp/
	* libgomp.tex (ACC_DEVICE_TYPE, ACC_DEVICE_NUM, ACC_PROFLIB):
	Actually document what the function does.
	(GCC_ACC_NOTIFY): Remove unused env var.

diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 526d1be2955..78a3082c2f6 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -4989,13 +4989,11 @@ The variables @env{ACC_DEVICE_TYPE} and @env{ACC_DEVICE_NUM}
 are defined by section 4 of the OpenACC specification in version 2.0.
 The variable @env{ACC_PROFLIB}
 is defined by section 4 of the OpenACC specification in version 2.6.
-The variable @env{GCC_ACC_NOTIFY} is used for diagnostic purposes.
 
 @menu
 * ACC_DEVICE_TYPE::
 * ACC_DEVICE_NUM::
 * ACC_PROFLIB::
-* GCC_ACC_NOTIFY::
 @end menu
 
 
@@ -5003,6 +5001,17 @@ The variable @env{GCC_ACC_NOTIFY} is used for diagnostic purposes.
 @node ACC_DEVICE_TYPE
 @section @code{ACC_DEVICE_TYPE}
 @table @asis
+@item @emph{Description}:
+Control the default device type to use when executing compute regions.
+If unset, the code can be run on any device type, favoring a non-host
+device type.
+
+Supported values in GCC (if compiled in) are
+@itemize
+@item @code{host}
+@item @code{nvidia}
+@item @code{radeon}
+@end itemize
 @item @emph{Reference}:
 @uref{https://www.openacc.org, OpenACC specification v2.6}, section
 4.1.
@@ -5013,6 +5022,10 @@ The variable @env{GCC_ACC_NOTIFY} is used for diagnostic purposes.
 @node ACC_DEVICE_NUM
 @section @code{ACC_DEVICE_NUM}
 @table @asis
+@item @emph{Description}:
+Control which device, identified by device number, is the default device.
+The value must be a nonnegative integer less than the number of devices.
+If unset, device number zero is used.
 @item @emph{Reference}:
 @uref{https://www.openacc.org, OpenACC specification v2.6}, section
 4.2.
@@ -5023,6 +5036,11 @@ The variable @env{GCC_ACC_NOTIFY} is used for diagnostic purposes.
 @node ACC_PROFLIB
 @section @code{ACC_PROFLIB}
 @table @asis
+@item @emph{Description}:
+Semicolon-separated list of dynamic libraries that are loaded as profiling
+libraries.  Each library must provide at least the @code{acc_register_library}
+routine.  Each library file is found as described by the documentation of
+@code{dlopen} of your operating system.
 @item @emph{See also}:
 @ref{acc_register_library}, @ref{OpenACC Profiling Interface}
 
@@ -5033,15 +5051,6 @@ The variable @env{GCC_ACC_NOTIFY} is used for diagnostic purposes.
 
 
 
-@node GCC_ACC_NOTIFY
-@section @code{GCC_ACC_NOTIFY}
-@table @asis
-@item @emph{Description}:
-Print debug information pertaining to the accelerator.
-@end table
-
-
-
 @c -
 @c CUDA Streams Usage
 @c -


[patch] libgomp.texi: Update "Enabling OpenMP" + OpenACC / invoke.texi: -fopenacc/-fopenmp update (was: Re: [patch] libgomp.texi: Update "Enabling OpenMP")

2023-10-15 Thread Tobias Burnus

Hi Sandra and Jakub,

I have now updated the patch; on the way, I found an issue in -fopenacc ('!$' is
not OpenACC and no longer supported) and the same @code/@samp.

I also updated invoke.texi for the same @code/@samp - and added both '!$'
and mentioned the 'c$'/'*$' Fortran fixed-form variant. I think the most
important bit is that '!$' is also supported by -fopenmp-simd as that's not
covered by the OpenMP specification.

Otherwise:

On 14.10.23 23:46, Sandra Loosemore wrote:

On 10/14/23 13:43, Tobias Burnus wrote:

The attached patch tries to improve this. Note that it talks about C and
C++ attributes, even though C23's [[omp::]] support has not yet landed.
(But is expected very soon.)


Is somebody actively working on implementing that, and expecting to
get it in before Stage 1 closes?  I don't think we should document
features that don't exist yet.

Yes. But I have now sneaked in an 'in C++' which can also be easily
removed once Jakub's patch is committed or as part of Jakub's patch.

This syntax for C also isn't even in the draft OpenMP 6.0 document so
at this point


Well, it is in the git version, which will be released as TR12 in about
a month (in time for SC23). It is very unlikely to get removed before
OpenMP 6.0 as it is an obvious extension to C++11's attribute support,
now that C supports attributes as well.


Other than that...
Use @option markup on options, not @command.


Fixed. Was preexisting and I copied it once. I've now checked, the only
other use in libgomp.texi was for an actual command (nvprof).



And I think all those @code markups should be @samp instead, or you
could just replace this whole blurb with something like "This flag
enables recognition of the directive syntax documented in the OpenMP
specification, and also arranges for automatic linking..."


I think it is more user friendly to document the sentinels. However, I
concur that @samp is better.


+OpenMP directives, which do not require the linking of neither the

s/, which/ that/


I have now used it, but I think it sound odd:

"enables *a* subset of OpenMP directives *that* do not require the linking"

I concur that with "*the* subset ... *that*" makes sense but I want to
avoid stating that *all* directives that do not require linking of
libgomp/libpthread are supported.

invoke.texi lists all supported directives, but I am not really fond of
repeating that list.


s/neither/either/


The fun of whether double negation cancels or enforces the negation or
.. ("not .. neither / nor").

Cf. https://en.wikipedia.org/wiki/Double_negative

In German and English, both cancellation and enforcement seem to be
possible, the latter especially with dialects - while the standard
language tends to avoid double negation.

Updated patch attached.

Thanks,

Tobias
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
libgomp.texi: Update "Enabling OpenMP" + OpenACC / invoke.texi: -fopenacc/-fopenmp update

The OpenACC specification does not mention the '!$ ' sentinel for conditional
compilation and the feature was removed in r11-5572-g1d6f6ac693a860
for PR fortran/98011.

libgomp/
	* libgomp.texi (Enabling OpenMP): Update for C/C++ attributes;
	improve wording especially for Fortran; mention -fopenmp-simd.
	(Enabling OpenACC): Minor cleanup; remove conditional compilation
	sentinel.

gcc/
	* doc/invoke.texi (-fopenacc, -fopenmp, -fopenmp-simd): Use @samp not
	@code; document more completely the supported Fortran sentinels.

gcc/fortran
	* scanner.cc (skip_free_comments, skip_fixed_comments): Remove
	leftover 'OpenACC' from comments about OpenMP's conditional
	compilation sentinel.

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fee659462ff..eb714d18511 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -2748,9 +2748,10 @@ Typical command lines are
 @opindex fopenacc
 @cindex OpenACC accelerator programming
 @item -fopenacc
-Enable handling of OpenACC directives @code{#pragma acc} in C/C++ and
-@code{!$acc} in Fortran.  When @option{-fopenacc} is specified, the
-compiler generates accelerated code according to the OpenACC Application
+Enable handling of OpenACC directives @samp{#pragma acc} in C/C++ and
+@samp{!$acc} in free-form Fortran and @samp{!$acc}, @samp{c$acc} and
+@samp{*$acc} in fixed-form Fortran.  When @option{-fopenacc} is specified,
+the compiler generates accelerated code according to the OpenACC Application
 Programming Interface v2.6 @w{@uref{https://www.openacc.org}}.  This option
 implies @option{-pthread}, and thus is only supported on targets that
 have support for @option{-pthread}.
@@ -2766,10 +2767,12 @@ can be omitted, to use a target-specific default value.
 @opindex fopenmp
 @cindex OpenMP parallel
 @item -fopenmp
-Enable handling of OpenMP directives @code{#pragma omp} in C/C+

RE: [PATCH] Support g++ 4.8 as a host compiler.

2023-10-15 Thread Roger Sayle


I'd like to ping my patch for restoring bootstrap using g++ 4.8.5
(the system compiler on RHEL 7 and later systems).
https://gcc.gnu.org/pipermail/gcc-patches/2023-October/632008.html

Note the preprocessor #ifs can be removed; they are only there to document
why the union u must have an explicit, empty (but not default) constructor.

I completely agree with the various opinions that we might consider
upgrading the minimum host compiler for many good reasons (Ada,
D, newer C++ features etc.).  It's inevitable that older compilers and
systems can't be supported indefinitely.

Having said that I don't think that this unintentional trivial breakage,
that has a safe one-line work around is sufficient cause (or non-neglible
risk or support burden), to inconvenice a large number of GCC users
(the impact/disruption to cfarm has already been mentioned).

Interestingly, "scl enable devtoolset-XX" to use a newer host compiler,
v10 or v11, results in a significant increase (100+) in unexpected failures I 
see
during mainline regression testing using "make -k check" (on RedHat 7.9).
(Older) system compilers, despite their flaws, are selected for their
(overall) stability and maturity.

If another patch/change hits the compiler next week that reasonably
means that 4.8.5 can no longer be supported, so be it, but its an
annoying (and unnecessary?) inconvenience in the meantime.

Perhaps we should file a Bugzilla PR indicating that the documentation
and release notes need updating, if my fix isn't considered acceptable?

Why this patch is an trigger issue (that requires significant discussion
and deliberation) is somewhat of a mystery.

Thanks in advance.
Roger
> -Original Message-
> From: Jeff Law 
> Sent: 07 October 2023 17:20
> To: Roger Sayle ; gcc-patches@gcc.gnu.org
> Cc: 'Richard Sandiford' 
> Subject: Re: [PATCH] Support g++ 4.8 as a host compiler.
> 
> 
> 
> On 10/4/23 16:19, Roger Sayle wrote:
> >
> > The recent patch to remove poly_int_pod triggers a bug in g++ 4.8.5's
> > C++ 11 support which mistakenly believes poly_uint16 has a non-trivial
> > constructor.  This in turn prohibits it from being used as a member in
> > a union (rtxunion) that constructed statically, resulting in a (fatal)
> > error during stage 1.  A workaround is to add an explicit constructor
> > to the problematic union, which allows mainline to be bootstrapped
> > with the system compiler on older RedHat 7 systems.
> >
> > This patch has been tested on x86_64-pc-linux-gnu where it allows a
> > bootstrap to complete when using g++ 4.8.5 as the host compiler.
> > Ok for mainline?
> >
> >
> > 2023-10-04  Roger Sayle  
> >
> > gcc/ChangeLog
> > * rtl.h (rtx_def::u): Add explicit constructor to workaround
> > issue using g++ 4.8 as a host compiler.
> I think the bigger question is whether or not we're going to step forward on 
> the
> minimum build requirements.
> 
> My recollection was we settled on gcc-4.8 for the benefit of RHEL 7 and 
> Centos 7
> which are rapidly approaching EOL (June 2024).
> 
> I would certainly support stepping forward to a more modern compiler for the
> build requirements, which might make this patch obsolete.
> 
> Jeff



[committed] d: Merge upstream dmd, druntime f9efc98fd7, phobos a3f22129d.

2023-10-15 Thread Iain Buclaw
Hi,

This patch merges the D front-end and run-time library with upstream dmd
f9efc98fd7, and standard library with phobos a3f22129d.

Synchronizing with the latest bug fixes in the v2.105.2 release.

D front-end changes:

- Import dmd v2.105.2.
- A function with enum storage class is now deprecated.
- Global variables can now be initialized with Associative
  Arrays.
- Improvements for the C++ header generation of static variables
  used in a default argument context.

D runtime changes:

- Import druntime v2.105.2.
- The `core.memory.GC' functions `GC.enable', `GC.disable',
  `GC.collect', and `GC.minimize' `have been marked `@safe'.

Phobos changes:

- Import phobos v2.105.2.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32, committed
to mainline.

Regards,
Iain.

---
gcc/d/ChangeLog:

* dmd/MERGE: Merge upstream dmd f9efc98fd7.
* dmd/VERSION: Bump version to v2.105.2.
* d-builtins.cc (build_frontend_type): Update for new front-end
interface.
* d-diagnostic.cc (verrorReport): Don't emit tips when error gagging
is turned on.
* d-lang.cc (d_handle_option): Remove obsolete parameter.
(d_post_options): Likewise.
(d_read_ddoc_files): New function.
(d_generate_ddoc_file): New function.
(d_parse_file): Update for new front-end interface.
* expr.cc (ExprVisitor::visit (AssocArrayLiteralExp *)): Check for new
front-end lowering of static associative arrays.

libphobos/ChangeLog:

* libdruntime/MERGE: Merge upstream druntime f9efc98fd7.
* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add
core/internal/newaa.d.
* libdruntime/Makefile.in: Regenerate.
* src/MERGE: Merge upstream phobos a3f22129d.
* testsuite/libphobos.hash/test_hash.d: Update test.
* testsuite/libphobos.phobos/phobos.exp: Add compiler flags
-Wno-deprecated.
* testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.

gcc/testsuite/ChangeLog:

* lib/gdc-utils.exp (gdc-convert-args): Handle new compiler options.
---
 gcc/d/d-builtins.cc   |   3 +-
 gcc/d/d-diagnostic.cc |   5 +-
 gcc/d/d-lang.cc   |  78 +++-
 gcc/d/dmd/MERGE   |   2 +-
 gcc/d/dmd/VERSION |   2 +-
 gcc/d/dmd/attrib.d|   2 +-
 gcc/d/dmd/blockexit.d | 107 +++--
 gcc/d/dmd/canthrow.d  |   2 +-
 gcc/d/dmd/chkformat.d |  32 +-
 gcc/d/dmd/clone.d |  20 +-
 gcc/d/dmd/cond.d  |   2 +-
 gcc/d/dmd/cparse.d|  11 +-
 gcc/d/dmd/cppmangle.d |   2 -
 gcc/d/dmd/ctfeexpr.d  |   6 +-
 gcc/d/dmd/dcast.d |  13 +-
 gcc/d/dmd/dclass.d|   6 +-
 gcc/d/dmd/declaration.d   |   7 +-
 gcc/d/dmd/delegatize.d|   1 -
 gcc/d/dmd/denum.d |   2 -
 gcc/d/dmd/dinterpret.d|  14 +-
 gcc/d/dmd/dmacro.d|  56 ++-
 gcc/d/dmd/dmodule.d   |   4 +-
 gcc/d/dmd/doc.d   | 353 -
 gcc/d/dmd/doc.h   |   3 +-
 gcc/d/dmd/dscope.d|   1 +
 gcc/d/dmd/dstruct.d   |   1 +
 gcc/d/dmd/dsymbol.d   |   1 +
 gcc/d/dmd/dsymbolsem.d|  58 ++-
 gcc/d/dmd/dtemplate.d |  24 +-
 gcc/d/dmd/dtoh.d  |  10 +-
 gcc/d/dmd/errors.h|   3 +-
 gcc/d/dmd/errorsink.d |   1 +
 gcc/d/dmd/escape.d|  40 +-
 gcc/d/dmd/expression.d|  47 ++-
 gcc/d/dmd/expression.h|   3 +-
 gcc/d/dmd/expressionsem.d | 109 ++---
 gcc/d/dmd/func.d  |  21 +-
 gcc/d/dmd/globals.d   |  33 +-
 gcc/d/dmd/globals.h   |  35 +-
 gcc/d/dmd/hdrgen.d| 375 +-
 gcc/d/dmd/hdrgen.h|   4 +-
 gcc/d/dmd/iasmgcc.d   |   2 +-
 gcc/d/dmd/id.d|   2 +
 gcc/d/dmd/init.d  |   2 +-
 gcc/d/dmd/initsem.d   |  31 +-
 gcc/d/dmd/json.d  |  23 +-
 gcc/d/dmd/json.h  |   2 +-
 gcc/d/dmd/lexer.d |  88 +++-
 gcc/d/dmd/location.d  |  20 +-
 gcc/d/dmd/module.h

Re: [PATCH] Support g++ 4.8 as a host compiler.

2023-10-15 Thread Richard Sandiford
"Roger Sayle"  writes:
> I'd like to ping my patch for restoring bootstrap using g++ 4.8.5
> (the system compiler on RHEL 7 and later systems).
> https://gcc.gnu.org/pipermail/gcc-patches/2023-October/632008.html
>
> Note the preprocessor #ifs can be removed; they are only there to document
> why the union u must have an explicit, empty (but not default) constructor.
>
> I completely agree with the various opinions that we might consider
> upgrading the minimum host compiler for many good reasons (Ada,
> D, newer C++ features etc.).  It's inevitable that older compilers and
> systems can't be supported indefinitely.
>
> Having said that I don't think that this unintentional trivial breakage,
> that has a safe one-line work around is sufficient cause (or non-neglible
> risk or support burden), to inconvenice a large number of GCC users
> (the impact/disruption to cfarm has already been mentioned).
>
> Interestingly, "scl enable devtoolset-XX" to use a newer host compiler,
> v10 or v11, results in a significant increase (100+) in unexpected failures I 
> see
> during mainline regression testing using "make -k check" (on RedHat 7.9).
> (Older) system compilers, despite their flaws, are selected for their
> (overall) stability and maturity.
>
> If another patch/change hits the compiler next week that reasonably
> means that 4.8.5 can no longer be supported, so be it, but its an
> annoying (and unnecessary?) inconvenience in the meantime.
>
> Perhaps we should file a Bugzilla PR indicating that the documentation
> and release notes need updating, if my fix isn't considered acceptable?
>
> Why this patch is an trigger issue (that requires significant discussion
> and deliberation) is somewhat of a mystery.

It seemed like there was considerable support for bumping the minimum
to beyond 4.8.  I think we should wait until a decision has been made
before adding more 4.8 workarounds.

Having a conditional explicit constructor is dangerous because it changes
semantics.  E.g. consider:

  #include 

  union u { int x; };
  void f(u *ptr) { new(ptr) u; }
  void g(u *ptr) { new(ptr) u(); }

g(ptr) zeros ptr->x whereas f(ptr) doesn't.  If we add "u() {}" then g()
does not zero ptr->x.

So if we did add the workaround, it would need to be unconditional,
like you say.

Thanks,
Richard


[PING ^0][PATCH v3] rs6000: fmr gets used instead of faster xxlor [PR93571]

2023-10-15 Thread Ajit Agarwal


Hello Segher:


Please review.

Thanks & Regards
Ajit

 Forwarded Message 
Subject: PATCH v3] rs6000: fmr gets used instead of faster xxlor [PR93571]
Date: Tue, 10 Oct 2023 18:14:00 +0530
From: Ajit Agarwal 
To: gcc-patches 
CC: Segher Boessenkool , Peter Bergner 
, Kewen.Lin 

Hello Segher:

Here is the patch that uses xxlor instead of fmr where possible.
Performance results shows that fmr is better in power9 and 
power10 architectures whereas xxlor is better in power7 and
power 8 architectures. fmr is the only option before p7.

Incorporated review comments.

Bootstrapped and regtested on powerpc64-linux-gnu

Thanks & Regards
Ajit

rs6000: Use xxlor instead of fmr where possible

Replaces fmr with xxlor instruction for power7 and power8
architectures whereas for power9 and power10 keep fmr
instruction.

Perf measurement results:

Power9 fmr:  201,847,661 cycles.
Power9 xxlor: 201,877,78 cycles.
Power8 fmr: 200,901,043 cycles.
Power8 xxlor: 201,020,518 cycles.
Power7 fmr: 201,059,524 cycles.
Power7 xxlor: 201,042,851 cycles.

2023-10-10  Ajit Kumar Agarwal  

gcc/ChangeLog:

* config/rs6000/rs6000.md (*movdf_hardfloat64): Use xxlor for power7
and power8 and fmr for power9 and power10.
---
 gcc/config/rs6000/rs6000.md | 45 -
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d4337ce42a9..46982637d79 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -355,7 +355,7 @@
   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
 
 ;; The ISA we implement.
-(define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
+(define_attr "isa" "any,p5,p6,p7,p7v,p8v,p7p8v,p9,p9v,p9kf,p9tf,p10"
   (const_string "any"))
 
 ;; Is this alternative enabled for the current CPU/ISA/etc.?
@@ -403,6 +403,12 @@
  (and (eq_attr "isa" "p10")
  (match_test "TARGET_POWER10"))
  (const_int 1)
+
+ (and (eq_attr "isa" "p7p8v")
+ (match_test "rs6000_tune != PROCESSOR_POWER9
+  && TARGET_VSX && !TARGET_P9_VECTOR"))
+ (const_int 1)
+
 ] (const_int 0)))
 
 ;; If this instruction is microcoded on the CELL processor
@@ -8551,27 +8557,29 @@
 
 (define_insn "*mov_hardfloat64"
   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
-   "=m,   d,  d,  ,   wY,
- ,Z,  ,  ,  !r,
+   "=m,   d,  ,  ,   wY,
+ ,Z,  wa, ,  !r,
  YZ,  r,  !r, *c*l,   !r,
-*h,   r,  ,   wa")
+*h,   r,  ,   d,  wn,
+wa")
(match_operand:FMOVE64 1 "input_operand"
-"d,   m,  d,  wY, ,
- Z,   ,   ,  ,  ,
+"d,   m,  ,  wY, ,
+ Z,   ,   wa, ,  ,
  r,   YZ, r,  r,  *h,
- 0,   ,   r,  eP"))]
+ 0,   ,   r,  d,  wn,
+ eP"))]
   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
&& (gpc_reg_operand (operands[0], mode)
|| gpc_reg_operand (operands[1], mode))"
   "@
stfd%U0%X0 %1,%0
lfd%U1%X1 %0,%1
-   fmr %0,%1
+   xxlor %x0,%x1,%x1
lxsd %0,%1
stxsd %1,%0
lxsdx %x0,%y1
stxsdx %x1,%y0
-   xxlor %x0,%x1,%x1
+   fmr %0,%1
xxlxor %x0,%x0,%x0
li %0,0
std%U0%X0 %1,%0
@@ -8582,23 +8590,28 @@
nop
mfvsrd %0,%x1
mtvsrd %x0,%1
+   fmr %0,%1
+   fmr %0,%1
#"
   [(set_attr "type"
-"fpstore, fpload, fpsimple,   fpload, fpstore,
+"fpstore, fpload, veclogical, fpload, fpstore,
  fpload,  fpstore,veclogical, veclogical, integer,
  store,   load,   *,  mtjmpr, mfjmpr,
- *,   mfvsr,  mtvsr,  vecperm")
+ *,   mfvsr,  mtvsr,  fpsimple,   fpsimple,
+ vecperm")
(set_attr "size" "64")
(set_attr "isa"
-"*,   *,  *,  p9v,p9v,
- p7v, p7v,*,  *,  *,
- *,   *,  *,  *,  *,
- *,   p8v,p8v,p10")
+"*,  *,  p7p8v,   p9v,p9v,
+ p7v, p7v,*,   *,  *,
+ *,   *,  *,   *,  *,
+ *,   p8v,p8v, *,  *,
+ p10")
(set_attr "prefixed"
 "*,   *,  *,  *,  *,
  *,   *,  *,  *,  *,
  *,   *,  *,  *,  *,
- *,   *, 

[PING ^0][PATCH v2] rs6000: Add new pass for replacement of contiguous addresses vector load lxv with lxvp

2023-10-15 Thread Ajit Agarwal
Hello All:

Please review.

Thanks & Regards
Ajit


 Forwarded Message 
Subject: [PATCH v2] rs6000: Add new pass for replacement of contiguous 
addresses vector load lxv with lxvp
Date: Sun, 8 Oct 2023 00:34:27 +0530
From: Ajit Agarwal 
To: gcc-patches 
CC: Segher Boessenkool , Peter Bergner 
, Kewen.Lin 

Hello All:

This patch add new pass to replace contiguous addresses vector load lxv with 
mma instruction
lxvp. This patch addresses one regressions failure in ARM architecture.

Bootstrapped and regtested with powepc64-linux-gnu.

Thanks & Regards
Ajit


rs6000: Add new pass for replacement of contiguous lxv with lxvp.

New pass to replace contiguous addresses lxv with lxvp. This pass
is registered after ree rtl pass.

2023-10-07  Ajit Kumar Agarwal  

gcc/ChangeLog:

* config/rs6000/rs6000-passes.def: Registered vecload pass.
* config/rs6000/rs6000-vecload-opt.cc: Add new pass.
* config.gcc: Add new executable.
* config/rs6000/rs6000-protos.h: Add new prototype for vecload
pass.
* config/rs6000/rs6000.cc: Add new prototype for vecload pass.
* config/rs6000/t-rs6000: Add new rule.

gcc/testsuite/ChangeLog:

* g++.target/powerpc/vecload.C: New test.
---
 gcc/config.gcc |   4 +-
 gcc/config/rs6000/rs6000-passes.def|   1 +
 gcc/config/rs6000/rs6000-protos.h  |   2 +
 gcc/config/rs6000/rs6000-vecload-opt.cc| 234 +
 gcc/config/rs6000/rs6000.cc|   3 +-
 gcc/config/rs6000/t-rs6000 |   4 +
 gcc/testsuite/g++.target/powerpc/vecload.C |  15 ++
 7 files changed, 260 insertions(+), 3 deletions(-)
 create mode 100644 gcc/config/rs6000/rs6000-vecload-opt.cc
 create mode 100644 gcc/testsuite/g++.target/powerpc/vecload.C

diff --git a/gcc/config.gcc b/gcc/config.gcc
index ee46d96bf62..482ab094b89 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -515,7 +515,7 @@ or1k*-*-*)
;;
 powerpc*-*-*)
cpu_type=rs6000
-   extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o"
+   extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o 
rs6000-vecload-opt.o"
extra_objs="${extra_objs} rs6000-call.o rs6000-pcrel-opt.o"
extra_objs="${extra_objs} rs6000-builtins.o rs6000-builtin.o"
extra_headers="ppc-asm.h altivec.h htmintrin.h htmxlintrin.h"
@@ -552,7 +552,7 @@ riscv*)
;;
 rs6000*-*-*)
extra_options="${extra_options} g.opt fused-madd.opt 
rs6000/rs6000-tables.opt"
-   extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o"
+   extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o 
rs6000-vecload-opt.o"
extra_objs="${extra_objs} rs6000-call.o rs6000-pcrel-opt.o"
target_gtfiles="$target_gtfiles 
\$(srcdir)/config/rs6000/rs6000-logue.cc 
\$(srcdir)/config/rs6000/rs6000-call.cc"
target_gtfiles="$target_gtfiles 
\$(srcdir)/config/rs6000/rs6000-pcrel-opt.cc"
diff --git a/gcc/config/rs6000/rs6000-passes.def 
b/gcc/config/rs6000/rs6000-passes.def
index ca899d5f7af..9ecf8ce6a9c 100644
--- a/gcc/config/rs6000/rs6000-passes.def
+++ b/gcc/config/rs6000/rs6000-passes.def
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
  The power8 does not have instructions that automaticaly do the byte swaps
  for loads and stores.  */
   INSERT_PASS_BEFORE (pass_cse, 1, pass_analyze_swaps);
+  INSERT_PASS_AFTER (pass_ree, 1, pass_analyze_vecload);
 
   /* Pass to do the PCREL_OPT optimization that combines the load of an
  external symbol's address along with a single load or store using that
diff --git a/gcc/config/rs6000/rs6000-protos.h 
b/gcc/config/rs6000/rs6000-protos.h
index f70118ea40f..9c44bae33d3 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -91,6 +91,7 @@ extern int mems_ok_for_quad_peep (rtx, rtx);
 extern bool gpr_or_gpr_p (rtx, rtx);
 extern bool direct_move_p (rtx, rtx);
 extern bool quad_address_p (rtx, machine_mode, bool);
+extern bool mode_supports_dq_form (machine_mode);
 extern bool quad_load_store_p (rtx, rtx);
 extern bool fusion_gpr_load_p (rtx, rtx, rtx, rtx);
 extern void expand_fusion_gpr_load (rtx *);
@@ -344,6 +345,7 @@ class rtl_opt_pass;
 
 extern rtl_opt_pass *make_pass_analyze_swaps (gcc::context *);
 extern rtl_opt_pass *make_pass_pcrel_opt (gcc::context *);
+extern rtl_opt_pass *make_pass_analyze_vecload (gcc::context *);
 extern bool rs6000_sum_of_two_registers_p (const_rtx expr);
 extern bool rs6000_quadword_masked_address_p (const_rtx exp);
 extern rtx rs6000_gen_lvx (enum machine_mode, rtx, rtx);
diff --git a/gcc/config/rs6000/rs6000-vecload-opt.cc 
b/gcc/config/rs6000/rs6000-vecload-opt.cc
new file mode 100644
index 000..63ee733af89
--- /dev/null
+++ b/gcc/config/rs6000/rs6000-vecload-opt.cc
@@ -0,0 +1,234 @@
+/* Subroutines used to replace lxv with lxvp
+   for p10 little-endian VSX code.
+   Copyright (C) 2020-2023 Free Software Foundation, Inc.
+   

[PING ^0] [PATCH v8 4/4] ree: Improve ree pass for rs6000 target using defined ABI interfaces

2023-10-15 Thread Ajit Agarwal


Hello All:

Please review and update with your comments so that code changes are committed 
in trunk.

Thanks & Regards
Ajit

 Forwarded Message 
Subject: [PATCH v8 4/4] ree: Improve ree pass for rs6000 target using defined 
ABI interfaces
Date: Wed, 20 Sep 2023 02:40:49 +0530
From: Ajit Agarwal 
To: gcc-patches 
CC: Jeff Law , Vineet Gupta , 
Richard Biener , Segher Boessenkool 
, Peter Bergner 

Hello All:

This version 8 of the patch uses abi interfaces to remove zero and sign 
extension elimination.
Bootstrapped and regtested on powerpc-linux-gnu.

Incorporated all the review comments of version 6. Added sign extension 
elimination using abi 
interfaces.

Thanks & Regards
Ajit

ree: Improve ree pass for rs6000 target using defined abi interfaces

For rs6000 target we see redundant zero and sign extension and done
to improve ree pass to eliminate such redundant zero and sign extension
using defined ABI interfaces.

2023-09-20  Ajit Kumar Agarwal  

gcc/ChangeLog:

* ree.cc (combine_reaching_defs): Use of zero_extend and sign_extend
defined abi interfaces.
(add_removable_extension): Use of defined abi interfaces for no
reaching defs.
(abi_extension_candidate_return_reg_p): New function.
(abi_extension_candidate_p): New function.
(abi_extension_candidate_argno_p): New function.
(abi_handle_regs_without_defs_p): New function.
(abi_target_promote_function_mode): New function.

gcc/testsuite/ChangeLog:

* g++.target/powerpc/zext-elim-3.C
---
 gcc/ree.cc| 161 +-
 .../g++.target/powerpc/zext-elim-3.C  |  13 ++
 2 files changed, 171 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/powerpc/zext-elim-3.C

diff --git a/gcc/ree.cc b/gcc/ree.cc
index fc04249fa84..e833db2432d 100644
--- a/gcc/ree.cc
+++ b/gcc/ree.cc
@@ -514,7 +514,8 @@ get_uses (rtx_insn *insn, rtx reg)
 if (REGNO (DF_REF_REG (def)) == REGNO (reg))
   break;
 
-  gcc_assert (def != NULL);
+  if (def == NULL)
+return NULL;
 
   ref_chain = DF_REF_CHAIN (def);
 
@@ -750,6 +751,134 @@ get_extended_src_reg (rtx src)
   return src;
 }
 
+/* Return TRUE if target mode is equal to source mode of zero_extend
+   or sign_extend otherwise false.  */
+
+static bool
+abi_target_promote_function_mode (machine_mode mode)
+{
+  int unsignedp;
+  machine_mode tgt_mode
+= targetm.calls.promote_function_mode (NULL_TREE, mode, &unsignedp,
+  NULL_TREE, 1);
+
+  if (tgt_mode == mode)
+return true;
+  else
+return false;
+}
+
+/* Return TRUE if the candidate insn is zero extend and regno is
+   a return registers.  */
+
+static bool
+abi_extension_candidate_return_reg_p (rtx_insn *insn, int regno)
+{
+  rtx set = single_set (insn);
+  rtx src = SET_SRC (set);
+
+  if (GET_CODE (src) != ZERO_EXTEND && GET_CODE (src) != SIGN_EXTEND)
+return false;
+
+  if (targetm.calls.function_value_regno_p (regno))
+return true;
+
+  return false;
+}
+
+/* Return TRUE if reg source operand of zero_extend is argument registers
+   and not return registers and source and destination operand are same
+   and mode of source and destination operand are not same.  */
+
+static bool
+abi_extension_candidate_p (rtx_insn *insn)
+{
+  rtx set = single_set (insn);
+  rtx src = SET_SRC (set);
+
+  if (GET_CODE (src) != ZERO_EXTEND && GET_CODE (src) != SIGN_EXTEND)
+return false;
+
+  machine_mode dst_mode = GET_MODE (SET_DEST (set));
+  rtx orig_src = XEXP (SET_SRC (set), 0);
+
+  if (!FUNCTION_ARG_REGNO_P (REGNO (orig_src))
+  || abi_extension_candidate_return_reg_p (insn, REGNO (orig_src)))
+return false;
+
+  /* Mode of destination and source of zero_extend should be different.  */
+  if (dst_mode == GET_MODE (orig_src))
+return false;
+
+  /* REGNO of source and destination of zero_extend should be same.  */
+  if (REGNO (SET_DEST (set)) != REGNO (orig_src))
+return false;
+
+  return true;
+}
+
+/* Return TRUE if the candidate insn is zero extend and regno is
+   an argument registers.  */
+
+static bool
+abi_extension_candidate_argno_p (rtx_code code, int regno)
+{
+  if (code != ZERO_EXTEND && code != SIGN_EXTEND)
+return false;
+
+  if (FUNCTION_ARG_REGNO_P (regno))
+return true;
+
+  return false;
+}
+
+/* Return TRUE if the candidate insn doesn't have defs and have
+ * uses without RTX_BIN_ARITH/RTX_COMM_ARITH/RTX_UNARY rtx class.  */
+
+static bool
+abi_handle_regs (rtx_insn *insn)
+{
+  if (side_effects_p (PATTERN (insn)))
+return false;
+
+  struct df_link *uses = get_uses (insn, SET_DEST (PATTERN (insn)));
+
+  if (!uses)
+return false;
+
+  for (df_link *use = uses; use; use = use->next)
+{
+  if (!use->ref)
+   return false;
+
+  if (BLOCK_FOR_INSN (insn) != BLOCK_FOR_INSN (DF_REF_INSN (use->ref)))
+   return false;
+
+  rtx_insn *use_insn = DF_REF_INSN (use->ref);
+
+

[PING ^0] [PATCH v2 3/4] Improve functionality of ree pass with various constants with AND operation.

2023-10-15 Thread Ajit Agarwal



Hello All:

Please review. In this patch I have different modes and constants that are 
supported in ree pass for 
sign and zero extension eliminations.

Please review and update with your comments so that it will be committed in 
trunk.

Thanks & Regards
Ajit
 Forwarded Message 
Subject: [PATCH v2 3/4] Improve functionality of ree pass with various 
constants with AND operation.
Date: Tue, 19 Sep 2023 14:51:16 +0530
From: Ajit Agarwal 
To: gcc-patches 
CC: Jeff Law , Vineet Gupta , 
Richard Biener , Peter Bergner 
, Segher Boessenkool 


Hello Jeff:

This patch eliminates redundant zero and sign extension with ree pass for rs6000
target.

Bootstrapped and regtested for powerpc64-linux-gnu.

Thanks & Regards
Ajit


ree: Improve ree pass

For rs6000 target we see redundant zero and sign extension and ree pass
s improved to eliminate such redundant zero and sign extension. Support of
zero_extend/sign_extend/AND.

2023-09-04  Ajit Kumar Agarwal  

gcc/ChangeLog:

* ree.cc (eliminate_across_bbs_p): Add checks to enable extension
elimination across and within basic blocks.
(def_arith_p): New function to check definition has arithmetic
operation.
(combine_set_extension): Modification to incorporate AND
and current zero_extend and sign_extend instruction.
(merge_def_and_ext): Add calls to eliminate_across_bbs_p and
zero_extend sign_extend and AND instruction.
(rtx_is_zext_p): New function.
(feasible_cfg): New function.
* rtl.h (reg_used_set_between_p): Add prototype.
* rtlanal.cc (reg_used_set_between_p): New function.

gcc/testsuite/ChangeLog:

* g++.target/powerpc/zext-elim.C: New testcase.
* g++.target/powerpc/zext-elim-1.C: New testcase.
* g++.target/powerpc/zext-elim-2.C: New testcase.
* g++.target/powerpc/sext-elim.C: New testcase.
---
 gcc/ree.cc| 487 --
 gcc/rtl.h |   1 +
 gcc/rtlanal.cc|  15 +
 gcc/testsuite/g++.target/powerpc/sext-elim.C  |  17 +
 .../g++.target/powerpc/zext-elim-1.C  |  19 +
 .../g++.target/powerpc/zext-elim-2.C  |  11 +
 gcc/testsuite/g++.target/powerpc/zext-elim.C  |  30 ++
 7 files changed, 534 insertions(+), 46 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/powerpc/sext-elim.C
 create mode 100644 gcc/testsuite/g++.target/powerpc/zext-elim-1.C
 create mode 100644 gcc/testsuite/g++.target/powerpc/zext-elim-2.C
 create mode 100644 gcc/testsuite/g++.target/powerpc/zext-elim.C

diff --git a/gcc/ree.cc b/gcc/ree.cc
index fc04249fa84..931b9b08821 100644
--- a/gcc/ree.cc
+++ b/gcc/ree.cc
@@ -253,6 +253,77 @@ struct ext_cand
 
 static int max_insn_uid;
 
+/* Return TRUE if OP can be considered a zero extension from one or
+   more sub-word modes to larger modes up to a full word.
+
+   For example (and:DI (reg) (const_int X))
+
+   Depending on the value of X could be considered a zero extension
+   from QI, HI and SI to larger modes up to DImode.  */
+
+static bool
+rtx_is_zext_p (rtx insn)
+{
+  if (GET_CODE (insn) == AND)
+{
+  rtx set = XEXP (insn, 0);
+  if (REG_P (set))
+   {
+ rtx src = XEXP (insn, 1);
+ machine_mode m_mode = GET_MODE (set);
+
+ if (CONST_INT_P (src)
+ && (INTVAL (src) == 1
+ || (m_mode == QImode && INTVAL (src) == 0x7)
+ || (m_mode == QImode && INTVAL (src) == 0x007F)
+ || (m_mode == HImode && INTVAL (src) == 0x7FFF)
+ || (m_mode == SImode && INTVAL (src) == 0x007F)))
+   return true;
+
+   }
+  else
+   return false;
+}
+
+  return false;
+}
+/* Return TRUE if OP can be considered a zero extension from one or
+   more sub-word modes to larger modes up to a full word.
+
+   For example (and:DI (reg) (const_int X))
+
+   Depending on the value of X could be considered a zero extension
+   from QI, HI and SI to larger modes up to DImode.  */
+
+static bool
+rtx_is_zext_p (rtx_insn *insn)
+{
+  rtx body = single_set (insn);
+
+  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == AND)
+   {
+ rtx set = XEXP (SET_SRC (body), 0);
+
+ if (REG_P (set) && GET_MODE (SET_DEST (body)) == GET_MODE (set))
+   {
+ rtx src = XEXP (SET_SRC (body), 1);
+ machine_mode m_mode = GET_MODE (set);
+
+ if (CONST_INT_P (src)
+ && (INTVAL (src) == 1
+ || (m_mode == QImode && INTVAL (src) == 0x7)
+ || (m_mode == QImode && INTVAL (src) == 0x007F)
+ || (m_mode == HImode && INTVAL (src) == 0x7FFF)
+ || (m_mode == SImode && INTVAL (src) == 0x007F)))
+   return true;
+   }
+ else
+  return false;
+   }
+
+   return false;
+}
+
 /* Update or remove REG_EQUAL or REG_EQUIV notes for INSN.  */
 
 static bool

[pushed] wwwdocs: conduct: Link creativecommons.org via https

2023-10-15 Thread Gerald Pfeifer
Browers are starting to complain about http links, and the server
actually redirects.

On the way break really long lines.

Pushed.
Gerald
---
 htdocs/conduct-faq.html  | 4 +++-
 htdocs/conduct-report.html   | 4 +++-
 htdocs/conduct-response.html | 4 +++-
 htdocs/conduct.html  | 4 +++-
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/htdocs/conduct-faq.html b/htdocs/conduct-faq.html
index 5b7a82a3..9ac65fbc 100644
--- a/htdocs/conduct-faq.html
+++ b/htdocs/conduct-faq.html
@@ -64,4 +64,6 @@ email mailto:cond...@gcc.gnu.org";>cond...@gcc.gnu.org with any
 additional questions or feedback.
 
 http://creativecommons.org/licenses/by-sa/4.0/";>https://i.creativecommons.org/l/by-sa/4.0/88x31.png"; />
-This work is licensed under a http://creativecommons.org/licenses/by-sa/4.0/";>Creative Commons 
Attribution-ShareAlike 4.0 International License.
+This work is licensed under a
+https://creativecommons.org/licenses/by-sa/4.0/";>
+Creative Commons Attribution-ShareAlike 4.0 International License.
diff --git a/htdocs/conduct-report.html b/htdocs/conduct-report.html
index 5f3fae90..58e4489e 100644
--- a/htdocs/conduct-report.html
+++ b/htdocs/conduct-report.html
@@ -114,7 +114,9 @@ of the committee's decision. To make such a request, 
contact a member of the
 Steering Committee with your request and motivation.
 
 http://creativecommons.org/licenses/by-sa/4.0/";>https://i.creativecommons.org/l/by-sa/4.0/88x31.png"; />
-This work is licensed under a http://creativecommons.org/licenses/by-sa/4.0/";>Creative Commons 
Attribution-ShareAlike 4.0 International License.
+This work is licensed under a
+https://creativecommons.org/licenses/by-sa/4.0/";>
+Creative Commons Attribution-ShareAlike 4.0 International License.
 
 Text derived from
 the https://www.djangoproject.com/conduct/reporting/";>Django project
diff --git a/htdocs/conduct-response.html b/htdocs/conduct-response.html
index a25f6ae4..a261554d 100644
--- a/htdocs/conduct-response.html
+++ b/htdocs/conduct-response.html
@@ -133,7 +133,9 @@ directly to any of the committee members, as documented in 
the reporting
 guidelines.
 
 http://creativecommons.org/licenses/by-sa/4.0/";>https://i.creativecommons.org/l/by-sa/4.0/88x31.png"; />
-This work is licensed under a http://creativecommons.org/licenses/by-sa/4.0/";>Creative Commons 
Attribution-ShareAlike 4.0 International License.
+This work is licensed under a
+https://creativecommons.org/licenses/by-sa/4.0/";>
+Creative Commons Attribution-ShareAlike 4.0 International License.
 
 Text derived from
 the https://www.djangoproject.com/conduct/enforcement-manual/";>Django
diff --git a/htdocs/conduct.html b/htdocs/conduct.html
index 87bd01bf..25790035 100644
--- a/htdocs/conduct.html
+++ b/htdocs/conduct.html
@@ -115,7 +115,9 @@ that doesn't answer your questions, feel free
 to mailto:cond...@gcc.gnu.org";>contact us.
 
 http://creativecommons.org/licenses/by-sa/4.0/";>https://i.creativecommons.org/l/by-sa/4.0/88x31.png"; />
-This work is licensed under a http://creativecommons.org/licenses/by-sa/4.0/";>Creative Commons 
Attribution-ShareAlike 4.0 International License.
+This work is licensed under a
+https://creativecommons.org/licenses/by-sa/4.0/";>
+Creative Commons Attribution-ShareAlike 4.0 International License.
 
 Text derived from the https://www.djangoproject.com/conduct/";>Django
 project Code of Conduct, used under
-- 
2.42.0


[pushed] wwwdocs: gcc-9: Editorial changes to porting_to.html

2023-10-15 Thread Gerald Pfeifer
Of course GCC 9 is not exactly fresh, though since I found this in a local 
tree still worth pushing.

Pushed.

Gerald
---
 htdocs/gcc-9/porting_to.html | 31 ---
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/htdocs/gcc-9/porting_to.html b/htdocs/gcc-9/porting_to.html
index 796c402e..fc85dae2 100644
--- a/htdocs/gcc-9/porting_to.html
+++ b/htdocs/gcc-9/porting_to.html
@@ -64,22 +64,23 @@ and provide solutions. Let us know if you have suggestions 
for improvements!
   that const qualified variables without mutable
   member are predetermined shared, but as an exception may be specified
   in the firstprivate clause.  OpenMP 4.0 dropped this rule,
-  but in the hope that the incompatible change will be reverted GCC kept
-  implementing the previous behavior.  Now that for OpenMP 5.0 it has been
+  but in the hope that this incompatible change will be reverted GCC kept
+  the previous behavior.  Now that for OpenMP 5.0 it has been
   confirmed this is not going to change, GCC 9 started implementing the
-  OpenMP 4.0 and later behavior.  When not using default
+  OpenMP 4.0 and later behavior.  When not using a default
   clause or when using default(shared), this makes no
-  difference, but if using default(none), previously the
-  choice was not specify the const qualified variables
-  on the construct at all, or specify in firstprivate clause.
-  In GCC 9 as well as for OpenMP 4.0 compliance, those variables need
-  to be specified on constructs in which they are used, either in
-  shared or in firstprivate clause.  Specifying
-  them in firstprivate clause is one way to achieve
-  compatibility with both older GCC versions and GCC 9, another option
+  difference. When using default(none), previously the
+  choice was not to specify const qualified variables
+  on the construct at all, or specify them in the
+  firstprivate clause.
+  In GCC 9 as well as for OpenMP 4.0 compliance those variables need
+  to be specified on constructs in which they are used, either in a
+  shared or in a firstprivate clause.  Specifying
+  them in a firstprivate clause is one way to achieve
+  compatibility with both older GCC versions and GCC 9. Another option
   is to drop the default(none) clause.  In C++,
   const variables with constant initializers which are not
-  odr-used in the region, but replaced with their constant initializer
+  odr-used in the region, but replaced with their constant initializer,
   are not considered to be referenced in the region for
   default(none) purposes.
 
@@ -93,8 +94,8 @@ and provide solutions. Let us know if you have suggestions 
for improvements!
 for (int i = 0; i < a; i += b)
   ;
 // The above used to compile with GCC 8 and older, but will
-// not anymore with GCC 9.  firstprivate(a, b) clause needs
-// to be added for C, for C++ it could be just firstprivate(a)
+// not anymore with GCC 9. A firstprivate(a, b) clause needs
+// to be added for C; for C++ it could be just firstprivate(a)
 // to make it compatible with all GCC releases.
   }
   const int huge_array[1024] wwwdocs: = { ... };
@@ -104,7 +105,7 @@ and provide solutions. Let us know if you have suggestions 
for improvements!
   use (huge_array[i] wwwdocs:);
 // Similarly, this used to compile with GCC 8 and older and
 // will not anymore.  Adding firstprivate(huge_array) is
-// probably undesirable here, so, either
+// probably undesirable here, so either
 // default(none) shared(huge_array) should be used and it will
 // only support GCC 9 and later, or default(none) should be
 // removed and then it will be compatible with all GCC releases
-- 
2.42.0


[PATCH/committed] sim: add distclean dep for gnulib

2023-10-15 Thread Mike Frysinger
ChangeLog:

* Makefile.def: Add distclean-sim dependency on distclean-gnulib.
* Makefile.in: Regenerate.
---
 Makefile.def | 1 +
 Makefile.in  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/Makefile.def b/Makefile.def
index 870150183b9a..15c068e4ac40 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -612,6 +612,7 @@ dependencies = { module=check-libctf; on=all-ld; };
 // gdb and gdbserver.
 dependencies = { module=distclean-gnulib; on=distclean-gdb; };
 dependencies = { module=distclean-gnulib; on=distclean-gdbserver; };
+dependencies = { module=distclean-gnulib; on=distclean-sim; };
 
 // Warning, these are not well tested.
 dependencies = { module=all-bison; on=all-intl; };
diff --git a/Makefile.in b/Makefile.in
index e0e3c4c8fe80..1dda62a03032 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -66891,6 +66891,7 @@ check-stageautoprofile-libctf: 
maybe-all-stageautoprofile-ld
 check-stageautofeedback-libctf: maybe-all-stageautofeedback-ld
 distclean-gnulib: maybe-distclean-gdb
 distclean-gnulib: maybe-distclean-gdbserver
+distclean-gnulib: maybe-distclean-sim
 all-bison: maybe-all-build-texinfo
 all-flex: maybe-all-build-bison
 all-flex: maybe-all-m4
-- 
2.42.0



[PATCH] RISC-V/testsuite: add a default march (lacking zfa) to some fp tests

2023-10-15 Thread Vineet Gupta
A bunch of FP tests expecting specific FP asm output fail when built
with zfa because different insns are generated. And this happens
because those tests don't have an explicit -march and the default
used to configure gcc could end up with zfa causing the false fails.

Fix that by adding the -march explicitly which doesn't have zfa.

BTW it seems we have some duplication in tests for zfa and non-zfa and
it would have been better if they were consolidated, but oh well.

gcc/testsuite:
* gcc.target/riscv/fle-ieee.c: Updates dg-options with
explicit -march=rv64gc and -march=rv43gc.
* gcc.target/riscv/fle-snan.c: Ditto.
* gcc.target/riscv/fle.c: Ditto.
* gcc.target/riscv/flef-ieee.c: Ditto.
* gcc.target/riscv/flef.c: Ditto.
* gcc.target/riscv/flef-snan.c: Ditto.
* gcc.target/riscv/flt-ieee.c: Ditto.
* gcc.target/riscv/flt-snan.c: Ditto.
* gcc.target/riscv/fltf-ieee.c: Ditto.
* gcc.target/riscv/fltf-snan.c: Ditto.

Signed-off-by: Vineet Gupta 
---
 gcc/testsuite/gcc.target/riscv/fle-ieee.c  | 3 ++-
 gcc/testsuite/gcc.target/riscv/fle-snan.c  | 3 ++-
 gcc/testsuite/gcc.target/riscv/fle.c   | 3 ++-
 gcc/testsuite/gcc.target/riscv/flef-ieee.c | 3 ++-
 gcc/testsuite/gcc.target/riscv/flef-snan.c | 3 ++-
 gcc/testsuite/gcc.target/riscv/flef.c  | 3 ++-
 gcc/testsuite/gcc.target/riscv/flt-ieee.c  | 3 ++-
 gcc/testsuite/gcc.target/riscv/flt-snan.c  | 3 ++-
 gcc/testsuite/gcc.target/riscv/fltf-ieee.c | 3 ++-
 gcc/testsuite/gcc.target/riscv/fltf-snan.c | 3 ++-
 10 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/fle-ieee.c 
b/gcc/testsuite/gcc.target/riscv/fle-ieee.c
index e55331f925d6..12d04514ca29 100644
--- a/gcc/testsuite/gcc.target/riscv/fle-ieee.c
+++ b/gcc/testsuite/gcc.target/riscv/fle-ieee.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target hard_float } */
-/* { dg-options "-fno-finite-math-only -ftrapping-math -fno-signaling-nans" } 
*/
+/* { dg-options "-march=rv64gc -mabi=lp64d  -fno-finite-math-only 
-ftrapping-math -fno-signaling-nans" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -fno-finite-math-only 
-ftrapping-math -fno-signaling-nans" { target { rv32 } } } */
 
 long
 fle (double x, double y)
diff --git a/gcc/testsuite/gcc.target/riscv/fle-snan.c 
b/gcc/testsuite/gcc.target/riscv/fle-snan.c
index f40bb2cbf662..146b7866e888 100644
--- a/gcc/testsuite/gcc.target/riscv/fle-snan.c
+++ b/gcc/testsuite/gcc.target/riscv/fle-snan.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target hard_float } */
-/* { dg-options "-fno-finite-math-only -ftrapping-math -fsignaling-nans" } */
+/* { dg-options "-march=rv64gc -mabi=lp64d  -fno-finite-math-only 
-ftrapping-math -fsignaling-nans" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -fno-finite-math-only 
-ftrapping-math -fsignaling-nans" { target { rv32 } } } */
 
 long
 fle (double x, double y)
diff --git a/gcc/testsuite/gcc.target/riscv/fle.c 
b/gcc/testsuite/gcc.target/riscv/fle.c
index 97c8ab9ad864..2379e22d5062 100644
--- a/gcc/testsuite/gcc.target/riscv/fle.c
+++ b/gcc/testsuite/gcc.target/riscv/fle.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target hard_float } */
-/* { dg-options "-fno-finite-math-only -fno-trapping-math -fno-signaling-nans" 
} */
+/* { dg-options "-march=rv64gc -mabi=lp64d  -fno-finite-math-only 
-fno-trapping-math -fno-signaling-nans" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -fno-finite-math-only 
-fno-trapping-math -fno-signaling-nans" { target { rv32 } } } */
 
 long
 fle (double x, double y)
diff --git a/gcc/testsuite/gcc.target/riscv/flef-ieee.c 
b/gcc/testsuite/gcc.target/riscv/flef-ieee.c
index f3e7e7d75d6c..b6ee6ed08a4d 100644
--- a/gcc/testsuite/gcc.target/riscv/flef-ieee.c
+++ b/gcc/testsuite/gcc.target/riscv/flef-ieee.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target hard_float } */
-/* { dg-options "-fno-finite-math-only -ftrapping-math -fno-signaling-nans" } 
*/
+/* { dg-options "-march=rv64gc -mabi=lp64d  -fno-finite-math-only 
-ftrapping-math -fno-signaling-nans" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32f -fno-finite-math-only 
-ftrapping-math -fno-signaling-nans" { target { rv32 } } } */
 
 long
 flef (float x, float y)
diff --git a/gcc/testsuite/gcc.target/riscv/flef-snan.c 
b/gcc/testsuite/gcc.target/riscv/flef-snan.c
index ef75b3523057..e8611e8c0215 100644
--- a/gcc/testsuite/gcc.target/riscv/flef-snan.c
+++ b/gcc/testsuite/gcc.target/riscv/flef-snan.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target hard_float } */
-/* { dg-options "-fno-finite-math-only -ftrapping-math -fsignaling-nans" } */
+/* { dg-options "-march=rv64gc -mabi=lp64d  -fno-finite-math-only 
-ftrapping-math -fsignaling-nans" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32f 

Ping: [PATCH v2 0/2] Replace intl/ with out-of-tree GNU gettext

2023-10-15 Thread Arsen Arsenović
Evening,

Arsen Arsenović  writes:

> Afternoon,
>
> This patch is a rebase and rewording of
> https://inbox.sourceware.org/20230925150921.894157-1-ar...@aarsen.me/
>
> Changes since v1:
> - Implement Brunos suggested changes to install.texi.
> - Elaborate commit message in p2 (as requested by the Binutils
>   maintainers).
>
> Arsen Arsenović (2):
>   intl: remove, in favor of out-of-tree gettext
>   *: add modern gettext
>

Ping on this patch series.

TIA, have a lovely night :-)
-- 
Arsen Arsenović


signature.asc
Description: PGP signature


Re: [patch] libgomp.texi: Use present not future tense (was: [Patch] libgomp.texi: Clarify OMP_TARGET_OFFLOAD=mandatory)

2023-10-15 Thread Sandra Loosemore

On 10/15/23 04:39, Tobias Burnus wrote:


@@ -905,8 +905,8 @@ For @code{omp_sched_auto} the @var{chunk_size} argument is 
ignored.
 @subsection @code{omp_get_schedule} -- Obtain the runtime scheduling method
 @table @asis
 @item @emph{Description}:
-Obtain the runtime scheduling method.  The @var{kind} argument will be
-set to the value @code{omp_sched_static}, @code{omp_sched_dynamic},
+Obtain the runtime scheduling method.  The @var{kind} argument is set to
+to @code{omp_sched_static}, @code{omp_sched_dynamic},


You've introduced an extra "to" here.


@@ -3029,7 +3029,7 @@ 
OMP_ALLOCATOR=omp_low_lat_mem_space:pinned=true,partition=nearest
 Sets the format string used when displaying OpenMP thread affinity information.
 Special values are output using @code{%} followed by an optional size
 specification and then either the single-character field type or its long
-name enclosed in curly braces; using @code{%%} will display a literal percent.
+name enclosed in curly braces; using @code{%%} displays a literal percent.
 The size specification consists of an optional @code{0.} or @code{.} followed
 by a positive integer, specifying the minimal width of the output.  With
 @code{0.} and numerical values, the output is padded with zeros on the left;


I think all the @code markups here ought to be @samp, but let's not do that in 
this patch.



-If set to @code{DISABLED}, then offloading is disabled and all code will run on
-the host. If set to @code{DEFAULT}, the program will try offloading to the
+If set to @code{DISABLED}, then offloading is disabled and all code runs on
+the host. If set to @code{DEFAULT}, the program tries offloading to the
 device first, then fall back to running code on the host if it cannot.


Missed one here; s/[will] fall back/falls back/.


@@ -3559,7 +3559,7 @@ Binds threads to specific CPUs.  The variable should 
contain a space-separated
 or comma-separated list of CPUs.  This list may contain different kinds of 
 entries: either single CPU numbers in any order, a range of CPUs (M-N) 
 or a range with some stride (M-N:S).  CPU numbers are zero based.  For example,

-@code{GOMP_CPU_AFFINITY="0 3 1-2 4-15:2"} will bind the initial thread
+@code{GOMP_CPU_AFFINITY="0 3 1-2 4-15:2"} binds the initial thread
 to CPU 0, the second to CPU 3, the third to CPU 1, the fourth to 
 CPU 2, the fifth to CPU 4, the sixth through tenth to CPUs 6, 8, 10, 12,

 and 14 respectively and then start assigning back from the beginning of


Similarly, s/[will] start/starts/.


 @item @emph{C/C++}:
@@ -3983,8 +3983,8 @@ but might be removed in a future version of GCC.
 @table @asis
 @item @emph{Description}
 This function tests for completion of the asynchronous operation specified
-in @var{arg}. In C/C++, a non-zero value will be returned to indicate
-the specified asynchronous operation has completed. While Fortran will return
+in @var{arg}. In C/C++, a non-zero value is returned to indicate
+the specified asynchronous operation has completed. While Fortran returns
 a @code{true}. If the asynchronous operation has not completed, C/C++ returns
 a zero and Fortran returns a @code{false}.


H.  How about s/, While/while/ here.  And it sounds odd to me to say "a 
true" or a "a zero"; I'd suggest deleting the indefinite article from all those 
uses.



@@ -4012,8 +4012,8 @@ a zero and Fortran returns a @code{false}.
 @table @asis
 @item @emph{Description}
 This function tests for completion of all asynchronous operations.
-In C/C++, a non-zero value will be returned to indicate all asynchronous
-operations have completed. While Fortran will return a @code{true}. If
+In C/C++, a non-zero value is returned to indicate all asynchronous
+operations have completed. While Fortran returns a @code{true}. If
 any asynchronous operation has not completed, C/C++ returns a zero and
 Fortran returns a @code{false}.


Ditto here.

 
@@ -4196,9 +4196,9 @@ This function shuts down the runtime for the device type specified in

 This function returns whether the program is executing on a particular
 device specified in @var{devicetype}. In C/C++ a non-zero value is
 returned to indicate the device is executing on the specified device type.
-In Fortran, @code{true} will be returned. If the program is not executing
-on the specified device type C/C++ will return a zero, while Fortran will
-return @code{false}.
+In Fortran, @code{true} is returned. If the program is not executing
+on the specified device type C/C++ will return a zero, while Fortran


You missed a "will return" here, and same issues with "a zero".


@@ -5178,7 +5178,7 @@ subsequent to the calls to @code{acc_copyin()}.
 As seen in the previous use case, a call to @code{cublasCreate()}
 initializes the CUBLAS library and allocates the hardware resources on the
 host and the device.  However, since the device has already been allocated,
-@code{cublasCreate()} will only initialize the CUBLAS library and allocate
+@code{cublasCreate()} only initializes the CUBLAS li

Re: [patch] libgomp.texi: Improve "OpenACC Environment Variables"

2023-10-15 Thread Sandra Loosemore

On 10/15/23 04:40, Tobias Burnus wrote:

Hi Sandra,

thanks for the comments.

On 15.10.23 00:46, Sandra Loosemore wrote:

+Semicolon separated list of dynamic libraries to be loaded as
profiling library.


s/Semicolon separated/Semicolon-separated/

There's also a semantic issue with "list of dynamic libraries"
(plural) and "profiling library" (singular).  Are they all separately
profiling libraries, or does the entire list constitute a single
logical profiling library and its dependencies?


No, each library works as separate "profiling library", everything else
does not make much sense.

Updated patch attached - I hope it is now clearer.


Yup, this version is fine to commit.

-Sandra



Re: [PATCH v19 02/40] c-family, c++: Look up built-in traits through gperf

2023-10-15 Thread Patrick Palka
On Fri, 13 Oct 2023, Ken Matsui wrote:

> Since RID_MAX soon reaches 255 and all built-in traits are used approximately
> once in a C++ translation unit, this patch removes all RID values for built-in
> traits and uses gperf to look up the specific trait.  Rather than holding
> traits as keywords, we set all trait identifiers as cik_trait, which is a new
> cp_identifier_kind.  As cik_reserved_for_udlit was unused and
> cp_identifier_kind is 3 bits, we replaced the unused field with the new
> cik_trait.  Also, the later patch handles a subsequent token to the built-in
> identifier so that we accept the use of non-function-like built-in trait
> identifiers.

Awesome!  It's great we won't have to rename any existing identifiers in
libstdc++ with this approach.

I think this patch looks perfect, assuming we want to stick with the gperf
approach, but I just noticed that IDENTIFIER nodes have an IDENTIFIER_CP_INDEX
field which is currently only used for operator name identifiers to
optimize looking up operator information.  Could we reuse this field for
IDENTIFIER_TRAIT_P identifiers as well in order to store their
corresponding cp_trait_kind?  If so then I think we wouldn't need to use
gperf for the built-in traits at all, since the mapping from identifier
to cp_trait_kind would be implicit in each IDENTIFIER node, which would
perhaps be a nice simplification (and just as fast if not faster than gperf)?

> 
> gcc/c-family/ChangeLog:
> 
>   * c-common.cc (c_common_reswords): Remove all mappings of
>   built-in traits.
>   * c-common.h (enum rid): Remove all RID values for built-in traits.
> 
> gcc/cp/ChangeLog:
> 
>   * Make-lang.in: Add targets to generate cp-trait.gperf and
>   cp-trait.h.
>   * cp-objcp-common.cc (names_builtin_p): Remove all RID value
>   cases for built-in traits.  Check for built-in traits via
>   the new cik_trait identifier.
>   * cp-tree.h (cik_reserved_for_udlit): Rename to ...
>   (cik_trait): ... this.
>   (IDENTIFIER_ANY_OP_P): Exclude cik_trait.
>   (IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
>   * lex.cc (init_cp_traits): New function to set cik_trait for all
>   built-in trait identifiers.
>   (cxx_init): Call init_cp_traits function.
>   * parser.cc (cp_lexer_lookup_trait): New function to look up a
>   built-in trait from a token by gperf.
>   (cp_lexer_lookup_trait_expr): Likewise, look up an
>   expression-yielding built-in trait.
>   (cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
>   built-in trait.
>   (cp_keyword_starts_decl_specifier_p): Remove all RID value cases
>   for built-in traits.
>   (cp_lexer_next_token_is_decl_specifier_keyword): Handle
>   type-yielding built-in traits.
>   (cp_parser_primary_expression): Remove all RID value cases for
>   built-in traits.  Handle expression-yielding built-in traits.
>   (cp_parser_trait): Handle cp_trait instead of enum rid.
>   (cp_parser_simple_type_specifier): Remove all RID value cases
>   for built-in traits.  Handle type-yielding built-in traits.
>   * cp-trait-head.in: New file.
>   * cp-trait.gperf: New file.
>   * cp-trait.h: New file.
> 
> Co-authored-by: Patrick Palka 
> Signed-off-by: Ken Matsui 
> ---
>  gcc/c-family/c-common.cc  |   7 --
>  gcc/c-family/c-common.h   |   5 -
>  gcc/cp/Make-lang.in   |  26 
>  gcc/cp/cp-objcp-common.cc |   8 +-
>  gcc/cp/cp-trait-head.in   |  30 +
>  gcc/cp/cp-trait.gperf |  74 
>  gcc/cp/cp-trait.h | 247 ++
>  gcc/cp/cp-tree.h  |  14 ++-
>  gcc/cp/lex.cc |  19 +++
>  gcc/cp/parser.cc  | 132 
>  10 files changed, 492 insertions(+), 70 deletions(-)
>  create mode 100644 gcc/cp/cp-trait-head.in
>  create mode 100644 gcc/cp/cp-trait.gperf
>  create mode 100644 gcc/cp/cp-trait.h
> 
> diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> index f044db5b797..21fd333ef57 100644
> --- a/gcc/c-family/c-common.cc
> +++ b/gcc/c-family/c-common.cc
> @@ -508,13 +508,6 @@ const struct c_common_resword c_common_reswords[] =
>{ "wchar_t",   RID_WCHAR,  D_CXXONLY },
>{ "while", RID_WHILE,  0 },
>  
> -#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
> -  { NAME,RID_##CODE, D_CXXONLY },
> -#include "cp/cp-trait.def"
> -#undef DEFTRAIT
> -  /* An alias for __is_same.  */
> -  { "__is_same_as",  RID_IS_SAME,D_CXXONLY },
> -
>/* C++ transactional memory.  */
>{ "synchronized",  RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
>{ "atomic_noexcept",   RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
> index 1fdba7ef3ea..051a442e0f4 100644
> --- a/gcc/c-family/c-common.h
> +++ b/gcc/c-family/c-common.h
> @@ -168,11 +168,6 @@ enum rid
>RID_BUILTIN_LAUNDER,
>RID_BUILTIN_BIT_CAST,
>  
> -#def

Re: [PATCH v19 02/40] c-family, c++: Look up built-in traits through gperf

2023-10-15 Thread Ken Matsui
On Sun, Oct 15, 2023 at 1:43 PM Patrick Palka  wrote:
>
> On Fri, 13 Oct 2023, Ken Matsui wrote:
>
> > Since RID_MAX soon reaches 255 and all built-in traits are used 
> > approximately
> > once in a C++ translation unit, this patch removes all RID values for 
> > built-in
> > traits and uses gperf to look up the specific trait.  Rather than holding
> > traits as keywords, we set all trait identifiers as cik_trait, which is a 
> > new
> > cp_identifier_kind.  As cik_reserved_for_udlit was unused and
> > cp_identifier_kind is 3 bits, we replaced the unused field with the new
> > cik_trait.  Also, the later patch handles a subsequent token to the built-in
> > identifier so that we accept the use of non-function-like built-in trait
> > identifiers.
>
> Awesome!  It's great we won't have to rename any existing identifiers in
> libstdc++ with this approach.
>
> I think this patch looks perfect, assuming we want to stick with the gperf
> approach, but I just noticed that IDENTIFIER nodes have an IDENTIFIER_CP_INDEX
> field which is currently only used for operator name identifiers to
> optimize looking up operator information.  Could we reuse this field for
> IDENTIFIER_TRAIT_P identifiers as well in order to store their
> corresponding cp_trait_kind?  If so then I think we wouldn't need to use
> gperf for the built-in traits at all, since the mapping from identifier
> to cp_trait_kind would be implicit in each IDENTIFIER node, which would
> perhaps be a nice simplification (and just as fast if not faster than gperf)?
>

Thank you! I think this way decreases the size of the compiler even if
we do not see speed improvements. Since IDENTIFIER_CP_INDEX
(base.u.bits.address_space) is an unsigned char (addr_space_t), we can
have only up to 255 traits. Is this acceptable?

> >
> > gcc/c-family/ChangeLog:
> >
> >   * c-common.cc (c_common_reswords): Remove all mappings of
> >   built-in traits.
> >   * c-common.h (enum rid): Remove all RID values for built-in traits.
> >
> > gcc/cp/ChangeLog:
> >
> >   * Make-lang.in: Add targets to generate cp-trait.gperf and
> >   cp-trait.h.
> >   * cp-objcp-common.cc (names_builtin_p): Remove all RID value
> >   cases for built-in traits.  Check for built-in traits via
> >   the new cik_trait identifier.
> >   * cp-tree.h (cik_reserved_for_udlit): Rename to ...
> >   (cik_trait): ... this.
> >   (IDENTIFIER_ANY_OP_P): Exclude cik_trait.
> >   (IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
> >   * lex.cc (init_cp_traits): New function to set cik_trait for all
> >   built-in trait identifiers.
> >   (cxx_init): Call init_cp_traits function.
> >   * parser.cc (cp_lexer_lookup_trait): New function to look up a
> >   built-in trait from a token by gperf.
> >   (cp_lexer_lookup_trait_expr): Likewise, look up an
> >   expression-yielding built-in trait.
> >   (cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
> >   built-in trait.
> >   (cp_keyword_starts_decl_specifier_p): Remove all RID value cases
> >   for built-in traits.
> >   (cp_lexer_next_token_is_decl_specifier_keyword): Handle
> >   type-yielding built-in traits.
> >   (cp_parser_primary_expression): Remove all RID value cases for
> >   built-in traits.  Handle expression-yielding built-in traits.
> >   (cp_parser_trait): Handle cp_trait instead of enum rid.
> >   (cp_parser_simple_type_specifier): Remove all RID value cases
> >   for built-in traits.  Handle type-yielding built-in traits.
> >   * cp-trait-head.in: New file.
> >   * cp-trait.gperf: New file.
> >   * cp-trait.h: New file.
> >
> > Co-authored-by: Patrick Palka 
> > Signed-off-by: Ken Matsui 
> > ---
> >  gcc/c-family/c-common.cc  |   7 --
> >  gcc/c-family/c-common.h   |   5 -
> >  gcc/cp/Make-lang.in   |  26 
> >  gcc/cp/cp-objcp-common.cc |   8 +-
> >  gcc/cp/cp-trait-head.in   |  30 +
> >  gcc/cp/cp-trait.gperf |  74 
> >  gcc/cp/cp-trait.h | 247 ++
> >  gcc/cp/cp-tree.h  |  14 ++-
> >  gcc/cp/lex.cc |  19 +++
> >  gcc/cp/parser.cc  | 132 
> >  10 files changed, 492 insertions(+), 70 deletions(-)
> >  create mode 100644 gcc/cp/cp-trait-head.in
> >  create mode 100644 gcc/cp/cp-trait.gperf
> >  create mode 100644 gcc/cp/cp-trait.h
> >
> > diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> > index f044db5b797..21fd333ef57 100644
> > --- a/gcc/c-family/c-common.cc
> > +++ b/gcc/c-family/c-common.cc
> > @@ -508,13 +508,6 @@ const struct c_common_resword c_common_reswords[] =
> >{ "wchar_t",   RID_WCHAR,  D_CXXONLY },
> >{ "while", RID_WHILE,  0 },
> >
> > -#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
> > -  { NAME,RID_##CODE, D_CXXONLY },
> > -#include "cp/cp-trait.def"
> > -#undef DEFTRAIT
> > -  /* An alias for __is_same.  */
> > -

Re: [patch] libgomp.texi: Update "Enabling OpenMP" + OpenACC / invoke.texi: -fopenacc/-fopenmp update (was: Re: [patch] libgomp.texi: Update "Enabling OpenMP")

2023-10-15 Thread Sandra Loosemore

On 10/15/23 04:42, Tobias Burnus wrote:


Updated patch attached.


This version looks OK to me.

-Sandra


[pushed] wwwdocs: *: Remove unused buildstat pages

2023-10-15 Thread Gerald Pfeifer
[ Release managers, heads-up for when you branch future releases! ]

For GCC 9 to GCC 13 the per-release series buildstat pages have not
been populated at all, so remove them and reference from the respective
main release pages.

Pushed.
Gerald
---
 htdocs/gcc-10/buildstat.html | 27 ---
 htdocs/gcc-10/index.html |  3 ---
 htdocs/gcc-11/buildstat.html | 27 ---
 htdocs/gcc-11/index.html |  3 ---
 htdocs/gcc-12/buildstat.html | 27 ---
 htdocs/gcc-12/index.html |  3 ---
 htdocs/gcc-13/buildstat.html | 27 ---
 htdocs/gcc-13/index.html |  3 ---
 htdocs/gcc-9/buildstat.html  | 27 ---
 htdocs/gcc-9/index.html  |  3 ---
 10 files changed, 150 deletions(-)
 delete mode 100644 htdocs/gcc-10/buildstat.html
 delete mode 100644 htdocs/gcc-11/buildstat.html
 delete mode 100644 htdocs/gcc-12/buildstat.html
 delete mode 100644 htdocs/gcc-13/buildstat.html
 delete mode 100644 htdocs/gcc-9/buildstat.html

diff --git a/htdocs/gcc-10/buildstat.html b/htdocs/gcc-10/buildstat.html
deleted file mode 100644
index 5d18742e..
--- a/htdocs/gcc-10/buildstat.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-Build status for GCC 10
-https://gcc.gnu.org/gcc.css";>
-
-
-
-Build status for GCC 10
-
-This list summarizes build reports for GCC 10.x, with links to the
-archived mail messages that reported the builds and to test result
-summaries.
-
-Instructions for running the test suite and for submitting test results
-are part of
-http://gcc.gnu.org/install/test.html";>
-Installing GCC: Testing.
-Instructions for reporting a successful "make bootstrap",
-including a list of information to include in such a report, are part of
-http://gcc.gnu.org/install/finalinstall.html";>
-Installing GCC: Final Installation.
-
-
-
diff --git a/htdocs/gcc-10/index.html b/htdocs/gcc-10/index.html
index a9547d18..5fb1e02e 100644
--- a/htdocs/gcc-10/index.html
+++ b/htdocs/gcc-10/index.html
@@ -63,9 +63,6 @@ GCC 10.4 relative to previous releases of GCC.
 supports several other languages aside from C, it now stands for the
 GNU Compiler Collection.
 
-A list of successful builds is updated
-as new information becomes available.
-
 The GCC developers would like to thank the numerous people that have
 contributed new features, improvements, bug fixes, and other changes as
 well as test results to GCC.
diff --git a/htdocs/gcc-11/buildstat.html b/htdocs/gcc-11/buildstat.html
deleted file mode 100644
index c86238c6..
--- a/htdocs/gcc-11/buildstat.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-Build status for GCC 11
-https://gcc.gnu.org/gcc.css";>
-
-
-
-Build status for GCC 11
-
-This list summarizes build reports for GCC 11.x, with links to the
-archived mail messages that reported the builds and to test result
-summaries.
-
-Instructions for running the test suite and for submitting test results
-are part of
-http://gcc.gnu.org/install/test.html";>
-Installing GCC: Testing.
-Instructions for reporting a successful "make bootstrap",
-including a list of information to include in such a report, are part of
-http://gcc.gnu.org/install/finalinstall.html";>
-Installing GCC: Final Installation.
-
-
-
diff --git a/htdocs/gcc-11/index.html b/htdocs/gcc-11/index.html
index 7cd96f7e..bb41c492 100644
--- a/htdocs/gcc-11/index.html
+++ b/htdocs/gcc-11/index.html
@@ -54,9 +54,6 @@ GCC 11.3 relative to previous releases of GCC.
 supports several other languages aside from C, it now stands for the
 GNU Compiler Collection.
 
-A list of successful builds is updated
-as new information becomes available.
-
 The GCC developers would like to thank the numerous people that have
 contributed new features, improvements, bug fixes, and other changes as
 well as test results to GCC.
diff --git a/htdocs/gcc-12/buildstat.html b/htdocs/gcc-12/buildstat.html
deleted file mode 100644
index e066026f..
--- a/htdocs/gcc-12/buildstat.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-Build status for GCC 12
-https://gcc.gnu.org/gcc.css";>
-
-
-
-Build status for GCC 12
-
-This list summarizes build reports for GCC 12.x, with links to the
-archived mail messages that reported the builds and to test result
-summaries.
-
-Instructions for running the test suite and for submitting test results
-are part of
-http://gcc.gnu.org/install/test.html";>
-Installing GCC: Testing.
-Instructions for reporting a successful "make bootstrap",
-including a list of information to include in such a report, are part of
-http://gcc.gnu.org/install/finalinstall.html";>
-Installing GCC: Final Installation.
-
-
-
diff --git a/htdocs/gcc-12/index.html b/htdocs/gcc-12/index.html
index f8c589e8..a76ef1dc 100644
--- a/htdocs/gcc-12/index.html
+++ b/htdocs/gcc-12/index.html
@@ -48,9 +48,6 @@ GCC 12.2 relative to previous releases of GCC.
 supports several other languages aside from C, it now stands for the
 GNU Compiler Collection.
 
-A list of successful builds is up

[pushed] wwwdocs: buildstat: Don't reference buildstats we no longer carry

2023-10-15 Thread Gerald Pfeifer
Having just removed the buildstats pages for GCC 9 to GCC 13 also
drop references from this main buildstats overview.

Pushed.

Gerald
---
 htdocs/buildstat.html | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/htdocs/buildstat.html b/htdocs/buildstat.html
index cb27a979..08c9c2b7 100644
--- a/htdocs/buildstat.html
+++ b/htdocs/buildstat.html
@@ -10,14 +10,10 @@
 
 Build status for GCC
 
-These pages summarize build reports for GCC.
+These pages summarize build reports we gathered for older releases
+of GCC.
 
 
-GCC 13.x
-GCC 12.x
-GCC 11.x
-GCC 10.x
-GCC 9.x
 GCC 8.x
 GCC 7.x
 GCC 6.x
-- 
2.42.0


Re: [PATCH v19 02/40] c-family, c++: Look up built-in traits through gperf

2023-10-15 Thread Patrick Palka
On Sun, 15 Oct 2023, Ken Matsui wrote:

> On Sun, Oct 15, 2023 at 1:43 PM Patrick Palka  wrote:
> >
> > On Fri, 13 Oct 2023, Ken Matsui wrote:
> >
> > > Since RID_MAX soon reaches 255 and all built-in traits are used 
> > > approximately
> > > once in a C++ translation unit, this patch removes all RID values for 
> > > built-in
> > > traits and uses gperf to look up the specific trait.  Rather than holding
> > > traits as keywords, we set all trait identifiers as cik_trait, which is a 
> > > new
> > > cp_identifier_kind.  As cik_reserved_for_udlit was unused and
> > > cp_identifier_kind is 3 bits, we replaced the unused field with the new
> > > cik_trait.  Also, the later patch handles a subsequent token to the 
> > > built-in
> > > identifier so that we accept the use of non-function-like built-in trait
> > > identifiers.
> >
> > Awesome!  It's great we won't have to rename any existing identifiers in
> > libstdc++ with this approach.
> >
> > I think this patch looks perfect, assuming we want to stick with the gperf
> > approach, but I just noticed that IDENTIFIER nodes have an 
> > IDENTIFIER_CP_INDEX
> > field which is currently only used for operator name identifiers to
> > optimize looking up operator information.  Could we reuse this field for
> > IDENTIFIER_TRAIT_P identifiers as well in order to store their
> > corresponding cp_trait_kind?  If so then I think we wouldn't need to use
> > gperf for the built-in traits at all, since the mapping from identifier
> > to cp_trait_kind would be implicit in each IDENTIFIER node, which would
> > perhaps be a nice simplification (and just as fast if not faster than 
> > gperf)?
> >
> 
> Thank you! I think this way decreases the size of the compiler even if
> we do not see speed improvements. Since IDENTIFIER_CP_INDEX
> (base.u.bits.address_space) is an unsigned char (addr_space_t), we can
> have only up to 255 traits. Is this acceptable?

Good points.  Given there's so far around 150 standard library traits, a
limit of 255 should last us quite a while so IMHO it's acceptable :)

> 
> > >
> > > gcc/c-family/ChangeLog:
> > >
> > >   * c-common.cc (c_common_reswords): Remove all mappings of
> > >   built-in traits.
> > >   * c-common.h (enum rid): Remove all RID values for built-in traits.
> > >
> > > gcc/cp/ChangeLog:
> > >
> > >   * Make-lang.in: Add targets to generate cp-trait.gperf and
> > >   cp-trait.h.
> > >   * cp-objcp-common.cc (names_builtin_p): Remove all RID value
> > >   cases for built-in traits.  Check for built-in traits via
> > >   the new cik_trait identifier.
> > >   * cp-tree.h (cik_reserved_for_udlit): Rename to ...
> > >   (cik_trait): ... this.
> > >   (IDENTIFIER_ANY_OP_P): Exclude cik_trait.
> > >   (IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
> > >   * lex.cc (init_cp_traits): New function to set cik_trait for all
> > >   built-in trait identifiers.
> > >   (cxx_init): Call init_cp_traits function.
> > >   * parser.cc (cp_lexer_lookup_trait): New function to look up a
> > >   built-in trait from a token by gperf.
> > >   (cp_lexer_lookup_trait_expr): Likewise, look up an
> > >   expression-yielding built-in trait.
> > >   (cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
> > >   built-in trait.
> > >   (cp_keyword_starts_decl_specifier_p): Remove all RID value cases
> > >   for built-in traits.
> > >   (cp_lexer_next_token_is_decl_specifier_keyword): Handle
> > >   type-yielding built-in traits.
> > >   (cp_parser_primary_expression): Remove all RID value cases for
> > >   built-in traits.  Handle expression-yielding built-in traits.
> > >   (cp_parser_trait): Handle cp_trait instead of enum rid.
> > >   (cp_parser_simple_type_specifier): Remove all RID value cases
> > >   for built-in traits.  Handle type-yielding built-in traits.
> > >   * cp-trait-head.in: New file.
> > >   * cp-trait.gperf: New file.
> > >   * cp-trait.h: New file.
> > >
> > > Co-authored-by: Patrick Palka 
> > > Signed-off-by: Ken Matsui 
> > > ---
> > >  gcc/c-family/c-common.cc  |   7 --
> > >  gcc/c-family/c-common.h   |   5 -
> > >  gcc/cp/Make-lang.in   |  26 
> > >  gcc/cp/cp-objcp-common.cc |   8 +-
> > >  gcc/cp/cp-trait-head.in   |  30 +
> > >  gcc/cp/cp-trait.gperf |  74 
> > >  gcc/cp/cp-trait.h | 247 ++
> > >  gcc/cp/cp-tree.h  |  14 ++-
> > >  gcc/cp/lex.cc |  19 +++
> > >  gcc/cp/parser.cc  | 132 
> > >  10 files changed, 492 insertions(+), 70 deletions(-)
> > >  create mode 100644 gcc/cp/cp-trait-head.in
> > >  create mode 100644 gcc/cp/cp-trait.gperf
> > >  create mode 100644 gcc/cp/cp-trait.h
> > >
> > > diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> > > index f044db5b797..21fd333ef57 100644
> > > --- a/gcc/c-family/c-common.cc
> > > +++ b/gcc/c-family/c-com

Re: [PATCH v19 02/40] c-family, c++: Look up built-in traits through gperf

2023-10-15 Thread Ken Matsui
On Sun, Oct 15, 2023 at 2:50 PM Patrick Palka  wrote:
>
> On Sun, 15 Oct 2023, Ken Matsui wrote:
>
> > On Sun, Oct 15, 2023 at 1:43 PM Patrick Palka  wrote:
> > >
> > > On Fri, 13 Oct 2023, Ken Matsui wrote:
> > >
> > > > Since RID_MAX soon reaches 255 and all built-in traits are used 
> > > > approximately
> > > > once in a C++ translation unit, this patch removes all RID values for 
> > > > built-in
> > > > traits and uses gperf to look up the specific trait.  Rather than 
> > > > holding
> > > > traits as keywords, we set all trait identifiers as cik_trait, which is 
> > > > a new
> > > > cp_identifier_kind.  As cik_reserved_for_udlit was unused and
> > > > cp_identifier_kind is 3 bits, we replaced the unused field with the new
> > > > cik_trait.  Also, the later patch handles a subsequent token to the 
> > > > built-in
> > > > identifier so that we accept the use of non-function-like built-in trait
> > > > identifiers.
> > >
> > > Awesome!  It's great we won't have to rename any existing identifiers in
> > > libstdc++ with this approach.
> > >
> > > I think this patch looks perfect, assuming we want to stick with the gperf
> > > approach, but I just noticed that IDENTIFIER nodes have an 
> > > IDENTIFIER_CP_INDEX
> > > field which is currently only used for operator name identifiers to
> > > optimize looking up operator information.  Could we reuse this field for
> > > IDENTIFIER_TRAIT_P identifiers as well in order to store their
> > > corresponding cp_trait_kind?  If so then I think we wouldn't need to use
> > > gperf for the built-in traits at all, since the mapping from identifier
> > > to cp_trait_kind would be implicit in each IDENTIFIER node, which would
> > > perhaps be a nice simplification (and just as fast if not faster than 
> > > gperf)?
> > >
> >
> > Thank you! I think this way decreases the size of the compiler even if
> > we do not see speed improvements. Since IDENTIFIER_CP_INDEX
> > (base.u.bits.address_space) is an unsigned char (addr_space_t), we can
> > have only up to 255 traits. Is this acceptable?
>
> Good points.  Given there's so far around 150 standard library traits, a
> limit of 255 should last us quite a while so IMHO it's acceptable :)
>

Sounds great! I will update the patch in this way. Thank you!

> >
> > > >
> > > > gcc/c-family/ChangeLog:
> > > >
> > > >   * c-common.cc (c_common_reswords): Remove all mappings of
> > > >   built-in traits.
> > > >   * c-common.h (enum rid): Remove all RID values for built-in 
> > > > traits.
> > > >
> > > > gcc/cp/ChangeLog:
> > > >
> > > >   * Make-lang.in: Add targets to generate cp-trait.gperf and
> > > >   cp-trait.h.
> > > >   * cp-objcp-common.cc (names_builtin_p): Remove all RID value
> > > >   cases for built-in traits.  Check for built-in traits via
> > > >   the new cik_trait identifier.
> > > >   * cp-tree.h (cik_reserved_for_udlit): Rename to ...
> > > >   (cik_trait): ... this.
> > > >   (IDENTIFIER_ANY_OP_P): Exclude cik_trait.
> > > >   (IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
> > > >   * lex.cc (init_cp_traits): New function to set cik_trait for all
> > > >   built-in trait identifiers.
> > > >   (cxx_init): Call init_cp_traits function.
> > > >   * parser.cc (cp_lexer_lookup_trait): New function to look up a
> > > >   built-in trait from a token by gperf.
> > > >   (cp_lexer_lookup_trait_expr): Likewise, look up an
> > > >   expression-yielding built-in trait.
> > > >   (cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
> > > >   built-in trait.
> > > >   (cp_keyword_starts_decl_specifier_p): Remove all RID value cases
> > > >   for built-in traits.
> > > >   (cp_lexer_next_token_is_decl_specifier_keyword): Handle
> > > >   type-yielding built-in traits.
> > > >   (cp_parser_primary_expression): Remove all RID value cases for
> > > >   built-in traits.  Handle expression-yielding built-in traits.
> > > >   (cp_parser_trait): Handle cp_trait instead of enum rid.
> > > >   (cp_parser_simple_type_specifier): Remove all RID value cases
> > > >   for built-in traits.  Handle type-yielding built-in traits.
> > > >   * cp-trait-head.in: New file.
> > > >   * cp-trait.gperf: New file.
> > > >   * cp-trait.h: New file.
> > > >
> > > > Co-authored-by: Patrick Palka 
> > > > Signed-off-by: Ken Matsui 
> > > > ---
> > > >  gcc/c-family/c-common.cc  |   7 --
> > > >  gcc/c-family/c-common.h   |   5 -
> > > >  gcc/cp/Make-lang.in   |  26 
> > > >  gcc/cp/cp-objcp-common.cc |   8 +-
> > > >  gcc/cp/cp-trait-head.in   |  30 +
> > > >  gcc/cp/cp-trait.gperf |  74 
> > > >  gcc/cp/cp-trait.h | 247 ++
> > > >  gcc/cp/cp-tree.h  |  14 ++-
> > > >  gcc/cp/lex.cc |  19 +++
> > > >  gcc/cp/parser.cc  | 132 
> > > >  10 files changed, 492 insertions(+), 70 deletions(-)

[PATCH] MATCH: Improve `A CMP 0 ? A : -A` set of patterns to use bitwise_equal_p.

2023-10-15 Thread Andrew Pinski
This improves the `A CMP 0 ? A : -A` set of match patterns to use
bitwise_equal_p which allows an nop cast between signed and unsigned.
This allows catching a few extra cases which were not being caught before.

OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

gcc/ChangeLog:

PR tree-optimization/101541
* match.pd (A CMP 0 ? A : -A): Improve
using bitwise_equal_p.

gcc/testsuite/ChangeLog:

PR tree-optimization/101541
* gcc.dg/tree-ssa/phi-opt-36.c: New test.
* gcc.dg/tree-ssa/phi-opt-37.c: New test.
---
 gcc/match.pd   | 49 -
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-36.c | 51 ++
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c | 24 ++
 3 files changed, 104 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-36.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 45624f3dcb4..142e2dfbeb1 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5668,42 +5668,51 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  /* A == 0 ? A : -Asame as -A */
  (for cmp (eq uneq)
   (simplify
-   (cnd (cmp @0 zerop) @0 (negate@1 @0))
-(if (!HONOR_SIGNED_ZEROS (type))
+   (cnd (cmp @0 zerop) @2 (negate@1 @2))
+(if (!HONOR_SIGNED_ZEROS (type)
+&& bitwise_equal_p (@0, @2))
  @1))
   (simplify
-   (cnd (cmp @0 zerop) zerop (negate@1 @0))
-(if (!HONOR_SIGNED_ZEROS (type))
+   (cnd (cmp @0 zerop) zerop (negate@1 @2))
+(if (!HONOR_SIGNED_ZEROS (type)
+&& bitwise_equal_p (@0, @2))
  @1))
  )
  /* A != 0 ? A : -Asame as A */
  (for cmp (ne ltgt)
   (simplify
-   (cnd (cmp @0 zerop) @0 (negate @0))
-(if (!HONOR_SIGNED_ZEROS (type))
- @0))
+   (cnd (cmp @0 zerop) @1 (negate @1))
+(if (!HONOR_SIGNED_ZEROS (type)
+&& bitwise_equal_p (@0, @1))
+ @1))
   (simplify
-   (cnd (cmp @0 zerop) @0 integer_zerop)
-(if (!HONOR_SIGNED_ZEROS (type))
- @0))
+   (cnd (cmp @0 zerop) @1 integer_zerop)
+(if (!HONOR_SIGNED_ZEROS (type)
+&& bitwise_equal_p (@0, @1))
+ @1))
  )
  /* A >=/> 0 ? A : -Asame as abs (A) */
  (for cmp (ge gt)
   (simplify
-   (cnd (cmp @0 zerop) @0 (negate @0))
-(if (!HONOR_SIGNED_ZEROS (type)
-&& !TYPE_UNSIGNED (type))
- (abs @0
+   (cnd (cmp @0 zerop) @1 (negate @1))
+(if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
+&& !TYPE_UNSIGNED (TREE_TYPE(@0))
+&& bitwise_equal_p (@0, @1))
+ (if (TYPE_UNSIGNED (type))
+  (absu:type @0)
+  (abs @0)
  /* A <=/< 0 ? A : -Asame as -abs (A) */
  (for cmp (le lt)
   (simplify
-   (cnd (cmp @0 zerop) @0 (negate @0))
-(if (!HONOR_SIGNED_ZEROS (type)
-&& !TYPE_UNSIGNED (type))
- (if (ANY_INTEGRAL_TYPE_P (type)
- && !TYPE_OVERFLOW_WRAPS (type))
+   (cnd (cmp @0 zerop) @1 (negate @1))
+(if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
+&& !TYPE_UNSIGNED (TREE_TYPE(@0))
+&& bitwise_equal_p (@0, @1))
+ (if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+  && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+ || TYPE_UNSIGNED (type))
   (with {
-   tree utype = unsigned_type_for (type);
+   tree utype = unsigned_type_for (TREE_TYPE(@0));
}
(convert (negate (absu:utype @0
(negate (abs @0)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-36.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-36.c
new file mode 100644
index 000..4baf9f82a22
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-36.c
@@ -0,0 +1,51 @@
+/* { dg-options "-O2 -fdump-tree-phiopt" } */
+
+unsigned f0(int A)
+{
+  unsigned t = A;
+// A == 0? A : -Asame as -A
+  if (A == 0)  return t;
+  return -t;
+}
+
+unsigned f1(int A)
+{
+  unsigned t = A;
+// A != 0? A : -Asame as A
+  if (A != 0)  return t;
+  return -t;
+}
+unsigned f2(int A)
+{
+  unsigned t = A;
+// A >= 0? A : -Asame as abs (A)
+  if (A >= 0)  return t;
+  return -t;
+}
+unsigned f3(int A)
+{
+  unsigned t = A;
+// A > 0?  A : -Asame as abs (A)
+  if (A > 0)  return t;
+  return -t;
+}
+unsigned f4(int A)
+{
+  unsigned t = A;
+// A <= 0? A : -Asame as -abs (A)
+  if (A <= 0)  return t;
+  return -t;
+}
+unsigned f5(int A)
+{
+  unsigned t = A;
+// A < 0?  A : -Asame as -abs (A)
+  if (A < 0)  return t;
+  return -t;
+}
+
+/* f4 and f5 are not allowed to be optimized in early phi-opt. */
+/* { dg-final { scan-tree-dump-times "if " 2 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "if " "phiopt2" } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c
new file mode 100644
index 000..f1ff472aaff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-37.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-phiopt1" } */
+
+unsigned abs_with_convert0 (int x)
+{
+unsigned int y = x

[PATCH] Improve factor_out_conditional_operation for conversions and constants

2023-10-15 Thread Andrew Pinski
In the case of a NOP conversion (precisions of the 2 types are equal),
factoring out the conversion can be done even if int_fits_type_p returns
false and even when the conversion is defined by a statement inside the
conditional. Since it is a NOP conversion there is no zero/sign extending
happening which is why it is ok to be done here.

OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

gcc/ChangeLog:

PR tree-optimization/104376
PR tree-optimization/101541
* tree-ssa-phiopt.cc (factor_out_conditional_operation):
Allow nop conversions even if it is defined by a statement
inside the conditional.

gcc/testsuite/ChangeLog:

PR tree-optimization/101541
* gcc.dg/tree-ssa/phi-opt-38.c: New test.
---
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c | 44 ++
 gcc/tree-ssa-phiopt.cc |  8 +++-
 2 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c
new file mode 100644
index 000..ca04d1619e6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-38.c
@@ -0,0 +1,44 @@
+/* { dg-options "-O2 -fdump-tree-phiopt" } */
+
+unsigned f0(int A)
+{
+// A == 0? A : -Asame as -A
+  if (A == 0)  return A;
+  return -A;
+}
+
+unsigned f1(int A)
+{
+// A != 0? A : -Asame as A
+  if (A != 0)  return A;
+  return -A;
+}
+unsigned f2(int A)
+{
+// A >= 0? A : -Asame as abs (A)
+  if (A >= 0)  return A;
+  return -A;
+}
+unsigned f3(int A)
+{
+// A > 0?  A : -Asame as abs (A)
+  if (A > 0)  return A;
+  return -A;
+}
+unsigned f4(int A)
+{
+// A <= 0? A : -Asame as -abs (A)
+  if (A <= 0)  return A;
+  return -A;
+}
+unsigned f5(int A)
+{
+// A < 0?  A : -Asame as -abs (A)
+  if (A < 0)  return A;
+  return -A;
+}
+
+/* f4 and f5 are not allowed to be optimized in early phi-opt. */
+/* { dg-final { scan-tree-dump-times "if" 2 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */
+
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 312a6f9082b..0ab8fad5898 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -310,7 +310,9 @@ factor_out_conditional_operation (edge e0, edge e1, gphi 
*phi,
return NULL;
   /* If arg1 is an INTEGER_CST, fold it to new type.  */
   if (INTEGRAL_TYPE_P (TREE_TYPE (new_arg0))
- && int_fits_type_p (arg1, TREE_TYPE (new_arg0)))
+ && (int_fits_type_p (arg1, TREE_TYPE (new_arg0))
+ || TYPE_PRECISION (TREE_TYPE (new_arg0))
+ == TYPE_PRECISION (TREE_TYPE (arg1
{
  if (gimple_assign_cast_p (arg0_def_stmt))
{
@@ -323,7 +325,9 @@ factor_out_conditional_operation (edge e0, edge e1, gphi 
*phi,
 its basic block, because then it is possible this
 could enable further optimizations (minmax replacement
 etc.).  See PR71016.  */
- if (new_arg0 != gimple_cond_lhs (cond_stmt)
+ if (TYPE_PRECISION (TREE_TYPE (new_arg0))
+   != TYPE_PRECISION (TREE_TYPE (arg1))
+ && new_arg0 != gimple_cond_lhs (cond_stmt)
  && new_arg0 != gimple_cond_rhs (cond_stmt)
  && gimple_bb (arg0_def_stmt) == e0->src)
{
-- 
2.34.1



[PATCH v20 00/40] Optimize type traits performance

2023-10-15 Thread Ken Matsui
This patch series optimizes type traits performance by implementing
built-in type traits and using them in libstdc++.

Changes in v20:

* Used identifier node instead of gperf to look up built-in
traits.

Changes in v19:

* Fixed a typo.
* Rebased on top of trunk.
* Improved clarity of the commit message.

Changes in v18:

* Removed all RID values for built-in traits and used cik_trait
instead.
* Improved to handle the use of non-function-like built-in trait
identifiers.
* Reverted all changes to conflicted identifiers with new built-ins
in the existing code base.

Changes in v17:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in.
* Made ridpointers for RID_TRAIT_EXPR and RID_TRAIT_TYPE empty.

Changes in v16:

* Rebased on top of trunk.
* Improved clarity of the commit message.
* Simplified Make-lang.in and gperf struct.
* Supply -k option to gperf to support older versions than 2.8.

Changes in v15:

* Rebased on top of trunk.
* Use gperf to look up traits instead of enum rid.

Changes in v14:

* Added padding calculation to the commit message.

Changes in v13:

* Fixed ambiguous commit message and comment.

Changes in v12:

* Evaluated all paddings affected by the enum rid change.

Changes in v11:

* Merged all patches into one patch series.
* Rebased on top of trunk.
* Unified commit message style.
* Used _GLIBCXX_USE_BUILTIN_TRAIT.

Ken Matsui (40):
  c++: Sort built-in traits alphabetically
  c-family, c++: Look up built-in traits via identifier node
  c++: Accept the use of built-in trait identifiers
  c++: Implement __is_const built-in trait
  libstdc++: Optimize is_const trait performance
  c++: Implement __is_volatile built-in trait
  libstdc++: Optimize is_volatile trait performance
  c++: Implement __is_array built-in trait
  libstdc++: Optimize is_array trait performance
  c++: Implement __is_unbounded_array built-in trait
  libstdc++: Optimize is_unbounded_array trait performance
  c++: Implement __is_bounded_array built-in trait
  libstdc++: Optimize is_bounded_array trait performance
  c++: Implement __is_scoped_enum built-in trait
  libstdc++: Optimize is_scoped_enum trait performance
  c++: Implement __is_member_pointer built-in trait
  libstdc++: Optimize is_member_pointer trait performance
  c++: Implement __is_member_function_pointer built-in trait
  libstdc++: Optimize is_member_function_pointer trait performance
  c++: Implement __is_member_object_pointer built-in trait
  libstdc++: Optimize is_member_object_pointer trait performance
  c++: Implement __is_reference built-in trait
  libstdc++: Optimize is_reference trait performance
  c++: Implement __is_function built-in trait
  libstdc++: Optimize is_function trait performance
  libstdc++: Optimize is_object trait performance
  c++: Implement __remove_pointer built-in trait
  libstdc++: Optimize remove_pointer trait performance
  c++: Implement __is_pointer built-in trait
  libstdc++: Optimize is_pointer trait performance
  c++: Implement __is_arithmetic built-in trait
  libstdc++: Optimize is_arithmetic trait performance
  libstdc++: Optimize is_fundamental trait performance
  libstdc++: Optimize is_compound trait performance
  c++: Implement __is_unsigned built-in trait
  libstdc++: Optimize is_unsigned trait performance
  c++: Implement __is_signed built-in trait
  libstdc++: Optimize is_signed trait performance
  c++: Implement __is_scalar built-in trait
  libstdc++: Optimize is_scalar trait performance

 gcc/c-family/c-common.cc  |   7 -
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/constraint.cc  | 112 +--
 gcc/cp/cp-objcp-common.cc |   8 +-
 gcc/cp/cp-trait.def   |  27 +-
 gcc/cp/cp-tree.h  |  31 +-
 gcc/cp/lex.cc |  21 ++
 gcc/cp/parser.cc  | 153 +++---
 gcc/cp/semantics.cc   | 157 +++---
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  | 117 ++--
 gcc/testsuite/g++.dg/ext/is_arithmetic.C  |  33 ++
 gcc/testsuite/g++.dg/ext/is_array.C   |  28 ++
 gcc/testsuite/g++.dg/ext/is_bounded_array.C   |  38 +++
 gcc/testsuite/g++.dg/ext/is_const.C   |  19 ++
 gcc/testsuite/g++.dg/ext/is_function.C|  58 
 .../g++.dg/ext/is_member_function_pointer.C   |  31 ++
 .../g++.dg/ext/is_member_object_pointer.C |  30 ++
 gcc/testsuite/g++.dg/ext/is_member_pointer.C  |  30 ++
 gcc/testsuite/g++.dg/ext/is_pointer.C |  51 
 gcc/testsuite/g++.dg/ext/is_reference.C   |  34 +++
 gcc/testsuite/g++.dg/ext/is_scalar.C  |  31 ++
 gcc/testsuite/g++.dg/ext/is_scoped_enum.C |  67 +
 gcc/testsuite/g++

[PATCH v20 01/40] c++: Sort built-in traits alphabetically

2023-10-15 Thread Ken Matsui
This patch sorts built-in traits alphabetically for better code
readability.

gcc/cp/ChangeLog:

* constraint.cc (diagnose_trait_expr): Sort built-in traits
alphabetically.
* cp-trait.def: Likewise.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
(finish_trait_type): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc | 68 -
 gcc/cp/cp-trait.def  | 10 +--
 gcc/cp/semantics.cc  | 94 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +-
 4 files changed, 121 insertions(+), 121 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9e4e7043cd..722fc334e6f 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
   inform (loc, "  %qT is not trivially destructible", t1);
   break;
+case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
+  inform (loc, "  %qT does not have unique object representations", t1);
+  break;
 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
   inform (loc, "  %qT does not have a virtual destructor", t1);
   break;
 case CPTK_IS_ABSTRACT:
   inform (loc, "  %qT is not an abstract class", t1);
   break;
+case CPTK_IS_AGGREGATE:
+  inform (loc, "  %qT is not an aggregate", t1);
+  break;
+case CPTK_IS_ASSIGNABLE:
+  inform (loc, "  %qT is not assignable from %qT", t1, t2);
+  break;
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
+case CPTK_IS_CONSTRUCTIBLE:
+  if (!t2)
+inform (loc, "  %qT is not default constructible", t1);
+  else
+inform (loc, "  %qT is not constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_CONVERTIBLE:
+  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_EMPTY:
   inform (loc, "  %qT is not an empty class", t1);
   break;
@@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_NOTHROW_ASSIGNABLE:
+  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+  if (!t2)
+   inform (loc, "  %qT is not nothrow default constructible", t1);
+  else
+   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
+  break;
+case CPTK_IS_NOTHROW_CONVERTIBLE:
+ inform (loc, "  %qT is not nothrow convertible from %qE", t2, t1);
+  break;
 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
   inform (loc, "  %qT is not pointer-interconvertible base of %qT",
  t1, t2);
@@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIAL:
   inform (loc, "  %qT is not a trivial type", t1);
   break;
-case CPTK_IS_UNION:
-  inform (loc, "  %qT is not a union", t1);
-  break;
-case CPTK_IS_AGGREGATE:
-  inform (loc, "  %qT is not an aggregate", t1);
-  break;
-case CPTK_IS_TRIVIALLY_COPYABLE:
-  inform (loc, "  %qT is not trivially copyable", t1);
-  break;
-case CPTK_IS_ASSIGNABLE:
-  inform (loc, "  %qT is not assignable from %qT", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
   inform (loc, "  %qT is not trivially assignable from %qT", t1, t2);
   break;
-case CPTK_IS_NOTHROW_ASSIGNABLE:
-  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
-  break;
-case CPTK_IS_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not default constructible", t1);
-  else
-   inform (loc, "  %qT is not constructible from %qE", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
   if (!t2)
inform (loc, "  %qT is not trivially default constructible", t1);
   else
inform (loc, "  %qT is not trivially constructible from %qE", t1, t2);
   break;
-case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not nothrow default constructible", t1);
-  else
-   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
-  break;
-case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
-  inform (loc, "  %qT does not have unique object representations", t1);
-  break;
-case CPTK_IS_CONVERTIBLE:
-  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+case CPTK_IS_TRIVIALLY_COPYABLE:
+  inform (loc, "  %qT is not trivially copyable", t1);
   break;
-case CPTK_IS_NOTHROW_CONVERTIBLE:
-   infor

[PATCH v20 36/40] libstdc++: Optimize is_unsigned trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_unsigned trait by dispatching
to the new __is_unsigned built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unsigned): Use __is_unsigned built-in
trait.
(is_unsigned_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 48d630a1478..f7d3815f332 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1001,10 +1001,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_unsigned
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
+  template
+struct is_unsigned
+: public __bool_constant<__is_unsigned(_Tp)>
+{ };
+#else
   template
 struct is_unsigned
 : public __and_, __not_>>::type
 { };
+#endif
 
   /// @cond undocumented
   template
@@ -3440,8 +3447,14 @@ template 
 
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
+template 
+  inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
+#else
 template 
   inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
+#endif
 
 template 
   inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
-- 
2.42.0



[PATCH v20 02/40] c-family, c++: Look up built-in traits via identifier node

2023-10-15 Thread Ken Matsui
Since RID_MAX soon reaches 255 and all built-in traits are used approximately
once in a C++ translation unit, this patch removes all RID values for built-in
traits and uses the identifier node to look up the specific trait.  Rather
than holding traits as keywords, we set all trait identifiers as cik_trait,
which is a new cp_identifier_kind.  As cik_reserved_for_udlit was unused and
cp_identifier_kind is 3 bits, we replaced the unused field with the new
cik_trait.  Also, the later patch handles a subsequent token to the built-in
identifier so that we accept the use of non-function-like built-in trait
identifiers.

gcc/c-family/ChangeLog:

* c-common.cc (c_common_reswords): Remove all mappings of
built-in traits.
* c-common.h (enum rid): Remove all RID values for built-in traits.

gcc/cp/ChangeLog:

* cp-objcp-common.cc (names_builtin_p): Remove all RID value
cases for built-in traits.  Check for built-in traits via
the new cik_trait kind.
* cp-tree.h (enum cp_trait_kind): Set its underlying type to
addr_space_t.
(struct cp_trait): New struct to hold trait information.
(cp_traits): New array to hold a mapping to all traits.
(cik_reserved_for_udlit): Rename to ...
(cik_trait): ... this.
(IDENTIFIER_ANY_OP_P): Exclude cik_trait.
(IDENTIFIER_TRAIT_P): New macro to detect cik_trait.
* lex.cc (init_cp_traits): New function to set cik_trait for all
built-in trait identifiers.
(cxx_init): Call init_cp_traits function.
* parser.cc (cp_traits): Define its values, declared in cp-tree.h.
(cp_lexer_lookup_trait): New function to look up a
built-in trait by IDENTIFIER_CP_INDEX.
(cp_lexer_lookup_trait_expr): Likewise, look up an
expression-yielding built-in trait.
(cp_lexer_lookup_trait_type): Likewise, look up a type-yielding
built-in trait.
(cp_keyword_starts_decl_specifier_p): Remove all RID value cases
for built-in traits.
(cp_lexer_next_token_is_decl_specifier_keyword): Handle
type-yielding built-in traits.
(cp_parser_primary_expression): Remove all RID value cases for
built-in traits.  Handle expression-yielding built-in traits.
(cp_parser_trait): Handle cp_trait instead of enum rid.
(cp_parser_simple_type_specifier): Remove all RID value cases
for built-in traits.  Handle type-yielding built-in traits.

Co-authored-by: Patrick Palka 
Signed-off-by: Ken Matsui 
---
 gcc/c-family/c-common.cc  |   7 --
 gcc/c-family/c-common.h   |   5 --
 gcc/cp/cp-objcp-common.cc |   8 +--
 gcc/cp/cp-tree.h  |  31 ++---
 gcc/cp/lex.cc |  21 ++
 gcc/cp/parser.cc  | 141 --
 6 files changed, 139 insertions(+), 74 deletions(-)

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index f044db5b797..21fd333ef57 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -508,13 +508,6 @@ const struct c_common_resword c_common_reswords[] =
   { "wchar_t", RID_WCHAR,  D_CXXONLY },
   { "while",   RID_WHILE,  0 },
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  { NAME,  RID_##CODE, D_CXXONLY },
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-  /* An alias for __is_same.  */
-  { "__is_same_as",RID_IS_SAME,D_CXXONLY },
-
   /* C++ transactional memory.  */
   { "synchronized",RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
   { "atomic_noexcept", RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1fdba7ef3ea..051a442e0f4 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -168,11 +168,6 @@ enum rid
   RID_BUILTIN_LAUNDER,
   RID_BUILTIN_BIT_CAST,
 
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-  RID_##CODE,
-#include "cp/cp-trait.def"
-#undef DEFTRAIT
-
   /* C++11 */
   RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
 
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index 93b027b80ce..b1adacfec07 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -421,6 +421,10 @@ names_builtin_p (const char *name)
}
 }
 
+  /* Check for built-in traits.  */
+  if (IDENTIFIER_TRAIT_P (id))
+return true;
+
   /* Also detect common reserved C++ words that aren't strictly built-in
  functions.  */
   switch (C_RID_CODE (id))
@@ -434,10 +438,6 @@ names_builtin_p (const char *name)
 case RID_BUILTIN_ASSOC_BARRIER:
 case RID_BUILTIN_BIT_CAST:
 case RID_OFFSETOF:
-#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
-case RID_##CODE:
-#include "cp-trait.def"
-#undef DEFTRAIT
   return true;
 default:
   break;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6e34952da99..583abb2e79a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1226,7 +1226,7 @@ enum cp_identifie

[PATCH v20 18/40] c++: Implement __is_member_function_pointer built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_member_function_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_function_pointer.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_FUNCTION_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of
__is_member_function_pointer.
* g++.dg/ext/is_member_function_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |  3 ++
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/semantics.cc   |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 .../g++.dg/ext/is_member_function_pointer.C   | 31 +++
 5 files changed, 42 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_function_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f0d3f89464c..d0464dd4f6a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_FUNCTION_POINTER:
+  inform (loc, "  %qT is not a member function pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 26087da3bdf..897b96630f2 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
+DEFTRAIT_EXPR (IS_MEMBER_FUNCTION_POINTER, "__is_member_function_pointer", 1)
 DEFTRAIT_EXPR (IS_MEMBER_POINTER, "__is_member_pointer", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
 DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 6c4880d8a33..4d521f87bbb 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12184,6 +12184,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_LITERAL_TYPE:
   return literal_type_p (type1);
 
+case CPTK_IS_MEMBER_FUNCTION_POINTER:
+  return TYPE_PTRMEMFUNC_P (type1);
+
 case CPTK_IS_MEMBER_POINTER:
   return TYPE_PTRMEM_P (type1);
 
@@ -12396,6 +12399,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_CLASS:
 case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
+case CPTK_IS_MEMBER_FUNCTION_POINTER:
 case CPTK_IS_MEMBER_POINTER:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 994873f14e9..0dfe957474b 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -95,6 +95,9 @@
 #if !__has_builtin (__is_literal_type)
 # error "__has_builtin (__is_literal_type) failed"
 #endif
+#if !__has_builtin (__is_member_function_pointer)
+# error "__has_builtin (__is_member_function_pointer) failed"
+#endif
 #if !__has_builtin (__is_member_pointer)
 # error "__has_builtin (__is_member_pointer) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_member_function_pointer.C 
b/gcc/testsuite/g++.dg/ext/is_member_function_pointer.C
new file mode 100644
index 000..555123e8f07
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_member_function_pointer.C
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_FN(TRAIT, TYPE, EXPECT)\
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT);
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+// Positive tests.
+SA_TEST_FN(__is_member_function_pointer, int (ClassType::*) (int), true);
+SA_TEST_FN(__is_member_function_pointer, int (ClassType::*) (int) const, true);
+SA_TEST_FN(__is_member_function_pointer, int (ClassType::*) (float, ...), 
true);
+SA_TEST_FN(__is_member_function_pointer, ClassType (ClassType::*) (ClassType), 
true);
+SA_TEST_FN(__is_member_function_pointer, float (ClassType::*) (int, float, 
int[], int&), true);
+
+// Negative tests.
+SA_TEST_CATEGORY(__is_member_function_pointer, int (ClassType::*), false);
+SA_TEST_CATEGORY(__is_member_function_pointer, ClassType (ClassType::*), 
false);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_member_fu

[PATCH v20 03/40] c++: Accept the use of built-in trait identifiers

2023-10-15 Thread Ken Matsui
This patch accepts the use of built-in trait identifiers when they are
actually not used as traits.  Specifically, we check if the subsequent token
is '(' for ordinary built-in traits or is '<' only for the special
__type_pack_element built-in trait.  If those identifiers are used
differently, the parser treats them as normal identifiers.  This allows
us to accept code like: struct __is_pointer {};.

gcc/cp/ChangeLog:

* parser.cc (cp_lexer_lookup_trait): Rename to ...
(cp_lexer_peek_trait): ... this.  Handle a subsequent token for
the corresponding built-in trait.
(cp_lexer_lookup_trait_expr): Rename to ...
(cp_lexer_peek_trait_expr): ... this.
(cp_lexer_lookup_trait_type): Rename to ...
(cp_lexer_peek_trait_type): ... this.
(cp_lexer_next_token_is_decl_specifier_keyword): Call
cp_lexer_peek_trait_type.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_primary_expression): Call cp_lexer_peek_trait_expr.

Signed-off-by: Ken Matsui 
---
 gcc/cp/parser.cc | 48 ++--
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index eba5272be03..0f2a1baee6a 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -246,12 +246,12 @@ static void cp_lexer_start_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
 static void cp_lexer_stop_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
-static const cp_trait *cp_lexer_lookup_trait
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_expr
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_type
-  (const cp_token *);
+static const cp_trait *cp_lexer_peek_trait
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_expr
+  (cp_lexer *lexer, const cp_token *);
+static const cp_trait *cp_lexer_peek_trait_type
+  (cp_lexer *lexer, const cp_token *);
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
@@ -1195,19 +1195,31 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
 }
 }
 
-/* Look ups the corresponding built-in trait if a given token is
+/* Peeks the corresponding built-in trait if a given token is
a built-in trait.  Otherwise, returns nullptr.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait (const cp_token *token)
+cp_lexer_peek_trait (cp_lexer *lexer, const cp_token *token1)
 {
-  tree id = token->u.value;
+  tree id = token1->u.value;
 
-  if (token->type == CPP_NAME
+  if (token1->type == CPP_NAME
   && TREE_CODE (id) == IDENTIFIER_NODE
   && IDENTIFIER_TRAIT_P (id))
-return &cp_traits[IDENTIFIER_CP_INDEX (id)];
+{
+  const cp_trait &trait = cp_traits[IDENTIFIER_CP_INDEX (id)];
+  const bool is_pack_element = (trait.kind == CPTK_TYPE_PACK_ELEMENT);
 
+  /* Check if the subsequent token is a `<' token to
+ __type_pack_element or is a `(' token to everything else.  */
+  const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
+  if (is_pack_element && token2->type != CPP_LESS)
+   return nullptr;
+  if (!is_pack_element && token2->type != CPP_OPEN_PAREN)
+   return nullptr;
+
+  return &trait;
+}
   return nullptr;
 }
 
@@ -1215,9 +1227,9 @@ cp_lexer_lookup_trait (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_expr (const cp_token *token)
+cp_lexer_peek_trait_expr (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && !trait->type)
 return trait;
 
@@ -1228,9 +1240,9 @@ cp_lexer_lookup_trait_expr (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_type (const cp_token *token)
+cp_lexer_peek_trait_type (cp_lexer *lexer, const cp_token *token1)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer, token1);
   if (trait && trait->type)
 return trait;
 
@@ -1245,7 +1257,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer 
*lexer)
   cp_token *token;
 
   token = cp_lexer_peek_token (lexer);
-  if (cp_lexer_lookup_trait_type (token))
+  if (cp_lexer_peek_trait_type (lexer, token))
 return true;
   return cp_keyword_starts_decl_specifier_p (token->keyword);
 }
@@ -6117,7 +6129,7 @@ cp_parser_primary_expression (cp_parser *parser,
 keyword.  */
 case CPP_NAME:
   {
-   const cp_trait* trait = cp_lexer_lookup_trait_expr (token);
+   const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer, token);
if (trait)
  return cp_parser_trait (parser, trait);
   }
@@ -20126,7 +20138,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 }
 
   /* If token is a type-yielding built-in traits, parse it.  */
-  const cp_trait* trait = cp_lexer_lookup_trait_type (token);
+  const cp_trait* tr

[PATCH v20 15/40] libstdc++: Optimize is_scoped_enum trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_scoped_enum trait
by dispatching to the new __is_scoped_enum built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_scoped_enum): Use
__is_scoped_enum built-in trait.
(is_scoped_enum_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 12 
 1 file changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index d306073a797..7fd29d8d9f2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3633,6 +3633,12 @@ template
   /// True if the type is a scoped enumeration type.
   /// @since C++23
 
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
+  template
+struct is_scoped_enum
+: bool_constant<__is_scoped_enum(_Tp)>
+{ };
+# else
   template
 struct is_scoped_enum
 : false_type
@@ -3644,11 +3650,17 @@ template
 struct is_scoped_enum<_Tp>
 : bool_constant
 { };
+# endif
 
   /// @ingroup variable_templates
   /// @since C++23
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
+  template
+inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
+# else
   template
 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
+# endif
 #endif
 
 #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && 
ref_{converts,constructs}_from_temp
-- 
2.42.0



[PATCH v20 23/40] libstdc++: Optimize is_reference trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_reference trait by dispatching
to the new __is_reference built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_reference): Use __is_reference built-in
trait.
(is_reference_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 792213ebfe8..36ad9814047 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -682,6 +682,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Composite type categories.
 
   /// is_reference
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_reference
+: public __bool_constant<__is_reference(_Tp)>
+{ };
+#else
   template
 struct is_reference
 : public false_type
@@ -696,6 +702,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_reference<_Tp&&>
 : public true_type
 { };
+#endif
 
   /// is_arithmetic
   template
@@ -3264,12 +3271,19 @@ template 
   inline constexpr bool is_class_v = __is_class(_Tp);
 template 
   inline constexpr bool is_function_v = is_function<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_reference_v = __is_reference(_Tp);
+#else
 template 
   inline constexpr bool is_reference_v = false;
 template 
   inline constexpr bool is_reference_v<_Tp&> = true;
 template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
+#endif
+
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
-- 
2.42.0



[PATCH v20 30/40] libstdc++: Optimize is_pointer trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_pointer trait by dispatching to
the new __is_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_pointer): Use __is_pointer
built-in trait.
* include/std/type_traits (is_pointer): Likewise. Optimize its
implementation.
(is_pointer_v): Likewise.

Co-authored-by: Jonathan Wakely 
Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/bits/cpp_type_traits.h |  8 
 libstdc++-v3/include/std/type_traits| 44 +
 2 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 4312f32a4e0..cd5ce45951f 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -363,6 +363,13 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   //
   // Pointer types
   //
+#if __has_builtin(__is_pointer)
+  template
+struct __is_pointer : __truth_type<__is_pointer(_Tp)>
+{
+  enum { __value = __is_pointer(_Tp) };
+};
+#else
   template
 struct __is_pointer
 {
@@ -376,6 +383,7 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   enum { __value = 1 };
   typedef __true_type __type;
 };
+#endif
 
   //
   // An arithmetic type is an integer type or a floating point type
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 9c56d15c0b7..3acd843f2f2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -542,19 +542,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
 #endif
 
-  template
-struct __is_pointer_helper
+  /// is_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
+  template
+struct is_pointer
+: public __bool_constant<__is_pointer(_Tp)>
+{ };
+#else
+  template
+struct is_pointer
 : public false_type { };
 
   template
-struct __is_pointer_helper<_Tp*>
+struct is_pointer<_Tp*>
 : public true_type { };
 
-  /// is_pointer
   template
-struct is_pointer
-: public __is_pointer_helper<__remove_cv_t<_Tp>>::type
-{ };
+struct is_pointer<_Tp* const>
+: public true_type { };
+
+  template
+struct is_pointer<_Tp* volatile>
+: public true_type { };
+
+  template
+struct is_pointer<_Tp* const volatile>
+: public true_type { };
+#endif
 
   /// is_lvalue_reference
   template
@@ -3254,8 +3268,22 @@ template 
   inline constexpr bool is_array_v<_Tp[_Num]> = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
+template 
+  inline constexpr bool is_pointer_v = __is_pointer(_Tp);
+#else
 template 
-  inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
+  inline constexpr bool is_pointer_v = false;
+template 
+  inline constexpr bool is_pointer_v<_Tp*> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* const> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* volatile> = true;
+template 
+  inline constexpr bool is_pointer_v<_Tp* const volatile> = true;
+#endif
+
 template 
   inline constexpr bool is_lvalue_reference_v = false;
 template 
-- 
2.42.0



[PATCH v20 10/40] c++: Implement __is_unbounded_array built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_unbounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unbounded_array.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_UNBOUNDED_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_unbounded_array.
* g++.dg/ext/is_unbounded_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |  3 ++
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/semantics.cc   |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/is_unbounded_array.C | 37 +++
 5 files changed, 48 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_unbounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5e30a4a907a..751ac61b25a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3796,6 +3796,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIALLY_COPYABLE:
   inform (loc, "  %qT is not trivially copyable", t1);
   break;
+case CPTK_IS_UNBOUNDED_ARRAY:
+  inform (loc, "  %qT is not an unbounded array", t1);
+  break;
 case CPTK_IS_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 99bc05360b9..4e02f68e4a9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -83,6 +83,7 @@ DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
 DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
+DEFTRAIT_EXPR (IS_UNBOUNDED_ARRAY, "__is_unbounded_array", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
 DEFTRAIT_EXPR (IS_VOLATILE, "__is_volatile", 1)
 DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_temporary", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index e1358afcb3f..0a2699be476 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12217,6 +12217,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_TRIVIALLY_COPYABLE:
   return trivially_copyable_p (type1);
 
+case CPTK_IS_UNBOUNDED_ARRAY:
+  return array_of_unknown_bound_p (type1);
+
 case CPTK_IS_UNION:
   return type_code1 == UNION_TYPE;
 
@@ -12384,6 +12387,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
 case CPTK_IS_SAME:
+case CPTK_IS_UNBOUNDED_ARRAY:
 case CPTK_IS_UNION:
 case CPTK_IS_VOLATILE:
   break;
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 645cabe088e..90997210c12 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -131,6 +131,9 @@
 #if !__has_builtin (__is_trivially_copyable)
 # error "__has_builtin (__is_trivially_copyable) failed"
 #endif
+#if !__has_builtin (__is_unbounded_array)
+# error "__has_builtin (__is_unbounded_array) failed"
+#endif
 #if !__has_builtin (__is_union)
 # error "__has_builtin (__is_union) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_unbounded_array.C 
b/gcc/testsuite/g++.dg/ext/is_unbounded_array.C
new file mode 100644
index 000..1307d24f5a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_unbounded_array.C
@@ -0,0 +1,37 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+SA_TEST_CATEGORY(__is_unbounded_array, int[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, int[], true);
+SA_TEST_CATEGORY(__is_unbounded_array, int[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, int[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[], true);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, float*[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[], true);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, ClassType[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, IncompleteClass[2][3], false);
+SA_TEST_CATEGORY(__is_unbounded_array, IncompleteClass[][3], true);
+SA_TEST_CATEGORY(__is_unbounded_array, int(*)[2], false);
+SA_TEST_CATEGORY(__is_unbounded_array

[PATCH v20 05/40] libstdc++: Optimize is_const trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_const trait by dispatching to
the new __is_const built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_const): Use __is_const built-in trait.
(is_const_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 677cd934b94..686e38e47c3 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,6 +784,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Type properties.
 
   /// is_const
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
+  template
+struct is_const
+: public __bool_constant<__is_const(_Tp)>
+{ };
+#else
   template
 struct is_const
 : public false_type { };
@@ -791,6 +797,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_const<_Tp const>
 : public true_type { };
+#endif
 
   /// is_volatile
   template
@@ -3218,10 +3225,17 @@ template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
+template 
+  inline constexpr bool is_const_v = __is_const(_Tp);
+#else
 template 
   inline constexpr bool is_const_v = false;
 template 
   inline constexpr bool is_const_v = true;
+#endif
+
 template 
   inline constexpr bool is_volatile_v = false;
 template 
-- 
2.42.0



[PATCH v20 14/40] c++: Implement __is_scoped_enum built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_scoped_enum.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scoped_enum.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCOPED_ENUM.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_scoped_enum.
* g++.dg/ext/is_scoped_enum.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |  3 +
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/semantics.cc   |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +
 gcc/testsuite/g++.dg/ext/is_scoped_enum.C | 67 +++
 5 files changed, 78 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scoped_enum.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d09252a56b6..1c0b2e0f178 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3781,6 +3781,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCOPED_ENUM:
+  inform (loc, "  %qT is not a scoped enum", t1);
+  break;
 case CPTK_IS_STD_LAYOUT:
   inform (loc, "  %qT is not an standard layout type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 6d6dff7a4c3..e0e3fe1d23f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -79,6 +79,7 @@ DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertib
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
 DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 32880754020..f56ab031d5f 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12205,6 +12205,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_SAME:
   return same_type_p (type1, type2);
 
+case CPTK_IS_SCOPED_ENUM:
+  return SCOPED_ENUM_P (type1);
+
 case CPTK_IS_STD_LAYOUT:
   return std_layout_type_p (type1);
 
@@ -12391,6 +12394,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
 case CPTK_IS_SAME:
+case CPTK_IS_SCOPED_ENUM:
 case CPTK_IS_UNBOUNDED_ARRAY:
 case CPTK_IS_UNION:
 case CPTK_IS_VOLATILE:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 4142da518b1..ba97beea3c3 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -119,6 +119,9 @@
 #if !__has_builtin (__is_same_as)
 # error "__has_builtin (__is_same_as) failed"
 #endif
+#if !__has_builtin (__is_scoped_enum)
+# error "__has_builtin (__is_scoped_enum) failed"
+#endif
 #if !__has_builtin (__is_standard_layout)
 # error "__has_builtin (__is_standard_layout) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_scoped_enum.C 
b/gcc/testsuite/g++.dg/ext/is_scoped_enum.C
new file mode 100644
index 000..a563b6ee67d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_scoped_enum.C
@@ -0,0 +1,67 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_FN(TRAIT, TYPE, EXPECT)\
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT);
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+enum class E { e1, e2 };
+SA_TEST_CATEGORY(__is_scoped_enum, E, true);
+enum class Ec : char { e1, e2 };
+SA_TEST_CATEGORY(__is_scoped_enum, Ec, true);
+
+// negative tests
+enum U { u1, u2 };
+SA_TEST_CATEGORY(__is_scoped_enum, U, false);
+enum F : int { f1, f2 };
+SA_TEST_CATEGORY(__is_scoped_enum, F, false);
+struct S;
+SA_TEST_CATEGORY(__is_scoped_enum, S, false);
+struct S { };
+SA_TEST_CATEGORY(__is_scoped_enum, S, false);
+
+SA_TEST_CATEGORY(__is_scoped_enum, int, false);
+SA_TEST_CATEGORY(__is_scoped_enum, int[], false);
+SA_TEST_CATEGORY(__is_scoped_enum, int[2], false);
+SA_TEST_CATEGORY(__is_scoped_enum, int[][2], false);
+SA_TEST_CATEGORY(__is_scoped_enum, int[2][3], false);
+SA_TEST_CATEGORY(__is_scoped_enum, int*, false);
+SA_TEST_CATEGORY(__is_scoped_enum, int&, false);
+SA_TEST_CATEGORY(__is_scoped_enum, int*&, false);
+SA_TEST_FN(__is_scoped_enum, int(), false);
+SA_TEST_FN(__is_scoped_enum, int(*)(), false);
+SA_TEST_F

[PATCH v20 19/40] libstdc++: Optimize is_member_function_pointer trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_member_function_pointer trait
by dispatching to the new __is_member_function_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_function_pointer): Use
__is_member_function_pointer built-in trait.
(is_member_function_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 16 
 1 file changed, 16 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index d7f89cf7c06..e1b10240dc2 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -588,6 +588,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
+  /// is_member_function_pointer
+  template
+struct is_member_function_pointer
+: public __bool_constant<__is_member_function_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_function_pointer_helper
 : public false_type { };
@@ -601,6 +608,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_member_function_pointer
 : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   /// is_enum
   template
@@ -3222,9 +3230,17 @@ template 
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
+template 
+  inline constexpr bool is_member_function_pointer_v =
+__is_member_function_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_function_pointer_v =
 is_member_function_pointer<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_enum_v = __is_enum(_Tp);
 template 
-- 
2.42.0



[PATCH v20 16/40] c++: Implement __is_member_pointer built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_member_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_pointer.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_MEMBER_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_member_pointer.
* g++.dg/ext/is_member_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_member_pointer.C | 30 
 5 files changed, 41 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 1c0b2e0f178..f0d3f89464c 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3756,6 +3756,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_LITERAL_TYPE:
   inform (loc, "  %qT is not a literal type", t1);
   break;
+case CPTK_IS_MEMBER_POINTER:
+  inform (loc, "  %qT is not a member pointer", t1);
+  break;
 case CPTK_IS_NOTHROW_ASSIGNABLE:
   inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index e0e3fe1d23f..26087da3bdf 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -72,6 +72,7 @@ DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
+DEFTRAIT_EXPR (IS_MEMBER_POINTER, "__is_member_pointer", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
 DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
 DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index f56ab031d5f..6c4880d8a33 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12184,6 +12184,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_LITERAL_TYPE:
   return literal_type_p (type1);
 
+case CPTK_IS_MEMBER_POINTER:
+  return TYPE_PTRMEM_P (type1);
+
 case CPTK_IS_NOTHROW_ASSIGNABLE:
   return is_nothrow_xible (MODIFY_EXPR, type1, type2);
 
@@ -12393,6 +12396,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_CLASS:
 case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
+case CPTK_IS_MEMBER_POINTER:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
 case CPTK_IS_UNBOUNDED_ARRAY:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index ba97beea3c3..994873f14e9 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -95,6 +95,9 @@
 #if !__has_builtin (__is_literal_type)
 # error "__has_builtin (__is_literal_type) failed"
 #endif
+#if !__has_builtin (__is_member_pointer)
+# error "__has_builtin (__is_member_pointer) failed"
+#endif
 #if !__has_builtin (__is_nothrow_assignable)
 # error "__has_builtin (__is_nothrow_assignable) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_member_pointer.C 
b/gcc/testsuite/g++.dg/ext/is_member_pointer.C
new file mode 100644
index 000..7ee2e3ab90c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_member_pointer.C
@@ -0,0 +1,30 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_NON_VOLATILE(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT)
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+SA_TEST_CATEGORY(__is_member_pointer, int (ClassType::*), true);
+SA_TEST_CATEGORY(__is_member_pointer, ClassType (ClassType::*), true);
+
+SA_TEST_NON_VOLATILE(__is_member_pointer, int (ClassType::*)(int), true);
+SA_TEST_NON_VOLATILE(__is_member_pointer, int (ClassType::*)(int) const, true);
+SA_TEST_NON_VOLATILE(__is_member_pointer, int (ClassType::*)(float, ...), 
true);
+SA_TEST_NON_VOLATILE(__is_member_pointer, ClassType (ClassType::*)(ClassType), 
true);
+SA_TEST_NON_VOLATILE(__is_member_pointer,
+float (ClassType::*)(int, float, int[], int&), true);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_member_pointer, ClassType, false);
-- 
2.42.0



[PATCH v20 12/40] c++: Implement __is_bounded_array built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_bounded_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_bounded_array.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_BOUNDED_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_bounded_array.
* g++.dg/ext/is_bounded_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc|  3 ++
 gcc/cp/cp-trait.def |  1 +
 gcc/cp/semantics.cc |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 ++
 gcc/testsuite/g++.dg/ext/is_bounded_array.C | 38 +
 5 files changed, 49 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_bounded_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 751ac61b25a..d09252a56b6 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_BASE_OF:
   inform (loc, "  %qT is not a base of %qT", t1, t2);
   break;
+case CPTK_IS_BOUNDED_ARRAY:
+  inform (loc, "  %qT is not a bounded array", t1);
+  break;
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 4e02f68e4a9..6d6dff7a4c3 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
+DEFTRAIT_EXPR (IS_BOUNDED_ARRAY, "__is_bounded_array", 1)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
 DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
 DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 0a2699be476..32880754020 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12154,6 +12154,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
  || DERIVED_FROM_P (type1, type2)));
 
+case CPTK_IS_BOUNDED_ARRAY:
+  return type_code1 == ARRAY_TYPE && TYPE_DOMAIN (type1);
+
 case CPTK_IS_CLASS:
   return NON_UNION_CLASS_TYPE_P (type1);
 
@@ -12383,6 +12386,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
   break;
 
 case CPTK_IS_ARRAY:
+case CPTK_IS_BOUNDED_ARRAY:
 case CPTK_IS_CLASS:
 case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 90997210c12..4142da518b1 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -65,6 +65,9 @@
 #if !__has_builtin (__is_base_of)
 # error "__has_builtin (__is_base_of) failed"
 #endif
+#if !__has_builtin (__is_bounded_array)
+# error "__has_builtin (__is_bounded_array) failed"
+#endif
 #if !__has_builtin (__is_class)
 # error "__has_builtin (__is_class) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_bounded_array.C 
b/gcc/testsuite/g++.dg/ext/is_bounded_array.C
new file mode 100644
index 000..346790eba12
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_bounded_array.C
@@ -0,0 +1,38 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_CONST(TRAIT, TYPE, EXPECT) \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT)
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+SA_TEST_CATEGORY(__is_bounded_array, int[2], true);
+SA_TEST_CATEGORY(__is_bounded_array, int[], false);
+SA_TEST_CATEGORY(__is_bounded_array, int[2][3], true);
+SA_TEST_CATEGORY(__is_bounded_array, int[][3], false);
+SA_TEST_CATEGORY(__is_bounded_array, float*[2], true);
+SA_TEST_CATEGORY(__is_bounded_array, float*[], false);
+SA_TEST_CATEGORY(__is_bounded_array, float*[2][3], true);
+SA_TEST_CATEGORY(__is_bounded_array, float*[][3], false);
+SA_TEST_CATEGORY(__is_bounded_array, ClassType[2], true);
+SA_TEST_CATEGORY(__is_bounded_array, ClassType[], false);
+SA_TEST_CATEGORY(__is_bounded_array, ClassType[2][3], true);
+SA_TEST_CATEGORY(__is_bounded_array, ClassType[][3], false);
+SA_TEST_CATEGORY(__is_bounded_array, int(*)[2], false);
+SA_TEST_CATEGORY(__is_bounded_array, int(*)[], false);
+SA_TEST_CATEGORY(__is_bounded_array, int(&)[2], false);
+SA_TEST_CONST(__is_bounded_array, int(&)[], false);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_bounde

[PATCH v20 39/40] c++: Implement __is_scalar built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_scalar.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scalar.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCALAR.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_scalar.
* g++.dg/ext/is_scalar.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/is_scalar.C | 31 
 5 files changed, 42 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_scalar.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index b161c9b2c9e..78f100d2745 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SCALAR:
+  inform (loc, "  %qT is not a scalar type", t1);
+  break;
 case CPTK_IS_SIGNED:
   inform (loc, "  %qT is not a signed type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b0faa4c8937..08a2780c929 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SCALAR, "__is_scalar", 1)
 DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 5e6b2ca37ac..be345f9aa47 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12226,6 +12226,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_SAME:
   return same_type_p (type1, type2);
 
+case CPTK_IS_SCALAR:
+  return SCALAR_TYPE_P (type1);
+
 case CPTK_IS_SIGNED:
   return ARITHMETIC_TYPE_P (type1) && TYPE_SIGN (type1) == SIGNED;
 
@@ -12428,6 +12431,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_POINTER:
 case CPTK_IS_REFERENCE:
 case CPTK_IS_SAME:
+case CPTK_IS_SCALAR:
 case CPTK_IS_SIGNED:
 case CPTK_IS_SCOPED_ENUM:
 case CPTK_IS_UNBOUNDED_ARRAY:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index aaf7254df4b..f4f6fed6876 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -140,6 +140,9 @@
 #if !__has_builtin (__is_same_as)
 # error "__has_builtin (__is_same_as) failed"
 #endif
+#if !__has_builtin (__is_scalar)
+# error "__has_builtin (__is_scalar) failed"
+#endif
 #if !__has_builtin (__is_signed)
 # error "__has_builtin (__is_signed) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_scalar.C 
b/gcc/testsuite/g++.dg/ext/is_scalar.C
new file mode 100644
index 000..457fddc52fc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_scalar.C
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++11 } }
+
+#include   // std::nullptr_t
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+// volatile return type would cause a warning.
+#define SA_FN_TEST_CATEGORY(TRAIT, TYPE, EXPECT)   \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT)
+
+SA_TEST_CATEGORY(__is_scalar, int, true);
+SA_TEST_CATEGORY(__is_scalar, float, true);
+SA_TEST_CATEGORY(__is_scalar, EnumType, true);
+SA_TEST_CATEGORY(__is_scalar, int*, true);
+SA_FN_TEST_CATEGORY(__is_scalar, int(*)(int), true);
+SA_TEST_CATEGORY(__is_scalar, int (ClassType::*), true);
+SA_FN_TEST_CATEGORY(__is_scalar, int (ClassType::*) (int), true);
+SA_TEST_CATEGORY(__is_scalar, std::nullptr_t, true);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_scalar, ClassType, false);
-- 
2.42.0



[PATCH v20 33/40] libstdc++: Optimize is_fundamental trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_fundamental trait by
dispatching to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_fundamental_v): Use __is_arithmetic
built-in trait.
(is_fundamental): Likewise. Optimize the original implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index cc466e0f606..88171e1a672 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -739,11 +739,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_fundamental
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+  template
+struct is_fundamental
+: public __bool_constant<__is_arithmetic(_Tp)
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
+{ };
+#else
   template
 struct is_fundamental
-: public __or_, is_void<_Tp>,
-  is_null_pointer<_Tp>>::type
+: public __bool_constant::value
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
 { };
+#endif
 
   /// is_object
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
@@ -3354,13 +3364,15 @@ template 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
 template 
   inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+template 
+  inline constexpr bool is_fundamental_v
+= __is_arithmetic(_Tp) || is_void_v<_Tp> || is_null_pointer_v<_Tp>;
 #else
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
-#endif
-
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
  && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
-- 
2.42.0



[PATCH v20 11/40] libstdc++: Optimize is_unbounded_array trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_unbounded_array trait by
dispatching to the new __is_unbounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_unbounded_array_v): Use
__is_unbounded_array built-in trait.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 4e8165e5af5..cb3d9e238fa 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3541,11 +3541,16 @@ template
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array)
+  template
+inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
+# else
   template
 inline constexpr bool is_unbounded_array_v = false;
 
   template
 inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
+# endif
 
   /// True for a type that is an array of known bound.
   /// @since C++20
-- 
2.42.0



[PATCH v20 06/40] c++: Implement __is_volatile built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_volatile.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_volatile.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_VOLATILE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_volatile.
* g++.dg/ext/is_volatile.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/is_volatile.C   | 19 +++
 5 files changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_volatile.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 567dd35fe0a..f031e022541 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3796,6 +3796,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
+case CPTK_IS_VOLATILE:
+  inform (loc, "  %qT is not a volatile type", t1);
+  break;
 case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
   inform (loc, "  %qT is not a reference that binds to a temporary "
  "object of type %qT (direct-initialization)", t1, t2);
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 9e4e6d798a0..d786f47e60c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -83,6 +83,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, 
"__is_trivially_assignable", 2)
 DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
+DEFTRAIT_EXPR (IS_VOLATILE, "__is_volatile", 1)
 DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_temporary", 2)
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, 
"__reference_converts_from_temporary", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 23f1d1c249a..73178540fbd 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12217,6 +12217,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_UNION:
   return type_code1 == UNION_TYPE;
 
+case CPTK_IS_VOLATILE:
+  return CP_TYPE_VOLATILE_P (type1);
+
 case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
   return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
 
@@ -12378,6 +12381,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_ENUM:
 case CPTK_IS_SAME:
 case CPTK_IS_UNION:
+case CPTK_IS_VOLATILE:
   break;
 
 case CPTK_IS_LAYOUT_COMPATIBLE:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index e6e481b13c5..fb03dd20e84 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -131,6 +131,9 @@
 #if !__has_builtin (__is_union)
 # error "__has_builtin (__is_union) failed"
 #endif
+#if !__has_builtin (__is_volatile)
+# error "__has_builtin (__is_volatile) failed"
+#endif
 #if !__has_builtin (__reference_constructs_from_temporary)
 # error "__has_builtin (__reference_constructs_from_temporary) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_volatile.C 
b/gcc/testsuite/g++.dg/ext/is_volatile.C
new file mode 100644
index 000..004e397e5e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_volatile.C
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+// Positive tests.
+SA(__is_volatile(volatile int));
+SA(__is_volatile(const volatile int));
+SA(__is_volatile(vClassType));
+SA(__is_volatile(cvClassType));
+
+// Negative tests.
+SA(!__is_volatile(int));
+SA(!__is_volatile(const int));
+SA(!__is_volatile(ClassType));
+SA(!__is_volatile(cClassType));
-- 
2.42.0



[PATCH v20 17/40] libstdc++: Optimize is_member_pointer trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_member_pointer trait
by dispatching to the new __is_member_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_pointer): Use __is_member_pointer
built-in trait.
(is_member_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7fd29d8d9f2..d7f89cf7c06 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -716,6 +716,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_compound
 : public __not_>::type { };
 
+  /// is_member_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+  template
+struct is_member_pointer
+: public __bool_constant<__is_member_pointer(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template
 struct __is_member_pointer_helper
@@ -726,11 +733,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public true_type { };
   /// @endcond
 
-  /// is_member_pointer
   template
 struct is_member_pointer
 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
   template
 struct is_same;
@@ -3242,8 +3249,14 @@ template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
   inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
+template 
+  inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
 template 
-- 
2.42.0



[PATCH v20 32/40] libstdc++: Optimize is_arithmetic trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_arithmetic trait by dispatching
to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_arithmetic): Use __is_arithmetic
built-in trait.
(is_arithmetic_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 3acd843f2f2..cc466e0f606 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -726,10 +726,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_arithmetic
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+  template
+struct is_arithmetic
+: public __bool_constant<__is_arithmetic(_Tp)>
+{ };
+#else
   template
 struct is_arithmetic
 : public __or_, is_floating_point<_Tp>>::type
 { };
+#endif
 
   /// is_fundamental
   template
@@ -3344,8 +3351,14 @@ template 
   inline constexpr bool is_reference_v<_Tp&&> = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_arithmetic)
+template 
+  inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+#else
 template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
 
-- 
2.42.0



[PATCH v20 08/40] c++: Implement __is_array built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_array.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_array.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARRAY.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_array.
* g++.dg/ext/is_array.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/is_array.C  | 28 
 5 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_array.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f031e022541..5e30a4a907a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARRAY:
+  inform (loc, "  %qT is not an array", t1);
+  break;
 case CPTK_IS_ASSIGNABLE:
   inform (loc, "  %qT is not assignable from %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index d786f47e60c..99bc05360b9 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 73178540fbd..e1358afcb3f 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12143,6 +12143,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_AGGREGATE:
   return CP_AGGREGATE_TYPE_P (type1);
 
+case CPTK_IS_ARRAY:
+  return type_code1 == ARRAY_TYPE;
+
 case CPTK_IS_ASSIGNABLE:
   return is_xible (MODIFY_EXPR, type1, type2);
 
@@ -12376,6 +12379,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
return error_mark_node;
   break;
 
+case CPTK_IS_ARRAY:
 case CPTK_IS_CLASS:
 case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index fb03dd20e84..645cabe088e 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -56,6 +56,9 @@
 #if !__has_builtin (__is_aggregate)
 # error "__has_builtin (__is_aggregate) failed"
 #endif
+#if !__has_builtin (__is_array)
+# error "__has_builtin (__is_array) failed"
+#endif
 #if !__has_builtin (__is_assignable)
 # error "__has_builtin (__is_assignable) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_array.C 
b/gcc/testsuite/g++.dg/ext/is_array.C
new file mode 100644
index 000..facfed5c7cb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_array.C
@@ -0,0 +1,28 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+#define SA_TEST_CATEGORY(TRAIT, X, expect) \
+  SA(TRAIT(X) == expect);  \
+  SA(TRAIT(const X) == expect);\
+  SA(TRAIT(volatile X) == expect); \
+  SA(TRAIT(const volatile X) == expect)
+
+SA_TEST_CATEGORY(__is_array, int[2], true);
+SA_TEST_CATEGORY(__is_array, int[], true);
+SA_TEST_CATEGORY(__is_array, int[2][3], true);
+SA_TEST_CATEGORY(__is_array, int[][3], true);
+SA_TEST_CATEGORY(__is_array, float*[2], true);
+SA_TEST_CATEGORY(__is_array, float*[], true);
+SA_TEST_CATEGORY(__is_array, float*[2][3], true);
+SA_TEST_CATEGORY(__is_array, float*[][3], true);
+SA_TEST_CATEGORY(__is_array, ClassType[2], true);
+SA_TEST_CATEGORY(__is_array, ClassType[], true);
+SA_TEST_CATEGORY(__is_array, ClassType[2][3], true);
+SA_TEST_CATEGORY(__is_array, ClassType[][3], true);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_array, ClassType, false);
-- 
2.42.0



[PATCH v20 09/40] libstdc++: Optimize is_array trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_array trait by dispatching to
the new __is_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_array): Use __is_array built-in trait.
(is_array_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 12 
 1 file changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index c01f65df22b..4e8165e5af5 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -523,6 +523,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_array
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
+  template
+struct is_array
+: public __bool_constant<__is_array(_Tp)>
+{ };
+#else
   template
 struct is_array
 : public false_type { };
@@ -534,6 +540,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_array<_Tp[]>
 : public true_type { };
+#endif
 
   template
 struct __is_pointer_helper
@@ -3183,12 +3190,17 @@ template 
 template 
   inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
+template 
+  inline constexpr bool is_array_v = __is_array(_Tp);
+#else
 template 
   inline constexpr bool is_array_v = false;
 template 
   inline constexpr bool is_array_v<_Tp[]> = true;
 template 
   inline constexpr bool is_array_v<_Tp[_Num]> = true;
+#endif
 
 template 
   inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
-- 
2.42.0



[PATCH v20 34/40] libstdc++: Optimize is_compound trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_compound trait by dispatching
to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_compound): Do not use __not_.
(is_compound_v): Use is_fundamental_v instead.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 88171e1a672..48d630a1478 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -784,7 +784,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_compound
   template
 struct is_compound
-: public __not_>::type { };
+: public __bool_constant::value> { };
 
   /// is_member_pointer
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
@@ -3387,7 +3387,7 @@ template 
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-  inline constexpr bool is_compound_v = is_compound<_Tp>::value;
+  inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
 template 
-- 
2.42.0



[PATCH v20 27/40] c++: Implement __remove_pointer built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::remove_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __remove_pointer.
* semantics.cc (finish_trait_type): Handle CPTK_REMOVE_POINTER.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __remove_pointer.
* g++.dg/ext/remove_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/semantics.cc   |  5 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++
 4 files changed, 60 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/remove_pointer.C

diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index fa79bc0c68c..2add97ae749 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -97,6 +97,7 @@ DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_tempo
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, 
"__reference_converts_from_temporary", 2)
 DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
 DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
+DEFTRAIT_TYPE (REMOVE_POINTER, "__remove_pointer", 1)
 DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
 DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
 DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 4b8e80f3e62..168411f6700 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12488,6 +12488,11 @@ finish_trait_type (cp_trait_kind kind, tree type1, 
tree type2,
type1 = TREE_TYPE (type1);
   return cv_unqualified (type1);
 
+case CPTK_REMOVE_POINTER:
+  if (TYPE_PTR_P (type1))
+type1 = TREE_TYPE (type1);
+  return type1;
+
 case CPTK_REMOVE_REFERENCE:
   if (TYPE_REF_P (type1))
type1 = TREE_TYPE (type1);
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 4d3947572a4..bcab0599d1a 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -173,6 +173,9 @@
 #if !__has_builtin (__remove_cvref)
 # error "__has_builtin (__remove_cvref) failed"
 #endif
+#if !__has_builtin (__remove_pointer)
+# error "__has_builtin (__remove_pointer) failed"
+#endif
 #if !__has_builtin (__remove_reference)
 # error "__has_builtin (__remove_reference) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/remove_pointer.C 
b/gcc/testsuite/g++.dg/ext/remove_pointer.C
new file mode 100644
index 000..7b13db93950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/remove_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(__is_same(__remove_pointer(int), int));
+SA(__is_same(__remove_pointer(int*), int));
+SA(__is_same(__remove_pointer(int**), int*));
+
+SA(__is_same(__remove_pointer(const int*), const int));
+SA(__is_same(__remove_pointer(const int**), const int*));
+SA(__is_same(__remove_pointer(int* const), int));
+SA(__is_same(__remove_pointer(int** const), int*));
+SA(__is_same(__remove_pointer(int* const* const), int* const));
+
+SA(__is_same(__remove_pointer(volatile int*), volatile int));
+SA(__is_same(__remove_pointer(volatile int**), volatile int*));
+SA(__is_same(__remove_pointer(int* volatile), int));
+SA(__is_same(__remove_pointer(int** volatile), int*));
+SA(__is_same(__remove_pointer(int* volatile* volatile), int* volatile));
+
+SA(__is_same(__remove_pointer(const volatile int*), const volatile int));
+SA(__is_same(__remove_pointer(const volatile int**), const volatile int*));
+SA(__is_same(__remove_pointer(const int* volatile), const int));
+SA(__is_same(__remove_pointer(volatile int* const), volatile int));
+SA(__is_same(__remove_pointer(int* const volatile), int));
+SA(__is_same(__remove_pointer(const int** volatile), const int*));
+SA(__is_same(__remove_pointer(volatile int** const), volatile int*));
+SA(__is_same(__remove_pointer(int** const volatile), int*));
+SA(__is_same(__remove_pointer(int* const* const volatile), int* const));
+SA(__is_same(__remove_pointer(int* volatile* const volatile), int* volatile));
+SA(__is_same(__remove_pointer(int* const volatile* const volatile), int* const 
volatile));
+
+SA(__is_same(__remove_pointer(int&), int&));
+SA(__is_same(__remove_pointer(const int&), const int&));
+SA(__is_same(__remove_pointer(volatile int&), volatile int&));
+SA(__is_same(__remove_pointer(const volatile int&), const volatile int&));
+
+SA(__is_same(__remove_pointer(int&&), int&&));
+SA(__is_same(__remove_pointer(const int&&), const int&&));
+SA(__is_same(__remove_pointer(volatile int&&), volatile int&&));
+SA(__is_same(__remove_pointer(const volatile int&&), const volatile int&&));
+
+SA(__is_same(__remove_pointer(int[3]), int[3]));
+SA(__is_same(__remove_pointer(const int[3]), const int[3]));
+SA(__is_same(__remove_pointer(volatile int[3]), volatile int[3]));
+SA(__is_same(__remove_pointer(co

[PATCH v20 25/40] libstdc++: Optimize is_function trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_function trait by dispatching
to the new __is_function built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_function): Use __is_function built-in
trait.
(is_function_v): Likewise. Optimize its implementation.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 36ad9814047..bd57488824b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -637,6 +637,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_function
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
+  template
+struct is_function
+: public __bool_constant<__is_function(_Tp)>
+{ };
+#else
   template
 struct is_function
 : public __bool_constant::value> { };
@@ -648,6 +654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_function<_Tp&&>
 : public false_type { };
+#endif
 
 #ifdef __cpp_lib_is_null_pointer // C++ >= 11
   /// is_null_pointer (LWG 2247).
@@ -3269,8 +3276,18 @@ template 
   inline constexpr bool is_union_v = __is_union(_Tp);
 template 
   inline constexpr bool is_class_v = __is_class(_Tp);
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
 template 
-  inline constexpr bool is_function_v = is_function<_Tp>::value;
+  inline constexpr bool is_function_v = __is_function(_Tp);
+#else
+template 
+  inline constexpr bool is_function_v = !is_const_v;
+template 
+  inline constexpr bool is_function_v<_Tp&> = false;
+template 
+  inline constexpr bool is_function_v<_Tp&&> = false;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
 template 
-- 
2.42.0



[PATCH v20 28/40] libstdc++: Optimize remove_pointer trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the remove_pointer trait by
dispatching to the new remove_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (remove_pointer): Use __remove_pointer
built-in trait.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 674d398c075..9c56d15c0b7 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2105,6 +2105,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Pointer modifications.
 
+  /// remove_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer)
+  template
+struct remove_pointer
+{ using type = __remove_pointer(_Tp); };
+#else
   template
 struct __remove_pointer_helper
 { using type = _Tp; };
@@ -2113,11 +2119,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __remove_pointer_helper<_Tp, _Up*>
 { using type = _Up; };
 
-  /// remove_pointer
   template
 struct remove_pointer
 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
 { };
+#endif
 
   template
 struct __add_pointer_helper
-- 
2.42.0



[PATCH v20 26/40] libstdc++: Optimize is_object trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_object trait by dispatching to
the new __is_function and __is_reference built-in traits.

libstdc++-v3/ChangeLog:
* include/std/type_traits (is_object): Use __is_function and
__is_reference built-in traits.
(is_object_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index bd57488824b..674d398c075 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -725,11 +725,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_object
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+  template
+struct is_object
+: public __bool_constant::value)>
+{ };
+#else
   template
 struct is_object
 : public __not_<__or_, is_reference<_Tp>,
   is_void<_Tp>>>::type
 { };
+#endif
 
   template
 struct is_member_pointer;
@@ -3305,8 +3314,17 @@ template 
   inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
 template 
   inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) \
+ && _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
+template 
+  inline constexpr bool is_object_v
+= !(__is_function(_Tp) || __is_reference(_Tp) || is_void<_Tp>::value);
+#else
 template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
 template 
-- 
2.42.0



[PATCH v20 13/40] libstdc++: Optimize is_bounded_array trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_bounded_array trait by
dispatching to the new __is_bounded_array built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_bounded_array_v): Use __is_bounded_array
built-in trait.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index cb3d9e238fa..d306073a797 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3532,11 +3532,16 @@ template
   /// True for a type that is an array of known bound.
   /// @ingroup variable_templates
   /// @since C++20
+# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array)
+  template
+inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
+# else
   template
 inline constexpr bool is_bounded_array_v = false;
 
   template
 inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
+# endif
 
   /// True for a type that is an array of unknown bound.
   /// @ingroup variable_templates
-- 
2.42.0



[PATCH v20 40/40] libstdc++: Optimize is_scalar trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_scalar trait by dispatching to
the new __is_scalar built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_scalar): Use __is_scalar built-in
trait.
(is_scalar_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7e93923f44b..eb16a642575 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -775,11 +775,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_member_pointer;
 
   /// is_scalar
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scalar)
+  template
+struct is_scalar
+: public __bool_constant<__is_scalar(_Tp)>
+{ };
+#else
   template
 struct is_scalar
 : public __or_, is_enum<_Tp>, is_pointer<_Tp>,
is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type
 { };
+#endif
 
   /// is_compound
   template
@@ -3398,8 +3405,14 @@ template 
   inline constexpr bool is_object_v = is_object<_Tp>::value;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scalar)
+template 
+  inline constexpr bool is_scalar_v = __is_scalar(_Tp);
+#else
 template 
   inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
+#endif
+
 template 
   inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
 
-- 
2.42.0



[PATCH v20 20/40] c++: Implement __is_member_object_pointer built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_member_object_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_object_pointer.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_MEMBER_OBJECT_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of
__is_member_object_pointer.
* g++.dg/ext/is_member_object_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc  |  3 ++
 gcc/cp/cp-trait.def   |  1 +
 gcc/cp/semantics.cc   |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 .../g++.dg/ext/is_member_object_pointer.C | 30 +++
 5 files changed, 41 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_member_object_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d0464dd4f6a..98b1f004a68 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3759,6 +3759,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
   inform (loc, "  %qT is not a member function pointer", t1);
   break;
+case CPTK_IS_MEMBER_OBJECT_POINTER:
+  inform (loc, "  %qT is not a member object pointer", t1);
+  break;
 case CPTK_IS_MEMBER_POINTER:
   inform (loc, "  %qT is not a member pointer", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 897b96630f2..11fd70b3964 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -73,6 +73,7 @@ DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
 DEFTRAIT_EXPR (IS_MEMBER_FUNCTION_POINTER, "__is_member_function_pointer", 1)
+DEFTRAIT_EXPR (IS_MEMBER_OBJECT_POINTER, "__is_member_object_pointer", 1)
 DEFTRAIT_EXPR (IS_MEMBER_POINTER, "__is_member_pointer", 1)
 DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2)
 DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 4d521f87bbb..9cbb434d4c2 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12187,6 +12187,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
   return TYPE_PTRMEMFUNC_P (type1);
 
+case CPTK_IS_MEMBER_OBJECT_POINTER:
+  return TYPE_PTRMEM_P (type1) && !TYPE_PTRMEMFUNC_P (type1);
+
 case CPTK_IS_MEMBER_POINTER:
   return TYPE_PTRMEM_P (type1);
 
@@ -12400,6 +12403,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
+case CPTK_IS_MEMBER_OBJECT_POINTER:
 case CPTK_IS_MEMBER_POINTER:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 0dfe957474b..8d9cdc528cd 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -98,6 +98,9 @@
 #if !__has_builtin (__is_member_function_pointer)
 # error "__has_builtin (__is_member_function_pointer) failed"
 #endif
+#if !__has_builtin (__is_member_object_pointer)
+# error "__has_builtin (__is_member_object_pointer) failed"
+#endif
 #if !__has_builtin (__is_member_pointer)
 # error "__has_builtin (__is_member_pointer) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_member_object_pointer.C 
b/gcc/testsuite/g++.dg/ext/is_member_object_pointer.C
new file mode 100644
index 000..835e48c8f8e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_member_object_pointer.C
@@ -0,0 +1,30 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_NON_VOLATILE(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT)
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+// Positive tests.
+SA_TEST_CATEGORY(__is_member_object_pointer, int (ClassType::*), true);
+SA_TEST_CATEGORY(__is_member_object_pointer, ClassType (ClassType::*), true);
+
+// Negative tests.
+SA_TEST_NON_VOLATILE(__is_member_object_pointer, int (ClassType::*) (int), 
false);
+SA_TEST_NON_VOLATILE(__is_member_object_pointer, int (ClassType::*) (float, 
...), false);
+SA_TEST_NON_VOLATILE(__is_member_object_pointer, ClassType (ClassType::*) 
(ClassType), false);
+SA_TEST_NON_VOLATILE(__is_member_object_pointer, float (ClassType::*) (i

[PATCH v20 37/40] c++: Implement __is_signed built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_signed.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_signed.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SIGNED.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_signed.
* g++.dg/ext/is_signed.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_signed.C | 47 
 5 files changed, 58 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_signed.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c28dad702c3..b161c9b2c9e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
+case CPTK_IS_SIGNED:
+  inform (loc, "  %qT is not a signed type", t1);
+  break;
 case CPTK_IS_SCOPED_ENUM:
   inform (loc, "  %qT is not a scoped enum", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 0603b4a230f..b0faa4c8937 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
+DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
 DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 14387821b85..5e6b2ca37ac 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12226,6 +12226,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_SAME:
   return same_type_p (type1, type2);
 
+case CPTK_IS_SIGNED:
+  return ARITHMETIC_TYPE_P (type1) && TYPE_SIGN (type1) == SIGNED;
+
 case CPTK_IS_SCOPED_ENUM:
   return SCOPED_ENUM_P (type1);
 
@@ -12425,6 +12428,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_POINTER:
 case CPTK_IS_REFERENCE:
 case CPTK_IS_SAME:
+case CPTK_IS_SIGNED:
 case CPTK_IS_SCOPED_ENUM:
 case CPTK_IS_UNBOUNDED_ARRAY:
 case CPTK_IS_UNION:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 3d380f94b06..aaf7254df4b 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -140,6 +140,9 @@
 #if !__has_builtin (__is_same_as)
 # error "__has_builtin (__is_same_as) failed"
 #endif
+#if !__has_builtin (__is_signed)
+# error "__has_builtin (__is_signed) failed"
+#endif
 #if !__has_builtin (__is_scoped_enum)
 # error "__has_builtin (__is_scoped_enum) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_signed.C 
b/gcc/testsuite/g++.dg/ext/is_signed.C
new file mode 100644
index 000..a04b548105d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_signed.C
@@ -0,0 +1,47 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+#define SA_TEST_CATEGORY(TRAIT, X, expect) \
+  SA(TRAIT(X) == expect);  \
+  SA(TRAIT(const X) == expect);\
+  SA(TRAIT(volatile X) == expect); \
+  SA(TRAIT(const volatile X) == expect)
+
+SA_TEST_CATEGORY(__is_signed, void, false);
+
+SA_TEST_CATEGORY(__is_signed, bool, bool(-1) < bool(0));
+SA_TEST_CATEGORY(__is_signed, char, char(-1) < char(0));
+SA_TEST_CATEGORY(__is_signed, signed char, true);
+SA_TEST_CATEGORY(__is_signed, unsigned char, false);
+SA_TEST_CATEGORY(__is_signed, wchar_t, wchar_t(-1) < wchar_t(0));
+SA_TEST_CATEGORY(__is_signed, short, true);
+SA_TEST_CATEGORY(__is_signed, unsigned short, false);
+SA_TEST_CATEGORY(__is_signed, int, true);
+SA_TEST_CATEGORY(__is_signed, unsigned int, false);
+SA_TEST_CATEGORY(__is_signed, long, true);
+SA_TEST_CATEGORY(__is_signed, unsigned long, false);
+SA_TEST_CATEGORY(__is_signed, long long, true);
+SA_TEST_CATEGORY(__is_signed, unsigned long long, false);
+
+SA_TEST_CATEGORY(__is_signed, float, true);
+SA_TEST_CATEGORY(__is_signed, double, true);
+SA_TEST_CATEGORY(__is_signed, long double, true);
+
+#ifndef __STRICT_ANSI__
+// GNU Extensions.
+#ifdef __SIZEOF_INT128__
+SA_TEST_CATEGORY(__is_signed, __int128, true);
+SA_TEST_CATEGORY(__is_signed, unsigned __int128, false);
+#endif
+
+#ifdef _GLIBCXX_USE_FLOAT128
+SA_TEST_CATEGORY(__is_signed, __float128, true);
+#endif
+#endif
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_signed, ClassType, false);
-- 
2.42.0



[PATCH v20 38/40] libstdc++: Optimize is_signed trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_signed trait by dispatching to
the new __is_signed built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_signed): Use __is_signed built-in trait.
(is_signed_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index f7d3815f332..7e93923f44b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -982,6 +982,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __bool_constant<__is_abstract(_Tp)>
 { };
 
+  /// is_signed
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+  template
+struct is_signed
+: public __bool_constant<__is_signed(_Tp)>
+{ };
+#else
   /// @cond undocumented
   template::value>
@@ -994,11 +1001,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
   /// @endcond
 
-  /// is_signed
   template
 struct is_signed
 : public __is_signed_helper<_Tp>::type
 { };
+#endif
 
   /// is_unsigned
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
@@ -3445,8 +3452,13 @@ template 
 template 
   inline constexpr bool is_final_v = __is_final(_Tp);
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_signed)
+template 
+  inline constexpr bool is_signed_v = __is_signed(_Tp);
+#else
 template 
   inline constexpr bool is_signed_v = is_signed<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unsigned)
 template 
-- 
2.42.0



[PATCH v20 24/40] c++: Implement __is_function built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_function.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_function.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_FUNCTION.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_function.
* g++.dg/ext/is_function.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_function.C   | 58 
 5 files changed, 69 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_function.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5cdb59d174e..99a7e7247ce 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3750,6 +3750,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_FINAL:
   inform (loc, "  %qT is not a final class", t1);
   break;
+case CPTK_IS_FUNCTION:
+  inform (loc, "  %qT is not a function", t1);
+  break;
 case CPTK_IS_LAYOUT_COMPATIBLE:
   inform (loc, "  %qT is not layout compatible with %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index e867d9c4c47..fa79bc0c68c 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -70,6 +70,7 @@ DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
 DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
 DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1)
 DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1)
+DEFTRAIT_EXPR (IS_FUNCTION, "__is_function", 1)
 DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2)
 DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1)
 DEFTRAIT_EXPR (IS_MEMBER_FUNCTION_POINTER, "__is_member_function_pointer", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index df720459458..4b8e80f3e62 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12178,6 +12178,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_FINAL:
   return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1);
 
+case CPTK_IS_FUNCTION:
+  return type_code1 == FUNCTION_TYPE;
+
 case CPTK_IS_LAYOUT_COMPATIBLE:
   return layout_compatible_type_p (type1, type2);
 
@@ -12405,6 +12408,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_CLASS:
 case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
+case CPTK_IS_FUNCTION:
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
 case CPTK_IS_MEMBER_OBJECT_POINTER:
 case CPTK_IS_MEMBER_POINTER:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index e112d317657..4d3947572a4 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -89,6 +89,9 @@
 #if !__has_builtin (__is_final)
 # error "__has_builtin (__is_final) failed"
 #endif
+#if !__has_builtin (__is_function)
+# error "__has_builtin (__is_function) failed"
+#endif
 #if !__has_builtin (__is_layout_compatible)
 # error "__has_builtin (__is_layout_compatible) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_function.C 
b/gcc/testsuite/g++.dg/ext/is_function.C
new file mode 100644
index 000..2e1594b12ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_function.C
@@ -0,0 +1,58 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+struct A
+{ void fn(); };
+
+template
+struct AHolder { };
+
+template
+struct AHolder
+{ using type = U; };
+
+// Positive tests.
+SA(__is_function(int (int)));
+SA(__is_function(ClassType (ClassType)));
+SA(__is_function(float (int, float, int[], int&)));
+SA(__is_function(int (int, ...)));
+SA(__is_function(bool (ClassType) const));
+SA(__is_function(AHolder::type));
+
+void fn();
+SA(__is_function(decltype(fn)));
+
+// Negative tests.
+SA_TEST_CATEGORY(__is_function, int, false);
+SA_TEST_CATEGORY(__is_function, int*, false);
+SA_TEST_CATEGORY(__is_function, int&, false);
+SA_TEST_CATEGORY(__is_function, void, false);
+SA_TEST_CATEGORY(__is_function, void*, false);
+SA_TEST_CATEGORY(__is_function, void**, false);
+SA_TEST_CATEGORY(__is_function, std::nullptr_t, false);
+
+SA_TEST_CATEGORY(__is_function, AbstractClass, false);
+SA(!__is_function(int(&)(int)));
+SA(!__is_function(int(*)(int)));
+
+SA_TEST_CATEGORY(__is_function, A, false);
+SA_TEST_CATEGORY(__is_function, decltype(&A::fn), false);
+
+struct FnCallOverload
+{ void operator()(); };
+S

[PATCH v20 31/40] c++: Implement __is_arithmetic built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_arithmetic.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_arithmetic.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARITHMETIC.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_arithmetic.
* g++.dg/ext/is_arithmetic.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/is_arithmetic.C | 33 
 5 files changed, 44 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_arithmetic.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9d627fa782..3a7f968eae8 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3714,6 +3714,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_AGGREGATE:
   inform (loc, "  %qT is not an aggregate", t1);
   break;
+case CPTK_IS_ARITHMETIC:
+  inform (loc, "  %qT is not an arithmetic type", t1);
+  break;
 case CPTK_IS_ARRAY:
   inform (loc, "  %qT is not an array", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index c60724e869e..b2be7b7bbd7 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -59,6 +59,7 @@ DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, 
"__has_unique_object_representati
 DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1)
 DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1)
 DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
+DEFTRAIT_EXPR (IS_ARITHMETIC, "__is_arithmetic", 1)
 DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 83ed674b9d4..deab0134509 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12143,6 +12143,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_AGGREGATE:
   return CP_AGGREGATE_TYPE_P (type1);
 
+case CPTK_IS_ARITHMETIC:
+  return ARITHMETIC_TYPE_P (type1);
+
 case CPTK_IS_ARRAY:
   return type_code1 == ARRAY_TYPE;
 
@@ -12406,6 +12409,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
return error_mark_node;
   break;
 
+case CPTK_IS_ARITHMETIC:
 case CPTK_IS_ARRAY:
 case CPTK_IS_BOUNDED_ARRAY:
 case CPTK_IS_CLASS:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index efce04fd09d..4bc85f4babb 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -56,6 +56,9 @@
 #if !__has_builtin (__is_aggregate)
 # error "__has_builtin (__is_aggregate) failed"
 #endif
+#if !__has_builtin (__is_arithmetic)
+# error "__has_builtin (__is_arithmetic) failed"
+#endif
 #if !__has_builtin (__is_array)
 # error "__has_builtin (__is_array) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_arithmetic.C 
b/gcc/testsuite/g++.dg/ext/is_arithmetic.C
new file mode 100644
index 000..fd35831f646
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_arithmetic.C
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+SA_TEST_CATEGORY(__is_arithmetic, void, false);
+
+SA_TEST_CATEGORY(__is_arithmetic, char, true);
+SA_TEST_CATEGORY(__is_arithmetic, signed char, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned char, true);
+SA_TEST_CATEGORY(__is_arithmetic, wchar_t, true);
+SA_TEST_CATEGORY(__is_arithmetic, short, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned short, true);
+SA_TEST_CATEGORY(__is_arithmetic, int, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned int, true);
+SA_TEST_CATEGORY(__is_arithmetic, long, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned long, true);
+SA_TEST_CATEGORY(__is_arithmetic, long long, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned long long, true);
+SA_TEST_CATEGORY(__is_arithmetic, float, true);
+SA_TEST_CATEGORY(__is_arithmetic, double, true);
+SA_TEST_CATEGORY(__is_arithmetic, long double, true);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_arithmetic, ClassType, false);
-- 
2.42.0



[PATCH v20 35/40] c++: Implement __is_unsigned built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_unsigned.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unsigned.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_UNSIGNED.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_unsigned.
* g++.dg/ext/is_unsigned.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_unsigned.C   | 47 
 5 files changed, 58 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_unsigned.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 3a7f968eae8..c28dad702c3 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3829,6 +3829,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_UNION:
   inform (loc, "  %qT is not a union", t1);
   break;
+case CPTK_IS_UNSIGNED:
+  inform (loc, "  %qT is not an unsigned type", t1);
+  break;
 case CPTK_IS_VOLATILE:
   inform (loc, "  %qT is not a volatile type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b2be7b7bbd7..0603b4a230f 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -94,6 +94,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, 
"__is_trivially_constructible", -1)
 DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
 DEFTRAIT_EXPR (IS_UNBOUNDED_ARRAY, "__is_unbounded_array", 1)
 DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
+DEFTRAIT_EXPR (IS_UNSIGNED, "__is_unsigned", 1)
 DEFTRAIT_EXPR (IS_VOLATILE, "__is_volatile", 1)
 DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_temporary", 2)
 DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, 
"__reference_converts_from_temporary", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index deab0134509..14387821b85 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12250,6 +12250,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_UNION:
   return type_code1 == UNION_TYPE;
 
+case CPTK_IS_UNSIGNED:
+  return TYPE_UNSIGNED (type1);
+
 case CPTK_IS_VOLATILE:
   return CP_TYPE_VOLATILE_P (type1);
 
@@ -12425,6 +12428,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_SCOPED_ENUM:
 case CPTK_IS_UNBOUNDED_ARRAY:
 case CPTK_IS_UNION:
+case CPTK_IS_UNSIGNED:
 case CPTK_IS_VOLATILE:
   break;
 
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 4bc85f4babb..3d380f94b06 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -164,6 +164,9 @@
 #if !__has_builtin (__is_union)
 # error "__has_builtin (__is_union) failed"
 #endif
+#if !__has_builtin (__is_unsigned)
+# error "__has_builtin (__is_unsigned) failed"
+#endif
 #if !__has_builtin (__is_volatile)
 # error "__has_builtin (__is_volatile) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_unsigned.C 
b/gcc/testsuite/g++.dg/ext/is_unsigned.C
new file mode 100644
index 000..2bb45d209a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_unsigned.C
@@ -0,0 +1,47 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+#define SA_TEST_CATEGORY(TRAIT, X, expect) \
+  SA(TRAIT(X) == expect);  \
+  SA(TRAIT(const X) == expect);\
+  SA(TRAIT(volatile X) == expect); \
+  SA(TRAIT(const volatile X) == expect)
+
+SA_TEST_CATEGORY(__is_unsigned, void, false);
+
+SA_TEST_CATEGORY(__is_unsigned, bool, (bool(-1) > bool(0)));
+SA_TEST_CATEGORY(__is_unsigned, char, (char(-1) > char(0)));
+SA_TEST_CATEGORY(__is_unsigned, signed char, false);
+SA_TEST_CATEGORY(__is_unsigned, unsigned char, true);
+SA_TEST_CATEGORY(__is_unsigned, wchar_t, (wchar_t(-1) > wchar_t(0)));
+SA_TEST_CATEGORY(__is_unsigned, short, false);
+SA_TEST_CATEGORY(__is_unsigned, unsigned short, true);
+SA_TEST_CATEGORY(__is_unsigned, int, false);
+SA_TEST_CATEGORY(__is_unsigned, unsigned int, true);
+SA_TEST_CATEGORY(__is_unsigned, long, false);
+SA_TEST_CATEGORY(__is_unsigned, unsigned long, true);
+SA_TEST_CATEGORY(__is_unsigned, long long, false);
+SA_TEST_CATEGORY(__is_unsigned, unsigned long long, true);
+
+SA_TEST_CATEGORY(__is_unsigned, float, false);
+SA_TEST_CATEGORY(__is_unsigned, double, false);
+SA_TEST_CATEGORY(__is_unsigned, long double, false);
+
+#ifndef __STRICT_ANSI__
+// GNU Extensions.
+#ifdef __SIZEOF_INT128__
+SA_TEST_CATEGORY(__is_unsigned, unsigned __int128, true);
+SA_TEST_CATEGORY(__is_unsigned, __int128, false);
+#endif
+
+#ifdef _GLIBCXX_USE_FLOAT128
+SA_TEST_CATEGORY(__is_unsig

[PATCH v20 21/40] libstdc++: Optimize is_member_object_pointer trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_member_object_pointer trait
by dispatching to the new __is_member_object_pointer built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_member_object_pointer): Use
__is_member_object_pointer built-in trait.
(is_member_object_pointer_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index e1b10240dc2..792213ebfe8 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -574,6 +574,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct is_rvalue_reference<_Tp&&>
 : public true_type { };
 
+  /// is_member_object_pointer
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+  template
+struct is_member_object_pointer
+: public __bool_constant<__is_member_object_pointer(_Tp)>
+{ };
+#else
   template
 struct __is_member_object_pointer_helper
 : public false_type { };
@@ -582,11 +589,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 struct __is_member_object_pointer_helper<_Tp _Cp::*>
 : public __not_>::type { };
 
-  /// is_member_object_pointer
+
   template
 struct is_member_object_pointer
 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
 { };
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
   /// is_member_function_pointer
@@ -3227,9 +3235,16 @@ template 
   inline constexpr bool is_rvalue_reference_v = false;
 template 
   inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
+template 
+  inline constexpr bool is_member_object_pointer_v =
+__is_member_object_pointer(_Tp);
+#else
 template 
   inline constexpr bool is_member_object_pointer_v =
 is_member_object_pointer<_Tp>::value;
+#endif
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
 template 
-- 
2.42.0



[PATCH v20 22/40] c++: Implement __is_reference built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_reference.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_reference.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_REFERENCE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_reference.
* g++.dg/ext/is_reference.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/is_reference.C  | 34 
 5 files changed, 45 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_reference.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 98b1f004a68..5cdb59d174e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3787,6 +3787,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_POLYMORPHIC:
   inform (loc, "  %qT is not a polymorphic type", t1);
   break;
+case CPTK_IS_REFERENCE:
+  inform (loc, "  %qT is not a reference", t1);
+  break;
 case CPTK_IS_SAME:
   inform (loc, "  %qT is not the same as %qT", t1, t2);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 11fd70b3964..e867d9c4c47 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -81,6 +81,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, 
"__is_nothrow_convertible", 2)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
+DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 9cbb434d4c2..df720459458 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12211,6 +12211,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_POLYMORPHIC:
   return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
 
+case CPTK_IS_REFERENCE:
+  return type_code1 == REFERENCE_TYPE;
+
 case CPTK_IS_SAME:
   return same_type_p (type1, type2);
 
@@ -12405,6 +12408,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
 case CPTK_IS_MEMBER_OBJECT_POINTER:
 case CPTK_IS_MEMBER_POINTER:
+case CPTK_IS_REFERENCE:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
 case CPTK_IS_UNBOUNDED_ARRAY:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 8d9cdc528cd..e112d317657 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -122,6 +122,9 @@
 #if !__has_builtin (__is_polymorphic)
 # error "__has_builtin (__is_polymorphic) failed"
 #endif
+#if !__has_builtin (__is_reference)
+# error "__has_builtin (__is_reference) failed"
+#endif
 #if !__has_builtin (__is_same)
 # error "__has_builtin (__is_same) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_reference.C 
b/gcc/testsuite/g++.dg/ext/is_reference.C
new file mode 100644
index 000..b5ce4db7afd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_reference.C
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+// Positive tests.
+SA_TEST_CATEGORY(__is_reference, int&, true);
+SA_TEST_CATEGORY(__is_reference, ClassType&, true);
+SA(__is_reference(int(&)(int)));
+SA_TEST_CATEGORY(__is_reference, int&&, true);
+SA_TEST_CATEGORY(__is_reference, ClassType&&, true);
+SA(__is_reference(int(&&)(int)));
+SA_TEST_CATEGORY(__is_reference, IncompleteClass&, true);
+
+// Negative tests
+SA_TEST_CATEGORY(__is_reference, void, false);
+SA_TEST_CATEGORY(__is_reference, int*, false);
+SA_TEST_CATEGORY(__is_reference, int[3], false);
+SA(!__is_reference(int(int)));
+SA(!__is_reference(int(*const)(int)));
+SA(!__is_reference(int(*volatile)(int)));
+SA(!__is_reference(int(*const volatile)(int)));
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_reference, ClassType, false);
+SA_TEST_CATEGORY(__is_reference, IncompleteClass, false);
-- 
2.42.0



[PATCH v20 04/40] c++: Implement __is_const built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_const.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_const.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_CONST.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_const.
* g++.dg/ext/is_const.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 +++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 +++
 gcc/testsuite/g++.dg/ext/is_const.C  | 19 +++
 5 files changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_const.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 722fc334e6f..567dd35fe0a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3723,6 +3723,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_CLASS:
   inform (loc, "  %qT is not a class", t1);
   break;
+case CPTK_IS_CONST:
+  inform (loc, "  %qT is not a const type", t1);
+  break;
 case CPTK_IS_CONSTRUCTIBLE:
   if (!t2)
 inform (loc, "  %qT is not default constructible", t1);
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 0e48e64b8dd..9e4e6d798a0 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
 DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
 DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
 DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
+DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
 DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
 DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
 DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 782aa515da0..23f1d1c249a 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12154,6 +12154,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_CLASS:
   return NON_UNION_CLASS_TYPE_P (type1);
 
+case CPTK_IS_CONST:
+  return CP_TYPE_CONST_P (type1);
+
 case CPTK_IS_CONSTRUCTIBLE:
   return is_xible (INIT_EXPR, type1, type2);
 
@@ -12371,6 +12374,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
   break;
 
 case CPTK_IS_CLASS:
+case CPTK_IS_CONST:
 case CPTK_IS_ENUM:
 case CPTK_IS_SAME:
 case CPTK_IS_UNION:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 2223f08a628..e6e481b13c5 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -65,6 +65,9 @@
 #if !__has_builtin (__is_class)
 # error "__has_builtin (__is_class) failed"
 #endif
+#if !__has_builtin (__is_const)
+# error "__has_builtin (__is_const) failed"
+#endif
 #if !__has_builtin (__is_constructible)
 # error "__has_builtin (__is_constructible) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_const.C 
b/gcc/testsuite/g++.dg/ext/is_const.C
new file mode 100644
index 000..8f2d7c2fce9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_const.C
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+// Positive tests.
+SA(__is_const(const int));
+SA(__is_const(const volatile int));
+SA(__is_const(cClassType));
+SA(__is_const(cvClassType));
+
+// Negative tests.
+SA(!__is_const(int));
+SA(!__is_const(volatile int));
+SA(!__is_const(ClassType));
+SA(!__is_const(vClassType));
-- 
2.42.0



[PATCH v20 07/40] libstdc++: Optimize is_volatile trait performance

2023-10-15 Thread Ken Matsui
This patch optimizes the performance of the is_volatile trait by dispatching
to the new __is_volatile built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_volatile): Use __is_volatile built-in
trait.
(is_volatile_v): Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits | 12 
 1 file changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 686e38e47c3..c01f65df22b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -800,6 +800,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   /// is_volatile
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
+  template
+struct is_volatile
+: public __bool_constant<__is_volatile(_Tp)>
+{ };
+#else
   template
 struct is_volatile
 : public false_type { };
@@ -807,6 +813,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct is_volatile<_Tp volatile>
 : public true_type { };
+#endif
 
   /// is_trivial
   template
@@ -3236,10 +3243,15 @@ template 
   inline constexpr bool is_const_v = true;
 #endif
 
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
+template 
+  inline constexpr bool is_volatile_v = __is_volatile(_Tp);
+#else
 template 
   inline constexpr bool is_volatile_v = false;
 template 
   inline constexpr bool is_volatile_v = true;
+#endif
 
 template 
   inline constexpr bool is_trivial_v = __is_trivial(_Tp);
-- 
2.42.0



[PATCH v20 29/40] c++: Implement __is_pointer built-in trait

2023-10-15 Thread Ken Matsui
This patch implements built-in trait for std::is_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_pointer.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_pointer.
* g++.dg/ext/is_pointer.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |  3 ++
 gcc/cp/cp-trait.def  |  1 +
 gcc/cp/semantics.cc  |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_pointer.C| 51 
 5 files changed, 62 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 99a7e7247ce..c9d627fa782 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3787,6 +3787,9 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_POD:
   inform (loc, "  %qT is not a POD type", t1);
   break;
+case CPTK_IS_POINTER:
+  inform (loc, "  %qT is not a pointer", t1);
+  break;
 case CPTK_IS_POLYMORPHIC:
   inform (loc, "  %qT is not a polymorphic type", t1);
   break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 2add97ae749..c60724e869e 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -81,6 +81,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, 
"__is_nothrow_constructible", -1)
 DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
+DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 168411f6700..83ed674b9d4 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12211,6 +12211,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_POD:
   return pod_type_p (type1);
 
+case CPTK_IS_POINTER:
+  return TYPE_PTR_P (type1);
+
 case CPTK_IS_POLYMORPHIC:
   return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
 
@@ -12412,6 +12415,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
 case CPTK_IS_MEMBER_OBJECT_POINTER:
 case CPTK_IS_MEMBER_POINTER:
+case CPTK_IS_POINTER:
 case CPTK_IS_REFERENCE:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index bcab0599d1a..efce04fd09d 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -122,6 +122,9 @@
 #if !__has_builtin (__is_pod)
 # error "__has_builtin (__is_pod) failed"
 #endif
+#if !__has_builtin (__is_pointer)
+# error "__has_builtin (__is_pointer) failed"
+#endif
 #if !__has_builtin (__is_polymorphic)
 # error "__has_builtin (__is_polymorphic) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_pointer.C 
b/gcc/testsuite/g++.dg/ext/is_pointer.C
new file mode 100644
index 000..d6e39565950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(!__is_pointer(int));
+SA(__is_pointer(int*));
+SA(__is_pointer(int**));
+
+SA(__is_pointer(const int*));
+SA(__is_pointer(const int**));
+SA(__is_pointer(int* const));
+SA(__is_pointer(int** const));
+SA(__is_pointer(int* const* const));
+
+SA(__is_pointer(volatile int*));
+SA(__is_pointer(volatile int**));
+SA(__is_pointer(int* volatile));
+SA(__is_pointer(int** volatile));
+SA(__is_pointer(int* volatile* volatile));
+
+SA(__is_pointer(const volatile int*));
+SA(__is_pointer(const volatile int**));
+SA(__is_pointer(const int* volatile));
+SA(__is_pointer(volatile int* const));
+SA(__is_pointer(int* const volatile));
+SA(__is_pointer(const int** volatile));
+SA(__is_pointer(volatile int** const));
+SA(__is_pointer(int** const volatile));
+SA(__is_pointer(int* const* const volatile));
+SA(__is_pointer(int* volatile* const volatile));
+SA(__is_pointer(int* const volatile* const volatile));
+
+SA(!__is_pointer(int&));
+SA(!__is_pointer(const int&));
+SA(!__is_pointer(volatile int&));
+SA(!__is_pointer(const volatile int&));
+
+SA(!__is_pointer(int&&));
+SA(!__is_pointer(const int&&));
+SA(!__is_pointer(volatile int&&));
+SA(!__is_pointer(const volatile int&&));
+
+SA(!__is_pointer(int[3]));
+SA(!__is_pointer(const int[3]));
+SA(!__is_pointer(volatile int[3]));
+SA(!__is_pointer(const volatile int[3]));
+
+SA(!__is_pointer(int(int)));
+SA(__is_pointer(int(*const)(int)));
+SA(__is_pointer(int(*volatile)(in

[PATCH 0/3] Optimize loongarch vector implementation.

2023-10-15 Thread Jiahao Xu
The following three patches further enhance loongarch’s vectorization 
capabilities.

Patch one add LoongArch support for AVG_CEIL/FLOOR.

Patch 2 add LoongArch support for vec_widen_mult/add/sub_lo/hi patterns.

patch 3 make loongarch use the new vector hooks and implements the costing
function determine_suggested_unroll_factor, to make it be able to suggest the
unroll factor for a given loop being vectorized base vec_ops analysis during
vector costing and the available issue information.The patch also adjusts cost
model through performance analysis.

Jiahao Xu (3):
  LoongArch:Implement avg and sad standard names.
  LoongArch:Implement vec_widen standard names.
  LoongArch:Implement the new vector cost model framework.

 gcc/config/loongarch/genopts/loongarch.opt.in |  15 +-
 gcc/config/loongarch/lasx.md  | 156 -
 gcc/config/loongarch/loongarch-protos.h   |   1 +
 gcc/config/loongarch/loongarch.cc | 309 +-
 gcc/config/loongarch/loongarch.md |   2 +
 gcc/config/loongarch/loongarch.opt|  15 +-
 gcc/config/loongarch/lsx.md   |  74 +
 gcc/doc/invoke.texi   |   7 +
 .../gcc.target/loongarch/avg-ceil-lasx.c  |  22 ++
 .../gcc.target/loongarch/avg-ceil-lsx.c   |  22 ++
 .../gcc.target/loongarch/avg-floor-lasx.c |  22 ++
 .../gcc.target/loongarch/avg-floor-lsx.c  |  22 ++
 gcc/testsuite/gcc.target/loongarch/sad-lasx.c |  20 ++
 gcc/testsuite/gcc.target/loongarch/sad-lsx.c  |  20 ++
 .../gcc.target/loongarch/vect-widen-add.c |  26 ++
 .../gcc.target/loongarch/vect-widen-mul.c |  26 ++
 .../gcc.target/loongarch/vect-widen-sub.c |  26 ++
 17 files changed, 746 insertions(+), 39 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/avg-ceil-lasx.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/avg-ceil-lsx.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/avg-floor-lasx.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/avg-floor-lsx.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/sad-lasx.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/sad-lsx.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/vect-widen-add.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/vect-widen-mul.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/vect-widen-sub.c

-- 
2.20.1



[PATCH 3/3] LoongArch:Implement the new vector cost model framework.

2023-10-15 Thread Jiahao Xu
This patch make loongarch use the new vector hooks and implements the costing
function determine_suggested_unroll_factor, to make it be able to suggest the
unroll factor for a given loop being vectorized base vec_ops analysis during
vector costing and the available issue information. Referring to aarch64 and
rs6000 port.

The patch also reduces the cost of unaligned stores, making it equal to the
cost of aligned ones in order to avoid odd alignment peeling.

gcc/ChangeLog:
* config/loongarch/loongarch.cc (loongarch_vector_costs): Inherit from
vector_costs.  Add a constructor.
(loongarch_vector_costs::add_stmt_cost): Use adjust_cost_for_freq to
adjust the cost for inner loops.
(loongarch_vector_costs::count_operations): New function.
(loongarch_vector_costs::determine_suggested_unroll_factor):Ditto.
(loongarch_vector_costs::finish_cost): Ditto.
(loongarch_builtin_vectorization_cost): Adjust.
* config/loongarch/loongarch.opt (loongarch-vect-unroll-limit): New 
parameter.
(loongarcg-vect-issue-info): Ditto.
(mmemvec-cost): Delete.
* doc/invoke.texi: (loongarcg-vect-unroll-limit): Document new option.

diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in 
b/gcc/config/loongarch/genopts/loongarch.opt.in
index 9f98f2d845a..4a2d7438f1b 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -146,10 +146,6 @@ mbranch-cost=
 Target RejectNegative Joined UInteger Var(loongarch_branch_cost)
 -mbranch-cost=COST Set the cost of branches to roughly COST instructions.
 
-mmemvec-cost=
-Target RejectNegative Joined UInteger Var(loongarch_vector_access_cost) 
IntegerRange(1, 5)
-mmemvec-cost=COST  Set the cost of vector memory access instructions.
-
 mcheck-zero-division
 Target Mask(CHECK_ZERO_DIV)
 Trap on integer divide by zero.
@@ -213,3 +209,14 @@ mrelax
 Target Var(loongarch_mrelax) Init(HAVE_AS_MRELAX_OPTION)
 Take advantage of linker relaxations to reduce the number of instructions
 required to materialize symbol addresses.
+
+-param=loongarch-vect-unroll-limit=
+Target Joined UInteger Var(loongarch_vect_unroll_limit) Init(6) 
IntegerRange(1, 64) Param
+Used to limit unroll factor which indicates how much the autovectorizer may
+unroll a loop.  The default value is 6.
+
+-param=loongarch-vect-issue-info=
+Target Undocumented Joined UInteger Var(loongarch_vect_issue_info) Init(4) 
IntegerRange(1, 64) Param
+Indicate how many non memory access vector instructions can be issued per
+cycle, it's used in unroll factor determination for autovectorizer.  The
+default value is 4.
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 472f8fd37c9..cfd35a63ff1 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -65,6 +65,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "rtl-iter.h"
 #include "opts.h"
 #include "function-abi.h"
+#include "cfgloop.h"
+#include "tree-vectorizer.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -3845,8 +3847,6 @@ loongarch_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
 }
 }
 
-/* Vectorizer cost model implementation.  */
-
 /* Implement targetm.vectorize.builtin_vectorization_cost.  */
 
 static int
@@ -3865,36 +3865,182 @@ loongarch_builtin_vectorization_cost (enum 
vect_cost_for_stmt type_of_cost,
   case vector_load:
   case vec_to_scalar:
   case scalar_to_vec:
-  case cond_branch_not_taken:
-  case vec_promote_demote:
   case scalar_store:
   case vector_store:
return 1;
 
+  case vec_promote_demote:
   case vec_perm:
return LASX_SUPPORTED_MODE_P (mode)
  && !LSX_SUPPORTED_MODE_P (mode) ? 2 : 1;
 
   case unaligned_load:
-  case vector_gather_load:
-   return 2;
-
   case unaligned_store:
-  case vector_scatter_store:
-   return 10;
+   return 2;
 
   case cond_branch_taken:
-   return 3;
+   return 4;
+
+  case cond_branch_not_taken:
+   return 2;
 
   case vec_construct:
elements = TYPE_VECTOR_SUBPARTS (vectype);
-   return elements / 2 + 1;
+   if (ISA_HAS_LASX)
+ return elements + 1;
+   else
+ return elements;
 
   default:
gcc_unreachable ();
 }
 }
 
+class loongarch_vector_costs : public vector_costs
+{
+public:
+  using vector_costs::vector_costs;
+
+  unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
+ stmt_vec_info stmt_info, slp_tree, tree vectype,
+ int misalign,
+ vect_cost_model_location where) override;
+  void finish_cost (const vector_costs *) override;
+
+protected:
+  void count_operations (vect_cost_for_stmt, stmt_vec_info,
+vect_cost_model_location, unsigned int);
+  unsigned int determine_suggested

[PATCH 2/3] LoongArch:Implement vec_widen standard names.

2023-10-15 Thread Jiahao Xu
Add support for vec_widen lo/hi patterns.  These do not directly
match on Loongarch lasx instructions but can be emulated with
even/odd + vector merge.

gcc/ChangeLog:
* config/loongarch/lasx.md (vec_widen_add_hi_, 
vec_widen_add_lo_,
vec_widen_sub_hi_, vec_widen_sub_lo_,
vec_widen_mult_hi_, vec_widen_mult_lo_): New 
patterns.
* config/loongarch/loongarch.cc (loongarch_expand_vec_widen_hilo):New 
function.

gcc/testsuite/ChangeLog:
* gcc.target/loongarch/vect-widen-add.c: New test.
* gcc.target/loongarch/vect-widen-sub.c: New test.
* gcc.target/loongarch/vect-widen-mul.c: New test.

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 483d78bb210..02c6019e1dd 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -5048,23 +5048,71 @@
   [(set_attr "type" "simd_store")
(set_attr "mode" "DI")])
 
-(define_insn "vec_widen_mult_even_v8si"
-  [(set (match_operand:V4DI 0 "register_operand" "=f")
-(mult:V4DI
-  (any_extend:V4DI
-(vec_select:V4SI
-  (match_operand:V8SI 1 "register_operand" "%f")
-  (parallel [(const_int 0) (const_int 2)
- (const_int 4) (const_int 6)])))
-  (any_extend:V4DI
-(vec_select:V4SI
-  (match_operand:V8SI 2 "register_operand" "f")
-  (parallel [(const_int 0) (const_int 2)
- (const_int 4) (const_int 6)])]
-  "ISA_HAS_LASX"
-  "xvmulwev.d.w\t%u0,%u1,%u2"
-  [(set_attr "type" "simd_int_arith")
-   (set_attr "mode" "V4DI")])
+(define_expand "vec_widen_add_hi_"
+  [(match_operand: 0 "register_operand")
+   (any_extend: (match_operand:ILASX_HB 1 "register_operand"))
+   (any_extend: (match_operand:ILASX_HB 2 "register_operand"))]
+  "ISA_HAS_LASX"
+{
+  loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+, true, "add");
+  DONE;
+})
+
+(define_expand "vec_widen_add_lo_"
+  [(match_operand: 0 "register_operand")
+   (any_extend: (match_operand:ILASX_HB 1 "register_operand"))
+   (any_extend: (match_operand:ILASX_HB 2 "register_operand"))]
+  "ISA_HAS_LASX"
+{
+  loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+, false, "add");
+  DONE;
+})
+
+(define_expand "vec_widen_sub_hi_"
+  [(match_operand: 0 "register_operand")
+   (any_extend: (match_operand:ILASX_HB 1 "register_operand"))
+   (any_extend: (match_operand:ILASX_HB 2 "register_operand"))]
+  "ISA_HAS_LASX"
+{
+  loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+, true, "sub");
+  DONE;
+})
+
+(define_expand "vec_widen_sub_lo_"
+  [(match_operand: 0 "register_operand")
+   (any_extend: (match_operand:ILASX_HB 1 "register_operand"))
+   (any_extend: (match_operand:ILASX_HB 2 "register_operand"))]
+  "ISA_HAS_LASX"
+{
+  loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+, false, "sub");
+  DONE;
+})
+
+(define_expand "vec_widen_mult_hi_"
+  [(match_operand: 0 "register_operand")
+   (any_extend: (match_operand:ILASX_HB 1 "register_operand"))
+   (any_extend: (match_operand:ILASX_HB 2 "register_operand"))]
+  "ISA_HAS_LASX"
+{
+  loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+, true, "mult");
+  DONE;
+})
+
+(define_expand "vec_widen_mult_lo_"
+  [(match_operand: 0 "register_operand")
+   (any_extend: (match_operand:ILASX_HB 1 "register_operand"))
+   (any_extend: (match_operand:ILASX_HB 2 "register_operand"))]
+  "ISA_HAS_LASX"
+{
+  loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+, false, "mult");
+  DONE;
+})
 
 ;; Vector reduction operation
 (define_expand "reduc_plus_scal_v4di"
diff --git a/gcc/config/loongarch/loongarch-protos.h 
b/gcc/config/loongarch/loongarch-protos.h
index 251011c5414..72ae9918b09 100644
--- a/gcc/config/loongarch/loongarch-protos.h
+++ b/gcc/config/loongarch/loongarch-protos.h
@@ -205,6 +205,7 @@ extern void loongarch_register_frame_header_opt (void);
 extern void loongarch_expand_vec_cond_expr (machine_mode, machine_mode, rtx *);
 extern void loongarch_expand_vec_cond_mask_expr (machine_mode, machine_mode,
 rtx *);
+extern void loongarch_expand_vec_widen_hilo (rtx, rtx, rtx, bool, bool, const 
char *);
 
 /* Routines implemented in loongarch-c.c.  */
 void loongarch_cpu_cpp_builtins (cpp_reader *);
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 9e1b0d0cfa8..472f8fd37c9 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -8032,6 +8032,142 @@ loongarch_expand_vec_perm_even_odd (struct 
expand_vec_perm_d *d)
   return loongarch_expand_vec_perm_even_odd_1 (d, odd);
 }
 
+static void
+loongarch_expand_vec_interleave (rtx target, rtx op0, rtx op1, bool high_p)
+{
+  struct expand_vec_perm_d d;
+  unsigned i,

[PATCH 1/3] LoongArch:Implement avg and sad standard names.

2023-10-15 Thread Jiahao Xu
gcc/ChangeLog:
* config/loongarch/lasx.md (avg3_floor, uavg3_floor,
avg3_ceil, uavg3_ceil, ssadv16qi, usadv16qi): New patterns.
* config/loongarch/lsx.md (avg3_floor, uavg3_floor,
avg3_ceil, uavg3_ceil, ssadv16qi, usadv16qi): New patterns.

gcc/testsuite/ChangeLog:
* gcc.target/loongarch/avg-ceil-lasx.c: New test.
* gcc.target/loongarch/avg-ceil-lsx.c: New test.
* gcc.target/loongarch/avg-floor-lasx.c: New test.
* gcc.target/loongarch/avg-floor-lsx.c: New test.
* gcc.target/loongarch/sad-lasx.c.c: New test.
* gcc.target/loongarch/sad-lsx.c: New test.

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 2bc5d47ed4a..483d78bb210 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -5171,3 +5171,77 @@
  const0_rtx));
   DONE;
 })
+
+(define_expand "avg3_ceil"
+  [(match_operand:ILASX_WHB 0 "register_operand")
+   (match_operand:ILASX_WHB 1 "register_operand")
+   (match_operand:ILASX_WHB 2 "register_operand")]
+  "ISA_HAS_LASX"
+{
+  emit_insn (gen_lasx_xvavgr_s_ (operands[0], operands[1], 
operands[2]));
+  DONE;
+})
+
+(define_expand "uavg3_ceil"
+  [(match_operand:ILASX_WHB 0 "register_operand")
+   (match_operand:ILASX_WHB 1 "register_operand")
+   (match_operand:ILASX_WHB 2 "register_operand")]
+  "ISA_HAS_LASX"
+{
+  emit_insn (gen_lasx_xvavgr_u_ (operands[0], operands[1], 
operands[2]));
+  DONE;
+})
+
+(define_expand "avg3_floor"
+  [(match_operand:ILASX_WHB 0 "register_operand")
+   (match_operand:ILASX_WHB 1 "register_operand")
+   (match_operand:ILASX_WHB 2 "register_operand")]
+  "ISA_HAS_LASX"
+{
+  emit_insn (gen_lasx_xvavg_s_ (operands[0], operands[1], 
operands[2]));
+  DONE;
+})
+
+(define_expand "uavg3_floor"
+  [(match_operand:ILASX_WHB 0 "register_operand")
+   (match_operand:ILASX_WHB 1 "register_operand")
+   (match_operand:ILASX_WHB 2 "register_operand")]
+  "ISA_HAS_LASX"
+{
+  emit_insn (gen_lasx_xvavg_u_ (operands[0], operands[1], 
operands[2]));
+  DONE;
+})
+
+(define_expand "usadv32qi"
+  [(match_operand:V8SI 0 "register_operand")
+   (match_operand:V32QI 1 "register_operand")
+   (match_operand:V32QI 2 "register_operand")
+   (match_operand:V8SI 3 "register_operand")]
+  "ISA_HAS_LASX"
+{
+  rtx t1 = gen_reg_rtx (V32QImode);
+  rtx t2 = gen_reg_rtx (V16HImode);
+  rtx t3 = gen_reg_rtx (V8SImode);
+  emit_insn (gen_lasx_xvabsd_u_bu (t1, operands[1], operands[2]));
+  emit_insn (gen_lasx_xvhaddw_h_b (t2, t1, t1));
+  emit_insn (gen_lasx_xvhaddw_w_h (t3, t2, t2));
+  emit_insn (gen_addv8si3 (operands[0], t3, operands[3]));
+  DONE;
+})
+
+(define_expand "ssadv32qi"
+  [(match_operand:V8SI 0 "register_operand")
+   (match_operand:V32QI 1 "register_operand")
+   (match_operand:V32QI 2 "register_operand")
+   (match_operand:V8SI 3 "register_operand")]
+  "ISA_HAS_LASX"
+{
+  rtx t1 = gen_reg_rtx (V32QImode);
+  rtx t2 = gen_reg_rtx (V16HImode);
+  rtx t3 = gen_reg_rtx (V8SImode);
+  emit_insn (gen_lasx_xvabsd_s_b (t1, operands[1], operands[2]));
+  emit_insn (gen_lasx_xvhaddw_h_b (t2, t1, t1));
+  emit_insn (gen_lasx_xvhaddw_w_h (t3, t2, t2));
+  emit_insn (gen_addv8si3 (operands[0], t3, operands[3]));
+  DONE;
+})
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index 075f6ba569d..b63c6ff4dee 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -3581,6 +3581,80 @@
   DONE;
 })
 
+(define_expand "avg3_ceil"
+  [(match_operand:ILSX_WHB 0 "register_operand")
+   (match_operand:ILSX_WHB 1 "register_operand")
+   (match_operand:ILSX_WHB 2 "register_operand")]
+  "ISA_HAS_LSX"
+{
+  emit_insn (gen_lsx_vavgr_s_ (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "uavg3_ceil"
+  [(match_operand:ILSX_WHB 0 "register_operand")
+   (match_operand:ILSX_WHB 1 "register_operand")
+   (match_operand:ILSX_WHB 2 "register_operand")]
+  "ISA_HAS_LSX"
+{
+  emit_insn (gen_lsx_vavgr_u_ (operands[0], operands[1], 
operands[2]));
+  DONE;
+})
+
+(define_expand "avg3_floor"
+  [(match_operand:ILSX_WHB 0 "register_operand")
+   (match_operand:ILSX_WHB 1 "register_operand")
+   (match_operand:ILSX_WHB 2 "register_operand")]
+  "ISA_HAS_LSX"
+{
+  emit_insn (gen_lsx_vavg_s_ (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "uavg3_floor"
+  [(match_operand:ILSX_WHB 0 "register_operand")
+   (match_operand:ILSX_WHB 1 "register_operand")
+   (match_operand:ILSX_WHB 2 "register_operand")]
+  "ISA_HAS_LSX"
+{
+  emit_insn (gen_lsx_vavg_u_ (operands[0], operands[1], 
operands[2]));
+  DONE;
+})
+
+(define_expand "usadv16qi"
+  [(match_operand:V4SI 0 "register_operand")
+   (match_operand:V16QI 1 "register_operand")
+   (match_operand:V16QI 2 "register_operand")
+   (match_operand:V4SI 3 "register_operand")]
+  "ISA_HAS_LSX"
+{
+  rtx t1 = gen_reg_rtx (V16QImode);
+  rtx t2 = gen_reg_rtx (V8HImode);
+  rtx t3 = gen_reg_rtx (V4SImode);
+  emit_insn (gen_

[PATCH] [PR31531] MATCH: Improve ~a < ~b and ~a < CST, allow a nop cast inbetween ~ and a/b

2023-10-15 Thread Andrew Pinski
Currently we able to simplify `~a CMP ~b` to `b CMP a` but we should allow a nop
conversion in between the `~` and the `a` which can show up. A similarly thing 
should
be done for `~a CMP CST`.

I had originally submitted the `~a CMP CST` case as
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585088.html;
I noticed we should do the same thing for the `~a CMP ~b` case and combined
it with that one here.

OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

PR tree-optimization/31531

gcc/ChangeLog:

* match.pd (~X op ~Y): Allow for an optional nop convert.
(~X op C): Likewise.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/pr31531-1.c: New test.
* gcc.dg/tree-ssa/pr31531-2.c: New test.
---
 gcc/match.pd  | 10 ---
 gcc/testsuite/gcc.dg/tree-ssa/pr31531-1.c | 19 +
 gcc/testsuite/gcc.dg/tree-ssa/pr31531-2.c | 34 +++
 3 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr31531-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr31531-2.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 51e5065d086..e76ec1ec034 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5944,18 +5944,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* Fold ~X op ~Y as Y op X.  */
 (for cmp (simple_comparison)
  (simplify
-  (cmp (bit_not@2 @0) (bit_not@3 @1))
+  (cmp (nop_convert1?@4 (bit_not@2 @0)) (nop_convert2? (bit_not@3 @1)))
   (if (single_use (@2) && single_use (@3))
-   (cmp @1 @0
+   (with { tree otype = TREE_TYPE (@4); }
+(cmp (convert:otype @1) (convert:otype @0))
 
 /* Fold ~X op C as X op' ~C, where op' is the swapped comparison.  */
 (for cmp (simple_comparison)
  scmp (swapped_simple_comparison)
  (simplify
-  (cmp (bit_not@2 @0) CONSTANT_CLASS_P@1)
+  (cmp (nop_convert? (bit_not@2 @0)) CONSTANT_CLASS_P@1)
   (if (single_use (@2)
&& (TREE_CODE (@1) == INTEGER_CST || TREE_CODE (@1) == VECTOR_CST))
-   (scmp @0 (bit_not @1)
+   (with { tree otype = TREE_TYPE (@1); }
+(scmp (convert:otype @0) (bit_not @1))
 
 (for cmp (simple_comparison)
  (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr31531-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr31531-1.c
new file mode 100644
index 000..c27299151eb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr31531-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/31531 */
+
+int f(int a)
+{
+  int b = ~a;
+  return b<0;
+}
+
+
+int f1(unsigned a)
+{
+  int b = ~a;
+  return b<0;
+}
+/* We should convert the above two functions from b <0 to ((int)a) >= 0. */
+/* { dg-final { scan-tree-dump-times ">= 0" 2 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "~" 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr31531-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr31531-2.c
new file mode 100644
index 000..865ea292215
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr31531-2.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/31531 */
+
+int f0(unsigned x, unsigned t)
+{
+x = ~x;
+t = ~t;
+int xx = x;
+int tt = t;
+return tt < xx;
+}
+
+int f1(unsigned x, int t)
+{
+x = ~x;
+t = ~t;
+int xx = x;
+int tt = t;
+return tt < xx;
+}
+
+int f2(int x, unsigned t)
+{
+x = ~x;
+t = ~t;
+int xx = x;
+int tt = t;
+return tt < xx;
+}
+
+
+/* We should be able to remove all ~ from the above functions. */
+/* { dg-final { scan-tree-dump-times "~" 0 "optimized"} } */
-- 
2.39.3



[PATCH v2] libstdc++: Workaround for LLVM-61763 in ranges

2023-10-15 Thread Benjamin Acker Brock
> I don't think this patch counts as legally significant, but if you contribute 
> again in future you should be aware of 
> https://gcc.gnu.org/contribute.html#legal and either complete the copyright 
> assignment paperwork, or add a DCO sign-off to the commit message.

Thanks for the reminder. I just added a sign-off.

> This should be a complete sentence, so capital letter and full stop.

Fixed!

---

Signed-off-by: Benjamin Brock 

libstdc++-v3/ChangeLog:

* include/std/ranges: Implement workaround for LLVM-61763 in
  zip_view and adjacency_view.

---

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 1d529a886be..7893e3a84c9 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -4632,6 +4632,9 @@ namespace views::__adaptor
   class zip_view<_Vs...>::_Iterator
 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
   {
+#ifdef __clang__ // LLVM-61763 workaround
+  public:
+#endif
 __detail::__tuple_or_pair_t>...> _M_current;

 constexpr explicit
@@ -4652,11 +4655,13 @@ namespace views::__adaptor
return input_iterator_tag{};
 }

+#ifndef __clang__ // LLVM-61763 workaround
 template
   requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
&& regular_invocable<_Fp&, range_reference_t<_Ws>...>
&& std::__detail::__can_reference...>>
   friend class zip_transform_view;
+#endif

   public:
 // iterator_category defined in __zip_view_iter_cat
@@ -5327,6 +5332,9 @@ namespace views::__adaptor
   template
   class adjacent_view<_Vp, _Nm>::_Iterator
   {
+#ifdef __clang__ // LLVM-61763 workaround
+  public:
+#endif
 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
 array, _Nm> _M_current = array, _Nm>();

@@ -5367,12 +5375,14 @@ namespace views::__adaptor

 friend class adjacent_view;

+#ifndef __clang__ // LLVM-61763 workaround
 template
   requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
 && regular_invocable<__detail::__unarize<_Fp&, _Mm>,
range_reference_t<_Wp>>
 && 
std::__detail::__can_reference,

range_reference_t<_Wp>>>
   friend class adjacent_transform_view;
+#endif

   public:
 using iterator_category = input_iterator_tag;


[PATCH] RISC-V: Fix unexpected big LMUL choosing in dynamic LMUL model for non-adjacent load/store

2023-10-15 Thread Juzhe-Zhong
Consider this following case:
int
bar (int *x, int a, int b, int n)
{
  x = __builtin_assume_aligned (x, __BIGGEST_ALIGNMENT__);
  int sum1 = 0;
  int sum2 = 0;
  for (int i = 0; i < n; ++i)
{
  sum1 += x[2*i] - a;
  sum1 += x[2*i+1] * b;
  sum2 += x[2*i] - b;
  sum2 += x[2*i+1] * a;
}
  return sum1 + sum2;
}

Before this patch:

bar:
ble a3,zero,.L5
csrrt0,vlenb
csrra6,vlenb
sllit1,t0,3
vsetvli a5,zero,e32,m4,ta,ma
sub sp,sp,t1
vid.v   v20
vmv.v.x v12,a1
vand.vi v4,v20,1
vmv.v.x v16,a2
vmseq.viv4,v4,1
sllit3,a6,2
vsetvli zero,a5,e32,m4,ta,ma
vmv1r.v v0,v4
viota.m v8,v4
add a7,t3,sp
vsetvli a5,zero,e32,m4,ta,mu
vand.vi v28,v20,-2
vadd.vi v4,v28,1
vs4r.v  v20,0(a7)-  spill
vrgather.vv v24,v12,v8
vrgather.vv v20,v16,v8
vrgather.vv v24,v16,v8,v0.t
vrgather.vv v20,v12,v8,v0.t
vs4r.v  v4,0(sp)  - spill
sllia3,a3,1
addit4,a6,-1
neg t1,a6
vmv4r.v v0,v20
vmv.v.i v4,0
j   .L4
.L13:
vsetvli a5,zero,e32,m4,ta,ma
.L4:
mv  a7,a3
mv  a4,a3
bleua3,a6,.L3
csrra4,vlenb
.L3:
vmv.v.x v8,t4
vl4re32.v   v12,0(sp) spill
vand.vv v20,v28,v8
vand.vv v8,v12,v8
vsetvli zero,a4,e32,m4,ta,ma
vle32.v v16,0(a0)
vsetvli a5,zero,e32,m4,ta,ma
add a3,a3,t1
vrgather.vv v12,v16,v20
add a0,a0,t3
vrgather.vv v20,v16,v8
vsub.vv v12,v12,v0
vsetvli zero,a4,e32,m4,tu,ma
vadd.vv v4,v4,v12
vmacc.vvv4,v24,v20
bgtua7,a6,.L13
csrra1,vlenb
sllia1,a1,2
add a1,a1,sp
li  a4,-1
csrrt0,vlenb
vsetvli a5,zero,e32,m4,ta,ma
vl4re32.v   v12,0(a1)    spill
vmv.v.i v8,0
vmul.vx v0,v12,a4
li  a2,0
sllit1,t0,3
vadd.vi v0,v0,-1
vand.vi v0,v0,1
vmseq.vvv0,v0,v8
vand.vi v12,v12,1
vmerge.vvm  v16,v8,v4,v0
vmseq.vvv12,v12,v8
vmv.s.x v1,a2
vmv1r.v v0,v12
vredsum.vs  v16,v16,v1
vmerge.vvm  v8,v8,v4,v0
vmv.x.s a0,v16
vredsum.vs  v8,v8,v1
vmv.x.s a5,v8
add sp,sp,t1
addwa0,a0,a5
jr  ra
.L5:
li  a0,0
ret

We can there are multiple horrible register spillings.
The root cause of this issue is for a scalar IR load:

_5 = *_4;

We didn't check whether it is a continguous load/store or gather/scatter 
load/store

Since it will be translate into:

   1. MASK_LEN_GATHER_LOAD (..., perm indice).
   2. Continguous load/store + VEC_PERM (..., perm indice)

It's obvious that no matter which situation, we will end up with consuming one 
vector register group (perm indice)
that we didn't count it before.

So this case we pick LMUL = 4 which is incorrect choice for dynamic LMUL cost 
model.

The key of this patch is:

  if ((type == load_vec_info_type || type == store_vec_info_type)
  && !adjacent_dr_p (STMT_VINFO_DATA_REF (stmt_info)))
{
   ...
}

Add one more register consumption if it is not an adjacent load/store.

After this patch, it pick LMUL = 2 which is optimal:

bar:
ble a3,zero,.L4
csrra6,vlenb
vsetvli a5,zero,e32,m2,ta,ma
vmv.v.x v6,a2
srlia2,a6,1
vmv.v.x v4,a1
vid.v   v12
sllia3,a3,1
vand.vi v0,v12,1
addit1,a2,-1
vmseq.viv0,v0,1
sllia6,a6,1
vsetvli zero,a5,e32,m2,ta,ma
neg a7,a2
viota.m v2,v0
vsetvli a5,zero,e32,m2,ta,mu
vrgather.vv v16,v4,v2
vrgather.vv v14,v6,v2
vrgather.vv v16,v6,v2,v0.t
vrgather.vv v14,v4,v2,v0.t
vand.vi v18,v12,-2
vmv.v.i v2,0
vadd.vi v20,v18,1
.L3:
minua4,a3,a2
vsetvli zero,a4,e32,m2,ta,ma
vle32.v v8,0(a0)
vsetvli a5,zero,e32,m2,ta,ma
vmv.v.x v4,t1
vand.vv v10,v18,v4
vrgather.vv v6,v8,v10
vsub.vv v6,v6,v14
vsetvli zero,a4,e32,m2,tu,ma
vadd.vv v2,v2,v6
vsetvli a1,zero,e32,m2,ta,ma
vand.vv v4,v20,v4
vrgather.vv v6,v8,v4
vsetvli zero,a4,e32,m2,tu,ma
mv  a4,a3
add a0,a0,a6
add a3,a3,a7
vmacc.vvv2,v16,v6
bgtua4,a2,.L3
vsetvli a1,zero,e32,m2,ta,ma
vand.vi v0,v12,1
vmv.v.i v4,0
li  a3,

[PATCH] Do not prepend target triple to -fuse-ld=lld,mold.

2023-10-15 Thread Tatsuyuki Ishi
lld and mold are platform-agnostic and not prefixed with target triple.
Prepending the target triple makes it less likely to find the intended
linker executable.

A potential breaking change is that we no longer try to search for
triple-prefixed lld/mold binaries anymore. However, since there doesn't
seem to be support to build LLVM or mold with triple-prefixed executable
names, it seems better to just not bother with that case.

PR driver/111605

gcc/Changelog:

* collect2.cc (main): Do not prepend target triple to
-fuse-ld=lld,mold.
---
 gcc/collect2.cc | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/gcc/collect2.cc b/gcc/collect2.cc
index 63b9a0c233a..c943f9f577c 100644
--- a/gcc/collect2.cc
+++ b/gcc/collect2.cc
@@ -865,12 +865,15 @@ main (int argc, char **argv)
   int i;
 
   for (i = 0; i < USE_LD_MAX; i++)
-full_ld_suffixes[i]
 #ifdef CROSS_DIRECTORY_STRUCTURE
-  = concat (target_machine, "-", ld_suffixes[i], NULL);
-#else
-  = ld_suffixes[i];
-#endif
+/* lld and mold are platform-agnostic and not prefixed with target
+   triple.  */
+if (!(i == USE_LLD_LD || i == USE_MOLD_LD))
+  full_ld_suffixes[i] = concat (target_machine, "-", ld_suffixes[i],
+   NULL);
+else
+#endif
+  full_ld_suffixes[i] = ld_suffixes[i];
 
   p = argv[0] + strlen (argv[0]);
   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
-- 
2.42.0



Re: [PATCH] Do not prepend target triple to -fuse-ld=lld,mold.

2023-10-15 Thread Sam James


Tatsuyuki Ishi  writes:

> lld and mold are platform-agnostic and not prefixed with target triple.
> Prepending the target triple makes it less likely to find the intended
> linker executable.
>
> A potential breaking change is that we no longer try to search for
> triple-prefixed lld/mold binaries anymore. However, since there doesn't
> seem to be support to build LLVM or mold with triple-prefixed executable
> names, it seems better to just not bother with that case.
>

We do provide those symlinks for LLVM in Gentoo, but we don't for mold.


>   PR driver/111605
>
> gcc/Changelog:
>
>   * collect2.cc (main): Do not prepend target triple to
>   -fuse-ld=lld,mold.
> ---
>  gcc/collect2.cc | 13 -
>  1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/gcc/collect2.cc b/gcc/collect2.cc
> index 63b9a0c233a..c943f9f577c 100644
> --- a/gcc/collect2.cc
> +++ b/gcc/collect2.cc
> @@ -865,12 +865,15 @@ main (int argc, char **argv)
>int i;
>  
>for (i = 0; i < USE_LD_MAX; i++)
> -full_ld_suffixes[i]
>  #ifdef CROSS_DIRECTORY_STRUCTURE
> -  = concat (target_machine, "-", ld_suffixes[i], NULL);
> -#else
> -  = ld_suffixes[i];
> -#endif
> +/* lld and mold are platform-agnostic and not prefixed with target
> +   triple.  */
> +if (!(i == USE_LLD_LD || i == USE_MOLD_LD))
> +  full_ld_suffixes[i] = concat (target_machine, "-", ld_suffixes[i],
> + NULL);
> +else
> +#endif
> +  full_ld_suffixes[i] = ld_suffixes[i];
>  
>p = argv[0] + strlen (argv[0]);
>while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))



[PATCH 0/3] Add Intel new cpu archs

2023-10-15 Thread Haochen Jiang
Hi all,

The patches aim to add new cpu archs Clear Water Forest and
Panther Lake. Here comes the documentation:

https://cdrdv2.intel.com/v1/dl/getContent/671368

Also in the patches, I refactored how we detect cpu according to features
and added m_CORE_ATOM.

Regtested on x86_64-pc-linux-gnu. Ok for trunk?

Thx,
Haochen




[PATCH 2/3] x86: Add m_CORE_HYBRID for hybrid clients tuning

2023-10-15 Thread Haochen Jiang
gcc/Changelog:

* config/i386/i386-options.cc (m_CORE_HYBRID): New.
* config/i386/x86-tune.def: Replace hybrid client tune to
m_CORE_HYBRID.
---
 gcc/config/i386/i386-options.cc |   1 +
 gcc/config/i386/x86-tune.def| 113 ++--
 2 files changed, 52 insertions(+), 62 deletions(-)

diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index 1d28258b4fa..952cfe54da0 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -143,6 +143,7 @@ along with GCC; see the file COPYING3.  If not see
 #define m_ARROWLAKE_S (HOST_WIDE_INT_1U<> (W-1) ^ x) -
@@ -386,8 +381,7 @@ DEF_TUNE (X86_TUNE_USE_SIMODE_FIOP, "use_simode_fiop",
   ~(m_PENT | m_LAKEMONT | m_PPRO | m_CORE_ALL | m_BONNELL
| m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_AMD_MULTIPLE
| m_LUJIAZUI | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT
-   | m_ALDERLAKE | m_ARROWLAKE | m_ARROWLAKE_S | m_CORE_ATOM
-   | m_GENERIC))
+   | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC))
 
 /* X86_TUNE_USE_FFREEP: Use freep instruction instead of fstp.  */
 DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE | m_LUJIAZUI)
@@ -396,8 +390,8 @@ DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE 
| m_LUJIAZUI)
 DEF_TUNE (X86_TUNE_EXT_80387_CONSTANTS, "ext_80387_constants",
   m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BONNELL | m_SILVERMONT
  | m_KNL | m_KNM | m_INTEL | m_K6_GEODE | m_ATHLON_K8 | m_LUJIAZUI
- | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE | m_ARROWLAKE
- | m_ARROWLAKE_S | m_CORE_ATOM | m_GENERIC)
+ | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID
+ | m_CORE_ATOM | m_GENERIC)
 
 /*/
 /* SSE instruction selection tuning  */
@@ -412,17 +406,16 @@ DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, 
"general_regs_sse_spill",
of a sequence loading registers by parts.  */
 DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal",
  m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM
- | m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE
- | m_ARROWLAKE | m_ARROWLAKE_S | m_CORE_ATOM | m_AMDFAM10 | m_BDVER
- | m_BTVER | m_ZNVER | m_LUJIAZUI | m_GENERIC)
+ | m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID
+ | m_CORE_ATOM | m_AMDFAM10 | m_BDVER | m_BTVER | m_ZNVER | m_LUJIAZUI
+ | m_GENERIC)
 
 /* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL: Use movups for misaligned stores
instead of a sequence loading registers by parts.  */
 DEF_TUNE (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, "sse_unaligned_store_optimal",
  m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM
- | m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE
- | m_ARROWLAKE | m_ARROWLAKE_S| m_CORE_ATOM | m_BDVER | m_ZNVER
- | m_LUJIAZUI | m_GENERIC)
+ | m_INTEL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_CORE_HYBRID
+ | m_CORE_ATOM | m_BDVER | m_ZNVER | m_LUJIAZUI | m_GENERIC)
 
 /* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL: Use packed single
precision 128bit instructions instead of double where possible.   */
@@ -431,15 +424,14 @@ DEF_TUNE (X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL, 
"sse_packed_single_insn_optim
 
 /* X86_TUNE_SSE_TYPELESS_STORES: Always movaps/movups for 128bit stores.   */
 DEF_TUNE (X86_TUNE_SSE_TYPELESS_STORES, "sse_typeless_stores",
- m_AMD_MULTIPLE | m_LUJIAZUI | m_CORE_ALL | m_TREMONT | m_ALDERLAKE
- | m_ARROWLAKE | m_ARROWLAKE_S | m_CORE_ATOM | m_GENERIC)
+ m_AMD_MULTIPLE | m_LUJIAZUI | m_CORE_ALL | m_TREMONT | m_CORE_HYBRID
+ | m_CORE_ATOM | m_GENERIC)
 
 /* X86_TUNE_SSE_LOAD0_BY_PXOR: Always use pxor to load0 as opposed to
xorps/xorpd and other variants.  */
 DEF_TUNE (X86_TUNE_SSE_LOAD0_BY_PXOR, "sse_load0_by_pxor",
  m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_BDVER | m_BTVER | m_ZNVER
- | m_LUJIAZUI | m_TREMONT | m_ALDERLAKE | m_ARROWLAKE | m_ARROWLAKE_S
- | m_CORE_ATOM | m_GENERIC)
+ | m_LUJIAZUI | m_TREMONT | m_CORE_HYBRID | m_CORE_ATOM | m_GENERIC)
 
 /* X86_TUNE_INTER_UNIT_MOVES_TO_VEC: Enable moves in from integer
to SSE registers.  If disabled, the moves will be done by storing
@@ -485,14 +477,14 @@ DEF_TUNE (X86_TUNE_SLOW_PSHUFB, "slow_pshufb",
 
 /* X86_TUNE_AVOID_4BYTE_PREFIXES: Avoid instructions requiring 4+ bytes of 
prefixes.  */
 DEF_TUNE (X86_TUNE_AVOID_4BYTE_PREFIXES, "avoid_4byte_prefixes",
- m_SILVERMONT | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_ALDERLAKE
- | m_ARROWLAKE | m_ARROWLAKE_S | m_CORE_ATOM | m_INTEL)
+ m_SILVERMONT | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | 
m_CORE_HYBRID
+ | m_CORE_ATOM | m_INTEL)
 
 /* X86_TUNE

[PATCH 1/3] Initial Clear Water Forest Support

2023-10-15 Thread Haochen Jiang
gcc/ChangeLog:

* common/config/i386/cpuinfo.h
(get_intel_cpu): Handle Clear Water Forest.
* common/config/i386/i386-common.cc (processor_name):
Add Clear Water Forest.
(processor_alias_table): Ditto.
* common/config/i386/i386-cpuinfo.h (enum processor_types):
Add INTEL_CLEARWATERFOREST.
* config.gcc: Add -march=clearwaterforest.
* config/i386/driver-i386.cc (host_detect_local_cpu): Handle
clearwaterforest.
* config/i386/i386-c.cc (ix86_target_macros_internal): Ditto.
* config/i386/i386-options.cc (processor_cost_table): Ditto.
(m_CLEARWATERFOREST): New.
(m_CORE_ATOM): Add clearwaterforest.
* config/i386/i386.h (enum processor_type): Ditto.
* doc/extend.texi: Ditto.
* doc/invoke.texi: Ditto.

gcc/testsuite/ChangeLog:

* g++.target/i386/mv16.C: Ditto.
* gcc.target/i386/funcspec-56.inc: Handle new march.
---
 gcc/common/config/i386/cpuinfo.h  | 6 ++
 gcc/common/config/i386/i386-common.cc | 3 +++
 gcc/common/config/i386/i386-cpuinfo.h | 1 +
 gcc/config.gcc| 2 +-
 gcc/config/i386/driver-i386.cc| 5 -
 gcc/config/i386/i386-c.cc | 7 +++
 gcc/config/i386/i386-options.cc   | 4 +++-
 gcc/config/i386/i386.h| 3 +++
 gcc/doc/extend.texi   | 3 +++
 gcc/doc/invoke.texi   | 9 +
 gcc/testsuite/g++.target/i386/mv16.C  | 6 ++
 gcc/testsuite/gcc.target/i386/funcspec-56.inc | 1 +
 12 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 0f86b44730b..57394a18c67 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -608,6 +608,12 @@ get_intel_cpu (struct __processor_model *cpu_model,
   cpu_model->__cpu_type = INTEL_COREI7;
   cpu_model->__cpu_subtype = INTEL_COREI7_ARROWLAKE_S;
   break;
+case 0xdd:
+  /* Clear Water Forest.  */
+  cpu = "clearwaterforest";
+  CHECK___builtin_cpu_is ("clearwaterforest");
+  cpu_model->__cpu_type = INTEL_CLEARWATERFOREST;
+  break;
 case 0x17:
 case 0x1d:
   /* Penryn.  */
diff --git a/gcc/common/config/i386/i386-common.cc 
b/gcc/common/config/i386/i386-common.cc
index 13e423deceb..903034d2afd 100644
--- a/gcc/common/config/i386/i386-common.cc
+++ b/gcc/common/config/i386/i386-common.cc
@@ -2077,6 +2077,7 @@ const char *const processor_names[] =
   "tremont",
   "sierraforest",
   "grandridge",
+  "clearwaterforest",
   "knl",
   "knm",
   "skylake",
@@ -2246,6 +2247,8 @@ const pta processor_alias_table[] =
 M_CPU_SUBTYPE (INTEL_SIERRAFOREST), P_PROC_AVX2},
   {"grandridge", PROCESSOR_GRANDRIDGE, CPU_HASWELL, PTA_GRANDRIDGE,
 M_CPU_TYPE (INTEL_GRANDRIDGE), P_PROC_AVX2},
+  {"clearwaterforest", PROCESSOR_CLEARWATERFOREST, CPU_HASWELL,
+PTA_CLEARWATERFOREST, M_CPU_TYPE (INTEL_CLEARWATERFOREST), P_PROC_AVX2},
   {"knl", PROCESSOR_KNL, CPU_SLM, PTA_KNL,
 M_CPU_TYPE (INTEL_KNL), P_PROC_AVX512F},
   {"knm", PROCESSOR_KNM, CPU_SLM, PTA_KNM,
diff --git a/gcc/common/config/i386/i386-cpuinfo.h 
b/gcc/common/config/i386/i386-cpuinfo.h
index 47e9dcfb8f7..44db6a07076 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -62,6 +62,7 @@ enum processor_types
   ZHAOXIN_FAM7H,
   INTEL_SIERRAFOREST,
   INTEL_GRANDRIDGE,
+  INTEL_CLEARWATERFOREST,
   CPU_TYPE_MAX,
   BUILTIN_CPU_TYPE_MAX = CPU_TYPE_MAX
 };
diff --git a/gcc/config.gcc b/gcc/config.gcc
index fa192637a52..2d045d6d00f 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -708,7 +708,7 @@ skylake goldmont goldmont-plus tremont cascadelake 
tigerlake cooperlake \
 sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 
\
 nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 \
 sierraforest graniterapids graniterapids-d grandridge arrowlake arrowlake-s \
-native"
+clearwaterforest native"
 
 # Additional x86 processors supported by --with-cpu=.  Each processor
 # MUST be separated by exactly one space.
diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc
index 08d0aed6183..a21f2dfe82f 100644
--- a/gcc/config/i386/driver-i386.cc
+++ b/gcc/config/i386/driver-i386.cc
@@ -591,8 +591,11 @@ const char *host_detect_local_cpu (int argc, const char 
**argv)
  /* This is unknown family 0x6 CPU.  */
  if (has_feature (FEATURE_AVX))
{
+ /* Assume Clear Water Forest.  */
+ if (has_feature (FEATURE_USER_MSR))
+   cpu = "clearwaterforest";
  /* Assume Arrow Lake S.  */
- if (has_feature (FEATURE_SM3))
+ else if (has_feature (FEATURE_SM3))
cpu = "arrowlake-s";

[PATCH 3/3] Initial Panther Lake Support

2023-10-15 Thread Haochen Jiang
gcc/ChangeLog:

* common/config/i386/i386-common.cc (processor_name):
Add Panther Lake.
(processor_alias_table): Ditto.
* common/config/i386/i386-cpuinfo.h (enum processor_types):
Add INTEL_PANTHERLAKE.
* config.gcc: Add -march=pantherlake.
* config/i386/driver-i386.cc (host_detect_local_cpu): Refactor
the if clause. Handle pantherlake.
* config/i386/i386-c.cc (ix86_target_macros_internal):
Handle pantherlake.
* config/i386/i386-options.cc (processor_cost_table): Ditto.
(m_PANTHERLAKE): New.
(m_CORE_HYBRID): Add pantherlake.
* config/i386/i386.h (enum processor_type): Ditto.
* doc/extend.texi: Ditto.
* doc/invoke.texi: Ditto.

gcc/testsuite/ChangeLog:

* g++.target/i386/mv16.C: Ditto.
* gcc.target/i386/funcspec-56.inc: Handle new march.
---
 gcc/common/config/i386/cpuinfo.h  |  8 ++
 gcc/common/config/i386/i386-common.cc |  3 +
 gcc/common/config/i386/i386-cpuinfo.h |  1 +
 gcc/config.gcc|  2 +-
 gcc/config/i386/driver-i386.cc| 92 ++-
 gcc/config/i386/i386-c.cc |  7 ++
 gcc/config/i386/i386-options.cc   |  5 +-
 gcc/config/i386/i386.h|  2 +
 gcc/doc/extend.texi   |  3 +
 gcc/doc/invoke.texi   |  9 ++
 gcc/testsuite/g++.target/i386/mv16.C  |  6 ++
 gcc/testsuite/gcc.target/i386/funcspec-56.inc |  1 +
 12 files changed, 94 insertions(+), 45 deletions(-)

diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 57394a18c67..f7060ed7254 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -614,6 +614,14 @@ get_intel_cpu (struct __processor_model *cpu_model,
   CHECK___builtin_cpu_is ("clearwaterforest");
   cpu_model->__cpu_type = INTEL_CLEARWATERFOREST;
   break;
+case 0xcc:
+  /* Panther Lake.  */
+  cpu = "pantherlake";
+  CHECK___builtin_cpu_is ("corei7");
+  CHECK___builtin_cpu_is ("pantherlake");
+  cpu_model->__cpu_type = INTEL_COREI7;
+  cpu_model->__cpu_subtype = INTEL_COREI7_PANTHERLAKE;
+  break;
 case 0x17:
 case 0x1d:
   /* Penryn.  */
diff --git a/gcc/common/config/i386/i386-common.cc 
b/gcc/common/config/i386/i386-common.cc
index 903034d2afd..79b1b35ad6c 100644
--- a/gcc/common/config/i386/i386-common.cc
+++ b/gcc/common/config/i386/i386-common.cc
@@ -2095,6 +2095,7 @@ const char *const processor_names[] =
   "graniterapids-d",
   "arrowlake",
   "arrowlake-s",
+  "pantherlake",
   "intel",
   "lujiazui",
   "geode",
@@ -2227,6 +2228,8 @@ const pta processor_alias_table[] =
 M_CPU_SUBTYPE (INTEL_COREI7_ARROWLAKE_S), P_PROC_AVX2},
   {"lunarlake", PROCESSOR_ARROWLAKE_S, CPU_HASWELL, PTA_ARROWLAKE_S,
 M_CPU_SUBTYPE (INTEL_COREI7_ARROWLAKE_S), P_PROC_AVX2},
+  {"pantherlake", PROCESSOR_PANTHERLAKE, CPU_HASWELL, PTA_PANTHERLAKE,
+M_CPU_SUBTYPE (INTEL_COREI7_PANTHERLAKE), P_PROC_AVX2},
   {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL,
 M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3},
   {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL,
diff --git a/gcc/common/config/i386/i386-cpuinfo.h 
b/gcc/common/config/i386/i386-cpuinfo.h
index 44db6a07076..533b7481c16 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -102,6 +102,7 @@ enum processor_subtypes
   INTEL_COREI7_GRANITERAPIDS_D,
   INTEL_COREI7_ARROWLAKE,
   INTEL_COREI7_ARROWLAKE_S,
+  INTEL_COREI7_PANTHERLAKE,
   CPU_SUBTYPE_MAX
 };
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 2d045d6d00f..37311fcd075 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -708,7 +708,7 @@ skylake goldmont goldmont-plus tremont cascadelake 
tigerlake cooperlake \
 sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 
\
 nano-x2 eden-x4 nano-x4 lujiazui x86-64 x86-64-v2 x86-64-v3 x86-64-v4 \
 sierraforest graniterapids graniterapids-d grandridge arrowlake arrowlake-s \
-clearwaterforest native"
+clearwaterforest pantherlake native"
 
 # Additional x86 processors supported by --with-cpu=.  Each processor
 # MUST be separated by exactly one space.
diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc
index a21f2dfe82f..2b4d6afe8db 100644
--- a/gcc/config/i386/driver-i386.cc
+++ b/gcc/config/i386/driver-i386.cc
@@ -589,26 +589,14 @@ const char *host_detect_local_cpu (int argc, const char 
**argv)
  if (arch)
{
  /* This is unknown family 0x6 CPU.  */
- if (has_feature (FEATURE_AVX))
+ if (has_feature (FEATURE_AVX512F))
{
- /* Assume Clear Water Forest.  */
- if (has_feature (FEATURE_USER_MSR))
-   cpu = "clearwaterforest";
- /* Assume Arrow Lake S.  */
-