Re: [PATCH v3] Many pages: Document fixed-width types with ISO C naming

2022-08-24 Thread Florian Weimer via Gcc-patches
* Greg Kroah-Hartman:

> On Thu, Aug 25, 2022 at 01:36:10AM +0200, Alejandro Colomar wrote:
>> But from your side what do we have?  Just direct NAKs without much
>> explanation.  The only one who gave some explanation was Greg, and he
>> vaguely pointed to Linus's comments about it in the past, with no precise
>> pointer to it.  I investigated a lot before v2, and could not find anything
>> strong enough to recommend using kernel types in user space, so I pushed v2,
>> and the discussion was kept.
>
> So despite me saying that "this is not ok", and many other maintainers
> saying "this is not ok", you applied a patch with our objections on it?
> That is very odd and a bit rude.

The justifications brought forward are just regurgitating previous
misinformation.  If you do that, it's hard to take you seriously.

There is actually a good reason for using __u64: it's always based on
long long, so the format strings are no longer architecture-specific,
and those ugly macro hacks are not needed to achieve portability.  But
that's really the only reason I'm aware of.  Admittedly, it's a pretty
good reason.

>> I would like that if you still oppose to the patch, at least were able to
>> provide some facts to this discussion.
>
> The fact is that the kernel can not use the namespace that userspace has
> with ISO C names.  It's that simple as the ISO standard does NOT
> describe the variable types for an ABI that can cross the user/kernel
> boundry.

You cannot avoid using certain ISO C names with current GCC or Clang,
however hard you try.  But currently, the kernel does not try at all,
not really: it is not using -ffreestanding and -fno-builtin, at least
not consistently.  This means that if the compiler sees a known function
(with the right name and a compatible prototype), it will optimize based
on that.  What kind of headers you use does not matter.

, ,  are compiler-provided headers that
are designed to be safe to use for bare-metal contexts (like in
kernels).  Avoiding them is not necessary per se.  However, 
is not particularly useful if you want to use your own printf-style
functions with the usual format specifiers (see above for __u64).  But
on its own, it's perfectly safe to use.  You have problems with
 *because* you use well-known, standard facilities in kernel
space (the printf format specifiers), not because you avoid them.  So
exactly the opposite of what you say.

> But until then, we have to stick to our variable name types,
> just like all other operating systems have to (we are not alone here.)

FreeBSD uses  and the  formatting macros in kernel
space.  I don't think that's unusual at all for current kernels.  It's
particularly safe for FreeBSD because they use a monorepo and toolchain
variance among developers is greatly reduced.  Linux would need to
provide its own  equivalent for the formatting macros
(as it's not a compiler header; FreeBSD has ).

At this point and with the current ABIs we have for Linux, it makes
equal (maybe more) sense to avoid the  types altogether and
use Linux-specific typedefs with have architecture-independent format
strings.

Thanks,
Florian



Re: [PATCH v3] rs6000: Rework ELFv2 support for -fpatchable-function-entry* [PR99888]

2022-08-24 Thread Kewen.Lin via Gcc-patches
on 2022/8/24 22:01, Segher Boessenkool wrote:
> On Wed, Aug 24, 2022 at 03:30:51PM +0800, Kewen.Lin wrote:
>> on 2022/8/23 22:33, Segher Boessenkool wrote:
>> I thought if we can consider [1] and updated the documentation similarly
>> like "For PowerPC with the ELFv2 ABI, there will be M nops before the global
>> entry point, and N-M after the local entry point".
> 
> But that does not agree with the documentation.  The N nops have to be
> consecutive.  If you want to support adding separate nop regions before
> the LEP and GEP entry points, that is fine, but it will need a separate
> command line option.
> 

OK, previously I thought if we can claim GEP and LEP (and the area between) as
one special function entry (area) in documentation, but admittedly it's too 
tricky.

Adding one separated command line option now just for one potential use case in
future seems not a good idea.  Following the previous proposal, I just posted
v4 at:

https://gcc.gnu.org/pipermail/gcc-patches/2022-August/600277.html

BR,
Kewen


Re: [PATCH v3] Many pages: Document fixed-width types with ISO C naming

2022-08-24 Thread Greg Kroah-Hartman via Gcc-patches
On Thu, Aug 25, 2022 at 01:36:10AM +0200, Alejandro Colomar wrote:
> But from your side what do we have?  Just direct NAKs without much
> explanation.  The only one who gave some explanation was Greg, and he
> vaguely pointed to Linus's comments about it in the past, with no precise
> pointer to it.  I investigated a lot before v2, and could not find anything
> strong enough to recommend using kernel types in user space, so I pushed v2,
> and the discussion was kept.

So despite me saying that "this is not ok", and many other maintainers
saying "this is not ok", you applied a patch with our objections on it?
That is very odd and a bit rude.

> I would like that if you still oppose to the patch, at least were able to
> provide some facts to this discussion.

The fact is that the kernel can not use the namespace that userspace has
with ISO C names.  It's that simple as the ISO standard does NOT
describe the variable types for an ABI that can cross the user/kernel
boundry.

Work with the ISO C standard if you wish to document such type usage,
and get it approved and then we would be willing to consider such a
change.  But until then, we have to stick to our variable name types,
just like all other operating systems have to (we are not alone here.)

Please revert your change.

greg k-h


Re: [PATCH] libstdc++: Optimize operator+(string/char*, string/char*) equally

2022-08-24 Thread Will Hawkins
On Wed, Aug 24, 2022 at 7:03 PM Jonathan Wakely  wrote:
>
> On Wed, 24 Aug 2022 at 23:47, Jonathan Wakely  wrote:
> >
> > On Wed, 24 Aug 2022 at 23:39, Alexandre Oliva  wrote:
> > >
> > > On Aug 24, 2022, Jonathan Wakely via Gcc-patches 
> > >  wrote:
> > >
> > > >* include/bits/basic_string.h (operator+(const string&,
> > > > const char*)):
> > > >Remove naive implementation.
> > > >* include/bits/basic_string.tcc (operator+(const string&,
> > > > const char*)):
> > > >Add single-allocation implementation.
> > >
> > > ISTM this requires the following additional tweak:
> > >
> > > diff --git a/libstdc++-v3/src/c++11/string-inst.cc 
> > > b/libstdc++-v3/src/c++11/string-inst.cc
> > > index bfae6d902a1dd..2ec0e9d85f947 100644
> > > --- a/libstdc++-v3/src/c++11/string-inst.cc
> > > +++ b/libstdc++-v3/src/c++11/string-inst.cc
> > > @@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >
> > >template class basic_string;
> > >template S operator+(const C*, const S&);
> > > +  template S operator+(const S&, const C*);
> > >template S operator+(C, const S&);
> > >template S operator+(const S&, const S&);
> > >

I realize that I should have noticed that asymmetry as well. Sorry!

> > >
> > > Without this, I'm getting undefined references to this specialization in
> > > libstdc++.so, that I tracked down to a std::system_error ctor in
> > > cxx11-ios_failure.o.  I got this while testing another patch that might
> > > be the reason why the template instantiation doesn't get inlined, but...
> > > we can't depend on its being inlined, can we?
> >
> > Right. But adding that will cause another symbol to be exported,
> > probably with the wrong symbol version.
>
> Oh, but those symbols aren't exported ... they're just needed because
> we compile with -fno-implicit-templatesand other symbols in
> libstdc++.so require them.
>
> So that probably is the right fix. I have another change for operator+
> in mind now anyway, which optimizes operator(const string&, char) the
> same way, and removes the duplication in those five operator+
> overloads.

Let me know if/how I can help.

Will

>
> >
> > To fix https://gcc.gnu.org/PR106735 I'm just going to revert it for
> > now, and revisit in the morning.
>


[PATCH v4] rs6000: Rework ELFv2 support for -fpatchable-function-entry* [PR99888]

2022-08-24 Thread Kewen.Lin via Gcc-patches
Hi,

As PR99888 and its related show, the current support for
-fpatchable-function-entry on powerpc ELFv2 doesn't work
well with global entry existence.  For example, with one
command line option -fpatchable-function-entry=3,2, it got
below w/o this patch:

  .LPFE1:
  nop
  nop
  .type   foo, @function
  foo:
  nop
  .LFB0:
  .cfi_startproc
  .LCF0:
  0:  addis 2,12,.TOC.-.LCF0@ha
  addi 2,2,.TOC.-.LCF0@l
  .localentry foo,.-foo

, the assembly is unexpected since the patched nops have
no effects when being entered from local entry.

This patch is to update the nops patched before and after
local entry, it looks like:

  .type   foo, @function
  foo:
  .LFB0:
  .cfi_startproc
  .LCF0:
  0:  addis 2,12,.TOC.-.LCF0@ha
  addi 2,2,.TOC.-.LCF0@l
  nop
  nop
  .localentry foo,.-foo
  nop

Bootstrapped and regtested on powerpc64-linux-gnu P7 & P8,
and powerpc64le-linux-gnu P9 & P10.

v4: Change the remaining NOP to nop and update documentation of option
-fpatchable-function-entry for PowerPC ELFv2 ABI dual entry points
as Segher suggested.

v3: https://gcc.gnu.org/pipermail/gcc-patches/2022-August/599925.html

v2: https://gcc.gnu.org/pipermail/gcc-patches/2022-August/599617.html

v1: https://gcc.gnu.org/pipermail/gcc-patches/2022-August/599461.html

Is it ok for trunk?

BR,
Kewen

PR target/99888
PR target/105649

gcc/ChangeLog:

* doc/invoke.texi (option -fpatchable-function-entry): Adjust the
documentation for PowerPC ELFv2 ABI dual entry points.
* config/rs6000/rs6000-internal.h
(rs6000_print_patchable_function_entry): New function declaration.
* config/rs6000/rs6000-logue.cc (rs6000_output_function_prologue):
Support patchable-function-entry by emitting nops before and after
local entry for the function that needs global entry.
* config/rs6000/rs6000.cc (rs6000_print_patchable_function_entry): Skip
the function that needs global entry till global entry has been
emitted.
* config/rs6000/rs6000.h (struct machine_function): New bool member
global_entry_emitted.

gcc/testsuite/ChangeLog:

* gcc.target/powerpc/pr99888-1.c: New test.
* gcc.target/powerpc/pr99888-2.c: New test.
* gcc.target/powerpc/pr99888-3.c: New test.
* gcc.target/powerpc/pr99888-4.c: New test.
* gcc.target/powerpc/pr99888-5.c: New test.
* gcc.target/powerpc/pr99888-6.c: New test.
* c-c++-common/patchable_function_entry-default.c: Adjust for
powerpc_elfv2 to avoid compilation error.
---
 gcc/config/rs6000/rs6000-internal.h   |  5 +++
 gcc/config/rs6000/rs6000-logue.cc | 32 ++
 gcc/config/rs6000/rs6000.cc   | 10 -
 gcc/config/rs6000/rs6000.h|  4 ++
 gcc/doc/invoke.texi   |  8 +++-
 .../patchable_function_entry-default.c|  3 ++
 gcc/testsuite/gcc.target/powerpc/pr99888-1.c  | 43 +++
 gcc/testsuite/gcc.target/powerpc/pr99888-2.c  | 43 +++
 gcc/testsuite/gcc.target/powerpc/pr99888-3.c  | 11 +
 gcc/testsuite/gcc.target/powerpc/pr99888-4.c  | 13 ++
 gcc/testsuite/gcc.target/powerpc/pr99888-5.c  | 13 ++
 gcc/testsuite/gcc.target/powerpc/pr99888-6.c  | 14 ++
 12 files changed, 195 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-1.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-2.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-4.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-5.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-6.c

diff --git a/gcc/config/rs6000/rs6000-internal.h 
b/gcc/config/rs6000/rs6000-internal.h
index 8ee8c987b81..d80c04b5ae5 100644
--- a/gcc/config/rs6000/rs6000-internal.h
+++ b/gcc/config/rs6000/rs6000-internal.h
@@ -183,10 +183,15 @@ extern tree rs6000_fold_builtin (tree fndecl 
ATTRIBUTE_UNUSED,
 tree *args ATTRIBUTE_UNUSED,
 bool ignore ATTRIBUTE_UNUSED);

+extern void rs6000_print_patchable_function_entry (FILE *,
+  unsigned HOST_WIDE_INT,
+  bool);
+
 extern bool rs6000_passes_float;
 extern bool rs6000_passes_long_double;
 extern bool rs6000_passes_vector;
 extern bool rs6000_returns_struct;
 extern bool cpu_builtin_p;

+
 #endif
diff --git a/gcc/config/rs6000/rs6000-logue.cc 
b/gcc/config/rs6000/rs6000-logue.cc
index 59fe1c8cb8b..51f55d1d527 100644
--- a/gcc/config/rs6000/rs6000-logue.cc
+++ b/gcc/config/rs6000/rs6000-logue.cc
@@ -4013,11 +4013,43 @@ rs6000_output_function_prologue (FILE *file)
  fprintf (file, "\tadd 2,2,12\n");
 

Re: [PATCH, rs6000] Change insn condition from TARGET_64BIT to TARGET_POWERPC64 for VSX scalar extract/insert instructions

2022-08-24 Thread Kewen.Lin via Gcc-patches
on 2022/8/25 11:37, HAO CHEN GUI wrote:
> Hi,
> 
> On 24/8/2022 下午 1:24, Kewen.Lin wrote:
>> Could you try to test with dg-options "-mdejagnu-cpu=power9 -mpowerpc64" all 
>> the time, but still
>> having that has_arch_ppc64 effective target on aix?
>>
>> I'd expect has_arch_ppc64 check to fail on aix 32bit, the error will not be 
>> a problem (turning
>> into an UNSUPPORTED then)?
> 
> I tested it on AIX. "has_arch_ppc64" fails with dg-options 
> "-mdejagnu-cpu=power9 -mpowerpc64" on
> 32-bit AIX environment. It works as we expected.

Nice, thanks for your time on testing.

> 
> Also I found that AIX and Darwin are skipped for bfp test. So in testcase, 
> it's no need to care
> about them. Not sure if it's intention.
> 
> In bfp.exp
> 
> # Exit immediately if this isn't a PowerPC target or if the target is
> # aix or Darwin.
> if { (![istarget powerpc*-*-*] && ![istarget rs6000-*-*])
>  || [istarget "powerpc*-*-aix*"]
>  || [istarget "powerpc*-*-darwin*"]  } then {
>   return
> }

I can't find a hint about why we wanted to disable bfp testing on aix, it looks 
like a overkill to me.

Could you help to further test if all test cases in this small bucket available 
on aix?

Maybe it can give us some evidences on why it's intentional or not.

Hi David & Segher,

Do you have some insights on this?

BR,
Kewen


Re: [PATCH] Don't gimple fold ymm-version vblendvpd/vblendvps/vpblendvb w/o TARGET_AVX2

2022-08-24 Thread Hongtao Liu via Gcc-patches
On Wed, Aug 24, 2022 at 9:15 AM liuhongt  wrote:
>
> Since 256-bit vector integer comparison is under TARGET_AVX2,
> and gimple folding for vblendvpd/vblendvps/vpblendvb relies on that.
> Restrict gimple fold condition to TARGET_AVX2.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> Ok for trunk?
ready push to trunk and backport to gcc-12 branch.
>
> gcc/ChangeLog:
>
> PR target/106704
> * config/i386/i386-builtin.def (BDESC): Add
> CODE_FOR_avx_blendvpd256/CODE_FOR_avx_blendvps256 to
> corresponding builtins.
> * config/i386/i386.cc (ix86_gimple_fold_builtin):
> Don't fold IX86_BUILTIN_PBLENDVB256, IX86_BUILTIN_BLENDVPS256,
> IX86_BUILTIN_BLENDVPD256 w/o TARGET_AVX2.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/pr106704.c: New test.
> ---
>  gcc/config/i386/i386-builtin.def |  4 ++--
>  gcc/config/i386/i386.cc  | 12 +---
>  gcc/testsuite/gcc.target/i386/pr106704.c | 16 
>  3 files changed, 27 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr106704.c
>
> diff --git a/gcc/config/i386/i386-builtin.def 
> b/gcc/config/i386/i386-builtin.def
> index acb7e8ca64b..f9c7abde2cf 100644
> --- a/gcc/config/i386/i386-builtin.def
> +++ b/gcc/config/i386/i386-builtin.def
> @@ -1036,8 +1036,8 @@ BDESC (OPTION_MASK_ISA_AVX, 0, 
> CODE_FOR_avx_vpermilvarv8sf3, "__builtin_ia32_vpe
>
>  BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_blendpd256, 
> "__builtin_ia32_blendpd256", IX86_BUILTIN_BLENDPD256, UNKNOWN, (int) 
> V4DF_FTYPE_V4DF_V4DF_INT)
>  BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_blendps256, 
> "__builtin_ia32_blendps256", IX86_BUILTIN_BLENDPS256, UNKNOWN, (int) 
> V8SF_FTYPE_V8SF_V8SF_INT)
> -BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, 
> "__builtin_ia32_blendvpd256", IX86_BUILTIN_BLENDVPD256, UNKNOWN, (int) 
> V4DF_FTYPE_V4DF_V4DF_V4DF)
> -BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, 
> "__builtin_ia32_blendvps256", IX86_BUILTIN_BLENDVPS256, UNKNOWN, (int) 
> V8SF_FTYPE_V8SF_V8SF_V8SF)
> +BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_blendvpd256, 
> "__builtin_ia32_blendvpd256", IX86_BUILTIN_BLENDVPD256, UNKNOWN, (int) 
> V4DF_FTYPE_V4DF_V4DF_V4DF)
> +BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_blendvps256, 
> "__builtin_ia32_blendvps256", IX86_BUILTIN_BLENDVPS256, UNKNOWN, (int) 
> V8SF_FTYPE_V8SF_V8SF_V8SF)
>  BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_dpps256, 
> "__builtin_ia32_dpps256", IX86_BUILTIN_DPPS256, UNKNOWN, (int) 
> V8SF_FTYPE_V8SF_V8SF_INT)
>  BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_shufpd256, 
> "__builtin_ia32_shufpd256", IX86_BUILTIN_SHUFPD256, UNKNOWN, (int) 
> V4DF_FTYPE_V4DF_V4DF_INT)
>  BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_shufps256, 
> "__builtin_ia32_shufps256", IX86_BUILTIN_SHUFPS256, UNKNOWN, (int) 
> V8SF_FTYPE_V8SF_V8SF_INT)
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index e27c87f8c83..c4d0e36e9c0 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -18452,6 +18452,15 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> }
>break;
>
> +case IX86_BUILTIN_PBLENDVB256:
> +case IX86_BUILTIN_BLENDVPS256:
> +case IX86_BUILTIN_BLENDVPD256:
> +  /* pcmpeqb/d/q is under avx2, w/o avx2, it's veclower
> +to scalar operations and not combined back.  */
> +  if (!TARGET_AVX2)
> +   break;
> +
> +  /* FALLTHRU.  */
>  case IX86_BUILTIN_BLENDVPD:
>/* blendvpd is under sse4.1 but pcmpgtq is under sse4.2,
>  w/o sse4.2, it's veclowered to scalar operations and
> @@ -18460,10 +18469,7 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
> break;
>/* FALLTHRU.  */
>  case IX86_BUILTIN_PBLENDVB128:
> -case IX86_BUILTIN_PBLENDVB256:
>  case IX86_BUILTIN_BLENDVPS:
> -case IX86_BUILTIN_BLENDVPS256:
> -case IX86_BUILTIN_BLENDVPD256:
>gcc_assert (n_args == 3);
>arg0 = gimple_call_arg (stmt, 0);
>arg1 = gimple_call_arg (stmt, 1);
> diff --git a/gcc/testsuite/gcc.target/i386/pr106704.c 
> b/gcc/testsuite/gcc.target/i386/pr106704.c
> new file mode 100644
> index 000..44e052a4caa
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr106704.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mavx -O2 -mno-avx2" } */
> +/* { dg-final { scan-assembler-times {vblendvps[ \t]+%ymm[0-9]+} 1 } } */
> +/* { dg-final { scan-assembler-times {vblendvpd[ \t]+%ymm[0-9]+} 1 } } */
> +
> +#include 
> +
> +__m256 bend_stuff( __m256 a, __m256 b, __m256 mask)
> +{
> +  return _mm256_blendv_ps(a, b, mask);
> +}
> +
> +__m256d bend_stuff1( __m256d a, __m256d b, __m256d mask)
> +{
> +  return _mm256_blendv_pd(a, b, mask);
> +}
> --
> 2.18.1
>


-- 
BR,
Hongtao


Re: [PATCH, rs6000] Change insn condition from TARGET_64BIT to TARGET_POWERPC64 for VSX scalar extract/insert instructions

2022-08-24 Thread HAO CHEN GUI via Gcc-patches
Hi,

On 24/8/2022 下午 1:24, Kewen.Lin wrote:
> Could you try to test with dg-options "-mdejagnu-cpu=power9 -mpowerpc64" all 
> the time, but still
> having that has_arch_ppc64 effective target on aix?
> 
> I'd expect has_arch_ppc64 check to fail on aix 32bit, the error will not be a 
> problem (turning
> into an UNSUPPORTED then)?

I tested it on AIX. "has_arch_ppc64" fails with dg-options 
"-mdejagnu-cpu=power9 -mpowerpc64" on
32-bit AIX environment. It works as we expected.

Also I found that AIX and Darwin are skipped for bfp test. So in testcase, it's 
no need to care
about them. Not sure if it's intention.

In bfp.exp

# Exit immediately if this isn't a PowerPC target or if the target is
# aix or Darwin.
if { (![istarget powerpc*-*-*] && ![istarget rs6000-*-*])
 || [istarget "powerpc*-*-aix*"]
 || [istarget "powerpc*-*-darwin*"]  } then {
  return
}


Re: [PATCH v3] Many pages: Document fixed-width types with ISO C naming

2022-08-24 Thread Linus Torvalds
On Wed, Aug 24, 2022 at 4:36 PM Alejandro Colomar
 wrote:
>
> I'm trying to be nice, and ask for review to make sure I'm not making
> some big mistake by accident, and I get disrespect?  No thanks.

You've been told multiple times that the kernel doesn't use the
"standard" names, and *cannot* use them for namespace reasons, and you
ignore all the feedback, and then you claim you are asking for review?

That's not "asking for review". That's "I think I know the answer, and
when people tell me otherwise I ignore them".

The fact is, kernel UAPI header files MUST NOT use the so-called standard names.

We cannot provide said names, because they are only provided by the
standard header files.

And since kernel header files cannot provide them, then kernel UAPI
header files cannot _use_ them.

End result: any kernel UAPI header file will continue to use __u32 etc
naming that doesn't have any namespace pollution issues.

Nothing else is even remotely acceptable.

Stop trying to make this something other than it is.

And if you cannot accept these simple technical reasons, why do you
expect respect?

Why are you so special that you think you can change the rules for
kernel uapi files over the *repeated* objections from maintainers who
know better?

  Linus


Re: [PATCH v3] Many pages: Document fixed-width types with ISO C naming

2022-08-24 Thread Alejandro Colomar via Gcc-patches

Alexei,


On 8/24/22 20:55, Alejandro Colomar wrote:
> Link: 


> Link: 
> Signed-off-by: Alejandro Colomar 
> Nacked-by: Alexei Starovoitov 
> Nacked-by: Greg Kroah-Hartman 
> Nacked-by: Daniel Borkmann 
> Acked-by: Zack Weinberg 



On 8/25/22 00:40, Alexei Starovoitov wrote:

On Wed, Aug 24, 2022 at 12:04 PM Alejandro Colomar
 wrote:


diff --git a/man2/bpf.2 b/man2/bpf.2
index d05b73ec2..84d1b62e5 100644
--- a/man2/bpf.2
+++ b/man2/bpf.2


[...]



  struct {/* Used by BPF_PROG_LOAD */
-__u32 prog_type;
-__u32 insn_cnt;
+uint32_t  prog_type;
+uint32_t  insn_cnt;


For the N-th time:
Nacked-by: Alexei Starovoitov 

Please stop sending this patch.


Sorry, but no.

First, this has only been v3, and v1 was a year and a half ago, don't 
make it like I'm constantly making you lose your precious time, because 
I'm actively trying not to.


Second, I already made a big notice that you and a few more have 
strongly opposed to the patch, respectfully keeping all of your NAKs in 
my patch, as you can see above.


I gave very detailed reasons of why this patch is reasonable and, back 
in the days of v1, Zack (from glibc) gave even better reasons of why the 
manual pages should document ISO C (libc) types, and not kernel ones, 
and why it shouldn't matter to user-space programmers.


But from your side what do we have?  Just direct NAKs without much 
explanation.  The only one who gave some explanation was Greg, and he 
vaguely pointed to Linus's comments about it in the past, with no 
precise pointer to it.  I investigated a lot before v2, and could not 
find anything strong enough to recommend using kernel types in user 
space, so I pushed v2, and the discussion was kept.


I would like that if you still oppose to the patch, at least were able 
to provide some facts to this discussion.


But the most fundamental thing that I ask is that you respect me.

With this attitude, the only thing you're going to get is that I apply 
the patch right after, because:


1) The patch is right.  Go talk to glibc and gcc maintainers, who know 
how types work by heart if you have doubts.


2) I'm the maintainer of this project, and under doubts, it's my decission.

I'm trying to be nice, and ask for review to make sure I'm not making 
some big mistake by accident, and I get disrespect?  No thanks.



Patch applied.


Now, if someone with a bit more respect still thinks this change is 
incorrect, and is wanting to share some facts to show me my mistake, 
I'll happily review it and revert the patch if necessary.  For now, the 
patch is applied.



Alex


--
Alejandro Colomar
Linux man-pages maintainer



OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] libstdc++: Optimize operator+(string/char*, string/char*) equally

2022-08-24 Thread Jonathan Wakely via Gcc-patches
On Wed, 24 Aug 2022 at 23:47, Jonathan Wakely  wrote:
>
> On Wed, 24 Aug 2022 at 23:39, Alexandre Oliva  wrote:
> >
> > On Aug 24, 2022, Jonathan Wakely via Gcc-patches  
> > wrote:
> >
> > >* include/bits/basic_string.h (operator+(const string&,
> > > const char*)):
> > >Remove naive implementation.
> > >* include/bits/basic_string.tcc (operator+(const string&,
> > > const char*)):
> > >Add single-allocation implementation.
> >
> > ISTM this requires the following additional tweak:
> >
> > diff --git a/libstdc++-v3/src/c++11/string-inst.cc 
> > b/libstdc++-v3/src/c++11/string-inst.cc
> > index bfae6d902a1dd..2ec0e9d85f947 100644
> > --- a/libstdc++-v3/src/c++11/string-inst.cc
> > +++ b/libstdc++-v3/src/c++11/string-inst.cc
> > @@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >
> >template class basic_string;
> >template S operator+(const C*, const S&);
> > +  template S operator+(const S&, const C*);
> >template S operator+(C, const S&);
> >template S operator+(const S&, const S&);
> >
> >
> > Without this, I'm getting undefined references to this specialization in
> > libstdc++.so, that I tracked down to a std::system_error ctor in
> > cxx11-ios_failure.o.  I got this while testing another patch that might
> > be the reason why the template instantiation doesn't get inlined, but...
> > we can't depend on its being inlined, can we?
>
> Right. But adding that will cause another symbol to be exported,
> probably with the wrong symbol version.

Oh, but those symbols aren't exported ... they're just needed because
we compile with -fno-implicit-templatesand other symbols in
libstdc++.so require them.

So that probably is the right fix. I have another change for operator+
in mind now anyway, which optimizes operator(const string&, char) the
same way, and removes the duplication in those five operator+
overloads.

>
> To fix https://gcc.gnu.org/PR106735 I'm just going to revert it for
> now, and revisit in the morning.



Re: [PATCH] libstdc++: Optimize operator+(string/char*, string/char*) equally

2022-08-24 Thread Jonathan Wakely via Gcc-patches
On Wed, 24 Aug 2022 at 23:39, Alexandre Oliva  wrote:
>
> On Aug 24, 2022, Jonathan Wakely via Gcc-patches  
> wrote:
>
> >* include/bits/basic_string.h (operator+(const string&,
> > const char*)):
> >Remove naive implementation.
> >* include/bits/basic_string.tcc (operator+(const string&,
> > const char*)):
> >Add single-allocation implementation.
>
> ISTM this requires the following additional tweak:
>
> diff --git a/libstdc++-v3/src/c++11/string-inst.cc 
> b/libstdc++-v3/src/c++11/string-inst.cc
> index bfae6d902a1dd..2ec0e9d85f947 100644
> --- a/libstdc++-v3/src/c++11/string-inst.cc
> +++ b/libstdc++-v3/src/c++11/string-inst.cc
> @@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>template class basic_string;
>template S operator+(const C*, const S&);
> +  template S operator+(const S&, const C*);
>template S operator+(C, const S&);
>template S operator+(const S&, const S&);
>
>
> Without this, I'm getting undefined references to this specialization in
> libstdc++.so, that I tracked down to a std::system_error ctor in
> cxx11-ios_failure.o.  I got this while testing another patch that might
> be the reason why the template instantiation doesn't get inlined, but...
> we can't depend on its being inlined, can we?

Right. But adding that will cause another symbol to be exported,
probably with the wrong symbol version.

To fix https://gcc.gnu.org/PR106735 I'm just going to revert it for
now, and revisit in the morning.



Re: [PATCH v3] Many pages: Document fixed-width types with ISO C naming

2022-08-24 Thread Alexei Starovoitov via Gcc-patches
On Wed, Aug 24, 2022 at 12:04 PM Alejandro Colomar
 wrote:
>
> diff --git a/man2/bpf.2 b/man2/bpf.2
> index d05b73ec2..84d1b62e5 100644
> --- a/man2/bpf.2
> +++ b/man2/bpf.2
> @@ -169,34 +169,34 @@ commands:
>  .EX
>  union bpf_attr {
>  struct {/* Used by BPF_MAP_CREATE */
> -__u32 map_type;
> -__u32 key_size;/* size of key in bytes */
> -__u32 value_size;  /* size of value in bytes */
> -__u32 max_entries; /* maximum number of entries
> +uint32_t  map_type;
> +uint32_t  key_size;/* size of key in bytes */
> +uint32_t  value_size;  /* size of value in bytes */
> +uint32_t  max_entries; /* maximum number of entries
>in a map */
>  };
>
>  struct {/* Used by BPF_MAP_*_ELEM and BPF_MAP_GET_NEXT_KEY
> commands */
> -__u32 map_fd;
> +uint32_t  map_fd;
>  __aligned_u64 key;
>  union {
>  __aligned_u64 value;
>  __aligned_u64 next_key;
>  };
> -__u64 flags;
> +uint64_t  flags;
>  };
>
>  struct {/* Used by BPF_PROG_LOAD */
> -__u32 prog_type;
> -__u32 insn_cnt;
> +uint32_t  prog_type;
> +uint32_t  insn_cnt;

For the N-th time:
Nacked-by: Alexei Starovoitov 

Please stop sending this patch.


Re: [PATCH] libstdc++: Optimize operator+(string/char*, string/char*) equally

2022-08-24 Thread Alexandre Oliva via Gcc-patches
On Aug 24, 2022, Jonathan Wakely via Gcc-patches  
wrote:

>* include/bits/basic_string.h (operator+(const string&,
> const char*)):
>Remove naive implementation.
>* include/bits/basic_string.tcc (operator+(const string&,
> const char*)):
>Add single-allocation implementation.

ISTM this requires the following additional tweak:

diff --git a/libstdc++-v3/src/c++11/string-inst.cc 
b/libstdc++-v3/src/c++11/string-inst.cc
index bfae6d902a1dd..2ec0e9d85f947 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template class basic_string;
   template S operator+(const C*, const S&);
+  template S operator+(const S&, const C*);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
 

Without this, I'm getting undefined references to this specialization in
libstdc++.so, that I tracked down to a std::system_error ctor in
cxx11-ios_failure.o.  I got this while testing another patch that might
be the reason why the template instantiation doesn't get inlined, but...
we can't depend on its being inlined, can we?

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH v4] c++: Implement -Wself-move warning [PR81159]

2022-08-24 Thread Marek Polacek via Gcc-patches
On Tue, Aug 23, 2022 at 05:27:00PM -0400, Jason Merrill wrote:
> On 8/23/22 09:39, Marek Polacek wrote:
> > +  tree arg = CALL_EXPR_ARG (fn, 0);
> > +  extract_op (arg);
> > +  if (TREE_CODE (arg) == ADDR_EXPR)
> > +arg = TREE_OPERAND (arg, 0);
> > +  tree type = TREE_TYPE (lhs);
> > +  lhs = maybe_undo_parenthesized_ref (lhs);
> > +  STRIP_ANY_LOCATION_WRAPPER (lhs);
> > +  const bool print_var_p = (DECL_P (lhs)
> > +   || REFERENCE_REF_P (lhs)
> > +   || TREE_CODE (lhs) == COMPONENT_REF);
> 
> Why include REFERENCE_REF_P and COMPONENT_REF?  Reference refs should be
> stripped before this test, member refs aren't variables.

I'm checking REFERENCE_REF_P and COMPONENT_REF to say "moving a variable"
in #1 and #3.  The REFERENCE_REF_P check means that we also say "variable"
for #2.  Sure, "A variable is introduced by the declaration of a reference
other than a non-static data member", but I'm not sure if users care about
that here?

If I strip REFERENCE_REFs before the check then the result will be the
same.  Or I could keep only the DECL_P check, but then we'll say "moving
an expression" for #1 and #2, which seems strange.

struct S {
  int x;
  int &r;
  void foo () {
x = std::move (x); // #1
r = std::move (r); // #2
  };
};

void
foo (int &r)
{
  r = std::move (r); // #3
}

Marek



Re: [PATCH] c++: Implement C++23 P2071R2 - Named universal character escapes [PR106648]

2022-08-24 Thread Jason Merrill via Gcc-patches

On 8/21/22 14:18, Jakub Jelinek wrote:

Hi!

The following patch implements the
C++23 P2071R2 - Named universal character escapes
paper to support \N{LATIN SMALL LETTER E} etc.
I've used Unicode 14.0, there are 144803 character name properties
(including the ones generated by Unicode NR1 and NR2 rules)
and correction/control/alternate aliases, together with zero terminators
that would be 3884745 bytes, which is clearly unacceptable for libcpp.
This patch instead contains a generator which from the UnicodeData.txt
and NameAliases.txt files emits a space optimized radix tree (208765
bytes long for 14.0), a single string literal dictionary (59418 bytes),
maximum name length (currently 88 chars) and two small helper arrays
for the NR1/NR2 name generation.
The radix tree needs 2 to 9 bytes per node, the exact format is
described in the generator program.  There could be ways to shrink
the dictionary size somewhat at the expense of slightly slower lookups.

Currently the patch implements strict matching (that is what is needed
to actually implement it on valid code) and Unicode UAX44-LM2 algorithm
loose matching to provide hints (that algorithm essentially ignores
hyphens in between two alphanumeric characters, spaces and underscores
(with one exception for hyphen) and does case insensitive matching).
In the attachment is a WIP patch that shows how to implement also
spellcheck.{h,cc} style discovery of misspellings, but I'll need to talk
to David Malcolm about it, as spellcheck.{h,cc} is in gcc/ subdir
(so the WIP incremental patch instead prints all the names to stderr).

Resending with the generated uname2c.h part of patch split into
compressed attachment, as it was too large for gcc-patches.

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


Does the copyright 2005-2022 mean that this code is partly derived from 
some other?



2022-08-20  Jakub Jelinek  

PR c++/106648
libcpp/
* charset.cc - Implement C++23
P2071R2 - Named universal character escapes.  Include uname2c.h.
(hangul_syllables, hangul_count): New variables.
(struct uname2c_data): New type.
(_cpp_uname2c): New function.
(_cpp_valid_ucn): Use it.  Handle named universal character escapes.
(convert_ucn): Adjust comment.
(convert_escape): Call convert_ucn even for \N.
(_cpp_interpret_identifier): Handle named universal character escapes.
* lex.cc (get_bidi_ucn): Fix up function comment formatting.
(get_bidi_named): New function.
(forms_identifier_p, lex_string): Handle named universal character
escapes.
* makeuname2c.cc: New file.
* uname2c.h: New generated file.
gcc/testsuite/
* c-c++-common/cpp/named-universal-char-escape-1.c: New test.
* c-c++-common/cpp/named-universal-char-escape-2.c: New test.
* c-c++-common/cpp/named-universal-char-escape-3.c: New test.
* c-c++-common/cpp/named-universal-char-escape-4.c: New test.
* c-c++-common/Wbidi-chars-25.c: New test.
* gcc.dg/cpp/named-universal-char-escape-1.c: New test.
* gcc.dg/cpp/named-universal-char-escape-2.c: New test.
* g++.dg/cpp/named-universal-char-escape-1.C: New test.
* g++.dg/cpp/named-universal-char-escape-2.C: New test.

--- libcpp/charset.cc.jj2022-08-20 10:26:30.971107520 +0200
+++ libcpp/charset.cc   2022-08-20 23:29:12.817996729 +0200
@@ -921,6 +921,282 @@ struct ucnrange {
  /* ISO 10646 defines the UCS codespace as the range 0-0x10 inclusive.  */
  #define UCS_LIMIT 0x10
  
+#include "uname2c.h"

+
+static const char hangul_syllables[][4] = {
+  /* L */
+  "G", "GG", "N", "D", "DD", "R", "M", "B", "BB", "S", "SS", "",
+  "J", "JJ", "C", "K", "T", "P", "H",
+  /* V */
+  "A", "AE", "YA", "YAE", "EO", "E", "YEO", "YE", "O", "WA", "WAE",
+  "OE", "YO", "U", "WEO", "WE", "WI", "YU", "EU", "YI", "I",
+  /* T */
+  "", "G", "GG", "GS", "N", "NJ", "NH", "D", "L", "LG", "LM", "LB",
+  "LS", "LT", "LP", "LH", "M", "B", "BS", "S", "SS", "NG", "J", "C",
+  "K", "T", "P", "H"
+};
+
+static const short hangul_count[6] = { 19, 21, 28 };
+
+/* Used for Unicode loose matching rule UAX44-LM2 matching.  */
+
+struct uname2c_data
+{
+  char *canon_name;
+  char prev_char;
+};
+
+/* Map NAME, a Unicode character name or correction/control/alternate
+   alias, to a Unicode codepoint, or return (cppchar_t) -1 if
+   not found.  This uses a space optimized radix tree precomputed
+   by the makeuname2c utility, with binary format documented in its
+   source makeuname2c.cc.  */
+
+static cppchar_t
+_cpp_uname2c (const char *name, size_t len, const unsigned char *n,
+ struct uname2c_data *data)
+{
+  do
+{
+  char k;
+  const char *key;
+  size_t key_len, len_adj;
+  bool has_value = *n & 0x40;
+  bool has_children, no_sibling = false;
+  cppchar_t codepoint = -1;
+  const unsigned char *child = NULL;
+  int ret;
+
+  if 

[PATCH] libstdc++: Optimize std::con/disjunction, __and_/__or_, etc

2022-08-24 Thread Patrick Palka via Gcc-patches
The internal type-level logical operations __and_ and __or_ are
currently quite slow to compile for a couple of reasons:

  1. They are drop-in replacements for std::con/disjunction, which
 are rigidly specified to form a type that derives from the first
 type argument that caused the overall computation to short-circuit.
 In practice this inheritance property seems to be rarely needed;
 usually all we care about is the value of the overall expression.
  2. Their recursive implementations instantiate up to ~N class templates
 and form up to a depth ~N inheritance chain.

This patch does away with this inheritance property of __and_ and __or_
(which seems to be unneeded in the library except indirectly by
std::con/disjunction) and redefines them as alias templates that yield
either false_type or true_type via SFINAE and overload resolution of a
pair of function templates.

As for std::con/disjunction, it seems we need to keep defining them in
terms of recursive class templates for sake of the inheritance property.
But in the recursive step, instead of using inheritance which would
yield a depth ~N inheritance chain, use a recursive member typedef which
gets immediately flattened.  Thus a specialization of conjunction and
disjunction now has depth ~1 instead of up to ~N.

In passing, redefine __not_ as an alias template for consistency with
__and_ and __or_, and to remove a layer of indirection.

Together these changes have a substantial effect on compile time and
memory usage for code that indirectly makes heavy use of these internal
type traits.  For example, for the following which tests constructibility
between two compatible 257-element tuple types

  #include 

  struct A { A(int); };

  #define M(x) x, x

  using ty1 = std::tuple;
  using ty2 = std::tuple;

  static_assert(std::is_constructible_v);

memory usage improves by ~27% from 440MB to 320M and compile time
improves by ~20% from ~2s to ~1.6s (with -std=c++23).

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

libstdc++-v3/ChangeLog:

* include/std/type_traits (enable_if, __enable_if_t): Move up
their definitions.
(__detail::__first_t): Define.
(__detail::__or_fn, __detail::__and_fn): Declare.
(__or_, __and_): Redefine as alias templates in terms of __or_fn
and __and_fn.
(__not_): Redefine as an alias template.
(__detail::__disjunction_impl, __detail::__conjunction_impl):
Define.
(conjuction, disjunction): Redefine in terms of __disjunction_impl
and __conjunction_impl.
---
 libstdc++-v3/include/std/type_traits | 152 ---
 1 file changed, 93 insertions(+), 59 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 14b029cec64..07a50a31e86 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -100,6 +100,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Metaprogramming helper types.
 
+  // Primary template.
+  /// Define a member typedef `type` only if a boolean constant is true.
+  template
+struct enable_if
+{ };
+
+  // Partial specialization for true.
+  template
+struct enable_if
+{ typedef _Tp type; };
+
+  // __enable_if_t (std::enable_if_t for C++11)
+  template
+using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
+
   template
 struct __conditional
 {
@@ -127,56 +142,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 using __type_identity_t = typename __type_identity<_Tp>::type;
 
-  template
-struct __or_;
-
-  template<>
-struct __or_<>
-: public false_type
-{ };
+  namespace __detail
+  {
+// A variadic alias template that resolves to its first argument.
+template
+  using __first_t = _Tp;
 
-  template
-struct __or_<_B1>
-: public _B1
-{ };
+// These are deliberately not defined.
+template
+  auto __or_fn(int) -> __first_t...>;
 
-  template
-struct __or_<_B1, _B2>
-: public __conditional_t<_B1::value, _B1, _B2>
-{ };
+template
+  auto __or_fn(...) -> true_type;
 
-  template
-struct __or_<_B1, _B2, _B3, _Bn...>
-: public __conditional_t<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>
-{ };
+template
+  auto __and_fn(int) -> __first_t...>;
 
-  template
-struct __and_;
+template
+  auto __and_fn(...) -> false_type;
+  } // namespace detail
 
-  template<>
-struct __and_<>
-: public true_type
-{ };
-
-  template
-struct __and_<_B1>
-: public _B1
-{ };
-
-  template
-struct __and_<_B1, _B2>
-: public __conditional_t<_B1::value, _B2, _B1>
-{ };
+  // Like C++17 std::dis/conjunction, but usable in C++11 and resolves
+  // to either true_type or false_type which allows for a more efficient
+  // implementation that avoids instantiating any class templates.
+  template
+using __or_ = decltype(__detail::__or_fn<_B

Re: [PATCH 0/3] picolibc: Add picolibc linking help

2022-08-24 Thread Keith Packard via Gcc-patches
Andrew Pinski  writes:

(removing gcc@ as not appropriate for patch discussions)

Thanks for reviewing my patches; I appreciate the time you have taken to
think about this.

> Why do you need to change the specs to support picolibc? Why not have
> the library supply the specs file instead, like what is done for
> newlib and libgloss?

Several architectures do include support for newlib's libgloss in their
gcc configuration today (i386, m32r, microblaze, nds32, pru, riscv and
sh), so I wondered if it made sense to add support for picolibc's
target-specific libraries as well.

Picolibc does deliver a spec file fragment which implements this
functionality, but that requires the addition of --specs=picolibc.specs
to the gcc command line instead of being built-in to gcc itself. When
creating an integrated toolchain using picolibc, it seems a bit odd to
require an option for the toolchain to work.

> What OS libraries are not included in libc? I trying to figure out why
> this needs to be special cased here.

As a general-purpose embedded C library, picolibc doesn't include any
OS-specific code. Instead, it defines a limited subset of POSIX
interfaces which are to be supplied by the target platform.

Picolibc itself supplies sample implementations of these ABIs that can
run on top of bare metal systems with semihosting support which are used
while testing picolibc itself.

This is similar to newlib's libgloss: the C library is built atop
another library which needs to follow it in the linker command line for
symbol resolution to work correctly. Making this work requires a change
in the *lib spec file fragment.

Adjusting the *lib fragment can either be done in an externally provided
specs file, or built-in to gcc. Both of these mechanisms are present in
the gcc ecosystem today, leading me to wonder whether the gcc community
would be interested in having an integrated option available.

-- 
-keith


signature.asc
Description: PGP signature


[PATCH v3] Many pages: Document fixed-width types with ISO C naming

2022-08-24 Thread Alejandro Colomar via Gcc-patches
Kernel __u64 and similar types are ABI-compatible, and mostly
API-compatible with ISO C types.  User-space programmers don't
care about kernel details, and should only use libc types.
Document syscalls and structures provided by the Linux kernel as
if they used libc types.

There's work in the kernel to remove this small API
incompatibility, which is only for pointers or printf specifiers.

Since I couldn't find any structure that uses pointers, there
shouldn't be any issues here.  Also, the only pointer I found was
in a syscall parameter, but since syscall(2) doesn't check its
arguments' types, we're also safe there.

This patch doesn't go without controversy.  Check the discussions
in the links below.

Found with:

$ grep -rn '\b_*[su][8136][624]*\b' man* \
  | grep -v -e /bpf-helpers.7 -e /proc.5 -e /epoll_event.3type -e /wcscmp.3 \
-e /crypt.3 -e /mempcpy.3 -e /memcmp.3 -e /string.3 -e /wcsncmp.3 \
-e /wcscasecmp.3 -e /wmemcmp.3 -e /strcasecmp.3 -e /bcmp.3 \
-e /bstring.3 -e /endian.3 -e /strverscmp.3 -e /wcsncasecmp.3 \
-e /strcoll.3 -e /strcmp.3 \
  | tee /dev/tty \
  | wc -l;

Link: 

Link: 
Signed-off-by: Alejandro Colomar 
Nacked-by: Alexei Starovoitov 
Nacked-by: Greg Kroah-Hartman 
Nacked-by: Daniel Borkmann 
Acked-by: Zack Weinberg 
Cc: LKML 
Cc: glibc 
Cc: GCC 
Cc: bpf 
Cc: LTP List 
Cc: Linux API 
Cc: linux-arch 
Cc: David Laight 
Cc: Joseph Myers 
Cc: Florian Weimer 
Cc: Daniel Borkmann 
Cc: Cyril Hrubis 
Cc: David Howells 
Cc: Arnd Bergmann 
Cc: Florian Weimer 
Cc: Rich Felker 
Cc: Adhemerval Zanella 
---

Hi,

I removed attributes from this patch.  It now only changes types,
and only types that don't have anything special in them.  __be64
or things like that are not included in this patch.  __aligned_u64
isn't either.

I made clear what the incompatibilities are, and I hope Cyril
fixes them soon, but anyway, they shouldn't affect for the cases
documented here.  And if they affect somehow, a programmer will
probably know the reason; but I'd consider that a kernel bug, or
at least something to improve there.

I'm decided to push for this change, and would like to see the
kernel making the necessary steps to make it smoother, since it
shouldn't be hard (the patch is there already; it only needs a
little bit of love).

Anyway, I don't think it will cause important problems to readers
of the manual pages, and instead expect an improvement.

Cheers,

Alex


 man2/bpf.2 |  28 +-
 man2/capget.2  |  10 +-
 man2/clone.2   |  36 +--
 man2/getunwind.2   |   6 +-
 man2/io_submit.2   |  22 +-
 man2/ioctl_ficlonerange.2  |   8 +-
 man2/ioctl_fideduperange.2 |  20 +-
 man2/ioctl_getfsmap.2  |  28 +-
 man2/ioctl_userfaultfd.2   |  37 +--
 man2/kcmp.2|   6 +-
 man2/keyctl.2  |   8 +-
 man2/landlock_add_rule.2   |   4 +-
 man2/landlock_create_ruleset.2 |   2 +-
 man2/mount_setattr.2   |   8 +-
 man2/perf_event_open.2 | 486 -
 man2/ptrace.2  |  40 +--
 man2/sched_setattr.2   |  20 +-
 man2/seccomp.2 |  24 +-
 man2/seccomp_unotify.2 |  32 +--
 man2/statx.2   |  42 +--
 man2/userfaultfd.2 |  28 +-
 man2type/open_how.2type|   6 +-
 man3type/epoll_event.3type |   2 +-
 man4/loop.4|   6 +-
 man4/random.4  |   6 +-
 man7/fanotify.7|  28 +-
 man7/netdevice.7   |   2 +-
 man7/netlink.7 |  14 +-
 man7/packet.7  |  16 +-
 man7/rtnetlink.7   |  20 +-
 man7/sock_diag.7   | 122 +
 31 files changed, 568 insertions(+), 549 deletions(-)

diff --git a/man2/bpf.2 b/man2/bpf.2
index d05b73ec2..84d1b62e5 100644
--- a/man2/bpf.2
+++ b/man2/bpf.2
@@ -169,34 +169,34 @@ commands:
 .EX
 union bpf_attr {
 struct {/* Used by BPF_MAP_CREATE */
-__u32 map_type;
-__u32 key_size;/* size of key in bytes */
-__u32 value_size;  /* size of value in bytes */
-__u32 max_entries; /* maximum number of entries
+uint32_t  map_type;
+uint32_t  key_size;/* size of key in bytes */
+uint32_t  value_size;  /* size of value in bytes */
+uint32_t  max_entries; /* maximum number of entries
   in a map */
 };
 
 struct {/* Used by BPF_MAP_*_ELEM and BPF_MAP_GET_NEXT_KEY
commands */
-__u32 map_fd;
+uint32_t  map_fd;
 __aligned_u64 key;
 union {
 __aligned_u64 value;
 __aligned_u64 next_key;
 };
-__u64

Re: [Patch] Fortran/OpenMP: Fix strictly structured blocks parsing

2022-08-24 Thread Harald Anlauf via Gcc-patches

Hi Tobias,

Am 24.08.22 um 19:47 schrieb Tobias Burnus:

This patch is about error diagnostic + an ICE for invalid code.

[...]

(So far, so good, but then the parsing-code did run into a bug.)

For the blocks, the following applies. OpenMP permits either
* strictly structured blocks (with optional END_ST == 'end target')
  !$omp target
    block
  ...
    end block
  !$omp end target  ! << this line is optional
* loosely structured block
  !$omp target
     ... ! may not start with 'block' (and hence cannot end with 'end
block')
  !$omp end target  ! << required


The parsing issue is in the following code,
which first takes care of the 'strictly':  'end block' + optional 'end
target'
and then of the 'loosely structured' case with just:  'end target':

  else if (block_construct && st == ST_END_BLOCK)
    ...
  st = next_statement ();
  if (st == omp_end_st)
  accept_statement (st);
    ...
  else if (st != omp_end_st)
    {
  unexpected_statement (st);
  st = next_statement ();
    }

The fix is to change the second if condition to:
  else if (st != omp_end_st || (block_construct && st == omp_end_st))

or rather to the following equivalent code:
  else if (st != omp_end_st || block_construct)


LGTM.


OK for mainline and GCC 12?*


Yes for both.

Thanks for the patch!

Harald


Tobias

*strictly structured blocks were added in r12-4592.


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




Re: [PATCH] IBM zSystems: Fix function_ok_for_sibcall [PR106355]

2022-08-24 Thread Stefan Schulze Frielinghaus via Gcc-patches
On Wed, Aug 17, 2022 at 01:50:45PM +0200, Stefan Schulze Frielinghaus wrote:
> For a parameter with BLKmode we cannot use REG_NREGS in order to
> determine the number of consecutive registers.  Streamlined this with
> the implementation of s390_function_arg.
> 
> Fix some indentation whitespace, too.
> 
> Assuming bootstrap and regtest are ok for mainline and gcc-{10,11,12},
> ok to install for all of those?

Meanwhile bootstrap and regtest ran successfully for all branches.


Re: [PATCH] libstdc++: Fix fallout from P2321R2 pair/tuple enhancements

2022-08-24 Thread Jonathan Wakely via Gcc-patches
On Wed, 24 Aug 2022 at 18:00, Patrick Palka via Libstdc++
 wrote:
>
> On Wed, 24 Aug 2022, Patrick Palka wrote:
>
> > r13-2159-g72886fcc626953 introduced some testsuite regressions in C++23
> > mode:
> >
> >   FAIL: 20_util/pair/requirements/explicit_instantiation/1.cc (test for 
> > excess errors)
> >   FAIL: 20_util/tuple/53648.cc (test for excess errors)
> >   FAIL: 20_util/tuple/cons/noexcept_specs.cc (test for excess errors)
> >   FAIL: 20_util/tuple/requirements/explicit_instantiation.cc (test for 
> > excess errors)
> >
> > The test noexcept_specs.cc just needs to be updated to consider the
> > additional converting constructors of tuple in C++23 mode, which happen
> > to improve constructing from a const tuple rvalue containing rvalue
> > reference elements (for the better, as far as I can tell).
> >
> > The other three tests fail because they explicitly instantiate a 
> > specialization
> > of tuple whose elements are not all const swappable, which in C++23 mode now
> > results in a hard error due to tuple's new const swap member function.  
> > Rather
> > than XFAILing the tests in C++23 mode, this patch adds non-standard 
> > constraints
> > to this member function so that we continue to accept such explicit 
> > instantiations.
> >
> > Tested on x86_64-pc-linux-gnu with and without 
> > --target_board=unix/-std=gnu++23,
> > does this look OK for trunk?
> >
> > libstdc++-v3/ChangeLog:
> >
> >   * include/std/tuple (tuple::swap const): Add is_swappable_v 
> > constraints.
>
> D'oh, pair's const swap needs the same workaround:

OK for trunk, thanks for the quick fix.

>
> -- >8 --
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/stl_pair.h (pair::swap const): Add non-standard
> is_swappable_v constraints.
> * include/std/tuple (tuple::swap const): Likewise.
> * testsuite/20_util/tuple/cons/noexcept_specs.cc: Update some
> asserts in C++23 mode.
> ---
>  libstdc++-v3/include/bits/stl_pair.h  |  8 
>  libstdc++-v3/include/std/tuple|  9 
>  .../20_util/tuple/cons/noexcept_specs.cc  | 41 +++
>  3 files changed, 58 insertions(+)
>
> diff --git a/libstdc++-v3/include/bits/stl_pair.h 
> b/libstdc++-v3/include/bits/stl_pair.h
> index bffca0daf65..a65a4763c54 100644
> --- a/libstdc++-v3/include/bits/stl_pair.h
> +++ b/libstdc++-v3/include/bits/stl_pair.h
> @@ -213,10 +213,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>}
>
>  #if __cplusplus > 202002L
> +  // As an extension, we constrain the const swap member function
> +  // in order to continue accepting explicit instantiation of tuple
> +  // specializations whose elements are not all const swappable.
> +  // Without this constraint, such an explicit instantiation would
> +  // also instantiate the ill-formed body of this function and yield
> +  // a hard error.  This constraint shouldn't affect the behavior of
> +  // valid programs.
>constexpr void
>swap(const pair& __p) const
>noexcept(__and_v<__is_nothrow_swappable,
>__is_nothrow_swappable>)
> +  requires is_swappable_v && is_swappable_v
>{
> using std::swap;
> swap(first, __p.first);
> diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
> index 05433d5ae36..9d1abc2f80e 100644
> --- a/libstdc++-v3/include/std/tuple
> +++ b/libstdc++-v3/include/std/tuple
> @@ -1176,9 +1176,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>{ _Inherited::_M_swap(__in); }
>
>  #if __cplusplus > 202002L
> +  // As an extension, we constrain this const swap member function
> +  // in order to continue accepting explicit instantiation of tuple
> +  // specializations whose elements are not all const swappable.
> +  // Without this constraint, such an explicit instantiation would
> +  // also instantiate the ill-formed body of this function and
> +  // yield a hard error.  This constraint shouldn't affect the behavior 
> of
> +  // valid programs.
>constexpr void
>swap(const tuple& __in) const
>noexcept(__and_v<__is_nothrow_swappable...>)
> +  requires (is_swappable_v && ...)
>{ _Inherited::_M_swap(__in); }
>  #endif // C++23
>  };
> @@ -1730,6 +1738,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>swap(const tuple& __in) const
>noexcept(__and_v<__is_nothrow_swappable,
>__is_nothrow_swappable>)
> +  requires is_swappable_v && is_swappable_v
>{ _Inherited::_M_swap(__in); }
>  #endif // C++23
>  };
> diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc 
> b/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
> index 6044a377348..a326d1bc228 100644
> --- a/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
> +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
> @@ -503,7 +503,17 @@ namespace 
> NothrowCopyThrowMoveThrowCopyConversionNothrowMoveCon

Re: [PATCH] c: Implement C23 nullptr (N3042)

2022-08-24 Thread Marek Polacek via Gcc-patches
On Mon, Aug 15, 2022 at 04:03:13PM -0400, Jason Merrill wrote:
> On 8/13/22 14:35, Marek Polacek wrote:
> > This patch implements the C23 nullptr literal:
> > , which is
> > intended to replace the problematic definition of NULL which might be
> > either of integer type or void*.
> > 
> > Since C++ has had nullptr for over a decade now, it was relatively easy
> > to just move the built-in node definitions from the C++ FE to the C/C++
> > common code.  Also, our DWARF emitter already handles NULLPTR_TYPE by
> > emitting DW_TAG_unspecified_type.  However, I had to handle a lot of
> > contexts such as ?:, comparison, conversion, etc.
> > 
> > There are some minor differences, e.g. in C you can do
> > 
> >bool b = nullptr;
> > 
> > but in C++ you have to use direct-initialization:
> > 
> >bool b{nullptr};
> > 
> > And I think that
> > 
> >nullptr_t n = 0;
> > 
> > is only valid in C++.
> > 
> > Of course, C doesn't have to handle mangling, RTTI, substitution,
> > overloading, ...
> > 
> > This patch also defines nullptr_t in .  I'm uncertain about
> > the __STDC_VERSION__ version I should be checking.  Also, I'm not
> > defining __STDC_VERSION_STDDEF_H__ yet, because I don't know what value
> > it should be defined to.  Do we know yet?
> > 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> The C++ changes are OK, but you probably want a comment in
> c_common_nodes_and_builtins that we aren't setting the alignment there for
> C++ backward ABI bug compatibility.  Or perhaps set it there and then break
> it in the C++ front end when abi < 9.

Thanks!  I added a comment to that effect in the v2 patch I just posted.

Marek



Re: [PATCH 0/3] picolibc: Add picolibc linking help

2022-08-24 Thread Andrew Pinski via Gcc-patches
On Wed, Aug 24, 2022 at 11:12 AM Keith Packard via Gcc-patches
 wrote:
>
> Picolibc is a C library for embedded systems based on code from newlib
> and avr libc. To connect some system-dependent picolibc functions
> (like stdio) to an underlying platform, the platform may provide an OS
> library.
>
> This OS library must follow the C library in the link command line. In
> current picolibc, that is done by providing an alternate .specs file
> which can rewrite the *lib spec to insert the OS library in the right
> spot.

Why do you need to change the specs to support picolibc? Why not have
the library supply the specs file instead, like what is done for
newlib and libgloss?

>
> This patch series adds the ability to specify the OS library on the
> gcc command line when GCC is configured to us picolibc as the default
> C library, and then hooks that up for arm, nds32, riscv and sh targets.


What OS libraries are not included in libc? I trying to figure out why
this needs to be special cased here.

Thanks,
Andrew Pinski

>
> Keith Packard (3):
>   Allow default libc to be specified to configure
>   Add newlib and picolibc as default C library choices
>   Add '--oslib=' option when default C library is picolibc
>
>  gcc/config.gcc| 56 ---
>  gcc/config/arm/elf.h  |  5 
>  gcc/config/nds32/elf.h|  4 +++
>  gcc/config/picolibc.opt   | 26 ++
>  gcc/config/riscv/elf.h|  4 +++
>  gcc/config/sh/embed-elf.h |  5 
>  gcc/configure.ac  |  4 +++
>  7 files changed, 95 insertions(+), 9 deletions(-)
>  create mode 100644 gcc/config/picolibc.opt
>
> --
> 2.36.1
>


[PATCH v2] c: Implement C23 nullptr (N3042)

2022-08-24 Thread Marek Polacek via Gcc-patches
On Mon, Aug 15, 2022 at 05:48:34PM +, Joseph Myers wrote:
> On Sat, 13 Aug 2022, Marek Polacek via Gcc-patches wrote:
> 
> > This patch also defines nullptr_t in .  I'm uncertain about
> > the __STDC_VERSION__ version I should be checking.  Also, I'm not
> 
> We're using defined (__STDC_VERSION__) && __STDC_VERSION__ > 201710L until 
> the final version for C23 is settled.
 
OK, adjusted.

> > defining __STDC_VERSION_STDDEF_H__ yet, because I don't know what value
> > it should be defined to.  Do we know yet?
> 
> No, and Jens's comments on the editorial review before CD ballot include 
> that lots of headers don't yet have such a macro definition but should 
> have one, as well as needing consistency for the numbers.
> 
> We won't know the final values for these macros until much later, because 
> the timescale depends on whether ISO decides to delay things at any point 
> by coming up with a long list of editorial issues required to follow the 
> JTC1 Directives as they did for C17 (objections to particular words 
> appearing in non-normative text, etc.).
 
Ack, thanks.

> > -  { "nullptr", RID_NULLPTR,D_CXXONLY | D_CXX11 | D_CXXWARN 
> > },
> > +  { "nullptr", RID_NULLPTR,D_CXX11 | D_CXXWARN },
> 
> You need to use D_C2X (which doesn't yet exist).  In pre-C23 modes, 
> nullptr needs to be a normal identifier that can be used in all contexts 
> where identifiers can be used, not a keyword at all (and then you need a 
> c11-nullptr*.c test to verify that use of it as an identifier works as 
> expected).

Fixed.  Adding D_C2X meant that I had to enlarge struct c_common_resword
by a word.
 
> > diff --git a/gcc/c/c-convert.cc b/gcc/c/c-convert.cc
> > index 18083d59618..013fe6b2a53 100644
> > --- a/gcc/c/c-convert.cc
> > +++ b/gcc/c/c-convert.cc
> > @@ -133,6 +133,14 @@ c_convert (tree type, tree expr, bool init_const)
> > (loc, type, c_objc_common_truthvalue_conversion (input_location, expr));
> >  
> >  case POINTER_TYPE:
> > +  /* The type nullptr_t may be converted to a pointer type.  The 
> > result is
> > +a null pointer value.  */
> > +  if (NULLPTR_TYPE_P (TREE_TYPE (e)))
> > +   {
> > + ret = build_int_cst (type, 0);
> > + goto maybe_fold;
> > +   }
> 
> That looks like it would lose side-effects.  You need to preserve 
> side-effects in an expression of nullptr_t type being converted to a 
> pointer type, and need an execution testcase that verifies such 
> side-effects are preserved.

Ah, of course.  Fixed by building up a COMPOUND_EXPR.  Covered by
c2x-nullptr-5.c.
 
> Also, you need to make sure that (void *)nullptr is not treated as a null 
> pointer constant, only a null pointer; build_int_cst (type, 0) would 
> produce a null pointer constant when type is void *.  (void *)nullptr 
> should be handled similarly to (void *)(void *)0, which isn't a null 
> pointer constant either.

That (void *)nullptr is not considered an NPC ought to be achieved by
build_c_cast wrapping the result of c_convert in a NOP_EXPR:

  /* Don't allow the results of casting to floating-point or complex
 types be confused with actual constants, or casts involving
 integer and pointer types other than direct integer-to-integer
 and integer-to-pointer be confused with integer constant
 expressions and null pointer constants.  */

Then null_pointer_constant_p sees the NOP_EXPR and returns false.  I've
added a comment explaining that.

> > @@ -133,6 +133,13 @@ null_pointer_constant_p (const_tree expr)
> >/* This should really operate on c_expr structures, but they aren't
> >   yet available everywhere required.  */
> >tree type = TREE_TYPE (expr);
> > +
> > +  /* An integer constant expression with the value 0, such an expression
> > + cast to type void*, or the predefined constant nullptr, are a null
> > + pointer constant.  */
> > +  if (NULLPTR_TYPE_P (type))
> > +return true;
> 
> That looks wrong.  You need to distinguish null pointer constants of type 
> nullptr_t (nullptr, possibly enclosed in parentheses, possibly the 
> selected alternative from _Generic) from all other expressions of type 
> nullptr_t (including (nullptr_t)nullptr, which isn't a null pointer 
> constant any more than (void *)(void *)0).

Ah, okay.  I had just copied what we do in C++ in null_ptr_cst_p and the
rest of the patch worked under that assumption.  I've added some tests
for this too.  Except I don't really understand the _Generic comment so
I only have tests for _Generic that were in the previous version.

Changing null_pointer_constant_p mean that I had to adjust
build_binary_op/EQ_EXPR.
 
> Then, for each context where it matters whether a nullptr_t value is a 
> null pointer constant, there need to be testcases that the two cases are 
> properly distinguished.  This includes at least equality comparisons with 
> a pointer that is not a null pointer constant (seem only to be allowed 
> with nullptr, not with other nullptr_t expression

[PATCH 0/3] picolibc: Add picolibc linking help

2022-08-24 Thread Keith Packard via Gcc-patches
Picolibc is a C library for embedded systems based on code from newlib
and avr libc. To connect some system-dependent picolibc functions
(like stdio) to an underlying platform, the platform may provide an OS
library.

This OS library must follow the C library in the link command line. In
current picolibc, that is done by providing an alternate .specs file
which can rewrite the *lib spec to insert the OS library in the right
spot.

This patch series adds the ability to specify the OS library on the
gcc command line when GCC is configured to us picolibc as the default
C library, and then hooks that up for arm, nds32, riscv and sh targets.

Keith Packard (3):
  Allow default libc to be specified to configure
  Add newlib and picolibc as default C library choices
  Add '--oslib=' option when default C library is picolibc

 gcc/config.gcc| 56 ---
 gcc/config/arm/elf.h  |  5 
 gcc/config/nds32/elf.h|  4 +++
 gcc/config/picolibc.opt   | 26 ++
 gcc/config/riscv/elf.h|  4 +++
 gcc/config/sh/embed-elf.h |  5 
 gcc/configure.ac  |  4 +++
 7 files changed, 95 insertions(+), 9 deletions(-)
 create mode 100644 gcc/config/picolibc.opt

-- 
2.36.1



[PATCH 3/3] picolibc: Add '--oslib=' option when default C library is picolibc

2022-08-24 Thread Keith Packard via Gcc-patches
This option allows targets to insert an OS library after the C library
in the LIB_PATH spec file fragment. This library maps a few POSIX APIs
used by picolibc to underlying system capabilities.

For example, picolibc provides 'libsemihost' on various targets which
maps these APIs to semihosting capabilities. This would be used with
this option by specifying --oslib=semihost

This patch enables --oslib= on arm, nds32, riscv and sh.

Signed-off-by: Keith Packard 
---
 gcc/config.gcc|  6 ++
 gcc/config/arm/elf.h  |  5 +
 gcc/config/nds32/elf.h|  4 
 gcc/config/picolibc.opt   | 26 ++
 gcc/config/riscv/elf.h|  4 
 gcc/config/sh/embed-elf.h |  5 +
 6 files changed, 50 insertions(+)
 create mode 100644 gcc/config/picolibc.opt

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 0aa4bd6c3dd..80740d8f04e 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -5893,3 +5893,9 @@ case "$default_libc" in
tm_defines="$tm_defines DEFAULT_LIBC=$default_libc"
;;
 esac
+
+case "$default_libc" in
+LIBC_PICOLIBC)
+   extra_options="${extra_options} picolibc.opt"
+   ;;
+esac
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 3d111433ede..d83ee4a1a8c 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -150,3 +150,8 @@
 #undef L_floatundisf
 #endif
 
+#if defined(DEFAULT_LIBC) && defined(LIBC_PICOLIBC) && DEFAULT_LIBC == 
LIBC_PICOLIBC
+#undef  LIB_SPEC
+#define LIB_SPEC "--start-group %(libgcc)  -lc %{-oslib=*:-l%*} --end-group"
+#endif
+
diff --git a/gcc/config/nds32/elf.h b/gcc/config/nds32/elf.h
index ebdc18cee2a..a956d531ef4 100644
--- a/gcc/config/nds32/elf.h
+++ b/gcc/config/nds32/elf.h
@@ -34,8 +34,12 @@
   " %{shared:-shared}" \
   NDS32_RELAX_SPEC
 
+#if defined(DEFAULT_LIBC) && defined(LIBC_PICOLIBC) && DEFAULT_LIBC == 
LIBC_PICOLIBC
+#define LIB_SPEC "--start-group %(libgcc)  -lc %{-oslib=*:-l%*} --end-group"
+#else
 #define LIB_SPEC \
   " -lc -lgloss"
+#endif
 
 #define LIBGCC_SPEC \
   " -lgcc"
diff --git a/gcc/config/picolibc.opt b/gcc/config/picolibc.opt
new file mode 100644
index 000..194b3362b03
--- /dev/null
+++ b/gcc/config/picolibc.opt
@@ -0,0 +1,26 @@
+; Processor-independent options for picolibc.
+;
+; Copyright (C) 2022 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; .
+
+-oslib
+Driver Separate Alias(-oslib=)
+
+-oslib=
+Driver Joined
+Specify an OS support library to load after libc.
diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index f0e865d6ef4..ca906afcd52 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -27,7 +27,11 @@ along with GCC; see the file COPYING3.  If not see
 /* Link against Newlib libraries, because the ELF backend assumes Newlib.
Handle the circular dependence between libc and libgloss. */
 #undef  LIB_SPEC
+#if defined(DEFAULT_LIBC) && defined(LIBC_PICOLIBC) && DEFAULT_LIBC == 
LIBC_PICOLIBC
+#define LIB_SPEC "--start-group %(libgcc)  -lc %{-oslib=*:-l%*} --end-group"
+#else
 #define LIB_SPEC "--start-group -lc %{!specs=nosys.specs:-lgloss} --end-group"
+#endif
 
 #undef  STARTFILE_SPEC
 #define STARTFILE_SPEC "crt0%O%s crtbegin%O%s"
diff --git a/gcc/config/sh/embed-elf.h b/gcc/config/sh/embed-elf.h
index 21e51dd0bb9..e8605849e07 100644
--- a/gcc/config/sh/embed-elf.h
+++ b/gcc/config/sh/embed-elf.h
@@ -34,3 +34,8 @@ along with GCC; see the file COPYING3.  If not see
   %{Os: -lgcc-Os-4-200} \
   -lgcc \
   %{!Os: -lgcc-Os-4-200}"
+
+#if defined(DEFAULT_LIBC) && defined(LIBC_PICOLIBC) && DEFAULT_LIBC == 
LIBC_PICOLIBC
+#undef  LIB_SPEC
+#define LIB_SPEC "--start-group %(libgcc)  -lc %{-oslib=*:-l%*} --end-group"
+#endif
-- 
2.36.1



[PATCH 1/3] picolibc: Allow default libc to be specified to configure

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

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

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 02f58970db0..f8b6da4f4e7 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -641,6 +641,8 @@ esac
 # Common C libraries.
 tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3 LIBC_MUSL=4"
 
+default_libc=""
+
 # 32-bit x86 processors supported by --with-arch=.  Each processor
 # MUST be separated by exactly one space.
 x86_archs="athlon athlon-4 athlon-fx athlon-mp athlon-tbird \
@@ -847,16 +849,16 @@ case ${target} in
   esac
   case $target in
 *-*-*android*)
-  tm_defines="$tm_defines DEFAULT_LIBC=LIBC_BIONIC"
+  default_libc=LIBC_BIONIC
   ;;
 *-*-*uclibc* | *-*-uclinuxfdpiceabi)
-  tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC"
+  default_libc=LIBC_UCLIBC
   ;;
 *-*-*musl*)
-  tm_defines="$tm_defines DEFAULT_LIBC=LIBC_MUSL"
+  default_libc=LIBC_MUSL
   ;;
 *)
-  tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
+  default_libc=LIBC_GLIBC
   ;;
   esac
   # Assume that glibc or uClibc or Bionic are being used and so __cxa_atexit
@@ -949,7 +951,8 @@ case ${target} in
   case ${enable_threads} in
 "" | yes | posix) thread_file='posix' ;;
   esac
-  tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC SINGLE_LIBC"
+  tm_defines="$tm_defines SINGLE_LIBC"
+  default_libc=LIBC_UCLIBC
   ;;
 *-*-rdos*)
   use_gcc_stdint=wrap
@@ -1606,13 +1609,13 @@ csky-*-*)
 
case ${target} in
csky-*-linux-gnu*)
-   tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
+   default_libc=LIBC_GLIBC
# Force .init_array support.  The configure script 
cannot always
# automatically detect that GAS supports it, yet we 
require it.
gcc_cv_initfini_array=yes
;;
csky-*-linux-uclibc*)
-   tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC"
+   default_libc=LIBC_UCLIBC
default_use_cxa_atexit=no
;;
*)
@@ -3065,7 +3068,7 @@ powerpc*-wrs-vxworks7r*)
tmake_file="${tmake_file} t-linux rs6000/t-linux64 rs6000/t-fprules 
rs6000/t-ppccomm"
tmake_file="${tmake_file} rs6000/t-vxworks"
 
-   tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
+   default_libc=LIBC_GLIBC
extra_objs="$extra_objs linux.o rs6000-linux.o"
;;
 powerpc-wrs-vxworks*)
@@ -5861,3 +5864,26 @@ i[34567]86-*-* | x86_64-*-*)
fi
;;
 esac
+
+case "${with_default_libc}" in
+glibc)
+default_libc=LIBC_GLIBC
+;;
+uclibc)
+default_libc=LIBC_UCLIBC
+;;
+bionic)
+default_libc=LIBC_BIONIC
+;;
+musl)
+default_libc=LIBC_MUSL
+;;
+esac
+
+case "$default_libc" in
+"")
+;;
+*)
+   tm_defines="$tm_defines DEFAULT_LIBC=$default_libc"
+   ;;
+esac
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 819b490d1b6..0b76613b635 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2490,6 +2490,10 @@ if { { test x$host != x$target && test "x$with_sysroot" 
= x ; } ||
 fi
 AC_SUBST(inhibit_libc)
 
+AC_ARG_WITH(default-libc,
+   [AS_HELP_STRING([--with-default-libc],
+   [Use specified default C library])])
+
 # When building gcc with a cross-compiler, we need to adjust things so
 # that the generator programs are still built with the native compiler.
 # Also, we cannot run fixincludes.
-- 
2.36.1



[PATCH 2/3] picolibc: Add newlib and picolibc as default C library choices

2022-08-24 Thread Keith Packard via Gcc-patches
Signed-off-by: Keith Packard 
---
 gcc/config.gcc | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index f8b6da4f4e7..0aa4bd6c3dd 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -639,7 +639,7 @@ case ${target} in
 esac
 
 # Common C libraries.
-tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3 LIBC_MUSL=4"
+tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3 LIBC_MUSL=4 
LIBC_NEWLIB=5 LIBC_PICOLIBC=6"
 
 default_libc=""
 
@@ -5878,6 +5878,12 @@ bionic)
 musl)
 default_libc=LIBC_MUSL
 ;;
+newlib)
+default_libc=LIBC_NEWLIB
+;;
+picolibc)
+default_libc=LIBC_PICOLIBC
+;;
 esac
 
 case "$default_libc" in
-- 
2.36.1



Re: [PATCH] Fortran: improve error recovery while simplifying size of bad array [PR103694]

2022-08-24 Thread Tobias Burnus

Dear Harald,

On 23.08.22 22:29, Harald Anlauf via Fortran wrote:

the simplification of the size of an array with a bad decl
should not be successful.  Improve the error recovery for
such a situation.

[...]

Regtested on x86_64-pc-linux-gnu.
The PR is marked as a 12/13 regression.  Will therefore
commit to both.


LGTM – and thanks for taking care of the Fortran bugs!

Tobias

[PATCH] Fortran: improve error recovery while simplifying size of bad array 
[PR103694]

gcc/fortran/ChangeLog:

   PR fortran/103694
   * simplify.cc (simplify_size): The size expression of an array cannot
   be simplified if an error occurs while resolving the array spec.

gcc/testsuite/ChangeLog:

   PR fortran/103694
   * gfortran.dg/pr103694.f90: New test.
---
gcc/fortran/simplify.cc|  5 +++--
gcc/testsuite/gfortran.dg/pr103694.f90 | 11 +++
2 files changed, 14 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/pr103694.f90

diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index f992c31e5d7..bc178d54891 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -7536,8 +7536,9 @@ simplify_size (gfc_expr *array, gfc_expr *dim, int k)
}

  for (ref = array->ref; ref; ref = ref->next)
-if (ref->type == REF_ARRAY && ref->u.ar.as)
-  gfc_resolve_array_spec (ref->u.ar.as, 0);
+if (ref->type == REF_ARRAY && ref->u.ar.as
+   && !gfc_resolve_array_spec (ref->u.ar.as, 0))
+  return NULL;

  if (dim == NULL)
{
diff --git a/gcc/testsuite/gfortran.dg/pr103694.f90 
b/gcc/testsuite/gfortran.dg/pr103694.f90
new file mode 100644
index 000..3ed8b2088da
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr103694.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! PR fortran/103694 - ICE in gfc_conv_expr_op
+! Contributed by G.Steinmetz
+
+subroutine s
+  type t
+ integer :: a(2)
+  end type
+  type(t) :: x((0.)/0)
+  integer :: n = size(x(1)%a) ! { dg-error "does not reduce to a constant 
expression" }
+end


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


[Patch] Fortran/OpenMP: Fix strictly structured blocks parsing

2022-08-24 Thread Tobias Burnus

This patch is about error diagnostic + an ICE for invalid code.

Before the patch, gfortran/f951 showed:

...
Error: 'ancestor' device modifier not preceded by 'requires' directive with 
'reverse_offload' clause
  18 | end block
 |   1
Error: Expecting END PROGRAM statement at (1)
gfortran: internal compiler error: Segmentation fault signal terminated program 
f951

* The first error is for a user error and fine.
* A follow-up error is expected (due to the now dangling '!$omp end target'),
 but the error location and wording is misleading
* And the ICE is plainly wrong.


With the patch, there is no ICE and the the second error reads:

  16 |   !$omp end target
Error: Unexpected !$OMP END TARGET statement at (1)


The problem was due to nesting '!$omp target' (= same directive),
where the outer one was a strictly structured block - and parsing
the inner '!$omp target' failed with MATCH_ERROR, which ignored that
line - while '!$omp end target' remained.

(So far, so good, but then the parsing-code did run into a bug.)

For the blocks, the following applies. OpenMP permits either
* strictly structured blocks (with optional END_ST == 'end target')
 !$omp target
   block
 ...
   end block
 !$omp end target  ! << this line is optional
* loosely structured block
 !$omp target
... ! may not start with 'block' (and hence cannot end with 'end block')
 !$omp end target  ! << required


The parsing issue is in the following code,
which first takes care of the 'strictly':  'end block' + optional 'end target'
and then of the 'loosely structured' case with just:  'end target':

 else if (block_construct && st == ST_END_BLOCK)
   ...
 st = next_statement ();
 if (st == omp_end_st)
 accept_statement (st);
   ...
 else if (st != omp_end_st)
   {
 unexpected_statement (st);
 st = next_statement ();
   }

The fix is to change the second if condition to:
 else if (st != omp_end_st || (block_construct && st == omp_end_st))

or rather to the following equivalent code:
 else if (st != omp_end_st || block_construct)


OK for mainline and GCC 12?*

Tobias

*strictly structured blocks were added in r12-4592.


-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
Fortran/OpenMP: Fix strictly structured blocks parsing

gcc/fortran/ChangeLog:

	* parse.cc (parse_omp_structured_block): When parsin strictly
	structured blocks, issue an error if the end-directive comes
	before the 'end block'.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/strictly-structured-block-4.f90: New test.

 gcc/fortran/parse.cc|  2 +-
 .../gomp/strictly-structured-block-4.f90| 21 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index 0b4c596996c..80492c952aa 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -5709,7 +5709,7 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
 	}
 	  return st;
 	}
-  else if (st != omp_end_st)
+  else if (st != omp_end_st || block_construct)
 	{
 	  unexpected_statement (st);
 	  st = next_statement ();
diff --git a/gcc/testsuite/gfortran.dg/gomp/strictly-structured-block-4.f90 b/gcc/testsuite/gfortran.dg/gomp/strictly-structured-block-4.f90
new file mode 100644
index 000..66cf0a3925e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/strictly-structured-block-4.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+implicit none
+integer ::x,z
+x = 42
+print '(*(z16:" "))', loc(x)
+!$omp target map(x, z)
+block
+  integer :: y
+  x = 123
+  y = 99
+  !$omp target device(ancestor:1) map(always,tofrom:x) map(y) ! { dg-error "'ancestor' device modifier not preceded by 'requires' directive with 'reverse_offload' clause" }
+print '(*(z16:" "))', loc(x), loc(y)
+print * ,x, y
+x = -x
+y = -y
+  !$omp end target ! { dg-error "Unexpected ..OMP END TARGET statement" }
+  z = y
+end block
+print * ,x !, z
+end
+


Re: [PATCH] libstdc++: Fix fallout from P2321R2 pair/tuple enhancements

2022-08-24 Thread Patrick Palka via Gcc-patches
On Wed, 24 Aug 2022, Patrick Palka wrote:

> r13-2159-g72886fcc626953 introduced some testsuite regressions in C++23
> mode:
> 
>   FAIL: 20_util/pair/requirements/explicit_instantiation/1.cc (test for 
> excess errors)
>   FAIL: 20_util/tuple/53648.cc (test for excess errors)
>   FAIL: 20_util/tuple/cons/noexcept_specs.cc (test for excess errors)
>   FAIL: 20_util/tuple/requirements/explicit_instantiation.cc (test for excess 
> errors)
> 
> The test noexcept_specs.cc just needs to be updated to consider the
> additional converting constructors of tuple in C++23 mode, which happen
> to improve constructing from a const tuple rvalue containing rvalue
> reference elements (for the better, as far as I can tell).
> 
> The other three tests fail because they explicitly instantiate a 
> specialization
> of tuple whose elements are not all const swappable, which in C++23 mode now
> results in a hard error due to tuple's new const swap member function.  Rather
> than XFAILing the tests in C++23 mode, this patch adds non-standard 
> constraints
> to this member function so that we continue to accept such explicit 
> instantiations.
> 
> Tested on x86_64-pc-linux-gnu with and without 
> --target_board=unix/-std=gnu++23,
> does this look OK for trunk?
> 
> libstdc++-v3/ChangeLog:
> 
>   * include/std/tuple (tuple::swap const): Add is_swappable_v constraints.

D'oh, pair's const swap needs the same workaround:

-- >8 --

libstdc++-v3/ChangeLog:

* include/bits/stl_pair.h (pair::swap const): Add non-standard
is_swappable_v constraints.
* include/std/tuple (tuple::swap const): Likewise.
* testsuite/20_util/tuple/cons/noexcept_specs.cc: Update some
asserts in C++23 mode.
---
 libstdc++-v3/include/bits/stl_pair.h  |  8 
 libstdc++-v3/include/std/tuple|  9 
 .../20_util/tuple/cons/noexcept_specs.cc  | 41 +++
 3 files changed, 58 insertions(+)

diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index bffca0daf65..a65a4763c54 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -213,10 +213,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 #if __cplusplus > 202002L
+  // As an extension, we constrain the const swap member function
+  // in order to continue accepting explicit instantiation of tuple
+  // specializations whose elements are not all const swappable.
+  // Without this constraint, such an explicit instantiation would
+  // also instantiate the ill-formed body of this function and yield
+  // a hard error.  This constraint shouldn't affect the behavior of
+  // valid programs.
   constexpr void
   swap(const pair& __p) const
   noexcept(__and_v<__is_nothrow_swappable,
   __is_nothrow_swappable>)
+  requires is_swappable_v && is_swappable_v
   {
using std::swap;
swap(first, __p.first);
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 05433d5ae36..9d1abc2f80e 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1176,9 +1176,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { _Inherited::_M_swap(__in); }
 
 #if __cplusplus > 202002L
+  // As an extension, we constrain this const swap member function
+  // in order to continue accepting explicit instantiation of tuple
+  // specializations whose elements are not all const swappable.
+  // Without this constraint, such an explicit instantiation would
+  // also instantiate the ill-formed body of this function and
+  // yield a hard error.  This constraint shouldn't affect the behavior of
+  // valid programs.
   constexpr void
   swap(const tuple& __in) const
   noexcept(__and_v<__is_nothrow_swappable...>)
+  requires (is_swappable_v && ...)
   { _Inherited::_M_swap(__in); }
 #endif // C++23
 };
@@ -1730,6 +1738,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   swap(const tuple& __in) const
   noexcept(__and_v<__is_nothrow_swappable,
   __is_nothrow_swappable>)
+  requires is_swappable_v && is_swappable_v
   { _Inherited::_M_swap(__in); }
 #endif // C++23
 };
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc 
b/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
index 6044a377348..a326d1bc228 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
@@ -503,7 +503,17 @@ namespace 
NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
   static_assert(!std::is_nothrow_constructible::value, "");
   static_assert(!std::is_nothrow_constructible::value, "");
   static_assert(!std::is_nothrow_constructible>::value, 
"");
+#if __cplusplus > 202002L
+  // C++23 extended tuple's constructor overload set as part of P2321R2, after
+  // which its converting cons

[PATCH] libstdc++: Fix fallout from P2321R2 pair/tuple enhancements

2022-08-24 Thread Patrick Palka via Gcc-patches
r13-2159-g72886fcc626953 introduced some testsuite regressions in C++23
mode:

  FAIL: 20_util/pair/requirements/explicit_instantiation/1.cc (test for excess 
errors)
  FAIL: 20_util/tuple/53648.cc (test for excess errors)
  FAIL: 20_util/tuple/cons/noexcept_specs.cc (test for excess errors)
  FAIL: 20_util/tuple/requirements/explicit_instantiation.cc (test for excess 
errors)

The test noexcept_specs.cc just needs to be updated to consider the
additional converting constructors of tuple in C++23 mode, which happen
to improve constructing from a const tuple rvalue containing rvalue
reference elements (for the better, as far as I can tell).

The other three tests fail because they explicitly instantiate a specialization
of tuple whose elements are not all const swappable, which in C++23 mode now
results in a hard error due to tuple's new const swap member function.  Rather
than XFAILing the tests in C++23 mode, this patch adds non-standard constraints
to this member function so that we continue to accept such explicit 
instantiations.

Tested on x86_64-pc-linux-gnu with and without --target_board=unix/-std=gnu++23,
does this look OK for trunk?

libstdc++-v3/ChangeLog:

* include/std/tuple (tuple::swap const): Add is_swappable_v constraints.
* testsuite/20_util/tuple/cons/noexcept_specs.cc: Adjust some asserts 
for
C++23 mode.
---
 libstdc++-v3/include/std/tuple|  9 
 .../20_util/tuple/cons/noexcept_specs.cc  | 41 +++
 2 files changed, 50 insertions(+)

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 05433d5ae36..9d1abc2f80e 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1176,9 +1176,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { _Inherited::_M_swap(__in); }
 
 #if __cplusplus > 202002L
+  // As an extension, we constrain this const swap member function
+  // in order to continue accepting explicit instantiation of tuple
+  // specializations whose elements are not all const swappable.
+  // Without this constraint, such an explicit instantiation would
+  // also instantiate the ill-formed body of this function and
+  // yield a hard error.  This constraint shouldn't affect the behavior of
+  // valid programs.
   constexpr void
   swap(const tuple& __in) const
   noexcept(__and_v<__is_nothrow_swappable...>)
+  requires (is_swappable_v && ...)
   { _Inherited::_M_swap(__in); }
 #endif // C++23
 };
@@ -1730,6 +1738,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   swap(const tuple& __in) const
   noexcept(__and_v<__is_nothrow_swappable,
   __is_nothrow_swappable>)
+  requires is_swappable_v && is_swappable_v
   { _Inherited::_M_swap(__in); }
 #endif // C++23
 };
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc 
b/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
index 6044a377348..a326d1bc228 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
@@ -503,7 +503,17 @@ namespace 
NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
   static_assert(!std::is_nothrow_constructible::value, "");
   static_assert(!std::is_nothrow_constructible::value, "");
   static_assert(!std::is_nothrow_constructible>::value, 
"");
+#if __cplusplus > 202002L
+  // C++23 extended tuple's constructor overload set as part of P2321R2, after
+  // which its converting constructors more accurately forward the elements
+  // from a non-const tuple lvalue and from a const tuple rvalue.  In 
particular
+  // for the below test we now forward int&& as an rvalue reference instead of
+  // as an lvalue reference, which means we now select the noexcept B(int&&)
+  // ctor instead of the non-noexcept B(const int&) ctor.
+  static_assert(std::is_nothrow_constructible>::value, "");
+#else
   static_assert(!std::is_nothrow_constructible>::value, "");
+#endif
 
   static_assert(test_trait::is_nothrow_convertible::value,"");
   static_assert(!test_trait::is_nothrow_convertible::value,"");
@@ -515,7 +525,13 @@ namespace 
NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
   static_assert(!test_trait::is_nothrow_convertible::value,"");
   static_assert(!test_trait::is_nothrow_convertible::value,"");
   
static_assert(!test_trait::is_nothrow_convertible,BT>::value,"");
+#if __cplusplus > 202002L
+  // See the note about P2321R2 above.
+  static_assert(test_trait::is_nothrow_convertible,BT>::value,"");
+#else
   static_assert(!test_trait::is_nothrow_convertible,BT>::value,"");
+#endif
+
 
 
   static_assert(!std::is_nothrow_constructible::value, "");
@@ -528,7 +544,12 @@ namespace 
NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
   static_assert(std::is_nothrow_constructible::value, "");
   static_assert(std::is_nothrow_constructible::value, "");
   static_assert(std::is_nothrow_constructi

[PATCH][RFC] Uninit diagnostic consistency

2022-08-24 Thread Richard Biener via Gcc-patches
I've figured that while the uninit diagnostic is intended to diagnose
all cases where we cannot prove the must-uninit paths are not reaching
any use the actual implementation errors on the wrong side in two
places.  First the recently added use_cannot_happen computes the
must-uninit predicate using compute_control_dep_chain which errors
on the side making the covered domain too small (pruning OR components),
second, init_use_preds which computes the predicate that holds when
the use is executed also uses the same function.  In both cases the
computational limits implemented in compute_control_dep_chain will cause
false negatives.  The following corrects this by using the recently
introduced simple_control_dep_chain instead which errors on the side
of making the domain larger (pruning AND components).

I shall note that I didn't yet find a testcase that requires
use_cannot_happen which does the same as the init_from_phi_def
and superset_of combination.  The only difference is that
init_from_phi_def computes conjunction of the edge predicates
covering the not must-uninitialized control flow, also handling
the case of PHI cascading and verifying the use predicate is
a subset of this while use_cannot_happen computes whether
each predicate on the uninitialized edges (may-uninit for the
case of PHI cascading) has an empty intersection with the
use predicate.  Due to the PHI cascading handling the original
should be superior but since both implementations apply the
computational limit of compute_control_dep_chain in different
ways and have different false negative issues it may have catched
some extra bits at times.  A patch to remove use_cannot_happen
passes bootstrap and regtest with all languages on x86_64, my
preference would be to axe it instead of fixing it.

Note I am yet not sure why compute_control_dep_chain goes the
length of computing all (well, only some) paths from the
root to the PHI edge source rather than walking dominators
as simple_control_dep_chain or using control dependences (and
pruning them appropriately).

The patch as-is causes

FAIL: g++.dg/warn/uninit-pr55288.C (test for bogus messages, line 16)

the testcase was fixed by r0-125162-g5c2961cf38a69f, the issue here
is that simple_control_dep_chain does not handle A || A with the
same predicate on different paths.

XPASS: gcc.dg/uninit-pred-7_a.c bogus warning (test for bogus messages, line 26)
FAIL: gcc.dg/uninit-pred-9_b.c pr101674 (test for bogus messages, line 23)

where the FAIL is PR101674.  I've commented extensively in the PR.

Bootstrapped on x86_64-unknown-linux-gnu, full testing is still in
progress.

* gimple-predicate-analysis.cc (dump_dep_chains): Don't
use auto_vec[] arguments.
(uninit_analysis::use_cannot_happen): Only use
simple_control_dep_chain.
(uninit_analysis::init_use_preds): Likewise.
(uninit_analysis::init_from_phi_def): Add comment why
using compute_control_dep_chain here is OK.
---
 gcc/gimple-predicate-analysis.cc | 72 
 1 file changed, 27 insertions(+), 45 deletions(-)

diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index 079e06009fd..44f00507d83 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -238,14 +238,14 @@ dump_predicates (gimple *stmt, const pred_chain_union 
&preds, const char *msg)
 /* Dump the first NCHAINS elements of the DEP_CHAINS array into DUMP_FILE.  */
 
 static void
-dump_dep_chains (const auto_vec dep_chains[], unsigned nchains)
+dump_dep_chains (const vec dep_chains[], unsigned nchains)
 {
   if (!dump_file)
 return;
 
   for (unsigned i = 0; i != nchains; ++i)
 {
-  const auto_vec &v = dep_chains[i];
+  const vec &v = dep_chains[i];
   unsigned n = v.length ();
   for (unsigned j = 0; j != n; ++j)
{
@@ -1309,41 +1309,27 @@ uninit_analysis::use_cannot_happen (gphi *phi, unsigned 
opnds, const predicate &
continue;
 
   edge e = gimple_phi_arg_edge (phi, i);
-  auto_vec dep_chains[MAX_NUM_CHAINS];
-  auto_vec cur_chain;
-  unsigned num_chains = 0;
-  unsigned num_calls = 0;
 
-  /* Build the control dependency chain for the PHI argument...  */
-  if (!compute_control_dep_chain (cd_root,
- e->src, dep_chains, &num_chains,
- cur_chain, &num_calls))
-   {
- gcc_assert (num_chains == 0);
- /* If compute_control_dep_chain bailed out due to limits
-build a partial sparse path using dominators.  Collect
-only edges whose predicates are always true when reaching E.  */
- simple_control_dep_chain (dep_chains[0], cd_root, e);
- num_chains++;
-   }
-  /* Update the chains with the phi operand edge.  */
-  else if (EDGE_COUNT (e->src->succs) > 1)
-   {
- for (unsigned j = 0; j < num_chains; j++)
-   dep_chains[j].safe

[committed] libstdc++: Fix regression in std::stable_sort

2022-08-24 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

No backport needed as the regression is only on trunk.

-- >8 --

The recent change to split out the cold path of std::stable_sort caused
a regression for some Qt code. The problem is that the library now adds
a value of type ptrdiff_t to the iterator, which is ambiguous with
-pedantic. The addition could either convert the iterator to a built-in
pointer and add the ptrdiff_t to that, or it could convert the ptrdiff_t
to the iterator's difference_type and use the iterator's own operator+.

The fix is to cast the ptrdiff_t value to the difference type first.

libstdc++-v3/ChangeLog:

* include/bits/stl_algo.h (__stable_sort): Cast size to
iterator's difference type.
* testsuite/25_algorithms/stable_sort/4.cc: New test.
---
 libstdc++-v3/include/bits/stl_algo.h  |  5 +-
 .../testsuite/25_algorithms/stable_sort/4.cc  | 51 +++
 2 files changed, 54 insertions(+), 2 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/stable_sort/4.cc

diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index c6078054514..57fa1c1dc55 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -5026,8 +5026,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   _TmpBuf __buf(__first, (__last - __first + 1) / 2);
 
   if (__builtin_expect(__buf.requested_size() == __buf.size(), true))
-   std::__stable_sort_adaptive(__first, __first + __buf.size(), __last,
-   __buf.begin(), __comp);
+   std::__stable_sort_adaptive(__first,
+   __first + _DistanceType(__buf.size()),
+   __last, __buf.begin(), __comp);
   else if (__builtin_expect(__buf.begin() == 0, false))
std::__inplace_stable_sort(__first, __last, __comp);
   else
diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_sort/4.cc 
b/libstdc++-v3/testsuite/25_algorithms/stable_sort/4.cc
new file mode 100644
index 000..b7bda4eeaca
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/stable_sort/4.cc
@@ -0,0 +1,51 @@
+// { dg-options "-pedantic" }
+// { dg-do compile }
+
+#include 
+
+/* This type is reduced from QTypedArrayData::iterator which has an implicit
+ * conversion to its pointer type and a difference type of int.
+ * The expression Iter() + ptrdiff_t(0) is ambiguous with -pedantic because it
+ * could either convert the RHS to int and use Iter::operator+(int)
+ * or it could convert the LHS to pointer and use built-in pointer arithmetic.
+ */
+struct Iter
+{
+  struct value_type { bool operator<(value_type) const; };
+  typedef value_type* pointer;
+  typedef value_type& reference;
+  typedef std::random_access_iterator_tag iterator_category;
+  typedef int difference_type;
+
+  reference operator*() const;
+  pointer operator->() const;
+
+  reference operator[](difference_type) const;
+
+  Iter& operator++();
+  Iter& operator--();
+  Iter operator++(int);
+  Iter operator--(int);
+
+  Iter& operator+=(difference_type);
+  Iter& operator-=(difference_type);
+
+  Iter operator+(difference_type) const;
+  Iter operator-(difference_type) const;
+
+  difference_type operator-(Iter) const;
+
+  operator pointer() const; // XXX this causes the ambiguity
+
+  bool operator==(Iter) const;
+  bool operator!=(Iter) const;
+
+  bool operator<(Iter) const;
+};
+
+Iter operator+(Iter::difference_type, Iter);
+
+int main()
+{
+  std::stable_sort(Iter(), Iter());
+}
-- 
2.37.2



Re: [PATCH Rust front-end v2 01/37] Use DW_ATE_UTF for the Rust 'char' type

2022-08-24 Thread Jason Merrill via Gcc-patches

On 8/24/22 04:59, herron.phi...@googlemail.com wrote:

From: Tom Tromey 

The Rust 'char' type should use the DWARF DW_ATE_UTF encoding.


The DWARF changes are OK.


---
  gcc/dwarf2out.cc | 23 ++-
  1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index e3920c898f5..a8bccbabca4 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -5600,6 +5600,16 @@ is_fortran (const_tree decl)
return is_fortran ();
  }
  
+/* Return TRUE if the language is Rust.  */

+
+static inline bool
+is_rust ()
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
+
+  return lang == DW_LANG_Rust || lang == DW_LANG_Rust_old;
+}
+
  /* Return TRUE if the language is Ada.  */
  
  static inline bool

@@ -13231,7 +13241,11 @@ base_type_die (tree type, bool reverse)
}
if (TYPE_STRING_FLAG (type))
{
- if (TYPE_UNSIGNED (type))
+ if ((dwarf_version >= 4 || !dwarf_strict)
+ && is_rust ()
+ && int_size_in_bytes (type) == 4)
+   encoding = DW_ATE_UTF;
+ else if (TYPE_UNSIGNED (type))
encoding = DW_ATE_unsigned_char;
  else
encoding = DW_ATE_signed_char;
@@ -25201,6 +25215,13 @@ gen_compile_unit_die (const char *filename)
  }
else if (strcmp (language_string, "GNU F77") == 0)
  language = DW_LANG_Fortran77;
+  else if (strcmp (language_string, "GNU Rust") == 0)
+{
+  if (dwarf_version >= 5 || !dwarf_strict)
+   language = DW_LANG_Rust;
+  else
+   language = DW_LANG_Rust_old;
+}
else if (dwarf_version >= 3 || !dwarf_strict)
  {
if (strcmp (language_string, "GNU Ada") == 0)




Re: [PATCH] libstdc++: Optimize operator+(string/char*, string/char*) equally

2022-08-24 Thread Jonathan Wakely via Gcc-patches
On Wed, 24 Aug 2022 at 07:17, Will Hawkins wrote:
>
> Until now operator+(char*, string) and operator+(string, char*) had
> different performance characteristics. The former required a single
> memory allocation and the latter required two. This patch makes the
> performance equal.
>
> libstdc++-v3/ChangeLog:

There should be a blank line here.

> * libstdc++-v3/include/bits/basic_string.h (operator+(string, char*)):

The path should be relative to the ChangeLog, so should not include
the libstdc++-v3/ directory component. You can use the git gcc-verify
alias to check your commit msgs format before submitting. That runs
the same checks as will be used for the server-side hook that decides
whether to allow a push. See the customization script described at
https://gcc.gnu.org/gitwrite.html#vendor for the alaises.

Also, the overload you're changing is operator+(const string&, const
char*). The distinction matters, because there is also
operator+(string&&, const char*) and what you wrote looks more like
that one.

So I've committed it with this changelog:


   libstdc++-v3/ChangeLog:

   * include/bits/basic_string.h (operator+(const string&,
const char*)):
   Remove naive implementation.
   * include/bits/basic_string.tcc (operator+(const string&,
const char*)):
   Add single-allocation implementation.

Thanks for the patch!



[PATCH v2 2/2 resend] LoongArch: add model attribute

2022-08-24 Thread Xi Ruoyao via Gcc-patches
On Wed, 2022-08-24 at 22:08 +0800, Xi Ruoyao wrote:
> v1 -> v2:
> 
>  * Avoid introduce of SYMBOL_PCREL32, use SYMBOL_PCREL for 32-bit PC
>    relative.
>  * Rebase onto a bug fix ([1/2] in the series) to avoid merge conflict.
>  * Fix missed ChangeLog entries.

Resend because my mail client has done some stupid thing to the patch :(

-- >8 --

A linker script and/or a section attribute may locate some object
specially, so we need to handle the code model for such objects
differently than the -mcmodel setting. This happens when the Linux
kernel loads a module with per-CPU variables.

Add an attribute to override the code model for a specific variable.

gcc/ChangeLog:

* config/loongarch/loongarch-protos.h (loongarch_symbol_type):
Add SYMBOL_PCREL64 and change the description for SYMBOL_PCREL.
* config/loongarch/loongarch.cc (loongarch_attribute_table):
New attribute table.
(TARGET_ATTRIBUTE_TABLE): Define the target hook.
(loongarch_handle_model_attribute): New static function.
(loongarch_classify_symbol): Take TARGET_CMODEL_EXTREME and the
model attribute of SYMBOL_REF_DECL into account returning
SYMBOL_PCREL or SYMBOL_PCREL64.
(loongarch_use_anchors_for_symbol_p): New static function.
(TARGET_USE_ANCHORS_FOR_SYMBOL_P): Define the target hook.
(loongarch_symbol_extreme_p): New static function.
(loongarch_symbolic_constant_p): Handle SYMBOL_PCREL64.
(loongarch_symbol_insns): Likewise.
(loongarch_split_symbol_type): Likewise.
(loongarch_split_symbol): Check SYMBOL_PCREL64 instead of
TARGET_CMODEL_EXTREME for PC-relative addressing.
(loongarch_print_operand_reloc): Likewise.
* doc/extend.texi (Variable Attributes): Document new
LoongArch specific attribute.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/attr-model-test.c: New test.
* gcc.target/loongarch/attr-model-1.c: New test.
* gcc.target/loongarch/attr-model-2.c: New test.
* gcc.target/loongarch/attr-model-diag.c: New test.
---
 gcc/config/loongarch/loongarch-protos.h   |   8 +-
 gcc/config/loongarch/loongarch.cc | 190 --
 gcc/doc/extend.texi   |  16 ++
 .../gcc.target/loongarch/attr-model-1.c   |   6 +
 .../gcc.target/loongarch/attr-model-2.c   |   6 +
 .../gcc.target/loongarch/attr-model-diag.c|   7 +
 .../gcc.target/loongarch/attr-model-test.c|  25 +++
 7 files changed, 237 insertions(+), 21 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-1.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-2.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-diag.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-test.c

diff --git a/gcc/config/loongarch/loongarch-protos.h 
b/gcc/config/loongarch/loongarch-protos.h
index cadaad7519c..77b2217247d 100644
--- a/gcc/config/loongarch/loongarch-protos.h
+++ b/gcc/config/loongarch/loongarch-protos.h
@@ -28,7 +28,12 @@ along with GCC; see the file COPYING3.  If not see
The symbol's value will be loaded directly from the GOT.
 
SYMBOL_PCREL
-   The symbol's value will be loaded directly from data section.
+   The symbol's value will be loaded directly from data section within
+   +/- 2GiB range.
+
+   SYMBOL_PCREL64
+   The symbol's value will be loaded directly from data section within
+   +/- 8EiB range.
 
SYMBOL_TLS
A thread-local symbol.
@@ -42,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 enum loongarch_symbol_type {
   SYMBOL_GOT_DISP,
   SYMBOL_PCREL,
+  SYMBOL_PCREL64,
   SYMBOL_TLS,
   SYMBOL_TLS_IE,
   SYMBOL_TLS_LE,
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 41d9cca6d31..d9061cdeee3 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -1633,8 +1633,11 @@ loongarch_rtx_constant_in_small_data_p (machine_mode 
mode)
 static enum loongarch_symbol_type
 loongarch_classify_symbol (const_rtx x)
 {
+  enum loongarch_symbol_type pcrel =
+TARGET_CMODEL_EXTREME ? SYMBOL_PCREL64 : SYMBOL_PCREL;
+
   if (!SYMBOL_REF_P (x))
-return SYMBOL_PCREL;
+return pcrel;
 
   if (SYMBOL_REF_TLS_MODEL (x))
 return SYMBOL_TLS;
@@ -1642,7 +1645,28 @@ loongarch_classify_symbol (const_rtx x)
   if (!loongarch_symbol_binds_local_p (x))
 return SYMBOL_GOT_DISP;
 
-  return SYMBOL_PCREL;
+  tree t = SYMBOL_REF_DECL (x);
+  if (!t)
+return pcrel;
+
+  t = lookup_attribute ("model", DECL_ATTRIBUTES (t));
+  if (!t)
+return pcrel;
+
+  t = TREE_VALUE (TREE_VALUE (t));
+
+  /* loongarch_handle_model_attribute should reject other values.  */
+  gcc_assert (TREE_CODE (t) == STRING_CST);
+
+  const char *model = TREE_STRING_POINTER (t);
+  if (strcmp (model, "normal") == 0)
+return SYMBOL_PCREL;
+  if (strcmp (model, "extreme") == 0)
+  

[PATCH] LoongArch: testsuite: refine __tls_get_addr tests with tls_native

2022-08-24 Thread Xi Ruoyao via Gcc-patches
If GCC is not built with a working linker for the target (developers
occansionally build such a "minimal" GCC for testing and debugging),
TLS will be emulated and __tls_get_addr won't be used.  Refine those
tests depending on __tls_get_addr with tls_native to avoid test
failures.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/func-call-medium-1.c: Refine test
depending on __tls_get_addr with { target tls_native }.
* gcc.target/loongarch/func-call-medium-2.c: Likewise.
* gcc.target/loongarch/func-call-medium-3.c: Likewise.
* gcc.target/loongarch/func-call-medium-4.c: Likewise.
* gcc.target/loongarch/func-call-medium-5.c: Likewise.
* gcc.target/loongarch/func-call-medium-6.c: Likewise.
* gcc.target/loongarch/func-call-medium-7.c: Likewise.
* gcc.target/loongarch/func-call-medium-8.c: Likewise.
* gcc.target/loongarch/tls-gd-noplt.c: Likewise.
---
 gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c | 2 +-
 gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c | 2 +-
 gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c | 2 +-
 gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c | 2 +-
 gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c | 2 +-
 gcc/testsuite/gcc.target/loongarch/func-call-medium-6.c | 2 +-
 gcc/testsuite/gcc.target/loongarch/func-call-medium-7.c | 2 +-
 gcc/testsuite/gcc.target/loongarch/func-call-medium-8.c | 3 ++-
 gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c   | 2 +-
 9 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c 
b/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c
index 276d73e5ee8..6339e832fe5 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c
@@ -3,7 +3,7 @@
 /* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */
 /* { dg-final { scan-assembler "test1:.*la\.global\t.*f\n\tjirl" } } */
 /* { dg-final { scan-assembler "test2:.*la\.local\t.*l\n\tjirl" } } */
-/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" } } 
*/
+/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" { 
target tls_native } } } */
 
 extern void g (void);
 void
diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c 
b/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c
index 237821c066b..a53e75e0bf9 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c
@@ -3,7 +3,7 @@
 /* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */
 /* { dg-final { scan-assembler "test1:.*la\.local\t.*f\n\tjirl" } } */
 /* { dg-final { scan-assembler "test2:.*la\.local\t.*l\n\tjirl" } } */
-/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" } } 
*/
+/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" { 
target tls_native } } } */
 
 extern void g (void);
 void
diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c 
b/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c
index 9a6e16103bc..0da7bf98e3c 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c
@@ -3,7 +3,7 @@
 /* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */
 /* { dg-final { scan-assembler "test1:.*la\.global\t.*f\n\tjirl" } } */
 /* { dg-final { scan-assembler "test2:.*la\.local\t.*l\n\tjirl" } } */
-/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" } } 
*/
+/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" { 
target tls_native } } } */
 
 extern void g (void);
 void
diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c 
b/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c
index 2577e345239..0219688ae80 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c
@@ -3,7 +3,7 @@
 /* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */
 /* { dg-final { scan-assembler "test1:.*la\.local\t.*f\n\tjirl" } } */
 /* { dg-final { scan-assembler "test2:.*la\.local\t.*l\n\tjirl" } } */
-/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" } } 
*/
+/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" { 
target tls_native } } } */
 
 extern void g (void);
 void
diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c 
b/gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c
index d70b6ea4663..8a47b5afcba 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c
@@ -3,7 +3,7 @@
 /* { dg-final { scan-assembler 
"test:.*pcalau12i.*%pc_hi20\\(g\\)\n\tjirl.*pc_lo12\\(g\\)" } } */
 /* { dg-final { scan-assembler 
"test1:.*pcalau12i.*%pc_hi

[PATCH v2 2/2] LoongArch: add model attribute

2022-08-24 Thread Xi Ruoyao via Gcc-patches
v1 -> v2:

 * Avoid introduce of SYMBOL_PCREL32, use SYMBOL_PCREL for 32-bit PC
   relative.
 * Rebase onto a bug fix ([1/2] in the series) to avoid merge conflict.
 * Fix missed ChangeLog entries.

-- >8 --

A linker script and/or a section attribute may locate some object
specially, so we need to handle the code model for such objects
differently than the -mcmodel setting. This happens when the Linux
kernel loads a module with per-CPU variables.

Add an attribute to override the code model for a specific variable.

gcc/ChangeLog:

 * config/loongarch/loongarch-protos.h (loongarch_symbol_type):
 Add SYMBOL_PCREL64 and change the description for SYMBOL_PCREL.
 * config/loongarch/loongarch.cc (loongarch_attribute_table):
 New attribute table.
 (TARGET_ATTRIBUTE_TABLE): Define the target hook.
 (loongarch_handle_model_attribute): New static function.
 (loongarch_classify_symbol): Take TARGET_CMODEL_EXTREME and the
 model attribute of SYMBOL_REF_DECL into account returning
 SYMBOL_PCREL or SYMBOL_PCREL64.
 (loongarch_use_anchors_for_symbol_p): New static function.
 (TARGET_USE_ANCHORS_FOR_SYMBOL_P): Define the target hook.
 (loongarch_symbol_extreme_p): New static function.
 (loongarch_symbolic_constant_p): Handle SYMBOL_PCREL64.
 (loongarch_symbol_insns): Likewise.
 (loongarch_split_symbol_type): Likewise.
 (loongarch_split_symbol): Check SYMBOL_PCREL64 instead of
 TARGET_CMODEL_EXTREME for PC-relative addressing.
 (loongarch_print_operand_reloc): Likewise.
 * doc/extend.texi (Variable Attributes): Document new
 LoongArch specific attribute.

gcc/testsuite/ChangeLog:

 * gcc.target/loongarch/attr-model-test.c: New test.
 * gcc.target/loongarch/attr-model-1.c: New test.
 * gcc.target/loongarch/attr-model-2.c: New test.
 * gcc.target/loongarch/attr-model-diag.c: New test.
---
 gcc/config/loongarch/loongarch-protos.h | 8 +-
 gcc/config/loongarch/loongarch.cc | 190 --
 gcc/doc/extend.texi | 16 ++
 .../gcc.target/loongarch/attr-model-1.c | 6 +
 .../gcc.target/loongarch/attr-model-2.c | 6 +
 .../gcc.target/loongarch/attr-model-diag.c | 7 +
 .../gcc.target/loongarch/attr-model-test.c | 25 +++
 7 files changed, 237 insertions(+), 21 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-1.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-2.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-diag.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-test.c

diff --git a/gcc/config/loongarch/loongarch-protos.h 
b/gcc/config/loongarch/loongarch-protos.h
index cadaad7519c..77b2217247d 100644
--- a/gcc/config/loongarch/loongarch-protos.h
+++ b/gcc/config/loongarch/loongarch-protos.h
@@ -28,7 +28,12 @@ along with GCC; see the file COPYING3. If not see
 The symbol's value will be loaded directly from the GOT.
 SYMBOL_PCREL
- The symbol's value will be loaded directly from data section.
+ The symbol's value will be loaded directly from data section within
+ +/- 2GiB range.
+
+ SYMBOL_PCREL64
+ The symbol's value will be loaded directly from data section within
+ +/- 8EiB range.
 SYMBOL_TLS
 A thread-local symbol.
@@ -42,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
 enum loongarch_symbol_type {
 SYMBOL_GOT_DISP,
 SYMBOL_PCREL,
+ SYMBOL_PCREL64,
 SYMBOL_TLS,
 SYMBOL_TLS_IE,
 SYMBOL_TLS_LE,
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 41d9cca6d31..d9061cdeee3 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -1633,8 +1633,11 @@ loongarch_rtx_constant_in_small_data_p (machine_mode 
mode)
 static enum loongarch_symbol_type
 loongarch_classify_symbol (const_rtx x)
 {
+ enum loongarch_symbol_type pcrel =
+ TARGET_CMODEL_EXTREME ? SYMBOL_PCREL64 : SYMBOL_PCREL;
+
 if (!SYMBOL_REF_P (x))
- return SYMBOL_PCREL;
+ return pcrel;
 if (SYMBOL_REF_TLS_MODEL (x))
 return SYMBOL_TLS;
@@ -1642,7 +1645,28 @@ loongarch_classify_symbol (const_rtx x)
 if (!loongarch_symbol_binds_local_p (x))
 return SYMBOL_GOT_DISP;
- return SYMBOL_PCREL;
+ tree t = SYMBOL_REF_DECL (x);
+ if (!t)
+ return pcrel;
+
+ t = lookup_attribute ("model", DECL_ATTRIBUTES (t));
+ if (!t)
+ return pcrel;
+
+ t = TREE_VALUE (TREE_VALUE (t));
+
+ /* loongarch_handle_model_attribute should reject other values. */
+ gcc_assert (TREE_CODE (t) == STRING_CST);
+
+ const char *model = TREE_STRING_POINTER (t);
+ if (strcmp (model, "normal") == 0)
+ return SYMBOL_PCREL;
+ if (strcmp (model, "extreme") == 0)
+ return SYMBOL_PCREL64;
+
+ /* loongarch_handle_model_attribute should reject unknown model
+ name. */
+ gcc_unreachable ();
 }
 /* Classify the base of symbolic expression X, given that X appears in
@@ -1695,6 +1719,7 @@ loongarch_symbolic_constant_p (rtx x, enum 
loongarch_symbol_type *symbol_type)
 case SYMBOL_TLSGD:
 case SYMBOL_TLSLDM:
 case SYMBOL_PCREL:
+ case SYMBOL_PCREL64:
 /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */
 return sext_hwi (INTVAL (offset), 32) == INTVAL (

Re: [PATCH V4] rs6000: Optimize cmp on rotated 16bits constant

2022-08-24 Thread Segher Boessenkool
On Wed, Aug 24, 2022 at 03:48:49PM +0800, Jiufu Guo wrote:
> Segher Boessenkool  writes:
> >> +  "TARGET_POWERPC64 && !reload_completed && can_create_pseudo_p ()
> >
> > reload_completed in splitters is almost always wrong.  It isn't any
> > better if it is in the insn condition of a define_insn_and_split :-)
> >
> Thanks, 'can_create_pseudo_p' would be ok for this patch.
> Or just FAIL, if !can_create_pseudo_p()?

You usually can split fine if you cannot create new pseudos, by reusing
existing registers.

FAIL will cause an ICE: the RTL instruction does match, but will fail
when trying to generate machine code for it.

> >> +   && num_insns_constant (operands[2], DImode) > 1
> >> +   && (rotate_from_leading_zeros_const (~UINTVAL (operands[2]), 49) > 0
> >> +   || rotate_from_leading_zeros_const (UINTVAL (operands[2]), 48) > 
> >> 0)"
> > There must be a better way to describe this.
> Will update this. I'm thinking to replace this with a meaning function,
> maybe 'compare_rotate_immediate_p'.

Thanks!

> > Why is this doing a conditional branch at all?  Unpredictable
> > conditional branches are extremely costly.
> This optimization needs to check whether the comparison code is ne/eq or
> not.  To get the comparison code, we need to check the parent insn of
> the 'cmp' insn.  This is why conditional branch patterns in used here.
> 
> This patch should not change the information (about prediction) of the
> branch insn. I'm  thinking of updating the patch to keep the 'note info
> REG_BR_PROB' for the branch instruction.

Ah, good.  Explain a bit about that?  In a code comment or in the commit
message, whichever works best here.

Thanks!


Segher


[PATCH 1/2] LoongArch: Avoid RTL flag check failure in loongarch_classify_symbol

2022-08-24 Thread Xi Ruoyao via Gcc-patches
SYMBOL_REF_TLS_MODEL invokes SYMBOL_REF_FLAGS, and SYMBOL_REF_FLAGS
invokes RTL_FLAG_CHECK1 and aborts when RTL code is not SYMBOL_REF.

r13-1833 removed "gcc_assert (SYMBOL_REF_P (x))" before invoking
"SYMBOL_REF_TLS_MODEL (x)", indicating that it's now possible that "x"
is not a SYMBOL_REF.  So we need to check if "x" is SYMBOL_REF first.

This fixes a test failure happening with r13-2173:

pr106096.C:26:1: internal compiler error: RTL flag check:
SYMBOL_REF_FLAGS used with unexpected rtx code 'const' in
loongarch_classify_symbol

gcc/ChangeLog:

* config/loongarch/loongarch.cc (loongarch_classify_symbol):
Return early if the rtx is not SYMBOL_REF.
---
 gcc/config/loongarch/loongarch.cc | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 16fd4acc970..41d9cca6d31 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -1633,14 +1633,13 @@ loongarch_rtx_constant_in_small_data_p (machine_mode 
mode)
 static enum loongarch_symbol_type
 loongarch_classify_symbol (const_rtx x)
 {
-  if (LABEL_REF_P (x))
+  if (!SYMBOL_REF_P (x))
 return SYMBOL_PCREL;
 
   if (SYMBOL_REF_TLS_MODEL (x))
 return SYMBOL_TLS;
 
-  if (SYMBOL_REF_P (x)
-  && !loongarch_symbol_binds_local_p (x))
+  if (!loongarch_symbol_binds_local_p (x))
 return SYMBOL_GOT_DISP;
 
   return SYMBOL_PCREL;
-- 
2.37.2




Re: [PATCH v3] rs6000: Rework ELFv2 support for -fpatchable-function-entry* [PR99888]

2022-08-24 Thread Segher Boessenkool
On Wed, Aug 24, 2022 at 03:30:51PM +0800, Kewen.Lin wrote:
> on 2022/8/23 22:33, Segher Boessenkool wrote:
> I thought if we can consider [1] and updated the documentation similarly
> like "For PowerPC with the ELFv2 ABI, there will be M nops before the global
> entry point, and N-M after the local entry point".

But that does not agree with the documentation.  The N nops have to be
consecutive.  If you want to support adding separate nop regions before
the LEP and GEP entry points, that is fine, but it will need a separate
command line option.


Segher


Re: Rust frontend patches v1

2022-08-24 Thread Martin Liška
On 8/24/22 15:51, Philip Herron wrote:
> Hi Martin,
> 
> Not right now, it is on the to-do list, but do we have to do it in texinfo?

Well, I still hope we will move to Sphinx (and remove Texinfo) after the 
Cauldron.
Anyway, using Sphinx is even now possible as a default documentation formal 
(see libgccjit,
Ada manuals), where one exports Sphinx to texinfo.

Cheers,
Martin

> 
> Thanks
> 
> --Phil
> 
> On Wed, 24 Aug 2022 at 14:49, Martin Liška  wrote:
>>
>> On 8/15/22 16:33, Martin Liška wrote:
>>> On 8/15/22 16:07, Manuel López-Ibáñez via Gcc-patches wrote:
 Dear Philip,

 Another thing to pay attention to is the move to Sphinx for documentation:
 https://gcc.gnu.org/pipermail/gcc/2022-August/239233.html
>>>
>>> Hi.
>>>
>>> Which is something I can help you with. I have a script that converts a 
>>> texinfo documentation
>>> to Sphinx.
>>
>> @Herron: Do you have any significant documentation changes in the rust 
>> branch right now?
>> I can't see any.
>>
>> Thanks,
>> Martin
>>
>>>
>>> Cheers,
>>> Martin
>>



Re: Rust frontend patches v1

2022-08-24 Thread Philip Herron
Hi Martin,

Not right now, it is on the to-do list, but do we have to do it in texinfo?

Thanks

--Phil

On Wed, 24 Aug 2022 at 14:49, Martin Liška  wrote:
>
> On 8/15/22 16:33, Martin Liška wrote:
> > On 8/15/22 16:07, Manuel López-Ibáñez via Gcc-patches wrote:
> >> Dear Philip,
> >>
> >> Another thing to pay attention to is the move to Sphinx for documentation:
> >> https://gcc.gnu.org/pipermail/gcc/2022-August/239233.html
> >
> > Hi.
> >
> > Which is something I can help you with. I have a script that converts a 
> > texinfo documentation
> > to Sphinx.
>
> @Herron: Do you have any significant documentation changes in the rust branch 
> right now?
> I can't see any.
>
> Thanks,
> Martin
>
> >
> > Cheers,
> > Martin
>


Re: Rust frontend patches v1

2022-08-24 Thread Martin Liška
On 8/15/22 16:33, Martin Liška wrote:
> On 8/15/22 16:07, Manuel López-Ibáñez via Gcc-patches wrote:
>> Dear Philip,
>>
>> Another thing to pay attention to is the move to Sphinx for documentation:
>> https://gcc.gnu.org/pipermail/gcc/2022-August/239233.html
> 
> Hi.
> 
> Which is something I can help you with. I have a script that converts a 
> texinfo documentation
> to Sphinx.

@Herron: Do you have any significant documentation changes in the rust branch 
right now?
I can't see any.

Thanks,
Martin

> 
> Cheers,
> Martin



[COMMITTED] bpf: facilitate constant propagation of function addresses

2022-08-24 Thread Jose E. Marchesi via Gcc-patches


eBPF effectively supports two kind of call instructions:

- The so called pseudo-calls ("bpf to bpf").
- External calls ("bpf to kernel").

The BPF call instruction always gets an immediate argument, whose
interpretation varies depending on the purpose of the instruction:

- For pseudo-calls, the immediate argument is interpreted as a
  32-bit PC-relative displacement measured in number of 64-bit words
  minus one.

- For external calls, the immediate argument is interpreted as the
  identification of a kernel helper.

In order to differenciate both flavors of CALL instructions the SRC
field of the instruction (otherwise unused) is abused as an opcode;
if the field holds 0 the instruction is an external call, if it holds
BPF_PSEUDO_CALL the instruction is a pseudo-call.

C-to-BPF toolchains, including the GNU toolchain, use the following
practical heuristic at assembly time in order to determine what kind
of CALL instruction to generate: call instructions requiring a fixup
at assembly time are interpreted as pseudo-calls.  This means that in
practice a call instruction involving symbols at assembly time (such
as `call foo') is assembled into a pseudo-call instruction, whereas
something like `call 12' is assembled into an external call
instruction.

In both cases, the argument of CALL is an immediate: at the time of
writing eBPF lacks support for indirect calls, i.e. there is no
call-to-register instruction.

This is the reason why BPF programs, in practice, rely on certain
optimizations to happen in order to generate calls to immediates.
This is a typical example involving a kernel helper:

  static void * (*bpf_map_lookup_elem)(void *map, const void *key)
= (void *) 1;

  int foo (...)
  {
char *ret;

ret = bpf_map_lookup_elem (args...);
if (ret)
  return 1;
return 0;
  }

Note how the code above relies on the compiler to do constant
propagation so the call to bpf_map_lookup_elem can be compiled to a
`call 1' instruction.

While GCC provides a kernel_helper function declaration attribute that
can be used in a robust way to tell GCC to generate an external call
despite of optimization level and any other consideration, the Linux
kernel bpf_helpers.h file relies on tricks like the above.

This patch modifies the BPF backend to avoid SSA sparse constant
propagation to be "undone" by the expander loading the function
address into a register.  A new test is also added.

Tested in bpf-unknown-linux-gnu.
No regressions.

gcc/ChangeLog:

PR target/106733
* config/bpf/bpf.cc (bpf_legitimate_address_p): Recognize integer
constants as legitimate addresses for functions.
(bpf_small_register_classes_for_mode_p): Define target hook.

gcc/testsuite/ChangeLog:

PR target/106733
* gcc.target/bpf/constant-calls.c: Rename to ...
* gcc.target/bpf/constant-calls-1.c: and modify to not expect
failure anymore.
* gcc.target/bpf/constant-calls-2.c: New test.
---
 gcc/config/bpf/bpf.cc | 21 ++-
 .../{constant-calls.c => constant-calls-1.c}  |  1 -
 .../gcc.target/bpf/constant-calls-2.c | 16 ++
 3 files changed, 36 insertions(+), 2 deletions(-)
 rename gcc/testsuite/gcc.target/bpf/{constant-calls.c => constant-calls-1.c} 
(88%)
 create mode 100644 gcc/testsuite/gcc.target/bpf/constant-calls-2.c

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 6a0e3bbca9e..7e37e080808 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -659,12 +659,15 @@ bpf_address_base_p (rtx x, bool strict)
target machine for a memory operand of mode MODE.  */
 
 static bool
-bpf_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
+bpf_legitimate_address_p (machine_mode mode,
  rtx x,
  bool strict)
 {
   switch (GET_CODE (x))
 {
+case CONST_INT:
+  return (mode == FUNCTION_MODE);
+
 case REG:
   return bpf_address_base_p (x, strict);
 
@@ -1311,6 +1314,22 @@ bpf_core_walk (tree *tp, int *walk_subtrees, void *data)
   return NULL_TREE;
 }
 
+/* Implement target hook small_register_classes_for_mode_p.  */
+
+static bool
+bpf_small_register_classes_for_mode_p (machine_mode mode)
+{
+  if (TARGET_XBPF)
+return 1;
+  else
+/* Avoid putting function addresses in registers, as calling these
+   is not supported in eBPF.  */
+return (mode != FUNCTION_MODE);
+}
+
+#undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
+  bpf_small_register_classes_for_mode_p
 
 /* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN (see gccint manual section
Target Macros::Misc.).
diff --git a/gcc/testsuite/gcc.target/bpf/constant-calls.c 
b/gcc/testsuite/gcc.target/bpf/constant-calls-1.c
similarity index 88%
rename from gcc/testsuite/gcc.target/bpf/constant-calls.c
rename to gcc/testsuite/gcc.target/bpf/constant-calls-1.c
index 84612a92ae9..6effc7dfdd4 100644
--- a/gcc

[committed] libstdc++: Add check for LWG 3741 problem case

2022-08-24 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8 --

This LWG issue was closed as NAD, as it was just a bug in an
implementation, not a defect in the standard. Libstdc++ never had that
bug and always worked for the problem case. Add a test to ensure we
don't regress.

The problem occurs when abs is implemented using a ternary expression:

 return d >= d.zero() ? d : -d;

If decltype(-d) is not the same as decltype(d) then this is ambiguous,
because each type can be converted to the other, so there is no common
type.

libstdc++-v3/ChangeLog:

* testsuite/20_util/duration_cast/rounding.cc: Check abs with
non-reduced duration.
---
 libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc 
b/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
index af6e72d9e2e..c5179b6eb6e 100644
--- a/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
+++ b/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
@@ -58,3 +58,8 @@ static_assert( std::chrono::round(2501ms) == 3s );
 
 static_assert( std::chrono::abs(100ms) == 100ms );
 static_assert( std::chrono::abs(-100ms) == 100ms );
+
+// LWG 3741. std::chrono::abs(duration) is ill-formed with non-reduced periods
+using D1000 = std::chrono::duration>;
+static_assert( std::chrono::abs(D1000(-2)) == D1000(2) );
+static_assert( std::is_same_v );
-- 
2.37.2



Re: [PATCH 3/3] libstdc++: Implement ranges::zip_view from P2321R2

2022-08-24 Thread Jonathan Wakely via Gcc-patches
On Tue, 23 Aug 2022 at 02:38, Patrick Palka via Libstdc++
 wrote:
>
> Tested on 86_64-pc-linux-gnu, does this look OK for trunk?

As discussed privately, please remove the #include  (which is
not needed, and adds declarations to the global namespace that we
don't need).

OK with that change, thanks.

N.B. re the TODOs, we already have a constexpr abs in  but
it's probably not worth including that just for one function, that
you've already managed without.



[PATCH Rust front-end v2 37/37] gccrs: Add README, CONTRIBUTING and compiler logo

2022-08-24 Thread herron . philip
From: Philip Herron 

We still need to write out documentation section but these README's will
help in the mean time.
---
 gcc/rust/CONTRIBUTING.md | 130 +++
 gcc/rust/README.md   | 264 +++
 gcc/rust/logo.png| Bin 0 -> 70864 bytes
 3 files changed, 394 insertions(+)
 create mode 100644 gcc/rust/CONTRIBUTING.md
 create mode 100644 gcc/rust/README.md
 create mode 100644 gcc/rust/logo.png

diff --git a/gcc/rust/CONTRIBUTING.md b/gcc/rust/CONTRIBUTING.md
new file mode 100644
index 000..20e499c29e1
--- /dev/null
+++ b/gcc/rust/CONTRIBUTING.md
@@ -0,0 +1,130 @@
+## How to contribute to GCC Rust
+
+ **Did you find a bug?**
+
+* **Ensure the bug was not already reported** by searching on GitHub under 
[Issues](https://github.com/Rust-GCC/gccrs/issues).
+
+* If you're unable to find an open issue addressing the problem, [open a new 
one](https://github.com/Rust-GCC/gccrs/issues/new). 
+  Be sure to include a **title and clear description**, as much relevant 
information as possible, and a **code sample** 
+  or an **executable test case** demonstrating the expected behavior that is 
not occurring.
+
+ **Do you want to submit a patch?**
+
+* Open a new GitHub pull request with the patch.
+
+* Ensure the PR description clearly describes the problem and solution. 
Include the relevant issue number if applicable.
+
+* Before submitting, GCC development requires copyright assignment or the 
Developer's Certificate of Origin sign-off.
+   Please see the [Contributing to GCC](https://gcc.gnu.org/contribute.html) 
guide or [Developer's Certificate of Origin (DCO) 
Sign-off](https://gcc.gnu.org/dco.html) guide.
+
+* Patches sent to the [`gcc-rust` mailing 
list](https://gcc.gnu.org/mailman/listinfo/gcc-rust) are likewise welcome.
+These will be imported into a GitHub PR to follow the normal review process, 
+and the link to the GitHub PR sent to the submitter.
+
+ **Do you intend to add a new feature or change an existing one?**
+
+* Suggest your change in the [Zulip](https://gcc-rust.zulipchat.com/) and 
start writing code.
+
+* Do not open an issue on GitHub until you have collected positive feedback 
about the change. 
+  GitHub issues are primarily intended for bug reports and fixes.
+
+ **Do you have questions about the source code?**
+
+* Ask any question about how to use GCCRS in 
[Zulip](https://gcc-rust.zulipchat.com/).
+
+### **PR Policy**
+
+* The PR policy: Everything has to go through a PR
+  - An exception to this rule will be the merge commits of updating the repo 
against upstream GCC
+
+* Reviewers/Maintainers of the project (aka people who have bors rights) 
should be pinged for reviews/questions.
+
+* A PR can have one or several commits (split should have a technical/logical 
reason, ie. no fixup-ish commit)
+
+* Avoid PR's with merge commit unless there's a good reason
+
+* Where possible please add test cases to `gcc/testsuite/rust/` for all PRs. 
+  Some issues may not be testable via dejagnu/automation such as debug dump 
changes.
+
+* Follow the [GCC coding style](https://gcc.gnu.org/codingconventions.html) 
(see `clang-format` below).
+
+* PRs won't be merged until the build and tests pass.
+
+* Please take the time to create good git commit messages. 
+  See the existing format of them in the git log or refer to something like: 
https://chris.beams.io/posts/git-commit/
+
+ Running `clang-format` locally
+
+* on all files using python scripts
+... corresponding to what the _Clang Format Lint_ 
(`.github/workflows/clang-format.yml`) 
+is doing, with `clang-format-10` being available locally, and avoiding the 
Docker overhead.
+
+```shell
+$ wget 
'https://github.com/DoozyX/clang-format-lint-action/raw/v0.11/run-clang-format.py'
+$ cp contrib/clang-format .clang-format
+$ python3 run-clang-format.py --clang-format-executable clang-format-10 
--recursive --extensions h,cc gcc/rust/
+```
+
+* on a given patch using python scripts
+See the [clang-format 
documentation](https://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting)
 :
+
+$ git diff -U0 --no-color HEAD^ | clang-format-diff.py -i -p1
+
+* using `git` interface
+
+At least on Debian and its derivative, each `clang-format` packages also comes
+with `git-clang-format` command that can be used easily. It applies on staged
+changes, and any modification can be seen as unstaged changes:
+
+```diff
+$ git diff --cached
+diff --git a/gcc/rust/rust-abi.h b/gcc/rust/rust-abi.h
+index bd3043295ce..9559374ce60 100644
+--- a/gcc/rust/rust-abi.h
 b/gcc/rust/rust-abi.h
+@@ -22,10 +22,10 @@ namespace Rust {
+ enum ABI
+ {
+   UNKNOWN,
+-  RUST,
++ RUST,
+   INTRINSIC,
+   C,
+-  CDECL,
++ CDECL,
+   STDCALL,
+   FASTCALL,
+ };
+ 
+gccrs/gcc/rust on  dkm/clang_format [$!+?]
+❯ git clang-format
+changed files:
+gcc/rust/rust-abi.h
+ 
+gccrs/gcc/rust on  dkm/clang_format [$!+?]
+$ git diff rust-abi.h
+diff --git a/gcc/rust/rust-abi.h

[PATCH Rust front-end v2 28/37] gccrs: Add metadata ouptput pass

2022-08-24 Thread herron . philip
From: Philip Herron 

Extern crates statements to tell the front-end to look for another library.
The mechanism here is heavily inspired from gccgo, so when we compile a
library for example we invoke:

  gccrs -g -O2 -frust-crate=mylib -c src/lib.rs -o src/mylib.o

All going well this object file will now contain extra data inside
.rust-export section inside the object file which will be preserved inside
archives and shared objects. When we have another application which uses
this library 'mylib'.

  extern crate mylib;
  use mylib::foo;

  fn main() {
foo();
  }

We compile using:

  gcc -g -O2 -frust-crate=test -c src/main.rs -o src/main.o

When the extern crate line is hit the front-end will look for mylib.o,
libmylib.a, mylib.rox. If it finds a raw object file it will read the
.rust-export section directly from the object for the public metadata
such as public functions, types constants etc. If it fails to find an
object it might find .rox which is the objdump of the .rust-export to a
raw file, it might even find libmylib.a and read the export directly out
of the archive file reusing code from gccgo to do so.

The full compiler pipeline is reused here, so the metatadata is actually
just real rust code. The benifit here is that Rust supports exporting,
macros and generics so this requires the name-resolution and type info
all to be generated and inserted into the apropriate context classes. Since
the metadata is real rust code it means we can reuse the full pipeline to
generate the code as nessecary. So for the simple case of a public struct
we simply emit the AST dump of this struct directly into the metadata. If
its a non-generic public function we emit and extern rust abi block for
that function. If its a trait we can simply emit the trait with the public
memebers. Generics are more complicated since we need to emit the function
fully for it to be compiled correctly this still needs tests to be added.
The hardest part is non generic impl blocks which is still a WIP.

To finally link the two crates together you run:

  gcc -g -O2 -o rust-program.exe src/main.o src/mylib.o
---
 gcc/rust/metadata/rust-export-metadata.cc | 385 ++
 gcc/rust/metadata/rust-export-metadata.h  |  85 +++
 gcc/rust/metadata/rust-extern-crate.cc| 173 +
 gcc/rust/metadata/rust-extern-crate.h |  55 ++
 gcc/rust/metadata/rust-import-archive.cc  | 885 ++
 gcc/rust/metadata/rust-imports.cc | 441 +++
 gcc/rust/metadata/rust-imports.h  | 257 +++
 gcc/rust/rust-object-export.cc| 177 +
 gcc/rust/rust-object-export.h |  33 +
 9 files changed, 2491 insertions(+)
 create mode 100644 gcc/rust/metadata/rust-export-metadata.cc
 create mode 100644 gcc/rust/metadata/rust-export-metadata.h
 create mode 100644 gcc/rust/metadata/rust-extern-crate.cc
 create mode 100644 gcc/rust/metadata/rust-extern-crate.h
 create mode 100644 gcc/rust/metadata/rust-import-archive.cc
 create mode 100644 gcc/rust/metadata/rust-imports.cc
 create mode 100644 gcc/rust/metadata/rust-imports.h
 create mode 100644 gcc/rust/rust-object-export.cc
 create mode 100644 gcc/rust/rust-object-export.h

diff --git a/gcc/rust/metadata/rust-export-metadata.cc 
b/gcc/rust/metadata/rust-export-metadata.cc
new file mode 100644
index 000..4856bc26149
--- /dev/null
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -0,0 +1,385 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-export-metadata.h"
+#include "rust-hir-visitor.h"
+#include "rust-hir-full.h"
+#include "rust-hir-map.h"
+#include "rust-ast-dump.h"
+#include "rust-abi.h"
+#include "rust-object-export.h"
+
+#include "md5.h"
+
+namespace Rust {
+namespace Metadata {
+
+static const std::string extension_path = ".rox";
+
+ExportContext::ExportContext () : mappings (Analysis::Mappings::get ()) {}
+
+ExportContext::~ExportContext () {}
+
+void
+ExportContext::push_module_scope (const HIR::Module &module)
+{
+  module_stack.push_back (module);
+}
+
+const HIR::Module &
+ExportContext::pop_module_scope ()
+{
+  rust_assert (!module_stack.empty ());
+  const HIR::Module &poped = module_stack.back ();
+  module_stack.pop_back ();
+  return poped;
+}
+
+void
+ExportContext::emit_trait (const HIR::Trait &trait)
+{
+  // lookup the AST node for th

[PATCH Rust front-end v2 35/37] gccrs: add compiler driver

2022-08-24 Thread herron . philip
From: Philip Herron 

Our compiler driver is pretty simple so far, the key piece to enforce is
that a compilation unit in Rust is the whole crate so the process for
compiling rust means pointing the compiler at the main entry point such as
src/lib.rs or src/main.rs where the expansion pass takes over loading the
other source files to include them in the crate.
---
 gcc/rust/rustspec.cc | 191 +++
 1 file changed, 191 insertions(+)
 create mode 100644 gcc/rust/rustspec.cc

diff --git a/gcc/rust/rustspec.cc b/gcc/rust/rustspec.cc
new file mode 100644
index 000..b05f8ae5454
--- /dev/null
+++ b/gcc/rust/rustspec.cc
@@ -0,0 +1,191 @@
+/* rustspec.c -- Specific flags and argument handling of the gcc Rust front 
end.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "opts.h"
+
+// satisfy intellisense
+#include "options.h"
+
+/* This bit is set if we saw a `-xfoo' language specification.  */
+#define LANGSPEC (1 << 1)
+/* This bit is set if they did `-lc'.  */
+#define WITHLIBC (1 << 2)
+/* Skip this option.  */
+#define SKIPOPT (1 << 3)
+
+void
+lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+ unsigned int *in_decoded_options_count,
+ int *in_added_libraries)
+{
+  unsigned int i, j;
+
+  /* The new argument list will be contained in this.  */
+  struct cl_decoded_option *new_decoded_options;
+
+  /* "-lc" if it appears on the command line.  */
+  const struct cl_decoded_option *saw_libc = 0;
+
+  /* An array used to flag each argument that needs a bit set for
+ LANGSPEC or WITHLIBC.  */
+  int *args;
+
+  /* True if we saw -static.  */
+  int static_link = 0;
+
+  /* True if we should add -shared-libgcc to the command-line.  */
+  int shared_libgcc = 1;
+
+  /* The total number of arguments with the new stuff.  */
+  unsigned int argc;
+
+  /* The argument list.  */
+  struct cl_decoded_option *decoded_options;
+
+  /* The number of libraries added in.  */
+  int added_libraries;
+
+  /* The total number of arguments with the new stuff.  */
+  int num_args = 1;
+
+  /* Whether the -o option was used.  */
+  bool saw_opt_o = false;
+
+  /* The first input file with an extension of .rs.  */
+  const char *first_rust_file = NULL;
+
+  argc = *in_decoded_options_count;
+  decoded_options = *in_decoded_options;
+  added_libraries = *in_added_libraries;
+
+  args = XCNEWVEC (int, argc);
+
+  for (i = 1; i < argc; i++)
+{
+  const char *arg = decoded_options[i].arg;
+
+  switch (decoded_options[i].opt_index)
+   {
+   case OPT_l:
+ if (strcmp (arg, "c") == 0)
+   args[i] |= WITHLIBC;
+ break;
+
+   case OPT_o:
+ saw_opt_o = true;
+ break;
+
+   case OPT_static:
+ static_link = 1;
+ break;
+
+   case OPT_static_libgcc:
+ shared_libgcc = 0;
+ break;
+
+   case OPT_SPECIAL_input_file:
+ if (first_rust_file == NULL)
+   {
+ int len;
+
+ len = strlen (arg);
+ if (len > 3 && strcmp (arg + len - 3, ".rs") == 0)
+   first_rust_file = arg;
+   }
+ else
+   {
+ // FIXME: ARTHUR: Do we want to error here? If there's already one
+ // file?
+ // How do we error here? Do we want to instead just handle that in
+ // the session manager?
+   }
+
+ break;
+   }
+}
+
+/* There's no point adding -shared-libgcc if we don't have a shared
+   libgcc.  */
+#ifndef ENABLE_SHARED_LIBGCC
+  shared_libgcc = 0;
+#endif
+
+  /* Make sure to have room for the trailing NULL argument.  */
+  num_args = argc + shared_libgcc * 5 + 10;
+  new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
+
+  i = 0;
+  j = 0;
+
+  /* Copy the 0th argument, i.e., the name of the program itself.  */
+  new_decoded_options[j++] = decoded_options[i++];
+
+  /* NOTE: We start at 1 now, not 0.  */
+  while (i < argc)
+{
+  new_decoded_options[j] = decoded_options[i];
+
+  if (!saw_libc && (args[i] & WITHLIBC))
+   {
+ --j;
+ saw_libc = &decoded_options[i];
+   }
+
+  if ((args[i] & SKIPOPT) != 0)
+   --j

[PATCH Rust front-end v2 31/37] gccrs: Add GCC Rust front-end Make-lang.in

2022-08-24 Thread herron . philip
From: Philip Herron 

This is the Makefile for our front-end.
---
 gcc/rust/Make-lang.in | 400 ++
 1 file changed, 400 insertions(+)
 create mode 100644 gcc/rust/Make-lang.in

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
new file mode 100644
index 000..f687cc2f667
--- /dev/null
+++ b/gcc/rust/Make-lang.in
@@ -0,0 +1,400 @@
+# Make-lang.in -- Top level -*- makefile -*- fragment for GCC Rust frontend.
+
+# Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# .
+
+# This file provides the language dependent support in the main Makefile.
+
+#RUST_EXES = rust
+
+# Use strict warnings for this front end.
+rust-warn = $(STRICT_WARN)
+
+# Installation name. Useful for cross compilers and used during install.
+GCCRS_INSTALL_NAME := $(shell echo gccrs|sed '$(program_transform_name)')
+GCCRS_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gccrs|sed 
'$(program_transform_name)')
+
+# Define the names for selecting rust in LANGUAGES.
+rust: rust1$(exeext)
+
+# Tell GNU make to ignore files by these names if they exist.
+.PHONY: rust
+
+# removed GRS_CFLAGS from here
+
+CFLAGS-rust/rustspec.o += $(DRIVER_DEFINES)
+
+# Create the compiler driver gccrs.
+# A compiler driver is the program that interprets command argument and can be 
called from the command
+# line - e.g. gcc or g++, and not cc1, which is the actual compiler
+
+# Create driver objects
+GCCRS_D_OBJS = \
+   $(GCC_OBJS) \
+   rust/rustspec.o \
+   $(END)
+
+gccrs$(exeext): $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
+   +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+ $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
+ $(EXTRA_GCC_LIBS) $(LIBS)
+
+# List of host object files used by the rust language - files for translation 
from the parse tree
+# to GENERIC
+# The compiler proper, not driver
+GRS_OBJS = \
+rust/rust-lang.o \
+rust/rust-object-export.o \
+rust/rust-linemap.o \
+rust/rust-gcc-diagnostics.o \
+rust/rust-diagnostics.o \
+rust/rust-gcc.o \
+rust/rust-token.o \
+rust/rust-lex.o \
+rust/rust-cfg-parser.o \
+rust/rust-parse.o \
+rust/rust-ast-full-test.o \
+rust/rust-ast-dump.o \
+rust/rust-hir-dump.o \
+rust/rust-session-manager.o \
+rust/rust-compile.o \
+rust/rust-mangle.o \
+rust/rust-compile-resolve-path.o \
+rust/rust-macro-expand.o \
+rust/rust-attribute-visitor.o \
+rust/rust-macro-invoc-lexer.o \
+rust/rust-macro-substitute-ctx.o \
+rust/rust-macro-builtins.o \
+rust/rust-hir-full-test.o \
+rust/rust-hir-map.o \
+rust/rust-attributes.o \
+rust/rust-abi.o \
+rust/rust-ast-lower.o \
+rust/rust-ast-lower-base.o \
+rust/rust-ast-lower-pattern.o \
+rust/rust-ast-lower-item.o \
+rust/rust-name-resolver.o \
+rust/rust-ast-resolve.o \
+rust/rust-ast-resolve-base.o \
+rust/rust-ast-resolve-item.o \
+rust/rust-ast-resolve-pattern.o \
+rust/rust-ast-resolve-expr.o \
+rust/rust-ast-resolve-type.o \
+rust/rust-ast-resolve-path.o \
+rust/rust-ast-resolve-stmt.o \
+rust/rust-ast-resolve-struct-expr-field.o \
+rust/rust-hir-type-check.o \
+rust/rust-privacy-check.o \
+rust/rust-privacy-ctx.o \
+rust/rust-reachability.o \
+rust/rust-visibility-resolver.o \
+rust/rust-pub-restricted-visitor.o \
+rust/rust-privacy-reporter.o \
+rust/rust-tyty.o \
+rust/rust-tyty-call.o \
+rust/rust-tyctx.o \
+rust/rust-tyty-bounds.o \
+rust/rust-hir-type-check-util.o \
+rust/rust-hir-trait-resolve.o \
+rust/rust-hir-type-check-toplevel.o \
+rust/rust-hir-type-check-item.o \
+rust/rust-hir-type-check-type.o \
+rust/rust-hir-type-check-struct.o \
+rust/rust-hir-type-check-pattern.o \
+rust/rust-hir-type-check-expr.o \
+rust/rust-hir-type-check-stmt.o \
+rust/rust-hir-type-check-enumitem.o \
+rust/rust-hir-type-check-implitem.o \
+rust/rust-hir-dot-operator.o \
+rust/rust-coercion.o \
+rust/rust-casts.o \
+rust/rust-hir-type-check-base.o \
+rust/rust-autoderef.o \
+rust/rust-substitution-mapper.o \
+rust/rust-const-checker.o \
+rust/rust-lint-marklive.o \
+rust/rust-lint-unused-var.o \
+rust/rust-hir-type-check-path.o \
+rust/r

[PATCH Rust front-end v2 30/37] gccrs: These are wrappers ported from reusing gccgo

2022-08-24 Thread herron . philip
From: Philip Herron 

The wrappers over linemap and location will eventually disappear here but
served as a useful starting point for us. We have wrappers over the
diagnostics system which we might be able to get rid of as well.
---
 gcc/rust/rust-diagnostics.cc | 244 +++
 gcc/rust/rust-diagnostics.h  | 154 +++
 gcc/rust/rust-gcc-diagnostics.cc |  84 +++
 gcc/rust/rust-linemap.cc | 229 +
 gcc/rust/rust-linemap.h  | 163 +
 gcc/rust/rust-location.h | 105 +
 gcc/rust/rust-system.h   |  86 +++
 7 files changed, 1065 insertions(+)
 create mode 100644 gcc/rust/rust-diagnostics.cc
 create mode 100644 gcc/rust/rust-diagnostics.h
 create mode 100644 gcc/rust/rust-gcc-diagnostics.cc
 create mode 100644 gcc/rust/rust-linemap.cc
 create mode 100644 gcc/rust/rust-linemap.h
 create mode 100644 gcc/rust/rust-location.h
 create mode 100644 gcc/rust/rust-system.h

diff --git a/gcc/rust/rust-diagnostics.cc b/gcc/rust/rust-diagnostics.cc
new file mode 100644
index 000..c2d3e4ee8be
--- /dev/null
+++ b/gcc/rust/rust-diagnostics.cc
@@ -0,0 +1,244 @@
+// rust-diagnostics.cc -- GCC implementation of rust diagnostics interface.
+// Copyright (C) 2016-2022 Free Software Foundation, Inc.
+// Contributed by Than McIntosh, Google.
+
+// 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
+// .
+
+#include "rust-system.h"
+#include "rust-diagnostics.h"
+
+static std::string
+mformat_value ()
+{
+  return std::string (xstrerror (errno));
+}
+
+// Rewrite a format string to expand any extensions not
+// supported by sprintf(). See comments in rust-diagnostics.h
+// for list of supported format specifiers.
+
+static std::string
+expand_format (const char *fmt)
+{
+  std::stringstream ss;
+  for (const char *c = fmt; *c; ++c)
+{
+  if (*c != '%')
+   {
+ ss << *c;
+ continue;
+   }
+  c++;
+  switch (*c)
+   {
+ case '\0': {
+   // malformed format string
+   rust_unreachable ();
+ }
+ case '%': {
+   ss << "%";
+   break;
+ }
+ case 'm': {
+   ss << mformat_value ();
+   break;
+ }
+ case '<': {
+   ss << rust_open_quote ();
+   break;
+ }
+ case '>': {
+   ss << rust_close_quote ();
+   break;
+ }
+ case 'q': {
+   ss << rust_open_quote ();
+   c++;
+   if (*c == 'm')
+ {
+   ss << mformat_value ();
+ }
+   else
+ {
+   ss << "%" << *c;
+ }
+   ss << rust_close_quote ();
+   break;
+ }
+ default: {
+   ss << "%" << *c;
+ }
+   }
+}
+  return ss.str ();
+}
+
+// Expand message format specifiers, using a combination of
+// expand_format above to handle extensions (ex: %m, %q) and vasprintf()
+// to handle regular printf-style formatting. A pragma is being used here to
+// suppress this warning:
+//
+//   warning: function ‘std::__cxx11::string expand_message(const char*,
+//   __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute
+//   [-Wsuggest-attribute=format]
+//
+// What appears to be happening here is that the checker is deciding that
+// because of the call to vasprintf() (which has attribute gnu_printf), the
+// calling function must need to have attribute gnu_printf as well, even
+// though there is already an attribute declaration for it.
+
+static std::string
+expand_message (const char *fmt, va_list ap) RUST_ATTRIBUTE_GCC_DIAG (1, 0);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
+
+static std::string
+expand_message (const char *fmt, va_list ap)
+{
+  char *mbuf = 0;
+  std::string expanded_fmt = expand_format (fmt);
+  int nwr = vasprintf (&mbuf, expanded_fmt.c_str (), ap);
+  if (nwr == -1)
+{
+  // memory allocation failed
+  rust_be_error_at (Linemap::unknown_location (),
+   "memory allocation failed in vasprintf");
+  rust_assert (0);
+}
+  std::string rval = std::string (mbuf);
+  free (mbuf);
+  return rval;
+}
+
+#pragma GCC diagnostic pop
+
+static const char *cached_open_quote = NULL;
+s

[PATCH Rust front-end v2 33/37] gccrs: add lang-spec.h

2022-08-24 Thread herron . philip
From: Philip Herron 

This specifies the extensions of the Rust language.
---
 gcc/rust/lang-specs.h | 26 ++
 1 file changed, 26 insertions(+)
 create mode 100644 gcc/rust/lang-specs.h

diff --git a/gcc/rust/lang-specs.h b/gcc/rust/lang-specs.h
new file mode 100644
index 000..9b14a559dd6
--- /dev/null
+++ b/gcc/rust/lang-specs.h
@@ -0,0 +1,26 @@
+/* lang-specs.h -- gcc driver specs for Rust frontend.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   .  */
+
+/* This is the contribution to the `default_compilers' array in gcc.cc
+   for the Rust language.  */
+
+{".rs", "@rs", 0, 1, 0},
+  {"@rs",
+   "rust1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", 0, 
1,
+   0},
-- 
2.25.1



[PATCH Rust front-end v2 32/37] gccrs: Add config-lang.in

2022-08-24 Thread herron . philip
From: Philip Herron 

This was a copy paste from gccgo front-end, we do not use any of the
target_libs yet but we will need these when we support the libpanic crate.
---
 gcc/rust/config-lang.in | 34 ++
 1 file changed, 34 insertions(+)
 create mode 100644 gcc/rust/config-lang.in

diff --git a/gcc/rust/config-lang.in b/gcc/rust/config-lang.in
new file mode 100644
index 000..d2ff376032a
--- /dev/null
+++ b/gcc/rust/config-lang.in
@@ -0,0 +1,34 @@
+# config-lang.in -- Top level configure fragment for gcc Rust frontend.
+
+# Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# .
+
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language - name of language as it would appear in $(LANGUAGES)
+# compilers- value to add to $(COMPILERS)
+
+language="rust"
+compilers="rust1\$(exeext)"
+
+build_by_default="no"
+
+target_libs="target-libffi target-libbacktrace"
+
+gtfiles="\$(srcdir)/rust/rust-lang.cc"
-- 
2.25.1



[PATCH Rust front-end v2 24/37] gccrs: Add const checker

2022-08-24 Thread herron . philip
From: Arthur Cohen 

Similarly to the unsafe checker, constant evaluation can only be performed
in a few contexts and include restrictions on the Rust language. Should
the user fail to uphold those conditions, errors will be reported and the
compilation pipeline interrupted.

These contexts are as follow:

- Array type length expressions
- Array repeat length expressions
- Constants
- Statics
- Enum discriminants
- Const generic arguments

In these contexts, the user is restricted to calling only functions marked
as `const` or perform arithmetic operations only on certain types, among
other restrictions.
---
 gcc/rust/checks/errors/rust-const-checker.cc | 844 +++
 gcc/rust/checks/errors/rust-const-checker.h  | 189 +
 2 files changed, 1033 insertions(+)
 create mode 100644 gcc/rust/checks/errors/rust-const-checker.cc
 create mode 100644 gcc/rust/checks/errors/rust-const-checker.h

diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
new file mode 100644
index 000..35c61fe03f0
--- /dev/null
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -0,0 +1,844 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-const-checker.h"
+#include "rust-hir.h"
+#include "rust-hir-expr.h"
+#include "rust-hir-stmt.h"
+#include "rust-hir-item.h"
+
+namespace Rust {
+namespace HIR {
+
+ConstChecker::ConstChecker ()
+  : resolver (*Resolver::Resolver::get ()),
+mappings (*Analysis::Mappings::get ())
+{}
+
+void
+ConstChecker::go (HIR::Crate &crate)
+{
+  for (auto &item : crate.items)
+item->accept_vis (*this);
+}
+
+bool
+ConstChecker::is_const_extern_fn (HIR::ExternalFunctionItem &fn)
+{
+  // FIXME: Is it really how we want to handle `rustc_const_stable`
+  // and `rustc_const_unstable`?
+  // TODO: Add these attributes to the attribute check and handle
+  // `stable` and `unstable` as well
+  return std::any_of (
+fn.get_outer_attrs ().begin (), fn.get_outer_attrs ().end (),
+[] (const AST::Attribute &attr) {
+  // `starts_with` in C++11...
+  return attr.get_path ().as_string ().rfind ("rustc_const_", 0) == 0;
+});
+}
+
+void
+ConstChecker::visit (Lifetime &lifetime)
+{}
+
+void
+ConstChecker::visit (LifetimeParam &lifetime_param)
+{}
+
+void
+ConstChecker::visit (PathInExpression &path)
+{}
+
+void
+ConstChecker::visit (TypePathSegment &segment)
+{}
+
+void
+ConstChecker::visit (TypePathSegmentGeneric &segment)
+{}
+
+void
+ConstChecker::visit (TypePathSegmentFunction &segment)
+{}
+
+void
+ConstChecker::visit (TypePath &path)
+{}
+
+void
+ConstChecker::visit (QualifiedPathInExpression &path)
+{}
+
+void
+ConstChecker::visit (QualifiedPathInType &path)
+{}
+
+void
+ConstChecker::visit (LiteralExpr &expr)
+{}
+
+void
+ConstChecker::visit (BorrowExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (DereferenceExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ErrorPropagationExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (NegationExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArithmeticOrLogicalExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ComparisonExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (LazyBooleanExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (TypeCastExpr &expr)
+{
+  expr.get_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (AssignmentExpr &expr)
+{
+  expr.get_lhs ()->accept_vis (*this);
+  expr.get_rhs ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (CompoundAssignmentExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (GroupedExpr &expr)
+{
+  expr.get_expr_in_parens ()->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArrayElemsValues &elems)
+{
+  for (auto &elem : elems.get_values ())
+elem->accept_vis (*this);
+}
+
+void
+ConstChecker::visit (ArrayElemsCopied &elems)
+{
+  elems.get_elem_to_copy ()->accept_

[PATCH Rust front-end v2 26/37] gccrs: Add dead code scan on HIR

2022-08-24 Thread herron . philip
From: Thomas Young 

In order to find dead code we use a depth first search and keep liveness
variables, after type resolution. In this case, if a function is unused
and it calls another function the 2nd function is now unused since the
caller is not used etc. The algorithm is a depth first search.
---
 .../checks/lints/rust-lint-marklive-base.h|  45 +++
 gcc/rust/checks/lints/rust-lint-marklive.cc   | 282 
 gcc/rust/checks/lints/rust-lint-marklive.h| 308 ++
 .../checks/lints/rust-lint-scan-deadcode.h| 154 +
 4 files changed, 789 insertions(+)
 create mode 100644 gcc/rust/checks/lints/rust-lint-marklive-base.h
 create mode 100644 gcc/rust/checks/lints/rust-lint-marklive.cc
 create mode 100644 gcc/rust/checks/lints/rust-lint-marklive.h
 create mode 100644 gcc/rust/checks/lints/rust-lint-scan-deadcode.h

diff --git a/gcc/rust/checks/lints/rust-lint-marklive-base.h 
b/gcc/rust/checks/lints/rust-lint-marklive-base.h
new file mode 100644
index 000..97c068188b1
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-marklive-base.h
@@ -0,0 +1,45 @@
+// Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_HIR_LIVENESS_BASE
+#define RUST_HIR_LIVENESS_BASE
+
+#include "rust-diagnostics.h"
+#include "rust-lint-marklive.h"
+#include "rust-lint-marklive-base.h"
+#include "rust-hir-visitor.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace Analysis {
+
+class MarkLiveBase : public HIR::HIRFullVisitorBase
+{
+public:
+  virtual ~MarkLiveBase () {}
+
+protected:
+  MarkLiveBase () : mappings (Analysis::Mappings::get ()) {}
+
+  Analysis::Mappings *mappings;
+};
+
+} // namespace Analysis
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc 
b/gcc/rust/checks/lints/rust-lint-marklive.cc
new file mode 100644
index 000..245632b4b4c
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -0,0 +1,282 @@
+// Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+// The idea is that all reachable symbols are live, codes called
+// from live codes are live, and everything else is dead.
+
+#include "rust-lint-marklive.h"
+#include "rust-hir-full.h"
+#include "rust-name-resolver.h"
+
+namespace Rust {
+namespace Analysis {
+
+// This class trys to find the live symbols which can be used as
+// seeds in MarkLive
+//
+// 1. TODO: explicit live
+//- Attribute like #[allow(dead_code)]
+//- Attribute like #[lang=".."], it's not a intra-crate item.
+// 2. TODO: foreign item
+class FindEntryPoint : public MarkLiveBase
+{
+  using Rust::Analysis::MarkLiveBase::visit;
+
+public:
+  static std::vector find (HIR::Crate &crate)
+  {
+FindEntryPoint findEntryPoint;
+for (auto it = crate.items.begin (); it != crate.items.end (); it++)
+  {
+   it->get ()->accept_vis (findEntryPoint);
+  }
+return findEntryPoint.getEntryPoint ();
+  }
+
+  // TODO not only fn main can be a entry point.
+  void visit (HIR::Function &function) override
+  {
+if (function.get_function_name () == "main")
+  {
+   entryPoints.push_back (function.get_mappings ().get_hirid ());
+  }
+  }
+
+private:
+  FindEntryPoint () : MarkLiveBase () {}
+  std::vector entryPoints;
+  std::vector getEntryPoint () { return entryPoints; }
+};
+
+std::set
+MarkLive::Analysis (HIR::Crate &crate)
+{
+  MarkLive marklive (FindEntryPoint::find (crate));
+  marklive.go (crate);
+
+  return marklive.liveSymbols;
+}
+
+// pop a live symbol from worklist every iteration,
+// if it's a function then walk the function body, and
+// 1. save all the live symbols in worklist which is
+//visi

[PATCH Rust front-end v2 27/37] gccrs: Add unused variable scan

2022-08-24 Thread herron . philip
From: Philip Herron 

This is a simple walk_tree which acts on the monomorphized code. By walking
the compiled translation unit of functions.
---
 gcc/rust/checks/lints/rust-lint-unused-var.cc | 98 +++
 gcc/rust/checks/lints/rust-lint-unused-var.h  | 36 +++
 2 files changed, 134 insertions(+)
 create mode 100644 gcc/rust/checks/lints/rust-lint-unused-var.cc
 create mode 100644 gcc/rust/checks/lints/rust-lint-unused-var.h

diff --git a/gcc/rust/checks/lints/rust-lint-unused-var.cc 
b/gcc/rust/checks/lints/rust-lint-unused-var.cc
new file mode 100644
index 000..d4317e53280
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-unused-var.cc
@@ -0,0 +1,98 @@
+// Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-lint-unused-var.h"
+#include "print-tree.h"
+
+namespace Rust {
+namespace Analysis {
+
+static void
+check_decl (tree *t)
+{
+  rust_assert (TREE_CODE (*t) == VAR_DECL || TREE_CODE (*t) == PARM_DECL
+  || TREE_CODE (*t) == CONST_DECL);
+
+  tree var_name = DECL_NAME (*t);
+  const char *var_name_ptr = IDENTIFIER_POINTER (var_name);
+  bool starts_with_under_score = strncmp (var_name_ptr, "_", 1) == 0;
+
+  bool is_constant = TREE_CODE (*t) == CONST_DECL;
+  // if (!is_constant)
+  //   {
+  // debug_tree (*t);
+  // rust_debug ("found var-decl: used %s artifical %s underscore %s name
+  // %s",
+  // TREE_USED (*t) ? "true" : "false",
+  // DECL_ARTIFICIAL (*t) ? "true" : "false",
+  // starts_with_under_score ? "true" : "false", var_name_ptr);
+  //   }
+
+  if (!TREE_USED (*t) && !DECL_ARTIFICIAL (*t) && !starts_with_under_score)
+{
+  warning_at (DECL_SOURCE_LOCATION (*t),
+ is_constant ? OPT_Wunused_const_variable_
+ : OPT_Wunused_variable,
+ "unused name %qE", *t);
+}
+}
+
+static tree
+unused_var_walk_fn (tree *t, int *walk_subtrees, void *closure)
+{
+  switch (TREE_CODE (*t))
+{
+case VAR_DECL:
+case CONST_DECL:
+  check_decl (t);
+  break;
+
+default:
+  break;
+}
+  return NULL_TREE;
+}
+
+void
+UnusedVariables::Lint (Compile::Context &ctx)
+{
+  for (auto &fndecl : ctx.get_func_decls ())
+{
+  for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN 
(p))
+   {
+ check_decl (&p);
+   }
+
+  walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
+   &unused_var_walk_fn, &ctx);
+}
+
+  for (auto &var : ctx.get_var_decls ())
+{
+  tree t = ctx.get_backend ()->var_expression (var, Location ());
+  check_decl (&t);
+}
+
+  for (auto &const_decl : ctx.get_const_decls ())
+{
+  check_decl (&const_decl);
+}
+}
+
+} // namespace Analysis
+} // namespace Rust
diff --git a/gcc/rust/checks/lints/rust-lint-unused-var.h 
b/gcc/rust/checks/lints/rust-lint-unused-var.h
new file mode 100644
index 000..6fabfeff01b
--- /dev/null
+++ b/gcc/rust/checks/lints/rust-lint-unused-var.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_LINT_UNUSED_VAR
+#define RUST_LINT_UNUSED_VAR
+
+#include "rust-compile-context.h"
+
+namespace Rust {
+namespace Analysis {
+
+class UnusedVariables
+{
+public:
+  static void Lint (Compile::Context &ctx);
+};
+
+} // namespace Analysis
+} // namespace Rust
+
+#endif // RUST_LINT_UNUSED_VAR
-- 
2.25.1



[PATCH Rust front-end v2 21/37] gccrs: Add helpers mappings canonical path and lang items

2022-08-24 Thread herron . philip
From: Philip Herron 

These are various helper classes used in the compiler pipeline.
---
 gcc/rust/util/rust-canonical-path.h   | 195 +
 gcc/rust/util/rust-common.h   |  53 ++
 gcc/rust/util/rust-hir-map.cc | 980 ++
 gcc/rust/util/rust-hir-map.h  | 356 ++
 gcc/rust/util/rust-identifier.h   |  49 ++
 gcc/rust/util/rust-lang-item.h| 377 ++
 gcc/rust/util/rust-mapping-common.h   |  85 +++
 gcc/rust/util/rust-stacked-contexts.h |  86 +++
 8 files changed, 2181 insertions(+)
 create mode 100644 gcc/rust/util/rust-canonical-path.h
 create mode 100644 gcc/rust/util/rust-common.h
 create mode 100644 gcc/rust/util/rust-hir-map.cc
 create mode 100644 gcc/rust/util/rust-hir-map.h
 create mode 100644 gcc/rust/util/rust-identifier.h
 create mode 100644 gcc/rust/util/rust-lang-item.h
 create mode 100644 gcc/rust/util/rust-mapping-common.h
 create mode 100644 gcc/rust/util/rust-stacked-contexts.h

diff --git a/gcc/rust/util/rust-canonical-path.h 
b/gcc/rust/util/rust-canonical-path.h
new file mode 100644
index 000..54cc0390849
--- /dev/null
+++ b/gcc/rust/util/rust-canonical-path.h
@@ -0,0 +1,195 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_CANONICAL_PATH
+#define RUST_CANONICAL_PATH
+
+#include "rust-system.h"
+#include "rust-mapping-common.h"
+
+namespace Rust {
+namespace Resolver {
+
+// https://doc.rust-lang.org/reference/paths.html#canonical-paths
+//
+// struct X - path X
+// impl X { fn test - path X::test }
+//
+// struct X - path X
+//
+// impl X   { fn test - path X::test}
+// impl X { fn test - path X::test }
+// impl X { fn test - path X::test }
+//
+// pub trait Trait { // ::a::Trait
+//   fn f(&self); // ::a::Trait::f
+// }
+//
+// impl Trait for Struct {
+//fn f(&self) {} // <::a::Struct as ::a::Trait>::f
+// }
+class CanonicalPath
+{
+public:
+  CanonicalPath (const CanonicalPath &other) : segs (other.segs) {}
+
+  CanonicalPath &operator= (const CanonicalPath &other)
+  {
+segs = other.segs;
+return *this;
+  }
+
+  static CanonicalPath new_seg (NodeId id, const std::string &path)
+  {
+rust_assert (!path.empty ());
+return CanonicalPath ({std::pair (id, path)},
+ UNKNOWN_CREATENUM);
+  }
+
+  static CanonicalPath
+  trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg,
+const CanonicalPath &impl_type_seg)
+  {
+return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + " as "
++ trait_seg.get () + ">");
+  }
+
+  std::string get () const
+  {
+std::string buf;
+for (size_t i = 0; i < segs.size (); i++)
+  {
+   bool have_more = (i + 1) < segs.size ();
+   const std::string &seg = segs.at (i).second;
+   buf += seg + (have_more ? "::" : "");
+  }
+return buf;
+  }
+
+  static CanonicalPath get_big_self (NodeId id)
+  {
+return CanonicalPath::new_seg (id, "Self");
+  }
+
+  static CanonicalPath create_empty ()
+  {
+return CanonicalPath ({}, UNKNOWN_CREATENUM);
+  }
+
+  bool is_empty () const { return segs.size () == 0; }
+
+  CanonicalPath append (const CanonicalPath &other) const
+  {
+rust_assert (!other.is_empty ());
+if (is_empty ())
+  return CanonicalPath (other.segs, crate_num);
+
+std::vector> copy (segs);
+for (auto &s : other.segs)
+  copy.push_back (s);
+
+return CanonicalPath (copy, crate_num);
+  }
+
+  // if we have the path A::B::C this will give a callback for each segment
+  // including the prefix, example:
+  //
+  // path:
+  //   A::B::C
+  //
+  // iterate:
+  //   A
+  //   A::B
+  //   A::B::C
+  void iterate (std::function cb) const
+  {
+std::vector> buf;
+for (auto &seg : segs)
+  {
+   buf.push_back (seg);
+   if (!cb (CanonicalPath (buf, crate_num)))
+ return;
+  }
+  }
+
+  // if we have the path A::B::C this will give a callback for each segment
+  // example:
+  //
+  // path:
+  //   A::B::C
+  //
+  // iterate:
+  //   A
+  //  B
+  // C
+  void iterate_segs (std::function cb) const
+  {
+for (auto &seg : segs)
+  {
+   std::vector> buf;
+   buf.push_back ({seg.first, seg.second});
+   if (!cb (CanonicalPath (buf, crate_num)))

[PATCH Rust front-end v2 23/37] gccrs: Add unsafe checks for Rust

2022-08-24 Thread herron . philip
From: Arthur Cohen 

The UnsafeChecker visitor verifies that unsafe actions are only performed
in unsafe contexts. Otherwise, an error should be reported to the user and
the compilation pipeline should be halted. These contexts, which include
unsafe blocks or unsafe functions, are allowed to perform more actions
than regular safe Rust code. These actions currently include:

- Dereferencing raw pointers
- Calls to unsafe functions
- Use of inline assembly
- Use of mutable static
- Use of extern static
- Access to a union's field
- Call to functions with #[target(feature)] attribute
- Initializing type with rustc_layout_scalar_valid_range attribute
- Mutation of layout constrained field
- Borrow of layout constrained field
---
 gcc/rust/checks/errors/rust-unsafe-checker.cc | 963 ++
 gcc/rust/checks/errors/rust-unsafe-checker.h  | 191 
 2 files changed, 1154 insertions(+)
 create mode 100644 gcc/rust/checks/errors/rust-unsafe-checker.cc
 create mode 100644 gcc/rust/checks/errors/rust-unsafe-checker.h

diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
new file mode 100644
index 000..e3f32539562
--- /dev/null
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -0,0 +1,963 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-unsafe-checker.h"
+#include "rust-hir.h"
+#include "rust-hir-expr.h"
+#include "rust-hir-stmt.h"
+#include "rust-hir-item.h"
+
+namespace Rust {
+namespace HIR {
+
+UnsafeChecker::UnsafeChecker ()
+  : context (*Resolver::TypeCheckContext::get ()),
+resolver (*Resolver::Resolver::get ()),
+mappings (*Analysis::Mappings::get ())
+{}
+
+void
+UnsafeChecker::go (HIR::Crate &crate)
+{
+  for (auto &item : crate.items)
+item->accept_vis (*this);
+}
+
+static void
+check_static_mut (HIR::Item *maybe_static, Location locus)
+{
+  if (maybe_static->get_hir_kind () == Node::BaseKind::VIS_ITEM)
+{
+  auto item = static_cast (maybe_static);
+  if (item->get_item_kind () == Item::ItemKind::Static)
+   {
+ auto static_item = static_cast (item);
+ if (static_item->is_mut ())
+   rust_error_at (
+ locus, "use of mutable static requires unsafe function or block");
+   }
+}
+}
+
+static void
+check_extern_static (HIR::ExternalItem *maybe_static, Location locus)
+{
+  if (maybe_static->get_extern_kind () == ExternalItem::ExternKind::Static)
+rust_error_at (locus,
+  "use of extern static requires unsafe function or block");
+}
+
+void
+UnsafeChecker::check_use_of_static (HirId node_id, Location locus)
+{
+  if (unsafe_context.is_in_context ())
+return;
+
+  auto maybe_static_mut = mappings.lookup_hir_item (node_id);
+
+  HirId extern_block;
+  auto maybe_extern_static
+= mappings.lookup_hir_extern_item (node_id, &extern_block);
+
+  if (maybe_static_mut)
+check_static_mut (maybe_static_mut, locus);
+
+  if (maybe_extern_static)
+check_extern_static (static_cast (maybe_extern_static),
+locus);
+}
+
+static void
+check_unsafe_call (HIR::Function *fn, Location locus, const std::string &kind)
+{
+  if (fn->get_qualifiers ().is_unsafe ())
+rust_error_at (locus, "call to unsafe %s requires unsafe function or 
block",
+  kind.c_str ());
+}
+
+static bool
+is_safe_intrinsic (const std::string &fn_name)
+{
+  static const std::unordered_set safe_intrinsics = {
+"abort",
+"size_of",
+"min_align_of",
+"needs_drop",
+"caller_location",
+"add_with_overflow",
+"sub_with_overflow",
+"mul_with_overflow",
+"wrapping_add",
+"wrapping_sub",
+"wrapping_mul",
+"saturating_add",
+"saturating_sub",
+"rotate_left",
+"rotate_right",
+"ctpop",
+"ctlz",
+"cttz",
+"bswap",
+"bitreverse",
+"discriminant_value",
+"type_id",
+"likely",
+"unlikely",
+"ptr_guaranteed_eq",
+"ptr_guaranteed_ne",
+"minnumf32",
+"minnumf64",
+"maxnumf32",
+"rustc_peek",
+"maxnumf64",
+"type_name",
+"forget",
+"black_box",
+"variant_count",
+  };
+
+  return safe_intrinsics.find (fn_name) != safe_intrinsics.end ();
+}
+
+static void
+check_extern_call (HIR::ExternalItem *maybe_fn, HIR::ExternBlock *paren

[PATCH Rust front-end v2 36/37] gccrs: compiler proper interface kicks off the pipeline

2022-08-24 Thread herron . philip
From: Philip Herron 

This is a wrapper to get out of C land in the rust-lang.cc and into our
class hierarchy for the rust front-end. We expect that the front-end only
support one source file input as the expansion pass will attempt to resolve
that relative pass and parse accordingly.

The main missing piece here is that we are using saw_errors() to return
early which is unnecessary but as our error handling has been improving
over time we will start to take advantage of error node in our type system
as well as error_mark_node from GCC. The caveat being that our lints/checks
expect no errors and will throw an assertion.
---
 gcc/rust/rust-lang.cc|  452 
 gcc/rust/rust-session-manager.cc | 1189 ++
 gcc/rust/rust-session-manager.h  |  358 +
 3 files changed, 1999 insertions(+)
 create mode 100644 gcc/rust/rust-lang.cc
 create mode 100644 gcc/rust/rust-session-manager.cc
 create mode 100644 gcc/rust/rust-session-manager.h

diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
new file mode 100644
index 000..c9af790f66b
--- /dev/null
+++ b/gcc/rust/rust-lang.cc
@@ -0,0 +1,452 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-diagnostics.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "diagnostic.h"
+#include "opts.h"
+#include "fold-const.h"
+#include "gimplify.h"
+#include "stor-layout.h"
+#include "debug.h"
+#include "convert.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+
+#include "selftest.h"
+#include "rust-cfg-parser.h"
+#include "rust-privacy-ctx.h"
+#include "rust-ast-resolve-item.h"
+#include "rust-optional.h"
+
+#include 
+// note: header files must be in this order or else forward declarations don't
+// work properly. Kinda dumb system, but have to live with it. clang-format
+// seems to mess it up
+/* Order: config, system, coretypes, target, tree, gimple-expr, diagnostic,
+ * opts, fold-const, gimplify, stor-layout, debug, convert, langhooks,
+ * langhooks-def */
+
+// FIXME: test saving intellisense
+#include "options.h"
+
+// version check to stop compiling if c++ isn't c++11 or higher
+#if __cplusplus < 201103
+#error 
\
+  "GCC Rust frontend requires C++11 or higher. You can compile the g++ 
frontend first and then compile the Rust frontend using that."
+#endif
+// TODO: is this best way to do it? Is it allowed? (should be)
+
+/* General TODOs:
+ *  - convert all copies of expensive-to-copy (deep copy) AST objects into
+ * moves, if possible. Don't remove clone functionality - it may be required 
for
+ * e.g. HIR conversion.
+ */
+
+#include "rust-system.h"
+#include "rust-session-manager.h"
+
+// Language-dependent contents of a type. GTY() mark used for garbage 
collector.
+struct GTY (()) lang_type
+{
+};
+
+// Language-dependent contents of a decl.
+struct GTY (()) lang_decl
+{
+};
+
+// Language-dependent contents of an identifier.  This must include a
+// tree_identifier.
+struct GTY (()) lang_identifier
+{
+  struct tree_identifier common;
+};
+
+// The resulting tree type.
+union GTY ((
+  desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
+  chain_next (
+"CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
+"TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : 
NULL")))
+  lang_tree_node
+{
+  union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) 
generic;
+  struct lang_identifier GTY ((tag ("1"))) identifier;
+};
+
+// We don't use language_function.
+struct GTY (()) language_function
+{
+};
+
+// has to be in same compilation unit as session, so here for now
+void
+rust_add_target_info (const char *key, const char *value)
+{
+  sorry ("TODO");
+
+  Rust::Session::get_instance ().options.target_data.insert_key_value_pair (
+key, value);
+}
+
+/* Language hooks.  */
+
+/* Initial lang hook called (possibly), used for initialisation.
+ * Must call build_common_tree_nodes, set_sizetype, build_common_tree_nodes_2,
+ * and build_common_builtin_nodes, as well as set global variable
+ * void_list_node. Apparently called after option handling? */
+static bool
+grs_langhook_init (void)
+{
+  /* Something to do with

[PATCH Rust front-end v2 17/37] gccrs: Add Rust ABI enum helpers

2022-08-24 Thread herron . philip
From: Philip Herron 

This is a simple helper over an enum of possible ABI options in Rust.
---
 gcc/rust/util/rust-abi.cc | 72 +++
 gcc/rust/util/rust-abi.h  | 45 
 2 files changed, 117 insertions(+)
 create mode 100644 gcc/rust/util/rust-abi.cc
 create mode 100644 gcc/rust/util/rust-abi.h

diff --git a/gcc/rust/util/rust-abi.cc b/gcc/rust/util/rust-abi.cc
new file mode 100644
index 000..6477c3790af
--- /dev/null
+++ b/gcc/rust/util/rust-abi.cc
@@ -0,0 +1,72 @@
+// 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
+// .
+
+#include "rust-abi.h"
+
+namespace Rust {
+
+Rust::ABI
+get_abi_from_string (const std::string &abi)
+{
+  if (abi.compare ("rust") == 0)
+return Rust::ABI::RUST;
+  else if (abi.compare ("rust-intrinsic") == 0)
+return Rust::ABI::INTRINSIC;
+  else if (abi.compare ("C") == 0)
+return Rust::ABI::C;
+  else if (abi.compare ("cdecl") == 0)
+return Rust::ABI::CDECL;
+  else if (abi.compare ("stdcall") == 0)
+return Rust::ABI::STDCALL;
+  else if (abi.compare ("fastcall") == 0)
+return Rust::ABI::FASTCALL;
+  else if (abi.compare ("sysv64") == 0)
+return Rust::ABI::SYSV64;
+  else if (abi.compare ("win64") == 0)
+return Rust::ABI::WIN64;
+
+  return Rust::ABI::UNKNOWN;
+}
+
+std::string
+get_string_from_abi (Rust::ABI abi)
+{
+  switch (abi)
+{
+case Rust::ABI::RUST:
+  return "rust";
+case Rust::ABI::INTRINSIC:
+  return "rust-intrinsic";
+case Rust::ABI::C:
+  return "C";
+case Rust::ABI::CDECL:
+  return "cdecl";
+case Rust::ABI::STDCALL:
+  return "stdcall";
+case Rust::ABI::FASTCALL:
+  return "fastcall";
+case Rust::ABI::SYSV64:
+  return "sysv64";
+case Rust::ABI::WIN64:
+  return "win64";
+
+case Rust::ABI::UNKNOWN:
+  return "unknown";
+}
+  return "unknown";
+}
+
+} // namespace Rust
diff --git a/gcc/rust/util/rust-abi.h b/gcc/rust/util/rust-abi.h
new file mode 100644
index 000..d794cc35fb3
--- /dev/null
+++ b/gcc/rust/util/rust-abi.h
@@ -0,0 +1,45 @@
+// 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 RUST_ABI_OPTIONS_H
+#define RUST_ABI_OPTIONS_H
+
+#include "rust-system.h"
+
+namespace Rust {
+
+enum ABI
+{
+  UNKNOWN,
+  RUST,
+  INTRINSIC,
+  C,
+  CDECL,
+  STDCALL,
+  FASTCALL,
+  WIN64,
+  SYSV64
+};
+
+extern Rust::ABI
+get_abi_from_string (const std::string &abi);
+
+extern std::string
+get_string_from_abi (Rust::ABI abi);
+
+} // namespace Rust
+
+#endif // RUST_ABI_OPTIONS_H
-- 
2.25.1



[PATCH Rust front-end v2 15/37] gccrs: Add wrapper for make_unique

2022-08-24 Thread herron . philip
From: Philip Herron 

This is a wrapper for make_unique we can likely get rid of this as there
are other implementations available or simply keep using the unique_ptr
constructor.
---
 gcc/rust/util/rust-make-unique.h | 35 
 1 file changed, 35 insertions(+)
 create mode 100644 gcc/rust/util/rust-make-unique.h

diff --git a/gcc/rust/util/rust-make-unique.h b/gcc/rust/util/rust-make-unique.h
new file mode 100644
index 000..f33f9125f89
--- /dev/null
+++ b/gcc/rust/util/rust-make-unique.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_MAKE_UNIQUE_H
+#define RUST_MAKE_UNIQUE_H
+
+#include 
+
+namespace Rust {
+
+template 
+std::unique_ptr
+make_unique (Ts &&... params)
+{
+  return std::unique_ptr (new T (std::forward (params)...));
+}
+
+} // namespace Rust
+
+#endif // RUST_MAKE_UNIQUE_H
-- 
2.25.1



[PATCH Rust front-end v2 34/37] gccrs: add lang.opt

2022-08-24 Thread herron . philip
From: Philip Herron 

We have some rust specific langugage options note -fwrapv is enabled by
default in the code. We are trying to respect options such as
-Wunused-result which we get by porting over c++ no-discard for rust's
must-use attribute, so we have enabled these by default directly here.
---
 gcc/rust/lang.opt | 118 ++
 1 file changed, 118 insertions(+)
 create mode 100644 gcc/rust/lang.opt

diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
new file mode 100644
index 000..1f6855ede1d
--- /dev/null
+++ b/gcc/rust/lang.opt
@@ -0,0 +1,118 @@
+; Options for the Rust front end.
+; Copyright (C) 2003-2022 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+; 
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+; 
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; .
+
+; See the GCC internals manual for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+; Describes command-line options used by this frontend
+
+Language
+Rust
+
+I
+Rust Joined Separate
+; Documented in c.opt
+
+L
+Rust Joined Separate
+; Not documented
+
+Wall
+Rust
+; Documented in c.opt
+
+Wunused-variable
+Rust Var(warn_unused_variable) Init(1) Warning
+; documented in common.opt
+
+Wunused-const-variable
+Rust Warning Alias(Wunused-const-variable=, 2, 0)
+Warn when a const variable is unused.
+
+Wunused-const-variable=
+Rust Joined RejectNegative UInteger Var(warn_unused_const_variable) Init(1) 
Warning LangEnabledBy(Rust,Wunused-variable, 1, 0) IntegerRange(0, 2)
+Warn when a const variable is unused.
+
+Wunused-result
+Rust Var(warn_unused_result) Init(1) Warning
+Warn if a caller of a function, marked with attribute warn_unused_result, does 
not use its return value.
+
+frust-crate=
+Rust Joined RejectNegative
+-frust-crate= Set the crate name for the compilation
+
+frust-debug
+Rust Var(flag_rust_debug)
+Dump various Rust front end internals.
+
+frust-dump-
+Rust Joined RejectNegative
+-frust-dump- Dump Rust frontend internal information.
+
+frust-max-recursion-depth=
+Rust RejectNegative Type(int) Var(rust_max_recursion_depth) Init(64)
+-frust-max-recursion-depth=integer
+
+frust-mangling=
+Rust Joined RejectNegative Enum(frust_mangling) Var(flag_rust_mangling)
+-frust-mangling=[legacy|v0] Choose which version to use for name mangling
+
+Enum
+Name(frust_mangling) Type(int) UnknownError(unknown rust mangling option %qs)
+
+EnumValue
+Enum(frust_mangling) String(legacy) Value(0)
+
+EnumValue
+Enum(frust_mangling) String(v0) Value(1)
+
+frust-cfg=
+Rust Joined RejectNegative
+-frust-cfg= Set a config expansion option
+
+frust-edition=
+Rust Joined RejectNegative Enum(frust_edition) Var(flag_rust_edition)
+-frust-edition=[2015|2018|2021] Choose which edition to use when 
compiling rust code
+
+Enum
+Name(frust_edition) Type(int) UnknownError(unknown rust edition %qs)
+
+EnumValue
+Enum(frust_edition) String(2015) Value(0)
+
+EnumValue
+Enum(frust_edition) String(2018) Value(1)
+
+EnumValue
+Enum(frust_edition) String(2021) Value(2)
+
+frust-embed-metadata
+Rust Var(flag_rust_embed_metadata)
+Flag to enable embeding metadata directly into object files
+
+frust-metadata-output=
+Rust Joined RejectNegative
+-frust-metadata-output=  Path to output crate metadata
+
+o
+Rust Joined Separate
+; Documented in common.opt
+
+; This comment is to ensure we retain the blank line above.
-- 
2.25.1



[PATCH Rust front-end v2 20/37] gccrs: Add attributes checker

2022-08-24 Thread herron . philip
From: Arthur Cohen 

The attribute checker is responsible for checking the validity of various
attributes including built-in ones. It is currently unfinished and will
receive some modifications, as well as become the host of some existing
code in the compiler which needs to be refactored. One of its
responsibilities is to make sure that arguments given to built-in
attributes are correct, or contain the correct type of information. This
visitor also checks that an attribute is allowed to be used in the current
particular context.
---
 gcc/rust/util/rust-attributes.cc | 839 +++
 gcc/rust/util/rust-attributes.h  | 270 ++
 2 files changed, 1109 insertions(+)
 create mode 100644 gcc/rust/util/rust-attributes.cc
 create mode 100644 gcc/rust/util/rust-attributes.h

diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
new file mode 100644
index 000..bf4bb2fbfe9
--- /dev/null
+++ b/gcc/rust/util/rust-attributes.cc
@@ -0,0 +1,839 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-attributes.h"
+#include "rust-ast.h"
+#include "rust-ast-full.h"
+#include "rust-diagnostics.h"
+#include "safe-ctype.h"
+
+namespace Rust {
+namespace Analysis {
+
+// 
https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
+static const BuiltinAttrDefinition __definitions[] = {
+  {"inline", CODE_GENERATION},
+  {"cold", CODE_GENERATION},
+  {"cfg", EXPANSION},
+  {"cfg_attr", EXPANSION},
+  {"deprecated", STATIC_ANALYSIS},
+  {"allow", STATIC_ANALYSIS},
+  {"doc", HIR_LOWERING},
+  {"must_use", STATIC_ANALYSIS},
+  {"lang", HIR_LOWERING},
+  {"link_section", CODE_GENERATION},
+  {"no_mangle", CODE_GENERATION},
+  {"repr", CODE_GENERATION},
+  {"path", EXPANSION},
+};
+
+BuiltinAttributeMappings *
+BuiltinAttributeMappings::get ()
+{
+  static BuiltinAttributeMappings *instance = nullptr;
+  if (instance == nullptr)
+instance = new BuiltinAttributeMappings ();
+
+  return instance;
+}
+
+const BuiltinAttrDefinition &
+BuiltinAttributeMappings::lookup_builtin (const std::string &attr_name) const
+{
+  auto it = mappings.find (attr_name);
+  if (it == mappings.end ())
+return BuiltinAttrDefinition::error_node ();
+
+  return it->second;
+}
+
+BuiltinAttributeMappings::BuiltinAttributeMappings ()
+{
+  size_t ndefinitions = sizeof (__definitions) / sizeof 
(BuiltinAttrDefinition);
+  for (size_t i = 0; i < ndefinitions; i++)
+{
+  const BuiltinAttrDefinition &def = __definitions[i];
+  mappings.insert ({def.name, def});
+}
+}
+
+AttributeChecker::AttributeChecker () {}
+
+void
+AttributeChecker::go (AST::Crate &crate)
+{
+  check_attributes (crate.get_inner_attrs ());
+
+  for (auto &item : crate.items)
+item->accept_vis (*this);
+}
+
+static bool
+is_builtin (const AST::Attribute &attribute, BuiltinAttrDefinition &builtin)
+{
+  auto &segments = attribute.get_path ().get_segments ();
+
+  // Builtin attributes always have a single segment. This avoids us creating
+  // strings all over the place and performing a linear search in the builtins
+  // map
+  if (segments.size () != 1)
+return false;
+
+  builtin = BuiltinAttributeMappings::get ()->lookup_builtin (
+segments.at (0).get_segment_name ());
+
+  return !builtin.is_error ();
+}
+
+/**
+ * Check that the string given to #[doc(alias = ...)] or #[doc(alias(...))] is
+ * valid.
+ *
+ * This means no whitespace characters other than spaces and no quoting
+ * characters.
+ */
+static void
+check_doc_alias (const std::string &alias_input, const Location &locus)
+{
+  // FIXME: The locus here is for the whole attribute. Can we get the locus
+  // of the alias input instead?
+  for (auto c : alias_input)
+if ((ISSPACE (c) && c != ' ') || c == '\'' || c == '\"')
+  {
+   auto to_print = std::string (1, c);
+   switch (c)
+ {
+ case '\n':
+   to_print = "\\n";
+   break;
+ case '\t':
+   to_print = "\\t";
+   break;
+ default:
+   break;
+ }
+   rust_error_at (locus,
+  "invalid character used in %<#[doc(alias)]%> input: %qs",
+  to_print.c_str ());
+  }
+
+  if (alias_input.empty ())
+return;
+
+  if (alias_input.front 

[PATCH Rust front-end v2 19/37] gccrs: Add implementation of Optional

2022-08-24 Thread herron . philip
From: Arthur Cohen 

Add an Optional class to improve error handling
---
 gcc/rust/util/rust-optional-test.cc | 111 +++
 gcc/rust/util/rust-optional.h   | 278 
 2 files changed, 389 insertions(+)
 create mode 100644 gcc/rust/util/rust-optional-test.cc
 create mode 100644 gcc/rust/util/rust-optional.h

diff --git a/gcc/rust/util/rust-optional-test.cc 
b/gcc/rust/util/rust-optional-test.cc
new file mode 100644
index 000..9d5b4ba5735
--- /dev/null
+++ b/gcc/rust/util/rust-optional-test.cc
@@ -0,0 +1,111 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-optional.h"
+
+#include "config.h"
+#include "selftest.h"
+
+#if CHECKING_P
+
+static void
+rust_optional_create ()
+{
+  auto opt = Rust::Optional::some (15);
+
+  ASSERT_TRUE (opt.is_some ());
+  ASSERT_EQ (opt.get (), 15);
+
+  Rust::Optional const_opt = Rust::Optional::some (15);
+  const int &value = const_opt.get ();
+
+  ASSERT_EQ (value, 15);
+}
+
+static void
+rust_optional_operators ()
+{
+  auto opt = Rust::Optional::some (15);
+
+  // as bool
+  ASSERT_TRUE (opt);
+
+  // deref
+  ASSERT_EQ (*opt, 15);
+
+  class Methodable
+  {
+  public:
+int method () { return 15; }
+  };
+
+  auto m_opt = Rust::Optional::some (Methodable ());
+  ASSERT_EQ (m_opt->method (), 15);
+}
+
+static void
+rust_optional_take ()
+{
+  auto opt = Rust::Optional::some (15);
+  auto value = opt.take ();
+
+  ASSERT_EQ (value, 15);
+  ASSERT_TRUE (opt.is_none ());
+}
+
+static void
+rust_optional_map ()
+{
+  auto opt = Rust::Optional::some (15);
+  auto twice = opt.map ([] (int value) { return value * 2; });
+
+  ASSERT_FALSE (opt);
+  ASSERT_TRUE (twice);
+  ASSERT_EQ (*twice, 30);
+}
+
+static void
+rust_optional_reference ()
+{
+  auto value = std::vector ();
+  value.emplace_back ("rust");
+  value.emplace_back ("+");
+  value.emplace_back ("gcc");
+  value.emplace_back ("=");
+  value.emplace_back ("<3");
+
+  auto opt = Rust::Optional &>::some (value);
+
+  ASSERT_EQ (opt->at (0), "rust");
+  ASSERT_EQ (opt->at (2), "gcc");
+}
+
+#endif /* #if CHECKING_P */
+
+void
+rust_optional_test ()
+{
+#if CHECKING_P
+  rust_optional_create ();
+  rust_optional_operators ();
+  rust_optional_take ();
+  rust_optional_map ();
+  rust_optional_reference ();
+
+#endif /* #if CHECKING_P */
+}
diff --git a/gcc/rust/util/rust-optional.h b/gcc/rust/util/rust-optional.h
new file mode 100644
index 000..56465400250
--- /dev/null
+++ b/gcc/rust/util/rust-optional.h
@@ -0,0 +1,278 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_OPTIONAL_H
+#define RUST_OPTIONAL_H
+
+#include "config.h"
+#include "rust-system.h"
+
+#include "selftest.h"
+
+namespace Rust {
+
+/**
+ * Tagged union to try and simulate a sum type. This is safer and more 
ergonomic
+ * than one of the two alternatives we're currently using in the compiler:
+ *
+ * 1. Storing a raw pointer, which can be `nullptr` or valid
+ *
+ * This is wildly unsafe, and usable in conjunction with local references, 
stack
+ * variables, or pointers managed elsewhere, which can cause crashes, hard to
+ * debug issues or undefined behavior. Likewise, if you do not check for the
+ * pointer's validity, this will cause a crash.
+ *
+ * 2. Storing an extra boolean alongside the object
+ *
+ * This causes implementors to use a "dummy object": Either an empty version or
+ * an error version. But what happens if what you really wanted to store was
+ * the empty or error version? You can also easily incorporate logic bugs if 
you
+ * forget to check for the associated boolean.
+ *
+ * The `Optional` type has the same "

[PATCH Rust front-end v2 18/37] gccrs: Add Base62 implementation

2022-08-24 Thread herron . philip
From: Arthur Cohen 

Used for V0 symbol mangling scheme which.
---
 gcc/rust/util/rust-base62.cc | 46 
 gcc/rust/util/rust-base62.h  | 34 ++
 2 files changed, 80 insertions(+)
 create mode 100644 gcc/rust/util/rust-base62.cc
 create mode 100644 gcc/rust/util/rust-base62.h

diff --git a/gcc/rust/util/rust-base62.cc b/gcc/rust/util/rust-base62.cc
new file mode 100644
index 000..bdab23338c3
--- /dev/null
+++ b/gcc/rust/util/rust-base62.cc
@@ -0,0 +1,46 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-base62.h"
+
+namespace Rust {
+
+std::string
+base62_integer (uint64_t value)
+{
+  const static std::string base_64
+= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@$";
+  std::string buffer (128, '\0');
+  size_t idx = 0;
+  size_t base = 62;
+
+  do
+{
+  buffer[idx] = base_64[(value % base)];
+  idx++;
+  value = value / base;
+}
+  while (value != 0);
+
+  std::reverse (buffer.begin (), buffer.begin () + idx);
+  return buffer.substr (0, idx);
+}
+
+} // namespace Rust
+
+// FIXME: Add unit testing using the selftest framework
diff --git a/gcc/rust/util/rust-base62.h b/gcc/rust/util/rust-base62.h
new file mode 100644
index 000..fa610d3e5a4
--- /dev/null
+++ b/gcc/rust/util/rust-base62.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_BASE62_H
+#define RUST_BASE62_H
+
+#include "rust-system.h"
+
+namespace Rust {
+
+/**
+ * Get the Base62 representation of an integer
+ */
+std::string
+base62_integer (uint64_t value);
+
+} // namespace Rust
+
+#endif /* !RUST_BASE62_H */
-- 
2.25.1



[PATCH Rust front-end v2 25/37] gccrs: Add privacy checks

2022-08-24 Thread herron . philip
From: Arthur Cohen 

This pass is responsible for resolving the privacy of items and verifying
that access to these items is performed within the limits of that privacy.
By default, items in Rust are private and only public to the current
module and its submodules. However, the user can annotate an item with
various qualifiers such as `pub` to publicly expose an item. Furthermore,
a module path can be given to `pub` to restrict an item's privacy to a
certain module: These paths need to be resolved and later on checked by
the privacy error reporter.
---
 .../errors/privacy/rust-privacy-check.cc  |  63 ++
 .../errors/privacy/rust-privacy-check.h   |  44 +
 .../errors/privacy/rust-privacy-common.h  |  67 ++
 .../checks/errors/privacy/rust-privacy-ctx.cc |  93 +++
 .../checks/errors/privacy/rust-privacy-ctx.h  |  79 ++
 .../errors/privacy/rust-privacy-reporter.cc   | 753 ++
 .../errors/privacy/rust-privacy-reporter.h| 173 
 .../privacy/rust-pub-restricted-visitor.cc| 182 +
 .../privacy/rust-pub-restricted-visitor.h | 120 +++
 .../errors/privacy/rust-reachability.cc   | 236 ++
 .../checks/errors/privacy/rust-reachability.h |  87 ++
 .../privacy/rust-visibility-resolver.cc   | 245 ++
 .../errors/privacy/rust-visibility-resolver.h | 103 +++
 13 files changed, 2245 insertions(+)
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-check.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-check.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-common.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-ctx.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-ctx.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
 create mode 100644 
gcc/rust/checks/errors/privacy/rust-pub-restricted-visitor.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-pub-restricted-visitor.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-reachability.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-reachability.h
 create mode 100644 gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
 create mode 100644 gcc/rust/checks/errors/privacy/rust-visibility-resolver.h

diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
new file mode 100644
index 000..9664d62f65c
--- /dev/null
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-privacy-check.h"
+#include "rust-reachability.h"
+#include "rust-hir-type-check.h"
+#include "rust-hir-map.h"
+#include "rust-name-resolver.h"
+#include "rust-visibility-resolver.h"
+#include "rust-pub-restricted-visitor.h"
+#include "rust-privacy-reporter.h"
+
+extern bool
+saw_errors (void);
+
+namespace Rust {
+namespace Privacy {
+
+void
+Resolver::resolve (HIR::Crate &crate)
+{
+  PrivacyContext ctx;
+  auto mappings = Analysis::Mappings::get ();
+  auto resolver = Rust::Resolver::Resolver::get ();
+  auto ty_ctx = ::Rust::Resolver::TypeCheckContext::get ();
+
+  VisibilityResolver (*mappings, *resolver).go (crate);
+  PubRestrictedVisitor (*mappings).go (crate);
+  PrivacyReporter (*mappings, *resolver, *ty_ctx).go (crate);
+
+  auto visitor = ReachabilityVisitor (ctx, *ty_ctx);
+
+  const auto &items = crate.items;
+
+  for (auto &item : items)
+{
+  if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
+   {
+ auto vis_item = static_cast (item.get ());
+ vis_item->accept_vis (visitor);
+   }
+}
+
+  if (saw_errors ())
+return;
+}
+} // namespace Privacy
+} // namespace Rust
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-check.h 
b/gcc/rust/checks/errors/privacy/rust-privacy-check.h
new file mode 100644
index 000..290b5eacb6c
--- /dev/null
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-check.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundat

[PATCH Rust front-end v2 16/37] gccrs: Add port of FNV hash used during legacy symbol mangling

2022-08-24 Thread herron . philip
From: Philip Herron 

This hash was ported from the go runime as we needed a hash for the legacy
symbol mangling system. Which means all symbols in Rust contain a hash of
some metadata for uniqueness on generic functions.
---
 gcc/rust/util/fnv-hash.h | 95 
 1 file changed, 95 insertions(+)
 create mode 100644 gcc/rust/util/fnv-hash.h

diff --git a/gcc/rust/util/fnv-hash.h b/gcc/rust/util/fnv-hash.h
new file mode 100644
index 000..78e54c99411
--- /dev/null
+++ b/gcc/rust/util/fnv-hash.h
@@ -0,0 +1,95 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_FNV_HASH_H
+#define RUST_FNV_HASH_H
+
+namespace Rust {
+namespace Hash {
+
+const uint64_t offset128Lower = 0x62b821756295c58d;
+const uint64_t offset128Higher = 0x6c62272e07bb0142;
+const uint64_t prime128Lower = 0x13b;
+const uint64_t prime128Shift = 24;
+
+// ported from https://github.com/golang/go/blob/master/src/hash/fnv/fnv.go
+class FNV128
+{
+public:
+  FNV128 () { reset (); }
+
+  void reset ()
+  {
+buf[0] = offset128Higher;
+buf[1] = offset128Lower;
+  }
+
+  void write (const unsigned char *in, size_t len)
+  {
+for (size_t i = 0; i < len; i++)
+  {
+   unsigned char c = in[i];
+
+   // 
https://stackoverflow.com/questions/28868367/getting-the-high-part-of-64-bit-integer-multiplication
+   uint64_t a = prime128Lower;
+   uint64_t b = buf[1];
+
+   uint64_t a_lo = (uint32_t) a;
+   uint64_t a_hi = a >> 32;
+   uint64_t b_lo = (uint32_t) b;
+   uint64_t b_hi = b >> 32;
+
+   uint64_t a_x_b_hi = a_hi * b_hi;
+   uint64_t a_x_b_mid = a_hi * b_lo;
+   uint64_t b_x_a_mid = b_hi * a_lo;
+   uint64_t a_x_b_lo = a_lo * b_lo;
+
+   uint64_t carry_bit
+ = ((uint64_t) (uint32_t) a_x_b_mid + (uint64_t) (uint32_t) b_x_a_mid
++ (a_x_b_lo >> 32))
+   >> 32;
+
+   uint64_t multhi
+ = a_x_b_hi + (a_x_b_mid >> 32) + (b_x_a_mid >> 32) + carry_bit;
+
+   uint64_t s0 = multhi; // high
+   uint64_t s1 = prime128Lower * buf[1]; // low
+
+   s0 += buf[1] << (prime128Shift + prime128Lower * buf[0]);
+
+   // Update the values
+   buf[1] = s1;
+   buf[0] = s0;
+   buf[1] ^= (uint64_t) c;
+  }
+  }
+
+  void sum (uint64_t *hi, uint64_t *lo) const
+  {
+*hi = buf[0];
+*lo = buf[1];
+  }
+
+private:
+  uint64_t buf[2];
+};
+
+} // namespace Hash
+} // namespace Rust
+
+#endif // RUST_FNV_HASH_H
-- 
2.25.1



[PATCH Rust front-end v2 07/37] gccrs: Add gcc-check-target check-rust

2022-08-24 Thread herron . philip
From: Philip Herron 

This allows us to invoke the rust testsuite.

ChangeLog:
* Makefile.def: Add autogen target
* Makefile.in: regenerate via autogen
---
 Makefile.def | 1 +
 Makefile.in  | 8 
 2 files changed, 9 insertions(+)

diff --git a/Makefile.def b/Makefile.def
index 3291b126b26..821016af3a2 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -681,6 +681,7 @@ languages = { language=go;  gcc-check-target=check-go;
 languages = { language=d;  gcc-check-target=check-d;
lib-check-target=check-target-libphobos; };
 languages = { language=jit;gcc-check-target=check-jit; };
+languages = { language=rust;   gcc-check-target=check-rust; };
 
 // Toplevel bootstrap
 bootstrap_stage = { id=1 ; };
diff --git a/Makefile.in b/Makefile.in
index 1919dfee829..9ed2c0dec52 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -60583,6 +60583,14 @@ check-gcc-jit:
(cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-jit);
 check-jit: check-gcc-jit
 
+.PHONY: check-gcc-rust check-rust
+check-gcc-rust:
+   r=`${PWD_COMMAND}`; export r; \
+   s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+   $(HOST_EXPORTS) \
+   (cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-rust);
+check-rust: check-gcc-rust
+
 
 # The gcc part of install-no-fixedincludes, which relies on an intimate
 # knowledge of how a number of gcc internal targets (inter)operate.  Delegate.
-- 
2.25.1



[PATCH Rust front-end v2 04/37] gccrs: Add link cases testsuite

2022-08-24 Thread herron . philip
From: Philip Herron 

This testsuite is heavily inspired from the lto testsuite which uses a
pattern that each file is compiled to an object file and finally linked
together. Since rust does not have headers/prototypes we rely on the
ordering here so that all files numbered greater than zero get compiled to
object files first leaving the _0 file free to test the 'extern crate' and
use keywords to force testing of the compiler to read metadata from the
other 'crates'.
---
 gcc/testsuite/rust/link/generic_function_0.rs |   7 +
 gcc/testsuite/rust/link/generic_function_1.rs |   3 +
 gcc/testsuite/rust/link/link.exp  | 172 ++
 gcc/testsuite/rust/link/simple_function_0.rs  |   8 +
 gcc/testsuite/rust/link/simple_function_1.rs  |   3 +
 gcc/testsuite/rust/link/trait_import_0.rs |  19 ++
 gcc/testsuite/rust/link/trait_import_1.rs |   6 +
 7 files changed, 218 insertions(+)
 create mode 100644 gcc/testsuite/rust/link/generic_function_0.rs
 create mode 100644 gcc/testsuite/rust/link/generic_function_1.rs
 create mode 100644 gcc/testsuite/rust/link/link.exp
 create mode 100644 gcc/testsuite/rust/link/simple_function_0.rs
 create mode 100644 gcc/testsuite/rust/link/simple_function_1.rs
 create mode 100644 gcc/testsuite/rust/link/trait_import_0.rs
 create mode 100644 gcc/testsuite/rust/link/trait_import_1.rs

diff --git a/gcc/testsuite/rust/link/generic_function_0.rs 
b/gcc/testsuite/rust/link/generic_function_0.rs
new file mode 100644
index 000..58b8eb13db6
--- /dev/null
+++ b/gcc/testsuite/rust/link/generic_function_0.rs
@@ -0,0 +1,7 @@
+extern crate generic_function_1;
+use generic_function_1::generic_function;
+
+fn main() -> i32 {
+let a = generic_function(123);
+a - 123
+}
diff --git a/gcc/testsuite/rust/link/generic_function_1.rs 
b/gcc/testsuite/rust/link/generic_function_1.rs
new file mode 100644
index 000..8fb0788e388
--- /dev/null
+++ b/gcc/testsuite/rust/link/generic_function_1.rs
@@ -0,0 +1,3 @@
+pub fn generic_function(a: X) -> X {
+a
+}
diff --git a/gcc/testsuite/rust/link/link.exp b/gcc/testsuite/rust/link/link.exp
new file mode 100644
index 000..8b2e93ceab6
--- /dev/null
+++ b/gcc/testsuite/rust/link/link.exp
@@ -0,0 +1,172 @@
+# Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program 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
+# .
+
+# Execute tests, torture testing.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "assemble"
+
+# rs-obj -- compile to an object file
+#
+# SOURCE is the source file
+# DEST is the object file
+# OPTALL is the list of compiler options to use with all tests
+# OPTFILE is the list of compiler options to use with this file
+# OPTSTR is the options to print with test messages
+# XFAILDATA is the xfail data to be passed to the compiler
+proc rs-obj { source dest optall optfile optstr xfaildata } {
+global tool
+global compiler_conditional_xfail_data
+
+# Set up the options for compiling this file.
+set options ""
+lappend options "additional_flags=$optall $optfile"
+
+set compiler_conditional_xfail_data $xfaildata
+set comp_output [${tool}_target_compile "$source" "$dest" object $options]
+}
+
+# rs-execute -- compile multi-file tests
+#
+# SRC1 is the full pathname of the main file of the testcase.
+# SID identifies a test suite in the names of temporary files.
+proc rs-execute-1 { src1 } {
+global srcdir tmpdir
+
+# Get extra flags for this test from the primary source file, and
+# process other dg-* options that this suite supports.  Warn about
+# unsupported flags.
+verbose "rs-execute: $src1" 1
+set compile_type "run"
+set compile_xfail(0) "" 
+
+# Set up the names of the other source files.
+set dir [file dirname $src1]
+set base [file rootname $src1]
+set base [string range $base [string length $dir] end]
+regsub "_0" $base "" base
+regsub "/" $base "" base
+set src_list $src1
+set i 1
+set done 0
+while { !$done } {
+   set names [glob -nocomplain -types f -- "${dir}/${base}_${i}.*"]
+   if { [llength ${names}] > 1 } {
+   warning "rs-link-execute: more than one file matched 
${dir}/${base}_${i}.*"
+   }
+   if { [llength ${names}] == 1 } {
+   

[PATCH Rust front-end v2 06/37] gccrs: Add execution test cases

2022-08-24 Thread herron . philip
From: Philip Herron 

This is similar to the compile/torture/*.rs test cases but all of these are
dg-execute testcases so they get compiled, linked and executed by default,
all the while being compiled with the matrix of torture options.

The only caveat here is that currently gccrs does not currently support
the main shim yet so we have a C-style main function here returning zero
which is not supported in Rustc.

Co-authored-by: Arthur Cohen 
Co-authored-by: Thomas Schwinge 
Co-authored-by: Mark Wielaard 
Co-authored-by: Marc Poulhiès 
---
 .../rust/execute/torture/block_expr1.rs   |   8 +
 .../rust/execute/torture/builtin_macro_cfg.rs |  32 
 .../execute/torture/builtin_macro_concat.rs   |  29 +++
 .../rust/execute/torture/builtin_macro_env.rs |  31 
 .../torture/builtin_macro_include_bytes.rs|  46 +
 .../torture/builtin_macro_include_str.rs  |  27 +++
 .../execute/torture/builtin_macro_line.rs |  25 +++
 .../rust/execute/torture/builtin_macros1.rs   |  21 +++
 .../rust/execute/torture/builtin_macros3.rs   |  28 +++
 gcc/testsuite/rust/execute/torture/cfg1.rs|  32 
 gcc/testsuite/rust/execute/torture/cfg2.rs|  31 
 gcc/testsuite/rust/execute/torture/cfg3.rs|  37 
 gcc/testsuite/rust/execute/torture/cfg4.rs|  38 
 gcc/testsuite/rust/execute/torture/cfg5.rs|  13 ++
 .../rust/execute/torture/coercion1.rs |  41 +
 .../rust/execute/torture/coercion2.rs |  39 
 .../rust/execute/torture/const_fold1.rs   |  13 ++
 .../rust/execute/torture/const_fold2.rs   |  16 ++
 .../execute/torture/copy_nonoverlapping1.rs   |  17 ++
 .../rust/execute/torture/empty_main.rs|   3 +
 .../rust/execute/torture/execute.exp  |  33 
 .../rust/execute/torture/exit_error.rs|   5 +
 .../rust/execute/torture/extern_mod4.rs   |  19 ++
 gcc/testsuite/rust/execute/torture/func1.rs   |   5 +
 .../rust/execute/torture/helloworld1.rs   |  15 ++
 .../rust/execute/torture/helloworld2.rs   |  15 ++
 .../rust/execute/torture/include.txt  |   1 +
 gcc/testsuite/rust/execute/torture/index1.rs  |  28 +++
 .../rust/execute/torture/issue-1120.rs| 123 +
 .../rust/execute/torture/issue-1133.rs| 146 +++
 .../rust/execute/torture/issue-1198.rs|  75 
 .../rust/execute/torture/issue-1231.rs|  36 
 .../rust/execute/torture/issue-1232.rs| 159 
 .../rust/execute/torture/issue-1249.rs|  39 
 .../rust/execute/torture/issue-1436.rs| 172 ++
 .../rust/execute/torture/issue-1496.rs|  75 
 .../rust/execute/torture/issue-647.rs |  33 
 .../rust/execute/torture/issue-845.rs |  47 +
 .../rust/execute/torture/issue-851.rs |  35 
 .../rust/execute/torture/issue-858.rs |  32 
 .../rust/execute/torture/issue-976.rs |  14 ++
 .../rust/execute/torture/issue-995.rs |   9 +
 gcc/testsuite/rust/execute/torture/macros1.rs |  13 ++
 .../rust/execute/torture/macros10.rs  |  22 +++
 .../rust/execute/torture/macros11.rs  |  25 +++
 .../rust/execute/torture/macros12.rs  |  22 +++
 .../rust/execute/torture/macros13.rs  |  22 +++
 .../rust/execute/torture/macros14.rs  |  22 +++
 .../rust/execute/torture/macros16.rs  |  14 ++
 .../rust/execute/torture/macros17.rs  |  17 ++
 .../rust/execute/torture/macros18.rs  |  14 ++
 .../rust/execute/torture/macros19.rs  |  14 ++
 gcc/testsuite/rust/execute/torture/macros2.rs |  40 
 .../rust/execute/torture/macros20.rs  |  14 ++
 .../rust/execute/torture/macros21.rs  |  15 ++
 .../rust/execute/torture/macros22.rs  |  27 +++
 .../rust/execute/torture/macros23.rs  |  19 ++
 .../rust/execute/torture/macros24.rs  |   9 +
 .../rust/execute/torture/macros25.rs  |  13 ++
 .../rust/execute/torture/macros26.rs  |  12 ++
 .../rust/execute/torture/macros27.rs  |  24 +++
 .../rust/execute/torture/macros28.rs  |  13 ++
 .../rust/execute/torture/macros29.rs  |  24 +++
 gcc/testsuite/rust/execute/torture/macros3.rs |  61 +++
 .../rust/execute/torture/macros30.rs  |  25 +++
 .../rust/execute/torture/macros31.rs  |  32 
 gcc/testsuite/rust/execute/torture/macros4.rs |  15 ++
 gcc/testsuite/rust/execute/torture/macros5.rs |  13 ++
 gcc/testsuite/rust/execute/torture/macros6.rs |  12 ++
 gcc/testsuite/rust/execute/torture/macros7.rs |  28 +++
 gcc/testsuite/rust/execute/torture/macros8.rs |  27 +++
 gcc/testsuite/rust/execute/torture/macros9.rs |  28 +++
 gcc/testsuite/rust/execute/torture/match1.rs  |  58 ++
 gcc/testsuite/rust/execute/torture/match2.rs  |  41 +
 gcc/testsuite/rust/execute/torture/match3.rs  |  51 ++
 .../rust/execute/torture/match_bool1.rs   |  49 +
 .../rust/execute/torture/match_byte1.rs   |  56 ++
 

[PATCH Rust front-end v2 03/37] gccrs: Add Debug info testsuite

2022-08-24 Thread herron . philip
From: Philip Herron 

This testsuite is specifically about testcases which scan the asm debug
info for results.

Co-authored-by: Tom Tromey 
---
 gcc/testsuite/rust/debug/chartype.rs  | 10 ++
 .../rust/debug/custom_link_section.rs | 13 
 gcc/testsuite/rust/debug/debug.exp| 33 +++
 gcc/testsuite/rust/debug/i8u8.rs  | 12 +++
 gcc/testsuite/rust/debug/lang.rs  |  6 
 gcc/testsuite/rust/debug/no_mangle.rs | 17 ++
 gcc/testsuite/rust/debug/oldlang.rs   |  6 
 gcc/testsuite/rust/debug/tuple.rs |  8 +
 gcc/testsuite/rust/debug/win64-abi.rs | 11 +++
 9 files changed, 116 insertions(+)
 create mode 100644 gcc/testsuite/rust/debug/chartype.rs
 create mode 100644 gcc/testsuite/rust/debug/custom_link_section.rs
 create mode 100644 gcc/testsuite/rust/debug/debug.exp
 create mode 100644 gcc/testsuite/rust/debug/i8u8.rs
 create mode 100644 gcc/testsuite/rust/debug/lang.rs
 create mode 100644 gcc/testsuite/rust/debug/no_mangle.rs
 create mode 100644 gcc/testsuite/rust/debug/oldlang.rs
 create mode 100644 gcc/testsuite/rust/debug/tuple.rs
 create mode 100644 gcc/testsuite/rust/debug/win64-abi.rs

diff --git a/gcc/testsuite/rust/debug/chartype.rs 
b/gcc/testsuite/rust/debug/chartype.rs
new file mode 100644
index 000..69e7ab0b17f
--- /dev/null
+++ b/gcc/testsuite/rust/debug/chartype.rs
@@ -0,0 +1,10 @@
+// 'char' should use DW_ATE_UTF
+fn main () {
+let c = 'x';
+// { dg-do compile }
+// Use -w to avoid warnings about the unused variables
+// DW_ATE_UTF entered in DWARF 4.
+// { dg-options "-w -gdwarf-4 -dA" }
+// DW_ATE_UTF = 0x10
+// { dg-final { scan-assembler "0x10\[ \t]\[^\n\r]* DW_AT_encoding" } } */
+}
diff --git a/gcc/testsuite/rust/debug/custom_link_section.rs 
b/gcc/testsuite/rust/debug/custom_link_section.rs
new file mode 100644
index 000..142f3513136
--- /dev/null
+++ b/gcc/testsuite/rust/debug/custom_link_section.rs
@@ -0,0 +1,13 @@
+#[link_section = ".universe"]
+fn not_in_text() -> i32 {
+42
+}
+
+fn main() -> i32 {
+// { dg-do compile }
+// { dg-options "-gdwarf-5 -dA -w" }
+not_in_text();
+// { dg-final { scan-assembler ".universe" } } */
+
+0
+}
diff --git a/gcc/testsuite/rust/debug/debug.exp 
b/gcc/testsuite/rust/debug/debug.exp
new file mode 100644
index 000..c71b5930d90
--- /dev/null
+++ b/gcc/testsuite/rust/debug/debug.exp
@@ -0,0 +1,33 @@
+# Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program 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
+# .
+
+# Debugging tests.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "compile"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rust/debug/i8u8.rs b/gcc/testsuite/rust/debug/i8u8.rs
new file mode 100644
index 000..1cd21a4a8ff
--- /dev/null
+++ b/gcc/testsuite/rust/debug/i8u8.rs
@@ -0,0 +1,12 @@
+// i8 and u8 types should not have the DWARF 'char' encoding.
+fn main () {
+let x : i8 = 5;
+let y : u8 = 7;
+// { dg-do compile }
+// Use -w to avoid warnings about the unused variables
+// { dg-options "-w -g -dA" }
+// DW_ATE_signed_char = 6
+// { dg-final { scan-assembler-not "0x6\[ \t]\[^\n\r]* DW_AT_encoding" } } */
+// DW_ATE_unsigned_char = 8
+// { dg-final { scan-assembler-not "0x8\[ \t]\[^\n\r]* DW_AT_encoding" } } */
+}
diff --git a/gcc/testsuite/rust/debug/lang.rs b/gcc/testsuite/rust/debug/lang.rs
new file mode 100644
index 000..12e0b587a02
--- /dev/null
+++ b/gcc/testsuite/rust/debug/lang.rs
@@ -0,0 +1,6 @@
+fn main () {
+// { dg-do compile }
+// { dg-options "-gdwarf-5 -dA" }
+// DW_LANG_Rust is 0x1c
+// { dg-final { scan-assembler "0x1c\[ \t]\[^\n\r]* DW_AT_language" } } */
+}
diff --git a/gcc/testsuite/rust/debug/no_mangle.rs 
b/gcc/testsuite/rust/debug/no_mangle.rs
new file mode 100644
index 000..0cef40482f4
--- /dev/null
+++ b/gcc/testsuite/rust/debug/no_mangle.rs
@@ -0,0 +1,17 @@
+#[no_mangle]
+fn do_not_mangle() -> i32 {
+0 
+}
+
+fn please_mangle() {}
+
+fn main() {
+// { dg-do compile }
+// { dg-options "-gdwarf-5 -dA" }
+let _ = do_not_mangle();
+please_mangle();
+// look for 

[PATCH Rust front-end v2 09/37] gccrs: Add Lexer for Rust front-end

2022-08-24 Thread herron . philip
From: The Other 

The lexer is refered to as a ManagedTokenSource within the parser, this
lexer does not currently support unicode but serves as a starting point
to do so.

Co-authored-by: Philip Herron 
Co-authored-by: Arthur Cohen 
Co-authored-by: Mark Wielaard 
---
 gcc/rust/lex/rust-codepoint.h  |   46 +
 gcc/rust/lex/rust-lex.cc   | 2729 
 gcc/rust/lex/rust-lex.h|  271 
 gcc/rust/lex/rust-token.cc |  135 ++
 gcc/rust/lex/rust-token.h  |  455 ++
 gcc/rust/rust-buffered-queue.h |  204 +++
 6 files changed, 3840 insertions(+)
 create mode 100644 gcc/rust/lex/rust-codepoint.h
 create mode 100644 gcc/rust/lex/rust-lex.cc
 create mode 100644 gcc/rust/lex/rust-lex.h
 create mode 100644 gcc/rust/lex/rust-token.cc
 create mode 100644 gcc/rust/lex/rust-token.h
 create mode 100644 gcc/rust/rust-buffered-queue.h

diff --git a/gcc/rust/lex/rust-codepoint.h b/gcc/rust/lex/rust-codepoint.h
new file mode 100644
index 000..22da080bbb2
--- /dev/null
+++ b/gcc/rust/lex/rust-codepoint.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_CODEPOINT_H
+#define RUST_CODEPOINT_H
+
+#include 
+
+namespace Rust {
+struct Codepoint
+{
+  uint32_t value;
+
+  // Creates a zero codepoint.
+  Codepoint () : value (0) {}
+
+  // Creates a codepoint from an encoded UTF-8 value.
+  Codepoint (uint32_t value) : value (value) {}
+
+  static Codepoint eof () { return Codepoint (UINT32_MAX); }
+  bool is_eof () const { return value == UINT32_MAX; }
+
+  // Returns a C++ string containing string value of codepoint.
+  std::string as_string ();
+
+  bool operator== (Codepoint other) const { return value == other.value; }
+  bool operator!= (Codepoint other) const { return !operator== (other); }
+};
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
new file mode 100644
index 000..70e6b50209f
--- /dev/null
+++ b/gcc/rust/lex/rust-lex.cc
@@ -0,0 +1,2729 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-lex.h"
+
+#include "rust-system.h"  // for rust_assert and rust_unreachable
+#include "rust-diagnostics.h" // for rust_error_at
+#include "rust-linemap.h"
+#include "rust-session-manager.h"
+#include "safe-ctype.h"
+
+namespace Rust {
+// TODO: move to separate compilation unit?
+// overload += for uint32_t to allow 32-bit encoded utf-8 to be added
+std::string &
+operator+= (std::string &str, Codepoint char32)
+{
+  if (char32.value < 0x80)
+{
+  str += static_cast (char32.value);
+}
+  else if (char32.value < (0x1F + 1) << (1 * 6))
+{
+  str += static_cast (0xC0 | ((char32.value >> 6) & 0x1F));
+  str += static_cast (0x80 | ((char32.value >> 0) & 0x3F));
+}
+  else if (char32.value < (0x0F + 1) << (2 * 6))
+{
+  str += static_cast (0xE0 | ((char32.value >> 12) & 0x0F));
+  str += static_cast (0x80 | ((char32.value >> 6) & 0x3F));
+  str += static_cast (0x80 | ((char32.value >> 0) & 0x3F));
+}
+  else if (char32.value < (0x07 + 1) << (3 * 6))
+{
+  str += static_cast (0xF0 | ((char32.value >> 18) & 0x07));
+  str += static_cast (0x80 | ((char32.value >> 12) & 0x3F));
+  str += static_cast (0x80 | ((char32.value >> 6) & 0x3F));
+  str += static_cast (0x80 | ((char32.value >> 0) & 0x3F));
+}
+  else
+{
+  rust_debug ("Invalid unicode codepoint found: '%u' ", char32.value);
+}
+  return str;
+}
+
+std::string
+Codepoint::as_string ()
+{
+  std::string str;
+
+  // str += Codepoint (value);
+  str += *this;
+
+  return str;
+}
+
+/* Includes all allowable

[PATCH Rust front-end v2 02/37] gccrs: Add nessecary hooks for a Rust front-end testsuite

2022-08-24 Thread herron . philip
From: Philip Herron 

This copy's over code from other front-end testsuites to enable testing
for the rust front-end specifically.

Co-authored-by: Marc Poulhiès 
Co-authored-by: Thomas Schwinge 
---
 gcc/testsuite/lib/rust-dg.exp |  49 +
 gcc/testsuite/lib/rust.exp| 186 ++
 2 files changed, 235 insertions(+)
 create mode 100644 gcc/testsuite/lib/rust-dg.exp
 create mode 100644 gcc/testsuite/lib/rust.exp

diff --git a/gcc/testsuite/lib/rust-dg.exp b/gcc/testsuite/lib/rust-dg.exp
new file mode 100644
index 000..a8a2ac0c8eb
--- /dev/null
+++ b/gcc/testsuite/lib/rust-dg.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 1997-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# .
+
+load_lib gcc-dg.exp
+
+# Define rust callbacks for dg.exp.
+
+proc rust-dg-test { prog do_what extra_tool_flags } {
+return [gcc-dg-test-1 rust_target_compile $prog $do_what $extra_tool_flags]
+}
+
+proc rust-dg-prune { system text } {
+return [gcc-dg-prune $system $text]
+}
+
+# Utility routines.
+
+#
+# rust_load -- wrapper around default rust_load to handle tests that
+# require program arguments passed to them.
+#
+
+if { [info procs rust_load] != [list] \
+  && [info procs prev_rust_load] == [list] } {
+rename rust_load prev_rust_load
+
+proc rust_load { program args } {
+   global RUST_EXECUTE_ARGS
+   if [info exists RUST_EXECUTE_ARGS] then {
+   set args [concat "{$RUST_EXECUTE_ARGS}"]
+   }
+   set result [eval [list prev_rust_load $program] $args ]
+   return $result
+}
+}
+
diff --git a/gcc/testsuite/lib/rust.exp b/gcc/testsuite/lib/rust.exp
new file mode 100644
index 000..6993c976304
--- /dev/null
+++ b/gcc/testsuite/lib/rust.exp
@@ -0,0 +1,186 @@
+# Copyright (C) 2012-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# .
+
+#
+# rust support library routines
+#
+
+load_lib prune.exp
+load_lib gcc-defs.exp
+load_lib timeout.exp
+load_lib target-libpath.exp
+
+#
+# RUST_UNDER_TEST is the compiler under test.
+#
+
+set rust_compile_options ""
+
+
+#
+# rust_include_flags -- include flags for the gcc tree structure
+#
+
+proc rust_include_flags { paths } {
+global srcdir
+global TESTING_IN_BUILD_TREE
+
+set flags ""
+
+if { [is_remote host] || ![info exists TESTING_IN_BUILD_TREE] } {
+   return "${flags}"
+}
+
+set gccpath ${paths}
+
+return "$flags"
+}
+
+#
+# rust_link_flags -- linker flags for the gcc tree structure
+#
+
+proc rust_link_flags { paths } {
+global srcdir
+global ld_library_path
+global RUST_UNDER_TEST
+global shlib_ext
+global SHARED_OPTION
+
+set gccpath ${paths}
+set libio_dir ""
+set flags ""
+set ld_library_path "."
+set shlib_ext [get_shlib_extension]
+set SHARED_OPTION ""
+verbose "shared lib extension: $shlib_ext"
+
+set_ld_library_path_env_vars
+
+return "$flags"
+}
+
+#
+# rust_init -- called at the start of each subdir of tests
+#
+
+proc rust_init { args } {
+global subdir
+global rust_initialized
+global base_dir
+global tmpdir
+global libdir
+global gluefile wrap_flags
+global objdir srcdir
+global ALWAYS_RUSTFLAGS
+global TOOL_EXECUTABLE TOOL_OPTIONS
+global RUST_UNDER_TEST
+global TESTING_IN_BUILD_TREE
+global TEST_ALWAYS_FLAGS
+global gcc_warning_prefix
+global gcc_error_prefix
+
+# We set LC_ALL and LANG to C so that we get the same error messages as 
expected.
+setenv LC_ALL C
+setenv LANG C
+
+if ![info exists RUST_UNDER_TEST] then {
+   if [info exists TOOL_EXECUTABLE] {
+   set RUST_UNDER_TEST $TOOL_EXECUTABLE
+   } else {
+   if { [is_remot

Rust frontend patches v2

2022-08-24 Thread herron . philip
This is the 2nd patch set for gccrs, since v1 we have dropped the changes
for target hooks which are not nessecary for us right now. This now
focuses directly on the front-end the only patch that affects GCC now is a
tweak to debug info. Note we are close to merging our port of the C++
constexpr code into our front-end but this patch set does not include this
yet.

Thanks to Open Source Security, inc and Embecosm for sponsoring this work.
Special thanks to all of those who have contributed thus far.

See our branch over on 
https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master

We are currently testing on every commit the following systems:

- Debian i386 - all tests passing
- Debian testing-x86_64 - all tests passing
- Fedora arm64 - all tests passing
- Fedora X86_64 - all tests passing
- OpenSUSE Leap X86_64 - all tests passing
- OpenSUSE tw X86_64 - all tests passing
- Rawhide X86_64 - all tests passing
- macos x86_64 - all tests passing
- Debian ppc64 - some tests failing
- Fedora ppc64le - some tests failing
- Fedora s390x - some tests failing

The patch set is as follows:

[PATCH Rust front-end v2 01/37] Use DW_ATE_UTF for the Rust 'char'
[PATCH Rust front-end v2 02/37] gccrs: Add nessecary hooks for a Rust
[PATCH Rust front-end v2 03/37] gccrs: Add Debug info testsuite
[PATCH Rust front-end v2 04/37] gccrs: Add link cases testsuite
[PATCH Rust front-end v2 05/37] gccrs: Add general compilation test
[PATCH Rust front-end v2 06/37] gccrs: Add execution test cases
[PATCH Rust front-end v2 07/37] gccrs: Add gcc-check-target
[PATCH Rust front-end v2 08/37] gccrs: Add the Rust front-end AST
[PATCH Rust front-end v2 09/37] gccrs: Add Lexer for Rust front-end
[PATCH Rust front-end v2 10/37] gccrs: Add Parser for Rust front-end
[PATCH Rust front-end v2 11/37] gccrs: Add expansion pass for the
[PATCH Rust front-end v2 12/37] gccrs: Add name resolution pass to
[PATCH Rust front-end v2 13/37] gccrs: Add second intermedite
[PATCH Rust front-end v2 14/37] gccrs: Add AST to HIR lowering pass
[PATCH Rust front-end v2 15/37] gccrs: Add wrapper for make_unique
[PATCH Rust front-end v2 16/37] gccrs: Add port of FNV hash used
[PATCH Rust front-end v2 17/37] gccrs: Add Rust ABI enum helpers
[PATCH Rust front-end v2 18/37] gccrs: Add Base62 implementation
[PATCH Rust front-end v2 19/37] gccrs: Add implementation of Optional
[PATCH Rust front-end v2 20/37] gccrs: Add attributes checker
[PATCH Rust front-end v2 21/37] gccrs: Add helpers mappings canonical
[PATCH Rust front-end v2 22/37] gccrs: Add type resolution and trait
[PATCH Rust front-end v2 23/37] gccrs: Add unsafe checks for Rust
[PATCH Rust front-end v2 24/37] gccrs: Add const checker
[PATCH Rust front-end v2 25/37] gccrs: Add privacy checks
[PATCH Rust front-end v2 26/37] gccrs: Add dead code scan on HIR
[PATCH Rust front-end v2 27/37] gccrs: Add unused variable scan
[PATCH Rust front-end v2 28/37] gccrs: Add metadata ouptput pass
[PATCH Rust front-end v2 29/37] gccrs: HIR to GCC GENERIC lowering
[PATCH Rust front-end v2 30/37] gccrs: These are wrappers ported from
[PATCH Rust front-end v2 31/37] gccrs: Add GCC Rust front-end
[PATCH Rust front-end v2 32/37] gccrs: Add config-lang.in
[PATCH Rust front-end v2 33/37] gccrs: add lang-spec.h
[PATCH Rust front-end v2 34/37] gccrs: add lang.opt
[PATCH Rust front-end v2 35/37] gccrs: add compiler driver
[PATCH Rust front-end v2 36/37] gccrs: compiler proper interface
[PATCH Rust front-end v2 37/37] gccrs: Add README, CONTRIBUTING and



[PATCH Rust front-end v2 01/37] Use DW_ATE_UTF for the Rust 'char' type

2022-08-24 Thread herron . philip
From: Tom Tromey 

The Rust 'char' type should use the DWARF DW_ATE_UTF encoding.
---
 gcc/dwarf2out.cc | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index e3920c898f5..a8bccbabca4 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -5600,6 +5600,16 @@ is_fortran (const_tree decl)
   return is_fortran ();
 }
 
+/* Return TRUE if the language is Rust.  */
+
+static inline bool
+is_rust ()
+{
+  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);
+
+  return lang == DW_LANG_Rust || lang == DW_LANG_Rust_old;
+}
+
 /* Return TRUE if the language is Ada.  */
 
 static inline bool
@@ -13231,7 +13241,11 @@ base_type_die (tree type, bool reverse)
}
   if (TYPE_STRING_FLAG (type))
{
- if (TYPE_UNSIGNED (type))
+ if ((dwarf_version >= 4 || !dwarf_strict)
+ && is_rust ()
+ && int_size_in_bytes (type) == 4)
+   encoding = DW_ATE_UTF;
+ else if (TYPE_UNSIGNED (type))
encoding = DW_ATE_unsigned_char;
  else
encoding = DW_ATE_signed_char;
@@ -25201,6 +25215,13 @@ gen_compile_unit_die (const char *filename)
 }
   else if (strcmp (language_string, "GNU F77") == 0)
 language = DW_LANG_Fortran77;
+  else if (strcmp (language_string, "GNU Rust") == 0)
+{
+  if (dwarf_version >= 5 || !dwarf_strict)
+   language = DW_LANG_Rust;
+  else
+   language = DW_LANG_Rust_old;
+}
   else if (dwarf_version >= 3 || !dwarf_strict)
 {
   if (strcmp (language_string, "GNU Ada") == 0)
-- 
2.25.1



Re: [PATCH] i386: avoid zero extension for crc32q

2022-08-24 Thread Alexander Monakov via Gcc-patches
On Tue, 23 Aug 2022, Alexander Monakov via Gcc-patches wrote:

> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr106453.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msse4.2 -O2 -fdump-rtl-final" } */
> +/* { dg-final { scan-rtl-dump-not "zero_extendsidi" "final" } } */

I noticed that the test is 64-bit only and added the following fixup in my
tree:

--- a/gcc/testsuite/gcc.target/i386/pr106453.c
+++ b/gcc/testsuite/gcc.target/i386/pr106453.c
@@ -1,4 +1,4 @@
-/* { dg-do compile } */
+/* { dg-do compile { target { ! ia32 } } */
 /* { dg-options "-msse4.2 -O2 -fdump-rtl-final" } */
 /* { dg-final { scan-rtl-dump-not "zero_extendsidi" "final" } } */




[PATCH V5] rs6000: Optimize cmp on rotated 16bits constant

2022-08-24 Thread Jiufu Guo via Gcc-patches
Hi,

When checking eq/ne with a constant which has only 16bits, it can be
optimized to check the rotated data.  By this, the constant building
is optimized.

As the example in PR103743:
For "in == 0x8000LL", this patch generates:
rotldi %r3,%r3,16
cmpldi %cr0,%r3,32768
instead:
li %r9,-1
rldicr %r9,%r9,0,0
cmpd %cr0,%r3,%r9

This is updated patch based on previous patch and comments:
https://gcc.gnu.org/pipermail/gcc-patches/2022-August/600164.html

This patch pass bootstrap and regtest on ppc64 and ppc64le.
Is it ok for trunk?  Thanks for comments!

BR,
Jeff(Jiufu)


PR target/103743

gcc/ChangeLog:

* config/rs6000/rs6000-protos.h (rotate_from_leading_zeros_const): New.
(compare_rotate_immediate_p): New.
* config/rs6000/rs6000.cc (rotate_from_leading_zeros_const): New
definition.
(compare_rotate_immediate_p): New definition.
* config/rs6000/rs6000.md (EQNE): New code_attr.
(*rotate_on_cmpdi): New define_insn_and_split.

gcc/testsuite/ChangeLog:

* gcc.target/powerpc/pr103743.c: New test.
* gcc.target/powerpc/pr103743_1.c: New test.

---
 gcc/config/rs6000/rs6000-protos.h |  2 +
 gcc/config/rs6000/rs6000.cc   | 41 
 gcc/config/rs6000/rs6000.md   | 58 ++-
 gcc/testsuite/gcc.target/powerpc/pr103743.c   | 52 ++
 gcc/testsuite/gcc.target/powerpc/pr103743_1.c | 95 +++
 5 files changed, 247 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr103743.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr103743_1.c

diff --git a/gcc/config/rs6000/rs6000-protos.h 
b/gcc/config/rs6000/rs6000-protos.h
index b3c16e7448d..78847e6b3db 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -35,6 +35,8 @@ extern bool xxspltib_constant_p (rtx, machine_mode, int *, 
int *);
 extern int vspltis_shifted (rtx);
 extern HOST_WIDE_INT const_vector_elt_as_int (rtx, unsigned int);
 extern bool macho_lo_sum_memory_operand (rtx, machine_mode);
+extern int rotate_from_leading_zeros_const (unsigned HOST_WIDE_INT, int);
+extern bool compare_rotate_immediate_p (unsigned HOST_WIDE_INT);
 extern int num_insns_constant (rtx, machine_mode);
 extern int small_data_operand (rtx, machine_mode);
 extern bool mem_operand_gpr (rtx, machine_mode);
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index df491bee2ea..a548db42660 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -14797,6 +14797,47 @@ rs6000_reverse_condition (machine_mode mode, enum 
rtx_code code)
 return reverse_condition (code);
 }
 
+/* Check if C can be rotated from an immediate which starts (as 64bit integer)
+   with at least CLZ bits zero.
+
+   Return the number by which C can be rotated from the immediate.
+   Return -1 if C can not be rotated as from.  */
+
+int
+rotate_from_leading_zeros_const (unsigned HOST_WIDE_INT c, int clz)
+{
+  /* case a. 0..0xxx: already at least clz zeros.  */
+  int lz = clz_hwi (c);
+  if (lz >= clz)
+return 0;
+
+  /* case b. 0..0xxx0..0: at least clz zeros.  */
+  int tz = ctz_hwi (c);
+  if (lz + tz >= clz)
+return tz;
+
+  /* case c. xx10.0xx: rotate 'clz + 1' bits firstly, then check case b.
+  ^bit -> Vbit
+00...00xxx100, 'clz + 1' >= bits of .  */
+  const int rot_bits = HOST_BITS_PER_WIDE_INT - clz + 1;
+  unsigned HOST_WIDE_INT rc = (c >> rot_bits) | (c << (clz - 1));
+  tz = ctz_hwi (rc);
+  if (clz_hwi (rc) + tz >= clz)
+return tz + rot_bits;
+
+  return -1;
+}
+
+/* Check if C can be rotated from an immediate operand of cmpdi or cmpldi.  */
+
+bool
+compare_rotate_immediate_p (unsigned HOST_WIDE_INT c)
+{
+  /* leading 48 zeros (cmpldi), or leading 49 ones (cmpdi).  */
+  return rotate_from_leading_zeros_const (~c, 49) > 0
+|| rotate_from_leading_zeros_const (c, 48) > 0;
+}
+
 /* Generate a compare for CODE.  Return a brand-new rtx that
represents the result of the compare.  */
 
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index e9e5cd1e54d..b5a54d1c79e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7766,6 +7766,63 @@ (define_insn "*movsi_from_df"
   "xscvdpsp %x0,%x1"
   [(set_attr "type" "fp")])
 
+
+(define_code_iterator eqne [eq ne])
+(define_code_attr EQNE [(eq "EQ") (ne "NE")])
+
+;; "i == C" ==> "rotl(i,N) == rotl(C,N)"
+(define_insn_and_split "*rotate_on_cmpdi"
+  [(set (pc)
+   (if_then_else (eqne (match_operand:DI 1 "gpc_reg_operand" "r")
+   (match_operand:DI 2 "const_int_operand" "n"))
+ (label_ref (match_operand 0 ""))
+ (pc)))]
+  "TARGET_POWERPC64 && can_create_pseudo_p ()
+   && num_insns_constant (operands[2], DImode) > 1
+   && compare_rotate_immediate_p (UINTVAL (operands[2]))"
+   "#"
+   "&& 1"
+  [(

[PATCH 2/2] Move things around in predicate analysis

2022-08-24 Thread Richard Biener via Gcc-patches
This moves a few functions, notably normalization after a big comment
documenting it.  I've left the rest unorganized for now.

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

* gimple-predicate-analysis.cc: Move predicate normalization
after the comment documenting it.
---
 gcc/gimple-predicate-analysis.cc | 996 +++
 1 file changed, 498 insertions(+), 498 deletions(-)

diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index 8995c11a45c..079e06009fd 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -1694,570 +1694,284 @@ predicate::simplify (gimple *use_or_def, bool is_use)
   (_2 RELOP1 _1) AND (_5 RELOP2 _4) AND (_8 RELOP3 _7) AND (_0 != 0)
   */
 
-/* Store a PRED in *THIS.  */
-
-void
-predicate::push_pred (const pred_info &pred)
-{
-  pred_chain chain = vNULL;
-  chain.safe_push (pred);
-  m_preds.safe_push (chain);
-}
-
-/* Dump predicates in *THIS for STMT prepended by MSG.  */
+/* Normalize predicate PRED:
+   1) if PRED can no longer be normalized, append it to *THIS.
+   2) otherwise if PRED is of the form x != 0, follow x's definition
+  and put normalized predicates into WORK_LIST.  */
 
 void
-predicate::dump (gimple *stmt, const char *msg) const
+predicate::normalize (pred_chain *norm_chain,
+ pred_info pred,
+ tree_code and_or_code,
+ pred_chain *work_list,
+ hash_set *mark_set)
 {
-  fprintf (dump_file, "%s", msg);
-  if (stmt)
+  if (!is_neq_zero_form_p (pred))
 {
-  fputc ('\t', dump_file);
-  print_gimple_stmt (dump_file, stmt, 0);
-  fprintf (dump_file, "  is conditional on:\n");
+  if (and_or_code == BIT_IOR_EXPR)
+   push_pred (pred);
+  else
+   norm_chain->safe_push (pred);
+  return;
 }
 
-  unsigned np = m_preds.length ();
-  if (np == 0)
+  gimple *def_stmt = SSA_NAME_DEF_STMT (pred.pred_lhs);
+
+  if (gimple_code (def_stmt) == GIMPLE_PHI
+  && is_degenerate_phi (def_stmt, &pred))
+/* PRED has been modified above.  */
+work_list->safe_push (pred);
+  else if (gimple_code (def_stmt) == GIMPLE_PHI && and_or_code == BIT_IOR_EXPR)
 {
-  fprintf (dump_file, "\t(empty)\n");
-  return;
-}
+  unsigned n = gimple_phi_num_args (def_stmt);
 
-  {
-tree expr = build_pred_expr (m_preds);
-char *str = print_generic_expr_to_str (expr);
-fprintf (dump_file, "\t%s (expanded)\n", str);
-free (str);
-  }
+  /* Punt for a nonzero constant.  The predicate should be one guarding
+the phi edge.  */
+  for (unsigned i = 0; i < n; ++i)
+   {
+ tree op = gimple_phi_arg_def (def_stmt, i);
+ if (TREE_CODE (op) == INTEGER_CST && !integer_zerop (op))
+   {
+ push_pred (pred);
+ return;
+   }
+   }
 
-  if (np > 1)
-fprintf (dump_file, "\tOR (");
+  for (unsigned i = 0; i < n; ++i)
+   {
+ tree op = gimple_phi_arg_def (def_stmt, i);
+ if (integer_zerop (op))
+   continue;
+
+ push_to_worklist (op, work_list, mark_set);
+   }
+}
+  else if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
+{
+  if (and_or_code == BIT_IOR_EXPR)
+   push_pred (pred);
+  else
+   norm_chain->safe_push (pred);
+}
+  else if (gimple_assign_rhs_code (def_stmt) == and_or_code)
+{
+  /* Avoid splitting up bit manipulations like x & 3 or y | 1.  */
+  if (is_gimple_min_invariant (gimple_assign_rhs2 (def_stmt)))
+   {
+ /* But treat x & 3 as a condition.  */
+ if (and_or_code == BIT_AND_EXPR)
+   {
+ pred_info n_pred;
+ n_pred.pred_lhs = gimple_assign_rhs1 (def_stmt);
+ n_pred.pred_rhs = gimple_assign_rhs2 (def_stmt);
+ n_pred.cond_code = and_or_code;
+ n_pred.invert = false;
+ norm_chain->safe_push (n_pred);
+   }
+   }
+  else
+   {
+ push_to_worklist (gimple_assign_rhs1 (def_stmt), work_list, mark_set);
+ push_to_worklist (gimple_assign_rhs2 (def_stmt), work_list, mark_set);
+   }
+}
+  else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
+  == tcc_comparison)
+{
+  pred_info n_pred = get_pred_info_from_cmp (def_stmt);
+  if (and_or_code == BIT_IOR_EXPR)
+   push_pred (n_pred);
+  else
+   norm_chain->safe_push (n_pred);
+}
   else
-fputc ('\t', dump_file);
-  for (unsigned i = 0; i < np; i++)
 {
-  dump_pred_chain (m_preds[i]);
-  if (i < np - 1)
-   fprintf (dump_file, ", ");
-  else if (i > 0)
-   fputc (')', dump_file);
+  if (and_or_code == BIT_IOR_EXPR)
+   push_pred (pred);
+  else
+   norm_chain->safe_push (pred);
 }
-  fputc ('\n', dump_file);
 }
 
-/* Initialize USE_PREDS with the predicates of the control dependence chains
-   between the bas

[PATCH 1/2] Split uninit analysis from predicate analysis

2022-08-24 Thread Richard Biener via Gcc-patches
This splits the API collected in gimple-predicate-analysis.h into
what I'd call a predicate and assorted functionality plus utility
used by the uninit pass that happens to use that.  I've tried to
be minimalistic with refactoring, there's still recursive
instantiation of uninit_analysis, the new class encapsulating a
series of uninit analysis queries from the uninit pass.  But it
at least should make the predicate part actually reusable and
what predicate is dealt with is a little bit more clear in the
uninit_analysis part.

I will followup with moving the predicate implementation bits
together in the gimple-predicate-analysis.cc file.

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

* gimple-predicate-analysis.h (predicate): Split out
non-predicate related functionality into ..
(uninit_analysis): .. this new class.
* gimple-predicate-analysis.cc: Refactor into two classes.
* tree-ssa-uninit.cc (find_uninit_use): Use uninit_analysis.
---
 gcc/gimple-predicate-analysis.cc | 116 ---
 gcc/gimple-predicate-analysis.h  | 101 ---
 gcc/tree-ssa-uninit.cc   |   6 +-
 3 files changed, 121 insertions(+), 102 deletions(-)

diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index f7170a8d068..8995c11a45c 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -483,19 +483,18 @@ find_var_cmp_const (pred_chain_union preds, gphi *phi, 
gimple **flag_def,
Checking recursively into (1), the compiler can find out that only
some_val (which is defined) can flow into (3) which is OK.  */
 
-static bool
-prune_phi_opnds (gphi *phi, unsigned opnds, gphi *flag_def,
-tree boundary_cst, tree_code cmp_code,
-predicate::func_t &eval,
-hash_set *visited_phis,
-bitmap *visited_flag_phis)
+bool
+uninit_analysis::prune_phi_opnds (gphi *phi, unsigned opnds, gphi *flag_def,
+ tree boundary_cst, tree_code cmp_code,
+ hash_set *visited_phis,
+ bitmap *visited_flag_phis)
 {
   /* The Boolean predicate guarding the PHI definition.  Initialized
  lazily from PHI in the first call to is_use_guarded() and cached
  for subsequent iterations.  */
-  predicate def_preds (eval);
+  uninit_analysis def_preds (m_eval);
 
-  unsigned n = MIN (eval.max_phi_args, gimple_phi_num_args (flag_def));
+  unsigned n = MIN (m_eval.max_phi_args, gimple_phi_num_args (flag_def));
   for (unsigned i = 0; i < n; i++)
 {
   if (!MASK_TEST_BIT (opnds, i))
@@ -532,9 +531,9 @@ prune_phi_opnds (gphi *phi, unsigned opnds, gphi *flag_def,
  bitmap_set_bit (*visited_flag_phis, SSA_NAME_VERSION (phi_result));
 
  /* Now recursively try to prune the interesting phi args.  */
- unsigned opnds_arg_phi = eval.phi_arg_set (phi_arg_def);
+ unsigned opnds_arg_phi = m_eval.phi_arg_set (phi_arg_def);
  if (!prune_phi_opnds (phi_arg_def, opnds_arg_phi, flag_arg_def,
-   boundary_cst, cmp_code, eval, visited_phis,
+   boundary_cst, cmp_code, visited_phis,
visited_flag_phis))
return false;
 
@@ -554,7 +553,7 @@ prune_phi_opnds (gphi *phi, unsigned opnds, gphi *flag_def,
  gimple *opnd_def = SSA_NAME_DEF_STMT (opnd);
  if (gphi *opnd_def_phi = dyn_cast  (opnd_def))
{
- unsigned opnds2 = eval.phi_arg_set (opnd_def_phi);
+ unsigned opnds2 = m_eval.phi_arg_set (opnd_def_phi);
  if (!MASK_EMPTY (opnds2))
{
  edge opnd_edge = gimple_phi_arg_edge (phi, i);
@@ -578,9 +577,10 @@ prune_phi_opnds (gphi *phi, unsigned opnds, gphi *flag_def,
up the CFG nodes that it's dominated by.  *EDGES holds the result, and
VISITED is used for detecting cycles.  */
 
-static void
-collect_phi_def_edges (gphi *phi, basic_block cd_root, auto_vec *edges,
-  predicate::func_t &eval, hash_set *visited)
+void
+uninit_analysis::collect_phi_def_edges (gphi *phi, basic_block cd_root,
+   vec *edges,
+   hash_set *visited)
 {
   if (visited->elements () == 0
   && DEBUG_PREDICATE_ANALYZER
@@ -607,9 +607,9 @@ collect_phi_def_edges (gphi *phi, basic_block cd_root, 
auto_vec *edges,
 
  if (gimple_code (def) == GIMPLE_PHI
  && dominated_by_p (CDI_DOMINATORS, gimple_bb (def), cd_root))
-   collect_phi_def_edges (as_a (def), cd_root, edges, eval,
+   collect_phi_def_edges (as_a (def), cd_root, edges,
   visited);
- else if (!eval (opnd))
+ else if (!m_eval (opnd))
{
  if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -63

Re: [PATCH] internal-fn, tree-cfg: Fix .TRAP handling and another __builtin_trap vops issue [PR106099]

2022-08-24 Thread Richard Biener via Gcc-patches
On Wed, 24 Aug 2022, Jakub Jelinek wrote:

> Hi!
> 
> This patch fixes 2 __builtin_unreachable/__builtin_trap related issues.
> One (first hunk) is that CDDCE happily removes calls to .TRAP ()
> internal-fn as useless.  The problem is that the internal-fn is
> ECF_CONST | ECF_NORETURN, doesn't have lhs and so DCE thinks it doesn't
> have side-effects and removes it.  __builtin_unreachable which has
> the same ECF_* flags works fine, as since PR44485 we implicitly add
> ECF_LOOPING_CONST_OR_PURE to ECF_CONST | ECF_NORETURN builtins, but
> do it in flags_from_decl_or_type which isn't called for internal-fns.
> As IFN_TRAP is the only ifn with such flags, it seems easier to
> add it explicitly.
> 
> The other issue (which on the testcase can be seen only with the
> first bug unfixed) is that execute_fixup_cfg can add a __builtin_trap
> which needs vops, but nothing adds it and it can appear in many passes
> which don't have corresponding TODO_update_ssa_only_virtuals etc.
> Fixed similarly as last time but emitting ifn there instead.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

I still disagree with this in general - but well, seems the ship
has sailed.

Do we have to repeat this pattern elsewhere?  It seems we have
build_builtin_unreachable (not using .IFN_TRAP) but no corresponding
GIMPLE variant?  Maybe have builtin_cfn_unreachable () that returns
BUILT_IN_UNREACHABLE or IFN_TRAP and use gimple_build () with that
combined_fn argument?  See below

> 2022-08-24  Jakub Jelinek  
> 
>   PR tree-optimization/106099
>   * internal-fn.def (TRAP): Add ECF_LOOPING_CONST_OR_PURE flag.
>   * tree-cfg.cc (execute_fixup_cfg): Add IFN_TRAP instead of
>   __builtin_trap to avoid the need of vops.
> 
>   * gcc.dg/pr106099.c: New test.
> 
> --- gcc/internal-fn.def.jj2022-07-28 12:43:12.876295553 +0200
> +++ gcc/internal-fn.def   2022-08-23 14:21:49.559364691 +0200
> @@ -458,7 +458,8 @@ DEF_INTERNAL_FN (SPACESHIP, ECF_CONST |
>  
>  /* __builtin_trap created from/for __builtin_unreachable.  */
>  DEF_INTERNAL_FN (TRAP, ECF_CONST | ECF_LEAF | ECF_NORETURN
> -| ECF_NOTHROW | ECF_COLD, NULL)
> +| ECF_NOTHROW | ECF_COLD | ECF_LOOPING_CONST_OR_PURE,
> +  NULL)
>  
>  #undef DEF_INTERNAL_INT_FN
>  #undef DEF_INTERNAL_FLT_FN
> --- gcc/tree-cfg.cc.jj2022-07-26 10:32:23.998267698 +0200
> +++ gcc/tree-cfg.cc   2022-08-23 12:36:03.818856327 +0200
> @@ -9879,10 +9879,16 @@ execute_fixup_cfg (void)
> if (stmt && is_gimple_call (stmt))
>   gimple_call_set_ctrl_altering (stmt, false);
> tree fndecl = builtin_decl_unreachable ();
> -   stmt = gimple_build_call (fndecl, 0);
> +   if (DECL_FUNCTION_CODE (fndecl) != BUILT_IN_TRAP)
> + stmt = gimple_build_call (fndecl, 0);
> +   else
> + /* Instead of __builtin_trap use .TRAP, so that it doesn't
> +need vops.  */
> + stmt = gimple_build_call_internal (IFN_TRAP, 0);
> gimple_stmt_iterator gsi = gsi_last_bb (bb);

So

   combined_fn cfn = builtin_cfn_unreachable ();
   gimple_build (&gsi, false, GSI_NEW_STMT, cfn, void_type_node);

?

> gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
> -   if (!cfun->after_inlining)
> +   if (!cfun->after_inlining
> +   && DECL_FUNCTION_CODE (fndecl) != BUILT_IN_TRAP)
>   {
> gcall *call_stmt = dyn_cast  (stmt);
> node->create_edge (cgraph_node::get_create (fndecl),
> --- gcc/testsuite/gcc.dg/pr106099.c.jj2022-08-23 14:30:51.992057144 
> +0200
> +++ gcc/testsuite/gcc.dg/pr106099.c   2022-08-23 14:29:04.271508337 +0200
> @@ -0,0 +1,10 @@
> +/* PR tree-optimization/106099 */
> +/* { dg-do compile } */
> +/* { dg-options "-O -fharden-compares -fno-tree-forwprop -fno-tree-ch 
> -fno-tree-dominator-opts -fno-tree-ccp -funreachable-traps 
> --param=scev-max-expr-size=1" } */
> +
> +void
> +foo (void)
> +{
> +  for (unsigned i = 0; i == 0; i++)
> +__builtin_printf ("%d", i);
> +}
> 
>   Jakub
> 
> 

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


Re: [PATCH] libstdc++: Optimize operator+(string/char*, string/char*) equally

2022-08-24 Thread Jonathan Wakely via Gcc-patches
On Wed, 24 Aug 2022 at 07:18, Will Hawkins  wrote:
>
> On Tue, Aug 23, 2022 at 12:33 PM Jonathan Wakely  wrote:
> >
> > On Mon, 22 Aug 2022 at 19:15, Will Hawkins wrote:
> > >
> > > Until now operator+(char*, string) and operator+(string, char*) had
> > > different performance characteristics. The former required a single
> > > memory allocation and the latter required two. This patch makes the
> > > performance equal.
> >
> > If you don't have a GCC copyright assignment on file with the FSF then
> > please follow the procedure described at https://gcc.gnu.org/dco.html
>
> Thank you.
>
> >
> >
> > > libstdc++-v3/ChangeLog:
> > > * libstdc++-v3/include/bits/basic_string.h (operator+(string, 
> > > char*)):
> > > Remove naive implementation.
> > > * libstdc++-v3/include/bits/basic_string.tcc (operator+(string, 
> > > char*)):
> > > Add single-allocation implementation.
> > > ---
> > >  libstdc++-v3/include/bits/basic_string.h   |  7 +--
> > >  libstdc++-v3/include/bits/basic_string.tcc | 21 +
> > >  2 files changed, 22 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/libstdc++-v3/include/bits/basic_string.h 
> > > b/libstdc++-v3/include/bits/basic_string.h
> > > index b04fba95678..bc048fc0689 100644
> > > --- a/libstdc++-v3/include/bits/basic_string.h
> > > +++ b/libstdc++-v3/include/bits/basic_string.h
> > > @@ -3523,12 +3523,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
> > >  _GLIBCXX20_CONSTEXPR
> > >  inline basic_string<_CharT, _Traits, _Alloc>
> >
> > Please remove the 'inline' specifier here, since you're moving the
> > definition into the non-inline .tcc file.
> >
> > There's a separate discussion to be had about whether these operator+
> > overloads *should* be inline. But for the purposes of this change, we
> > want these two operator+ overloads to be consistent, and so they
> > should both be non-inline.
>
> Thank you for the feedback. I sent out a v2 of the patch. Again, I
> hope that I followed the proper procedure by having my mailer put the
> patch in reply to my previous message.

It looks like the patch got attached in this thread, not the [PATCH v2] thread:
https://gcc.gnu.org/pipermail/gcc-patches/2022-August/600176.html
Presumably it was meant as a reply to:
https://gcc.gnu.org/pipermail/gcc-patches/2022-August/600175.html

It's more conventional to put the patch in the same email, not as a
separate reply, which would avoid that problem.

You can use git scissors to separate the patch submission from the
preceding discussion and comments, see
https://git-scm.com/docs/git-mailinfo#Documentation/git-mailinfo.txt---scissors

For example, see my patches like the one at
https://gcc.gnu.org/pipermail/gcc-patches/2022-August/600109.html
where the "informational" part comes first, describing where it was
tested, then the patch (and its commit msg) come after the -- >8 --
scissors.

If you use git send-email to send mails, you can use
--in-reply-to=$MessageId to make the email a reply to the specified
$MessageId from a previous mail in the thread.

Anyway, the v2 patch looks fine and I'll apply it to trunk after
testing - thanks!



[PATCH] Some more predicate analysis TLC

2022-08-24 Thread Richard Biener via Gcc-patches
This limits the simple control dep also to the cd_root plus avoids
filling the lazily computed PHI def predicate in the early out path
which would leave it not simplified and normalized if it were
re-used.  It also avoids computing the use predicates when the
post-dominance early out doesn't need it.  It also syncs
predicate::use_cannot_happen with init_from_phi_def, adding the
missing PHI edge to the computed chains (the simple control dep
code already adds it).

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

* gimple-predicate-analysis.cc (predicate::use_cannot_happen):
Do simple_control_dep_chain only up to cd_root, add the PHI
operand edge to the chains like init_from_phi_def does.
(predicate::is_use_guarded): Speedup early out, avoid half-way
initializing the PHI def predicate.
---
 gcc/gimple-predicate-analysis.cc | 31 ---
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index ea81daacd4f..f7170a8d068 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -1322,10 +1322,15 @@ predicate::use_cannot_happen (gphi *phi, unsigned opnds)
  /* If compute_control_dep_chain bailed out due to limits
 build a partial sparse path using dominators.  Collect
 only edges whose predicates are always true when reaching E.  */
- simple_control_dep_chain (dep_chains[0],
-   ENTRY_BLOCK_PTR_FOR_FN (cfun), e);
+ simple_control_dep_chain (dep_chains[0], cd_root, e);
  num_chains++;
}
+  /* Update the chains with the phi operand edge.  */
+  else if (EDGE_COUNT (e->src->succs) > 1)
+   {
+ for (unsigned j = 0; j < num_chains; j++)
+   dep_chains[j].safe_push (e);
+   }
 
   if (DEBUG_PREDICATE_ANALYZER && dump_file)
{
@@ -1916,24 +1921,14 @@ predicate::is_use_guarded (gimple *use_stmt, 
basic_block use_bb,
   /* The basic block where the PHI is defined.  */
   basic_block def_bb = gimple_bb (phi);
 
+  if (dominated_by_p (CDI_POST_DOMINATORS, def_bb, use_bb))
+/* The use is not guarded.  */
+return false;
+
   /* Try to build the predicate expression under which the PHI flows
  into its use.  This will be empty if the PHI is defined and used
  in the same bb.  */
   predicate use_preds (def_bb, use_bb, m_eval);
-
-  if (dominated_by_p (CDI_POST_DOMINATORS, def_bb, use_bb))
-{
-  if (is_empty ())
-   {
- /* Lazily initialize *THIS from the PHI and build its use
-expression.  */
- init_from_phi_def (phi);
-   }
-
-  /* The use is not guarded.  */
-  return false;
-}
-
   if (use_preds.is_empty ())
 return false;
 
@@ -1955,9 +1950,7 @@ predicate::is_use_guarded (gimple *use_stmt, basic_block 
use_bb,
 {
   /* Lazily initialize *THIS from PHI.  */
   if (!init_from_phi_def (phi))
-   {
- return false;
-   }
+   return false;
 
   simplify (phi);
   normalize (phi);
-- 
2.35.3


[PATCH] internal-fn, tree-cfg: Fix .TRAP handling and another __builtin_trap vops issue [PR106099]

2022-08-24 Thread Jakub Jelinek via Gcc-patches
Hi!

This patch fixes 2 __builtin_unreachable/__builtin_trap related issues.
One (first hunk) is that CDDCE happily removes calls to .TRAP ()
internal-fn as useless.  The problem is that the internal-fn is
ECF_CONST | ECF_NORETURN, doesn't have lhs and so DCE thinks it doesn't
have side-effects and removes it.  __builtin_unreachable which has
the same ECF_* flags works fine, as since PR44485 we implicitly add
ECF_LOOPING_CONST_OR_PURE to ECF_CONST | ECF_NORETURN builtins, but
do it in flags_from_decl_or_type which isn't called for internal-fns.
As IFN_TRAP is the only ifn with such flags, it seems easier to
add it explicitly.

The other issue (which on the testcase can be seen only with the
first bug unfixed) is that execute_fixup_cfg can add a __builtin_trap
which needs vops, but nothing adds it and it can appear in many passes
which don't have corresponding TODO_update_ssa_only_virtuals etc.
Fixed similarly as last time but emitting ifn there instead.

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

2022-08-24  Jakub Jelinek  

PR tree-optimization/106099
* internal-fn.def (TRAP): Add ECF_LOOPING_CONST_OR_PURE flag.
* tree-cfg.cc (execute_fixup_cfg): Add IFN_TRAP instead of
__builtin_trap to avoid the need of vops.

* gcc.dg/pr106099.c: New test.

--- gcc/internal-fn.def.jj  2022-07-28 12:43:12.876295553 +0200
+++ gcc/internal-fn.def 2022-08-23 14:21:49.559364691 +0200
@@ -458,7 +458,8 @@ DEF_INTERNAL_FN (SPACESHIP, ECF_CONST |
 
 /* __builtin_trap created from/for __builtin_unreachable.  */
 DEF_INTERNAL_FN (TRAP, ECF_CONST | ECF_LEAF | ECF_NORETURN
-  | ECF_NOTHROW | ECF_COLD, NULL)
+  | ECF_NOTHROW | ECF_COLD | ECF_LOOPING_CONST_OR_PURE,
+NULL)
 
 #undef DEF_INTERNAL_INT_FN
 #undef DEF_INTERNAL_FLT_FN
--- gcc/tree-cfg.cc.jj  2022-07-26 10:32:23.998267698 +0200
+++ gcc/tree-cfg.cc 2022-08-23 12:36:03.818856327 +0200
@@ -9879,10 +9879,16 @@ execute_fixup_cfg (void)
  if (stmt && is_gimple_call (stmt))
gimple_call_set_ctrl_altering (stmt, false);
  tree fndecl = builtin_decl_unreachable ();
- stmt = gimple_build_call (fndecl, 0);
+ if (DECL_FUNCTION_CODE (fndecl) != BUILT_IN_TRAP)
+   stmt = gimple_build_call (fndecl, 0);
+ else
+   /* Instead of __builtin_trap use .TRAP, so that it doesn't
+  need vops.  */
+   stmt = gimple_build_call_internal (IFN_TRAP, 0);
  gimple_stmt_iterator gsi = gsi_last_bb (bb);
  gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
- if (!cfun->after_inlining)
+ if (!cfun->after_inlining
+ && DECL_FUNCTION_CODE (fndecl) != BUILT_IN_TRAP)
{
  gcall *call_stmt = dyn_cast  (stmt);
  node->create_edge (cgraph_node::get_create (fndecl),
--- gcc/testsuite/gcc.dg/pr106099.c.jj  2022-08-23 14:30:51.992057144 +0200
+++ gcc/testsuite/gcc.dg/pr106099.c 2022-08-23 14:29:04.271508337 +0200
@@ -0,0 +1,10 @@
+/* PR tree-optimization/106099 */
+/* { dg-do compile } */
+/* { dg-options "-O -fharden-compares -fno-tree-forwprop -fno-tree-ch 
-fno-tree-dominator-opts -fno-tree-ccp -funreachable-traps 
--param=scev-max-expr-size=1" } */
+
+void
+foo (void)
+{
+  for (unsigned i = 0; i == 0; i++)
+__builtin_printf ("%d", i);
+}

Jakub



[PATCH] rs6000/test: Adjust pr104992.c with vect_int_mod [PR106516]

2022-08-24 Thread Kewen.Lin via Gcc-patches
Hi,

As PR106516 shows, we can get unexpected gimple outputs for
function thud on some target which supports modulus operation
for vector int.  This patch introduces one effective target
vect_int_mod for it, then adjusts the test case with it.

Tested on x86_64-redhat-linux and powerpc64{,le}-linux-gnu,
especially powerpc64le Power10.

Is it ok for trunk?

BR,
Kewen
-
PR testsuite/106516

gcc/testsuite/ChangeLog:

* gcc.dg/pr104992.c: Adjust with vect_int_mod.
* lib/target-supports.exp (check_effective_target_vect_int_mod): New
proc for effective target vect_int_mod.
---
 gcc/testsuite/gcc.dg/pr104992.c   | 3 ++-
 gcc/testsuite/lib/target-supports.exp | 8 
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/pr104992.c b/gcc/testsuite/gcc.dg/pr104992.c
index 217c89a458c..82f8c75559c 100644
--- a/gcc/testsuite/gcc.dg/pr104992.c
+++ b/gcc/testsuite/gcc.dg/pr104992.c
@@ -54,4 +54,5 @@ __attribute__((noipa)) unsigned waldo (unsigned x, unsigned 
y, unsigned z) {
 return x / y * z == x;
 }

-/* { dg-final {scan-tree-dump-times " % " 9 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " % " 9 "optimized" { target { ! 
vect_int_mod } } } } */
+/* { dg-final { scan-tree-dump-times " % " 6 "optimized" { target vect_int_mod 
} } } */
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 04a2a8e8659..a4bdd23bed0 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -8239,6 +8239,14 @@ proc check_effective_target_vect_long_mult { } {
 return $answer
 }

+# Return 1 if the target supports vector int modulus, 0 otherwise.
+
+proc check_effective_target_vect_int_mod { } {
+return [check_cached_effective_target_indexed vect_int_mod {
+  expr { [istarget powerpc*-*-*]
+&& [check_effective_target_power10_ok] }}]
+}
+
 # Return 1 if the target supports vector even/odd elements extraction, 0 
otherwise.

 proc check_effective_target_vect_extract_even_odd { } {
--
2.27.0


[PATCH] Adjust the symbol for SECTION_LINK_ORDER linked_to section [PR99889]

2022-08-24 Thread Kewen.Lin via Gcc-patches
Hi,

As discussed in PR98125, -fpatchable-function-entry with
SECTION_LINK_ORDER support doesn't work well on powerpc64
ELFv1 because the filled "Symbol" in

  .section name,"flags"o,@type,Symbol

sits in .opd section instead of in the function_section
like .text or named .text*.

Since we already generates one label LPFE* which sits in
function_section of current_function_decl, this patch is
to reuse it as the symbol for the linked_to section.  It
avoids the above ABI specific issue when using the symbol
concluded from current_function_decl.

Besides, with this support some previous workarounds for
powerpc64 ELFv1 can be reverted.

btw, rs6000_print_patchable_function_entry can be dropped
but there is another rs6000 patch which needs this rs6000
specific hook rs6000_print_patchable_function_entry, not
sure which one gets landed first, so just leave it here.

Bootstrapped and regtested on below:

  1) powerpc64-linux-gnu P8 with default binutils 2.27
 and latest binutils 2.39.
  2) powerpc64le-linux-gnu P9 (default binutils 2.30).
  3) powerpc64le-linux-gnu P10 (default binutils 2.30).
  4) x86_64-redhat-linux with default binutils 2.30
 and latest binutils 2.39.
  5) aarch64-linux-gnu  with default binutils 2.30
 and latest binutils 2.39.

Is it ok for trunk?

BR,
Kewen
-

PR target/99889

gcc/ChangeLog:

* config/rs6000/rs6000.cc (rs6000_print_patchable_function_entry):
Adjust to call function default_print_patchable_function_entry.
* targhooks.cc (default_print_patchable_function_entry_1): Remove and
move the flags preparation ...
(default_print_patchable_function_entry): ... here, adjust to use
current_function_funcdef_no for label no.
* targhooks.h (default_print_patchable_function_entry_1): Remove.
* varasm.cc (default_elf_asm_named_section): Adjust code for
__patchable_function_entries section support with LPFE label.

gcc/testsuite/ChangeLog:

* g++.dg/pr93195a.C: Remove the skip on powerpc*-*-* 64-bit.
* gcc.target/aarch64/pr92424-2.c: Adjust LPFE1 with LPFE0.
* gcc.target/aarch64/pr92424-3.c: Likewise.
* gcc.target/i386/pr93492-2.c: Likewise.
* gcc.target/i386/pr93492-3.c: Likewise.
* gcc.target/i386/pr93492-4.c: Likewise.
* gcc.target/i386/pr93492-5.c: Likewise.
---
 gcc/config/rs6000/rs6000.cc  | 13 +-
 gcc/varasm.cc| 15 ---
 gcc/targhooks.cc | 45 +++-
 gcc/targhooks.h  |  3 --
 gcc/testsuite/g++.dg/pr93195a.C  |  1 -
 gcc/testsuite/gcc.target/aarch64/pr92424-2.c |  4 +-
 gcc/testsuite/gcc.target/aarch64/pr92424-3.c |  4 +-
 gcc/testsuite/gcc.target/i386/pr93492-2.c|  4 +-
 gcc/testsuite/gcc.target/i386/pr93492-3.c|  4 +-
 gcc/testsuite/gcc.target/i386/pr93492-4.c|  4 +-
 gcc/testsuite/gcc.target/i386/pr93492-5.c|  4 +-
 11 files changed, 40 insertions(+), 61 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index df491bee2ea..dba28b8e647 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -14771,18 +14771,9 @@ rs6000_print_patchable_function_entry (FILE *file,
   unsigned HOST_WIDE_INT patch_area_size,
   bool record_p)
 {
-  unsigned int flags = SECTION_WRITE | SECTION_RELRO;
-  /* When .opd section is emitted, the function symbol
- default_print_patchable_function_entry_1 is emitted into the .opd section
- while the patchable area is emitted into the function section.
- Don't use SECTION_LINK_ORDER in that case.  */
-  if (!(TARGET_64BIT && DEFAULT_ABI != ABI_ELFv2)
-  && HAVE_GAS_SECTION_LINK_ORDER)
-flags |= SECTION_LINK_ORDER;
-  default_print_patchable_function_entry_1 (file, patch_area_size, record_p,
-   flags);
+  default_print_patchable_function_entry (file, patch_area_size, record_p);
 }
-

+
 enum rtx_code
 rs6000_reverse_condition (machine_mode mode, enum rtx_code code)
 {
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 4db8506b106..d4de6e164ee 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -6906,11 +6906,16 @@ default_elf_asm_named_section (const char *name, 
unsigned int flags,
fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
   if (flags & SECTION_LINK_ORDER)
{
- tree id = DECL_ASSEMBLER_NAME (decl);
- ultimate_transparent_alias_target (&id);
- const char *name = IDENTIFIER_POINTER (id);
- name = targetm.strip_name_encoding (name);
- fprintf (asm_out_file, ",%s", name);
+ /* For now, only section "__patchable_function_entries"
+adopts flag SECTION_LINK_ORDER, internal label LPFE*
+was emitted in default_print_patchable_function_entry,
+just place it here for linked_to secti

[PATCH] rs6000: using li/lis+oris/xoris to build constants

2022-08-24 Thread Jiufu Guo via Gcc-patches
Hi,

PR106708 constaint some constants which can be support by li/lis + oris/xoris.

For constant C:
if ((c & 0x80008000ULL) == 0x8000ULL) or say:
32(0)+1(1)+15(x)+1(0)+15(x), we could use li+oris to build constant 'C'.

if ((c & 0x8000ULL) == 0x8000ULL) or say:
32(1)+16(x)+1(1)+15(x), using li+xoris would be ok.

if ((c & 0xULL) == 0x) or say:
32(1)+1(0)+15(x)+16(0), using lis+xoris would be ok.

This patch update rs6000_emit_set_long_const to support these forms.
Bootstrap and regtest pass on ppc64 and ppc64le.

Is this ok for trunk?

BR,
Jeff(Jiufu)


PR target/106708

gcc/ChangeLog:

* config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Using li/lis +
oris/xoris to build constants.

gcc/testsuite/ChangeLog:

* gcc.target/powerpc/pr106708.c: New test.
* gcc.target/powerpc/pr106708.h: New file.
* gcc.target/powerpc/pr106708_1.c: New test.

---
 gcc/config/rs6000/rs6000.cc   | 22 +++
 gcc/testsuite/gcc.target/powerpc/pr106708.c   | 10 +
 gcc/testsuite/gcc.target/powerpc/pr106708.h   |  9 
 gcc/testsuite/gcc.target/powerpc/pr106708_1.c | 17 ++
 4 files changed, 58 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr106708.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr106708.h
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr106708_1.c

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index df491bee2ea..243247fb838 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -10112,6 +10112,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
 {
   rtx temp;
   HOST_WIDE_INT ud1, ud2, ud3, ud4;
+  HOST_WIDE_INT orig_c = c;
 
   ud1 = c & 0x;
   c = c >> 16;
@@ -10137,6 +10138,27 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
gen_rtx_IOR (DImode, copy_rtx (temp),
 GEN_INT (ud1)));
 }
+  else if (ud4 == 0 && ud3 == 0 && (ud2 & 0x8000) && !(ud1 & 0x8000))
+{
+  temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
+
+  /* li+oris */
+  emit_move_insn (copy_rtx (temp), GEN_INT (ud1));
+  emit_move_insn (dest, gen_rtx_IOR (DImode, copy_rtx (temp),
+GEN_INT (ud2 << 16)));
+}
+  else if ((ud4 == 0x && ud3 == 0x)
+  && ((ud1 & 0x8000) || (ud1 == 0 && !(ud2 & 0x8000
+{
+  temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
+
+  HOST_WIDE_INT imm = (ud1 & 0x8000) ? ((ud1 ^ 0x8000) - 0x8000)
+: ((ud2 << 16) - 0x8000);
+  /* li/lis + xoris */
+  emit_move_insn (copy_rtx (temp), GEN_INT (imm));
+  emit_move_insn (dest, gen_rtx_XOR (DImode, copy_rtx (temp),
+GEN_INT (orig_c ^ imm)));
+}
   else if (ud3 == 0 && ud4 == 0)
 {
   temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.c 
b/gcc/testsuite/gcc.target/powerpc/pr106708.c
new file mode 100644
index 000..6445fa47747
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr106708.c
@@ -0,0 +1,10 @@
+/* PR target/106708 */
+/* { dg-options "-O2 -mdejagnu-cpu=power8" } */
+/* { dg-do compile { target has_arch_ppc64 } } */
+
+#include "pr106708.h"
+
+/* { dg-final { scan-assembler-times {\mli\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mlis\M} 1 } } */
+/* { dg-final { scan-assembler-times {\moris\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxoris\M} 2 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.h 
b/gcc/testsuite/gcc.target/powerpc/pr106708.h
new file mode 100644
index 000..ad07eb30547
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr106708.h
@@ -0,0 +1,9 @@
+/* li/lis + oris/xoris */
+void  __attribute__ ((__noinline__, __noclone__)) foo (long long *arg)
+{
+  *arg++ = 0x98765432ULL;
+  *arg++ = 0x7cdeab55ULL;
+  *arg++ = 0x6543ULL;
+}
+
+
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708_1.c 
b/gcc/testsuite/gcc.target/powerpc/pr106708_1.c
new file mode 100644
index 000..df65c321f6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr106708_1.c
@@ -0,0 +1,17 @@
+/* PR target/106708 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "pr106708.h"
+
+long long arr[] = {0x98765432ULL, 0x7cdeab55ULL, 
0x6543ULL};
+int
+main ()
+{
+  long long a[3];
+
+  foo (a);
+  if (__builtin_memcmp (a, arr, sizeof (arr)) != 0)
+__builtin_abort ();
+  return 0;
+}
-- 
2.17.1



Re: [PATCH] sched1: Fix -fcompare-debug issue in schedule_region [PR105586]

2022-08-24 Thread Surya Kumari Jangala via Gcc-patches
Hi Peter, Segher,
Thanks for going thru the patch!
I will make the proposed changes to the Changelog.

Regards,
Surya


On 23/08/22 6:58 pm, Segher Boessenkool wrote:
> Hi!
> 
> On Tue, Aug 23, 2022 at 07:55:22AM -0500, Peter Bergner wrote:
>> It looks good to me, but I cannot approve it.
> 
> Same here (both statements).
> 
>> That said, you're missing
>> a ChangeLog entry for your new helper function.  The ChangeLog mentions
>> what changed, not why it changed.
> 
> And that is correct!  Changelogs should not say that, that isn't their
> purpose (in GCC), not what they are used for.  Explanations like that go
> in the email and/or the commit message.
> 
> The main remaining usefulness of changelogs is to spot unintended
> commmits.
> 
>> Maybe something like the following?
>>
>> gcc/
>>  PR rtl-optimization/105586
>>  * sched-rgn.cc (save_state_for_fallthru_edge): New function.
>>  (schedule_region): Use it for all blocks.
> 
> That looks perfect, it doesn't say "why" either :-)
> 
> 
> Segher


[committed] i386: Fix up mode iterators that weren't expanded [PR106721]

2022-08-24 Thread Jakub Jelinek via Gcc-patches
Hi!

Currently, when md file reader sees  and something is valid mode
(or code) attribute but which doesn't include case for the current mode
(or code), it just keeps the  untouched.
I went through all cases matching <[a-zA-Z] in tmp-mddump.md after make mddump.
Most of the cases were related to the recent V*BF mode additions, some
to V*HF mode too, and there was one typo.

Bootstrapped/regtested on x86_64-linux and i686-linux, preapproved in
bugzilla with the request to use i instead of f for V*[BH]F (similarly
to V*HI mode).

2022-08-24  Jakub Jelinek  

PR target/106721
* config/i386/sse.md (shuffletype): Add V32BF, V16BF and V8BF entries.
Change V32HF, V16HF and V8HF entries from "f" to "i".
(iptr): Add V32BF, V16BF, V8BF and BF entries.
(i128vldq): Add V16HF and V16BF entries.
(avx512er_vmrcp28): Fix typo,
mask_opernad3 -> mask_operand3.

* gcc.target/i386/avx512vl-pr106721.c: New test.

--- gcc/config/i386/sse.md.jj   2022-08-19 16:00:05.042390249 +0200
+++ gcc/config/i386/sse.md  2022-08-24 09:40:50.159956792 +0200
@@ -747,7 +747,8 @@
(V8HI "avx512vl") (V16HI "avx512vl") (V32HI "avx512bw")])
 
 (define_mode_attr shuffletype
-  [(V32HF "f") (V16HF "f") (V8HF "f")
+  [(V32HF "i") (V16HF "i") (V8HF "i")
+   (V32BF "i") (V16BF "i") (V8BF "i")
(V16SF "f") (V16SI "i") (V8DF "f") (V8DI "i")
(V8SF "f") (V8SI "i") (V4DF "f") (V4DI "i")
(V4SF "f") (V4SI "i") (V2DF "f") (V2DI "i")
@@ -1136,10 +1137,10 @@
   [(V64QI "b") (V32HI "w") (V16SI "k") (V8DI "q")
(V32QI "b") (V16HI "w") (V8SI "k") (V4DI "q")
(V16QI "b") (V8HI "w") (V4SI "k") (V2DI "q")
-   (V32HF "w") (V16SF "k") (V8DF "q")
-   (V16HF "w") (V8SF "k") (V4DF "q")
-   (V8HF "w") (V4SF "k") (V2DF "q")
-   (HF "w") (SF "k") (DF "q")])
+   (V32HF "w") (V32BF "w") (V16SF "k") (V8DF "q")
+   (V16HF "w") (V16BF "w") (V8SF "k") (V4DF "q")
+   (V8HF "w") (V8BF "w") (V4SF "k") (V2DF "q")
+   (HF "w") (BF "w") (SF "k") (DF "q")])
 
 ;; Mapping of vector modes to VPTERNLOG suffix
 (define_mode_attr ternlogsuffix
@@ -1251,7 +1252,7 @@
 ;; For 256-bit modes for TARGET_AVX512VL && TARGET_AVX512DQ
 ;; i32x4, f32x4, i64x2 or f64x2 suffixes.
 (define_mode_attr i128vldq
-  [(V8SF "f32x4") (V4DF "f64x2")
+  [(V16HF "i32x4") (V16BF "i32x4") (V8SF "f32x4") (V4DF "f64x2")
(V32QI "i32x4") (V16HI "i32x4") (V8SI "i32x4") (V4DI "i64x2")])
 
 ;; Mix-n-match
@@ -23897,7 +23898,7 @@
  (match_operand:VF_128 2 "register_operand" "v")
  (const_int 1)))]
   "TARGET_AVX512ER"
-  "vrcp28\t{%1, %2, 
%0|%0, %2, %1}"
+  "vrcp28\t{%1, %2, 
%0|%0, %2, %1}"
   [(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
(set_attr "type" "sse")
--- gcc/testsuite/gcc.target/i386/avx512vl-pr106721.c.jj2022-08-23 
13:31:57.590639970 +0200
+++ gcc/testsuite/gcc.target/i386/avx512vl-pr106721.c   2022-08-23 
13:31:31.271994165 +0200
@@ -0,0 +1,19 @@
+/* PR target/106721 */
+/* { dg-do assemble { target avx512vl } } */
+/* { dg-options "-O3 -mavx512vl" } */
+
+typedef __bf16 __m256bf16 __attribute__((__vector_size__(32)));
+void (*bar) (__m256bf16, __m256bf16, __m256bf16);
+__m256bf16 a;
+volatile __bf16 b, c, d, e, f, g, h;
+
+void
+foo (void)
+{
+  __m256bf16 x[8];
+  int i;
+  for (i = 0; i < 8; i++)
+x[i] = (__m256bf16) { b, c, d, e, f, g, h };
+  a = x[6];
+  bar (x[0], x[6], x[7]);
+}

Jakub



Re: [PATCH V4] rs6000: Optimize cmp on rotated 16bits constant

2022-08-24 Thread Jiufu Guo via Gcc-patches
Hi!

Segher Boessenkool  writes:

> Hi!
>
> On Mon, Jul 25, 2022 at 09:29:22PM +0800, Jiufu Guo wrote:
>> When checking eq/neq with a constant which has only 16bits, it can be
>> optimized to check the rotated data.  By this, the constant building
>> is optimized.
>
> "ne", not "neq".
Oh, thanks!
>
>> gcc/ChangeLog:
>> 
>>  * config/rs6000/rs6000-protos.h (rotate_from_leading_zeros_const):
>>  New decl.
>
> "New declaration." or just "New".  Also, don't break lines early please,
> especially if that means ending a line in a colon, which then looks as
> if you forgot to write something there.
OK, will update.
>
>>  * config/rs6000/rs6000.cc (rotate_from_leading_zeros_const): New
>>  define for checking simply rotated constant.
>
> "New." or "New definition." or such.
OK, will update.
>
>> +/* Check if C can be rotated from an immediate which contains leading
>> +   zeros at least CLZ.
>
> "Which starts (as 64 bit integer) with at least CLZ bits zero" or such.
Thanks a lot! Will update.
>
>> +  /* xx0..0xx: rotate enough bits firstly, then check case a.  */
>> +  const int rot_bits = HOST_BITS_PER_WIDE_INT - clz + 1;
>> +  unsigned HOST_WIDE_INT rc = (c >> rot_bits) | (c << (clz - 1));
>> +  tz = ctz_hwi (rc);
>> +  if (clz_hwi (rc) + tz >= clz)
>> +return tz + rot_bits;
>
> This could use some more explanation.
OK, thanks, will update.
>
>> +(define_code_iterator eqne [eq ne])
>
>
>> +;; "i == C" ==> "rotl(i,N) == rotl(C,N)"
>> +(define_insn_and_split "*rotate_on_cmpdi"
>> +  [(set (pc)
>> + (if_then_else (eqne (match_operand:DI 1 "gpc_reg_operand" "r")
>
> Wrong indentation.  The ( should be in the same column as the preceding (
> it matches.
Oh, thanks for point this out! Will update.
>
> Setting "pc" to either 0 or 1 is never correct.
>
>> +  "TARGET_POWERPC64 && !reload_completed && can_create_pseudo_p ()
>
> reload_completed in splitters is almost always wrong.  It isn't any
> better if it is in the insn condition of a define_insn_and_split :-)
>
Thanks, 'can_create_pseudo_p' would be ok for this patch.
Or just FAIL, if !can_create_pseudo_p()?

>> +   && num_insns_constant (operands[2], DImode) > 1
>> +   && (rotate_from_leading_zeros_const (~UINTVAL (operands[2]), 49) > 0
>> +   || rotate_from_leading_zeros_const (UINTVAL (operands[2]), 48) > 0)"
>
> There must be a better way to describe this.
Will update this. I'm thinking to replace this with a meaning function,
maybe 'compare_rotate_immediate_p'.

>
>> +  if (rot < 0)
>> +  {
>> + sgn = true;
>> + rot = rotate_from_leading_zeros_const (~C, 49);
>> +  }
>
> Bad indentation.
Will update.
>
>> +  rtx cmp = ne ? gen_rtx_NE (CCmode, cc, const0_rtx)
>> +   : gen_rtx_EQ (CCmode, cc, const0_rtx);
>
>   rtx cmp = gen_rtx_ (...);
>
> (and define a code_attr EQNE to just output the uppercase EQ or NE).
Great! Thanks for always helpful suggestions!
>
> Why is this doing a conditional branch at all?  Unpredictable
> conditional branches are extremely costly.
This optimization needs to check whether the comparison code is ne/eq or
not.  To get the comparison code, we need to check the parent insn of
the 'cmp' insn.  This is why conditional branch patterns in used here.

This patch should not change the information (about prediction) of the
branch insn. I'm  thinking of updating the patch to keep the 'note info
REG_BR_PROB' for the branch instruction.

I will submit the updated patch for review.

>
>> +/* { dg-require-effective-target lp64 } */
>
> arch_ppc64
OK, will update.
>
>> +/* { dg-final { scan-assembler-times "cmpldi" 10  } } */
>> +/* { dg-final { scan-assembler-times "cmpdi" 4  } } */
>> +/* { dg-final { scan-assembler-times "rotldi" 14  } } */
>
> Please use \m and \M .
OK, will update.

Thanks again!

BR,
Jeff (Jiufu)

>
> Thanks,
>
>
> Segher


[PATCH] LoongArch: Fix pr106459 by use HWIT instead of 1UL.

2022-08-24 Thread xuchenghua
From: Chenghua Xu 

gcc/ChangeLog:

PR target/106459
* config/loongarch/loongarch.cc (loongarch_build_integer): Use 
HOST_WIDE_INT.
* config/loongarch/loongarch.h (IMM_REACH): Likewise.
(HWIT_1U): New Defined.
(LU12I_OPERAND): Use HOST_WIDE_INT.
(LU32I_OPERAND): Likewise.
(LU52I_OPERAND): Likewise.
(HWIT_UC_0xFFF): Likwise.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/pr106459.c: New test.
---
 gcc/config/loongarch/loongarch.cc |  6 +++---
 gcc/config/loongarch/loongarch.h  | 15 +--
 gcc/testsuite/gcc.target/loongarch/pr106459.c | 13 +
 3 files changed, 25 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/pr106459.c

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 207ac2762c6..1a33f668f20 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -1500,8 +1500,8 @@ loongarch_build_integer (struct loongarch_integer_op 
*codes,
   bool lu32i[2] = {(value & LU32I_B) == 0, (value & LU32I_B) == LU32I_B};
   bool lu52i[2] = {(value & LU52I_B) == 0, (value & LU52I_B) == LU52I_B};
 
-  int sign31 = (value & (1UL << 31)) >> 31;
-  int sign51 = (value & (1UL << 51)) >> 51;
+  int sign31 = (value & (HOST_WIDE_INT_1U << 31)) >> 31;
+  int sign51 = (value & (HOST_WIDE_INT_1U << 51)) >> 51;
   /* Determine whether the upper 32 bits are sign-extended from the lower
 32 bits. If it is, the instructions to load the high order can be
 ommitted.  */
@@ -1522,7 +1522,7 @@ loongarch_build_integer (struct loongarch_integer_op 
*codes,
 
   /* Determine whether the 52-61 bits are sign-extended from the low order,
 and if not, load the 52-61 bits.  */
-  if (!lu52i[(value & (1ULL << 51)) >> 51])
+  if (!lu52i[(value & (HOST_WIDE_INT_1U << 51)) >> 51])
{
  codes[cost].method = METHOD_LU52I;
  codes[cost].value = value & LU52I_B;
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
index 8b1288961e4..f4a9c329fef 100644
--- a/gcc/config/loongarch/loongarch.h
+++ b/gcc/config/loongarch/loongarch.h
@@ -561,7 +561,8 @@ enum reg_class
   64, 65, 66, 67, 68, 69, 70, 71, 72, 73}
 
 #define IMM_BITS 12
-#define IMM_REACH (1LL << IMM_BITS)
+#define IMM_REACH (HOST_WIDE_INT_1 << IMM_BITS)
+#define HWIT_1U HOST_WIDE_INT_1U
 
 /* True if VALUE is an unsigned 6-bit number.  */
 
@@ -589,18 +590,20 @@ enum reg_class
 /* True if VALUE can be loaded into a register using LU12I.  */
 
 #define LU12I_OPERAND(VALUE) \
-  (((VALUE) | ((1UL << 31) - IMM_REACH)) == ((1UL << 31) - IMM_REACH) \
-   || ((VALUE) | ((1UL << 31) - IMM_REACH)) + IMM_REACH == 0)
+  (((VALUE) | ((HWIT_1U << 31) - IMM_REACH)) == ((HWIT_1U << 31) - IMM_REACH) \
+   || ((VALUE) | ((HWIT_1U << 31) - IMM_REACH)) + IMM_REACH == 0)
 
 /* True if VALUE can be loaded into a register using LU32I.  */
 
 #define LU32I_OPERAND(VALUE) \
-  (((VALUE) | (((1ULL << 19) - 1) << 32)) == (((1ULL << 19) - 1) << 32) \
-   || ((VALUE) | (((1ULL << 19) - 1) << 32)) + (1ULL << 32) == 0)
+  (((VALUE) | (((HWIT_1U << 19) - 1) << 32)) == (((HWIT_1U << 19) - 1) << 32) \
+   || ((VALUE) | (((HWIT_1U << 19) - 1) << 32)) + (HWIT_1U << 32) == 0)
 
 /* True if VALUE can be loaded into a register using LU52I.  */
 
-#define LU52I_OPERAND(VALUE) (((VALUE) | (0xfffULL << 52)) == (0xfffULL << 52))
+#define HWIT_UC_0xFFF HOST_WIDE_INT_UC(0xfff)
+#define LU52I_OPERAND(VALUE) \
+  (((VALUE) | (HWIT_UC_0xFFF << 52)) == (HWIT_UC_0xFFF << 52))
 
 /* Return a value X with the low 12 bits clear, and such that
VALUE - X is a signed 12-bit value.  */
diff --git a/gcc/testsuite/gcc.target/loongarch/pr106459.c 
b/gcc/testsuite/gcc.target/loongarch/pr106459.c
new file mode 100644
index 000..eb737dc49c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr106459.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106459 */
+
+typedef unsigned int UDItype __attribute__((mode(DI)));
+int foo(UDItype x) {
+  x = x & (((UDItype)(((UDItype)(((UDItype)0x0F << 8) | 0x0F) << (2 * 8)) |
+  (((UDItype)0x0F << 8) | 0x0F))
+<< (4 * 8)) |
+   (((UDItype)(((UDItype)0x0F << 8) | 0x0F) << (2 * 8)) |
+(((UDItype)0x0F << 8) | 0x0F)));
+  return x;
+}
-- 
2.31.1



Re: [PATCH] gcov: fix file and function summary information

2022-08-24 Thread Martin Liška
On 8/24/22 09:12, Jørgen Kvalsvik wrote:
> I tested it and get the file summary as expected:
> 
> File 'demo.cc'
> Lines executed:84.62% of 26
> Branches executed:100.00% of 6
> Taken at least once:50.00% of 6
> Calls executed:100.00% of 4
> Creating 'demo.cc.gcov'
> 
> Thanks,
> Jørgen

Great, I've just pushed that as revision r13-2166-g42301c02e458cd.

Cheers,
Martin


Re: [PATCH v3] rs6000: Rework ELFv2 support for -fpatchable-function-entry* [PR99888]

2022-08-24 Thread Kewen.Lin via Gcc-patches
Hi Segher,

on 2022/8/23 22:33, Segher Boessenkool wrote:
> On Fri, Aug 19, 2022 at 10:40:10AM +0800, Kewen.Lin wrote:
>> Since you proposed to update the documentation, I'm thinking if we can
>> reconsider Fangrui's proposal in the PR which Alan seconded: Put preceding
>> nops before GEP and succeeding nops after LEP.  Previously I had the concern
>> that the nops inserted doesn't respect to a same function entry, it looks
>> inconsistent to the documentation, and you also noted that "The nops have
>> to be consecutive".  If we want to update the documentation, could we reword
>> it for PowerPC ELFv2 ABI?
>>
>> What's your opinion?
> 
> I'm not sure what the question is, sorry.
> 

Sorry for confusion.  The question is that if we can consider the proposal
in [1], by noting the particularity on ppc64le in documentation.

btw, I did some searching on why the feature supports preceding nops, and
commented it in [2].

> If you want different semantics for ELFv2 (which might well be useful),
> we need some new command line option for that.
> 

Not sure if we really needs one new command line option, dual entries on
ppc64le is special comparing with a normal unique function entry, couldn't
it be a special case in the documentation?

> I suggested here to just describe in the existing doc what is done for
> global and local entry points on ELFv2.
> 

Yeah, you have suggested nice wordings "For PowerPC with the ELFv2 ABI,
there will be M nops before the local entry point, and N-M after".

I thought if we can consider [1] and updated the documentation similarly
like "For PowerPC with the ELFv2 ABI, there will be M nops before the global
entry point, and N-M after the local entry point".

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99888#c5
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99888#c10

BR,
Kewen


Re: [PATCH] gcov: fix file and function summary information

2022-08-24 Thread Jørgen Kvalsvik



On 22/08/2022 21:25, Martin Liška wrote:

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Jorgen: Can you please test it before I'll install it?

Thanks,
Martin

gcc/ChangeLog:

* gcov.cc (add_line_counts): Add group functions to coverage
summary.
(accumulate_line_counts): Similarly for files.

Co-Authored-By: Jørgen Kvalsvik 
---
  gcc/gcov.cc | 9 -
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/gcc/gcov.cc b/gcc/gcov.cc
index 27be5ff0911..9cf1071166f 100644
--- a/gcc/gcov.cc
+++ b/gcc/gcov.cc
@@ -2694,6 +2694,13 @@ add_line_counts (coverage_info *coverage, function_info 
*fn)
{
  gcc_assert (lines[j] - fn->start_line < fn->lines.size ());
  line = &(fn->lines[lines[j] - fn->start_line]);
+ if (coverage)
+   {
+ if (!line->exists)
+   coverage->lines++;
+ if (!line->count && block->count)
+   coverage->lines_executed++;
+   }
  line->exists = 1;
  if (!block->exceptional)
{
@@ -2815,7 +2822,7 @@ accumulate_line_counts (source_info *src)
   it2 != fn->lines.end (); it2++)
  {
line_info *line = &(*it2);
-   accumulate_line_info (line, src, false);
+   accumulate_line_info (line, src, true);
  }
  }
  


I tested it and get the file summary as expected:

File 'demo.cc'
Lines executed:84.62% of 26
Branches executed:100.00% of 6
Taken at least once:50.00% of 6
Calls executed:100.00% of 4
Creating 'demo.cc.gcov'

Thanks,
Jørgen