Re: [PATCH] use get_range_query to replace get_global_range_query

2023-10-10 Thread Richard Biener
On Tue, 10 Oct 2023, Jiufu Guo wrote:

> Hi,
> 
> For "get_global_range_query" SSA_NAME_RANGE_INFO can be queried.
> For "get_range_query", it could get more context-aware range info.
> And look at the implementation of "get_range_query",  it returns
> global range if no local fun info.
> 
> So, if not quering for SSA_NAME, it would be ok to use get_range_query
> to replace get_global_range_query.
> 
> Patch https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630389.html,
> Uses get_range_query could handle more cases.
> 
> This patch replaces get_global_range_query by get_range_query for
> most possible code pieces (but deoes not draft new test cases).
> 
> Pass bootstrap & regtest on ppc64{,le} and x86_64.
> Is this ok for trunk.

See below

> 
> BR,
> Jeff (Jiufu Guo)
> 
> gcc/ChangeLog:
> 
>   * builtins.cc (expand_builtin_strnlen): Replace get_global_range_query
>   by get_range_query.
>   * fold-const.cc (expr_not_equal_to): Likewise.
>   * gimple-fold.cc (size_must_be_zero_p): Likewise.
>   * gimple-range-fold.cc (fur_source::fur_source): Likewise.
>   * gimple-ssa-warn-access.cc (check_nul_terminated_array): Likewise.
>   * tree-dfa.cc (get_ref_base_and_extent): Likewise.
>   * tree-ssa-loop-split.cc (split_at_bb_p): Likewise.
>   * tree-ssa-loop-unswitch.cc (evaluate_control_stmt_using_entry_checks):
>   Likewise.
> 
> ---
>  gcc/builtins.cc   | 2 +-
>  gcc/fold-const.cc | 6 +-
>  gcc/gimple-fold.cc| 6 ++
>  gcc/gimple-range-fold.cc  | 4 +---
>  gcc/gimple-ssa-warn-access.cc | 2 +-
>  gcc/tree-dfa.cc   | 5 +
>  gcc/tree-ssa-loop-split.cc| 2 +-
>  gcc/tree-ssa-loop-unswitch.cc | 2 +-
>  8 files changed, 9 insertions(+), 20 deletions(-)
> 
> diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> index cb90bd03b3e..4e0a77ff8e0 100644
> --- a/gcc/builtins.cc
> +++ b/gcc/builtins.cc
> @@ -3477,7 +3477,7 @@ expand_builtin_strnlen (tree exp, rtx target, 
> machine_mode target_mode)
>  
>wide_int min, max;
>value_range r;
> -  get_global_range_query ()->range_of_expr (r, bound);
> +  get_range_query (cfun)->range_of_expr (r, bound);

expand doesn't have a ranger instance so this is a no-op.  I'm unsure
if it would be safe given we're half GIMPLE, half RTL.  Please leave it
out.

>if (r.varying_p () || r.undefined_p ())
>  return NULL_RTX;
>min = r.lower_bound ();
> diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
> index 4f8561509ff..15134b21b9f 100644
> --- a/gcc/fold-const.cc
> +++ b/gcc/fold-const.cc
> @@ -11056,11 +11056,7 @@ expr_not_equal_to (tree t, const wide_int &w)
>if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
>   return false;
>  
> -  if (cfun)
> - get_range_query (cfun)->range_of_expr (vr, t);
> -  else
> - get_global_range_query ()->range_of_expr (vr, t);
> -
> +  get_range_query (cfun)->range_of_expr (vr, t);

These kind of changes look obvious.

>if (!vr.undefined_p () && !vr.contains_p (w))
>   return true;
>/* If T has some known zero bits and W has any of those bits set,
> diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
> index dc89975270c..853edd9e5d4 100644
> --- a/gcc/gimple-fold.cc
> +++ b/gcc/gimple-fold.cc
> @@ -876,10 +876,8 @@ size_must_be_zero_p (tree size)
>wide_int zero = wi::zero (TYPE_PRECISION (type));
>value_range valid_range (type, zero, ssize_max);
>value_range vr;
> -  if (cfun)
> -get_range_query (cfun)->range_of_expr (vr, size);
> -  else
> -get_global_range_query ()->range_of_expr (vr, size);
> +  get_range_query (cfun)->range_of_expr (vr, size);
> +
>if (vr.undefined_p ())
>  vr.set_varying (TREE_TYPE (size));
>vr.intersect (valid_range);
> diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
> index d1945ccb554..6e9530c3d7f 100644
> --- a/gcc/gimple-range-fold.cc
> +++ b/gcc/gimple-range-fold.cc
> @@ -50,10 +50,8 @@ fur_source::fur_source (range_query *q)
>  {
>if (q)
>  m_query = q;
> -  else if (cfun)
> -m_query = get_range_query (cfun);
>else
> -m_query = get_global_range_query ();
> +m_query = get_range_query (cfun);
>m_gori = NULL;
>  }
>  
> diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
> index fcaff128d60..e439d1b9b68 100644
> --- a/gcc/gimple-ssa-warn-access.cc
> +++ b/gcc/gimple-ssa-warn-access.cc
> @@ -332,7 +332,7 @@ check_nul_terminated_array (GimpleOrTree expr, tree src, 
> tree bound)
>  {
>Value_Range r (TREE_TYPE (bound));
>  
> -  get_global_range_query ()->range_of_expr (r, bound);
> +  get_range_query (cfun)->range_of_expr (r, bound);
>  
>if (r.undefined_p () || r.varying_p ())
>   return true;

The pass has a ranger instance, so yes, this should improve things.
Since the pass doesn't do any IL modification it should also be safe.

> diff --git a/gcc/tree-dfa.cc b/gcc/tree-dfa.cc
> index af8e9243947..5355af2c869 100644
> --- a/gcc/tree-df

[PATCH] [x86] Refine predicate of operands[2] in divv4hf3 with register_operand.

2023-10-10 Thread liuhongt
In the expander, it will emit below insn.

rtx tmp = gen_rtx_VEC_CONCAT (V4SFmode, operands[2],
force_reg (V2SFmode, CONST1_RTX (V2SFmode)));

but *vec_concat only allow register_operand.

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
Ready push to trunk.

gcc/ChangeLog:

PR target/111745
* config/i386/mmx.md (divv4hf3): Refine predicate of
operands[2] with register_operand.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr111745.c: New test.
---
 gcc/config/i386/mmx.md   |  2 +-
 gcc/testsuite/gcc.target/i386/pr111745.c | 18 ++
 2 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr111745.c

diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index c84a37a8444..4707cfae93f 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -1950,7 +1950,7 @@ (define_expand "divv4hf3"
   [(set (match_operand:V4HF 0 "register_operand")
(div:V4HF
  (match_operand:V4HF 1 "nonimmediate_operand")
- (match_operand:V4HF 2 "nonimmediate_operand")))]
+ (match_operand:V4HF 2 "register_operand")))]
   "TARGET_AVX512FP16 && TARGET_AVX512VL && ix86_partial_vec_fp_math"
 {
   rtx op2 = gen_reg_rtx (V8HFmode);
diff --git a/gcc/testsuite/gcc.target/i386/pr111745.c 
b/gcc/testsuite/gcc.target/i386/pr111745.c
new file mode 100644
index 000..e8989d96abf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr111745.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512fp16 -mavx512vl -ffloat-store -O2" } */
+
+char c;
+_Float16 __attribute__((__vector_size__ (4 * sizeof (_Float16 f;
+_Float16 __attribute__((__vector_size__ (2 * sizeof (_Float16 f1;
+
+void
+foo (void)
+{
+  f /= c;
+}
+
+void
+foo1 (void)
+{
+  f1 /= c;
+}
-- 
2.31.1



Re: [PATCH] use get_range_query to replace get_global_range_query

2023-10-10 Thread Andrew Pinski
On Tue, Oct 10, 2023 at 12:02 AM Richard Biener  wrote:
>
> On Tue, 10 Oct 2023, Jiufu Guo wrote:
>
> > Hi,
> >
> > For "get_global_range_query" SSA_NAME_RANGE_INFO can be queried.
> > For "get_range_query", it could get more context-aware range info.
> > And look at the implementation of "get_range_query",  it returns
> > global range if no local fun info.
> >
> > So, if not quering for SSA_NAME, it would be ok to use get_range_query
> > to replace get_global_range_query.
> >
> > Patch https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630389.html,
> > Uses get_range_query could handle more cases.
> >
> > This patch replaces get_global_range_query by get_range_query for
> > most possible code pieces (but deoes not draft new test cases).
> >
> > Pass bootstrap & regtest on ppc64{,le} and x86_64.
> > Is this ok for trunk.
>
> See below
>
> >
> > BR,
> > Jeff (Jiufu Guo)
> >
> > gcc/ChangeLog:
> >
> >   * builtins.cc (expand_builtin_strnlen): Replace get_global_range_query
> >   by get_range_query.
> >   * fold-const.cc (expr_not_equal_to): Likewise.
> >   * gimple-fold.cc (size_must_be_zero_p): Likewise.
> >   * gimple-range-fold.cc (fur_source::fur_source): Likewise.
> >   * gimple-ssa-warn-access.cc (check_nul_terminated_array): Likewise.
> >   * tree-dfa.cc (get_ref_base_and_extent): Likewise.
> >   * tree-ssa-loop-split.cc (split_at_bb_p): Likewise.
> >   * tree-ssa-loop-unswitch.cc 
> > (evaluate_control_stmt_using_entry_checks):
> >   Likewise.
> >
> > ---
> >  gcc/builtins.cc   | 2 +-
> >  gcc/fold-const.cc | 6 +-
> >  gcc/gimple-fold.cc| 6 ++
> >  gcc/gimple-range-fold.cc  | 4 +---
> >  gcc/gimple-ssa-warn-access.cc | 2 +-
> >  gcc/tree-dfa.cc   | 5 +
> >  gcc/tree-ssa-loop-split.cc| 2 +-
> >  gcc/tree-ssa-loop-unswitch.cc | 2 +-
> >  8 files changed, 9 insertions(+), 20 deletions(-)
> >
> > diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> > index cb90bd03b3e..4e0a77ff8e0 100644
> > --- a/gcc/builtins.cc
> > +++ b/gcc/builtins.cc
> > @@ -3477,7 +3477,7 @@ expand_builtin_strnlen (tree exp, rtx target, 
> > machine_mode target_mode)
> >
> >wide_int min, max;
> >value_range r;
> > -  get_global_range_query ()->range_of_expr (r, bound);
> > +  get_range_query (cfun)->range_of_expr (r, bound);
>
> expand doesn't have a ranger instance so this is a no-op.  I'm unsure
> if it would be safe given we're half GIMPLE, half RTL.  Please leave it
> out.

It definitely does not work and can't as I tried to enable a ranger
instance and it didn't work. I wrote up my experience here:
https://gcc.gnu.org/pipermail/gcc/2023-September/242407.html

Thanks,
Andrew Pinski

>
> >if (r.varying_p () || r.undefined_p ())
> >  return NULL_RTX;
> >min = r.lower_bound ();
> > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
> > index 4f8561509ff..15134b21b9f 100644
> > --- a/gcc/fold-const.cc
> > +++ b/gcc/fold-const.cc
> > @@ -11056,11 +11056,7 @@ expr_not_equal_to (tree t, const wide_int &w)
> >if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
> >   return false;
> >
> > -  if (cfun)
> > - get_range_query (cfun)->range_of_expr (vr, t);
> > -  else
> > - get_global_range_query ()->range_of_expr (vr, t);
> > -
> > +  get_range_query (cfun)->range_of_expr (vr, t);
>
> These kind of changes look obvious.
>
> >if (!vr.undefined_p () && !vr.contains_p (w))
> >   return true;
> >/* If T has some known zero bits and W has any of those bits set,
> > diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
> > index dc89975270c..853edd9e5d4 100644
> > --- a/gcc/gimple-fold.cc
> > +++ b/gcc/gimple-fold.cc
> > @@ -876,10 +876,8 @@ size_must_be_zero_p (tree size)
> >wide_int zero = wi::zero (TYPE_PRECISION (type));
> >value_range valid_range (type, zero, ssize_max);
> >value_range vr;
> > -  if (cfun)
> > -get_range_query (cfun)->range_of_expr (vr, size);
> > -  else
> > -get_global_range_query ()->range_of_expr (vr, size);
> > +  get_range_query (cfun)->range_of_expr (vr, size);
> > +
> >if (vr.undefined_p ())
> >  vr.set_varying (TREE_TYPE (size));
> >vr.intersect (valid_range);
> > diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
> > index d1945ccb554..6e9530c3d7f 100644
> > --- a/gcc/gimple-range-fold.cc
> > +++ b/gcc/gimple-range-fold.cc
> > @@ -50,10 +50,8 @@ fur_source::fur_source (range_query *q)
> >  {
> >if (q)
> >  m_query = q;
> > -  else if (cfun)
> > -m_query = get_range_query (cfun);
> >else
> > -m_query = get_global_range_query ();
> > +m_query = get_range_query (cfun);
> >m_gori = NULL;
> >  }
> >
> > diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
> > index fcaff128d60..e439d1b9b68 100644
> > --- a/gcc/gimple-ssa-warn-access.cc
> > +++ b/gcc/gimple-ssa-warn-access.cc
> > @@ -332,7 +332,7 @@ check_nul_terminated_array (GimpleOrTree expr, tree 
> > src, 

[PATCH] Support Intel USER_MSR

2023-10-10 Thread Hu, Lin1
This patch aims to support Intel USER_MSR.

gcc/ChangeLog:

* common/config/i386/cpuinfo.h (get_available_features):
Detect USER_MSR.
* common/config/i386/i386-common.cc (OPTION_MASK_ISA2_USER_MSR_SET): 
New.
(OPTION_MASK_ISA2_USER_MSR_UNSET): Ditto.
(ix86_handle_option): Handle -musermsr.
* common/config/i386/i386-cpuinfo.h (enum processor_features):
Add FEATURE_USER_MSR.
* common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for usermsr.
* config.gcc: Add usermsrintrin.h
* config/i386/cpuid.h (bit_USER_MSR): New.
* config/i386/i386-builtin-types.def:
Add DEF_FUNCTION_TYPE (VOID, UINT64, UINT64).
* config/i386/i386-builtins.cc (ix86_init_mmx_sse_builtins):
Add __builtin_urdmsr and __builtin_uwrmsr.
* config/i386/i386-builtins.h (ix86_builtins):
Add IX86_BUILTIN_URDMSR and IX86_BUILTIN_UWRMSR.
* config/i386/i386-c.cc (ix86_target_macros_internal):
Define __USER_MSR__.
* config/i386/i386-expand.cc (ix86_expand_builtin):
Handle new builtins.
* config/i386/i386-isa.def (USER_MSR): Add DEF_PTA(USER_MSR).
* config/i386/i386-options.cc (ix86_valid_target_attribute_inner_p):
Handle usermsr.
* config/i386/i386.md (urdmsr): New define_insn.
(uwrmsr): Ditto.
* config/i386/i386.opt: Add option -musermsr.
* config/i386/x86gprintrin.h: Include usermsrintrin.h
* doc/extend.texi: Document usermsr.
* doc/invoke.texi: Document -musermsr.
* doc/sourcebuild.texi: Document target usermsr.
* config/i386/usermsrintrin.h: New file.

gcc/testsuite/ChangeLog:

* gcc.target/i386/funcspec-56.inc: Add new target attribute.
* gcc.target/i386/x86gprintrin-1.c: Add -musermsr for 64bit target.
* gcc.target/i386/x86gprintrin-2.c: Ditto.
* gcc.target/i386/x86gprintrin-3.c: Ditto.
* gcc.target/i386/x86gprintrin-4.c: Add musermsr for 64bit target.
* gcc.target/i386/x86gprintrin-5.c: Ditto
* gcc.target/i386/usermsr-1.c: New test.
* gcc.target/i386/usermsr-2.c: Ditto.
---
 gcc/common/config/i386/cpuinfo.h  |  2 +
 gcc/common/config/i386/i386-common.cc | 15 +
 gcc/common/config/i386/i386-cpuinfo.h |  1 +
 gcc/common/config/i386/i386-isas.h|  1 +
 gcc/config.gcc|  3 +-
 gcc/config/i386/cpuid.h   |  1 +
 gcc/config/i386/i386-builtin-types.def|  3 +
 gcc/config/i386/i386-builtins.cc  |  8 +++
 gcc/config/i386/i386-builtins.h   |  2 +
 gcc/config/i386/i386-c.cc |  2 +
 gcc/config/i386/i386-expand.cc| 35 +++
 gcc/config/i386/i386-isa.def  |  1 +
 gcc/config/i386/i386-options.cc   |  4 +-
 gcc/config/i386/i386.md   | 24 
 gcc/config/i386/i386.opt  |  4 ++
 gcc/config/i386/usermsrintrin.h   | 60 +++
 gcc/config/i386/x86gprintrin.h|  2 +
 gcc/doc/extend.texi   |  5 ++
 gcc/doc/invoke.texi   |  6 +-
 gcc/doc/sourcebuild.texi  |  3 +
 gcc/testsuite/gcc.target/i386/funcspec-56.inc |  2 +
 gcc/testsuite/gcc.target/i386/user_msr-1.c| 20 +++
 gcc/testsuite/gcc.target/i386/user_msr-2.c| 16 +
 .../gcc.target/i386/x86gprintrin-1.c  |  2 +-
 .../gcc.target/i386/x86gprintrin-2.c  |  6 +-
 .../gcc.target/i386/x86gprintrin-3.c  | 28 -
 .../gcc.target/i386/x86gprintrin-4.c  | 32 +-
 .../gcc.target/i386/x86gprintrin-5.c  |  6 +-
 28 files changed, 286 insertions(+), 8 deletions(-)
 create mode 100644 gcc/config/i386/usermsrintrin.h
 create mode 100644 gcc/testsuite/gcc.target/i386/user_msr-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/user_msr-2.c

diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 141d3743316..0f86b44730b 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -838,6 +838,8 @@ get_available_features (struct __processor_model *cpu_model,
set_feature (FEATURE_IBT);
   if (edx & bit_UINTR)
set_feature (FEATURE_UINTR);
+  if (edx & bit_USER_MSR)
+   set_feature (FEATURE_USER_MSR);
   if (amx_usable)
{
  if (edx & bit_AMX_TILE)
diff --git a/gcc/common/config/i386/i386-common.cc 
b/gcc/common/config/i386/i386-common.cc
index 684b0451bb3..13e423deceb 100644
--- a/gcc/common/config/i386/i386-common.cc
+++ b/gcc/common/config/i386/i386-common.cc
@@ -125,6 +125,7 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA2_SM4_SET OPTION_MASK_ISA2_SM4
 #define OPTION_MASK_ISA2_APX_F_SET OPTION_MASK_ISA2_APX_F
 #define OPTION_MASK_ISA2_EVEX512_SET OPTION_MASK_ISA2_EVEX512
+#define OPTIO

Re: [PATCH] x86: set spincount 1 for x86 hybrid platform [PR109812]

2023-10-10 Thread Jakub Jelinek
On Tue, Oct 10, 2023 at 12:59:52PM +0800, Jun Zhang wrote:
> include/ChangeLog:
> 
>   * omphook.h: define RUNOMPHOOK macro.

ChangeLog formatting.  The description should start with
capital letter.  If you add a new file, you should just
mention : New file. or something similar.

But much more importantly, we don't do hooks like that in libgomp,
it should be better a static inline function where the name shows
what it is doing (e.g. do_adjust_default_spincount), best in some
already existing header (e.g. wait.h), and best at the end of the
if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
block in env.c.
> 
> libgomp/ChangeLog:
> 
>   * env.c (initialize_env): add RUNOMPHOOK macro.
>   * config/linux/x86/omphook.h: define RUNOMPHOOK macro.
> ---
>  include/omphook.h  |  1 +
>  libgomp/config/linux/x86/omphook.h | 19 +++
>  libgomp/env.c  |  3 +++
>  3 files changed, 23 insertions(+)
>  create mode 100644 include/omphook.h
>  create mode 100644 libgomp/config/linux/x86/omphook.h
> 
> diff --git a/include/omphook.h b/include/omphook.h
> new file mode 100644
> index 000..2ebe3ad57e6
> --- /dev/null
> +++ b/include/omphook.h
> @@ -0,0 +1 @@
> +#define RUNOMPHOOK()
> diff --git a/libgomp/config/linux/x86/omphook.h 
> b/libgomp/config/linux/x86/omphook.h
> new file mode 100644
> index 000..aefb311cc07
> --- /dev/null
> +++ b/libgomp/config/linux/x86/omphook.h
> @@ -0,0 +1,19 @@
> +#ifdef __x86_64__
> +#include "cpuid.h"
> +
> +/* only for x86 hybrid platform */

Comments should again start with capital letter and end with dot and 2
spaces before */

> +#define RUNOMPHOOK()  \
> +  do \
> +{ \
> +  unsigned int eax, ebx, ecx, edx; \
> +  if ((getenv ("GOMP_SPINCOUNT") == NULL) && (wait_policy < 0) \

Spurious ()s around the subcondition, the first shouldn't be tested when
placed right, if condition doesn't fit on one line, each subcondition
should be on separate line.

> +   && __get_cpuid_count (7, 0, &eax, &ebx, &ecx, &edx) \

If we don't have a macro for the CPUID.07H.0H:EDX[15] bit, there should
be a comment which says what that bit is.

> +   && ((edx >> 15) & 1)) \
> + gomp_spin_count_var = 1LL; \
> +  if (gomp_throttled_spin_count_var > gomp_spin_count_var) \
> + gomp_throttled_spin_count_var = gomp_spin_count_var; \

The above 2 lines won't be needed if placed right.

Jakub



RE: [PATCH] Support Intel USER_MSR

2023-10-10 Thread Hu, Lin1
There are some typos In /gcc/doc/extend.texi and /gcc/doc/invoke.texi. They 
should be USER_MSR, not UMSR. I have modified them in my branch.

-Original Message-
From: Hu, Lin1  
Sent: Tuesday, October 10, 2023 3:47 PM
To: gcc-patches@gcc.gnu.org
Cc: Liu, Hongtao ; ubiz...@gmail.com
Subject: [PATCH] Support Intel USER_MSR

This patch aims to support Intel USER_MSR.

gcc/ChangeLog:

* common/config/i386/cpuinfo.h (get_available_features):
Detect USER_MSR.
* common/config/i386/i386-common.cc (OPTION_MASK_ISA2_USER_MSR_SET): 
New.
(OPTION_MASK_ISA2_USER_MSR_UNSET): Ditto.
(ix86_handle_option): Handle -musermsr.
* common/config/i386/i386-cpuinfo.h (enum processor_features):
Add FEATURE_USER_MSR.
* common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for usermsr.
* config.gcc: Add usermsrintrin.h
* config/i386/cpuid.h (bit_USER_MSR): New.
* config/i386/i386-builtin-types.def:
Add DEF_FUNCTION_TYPE (VOID, UINT64, UINT64).
* config/i386/i386-builtins.cc (ix86_init_mmx_sse_builtins):
Add __builtin_urdmsr and __builtin_uwrmsr.
* config/i386/i386-builtins.h (ix86_builtins):
Add IX86_BUILTIN_URDMSR and IX86_BUILTIN_UWRMSR.
* config/i386/i386-c.cc (ix86_target_macros_internal):
Define __USER_MSR__.
* config/i386/i386-expand.cc (ix86_expand_builtin):
Handle new builtins.
* config/i386/i386-isa.def (USER_MSR): Add DEF_PTA(USER_MSR).
* config/i386/i386-options.cc (ix86_valid_target_attribute_inner_p):
Handle usermsr.
* config/i386/i386.md (urdmsr): New define_insn.
(uwrmsr): Ditto.
* config/i386/i386.opt: Add option -musermsr.
* config/i386/x86gprintrin.h: Include usermsrintrin.h
* doc/extend.texi: Document usermsr.
* doc/invoke.texi: Document -musermsr.
* doc/sourcebuild.texi: Document target usermsr.
* config/i386/usermsrintrin.h: New file.

gcc/testsuite/ChangeLog:

* gcc.target/i386/funcspec-56.inc: Add new target attribute.
* gcc.target/i386/x86gprintrin-1.c: Add -musermsr for 64bit target.
* gcc.target/i386/x86gprintrin-2.c: Ditto.
* gcc.target/i386/x86gprintrin-3.c: Ditto.
* gcc.target/i386/x86gprintrin-4.c: Add musermsr for 64bit target.
* gcc.target/i386/x86gprintrin-5.c: Ditto
* gcc.target/i386/usermsr-1.c: New test.
* gcc.target/i386/usermsr-2.c: Ditto.
---
 gcc/common/config/i386/cpuinfo.h  |  2 +
 gcc/common/config/i386/i386-common.cc | 15 +
 gcc/common/config/i386/i386-cpuinfo.h |  1 +
 gcc/common/config/i386/i386-isas.h|  1 +
 gcc/config.gcc|  3 +-
 gcc/config/i386/cpuid.h   |  1 +
 gcc/config/i386/i386-builtin-types.def|  3 +
 gcc/config/i386/i386-builtins.cc  |  8 +++
 gcc/config/i386/i386-builtins.h   |  2 +
 gcc/config/i386/i386-c.cc |  2 +
 gcc/config/i386/i386-expand.cc| 35 +++
 gcc/config/i386/i386-isa.def  |  1 +
 gcc/config/i386/i386-options.cc   |  4 +-
 gcc/config/i386/i386.md   | 24 
 gcc/config/i386/i386.opt  |  4 ++
 gcc/config/i386/usermsrintrin.h   | 60 +++
 gcc/config/i386/x86gprintrin.h|  2 +
 gcc/doc/extend.texi   |  5 ++
 gcc/doc/invoke.texi   |  6 +-
 gcc/doc/sourcebuild.texi  |  3 +
 gcc/testsuite/gcc.target/i386/funcspec-56.inc |  2 +
 gcc/testsuite/gcc.target/i386/user_msr-1.c| 20 +++
 gcc/testsuite/gcc.target/i386/user_msr-2.c| 16 +
 .../gcc.target/i386/x86gprintrin-1.c  |  2 +-
 .../gcc.target/i386/x86gprintrin-2.c  |  6 +-
 .../gcc.target/i386/x86gprintrin-3.c  | 28 -
 .../gcc.target/i386/x86gprintrin-4.c  | 32 +-
 .../gcc.target/i386/x86gprintrin-5.c  |  6 +-
 28 files changed, 286 insertions(+), 8 deletions(-)  create mode 100644 
gcc/config/i386/usermsrintrin.h  create mode 100644 
gcc/testsuite/gcc.target/i386/user_msr-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/user_msr-2.c

diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 141d3743316..0f86b44730b 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -838,6 +838,8 @@ get_available_features (struct __processor_model *cpu_model,
set_feature (FEATURE_IBT);
   if (edx & bit_UINTR)
set_feature (FEATURE_UINTR);
+  if (edx & bit_USER_MSR)
+   set_feature (FEATURE_USER_MSR);
   if (amx_usable)
{
  if (edx & bit_AMX_TILE)
diff --git a/gcc/common/config/i386/i386-common.cc 
b/gcc/common/config/i386/i386-common.cc
index 684b0451bb3..13e423deceb 100644
--- a/gcc/commo

Re: [PATCH-2, rs6000] Enable vector mode for memory equality compare [PR111449]

2023-10-10 Thread HAO CHEN GUI
Hi David,

  Thanks for your review comments.

在 2023/10/9 23:42, David Edelsohn 写道:
>  #define MOVE_MAX (! TARGET_POWERPC64 ? 4 : 8)
>  #define MAX_MOVE_MAX 8
> +#define MOVE_MAX_PIECES (!TARGET_POWERPC64 ? 4 : 16)
> +#define COMPARE_MAX_PIECES (!TARGET_POWERPC64 ? 4 : 16)
> 
> 
> How are the definitions of MOVE_MAX_PIECES and COMPARE_MAX_PIECES determined? 
>  The email does not provide any explanation for the implementation.  The rest 
> of the patch is related to vector support, but vector support is not 
> dependent on TARGET_POWERPC64.

By default, MOVE_MAX_PIECES and COMPARE_MAX_PIECES is set the same value
as MOVE_MAX. The move and compare instructions are required in
compare_by_pieces, those macros are set to 16 byte when supporting
vector mode (V16QImode). The problem is rs6000 hasn't supported TImode
for "-m32". We discussed it in issue 1307. TImode will be used for
move when MOVE_MAX_PIECES is set to 16. But TImode isn't supported
with "-m32" which might cause ICE.

So MOVE_MAX_PIECES and COMPARE_MAX_PIECES is set to 4 for 32 bit
target in this patch. They could be changed to 16 after rs6000
supports TImode with "-m32".

Thanks
Gui Haochen


[committed] arc: Refurbish add.f combiner patterns

2023-10-10 Thread Claudiu Zissulescu
Refurbish add compare patterns: use 'r' constraint, fix identation,
and fix pattern to match 'if (a+b) { ... }' constructions.

gcc/

* config/arc/arc.cc (arc_select_cc_mode): Match NEG code with
the first operand.
* config/arc/arc.md (addsi_compare): Make pattern canonical.
(addsi_compare_2): Fix identation, constraint letters.
(addsi_compare_3): Likewise.

gcc/testsuite/

* gcc.target/arc/add_f-combine.c: New test.

Signed-off-by: Claudiu Zissulescu 
---
 gcc/config/arc/arc.cc|  2 +-
 gcc/config/arc/arc.md| 25 ++--
 gcc/testsuite/gcc.target/arc/add_f-combine.c | 15 
 3 files changed, 28 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/add_f-combine.c

diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
index ecc681cff61..00427d859cc 100644
--- a/gcc/config/arc/arc.cc
+++ b/gcc/config/arc/arc.cc
@@ -1562,7 +1562,7 @@ arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
 
   /* add.f for if (a+b) */
   if (mode == SImode
-  && GET_CODE (y) == NEG
+  && GET_CODE (x) == NEG
   && (op == EQ || op == NE))
 return CC_ZNmode;
 
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index cedb9517bb0..a936a8be53d 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -1102,34 +1102,33 @@ (define_insn "*commutative_binary_cmp0"
 ; the combiner needs this pattern
 (define_insn "*addsi_compare"
   [(set (reg:CC_ZN CC_REG)
-   (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
-  (neg:SI (match_operand:SI 1 "register_operand" "c"]
+   (compare:CC_ZN (neg:SI
+   (match_operand:SI 0 "register_operand" "r"))
+  (match_operand:SI 1 "register_operand"  "r")))]
   ""
-  "add.f 0,%0,%1"
+  "add.f\\t0,%0,%1"
   [(set_attr "cond" "set")
(set_attr "type" "compare")
(set_attr "length" "4")])
 
-; for flag setting 'add' instructions like if (a+b < a) { ...}
-; the combiner needs this pattern
 (define_insn "addsi_compare_2"
   [(set (reg:CC_C CC_REG)
-   (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
-  (match_operand:SI 1 "nonmemory_operand" 
"cL,Cal"))
- (match_dup 0)))]
+   (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand"   "r,r")
+  (match_operand:SI 1 "nonmemory_operand" 
"rL,Cal"))
+ (match_dup 0)))]
   ""
-  "add.f 0,%0,%1"
+  "add.f\\t0,%0,%1"
   [(set_attr "cond" "set")
(set_attr "type" "compare")
(set_attr "length" "4,8")])
 
 (define_insn "*addsi_compare_3"
   [(set (reg:CC_C CC_REG)
-   (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
-  (match_operand:SI 1 "register_operand" "c"))
- (match_dup 1)))]
+   (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "r")
+  (match_operand:SI 1 "register_operand" "r"))
+ (match_dup 1)))]
   ""
-  "add.f 0,%0,%1"
+  "add.f\\t0,%0,%1"
   [(set_attr "cond" "set")
(set_attr "type" "compare")
(set_attr "length" "4")])
diff --git a/gcc/testsuite/gcc.target/arc/add_f-combine.c 
b/gcc/testsuite/gcc.target/arc/add_f-combine.c
new file mode 100644
index 000..cfa3676f7da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/add_f-combine.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* Check if combiner is matching add.f patterns.  */
+
+int a1 (int a, int b)
+{
+  if (a + b)
+{
+  return 1;
+}
+  return a + 2;
+}
+
+/* { dg-final { scan-assembler "add.f\\s+0,r\\d+,r\\d+" } } */
-- 
2.30.2



Re: [PATCH] use get_range_query to replace get_global_range_query

2023-10-10 Thread Jiufu Guo


Hi,

Richard Biener  writes:

> On Tue, 10 Oct 2023, Jiufu Guo wrote:
>
>> Hi,
>> 
>> For "get_global_range_query" SSA_NAME_RANGE_INFO can be queried.
>> For "get_range_query", it could get more context-aware range info.
>> And look at the implementation of "get_range_query",  it returns
>> global range if no local fun info.
>> 
>> So, if not quering for SSA_NAME, it would be ok to use get_range_query
>> to replace get_global_range_query.
>> 
>> Patch https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630389.html,
>> Uses get_range_query could handle more cases.
>> 
>> This patch replaces get_global_range_query by get_range_query for
>> most possible code pieces (but deoes not draft new test cases).
>> 
>> Pass bootstrap & regtest on ppc64{,le} and x86_64.
>> Is this ok for trunk.
>
> See below

Thanks so much for your quick review!

>
>> 
>> BR,
>> Jeff (Jiufu Guo)
>> 
>> gcc/ChangeLog:
>> 
>>  * builtins.cc (expand_builtin_strnlen): Replace get_global_range_query
>>  by get_range_query.
>>  * fold-const.cc (expr_not_equal_to): Likewise.
>>  * gimple-fold.cc (size_must_be_zero_p): Likewise.
>>  * gimple-range-fold.cc (fur_source::fur_source): Likewise.
>>  * gimple-ssa-warn-access.cc (check_nul_terminated_array): Likewise.
>>  * tree-dfa.cc (get_ref_base_and_extent): Likewise.
>>  * tree-ssa-loop-split.cc (split_at_bb_p): Likewise.
>>  * tree-ssa-loop-unswitch.cc (evaluate_control_stmt_using_entry_checks):
>>  Likewise.
>> 
>> ---
>>  gcc/builtins.cc   | 2 +-
>>  gcc/fold-const.cc | 6 +-
>>  gcc/gimple-fold.cc| 6 ++
>>  gcc/gimple-range-fold.cc  | 4 +---
>>  gcc/gimple-ssa-warn-access.cc | 2 +-
>>  gcc/tree-dfa.cc   | 5 +
>>  gcc/tree-ssa-loop-split.cc| 2 +-
>>  gcc/tree-ssa-loop-unswitch.cc | 2 +-
>>  8 files changed, 9 insertions(+), 20 deletions(-)
>> 
>> diff --git a/gcc/builtins.cc b/gcc/builtins.cc
>> index cb90bd03b3e..4e0a77ff8e0 100644
>> --- a/gcc/builtins.cc
>> +++ b/gcc/builtins.cc
>> @@ -3477,7 +3477,7 @@ expand_builtin_strnlen (tree exp, rtx target, 
>> machine_mode target_mode)
>>  
>>wide_int min, max;
>>value_range r;
>> -  get_global_range_query ()->range_of_expr (r, bound);
>> +  get_range_query (cfun)->range_of_expr (r, bound);
>
> expand doesn't have a ranger instance so this is a no-op.  I'm unsure
> if it would be safe given we're half GIMPLE, half RTL.  Please leave it
> out.

Oh, yeap.  There is no local ranger, and 'bound' is SSA_NAME,
and SSA_NAME_RANGE_INFO is there.
get_global_range_query should be used.

>
>>if (r.varying_p () || r.undefined_p ())
>>  return NULL_RTX;
>>min = r.lower_bound ();
>> diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
>> index 4f8561509ff..15134b21b9f 100644
>> --- a/gcc/fold-const.cc
>> +++ b/gcc/fold-const.cc
>> @@ -11056,11 +11056,7 @@ expr_not_equal_to (tree t, const wide_int &w)
>>if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
>>  return false;
>>  
>> -  if (cfun)
>> -get_range_query (cfun)->range_of_expr (vr, t);
>> -  else
>> -get_global_range_query ()->range_of_expr (vr, t);
>> -
>> +  get_range_query (cfun)->range_of_expr (vr, t);
>
> These kind of changes look obvious.
>
>>if (!vr.undefined_p () && !vr.contains_p (w))
>>  return true;
>>/* If T has some known zero bits and W has any of those bits set,
>> diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
>> index dc89975270c..853edd9e5d4 100644
>> --- a/gcc/gimple-fold.cc
>> +++ b/gcc/gimple-fold.cc
>> @@ -876,10 +876,8 @@ size_must_be_zero_p (tree size)
>>wide_int zero = wi::zero (TYPE_PRECISION (type));
>>value_range valid_range (type, zero, ssize_max);
>>value_range vr;
>> -  if (cfun)
>> -get_range_query (cfun)->range_of_expr (vr, size);
>> -  else
>> -get_global_range_query ()->range_of_expr (vr, size);
>> +  get_range_query (cfun)->range_of_expr (vr, size);
>> +
>>if (vr.undefined_p ())
>>  vr.set_varying (TREE_TYPE (size));
>>vr.intersect (valid_range);
>> diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
>> index d1945ccb554..6e9530c3d7f 100644
>> --- a/gcc/gimple-range-fold.cc
>> +++ b/gcc/gimple-range-fold.cc
>> @@ -50,10 +50,8 @@ fur_source::fur_source (range_query *q)
>>  {
>>if (q)
>>  m_query = q;
>> -  else if (cfun)
>> -m_query = get_range_query (cfun);
>>else
>> -m_query = get_global_range_query ();
>> +m_query = get_range_query (cfun);
>>m_gori = NULL;
>>  }
>>  
>> diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
>> index fcaff128d60..e439d1b9b68 100644
>> --- a/gcc/gimple-ssa-warn-access.cc
>> +++ b/gcc/gimple-ssa-warn-access.cc
>> @@ -332,7 +332,7 @@ check_nul_terminated_array (GimpleOrTree expr, tree src, 
>> tree bound)
>>  {
>>Value_Range r (TREE_TYPE (bound));
>>  
>> -  get_global_range_query ()->range_of_expr (r, bound);
>> +  get_range_query (cfun)->range_of_expr

Re: [PATCH] wide-int: Remove rwide_int, introduce dw_wide_int

2023-10-10 Thread Richard Biener
On Mon, 9 Oct 2023, Jakub Jelinek wrote:

> On Mon, Oct 09, 2023 at 12:55:02PM +0200, Jakub Jelinek wrote:
> > This makes wide_int unusable in GC structures, so for dwarf2out
> > which was the only place which needed it there is a new rwide_int type
> > (restricted wide_int) which supports only up to RWIDE_INT_MAX_ELTS limbs
> > inline and is trivially copyable (dwarf2out should never deal with large
> > _BitInt constants, those should have been lowered earlier).
> 
> As discussed on IRC, the dwarf2out.{h,cc} needs are actually quite limited,
> it just needs to allocate new GC structures val_wide points to (constructed
> from some const wide_int_ref &) and needs to call operator==,
> get_precision, elt, get_len and get_val methods on it.
> Even trailing_wide_int would be overkill for that, the following just adds
> a new struct with precision/len and trailing val array members and
> implements the needed methods (only 2 of them using wide_int_ref constructed
> from those).
> 
> Incremental patch, so far compile time tested only:

LGTM, wonder if we can push this separately as prerequesite?

Thanks,
Richard.

> --- gcc/wide-int.h.jj 2023-10-09 14:37:45.878940132 +0200
> +++ gcc/wide-int.h2023-10-09 16:06:39.326805176 +0200
> @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3.
> other longer storage GCC representations (rtl and tree).
>  
> The actual precision of a wide_int depends on the flavor.  There
> -   are four predefined flavors:
> +   are three predefined flavors:
>  
>   1) wide_int (the default).  This flavor does the math in the
>   precision of its input arguments.  It is assumed (and checked)
> @@ -80,12 +80,7 @@ along with GCC; see the file COPYING3.
> wi::leu_p (a, b) as a more efficient short-hand for
> "a >= 0 && a <= b". ]
>  
> - 3) rwide_int.  Restricted wide_int.  This is similar to
> - wide_int, but maximum possible precision is RWIDE_INT_MAX_PRECISION
> - and it always uses an inline buffer.  offset_int and rwide_int are
> - GC-friendly, wide_int and widest_int are not.
> -
> - 4) widest_int.  This representation is an approximation of
> + 3) widest_int.  This representation is an approximation of
>   infinite precision math.  However, it is not really infinite
>   precision math as in the GMP library.  It is really finite
>   precision math where the precision is WIDEST_INT_MAX_PRECISION.
> @@ -257,9 +252,6 @@ along with GCC; see the file COPYING3.
>  #define WIDE_INT_MAX_ELTS 255
>  #define WIDE_INT_MAX_PRECISION (WIDE_INT_MAX_ELTS * HOST_BITS_PER_WIDE_INT)
>  
> -#define RWIDE_INT_MAX_ELTS WIDE_INT_MAX_INL_ELTS
> -#define RWIDE_INT_MAX_PRECISION WIDE_INT_MAX_INL_PRECISION
> -
>  /* Precision of widest_int and largest _BitInt precision + 1 we can
> support.  */
>  #define WIDEST_INT_MAX_ELTS 510
> @@ -343,7 +335,6 @@ STATIC_ASSERT (WIDE_INT_MAX_INL_ELTS < W
>  template  class generic_wide_int;
>  template  class fixed_wide_int_storage;
>  class wide_int_storage;
> -class rwide_int_storage;
>  template  class widest_int_storage;
>  
>  /* An N-bit integer.  Until we can use typedef templates, use this instead.  
> */
> @@ -352,7 +343,6 @@ template  class widest_int_storag
>  
>  typedef generic_wide_int  wide_int;
>  typedef FIXED_WIDE_INT (ADDR_MAX_PRECISION) offset_int;
> -typedef generic_wide_int  rwide_int;
>  typedef generic_wide_int  > 
> widest_int;
>  typedef generic_wide_int  2> > widest2_int;
>  
> @@ -1371,180 +1361,6 @@ wi::int_traits ::get_b
>  return wi::get_precision (x);
>  }
>  
> -/* The storage used by rwide_int.  */
> -class GTY(()) rwide_int_storage
> -{
> -private:
> -  HOST_WIDE_INT val[RWIDE_INT_MAX_ELTS];
> -  unsigned int len;
> -  unsigned int precision;
> -
> -public:
> -  rwide_int_storage () = default;
> -  template 
> -  rwide_int_storage (const T &);
> -
> -  /* The standard generic_rwide_int storage methods.  */
> -  unsigned int get_precision () const;
> -  const HOST_WIDE_INT *get_val () const;
> -  unsigned int get_len () const;
> -  HOST_WIDE_INT *write_val (unsigned int);
> -  void set_len (unsigned int, bool = false);
> -
> -  template 
> -  rwide_int_storage &operator = (const T &);
> -
> -  static rwide_int from (const wide_int_ref &, unsigned int, signop);
> -  static rwide_int from_array (const HOST_WIDE_INT *, unsigned int,
> -unsigned int, bool = true);
> -  static rwide_int create (unsigned int);
> -};
> -
> -namespace wi
> -{
> -  template <>
> -  struct int_traits 
> -  {
> -static const enum precision_type precision_type = VAR_PRECISION;
> -/* Guaranteed by a static assert in the rwide_int_storage constructor.  
> */
> -static const bool host_dependent_precision = false;
> -static const bool is_sign_extended = true;
> -static const bool needs_write_val_arg = false;
> -template 
> -static rwide_int get_binary_result (const T1 &, const T2 &);
> -template 
> -static unsigned int get_binary_p

Re: [PATCH] MATCH: [PR111679] Add alternative simplification of `a | ((~a) ^ b)`

2023-10-10 Thread Richard Biener
On Mon, Oct 9, 2023 at 11:28 PM Andrew Pinski  wrote:
>
> So currently we have a simplification for `a | ~(a ^ b)` but
> that does not match the case where we had originally `(~a) | (a ^ b)`
> so we need to add a new pattern that matches that and uses 
> bitwise_inverted_equal_p
> that also catches comparisons too.
>
> OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

OK.

> PR tree-optimization/111679
>
> gcc/ChangeLog:
>
> * match.pd (`a | ((~a) ^ b)`): New pattern.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/tree-ssa/bitops-5.c: New test.
> ---
>  gcc/match.pd |  8 +++
>  gcc/testsuite/gcc.dg/tree-ssa/bitops-5.c | 27 
>  2 files changed, 35 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bitops-5.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 31bfd8b6b68..49740d189a7 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -1350,6 +1350,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>&& TYPE_PRECISION (TREE_TYPE (@0)) == 1)
>(bit_ior @0 (bit_xor @1 { build_one_cst (type); }
>
> +/* a | ((~a) ^ b)  -->  a | (~b) (alt version of the above 2) */
> +(simplify
> + (bit_ior:c @0 (bit_xor:cs @1 @2))
> + (with { bool wascmp; }
> + (if (bitwise_inverted_equal_p (@0, @1, wascmp)
> +  && (!wascmp || element_precision (type) == 1))
> +  (bit_ior @0 (bit_not @2)
> +
>  /* (a | b) | (a &^ b)  -->  a | b  */
>  (for op (bit_and bit_xor)
>   (simplify
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitops-5.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/bitops-5.c
> new file mode 100644
> index 000..990610e3002
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/bitops-5.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> +/* PR tree-optimization/111679 */
> +
> +int f1(int a, int b)
> +{
> +return (~a) | (a ^ b); // ~(a & b) or (~a) | (~b)
> +}
> +
> +_Bool fb(_Bool c, _Bool d)
> +{
> +return (!c) | (c ^ d); // ~(c & d) or (~c) | (~d)
> +}
> +
> +_Bool fb1(int x, int y)
> +{
> +_Bool a = x == 10,  b = y > 100;
> +return (!a) | (a ^ b); // ~(a & b) or (~a) | (~b)
> +// or (x != 10) | (y <= 100)
> +}
> +
> +/* { dg-final { scan-tree-dump-not   "bit_xor_expr, "   "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "bit_not_expr, " 2 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "bit_and_expr, " 2 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "bit_ior_expr, " 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "ne_expr, _\[0-9\]+, x_\[0-9\]+"  1 
> "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "le_expr, _\[0-9\]+, y_\[0-9\]+"  1 
> "optimized" } } */
> --
> 2.39.3
>


Re: [PATCH] RISC-V Regression: Fix FAIL of bb-slp-pr65935.c for RVV

2023-10-10 Thread Andrew Stubbs

On 10/10/2023 02:39, Juzhe-Zhong wrote:

Here is the reference comparing dump IR between ARM SVE and RVV.

https://godbolt.org/z/zqess8Gss

We can see RVV has one more dump IR:
optimized: basic block part vectorized using 128 byte vectors
since RVV has 1024 bit vectors.

The codegen is reasonable good.

However, I saw GCN also has 1024 bit vector.
This patch may cause this case FAIL in GCN port ?

Hi, GCN folk, could you check this patch in GCN port for me ?


This patch *fixes* an existing test fail on GCN. :)

It's probably one of the many I've never had time to analyze (and 
optimizing more than expected makes it low priority).


LGTM

Andrew


Re: Re: [PATCH] RISC-V Regression: Fix FAIL of bb-slp-pr65935.c for RVV

2023-10-10 Thread juzhe.zh...@rivai.ai
Great ! I am gonna wait for Richi's  approval.



juzhe.zh...@rivai.ai
 
From: Andrew Stubbs
Date: 2023-10-10 17:40
To: Juzhe-Zhong; gcc-patches@gcc.gnu.org
CC: rguent...@suse.de; jeffreya...@gmail.com
Subject: Re: [PATCH] RISC-V Regression: Fix FAIL of bb-slp-pr65935.c for RVV
On 10/10/2023 02:39, Juzhe-Zhong wrote:
> Here is the reference comparing dump IR between ARM SVE and RVV.
> 
> https://godbolt.org/z/zqess8Gss
> 
> We can see RVV has one more dump IR:
> optimized: basic block part vectorized using 128 byte vectors
> since RVV has 1024 bit vectors.
> 
> The codegen is reasonable good.
> 
> However, I saw GCN also has 1024 bit vector.
> This patch may cause this case FAIL in GCN port ?
> 
> Hi, GCN folk, could you check this patch in GCN port for me ?
 
This patch *fixes* an existing test fail on GCN. :)
 
It's probably one of the many I've never had time to analyze (and 
optimizing more than expected makes it low priority).
 
LGTM
 
Andrew
 


Re: [PATCH] wide-int: Remove rwide_int, introduce dw_wide_int

2023-10-10 Thread Jakub Jelinek
On Tue, Oct 10, 2023 at 09:30:31AM +, Richard Biener wrote:
> On Mon, 9 Oct 2023, Jakub Jelinek wrote:
> 
> > On Mon, Oct 09, 2023 at 12:55:02PM +0200, Jakub Jelinek wrote:
> > > This makes wide_int unusable in GC structures, so for dwarf2out
> > > which was the only place which needed it there is a new rwide_int type
> > > (restricted wide_int) which supports only up to RWIDE_INT_MAX_ELTS limbs
> > > inline and is trivially copyable (dwarf2out should never deal with large
> > > _BitInt constants, those should have been lowered earlier).
> > 
> > As discussed on IRC, the dwarf2out.{h,cc} needs are actually quite limited,
> > it just needs to allocate new GC structures val_wide points to (constructed
> > from some const wide_int_ref &) and needs to call operator==,
> > get_precision, elt, get_len and get_val methods on it.
> > Even trailing_wide_int would be overkill for that, the following just adds
> > a new struct with precision/len and trailing val array members and
> > implements the needed methods (only 2 of them using wide_int_ref constructed
> > from those).
> > 
> > Incremental patch, so far compile time tested only:
> 
> LGTM, wonder if we can push this separately as prerequesite?

The dwarf2out.{h,cc} changes sure, the wide-int.h changes obviously need to
be merged into the main patch.

Jakub



[PATCH v15 00/39] Optimize type traits performance

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

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 (39):
  c++: Sort built-in identifiers alphabetically
  c-family, c++: Look up traits through gperf instead of enum rid.
  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++, libstdc++: Implement __is_pointer built-in trait
  libstdc++: Optimize is_pointer trait performance
  c++, libstdc++: 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++, libstdc++: Implement __is_signed built-in trait
  libstdc++: Optimize is_signed trait performance
  c++, libstdc++: Implement __is_scalar built-in trait
  libstdc++: Optimize is_scalar trait performance

 gcc/c-family/c-common.cc  |  12 +-
 gcc/c-family/c-common.h   |   7 +-
 gcc/cp/Make-lang.in   |  26 ++
 gcc/cp/constraint.cc  | 112 +--
 gcc/cp/cp-objcp-common.cc |   6 +-
 gcc/cp/cp-trait-head.in   |  31 ++
 gcc/cp/cp-trait.def   |  27 +-
 gcc/cp/cp-trait.gperf |  92 ++
 gcc/cp/cp-trait.h | 287 ++
 gcc/cp/parser.cc  |  72 ++---
 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++.dg/ext/is_signed.C  |  47 +++
 gcc/testsuite/g++.dg/ext/is_unbounded_array.C |  37 +++
 gcc/testsuite/g++.dg/ext/is_unsigned.C|  47 +++
 gcc/testsuite/g++.dg/ext/is_volatile.C|  19 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C |  51 
 gcc/testsuite/g++.dg/tm/pr46567.C |  48 +--
 gcc/testsuite/g++.dg/torture/20070621-1.C |   4 +-
 gcc/testsuite/g++.dg/torture/pr57107.C|   8 +-
 libstdc++-v3/include/bits/charconv.h  |   2 +-
 libstdc++-v3/include/bits/cpp_type_traits.h   |  18 +-
 libstdc++-v3/include/bits/deque.tcc   |   6 +-
 libstdc++-v3/include/bits/locale_facets.tcc   |   6 +-
 libstdc++-v3/include/bits/stl_algobase.h  |  14 +-
 libstdc++-v3/include/bits/uniform_int_dist.h  |   4 +-
 libstdc++-v3/include/bits/valarray_array.h|   2 +-
 libstdc++-v3/include/c_globa

[PATCH v15 01/39] c++: Sort built-in identifiers alphabetically

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

gcc/cp/ChangeLog:

* constraint.cc (diagnose_trait_expr): Sort built-in identifiers
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 identifiers
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_CON

[PATCH v15 03/39] c++: Implement __is_const built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_const.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 202 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_const.C  |  19 +++
 7 files changed, 134 insertions(+), 99 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index c3feb78d3c4..ad720832ccb 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -43,6 +43,7 @@ struct cp_trait {
 "__is_assignable", CPTK_IS_ASSIGNABLE, true, false, false
 "__is_base_of", CPTK_IS_BASE_OF, true, false, false
 "__is_class", CPTK_IS_CLASS, false, false, false
+"__is_const", CPTK_IS_CONST, false, false, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, false, true, false
 "__is_convertible", CPTK_IS_CONVERTIBLE, true, false, false
 "__is_empty", CPTK_IS_EMPTY, false, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index db9476a8ac1..4a2100779cf 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -1,6 +1,6 @@
 /* C++ code produced by gperf version 3.1 */
 /* Command-line: gperf -o -C -E -D -N find -L C++ --output-file 
../../gcc/cp/cp-trait.h ../../gcc/cp/cp-trait.gperf  */
-/* Computed positions: -k'8' */
+/* Computed positions: -k'6,8' */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
   && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 79, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86,  1, 86, 86,
-   0, 35, 86,  0, 86,  0, 86, 86, 10, 10,
-  50, 15, 55, 86, 30,  5, 15,  0, 86, 86,
-  86, 20, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-  86, 86, 86, 86, 86, 86
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+

[PATCH v15 02/39] c-family, c++: Look up traits through gperf instead of enum rid.

2023-10-10 Thread Ken Matsui
Since RID_MAX soon reaches 255 and all traits are used approximately once in
a C++ translation unit, this patch instead uses only RID_TRAIT_EXPR and
RID_TRAIT_TYPE for all traits and uses gperf to look up the specific trait.

gcc/c-family/ChangeLog:

* c-common.cc (c_common_reswords): Map all traits to RID_TRAIT_EXPR
and RID_TRAIT_TYPE instead.
* c-common.h (enum rid): Remove all existing RID values for traits.
Use RID_TRAIT_EXPR and RID_TRAIT_TYPE instead.

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 existing RID values
for traits.  Use RID_TRAIT_EXPR and RID_TRAIT_TYPE instead.
* parser.cc (cp_keyword_starts_decl_specifier_p): Likewise, for
type-yielding traits.  Use RID_TRAIT_TYPE instead.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_primary_expression): Likewise, for expression-yielding
traits.  Use RID_TRAIT_EXPR instead.
(cp_parser_trait): Look up traits through gperf instead of enum rid.
* cp-trait-head.in: New file.
* cp-trait.gperf: New file.
* cp-trait.h: New file.

Signed-off-by: Ken Matsui 
---
 gcc/c-family/c-common.cc  |  12 +-
 gcc/c-family/c-common.h   |   7 +-
 gcc/cp/Make-lang.in   |  26 
 gcc/cp/cp-objcp-common.cc |   6 +-
 gcc/cp/cp-trait-head.in   |  31 +
 gcc/cp/cp-trait.gperf |  75 
 gcc/cp/cp-trait.h | 249 ++
 gcc/cp/parser.cc  |  72 ---
 8 files changed, 418 insertions(+), 60 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..f219ccd29e5 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -508,12 +508,16 @@ 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 },
+#define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
+  { NAME,  RID_TRAIT_EXPR, D_CXXONLY },
 #include "cp/cp-trait.def"
-#undef DEFTRAIT
+#undef DEFTRAIT_EXPR
   /* An alias for __is_same.  */
-  { "__is_same_as",RID_IS_SAME,D_CXXONLY },
+  { "__is_same_as",RID_TRAIT_EXPR, D_CXXONLY },
+#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
+  { NAME,  RID_TRAIT_TYPE, D_CXXONLY },
+#include "cp/cp-trait.def"
+#undef DEFTRAIT_TYPE
 
   /* C++ transactional memory.  */
   { "synchronized",RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1fdba7ef3ea..a1a641f4175 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -168,10 +168,9 @@ 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++ traits, defined in cp-trait.def.  */
+  RID_TRAIT_EXPR,
+  RID_TRAIT_TYPE,
 
   /* C++11 */
   RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 2727fb7f8cc..d27a6744cb9 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -34,6 +34,8 @@
 # - the compiler proper (eg: cc1plus)
 # - define the names for selecting the language in LANGUAGES.
 
+AWK = @AWK@
+
 # Actual names to use when installing a native compiler.
 CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
 GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
@@ -186,6 +188,30 @@ endif
 # This is the file that depends on the generated header file.
 cp/name-lookup.o: $(srcdir)/cp/std-name-hint.h
 
+# We always need the dependency on the .gperf file because it itself is 
generated.
+ifeq ($(ENABLE_MAINTAINER_RULES), true)
+$(srcdir)/cp/cp-trait.h: $(srcdir)/cp/cp-trait.gperf
+else
+$(srcdir)/cp/cp-trait.h: | $(srcdir)/cp/cp-trait.gperf
+endif
+   gperf -o -C -E -D -N 'find' -L C++ \
+   $(srcdir)/cp/cp-trait.gperf --output-file 
$(srcdir)/cp/cp-trait.h
+
+# The cp-trait.gperf file itself is generated from a cp-trait.def file.
+$(srcdir)/cp/cp-trait.gperf: $(srcdir)/cp/cp-trait.def
+   cat $(srcdir)/cp/cp-trait-head.in > $@
+   $(AWK) -F', *' '/^DEFTRAIT_/ { \
+   type = (index($$1, "DEFTRAIT_TYPE") != 0 ? "true" : "false"); \
+   gsub(/DEFTRAIT_(EXPR|TYPE) \(/, "", $$1); \
+   gsub(/\)/, "", $$3); \
+   binary = ($$3 == 2 ? "true" : "false"); \
+   variadic = ($$3 == -1 ? "true" : "false"); \
+   print $$2", CPTK_" $$1", "binary", "variadic", "type; \
+   }' $(srcdir)/cp/cp-trait.def >> $@
+
+# This is the file that depends on the generated head

[PATCH v15 04/39] libstdc++: Optimize is_const trait performance

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



Re: [PATCH v2 0/4] RISC-V target attribute

2023-10-10 Thread juzhe.zh...@rivai.ai
LGTM on my side.
IMHO, we need to support attribute (rvv_vector_bits) which depend on this 
patch, am I right?

If yes, will you support this feature in GCC-14 release?



juzhe.zh...@rivai.ai
 
From: Kito Cheng
Date: 2023-10-10 12:13
To: gcc-patches; kito.cheng; palmer; jeffreyalaw; rdapp; juzhe.zhong
Subject: [PATCH v2 0/4] RISC-V target attribute
This patch set implement target attribute for RISC-V target, which is similar 
to other target like x86 or ARM, let user able to set some local setting per 
function without changing global settings.
 
We support arch, tune and cpu first, and we will support other target attribute 
later, this version DOES NOT include multi-version function support yet, that 
is future work, probably work for GCC 15.
 
The full proposal is put in RISC-V C-API document[1], which has discussed with 
RISC-V LLVM community, so we have consistent syntax and semantics. 
 
[1] https://github.com/riscv-non-isa/riscv-c-api-doc/pull/35
 
v2 changelog:
- Resolve awk multi-dimensional issue.
- Tweak code format
- Tweak testcases
 
 
 


[PATCH v15 05/39] c++: Implement __is_volatile built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_volatile.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf|  1 +
 gcc/cp/cp-trait.h| 38 +---
 gcc/cp/semantics.cc  |  4 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |  3 ++
 gcc/testsuite/g++.dg/ext/is_volatile.C   | 19 
 7 files changed, 51 insertions(+), 18 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index ad720832ccb..ead136495fd 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -64,6 +64,7 @@ struct cp_trait {
 "__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, false, true, 
false
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, false, false, false
 "__is_union", CPTK_IS_UNION, false, false, false
+"__is_volatile", CPTK_IS_VOLATILE, false, false, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
true, false, false
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, true, 
false, false
 "__remove_cv", CPTK_REMOVE_CV, false, false, true
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 4a2100779cf..0fa702f1441 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -82,7 +82,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
   40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0, 96, 96,
+  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
   96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
   96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
@@ -118,7 +118,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 46,
+  TOTAL_KEYWORDS = 47,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -127,27 +127,29 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, false, false, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, false, false, false},
 #line 66 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, false, false, false},
-#line 69 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
 #line 70 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
+#line 71 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, false, false, true},
 #line 49 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, false, false, false},
 #line 62 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, false, false, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
+#line 72 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, false, false, true},
-#line 76 "../../gcc/cp/cp-trai

[PATCH v15 06/39] libstdc++: Optimize is_volatile trait performance

2023-10-10 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 v15 07/39] c++: Implement __is_array built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 148 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_array.C  |  28 +
 7 files changed, 116 insertions(+), 72 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index ead136495fd..a0c313af253 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -40,6 +40,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, false, false, false
 "__is_abstract", CPTK_IS_ABSTRACT, false, false, false
 "__is_aggregate", CPTK_IS_AGGREGATE, false, false, false
+"__is_array", CPTK_IS_ARRAY, false, false, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, true, false, false
 "__is_base_of", CPTK_IS_BASE_OF, true, false, false
 "__is_class", CPTK_IS_CLASS, false, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 0fa702f1441..5796810aa81 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 35, 10, 20,
-  40,  0, 30, 15, 96,  0, 96, 96,  5, 15,
-  30,  0,  5, 96, 10, 25,  5,  0,  5, 96,
-  96,  5, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
+   50,   0,  30,   5, 116,   0, 11

[PATCH v15 08/39] libstdc++: Optimize is_array trait performance

2023-10-10 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 v15 09/39] c++: Implement __is_unbounded_array built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unbounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 42 ++-
 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 
 7 files changed, 71 insertions(+), 20 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index a0c313af253..8059e1e8d9e 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -64,6 +64,7 @@ struct cp_trait {
 "__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, true, false, false
 "__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, false, true, 
false
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, false, false, false
+"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, false, false, false
 "__is_union", CPTK_IS_UNION, false, false, false
 "__is_volatile", CPTK_IS_VOLATILE, false, false, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
true, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 5796810aa81..b52f2985a66 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -118,7 +118,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 48,
+  TOTAL_KEYWORDS = 49,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -127,30 +127,32 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, false, false, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, false, false, false},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, false, false, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
 #line 72 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, false, false, true},
 #line 50 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, false, false, false},
 #line 63 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, false, false, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, false, false, true},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, false, false, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, false, false, true},
-#line 68 "../../gcc/cp/cp-trait.gperf"
+#line 69 "../../gcc/cp/cp-trait.gperf"
   {"__is_volatile", CPTK_IS_VOLATILE, false, false, false},
-#line

[PATCH v15 11/39] c++: Implement __is_bounded_array built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_bounded_array.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf   |  1 +
 gcc/cp/cp-trait.h   | 86 +++--
 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 +
 7 files changed, 94 insertions(+), 42 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 8059e1e8d9e..86d7453c9f8 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -43,6 +43,7 @@ struct cp_trait {
 "__is_array", CPTK_IS_ARRAY, false, false, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, true, false, false
 "__is_base_of", CPTK_IS_BASE_OF, true, false, false
+"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, false, false, false
 "__is_class", CPTK_IS_CLASS, false, false, false
 "__is_const", CPTK_IS_CONST, false, false, false
 "__is_constructible", CPTK_IS_CONSTRUCTIBLE, false, true, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index b52f2985a66..a44498b4b90 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -82,7 +82,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,   5, 116,
+   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
   116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
   116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
@@ -118,7 +118,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 49,
+  TOTAL_KEYWORDS = 50,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -127,54 +127,56 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, false, false, true},
-#line 51 "../../gcc/cp/cp-trait.gperf"
+#line 52 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, false, false, false},
-#line 68 "../../gcc/cp/cp-trait.gperf"
+#line 69 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, false, false, false},
-#line 72 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
 #line 73 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
+#line 74 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, false, false, true},
-#line 50 "../../gcc/cp/cp-trait.gperf"
+#line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, false, false, false},
-#line 63 "../../gcc/cp/cp-trait.gperf"
+#line 64 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, false, false, false},
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 75 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, false, false, true},
-#line 79 "../../gcc/cp/cp-trait.gperf"
+#line 80 "../../gcc/cp/cp-trait.gperf"
   {"__di

[PATCH v15 10/39] libstdc++: Optimize is_unbounded_array trait performance

2023-10-10 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 v15 12/39] libstdc++: Optimize is_bounded_array trait performance

2023-10-10 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 v15 13/39] c++: Implement __is_scoped_enum built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scoped_enum.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 161 +++---
 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 +
 7 files changed, 160 insertions(+), 80 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 86d7453c9f8..705bf377b87 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -60,6 +60,7 @@ struct cp_trait {
 "__is_pod", CPTK_IS_POD, false, false, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, false, false, false
 "__is_same", CPTK_IS_SAME, true, false, false
+"__is_scoped_enum", CPTK_IS_SCOPED_ENUM, false, false, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, false, false, false
 "__is_trivial", CPTK_IS_TRIVIAL, false, false, false
 "__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, true, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index a44498b4b90..8c5f0985f00 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 92, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116,  20, 116,  45,   5,  20,
-   50,   0,  30,   5, 116,   0, 116, 116,   5,  10,
-   30,   0,   5, 116,  10,  30,   5,   0,  25, 116,
-  116,   5, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  99, 99, 99, 99, 99, 99, 99, 99

[PATCH v15 15/39] c++: Implement __is_member_pointer built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_member_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 153 ++-
 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 
 7 files changed, 120 insertions(+), 75 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 705bf377b87..d3f1343448b 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -53,6 +53,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, false, false, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, true, false, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, false, false, false
+"__is_member_pointer", CPTK_IS_MEMBER_POINTER, false, false, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, true, false, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, false, true, false
 "__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, true, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 8c5f0985f00..3de93349f77 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 111, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99,  0,  5, 50,
-  30,  0, 40, 15, 99,  0, 99, 99,  5, 10,
-  30,  0,  5, 99, 10, 50,  5,  0, 35, 99,
-  99,  5, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+  118, 118, 118, 1

[PATCH v15 14/39] libstdc++: Optimize is_scoped_enum trait performance

2023-10-10 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 v15 16/39] libstdc++: Optimize is_member_pointer trait performance

2023-10-10 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 v15 17/39] c++: Implement __is_member_function_pointer built-in trait

2023-10-10 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.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf |   1 +
 gcc/cp/cp-trait.h | 176 +-
 gcc/cp/semantics.cc   |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |   3 +
 .../g++.dg/ext/is_member_function_pointer.C   |  31 +++
 7 files changed, 131 insertions(+), 88 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index d3f1343448b..505f49bca07 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -53,6 +53,7 @@ struct cp_trait {
 "__is_final", CPTK_IS_FINAL, false, false, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, true, false, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, false, false, false
+"__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, false, false, 
false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, false, false, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, true, false, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, false, true, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 3de93349f77..0dcb08cc601 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 111, duplicates = 0 */
+/* maximum key range = 89, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118,  20, 118,   0,  55,  50,
-   40,   0,  40,  20, 118,   0, 118, 118,   5,   5,
-   30,   0,   5, 118,  10,  50,   5,   0,   5, 118,
-  118,   5, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-  118, 118, 118, 118, 118, 118
+  96, 96, 96

[PATCH v15 18/39] libstdc++: Optimize is_member_function_pointer trait performance

2023-10-10 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 v15 19/39] c++: Implement __is_member_object_pointer built-in trait

2023-10-10 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.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 62 ++-
 gcc/cp/semantics.cc   |  4 ++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 +
 .../g++.dg/ext/is_member_object_pointer.C | 30 +
 7 files changed, 74 insertions(+), 30 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 505f49bca07..4a099120512 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -54,6 +54,7 @@ struct cp_trait {
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, true, false, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, false, false, false
 "__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, false, false, 
false
+"__is_member_object_pointer", CPTK_IS_MEMBER_OBJECT_POINTER, false, false, 
false
 "__is_member_pointer", CPTK_IS_MEMBER_POINTER, false, false, false
 "__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, true, false, false
 "__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, false, true, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 0dcb08cc601..f1fce9914b0 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -118,7 +118,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 53,
+  TOTAL_KEYWORDS = 54,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -127,57 +127,57 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, false, false, true},
 #line 52 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, false, false, false},
-#line 72 "../../gcc/cp/cp-trait.gperf"
+#line 73 "../../gcc/cp/cp-trait.gperf"
   {"__is_union", CPTK_IS_UNION, false, false, false},
-#line 76 "../../gcc/cp/cp-trait.gperf"
-  {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
 #line 77 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
+#line 78 "../../gcc/cp/cp-trait.gperf"
   {"__remove_cvref", CPTK_REMOVE_CVREF, false, false, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, false, false, false},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, false, false, false},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, false, false, true},
-#line 83 "../../gcc/cp/cp-trait.gperf"
+#line 84 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, false, false, true},
-#line 80 "../../gcc/cp/cp-trait.gperf"
+#line 81 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, false, false, true},

[PATCH v15 20/39] libstdc++: Optimize is_member_object_pointer trait performance

2023-10-10 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 v15 21/39] c++: Implement __is_reference built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_reference.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 113 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_reference.C  |  34 +++
 7 files changed, 104 insertions(+), 55 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 4a099120512..1d902612f5a 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -62,6 +62,7 @@ struct cp_trait {
 "__is_pointer_interconvertible_base_of", 
CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, true, false, false
 "__is_pod", CPTK_IS_POD, false, false, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, false, false, false
+"__is_reference", CPTK_IS_REFERENCE, false, false, false
 "__is_same", CPTK_IS_SAME, true, false, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, false, false, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, false, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index f1fce9914b0..7aa695210ce 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 89, duplicates = 0 */
+/* maximum key range = 94, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 20, 96, 40,  5, 40,
-  40,  0, 25, 10, 96,  0, 96, 96,  5, 25,
-  30,  0,  5, 96, 10, 15,  5,  0, 25, 96,
-  96, 20, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-  96, 96, 96, 96, 96, 96
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
+  101, 101, 101, 101, 101, 101, 101, 101, 101, 10

[PATCH v15 22/39] libstdc++: Optimize is_reference trait performance

2023-10-10 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 v15 24/39] libstdc++: Optimize is_function trait performance

2023-10-10 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 v15 23/39] c++: Implement __is_function built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_function.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 143 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_function.C   |  58 +
 7 files changed, 143 insertions(+), 70 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 1d902612f5a..4fa14de3e90 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -51,6 +51,7 @@ struct cp_trait {
 "__is_empty", CPTK_IS_EMPTY, false, false, false
 "__is_enum", CPTK_IS_ENUM, false, false, false
 "__is_final", CPTK_IS_FINAL, false, false, false
+"__is_function", CPTK_IS_FUNCTION, false, false, false
 "__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, true, false, false
 "__is_literal_type", CPTK_IS_LITERAL_TYPE, false, false, false
 "__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, false, false, 
false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 7aa695210ce..c53e234f631 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 94, duplicates = 0 */
+/* maximum key range = 109, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101,  20, 101,  40,   5,  40,
-   40,   0,  60,  10, 101,   0, 101, 101,   5,  25,
-   30,   0,   5, 101,  10,  15,   5,   0,  25, 101,
-  101,  20, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
-  101, 101, 101, 101, 101, 101
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+  116, 

[PATCH v15 25/39] libstdc++: Optimize is_object trait performance

2023-10-10 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 v15 26/39] c++: Implement __remove_pointer built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __remove_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf |  1 +
 gcc/cp/cp-trait.h | 32 +++---
 gcc/cp/semantics.cc   |  5 +++
 gcc/testsuite/g++.dg/ext/has-builtin-1.C  |  3 ++
 gcc/testsuite/g++.dg/ext/remove_pointer.C | 51 +++
 6 files changed, 78 insertions(+), 15 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 4fa14de3e90..de3779b6d82 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -78,6 +78,7 @@ struct cp_trait {
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, true, 
false, false
 "__remove_cv", CPTK_REMOVE_CV, false, false, true
 "__remove_cvref", CPTK_REMOVE_CVREF, false, false, true
+"__remove_pointer", CPTK_REMOVE_POINTER, false, false, true
 "__remove_reference", CPTK_REMOVE_REFERENCE, false, false, true
 "__type_pack_element", CPTK_TYPE_PACK_ELEMENT, false, true, true
 "__underlying_type", CPTK_UNDERLYING_TYPE, false, false, true
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index c53e234f631..503e6804145 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -118,7 +118,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 56,
+  TOTAL_KEYWORDS = 57,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -127,7 +127,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 85 "../../gcc/cp/cp-trait.gperf"
+#line 86 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, false, false, true},
 #line 52 "../../gcc/cp/cp-trait.gperf"
   {"__is_enum", CPTK_IS_ENUM, false, false, false},
@@ -139,17 +139,19 @@ cp_trait_lookup::find (const char *str, size_t len)
   {"__remove_cvref", CPTK_REMOVE_CVREF, false, false, true},
 #line 51 "../../gcc/cp/cp-trait.gperf"
   {"__is_empty", CPTK_IS_EMPTY, false, false, false},
+#line 81 "../../gcc/cp/cp-trait.gperf"
+  {"__remove_pointer", CPTK_REMOVE_POINTER, false, false, true},
 #line 70 "../../gcc/cp/cp-trait.gperf"
   {"__is_trivial", CPTK_IS_TRIVIAL, false, false, false},
-#line 81 "../../gcc/cp/cp-trait.gperf"
+#line 82 "../../gcc/cp/cp-trait.gperf"
   {"__remove_reference", CPTK_REMOVE_REFERENCE, false, false, true},
-#line 86 "../../gcc/cp/cp-trait.gperf"
+#line 87 "../../gcc/cp/cp-trait.gperf"
   {"__direct_bases", CPTK_DIRECT_BASES, false, false, true},
-#line 83 "../../gcc/cp/cp-trait.gperf"
+#line 84 "../../gcc/cp/cp-trait.gperf"
   {"__underlying_type", CPTK_UNDERLYING_TYPE, false, false, true},
 #line 46 "../../gcc/cp/cp-trait.gperf"
   {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, false, false, false},
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
   {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, false, true, true},
 #line 74 "../../gcc/cp/cp-trait.gperf"
   {"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, false, false, false},
@@ -237,21 +239,21 @@ cp_trait_lookup::find (const char *str, size_t len)
   {"__is_final", CPTK_IS_FINAL, false, false, false},
 #line 54 "../../gcc/cp/cp-trait.gperf"
   {"__is_function", CPTK_IS_FUNCTION, false, false, false},
-#line 84 "../../gcc/cp/cp-trait.gperf"
+#line 85 "../../gcc/cp/cp-trait.gperf"
   {"__is_deducible ", CPTK_IS_DEDUCIBLE, true, false, false}
 };
 
   static const signed char lookup[] =
 {
   -1, -1, -1, -1, -1, -1, -1,  0, -1,  1,  2,  3, -1, -1,
-   4,  5, -1,  6,  7,  8, -1, -1,  9, 10, 11, 12, 13, 14,
-  15, -1, 16, 17, 18, 19, -1, 20, -1, 21, 22, -1, 23, -1,
-  24, 25, 26, 27, -1, 28, 29, 30, 31, -1, 32, -1, 33, 34,
-  -1, -1, 35, 36, 37, 38, -1, 39, 40, -1, -1, -1, 41, 

[PATCH v15 28/39] c++, libstdc++: Implement __is_pointer built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_pointer.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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.
* g++.dg/tm/pr46567.C (__is_pointer): Rename to ...
(__is_ptr): ... this.
* g++.dg/torture/20070621-1.C: Likewise.
* g++.dg/torture/pr57107.C: Likewise.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_pointer): Rename to ...
(__is_ptr): ... this.
* include/bits/deque.tcc: Use __is_ptr instead.
* include/bits/stl_algobase.h: Likewise.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc|   3 +
 gcc/cp/cp-trait.def |   1 +
 gcc/cp/cp-trait.gperf   |   1 +
 gcc/cp/cp-trait.h   | 155 ++--
 gcc/cp/semantics.cc |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|   3 +
 gcc/testsuite/g++.dg/ext/is_pointer.C   |  51 +++
 gcc/testsuite/g++.dg/tm/pr46567.C   |  22 +--
 gcc/testsuite/g++.dg/torture/20070621-1.C   |   4 +-
 gcc/testsuite/g++.dg/torture/pr57107.C  |   4 +-
 libstdc++-v3/include/bits/cpp_type_traits.h |   6 +-
 libstdc++-v3/include/bits/deque.tcc |   6 +-
 libstdc++-v3/include/bits/stl_algobase.h|   6 +-
 13 files changed, 165 insertions(+), 101 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index de3779b6d82..07a333ea826 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -62,6 +62,7 @@ struct cp_trait {
 "__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, true, false, false
 "__is_pointer_interconvertible_base_of", 
CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, true, false, false
 "__is_pod", CPTK_IS_POD, false, false, false
+"__is_pointer", CPTK_IS_POINTER, false, false, false
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, false, false, false
 "__is_reference", CPTK_IS_REFERENCE, false, false, false
 "__is_same", CPTK_IS_SAME, true, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 503e6804145..011e454760c 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 92, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116,  20, 116,  40,   5,  40,
-   50,   0,  55,  10, 116,   0, 116, 116,   5,  25,
-   30,   0,   5, 116,  10,  15,   5,   0,  25, 116,
-  116,  20, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
-  116, 116, 116, 116, 116, 116, 116, 116, 116, 

[PATCH v15 27/39] libstdc++: Optimize remove_pointer trait performance

2023-10-10 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 v15 31/39] libstdc++: Optimize is_arithmetic trait performance

2023-10-10 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 v15 32/39] libstdc++: Optimize is_fundamental trait performance

2023-10-10 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 v15 29/39] libstdc++: Optimize is_pointer trait performance

2023-10-10 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_ptr): 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 3711e4be526..4da1e7c407c 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_ptr : __truth_type<__is_pointer(_Tp)>
+{
+  enum { __value = __is_pointer(_Tp) };
+};
+#else
   template
 struct __is_ptr
 {
@@ -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 v15 35/39] libstdc++: Optimize is_unsigned trait performance

2023-10-10 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 v15 37/39] libstdc++: Optimize is_signed trait performance

2023-10-10 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 v15 38/39] c++, libstdc++: Implement __is_scalar built-in trait

2023-10-10 Thread Ken Matsui
This patch implements built-in trait for std::is_scalar. The existent
__is_scalar codes were replaced with __is_scalar_type to avoid unintentional
macro replacement by the new built-in.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_scalar.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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.
* g++.dg/tm/pr46567.C: Use __is_scalar_type instead.
* g++.dg/torture/pr57107.C: Likewise.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_scalar): Rename to ...
(__is_scalar_type): ... this.
* include/bits/stl_algobase.h: Use __is_scalar_type instead.
* include/bits/valarray_array.h: Likewise.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc|   3 +
 gcc/cp/cp-trait.def |   1 +
 gcc/cp/cp-trait.gperf   |   1 +
 gcc/cp/cp-trait.h   | 186 ++--
 gcc/cp/semantics.cc |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|   3 +
 gcc/testsuite/g++.dg/ext/is_scalar.C|  31 
 gcc/testsuite/g++.dg/tm/pr46567.C   |  10 +-
 gcc/testsuite/g++.dg/torture/pr57107.C  |   4 +-
 libstdc++-v3/include/bits/cpp_type_traits.h |   2 +-
 libstdc++-v3/include/bits/stl_algobase.h|   8 +-
 libstdc++-v3/include/bits/valarray_array.h  |   2 +-
 12 files changed, 150 insertions(+), 105 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 67a1e37d754..654da0568ec 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -67,6 +67,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, false, false, false
 "__is_reference", CPTK_IS_REFERENCE, false, false, false
 "__is_same", CPTK_IS_SAME, true, false, false
+"__is_scalar", CPTK_IS_SCALAR, false, false, false
 "__is_signed", CPTK_IS_SIGNED, false, false, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, false, false, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, false, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index dd94ac56fec..3c13835a8df 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,10 +80,10 @@ cp_trait_lookup::hash (const char *str, size_t len)
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
-  126, 126, 126, 126, 126,  20, 126,  40,  45,  50,
-   55,   0,   5,  15, 126,   0, 126, 126,  35,  10,
-   35,   0,  10, 126,  30,   5,   5,  16,  30, 126,
-  126,  10, 126, 126, 126, 126, 126, 126, 126, 126,
+  126, 126, 126, 126, 126,  40, 126,  25,  21,  50,
+0,   0,  30,  10, 126,   0, 126, 126,  25,   5,
+   50,   0,  61, 126,  10,  10,   5,   0,  15, 126,
+  126,   5, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
   126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
@@ -118,7 +118,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
 {
-  TOTAL_KEYWORDS = 61,
+  TOTAL_KEYWORDS = 62,
   MIN_WORD_LENGTH = 7,
   MAX_WORD_LENGTH = 37,
   MIN_HASH_VALUE = 7,
@@ -127,141 +127,143 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
 {
-#line 90 "../../gcc/cp/cp-trait.gperf"
+#line 91 "../../gcc/cp/cp-trait.gperf"
   {"__bases", CPTK_BASES, false, false, true},
-#line 83 "../../gcc/cp/cp-trait.gperf"
-  

[PATCH v15 34/39] c++: Implement __is_unsigned built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_unsigned.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 118 ---
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_unsigned.C   |  47 +
 7 files changed, 120 insertions(+), 57 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 5493f38bcbb..c39b9d9007a 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -75,6 +75,7 @@ struct cp_trait {
 "__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, false, false, false
 "__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, false, false, false
 "__is_union", CPTK_IS_UNION, false, false, false
+"__is_unsigned", CPTK_IS_UNSIGNED, false, false, false
 "__is_volatile", CPTK_IS_VOLATILE, false, false, false
 "__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 
true, false, false
 "__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, true, 
false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index b6dcb19cefb..635c9a3a0e5 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 97, duplicates = 0 */
+/* maximum key range = 129, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104,  20, 104,  45,  50,  40,
-5,   0,  55,   0, 104,   0, 104, 104,  10,  15,
-   35,   0,  10, 104,  10,  15,   5,   0,  20, 104,
-  104,  20, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
-  104, 104, 104, 104, 104, 104
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+  136, 136, 136, 136, 136, 136

[PATCH v15 36/39] c++, libstdc++: Implement __is_signed built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_signed.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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.
* g++.dg/tm/pr46567.C (__is_signed): Rename to ...
(__is_signed_type): ... this.

libstdc++-v3/ChangeLog:

* include/ext/numeric_traits.h (__is_signed): Rename to ...
(__is_signed_type): ... this.
* include/bits/charconv.h: Use __is_signed_type instead.
* include/bits/locale_facets.tcc: Likewise.
* include/bits/uniform_int_dist.h: Likewise.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   3 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/cp-trait.gperf|   1 +
 gcc/cp/cp-trait.h| 211 ++-
 gcc/cp/semantics.cc  |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_signed.C |  47 +
 gcc/testsuite/g++.dg/tm/pr46567.C|  12 +-
 libstdc++-v3/include/bits/charconv.h |   2 +-
 libstdc++-v3/include/bits/locale_facets.tcc  |   6 +-
 libstdc++-v3/include/bits/uniform_int_dist.h |   4 +-
 libstdc++-v3/include/ext/numeric_traits.h|  18 +-
 12 files changed, 186 insertions(+), 126 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index c39b9d9007a..67a1e37d754 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -67,6 +67,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, false, false, false
 "__is_reference", CPTK_IS_REFERENCE, false, false, false
 "__is_same", CPTK_IS_SAME, true, false, false
+"__is_signed", CPTK_IS_SIGNED, false, false, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, false, false, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, false, false, false
 "__is_trivial", CPTK_IS_TRIVIAL, false, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 635c9a3a0e5..dd94ac56fec 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 129, duplicates = 0 */
+/* maximum key range = 119, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136,  20, 136,  45,  35,  40,
-   60,   0,  55,   0, 136,   0, 136, 136,  10,  15,
-   35,   0,  10, 136,  10,  15,   5,  15,   0, 136,
-  136,  20, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
-  136, 1

[PATCH v15 39/39] libstdc++: Optimize is_scalar trait performance

2023-10-10 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 v15 30/39] c++, libstdc++: Implement __is_arithmetic built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_arithmetic.
* cp-trait.gperf: Reflect cp-trait.def change.
* cp-trait.h: Likewise.
* 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.
* g++.dg/tm/pr46567.C (__is_arithmetic): Rename to ...
(__is_arith): ... this.
* g++.dg/torture/pr57107.C: Likewise.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_arithmetic): Rename to ...
(__is_arith): ... this.
* include/c_global/cmath: Use __is_arith instead.
* include/c_std/cmath: Likewise.
* include/tr1/cmath: Likewise.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc|   3 +
 gcc/cp/cp-trait.def |   1 +
 gcc/cp/cp-trait.gperf   |   1 +
 gcc/cp/cp-trait.h   | 184 ++--
 gcc/cp/semantics.cc |   4 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C|   3 +
 gcc/testsuite/g++.dg/ext/is_arithmetic.C|  33 
 gcc/testsuite/g++.dg/tm/pr46567.C   |   6 +-
 gcc/testsuite/g++.dg/torture/pr57107.C  |   4 +-
 libstdc++-v3/include/bits/cpp_type_traits.h |   4 +-
 libstdc++-v3/include/c_global/cmath |  48 ++---
 libstdc++-v3/include/c_std/cmath|  24 +--
 libstdc++-v3/include/tr1/cmath  |  24 +--
 13 files changed, 193 insertions(+), 146 deletions(-)
 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/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 07a333ea826..5493f38bcbb 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -40,6 +40,7 @@ struct cp_trait {
 "__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, false, false, false
 "__is_abstract", CPTK_IS_ABSTRACT, false, false, false
 "__is_aggregate", CPTK_IS_AGGREGATE, false, false, false
+"__is_arithmetic", CPTK_IS_ARITHMETIC, false, false, false
 "__is_array", CPTK_IS_ARRAY, false, false, false
 "__is_assignable", CPTK_IS_ASSIGNABLE, true, false, false
 "__is_base_of", CPTK_IS_BASE_OF, true, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index 011e454760c..b6dcb19cefb 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -56,7 +56,7 @@ struct cp_trait {
   bool variadic;
   bool type;
 };
-/* maximum key range = 92, duplicates = 0 */
+/* maximum key range = 97, duplicates = 0 */
 
 class cp_trait_lookup
 {
@@ -71,32 +71,32 @@ cp_trait_lookup::hash (const char *str, size_t len)
 {
   static const unsigned char asso_values[] =
 {
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 20, 99, 40, 45, 40,
-   5,  0, 55, 10, 99,  0, 99, 99, 10, 25,
-  30,  0, 10, 99, 10, 15,  5,  0, 20, 99,
-  99, 10, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-  99, 99, 99, 99, 9

Re: [PATCH] RISC-V Regression: Fix FAIL of bb-slp-pr65935.c for RVV

2023-10-10 Thread Richard Biener
On Tue, 10 Oct 2023, Juzhe-Zhong wrote:

> Here is the reference comparing dump IR between ARM SVE and RVV.
> 
> https://godbolt.org/z/zqess8Gss
> 
> We can see RVV has one more dump IR:
> optimized: basic block part vectorized using 128 byte vectors
> since RVV has 1024 bit vectors.
> 
> The codegen is reasonable good.
> 
> However, I saw GCN also has 1024 bit vector.
> This patch may cause this case FAIL in GCN port ?
> 
> Hi, GCN folk, could you check this patch in GCN port for me ?

OK

> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/vect/bb-slp-pr65935.c: Add vect1024 variant.
>   * lib/target-supports.exp: Ditto.
> 
> ---
>  gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c | 3 ++-
>  gcc/testsuite/lib/target-supports.exp  | 6 ++
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c 
> b/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
> index 8df35327e7a..9ef1330b47c 100644
> --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
> +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
> @@ -67,7 +67,8 @@ int main()
>  
>  /* We should also be able to use 2-lane SLP to initialize the real and
> imaginary components in the first loop of main.  */
> -/* { dg-final { scan-tree-dump-times "optimized: basic block" 10 "slp1" } } 
> */
> +/* { dg-final { scan-tree-dump-times "optimized: basic block" 10 "slp1" { 
> target {! { vect1024 } } } } } */
> +/* { dg-final { scan-tree-dump-times "optimized: basic block" 11 "slp1" { 
> target { { vect1024 } } } } } */
>  /* We should see the s->phase[dir] operand splatted and no other operand 
> built
> from scalars.  See PR97334.  */
>  /* { dg-final { scan-tree-dump "Using a splat" "slp1" } } */
> diff --git a/gcc/testsuite/lib/target-supports.exp 
> b/gcc/testsuite/lib/target-supports.exp
> index dc366d35a0a..95c489d7f76 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -8903,6 +8903,12 @@ proc check_effective_target_vect_variable_length { } {
>  return [expr { [lindex [available_vector_sizes] 0] == 0 }]
>  }
>  
> +# Return 1 if the target supports vectors of 1024 bits.
> +
> +proc check_effective_target_vect1024 { } {
> +return [expr { [lsearch -exact [available_vector_sizes] 1024] >= 0 }]
> +}
> +
>  # Return 1 if the target supports vectors of 512 bits.
>  
>  proc check_effective_target_vect512 { } {
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)


[PATCH v15 33/39] libstdc++: Optimize is_compound trait performance

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



Re: 回复: [PATCH] RISC-V/testsuite: Enable `vect_pack_trunc'

2023-10-10 Thread Maciej W. Rozycki
On Mon, 9 Oct 2023, Maciej W. Rozycki wrote:

> > Btw, could you rebase to the trunk and run regression again?
> 
>  Full regression-testing takes roughly 40 hours here and I do not normally
> update the tree midway through my work so as not to add variables and end 
> up chasing a moving target, especially with such an unstable state that we 
> have ended up with recently with the RISC-V port.  Since I'm done with 
> this part I can refresh and schedule another run if you are curious as to 
> how it looks like from my side.  For the C subset alone it'll take less.

 After 10 hours I have now got:

=== gcc Summary ===

# of expected passes194576
# of unexpected failures600
# of unexpected successes   11
# of expected failures  1631
# of unresolved testcases   120
# of unsupported tests  3828

as at commit cc5033721553 ("Fixes for profile count/probability 
maintenance"), which is slightly better, but still far from your 92 FAILs.  
NB I ran this testing with `--param=riscv-autovec-preference=scalable'; I 
guess I could have mentioned it.

  Maciej


Re: Re: [PATCH] RISC-V/testsuite: Enable `vect_pack_trunc'

2023-10-10 Thread juzhe.zh...@rivai.ai
It's weird. Could you give me the FAILs report?



juzhe.zh...@rivai.ai
 
From: Maciej W. Rozycki
Date: 2023-10-10 18:18
To: 钟居哲
CC: gcc-patches; Jeff Law; rdapp.gcc; kito.cheng
Subject: Re: 回复: [PATCH] RISC-V/testsuite: Enable `vect_pack_trunc'
On Mon, 9 Oct 2023, Maciej W. Rozycki wrote:
 
> > Btw, could you rebase to the trunk and run regression again?
> 
>  Full regression-testing takes roughly 40 hours here and I do not normally
> update the tree midway through my work so as not to add variables and end 
> up chasing a moving target, especially with such an unstable state that we 
> have ended up with recently with the RISC-V port.  Since I'm done with 
> this part I can refresh and schedule another run if you are curious as to 
> how it looks like from my side.  For the C subset alone it'll take less.
 
After 10 hours I have now got:
 
=== gcc Summary ===
 
# of expected passes 194576
# of unexpected failures 600
# of unexpected successes 11
# of expected failures 1631
# of unresolved testcases 120
# of unsupported tests 3828
 
as at commit cc5033721553 ("Fixes for profile count/probability 
maintenance"), which is slightly better, but still far from your 92 FAILs.  
NB I ran this testing with `--param=riscv-autovec-preference=scalable'; I 
guess I could have mentioned it.
 
  Maciej
 


Re: Re: [PATCH] RISC-V/testsuite: Enable `vect_pack_trunc'

2023-10-10 Thread Maciej W. Rozycki
On Tue, 10 Oct 2023, 钟居哲 wrote:

> I know you want vect_int to block the test for rv64gc. 
> But unfortunately it failed.

 Why?

> And I have changed everything to run vect testsuite with "riscv_v".
> [PATCH] RISC-V: Enable more tests of "vect" for RVV (gnu.org)
> 
> So to be consistent, plz add "riscv_v".

 I'll experiment with things here.

 NB it makes sense to sort targets alphabetically in these feature tests: 
not only it makes it easier to find whether your target of interest is 
present in the ever increasing list, but there's less clobber as new 
targets are added as well, because most time you don't need to fiddle with 
the test that becomes the second last, which in turn means `git blame' 
won't show you the noise and save you one step when chasing later on the 
original commit that has added it.  This is why I added my new check in 
the middle, roughly alphabetically (as the order is a bit messy at 
present), and you can see how cleaner the resulting change is.

  Maciej


[PATCH] Fix missed CSE with a BLKmode entity

2023-10-10 Thread Richard Biener
The following fixes fallout of r10-7145-g1dc00a8ec9aeba which made
us cautionous about CSEing a load to an object that has padding bits.
The added check also triggers for BLKmode entities like STRING_CSTs
but by definition a BLKmode entity does not have padding bits.

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

PR tree-optimization/111751
* tree-ssa-sccvn.cc (visit_reference_op_load): Exempt
BLKmode result from the padding bits check.
---
 gcc/tree-ssa-sccvn.cc | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index d2aab38c2d2..ce8ae8c6753 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -5747,8 +5747,9 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
 {
   /* Avoid the type punning in case the result mode has padding where
 the op we lookup has not.  */
-  if (maybe_lt (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (result))),
-   GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op)
+  if (TYPE_MODE (TREE_TYPE (result)) != BLKmode
+ && maybe_lt (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (result))),
+  GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op)
result = NULL_TREE;
   else
{
-- 
2.35.3


[PATCH] tree-optimization/111519 - strlen optimization skips clobbering store

2023-10-10 Thread Richard Biener
The following fixes a mistake in count_nonzero_bytes which happily
skips over stores clobbering the memory we load a value we store
from and then performs analysis on the memory state before the
intermediate store.

The patch implements the most simple fix - guarantee that there are
no intervening stores by tracking the original active virtual operand
and comparing that to the one of a load we attempt to analyze.

This simple approach breaks two subtests of gcc.dg/Wstringop-overflow-69.c
which I chose to XFAIL.

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

OK?

Thanks,
Richard.

PR tree-optimization/111519
* tree-ssa-strlen.cc (strlen_pass::count_nonzero_bytes):
Add virtual operand argument and pass it through.  Compare
the memory state we try to analyze to the memory state we
are going to use the result oon.
(strlen_pass::count_nonzero_bytes_addr): Add virtual
operand argument and pass it through.

* gcc.dg/torture/pr111519.c: New testcase.
* gcc.dg/Wstringop-overflow-69.c: XFAIL two subtests.
---
 gcc/testsuite/gcc.dg/Wstringop-overflow-69.c |  4 +-
 gcc/testsuite/gcc.dg/torture/pr111519.c  | 47 
 gcc/tree-ssa-strlen.cc   | 27 ++-
 3 files changed, 64 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr111519.c

diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-69.c 
b/gcc/testsuite/gcc.dg/Wstringop-overflow-69.c
index be361fe620d..3c17fe13d8e 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-69.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-69.c
@@ -57,9 +57,9 @@ void warn_vec_decl (void)
 {
   *(VC2*)a1 = c2;   // { dg-warning "writing 2 bytes into a region of size 
1" }
   *(VC4*)a2 = c4;   // { dg-warning "writing 4 bytes into a region of size 
2" }
-  *(VC4*)a3 = c4;   // { dg-warning "writing 4 bytes into a region of size 
3" }
+  *(VC4*)a3 = c4;   // { dg-warning "writing 4 bytes into a region of size 
3" "pr111519" { xfail *-*-* } }
   *(VC8*)a4 = c8;   // { dg-warning "writing 8 bytes into a region of size 
4" }
-  *(VC8*)a7 = c8;   // { dg-warning "writing 8 bytes into a region of size 
7" }
+  *(VC8*)a7 = c8;   // { dg-warning "writing 8 bytes into a region of size 
7" "pr111519" { xfail *-*-* } }
   *(VC16*)a15 = c16;// { dg-warning "writing 16 bytes into a region of 
size 15" }
 }
 
diff --git a/gcc/testsuite/gcc.dg/torture/pr111519.c 
b/gcc/testsuite/gcc.dg/torture/pr111519.c
new file mode 100644
index 000..095bb1cd13b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr111519.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+
+int a, o;
+char b, f, i;
+long c;
+static signed char d;
+static char g;
+unsigned *h;
+signed char *e = &f;
+static signed char **j = &e;
+static long k[2];
+unsigned **l = &h;
+short m;
+volatile int z;
+
+__attribute__((noipa)) void
+foo (char *p)
+{
+  (void) p;
+}
+
+int
+main ()
+{
+  int p = z;
+  signed char *n = &d;
+  *n = 0;
+  while (c)
+for (; i; i--)
+  ;
+  for (g = 0; g <= 1; g++)
+{
+  *n = **j;
+  k[g] = 0 != &m;
+  *e = l && k[0];
+}
+  if (p)
+foo (&b);
+  for (; o < 4; o++)
+{
+  a = d;
+  if (p)
+   foo (&b);
+}
+  if (a != 1)
+__builtin_abort ();
+}
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index 8b7ef919826..0ff3f2e308a 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -281,14 +281,14 @@ public:
gimple *stmt,
unsigned lenrange[3], bool *nulterm,
bool *allnul, bool *allnonnul);
-  bool count_nonzero_bytes (tree exp,
+  bool count_nonzero_bytes (tree exp, tree vuse,
gimple *stmt,
unsigned HOST_WIDE_INT offset,
unsigned HOST_WIDE_INT nbytes,
unsigned lenrange[3], bool *nulterm,
bool *allnul, bool *allnonnul,
ssa_name_limit_t &snlim);
-  bool count_nonzero_bytes_addr (tree exp,
+  bool count_nonzero_bytes_addr (tree exp, tree vuse,
 gimple *stmt,
 unsigned HOST_WIDE_INT offset,
 unsigned HOST_WIDE_INT nbytes,
@@ -4531,8 +4531,8 @@ nonzero_bytes_for_type (tree type, unsigned lenrange[3],
 }
 
 /* Recursively determine the minimum and maximum number of leading nonzero
-   bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
-   to each.
+   bytes in the representation of EXP at memory state VUSE and set
+   LENRANGE[0] and LENRANGE[1] to each.
Sets LENRANGE[2] to the total size of the access (which may be less
than LENRANGE[1] when what's being referenced by EXP is a pointer
rather than an array).
@@ -4546,7 +4546,7 @@ nonzero_bytes_for_type (tree type, unsigned lenrange[3],
Returns true

Re: [PATCH 2/3]middle-end: updated niters analysis to handle multiple exits.

2023-10-10 Thread Richard Biener
On Mon, 2 Oct 2023, Tamar Christina wrote:

> Hi All,
> 
> This second part updates niters analysis to be able to analyze any number of
> exits.  If we have multiple exits we determine the main exit by finding the
> first counting IV.
> 
> The change allows the vectorizer to pass analysis for multiple loops, but we
> later gracefully reject them.  It does however allow us to test if the exit
> handling is using the right exit everywhere.
> 
> Additionally since we analyze all exits, we now return all conditions for them
> and determine which condition belongs to the main exit.
> 
> The main condition is needed because the vectorizer needs to ignore the main 
> IV
> condition during vectorization as it will replace it during codegen.
> 
> To track versioned loops we extend the contract between ifcvt and the 
> vectorizer
> to store the exit number in aux so that we can match it up again during 
> peeling.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-linux-gnu, and
> no issues.
> 
> Ok for master?
> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
>   * tree-if-conv.cc (tree_if_conversion): Record exits in aux.
>   * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): Use
>   it.
>   * tree-vect-loop.cc (vect_get_loop_niters): Determine main exit.
>   (vec_init_loop_exit_info): Extend analysis when multiple exits.
>   (vect_analyze_loop_form): Record conds and determine main cond.
>   (vect_create_loop_vinfo): Extend bookkeeping of conds.
>   (vect_analyze_loop): Release conds.
>   * tree-vectorizer.h (LOOP_VINFO_LOOP_CONDS,
>   LOOP_VINFO_LOOP_IV_COND):  New.
>   (struct vect_loop_form_info): Add conds, alt_loop_conds;
>   (struct loop_vec_info): Add conds, loop_iv_cond.
> 
> --- inline copy of patch -- 
> diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
> index 
> 799f071965e5c41eb352b5530cf1d9c7ecf7bf25..3dc2290467797ebbfcef55903531b22829f4fdbd
>  100644
> --- a/gcc/tree-if-conv.cc
> +++ b/gcc/tree-if-conv.cc
> @@ -3795,6 +3795,13 @@ tree_if_conversion (class loop *loop, vec 
> *preds)
>  }
>if (need_to_ifcvt)
>  {
> +  /* Before we rewrite edges we'll record their original position in the
> +  edge map such that we can map the edges between the ifcvt and the
> +  non-ifcvt loop during peeling.  */
> +  uintptr_t idx = 0;
> +  for (edge exit : get_loop_exit_edges (loop))
> + exit->aux = (void*)idx++;
> +
>/* Now all statements are if-convertible.  Combine all the basic
>blocks into one huge basic block doing the if-conversion
>on-the-fly.  */
> diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
> index 
> e06717272aafc6d31cbdcb94840ac25de616da6d..77f8e668bcc8beca99ba4052e1b12e0d17300262
>  100644
> --- a/gcc/tree-vect-loop-manip.cc
> +++ b/gcc/tree-vect-loop-manip.cc
> @@ -1470,6 +1470,18 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop 
> *loop, edge loop_exit,
>scalar_loop = loop;
>scalar_exit = loop_exit;
>  }
> +  else if (scalar_loop == loop)
> +scalar_exit = loop_exit;
> +  else
> +{
> +  /* Loop has been version, match exits up using the aux index.  */
> +  for (edge exit : get_loop_exit_edges (scalar_loop))
> + if (exit->aux == loop_exit->aux)
> +   {
> + scalar_exit = exit;
> + break;
> +   }
> +}
>  
>bbs = XNEWVEC (basic_block, scalar_loop->num_nodes + 1);
>pbbs = bbs + 1;
> @@ -1501,6 +1513,8 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop 
> *loop, edge loop_exit,
>exit = loop_exit;
>basic_block new_preheader = new_bbs[0];
>  
> +  /* Record the new loop exit information.  new_loop doesn't have SCEV data 
> and
> + so we must initialize the exit information.  */
>if (new_e)
>  *new_e = new_exit;
>  
> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index 
> 6e60d84143626a8e1d801bb580f4dcebc73c7ba7..f1caa5f207d3b13da58c3a313b11d1ef98374349
>  100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -851,79 +851,106 @@ vect_fixup_scalar_cycles_with_patterns (loop_vec_info 
> loop_vinfo)
> in NUMBER_OF_ITERATIONSM1.  Place the condition under which the
> niter information holds in ASSUMPTIONS.
>  
> -   Return the loop exit condition.  */
> +   Return the loop exit conditions.  */
>  
>  
> -static gcond *
> -vect_get_loop_niters (class loop *loop, edge exit, tree *assumptions,
> +static vec
> +vect_get_loop_niters (class loop *loop, tree *assumptions, const_edge 
> main_exit,
> tree *number_of_iterations, tree *number_of_iterationsm1)

Any reason you swap exit and main_exit?  IMHO the input better pairs with
the other input 'loop'.


>  {
> +  auto_vec exits = get_loop_exit_edges (loop);
> +  vec conds;
> +  conds.create (exits.length ());
>class tree_niter_desc niter_desc;
>tree niter_assumptions, niter, may_be_zero;
> -  gcond *cond = get_loop_exit_condition (loop);
>  

Re: [PATCH 6/6] aarch64: Add front-end argument type checking for target builtins

2023-10-10 Thread Richard Earnshaw (lists)
On 09/10/2023 14:12, Victor Do Nascimento wrote:
> 
> 
> On 10/7/23 12:53, Richard Sandiford wrote:
>> Richard Earnshaw  writes:
>>> On 03/10/2023 16:18, Victor Do Nascimento wrote:
 In implementing the ACLE read/write system register builtins it was
 observed that leaving argument type checking to be done at expand-time
 meant that poorly-formed function calls were being "fixed" by certain
 optimization passes, meaning bad code wasn't being properly picked up
 in checking.

 Example:

     const char *regname = "amcgcr_el0";
     long long a = __builtin_aarch64_rsr64 (regname);

 is reduced by the ccp1 pass to

     long long a = __builtin_aarch64_rsr64 ("amcgcr_el0");

 As these functions require an argument of STRING_CST type, there needs
 to be a check carried out by the front-end capable of picking this up.

 The introduced `check_general_builtin_call' function will be called by
 the TARGET_CHECK_BUILTIN_CALL hook whenever a call to a builtin
 belonging to the AARCH64_BUILTIN_GENERAL category is encountered,
 carrying out any appropriate checks associated with a particular
 builtin function code.
>>>
>>> Doesn't this prevent reasonable wrapping of the __builtin... names with
>>> something more palatable?  Eg:
>>>
>>> static inline __attribute__(("always_inline")) long long get_sysreg_ll
>>> (const char *regname)
>>> {
>>>     return __builtin_aarch64_rsr64 (regname);
>>> }
>>>
>>> ...
>>>     long long x = get_sysreg_ll("amcgcr_el0");
>>> ...
>>
>> I think it's case of picking your poison.  If we didn't do this,
>> and only checked later, then it's unlikely that GCC and Clang would
>> be consistent about when a constant gets folded soon enough.
>>
>> But yeah, it means that the above would need to be a macro in C.
>> Enlightened souls using C++ could instead do:
>>
>>    template
>>    long long get_sysreg_ll()
>>    {
>>  return __builtin_aarch64_rsr64(regname);
>>    }
>>
>>    ... get_sysreg_ll<"amcgcr_el0">() ...
>>
>> Or at least I hope so.  Might be nice to have a test for this.
>>
>> Thanks,
>> Richard
> 
> As Richard Earnshaw mentioned, this does break the use of `static inline 
> __attribute__(("always_inline"))', something I had found out in my testing.  
> My chosen implementation was indeed, to quote Richard Sandiford, a case of 
> "picking your poison" to have things line up with Clang and behaving 
> consistently across optimization levels.
> 
> Relaxing the the use of `TARGET_CHECK_BUILTIN_CALL' meant optimizations were 
> letting too many things through. Example:
> 
> const char *regname = "amcgcr_el0";
> long long a = __builtin_aarch64_rsr64 (regname);
> 
> gets folded to
> 
> long long a = __builtin_aarch64_rsr64 ("amcgcr_el0");
> 
> and compilation passes at -01 even though it fails at -O0.
> 
> I had, however, not given any thought to the use of a template as a valid C++ 
> alternative.
> 
> I will evaluate the use of templates and add tests accordingly.

This just seems inconsistent with all the builtins we already have that require 
literal constants for parameters.  For example (to pick just one of many), 
vshr_n_q8(), where the second parameter must be a literal value.  In practice 
we accept anything that resolves to a compile-time constant integer expression 
and rely on that to avoid having to have hundreds of macros binding the ACLE 
names to the underlying builtin equivalents.

Furthermore, I don't really see the problem with the examples you cite.  It's 
not as though the user can change these at run-time and expect to get a 
different register.

R.

> 
> Cheers,
> Victor



Re: [PATCH] tree-optimization/111519 - strlen optimization skips clobbering store

2023-10-10 Thread Jakub Jelinek
On Tue, Oct 10, 2023 at 10:49:04AM +, Richard Biener wrote:
> The following fixes a mistake in count_nonzero_bytes which happily
> skips over stores clobbering the memory we load a value we store
> from and then performs analysis on the memory state before the
> intermediate store.
> 
> The patch implements the most simple fix - guarantee that there are
> no intervening stores by tracking the original active virtual operand
> and comparing that to the one of a load we attempt to analyze.
> 
> This simple approach breaks two subtests of gcc.dg/Wstringop-overflow-69.c
> which I chose to XFAIL.

This function is a total mess, but I think punting right after the
gimple_assign_single_p test is too big hammer.
There are various cases and some of them are fine even when vuse is
different, others aren't.
The function at that point tries to handle CONSTRUCTOR, MEM_REF, or decls.

I don't see why the CONSTRUCTOR case couldn't be fine regardless of the
vuse.  Though, am not really sure when a CONSTRUCTOR would appear, the
lhs would need to be an SSA_NAME, so wouldn't for vectors that be a
VECTOR_CST instead, etc.?  Ah, perhaps a vector with some non-constant
element in it.
The MEM_REF case supposedly only if we can guarantee nothing could overwrite
it (so MEM_REF of TREE_STATIC TREE_READONLY could be fine, STRING_CST too,
anything else is wrong - count_nonzero_bytes_addr uses the
get_stridx/get_strinfo APIs, which for something that can be changed
always reflects only the state at the current statement.  So, e.g. the
get_stridx (exp, stmt) > 0 case in count_nonzero_bytes_addr is when
the caller must definitely punt if vuse is different.
Then for decls, again, CONST_DECLs, DECL_IN_CONSTANT_POOLs are certainly
fine.  Other decls for which ctor_for_folding returns non-error_mark_node
should be fine as well, I think ctor_useable_for_folding_p is supposed
to verify that.  STRING_CSTs should be fine as well.

So maybe pass the vuse down to count_nonzero_bytes_addr and return false
in the idx > 0 case in there if gimple_vuse (stmt) != vuse?

Jakub



[Committed] RISC-V: Add testcase for SCCVN optimization[PR111751]

2023-10-10 Thread Juzhe-Zhong
Add testcase for PR111751 which has been fixed:
https://gcc.gnu.org/pipermail/gcc-patches/2023-October/632474.html

PR target/111751

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/pr111751.c: New test.

---
 .../gcc.target/riscv/rvv/autovec/pr111751.c   | 55 +++
 1 file changed, 55 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111751.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111751.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111751.c
new file mode 100644
index 000..0f1e8a7d567
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111751.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#define N 16
+
+int foo1 ()
+{
+  int i;
+  char ia[N];
+  char ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  char ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+
+  /* Not vectorizable, multiplication */
+  for (i = 0; i < N; i++)
+{
+  ia[i] = ib[i] * ic[i];
+}
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+{
+  if (ia[i] != (char) (ib[i] * ic[i]))
+__builtin_abort ();
+}
+
+  return 0;
+}
+
+typedef int half_word;
+
+int foo2 ()
+{
+  int i;
+  half_word ia[N];
+  half_word ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  half_word ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+
+  /* Not worthwhile, only 2 parts per int */
+  for (i = 0; i < N; i++)
+{
+  ia[i] = ib[i] + ic[i];
+}
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+{
+  if (ia[i] != ib[i] + ic[i])
+__builtin_abort ();
+}
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times {li\s+[a-x0-9]+,0\s+ret} 2 } } */
+/* { dg-final { scan-assembler-not {vset} } } */
-- 
2.36.3



Re: [PATCH] tree-optimization/111519 - strlen optimization skips clobbering store

2023-10-10 Thread Richard Biener
On Tue, 10 Oct 2023, Jakub Jelinek wrote:

> On Tue, Oct 10, 2023 at 10:49:04AM +, Richard Biener wrote:
> > The following fixes a mistake in count_nonzero_bytes which happily
> > skips over stores clobbering the memory we load a value we store
> > from and then performs analysis on the memory state before the
> > intermediate store.
> > 
> > The patch implements the most simple fix - guarantee that there are
> > no intervening stores by tracking the original active virtual operand
> > and comparing that to the one of a load we attempt to analyze.
> > 
> > This simple approach breaks two subtests of gcc.dg/Wstringop-overflow-69.c
> > which I chose to XFAIL.
> 
> This function is a total mess, but I think punting right after the
> gimple_assign_single_p test is too big hammer.
> There are various cases and some of them are fine even when vuse is
> different, others aren't.
> The function at that point tries to handle CONSTRUCTOR, MEM_REF, or decls.
> 
> I don't see why the CONSTRUCTOR case couldn't be fine regardless of the
> vuse.  Though, am not really sure when a CONSTRUCTOR would appear, the
> lhs would need to be an SSA_NAME, so wouldn't for vectors that be a
> VECTOR_CST instead, etc.?  Ah, perhaps a vector with some non-constant
> element in it.

Yeah, but what should that be interpreted to in terms of object-size?!

I think the only real case we'd see here is the MEM_REF RHS given
we know we have a register type value.  I'll note the function
totally misses handled_component_p (), it only seems to handle
*p and 'decl'.

> The MEM_REF case supposedly only if we can guarantee nothing could overwrite
> it (so MEM_REF of TREE_STATIC TREE_READONLY could be fine, STRING_CST too,
> anything else is wrong - count_nonzero_bytes_addr uses the
> get_stridx/get_strinfo APIs, which for something that can be changed
> always reflects only the state at the current statement.  So, e.g. the
> get_stridx (exp, stmt) > 0 case in count_nonzero_bytes_addr is when
> the caller must definitely punt if vuse is different.
> Then for decls, again, CONST_DECLs, DECL_IN_CONSTANT_POOLs are certainly
> fine.  Other decls for which ctor_for_folding returns non-error_mark_node
> should be fine as well, I think ctor_useable_for_folding_p is supposed
> to verify that.  STRING_CSTs should be fine as well.
> 
> So maybe pass the vuse down to count_nonzero_bytes_addr and return false
> in the idx > 0 case in there if gimple_vuse (stmt) != vuse?

I don't know enough of the pass to do better, can you take it from here?
One of the points is that we need to know the memory context (aka vuse)
of both the original store and the load we are interpreting.  For
_addr I wasn't sure how we arrive here.  As you said, this is a bit
of spaghetti and I don't want to untangle this any further.

Thanks,
Richard.


Re: [PATCH v6] Implement new RTL optimizations pass: fold-mem-offsets.

2023-10-10 Thread Manolis Tsamis
On Fri, Oct 6, 2023 at 8:57 PM Jeff Law  wrote:
>
>
>
> On 10/6/23 08:17, Manolis Tsamis wrote:
> SNIP
> >> So I was ready to ACK, but realized there weren't any testresults for a
> >> primary platform mentioned.  So I ran this on x86.
> >>
> >> It's triggering one regression (code quality).
> >>
> >> Specifically gcc.target/i386/pr52146.c
> >>
> >> The f-m-o code is slightly worse than without f-m-o.
> >>
> >> Without f-m-o we get this:
> >>
> >>  9  B88000E0  movl$-18874240, %eax
> >>  9  FE
> >> 10 0005 67C7  movl$0, (%eax)
> >> 10  00
> >> 11 000c C3ret
> >>
> >> With f-m-o we get this:
> >>
> >>  9  B800  movl$0, %eax
> >>  9  00
> >> 10 0005 67C78080  movl$0, -18874240(%eax)
> >> 10  00E0FE00
> >> 10  00
> >> 11 0010 C3ret
> >>
> >>
> >> The key being that we don't get rid of the original move instruction,
> >> nor does the original move instruction get smaller due to simplification
> >> of its constant.  Additionally, the memory store gets larger.  The net
> >> is a 4 byte increase in code size.
> >>
> > Yes, this case is not good for f-m-o. In theory there could be a cost
> > calculation step that tries to estimate the benefit of a
> > transformation, but given that f-m-o cannot transform code in a way
> > that we have big regressions it's unclear to me whether complicating
> > the code is worth it. At least if we can solve the issues in other
> > ways (also see discussion below).
> >
> >>
> >> This is probably a fairly rare scenario and the original bug report was
> >> for a correctness issue in using addresses in the range
> >> 0x8000..0x in x32.  So I wouldn't lose any sleep if we
> >> adjusted the test to pass -fno-fold-mem-offsets.  But before doing that
> >> I wanted to give you the chance to ponder if this is something you'd
> >> prefer to improve in f-m-o itself.   At some level if the base register
> >> collapses down to 0, then we could take the offset as a constant address
> >> and try to recognize that form.  If that fails, then just consider the
> >> change unprofitable rather than trying to recognize it as reg+d.
> >>
> >> Anyway, waiting to hear your thoughts...
> >>
> > Yes, this testcase has been bugging me too, I have brought that up in
> > previous iterations as well.
> I must have missed that in the earlier discussion.
>
> > I'm also not sure whether this is a code quality or a correctness
> > issue? From what I understand from the relevant ticket, if we emit
> > movl $0, -18874240 then it's wrong code?
> It's a code quality issue as long as we don't transform the code into
> movl $0, -18874240, at which point it would become a correctness issue.
>
Ok, thanks for pointing that out as I thought that movl $0, -18874240
and movl $0, -18874240(eax) with eax == 0 were the same.

>
> >
> > With regards to the "recognize that the base register is 0", that
> > would be nice but how would we recognise that? f-m-o can only
> > calculate the folded offset but that is not enough to prove that the
> > base register is zero or not.
> It's a chain of insns that produce an address and use it in the memory
> reference.  We essentially changed the first insn in the chain from movl
> -18874240, %eax into movl 0, %eax.  So we'd have to someone note that
> the base register in the memory reference has the value zero in the
> chain of instructions.  That may or may not be reasonable to do.
>
Ok, do you believe it would be worthwhile to add a REG_EQ note or
something similar? I assume some REG_EQ notes will be added from the
following cprop-hardreg pass too?

> >
> > One thought that I've had is that this started being an issue on x86
> > when I enabled folding of mv REG, INT in addition to the existing ADD
> > REG, REG, INT. The idea was that a move will be folded to mv REG, 0
> > and on targets that we have a zero register that can be beneficial for
> > a number of reasons... but on x86 we don't have a zero register so the
> > benefit is much more limited anyway. So maybe we could disable folding
> > of moves on targets that don't have a zero register? That would solve
> > the issue and I believe it also makes sense in general. If so, is
> > there a way to query wether the target has such register?
> We don't have a generalized query to do that.  You might be able to ask
> what the cost to load 0 into a register is, but many targets
> artificially decrease that value.
>
Ok, I see. Then let's not use that approach.

> You could use the costing model to cost the entire sequence
> before/after.  There's an interface to walk a sequence and return a
> cost.  In the case of f-m-o the insns are part of the larger chain, so
> we'd need a different API.
>
> The other option would be to declare this is known, but not important
> issue.  I would think that it's going to be rare to have absolute
> addresses and

[COMMITTED] ada: Crash processing pragmas Compile_Time_Error and Compile_Time_Warning

2023-10-10 Thread Marc Poulhiès
From: Javier Miranda 

gcc/ada/

* sem_attr.adb (Analyze_Attribute): Protect the frontend against
replacing 'Size by its static value if 'Size is not known at
compile time and we are processing pragmas Compile_Time_Warning or
Compile_Time_Errors.

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

---
 gcc/ada/sem_attr.adb | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index d03761b1e30..3eba3a29362 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -6457,17 +6457,30 @@ package body Sem_Attr is
or else Size_Known_At_Compile_Time (Entity (P)))
  then
 declare
-   Siz : Uint;
+   Prefix_E : Entity_Id := Entity (P);
+   Siz  : Uint;
 
 begin
-   if Known_Static_RM_Size (Entity (P)) then
-  Siz := RM_Size (Entity (P));
+   --  Handle private and incomplete types
+
+   if Present (Underlying_Type (Prefix_E)) then
+  Prefix_E := Underlying_Type (Prefix_E);
+   end if;
+
+   if Known_Static_RM_Size (Prefix_E) then
+  Siz := RM_Size (Prefix_E);
else
-  Siz := Esize (Entity (P));
+  Siz := Esize (Prefix_E);
end if;
 
-   Rewrite (N, Make_Integer_Literal (Sloc (N), Siz));
-   Analyze (N);
+   --  Protect the frontend against cases where the attribute
+   --  Size_Known_At_Compile_Time is set, but the Esize value
+   --  is not available (see Einfo.ads).
+
+   if Present (Siz) then
+  Rewrite (N, Make_Integer_Literal (Sloc (N), Siz));
+  Analyze (N);
+   end if;
 end;
  end if;
 
-- 
2.42.0



[COMMITTED] ada: Tweak documentation comments

2023-10-10 Thread Marc Poulhiès
From: Ronan Desplanques 

The concept of extended nodes was retired at the same time Gen_IL
was introduced, but there was a reference to that concept left over
in a comment. This patch removes that reference.

Also, the description of the field Comes_From_Check_Or_Contract was
incorrectly placed in a section for fields present in all nodes in
sinfo.ads. This patch fixes this.

gcc/ada/

* atree.ads, nlists.ads, types.ads: Remove references to extended
nodes. Fix typo.
* sinfo.ads: Likewise and fix position of
Comes_From_Check_Or_Contract description.

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

---
 gcc/ada/atree.ads  |  9 -
 gcc/ada/nlists.ads |  3 ---
 gcc/ada/sinfo.ads  | 31 ++-
 gcc/ada/types.ads  |  4 +---
 4 files changed, 11 insertions(+), 36 deletions(-)

diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads
index abe5cc5f3b5..2ff65d24679 100644
--- a/gcc/ada/atree.ads
+++ b/gcc/ada/atree.ads
@@ -252,7 +252,7 @@ package Atree is
--  The usual approach is to build a new node using this function and
--  then, using the value returned, use the Set_xxx functions to set
--  fields of the node as required. New_Node can only be used for
-   --  non-entity nodes, i.e. it never generates an extended node.
+   --  non-entity nodes.
--
--  If we are currently parsing, as indicated by a previous call to
--  Set_Comes_From_Source_Default (True), then this call also resets
@@ -308,8 +308,7 @@ package Atree is
--  returns Empty, and New_Copy (Error) returns Error. Note that, unlike
--  Copy_Separate_Tree, New_Copy does not recursively copy any descendants,
--  so in general parent pointers are not set correctly for the descendants
-   --  of the copied node. Both normal and extended nodes (entities) may be
-   --  copied using New_Copy.
+   --  of the copied node.
 
function Relocate_Node (Source : Node_Id) return Node_Id;
--  Source is a non-entity node that is to be relocated. A new node is
@@ -359,7 +358,7 @@ package Atree is
--  caller, according to context.
 
procedure Extend_Node (Source : Node_Id);
-   --  This turns a node into an entity; it function is used only by Sinfo.CN.
+   --  This turns a node into an entity; it is only used by Sinfo.CN.
 
type Ignored_Ghost_Record_Proc is access procedure (N : Node_Or_Entity_Id);
 
@@ -540,7 +539,7 @@ package Atree is
--  newly constructed replacement subtree. The actual mechanism is to swap
--  the contents of these two nodes fixing up the parent pointers of the
--  replaced node (we do not attempt to preserve parent pointers for the
-   --  original node). Neither Old_Node nor New_Node can be extended nodes.
+   --  original node).
--  ??? The above explanation is incorrect, instead Copy_Node is called.
--
--  Note: New_Node may not contain references to Old_Node, for example as
diff --git a/gcc/ada/nlists.ads b/gcc/ada/nlists.ads
index 5e88032ff7d..7afe80f0051 100644
--- a/gcc/ada/nlists.ads
+++ b/gcc/ada/nlists.ads
@@ -43,9 +43,6 @@ package Nlists is
--  this header, which may be used to access the nodes in the list using
--  the set of routines that define this interface.
 
-   --  Note: node lists can contain either nodes or entities (extended nodes)
-   --  or a mixture of nodes and extended nodes.
-
function In_Same_List (N1, N2 : Node_Or_Entity_Id) return Boolean;
pragma Inline (In_Same_List);
--  Equivalent to List_Containing (N1) = List_Containing (N2)
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 57fd704475c..fc9bcfbd44d 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -82,12 +82,6 @@ package Sinfo is
-- for this purpose, so e.g. in X := (if A then B else C);
-- Paren_Count for the right side will be 1.
 
-   --   Comes_From_Check_Or_Contract
-   -- This flag is present in all N_If_Statement nodes and
-   -- gets set when an N_If_Statement is generated as part of
-   -- the expansion of a Check, Assert, or contract-related
-   -- pragma.
-
--   Comes_From_Source
-- This flag is present in all nodes. It is set if the
-- node is built by the scanner or parser, and clear if
@@ -953,6 +947,12 @@ package Sinfo is
--attribute definition clause is given, rather than testing this at the
--freeze point.
 
+   --  Comes_From_Check_Or_Contract
+   --This flag is present in all N_If_Statement nodes and
+   --gets set when an N_If_Statement is generated as part of
+   --the expansion of a Check, Assert, or contract-related
+   --pragma.
+
--  Comes_From_Extended_Return_Statement
--Present in N_Simple_Return_Statement nodes. True if this node was
--constructed as part of the N_Extended_Return_Statement expansion.
@@ -2809,12 +2809,6 @@ package Sinfo is
   --  fields are defi

[COMMITTED] ada: Fix bad finalization of limited aggregate in conditional expression

2023-10-10 Thread Marc Poulhiès
From: Eric Botcazou 

This happens when the conditional expression is immediately returned, for
example in an expression function.

gcc/ada/

* exp_aggr.adb (Is_Build_In_Place_Aggregate_Return): Return true
if the aggregate is a dependent expression of a conditional
expression being returned from a build-in-place function.

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

---
 gcc/ada/exp_aggr.adb | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 165f517c031..e5f36326600 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -173,8 +173,11 @@ package body Exp_Aggr is
--
 
function Is_Build_In_Place_Aggregate_Return (N : Node_Id) return Boolean;
-   --  True if N is an aggregate (possibly qualified or converted) that is
-   --  being returned from a build-in-place function.
+   --  True if N is an aggregate (possibly qualified or a dependent expression
+   --  of a conditional expression, and possibly recursively so) that is being
+   --  returned from a build-in-place function. Such qualified and conditional
+   --  expressions are transparent for this purpose because an enclosing return
+   --  is propagated resp. distributed into these expressions by the expander.
 
function Build_Record_Aggr_Code
  (N   : Node_Id;
@@ -8463,7 +8466,11 @@ package body Exp_Aggr is
   P : Node_Id := Parent (N);
 
begin
-  while Nkind (P) = N_Qualified_Expression loop
+  while Nkind (P) in N_Case_Expression
+   | N_Case_Expression_Alternative
+   | N_If_Expression
+   | N_Qualified_Expression
+  loop
  P := Parent (P);
   end loop;
 
-- 
2.42.0



[COMMITTED] ada: Remove superfluous setter procedure

2023-10-10 Thread Marc Poulhiès
From: Eric Botcazou 

It is only called once.

gcc/ada/

* sem_util.ads (Set_Scope_Is_Transient): Delete.
* sem_util.adb (Set_Scope_Is_Transient): Likewise.
* exp_ch7.adb (Create_Transient_Scope): Set Is_Transient directly.

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

---
 gcc/ada/exp_ch7.adb  | 2 +-
 gcc/ada/sem_util.adb | 9 -
 gcc/ada/sem_util.ads | 3 ---
 3 files changed, 1 insertion(+), 13 deletions(-)

diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 5049de54dd7..00b7692c964 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -4529,7 +4529,7 @@ package body Exp_Ch7 is
 
  Push_Scope (Trans_Scop);
  Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped := Context;
- Set_Scope_Is_Transient;
+ Scope_Stack.Table (Scope_Stack.Last).Is_Transient := True;
 
  --  The transient scope must also manage the secondary stack
 
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index e778bab95d1..26ddb52bc4a 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -27792,15 +27792,6 @@ package body Sem_Util is
   end if;
end Set_Rep_Info;
 
-   
-   -- Set_Scope_Is_Transient --
-   
-
-   procedure Set_Scope_Is_Transient (V : Boolean := True) is
-   begin
-  Scope_Stack.Table (Scope_Stack.Last).Is_Transient := V;
-   end Set_Scope_Is_Transient;
-
---
-- Set_Size_Info --
---
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 92016bc0eef..dda71e402b2 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -3165,9 +3165,6 @@ package Sem_Util is
--  from sub(type) entity T2 to (sub)type entity T1, as well as Is_Volatile
--  if T1 is a base type.
 
-   procedure Set_Scope_Is_Transient (V : Boolean := True);
-   --  Set the flag Is_Transient of the current scope
-
procedure Set_Size_Info (T1, T2 : Entity_Id);
pragma Inline (Set_Size_Info);
--  Copies the Esize field and Has_Biased_Representation flag from sub(type)
-- 
2.42.0



[COMMITTED] ada: Tweak internal subprogram in Ada.Directories

2023-10-10 Thread Marc Poulhiès
From: Ronan Desplanques 

The purpose of this patch is to work around false-positive warnings
emitted by GNAT SAS (also known as CodePeer). It does not change
the behavior of the modified subprogram.

gcc/ada/

* libgnat/a-direct.adb (Start_Search_Internal): Tweak subprogram
body.

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

---
 gcc/ada/libgnat/a-direct.adb | 46 
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/gcc/ada/libgnat/a-direct.adb b/gcc/ada/libgnat/a-direct.adb
index f7a1d5dfd6d..594971c6021 100644
--- a/gcc/ada/libgnat/a-direct.adb
+++ b/gcc/ada/libgnat/a-direct.adb
@@ -1379,13 +1379,21 @@ package body Ada.Directories is
  Compose (Directory, File_Name) & ASCII.NUL;
   Path   : String renames
  Path_C (Path_C'First .. Path_C'Last - 1);
-  Found  : Boolean := False;
   Attr   : aliased File_Attributes;
   Exists : Integer;
   Error  : Integer;
-  Kind   : File_Kind;
-  Size   : File_Size;
 
+  type Result (Found : Boolean := False) is record
+ case Found is
+when True =>
+   Kind : File_Kind;
+   Size : File_Size;
+when False =>
+   null;
+ end case;
+  end record;
+
+  Res : Result := (Found => False);
begin
   --  Get the file attributes for the directory item
 
@@ -1416,32 +1424,28 @@ package body Ada.Directories is
  if Is_Regular_File_Attr (Path_C'Address, Attr'Access) = 1
  then
 if Filter (Ordinary_File) then
-   Found := True;
-   Kind := Ordinary_File;
-   Size :=
- File_Size
-   (File_Length_Attr
-  (-1, Path_C'Address, Attr'Access));
+   Res := (Found => True,
+   Kind => Ordinary_File,
+   Size => File_Size
+ (File_Length_Attr
+(-1, Path_C'Address, Attr'Access)));
 
 end if;
  elsif Is_Directory_Attr (Path_C'Address, Attr'Access) = 1
  then
 if Filter (File_Kind'First) then
-   Found := True;
-   Kind := File_Kind'First;
-   --  File_Kind'First is used instead of Directory due
-   --  to a name overload issue with the procedure
-   --  parameter Directory.
-   Size := 0;
+   Res := (Found => True,
+   Kind => File_Kind'First,
+   Size => 0);
 end if;
 
  elsif Filter (Special_File) then
-Found := True;
-Kind := Special_File;
-Size := 0;
+Res := (Found => True,
+Kind => Special_File,
+Size => 0);
  end if;
 
- if Found then
+ if Res.Found then
 Search.State.Dir_Contents.Append
   (Directory_Entry_Type'
  (Valid => True,
@@ -1449,9 +1453,9 @@ package body Ada.Directories is
 To_Unbounded_String (File_Name),
   Full_Name => To_Unbounded_String (Path),
   Attr_Error_Code   => 0,
-  Kind  => Kind,
+  Kind  => Res.Kind,
   Modification_Time => Modification_Time (Path),
-  Size  => Size));
+  Size  => Res.Size));
  end if;
   end if;
end;
-- 
2.42.0



[COMMITTED] ada: Fix infinite loop with multiple limited with clauses

2023-10-10 Thread Marc Poulhiès
From: Eric Botcazou 

This occurs when one of the types has an incomplete declaration in addition
to its full declaration in its package. In this case AI05-129 says that the
incomplete type is not part of the limited view of the package, i.e. only
the full view is. Now, in the GNAT implementation, it's the opposite in the
regular view of the package, i.e. the incomplete type is the visible one.

That's why the implementation needs to also swap the types on the visibility
chain while it is swapping the views when the clauses are either installed
or removed. This works correctly for the installation, but does not for the
removal, so this change rewrites the code doing the latter.

gcc/ada/
PR ada/111434
* sem_ch10.adb (Replace): New procedure to replace an entity with
another on the homonym chain.
(Install_Limited_With_Clause): Rename Non_Lim_View to Typ for the
sake of consistency.  Call Replace to do the replacements and split
the code into the regular and the special cases.  Add debuggging
output controlled by -gnatdi.
(Install_With_Clause): Print the Parent_With and Implicit_With flags
in the debugging output controlled by -gnatdi.
(Remove_Limited_With_Unit.Restore_Chain_For_Shadow (Shadow)): Rewrite
using a direct replacement of E4 by E2.   Call Replace to do the
replacements.  Add debuggging output controlled by -gnatdi.

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

---
 gcc/ada/sem_ch10.adb | 170 +++
 1 file changed, 107 insertions(+), 63 deletions(-)

diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index a6cbe466b75..ba4beae2851 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -238,6 +238,9 @@ package body Sem_Ch10 is
--  Reset all visibility flags on unit after compiling it, either as a main
--  unit or as a unit in the context.
 
+   procedure Replace (Old_E, New_E : Entity_Id);
+   --  Replace Old_E by New_E on visibility list
+
procedure Unchain (E : Entity_Id);
--  Remove single entity from visibility list
 
@@ -5310,15 +5313,12 @@ package body Sem_Ch10 is
   and then not Is_Child_Unit (Lim_Typ)
 then
declare
-  Non_Lim_View : constant Entity_Id :=
-   Non_Limited_View (Lim_Typ);
+  Typ : constant Entity_Id := Non_Limited_View (Lim_Typ);
 
   Prev : Entity_Id;
 
begin
-  Prev := Current_Entity (Lim_Typ);
-
-  --  Replace Non_Lim_View in the homonyms list, so that the
+  --  Replace Typ by Lim_Typ in the homonyms list, so that the
   --  limited view becomes available.
 
   --  If the nonlimited view is a record with an anonymous
@@ -5350,38 +5350,47 @@ package body Sem_Ch10 is
   --
   --  [*] denotes the visible entity (Current_Entity)
 
-  if Prev = Non_Lim_View
-or else
-  (Ekind (Prev) = E_Incomplete_Type
-and then Full_View (Prev) = Non_Lim_View)
-or else
-  (Ekind (Prev) = E_Incomplete_Type
-and then From_Limited_With (Prev)
-and then
-  Ekind (Non_Limited_View (Prev)) = E_Incomplete_Type
-and then
-  Full_View (Non_Limited_View (Prev)) = Non_Lim_View)
-  then
- Set_Current_Entity (Lim_Typ);
+  Prev := Current_Entity (Lim_Typ);
 
-  else
- while Present (Homonym (Prev))
-   and then Homonym (Prev) /= Non_Lim_View
- loop
-Prev := Homonym (Prev);
- end loop;
+  while Present (Prev) loop
+ --  This is a regular replacement
 
- Set_Homonym (Prev, Lim_Typ);
-  end if;
+ if Prev = Typ
+   or else (Ekind (Prev) = E_Incomplete_Type
+ and then Full_View (Prev) = Typ)
+ then
+Replace (Prev, Lim_Typ);
 
-  Set_Homonym (Lim_Typ, Homonym (Non_Lim_View));
-   end;
+if Debug_Flag_I then
+   Write_Str ("   (homonym) replace ");
+   Write_Name (Chars (Typ));
+   Write_Eol;
+end if;
 
-   if Debug_Flag_I then
-  Write_Str ("   (homonym) chain ");
-  Write_Name (Chars (Lim_Typ));
-  Write_Eol;
-   end if;
+exit;
+
+ --  This is where E1 

[COMMITTED] ada: Fix internal error on too large representation clause for small component

2023-10-10 Thread Marc Poulhiès
From: Eric Botcazou 

This is a small bug present on strict-alignment platforms for questionable
representation clauses.

gcc/ada/

* gcc-interface/decl.cc (inline_status_for_subprog): Minor tweak.
(gnat_to_gnu_field): Try harder to get a packable form of the type
for a bitfield.

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

---
 gcc/ada/gcc-interface/decl.cc | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 5e16b56217c..20ab185d577 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -5114,7 +5114,7 @@ inline_status_for_subprog (Entity_Id subprog)
   tree gnu_type;
 
   /* This is a kludge to work around a pass ordering issue: for small
-record types with many components, i.e. typically bit-fields, the
+record types with many components, i.e. typically bitfields, the
 initialization routine can contain many assignments that will be
 merged by the GIMPLE store merging pass.  But this pass runs very
 late in the pipeline, in particular after the inlining decisions
@@ -7702,6 +7702,18 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree 
gnu_record_type, int packed,
   gnu_field_type = maybe_pad_type (gnu_field_type, gnu_size, 0, gnat_field,
   false, definition, true);
 
+  /* For a bitfield, if the type still has BLKmode, try again to change it
+to an integral mode form.  This may be necessary on strict-alignment
+platforms with a size clause that is much larger than the field type,
+because maybe_pad_type has preserved the alignment of the field type,
+which may be too low for the new size.  */
+  if (!needs_strict_alignment
+ && RECORD_OR_UNION_TYPE_P (gnu_field_type)
+ && !TYPE_FAT_POINTER_P (gnu_field_type)
+ && TYPE_MODE (gnu_field_type) == BLKmode
+ && is_bitfield)
+   gnu_field_type = make_packable_type (gnu_field_type, true, 1);
+
   /* If a padding record was made, declare it now since it will never be
 declared otherwise.  This is necessary to ensure that its subtrees
 are properly marked.  */
-- 
2.42.0



[COMMITTED] ada: Fix filesystem entry filtering

2023-10-10 Thread Marc Poulhiès
From: Ronan Desplanques 

This patch fixes the behavior of Ada.Directories.Search when being
requested to filter out regular files or directories. One of the
configurations in which that behavior was incorrect was that when the
caller requested only the regular and special files but not the
directories, the directories would still be returned.

gcc/ada/

* libgnat/a-direct.adb: Fix filesystem entry filtering.

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

---
 gcc/ada/libgnat/a-direct.adb | 30 --
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/gcc/ada/libgnat/a-direct.adb b/gcc/ada/libgnat/a-direct.adb
index 4b08d41337d..f7a1d5dfd6d 100644
--- a/gcc/ada/libgnat/a-direct.adb
+++ b/gcc/ada/libgnat/a-direct.adb
@@ -1414,24 +1414,26 @@ package body Ada.Directories is
 
   elsif Exists = 1 then
  if Is_Regular_File_Attr (Path_C'Address, Attr'Access) = 1
-   and then Filter (Ordinary_File)
  then
-Found := True;
-Kind := Ordinary_File;
-Size :=
-  File_Size
-(File_Length_Attr
-   (-1, Path_C'Address, Attr'Access));
+if Filter (Ordinary_File) then
+   Found := True;
+   Kind := Ordinary_File;
+   Size :=
+ File_Size
+   (File_Length_Attr
+  (-1, Path_C'Address, Attr'Access));
 
+end if;
  elsif Is_Directory_Attr (Path_C'Address, Attr'Access) = 1
-   and then Filter (File_Kind'First)
  then
-Found := True;
-Kind := File_Kind'First;
---  File_Kind'First is used instead of Directory due
---  to a name overload issue with the procedure
---  parameter Directory.
-Size := 0;
+if Filter (File_Kind'First) then
+   Found := True;
+   Kind := File_Kind'First;
+   --  File_Kind'First is used instead of Directory due
+   --  to a name overload issue with the procedure
+   --  parameter Directory.
+   Size := 0;
+end if;
 
  elsif Filter (Special_File) then
 Found := True;
-- 
2.42.0



Re: [PATCH] RISC-V: Make xtheadcondmov-indirect tests robust against instruction reordering

2023-10-10 Thread Christoph Müllner
On Tue, Oct 10, 2023 at 5:08 AM Kito Cheng  wrote:
>
> I guess you may also want to clean up those bodies for 
> "check-function-bodies"?

I kept the comments on purpose, so that I have a basis for the
expected instruction counts.
But of course, there is no need to follow the format.
Would the following format change of the comments be ok?

-/*
-** ConEmv_imm_imm_reg:
-** addia[0-9]+,a[0-9]+,-1000
-** li  a[0-9]+,10
-** th\.mvnez   a[0-9]+,a[0-9]+,a[0-9]+
-** ret
-*/
+/* addi aX, aX, -1000
+   li aX, 10
+   th.mvnez aX, aX, aX  */

BR
Christoph

>
> On Mon, Oct 9, 2023 at 3:47 PM Christoph Muellner
>  wrote:
> >
> > From: Christoph Müllner 
> >
> > Fixes: c1bc7513b1d7 ("RISC-V: const: hide mvconst splitter from IRA")
> >
> > A recent change broke the xtheadcondmov-indirect tests, because the order of
> > emitted instructions changed. Since the test is too strict when testing for
> > a fixed instruction order, let's change the tests to simply count 
> > instruction,
> > like it is done for similar tests.
> >
> > Reported-by: Patrick O'Neill 
> > Signed-off-by: Christoph Müllner 
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/riscv/xtheadcondmov-indirect.c: Make robust against
> > instruction reordering.
> >
> > Signed-off-by: Christoph Müllner 
> > ---
> >  .../gcc.target/riscv/xtheadcondmov-indirect.c | 11 ---
> >  1 file changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c 
> > b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
> > index c3253ba5239..eba1b86137b 100644
> > --- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
> > +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect.c
> > @@ -1,8 +1,7 @@
> >  /* { dg-do compile } */
> > -/* { dg-options "-march=rv32gc_xtheadcondmov -fno-sched-pressure" { target 
> > { rv32 } } } */
> > -/* { dg-options "-march=rv64gc_xtheadcondmov -fno-sched-pressure" { target 
> > { rv64 } } } */
> > +/* { dg-options "-march=rv32gc_xtheadcondmov" { target { rv32 } } } */
> > +/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */
> >  /* { dg-skip-if "" { *-*-* } {"-O0" "-Os" "-Og" "-Oz" "-flto" } } */
> > -/* { dg-final { check-function-bodies "**" "" } } */
> >
> >  /*
> >  ** ConEmv_imm_imm_reg:
> > @@ -116,3 +115,9 @@ int ConNmv_reg_reg_reg(int x, int y, int z, int n)
> >  return z;
> >return n;
> >  }
> > +
> > +/* { dg-final { scan-assembler-times "addi\t" 5 } } */
> > +/* { dg-final { scan-assembler-times "li\t" 4 } } */
> > +/* { dg-final { scan-assembler-times "sub\t" 4 } } */
> > +/* { dg-final { scan-assembler-times "th.mveqz\t" 4 } } */
> > +/* { dg-final { scan-assembler-times "th.mvnez\t" 4 } } */
> > --
> > 2.41.0
> >


[PATCH] tree-optimization/111751 - support 1024 bit vector constant reinterpretation

2023-10-10 Thread Richard Biener
The following ups the limit in fold_view_convert_expr to handle
1024bit vectors as used by GCN and RVV.  It also robustifies
the handling in visit_reference_op_load to properly give up when
constants cannot be re-interpreted.

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

PR tree-optimization/111751
* fold-const.cc (fold_view_convert_expr): Up the buffer size
to 128 bytes.
* tree-ssa-scccvn.cc (visit_reference_op_load): Special case
constants, giving up when re-interpretation to the target type
fails.
---
 gcc/fold-const.cc | 4 ++--
 gcc/tree-ssa-sccvn.cc | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 4f8561509ff..82299bb7f1d 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -9266,8 +9266,8 @@ fold_view_convert_vector_encoding (tree type, tree expr)
 static tree
 fold_view_convert_expr (tree type, tree expr)
 {
-  /* We support up to 512-bit values (for V8DFmode).  */
-  unsigned char buffer[64];
+  /* We support up to 1024-bit values (for GCN/RISC-V V128QImode).  */
+  unsigned char buffer[128];
   int len;
 
   /* Check that the host and target are sane.  */
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index ce8ae8c6753..0b2c10dcc1a 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -5751,6 +5751,8 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
  && maybe_lt (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (result))),
   GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op)
result = NULL_TREE;
+  else if (CONSTANT_CLASS_P (result))
+   result = const_unop (VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
   else
{
  /* We will be setting the value number of lhs to the value number
-- 
2.35.3


[Committed] RISC-V: Add VLS BOOL mode vcond_mask[PR111751]

2023-10-10 Thread Juzhe-Zhong
Richard patch resolve PR111751: 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=7c76c876e917a1f20a788f602cc78fff7d0a2a65

which cause ICE in RISC-V regression:

FAIL: gcc.dg/torture/pr53144.c   -O2  (internal compiler error: in 
gimple_expand_vec_cond_expr, at gimple-isel.cc:328)
FAIL: gcc.dg/torture/pr53144.c   -O2  (test for excess errors)
FAIL: gcc.dg/torture/pr53144.c   -O2 -flto -fno-use-linker-plugin 
-flto-partition=none  (internal compiler error: in gimple_expand_vec_cond_expr, 
at gimple-isel.cc:328)
FAIL: gcc.dg/torture/pr53144.c   -O2 -flto -fno-use-linker-plugin 
-flto-partition=none  (test for excess errors)
FAIL: gcc.dg/torture/pr53144.c   -O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions  (internal compiler error: in 
gimple_expand_vec_cond_expr, at gimple-isel.cc:328)
FAIL: gcc.dg/torture/pr53144.c   -O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions  (test for excess errors)
FAIL: gcc.dg/torture/pr53144.c   -O3 -g  (internal compiler error: in 
gimple_expand_vec_cond_expr, at gimple-isel.cc:328)
FAIL: gcc.dg/torture/pr53144.c   -O3 -g  (test for excess errors)

VLS BOOL modes vcond_mask is needed to fix this regression ICE.

More details: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111751

Tested and Committed.

gcc/ChangeLog:

* config/riscv/autovec.md: Add VLS BOOL modes.

---
 gcc/config/riscv/autovec.md | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 53e9d34eea1..41bff3a318f 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -575,10 +575,10 @@
 ;; -
 
 (define_expand "vcond_mask_"
-  [(match_operand:VB 0 "register_operand")
-   (match_operand:VB 1 "register_operand")
-   (match_operand:VB 2 "register_operand")
-   (match_operand:VB 3 "register_operand")]
+  [(match_operand:VB_VLS 0 "register_operand")
+   (match_operand:VB_VLS 1 "register_operand")
+   (match_operand:VB_VLS 2 "register_operand")
+   (match_operand:VB_VLS 3 "register_operand")]
   "TARGET_VECTOR"
   {
 /* mask1 = operands[3] & operands[1].  */
-- 
2.36.3



[PATCH] Optimize (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) as (and:SI x 1).

2023-10-10 Thread Roger Sayle

This patch is the middle-end piece of an improvement to PRs 101955 and
106245, that adds a missing simplification to the RTL optimizers.
This transformation is to simplify (char)(x << 7) != 0 as x & 1.
Technically, the cast can be any truncation, where shift is by one
less than the narrower type's precision, setting the most significant
(only) bit from the least significant bit.

This transformation applies to any target, but it's easy to see
(and add a new test case) on x86, where the following function:

int f(int a) { return (a << 31) >> 31; }

currently gets compiled with -O2 to:

foo:movl%edi, %eax
sall$7, %eax
sarb$7, %al
movsbl  %al, %eax
ret

but with this patch, we now generate the slightly simpler.

foo:movl%edi, %eax
sall$31, %eax
sarl$31, %eax
ret


This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check with no new failures.  Ok for mainline?


2023-10-10  Roger Sayle  

gcc/ChangeLog
PR middle-end/101955
PR tree-optimization/106245
* simplify-rtx.c (simplify_relational_operation_1): Simplify
the RTL (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) to (and:SI x 1).

gcc/testsuite/ChangeLog
* gcc.target/i386/pr106245-1.c: New test case.


Thanks in advance,
Roger
--

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index bd9443d..69d8757 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -6109,6 +6109,23 @@ simplify_context::simplify_relational_operation_1 
(rtx_code code,
break;
   }
 
+  /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1).  */
+  if (code == NE
+  && op1 == const0_rtx
+  && (op0code == TRUNCATE
+ || (partial_subreg_p (op0)
+ && subreg_lowpart_p (op0)))
+  && SCALAR_INT_MODE_P (mode)
+  && STORE_FLAG_VALUE == 1)
+{
+  rtx tmp = XEXP (op0, 0);
+  if (GET_CODE (tmp) == ASHIFT
+ && GET_MODE (tmp) == mode
+ && CONST_INT_P (XEXP (tmp, 1))
+ && is_int_mode (GET_MODE (op0), &int_mode)
+ && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
+   return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
+}
   return NULL_RTX;
 }
 
diff --git a/gcc/testsuite/gcc.target/i386/pr106245-1.c 
b/gcc/testsuite/gcc.target/i386/pr106245-1.c
new file mode 100644
index 000..a0403e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr106245-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int f(int a)
+{
+return (a << 31) >> 31;
+}
+
+/* { dg-final { scan-assembler-not "sarb" } } */
+/* { dg-final { scan-assembler-not "movsbl" } } */


[COMMITTED] MAINTAINERS: Add myself to write after approval

2023-10-10 Thread Christoph Muellner
From: Christoph Müllner 

Signed-off-by: Christoph Müllner 

ChangeLog:

* MAINTAINERS: Add myself.
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e9154878517..aa441de5332 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -576,6 +576,7 @@ Catherine Moore 

 James A. Morrison  
 Brooks Moses   
 Dirk Mueller   
+Christoph Müllner  
 Phil Muldoon   
 Gaius Mulley   
 Steven Munroe  
-- 
2.41.0



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

2023-10-10 Thread Ajit Agarwal
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"
 "*,   *,  *,  *,  *,
  *,   *,  *,  *,  *,
  *,   *,  *,  *,  *,
- *,   *,  *,  *")])
+ *,   *,  *,  *,  *,
+ *")])
 
 ;;   STD  LD   MR  MT MF G-const
 ;;   H-const  F-const  Special
-- 
2.39.3



Re: [PATCH-2, rs6000] Enable vector mode for memory equality compare [PR111449]

2023-10-10 Thread David Edelsohn
On Tue, Oct 10, 2023 at 4:23 AM HAO CHEN GUI  wrote:

> Hi David,
>
>   Thanks for your review comments.
>
> 在 2023/10/9 23:42, David Edelsohn 写道:
> >  #define MOVE_MAX (! TARGET_POWERPC64 ? 4 : 8)
> >  #define MAX_MOVE_MAX 8
> > +#define MOVE_MAX_PIECES (!TARGET_POWERPC64 ? 4 : 16)
> > +#define COMPARE_MAX_PIECES (!TARGET_POWERPC64 ? 4 : 16)
> >
> >
> > How are the definitions of MOVE_MAX_PIECES and COMPARE_MAX_PIECES
> determined?  The email does not provide any explanation for the
> implementation.  The rest of the patch is related to vector support, but
> vector support is not dependent on TARGET_POWERPC64.
>
> By default, MOVE_MAX_PIECES and COMPARE_MAX_PIECES is set the same value
> as MOVE_MAX. The move and compare instructions are required in
> compare_by_pieces, those macros are set to 16 byte when supporting
> vector mode (V16QImode). The problem is rs6000 hasn't supported TImode
> for "-m32". We discussed it in issue 1307. TImode will be used for
> move when MOVE_MAX_PIECES is set to 16. But TImode isn't supported
> with "-m32" which might cause ICE.
>
> So MOVE_MAX_PIECES and COMPARE_MAX_PIECES is set to 4 for 32 bit
> target in this patch. They could be changed to 16 after rs6000
> supports TImode with "-m32".
>

Hi, Hao

Thanks for the explanation.

Are you stating that although PPC32 supports V16QImode in VSX, the
move_by_pieces support also requires TImode, which is not available on
PPC32?

Thanks, David


[PATCH] RISC-V Regression: Fix FAIL of pr65947-8.c for RVV

2023-10-10 Thread Juzhe-Zhong
This test is testing fold_extract_last pattern so it's more reasonable use
vect_fold_extract_last instead of specifying targets.

This is the vect_fold_extract_last property:
proc check_effective_target_vect_fold_extract_last { } {
return [expr { [check_effective_target_aarch64_sve]
   || [istarget amdgcn*-*-*]
   || [check_effective_target_riscv_v] }]
}

include ARM SVE/GCN/RVV.

It perfectly matches what we want and more reasonable, better maintainment.

gcc/testsuite/ChangeLog:

* gcc.dg/vect/pr65947-8.c: Use vect_fold_extract_last.

---
 gcc/testsuite/gcc.dg/vect/pr65947-8.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-8.c 
b/gcc/testsuite/gcc.dg/vect/pr65947-8.c
index d0426792e35..9ced4dbb69f 100644
--- a/gcc/testsuite/gcc.dg/vect/pr65947-8.c
+++ b/gcc/testsuite/gcc.dg/vect/pr65947-8.c
@@ -41,6 +41,6 @@ main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! { 
amdgcn*-*-* || aarch64_sve } } } } } */
-/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { amdgcn*-*-* 
|| aarch64_sve } } } } */
-/* { dg-final { scan-tree-dump "multiple types in double reduction or 
condition reduction" "vect" { target { ! { amdgcn*-*-* || aarch64_sve } } } } } 
*/
+/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! { 
vect_fold_extract_last } } } } } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { 
vect_fold_extract_last } } } } */
+/* { dg-final { scan-tree-dump "multiple types in double reduction or 
condition reduction" "vect" { target { ! { vect_fold_extract_last } } } } } */
-- 
2.36.3




Re: [PATCH 3/3]middle-end: maintain LCSSA throughout loop peeling

2023-10-10 Thread Richard Biener
On Mon, 2 Oct 2023, Tamar Christina wrote:

> Hi All,
> 
> This final patch updates peeling to maintain LCSSA all the way through.
> 
> It's significantly easier to maintain it during peeling while we still know
> where all new edges connect rather than touching it up later as is currently
> being done.
> 
> This allows us to remove many of the helper functions that touch up the loops
> at various parts.  The only complication is for loop distribution where we
> should be able to use the same,  however ldist depending on whether
> redirect_lc_phi_defs is true or not will either try to maintain a limited 
> LCSSA
> form itself or removes are non-virtual phis.
> 
> The problem here is that if we maintain LCSSA then in some cases the blocks
> connecting the two loops get PHIs to keep the loop IV up to date.
> 
> However there is no loop, the guard condition is rewritten as 0 != 0, to the
> "loop" always exits.   However due to the PHI nodes the probabilities get
> completely wrong.  It seems to think that the impossible exit is the likely
> edge.  This causes incorrect warnings and the presence of the PHIs prevent the
> blocks to be simplified.
> 
> While it may be possible to make ldist work with LCSSA form, doing so seems 
> more
> work than not.  For that reason the peeling code has an additional parameter
> used by only ldist to not connect the two loops during peeling.
> 
> This preserves the current behaviour from ldist until I can dive into the
> implementation more.  Hopefully that's ok for now.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-linux-gnu, and
> no issues.
> 
> Ok for master?
> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
>   * tree-loop-distribution.cc (copy_loop_before): Request no LCSSA.
>   * tree-vect-loop-manip.cc (adjust_phi_and_debug_stmts): Add additional
>   asserts.
>   (slpeel_tree_duplicate_loop_to_edge_cfg): Keep LCSSA during peeling.
>   (find_guard_arg): Look value up through explicit edge and original defs.
>   (vect_do_peeling): Use it.
>   (slpeel_update_phi_nodes_for_guard2): Take explicit exit edge.
>   (slpeel_update_phi_nodes_for_lcssa, slpeel_update_phi_nodes_for_loops):
>   Remove.
>   * tree-vect-loop.cc (vect_create_epilog_for_reduction): Initialize phi.
>   * tree-vectorizer.h (slpeel_tree_duplicate_loop_to_edge_cfg): Add
>   optional param to turn off LCSSA mode.
> 
> --- inline copy of patch -- 
> diff --git a/gcc/tree-loop-distribution.cc b/gcc/tree-loop-distribution.cc
> index 
> 902edc49ab588152a5b845f2c8a42a7e2a1d6080..14fb884d3e91d79785867debaee4956a2d5b0bb1
>  100644
> --- a/gcc/tree-loop-distribution.cc
> +++ b/gcc/tree-loop-distribution.cc
> @@ -950,7 +950,7 @@ copy_loop_before (class loop *loop, bool 
> redirect_lc_phi_defs)
>  
>initialize_original_copy_tables ();
>res = slpeel_tree_duplicate_loop_to_edge_cfg (loop, single_exit (loop), 
> NULL,
> - NULL, preheader, NULL);
> + NULL, preheader, NULL, false);
>gcc_assert (res != NULL);
>  
>/* When a not last partition is supposed to keep the LC PHIs computed
> diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
> index 
> 77f8e668bcc8beca99ba4052e1b12e0d17300262..0e8c0be5384aab2399ed93966e7bf4918f6c87a5
>  100644
> --- a/gcc/tree-vect-loop-manip.cc
> +++ b/gcc/tree-vect-loop-manip.cc
> @@ -252,6 +252,9 @@ adjust_phi_and_debug_stmts (gimple *update_phi, edge e, 
> tree new_def)
>  {
>tree orig_def = PHI_ARG_DEF_FROM_EDGE (update_phi, e);
>  
> +  gcc_assert (TREE_CODE (orig_def) != SSA_NAME
> +   || orig_def != new_def);
> +
>SET_PHI_ARG_DEF (update_phi, e->dest_idx, new_def);
>  
>if (MAY_HAVE_DEBUG_BIND_STMTS)
> @@ -1445,12 +1448,19 @@ slpeel_duplicate_current_defs_from_edges (edge from, 
> edge to)
> on E which is either the entry or exit of LOOP.  If SCALAR_LOOP is
> non-NULL, assume LOOP and SCALAR_LOOP are equivalent and copy the
> basic blocks from SCALAR_LOOP instead of LOOP, but to either the
> -   entry or exit of LOOP.  */
> +   entry or exit of LOOP.  If FLOW_LOOPS then connect LOOP to SCALAR_LOOP as 
> a
> +   continuation.  This is correct for cases where one loop continues from the
> +   other like in the vectorizer, but not true for uses in e.g. loop 
> distribution
> +   where the loop is duplicated and then modified.

But for loop distribution the other loop also "continues" from the other,
maybe better say ", but not true for uses in e.g. loop distribution where
the contents of the loop body are split but the iteration space of both
copies remains the same."  It's an implementation limitation in loop
distribution that it for example doesn't support producing reductions
as the first loop (aka it cannot handle LC PHI nodes "inbetween").

> +
> +   If UPDATED_DOMS is not NULL it is update with the list of basic blocks 
> whoms
> +   dominators were updated during the peeling.

Re: [PATCH] RISC-V Regression: Fix FAIL of pr65947-8.c for RVV

2023-10-10 Thread Jeff Law




On 10/10/23 06:55, Juzhe-Zhong wrote:

This test is testing fold_extract_last pattern so it's more reasonable use
vect_fold_extract_last instead of specifying targets.

This is the vect_fold_extract_last property:
proc check_effective_target_vect_fold_extract_last { } {
 return [expr { [check_effective_target_aarch64_sve]
   || [istarget amdgcn*-*-*]
   || [check_effective_target_riscv_v] }]
}

include ARM SVE/GCN/RVV.

It perfectly matches what we want and more reasonable, better maintainment.

gcc/testsuite/ChangeLog:

* gcc.dg/vect/pr65947-8.c: Use vect_fold_extract_last.

OK
jeff


Re: [PATCH] tree-optimization/111519 - strlen optimization skips clobbering store

2023-10-10 Thread Jakub Jelinek
On Tue, Oct 10, 2023 at 11:59:28AM +, Richard Biener wrote:
> > I don't see why the CONSTRUCTOR case couldn't be fine regardless of the
> > vuse.  Though, am not really sure when a CONSTRUCTOR would appear, the
> > lhs would need to be an SSA_NAME, so wouldn't for vectors that be a
> > VECTOR_CST instead, etc.?  Ah, perhaps a vector with some non-constant
> > element in it.
> 
> Yeah, but what should that be interpreted to in terms of object-size?!

The function in question doesn't compute object sizes, just minimum/maximum
number of non-zero bytes in some rhs of a store and whether everything
stored is 0s, or everything non-zeros, or some non-zeros followed by zero.

> I think the only real case we'd see here is the MEM_REF RHS given
> we know we have a register type value.  I'll note the function
> totally misses handled_component_p (), it only seems to handle
> *p and 'decl'.

Yeah, maybe we could handle even that at some point.
Though perhaps better first to rewrite it completely, because the recursive
calls where in some cases it means one thing and in another case something
completely different are just bad design (or lack thereof).

> > So maybe pass the vuse down to count_nonzero_bytes_addr and return false
> > in the idx > 0 case in there if gimple_vuse (stmt) != vuse?
> 
> I don't know enough of the pass to do better, can you take it from here?
> One of the points is that we need to know the memory context (aka vuse)
> of both the original store and the load we are interpreting.  For
> _addr I wasn't sure how we arrive here.  As you said, this is a bit
> of spaghetti and I don't want to untangle this any further.

I meant something like below, without getting rid of the -Wshadow stuff
in there my initial attempt didn't work.  This passes the new testcase
as well as the testcase you've been touching, but haven't tested it beyond
that yet.
In theory we could even handle some cases with gimple_vuse (stmt) != vuse,
because we save a copy of the strinfo state at the end of basic blocks and
only throw that away after we process all dominator children.  But we'd need
to figure out at which bb to look and temporarily switch the vectors.

2023-10-10  Richard Biener  
Jakub Jelinek  

PR tree-optimization/111519
* tree-ssa-strlen.cc (strlen_pass::count_nonzero_bytes): Add vuse
argument and pass it through to recursive calls and
count_nonzero_bytes_addr calls.  Don't shadow the stmt argument, but
change stmt for gimple_assign_single_p statements for which we don't
immediately punt.
(strlen_pass::count_nonzero_bytes_addr): Add vuse argument and pass
it through to recursive calls and count_nonzero_bytes calls.  Don't
use get_strinfo if gimple_vuse (stmt) is different from vuse.  Don't
shadow the stmt argument.

* gcc.dg/torture/pr111519.c: New testcase.

--- gcc/tree-ssa-strlen.cc.jj   2023-08-30 11:21:38.539521966 +0200
+++ gcc/tree-ssa-strlen.cc  2023-10-10 15:05:44.731871218 +0200
@@ -281,14 +281,14 @@ public:
gimple *stmt,
unsigned lenrange[3], bool *nulterm,
bool *allnul, bool *allnonnul);
-  bool count_nonzero_bytes (tree exp,
+  bool count_nonzero_bytes (tree exp, tree vuse,
gimple *stmt,
unsigned HOST_WIDE_INT offset,
unsigned HOST_WIDE_INT nbytes,
unsigned lenrange[3], bool *nulterm,
bool *allnul, bool *allnonnul,
ssa_name_limit_t &snlim);
-  bool count_nonzero_bytes_addr (tree exp,
+  bool count_nonzero_bytes_addr (tree exp, tree vuse,
 gimple *stmt,
 unsigned HOST_WIDE_INT offset,
 unsigned HOST_WIDE_INT nbytes,
@@ -4531,8 +4531,8 @@ nonzero_bytes_for_type (tree type, unsig
 }
 
 /* Recursively determine the minimum and maximum number of leading nonzero
-   bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
-   to each.
+   bytes in the representation of EXP at memory state VUSE and set
+   LENRANGE[0] and LENRANGE[1] to each.
Sets LENRANGE[2] to the total size of the access (which may be less
than LENRANGE[1] when what's being referenced by EXP is a pointer
rather than an array).
@@ -4546,7 +4546,7 @@ nonzero_bytes_for_type (tree type, unsig
Returns true on success and false otherwise.  */
 
 bool
-strlen_pass::count_nonzero_bytes (tree exp, gimple *stmt,
+strlen_pass::count_nonzero_bytes (tree exp, tree vuse, gimple *stmt,
  unsigned HOST_WIDE_INT offset,
  unsigned HOST_WIDE_INT nbytes,
  unsigned lenrange[3], bool *nulterm,
@@ -4566,22 +4566,23 @@ strlen_pass::count_nonzero_bytes (tree e
 exact value is no

RE: [PATCH] RISC-V Regression: Fix FAIL of pr65947-8.c for RVV

2023-10-10 Thread Li, Pan2
Committed, thanks Jeff.

Pan

-Original Message-
From: Jeff Law  
Sent: Tuesday, October 10, 2023 9:24 PM
To: Juzhe-Zhong ; gcc-patches@gcc.gnu.org
Cc: rguent...@suse.de
Subject: Re: [PATCH] RISC-V Regression: Fix FAIL of pr65947-8.c for RVV



On 10/10/23 06:55, Juzhe-Zhong wrote:
> This test is testing fold_extract_last pattern so it's more reasonable use
> vect_fold_extract_last instead of specifying targets.
> 
> This is the vect_fold_extract_last property:
> proc check_effective_target_vect_fold_extract_last { } {
>  return [expr { [check_effective_target_aarch64_sve]
>  || [istarget amdgcn*-*-*]
>  || [check_effective_target_riscv_v] }]
> }
> 
> include ARM SVE/GCN/RVV.
> 
> It perfectly matches what we want and more reasonable, better maintainment.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/vect/pr65947-8.c: Use vect_fold_extract_last.
OK
jeff


Re: [PATCH] RISC-V/testsuite: Enable `vect_pack_trunc'

2023-10-10 Thread Jeff Law




On 10/9/23 19:13, juzhe.zh...@rivai.ai wrote:

Oh. I realize this patch increase FAIL that I recently fixed:
https://gcc.gnu.org/pipermail/gcc-patches/2023-October/632247.html 



This fail because RVV doesn't have vec_pack_trunc_optab (Loop vectorizer 
will failed at first time but succeed at 2nd time),
then RVV will dump 4 times FOLD_EXTRACT_LAST instead of 2  (ARM SVE 2 
times because they have vec_pack_trunc_optab).


I think the root cause of RVV failing at multiple tests of "vect" is 
that we don't enable vec_pack/vec_unpack/... stuff,

we still succeed at vectorizations and we want to enable tests of them
(Mostly just using different approach to vectorize it (cause dump FAIL) 
because of some changing I have done previously in the middle-end).


So enabling "vec_pack" for RVV will fix some FAILs but increase some 
other FAILs.


CC to Richi to see more reasonable suggestions.
So what is the summary on Maciej's patch to enable vec_pack_trunc?  ie, 
is it something we should move forward with as-is, is it superceded by 
your work in this space or does it need further investigation because of 
differences in testing methodologies or something else?


jeff


Re: [PATCH] tree-optimization/111519 - strlen optimization skips clobbering store

2023-10-10 Thread Richard Biener
On Tue, 10 Oct 2023, Jakub Jelinek wrote:

> On Tue, Oct 10, 2023 at 11:59:28AM +, Richard Biener wrote:
> > > I don't see why the CONSTRUCTOR case couldn't be fine regardless of the
> > > vuse.  Though, am not really sure when a CONSTRUCTOR would appear, the
> > > lhs would need to be an SSA_NAME, so wouldn't for vectors that be a
> > > VECTOR_CST instead, etc.?  Ah, perhaps a vector with some non-constant
> > > element in it.
> > 
> > Yeah, but what should that be interpreted to in terms of object-size?!
> 
> The function in question doesn't compute object sizes, just minimum/maximum
> number of non-zero bytes in some rhs of a store and whether everything
> stored is 0s, or everything non-zeros, or some non-zeros followed by zero.
> 
> > I think the only real case we'd see here is the MEM_REF RHS given
> > we know we have a register type value.  I'll note the function
> > totally misses handled_component_p (), it only seems to handle
> > *p and 'decl'.
> 
> Yeah, maybe we could handle even that at some point.
> Though perhaps better first to rewrite it completely, because the recursive
> calls where in some cases it means one thing and in another case something
> completely different are just bad design (or lack thereof).

Yeah ... (true for many similar pieces in pointer-query and other
diagnostic passes...)

> > > So maybe pass the vuse down to count_nonzero_bytes_addr and return false
> > > in the idx > 0 case in there if gimple_vuse (stmt) != vuse?
> > 
> > I don't know enough of the pass to do better, can you take it from here?
> > One of the points is that we need to know the memory context (aka vuse)
> > of both the original store and the load we are interpreting.  For
> > _addr I wasn't sure how we arrive here.  As you said, this is a bit
> > of spaghetti and I don't want to untangle this any further.
> 
> I meant something like below, without getting rid of the -Wshadow stuff
> in there my initial attempt didn't work.  This passes the new testcase
> as well as the testcase you've been touching, but haven't tested it beyond
> that yet.

Works for me if it turns out working.

> In theory we could even handle some cases with gimple_vuse (stmt) != vuse,
> because we save a copy of the strinfo state at the end of basic blocks and
> only throw that away after we process all dominator children.  But we'd need
> to figure out at which bb to look and temporarily switch the vectors.

As we need sth for the branch(es) I think we should do that as followup
at most.

Thanks,
Richard.

> 2023-10-10  Richard Biener  
>   Jakub Jelinek  
> 
>   PR tree-optimization/111519
>   * tree-ssa-strlen.cc (strlen_pass::count_nonzero_bytes): Add vuse
>   argument and pass it through to recursive calls and
>   count_nonzero_bytes_addr calls.  Don't shadow the stmt argument, but
>   change stmt for gimple_assign_single_p statements for which we don't
>   immediately punt.
>   (strlen_pass::count_nonzero_bytes_addr): Add vuse argument and pass
>   it through to recursive calls and count_nonzero_bytes calls.  Don't
>   use get_strinfo if gimple_vuse (stmt) is different from vuse.  Don't
>   shadow the stmt argument.
> 
>   * gcc.dg/torture/pr111519.c: New testcase.
> 
> --- gcc/tree-ssa-strlen.cc.jj 2023-08-30 11:21:38.539521966 +0200
> +++ gcc/tree-ssa-strlen.cc2023-10-10 15:05:44.731871218 +0200
> @@ -281,14 +281,14 @@ public:
>   gimple *stmt,
>   unsigned lenrange[3], bool *nulterm,
>   bool *allnul, bool *allnonnul);
> -  bool count_nonzero_bytes (tree exp,
> +  bool count_nonzero_bytes (tree exp, tree vuse,
>   gimple *stmt,
>   unsigned HOST_WIDE_INT offset,
>   unsigned HOST_WIDE_INT nbytes,
>   unsigned lenrange[3], bool *nulterm,
>   bool *allnul, bool *allnonnul,
>   ssa_name_limit_t &snlim);
> -  bool count_nonzero_bytes_addr (tree exp,
> +  bool count_nonzero_bytes_addr (tree exp, tree vuse,
>gimple *stmt,
>unsigned HOST_WIDE_INT offset,
>unsigned HOST_WIDE_INT nbytes,
> @@ -4531,8 +4531,8 @@ nonzero_bytes_for_type (tree type, unsig
>  }
>  
>  /* Recursively determine the minimum and maximum number of leading nonzero
> -   bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
> -   to each.
> +   bytes in the representation of EXP at memory state VUSE and set
> +   LENRANGE[0] and LENRANGE[1] to each.
> Sets LENRANGE[2] to the total size of the access (which may be less
> than LENRANGE[1] when what's being referenced by EXP is a pointer
> rather than an array).
> @@ -4546,7 +4546,7 @@ nonzero_bytes_for_type (tree type, unsig
> Returns true on success and false otherwise.  */
>  
>  bool
> -strlen_pass::count_nonze

[PATCH] dwarf2out: Stop using wide_int in GC structures

2023-10-10 Thread Jakub Jelinek
Hi!

On Tue, Oct 10, 2023 at 09:30:31AM +, Richard Biener wrote:
> On Mon, 9 Oct 2023, Jakub Jelinek wrote:
> > > This makes wide_int unusable in GC structures, so for dwarf2out
> > > which was the only place which needed it there is a new rwide_int type
> > > (restricted wide_int) which supports only up to RWIDE_INT_MAX_ELTS limbs
> > > inline and is trivially copyable (dwarf2out should never deal with large
> > > _BitInt constants, those should have been lowered earlier).
> > 
> > As discussed on IRC, the dwarf2out.{h,cc} needs are actually quite limited,
> > it just needs to allocate new GC structures val_wide points to (constructed
> > from some const wide_int_ref &) and needs to call operator==,
> > get_precision, elt, get_len and get_val methods on it.
> > Even trailing_wide_int would be overkill for that, the following just adds
> > a new struct with precision/len and trailing val array members and
> > implements the needed methods (only 2 of them using wide_int_ref constructed
> > from those).
> > 
> > Incremental patch, so far compile time tested only:
> 
> LGTM, wonder if we can push this separately as prerequesite?

Here it is as a separate independent patch.  Even without the
wide_int changing patch it should save some memory, by not always
allocating room for 9 limbs, but say just the 2/3 or how many we actually
need.  And, another advantage is that if we really need it at some point,
it could support even more than 9 limbs if it is created from a wide_int_ref
with get_len () > 9.

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

2023-10-10  Jakub Jelinek  

* dwarf2out.h (wide_int_ptr): Remove.
(dw_wide_int_ptr): New typedef.
(struct dw_val_node): Change type of val_wide from wide_int_ptr
to dw_wide_int_ptr.
(struct dw_wide_int): New type.
(dw_wide_int::elt): New method.
(dw_wide_int::operator ==): Likewise.
* dwarf2out.cc (get_full_len): Change argument type to
const dw_wide_int & from const wide_int &.  Use CEIL.  Call
get_precision method instead of calling wi::get_precision.
(alloc_dw_wide_int): New function.
(add_AT_wide): Change w argument type to const wide_int_ref &
from const wide_int &.  Use alloc_dw_wide_int.
(mem_loc_descriptor, loc_descriptor): Use alloc_dw_wide_int.
(insert_wide_int): Change val argument type to const wide_int_ref &
from const wide_int &.
(add_const_value_attribute): Pass rtx_mode_t temporary directly to
add_AT_wide instead of using a temporary variable.

--- gcc/dwarf2out.h.jj  2023-10-09 14:37:45.890939965 +0200
+++ gcc/dwarf2out.h 2023-10-09 16:46:14.705816928 +0200
@@ -30,7 +30,7 @@ typedef struct dw_cfi_node *dw_cfi_ref;
 typedef struct dw_loc_descr_node *dw_loc_descr_ref;
 typedef struct dw_loc_list_struct *dw_loc_list_ref;
 typedef struct dw_discr_list_node *dw_discr_list_ref;
-typedef wide_int *wide_int_ptr;
+typedef struct dw_wide_int *dw_wide_int_ptr;
 
 
 /* Call frames are described using a sequence of Call Frame
@@ -252,7 +252,7 @@ struct GTY(()) dw_val_node {
   unsigned HOST_WIDE_INT
GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned;
   double_int GTY ((tag ("dw_val_class_const_double"))) val_double;
-  wide_int_ptr GTY ((tag ("dw_val_class_wide_int"))) val_wide;
+  dw_wide_int_ptr GTY ((tag ("dw_val_class_wide_int"))) val_wide;
   dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec;
   struct dw_val_die_union
{
@@ -313,6 +313,35 @@ struct GTY(()) dw_discr_list_node {
   int dw_discr_range;
 };
 
+struct GTY((variable_size)) dw_wide_int {
+  unsigned int precision;
+  unsigned int len;
+  HOST_WIDE_INT val[1];
+
+  unsigned int get_precision () const { return precision; }
+  unsigned int get_len () const { return len; }
+  const HOST_WIDE_INT *get_val () const { return val; }
+  inline HOST_WIDE_INT elt (unsigned int) const;
+  inline bool operator == (const dw_wide_int &) const;
+};
+
+inline HOST_WIDE_INT
+dw_wide_int::elt (unsigned int i) const
+{
+  if (i < len)
+return val[i];
+  wide_int_ref ref = wi::storage_ref (val, len, precision);
+  return wi::sign_mask (ref);
+}
+
+inline bool
+dw_wide_int::operator == (const dw_wide_int &o) const
+{
+  wide_int_ref ref1 = wi::storage_ref (val, len, precision);
+  wide_int_ref ref2 = wi::storage_ref (o.val, o.len, o.precision);
+  return ref1 == ref2;
+}
+
 /* Interface from dwarf2out.cc to dwarf2cfi.cc.  */
 extern struct dw_loc_descr_node *build_cfa_loc
   (dw_cfa_location *, poly_int64);
--- gcc/dwarf2out.cc.jj 2023-10-09 14:37:45.894939909 +0200
+++ gcc/dwarf2out.cc2023-10-09 16:48:24.565014459 +0200
@@ -397,11 +397,9 @@ dump_struct_debug (tree type, enum debug
of the number.  */
 
 static unsigned int
-get_full_len (const wide_int &op)
+get_full_len (const dw_wide_int &op)
 {
-  int prec = wi::get_precision (op);
-  return ((prec + HOST_BITS_PER_WIDE_INT - 1)
-  

Re: [PATCH] dwarf2out: Stop using wide_int in GC structures

2023-10-10 Thread Richard Biener
On Tue, 10 Oct 2023, Jakub Jelinek wrote:

> Hi!
> 
> On Tue, Oct 10, 2023 at 09:30:31AM +, Richard Biener wrote:
> > On Mon, 9 Oct 2023, Jakub Jelinek wrote:
> > > > This makes wide_int unusable in GC structures, so for dwarf2out
> > > > which was the only place which needed it there is a new rwide_int type
> > > > (restricted wide_int) which supports only up to RWIDE_INT_MAX_ELTS limbs
> > > > inline and is trivially copyable (dwarf2out should never deal with large
> > > > _BitInt constants, those should have been lowered earlier).
> > > 
> > > As discussed on IRC, the dwarf2out.{h,cc} needs are actually quite 
> > > limited,
> > > it just needs to allocate new GC structures val_wide points to 
> > > (constructed
> > > from some const wide_int_ref &) and needs to call operator==,
> > > get_precision, elt, get_len and get_val methods on it.
> > > Even trailing_wide_int would be overkill for that, the following just adds
> > > a new struct with precision/len and trailing val array members and
> > > implements the needed methods (only 2 of them using wide_int_ref 
> > > constructed
> > > from those).
> > > 
> > > Incremental patch, so far compile time tested only:
> > 
> > LGTM, wonder if we can push this separately as prerequesite?
> 
> Here it is as a separate independent patch.  Even without the
> wide_int changing patch it should save some memory, by not always
> allocating room for 9 limbs, but say just the 2/3 or how many we actually
> need.  And, another advantage is that if we really need it at some point,
> it could support even more than 9 limbs if it is created from a wide_int_ref
> with get_len () > 9.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK by me if Jason doesn't object.

Thanks,
Richard.

> 2023-10-10  Jakub Jelinek  
> 
>   * dwarf2out.h (wide_int_ptr): Remove.
>   (dw_wide_int_ptr): New typedef.
>   (struct dw_val_node): Change type of val_wide from wide_int_ptr
>   to dw_wide_int_ptr.
>   (struct dw_wide_int): New type.
>   (dw_wide_int::elt): New method.
>   (dw_wide_int::operator ==): Likewise.
>   * dwarf2out.cc (get_full_len): Change argument type to
>   const dw_wide_int & from const wide_int &.  Use CEIL.  Call
>   get_precision method instead of calling wi::get_precision.
>   (alloc_dw_wide_int): New function.
>   (add_AT_wide): Change w argument type to const wide_int_ref &
>   from const wide_int &.  Use alloc_dw_wide_int.
>   (mem_loc_descriptor, loc_descriptor): Use alloc_dw_wide_int.
>   (insert_wide_int): Change val argument type to const wide_int_ref &
>   from const wide_int &.
>   (add_const_value_attribute): Pass rtx_mode_t temporary directly to
>   add_AT_wide instead of using a temporary variable.
> 
> --- gcc/dwarf2out.h.jj2023-10-09 14:37:45.890939965 +0200
> +++ gcc/dwarf2out.h   2023-10-09 16:46:14.705816928 +0200
> @@ -30,7 +30,7 @@ typedef struct dw_cfi_node *dw_cfi_ref;
>  typedef struct dw_loc_descr_node *dw_loc_descr_ref;
>  typedef struct dw_loc_list_struct *dw_loc_list_ref;
>  typedef struct dw_discr_list_node *dw_discr_list_ref;
> -typedef wide_int *wide_int_ptr;
> +typedef struct dw_wide_int *dw_wide_int_ptr;
>  
>  
>  /* Call frames are described using a sequence of Call Frame
> @@ -252,7 +252,7 @@ struct GTY(()) dw_val_node {
>unsigned HOST_WIDE_INT
>   GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned;
>double_int GTY ((tag ("dw_val_class_const_double"))) val_double;
> -  wide_int_ptr GTY ((tag ("dw_val_class_wide_int"))) val_wide;
> +  dw_wide_int_ptr GTY ((tag ("dw_val_class_wide_int"))) val_wide;
>dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec;
>struct dw_val_die_union
>   {
> @@ -313,6 +313,35 @@ struct GTY(()) dw_discr_list_node {
>int dw_discr_range;
>  };
>  
> +struct GTY((variable_size)) dw_wide_int {
> +  unsigned int precision;
> +  unsigned int len;
> +  HOST_WIDE_INT val[1];
> +
> +  unsigned int get_precision () const { return precision; }
> +  unsigned int get_len () const { return len; }
> +  const HOST_WIDE_INT *get_val () const { return val; }
> +  inline HOST_WIDE_INT elt (unsigned int) const;
> +  inline bool operator == (const dw_wide_int &) const;
> +};
> +
> +inline HOST_WIDE_INT
> +dw_wide_int::elt (unsigned int i) const
> +{
> +  if (i < len)
> +return val[i];
> +  wide_int_ref ref = wi::storage_ref (val, len, precision);
> +  return wi::sign_mask (ref);
> +}
> +
> +inline bool
> +dw_wide_int::operator == (const dw_wide_int &o) const
> +{
> +  wide_int_ref ref1 = wi::storage_ref (val, len, precision);
> +  wide_int_ref ref2 = wi::storage_ref (o.val, o.len, o.precision);
> +  return ref1 == ref2;
> +}
> +
>  /* Interface from dwarf2out.cc to dwarf2cfi.cc.  */
>  extern struct dw_loc_descr_node *build_cfa_loc
>(dw_cfa_location *, poly_int64);
> --- gcc/dwarf2out.cc.jj   2023-10-09 14:37:45.894939909 +0200
> +++ gcc/dwarf2out.cc  2023-10

Re: [PATCH] RISC-V Regression: Fix dump check of bb-slp-68.c

2023-10-10 Thread Jeff Law




On 10/9/23 19:16, Juzhe-Zhong wrote:

Like GCN, RVV also has 64 bytes vectors (512 bits) which cause FAIL in this 
test.

It's more reasonable to use "vect512" instead of AMDGCN.

gcc/testsuite/ChangeLog:

* gcc.dg/vect/bb-slp-68.c: Use vect512.
Just a note for the record.  At this time the only target obviously 
advertising 512 bit vectors in available_vector_sizes is amdgcn -- 
avx512 doesn't signal 512 bit vectors right now.  SVE might, but it's a 
bit hard to tell easily and I don't have a cross handy.  I'd hazard a 
guess it would via -msve-vector-bits.


Anyway, OK for the trunk.  Just keep an eye out for reports of any 
issues with this test on aarch64.


Thanks,
Jeff



Re: [PATCH] RISC-V Regression: Make match patterns more accurate

2023-10-10 Thread Jeff Law




On 10/9/23 20:47, Juzhe-Zhong wrote:

This patch fixes following 2 FAILs in RVV regression since the check is not 
accurate.

It's inspired by Robin's previous patch:
https://patchwork.sourceware.org/project/gcc/patch/dde89b9e-49a0-d70b-0906-fb3022cac...@gmail.com/

gcc/testsuite/ChangeLog:

* gcc.dg/vect/no-scevccp-outer-7.c: Adjust regex pattern.
* gcc.dg/vect/no-scevccp-vect-iv-3.c: Ditto.
OK.   We might see other ports flipping to a pass if they were 
exhibiting the same behavior with failing to vectorize with the first 
selected type, but passing on the second type.


Jeff


[PATCH v5] c++: Check for indirect change of active union member in constexpr [PR101631,PR102286]

2023-10-10 Thread Nathaniel Shead
On Mon, Oct 09, 2023 at 04:46:46PM -0400, Jason Merrill wrote:
> On 10/8/23 21:03, Nathaniel Shead wrote:
> > Ping for 
> > https://gcc.gnu.org/pipermail/gcc-patches/2023-September/631203.html
> > 
> > + && (TREE_CODE (t) == MODIFY_EXPR
> > + /* Also check if initializations have implicit change of active
> > +member earlier up the access chain.  */
> > + || !refs->is_empty())
> 
> I'm not sure what the cumulative point of these two tests is.  TREE_CODE (t)
> will be either MODIFY_EXPR or INIT_EXPR, and either should be OK.
> 
> As I understand it, the problematic case is something like
> constexpr-union2.C, where we're also looking at a MODIFY_EXPR.  So what is
> this check doing?

The reasoning was to correctly handle cases like the the following (in
constexpr-union6.C):

  constexpr int test1() {
U u {};
std::construct_at(&u.s, S{ 1, 2 });
return u.s.b;
  }
  static_assert(test1() == 2);

The initialisation of &u.s here is not a member access expression within
the call to std::construct_at, since it's just a pointer, but this code
is still legal; in general, an INIT_EXPR to initialise a union member
should always be OK (I believe?), hence constraining to just
MODIFY_EXPR.

However, just that would then (incorrectly) allow all the following
cases in that test to compile, such as

  constexpr int test2() {
U u {};
int* p = &u.s.b;
std::construct_at(p, 5);
return u.s.b;
  }
  constexpr int x2 = test2();

since the INIT_EXPR is really only initialising 'b', but the implicit
"modification" of active member to 'u.s' is illegal.

Maybe a better way of expressing this condition would be something like
this?

  /* An INIT_EXPR of the last member in an access chain is always OK,
 but still check implicit change of members earlier on; see 
 cpp2a/constexpr-union6.C.  */
  && !(TREE_CODE (t) == INIT_EXPR && refs->is_empty ())

Otherwise I'll see if I can rework some of the other conditions instead.

> Incidentally, I think constexpr-union6.C could use a test where we pass &u.s
> to a function other than construct_at, and then try (and fail) to assign to
> the b member from that function.
> 
> Jason
> 

Sounds good; I've added the following test:

  constexpr void foo(S* s) {
s->b = 10;  // { dg-error "accessing .U::s. member instead of initialized 
.U::k." }
  }
  constexpr int test3() {
U u {};
foo(&u.s);  // { dg-message "in .constexpr. expansion" }
return u.s.b;
  }
  constexpr int x3 = test3();  // { dg-message "in .constexpr. expansion" }

Incidentally I found this particular example caused a very unhelpful
error + ICE due to reporting that S could not be value-initialized in
the current version of the patch. The updated version below fixes that
by using 'build_zero_init' instead -- is this an appropriate choice
here?

A similar (but unrelated) issue is with e.g.
  
  struct S { const int a; int b; };
  union U { int k; S s; };

  constexpr int test() {
U u {};
return u.s.b;
  }
  constexpr int x = test();

giving me this pretty unhelpful error message:

/home/ns/main.cpp:8:23:   in ‘constexpr’ expansion of ‘test()’
/home/ns/main.cpp:6:12: error: use of deleted function ‘S::S()’
6 |   return u.s.b;
  |  ~~^
/home/ns/main.cpp:1:8: note: ‘S::S()’ is implicitly deleted because the default 
definition would be ill-formed:
1 | struct S { const int a; int b; };
  |^
/home/ns/main.cpp:1:8: error: uninitialised const member in ‘struct S’
/home/ns/main.cpp:1:22: note: ‘const int S::a’ should be initialised
1 | struct S { const int a; int b; };
  |  ^
/home/ns/main.cpp:8:23:   in ‘constexpr’ expansion of ‘test()’
/home/ns/main.cpp:6:12: error: use of deleted function ‘S::S()’
6 |   return u.s.b;
  |  ~~^
/home/ns/main.cpp:8:23:   in ‘constexpr’ expansion of ‘test()’
/home/ns/main.cpp:6:12: error: use of deleted function ‘S::S()’

but I'll try and fix this separately (it exists on current trunk without
this patch as well).

Bootstrapped and regtested on x86_64-pc-linux-gnu. Thanks!

-- >8 --

This patch adds checks for attempting to change the active member of a
union by methods other than a member access expression.

To be able to properly distinguish `*(&u.a) = ` from `u.a = `, this
patch redoes the solution for c++/59950 to avoid extranneous *&; it
seems that the only case that needed the workaround was when copying
empty classes.

This patch also ensures that constructors for a union field mark that
field as the active member before entering the call itself; this ensures
that modifications of the field within the constructor's body don't
cause false positives (as these will not appear to be member access
expressions). This means that we no longer need to start the lifetime of
empty union members after the constructor body completes.

As a drive-by fix, this patch also ensures that value-initialised unions
are considered to have activated their initial 

Re: [PATCH] RISC-V Regression: Fix FAIL of predcom-2.c

2023-10-10 Thread Jeff Law




On 10/9/23 20:58, Juzhe-Zhong wrote:

Like GCN, add -fno-tree-vectorize.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/predcom-2.c: Add riscv.

OK.
jeff


Re: [PATCH v2 1/4] options: Define TARGET__P and TARGET__OPTS_P macro for Mask and InverseMask

2023-10-10 Thread Jeff Law




On 10/9/23 22:13, Kito Cheng wrote:

We TARGET__P marcro to test a Mask and InverseMask with user
specified target_variable, however we may want to test with specific
gcc_options variable rather than target_variable.

Like RISC-V has defined lots of Mask with TargetVariable, which is not
easy to use, because that means we need to known which Mask are associate with
which TargetVariable, so take a gcc_options variable is a better interface
for such use case.

gcc/ChangeLog:

* doc/options.texi (Mask): Document TARGET__P and
TARGET__OPTS_P.
(InverseMask): Ditto.
* opth-gen.awk (Mask): Generate TARGET__P and
TARGET__OPTS_P macro.
(InverseMask): Ditto.

OK assuming it passes a build cycle on x86 or some other common target.

jeff


Re: [PATCH v2 2/4] RISC-V: Refactor riscv_option_override and riscv_convert_vector_bits. [NFC]

2023-10-10 Thread Jeff Law




On 10/9/23 22:13, Kito Cheng wrote:

Allow those funciton apply from a local gcc_options rather than the
global options.

Preparatory for target attribute, sperate this change for eaiser reivew
since it's a NFC.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_convert_vector_bits): Get setting
from argument rather than get setting from global setting.
(riscv_override_options_internal): New, splited from
riscv_override_options, also take a gcc_options argument.
(riscv_option_override): Splited most part to
riscv_override_options_internal.

OK.
jeff


Re: [PATCH] RISC-V/testsuite: Enable `vect_pack_trunc'

2023-10-10 Thread juzhe.zhong
I am working on it. Currently,  we have about 50+ additional FAILs after enabling vectorization.some of them need fixed on middle-end. E.g richard fixed a missed cse optimization.Some need fix on test case.I am analyzing each fail one by one.I prefer postpone this patch since it will cause some additional fails and I will handle that eventually after full coverage analysis. Replied Message FromJeff LawDate10/10/2023 21:33 Tojuzhe.zh...@rivai.ai,macro Ccgcc-patches,Robin Dapp,Kito.cheng,Richard BienerSubjectRe: [PATCH] RISC-V/testsuite: Enable `vect_pack_trunc'

On 10/9/23 19:13, juzhe.zh...@rivai.ai wrote:
> Oh. I realize this patch increase FAIL that I recently fixed:
> https://gcc.gnu.org/pipermail/gcc-patches/2023-October/632247.html  
> 
>  
> This fail because RVV doesn't have vec_pack_trunc_optab (Loop vectorizer  
> will failed at first time but succeed at 2nd time),
> then RVV will dump 4 times FOLD_EXTRACT_LAST instead of 2  (ARM SVE 2  
> times because they have vec_pack_trunc_optab).
>  
> I think the root cause of RVV failing at multiple tests of "vect" is  
> that we don't enable vec_pack/vec_unpack/... stuff,
> we still succeed at vectorizations and we want to enable tests of them
> (Mostly just using different approach to vectorize it (cause dump FAIL)  
> because of some changing I have done previously in the middle-end).
>  
> So enabling "vec_pack" for RVV will fix some FAILs but increase some  
> other FAILs.
>  
> CC to Richi to see more reasonable suggestions.
So what is the summary on Maciej's patch to enable vec_pack_trunc?  ie,  
is it something we should move forward with as-is, is it superceded by  
your work in this space or does it need further investigation because of  
differences in testing methodologies or something else?

jeff



C++ patch ping^2

2023-10-10 Thread Jakub Jelinek
Hi!

I'd like to ping a couple of C++ patches.

- c++, v2: Implement C++26 P2169R4 - Placeholder variables with no name 
[PR110349]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630802.html

- c++: Implement C++26 P2361R6 - Unevaluated strings [PR110342]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628375.html

- c++, v2: Implement C++26 P2741R3 - user-generated static_assert messages 
[PR110348]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630803.html

- c++: Implement C++ DR 2406 - [[fallthrough]] attribute and iteration 
statements [PR107571]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628487.html
  (from this one Richi approved the middle-end changes)

- c++: Implement C++26 P1854R4 - Making non-encodable string literals 
ill-formed [PR110341]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628490.html

- libcpp, v2: Small incremental patch for P1854R4 [PR110341]
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628586.html

Jakub



Re: [PATCH v2 3/4] RISC-V: Extend riscv_subset_list, preparatory for target attribute support

2023-10-10 Thread Jeff Law




On 10/9/23 22:13, Kito Cheng wrote:

riscv_subset_list only accept a full arch string before, but we need to
parse single extension when supporting target attribute, also we may set
a riscv_subset_list directly rather than re-parsing the ISA string
again.

gcc/ChangeLog:

* config/riscv/riscv-subset.h (riscv_subset_list::parse_single_std_ext):
New.
(riscv_subset_list::parse_single_multiletter_ext): Ditto.
(riscv_subset_list::clone): Ditto.
(riscv_subset_list::parse_single_ext): Ditto.
(riscv_subset_list::set_loc): Ditto.
(riscv_set_arch_by_subset_list): Ditto.
* common/config/riscv/riscv-common.cc
(riscv_subset_list::parse_single_std_ext): New.
(riscv_subset_list::parse_single_multiletter_ext): Ditto.
(riscv_subset_list::clone): Ditto.
(riscv_subset_list::parse_single_ext): Ditto.
(riscv_subset_list::set_loc): Ditto.
(riscv_set_arch_by_subset_list): Ditto.
---
  gcc/common/config/riscv/riscv-common.cc | 203 
  gcc/config/riscv/riscv-subset.h |  11 ++
  2 files changed, 214 insertions(+)

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 9a0a68fe5db..25630d5923e 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -1138,6 +1173,102 @@ riscv_subset_list::handle_combine_ext ()
  }
  }
  
+/* Parsing function for multi-letter extensions.

+
+   Return Value:
+ Points to the end of extensions.
+
+   Arguments:
+ `p`: Current parsing position.
+ `ext_type`: What kind of extensions, 's', 'z' or 'x'.
+ `ext_type_str`: Full name for kind of extension.  */
+
+
+const char *
+riscv_subset_list::parse_single_multiletter_ext (const char *p,
+const char *ext_type,
+const char *ext_type_str)

[ ... ]





+
+  if (end_of_version == NULL)
+return NULL;

I think when we hit this path we leak SUBSET.




  
  std::string

@@ -1498,6 +1673,34 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
{NULL, NULL, 0}
  };
  
+void

+riscv_set_arch_by_subset_list (riscv_subset_list *subset_list,
+  struct gcc_options *opts)

Needs a function comment.

OK with those two minor issues fixed.

jeff


  1   2   >