Re: [PATCH] Support vec_cmpmn/vcondmn for v2hf/v4hf.

2023-10-23 Thread Hongtao Liu
On Tue, Oct 24, 2023 at 1:23 PM Hongtao Liu  wrote:
>
> On Tue, Oct 24, 2023 at 10:53 AM Hongtao Liu  wrote:
> >
> > On Mon, Oct 23, 2023 at 8:35 PM Richard Biener
> >  wrote:
> > >
> > > On Mon, Oct 23, 2023 at 10:48 AM liuhongt  wrote:
> > > >
> > > > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > > > Ready push to trunk.
> > >
> > > vcond and vcondeq shouldn't be necessary if there's
> > > vcond_mask and vcmp support which is the "modern"
> > > way of handling vcond.  Unless the ISA really can do
> > > compare and select with a single instruction.
> > For testcase
> >
> > typedef _Float16 __attribute__((__vector_size__ (4))) __v2hf;
> > typedef _Float16 __attribute__((__vector_size__ (8))) __v4hf;
> >
> >
> > __v4hf cf, df;
> >
> > __v4hf cfu (__v4hf c, __v4hf d) { return (c > d) ? cf : df; }
> >
> > The data_mode passes to ix86_get_mask_mode is v4hi, not v4hf since
> >
> >   /* Always construct signed integer vector type.  */
> >   intt = c_common_type_for_size
> > (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0);
> >   if (!intt)
> > {
> >   if (complain & tf_error)
> > error_at (location, "could not find an integer type "
> >   "of the same size as %qT", TREE_TYPE (type0));
> >   return error_mark_node;
> > }
> >   result_type = build_opaque_vector_type (intt,
> >   TYPE_VECTOR_SUBPARTS (type0));
> >   return build_vec_cmp (resultcode, result_type, op0, op1);
> >
> > The backend can't distinguish whether it's a vector fp16 comparison or
> > a vector hi comparison.
> > the former requires -mavx512fp16, the latter requires -mavx512bw
> Should we pass type0 instead of result_type here?
 6335@deftypefn {Target Hook} opt_machine_mode
TARGET_VECTORIZE_GET_MASK_MODE (machine_mode @var{mode})
 6336Return the mode to use for a vector mask that holds one boolean
 6337result for each element of vector mode @var{mode}.  The returned mask mode
 6338can be a vector of integers (class @code{MODE_VECTOR_INT}), a vector of
 6339booleans (class @code{MODE_VECTOR_BOOL}) or a scalar integer (class
 6340@code{MODE_INT}).  Return an empty @code{opt_machine_mode} if no such
 6341mask mode exists.

Looks like it's on purpose, v2hi is exactly what we needed here.

Then we use either kmask or v4hi for both v4hf and v4hi comparison,
but can't use v4hi for v4hi comparison, but kmask for v4hf comparison.
> > >
> > > Richard.
> > >
> > > > gcc/ChangeLog:
> > > >
> > > > PR target/103861
> > > > * config/i386/i386-expand.cc (ix86_expand_sse_movcc): Handle
> > > > V2HF/V2BF/V4HF/V4BFmode.
> > > > * config/i386/mmx.md (vec_cmpv4hfqi): New expander.
> > > > (vcondv4hf): Ditto.
> > > > (vcondv4hi): Ditto.
> > > > (vconduv4hi): Ditto.
> > > > (vcond_mask_v4hi): Ditto.
> > > > (vcond_mask_qi): Ditto.
> > > > (vec_cmpv2hfqi): Ditto.
> > > > (vcondv2hf): Ditto.
> > > > (vcondv2hi): Ditto.
> > > > (vconduv2hi): Ditto.
> > > > (vcond_mask_v2hi): Ditto.
> > > > * config/i386/sse.md (vcond): Merge this with ..
> > > > (vcond): .. this into ..
> > > > (vcond): .. this,
> > > > and extend to V8BF/V16BF/V32BFmode.
> > > >
> > > > gcc/testsuite/ChangeLog:
> > > >
> > > > * g++.target/i386/part-vect-vcondhf.C: New test.
> > > > * gcc.target/i386/part-vect-vec_cmphf.c: New test.
> > > > ---
> > > >  gcc/config/i386/i386-expand.cc|   4 +
> > > >  gcc/config/i386/mmx.md| 237 +-
> > > >  gcc/config/i386/sse.md|  25 +-
> > > >  .../g++.target/i386/part-vect-vcondhf.C   |  34 +++
> > > >  .../gcc.target/i386/part-vect-vec_cmphf.c |  26 ++
> > > >  5 files changed, 304 insertions(+), 22 deletions(-)
> > > >  create mode 100644 gcc/testsuite/g++.target/i386/part-vect-vcondhf.C
> > > >  create mode 100644 gcc/testsuite/gcc.target/i386/part-vect-vec_cmphf.c
> > > >
> > > > diff --git a/gcc/config/i386/i386-expand.cc 
> > > > b/gcc/config/i386/i386-expand.cc
> > > > index 1eae9d7c78c..9658f9c5a2d 100644
> > > > --- a/gcc/config/i386/i386-expand.cc
> > > > +++ b/gcc/config/i386/i386-expand.cc
> > > > @@ -4198,6 +4198,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx 
> > > > op_true, rtx op_false)
> > > >break;
> > > >  case E_V8QImode:
> > > >  case E_V4HImode:
> > > > +case E_V4HFmode:
> > > > +case E_V4BFmode:
> > > >  case E_V2SImode:
> > > >if (TARGET_SSE4_1)
> > > > {
> > > > @@ -4207,6 +4209,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx 
> > > > op_true, rtx op_false)
> > > >break;
> > > >  case E_V4QImode:
> > > >  case E_V2HImode:
> > > > +case E_V2HFmode:
> > > > +case E_V2BFmode:
> > > >if (TARGET_SSE4_1)
> > > > {
> > > >   gen = gen_mmx_pblendvb_v4qi;
> > > > diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
> > > > index 491a0a51272..b9617e9d8c6 

Re: [PATCH] Support vec_cmpmn/vcondmn for v2hf/v4hf.

2023-10-23 Thread Hongtao Liu
On Tue, Oct 24, 2023 at 10:53 AM Hongtao Liu  wrote:
>
> On Mon, Oct 23, 2023 at 8:35 PM Richard Biener
>  wrote:
> >
> > On Mon, Oct 23, 2023 at 10:48 AM liuhongt  wrote:
> > >
> > > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > > Ready push to trunk.
> >
> > vcond and vcondeq shouldn't be necessary if there's
> > vcond_mask and vcmp support which is the "modern"
> > way of handling vcond.  Unless the ISA really can do
> > compare and select with a single instruction.
> For testcase
>
> typedef _Float16 __attribute__((__vector_size__ (4))) __v2hf;
> typedef _Float16 __attribute__((__vector_size__ (8))) __v4hf;
>
>
> __v4hf cf, df;
>
> __v4hf cfu (__v4hf c, __v4hf d) { return (c > d) ? cf : df; }
>
> The data_mode passes to ix86_get_mask_mode is v4hi, not v4hf since
>
>   /* Always construct signed integer vector type.  */
>   intt = c_common_type_for_size
> (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0);
>   if (!intt)
> {
>   if (complain & tf_error)
> error_at (location, "could not find an integer type "
>   "of the same size as %qT", TREE_TYPE (type0));
>   return error_mark_node;
> }
>   result_type = build_opaque_vector_type (intt,
>   TYPE_VECTOR_SUBPARTS (type0));
>   return build_vec_cmp (resultcode, result_type, op0, op1);
>
> The backend can't distinguish whether it's a vector fp16 comparison or
> a vector hi comparison.
> the former requires -mavx512fp16, the latter requires -mavx512bw
Should we pass type0 instead of result_type here?
> >
> > Richard.
> >
> > > gcc/ChangeLog:
> > >
> > > PR target/103861
> > > * config/i386/i386-expand.cc (ix86_expand_sse_movcc): Handle
> > > V2HF/V2BF/V4HF/V4BFmode.
> > > * config/i386/mmx.md (vec_cmpv4hfqi): New expander.
> > > (vcondv4hf): Ditto.
> > > (vcondv4hi): Ditto.
> > > (vconduv4hi): Ditto.
> > > (vcond_mask_v4hi): Ditto.
> > > (vcond_mask_qi): Ditto.
> > > (vec_cmpv2hfqi): Ditto.
> > > (vcondv2hf): Ditto.
> > > (vcondv2hi): Ditto.
> > > (vconduv2hi): Ditto.
> > > (vcond_mask_v2hi): Ditto.
> > > * config/i386/sse.md (vcond): Merge this with ..
> > > (vcond): .. this into ..
> > > (vcond): .. this,
> > > and extend to V8BF/V16BF/V32BFmode.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * g++.target/i386/part-vect-vcondhf.C: New test.
> > > * gcc.target/i386/part-vect-vec_cmphf.c: New test.
> > > ---
> > >  gcc/config/i386/i386-expand.cc|   4 +
> > >  gcc/config/i386/mmx.md| 237 +-
> > >  gcc/config/i386/sse.md|  25 +-
> > >  .../g++.target/i386/part-vect-vcondhf.C   |  34 +++
> > >  .../gcc.target/i386/part-vect-vec_cmphf.c |  26 ++
> > >  5 files changed, 304 insertions(+), 22 deletions(-)
> > >  create mode 100644 gcc/testsuite/g++.target/i386/part-vect-vcondhf.C
> > >  create mode 100644 gcc/testsuite/gcc.target/i386/part-vect-vec_cmphf.c
> > >
> > > diff --git a/gcc/config/i386/i386-expand.cc 
> > > b/gcc/config/i386/i386-expand.cc
> > > index 1eae9d7c78c..9658f9c5a2d 100644
> > > --- a/gcc/config/i386/i386-expand.cc
> > > +++ b/gcc/config/i386/i386-expand.cc
> > > @@ -4198,6 +4198,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx 
> > > op_true, rtx op_false)
> > >break;
> > >  case E_V8QImode:
> > >  case E_V4HImode:
> > > +case E_V4HFmode:
> > > +case E_V4BFmode:
> > >  case E_V2SImode:
> > >if (TARGET_SSE4_1)
> > > {
> > > @@ -4207,6 +4209,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx 
> > > op_true, rtx op_false)
> > >break;
> > >  case E_V4QImode:
> > >  case E_V2HImode:
> > > +case E_V2HFmode:
> > > +case E_V2BFmode:
> > >if (TARGET_SSE4_1)
> > > {
> > >   gen = gen_mmx_pblendvb_v4qi;
> > > diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
> > > index 491a0a51272..b9617e9d8c6 100644
> > > --- a/gcc/config/i386/mmx.md
> > > +++ b/gcc/config/i386/mmx.md
> > > @@ -61,6 +61,9 @@ (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
> > >  (define_mode_iterator V_32 [V4QI V2HI V1SI V2HF V2BF])
> > >
> > >  (define_mode_iterator V2FI_32 [V2HF V2BF V2HI])
> > > +(define_mode_iterator V4FI_64 [V4HF V4BF V4HI])
> > > +(define_mode_iterator V4F_64 [V4HF V4BF])
> > > +(define_mode_iterator V2F_32 [V2HF V2BF])
> > >  ;; 4-byte integer vector modes
> > >  (define_mode_iterator VI_32 [V4QI V2HI])
> > >
> > > @@ -1972,10 +1975,12 @@ (define_mode_attr mov_to_sse_suffix
> > >[(V2HF "d") (V4HF "q") (V2HI "d") (V4HI "q")])
> > >
> > >  (define_mode_attr mmxxmmmode
> > > -  [(V2HF "V8HF") (V2HI "V8HI") (V2BF "V8BF")])
> > > +  [(V2HF "V8HF") (V2HI "V8HI") (V2BF "V8BF")
> > > +   (V4HF "V8HF") (V4HI "V8HI") (V4BF "V8BF")])
> > >
> > >  (define_mode_attr mmxxmmmodelower
> > > -  [(V2HF "v8hf") (V2HI "v8hi") (V2BF "v8bf")])
> > > +  [(V2HF "v8hf") (V2HI 

Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-10-23 Thread François Dumont

Hi

Still no one to complete this review ?

Thanks


On 07/10/2023 21:32, François Dumont wrote:
I've been told that previous patch generated with 'git diff -b' was 
not applying properly so here is the same patch again with a simple 
'git diff'.



On 07/10/2023 14:25, François Dumont wrote:

Hi

Here is a rebased version of this patch.

There are few test failures when running 'make check-c++' but nothing 
new.


Still, there are 2 patches awaiting validation to fix some of them, 
PR c++/111524 to fix another bunch and I fear that we will have to 
live with the others.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

    Use cxx11 abi when activating versioned namespace mode. To do 
support
    a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
_GLIBCXX_USE_CXX11_ABI.


    The main change is that std::__cow_string is now defined whenever 
_GLIBCXX_USE_DUAL_ABI
    or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
available std::string in

    case of dual abi and a subset of it when it's not.

    On the other side std::__sso_string is defined only when 
_GLIBCXX_USE_DUAL_ABI is true
    and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
std::__sso_string is a typedef for the
    cow std::string implementation when dual abi is disabled and cow 
string is being used.


    libstdcxx-v3/ChangeLog:

    PR libstdc++/83077
    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
Default to "new" libstdcxx abi

    when enable_symvers is gnu-versioned-namespace.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
    [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
    [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):

    Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):

    Likewise.
    * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW

    basic_string as __std_cow_string for use in stdexcept.
    * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.

    (__cow_string(const char*)): New.
    (__cow_string::c_str()): New.
    * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True

    when std::__8::basic_string type is found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define 
empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,

    cxx11-ios_failure.cc entries to...
    (sources): ...this.
    (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
    cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,

    cxx11-wlocale-inst.cc entries to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include .
    [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
    including . Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that

    __cow_string definition in  is skipped.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
    * src/c++11/string-inst.cc: Add sizeof/alignof 
static_assert on stdexcept

    __cow_string definition.
    (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
following _GLIBCXX_USE_CXX11_ABI

    value.
    [_GLIBCXX_USE_CXX11_ABI && 
!_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
    Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
Include .
    Define basic_string as __std_cow_string for the current 
translation unit.
    * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-string-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-io-inst.cc 

Re: [PATCH] RISC-V: Add AVL propagation PASS for RVV auto-vectorization

2023-10-23 Thread Patrick O'Neill
The CI just picked it up: 
https://github.com/ewlu/gcc-precommit-ci/issues/449#issue-1958483272
Since it doesn't apply to the CI's baseline hash it's only performing a 
build.

I'll re-run it in the morning once the baseline has been updated.

In the meantime I started a full build+test run on my local machine.
I'll send you the results in ~10 hours - morning my time :-)

Patrick

On 10/23/23 20:44, juzhe.zh...@rivai.ai wrote:

CCing Patrick...

Hi, @Patrick.
Could you apply this patch and trigger your regression CI?

I don't have an environment to test fortran for now (I only test it on 
C/C++).


Thanks.


juzhe.zh...@rivai.ai

*From:* Juzhe-Zhong 
*Date:* 2023-10-24 11:32
*To:* gcc-patches 
*CC:* kito.cheng ; kito.cheng
; jeffreyalaw
; rdapp.gcc
; Juzhe-Zhong

*Subject:* [PATCH] RISC-V: Add AVL propagation PASS for RVV
auto-vectorization
This patch addresses the redundant AVL/VL toggling in RVV partial
auto-vectorization
which is a known issue for a long time and I finally find the time
to address it.
Consider a simple vector addition operation:
https://godbolt.org/z/7hfGfEjW3
void
foo (int *__restrict a,
 int *__restrict b,
 int *__restrict n)
{
  for (int i = 0; i < n; i++)
  a[i] = a[i] + b[i];
}
Optimized IR:
Loop body:
  _38 = .SELECT_VL (ivtmp_36, POLY_INT_CST [4,
4]);  -> vsetvli a5,a2,e8,mf4,ta,ma
  ...
  vect__4.8_27 = .MASK_LEN_LOAD (vectp_a.6_29, 32B, { -1, ... },
_38, 0);    -> vle32.v v2,0(a0)
  vect__6.11_20 = .MASK_LEN_LOAD (vectp_b.9_25, 32B, { -1, ... },
_38, 0);   -> vle32.v v1,0(a1)
  vect__7.12_19 = vect__6.11_20 +
vect__4.8_27;  -> vsetvli
a6,zero,e32,m1,ta,ma + vadd.vv v1,v1,v2
  .MASK_LEN_STORE (vectp_a.13_11, 32B, { -1, ... }, _38, 0,
vect__7.12_19);  -> vsetvli zero,a5,e32,m1,ta,ma + vse32.v v1,0(a4)
We can see 2 redundant vsetvls inside the loop body due to AVL/VL
toggling.
The AVL/VL toggling is because we are missing LEN information in
simple PLUS_EXPR GIMPLE assignment:
vect__7.12_19 = vect__6.11_20 + vect__4.8_27;
GCC apply partial predicate load/store and un-predicated full
vector operation on partial vectorization.
Such flow are used by all other targets like ARM SVE (RVV also
uses such flow):
ARM SVE:
.L3:
    ld1w    z30.s, p7/z, [x0, x3, lsl 2]   -> predicated load
    ld1w    z31.s, p7/z, [x1, x3, lsl 2]   -> predicated load
    add z31.s, z31.s, z30.s    -> un-predicated add
    st1w    z31.s, p7, [x0, x3, lsl 2] -> predicated store
Such vectorization flow causes AVL/VL toggling on RVV so we need
AVL propagation PASS for it.
Also, It's very unlikely that we can apply predicated operations
on all vectorization for following reasons:
1. It's very heavy workload to support them on all vectorization
and we don't see any benefits if we can handle that on targets
backend.
2. Changing Loop vectorizer for it will make code base ugly and
hard to maintain.
3. We will need so many patterns for all operations. Not only
COND_LEN_ADD, COND_LEN_SUB, 
   We also need COND_LEN_EXTEND, , COND_LEN_CEIL, ... .. over
100+ patterns, unreasonable number of patterns.
To conclude, we prefer un-predicated operations here, and design a
nice and clean AVL propagation PASS for it to elide the redundant
vsetvls
due to AVL/VL toggling.
The second question is that why we separate a PASS called AVL
propagation. Why not optimize it in VSETVL PASS (We definitetly
can optimize AVL in VSETVL PASS)
Frankly, I was planning to address such issue in VSETVL PASS
that's why we recently refactored VSETVL PASS. However, I changed
my mind recently after several
experiments and tries.
The reasons as follows:
1. For code base management and maintainience. Current VSETVL PASS
is complicated enough and aleady has enough aggressive and fancy
optimizations which
   turns out it can always generate optimal codegen in most of the
cases. It's not a good idea keep adding more features into VSETVL
PASS to make VSETVL
PASS become heavy and heavy again, then we will need to refactor
it again in the future.
Actuall, the VSETVL PASS is very stable and optimal after the
recent refactoring. Hopefully, we should not change VSETVL PASS
any more except the minor
fixes.
2. vsetvl insertion (VSETVL PASS does this thing) and AVL
propagation are 2 different things,  I don't think we should fuse

Re: [PATCH] RISC-V: Add AVL propagation PASS for RVV auto-vectorization

2023-10-23 Thread juzhe.zh...@rivai.ai
CCing Patrick...

Hi, @Patrick.
Could you apply this patch and trigger your regression CI?

I don't have an environment to test fortran for now (I only test it on C/C++).

Thanks. 



juzhe.zh...@rivai.ai
 
From: Juzhe-Zhong
Date: 2023-10-24 11:32
To: gcc-patches
CC: kito.cheng; kito.cheng; jeffreyalaw; rdapp.gcc; Juzhe-Zhong
Subject: [PATCH] RISC-V: Add AVL propagation PASS for RVV auto-vectorization
This patch addresses the redundant AVL/VL toggling in RVV partial 
auto-vectorization
which is a known issue for a long time and I finally find the time to address 
it.
 
Consider a simple vector addition operation:
 
https://godbolt.org/z/7hfGfEjW3
 
void
foo (int *__restrict a,
 int *__restrict b,
 int *__restrict n)
{
  for (int i = 0; i < n; i++)
  a[i] = a[i] + b[i];
}
 
Optimized IR:
 
Loop body:
  _38 = .SELECT_VL (ivtmp_36, POLY_INT_CST [4, 4]);  -> 
vsetvli a5,a2,e8,mf4,ta,ma
  ...
  vect__4.8_27 = .MASK_LEN_LOAD (vectp_a.6_29, 32B, { -1, ... }, _38, 0);-> 
vle32.v v2,0(a0)
  vect__6.11_20 = .MASK_LEN_LOAD (vectp_b.9_25, 32B, { -1, ... }, _38, 0);   -> 
vle32.v v1,0(a1)
  vect__7.12_19 = vect__6.11_20 + vect__4.8_27;  -> 
vsetvli a6,zero,e32,m1,ta,ma + vadd.vv v1,v1,v2
  .MASK_LEN_STORE (vectp_a.13_11, 32B, { -1, ... }, _38, 0, vect__7.12_19);  -> 
vsetvli zero,a5,e32,m1,ta,ma + vse32.v v1,0(a4)
 
We can see 2 redundant vsetvls inside the loop body due to AVL/VL toggling.
The AVL/VL toggling is because we are missing LEN information in simple 
PLUS_EXPR GIMPLE assignment:
 
vect__7.12_19 = vect__6.11_20 + vect__4.8_27;
 
GCC apply partial predicate load/store and un-predicated full vector operation 
on partial vectorization.
Such flow are used by all other targets like ARM SVE (RVV also uses such flow):
 
ARM SVE:
   
.L3:
ld1wz30.s, p7/z, [x0, x3, lsl 2]   -> predicated load
ld1wz31.s, p7/z, [x1, x3, lsl 2]   -> predicated load
add z31.s, z31.s, z30.s-> un-predicated add
st1wz31.s, p7, [x0, x3, lsl 2] -> predicated store
 
Such vectorization flow causes AVL/VL toggling on RVV so we need AVL 
propagation PASS for it.
 
Also, It's very unlikely that we can apply predicated operations on all 
vectorization for following reasons:
 
1. It's very heavy workload to support them on all vectorization and we don't 
see any benefits if we can handle that on targets backend.
2. Changing Loop vectorizer for it will make code base ugly and hard to 
maintain.
3. We will need so many patterns for all operations. Not only COND_LEN_ADD, 
COND_LEN_SUB, 
   We also need COND_LEN_EXTEND, , COND_LEN_CEIL, ... .. over 100+ 
patterns, unreasonable number of patterns.
 
To conclude, we prefer un-predicated operations here, and design a nice and 
clean AVL propagation PASS for it to elide the redundant vsetvls
due to AVL/VL toggling.
 
The second question is that why we separate a PASS called AVL propagation. Why 
not optimize it in VSETVL PASS (We definitetly can optimize AVL in VSETVL PASS)
 
Frankly, I was planning to address such issue in VSETVL PASS that's why we 
recently refactored VSETVL PASS. However, I changed my mind recently after 
several
experiments and tries.
 
The reasons as follows:
 
1. For code base management and maintainience. Current VSETVL PASS is 
complicated enough and aleady has enough aggressive and fancy optimizations 
which
   turns out it can always generate optimal codegen in most of the cases. It's 
not a good idea keep adding more features into VSETVL PASS to make VSETVL
PASS become heavy and heavy again, then we will need to refactor it again in 
the future.
Actuall, the VSETVL PASS is very stable and optimal after the recent 
refactoring. Hopefully, we should not change VSETVL PASS any more except the 
minor
fixes.
 
2. vsetvl insertion (VSETVL PASS does this thing) and AVL propagation are 2 
different things,  I don't think we should fuse them into same PASS.
 
3. VSETVL PASS is an post-RA PASS, wheras AVL propagtion should be done before 
RA which can reduce register allocation.
 
4. This patch's AVL propagation PASS only does AVL propagation for RVV partial 
auto-vectorization situations.
   This patch's codes are only hundreds lines which is very managable and can 
be very easily extended features and enhancements.
We can easily extend and enhance more AVL propagation in a clean and separate 
PASS in the future. (If we do it on VSETVL PASS, we will complicate 
VSETVL PASS again which is already so complicated.) 
 
Here is an example to demonstrate more:
 
https://godbolt.org/z/bE86sv3q5
 
void foo2 (int *__restrict a,
  int *__restrict b,
  int *__restrict c,
  int *__restrict a2,
  int *__restrict b2,
  int *__restrict c2,
  int *__restrict a3,
  int *__restrict b3,
  int *__restrict c3,
  int *__restrict a4,
  int *__restrict b4,
  int *__restrict c4,
 

[PATCH] RISC-V: Add AVL propagation PASS for RVV auto-vectorization

2023-10-23 Thread Juzhe-Zhong
This patch addresses the redundant AVL/VL toggling in RVV partial 
auto-vectorization
which is a known issue for a long time and I finally find the time to address 
it.

Consider a simple vector addition operation:

https://godbolt.org/z/7hfGfEjW3

void
foo (int *__restrict a,
 int *__restrict b,
 int *__restrict n)
{
  for (int i = 0; i < n; i++)
  a[i] = a[i] + b[i];
}

Optimized IR:

Loop body:
  _38 = .SELECT_VL (ivtmp_36, POLY_INT_CST [4, 4]);  -> 
vsetvli a5,a2,e8,mf4,ta,ma
  ...
  vect__4.8_27 = .MASK_LEN_LOAD (vectp_a.6_29, 32B, { -1, ... }, _38, 0);-> 
vle32.v v2,0(a0)
  vect__6.11_20 = .MASK_LEN_LOAD (vectp_b.9_25, 32B, { -1, ... }, _38, 0);   -> 
vle32.v v1,0(a1)
  vect__7.12_19 = vect__6.11_20 + vect__4.8_27;  -> 
vsetvli a6,zero,e32,m1,ta,ma + vadd.vv v1,v1,v2
  .MASK_LEN_STORE (vectp_a.13_11, 32B, { -1, ... }, _38, 0, vect__7.12_19);  -> 
vsetvli zero,a5,e32,m1,ta,ma + vse32.v v1,0(a4)

We can see 2 redundant vsetvls inside the loop body due to AVL/VL toggling.
The AVL/VL toggling is because we are missing LEN information in simple 
PLUS_EXPR GIMPLE assignment:

vect__7.12_19 = vect__6.11_20 + vect__4.8_27;

GCC apply partial predicate load/store and un-predicated full vector operation 
on partial vectorization.
Such flow are used by all other targets like ARM SVE (RVV also uses such flow):

ARM SVE:
   
.L3:
ld1wz30.s, p7/z, [x0, x3, lsl 2]   -> predicated load
ld1wz31.s, p7/z, [x1, x3, lsl 2]   -> predicated load
add z31.s, z31.s, z30.s-> un-predicated add
st1wz31.s, p7, [x0, x3, lsl 2] -> predicated store

Such vectorization flow causes AVL/VL toggling on RVV so we need AVL 
propagation PASS for it.

Also, It's very unlikely that we can apply predicated operations on all 
vectorization for following reasons:

1. It's very heavy workload to support them on all vectorization and we don't 
see any benefits if we can handle that on targets backend.
2. Changing Loop vectorizer for it will make code base ugly and hard to 
maintain.
3. We will need so many patterns for all operations. Not only COND_LEN_ADD, 
COND_LEN_SUB, 
   We also need COND_LEN_EXTEND, , COND_LEN_CEIL, ... .. over 100+ 
patterns, unreasonable number of patterns.

To conclude, we prefer un-predicated operations here, and design a nice and 
clean AVL propagation PASS for it to elide the redundant vsetvls
due to AVL/VL toggling.

The second question is that why we separate a PASS called AVL propagation. Why 
not optimize it in VSETVL PASS (We definitetly can optimize AVL in VSETVL PASS)

Frankly, I was planning to address such issue in VSETVL PASS that's why we 
recently refactored VSETVL PASS. However, I changed my mind recently after 
several
experiments and tries.

The reasons as follows:

1. For code base management and maintainience. Current VSETVL PASS is 
complicated enough and aleady has enough aggressive and fancy optimizations 
which
   turns out it can always generate optimal codegen in most of the cases. It's 
not a good idea keep adding more features into VSETVL PASS to make VSETVL
 PASS become heavy and heavy again, then we will need to refactor it 
again in the future.
 Actuall, the VSETVL PASS is very stable and optimal after the recent 
refactoring. Hopefully, we should not change VSETVL PASS any more except the 
minor
 fixes.

2. vsetvl insertion (VSETVL PASS does this thing) and AVL propagation are 2 
different things,  I don't think we should fuse them into same PASS.

3. VSETVL PASS is an post-RA PASS, wheras AVL propagtion should be done before 
RA which can reduce register allocation.

4. This patch's AVL propagation PASS only does AVL propagation for RVV partial 
auto-vectorization situations.
   This patch's codes are only hundreds lines which is very managable and can 
be very easily extended features and enhancements.
 We can easily extend and enhance more AVL propagation in a clean and 
separate PASS in the future. (If we do it on VSETVL PASS, we will complicate 
 VSETVL PASS again which is already so complicated.) 

Here is an example to demonstrate more:

https://godbolt.org/z/bE86sv3q5

void foo2 (int *__restrict a,
  int *__restrict b,
  int *__restrict c,
  int *__restrict a2,
  int *__restrict b2,
  int *__restrict c2,
  int *__restrict a3,
  int *__restrict b3,
  int *__restrict c3,
  int *__restrict a4,
  int *__restrict b4,
  int *__restrict c4,
  int *__restrict a5,
  int *__restrict b5,
  int *__restrict c5,
  int n)
{
for (int i = 0; i < n; i++){
  a[i] = b[i] + c[i];
  b5[i] = b[i] + c[i];
  a2[i] = b2[i] + c2[i];
  a3[i] = b3[i] + c3[i];
  a4[i] = b4[i] + c4[i];
  a5[i] = a[i] + a4[i];
  a[i] = a5[i] + b5[i]+ a[i];

  a[i] = a[i] + c[i];
  b5[i] = a[i] + 

Re: Inquiry about ARM gcc5 CVE-2023-4039 Patch

2023-10-23 Thread Andrew Pinski
On Mon, Oct 23, 2023 at 7:54 PM 老小孩老小孩  wrote:
>
> Dear arms,
>
> I hope this message finds you well.
>
> I am writing to inquire about the issue of ARM gcc5 CVE-2023-4039. According 
> to the advisory on GitHub 
> (https://github.com/metaredteam/external-disclosures/security/advisories/GHSA-x7ch-h5rf-w2mf),
>  this bug affects versions from 5.4.0 to the trunk as of May 15, 2023.
>
> However, I noticed that currently, patches are only provided for gcc7 and 
> above, as per the information available on the ARM Security Center 
> (https://developer.arm.com/Arm%20Security%20Center/GCC%20Stack%20Protector%20Vulnerability%20AArch64).
>
> Given the potential impact of this vulnerability, I am particularly 
> interested in a patch for gcc5. Could you please provide information on 
> whether a patch for gcc5 is available or planned? If not, could you suggest 
> any possible workarounds or mitigation strategies for systems that are 
> currently using gcc5?
>
> I appreciate your attention to this matter and look forward to your response.

THIS should NEVER have been a security CVE in the first place.
This is not a security issue with any correct code that GCC will process.
GCC does not consider this a security issue according to its security policy.
See the "Security features implemented in GCC" section of
https://gcc.gnu.org/git/?p=gcc.git;a=blob_plain;f=SECURITY.txt;hb=HEAD
for more information on that policy.

Thanks,
Andrew Pinski

>
> Best regards,


Inquiry about ARM gcc5 CVE-2023-4039 Patch

2023-10-23 Thread 老小孩老小孩
Dear arms,


I hope this message finds you well.


I am writing to inquire about the issue of ARM gcc5 CVE-2023-4039. According to 
the advisory on GitHub 
(https://github.com/metaredteam/external-disclosures/security/advisories/GHSA-x7ch-h5rf-w2mf),
 this bug affects versions from 5.4.0 to the trunk as of May 15, 2023.


However, I noticed that currently, patches are only provided for gcc7 and 
above, as per the information available on the ARM Security Center 
(https://developer.arm.com/Arm%20Security%20Center/GCC%20Stack%20Protector%20Vulnerability%20AArch64).


Given the potential impact of this vulnerability, I am particularly interested 
in a patch for gcc5. Could you please provide information on whether a patch 
for gcc5 is available or planned? If not, could you suggest any possible 
workarounds or mitigation strategies for systems that are currently using gcc5?


I appreciate your attention to this matter and look forward to your response.


Best regards,

Re: [PATCH] Support vec_cmpmn/vcondmn for v2hf/v4hf.

2023-10-23 Thread Hongtao Liu
On Mon, Oct 23, 2023 at 8:35 PM Richard Biener
 wrote:
>
> On Mon, Oct 23, 2023 at 10:48 AM liuhongt  wrote:
> >
> > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > Ready push to trunk.
>
> vcond and vcondeq shouldn't be necessary if there's
> vcond_mask and vcmp support which is the "modern"
> way of handling vcond.  Unless the ISA really can do
> compare and select with a single instruction.
For testcase

typedef _Float16 __attribute__((__vector_size__ (4))) __v2hf;
typedef _Float16 __attribute__((__vector_size__ (8))) __v4hf;


__v4hf cf, df;

__v4hf cfu (__v4hf c, __v4hf d) { return (c > d) ? cf : df; }

The data_mode passes to ix86_get_mask_mode is v4hi, not v4hf since

  /* Always construct signed integer vector type.  */
  intt = c_common_type_for_size
(GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0);
  if (!intt)
{
  if (complain & tf_error)
error_at (location, "could not find an integer type "
  "of the same size as %qT", TREE_TYPE (type0));
  return error_mark_node;
}
  result_type = build_opaque_vector_type (intt,
  TYPE_VECTOR_SUBPARTS (type0));
  return build_vec_cmp (resultcode, result_type, op0, op1);

The backend can't distinguish whether it's a vector fp16 comparison or
a vector hi comparison.
the former require -mavx512fp16, the latter requires -mavx512bw
>
> Richard.
>
> > gcc/ChangeLog:
> >
> > PR target/103861
> > * config/i386/i386-expand.cc (ix86_expand_sse_movcc): Handle
> > V2HF/V2BF/V4HF/V4BFmode.
> > * config/i386/mmx.md (vec_cmpv4hfqi): New expander.
> > (vcondv4hf): Ditto.
> > (vcondv4hi): Ditto.
> > (vconduv4hi): Ditto.
> > (vcond_mask_v4hi): Ditto.
> > (vcond_mask_qi): Ditto.
> > (vec_cmpv2hfqi): Ditto.
> > (vcondv2hf): Ditto.
> > (vcondv2hi): Ditto.
> > (vconduv2hi): Ditto.
> > (vcond_mask_v2hi): Ditto.
> > * config/i386/sse.md (vcond): Merge this with ..
> > (vcond): .. this into ..
> > (vcond): .. this,
> > and extend to V8BF/V16BF/V32BFmode.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * g++.target/i386/part-vect-vcondhf.C: New test.
> > * gcc.target/i386/part-vect-vec_cmphf.c: New test.
> > ---
> >  gcc/config/i386/i386-expand.cc|   4 +
> >  gcc/config/i386/mmx.md| 237 +-
> >  gcc/config/i386/sse.md|  25 +-
> >  .../g++.target/i386/part-vect-vcondhf.C   |  34 +++
> >  .../gcc.target/i386/part-vect-vec_cmphf.c |  26 ++
> >  5 files changed, 304 insertions(+), 22 deletions(-)
> >  create mode 100644 gcc/testsuite/g++.target/i386/part-vect-vcondhf.C
> >  create mode 100644 gcc/testsuite/gcc.target/i386/part-vect-vec_cmphf.c
> >
> > diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> > index 1eae9d7c78c..9658f9c5a2d 100644
> > --- a/gcc/config/i386/i386-expand.cc
> > +++ b/gcc/config/i386/i386-expand.cc
> > @@ -4198,6 +4198,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx 
> > op_true, rtx op_false)
> >break;
> >  case E_V8QImode:
> >  case E_V4HImode:
> > +case E_V4HFmode:
> > +case E_V4BFmode:
> >  case E_V2SImode:
> >if (TARGET_SSE4_1)
> > {
> > @@ -4207,6 +4209,8 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx 
> > op_true, rtx op_false)
> >break;
> >  case E_V4QImode:
> >  case E_V2HImode:
> > +case E_V2HFmode:
> > +case E_V2BFmode:
> >if (TARGET_SSE4_1)
> > {
> >   gen = gen_mmx_pblendvb_v4qi;
> > diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
> > index 491a0a51272..b9617e9d8c6 100644
> > --- a/gcc/config/i386/mmx.md
> > +++ b/gcc/config/i386/mmx.md
> > @@ -61,6 +61,9 @@ (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
> >  (define_mode_iterator V_32 [V4QI V2HI V1SI V2HF V2BF])
> >
> >  (define_mode_iterator V2FI_32 [V2HF V2BF V2HI])
> > +(define_mode_iterator V4FI_64 [V4HF V4BF V4HI])
> > +(define_mode_iterator V4F_64 [V4HF V4BF])
> > +(define_mode_iterator V2F_32 [V2HF V2BF])
> >  ;; 4-byte integer vector modes
> >  (define_mode_iterator VI_32 [V4QI V2HI])
> >
> > @@ -1972,10 +1975,12 @@ (define_mode_attr mov_to_sse_suffix
> >[(V2HF "d") (V4HF "q") (V2HI "d") (V4HI "q")])
> >
> >  (define_mode_attr mmxxmmmode
> > -  [(V2HF "V8HF") (V2HI "V8HI") (V2BF "V8BF")])
> > +  [(V2HF "V8HF") (V2HI "V8HI") (V2BF "V8BF")
> > +   (V4HF "V8HF") (V4HI "V8HI") (V4BF "V8BF")])
> >
> >  (define_mode_attr mmxxmmmodelower
> > -  [(V2HF "v8hf") (V2HI "v8hi") (V2BF "v8bf")])
> > +  [(V2HF "v8hf") (V2HI "v8hi") (V2BF "v8bf")
> > +   (V4HF "v8hf") (V4HI "v8hi") (V4BF "v8bf")])
> >
> >  (define_expand "movd__to_sse"
> >[(set (match_operand: 0 "register_operand")
> > @@ -2114,6 +2119,234 @@ (define_insn_and_split "*mmx_nabs2"
> >[(set (match_dup 0)
> > (ior: (match_dup 1) (match_dup 2)))])
> >
> > 

Re: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

2023-10-23 Thread juzhe.zh...@rivai.ai
Fixed on trunk. Pl;z verify it.




juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 09:01
To: juzhe.zh...@rivai.ai; 丁乐华
CC: kito.cheng; Robin Dapp; palmer; jeffreyalaw; gcc-patches
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
IIRC --enable-checking=yes does not turn on RTL checking.
You need to pass in rtl explicitly using --enable-checking=rtl
You can also pass in a list of checks like this: --enable-checking=yes,rtl

Patrick

On 10/23/23 17:51, juzhe.zh...@rivai.ai wrote:
I don't have such issue:

[jzzhong@rios-cad121:/work/home/jzzhong/work/insn]$~/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/bin/riscv64-unknown-elf-gcc
 -v
Using built-in specs.
COLLECT_GCC=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/bin/riscv64-unknown-elf-gcc
COLLECT_LTO_WRAPPER=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/libexec/gcc/riscv64-unknown-elf/14.0.0/lto-wrapper
Target: riscv64-unknown-elf
Configured with: 
/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/../../gcc/configure
 --target=riscv64-unknown-elf 
--prefix=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install
 --disable-shared --disable-threads --enable-languages=c,c++ 
--with-pkgversion=g70b66ac9bcb-dirty --with-system-zlib --enable-tls 
--with-newlib 
--with-sysroot=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/riscv64-unknown-elf
 --with-native-system-header-dir=/include --disable-libmudflap --disable-libssp 
--disable-libquadmath --disable-libgomp --disable-nls 
--disable-tm-clone-registry --src=../../../gcc --enable-checking=yes 
--disable-multilib --with-abi=lp64d --with-arch=rv64gcv_zfh_zvfh 
--with-tune=rocket --with-isa-spec=20191213 CFLAGS='-O0 -g3' CXXFLAGS='-O0 -g3' 
'CFLAGS_FOR_TARGET=-Os-mcmodel=medany' 'CXXFLAGS_FOR_TARGET=-Os
-mcmodel=medany'
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 14.0.0 20231023 (experimental) (g70b66ac9bcb-dirty)




juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 07:42
To: 钟居哲; 丁乐华
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
When configuring, pass in --enable-checking=rtl
If you're using riscv-gnu-toolchain, pass in --enable-gcc-checking=rtl

The -freport-bug output attached to the bug report has the full configure 
command used:
/scratch/tc-testing/tc-trunk/build-rtl-checking/../gcc/configure 
--target=riscv64-unknown-linux-gnu 
--prefix=/scratch/tc-testing/tc-trunk/build-rtl-checking 
--with-sysroot=/scratch/tc-testing/tc-trunk/build-rtl-checking/sysroot 
--with-newlib --without-headers --disable-shared --disable-threads 
--with-system-zlib --enable-tls --enable-languages=c --disable-libatomic 
--disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp 
--disable-nls --disable-bootstrap --src=../../gcc --enable-checking=rtl 
--disable-multilib --with-abi=lp64d --with-arch=rv64gcv --with-tune=rocket 
--with-isa-spec=20191213 'CFLAGS_FOR_TARGET=-O2-mcmodel=medlow' 
'CXXFLAGS_FOR_TARGET=-O2-mcmodel=medlow'

On 10/23/23 15:50, 钟居哲 wrote:
I didn't reproduce it. How to enable RTL checking ?



juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 06:46
To: 钟居哲; 丁乐华
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
You're on top of it - thanks for fixing this! I'll send the testcase.

Unrelated to this failure, I'm seeing a build failure on glibc rv32/64gcv when 
RTL checking is enabled.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111947

Thanks,
Patrick
On 10/23/23 14:41, 钟居哲 wrote:
I have fixed it: 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0c4bd1321a6def5eb44c530e83b01a415633b660

Plz verify it and send a patch with testcase pr111941.c if you confirm it has 
been fixed on the trunk.

Thanks.


juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 02:30
To: Lehua Ding
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches; 钟居哲
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
Hi Lehua,
 
This patch causes a build failure with newlib 4.1.0 with -march=rv64gv_zbb.
 
I've creduced the failure here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111941
 
Thanks,
Patrick
 
On 10/19/23 20:58, Lehua Ding wrote:
> Committed, thanks Patrick and Juzhe.
>
> On 2023/10/20 2:04, Patrick O'Neill wrote:
>> I tested it this morning on my machine and it passed!
>>
>> Tested against:
>> 04d6c74564b7eb51660a00b35353aeab706b5a50
>>
>> Using targets:
>> glibc rv32gcv qemu
>> glibc rv64gcv qemu
>>
>> This patch series does not introduce any new failures.
>&g

[Committed] RISC-V: Fix ICE of RTL CHECK on VSETVL PASS[PR111947]

2023-10-23 Thread Juzhe-Zhong
ICE on vsetvli a5, 8 instruction demand info.

The AVL is const_int 8 which ICE on RENGO caller.

Committed as it is obvious fix.

PR target/111947

gcc/ChangeLog:

* config/riscv/riscv-vsetvl.cc 
(pre_vsetvl::compute_lcm_local_properties): Add REGNO check.

gcc/testsuite/ChangeLog:

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

---
 gcc/config/riscv/riscv-vsetvl.cc  | 15 +--
 .../gcc.target/riscv/rvv/vsetvl/pr111947.c| 13 +
 2 files changed, 22 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111947.c

diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 5ef0f726e4a..f2f19e423bf 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -2633,13 +2633,16 @@ pre_vsetvl::compute_lcm_local_properties ()
  if (!info.has_nonvlmax_reg_avl () && !info.has_vl ())
continue;
 
- unsigned int regno;
- sbitmap_iterator sbi;
- EXECUTE_IF_SET_IN_BITMAP (m_reg_def_loc[bb->index ()], 0, regno,
-   sbi)
+ if (info.has_nonvlmax_reg_avl ())
{
- if (regno == REGNO (info.get_avl ()))
-   bitmap_clear_bit (m_transp[bb->index ()], i);
+ unsigned int regno;
+ sbitmap_iterator sbi;
+ EXECUTE_IF_SET_IN_BITMAP (m_reg_def_loc[bb->index ()], 0,
+   regno, sbi)
+   {
+ if (regno == REGNO (info.get_avl ()))
+   bitmap_clear_bit (m_transp[bb->index ()], i);
+   }
}
 
  for (const insn_info *insn : bb->real_nondebug_insns ())
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111947.c 
b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111947.c
new file mode 100644
index 000..cea19b70e20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr111947.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O2 -Wno-implicit-int" } */
+
+char *a;
+b() {
+  int c[2];
+  int d = 0;
+  for (; d < 16; d += 2)
+c[d / 2] = a[d | 1];
+  if (c[0])
+for (;;)
+  ;
+}
-- 
2.36.3



[PATCH v25 14/33] c++: Implement __is_scoped_enum built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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

[PATCH v25 20/33] c++: Implement __is_member_object_pointer built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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

[PATCH v25 07/33] libstdc++: Optimize std::is_volatile compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_volatile
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 v25 18/33] c++: Implement __is_member_function_pointer built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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

[PATCH v25 28/33] c++: Implement __remove_pointer built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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

[PATCH v25 29/33] libstdc++: Optimize std::remove_pointer compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::remove_pointer
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 80ec0fd5475..0641ecfdf2b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2103,6 +2103,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; };
@@ -2111,11 +2117,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 v25 16/33] c++: Implement __is_member_pointer built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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



[PATCH v25 30/33] c++: Implement __is_pointer built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 444dbaacd78..9fce36e12d1 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3791,6 +3791,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 1f405f61861..05514a51c21 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, 
"__is_nothrow_convertible", 2)
 DEFTRAIT_EXPR (IS_OBJECT, "__is_object", 1)
 DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, 
"__is_pointer_interconvertible_base_of", 2)
 DEFTRAIT_EXPR (IS_POD, "__is_pod", 1)
+DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
 DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1)
 DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1)
 DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 45584e9045f..7cccbae5287 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12216,6 +12216,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_POD:
   return pod_type_p (type1);
 
+case CPTK_IS_POINTER:
+  return TYPE_PTR_P (type1);
+
 case CPTK_IS_POLYMORPHIC:
   return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
 
@@ -12418,6 +12421,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_MEMBER_OBJECT_POINTER:
 case CPTK_IS_MEMBER_POINTER:
 case CPTK_IS_OBJECT:
+case CPTK_IS_POINTER:
 case CPTK_IS_REFERENCE:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 719902d3f1a..b1430e9bd8b 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -125,6 +125,9 @@
 #if !__has_builtin (__is_pod)
 # error "__has_builtin (__is_pod) failed"
 #endif
+#if !__has_builtin (__is_pointer)
+# error "__has_builtin (__is_pointer) failed"
+#endif
 #if !__has_builtin (__is_polymorphic)
 # error "__has_builtin (__is_polymorphic) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_pointer.C 
b/gcc/testsuite/g++.dg/ext/is_pointer.C
new file mode 100644
index 000..d6e39565950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(!__is_pointer(int));
+SA(__is_pointer(int*));
+SA(__is_pointer(int**));
+
+SA(__is_pointer(const int*));
+SA(__is_pointer(const int**));
+SA(__is_pointer(int* const));
+SA(__is_pointer(int** const));
+SA(__is_pointer(int* const* const));
+
+SA(__is_pointer(volatile int*));
+SA(__is_pointer(volatile int**));
+SA(__is_pointer(int* volatile));
+SA(__is_pointer(int** volatile));
+SA(__is_pointer(int* volatile* volatile));
+
+SA(__is_pointer(const volatile int*));
+SA(__is_pointer(const volatile int**));
+SA(__is_pointer(const int* volatile));
+SA(__is_pointer(volatile int* const));
+SA(__is_pointer(int* const volatile));
+SA(__is_pointer(const int** volatile));
+SA(__is_pointer(volatile int** const));
+SA(__is_pointer(int** const volatile));
+SA(__is_pointer(int* const* const volatile));
+SA(__is_pointer(int* volatile* const volatile));
+SA(__is_pointer(int* const volatile* const volatile));
+
+SA(!__is_pointer(int&));
+SA(!__is_pointer(const int&));
+SA(!__is_pointer(volatile int&));
+SA(!__is_pointer(const volatile int&));
+
+SA(!__is_pointer(int&&));
+SA(!__is_pointer(const int&&));
+SA(!__is_pointer(volatile int&&));
+SA(!__is_pointer(const volatile int&&));
+
+SA(!__is_pointer(int[3]));
+SA(!__is_pointer(const int[3]));
+SA(!__is_pointer(volatile int[3]));
+SA(!__is_pointer(const volatile int[3]));
+
+SA(!__is_pointer(int(int)));
+SA(__is_pointer(int(*const)(int)));
+SA(__is_pointer(int(*volatile)(int)));
+SA(__is_pointer(int(*const 

[PATCH v25 32/33] c++: Implement __is_invocable built-in trait

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

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_invocable.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_INVOCABLE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
(is_invocable_p): New function.
* method.h: New file to export build_trait_object in method.cc.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_invocable.
* g++.dg/ext/is_invocable1.C: New test.
* g++.dg/ext/is_invocable2.C: New test.
* g++.dg/ext/is_invocable3.C: New test.
* g++.dg/ext/is_invocable4.C: New test.

Signed-off-by: Ken Matsui 
---
 gcc/cp/constraint.cc |   6 +
 gcc/cp/cp-trait.def  |   1 +
 gcc/cp/method.h  |  28 ++
 gcc/cp/semantics.cc  | 135 +
 gcc/testsuite/g++.dg/ext/has-builtin-1.C |   3 +
 gcc/testsuite/g++.dg/ext/is_invocable1.C | 337 +++
 gcc/testsuite/g++.dg/ext/is_invocable2.C | 139 ++
 gcc/testsuite/g++.dg/ext/is_invocable3.C |  51 
 gcc/testsuite/g++.dg/ext/is_invocable4.C |  33 +++
 9 files changed, 733 insertions(+)
 create mode 100644 gcc/cp/method.h
 create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable1.C
 create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable2.C
 create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable3.C
 create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable4.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 9fce36e12d1..29bf548d30a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3754,6 +3754,12 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_FUNCTION:
   inform (loc, "  %qT is not a function", t1);
   break;
+case CPTK_IS_INVOCABLE:
+  if (!t2)
+inform (loc, "  %qT is not invocable", t1);
+  else
+inform (loc, "  %qT is not invocable by %qE", t1, t2);
+  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 05514a51c21..b8b7608c122 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -71,6 +71,7 @@ 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_INVOCABLE, "__is_invocable", -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/method.h b/gcc/cp/method.h
new file mode 100644
index 000..1aec8ec5cfd
--- /dev/null
+++ b/gcc/cp/method.h
@@ -0,0 +1,28 @@
+/* Functions exported by method.cc.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#ifndef GCC_CP_METHOD_H
+#define GCC_CP_METHOD_H 1
+
+#include "tree.h"
+
+/* In method.cc  */
+extern tree build_trait_object (tree type);
+
+#endif  /* GCC_CP_METHOD_H  */
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 7cccbae5287..cc2e400531a 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -45,6 +45,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "gomp-constants.h"
 #include "predict.h"
 #include "memmodel.h"
+#include "method.h"
+
+#include "print-tree.h"
+#include "tree-pretty-print.h"
 
 /* There routines provide a modular interface to perform many parsing
operations.  They may therefore be used during actual parsing, or
@@ -11714,6 +11718,133 @@ classtype_has_nothrow_assign_or_copy_p (tree type, 
bool assign_p)
   return saw_copy;
 }
 
+/* Return true if FN_TYPE is invocable with the given ARG_TYPES.  */
+
+static bool
+is_invocable_p (tree fn_type, tree arg_types)
+{
+  /* ARG_TYPES must be a TREE_VEC.  */
+  gcc_assert (TREE_CODE (arg_types) == TREE_VEC);
+
+  /* Access check is required to determine if the given is invocable.  */
+  deferring_access_check_sentinel acs (dk_no_deferred);
+
+  /* std::is_invocable is an unevaluated context.  */
+  cp_unevaluated cp_uneval_guard;
+
+  bool is_ptrdatamem;
+  bool is_ptrmemfunc;
+  if (TREE_CODE (fn_type) == REFERENCE_TYPE)
+{
+  tree 

[PATCH v25 11/33] libstdc++: Optimize std::is_unbounded_array compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of
std::is_unbounded_array 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 v25 15/33] libstdc++: Optimize std::is_scoped_enum compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_scoped_enum
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



Re: [PATCH v25 00/33] Optimize type traits compilation performance

2023-10-23 Thread Ken Matsui
I accidentally sent is_invocable patches as well, but those have no changes.

On Mon, Oct 23, 2023 at 7:04 PM Ken Matsui  wrote:
>
> This patch series optimizes type traits compilation performance by
> implementing built-in type traits and using them in libstdc++.
>
> Changes in v25:
>
> * Optimized the __is_pointer implementation in cpp_type_traits.h.
> * Fix compilation error in cpp_type_traits.h with Clang 16.
> * Wrapped commit messages at 75 columns.
> * Used & instead of && for the new IDENTIFIER_TRAIT_P macro.
> * Made cp_lexer_peek_trait not to take cp_token.
> * Fixed indentation error in cp_lexer_peek_trait.
>
> Changes in v24:
>
> * Fixed the way to handle an incomplete type error from __is_invocable
> in the test cases so that we can correctly test both the use of
> built-in and vice-versa.
>
> Changes in v23:
>
> * Improved the comment in cp-tree.h.
> * Moved the definition of cp_traits to lex.cc from parser.cc.
> * Implemented __is_invocable built-in trait.
>
> Changes in v22:
>
> * Included a missing patch in v21.
>
> Changes in v21:
>
> * Used _GLIBCXX_USE_BUILTIN_TRAIT instead of __has_builtin in
> cpp_type_traits.h.
> * Added const char* name to struct cp_trait, and loop over cp_traits
> in init_cp_traits to get the name.
> * Isolated patches for integral-related built-in traits from
> this patch series since they are not ready for review yet.
> * Implemented __is_object built-in trait.
>
> Changes in v20:
>
> * Used identifier node instead of gperf to look up built-in
> traits.
>
> Changes in v19:
>
> * Fixed a typo.
> * Rebased on top of trunk.
> * Improved clarity of the commit message.
>
> Changes in v18:
>
> * Removed all RID values for built-in traits and used cik_trait
> instead.
> * Improved to handle the use of non-function-like built-in trait
> identifiers.
> * Reverted all changes to conflicted identifiers with new built-ins
> in the existing code base.
>
> Changes in v17:
>
> * Rebased on top of trunk.
> * Improved clarity of the commit message.
> * Simplified Make-lang.in.
> * Made ridpointers for RID_TRAIT_EXPR and RID_TRAIT_TYPE empty.
>
> Changes in v16:
>
> * Rebased on top of trunk.
> * Improved clarity of the commit message.
> * Simplified Make-lang.in and gperf struct.
> * Supply -k option to gperf to support older versions than 2.8.
>
> Changes in v15:
>
> * Rebased on top of trunk.
> * Use gperf to look up traits instead of enum rid.
>
> Changes in v14:
>
> * Added padding calculation to the commit message.
>
> Changes in v13:
>
> * Fixed ambiguous commit message and comment.
>
> Changes in v12:
>
> * Evaluated all paddings affected by the enum rid change.
>
> Changes in v11:
>
> * Merged all patches into one patch series.
> * Rebased on top of trunk.
> * Unified commit message style.
> * Used _GLIBCXX_USE_BUILTIN_TRAIT.
>
> Ken Matsui (33):
>   c++: Sort built-in traits alphabetically
>   c-family, c++: Look up built-in traits via identifier node
>   c++: Accept the use of built-in trait identifiers
>   c++: Implement __is_const built-in trait
>   libstdc++: Optimize std::is_const compilation performance
>   c++: Implement __is_volatile built-in trait
>   libstdc++: Optimize std::is_volatile compilation performance
>   c++: Implement __is_array built-in trait
>   libstdc++: Optimize std::is_array compilation performance
>   c++: Implement __is_unbounded_array built-in trait
>   libstdc++: Optimize std::is_unbounded_array compilation performance
>   c++: Implement __is_bounded_array built-in trait
>   libstdc++: Optimize std::is_bounded_array compilation performance
>   c++: Implement __is_scoped_enum built-in trait
>   libstdc++: Optimize std::is_scoped_enum compilation performance
>   c++: Implement __is_member_pointer built-in trait
>   libstdc++: Optimize std::is_member_pointer compilation performance
>   c++: Implement __is_member_function_pointer built-in trait
>   libstdc++: Optimize std::is_member_function_pointer compilation
> performance
>   c++: Implement __is_member_object_pointer built-in trait
>   libstdc++: Optimize std::is_member_object_pointer compilation
> performance
>   c++: Implement __is_reference built-in trait
>   libstdc++: Optimize std::is_reference compilation performance
>   c++: Implement __is_function built-in trait
>   libstdc++: Optimize std::is_function compilation performance
>   c++: Implement __is_object built-in trait
>   libstdc++: Optimize std::is_object compilation performance
>   c++: Implement __remove_pointer built-in trait
>   libstdc++: Optimize std::remove_pointer compilation performance
>   c++: Implement __is_pointer built-in trait
>  

[PATCH v25 24/33] c++: Implement __is_function built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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

[PATCH v25 31/33] libstdc++: Optimize std::is_pointer compilation performance

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

libstdc++-v3/ChangeLog:

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

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

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 4312f32a4e0..c348df97f72 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 _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
+  template
+struct __is_pointer : __truth_type<_IsPtr>
+{
+  enum { __value = _IsPtr };
+};
+#else
   template
 struct __is_pointer
 {
@@ -377,6 +384,28 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   typedef __true_type __type;
 };
 
+  template
+struct __is_pointer<_Tp* const>
+{
+  enum { __value = 1 };
+  typedef __true_type __type;
+};
+
+  template
+struct __is_pointer<_Tp* volatile>
+{
+  enum { __value = 1 };
+  typedef __true_type __type;
+};
+#endif
+
+  template
+struct __is_pointer<_Tp* const volatile>
+{
+  enum { __value = 1 };
+  typedef __true_type __type;
+};
+
   //
   // 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 0641ecfdf2b..75a94cb8d7e 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
@@ -3252,8 +3266,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 v25 06/33] c++: Implement __is_volatile built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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



[PATCH v25 13/33] libstdc++: Optimize std::is_bounded_array compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_bounded_array
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 v25 33/33] libstdc++: Optimize std::is_invocable compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_invocable
by dispatching to the new __is_invocable built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_invocable): Use __is_invocable
built-in trait.
* testsuite/20_util/is_invocable/incomplete_args_neg.cc: Handle
the new error from __is_invocable.
* testsuite/20_util/is_invocable/incomplete_neg.cc: Likewise.

Signed-off-by: Ken Matsui 
---
 libstdc++-v3/include/std/type_traits| 6 ++
 .../testsuite/20_util/is_invocable/incomplete_args_neg.cc   | 1 +
 .../testsuite/20_util/is_invocable/incomplete_neg.cc| 1 +
 3 files changed, 8 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 75a94cb8d7e..91851b78c7e 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3167,9 +3167,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
 
   /// std::is_invocable
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
+  template
+struct is_invocable
+: public __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
+#else
   template
 struct is_invocable
 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
+#endif
 {
   static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
"_Fn must be a complete class or an unbounded array");
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc 
b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
index 34d1d9431d1..3f9e5274f3c 100644
--- a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
@@ -18,6 +18,7 @@
 // .
 
 // { dg-error "must be a complete class" "" { target *-*-* } 0 }
+// { dg-prune-output "invalid use of incomplete type" }
 
 #include 
 
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc 
b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
index e1e54d25ee5..92af48c48b6 100644
--- a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
@@ -18,6 +18,7 @@
 // .
 
 // { dg-error "must be a complete class" "" { target *-*-* } 0 }
+// { dg-prune-output "invalid use of incomplete type" }
 
 #include 
 
-- 
2.42.0



[PATCH v25 09/33] libstdc++: Optimize std::is_array compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_array
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 v25 17/33] libstdc++: Optimize std::is_member_pointer compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_member_pointer
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 v25 25/33] libstdc++: Optimize std::is_function compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_function
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.
(is_const_v): Move on top of is_function_v as is_function_v now
depends on is_const_v.

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

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 36ad9814047..1e561c8ea38 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,28 @@ 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_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_function_v = is_function<_Tp>::value;
+  inline constexpr bool is_const_v = true;
+#endif
+
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
+template 
+  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 
@@ -3303,16 +3330,6 @@ template 
   inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
 #endif
 
-#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
-
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
 template 
   inline constexpr bool is_volatile_v = __is_volatile(_Tp);
-- 
2.42.0



[PATCH v25 27/33] libstdc++: Optimize std::is_object compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_object
by dispatching to the new __is_object built-in trait.

libstdc++-v3/ChangeLog:
* include/std/type_traits (is_object): Use __is_object built-in
trait.
(is_object_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 1e561c8ea38..80ec0fd5475 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -725,11 +725,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
   /// is_object
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object)
+  template
+struct is_object
+: public __bool_constant<__is_object(_Tp)>
+{ };
+#else
   template
 struct is_object
 : public __not_<__or_, is_reference<_Tp>,
   is_void<_Tp>>>::type
 { };
+#endif
 
   template
 struct is_member_pointer;
@@ -3315,8 +3322,15 @@ 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_object)
+template 
+  inline constexpr bool is_object_v = __is_object(_Tp);
+#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 v25 26/33] c++: Implement __is_object built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c394657d6b9..444dbaacd78 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_NOTHROW_CONVERTIBLE:
  inform (loc, "  %qT is not nothrow convertible from %qE", t2, t1);
   break;
+case CPTK_IS_OBJECT:
+  inform (loc, "  %qT is not an object type", t1);
+  break;
 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
   inform (loc, "  %qT is not pointer-interconvertible base of %qT",
  t1, t2);
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index fa79bc0c68c..191a86307fc 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -79,6 +79,7 @@ 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)
+DEFTRAIT_EXPR (IS_OBJECT, "__is_object", 1)
 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)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8118d3104c7..e3f71ff5902 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12205,6 +12205,11 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
 case CPTK_IS_NOTHROW_CONVERTIBLE:
   return is_nothrow_convertible (type1, type2);
 
+case CPTK_IS_OBJECT:
+  return (type_code1 != FUNCTION_TYPE
+ && type_code1 != REFERENCE_TYPE
+ && type_code1 != VOID_TYPE);
+
 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
   return pointer_interconvertible_base_of_p (type1, type2);
 
@@ -12412,6 +12417,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, 
tree type1, tree type2)
 case CPTK_IS_MEMBER_FUNCTION_POINTER:
 case CPTK_IS_MEMBER_OBJECT_POINTER:
 case CPTK_IS_MEMBER_POINTER:
+case CPTK_IS_OBJECT:
 case CPTK_IS_REFERENCE:
 case CPTK_IS_SAME:
 case CPTK_IS_SCOPED_ENUM:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index 4d3947572a4..163be1d710b 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -116,6 +116,9 @@
 #if !__has_builtin (__is_nothrow_convertible)
 # error "__has_builtin (__is_nothrow_convertible) failed"
 #endif
+#if !__has_builtin (__is_object)
+# error "__has_builtin (__is_object) failed"
+#endif
 #if !__has_builtin (__is_pointer_interconvertible_base_of)
 # error "__has_builtin (__is_pointer_interconvertible_base_of) failed"
 #endif
diff --git a/gcc/testsuite/g++.dg/ext/is_object.C 
b/gcc/testsuite/g++.dg/ext/is_object.C
new file mode 100644
index 000..5c759a5ef69
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_object.C
@@ -0,0 +1,29 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_NON_VOLATILE(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT)
+
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+SA_TEST_NON_VOLATILE(__is_object, int (int), false);
+SA_TEST_NON_VOLATILE(__is_object, ClassType (ClassType), false);
+SA_TEST_NON_VOLATILE(__is_object,
+float (int, float, int[], int&), false);
+SA_TEST_CATEGORY(__is_object, int&, false);
+SA_TEST_CATEGORY(__is_object, ClassType&, false);
+SA_TEST_NON_VOLATILE(__is_object, int(&)(int), false);
+SA_TEST_CATEGORY(__is_object, void, false);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_object, ClassType, true);
-- 
2.42.0



[PATCH v25 21/33] libstdc++: Optimize std::is_member_object_pointer compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of
std::is_member_object_pointer 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 v25 12/33] c++: Implement __is_bounded_array built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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

[PATCH v25 19/33] libstdc++: Optimize std::is_member_function_pointer compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of
std::is_member_function_pointer 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 v25 10/33] c++: Implement __is_unbounded_array built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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

[PATCH v25 22/33] c++: Implement __is_reference built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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



[PATCH v25 08/33] c++: Implement __is_array built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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



[PATCH v25 01/33] c++: Sort built-in traits alphabetically

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 64b64e17857..41fe2812ac4 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3703,18 +3703,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;
@@ -3730,6 +3748,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);
@@ -3749,50 +3779,20 @@ diagnose_trait_expr (tree expr, tree args)
 case CPTK_IS_TRIVIAL:
   inform (loc, "  %qT is not a trivial type", t1);
   break;
-case CPTK_IS_UNION:
-  inform (loc, "  %qT is not a union", t1);
-  break;
-case CPTK_IS_AGGREGATE:
-  inform (loc, "  %qT is not an aggregate", t1);
-  break;
-case CPTK_IS_TRIVIALLY_COPYABLE:
-  inform (loc, "  %qT is not trivially copyable", t1);
-  break;
-case CPTK_IS_ASSIGNABLE:
-  inform (loc, "  %qT is not assignable from %qT", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
   inform (loc, "  %qT is not trivially assignable from %qT", t1, t2);
   break;
-case CPTK_IS_NOTHROW_ASSIGNABLE:
-  inform (loc, "  %qT is not nothrow assignable from %qT", t1, t2);
-  break;
-case CPTK_IS_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not default constructible", t1);
-  else
-   inform (loc, "  %qT is not constructible from %qE", t1, t2);
-  break;
 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
   if (!t2)
inform (loc, "  %qT is not trivially default constructible", t1);
   else
inform (loc, "  %qT is not trivially constructible from %qE", t1, t2);
   break;
-case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
-  if (!t2)
-   inform (loc, "  %qT is not nothrow default constructible", t1);
-  else
-   inform (loc, "  %qT is not nothrow constructible from %qE", t1, t2);
-  break;
-case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
-  inform (loc, "  %qT does not have unique object representations", t1);
-  break;
-case CPTK_IS_CONVERTIBLE:
-  inform (loc, "  %qT is not convertible from %qE", t2, t1);
+case CPTK_IS_TRIVIALLY_COPYABLE:
+  inform (loc, "  %qT is not trivially copyable", t1);
   break;
-case CPTK_IS_NOTHROW_CONVERTIBLE:
-   

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

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

gcc/cp/ChangeLog:

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

Signed-off-by: Ken Matsui 
---
 gcc/cp/parser.cc | 53 +++-
 1 file changed, 34 insertions(+), 19 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index f87d4c0a855..ed48ddfde17 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -246,12 +246,12 @@ static void cp_lexer_start_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
 static void cp_lexer_stop_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
-static const cp_trait *cp_lexer_lookup_trait
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_expr
-  (const cp_token *);
-static const cp_trait *cp_lexer_lookup_trait_type
-  (const cp_token *);
+static const cp_trait *cp_lexer_peek_trait
+  (cp_lexer *);
+static const cp_trait *cp_lexer_peek_trait_expr
+  (cp_lexer *);
+static const cp_trait *cp_lexer_peek_trait_type
+  (cp_lexer *);
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
@@ -1182,15 +1182,29 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
 }
 }
 
-/* Look ups the corresponding built-in trait if a given token is
-   a built-in trait.  Otherwise, returns nullptr.  */
+/* Peeks the corresponding built-in trait if the first token is
+   a built-in trait and the second token is either `(' or `<' depending
+   on the trait.  Otherwise, returns nullptr.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait (const cp_token *token)
+cp_lexer_peek_trait (cp_lexer *lexer)
 {
-  if (token->type == CPP_NAME && IDENTIFIER_TRAIT_P (token->u.value))
-return _traits[IDENTIFIER_CP_INDEX (token->u.value)];
+  const cp_token *token1 = cp_lexer_peek_token (lexer);
+  if (token1->type == CPP_NAME && IDENTIFIER_TRAIT_P (token1->u.value))
+{
+  const cp_trait  = cp_traits[IDENTIFIER_CP_INDEX (token1->u.value)];
+  const bool is_pack_element = (trait.kind == CPTK_TYPE_PACK_ELEMENT);
+
+  /* Check if the subsequent token is a `<' token to
+__type_pack_element or is a `(' token to everything else.  */
+  const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
+  if (is_pack_element && token2->type != CPP_LESS)
+   return nullptr;
+  if (!is_pack_element && token2->type != CPP_OPEN_PAREN)
+   return nullptr;
 
+  return 
+}
   return nullptr;
 }
 
@@ -1198,9 +1212,9 @@ cp_lexer_lookup_trait (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_expr (const cp_token *token)
+cp_lexer_peek_trait_expr (cp_lexer *lexer)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer);
   if (trait && !trait->type)
 return trait;
 
@@ -1211,9 +1225,9 @@ cp_lexer_lookup_trait_expr (const cp_token *token)
built-in trait.  */
 
 static const cp_trait *
-cp_lexer_lookup_trait_type (const cp_token *token)
+cp_lexer_peek_trait_type (cp_lexer *lexer)
 {
-  const cp_trait *trait = cp_lexer_lookup_trait (token);
+  const cp_trait *trait = cp_lexer_peek_trait (lexer);
   if (trait && trait->type)
 return trait;
 
@@ -1227,9 +1241,10 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer 
*lexer)
 {
   cp_token *token;
 
-  token = cp_lexer_peek_token (lexer);
-  if (cp_lexer_lookup_trait_type (token))
+  if (cp_lexer_peek_trait_type (lexer))
 return true;
+
+  token = cp_lexer_peek_token (lexer);
   return cp_keyword_starts_decl_specifier_p (token->keyword);
 }
 
@@ -6107,7 +6122,7 @@ cp_parser_primary_expression (cp_parser *parser,
 `::' as the beginning of a qualified-id, or the "operator"
 keyword.  */
 case CPP_NAME:
-  if (const cp_trait* trait = cp_lexer_lookup_trait_expr (token))
+  if (const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer))
return cp_parser_trait (parser, trait);
   /* FALLTHRU */
 case CPP_SCOPE:
@@ -20116,7 +20131,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 }
 
   /* If token is a type-yielding built-in traits, parse it.  

[PATCH v25 23/33] libstdc++: Optimize std::is_reference compilation performance

2023-10-23 Thread Ken Matsui
This patch optimizes the compilation performance of std::is_reference
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 v25 04/33] c++: Implement __is_const built-in trait

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

gcc/cp/ChangeLog:

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

gcc/testsuite/ChangeLog:

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

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

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



[PATCH v25 05/33] libstdc++: Optimize std::is_const compilation performance

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

libstdc++-v3/ChangeLog:

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

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

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



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

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

gcc/c-family/ChangeLog:

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

gcc/cp/ChangeLog:

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

Co-authored-by: Patrick Palka 
Signed-off-by: Ken Matsui 
---
 gcc/c-family/c-common.cc  |   7 ---
 gcc/c-family/c-common.h   |   5 --
 gcc/cp/cp-objcp-common.cc |   8 +--
 gcc/cp/cp-tree.h  |  32 +---
 gcc/cp/lex.cc |  34 
 gcc/cp/parser.cc  | 105 +++---
 6 files changed, 126 insertions(+), 65 deletions(-)

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

[PATCH v25 00/33] Optimize type traits compilation performance

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

Changes in v25:

* Optimized the __is_pointer implementation in cpp_type_traits.h.
* Fix compilation error in cpp_type_traits.h with Clang 16.
* Wrapped commit messages at 75 columns.
* Used & instead of && for the new IDENTIFIER_TRAIT_P macro.
* Made cp_lexer_peek_trait not to take cp_token.
* Fixed indentation error in cp_lexer_peek_trait.

Changes in v24:

* Fixed the way to handle an incomplete type error from __is_invocable
in the test cases so that we can correctly test both the use of
built-in and vice-versa.

Changes in v23:

* Improved the comment in cp-tree.h.
* Moved the definition of cp_traits to lex.cc from parser.cc.
* Implemented __is_invocable built-in trait.

Changes in v22:

* Included a missing patch in v21.

Changes in v21:

* Used _GLIBCXX_USE_BUILTIN_TRAIT instead of __has_builtin in
cpp_type_traits.h.
* Added const char* name to struct cp_trait, and loop over cp_traits
in init_cp_traits to get the name.
* Isolated patches for integral-related built-in traits from
this patch series since they are not ready for review yet.
* Implemented __is_object built-in trait.

Changes in v20:

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

Changes in v19:

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

Changes in v18:

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

Changes in v17:

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

Changes in v16:

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

Changes in v15:

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

Changes in v14:

* Added padding calculation to the commit message.

Changes in v13:

* Fixed ambiguous commit message and comment.

Changes in v12:

* Evaluated all paddings affected by the enum rid change.

Changes in v11:

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

Ken Matsui (33):
  c++: Sort built-in traits alphabetically
  c-family, c++: Look up built-in traits via identifier node
  c++: Accept the use of built-in trait identifiers
  c++: Implement __is_const built-in trait
  libstdc++: Optimize std::is_const compilation performance
  c++: Implement __is_volatile built-in trait
  libstdc++: Optimize std::is_volatile compilation performance
  c++: Implement __is_array built-in trait
  libstdc++: Optimize std::is_array compilation performance
  c++: Implement __is_unbounded_array built-in trait
  libstdc++: Optimize std::is_unbounded_array compilation performance
  c++: Implement __is_bounded_array built-in trait
  libstdc++: Optimize std::is_bounded_array compilation performance
  c++: Implement __is_scoped_enum built-in trait
  libstdc++: Optimize std::is_scoped_enum compilation performance
  c++: Implement __is_member_pointer built-in trait
  libstdc++: Optimize std::is_member_pointer compilation performance
  c++: Implement __is_member_function_pointer built-in trait
  libstdc++: Optimize std::is_member_function_pointer compilation
performance
  c++: Implement __is_member_object_pointer built-in trait
  libstdc++: Optimize std::is_member_object_pointer compilation
performance
  c++: Implement __is_reference built-in trait
  libstdc++: Optimize std::is_reference compilation performance
  c++: Implement __is_function built-in trait
  libstdc++: Optimize std::is_function compilation performance
  c++: Implement __is_object built-in trait
  libstdc++: Optimize std::is_object compilation performance
  c++: Implement __remove_pointer built-in trait
  libstdc++: Optimize std::remove_pointer compilation performance
  c++: Implement __is_pointer built-in trait
  libstdc++: Optimize std::is_pointer compilation performance
  c++: Implement __is_invocable built-in trait
  libstdc++: Optimize std::is_invocable compilation performance

 gcc/c-family/c-common.cc  |   7 -
 gcc/c-family/c-common.h   |   5 -
 gcc/cp/constraint.cc  | 109 --
 

Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

2023-10-23 Thread Patrick O'Neill

IIRC --enable-checking=yes does not turn on RTL checking.
You need to pass in rtl explicitly using --enable-checking=rtl
You can also pass in a list of checks like this: --enable-checking=yes,rtl

Patrick

On 10/23/23 17:51, juzhe.zh...@rivai.ai wrote:

I don't have such issue:

[jzzhong@rios-cad121:/work/home/jzzhong/work/insn]$~/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/bin/riscv64-unknown-elf-gcc 
-v

Using built-in specs.
COLLECT_GCC=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/bin/riscv64-unknown-elf-gcc
COLLECT_LTO_WRAPPER=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/libexec/gcc/riscv64-unknown-elf/14.0.0/lto-wrapper
Target: riscv64-unknown-elf
Configured with: 
/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/../../gcc/configure 
--target=riscv64-unknown-elf 
--prefix=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install 
--disable-shared --disable-threads --enable-languages=c,c++ 
--with-pkgversion=g70b66ac9bcb-dirty --with-system-zlib --enable-tls 
--with-newlib 
--with-sysroot=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/riscv64-unknown-elf 
--with-native-system-header-dir=/include --disable-libmudflap 
--disable-libssp --disable-libquadmath --disable-libgomp --disable-nls 
--disable-tm-clone-registry --src=../../../gcc --enable-checking=yes 
--disable-multilib --with-abi=lp64d --with-arch=rv64gcv_zfh_zvfh 
--with-tune=rocket --with-isa-spec=20191213 CFLAGS='-O0 -g3' 
CXXFLAGS='-O0 -g3' 'CFLAGS_FOR_TARGET=-Os    -mcmodel=medany' 
'CXXFLAGS_FOR_TARGET=-Os    -mcmodel=medany'

Thread model: single
Supported LTO compression algorithms: zlib
gcc version 14.0.0 20231023 (experimental) (g70b66ac9bcb-dirty)



juzhe.zh...@rivai.ai

*From:* Patrick O'Neill <mailto:patr...@rivosinc.com>
*Date:* 2023-10-24 07:42
*To:* 钟居哲 <mailto:juzhe.zh...@rivai.ai>; 丁乐华
<mailto:lehua.d...@rivai.ai>
*CC:* kito.cheng <mailto:kito.ch...@gmail.com>; rdapp.gcc
<mailto:rdapp@gmail.com>; palmer <mailto:pal...@rivosinc.com>;
Jeff Law <mailto:jeffreya...@gmail.com>; gcc-patches
<mailto:gcc-patches@gcc.gnu.org>
*Subject:* Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

When configuring, pass in --enable-checking=rtl
If you're using riscv-gnu-toolchain, pass in --enable-gcc-checking=rtl

The -freport-bug output attached to the bug report has the full
configure command used:
/scratch/tc-testing/tc-trunk/build-rtl-checking/../gcc/configure
--target=riscv64-unknown-linux-gnu
--prefix=/scratch/tc-testing/tc-trunk/build-rtl-checking
--with-sysroot=/scratch/tc-testing/tc-trunk/build-rtl-checking/sysroot
--with-newlib --without-headers --disable-shared --disable-threads
--with-system-zlib --enable-tls --enable-languages=c
--disable-libatomic --disable-libmudflap --disable-libssp
--disable-libquadmath --disable-libgomp --disable-nls
--disable-bootstrap --src=../../gcc --enable-checking=rtl
--disable-multilib --with-abi=lp64d --with-arch=rv64gcv
--with-tune=rocket --with-isa-spec=20191213
'CFLAGS_FOR_TARGET=-O2    -mcmodel=medlow'
'CXXFLAGS_FOR_TARGET=-O2    -mcmodel=medlow'

On 10/23/23 15:50, 钟居哲 wrote:

I didn't reproduce it. How to enable RTL checking ?


juzhe.zh...@rivai.ai

*From:* Patrick O'Neill <mailto:patr...@rivosinc.com>
*Date:* 2023-10-24 06:46
*To:* 钟居哲 <mailto:juzhe.zh...@rivai.ai>; 丁乐华
<mailto:lehua.d...@rivai.ai>
*CC:* kito.cheng <mailto:kito.ch...@gmail.com>; rdapp.gcc
<mailto:rdapp@gmail.com>; palmer
<mailto:pal...@rivosinc.com>; Jeff Law
<mailto:jeffreya...@gmail.com>; gcc-patches
<mailto:gcc-patches@gcc.gnu.org>
*Subject:* Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

You're on top of it - thanks for fixing this! I'll send the
testcase.

Unrelated to this failure, I'm seeing a build failure on
glibc rv32/64gcv when RTL checking is enabled.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111947

Thanks,
Patrick

On 10/23/23 14:41, 钟居哲 wrote:

I have fixed it:

https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0c4bd1321a6def5eb44c530e83b01a415633b660

Plz verify it and send a patch with testcase pr111941.c if
you confirm it has been fixed on the trunk.

Thanks.
---

Re: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

2023-10-23 Thread juzhe.zh...@rivai.ai
I don't have such issue:

[jzzhong@rios-cad121:/work/home/jzzhong/work/insn]$~/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/bin/riscv64-unknown-elf-gcc
 -v
Using built-in specs.
COLLECT_GCC=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/bin/riscv64-unknown-elf-gcc
COLLECT_LTO_WRAPPER=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/libexec/gcc/riscv64-unknown-elf/14.0.0/lto-wrapper
Target: riscv64-unknown-elf
Configured with: 
/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/../../gcc/configure
 --target=riscv64-unknown-elf 
--prefix=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install
 --disable-shared --disable-threads --enable-languages=c,c++ 
--with-pkgversion=g70b66ac9bcb-dirty --with-system-zlib --enable-tls 
--with-newlib 
--with-sysroot=/work/home/jzzhong/work/toolchain/riscv/build/dev-rv64gcv_zfh_zvfh-lp64d-medany-newlib-spike-debug/install/riscv64-unknown-elf
 --with-native-system-header-dir=/include --disable-libmudflap --disable-libssp 
--disable-libquadmath --disable-libgomp --disable-nls 
--disable-tm-clone-registry --src=../../../gcc --enable-checking=yes 
--disable-multilib --with-abi=lp64d --with-arch=rv64gcv_zfh_zvfh 
--with-tune=rocket --with-isa-spec=20191213 CFLAGS='-O0 -g3' CXXFLAGS='-O0 -g3' 
'CFLAGS_FOR_TARGET=-Os-mcmodel=medany' 'CXXFLAGS_FOR_TARGET=-Os
-mcmodel=medany'
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 14.0.0 20231023 (experimental) (g70b66ac9bcb-dirty)




juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 07:42
To: 钟居哲; 丁乐华
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
When configuring, pass in --enable-checking=rtl
If you're using riscv-gnu-toolchain, pass in --enable-gcc-checking=rtl

The -freport-bug output attached to the bug report has the full configure 
command used:
/scratch/tc-testing/tc-trunk/build-rtl-checking/../gcc/configure 
--target=riscv64-unknown-linux-gnu 
--prefix=/scratch/tc-testing/tc-trunk/build-rtl-checking 
--with-sysroot=/scratch/tc-testing/tc-trunk/build-rtl-checking/sysroot 
--with-newlib --without-headers --disable-shared --disable-threads 
--with-system-zlib --enable-tls --enable-languages=c --disable-libatomic 
--disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp 
--disable-nls --disable-bootstrap --src=../../gcc --enable-checking=rtl 
--disable-multilib --with-abi=lp64d --with-arch=rv64gcv --with-tune=rocket 
--with-isa-spec=20191213 'CFLAGS_FOR_TARGET=-O2-mcmodel=medlow' 
'CXXFLAGS_FOR_TARGET=-O2-mcmodel=medlow'

On 10/23/23 15:50, 钟居哲 wrote:
I didn't reproduce it. How to enable RTL checking ?



juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 06:46
To: 钟居哲; 丁乐华
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
You're on top of it - thanks for fixing this! I'll send the testcase.

Unrelated to this failure, I'm seeing a build failure on glibc rv32/64gcv when 
RTL checking is enabled.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111947

Thanks,
Patrick
On 10/23/23 14:41, 钟居哲 wrote:
I have fixed it: 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0c4bd1321a6def5eb44c530e83b01a415633b660

Plz verify it and send a patch with testcase pr111941.c if you confirm it has 
been fixed on the trunk.

Thanks.


juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 02:30
To: Lehua Ding
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches; 钟居哲
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
Hi Lehua,
 
This patch causes a build failure with newlib 4.1.0 with -march=rv64gv_zbb.
 
I've creduced the failure here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111941
 
Thanks,
Patrick
 
On 10/19/23 20:58, Lehua Ding wrote:
> Committed, thanks Patrick and Juzhe.
>
> On 2023/10/20 2:04, Patrick O'Neill wrote:
>> I tested it this morning on my machine and it passed!
>>
>> Tested against:
>> 04d6c74564b7eb51660a00b35353aeab706b5a50
>>
>> Using targets:
>> glibc rv32gcv qemu
>> glibc rv64gcv qemu
>>
>> This patch series does not introduce any new failures.
>>
>> Here's a list of *resolved* failures by this patch series:
>> rv64gcv:
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g  execution test
>>
>> rv32gcv:
>> FAIL: gcc.target/riscv/rvv/autovec/binop/narrow_run-1.c execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 
>> -f

RE: [PATCH v4] libgfortran: Replace mutex with rwlock

2023-10-23 Thread Zhu, Lipeng
> 
> Hi Lipeng,
> 
> >>> Sure, as your comments, in the patch V6, I added 3 test cases with
> >>> OpenMP to test different cases in concurrency respectively:
> >>> 1. find and create unit very frequently to stress read lock and write 
> >>> lock.
> >>> 2. only access the unit which exist in cache to stress read lock.
> >>> 3. access the same unit in concurrency.
> >>> For the third test case, it also help to find a bug:  When unit
> >>> can't be found in cache nor unit list in read phase, then threads
> >>> will try to acquire write lock to insert the same unit, this will
> >>> cause duplicate key
> >> error.
> >>> To fix this bug, I get the unit from unit list once again before
> >>> insert in write
> >> lock.
> >>> More details you can refer the patch v6.
> >>>
> >>
> >> Could you help to review this update? I really appreciate your assistance.
> >>
> 
> > Could you help to review this update?  Any concern will be appreciated.
> 
> Fortran parts are OK (I think I wrote that already), we need somebody for the
> non-Fortran parts.
> 
Hi Thomas,

Thanks for your response. Very appreciate for your patience and help.

> Jakub, could you maybe take a look?
> 
> Best regards
> 
>   Thomas

Hi Jakub,

Can you help to take a look at the change for libgcc part that added 
several rwlock macros in libgcc/gthr-posix.h?

Best Regards,
Lipeng Zhu


[PATCH v2 3/3] c++: note other candidates when diagnosing deletedness

2023-10-23 Thread Patrick Palka
With the previous two patches in place, we can now extend our
deletedness diagnostic to note the other considered candidates, e.g.:

  deleted16.C: In function 'int main()':
  deleted16.C:10:4: error: use of deleted function 'void f(int)'
 10 |   f(0);
|   ~^~~
  deleted16.C:5:6: note: declared here
  5 | void f(int) = delete;
|  ^
  deleted16.C:5:6: note: candidate: 'void f(int)' (deleted)
  deleted16.C:6:6: note: candidate: 'void f(...)'
  6 | void f(...);
|  ^
  deleted16.C:7:6: note: candidate: 'void f(int, int)'
  7 | void f(int, int);
|  ^
  deleted16.C:7:6: note:   candidate expects 2 arguments, 1 provided

For now, these these notes are disabled when a deleted special member
function is selected because it introduces a lot of new "cannot bind
reference" errors in the testsuite when noting non-viable candidates,
e.g. in cpp0x/initlist-opt1.C we would need to expect an error when
noting unviability of A(A&&).  (It'd be nice if we could downgrade such
errors into notes when noting candidates...)

gcc/cp/ChangeLog:

* call.cc (build_over_call): Call print_z_candidates when
diagnosing deletedness.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/deleted16.C: New test.
---
 gcc/cp/call.cc | 10 +-
 gcc/testsuite/g++.dg/cpp0x/deleted16.C | 24 
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/deleted16.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 3212d5268e0..1313d6516bd 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9932,7 +9932,15 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
   if (DECL_DELETED_FN (fn))
 {
   if (complain & tf_error)
-   mark_used (fn);
+   {
+ mark_used (fn);
+ /* Note the other candidates we considered unless we selected a
+special member function since the mismatch reasons for other
+candidates are usually uninteresting, e.g. rvalue vs lvalue
+reference binding .  */
+ if (cand->next && !special_memfn_p (fn))
+   print_z_candidates (input_location, cand, /*only_viable_p=*/false);
+   }
   return error_mark_node;
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted16.C 
b/gcc/testsuite/g++.dg/cpp0x/deleted16.C
new file mode 100644
index 000..55acbfd9188
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/deleted16.C
@@ -0,0 +1,24 @@
+// Verify we note other candidates when a deleted function is
+// selected by overload resolution.
+// { dg-do compile { target c++11 } }
+
+void f(int) = delete; // { dg-message "declared here|candidate" }
+void f(...); // { dg-message "candidate" }
+void f(int, int); // { dg-message "candidate" }
+
+// An example where the perfect candidate optimization causes us
+// to ignore function templates.
+void g(int) = delete; // { dg-message "declared here|candidate" }
+template void g(T); // { dg-message "candidate" }
+
+// An example where we have a strictly viable candidate and
+// an incompletely considered bad candidate.
+template void h(T, T) = delete; // { dg-message "declared 
here|candidate" }
+void h(int*, int) = delete; // { dg-message "candidate" }
+
+int main() {
+  f(0); // { dg-error "deleted" }
+  g(0); // { dg-error "deleted" }
+  h(1, 1); // { dg-error "deleted" }
+   // { dg-error "invalid conversion" "" { target *-*-* } .-1 } when 
noting 2nd cand
+}
-- 
2.42.0.424.gceadf0f3cf



[PATCH v2 2/3] c++: remember candidates that we ignored

2023-10-23 Thread Patrick Palka
During overload resolution, we sometimes outright ignore a function from
the overload set and leave no trace of it in the candidates list, for
example when we find a perfect non-template candidate we discard all
function templates, or when the callee is a template-id we discard all
non-template functions.  We should still however make note of these
unviable functions when diagnosing overload resolution failure, but
that's not possible if they're not present in the returned candidates
list.

To that end, this patch reworks add_candidates to add such ignored
functions to the list.  The new rr_ignored rejection reason is somewhat
of a catch-all; we could perhaps split it up into more specific rejection
reasons, but I leave that as future work.

gcc/cp/ChangeLog:

* call.cc (enum rejection_reason_code): Add rr_ignored.
(add_ignored_candidate): Define.
(ignored_candidate_p): Define.
(add_template_candidate_real): Do add_ignored_candidate
instead of returning NULL.
(splice_viable): Put ignored (unviable) candidates last.
(print_z_candidate): Handle ignored candidates.
(build_new_function_call): Refine shortcut that calls
cp_build_function_call_vec now that non-templates can
appear in the candidate list for a template-id call.
(add_candidates): Replace 'bad_fns' overload with 'bad_cands'
candidate list.  When not considering a candidate, add it
to the list as an ignored candidate.  Add all 'bad_cands'
to the overload set as well.

gcc/testsuite/ChangeLog:

* g++.dg/diagnostic/param-type-mismatch-2.C: Rename template
function test_7 that accidentally (perhaps) shares the same
name as its non-template callee.
* g++.dg/overload/error6.C: New test.
---
 gcc/cp/call.cc| 149 +-
 .../g++.dg/diagnostic/param-type-mismatch-2.C |  20 +--
 gcc/testsuite/g++.dg/overload/error6.C|   9 ++
 3 files changed, 132 insertions(+), 46 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/overload/error6.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 89d422f7220..3212d5268e0 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -441,7 +441,8 @@ enum rejection_reason_code {
   rr_template_unification,
   rr_invalid_copy,
   rr_inherited_ctor,
-  rr_constraint_failure
+  rr_constraint_failure,
+  rr_ignored,
 };
 
 struct conversion_info {
@@ -2224,6 +2225,34 @@ add_candidate (struct z_candidate **candidates,
   return cand;
 }
 
+/* FN is a function from the overload set that we outright didn't even consider
+   (for some reason); add it to the list as an unviable "ignored" candidate.  
*/
+
+static z_candidate *
+add_ignored_candidate (z_candidate **candidates, tree fn)
+{
+  /* No need to dynamically allocate these.  */
+  static const rejection_reason reason_ignored = { rr_ignored, {} };
+
+  struct z_candidate *cand = (struct z_candidate *)
+conversion_obstack_alloc (sizeof (struct z_candidate));
+
+  cand->fn = fn;
+  cand->reason = const_cast (_ignored);
+  cand->next = *candidates;
+  *candidates = cand;
+
+  return cand;
+}
+
+/* True iff CAND is a candidate added by add_ignored_candidate.  */
+
+static bool
+ignored_candidate_p (const z_candidate *cand)
+{
+  return cand->reason && cand->reason->code == rr_ignored;
+}
+
 /* Return the number of remaining arguments in the parameter list
beginning with ARG.  */
 
@@ -3471,7 +3500,7 @@ add_template_candidate_real (struct z_candidate 
**candidates, tree tmpl,
 }
 
   if (len < skip_without_in_chrg)
-return NULL;
+return add_ignored_candidate (candidates, tmpl);
 
   if (DECL_CONSTRUCTOR_P (tmpl) && nargs == 2
   && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (first_arg),
@@ -3609,7 +3638,7 @@ add_template_candidate_real (struct z_candidate 
**candidates, tree tmpl,
   if (((flags & (LOOKUP_ONLYCONVERTING|LOOKUP_LIST_INIT_CTOR))
== LOOKUP_ONLYCONVERTING)
   && DECL_NONCONVERTING_P (fn))
-return NULL;
+return add_ignored_candidate (candidates, fn);
 
   if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
 {
@@ -3724,6 +3753,9 @@ splice_viable (struct z_candidate *cands,
   z_candidate *unviable = nullptr;
   z_candidate **unviable_tail = 
 
+  z_candidate *unviable_ignored = nullptr;
+  z_candidate **unviable_ignored_tail = _ignored;
+
   /* Be strict inside templates, since build_over_call won't actually
  do the conversions to get pedwarns.  */
   if (processing_template_decl)
@@ -3742,6 +3774,7 @@ splice_viable (struct z_candidate *cands,
 its viability.  */
   auto& tail = (cand->viable == 1 ? strictly_viable_tail
: cand->viable == -1 ? non_strictly_viable_tail
+   : ignored_candidate_p (cand) ? unviable_ignored_tail
: unviable_tail);
   *tail = cand;
   tail = >next;
@@ -3751,7 +3784,8 @@ splice_viable (struct z_candidate *cands,
   

[PATCH v2 1/3] c++: sort candidates according to viability

2023-10-23 Thread Patrick Palka
The second patch in this series is new and ensures that the candidates
list isn't mysteriously missing some candidates when noting other
candidates due to deletedness.

-- >8 --

This patch:

  * changes splice_viable to move the non-viable candidates to the end
of the list instead of removing them outright
  * makes tourney move the best candidate to the front of the candidate
list
  * adjusts print_z_candidates to preserve our behavior of printing only
viable candidates when diagnosing ambiguity
  * adds a parameter to print_z_candidates to control this default behavior
(the follow-up patch will want to print all candidates when diagnosing
deletedness)

Thus after this patch we have access to the entire candidate list through
the best viable candidate.

This change also happens to fix diagnostics for the below testcase where
we currently neglect to note the third candidate, since the presence of
the two unordered non-strictly viable candidates causes splice_viable to
prematurely get rid of the non-viable third candidate.

gcc/cp/ChangeLog:

* call.cc: Include "tristate.h".
(splice_viable): Sort the candidate list according to viability.
Don't remove non-viable candidates from the list.
(print_z_candidates): Add defaulted only_viable_p parameter.
By default only print non-viable candidates if there is no
viable candidate.
(tourney): Make 'candidates' parameter a reference.  Ignore
non-viable candidates.  Move the true champ to the front
of the candidates list, and update 'candidates' to point to
the front.

gcc/testsuite/ChangeLog:

* g++.dg/overload/error5.C: New test.
---
 gcc/cp/call.cc | 163 +++--
 gcc/testsuite/g++.dg/overload/error5.C |  12 ++
 2 files changed, 113 insertions(+), 62 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/overload/error5.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 2eb54b5b6ed..89d422f7220 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "decl.h"
 #include "gcc-rich-location.h"
+#include "tristate.h"
 
 /* The various kinds of conversion.  */
 
@@ -160,7 +161,7 @@ static struct obstack conversion_obstack;
 static bool conversion_obstack_initialized;
 struct rejection_reason;
 
-static struct z_candidate * tourney (struct z_candidate *, tsubst_flags_t);
+static struct z_candidate * tourney (struct z_candidate *&, tsubst_flags_t);
 static int equal_functions (tree, tree);
 static int joust (struct z_candidate *, struct z_candidate *, bool,
  tsubst_flags_t);
@@ -176,7 +177,8 @@ static void op_error (const op_location_t &, enum 
tree_code, enum tree_code,
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
 tsubst_flags_t);
 static void print_z_candidate (location_t, const char *, struct z_candidate *);
-static void print_z_candidates (location_t, struct z_candidate *);
+static void print_z_candidates (location_t, struct z_candidate *,
+   tristate = tristate::unknown ());
 static tree build_this (tree);
 static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
 static bool any_strictly_viable (struct z_candidate *);
@@ -3700,68 +3702,60 @@ add_template_conv_candidate (struct z_candidate 
**candidates, tree tmpl,
 }
 
 /* The CANDS are the set of candidates that were considered for
-   overload resolution.  Return the set of viable candidates, or CANDS
-   if none are viable.  If any of the candidates were viable, set
+   overload resolution.  Sort CANDS so that the strictly viable
+   candidates appear first, followed by non-strictly viable candidates,
+   followed by unviable candidates.  Returns the first candidate
+   in this sorted list.  If any of the candidates were viable, set
*ANY_VIABLE_P to true.  STRICT_P is true if a candidate should be
-   considered viable only if it is strictly viable.  */
+   considered viable only if it is strictly viable when setting
+   *ANY_VIABLE_P.  */
 
 static struct z_candidate*
 splice_viable (struct z_candidate *cands,
   bool strict_p,
   bool *any_viable_p)
 {
-  struct z_candidate *viable;
-  struct z_candidate **last_viable;
-  struct z_candidate **cand;
-  bool found_strictly_viable = false;
+  z_candidate *strictly_viable = nullptr;
+  z_candidate **strictly_viable_tail = _viable;
+
+  z_candidate *non_strictly_viable = nullptr;
+  z_candidate **non_strictly_viable_tail = _strictly_viable;
+
+  z_candidate *unviable = nullptr;
+  z_candidate **unviable_tail = 
 
   /* Be strict inside templates, since build_over_call won't actually
  do the conversions to get pedwarns.  */
   if (processing_template_decl)
 strict_p = true;
 
-  viable = NULL;
-  last_viable = 
-  *any_viable_p = false;

[PATCH] c++: cp_stabilize_reference and non-dep exprs [PR111919]

2023-10-23 Thread Patrick Palka
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
for trunk?

-- >8 --

After the removal of NON_DEPENDENT_EXPR, cp_stabilize_reference which
used to just exit early for NON_DEPENDENT_EXPR is now more prone to
passing a weird templated tree to middle-end routines, which leads to a
crash from contains_placeholder_p in the testcase below.  It seems the
best fix is to just disable cp_stabilize_reference when in a template
context like we already do for cp_save_expr; it seems SAVE_EXPR should
never appear in a templated tree (since e.g. tsubst doesn't handle it).

PR c++/111919

gcc/cp/ChangeLog:

* tree.cc (cp_stabilize_reference): Do nothing when
processing_template_decl.

gcc/testsuite/ChangeLog:

* g++.dg/template/non-dependent27.C: New test.
---
 gcc/cp/tree.cc  | 4 
 gcc/testsuite/g++.dg/template/non-dependent27.C | 8 
 2 files changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/template/non-dependent27.C

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index a3d61d3e7c9..417c92ba76f 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -408,6 +408,10 @@ bitfield_p (const_tree ref)
 tree
 cp_stabilize_reference (tree ref)
 {
+  if (processing_template_decl)
+/* As in cp_save_expr.  */
+return ref;
+
   STRIP_ANY_LOCATION_WRAPPER (ref);
   switch (TREE_CODE (ref))
 {
diff --git a/gcc/testsuite/g++.dg/template/non-dependent27.C 
b/gcc/testsuite/g++.dg/template/non-dependent27.C
new file mode 100644
index 000..cf7af6e6425
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent27.C
@@ -0,0 +1,8 @@
+// PR c++/111919
+
+int i[3];
+
+template
+void f() {
+  i[42 / (int) sizeof (T)] |= 0;
+}
-- 
2.42.0.424.gceadf0f3cf



Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

2023-10-23 Thread Patrick O'Neill

When configuring, pass in --enable-checking=rtl
If you're using riscv-gnu-toolchain, pass in --enable-gcc-checking=rtl

The -freport-bug output attached to the bug report has the full 
configure command used:
/scratch/tc-testing/tc-trunk/build-rtl-checking/../gcc/configure 
--target=riscv64-unknown-linux-gnu 
--prefix=/scratch/tc-testing/tc-trunk/build-rtl-checking 
--with-sysroot=/scratch/tc-testing/tc-trunk/build-rtl-checking/sysroot 
--with-newlib --without-headers --disable-shared --disable-threads 
--with-system-zlib --enable-tls --enable-languages=c --disable-libatomic 
--disable-libmudflap --disable-libssp --disable-libquadmath 
--disable-libgomp --disable-nls --disable-bootstrap --src=../../gcc 
--enable-checking=rtl --disable-multilib --with-abi=lp64d 
--with-arch=rv64gcv --with-tune=rocket --with-isa-spec=20191213 
'CFLAGS_FOR_TARGET=-O2    -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-O2    
-mcmodel=medlow'


On 10/23/23 15:50, 钟居哲 wrote:

I didn't reproduce it. How to enable RTL checking ?


juzhe.zh...@rivai.ai

*From:* Patrick O'Neill 
*Date:* 2023-10-24 06:46
*To:* 钟居哲 ; 丁乐华

*CC:* kito.cheng ; rdapp.gcc
; palmer ;
Jeff Law ; gcc-patches

*Subject:* Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

You're on top of it - thanks for fixing this! I'll send the testcase.

Unrelated to this failure, I'm seeing a build failure on glibc
rv32/64gcv when RTL checking is enabled.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111947

Thanks,
Patrick

On 10/23/23 14:41, 钟居哲 wrote:

I have fixed it:

https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0c4bd1321a6def5eb44c530e83b01a415633b660

Plz verify it and send a patch with testcase pr111941.c if you
confirm it has been fixed on the trunk.

Thanks.

juzhe.zh...@rivai.ai

*From:* Patrick O'Neill 
*Date:* 2023-10-24 02:30
*To:* Lehua Ding 
*CC:* kito.cheng ; rdapp.gcc
; palmer
; Jeff Law
; gcc-patches
; 钟居哲

*Subject:* Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
Hi Lehua,
This patch causes a build failure with newlib 4.1.0 with
-march=rv64gv_zbb.
I've creduced the failure here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111941
Thanks,
Patrick
On 10/19/23 20:58, Lehua Ding wrote:
> Committed, thanks Patrick and Juzhe.
>
> On 2023/10/20 2:04, Patrick O'Neill wrote:
>> I tested it this morning on my machine and it passed!
>>
>> Tested against:
>> 04d6c74564b7eb51660a00b35353aeab706b5a50
>>
>> Using targets:
>> glibc rv32gcv qemu
>> glibc rv64gcv qemu
>>
>> This patch series does not introduce any new failures.
>>
>> Here's a list of *resolved* failures by this patch series:
>> rv64gcv:
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g
execution test
>>
>> rv32gcv:
>> FAIL: gcc.target/riscv/rvv/autovec/binop/narrow_run-1.c
execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g
execution test
>>
>> Thanks for the quick revision Lehua!
>>
>> Tested-by: Patrick O'Neill 
>>
>> Patrick
>>
>> On 10/19/23 01:50, 钟居哲 wrote:
>>> LGTM now. But wait for Patrick CI testing.
>>>
>>> Hi, @Patrick. Could you apply this patch and trigger CI
in your
>>> github  so that we can see the full running result.
>>>
>>> Issues · patrick-rivos/riscv-gnu-toolchain · GitHub
>>> 
>>>
>>>


>>>
>>> juzhe.zh...@rivai.ai
>>>
>>>     *From:* Lehua Ding 
   

[PATCH] match: Fix the `popcnt(a) + popcnt(a|b)` patthern for types [PR111913]

2023-10-23 Thread Andrew Pinski
So this pattern needs a little help on the gimple side of things to know what
the type popcount should be. For most builtins, the type is the same as the 
input
but popcount and others are not. And when using it with another outer 
expression,
genmatch needs some slight help to know that the return type was type rather 
than
the argument type.

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

PR tree-optimization/111913

gcc/ChangeLog:

* match.pd (`popcount(X) + popcount(X|Y)`): Add the resulting
type for popcount.

gcc/testsuite/ChangeLog:

* gcc.c-torture/compile/fold-popcount-1.c: New test.
* gcc.dg/fold-popcount-8a.c: New test.
---
 gcc/match.pd  |  2 +-
 .../gcc.c-torture/compile/fold-popcount-1.c   | 13 
 gcc/testsuite/gcc.dg/fold-popcount-8a.c   | 33 +++
 3 files changed, 47 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c
 create mode 100644 gcc/testsuite/gcc.dg/fold-popcount-8a.c

diff --git a/gcc/match.pd b/gcc/match.pd
index ce8d159d260..f725a685863 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -8600,7 +8600,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* popcount(X) + popcount(X|Y) is popcount(x) + popcount(Y).  */
 (simplify
   (plus:c (POPCOUNT:s (bit_and:s @0 @1)) (POPCOUNT:s (bit_ior:cs @0 @1)))
-  (plus (POPCOUNT @0) (POPCOUNT @1)))
+  (plus (POPCOUNT:type @0) (POPCOUNT:type @1)))
 
 /* popcount(X) + popcount(Y) - popcount(X) is popcount(X|Y).  */
 /* popcount(X) + popcount(Y) - popcount(X|Y) is popcount(X).  */
diff --git a/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c 
b/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c
new file mode 100644
index 000..d3d3a2976e0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/111913 */
+
+int f(unsigned int x, unsigned int y)
+{
+  return __builtin_popcount (x) + __builtin_popcount (y|x--);
+}
+
+int f2(unsigned int x, unsigned int y)
+{
+  int t = __builtin_popcount (x);
+  int t1 = __builtin_popcount (x|y);
+  return t + t1;
+}
diff --git a/gcc/testsuite/gcc.dg/fold-popcount-8a.c 
b/gcc/testsuite/gcc.dg/fold-popcount-8a.c
new file mode 100644
index 000..3001522f259
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-popcount-8a.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo1(unsigned int x, unsigned int y)
+{
+  int t = __builtin_popcount (x);
+  int t1 = __builtin_popcount (x|y);
+  return t + t1;
+}
+
+int foo2(unsigned int x, unsigned int y)
+{
+  int t1 = __builtin_popcount (x|y);
+  int t = __builtin_popcount (x);
+  return t + t1;
+}
+
+int foo3(unsigned int y, unsigned int x)
+{
+  int t = __builtin_popcount (x);
+  int t1 = __builtin_popcount (x|y);
+  return t + t1;
+}
+
+int foo4(unsigned int y, unsigned int x)
+{
+  int t1 = __builtin_popcount (x|y);
+  int t = __builtin_popcount (x);
+  return t + t1;
+}
+
+/* { dg-final { scan-tree-dump-not " & " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\| " "optimized" } } */
-- 
2.39.3



Re: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

2023-10-23 Thread 钟居哲
I didn't reproduce it. How to enable RTL checking ?



juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 06:46
To: 钟居哲; 丁乐华
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
You're on top of it - thanks for fixing this! I'll send the testcase.

Unrelated to this failure, I'm seeing a build failure on glibc rv32/64gcv when 
RTL checking is enabled.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111947

Thanks,
Patrick
On 10/23/23 14:41, 钟居哲 wrote:
I have fixed it: 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0c4bd1321a6def5eb44c530e83b01a415633b660

Plz verify it and send a patch with testcase pr111941.c if you confirm it has 
been fixed on the trunk.

Thanks.


juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 02:30
To: Lehua Ding
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches; 钟居哲
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
Hi Lehua,
 
This patch causes a build failure with newlib 4.1.0 with -march=rv64gv_zbb.
 
I've creduced the failure here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111941
 
Thanks,
Patrick
 
On 10/19/23 20:58, Lehua Ding wrote:
> Committed, thanks Patrick and Juzhe.
>
> On 2023/10/20 2:04, Patrick O'Neill wrote:
>> I tested it this morning on my machine and it passed!
>>
>> Tested against:
>> 04d6c74564b7eb51660a00b35353aeab706b5a50
>>
>> Using targets:
>> glibc rv32gcv qemu
>> glibc rv64gcv qemu
>>
>> This patch series does not introduce any new failures.
>>
>> Here's a list of *resolved* failures by this patch series:
>> rv64gcv:
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g  execution test
>>
>> rv32gcv:
>> FAIL: gcc.target/riscv/rvv/autovec/binop/narrow_run-1.c execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g  execution test
>>
>> Thanks for the quick revision Lehua!
>>
>> Tested-by: Patrick O'Neill 
>>
>> Patrick
>>
>> On 10/19/23 01:50, 钟居哲 wrote:
>>> LGTM now. But wait for Patrick CI testing.
>>>
>>> Hi, @Patrick. Could you apply this patch and trigger CI in your 
>>> github  so that we can see the full running result.
>>>
>>> Issues · patrick-rivos/riscv-gnu-toolchain · GitHub 
>>> 
>>>
>>>  
>>>
>>> juzhe.zh...@rivai.ai
>>>
>>> *From:* Lehua Ding 
>>> *Date:* 2023-10-19 16:33
>>> *To:* gcc-patches 
>>> *CC:* juzhe.zhong ; kito.cheng
>>> ; rdapp.gcc
>>> ; palmer ;
>>> jeffreyalaw ; lehua.ding
>>> 
>>> *Subject:* [PATCH V3 00/11] Refactor and cleanup vsetvl pass
>>> This patch refactors and cleanups the vsetvl pass in order to make
>>> the code
>>> easier to modify and understand. This patch does several things:
>>> 1. Introducing a virtual CFG for vsetvl infos and Phase 1, 2 and 3
>>> only maintain
>>>and modify this virtual CFG. Phase 4 performs insertion,
>>> modification and
>>>deletion of vsetvl insns based on the virtual CFG. The Basic
>>> block in the
>>>virtual CFG is called vsetvl_block_info and the vsetvl
>>> information inside
>>>is called vsetvl_info.
>>> 2. Combine Phase 1 and 2 into a single Phase 1 and unified the
>>> demand system,
>>>this Phase only fuse local vsetvl info in forward direction.
>>> 3. Refactor Phase 3, change the logic for determining whether to
>>> uplift vsetvl
>>>info to a pred basic block to a more unified method that there
>>> is a vsetvl
>>>info in the vsetvl defintion reaching in compatible with it.
>>> 4. Place all modification operations to the RTL in Phase 4 and
>>> Phase 5.
>>>Phase 4 is responsible for inserting, modifying and deleting 
>>> vsetvl
>>>instructions based on fully optimized vsetvl infos. Phase 5
>>> removes the avl
>>>operand from the RVV instruction and removes the unused dest
>>> operand
>>>register from the vsetvl insns.
>>> These modifications resulted in some testcases needing to be
>>> updated. The reasons
>>> for updating are summarized below:
>>> 1. more optimized
>>> vlmax_back_prop-25.c/vlmax_back_prop-26.c/vlmax_conflict-3.c/
>>>vlmax_conflict-12.c/vsetvl-13.c/vsetvl-23.c/
>>> avl_single-23.c/avl_single-89.c/avl_single-95.c/pr109773-1.c
>>> 2. less unnecessary fusion
>>> 

Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Siddhesh Poyarekar

On 2023-10-23 15:43, Qing Zhao wrote:




On Oct 23, 2023, at 2:43 PM, Siddhesh Poyarekar  wrote:

On 2023-10-23 14:06, Martin Uecker wrote:

We should aim for a good integration with the BDOS pass, so
that it can propagate the information further, e.g. the
following should work:
struct { int L; char buf[] __counted_by(L) } x;
x.L = N;
x.buf = ...;
char *p = >f;
__bdos(p) -> N
So we need to be smart on how we provide the size
information for x->f to the backend.
This would also be desirable for the language extension.


This is essentially why there need to be frontend rules constraining reordering 
and reachability semantics of x.L, thus restricting DSE and reordering for it.


My understanding is that Restricting DSE and reordering should be done by the 
proper data flow information, with a new argument added to the BDOS call, this 
correct data flow information could be maintained, and then the DSE and 
reordering will not happen.

I don’t quite understand what kind of frontend rules should be added to 
constrain reordering and reachability semantics? Can you explain this a little 
bit more? Do you mean to add some rules or requirment to the new attribute that 
the users of the attribute should follow in the source code?


Yes, but let me try and summarize the issues and the potential solutions 
at the end:





  This is not really a __bdos/__bos question, because that bit is trivial; if 
the structure is visible, the value is simply x.L.  This is also why adding a 
reference to x.L in __bos/__bdos is not sufficient or even possible in, e.g. 
the above case you note.


I am a little confused here, are we discussing how to resolve the potential 
reordering issue of the following:

"
struct annotated {
   size_t foo;
   char array[] __attribute__((counted_by (foo)));
};

   p->foo = 10;
   size = __builtin_dynamic_object_size (p->array,1);
“?

Or a bigger issue?


Right, so the problem we're trying to solve is the reordering of __bdos 
w.r.t. initialization of the size parameter but to also account for DSE 
of the assignment, we can abstract this problem to that of DFA being 
unable to see implicit use of the size parameter.  __bdos is the one 
such implicit user of the size parameter and you're proposing to solve 
this by encoding the relationship between buffer and size at the __bdos 
call site.  But what about the case when the instantiation of the object 
is not at the same place as the __bdos call site, i.e. the DFA is unable 
to make that relationship?


The example Martin showed where the subobject gets "hidden" behind a 
pointer was a trivial one where DFA *may* actually work in practice 
(because the object-size pass can thread through these assignments) but 
think about this one:


struct A
{
  size_t size;
  char buf[] __attribute__((counted_by(size)));
}

static size_t
get_size_of (void *ptr)
{
  return __bdos (ptr, 1);
}

void
foo (size_t sz)
{
  struct A *obj = __builtin_malloc (sz);
  obj->size = sz;

  ...
  __builtin_printf ("%zu\n", get_size_of (obj->array));
  ...
}

Until get_size_of is inlined, no DFA can see the __bdos call in the same 
place as the point where obj is allocated.  As a result, the assignment 
to obj->size could get reordered (or the store eliminated) w.r.t. the 
__bdos call until the inlining happens.


As a result, the relationship between buf and size established by the 
attribute needs to be encoded into the type somehow.  There are two options:


Option 1: Encode the relationship in the type of buf

This is kinda what you end up doing with component_ref_has_counted_by 
and it does show the relationship if one is looking (through that call), 
but nothing more that can be used to, e.g. prevent reordering or tell 
the optimizer that the reference to the buf member may imply a reference 
to the size member as well.  This could be remedied by somehow encoding 
the USES relationship for size into the type of buf that the 
optimization passes can see.  I feel like this may be a bit convoluted 
to specify in a future language extension in a way that will actually be 
well understood by developers, but it will likely generate faster 
runtime code.  This will also likely require a bigger change across passes.


Option 2: Encode the relationship in the type of size

The other option is to enhance the type of size somehow so that it 
discourages reordering and store elimination, basically pessimizing 
code.  I think volatile semantics might be the way to do this and may 
even be straightforward to specify in the future language extension 
given that it builds on a known language construct and is thematically 
related.  However it does pessimize output for code that implements 
__counted_by__.


Thanks,
Sid


Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

2023-10-23 Thread Patrick O'Neill

You're on top of it - thanks for fixing this! I'll send the testcase.

Unrelated to this failure, I'm seeing a build failure on glibc 
rv32/64gcv when RTL checking is enabled.

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

Thanks,
Patrick

On 10/23/23 14:41, 钟居哲 wrote:

I have fixed it:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0c4bd1321a6def5eb44c530e83b01a415633b660

Plz verify it and send a patch with testcase pr111941.c if you confirm 
it has been fixed on the trunk.


Thanks.

juzhe.zh...@rivai.ai

*From:* Patrick O'Neill 
*Date:* 2023-10-24 02:30
*To:* Lehua Ding 
*CC:* kito.cheng ; rdapp.gcc
; palmer ;
Jeff Law ; gcc-patches
; 钟居哲 
*Subject:* Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
Hi Lehua,
This patch causes a build failure with newlib 4.1.0 with
-march=rv64gv_zbb.
I've creduced the failure here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111941
Thanks,
Patrick
On 10/19/23 20:58, Lehua Ding wrote:
> Committed, thanks Patrick and Juzhe.
>
> On 2023/10/20 2:04, Patrick O'Neill wrote:
>> I tested it this morning on my machine and it passed!
>>
>> Tested against:
>> 04d6c74564b7eb51660a00b35353aeab706b5a50
>>
>> Using targets:
>> glibc rv32gcv qemu
>> glibc rv64gcv qemu
>>
>> This patch series does not introduce any new failures.
>>
>> Here's a list of *resolved* failures by this patch series:
>> rv64gcv:
>> FAIL: gfortran.dg/host_assoc_function_7.f90 -O3
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90 -O3 -g  execution test
>>
>> rv32gcv:
>> FAIL: gcc.target/riscv/rvv/autovec/binop/narrow_run-1.c
execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90 -O3
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90 -O3 -g  execution test
>>
>> Thanks for the quick revision Lehua!
>>
>> Tested-by: Patrick O'Neill 
>>
>> Patrick
>>
>> On 10/19/23 01:50, 钟居哲 wrote:
>>> LGTM now. But wait for Patrick CI testing.
>>>
>>> Hi, @Patrick. Could you apply this patch and trigger CI in your
>>> github  so that we can see the full running result.
>>>
>>> Issues · patrick-rivos/riscv-gnu-toolchain · GitHub
>>> 
>>>
>>>


>>>
>>> juzhe.zh...@rivai.ai
>>>
>>>     *From:* Lehua Ding 
>>>     *Date:* 2023-10-19 16:33
>>>     *To:* gcc-patches 
>>>     *CC:* juzhe.zhong ; kito.cheng
>>> ; rdapp.gcc
>>> ; palmer ;
>>>     jeffreyalaw ; lehua.ding
>>> 
>>>     *Subject:* [PATCH V3 00/11] Refactor and cleanup vsetvl pass
>>>     This patch refactors and cleanups the vsetvl pass in order
to make
>>>     the code
>>>     easier to modify and understand. This patch does several
things:
>>>     1. Introducing a virtual CFG for vsetvl infos and Phase 1,
2 and 3
>>>     only maintain
>>>        and modify this virtual CFG. Phase 4 performs insertion,
>>>     modification and
>>>        deletion of vsetvl insns based on the virtual CFG. The
Basic
>>>     block in the
>>>        virtual CFG is called vsetvl_block_info and the vsetvl
>>>     information inside
>>>        is called vsetvl_info.
>>>     2. Combine Phase 1 and 2 into a single Phase 1 and unified the
>>>     demand system,
>>>        this Phase only fuse local vsetvl info in forward
direction.
>>>     3. Refactor Phase 3, change the logic for determining
whether to
>>>     uplift vsetvl
>>>        info to a pred basic block to a more unified method
that there
>>>     is a vsetvl
>>>        info in the vsetvl defintion reaching in compatible
with it.
>>>     4. Place all modification operations to the RTL in Phase 4 and
>>>     Phase 5.
>>>        Phase 4 is responsible for inserting, modifying and
deleting
>>> vsetvl
>>>        instructions based on fully optimized vsetvl infos. Phase 5
>>>     removes the avl
>>>        operand from the RVV instruction and removes 

Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Kees Cook
On Mon, Oct 23, 2023 at 09:57:45PM +0200, Martin Uecker wrote:
> Am Montag, dem 23.10.2023 um 12:52 -0700 schrieb Kees Cook:
> > On Fri, Oct 20, 2023 at 09:54:05PM +0200, Martin Uecker wrote:
> > > Am Freitag, dem 20.10.2023 um 18:48 + schrieb Qing Zhao:
> > > > 
> > > > > On Oct 20, 2023, at 2:34 PM, Kees Cook  wrote:
> > > > > 
> > > > > On Fri, Oct 20, 2023 at 11:50:11AM +0200, Martin Uecker wrote:
> > > > > > Am Donnerstag, dem 19.10.2023 um 16:33 -0700 schrieb Kees Cook:
> > > > > > > On Wed, Oct 18, 2023 at 09:11:43PM +, Qing Zhao wrote:
> > > > > > > > As I replied to Martin in another email, I plan to do the 
> > > > > > > > following to resolve this issue:
> > > > > > > > 
> > > > > > > > 1. No specification for signed or unsigned for counted_by field.
> > > > > > > > 2. Add a sanitizer option -fsanitize=counted-by-bound to catch 
> > > > > > > > the cases when the size of the counted-by is not positive.
> > > > > > > 
> > > > > > > I don't understand why this needs to be a runtime sanitizer. The
> > > > > > > signedness is known at compile time, so I would expect a -W 
> > > > > > > option.
> > > > > > 
> > > > > > The signedness of the type but not of the value.
> > > > > > 
> > > > > > But I would not want to have a warning for signed 
> > > > > > counter  types by default because I would prefer
> > > > > > to use signed types (for various reasons including
> > > > > > better overflow detection).
> > > > > > 
> > > > > > > Or
> > > > > > > do you mean you'd split up -fsanitize=bounds between unsigned and 
> > > > > > > signed
> > > > > > > indexes? I'd find that kind of awkward for the kernel... but I 
> > > > > > > feel like
> > > > > > > I've misunderstood something. :)
> > > > > > > 
> > > > > > > -Kees
> > > > > > 
> > > > > > The idea would be to detect at run-time the case
> > > > > > if  x->buf  is used at a time where   x->counter 
> > > > > > is negative and also when x->counter * sizeof(x->buf[0])
> > > > > > overflows or is too big.
> > > > > > 
> > > > > > This would be similar to
> > > > > > 
> > > > > > int a[n];
> > > > > > 
> > > > > > where it is detected at run-time if n is not-positive.
> > > > > 
> > > > > Right. I guess what I mean to say is that I would expect this case to
> > > > > already be caught by -fsanitize=bounds -- I don't see a reason to add 
> > > > > an
> > > > > additional sanitizer option.
> > > > > 
> > > > > struct foo {
> > > > >   int count;
> > > > >   int array[] __counted_by(count);
> > > > > };
> > > > > 
> > > > >   foo->count = 5;
> > > > >   foo->array[0] = 1;  // ok
> > > > >   foo->array[10] = 1; // -fsanitize=bounds will catch this
> > > > >   foo->array[-10] = 1;// -fsanitize=bounds will catch this too
> > > > > 
> > > > > 
> > > > 
> > > > just checked this testing case with my GCC, and YES, -fsanitize=bounds 
> > > > indeed caught this error:
> > > > 
> > > > ttt_1.c:31:12: runtime error: index 10 out of bounds for type 'char [*]'
> > > > ttt_1.c:32:12: runtime error: index -10 out of bounds for type 'char 
> > > > [*]’
> > > > 
> > > 
> > > Yes, but I thought we were discussing the case where count is
> > > set to a negative value:
> > > 
> > > foo->count = -1;
> > > int x = foo->array[3]; // UBSan should diagnose this
> > 
> > Oh right, I keep thinking about it backwards.
> > 
> > Yeah, we can't trap the "count" assignment, because it may be getting used
> > for other purposes. But yeah, access to "array" should trap if "count"
> > is negative.
> > 
> > > And also the case when foo->array becomes too big.
> > 
> > How do you mean?
> 
> count * sizeof(member) could overflow or otherwise be
> bigger than allowed.

Ah! Yes.

foo->count = SIZE_MAX;
foo->array[0]; // UBSan diagnose:
   // SIZE_MAX * sizeof(int) is larger than can be represented

> 
> Martin
> 
> 

-- 
Kees Cook


Re: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

2023-10-23 Thread 钟居哲
I have fixed it: 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0c4bd1321a6def5eb44c530e83b01a415633b660

Plz verify it and send a patch with testcase pr111941.c if you confirm it has 
been fixed on the trunk.

Thanks.


juzhe.zh...@rivai.ai
 
From: Patrick O'Neill
Date: 2023-10-24 02:30
To: Lehua Ding
CC: kito.cheng; rdapp.gcc; palmer; Jeff Law; gcc-patches; 钟居哲
Subject: Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass
Hi Lehua,
 
This patch causes a build failure with newlib 4.1.0 with -march=rv64gv_zbb.
 
I've creduced the failure here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111941
 
Thanks,
Patrick
 
On 10/19/23 20:58, Lehua Ding wrote:
> Committed, thanks Patrick and Juzhe.
>
> On 2023/10/20 2:04, Patrick O'Neill wrote:
>> I tested it this morning on my machine and it passed!
>>
>> Tested against:
>> 04d6c74564b7eb51660a00b35353aeab706b5a50
>>
>> Using targets:
>> glibc rv32gcv qemu
>> glibc rv64gcv qemu
>>
>> This patch series does not introduce any new failures.
>>
>> Here's a list of *resolved* failures by this patch series:
>> rv64gcv:
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g  execution test
>>
>> rv32gcv:
>> FAIL: gcc.target/riscv/rvv/autovec/binop/narrow_run-1.c execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 
>> -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
>> -finline-functions  execution test
>> FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g  execution test
>>
>> Thanks for the quick revision Lehua!
>>
>> Tested-by: Patrick O'Neill 
>>
>> Patrick
>>
>> On 10/19/23 01:50, 钟居哲 wrote:
>>> LGTM now. But wait for Patrick CI testing.
>>>
>>> Hi, @Patrick. Could you apply this patch and trigger CI in your 
>>> github  so that we can see the full running result.
>>>
>>> Issues · patrick-rivos/riscv-gnu-toolchain · GitHub 
>>> 
>>>
>>>  
>>>
>>> juzhe.zh...@rivai.ai
>>>
>>> *From:* Lehua Ding 
>>> *Date:* 2023-10-19 16:33
>>> *To:* gcc-patches 
>>> *CC:* juzhe.zhong ; kito.cheng
>>> ; rdapp.gcc
>>> ; palmer ;
>>> jeffreyalaw ; lehua.ding
>>> 
>>> *Subject:* [PATCH V3 00/11] Refactor and cleanup vsetvl pass
>>> This patch refactors and cleanups the vsetvl pass in order to make
>>> the code
>>> easier to modify and understand. This patch does several things:
>>> 1. Introducing a virtual CFG for vsetvl infos and Phase 1, 2 and 3
>>> only maintain
>>>and modify this virtual CFG. Phase 4 performs insertion,
>>> modification and
>>>deletion of vsetvl insns based on the virtual CFG. The Basic
>>> block in the
>>>virtual CFG is called vsetvl_block_info and the vsetvl
>>> information inside
>>>is called vsetvl_info.
>>> 2. Combine Phase 1 and 2 into a single Phase 1 and unified the
>>> demand system,
>>>this Phase only fuse local vsetvl info in forward direction.
>>> 3. Refactor Phase 3, change the logic for determining whether to
>>> uplift vsetvl
>>>info to a pred basic block to a more unified method that there
>>> is a vsetvl
>>>info in the vsetvl defintion reaching in compatible with it.
>>> 4. Place all modification operations to the RTL in Phase 4 and
>>> Phase 5.
>>>Phase 4 is responsible for inserting, modifying and deleting 
>>> vsetvl
>>>instructions based on fully optimized vsetvl infos. Phase 5
>>> removes the avl
>>>operand from the RVV instruction and removes the unused dest
>>> operand
>>>register from the vsetvl insns.
>>> These modifications resulted in some testcases needing to be
>>> updated. The reasons
>>> for updating are summarized below:
>>> 1. more optimized
>>> vlmax_back_prop-25.c/vlmax_back_prop-26.c/vlmax_conflict-3.c/
>>>vlmax_conflict-12.c/vsetvl-13.c/vsetvl-23.c/
>>> avl_single-23.c/avl_single-89.c/avl_single-95.c/pr109773-1.c
>>> 2. less unnecessary fusion
>>> avl_single-46.c/imm_bb_prop-1.c/pr109743-2.c/vsetvl-18.c
>>> 3. local fuse direction (backward -> forward)
>>>scalar_move-1.c/
>>> 4. add some bugfix testcases.
>>>pr111037-3.c/pr111037-4.c
>>>avl_single-89.c
>>> PR target/111037
>>> PR target/111234
>>> PR target/111725
>>> Lehua Ding (11):
>>>   RISC-V: P1: Refactor
>>> avl_info/vl_vtype_info/vector_insn_info/vector_block_info
>>>   RISC-V: P2: Refactor and cleanup demand system
>>>   RISC-V: P3: Refactor 

Re: [PATCH v23 32/33] c++: Implement __is_invocable built-in trait

2023-10-23 Thread Jason Merrill

On 10/20/23 17:37, Patrick Palka wrote:

On Fri, 20 Oct 2023, Patrick Palka wrote:


On Fri, 20 Oct 2023, Patrick Palka wrote:


On Fri, 20 Oct 2023, Ken Matsui wrote:


This patch implements built-in trait for std::is_invocable.


Nice!  My email client unfortunately ate my first review attempt, so
apologies for my brevity this time around.


gcc/cp/ChangeLog:

* cp-trait.def: Define __is_invocable.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_INVOCABLE.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
(is_invocable_p): New function.
* method.h: New file to export build_trait_object in method.cc.


Given how much larger semantics.cc is than method.cc, maybe let's put 
is_invocable_p in method.cc instead?  And in general declarations can go 
in cp-tree.h.



diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 7cccbae5287..cc2e400531a 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -45,6 +45,10 @@ along with GCC; see the file COPYING3.  If not see
  #include "gomp-constants.h"
  #include "predict.h"
  #include "memmodel.h"
+#include "method.h"
+
+#include "print-tree.h"
+#include "tree-pretty-print.h"
  
  /* There routines provide a modular interface to perform many parsing

 operations.  They may therefore be used during actual parsing, or
@@ -11714,6 +11718,133 @@ classtype_has_nothrow_assign_or_copy_p (tree type, 
bool assign_p)
return saw_copy;
  }
  
+/* Return true if FN_TYPE is invocable with the given ARG_TYPES.  */

+
+static bool
+is_invocable_p (tree fn_type, tree arg_types)


(Sorry for the spam)  We'll eventually want to implement a built-in for
invoke_result, so perhaps we should preemptively factor out the bulk
of this function into a 'build_INVOKE' helper function that returns the
built tree?


+{
+  /* ARG_TYPES must be a TREE_VEC.  */
+  gcc_assert (TREE_CODE (arg_types) == TREE_VEC);
+
+  /* Access check is required to determine if the given is invocable.  */
+  deferring_access_check_sentinel acs (dk_no_deferred);
+
+  /* std::is_invocable is an unevaluated context.  */
+  cp_unevaluated cp_uneval_guard;
+
+  bool is_ptrdatamem;
+  bool is_ptrmemfunc;
+  if (TREE_CODE (fn_type) == REFERENCE_TYPE)
+{
+  tree deref_fn_type = TREE_TYPE (fn_type);
+  is_ptrdatamem = TYPE_PTRDATAMEM_P (deref_fn_type);
+  is_ptrmemfunc = TYPE_PTRMEMFUNC_P (deref_fn_type);
+
+  /* Dereference fn_type if it is a pointer to member.  */
+  if (is_ptrdatamem || is_ptrmemfunc)
+   fn_type = deref_fn_type;
+}
+  else
+{
+  is_ptrdatamem = TYPE_PTRDATAMEM_P (fn_type);
+  is_ptrmemfunc = TYPE_PTRMEMFUNC_P (fn_type);
+}
+
+  if (is_ptrdatamem && TREE_VEC_LENGTH (arg_types) != 1)
+/* A pointer to data member with non-one argument is not invocable.  */
+return false;
+
+  if (is_ptrmemfunc && TREE_VEC_LENGTH (arg_types) == 0)
+/* A pointer to member function with no arguments is not invocable.  */
+return false;
+
+  /* Construct an expression of a pointer to member.  */
+  tree datum;
+  if (is_ptrdatamem || is_ptrmemfunc)
+{
+  tree datum_type = TREE_VEC_ELT (arg_types, 0);
+
+  /* Dereference datum.  */
+  if (CLASS_TYPE_P (datum_type))
+   {
+ bool is_refwrap = false;
+
+ tree datum_decl = TYPE_NAME (TYPE_MAIN_VARIANT (datum_type));
+ if (decl_in_std_namespace_p (datum_decl))
+   {
+ tree name = DECL_NAME (datum_decl);
+ if (name && (id_equal (name, "reference_wrapper")))
+   {
+ /* Handle std::reference_wrapper.  */
+ is_refwrap = true;
+ datum_type = cp_build_reference_type (datum_type, false);


Why do you change datum_type from std::reference_wrapper<...> to 
std::reference_wrapper<...>&?



+   }
+   }
+
+ datum = build_trait_object (datum_type);
+
+ /* If datum_type was not std::reference_wrapper, check if it has
+operator*() overload.  If datum_type was std::reference_wrapper,
+avoid dereferencing the datum twice.  */
+ if (!is_refwrap)
+   if (get_class_binding (datum_type, get_identifier ("operator*")))


We probably should use lookup_member instead of get_class_binding since
IIUC the latter doesn't look into bases:

   struct A { int m; };
   struct B { A& operator*(): };
   struct C : B { };
   static_assert(std::is_invocable_v);

However, I notice that the specification of INVOKE
(https://eel.is/c++draft/func.require#lib:INVOKE) doesn't mention name
lookup at all so it strikes me as suspicious that we'd perform name
lookup here.


Agreed.  It seems that whether or not to build_x_indirect_ref should 
depend instead on whether f is a pointer to a member of decltype(t1) (as 
well as is_refwrap).



 I think this would misbehave for:

   struct A { };
   struct B : A { A& operator*() = delete; };
   

Go patch committed: Move Selector_expression up in file

2023-10-23 Thread Ian Lance Taylor
This patch to the Go frontend just moves Selector_expression up in
file.  This is a mechanical change to expressions.cc.  This will make
Selector_expression visible to Builtin_call_expression for later work.
This produces a very large "git --diff", but "git diff --minimal" is
clear.  Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.
Committed to mainline.

Ian
02aa322c8cfd3f60fa5a3a0eee4340bb644261fe
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 35b9cd780da..aff74bd74dc 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-3c2a441ef6cafb018bb3cc16f8403ae3d1daf2e1
+e997b0201512110e9c20b1fdfd40014830031047
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index f218731041b..c9177b71174 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -8426,6 +8426,287 @@ Expression::make_bound_method(Expression* expr, const 
Method* method,
   return new Bound_method_expression(expr, method, function, location);
 }
 
+// A general selector.  This is a Parser_expression for LEFT.NAME.  It
+// is lowered after we know the type of the left hand side.
+
+class Selector_expression : public Parser_expression
+{
+ public:
+  Selector_expression(Expression* left, const std::string& name,
+ Location location)
+: Parser_expression(EXPRESSION_SELECTOR, location),
+  left_(left), name_(name)
+  { }
+
+ protected:
+  int
+  do_traverse(Traverse* traverse)
+  { return Expression::traverse(>left_, traverse); }
+
+  Expression*
+  do_lower(Gogo*, Named_object*, Statement_inserter*, int);
+
+  Expression*
+  do_copy()
+  {
+return new Selector_expression(this->left_->copy(), this->name_,
+  this->location());
+  }
+
+  void
+  do_dump_expression(Ast_dump_context* ast_dump_context) const;
+
+ private:
+  Expression*
+  lower_method_expression(Gogo*);
+
+  // The expression on the left hand side.
+  Expression* left_;
+  // The name on the right hand side.
+  std::string name_;
+};
+
+// Lower a selector expression once we know the real type of the left
+// hand side.
+
+Expression*
+Selector_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*,
+ int)
+{
+  Expression* left = this->left_;
+  if (left->is_type_expression())
+return this->lower_method_expression(gogo);
+  return Type::bind_field_or_method(gogo, left->type(), left, this->name_,
+   this->location());
+}
+
+// Lower a method expression T.M or (*T).M.  We turn this into a
+// function literal.
+
+Expression*
+Selector_expression::lower_method_expression(Gogo* gogo)
+{
+  Location location = this->location();
+  Type* left_type = this->left_->type();
+  Type* type = left_type;
+  const std::string& name(this->name_);
+
+  bool is_pointer;
+  if (type->points_to() == NULL)
+is_pointer = false;
+  else
+{
+  is_pointer = true;
+  type = type->points_to();
+}
+
+  Named_type* nt = type->named_type();
+  Struct_type* st = type->struct_type();
+  bool is_ambiguous;
+  Method* method = NULL;
+  if (nt != NULL)
+method = nt->method_function(name, _ambiguous);
+  else if (st != NULL)
+method = st->method_function(name, _ambiguous);
+  const Typed_identifier* imethod = NULL;
+  if (method == NULL && !is_pointer)
+{
+  Interface_type* it = type->interface_type();
+  if (it != NULL)
+   imethod = it->find_method(name);
+}
+
+  if ((method == NULL && imethod == NULL)
+  || (left_type->named_type() != NULL && left_type->points_to() != NULL))
+{
+  if (nt != NULL)
+   {
+ if (!is_ambiguous)
+   go_error_at(location, "type %<%s%s%> has no method %<%s%>",
+   is_pointer ? "*" : "",
+   nt->message_name().c_str(),
+   Gogo::message_name(name).c_str());
+ else
+   go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
+   Gogo::message_name(name).c_str(),
+   is_pointer ? "*" : "",
+   nt->message_name().c_str());
+   }
+  else
+   {
+ if (!is_ambiguous)
+   go_error_at(location, "type has no method %<%s%>",
+   Gogo::message_name(name).c_str());
+ else
+   go_error_at(location, "method %<%s%> is ambiguous",
+   Gogo::message_name(name).c_str());
+   }
+  return Expression::make_error(location);
+}
+
+  if (method != NULL && !is_pointer && !method->is_value_method())
+{
+  go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
+  nt->message_name().c_str(),
+  Gogo::message_name(name).c_str());
+  return Expression::make_error(location);
+ 

Go patch committed: Make xx_constant_value methods non-const

2023-10-23 Thread Ian Lance Taylor
This patch to the Go frontend changes the Expression
{numeric,string,boolean}_constant_value methods to be non-const.  This
does not affect anything immediately, but will be useful for later CLs
in this series.

The only real effect is to Builtin_call_expression::do_export, which
remains const and can no longer call numeric_constant_value.  But it
never needed to call it, as do_export runs after do_lower, and
do_lower replaces a constant expression with the actual constant.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
597dba85b3e66a0836dd7442edcc2fda7e0703fc
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index d962c4f5770..35b9cd780da 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-806217827fe30553d535f876f182a9e92f5f648e
+3c2a441ef6cafb018bb3cc16f8403ae3d1daf2e1
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index c7b442d3a03..f218731041b 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -846,7 +846,7 @@ class Error_expression : public Expression
   { return false; }
 
   bool
-  do_numeric_constant_value(Numeric_constant* nc) const
+  do_numeric_constant_value(Numeric_constant* nc)
   {
 nc->set_unsigned_long(NULL, 0);
 return true;
@@ -1992,7 +1992,7 @@ class Boolean_expression : public Expression
   { return this->val_ == false; }
 
   bool
-  do_boolean_constant_value(bool* val) const
+  do_boolean_constant_value(bool* val)
   {
 *val = this->val_;
 return true;
@@ -2537,7 +2537,7 @@ class Integer_expression : public Expression
   { return true; }
 
   bool
-  do_numeric_constant_value(Numeric_constant* nc) const;
+  do_numeric_constant_value(Numeric_constant* nc);
 
   Type*
   do_type();
@@ -2602,7 +2602,7 @@ Integer_expression::do_traverse(Traverse* traverse)
 // this as a character when appropriate.
 
 bool
-Integer_expression::do_numeric_constant_value(Numeric_constant* nc) const
+Integer_expression::do_numeric_constant_value(Numeric_constant* nc)
 {
   if (this->is_character_constant_)
 nc->set_rune(this->type_, this->val_);
@@ -2983,7 +2983,7 @@ class Float_expression : public Expression
   { return true; }
 
   bool
-  do_numeric_constant_value(Numeric_constant* nc) const
+  do_numeric_constant_value(Numeric_constant* nc)
   {
 nc->set_float(this->type_, this->val_);
 return true;
@@ -3219,7 +3219,7 @@ class Complex_expression : public Expression
   { return true; }
 
   bool
-  do_numeric_constant_value(Numeric_constant* nc) const
+  do_numeric_constant_value(Numeric_constant* nc)
   {
 nc->set_complex(this->type_, this->val_);
 return true;
@@ -3480,7 +3480,7 @@ Const_expression::do_lower(Gogo* gogo, Named_object*,
 // Return a numeric constant value.
 
 bool
-Const_expression::do_numeric_constant_value(Numeric_constant* nc) const
+Const_expression::do_numeric_constant_value(Numeric_constant* nc)
 {
   if (this->seen_)
 return false;
@@ -3508,7 +3508,7 @@ 
Const_expression::do_numeric_constant_value(Numeric_constant* nc) const
 }
 
 bool
-Const_expression::do_string_constant_value(std::string* val) const
+Const_expression::do_string_constant_value(std::string* val)
 {
   if (this->seen_)
 return false;
@@ -3523,7 +3523,7 @@ Const_expression::do_string_constant_value(std::string* 
val) const
 }
 
 bool
-Const_expression::do_boolean_constant_value(bool* val) const
+Const_expression::do_boolean_constant_value(bool* val)
 {
   if (this->seen_)
 return false;
@@ -4180,7 +4180,7 @@ Type_conversion_expression::do_is_static_initializer() 
const
 
 bool
 Type_conversion_expression::do_numeric_constant_value(
-Numeric_constant* nc) const
+Numeric_constant* nc)
 {
   if (!this->type_->is_numeric_type())
 return false;
@@ -4192,7 +4192,7 @@ Type_conversion_expression::do_numeric_constant_value(
 // Return the constant string value if there is one.
 
 bool
-Type_conversion_expression::do_string_constant_value(std::string* val) const
+Type_conversion_expression::do_string_constant_value(std::string* val)
 {
   if (this->type_->is_string_type() && this->expr_->type()->is_string_type())
 return this->expr_->string_constant_value(val);
@@ -4229,7 +4229,7 @@ 
Type_conversion_expression::do_string_constant_value(std::string* val) const
 // Return the constant boolean value if there is one.
 
 bool
-Type_conversion_expression::do_boolean_constant_value(bool* val) const
+Type_conversion_expression::do_boolean_constant_value(bool* val)
 {
   if (!this->type_->is_boolean_type())
 return false;
@@ -5141,7 +5141,7 @@ Unary_expression::eval_constant(Operator op, const 
Numeric_constant* unc,
 // Return the integral constant value of a unary expression, if it has one.
 
 bool
-Unary_expression::do_numeric_constant_value(Numeric_constant* nc) const

Go patch committed: Pass Gogo to Runtime::make_call

2023-10-23 Thread Ian Lance Taylor
This Go frontend patches passes the Gogo IR pointer to
Runtime::make_call.  This is a boilerplate change that doesn't affect
compiler output.  It's not currently used but will be used by later
CLs in this series.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
45a5ab0503569e57883dca4d8e76d83dc3a60ff6
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index d4095637cea..d962c4f5770 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-1c0a7c9338801d15afba7e39109554ed3406654e
+806217827fe30553d535f876f182a9e92f5f648e
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 5bea6238def..c7b442d3a03 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -305,8 +305,8 @@ Expression::convert_for_assignment(Gogo* gogo, Type* 
lhs_type,
 {
   // Type to interface conversions have been made explicit early.
   go_assert(rhs_type->interface_type() != NULL);
-  return Expression::convert_interface_to_interface(lhs_type, rhs, false,
-location);
+  return Expression::convert_interface_to_interface(gogo, lhs_type, rhs,
+   false, location);
 }
   else if (!are_identical && rhs_type->interface_type() != NULL)
 return Expression::convert_interface_to_type(gogo, lhs_type, rhs, 
location);
@@ -525,7 +525,8 @@ Expression::get_interface_type_descriptor(Expression* rhs)
 // interface type.
 
 Expression*
-Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
+Expression::convert_interface_to_interface(Gogo* gogo, Type *lhs_type,
+  Expression* rhs,
bool for_type_guard,
Location location)
 {
@@ -558,7 +559,7 @@ Expression::convert_interface_to_interface(Type *lhs_type, 
Expression* rhs,
   if (for_type_guard)
 {
   // A type assertion fails when converting a nil interface.
-  first_field = Runtime::make_call(Runtime::ASSERTITAB, location, 2,
+  first_field = Runtime::make_call(gogo, Runtime::ASSERTITAB, location, 2,
   lhs_type_expr, rhs_type_expr);
 }
   else if (lhs_is_empty)
@@ -571,7 +572,7 @@ Expression::convert_interface_to_interface(Type *lhs_type, 
Expression* rhs,
 {
   // A conversion to a non-empty interface may fail, but unlike a
   // type assertion converting nil will always succeed.
-  first_field = Runtime::make_call(Runtime::REQUIREITAB, location, 2,
+  first_field = Runtime::make_call(gogo, Runtime::REQUIREITAB, location, 2,
   lhs_type_expr, rhs_type_expr);
 }
 
@@ -610,7 +611,7 @@ Expression::convert_interface_to_type(Gogo* gogo, Type 
*lhs_type, Expression* rh
 
   Expression* cond;
   if (gogo->need_eqtype()) {
-cond = Runtime::make_call(Runtime::EQTYPE, location,
+cond = Runtime::make_call(gogo, Runtime::EQTYPE, location,
   2, lhs_type_expr,
   rhs_descriptor);
   } else {
@@ -619,7 +620,7 @@ Expression::convert_interface_to_type(Gogo* gogo, Type 
*lhs_type, Expression* rh
   }
 
   rhs_descriptor = Expression::get_interface_type_descriptor(rhs);
-  Expression* panic = Runtime::make_call(Runtime::PANICDOTTYPE, location,
+  Expression* panic = Runtime::make_call(gogo, Runtime::PANICDOTTYPE, location,
  3, lhs_type_expr->copy(),
  rhs_descriptor,
  rhs_inter_expr);
@@ -719,7 +720,8 @@ 
Expression::backend_numeric_constant_expression(Translate_context* context,
 // functions, which will panic.
 
 void
-Expression::check_bounds(Expression* val, Operator op, Expression* bound,
+Expression::check_bounds(Gogo* gogo, Expression* val, Operator op,
+Expression* bound,
 Runtime::Function code,
 Runtime::Function code_u,
 Runtime::Function code_extend,
@@ -813,7 +815,7 @@ Expression::check_bounds(Expression* val, Operator op, 
Expression* bound,
 }
 
   Expression* ignore = Expression::make_boolean(true, loc);
-  Expression* crash = Runtime::make_call(c, loc, 2,
+  Expression* crash = Runtime::make_call(gogo, c, loc, 2,
 val->copy(), bound->copy());
   Expression* cond = Expression::make_conditional(check, ignore, crash, loc);
   inserter->insert(Statement::make_statement(cond, true));
@@ -3916,7 +3918,7 @@ Type_conversion_expression::do_traverse(Traverse* 
traverse)
 // from slice to pointer-to-array, as they can panic.
 
 Expression*

Re: [PATCH v23 03/33] c++: Accept the use of built-in trait identifiers

2023-10-23 Thread Ken Matsui
On Mon, Oct 23, 2023 at 1:36 PM Jason Merrill  wrote:
>
> On 10/20/23 09:53, Ken Matsui wrote:
> > This patch accepts the use of built-in trait identifiers when they are
> > actually not used as traits.  Specifically, we check if the subsequent token
> > is '(' for ordinary built-in traits or is '<' only for the special
> > __type_pack_element built-in trait.  If those identifiers are used
> > differently, the parser treats them as normal identifiers.  This allows
> > us to accept code like: struct __is_pointer {};.
> >
> > +/* Peeks the corresponding built-in trait if a given token is
> >  a built-in trait.  Otherwise, returns nullptr.  */
> >
> >   static const cp_trait *
> > +cp_lexer_peek_trait (cp_lexer *lexer, const cp_token *token1)
>
> Passing in both the lexer and the peeked token seems awkward, let's just
> pass in the lexer.  Looking up the peeked token again is fast.
>
> >   {
> > +  if (token1->type == CPP_NAME && IDENTIFIER_TRAIT_P (token1->u.value))
> > +{
> > +  const cp_trait  = cp_traits[IDENTIFIER_CP_INDEX 
> > (token1->u.value)];
> > +  const bool is_pack_element = (trait.kind == CPTK_TYPE_PACK_ELEMENT);
> > +
> > +  /* Check if the subsequent token is a `<' token to
> > + __type_pack_element or is a `(' token to everything else.  */
>
> git complains about indentation with spaces instead of a tab on this line.
>

Thank you!

> Jason
>


Re: [PATCH v23 02/33] c-family, c++: Look up built-in traits via identifier node

2023-10-23 Thread Ken Matsui
On Mon, Oct 23, 2023 at 1:27 PM Jason Merrill  wrote:
>
> On 10/20/23 09:53, Ken Matsui wrote:
> > Since RID_MAX soon reaches 255 and all built-in traits are used 
> > approximately
> > once in a C++ translation unit, this patch removes all RID values for 
> > built-in
>
> These two lines are too long; please wrap at 75 columns so they don't go
> over 80 when git log adds 4 spaces at the beginning.
>
> > traits and uses the identifier node to look up the specific trait.  Rather
> > than holding traits as keywords, we set all trait identifiers as cik_trait,
> > which is a new cp_identifier_kind.  As cik_reserved_for_udlit was unused and
> > cp_identifier_kind is 3 bits, we replaced the unused field with the new
> > cik_trait.  Also, the later patch handles a subsequent token to the built-in
> > identifier so that we accept the use of non-function-like built-in trait
> > identifiers.
> >
> >   /* True if this identifier is for any operator name (including
> > -   conversions).  Value 4, 5, 6 or 7.  */
> > +   conversions).  Value 4, 5, or 6.  */
> >   #define IDENTIFIER_ANY_OP_P(NODE)   \
> > -  (IDENTIFIER_KIND_BIT_2 (NODE))
> > +  (IDENTIFIER_KIND_BIT_2 (NODE) && !IDENTIFIER_TRAIT_P (NODE))
> ...
> > +/* True if this identifier is the name of a built-in trait.  */
> > +#define IDENTIFIER_TRAIT_P(NODE) \
> > +  (IDENTIFIER_KIND_BIT_0 (NODE)  \
> > +   && IDENTIFIER_KIND_BIT_1 (NODE)   \
> > +   && IDENTIFIER_KIND_BIT_2 (NODE))
>
> The other macros use &, not &&; we might as well stay consistent with
> that pattern.
>

Thank you! Will fix these.

> Jason
>


Go patch committed: Add Expression::is_untyped method

2023-10-23 Thread Ian Lance Taylor
This Go frontend patches adds an Expression::is_untyped method.  This
method is not currently used by anything, but it will be used by later
changes in this series.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
ac50e9b72bf9bb6d5b28096bb164fb050db6e290
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 0f961157dfd..d4095637cea 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-081ec9824a74ec9d82628d8d2f6b9a7a4c35a529
+1c0a7c9338801d15afba7e39109554ed3406654e
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 273831fabf3..5bea6238def 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -201,6 +201,19 @@ Expression::report_error(const char* msg)
   this->set_is_error();
 }
 
+// A convenience function for handling a type in do_is_untyped.  If
+// TYPE is not abstract, return false.  Otherwise set *PTYPE to TYPE
+// and return true.
+
+bool
+Expression::is_untyped_type(Type* type, Type** ptype)
+{
+  if (!type->is_abstract())
+return false;
+  *ptype = type;
+  return true;
+}
+
 // Set types of variables and constants.  This is implemented by the
 // child class.
 
@@ -826,6 +839,10 @@ class Error_expression : public Expression
   do_is_constant() const
   { return true; }
 
+  bool
+  do_is_untyped(Type**) const
+  { return false; }
+
   bool
   do_numeric_constant_value(Numeric_constant* nc) const
   {
@@ -1965,6 +1982,9 @@ class Boolean_expression : public Expression
   do_is_constant() const
   { return true; }
 
+  bool
+  do_is_untyped(Type**) const;
+
   bool
   do_is_zero_value() const
   { return this->val_ == false; }
@@ -2023,6 +2043,15 @@ Boolean_expression::do_traverse(Traverse* traverse)
   return TRAVERSE_CONTINUE;
 }
 
+bool
+Boolean_expression::do_is_untyped(Type** ptype) const
+{
+  if (this->type_ != NULL)
+return Expression::is_untyped_type(this->type_, ptype);
+  *ptype = Type::make_boolean_type();
+  return true;
+}
+
 // Get the type.
 
 Type*
@@ -2096,6 +2125,15 @@ String_expression::do_traverse(Traverse* traverse)
   return TRAVERSE_CONTINUE;
 }
 
+bool
+String_expression::do_is_untyped(Type** ptype) const
+{
+  if (this->type_ != NULL)
+return Expression::is_untyped_type(this->type_, ptype);
+  *ptype = Type::make_string_type();
+  return true;
+}
+
 // Get the type.
 
 Type*
@@ -2485,6 +2523,9 @@ class Integer_expression : public Expression
   do_is_constant() const
   { return true; }
 
+  bool
+  do_is_untyped(Type**) const;
+
   bool
   do_is_zero_value() const
   { return mpz_sgn(this->val_) == 0; }
@@ -2568,6 +2609,18 @@ 
Integer_expression::do_numeric_constant_value(Numeric_constant* nc) const
   return true;
 }
 
+bool
+Integer_expression::do_is_untyped(Type** ptype) const
+{
+  if (this->type_ != NULL)
+return Expression::is_untyped_type(this->type_, ptype);
+  if (this->is_character_constant_)
+*ptype = Type::make_abstract_character_type();
+  else
+*ptype = Type::make_abstract_integer_type();
+  return true;
+}
+
 // Return the current type.  If we haven't set the type yet, we return
 // an abstract integer type.
 
@@ -2913,6 +2966,9 @@ class Float_expression : public Expression
   do_is_constant() const
   { return true; }
 
+  bool
+  do_is_untyped(Type**) const;
+
   bool
   do_is_zero_value() const
   {
@@ -2979,6 +3035,15 @@ Float_expression::do_traverse(Traverse* traverse)
   return TRAVERSE_CONTINUE;
 }
 
+bool
+Float_expression::do_is_untyped(Type** ptype) const
+{
+  if (this->type_ != NULL)
+return Expression::is_untyped_type(this->type_, ptype);
+  *ptype = Type::make_abstract_float_type();
+  return true;
+}
+
 // Return the current type.  If we haven't set the type yet, we return
 // an abstract float type.
 
@@ -3135,6 +3200,9 @@ class Complex_expression : public Expression
   do_is_constant() const
   { return true; }
 
+  bool
+  do_is_untyped(Type**) const;
+
   bool
   do_is_zero_value() const
   {
@@ -3205,6 +3273,15 @@ Complex_expression::do_traverse(Traverse* traverse)
   return TRAVERSE_CONTINUE;
 }
 
+bool
+Complex_expression::do_is_untyped(Type** ptype) const
+{
+  if (this->type_ != NULL)
+return Expression::is_untyped_type(this->type_, ptype);
+  *ptype = Type::make_abstract_complex_type();
+  return true;
+}
+
 // Return the current type.  If we haven't set the type yet, we return
 // an abstract complex type.
 
@@ -3458,6 +3535,21 @@ Const_expression::do_boolean_constant_value(bool* val) 
const
   return ok;
 }
 
+// Whether this is untyped.
+
+bool
+Const_expression::do_is_untyped(Type** ptype) const
+{
+  if (this->type_ != NULL)
+return Expression::is_untyped_type(this->type_, ptype);
+
+  Named_constant* nc = this->constant_->const_value();
+  if (nc->type() != NULL)
+return Expression::is_untyped_type(nc->type(), ptype);
+
+ 

libgo patch committed: Add missing type conversion

2023-10-23 Thread Ian Lance Taylor
This libgo patch adds a missing type conversion.  The gofrontend
incorrectly accepted code that was missing a type conversion.  The
test case for this is bug518.go in https://go.dev/cl/536537.  Future
CLs in this series will detect the type error.  Bootstrapped and ran
Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
2621bd1bac614b63e52d0deb4ab2ff287a9fafa8
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 398d2671b64..0f961157dfd 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-c201fa2a684ada551ca9a0825a3075a0a69498de
+081ec9824a74ec9d82628d8d2f6b9a7a4c35a529
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/syscall/errstr.go b/libgo/go/syscall/errstr.go
index 9f688e2a0c7..02f228adc59 100644
--- a/libgo/go/syscall/errstr.go
+++ b/libgo/go/syscall/errstr.go
@@ -24,7 +24,7 @@ func Errstr(errnum int) string {
}
return string(b[:i])
}
-   if errno != ERANGE {
+   if Errno(errno) != ERANGE {
return "strerror_r failure"
}
}


Re: [PATCH v23 03/33] c++: Accept the use of built-in trait identifiers

2023-10-23 Thread Jason Merrill

On 10/20/23 09:53, Ken Matsui wrote:

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

+/* Peeks the corresponding built-in trait if a given token is
 a built-in trait.  Otherwise, returns nullptr.  */
  
  static const cp_trait *

+cp_lexer_peek_trait (cp_lexer *lexer, const cp_token *token1)


Passing in both the lexer and the peeked token seems awkward, let's just 
pass in the lexer.  Looking up the peeked token again is fast.



  {
+  if (token1->type == CPP_NAME && IDENTIFIER_TRAIT_P (token1->u.value))
+{
+  const cp_trait  = cp_traits[IDENTIFIER_CP_INDEX (token1->u.value)];
+  const bool is_pack_element = (trait.kind == CPTK_TYPE_PACK_ELEMENT);
+
+  /* Check if the subsequent token is a `<' token to
+ __type_pack_element or is a `(' token to everything else.  */


git complains about indentation with spaces instead of a tab on this line.

Jason



Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Qing Zhao


> On Oct 23, 2023, at 3:37 PM, Martin Uecker  wrote:
> 
> Am Montag, dem 23.10.2023 um 19:00 + schrieb Qing Zhao:
>> 
>>> On Oct 23, 2023, at 2:31 PM, Martin Uecker  wrote:
>>> 
>>> Am Montag, dem 23.10.2023 um 20:06 +0200 schrieb Martin Uecker:
 Am Montag, dem 23.10.2023 um 16:37 + schrieb Qing Zhao:
> 
>> On Oct 23, 2023, at 11:57 AM, Richard Biener 
>>  wrote:
>> 
>> 
>> 
>>> Am 23.10.2023 um 16:56 schrieb Qing Zhao :
>>> 
>>> 
>>> 
 On Oct 23, 2023, at 3:57 AM, Richard Biener 
  wrote:
 
> On Fri, Oct 20, 2023 at 10:41 PM Qing Zhao  
> wrote:
> 
> 
> 
>> On Oct 20, 2023, at 3:10 PM, Siddhesh Poyarekar 
>>  wrote:
>> 
>> On 2023-10-20 14:38, Qing Zhao wrote:
>>> How about the following:
>>> Add one more parameter to __builtin_dynamic_object_size(), i.e
>>> __builtin_dynamic_object_size (_1,1,array_annotated->foo)?
>>> When we see the structure field has counted_by attribute.
>> 
>> Or maybe add a barrier preventing any assignments to 
>> array_annotated->foo from being reordered below the __bdos call? 
>> Basically an __asm__ with array_annotated->foo in the clobber list 
>> ought to do it I think.
> 
> Maybe just adding the array_annotated->foo to the use list of the 
> call to __builtin_dynamic_object_size should be enough?
> 
> But I am not sure how to implement this in the TREE level, is there a 
> USE_LIST/CLOBBER_LIST for each call?  Then I can just simply add the 
> counted_by field “array_annotated->foo” to the USE_LIST of the call 
> to __bdos?
> 
> This might be the simplest solution?
 
 If the dynamic object size is derived of a field then I think you need 
 to
 put the "load" of that memory location at the point (as argument)
 of the __bos call right at parsing time.  I know that's awkward because
 you try to play tricks "discovering" that field only late, but that's 
 not
 going to work.
>>> 
>>> Is it better to do this at gimplification phase instead of FE? 
>>> 
>>> VLA decls are handled in gimplification phase, the size calculation and 
>>> call to alloca are all generated during this phase. (gimplify_vla_decl).
>>> 
>>> For __bdos calls, we can add an additional argument if the object’s 
>>> first argument’s type include the counted_by attribute, i.e
>>> 
>>> ***During gimplification, 
>>> For a call to __builtin_dynamic_object_size (ptr, type)
>>> Check whether the type of ptr includes counted_by attribute, if so, 
>>> change the call to
>>> __builtin_dynamic_object_size (ptr, type, counted_by field)
>>> 
>>> Then the correct data dependence should be represented well in the IR.
>>> 
>>> **During object size phase,
>>> 
>>> The call to __builtin_dynamic_object_size will become an expression 
>>> includes the counted_by field or -1/0 when we cannot decide the size, 
>>> the correct data dependence will be kept even the call to 
>>> __builtin_dynamic_object_size is gone. 
>> 
>> But the whole point of the BOS pass is to derive information that is not 
>> available at parsing time, and that’s the cases you are after.  The case 
>> where the connection to the field with the length is apparent during 
>> parsing is easy - you simply insert a load of the value before the BOS 
>> call.
> 
> Yes, this is true. 
> I prefer to implement this in gimplification phase since I am more 
> familiar with the code there.. (I think that implementing it in 
> gimplification should be very similar as implementing it in FE? Or do I 
> miss anything here?)
> 
> Joseph, if implement this in FE, where in the FE I should look at? 
> 
 
 We should aim for a good integration with the BDOS pass, so
 that it can propagate the information further, e.g. the 
 following should work:
 
 struct { int L; char buf[] __counted_by(L) } x;
 x.L = N;
 x.buf = ...;
 char *p = >f;
 __bdos(p) -> N
 
 So we need to be smart on how we provide the size
 information for x->f to the backend. 
>>> 
>>> To follow up on this. I do not think we should change the
>>> builtin in the FE or gimplification. Instead, we want 
>>> to change the field access and compute the size there. 
>> Could you please clarify on this? What do you mean by
>> "change the field access and compute the size there”?
> 
> I think the FE should essentially give the
> type
> 
> char [buf.L]
> 
> to buf.x;
> 
> If the type (or its size) could be preserved
> at this point so that it can be later
> discovered by __bdos, then it could know 
> the size and propagate it further.

Currently, we already store the 

Re: [PATCH v23 02/33] c-family, c++: Look up built-in traits via identifier node

2023-10-23 Thread Jason Merrill

On 10/20/23 09:53, Ken Matsui wrote:

Since RID_MAX soon reaches 255 and all built-in traits are used approximately
once in a C++ translation unit, this patch removes all RID values for built-in


These two lines are too long; please wrap at 75 columns so they don't go 
over 80 when git log adds 4 spaces at the beginning.



traits and uses the identifier node to look up the specific trait.  Rather
than holding traits as keywords, we set all trait identifiers as cik_trait,
which is a new cp_identifier_kind.  As cik_reserved_for_udlit was unused and
cp_identifier_kind is 3 bits, we replaced the unused field with the new
cik_trait.  Also, the later patch handles a subsequent token to the built-in
identifier so that we accept the use of non-function-like built-in trait
identifiers.

  /* True if this identifier is for any operator name (including
-   conversions).  Value 4, 5, 6 or 7.  */
+   conversions).  Value 4, 5, or 6.  */
  #define IDENTIFIER_ANY_OP_P(NODE) \
-  (IDENTIFIER_KIND_BIT_2 (NODE))
+  (IDENTIFIER_KIND_BIT_2 (NODE) && !IDENTIFIER_TRAIT_P (NODE))

...

+/* True if this identifier is the name of a built-in trait.  */
+#define IDENTIFIER_TRAIT_P(NODE)   \
+  (IDENTIFIER_KIND_BIT_0 (NODE)\
+   && IDENTIFIER_KIND_BIT_1 (NODE) \
+   && IDENTIFIER_KIND_BIT_2 (NODE))


The other macros use &, not &&; we might as well stay consistent with 
that pattern.


Jason



RE: [PATCH 12/19]middle-end: implement loop peeling and IV updates for early break.

2023-10-23 Thread Tamar Christina
> -Original Message-
> From: Richard Biener 
> Sent: Friday, July 14, 2023 2:35 PM
> To: Tamar Christina 
> Cc: gcc-patches@gcc.gnu.org; nd ; j...@ventanamicro.com
> Subject: RE: [PATCH 12/19]middle-end: implement loop peeling and IV
> updates for early break.
> 
> On Thu, 13 Jul 2023, Tamar Christina wrote:
> 
> > > -Original Message-
> > > From: Richard Biener 
> > > Sent: Thursday, July 13, 2023 6:31 PM
> > > To: Tamar Christina 
> > > Cc: gcc-patches@gcc.gnu.org; nd ;
> j...@ventanamicro.com
> > > Subject: Re: [PATCH 12/19]middle-end: implement loop peeling and IV
> > > updates for early break.
> > >
> > > On Wed, 28 Jun 2023, Tamar Christina wrote:
> > >
> > > > Hi All,
> > > >
> > > > This patch updates the peeling code to maintain LCSSA during peeling.
> > > > The rewrite also naturally takes into account multiple exits and so it 
> > > > didn't
> > > > make sense to split them off.
> > > >
> > > > For the purposes of peeling the only change for multiple exits is that 
> > > > the
> > > > secondary exits are all wired to the start of the new loop preheader 
> > > > when
> > > doing
> > > > epilogue peeling.
> > > >
> > > > When doing prologue peeling the CFG is kept in tact.
> > > >
> > > > For both epilogue and prologue peeling we wire through between the
> two
> > > loops any
> > > > PHI nodes that escape the first loop into the second loop if flow_loops 
> > > > is
> > > > specified.  The reason for this conditionality is because
> > > > slpeel_tree_duplicate_loop_to_edge_cfg is used in the compiler in 3 
> > > > ways:
> > > >   - prologue peeling
> > > >   - epilogue peeling
> > > >   - loop distribution
> > > >
> > > > for the last case the loops should remain independent, and so not be
> > > connected.
> > > > Because of this propagation of only used phi nodes get_current_def can
> be
> > > used
> > > > to easily find the previous definitions.  However live statements that 
> > > > are
> > > > not used inside the loop itself are not propagated (since if unused, the
> > > moment
> > > > we add the guard in between the two loops the value across the bypass
> edge
> > > can
> > > > be wrong if the loop has been peeled.)
> > > >
> > > > This is dealt with easily enough in find_guard_arg.
> > > >
> > > > For multiple exits, while we are in LCSSA form, and have a correct DOM
> tree,
> > > the
> > > > moment we add the guard block we will change the dominators again.  To
> > > deal with
> > > > this slpeel_tree_duplicate_loop_to_edge_cfg can optionally return the
> blocks
> > > to
> > > > update without having to recompute the list of blocks to update again.
> > > >
> > > > When multiple exits and doing epilogue peeling we will also temporarily
> have
> > > an
> > > > incorrect VUSES chain for the secondary exits as it anticipates the 
> > > > final
> result
> > > > after the VDEFs have been moved.  This will thus be corrected once the
> code
> > > > motion is applied.
> > > >
> > > > Lastly by doing things this way we can remove the helper functions that
> > > > previously did lock step iterations to update things as it went along.
> > > >
> > > > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> > > >
> > > > Ok for master?
> > >
> > > Not sure if I get through all of this in one go - so be prepared that
> > > the rest of the review follows another day.
> >
> > No worries, I appreciate the reviews!
> > Just giving some quick replies for when you continue.
> 
> Continueing.
> 
> > >
> > > > Thanks,
> > > > Tamar
> > > >
> > > > gcc/ChangeLog:
> > > >
> > > > * tree-loop-distribution.cc (copy_loop_before): Pass flow_loops 
> > > > =
> > > false.
> > > > * tree-ssa-loop-niter.cc (loop_only_exit_p):  Fix bug when 
> > > > exit==null.
> > > > * tree-vect-loop-manip.cc (adjust_phi_and_debug_stmts): Add
> > > additional
> > > > assert.
> > > > (vect_set_loop_condition_normal): Skip modifying loop IV for 
> > > > multiple
> > > > exits.
> > > > (slpeel_tree_duplicate_loop_to_edge_cfg): Support multiple exit
> > > peeling.
> > > > (slpeel_can_duplicate_loop_p): Likewise.
> > > > (vect_update_ivs_after_vectorizer): Don't enter this...
> > > > (vect_update_ivs_after_early_break): ...but instead enter here.
> > > > (find_guard_arg): Update for new peeling code.
> > > > (slpeel_update_phi_nodes_for_loops): Remove.
> > > > (slpeel_update_phi_nodes_for_guard2): Remove hardcoded edge 0
> > > checks.
> > > > (slpeel_update_phi_nodes_for_lcssa): Remove.
> > > > (vect_do_peeling): Fix VF for multiple exits and force epilogue.
> > > > * tree-vect-loop.cc (_loop_vec_info::_loop_vec_info): Initialize
> > > > non_break_control_flow and early_breaks.
> > > > (vect_need_peeling_or_partial_vectors_p): Force partial vector 
> > > > if
> > > > multiple exits and VLA.
> > > > (vect_analyze_loop_form): Support inner loop multiple exits.
> 

Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Martin Uecker
Am Montag, dem 23.10.2023 um 12:52 -0700 schrieb Kees Cook:
> On Fri, Oct 20, 2023 at 09:54:05PM +0200, Martin Uecker wrote:
> > Am Freitag, dem 20.10.2023 um 18:48 + schrieb Qing Zhao:
> > > 
> > > > On Oct 20, 2023, at 2:34 PM, Kees Cook  wrote:
> > > > 
> > > > On Fri, Oct 20, 2023 at 11:50:11AM +0200, Martin Uecker wrote:
> > > > > Am Donnerstag, dem 19.10.2023 um 16:33 -0700 schrieb Kees Cook:
> > > > > > On Wed, Oct 18, 2023 at 09:11:43PM +, Qing Zhao wrote:
> > > > > > > As I replied to Martin in another email, I plan to do the 
> > > > > > > following to resolve this issue:
> > > > > > > 
> > > > > > > 1. No specification for signed or unsigned for counted_by field.
> > > > > > > 2. Add a sanitizer option -fsanitize=counted-by-bound to catch 
> > > > > > > the cases when the size of the counted-by is not positive.
> > > > > > 
> > > > > > I don't understand why this needs to be a runtime sanitizer. The
> > > > > > signedness is known at compile time, so I would expect a -W option.
> > > > > 
> > > > > The signedness of the type but not of the value.
> > > > > 
> > > > > But I would not want to have a warning for signed 
> > > > > counter  types by default because I would prefer
> > > > > to use signed types (for various reasons including
> > > > > better overflow detection).
> > > > > 
> > > > > > Or
> > > > > > do you mean you'd split up -fsanitize=bounds between unsigned and 
> > > > > > signed
> > > > > > indexes? I'd find that kind of awkward for the kernel... but I feel 
> > > > > > like
> > > > > > I've misunderstood something. :)
> > > > > > 
> > > > > > -Kees
> > > > > 
> > > > > The idea would be to detect at run-time the case
> > > > > if  x->buf  is used at a time where   x->counter 
> > > > > is negative and also when x->counter * sizeof(x->buf[0])
> > > > > overflows or is too big.
> > > > > 
> > > > > This would be similar to
> > > > > 
> > > > > int a[n];
> > > > > 
> > > > > where it is detected at run-time if n is not-positive.
> > > > 
> > > > Right. I guess what I mean to say is that I would expect this case to
> > > > already be caught by -fsanitize=bounds -- I don't see a reason to add an
> > > > additional sanitizer option.
> > > > 
> > > > struct foo {
> > > > int count;
> > > > int array[] __counted_by(count);
> > > > };
> > > > 
> > > > foo->count = 5;
> > > > foo->array[0] = 1;  // ok
> > > > foo->array[10] = 1; // -fsanitize=bounds will catch this
> > > > foo->array[-10] = 1;// -fsanitize=bounds will catch this too
> > > > 
> > > > 
> > > 
> > > just checked this testing case with my GCC, and YES, -fsanitize=bounds 
> > > indeed caught this error:
> > > 
> > > ttt_1.c:31:12: runtime error: index 10 out of bounds for type 'char [*]'
> > > ttt_1.c:32:12: runtime error: index -10 out of bounds for type 'char [*]’
> > > 
> > 
> > Yes, but I thought we were discussing the case where count is
> > set to a negative value:
> > 
> > foo->count = -1;
> > int x = foo->array[3]; // UBSan should diagnose this
> 
> Oh right, I keep thinking about it backwards.
> 
> Yeah, we can't trap the "count" assignment, because it may be getting used
> for other purposes. But yeah, access to "array" should trap if "count"
> is negative.
> 
> > And also the case when foo->array becomes too big.
> 
> How do you mean?

count * sizeof(member) could overflow or otherwise be
bigger than allowed.

Martin




Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Kees Cook
On Fri, Oct 20, 2023 at 09:54:05PM +0200, Martin Uecker wrote:
> Am Freitag, dem 20.10.2023 um 18:48 + schrieb Qing Zhao:
> > 
> > > On Oct 20, 2023, at 2:34 PM, Kees Cook  wrote:
> > > 
> > > On Fri, Oct 20, 2023 at 11:50:11AM +0200, Martin Uecker wrote:
> > > > Am Donnerstag, dem 19.10.2023 um 16:33 -0700 schrieb Kees Cook:
> > > > > On Wed, Oct 18, 2023 at 09:11:43PM +, Qing Zhao wrote:
> > > > > > As I replied to Martin in another email, I plan to do the following 
> > > > > > to resolve this issue:
> > > > > > 
> > > > > > 1. No specification for signed or unsigned for counted_by field.
> > > > > > 2. Add a sanitizer option -fsanitize=counted-by-bound to catch the 
> > > > > > cases when the size of the counted-by is not positive.
> > > > > 
> > > > > I don't understand why this needs to be a runtime sanitizer. The
> > > > > signedness is known at compile time, so I would expect a -W option.
> > > > 
> > > > The signedness of the type but not of the value.
> > > > 
> > > > But I would not want to have a warning for signed 
> > > > counter  types by default because I would prefer
> > > > to use signed types (for various reasons including
> > > > better overflow detection).
> > > > 
> > > > > Or
> > > > > do you mean you'd split up -fsanitize=bounds between unsigned and 
> > > > > signed
> > > > > indexes? I'd find that kind of awkward for the kernel... but I feel 
> > > > > like
> > > > > I've misunderstood something. :)
> > > > > 
> > > > > -Kees
> > > > 
> > > > The idea would be to detect at run-time the case
> > > > if  x->buf  is used at a time where   x->counter 
> > > > is negative and also when x->counter * sizeof(x->buf[0])
> > > > overflows or is too big.
> > > > 
> > > > This would be similar to
> > > > 
> > > > int a[n];
> > > > 
> > > > where it is detected at run-time if n is not-positive.
> > > 
> > > Right. I guess what I mean to say is that I would expect this case to
> > > already be caught by -fsanitize=bounds -- I don't see a reason to add an
> > > additional sanitizer option.
> > > 
> > > struct foo {
> > >   int count;
> > >   int array[] __counted_by(count);
> > > };
> > > 
> > >   foo->count = 5;
> > >   foo->array[0] = 1;  // ok
> > >   foo->array[10] = 1; // -fsanitize=bounds will catch this
> > >   foo->array[-10] = 1;// -fsanitize=bounds will catch this too
> > > 
> > > 
> > 
> > just checked this testing case with my GCC, and YES, -fsanitize=bounds 
> > indeed caught this error:
> > 
> > ttt_1.c:31:12: runtime error: index 10 out of bounds for type 'char [*]'
> > ttt_1.c:32:12: runtime error: index -10 out of bounds for type 'char [*]’
> > 
> 
> Yes, but I thought we were discussing the case where count is
> set to a negative value:
> 
> foo->count = -1;
> int x = foo->array[3]; // UBSan should diagnose this

Oh right, I keep thinking about it backwards.

Yeah, we can't trap the "count" assignment, because it may be getting used
for other purposes. But yeah, access to "array" should trap if "count"
is negative.

> And also the case when foo->array becomes too big.

How do you mean?

-- 
Kees Cook


Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Qing Zhao


> On Oct 23, 2023, at 2:43 PM, Siddhesh Poyarekar  wrote:
> 
> On 2023-10-23 14:06, Martin Uecker wrote:
>> We should aim for a good integration with the BDOS pass, so
>> that it can propagate the information further, e.g. the
>> following should work:
>> struct { int L; char buf[] __counted_by(L) } x;
>> x.L = N;
>> x.buf = ...;
>> char *p = >f;
>> __bdos(p) -> N
>> So we need to be smart on how we provide the size
>> information for x->f to the backend.
>> This would also be desirable for the language extension.
> 
> This is essentially why there need to be frontend rules constraining 
> reordering and reachability semantics of x.L, thus restricting DSE and 
> reordering for it.

My understanding is that Restricting DSE and reordering should be done by the 
proper data flow information, with a new argument added to the BDOS call, this 
correct data flow information could be maintained, and then the DSE and 
reordering will not happen. 

I don’t quite understand what kind of frontend rules should be added to 
constrain reordering and reachability semantics? Can you explain this a little 
bit more? Do you mean to add some rules or requirment to the new attribute that 
the users of the attribute should follow in the source code? 

>  This is not really a __bdos/__bos question, because that bit is trivial; if 
> the structure is visible, the value is simply x.L.  This is also why adding a 
> reference to x.L in __bos/__bdos is not sufficient or even possible in, e.g. 
> the above case you note.

I am a little confused here, are we discussing how to resolve the potential 
reordering issue of the following:

"
struct annotated {
  size_t foo;
  char array[] __attribute__((counted_by (foo)));
};

  p->foo = 10;
  size = __builtin_dynamic_object_size (p->array,1);
“?

Or a bigger issue?

Qing

> 
> Thanks,
> Sid



Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Martin Uecker
Am Montag, dem 23.10.2023 um 19:00 + schrieb Qing Zhao:
> 
> > On Oct 23, 2023, at 2:31 PM, Martin Uecker  wrote:
> > 
> > Am Montag, dem 23.10.2023 um 20:06 +0200 schrieb Martin Uecker:
> > > Am Montag, dem 23.10.2023 um 16:37 + schrieb Qing Zhao:
> > > > 
> > > > > On Oct 23, 2023, at 11:57 AM, Richard Biener 
> > > > >  wrote:
> > > > > 
> > > > > 
> > > > > 
> > > > > > Am 23.10.2023 um 16:56 schrieb Qing Zhao :
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > > On Oct 23, 2023, at 3:57 AM, Richard Biener 
> > > > > > >  wrote:
> > > > > > > 
> > > > > > > > On Fri, Oct 20, 2023 at 10:41 PM Qing Zhao 
> > > > > > > >  wrote:
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > > On Oct 20, 2023, at 3:10 PM, Siddhesh Poyarekar 
> > > > > > > > >  wrote:
> > > > > > > > > 
> > > > > > > > > On 2023-10-20 14:38, Qing Zhao wrote:
> > > > > > > > > > How about the following:
> > > > > > > > > > Add one more parameter to __builtin_dynamic_object_size(), 
> > > > > > > > > > i.e
> > > > > > > > > > __builtin_dynamic_object_size (_1,1,array_annotated->foo)?
> > > > > > > > > > When we see the structure field has counted_by attribute.
> > > > > > > > > 
> > > > > > > > > Or maybe add a barrier preventing any assignments to 
> > > > > > > > > array_annotated->foo from being reordered below the __bdos 
> > > > > > > > > call? Basically an __asm__ with array_annotated->foo in the 
> > > > > > > > > clobber list ought to do it I think.
> > > > > > > > 
> > > > > > > > Maybe just adding the array_annotated->foo to the use list of 
> > > > > > > > the call to __builtin_dynamic_object_size should be enough?
> > > > > > > > 
> > > > > > > > But I am not sure how to implement this in the TREE level, is 
> > > > > > > > there a USE_LIST/CLOBBER_LIST for each call?  Then I can just 
> > > > > > > > simply add the counted_by field “array_annotated->foo” to the 
> > > > > > > > USE_LIST of the call to __bdos?
> > > > > > > > 
> > > > > > > > This might be the simplest solution?
> > > > > > > 
> > > > > > > If the dynamic object size is derived of a field then I think you 
> > > > > > > need to
> > > > > > > put the "load" of that memory location at the point (as argument)
> > > > > > > of the __bos call right at parsing time.  I know that's awkward 
> > > > > > > because
> > > > > > > you try to play tricks "discovering" that field only late, but 
> > > > > > > that's not
> > > > > > > going to work.
> > > > > > 
> > > > > > Is it better to do this at gimplification phase instead of FE? 
> > > > > > 
> > > > > > VLA decls are handled in gimplification phase, the size calculation 
> > > > > > and call to alloca are all generated during this phase. 
> > > > > > (gimplify_vla_decl).
> > > > > > 
> > > > > > For __bdos calls, we can add an additional argument if the object’s 
> > > > > > first argument’s type include the counted_by attribute, i.e
> > > > > > 
> > > > > > ***During gimplification, 
> > > > > > For a call to __builtin_dynamic_object_size (ptr, type)
> > > > > > Check whether the type of ptr includes counted_by attribute, if so, 
> > > > > > change the call to
> > > > > > __builtin_dynamic_object_size (ptr, type, counted_by field)
> > > > > > 
> > > > > > Then the correct data dependence should be represented well in the 
> > > > > > IR.
> > > > > > 
> > > > > > **During object size phase,
> > > > > > 
> > > > > > The call to __builtin_dynamic_object_size will become an expression 
> > > > > > includes the counted_by field or -1/0 when we cannot decide the 
> > > > > > size, the correct data dependence will be kept even the call to 
> > > > > > __builtin_dynamic_object_size is gone. 
> > > > > 
> > > > > But the whole point of the BOS pass is to derive information that is 
> > > > > not available at parsing time, and that’s the cases you are after.  
> > > > > The case where the connection to the field with the length is 
> > > > > apparent during parsing is easy - you simply insert a load of the 
> > > > > value before the BOS call.
> > > > 
> > > > Yes, this is true. 
> > > > I prefer to implement this in gimplification phase since I am more 
> > > > familiar with the code there.. (I think that implementing it in 
> > > > gimplification should be very similar as implementing it in FE? Or do I 
> > > > miss anything here?)
> > > > 
> > > > Joseph, if implement this in FE, where in the FE I should look at? 
> > > > 
> > > 
> > > We should aim for a good integration with the BDOS pass, so
> > > that it can propagate the information further, e.g. the 
> > > following should work:
> > > 
> > > struct { int L; char buf[] __counted_by(L) } x;
> > > x.L = N;
> > > x.buf = ...;
> > > char *p = >f;
> > > __bdos(p) -> N
> > > 
> > > So we need to be smart on how we provide the size
> > > information for x->f to the backend. 
> > 
> > To follow up on this. I do not think we should change the
> > builtin in the FE or gimplification. Instead, we want 
> > to change the field access and compute the 

Re: [PATCH v1 1/1] gcc: config: microblaze: fix cpu version check

2023-10-23 Thread Michael Eager

On 10/23/23 11:37, Frager, Neal wrote:





Le 23 oct. 2023 à 18:40, Michael Eager  a écrit :

On 10/22/23 22:48, Neal Frager wrote:

There is a microblaze cpu version 10.0 included in versal. If the
minor version is only a single digit, then the version comparison
will fail as version 10.0 will appear as 100 compared to version
6.00 or 8.30 which will calculate to values 600 and 830.
The issue can be seen when using the '-mcpu=10.0' option.
With this fix, versions with a single digit minor number such as
10.0 will be calculated as greater than versions with a smaller
major version number, but with two minor version digits.
By applying this fix, several incorrect warning messages will no
longer be printed when building the versal plm application, such
as the warning message below:
warning: '-mxl-multiply-high' can be used only with '-mcpu=v6.00.a' or greater
Signed-off-by: Neal Frager 
---
  gcc/config/microblaze/microblaze.cc | 164 +---
  1 file changed, 76 insertions(+), 88 deletions(-)


Please add a test case.

--
Michael Eager


Hi Michael,

Would you mind helping me understand how to make a gcc test case for this patch?

This patch does not change the resulting binaries of a microblaze gcc build.  
The output will be the same with our without the patch, so I do not having 
anything in the binary itself to verify.

All that happens is false warning messages will not be printed when building 
with ‘-mcpu=10.0’.  Is there a way to test for warning messages?

In any case, please do not commit v1 of this patch.  I am going to work on 
making a v2 based on Mark’s feedback.


You can create a test case which passes the -mcpu=10.0 and other options
to GCC and verify that the message is not generated after the patch is
applied.

You can make all GCC warnings into errors with the "-Werror" option.
This means that the compile will fail if the warning is issued.

Take a look at gcc/testsuite/gcc.target/aarch64/bti-1.c for an example
of using { dg-options "" } to specify command line options.

There is a test suite option (dg-warning) which checks that a particular
source line generates a warning message, but it isn't clear whether is
is possible to check that a warning is not issued.

--
Michael Eager


[PATCH v3] gcc: Introduce -fhardened

2023-10-23 Thread Marek Polacek
On Thu, Oct 19, 2023 at 02:24:11PM +0200, Richard Biener wrote:
> On Wed, Oct 11, 2023 at 10:48 PM Marek Polacek  wrote:
> >
> > On Tue, Sep 19, 2023 at 10:58:19AM -0400, Marek Polacek wrote:
> > > On Mon, Sep 18, 2023 at 08:57:39AM +0200, Richard Biener wrote:
> > > > On Fri, Sep 15, 2023 at 5:09 PM Marek Polacek via Gcc-patches
> > > >  wrote:
> > > > >
> > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, 
> > > > > powerpc64le-unknown-linux-gnu,
> > > > > and aarch64-unknown-linux-gnu; ok for trunk?
> > > > >
> > > > > -- >8 --
> > > > > In 
> > > > > I proposed -fhardened, a new umbrella option that enables a 
> > > > > reasonable set
> > > > > of hardening flags.  The read of the room seems to be that the option
> > > > > would be useful.  So here's a patch implementing that option.
> > > > >
> > > > > Currently, -fhardened enables:
> > > > >
> > > > >   -D_FORTIFY_SOURCE=3 (or =2 for older glibcs)
> > > > >   -D_GLIBCXX_ASSERTIONS
> > > > >   -ftrivial-auto-var-init=pattern
> 
> I think =zero is much better here given the overhead is way
> cheaper and pointers get a more reliable behavior.

Ok, changed now.
 
> > > > >   -fPIE  -pie  -Wl,-z,relro,-z,now
> > > > >   -fstack-protector-strong
> > > > >   -fstack-clash-protection
> > > > >   -fcf-protection=full (x86 GNU/Linux only)
> > > > >
> > > > > -fhardened will not override options that were specified on the 
> > > > > command line
> > > > > (before or after -fhardened).  For example,
> > > > >
> > > > >  -D_FORTIFY_SOURCE=1 -fhardened
> > > > >
> > > > > means that _FORTIFY_SOURCE=1 will be used.  Similarly,
> > > > >
> > > > >   -fhardened -fstack-protector
> > > > >
> > > > > will not enable -fstack-protector-strong.
> > > > >
> > > > > In DW_AT_producer it is reflected only as -fhardened; it doesn't 
> > > > > expand
> > > > > to anything.  I think we need a better way to show what it actually
> > > > > enables.
> > > >
> > > > I do think we need to find a solution here to solve asserting 
> > > > compliance.
> > >
> > > Fair enough.
> > >
> > > > Maybe we can have -Whardened that will diagnose any altering of
> > > > -fhardened by other options on the command-line or by missed target
> > > > implementations?  People might for example use -fstack-protector
> > > > but don't really want to make protection lower than requested with 
> > > > -fhardened.
> > > >
> > > > Any such conflict is much less appearant than when you use the
> > > > flags -fhardened composes.
> > >
> > > How about: --help=hardened says which options -fhardened attempts to
> > > enable, and -Whardened warns when it didn't enable an option?  E.g.,
> > >
> > >   -fstack-protector -fhardened -Whardened
> > >
> > > would say that it didn't enable -fstack-protector-strong because
> > > -fstack-protector was specified on the command line?
> > >
> > > If !HAVE_LD_NOW_SUPPORT, --help=hardened probably doesn't even have to
> > > list -z now, likewise for -z relro.
> > >
> > > Unclear if -Whardened should be enabled by default, but probably yes?
> >
> > Here's v2 which adds -Whardened (enabled by default).
> >
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> I think it's OK but I'd like to see a second ACK here.  

Thanks!

> Can you see how our
> primary and secondary targets (+ host OS) behave here?

That's very reasonable.  I tried to build gcc on Compile Farm 119 (AIX) but
that fails with:

ar  -X64 x ../ppc64/libgcc/libgcc_s.a shr.o
ar: 0707-100 ../ppc64/libgcc/libgcc_s.a does not exist.
make[2]: *** [/home/polacek/gcc/libgcc/config/rs6000/t-slibgcc-aix:98: all] 
Error 1
make[2]: Leaving directory '/home/polacek/x/trunk/powerpc-ibm-aix7.3.1.0/libgcc'

and I tried Darwin (104) and that fails with

*** Configuration aarch64-apple-darwin21.6.0 not supported

Is anyone else able to build gcc on those machines, or test the attached
patch?

> I think the
> documentation should elaborate a bit on expectations for non-Linux/GNU
> targets, specifically I think the default configuration for a target should
> with -fhardened _not_ have any -Whardened diagnostics.  Maybe we can
> have a testcase for this?

Sorry, I'm not sure how to test that.  I suppose if -fhardened enables
something not supported on those systems, and it's something for which
we have a configure test, then we shouldn't warn.  This is already the
case for -pie, -z relro, and -z now.  

Should the docs say something like the following for features without
configure checks?

@option{-fhardened} can, on certain systems, attempt to enable features
not supported on that particular system.  In that case, it's possible to
prevent the warning using the @option{-Wno-hardened} option.

I've added a line saying:

+This option is intended to be used in production builds, not merely
+in debug builds.

-- >8 --
In 
I proposed -fhardened, a new umbrella option that enables 

Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Qing Zhao


> On Oct 23, 2023, at 2:31 PM, Martin Uecker  wrote:
> 
> Am Montag, dem 23.10.2023 um 20:06 +0200 schrieb Martin Uecker:
>> Am Montag, dem 23.10.2023 um 16:37 + schrieb Qing Zhao:
>>> 
 On Oct 23, 2023, at 11:57 AM, Richard Biener  
 wrote:
 
 
 
> Am 23.10.2023 um 16:56 schrieb Qing Zhao :
> 
> 
> 
>> On Oct 23, 2023, at 3:57 AM, Richard Biener  
>> wrote:
>> 
>>> On Fri, Oct 20, 2023 at 10:41 PM Qing Zhao  wrote:
>>> 
>>> 
>>> 
 On Oct 20, 2023, at 3:10 PM, Siddhesh Poyarekar  
 wrote:
 
 On 2023-10-20 14:38, Qing Zhao wrote:
> How about the following:
> Add one more parameter to __builtin_dynamic_object_size(), i.e
> __builtin_dynamic_object_size (_1,1,array_annotated->foo)?
> When we see the structure field has counted_by attribute.
 
 Or maybe add a barrier preventing any assignments to 
 array_annotated->foo from being reordered below the __bdos call? 
 Basically an __asm__ with array_annotated->foo in the clobber list 
 ought to do it I think.
>>> 
>>> Maybe just adding the array_annotated->foo to the use list of the call 
>>> to __builtin_dynamic_object_size should be enough?
>>> 
>>> But I am not sure how to implement this in the TREE level, is there a 
>>> USE_LIST/CLOBBER_LIST for each call?  Then I can just simply add the 
>>> counted_by field “array_annotated->foo” to the USE_LIST of the call to 
>>> __bdos?
>>> 
>>> This might be the simplest solution?
>> 
>> If the dynamic object size is derived of a field then I think you need to
>> put the "load" of that memory location at the point (as argument)
>> of the __bos call right at parsing time.  I know that's awkward because
>> you try to play tricks "discovering" that field only late, but that's not
>> going to work.
> 
> Is it better to do this at gimplification phase instead of FE? 
> 
> VLA decls are handled in gimplification phase, the size calculation and 
> call to alloca are all generated during this phase. (gimplify_vla_decl).
> 
> For __bdos calls, we can add an additional argument if the object’s first 
> argument’s type include the counted_by attribute, i.e
> 
> ***During gimplification, 
> For a call to __builtin_dynamic_object_size (ptr, type)
> Check whether the type of ptr includes counted_by attribute, if so, 
> change the call to
> __builtin_dynamic_object_size (ptr, type, counted_by field)
> 
> Then the correct data dependence should be represented well in the IR.
> 
> **During object size phase,
> 
> The call to __builtin_dynamic_object_size will become an expression 
> includes the counted_by field or -1/0 when we cannot decide the size, the 
> correct data dependence will be kept even the call to 
> __builtin_dynamic_object_size is gone. 
 
 But the whole point of the BOS pass is to derive information that is not 
 available at parsing time, and that’s the cases you are after.  The case 
 where the connection to the field with the length is apparent during 
 parsing is easy - you simply insert a load of the value before the BOS 
 call.
>>> 
>>> Yes, this is true. 
>>> I prefer to implement this in gimplification phase since I am more familiar 
>>> with the code there.. (I think that implementing it in gimplification 
>>> should be very similar as implementing it in FE? Or do I miss anything 
>>> here?)
>>> 
>>> Joseph, if implement this in FE, where in the FE I should look at? 
>>> 
>> 
>> We should aim for a good integration with the BDOS pass, so
>> that it can propagate the information further, e.g. the 
>> following should work:
>> 
>> struct { int L; char buf[] __counted_by(L) } x;
>> x.L = N;
>> x.buf = ...;
>> char *p = >f;
>> __bdos(p) -> N
>> 
>> So we need to be smart on how we provide the size
>> information for x->f to the backend. 
> 
> To follow up on this. I do not think we should change the
> builtin in the FE or gimplification. Instead, we want 
> to change the field access and compute the size there. 
Could you please clarify on this? What do you mean by "change the field access 
and compute the size there”?
> 
> In my toy patch I then made this have a VLA type that 
> encodes the size.  Here, this would need to be done 
> differently.
> 
> But still, what we are missing in both cases
> is a proper way to pass the information down to BDOS.

What’ s the issue with adding a new argument (x.L) to the BDOS call? What’s 
missing with this approach?

> 
> For VLAs this works because BDOS can see the size of
> the definition.  For calls to allocation functions
> it is read from an attribute. 

You mean for VLA, BDOS see the size of the definition from the attribute for 
the allocation function?
Yes, that’s the case for VLA. 

For VLA, the size computation and 

Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Martin Uecker
Am Montag, dem 23.10.2023 um 14:43 -0400 schrieb Siddhesh Poyarekar:
> On 2023-10-23 14:06, Martin Uecker wrote:
> > We should aim for a good integration with the BDOS pass, so
> > that it can propagate the information further, e.g. the
> > following should work:
> > 
> > struct { int L; char buf[] __counted_by(L) } x;
> > x.L = N;
> > x.buf = ...;
> > char *p = >f;
> > __bdos(p) -> N
> > 
> > So we need to be smart on how we provide the size
> > information for x->f to the backend.
> > 
> > This would also be desirable for the language extension.
> 
> This is essentially why there need to be frontend rules constraining 
> reordering and reachability semantics of x.L, thus restricting DSE and 
> reordering for it. 

Yes, this too.

>  This is not really a __bdos/__bos question, because 
> that bit is trivial; if the structure is visible, the value is simply 
> x.L.  This is also why adding a reference to x.L in __bos/__bdos is not 
> sufficient or even possible in, e.g. the above case you note.

The value x.L may change in time. I would argue that it needs
to be the value of x.L at the time where x.buf (not x->f, sorry) 
is accessed.  So the FE needs to evaluate x.L when x.buf is
accessed and store the value somewhere where __bdos can find
it later.  In the type information would make sense.

But I am not sure how to do this in the best way so that this 
information is not removed later when not used explicitely
before __bdos tries to look at it.

Martin





Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Siddhesh Poyarekar

On 2023-10-23 14:06, Martin Uecker wrote:

We should aim for a good integration with the BDOS pass, so
that it can propagate the information further, e.g. the
following should work:

struct { int L; char buf[] __counted_by(L) } x;
x.L = N;
x.buf = ...;
char *p = >f;
__bdos(p) -> N

So we need to be smart on how we provide the size
information for x->f to the backend.

This would also be desirable for the language extension.


This is essentially why there need to be frontend rules constraining 
reordering and reachability semantics of x.L, thus restricting DSE and 
reordering for it.  This is not really a __bdos/__bos question, because 
that bit is trivial; if the structure is visible, the value is simply 
x.L.  This is also why adding a reference to x.L in __bos/__bdos is not 
sufficient or even possible in, e.g. the above case you note.


Thanks,
Sid


Re: [PATCH v1 1/1] gcc: config: microblaze: fix cpu version check

2023-10-23 Thread Frager, Neal



> Le 23 oct. 2023 à 18:40, Michael Eager  a écrit :
> 
> On 10/22/23 22:48, Neal Frager wrote:
>> There is a microblaze cpu version 10.0 included in versal. If the
>> minor version is only a single digit, then the version comparison
>> will fail as version 10.0 will appear as 100 compared to version
>> 6.00 or 8.30 which will calculate to values 600 and 830.
>> The issue can be seen when using the '-mcpu=10.0' option.
>> With this fix, versions with a single digit minor number such as
>> 10.0 will be calculated as greater than versions with a smaller
>> major version number, but with two minor version digits.
>> By applying this fix, several incorrect warning messages will no
>> longer be printed when building the versal plm application, such
>> as the warning message below:
>> warning: '-mxl-multiply-high' can be used only with '-mcpu=v6.00.a' or 
>> greater
>> Signed-off-by: Neal Frager 
>> ---
>>  gcc/config/microblaze/microblaze.cc | 164 +---
>>  1 file changed, 76 insertions(+), 88 deletions(-)
> 
> Please add a test case.
> 
> --
> Michael Eager

Hi Michael,

Would you mind helping me understand how to make a gcc test case for this patch?

This patch does not change the resulting binaries of a microblaze gcc build.  
The output will be the same with our without the patch, so I do not having 
anything in the binary itself to verify.

All that happens is false warning messages will not be printed when building 
with ‘-mcpu=10.0’.  Is there a way to test for warning messages?

In any case, please do not commit v1 of this patch.  I am going to work on 
making a v2 based on Mark’s feedback.

Thanks for your help!

Best regards,
Neal Frager
AMD



Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Qing Zhao


> On Oct 23, 2023, at 2:06 PM, Martin Uecker  wrote:
> 
> Am Montag, dem 23.10.2023 um 16:37 + schrieb Qing Zhao:
>> 
>>> On Oct 23, 2023, at 11:57 AM, Richard Biener  
>>> wrote:
>>> 
>>> 
>>> 
 Am 23.10.2023 um 16:56 schrieb Qing Zhao :
 
 
 
> On Oct 23, 2023, at 3:57 AM, Richard Biener  
> wrote:
> 
>> On Fri, Oct 20, 2023 at 10:41 PM Qing Zhao  wrote:
>> 
>> 
>> 
>>> On Oct 20, 2023, at 3:10 PM, Siddhesh Poyarekar  
>>> wrote:
>>> 
>>> On 2023-10-20 14:38, Qing Zhao wrote:
 How about the following:
 Add one more parameter to __builtin_dynamic_object_size(), i.e
 __builtin_dynamic_object_size (_1,1,array_annotated->foo)?
 When we see the structure field has counted_by attribute.
>>> 
>>> Or maybe add a barrier preventing any assignments to 
>>> array_annotated->foo from being reordered below the __bdos call? 
>>> Basically an __asm__ with array_annotated->foo in the clobber list 
>>> ought to do it I think.
>> 
>> Maybe just adding the array_annotated->foo to the use list of the call 
>> to __builtin_dynamic_object_size should be enough?
>> 
>> But I am not sure how to implement this in the TREE level, is there a 
>> USE_LIST/CLOBBER_LIST for each call?  Then I can just simply add the 
>> counted_by field “array_annotated->foo” to the USE_LIST of the call to 
>> __bdos?
>> 
>> This might be the simplest solution?
> 
> If the dynamic object size is derived of a field then I think you need to
> put the "load" of that memory location at the point (as argument)
> of the __bos call right at parsing time.  I know that's awkward because
> you try to play tricks "discovering" that field only late, but that's not
> going to work.
 
 Is it better to do this at gimplification phase instead of FE? 
 
 VLA decls are handled in gimplification phase, the size calculation and 
 call to alloca are all generated during this phase. (gimplify_vla_decl).
 
 For __bdos calls, we can add an additional argument if the object’s first 
 argument’s type include the counted_by attribute, i.e
 
 ***During gimplification, 
 For a call to __builtin_dynamic_object_size (ptr, type)
 Check whether the type of ptr includes counted_by attribute, if so, change 
 the call to
 __builtin_dynamic_object_size (ptr, type, counted_by field)
 
 Then the correct data dependence should be represented well in the IR.
 
 **During object size phase,
 
 The call to __builtin_dynamic_object_size will become an expression 
 includes the counted_by field or -1/0 when we cannot decide the size, the 
 correct data dependence will be kept even the call to 
 __builtin_dynamic_object_size is gone. 
>>> 
>>> But the whole point of the BOS pass is to derive information that is not 
>>> available at parsing time, and that’s the cases you are after.  The case 
>>> where the connection to the field with the length is apparent during 
>>> parsing is easy - you simply insert a load of the value before the BOS call.
>> 
>> Yes, this is true. 
>> I prefer to implement this in gimplification phase since I am more familiar 
>> with the code there.. (I think that implementing it in gimplification should 
>> be very similar as implementing it in FE? Or do I miss anything here?)
>> 
>> Joseph, if implement this in FE, where in the FE I should look at? 
>> 
> 
> We should aim for a good integration with the BDOS pass, so
> that it can propagate the information further, e.g. the 
> following should work:
> 
> struct { int L; char buf[] __counted_by(L) } x;
> x.L = N;
> x.buf = ...;
> char *p = >f;
Is the above line should be: 
char *p = 
?
> __bdos(p) -> N
> 
> So we need to be smart on how we provide the size
> information for x->f to the backend. 

Do you have any other suggestion here?

(Right now, what we’d like to do is to add one more argument for the function 
__bdos as
 __bdos (p, type, x.L))
> 
> This would also be desirable for the language extension. 

Yes.

Qing
> 
> Martin
> 
> 
>> Thanks a lot for the help.
>> 
>> Qing
>> 
>>> For the late case there’s no way to invent data flow dependence without 
>>> inadvertently pessimizing optimization.
>>> 
>>> Richard 
>>> 
 
> 
> A related issue is that assignment to the field and storage allocation
> are not tied together
 
 Yes, this is different from VLA, in which, the size assignment and the 
 storage allocation are generated and tied together by the compiler.
 
 For the flexible array member, the storage allocation and the size 
 assignment are all done by the user. So, We need to clarify such 
 requirement  in the document to guide user to write correct code.  And 
 also, we might need to provide tools (warnings and sanitizer option) to 
 help users to catch such coding error.
 
> - if 

Re: [PATCH v9 4/4] ree: Improve ree pass for rs6000 target using defined ABI interfaces

2023-10-23 Thread Vineet Gupta




On 10/22/23 23:46, Ajit Agarwal wrote:

Hello All:

Addressed below review comments in the version 11 of the patch.
Please review and please let me know if its ok for trunk.

Thanks & Regards
Ajit


Again you are not paying attention to prior comments about fixing your 
submission practice and like some of the prior reviewers I'm starting to 
get tired, despite potentially good technical content.


1. The commentary above is NOT part of changelog. Either use a separate 
cover letter or add patch version change history between two "---" lines 
just before the start of code diff. And keep accumulating those as you 
post new versions. See [1]. This is so reviewers knwo what changed over 
10 months and automatically gets dropped when patch is eventually 
applied/merged into tree.


2. Acknowledge (even if it is yes) each and every comment of the 
reviewerw explicitly inline below. That ensures you don't miss 
addressing a change since this forces one to think about each of them.


I do have some technical comments which I'll follow up with later.
Just a short summary that v10 indeed bootstraps risc-v but I don't see 
any improvements at all - as in whenever abi interfaces code identifies 
and extension (saw missing a definition, the it is not able to eliminate 
any extensions despite the patch.


-Vineet

[1] https://gcc.gnu.org/pipermail/gcc-patches/2023-October/632180.html



On 22/10/23 12:56 am, rep.dot@gmail.com wrote:

On 21 October 2023 01:56:16 CEST, Vineet Gupta  wrote:

On 10/19/23 23:50, Ajit Agarwal wrote:

Hello All:

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

In this version (version 9) of the patch following review comments are 
incorporated.

a) Removal of hard code zero_extend and sign_extend  in abi interfaces.
b) Source and destination with different registers are considered.
c) Further enhancements.
d) Added sign extension elimination using abi interfaces.

As has been trend in the past, I don't think all the review comments have been 
addressed.

And apart from that, may I ask if this is just me, or does anybody else think 
that it might be worthwhile to actually read a patch before (re-)posting?

Seeing e.g. the proposed abi_extension_candidate_p as written in a first POC 
would deserve some manual CSE, if nothing more then for clarity and conciseness?

Just curious from a meta perspective..

And:


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

mentioning powerpc like this, and then changing generic code could be 
interpreted as misleading, IMHO.


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

Mentioning powerpc in the body as one of the affected target(s) is of course 
fine.



   +/* Return TRUE if target mode is equal to source mode of zero_extend
+   or sign_extend otherwise false.  */

, false otherwise.

But I'm not a native speaker



+/* Return TRUE if the candidate insn is zero extend and regno is
+   a return registers.  */
+
+static bool
+abi_extension_candidate_return_reg_p (/*rtx_insn *insn, */int regno)

Leftover debug comment.


+{
+  if (targetm.calls.function_value_regno_p (regno))
+return true;
+
+  return false;
+}
+

As said, I don't see why the below was not cleaned up before the V1 submission.
Iff it breaks when manually CSEing, I'm curious why?


+/* Return TRUE if reg source operand of zero_extend is argument registers
+   and not return registers and source and destination operand are same
+   and mode of source and destination operand are not same.  */
+
+static bool
+abi_extension_candidate_p (rtx_insn *insn)
+{
+  rtx set = single_set (insn);
+  machine_mode dst_mode = GET_MODE (SET_DEST (set));
+  rtx orig_src = XEXP (SET_SRC (set), 0);
+
+  if (!FUNCTION_ARG_REGNO_P (REGNO (orig_src))
+  || abi_extension_candidate_return_reg_p (/*insn,*/ REGNO (orig_src)))

On top, debug leftover.


+return false;
+
+  /* Mode of destination and source should be different.  */
+  if (dst_mode == GET_MODE (orig_src))
+return false;
+
+  machine_mode mode = GET_MODE (XEXP (SET_SRC (set), 0));
+  bool promote_p = abi_target_promote_function_mode (mode);
+
+  /* REGNO of source and destination should be same if not
+  promoted.  */
+  if (!promote_p && REGNO (SET_DEST (set)) != REGNO (orig_src))
+return false;
+
+  return true;
+}
+

As said, please also rephrase the above (and everything else if it obviously 
looks akin the above).

The rest, mentioned below,  should largely be covered by following the coding 
convention.


+/* Return TRUE if the candidate insn is zero extend and regno is
+   an argument registers.  */

Singular register.


+
+static bool
+abi_extension_candidate_argno_p (/*rtx_code code, */int regno)

Debug leftover.
I would probably have inlined this function manually, with a 

Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Martin Uecker
Am Montag, dem 23.10.2023 um 20:06 +0200 schrieb Martin Uecker:
> Am Montag, dem 23.10.2023 um 16:37 + schrieb Qing Zhao:
> > 
> > > On Oct 23, 2023, at 11:57 AM, Richard Biener  
> > > wrote:
> > > 
> > > 
> > > 
> > > > Am 23.10.2023 um 16:56 schrieb Qing Zhao :
> > > > 
> > > > 
> > > > 
> > > > > On Oct 23, 2023, at 3:57 AM, Richard Biener 
> > > > >  wrote:
> > > > > 
> > > > > > On Fri, Oct 20, 2023 at 10:41 PM Qing Zhao  
> > > > > > wrote:
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > > On Oct 20, 2023, at 3:10 PM, Siddhesh Poyarekar 
> > > > > > >  wrote:
> > > > > > > 
> > > > > > > On 2023-10-20 14:38, Qing Zhao wrote:
> > > > > > > > How about the following:
> > > > > > > > Add one more parameter to __builtin_dynamic_object_size(), i.e
> > > > > > > > __builtin_dynamic_object_size (_1,1,array_annotated->foo)?
> > > > > > > > When we see the structure field has counted_by attribute.
> > > > > > > 
> > > > > > > Or maybe add a barrier preventing any assignments to 
> > > > > > > array_annotated->foo from being reordered below the __bdos call? 
> > > > > > > Basically an __asm__ with array_annotated->foo in the clobber 
> > > > > > > list ought to do it I think.
> > > > > > 
> > > > > > Maybe just adding the array_annotated->foo to the use list of the 
> > > > > > call to __builtin_dynamic_object_size should be enough?
> > > > > > 
> > > > > > But I am not sure how to implement this in the TREE level, is there 
> > > > > > a USE_LIST/CLOBBER_LIST for each call?  Then I can just simply add 
> > > > > > the counted_by field “array_annotated->foo” to the USE_LIST of the 
> > > > > > call to __bdos?
> > > > > > 
> > > > > > This might be the simplest solution?
> > > > > 
> > > > > If the dynamic object size is derived of a field then I think you 
> > > > > need to
> > > > > put the "load" of that memory location at the point (as argument)
> > > > > of the __bos call right at parsing time.  I know that's awkward 
> > > > > because
> > > > > you try to play tricks "discovering" that field only late, but that's 
> > > > > not
> > > > > going to work.
> > > > 
> > > > Is it better to do this at gimplification phase instead of FE? 
> > > > 
> > > > VLA decls are handled in gimplification phase, the size calculation and 
> > > > call to alloca are all generated during this phase. (gimplify_vla_decl).
> > > > 
> > > > For __bdos calls, we can add an additional argument if the object’s 
> > > > first argument’s type include the counted_by attribute, i.e
> > > > 
> > > > ***During gimplification, 
> > > > For a call to __builtin_dynamic_object_size (ptr, type)
> > > > Check whether the type of ptr includes counted_by attribute, if so, 
> > > > change the call to
> > > > __builtin_dynamic_object_size (ptr, type, counted_by field)
> > > > 
> > > > Then the correct data dependence should be represented well in the IR.
> > > > 
> > > > **During object size phase,
> > > > 
> > > > The call to __builtin_dynamic_object_size will become an expression 
> > > > includes the counted_by field or -1/0 when we cannot decide the size, 
> > > > the correct data dependence will be kept even the call to 
> > > > __builtin_dynamic_object_size is gone. 
> > > 
> > > But the whole point of the BOS pass is to derive information that is not 
> > > available at parsing time, and that’s the cases you are after.  The case 
> > > where the connection to the field with the length is apparent during 
> > > parsing is easy - you simply insert a load of the value before the BOS 
> > > call.
> > 
> > Yes, this is true. 
> > I prefer to implement this in gimplification phase since I am more familiar 
> > with the code there.. (I think that implementing it in gimplification 
> > should be very similar as implementing it in FE? Or do I miss anything 
> > here?)
> > 
> > Joseph, if implement this in FE, where in the FE I should look at? 
> > 
> 
> We should aim for a good integration with the BDOS pass, so
> that it can propagate the information further, e.g. the 
> following should work:
> 
> struct { int L; char buf[] __counted_by(L) } x;
> x.L = N;
> x.buf = ...;
> char *p = >f;
> __bdos(p) -> N
> 
> So we need to be smart on how we provide the size
> information for x->f to the backend. 

To follow up on this. I do not think we should change the
builtin in the FE or gimplification. Instead, we want 
to change the field access and compute the size there. 

In my toy patch I then made this have a VLA type that 
encodes the size.  Here, this would need to be done 
differently.

But still, what we are missing in both cases
is a proper way to pass the information down to BDOS.

For VLAs this works because BDOS can see the size of
the definition.  For calls to allocation functions
it is read from an attribute. 

But I am not sure what would be the best way to encode
this information so that BDOS can later access it.

Martin




> 
> This would also be desirable for the language extension. 
> 
> Martin
> 
> 
> > Thanks a lot for the 

Re: [PATCH V3 00/11] Refactor and cleanup vsetvl pass

2023-10-23 Thread Patrick O'Neill

Hi Lehua,

This patch causes a build failure with newlib 4.1.0 with -march=rv64gv_zbb.

I've creduced the failure here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111941

Thanks,
Patrick

On 10/19/23 20:58, Lehua Ding wrote:

Committed, thanks Patrick and Juzhe.

On 2023/10/20 2:04, Patrick O'Neill wrote:

I tested it this morning on my machine and it passed!

Tested against:
04d6c74564b7eb51660a00b35353aeab706b5a50

Using targets:
glibc rv32gcv qemu
glibc rv64gcv qemu

This patch series does not introduce any new failures.

Here's a list of *resolved* failures by this patch series:
rv64gcv:
FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 
-fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
-finline-functions  execution test

FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g  execution test

rv32gcv:
FAIL: gcc.target/riscv/rvv/autovec/binop/narrow_run-1.c execution test
FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 
-fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer 
-finline-functions  execution test

FAIL: gfortran.dg/host_assoc_function_7.f90   -O3 -g  execution test

Thanks for the quick revision Lehua!

Tested-by: Patrick O'Neill 

Patrick

On 10/19/23 01:50, 钟居哲 wrote:

LGTM now. But wait for Patrick CI testing.

Hi, @Patrick. Could you apply this patch and trigger CI in your 
github  so that we can see the full running result.


Issues · patrick-rivos/riscv-gnu-toolchain · GitHub 



 


juzhe.zh...@rivai.ai

    *From:* Lehua Ding 
    *Date:* 2023-10-19 16:33
    *To:* gcc-patches 
    *CC:* juzhe.zhong ; kito.cheng
    ; rdapp.gcc
    ; palmer ;
    jeffreyalaw ; lehua.ding
    
    *Subject:* [PATCH V3 00/11] Refactor and cleanup vsetvl pass
    This patch refactors and cleanups the vsetvl pass in order to make
    the code
    easier to modify and understand. This patch does several things:
    1. Introducing a virtual CFG for vsetvl infos and Phase 1, 2 and 3
    only maintain
       and modify this virtual CFG. Phase 4 performs insertion,
    modification and
       deletion of vsetvl insns based on the virtual CFG. The Basic
    block in the
       virtual CFG is called vsetvl_block_info and the vsetvl
    information inside
       is called vsetvl_info.
    2. Combine Phase 1 and 2 into a single Phase 1 and unified the
    demand system,
       this Phase only fuse local vsetvl info in forward direction.
    3. Refactor Phase 3, change the logic for determining whether to
    uplift vsetvl
       info to a pred basic block to a more unified method that there
    is a vsetvl
       info in the vsetvl defintion reaching in compatible with it.
    4. Place all modification operations to the RTL in Phase 4 and
    Phase 5.
       Phase 4 is responsible for inserting, modifying and deleting 
vsetvl

       instructions based on fully optimized vsetvl infos. Phase 5
    removes the avl
       operand from the RVV instruction and removes the unused dest
    operand
       register from the vsetvl insns.
    These modifications resulted in some testcases needing to be
    updated. The reasons
    for updating are summarized below:
    1. more optimized
vlmax_back_prop-25.c/vlmax_back_prop-26.c/vlmax_conflict-3.c/
       vlmax_conflict-12.c/vsetvl-13.c/vsetvl-23.c/
avl_single-23.c/avl_single-89.c/avl_single-95.c/pr109773-1.c
    2. less unnecessary fusion
    avl_single-46.c/imm_bb_prop-1.c/pr109743-2.c/vsetvl-18.c
    3. local fuse direction (backward -> forward)
       scalar_move-1.c/
    4. add some bugfix testcases.
       pr111037-3.c/pr111037-4.c
       avl_single-89.c
    PR target/111037
    PR target/111234
    PR target/111725
    Lehua Ding (11):
      RISC-V: P1: Refactor
    avl_info/vl_vtype_info/vector_insn_info/vector_block_info
      RISC-V: P2: Refactor and cleanup demand system
      RISC-V: P3: Refactor vector_infos_manager
      RISC-V: P4: move method from pass_vsetvl to pre_vsetvl
      RISC-V: P5: combine phase 1 and 2
      RISC-V: P6: Add computing reaching definition data flow
      RISC-V: P7: Move earliest fuse and lcm code to pre_vsetvl class
      RISC-V: P8: Refactor emit-vsetvl phase and delete post 
optimization

      RISC-V: P9: Cleanup and reorganize helper functions
      RISC-V: P10: Delete riscv-vsetvl.h and adjust riscv-vsetvl.def
      RISC-V: P11: Adjust and add testcases
    gcc/config/riscv/riscv-vsetvl.cc  | 6502 
+++--

    gcc/config/riscv/riscv-vsetvl.def |  641 +-
    gcc/config/riscv/riscv-vsetvl.h   |  488 --
    gcc/config/riscv/t-riscv  |    2 +-
    

Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Qing Zhao


> On Oct 20, 2023, at 3:54 PM, Martin Uecker  wrote:
> 
> Am Freitag, dem 20.10.2023 um 18:48 + schrieb Qing Zhao:
>> 
>>> On Oct 20, 2023, at 2:34 PM, Kees Cook  wrote:
>>> 
>>> On Fri, Oct 20, 2023 at 11:50:11AM +0200, Martin Uecker wrote:
 Am Donnerstag, dem 19.10.2023 um 16:33 -0700 schrieb Kees Cook:
> On Wed, Oct 18, 2023 at 09:11:43PM +, Qing Zhao wrote:
>> As I replied to Martin in another email, I plan to do the following to 
>> resolve this issue:
>> 
>> 1. No specification for signed or unsigned for counted_by field.
>> 2. Add a sanitizer option -fsanitize=counted-by-bound to catch the cases 
>> when the size of the counted-by is not positive.
> 
> I don't understand why this needs to be a runtime sanitizer. The
> signedness is known at compile time, so I would expect a -W option.
 
 The signedness of the type but not of the value.
 
 But I would not want to have a warning for signed 
 counter  types by default because I would prefer
 to use signed types (for various reasons including
 better overflow detection).
 
> Or
> do you mean you'd split up -fsanitize=bounds between unsigned and signed
> indexes? I'd find that kind of awkward for the kernel... but I feel like
> I've misunderstood something. :)
> 
> -Kees
 
 The idea would be to detect at run-time the case
 if  x->buf  is used at a time where   x->counter 
 is negative and also when x->counter * sizeof(x->buf[0])
 overflows or is too big.
 
 This would be similar to
 
 int a[n];
 
 where it is detected at run-time if n is not-positive.
>>> 
>>> Right. I guess what I mean to say is that I would expect this case to
>>> already be caught by -fsanitize=bounds -- I don't see a reason to add an
>>> additional sanitizer option.
>>> 
>>> struct foo {
>>> int count;
>>> int array[] __counted_by(count);
>>> };
>>> 
>>> foo->count = 5;
>>> foo->array[0] = 1;  // ok
>>> foo->array[10] = 1; // -fsanitize=bounds will catch this
>>> foo->array[-10] = 1;// -fsanitize=bounds will catch this too
>>> 
>>> 
>> 
>> just checked this testing case with my GCC, and YES, -fsanitize=bounds 
>> indeed caught this error:
>> 
>> ttt_1.c:31:12: runtime error: index 10 out of bounds for type 'char [*]'
>> ttt_1.c:32:12: runtime error: index -10 out of bounds for type 'char [*]’
>> 
> 
> Yes, but I thought we were discussing the case where count is
> set to a negative value:
> 
> foo->count = -1;
> int x = foo->array[3]; // UBSan should diagnose this
> 
> And also the case when foo->array becomes too big.

Oops, yes, you are right. 

Thanks.

Qing
> 
> Martin



Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Joseph Myers
On Mon, 23 Oct 2023, Qing Zhao wrote:

> I prefer to implement this in gimplification phase since I am more 
> familiar with the code there.. (I think that implementing it in 
> gimplification should be very similar as implementing it in FE? Or do I 
> miss anything here?)
> 
> Joseph, if implement this in FE, where in the FE I should look at? 

I tend to think that gimplification time is appropriate for adding this 
dependency, but if you wish to rewrite a built-in function call in the 
front end before then, it could be done in build_function_call_vec.

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


Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Martin Uecker
Am Montag, dem 23.10.2023 um 16:37 + schrieb Qing Zhao:
> 
> > On Oct 23, 2023, at 11:57 AM, Richard Biener  
> > wrote:
> > 
> > 
> > 
> > > Am 23.10.2023 um 16:56 schrieb Qing Zhao :
> > > 
> > > 
> > > 
> > > > On Oct 23, 2023, at 3:57 AM, Richard Biener 
> > > >  wrote:
> > > > 
> > > > > On Fri, Oct 20, 2023 at 10:41 PM Qing Zhao  
> > > > > wrote:
> > > > > 
> > > > > 
> > > > > 
> > > > > > On Oct 20, 2023, at 3:10 PM, Siddhesh Poyarekar 
> > > > > >  wrote:
> > > > > > 
> > > > > > On 2023-10-20 14:38, Qing Zhao wrote:
> > > > > > > How about the following:
> > > > > > > Add one more parameter to __builtin_dynamic_object_size(), i.e
> > > > > > > __builtin_dynamic_object_size (_1,1,array_annotated->foo)?
> > > > > > > When we see the structure field has counted_by attribute.
> > > > > > 
> > > > > > Or maybe add a barrier preventing any assignments to 
> > > > > > array_annotated->foo from being reordered below the __bdos call? 
> > > > > > Basically an __asm__ with array_annotated->foo in the clobber list 
> > > > > > ought to do it I think.
> > > > > 
> > > > > Maybe just adding the array_annotated->foo to the use list of the 
> > > > > call to __builtin_dynamic_object_size should be enough?
> > > > > 
> > > > > But I am not sure how to implement this in the TREE level, is there a 
> > > > > USE_LIST/CLOBBER_LIST for each call?  Then I can just simply add the 
> > > > > counted_by field “array_annotated->foo” to the USE_LIST of the call 
> > > > > to __bdos?
> > > > > 
> > > > > This might be the simplest solution?
> > > > 
> > > > If the dynamic object size is derived of a field then I think you need 
> > > > to
> > > > put the "load" of that memory location at the point (as argument)
> > > > of the __bos call right at parsing time.  I know that's awkward because
> > > > you try to play tricks "discovering" that field only late, but that's 
> > > > not
> > > > going to work.
> > > 
> > > Is it better to do this at gimplification phase instead of FE? 
> > > 
> > > VLA decls are handled in gimplification phase, the size calculation and 
> > > call to alloca are all generated during this phase. (gimplify_vla_decl).
> > > 
> > > For __bdos calls, we can add an additional argument if the object’s first 
> > > argument’s type include the counted_by attribute, i.e
> > > 
> > > ***During gimplification, 
> > > For a call to __builtin_dynamic_object_size (ptr, type)
> > > Check whether the type of ptr includes counted_by attribute, if so, 
> > > change the call to
> > > __builtin_dynamic_object_size (ptr, type, counted_by field)
> > > 
> > > Then the correct data dependence should be represented well in the IR.
> > > 
> > > **During object size phase,
> > > 
> > > The call to __builtin_dynamic_object_size will become an expression 
> > > includes the counted_by field or -1/0 when we cannot decide the size, the 
> > > correct data dependence will be kept even the call to 
> > > __builtin_dynamic_object_size is gone. 
> > 
> > But the whole point of the BOS pass is to derive information that is not 
> > available at parsing time, and that’s the cases you are after.  The case 
> > where the connection to the field with the length is apparent during 
> > parsing is easy - you simply insert a load of the value before the BOS call.
> 
> Yes, this is true. 
> I prefer to implement this in gimplification phase since I am more familiar 
> with the code there.. (I think that implementing it in gimplification should 
> be very similar as implementing it in FE? Or do I miss anything here?)
> 
> Joseph, if implement this in FE, where in the FE I should look at? 
> 

We should aim for a good integration with the BDOS pass, so
that it can propagate the information further, e.g. the 
following should work:

struct { int L; char buf[] __counted_by(L) } x;
x.L = N;
x.buf = ...;
char *p = >f;
__bdos(p) -> N

So we need to be smart on how we provide the size
information for x->f to the backend. 

This would also be desirable for the language extension. 

Martin


> Thanks a lot for the help.
> 
> Qing
> 
> >  For the late case there’s no way to invent data flow dependence without 
> > inadvertently pessimizing optimization.
> > 
> > Richard 
> > 
> > > 
> > > > 
> > > > A related issue is that assignment to the field and storage allocation
> > > > are not tied together
> > > 
> > > Yes, this is different from VLA, in which, the size assignment and the 
> > > storage allocation are generated and tied together by the compiler.
> > > 
> > > For the flexible array member, the storage allocation and the size 
> > > assignment are all done by the user. So, We need to clarify such 
> > > requirement  in the document to guide user to write correct code.  And 
> > > also, we might need to provide tools (warnings and sanitizer option) to 
> > > help users to catch such coding error.
> > > 
> > > > - if there's no use of the size data we might
> > > > remove the store of it as dead.
> > > 
> > > Yes, when __bdos cannot decide 

Re: [PATCH v24 33/33] libstdc++: Optimize std::is_invocable compilation performance

2023-10-23 Thread Ken Matsui
On Mon, Oct 23, 2023 at 10:39 AM Patrick Palka  wrote:
>
> On Mon, 23 Oct 2023, Ken Matsui wrote:
>
> > On Mon, Oct 23, 2023 at 10:05 AM Patrick Palka  wrote:
> >   On Fri, Oct 20, 2023 at 12:22 PM Ken Matsui  
> > wrote:
> >   >
> >   > This patch optimizes the compilation performance of 
> > std::is_invocable
> >   > by dispatching to the new __is_invocable built-in trait.
> >   >
> >   > libstdc++-v3/ChangeLog:
> >   >
> >   > * include/std/type_traits (is_invocable): Use __is_invocable
> >   > built-in trait.
> >
> >   Nice!  We should use the trait directly in is_invocable_v too.
> >
> >
> > Thank you! But we want to take account of static_assert’s in is_invocable, 
> > so I think we cannot use the built-in directly?
>
> Good point, I guess that's a great reason to improvement the diagnostic
> that check_trait_type emits: it'd speed up the class template version
> because we could get rid of the static_asserts (without regressing
> diagnostic quality), and it'd speed up the variable template version
> because we could use the built-in directly there.
>
> Your patch LGTM as is though, that could be a follow-up if anything.
>

Thank you! I will also work on this after other built-in traits end!

> >
> >
> >   > * testsuite/20_util/is_invocable/incomplete_args_neg.cc: 
> > Handle
> >   > the new error from __is_invocable.
> >   > * testsuite/20_util/is_invocable/incomplete_neg.cc: 
> > Likewise.
> >   >
> >   > Signed-off-by: Ken Matsui 
> >   > ---
> >   >  libstdc++-v3/include/std/type_traits| 6 
> > ++
> >   >  .../testsuite/20_util/is_invocable/incomplete_args_neg.cc   | 1 +
> >   >  .../testsuite/20_util/is_invocable/incomplete_neg.cc| 1 +
> >   >  3 files changed, 8 insertions(+)
> >   >
> >   > diff --git a/libstdc++-v3/include/std/type_traits 
> > b/libstdc++-v3/include/std/type_traits
> >   > index 75a94cb8d7e..91851b78c7e 100644
> >   > --- a/libstdc++-v3/include/std/type_traits
> >   > +++ b/libstdc++-v3/include/std/type_traits
> >   > @@ -3167,9 +3167,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >   >  using invoke_result_t = typename invoke_result<_Fn, 
> > _Args...>::type;
> >   >
> >   >/// std::is_invocable
> >   > +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
> >   > +  template
> >   > +struct is_invocable
> >   > +: public __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
> >   > +#else
> >   >template
> >   >  struct is_invocable
> >   >  : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, 
> > void>::type
> >   > +#endif
> >   >  {
> >   >
> > static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
> >   > "_Fn must be a complete class or an unbounded array");
> >   > diff --git 
> > a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc 
> > b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> >   > index 34d1d9431d1..3f9e5274f3c 100644
> >   > --- 
> > a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> >   > +++ 
> > b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> >   > @@ -18,6 +18,7 @@
> >   >  // .
> >   >
> >   >  // { dg-error "must be a complete class" "" { target *-*-* } 0 }
> >   > +// { dg-prune-output "invalid use of incomplete type" }
> >   >
> >   >  #include 
> >   >
> >   > diff --git 
> > a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc 
> > b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> >   > index e1e54d25ee5..92af48c48b6 100644
> >   > --- a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> >   > +++ b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> >   > @@ -18,6 +18,7 @@
> >   >  // .
> >   >
> >   >  // { dg-error "must be a complete class" "" { target *-*-* } 0 }
> >   > +// { dg-prune-output "invalid use of incomplete type" }
> >   >
> >   >  #include 
> >   >
> >   > --
> >   > 2.42.0
> >   >
> >
> >
> >


Re: [PATCH v24 33/33] libstdc++: Optimize std::is_invocable compilation performance

2023-10-23 Thread Patrick Palka
On Mon, 23 Oct 2023, Ken Matsui wrote:

> On Mon, Oct 23, 2023 at 10:05 AM Patrick Palka  wrote:
>   On Fri, Oct 20, 2023 at 12:22 PM Ken Matsui  wrote:
>   >
>   > This patch optimizes the compilation performance of std::is_invocable
>   > by dispatching to the new __is_invocable built-in trait.
>   >
>   > libstdc++-v3/ChangeLog:
>   >
>   >         * include/std/type_traits (is_invocable): Use __is_invocable
>   >         built-in trait.
> 
>   Nice!  We should use the trait directly in is_invocable_v too.
> 
> 
> Thank you! But we want to take account of static_assert’s in is_invocable, so 
> I think we cannot use the built-in directly?

Good point, I guess that's a great reason to improvement the diagnostic
that check_trait_type emits: it'd speed up the class template version
because we could get rid of the static_asserts (without regressing
diagnostic quality), and it'd speed up the variable template version
because we could use the built-in directly there.

Your patch LGTM as is though, that could be a follow-up if anything.

> 
> 
>   >         * testsuite/20_util/is_invocable/incomplete_args_neg.cc: 
> Handle
>   >         the new error from __is_invocable.
>   >         * testsuite/20_util/is_invocable/incomplete_neg.cc: Likewise.
>   >
>   > Signed-off-by: Ken Matsui 
>   > ---
>   >  libstdc++-v3/include/std/type_traits                        | 6 
> ++
>   >  .../testsuite/20_util/is_invocable/incomplete_args_neg.cc   | 1 +
>   >  .../testsuite/20_util/is_invocable/incomplete_neg.cc        | 1 +
>   >  3 files changed, 8 insertions(+)
>   >
>   > diff --git a/libstdc++-v3/include/std/type_traits 
> b/libstdc++-v3/include/std/type_traits
>   > index 75a94cb8d7e..91851b78c7e 100644
>   > --- a/libstdc++-v3/include/std/type_traits
>   > +++ b/libstdc++-v3/include/std/type_traits
>   > @@ -3167,9 +3167,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   >      using invoke_result_t = typename invoke_result<_Fn, 
> _Args...>::type;
>   >
>   >    /// std::is_invocable
>   > +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
>   > +  template
>   > +    struct is_invocable
>   > +    : public __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
>   > +#else
>   >    template
>   >      struct is_invocable
>   >      : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, 
> void>::type
>   > +#endif
>   >      {
>   >        
> static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
>   >         "_Fn must be a complete class or an unbounded array");
>   > diff --git 
> a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc 
> b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
>   > index 34d1d9431d1..3f9e5274f3c 100644
>   > --- 
> a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
>   > +++ 
> b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
>   > @@ -18,6 +18,7 @@
>   >  // .
>   >
>   >  // { dg-error "must be a complete class" "" { target *-*-* } 0 }
>   > +// { dg-prune-output "invalid use of incomplete type" }
>   >
>   >  #include 
>   >
>   > diff --git 
> a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc 
> b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
>   > index e1e54d25ee5..92af48c48b6 100644
>   > --- a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
>   > +++ b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
>   > @@ -18,6 +18,7 @@
>   >  // .
>   >
>   >  // { dg-error "must be a complete class" "" { target *-*-* } 0 }
>   > +// { dg-prune-output "invalid use of incomplete type" }
>   >
>   >  #include 
>   >
>   > --
>   > 2.42.0
>   >
> 
> 
> 

Re: [PATCH v24 33/33] libstdc++: Optimize std::is_invocable compilation performance

2023-10-23 Thread Ken Matsui
On Mon, Oct 23, 2023 at 10:05 AM Patrick Palka  wrote:

> On Fri, Oct 20, 2023 at 12:22 PM Ken Matsui  wrote:
> >
> > This patch optimizes the compilation performance of std::is_invocable
> > by dispatching to the new __is_invocable built-in trait.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/std/type_traits (is_invocable): Use __is_invocable
> > built-in trait.
>
> Nice!  We should use the trait directly in is_invocable_v too.
>

Thank you! But we want to take account of static_assert’s in is_invocable,
so I think we cannot use the built-in directly?


> > * testsuite/20_util/is_invocable/incomplete_args_neg.cc: Handle
> > the new error from __is_invocable.
> > * testsuite/20_util/is_invocable/incomplete_neg.cc: Likewise.
> >
> > Signed-off-by: Ken Matsui 
> > ---
> >  libstdc++-v3/include/std/type_traits| 6 ++
> >  .../testsuite/20_util/is_invocable/incomplete_args_neg.cc   | 1 +
> >  .../testsuite/20_util/is_invocable/incomplete_neg.cc| 1 +
> >  3 files changed, 8 insertions(+)
> >
> > diff --git a/libstdc++-v3/include/std/type_traits
> b/libstdc++-v3/include/std/type_traits
> > index 75a94cb8d7e..91851b78c7e 100644
> > --- a/libstdc++-v3/include/std/type_traits
> > +++ b/libstdc++-v3/include/std/type_traits
> > @@ -3167,9 +3167,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >  using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
> >
> >/// std::is_invocable
> > +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
> > +  template
> > +struct is_invocable
> > +: public __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
> > +#else
> >template
> >  struct is_invocable
> >  : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>,
> void>::type
> > +#endif
> >  {
> >
> static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
> > "_Fn must be a complete class or an unbounded array");
> > diff --git
> a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> > index 34d1d9431d1..3f9e5274f3c 100644
> > --- a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> > +++ b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> > @@ -18,6 +18,7 @@
> >  // .
> >
> >  // { dg-error "must be a complete class" "" { target *-*-* } 0 }
> > +// { dg-prune-output "invalid use of incomplete type" }
> >
> >  #include 
> >
> > diff --git
> a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> > index e1e54d25ee5..92af48c48b6 100644
> > --- a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> > +++ b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> > @@ -18,6 +18,7 @@
> >  // .
> >
> >  // { dg-error "must be a complete class" "" { target *-*-* } 0 }
> > +// { dg-prune-output "invalid use of incomplete type" }
> >
> >  #include 
> >
> > --
> > 2.42.0
> >
>
>


Re: [PATCH v23 31/33] libstdc++: Optimize std::is_pointer compilation performance

2023-10-23 Thread Ken Matsui
On Mon, Oct 23, 2023 at 10:00 AM Patrick Palka  wrote:

> On Sun, 22 Oct 2023, Ken Matsui wrote:
>
> > Hi Patrick,
> >
> > There is an issue with the code in
> > libstdc++-v3/include/bits/cpp_type_traits.h. Specifically, Clang 16
> > does not accept the code, while Clang 17 does. Given that we aim to
> > support the last two versions of Clang, we need to ensure that Clang
> > 16 accepts this code. Can you please advise on the best course of
> > action regarding this matter?
>
> The following workaround seems to make Clang happy:
>
> #include 
>
> template
> struct __is_pointer : std::bool_constant { };
>

Ooh, this makes sense. Thank you!


> >
> > https://godbolt.org/z/PbxhYcb7q
> >
> > Sincerely,
> > Ken Matsui
> >
> > On Fri, Oct 20, 2023 at 7:12 AM Ken Matsui  wrote:
> > >
> > > This patch optimizes the compilation performance of std::is_pointer
> > > by dispatching to the new __is_pointer built-in trait.
> > >
> > > libstdc++-v3/ChangeLog:
> > >
> > > * include/bits/cpp_type_traits.h (__is_pointer): Use
> __is_pointer
> > > built-in trait.
> > > * include/std/type_traits (is_pointer): Likewise. Optimize its
> > > implementation.
> > > (is_pointer_v): Likewise.
> > >
> > > Co-authored-by: Jonathan Wakely 
> > > Signed-off-by: Ken Matsui 
> > > ---
> > >  libstdc++-v3/include/bits/cpp_type_traits.h |  8 
> > >  libstdc++-v3/include/std/type_traits| 44 +
> > >  2 files changed, 44 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h
> b/libstdc++-v3/include/bits/cpp_type_traits.h
> > > index 4312f32a4e0..246f2cc0b17 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 _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
> > > +  template
> > > +struct __is_pointer : __truth_type<__is_pointer(_Tp)>
> > > +{
> > > +  enum { __value = __is_pointer(_Tp) };
> > > +};
> > > +#else
> > >template
> > >  struct __is_pointer
> > >  {
> > > @@ -376,6 +383,7 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
> > >enum { __value = 1 };
> > >typedef __true_type __type;
> > >  };
> > > +#endif
> > >
> > >//
> > >// An arithmetic type is an integer type or a floating point type
> > > diff --git a/libstdc++-v3/include/std/type_traits
> b/libstdc++-v3/include/std/type_traits
> > > index 0641ecfdf2b..75a94cb8d7e 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
> > > @@ -3252,8 +3266,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
> > >
> >
> >


Re: [PATCH v24 33/33] libstdc++: Optimize std::is_invocable compilation performance

2023-10-23 Thread Patrick Palka
On Fri, Oct 20, 2023 at 12:22 PM Ken Matsui  wrote:
>
> This patch optimizes the compilation performance of std::is_invocable
> by dispatching to the new __is_invocable built-in trait.
>
> libstdc++-v3/ChangeLog:
>
> * include/std/type_traits (is_invocable): Use __is_invocable
> built-in trait.

Nice!  We should use the trait directly in is_invocable_v too.

> * testsuite/20_util/is_invocable/incomplete_args_neg.cc: Handle
> the new error from __is_invocable.
> * testsuite/20_util/is_invocable/incomplete_neg.cc: Likewise.
>
> Signed-off-by: Ken Matsui 
> ---
>  libstdc++-v3/include/std/type_traits| 6 ++
>  .../testsuite/20_util/is_invocable/incomplete_args_neg.cc   | 1 +
>  .../testsuite/20_util/is_invocable/incomplete_neg.cc| 1 +
>  3 files changed, 8 insertions(+)
>
> diff --git a/libstdc++-v3/include/std/type_traits 
> b/libstdc++-v3/include/std/type_traits
> index 75a94cb8d7e..91851b78c7e 100644
> --- a/libstdc++-v3/include/std/type_traits
> +++ b/libstdc++-v3/include/std/type_traits
> @@ -3167,9 +3167,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
>
>/// std::is_invocable
> +#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
> +  template
> +struct is_invocable
> +: public __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
> +#else
>template
>  struct is_invocable
>  : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
> +#endif
>  {
>static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
> "_Fn must be a complete class or an unbounded array");
> diff --git 
> a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc 
> b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> index 34d1d9431d1..3f9e5274f3c 100644
> --- a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> +++ b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_args_neg.cc
> @@ -18,6 +18,7 @@
>  // .
>
>  // { dg-error "must be a complete class" "" { target *-*-* } 0 }
> +// { dg-prune-output "invalid use of incomplete type" }
>
>  #include 
>
> diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc 
> b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> index e1e54d25ee5..92af48c48b6 100644
> --- a/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> +++ b/libstdc++-v3/testsuite/20_util/is_invocable/incomplete_neg.cc
> @@ -18,6 +18,7 @@
>  // .
>
>  // { dg-error "must be a complete class" "" { target *-*-* } 0 }
> +// { dg-prune-output "invalid use of incomplete type" }
>
>  #include 
>
> --
> 2.42.0
>



Re: [PATCH v23 31/33] libstdc++: Optimize std::is_pointer compilation performance

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

> Hi Patrick,
> 
> There is an issue with the code in
> libstdc++-v3/include/bits/cpp_type_traits.h. Specifically, Clang 16
> does not accept the code, while Clang 17 does. Given that we aim to
> support the last two versions of Clang, we need to ensure that Clang
> 16 accepts this code. Can you please advise on the best course of
> action regarding this matter?

The following workaround seems to make Clang happy:

#include 

template
struct __is_pointer : std::bool_constant { };

> 
> https://godbolt.org/z/PbxhYcb7q
> 
> Sincerely,
> Ken Matsui
> 
> On Fri, Oct 20, 2023 at 7:12 AM Ken Matsui  wrote:
> >
> > This patch optimizes the compilation performance of std::is_pointer
> > by dispatching to the new __is_pointer built-in trait.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/bits/cpp_type_traits.h (__is_pointer): Use __is_pointer
> > built-in trait.
> > * include/std/type_traits (is_pointer): Likewise. Optimize its
> > implementation.
> > (is_pointer_v): Likewise.
> >
> > Co-authored-by: Jonathan Wakely 
> > Signed-off-by: Ken Matsui 
> > ---
> >  libstdc++-v3/include/bits/cpp_type_traits.h |  8 
> >  libstdc++-v3/include/std/type_traits| 44 +
> >  2 files changed, 44 insertions(+), 8 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
> > b/libstdc++-v3/include/bits/cpp_type_traits.h
> > index 4312f32a4e0..246f2cc0b17 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 _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
> > +  template
> > +struct __is_pointer : __truth_type<__is_pointer(_Tp)>
> > +{
> > +  enum { __value = __is_pointer(_Tp) };
> > +};
> > +#else
> >template
> >  struct __is_pointer
> >  {
> > @@ -376,6 +383,7 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
> >enum { __value = 1 };
> >typedef __true_type __type;
> >  };
> > +#endif
> >
> >//
> >// An arithmetic type is an integer type or a floating point type
> > diff --git a/libstdc++-v3/include/std/type_traits 
> > b/libstdc++-v3/include/std/type_traits
> > index 0641ecfdf2b..75a94cb8d7e 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
> > @@ -3252,8 +3266,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
> >
> 
> 

Re: [PATCH] libgcc: make heap-based trampolines conditional on libc presence

2023-10-23 Thread Sergei Trofimovich
On Mon, 23 Oct 2023 13:54:01 +0100
Iain Sandoe  wrote:

> hi Sergei,
> 
> > On 23 Oct 2023, at 13:43, Sergei Trofimovich  wrote:
> > 
> > From: Sergei Trofimovich 
> > 
> > To build `libc` for a target one needs to build `gcc` without `libc`
> > support first. Commit r14-4823-g8abddb187b3348 "libgcc: support
> > heap-based trampolines" added unconditional `libc` dependency and broke
> > libc-less `gcc` builds.
> > 
> > An example failure on `x86_64-unknown-linux-gnu`:
> > 
> >$ mkdir -p /tmp/empty
> >$ ../gcc/configure \
> >--disable-multilib \
> >--without-headers \
> >--with-newlib \
> >--enable-languages=c \
> >--disable-bootstrap \
> >--disable-gcov \
> >--disable-threads \
> >--disable-shared \
> >--disable-libssp \
> >--disable-libquadmath \
> >--disable-libgomp \
> >--disable-libatomic \
> >--with-build-sysroot=/tmp/empty
> >$ make
> >...
> >/tmp/gb/./gcc/xgcc -B/tmp/gb/./gcc/ 
> > -B/usr/local/x86_64-pc-linux-gnu/bin/ -B/usr/local/x86_64-pc-linux-gnu/lib/ 
> > -isystem /usr/local/x86_64-pc-linux-gnu/include -isystem 
> > /usr/local/x86_64-pc-linux-gnu/sys-include --sysroot=/tmp/empty   -g -O2 
> > -O2  -g -O2 -DIN_GCC   -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual 
> > -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem 
> > ./include  -fpic -mlong-double-80 -DUSE_ELF_SYMVER -fcf-protection -mshstk 
> > -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc -fpic 
> > -mlong-double-80 -DUSE_ELF_SYMVER -fcf-protection -mshstk -I. -I. 
> > -I../.././gcc -I/home/slyfox/dev/git/gcc/libgcc 
> > -I/home/slyfox/dev/git/gcc/libgcc/. 
> > -I/home/slyfox/dev/git/gcc/libgcc/../gcc 
> > -I/home/slyfox/dev/git/gcc/libgcc/../include  -DHAVE_CC_TLS  -DUSE_TLS  -o 
> > heap-trampoline.o -MT heap-trampoline.o -MD -MP -MF heap-trampoline.dep  -c 
> > .../gcc/libgcc/config/i386/heap-trampoline.c -fvisibility=hidden 
> > -DHIDE_EXPORTS
> >../gcc/libgcc/config/i386/heap-trampoline.c:3:10: fatal error: unistd.h: 
> > No such file or directory
> >3 | #include 
> >  |  ^~
> >compilation terminated.
> >make[2]: *** [.../gcc/libgcc/static-object.mk:17: heap-trampoline.o] 
> > Error 1
> >make[2]: Leaving directory '/tmp/gb/x86_64-pc-linux-gnu/libgcc'
> >make[1]: *** [Makefile:13307: all-target-libgcc] Error 2
> > 
> > The change inhibits any heap-based trampoline code.  
> 
> That looks reasonable to me (I was considering using __has_include(), but the 
> inhibit_libc is neater).
> 
> The fact that this first compiler is buit without heap-trampoline support, 
> would become relevant, I guess if libc wanted to use them, it would need 
> another iteration.
> 
> so, it looks fine, but I cannot actually approve it.

Sounds good. Let's wait for others to chime in. Maybe Richard? :)

AFAIU libcs (like `glibc`) try hard not to use link tests and uses
mainly preprocessor and code generator to specifically accommodate this
case. Maybe there is a way to pass the support flag to libc without the
reliance on code presence in libgcc.

Otherwise we could use __builtin_trap() as an implementation for exposed
symbols.

> 
> > 
> > libgcc/
> > 
> > * libgcc/config/aarch64/heap-trampoline.c: Disable when libc is
> >   not present.
> > ---
> > libgcc/config/aarch64/heap-trampoline.c | 5 +
> > libgcc/config/i386/heap-trampoline.c| 5 +
> > 2 files changed, 10 insertions(+)
> > 
> > diff --git a/libgcc/config/aarch64/heap-trampoline.c 
> > b/libgcc/config/aarch64/heap-trampoline.c
> > index c8b83681ed7..f22233987ca 100644
> > --- a/libgcc/config/aarch64/heap-trampoline.c
> > +++ b/libgcc/config/aarch64/heap-trampoline.c
> > @@ -1,5 +1,8 @@
> > /* Copyright The GNU Toolchain Authors. */
> > 
> > +/* libc is required to allocate trampolines.  */
> > +#ifndef inhibit_libc
> > +
> > #include 
> > #include 
> > #include 
> > @@ -170,3 +173,5 @@ __builtin_nested_func_ptr_deleted (void)
> >   tramp_ctrl_curr = prev;
> > }
> > }
> > +
> > +#endif /* !inhibit_libc */
> > diff --git a/libgcc/config/i386/heap-trampoline.c 
> > b/libgcc/config/i386/heap-trampoline.c
> > index 96e13bf828e..4b9f4365868 100644
> > --- a/libgcc/config/i386/heap-trampoline.c
> > +++ b/libgcc/config/i386/heap-trampoline.c
> > @@ -1,5 +1,8 @@
> > /* Copyright The GNU Toolchain Authors. */
> > 
> > +/* libc is required to allocate trampolines.  */
> > +#ifndef inhibit_libc
> > +
> > #include 
> > #include 
> > #include 
> > @@ -170,3 +173,5 @@ __builtin_nested_func_ptr_deleted (void)
> >   tramp_ctrl_curr = prev;
> > }
> > }
> > +
> > +#endif /* !inhibit_libc */
> > -- 
> > 2.42.0
> >   
> 


-- 

  Sergei


Re: [PATCH v1 1/1] gcc: config: microblaze: fix cpu version check

2023-10-23 Thread Michael Eager

On 10/22/23 22:48, Neal Frager wrote:

There is a microblaze cpu version 10.0 included in versal. If the
minor version is only a single digit, then the version comparison
will fail as version 10.0 will appear as 100 compared to version
6.00 or 8.30 which will calculate to values 600 and 830.

The issue can be seen when using the '-mcpu=10.0' option.

With this fix, versions with a single digit minor number such as
10.0 will be calculated as greater than versions with a smaller
major version number, but with two minor version digits.

By applying this fix, several incorrect warning messages will no
longer be printed when building the versal plm application, such
as the warning message below:

warning: '-mxl-multiply-high' can be used only with '-mcpu=v6.00.a' or greater

Signed-off-by: Neal Frager 
---
  gcc/config/microblaze/microblaze.cc | 164 +---
  1 file changed, 76 insertions(+), 88 deletions(-)


Please add a test case.

--
Michael Eager


Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Qing Zhao


> On Oct 23, 2023, at 11:57 AM, Richard Biener  
> wrote:
> 
> 
> 
>> Am 23.10.2023 um 16:56 schrieb Qing Zhao :
>> 
>> 
>> 
>>> On Oct 23, 2023, at 3:57 AM, Richard Biener  
>>> wrote:
>>> 
 On Fri, Oct 20, 2023 at 10:41 PM Qing Zhao  wrote:
 
 
 
> On Oct 20, 2023, at 3:10 PM, Siddhesh Poyarekar  
> wrote:
> 
> On 2023-10-20 14:38, Qing Zhao wrote:
>> How about the following:
>> Add one more parameter to __builtin_dynamic_object_size(), i.e
>> __builtin_dynamic_object_size (_1,1,array_annotated->foo)?
>> When we see the structure field has counted_by attribute.
> 
> Or maybe add a barrier preventing any assignments to array_annotated->foo 
> from being reordered below the __bdos call? Basically an __asm__ with 
> array_annotated->foo in the clobber list ought to do it I think.
 
 Maybe just adding the array_annotated->foo to the use list of the call to 
 __builtin_dynamic_object_size should be enough?
 
 But I am not sure how to implement this in the TREE level, is there a 
 USE_LIST/CLOBBER_LIST for each call?  Then I can just simply add the 
 counted_by field “array_annotated->foo” to the USE_LIST of the call to 
 __bdos?
 
 This might be the simplest solution?
>>> 
>>> If the dynamic object size is derived of a field then I think you need to
>>> put the "load" of that memory location at the point (as argument)
>>> of the __bos call right at parsing time.  I know that's awkward because
>>> you try to play tricks "discovering" that field only late, but that's not
>>> going to work.
>> 
>> Is it better to do this at gimplification phase instead of FE? 
>> 
>> VLA decls are handled in gimplification phase, the size calculation and call 
>> to alloca are all generated during this phase. (gimplify_vla_decl).
>> 
>> For __bdos calls, we can add an additional argument if the object’s first 
>> argument’s type include the counted_by attribute, i.e
>> 
>> ***During gimplification, 
>> For a call to __builtin_dynamic_object_size (ptr, type)
>> Check whether the type of ptr includes counted_by attribute, if so, change 
>> the call to
>> __builtin_dynamic_object_size (ptr, type, counted_by field)
>> 
>> Then the correct data dependence should be represented well in the IR.
>> 
>> **During object size phase,
>> 
>> The call to __builtin_dynamic_object_size will become an expression includes 
>> the counted_by field or -1/0 when we cannot decide the size, the correct 
>> data dependence will be kept even the call to __builtin_dynamic_object_size 
>> is gone. 
> 
> But the whole point of the BOS pass is to derive information that is not 
> available at parsing time, and that’s the cases you are after.  The case 
> where the connection to the field with the length is apparent during parsing 
> is easy - you simply insert a load of the value before the BOS call.

Yes, this is true. 
I prefer to implement this in gimplification phase since I am more familiar 
with the code there.. (I think that implementing it in gimplification should be 
very similar as implementing it in FE? Or do I miss anything here?)

Joseph, if implement this in FE, where in the FE I should look at? 

Thanks a lot for the help.

Qing

>  For the late case there’s no way to invent data flow dependence without 
> inadvertently pessimizing optimization.
> 
> Richard 
> 
>> 
>>> 
>>> A related issue is that assignment to the field and storage allocation
>>> are not tied together
>> 
>> Yes, this is different from VLA, in which, the size assignment and the 
>> storage allocation are generated and tied together by the compiler.
>> 
>> For the flexible array member, the storage allocation and the size 
>> assignment are all done by the user. So, We need to clarify such requirement 
>>  in the document to guide user to write correct code.  And also, we might 
>> need to provide tools (warnings and sanitizer option) to help users to catch 
>> such coding error.
>> 
>>> - if there's no use of the size data we might
>>> remove the store of it as dead.
>> 
>> Yes, when __bdos cannot decide the size, we need to remove the dead store to 
>> the field.
>> I guess that the compiler should be able to do this automatically?
>> 
>> thanks.
>> 
>> Qing
>>> 
>>> Of course I guess __bos then behaves like sizeof ().
>>> 
>>> Richard.
>>> 
 
 Qing
 
> 
> It may not work for something like this though:
> 
> static size_t
> get_size_of (void *ptr)
> {
> return __bdos (ptr, 1);
> }
> 
> void
> foo (size_t sz)
> {
> array_annotated = __builtin_malloc (sz);
> array_annotated = sz;
> 
> ...
> __builtin_printf ("%zu\n", get_size_of (array_annotated->foo));
> ...
> }
> 
> because the call to get_size_of () may not have been inlined that early.
> 
> The more fool-proof alternative may be to put a compile time barrier 
> right below the assignment to 

[PATCH] internal-fn: Add VCOND_MASK_LEN.

2023-10-23 Thread Robin Dapp
The attached patch introduces a VCOND_MASK_LEN, helps for the riscv cases
that were broken before and looks unchanged on x86, aarch64 and power
bootstrap and testsuites.

I only went with the minimal number of new match.pd patterns and did not
try stripping the length of a COND_LEN_OP in order to simplify the
associated COND_OP.

An important part that I'm not sure how to handle properly is -
when we have a constant immediate length of e.g. 16 and the hardware
also operates on 16 units, vector length masking is actually
redundant and the vcond_mask_len can be reduced to a vec_cond.
For those (if_then_else unsplit) we have a large number of combine
patterns that fuse instruction which do not correspond to ifns
(like widening operations but also more complex ones).

Currently I achieve this in a most likely wrong way:

  auto sz = GET_MODE_NUNITS (TYPE_MODE (res_op->type));
  bool full_len = len && known_eq (sz.coeffs[0], ilen);
  if (!len || full_len)
 "vec_cond"
  else
 "vcond_mask_len"

Another thing not done in this patch:  For vcond_mask we only expect
register operands as mask and force to a register.  For a vcond_mask_len
that results from a simplification with all-one or all-zero mask we
could allow constant immediate vectors and expand them to simple
len moves in the backend.

Regards
 Robin

>From bc72e9b2f3ee46508404ee7723ca78790fa96b6b Mon Sep 17 00:00:00 2001
From: Robin Dapp 
Date: Fri, 13 Oct 2023 10:20:35 +0200
Subject: [PATCH] internal-fn: Add VCOND_MASK_LEN.

In order to prevent simplification of a COND_OP with degenerate mask
(all true or all zero) into just an OP in the presence of length
masking this patch introduces a length-masked analog to VEC_COND_EXPR:
IFN_VCOND_MASK_LEN.  If the to-be-simplified conditional operation has a
length that is not the full hardware vector length a simplification now
does not result int a VEC_COND but rather a VCOND_MASK_LEN.

For cases where the masks is known to be all true or all zero the patch
introduces new match patterns that allow combination of unconditional
unary, binary and ternay operations with the respective conditional
operations if the target supports it.

Similarly, if the length is known to be equal to the target hardware
length VCOND_MASK_LEN will be simplified to VEC_COND_EXPR.

gcc/ChangeLog:

* config/riscv/autovec.md (vcond_mask_len_): Add
expander.
* config/riscv/riscv-protos.h (enum insn_type):
* doc/md.texi: Add vcond_mask_len.
* gimple-match-exports.cc (maybe_resimplify_conditional_op):
Create VCOND_MASK_LEN when
length masking.
* gimple-match.h (gimple_match_op::gimple_match_op): Allow
matching of 6 and 7 parameters.
(gimple_match_op::set_op): Ditto.
(gimple_match_op::gimple_match_op): Always initialize len and
bias.
* internal-fn.cc (vec_cond_mask_len_direct): Add.
(expand_vec_cond_mask_len_optab_fn): Add.
(direct_vec_cond_mask_len_optab_supported_p): Add.
(internal_fn_len_index): Add VCOND_MASK_LEN.
(internal_fn_mask_index): Ditto.
* internal-fn.def (VCOND_MASK_LEN): New internal function.
* match.pd: Combine unconditional unary, binary and ternary
operations into the respective COND_LEN operations.
* optabs.def (OPTAB_CD): Add vcond_mask_len optab.
---
 gcc/config/riscv/autovec.md | 20 +
 gcc/config/riscv/riscv-protos.h |  4 ++
 gcc/doc/md.texi |  9 
 gcc/gimple-match-exports.cc | 20 +++--
 gcc/gimple-match.h  | 78 -
 gcc/internal-fn.cc  | 41 +
 gcc/internal-fn.def |  2 +
 gcc/match.pd| 74 +++
 gcc/optabs.def  |  1 +
 9 files changed, 244 insertions(+), 5 deletions(-)

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 80910ba3cc2..27a71bc1ef9 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -565,6 +565,26 @@ (define_insn_and_split "vcond_mask_"
   [(set_attr "type" "vector")]
 )
 
+(define_expand "vcond_mask_len_"
+  [(match_operand:V_VLS 0 "register_operand")
+(match_operand: 3 "register_operand")
+(match_operand:V_VLS 1 "nonmemory_operand")
+(match_operand:V_VLS 2 "register_operand")
+(match_operand 4 "autovec_length_operand")
+(match_operand 5 "const_0_operand")]
+  "TARGET_VECTOR"
+  {
+/* The order of vcond_mask is opposite to pred_merge.  */
+rtx ops[] = {operands[0], operands[0], operands[2], operands[1],
+operands[3]};
+riscv_vector::emit_nonvlmax_insn (code_for_pred_merge (mode),
+ riscv_vector::MERGE_OP_REAL_ELSE, ops,
+ operands[4]);
+DONE;
+  }
+  [(set_attr "type" "vector")]
+)
+
 ;; 

Re: HELP: Will the reordering happen? Re: [V3][PATCH 0/3] New attribute "counted_by" to annotate bounds for C99 FAM(PR108896)

2023-10-23 Thread Richard Biener



> Am 23.10.2023 um 16:56 schrieb Qing Zhao :
> 
> 
> 
>> On Oct 23, 2023, at 3:57 AM, Richard Biener  
>> wrote:
>> 
>>> On Fri, Oct 20, 2023 at 10:41 PM Qing Zhao  wrote:
>>> 
>>> 
>>> 
 On Oct 20, 2023, at 3:10 PM, Siddhesh Poyarekar  
 wrote:
 
 On 2023-10-20 14:38, Qing Zhao wrote:
> How about the following:
> Add one more parameter to __builtin_dynamic_object_size(), i.e
> __builtin_dynamic_object_size (_1,1,array_annotated->foo)?
> When we see the structure field has counted_by attribute.
 
 Or maybe add a barrier preventing any assignments to array_annotated->foo 
 from being reordered below the __bdos call? Basically an __asm__ with 
 array_annotated->foo in the clobber list ought to do it I think.
>>> 
>>> Maybe just adding the array_annotated->foo to the use list of the call to 
>>> __builtin_dynamic_object_size should be enough?
>>> 
>>> But I am not sure how to implement this in the TREE level, is there a 
>>> USE_LIST/CLOBBER_LIST for each call?  Then I can just simply add the 
>>> counted_by field “array_annotated->foo” to the USE_LIST of the call to 
>>> __bdos?
>>> 
>>> This might be the simplest solution?
>> 
>> If the dynamic object size is derived of a field then I think you need to
>> put the "load" of that memory location at the point (as argument)
>> of the __bos call right at parsing time.  I know that's awkward because
>> you try to play tricks "discovering" that field only late, but that's not
>> going to work.
> 
> Is it better to do this at gimplification phase instead of FE? 
> 
> VLA decls are handled in gimplification phase, the size calculation and call 
> to alloca are all generated during this phase. (gimplify_vla_decl).
> 
> For __bdos calls, we can add an additional argument if the object’s first 
> argument’s type include the counted_by attribute, i.e
> 
> ***During gimplification, 
> For a call to __builtin_dynamic_object_size (ptr, type)
> Check whether the type of ptr includes counted_by attribute, if so, change 
> the call to
> __builtin_dynamic_object_size (ptr, type, counted_by field)
> 
> Then the correct data dependence should be represented well in the IR.
> 
> **During object size phase,
> 
> The call to __builtin_dynamic_object_size will become an expression includes 
> the counted_by field or -1/0 when we cannot decide the size, the correct data 
> dependence will be kept even the call to __builtin_dynamic_object_size is 
> gone. 

But the whole point of the BOS pass is to derive information that is not 
available at parsing time, and that’s the cases you are after.  The case where 
the connection to the field with the length is apparent during parsing is easy 
- you simply insert a load of the value before the BOS call.  For the late case 
there’s no way to invent data flow dependence without inadvertently pessimizing 
optimization.

Richard 

> 
>> 
>> A related issue is that assignment to the field and storage allocation
>> are not tied together
> 
> Yes, this is different from VLA, in which, the size assignment and the 
> storage allocation are generated and tied together by the compiler.
> 
> For the flexible array member, the storage allocation and the size assignment 
> are all done by the user. So, We need to clarify such requirement  in the 
> document to guide user to write correct code.  And also, we might need to 
> provide tools (warnings and sanitizer option) to help users to catch such 
> coding error.
> 
>> - if there's no use of the size data we might
>> remove the store of it as dead.
> 
> Yes, when __bdos cannot decide the size, we need to remove the dead store to 
> the field.
> I guess that the compiler should be able to do this automatically?
> 
> thanks.
> 
> Qing
>> 
>> Of course I guess __bos then behaves like sizeof ().
>> 
>> Richard.
>> 
>>> 
>>> Qing
>>> 
 
 It may not work for something like this though:
 
 static size_t
 get_size_of (void *ptr)
 {
 return __bdos (ptr, 1);
 }
 
 void
 foo (size_t sz)
 {
 array_annotated = __builtin_malloc (sz);
 array_annotated = sz;
 
 ...
 __builtin_printf ("%zu\n", get_size_of (array_annotated->foo));
 ...
 }
 
 because the call to get_size_of () may not have been inlined that early.
 
 The more fool-proof alternative may be to put a compile time barrier right 
 below the assignment to array_annotated->foo; I reckon you could do that 
 early in the front end by marking the size identifier and then tracking 
 assignments to that identifier.  That may have a slight runtime 
 performance overhead since it may prevent even legitimate reordering.  I 
 can't think of another alternative at the moment...
 
 Sid
> 


  1   2   >