Bad interaction between gcc and glibc's handling of GNU extension [GCC PR 115724]

2024-07-02 Thread David Malcolm via Gcc
Back in 2007 glibc gained some logic to implement "error" and
"error_at_line" by splitting into zero and non-zero cases, with the
nonzero case calling a "noreturn" function [1].

This doesn't seem to work. I tested back to 4.8.1 with Compiler
Explorer [2], which seems to be the earliest GCC that supports -fdump-
tree-original=stderr.

What happens is that glibc's 

__extern_always_inline void
error (int __status, int __errnum, const char *__format, ...)
{
  if (__builtin_constant_p (__status) && __status != 0)
__error_noreturn (__status, __errnum, __format, __va_arg_pack ());
  else
__error_alias (__status, __errnum, __format, __va_arg_pack ());
}

comes out of GCC's C frontend as:

{
  if (0)
{
  __error_noreturn (__status, __errnum, __format, __builtin_va_arg_pack ());
}
  else
{
  __error_alias (__status, __errnum, __format, __builtin_va_arg_pack ());
}
}

since __status is not a builtin constant, and this rapidly gets
optimized down to just:

  __error_alias (__status, __errnum, __format, __builtin_va_arg_pack ());

and so by the time GCC gets to try inlining calls to

  error (EXIT_FAILURE, ...etc

we just have a call to __error_alias, and any "noreturn" logic is lost.

glib'c attempt to specialize the cases is causing false positives from
GCC's -fanalyzer, which is how I spotted this [3].  It's probably
trivial to workaround the issue within -fanalyzer, but I wonder to what
extent glibc has further such specializations being thwarted by gcc
optimizing away the __builtin_constant_p, and if gcc should be doing
this (e.g. keep it around for __always_inline__ functions???), hence I
thought it worth sharing this to both mailing lists.

Thoughts?

Dave

[1] ("Specializations of error functions"
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=fae56ce808e36e8112d15189bf4337b3a39ee683
[2] https://godbolt.org/z/WsvqxP6hY
[3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115724



Re: Bad interaction between gcc and glibc's handling of GNU extension [GCC PR 115724]

2024-07-02 Thread Jakub Jelinek via Gcc
On Tue, Jul 02, 2024 at 12:54:09PM -0400, David Malcolm via Gcc wrote:
> Back in 2007 glibc gained some logic to implement "error" and
> "error_at_line" by splitting into zero and non-zero cases, with the
> nonzero case calling a "noreturn" function [1].
> 
> This doesn't seem to work. I tested back to 4.8.1 with Compiler
> Explorer [2], which seems to be the earliest GCC that supports -fdump-
> tree-original=stderr.
> 
> What happens is that glibc's 
> 
> __extern_always_inline void
> error (int __status, int __errnum, const char *__format, ...)
> {
>   if (__builtin_constant_p (__status) && __status != 0)
> __error_noreturn (__status, __errnum, __format, __va_arg_pack ());
>   else
> __error_alias (__status, __errnum, __format, __va_arg_pack ());
> }
> 
> comes out of GCC's C frontend as:
> 
> {
>   if (0)
> {
>   __error_noreturn (__status, __errnum, __format, __builtin_va_arg_pack 
> ());
> }
>   else
> {
>   __error_alias (__status, __errnum, __format, __builtin_va_arg_pack ());
> }
> }
> 
> since __status is not a builtin constant,

At -O0 sure, that is how __builtin_constant_p works.
The above is intended for optimized compilation, and I think it works just
fine then.
The fact that in some cases the function after optimization appears to be
noreturn isn't something one can really rely on, just pass a function
parameter or something that will not optimize into a constant and it will be
fallthrough as well...

Jakub



Re: Bad interaction between gcc and glibc's handling of GNU extension [GCC PR 115724]

2024-07-02 Thread David Malcolm via Gcc
On Tue, 2024-07-02 at 19:02 +0200, Jakub Jelinek wrote:
> On Tue, Jul 02, 2024 at 12:54:09PM -0400, David Malcolm via Gcc
> wrote:
> > Back in 2007 glibc gained some logic to implement "error" and
> > "error_at_line" by splitting into zero and non-zero cases, with the
> > nonzero case calling a "noreturn" function [1].
> > 
> > This doesn't seem to work. I tested back to 4.8.1 with Compiler
> > Explorer [2], which seems to be the earliest GCC that supports -
> > fdump-
> > tree-original=stderr.
> > 
> > What happens is that glibc's 
> > 
> > __extern_always_inline void
> > error (int __status, int __errnum, const char *__format, ...)
> > {
> >   if (__builtin_constant_p (__status) && __status != 0)
> >     __error_noreturn (__status, __errnum, __format, __va_arg_pack
> > ());
> >   else
> >     __error_alias (__status, __errnum, __format, __va_arg_pack ());
> > }
> > 
> > comes out of GCC's C frontend as:
> > 
> > {
> >   if (0)
> >     {
> >   __error_noreturn (__status, __errnum, __format,
> > __builtin_va_arg_pack ());
> >     }
> >   else
> >     {
> >   __error_alias (__status, __errnum, __format,
> > __builtin_va_arg_pack ());
> >     }
> > }
> > 
> > since __status is not a builtin constant,
> 
> At -O0 sure, that is how __builtin_constant_p works.

Aha!  That's what I was missing.

> The above is intended for optimized compilation, and I think it works
> just
> fine then.

Indeed it does.

Sorry for the noise.
Dave

> The fact that in some cases the function after optimization appears
> to be
> noreturn isn't something one can really rely on, just pass a function
> parameter or something that will not optimize into a constant and it
> will be
> fallthrough as well...
> 
> Jakub
> 



Re: Bad interaction between gcc and glibc's handling of GNU extension [GCC PR 115724]

2024-07-02 Thread Florian Weimer
* Jakub Jelinek:

> On Tue, Jul 02, 2024 at 12:54:09PM -0400, David Malcolm via Gcc wrote:
>> Back in 2007 glibc gained some logic to implement "error" and
>> "error_at_line" by splitting into zero and non-zero cases, with the
>> nonzero case calling a "noreturn" function [1].
>> 
>> This doesn't seem to work. I tested back to 4.8.1 with Compiler
>> Explorer [2], which seems to be the earliest GCC that supports -fdump-
>> tree-original=stderr.
>> 
>> What happens is that glibc's 
>> 
>> __extern_always_inline void
>> error (int __status, int __errnum, const char *__format, ...)
>> {
>>   if (__builtin_constant_p (__status) && __status != 0)
>> __error_noreturn (__status, __errnum, __format, __va_arg_pack ());
>>   else
>> __error_alias (__status, __errnum, __format, __va_arg_pack ());
>> }
>> 
>> comes out of GCC's C frontend as:
>> 
>> {
>>   if (0)
>> {
>>   __error_noreturn (__status, __errnum, __format, __builtin_va_arg_pack 
>> ());
>> }
>>   else
>> {
>>   __error_alias (__status, __errnum, __format, __builtin_va_arg_pack ());
>> }
>> }
>> 
>> since __status is not a builtin constant,
>
> At -O0 sure, that is how __builtin_constant_p works.
> The above is intended for optimized compilation, and I think it works just
> fine then.

And it's generally needed with optimization only, to suppress warnings
in unreachable code that only happen when optimization is turned on.


Re: I have questions regarding the 4.3 codebase...

2024-07-02 Thread Sid Maxwell via Gcc
I have another gcc 4.3 question.  I'm trying to find where in the code base
the instrumentation for basic block coverage is done.  I've tracked down
where/how mcount() calls are generated, but I haven't even been able to
determine what function(s) are called to increment a basic block's count.
I'd also like to find more detailed information regarding profiling,
coverage, and function instrumentation.

On Wed, Mar 22, 2023 at 6:27 PM Sid Maxwell  wrote:

> Is there anyone on the list with experience with the gcc 4.3 codebase?
> I'm currently maintaining a fork of it, with a PDP10 code generator.
>
> I've run into an issue involving the transformation of a movmemhi to a
> single PDP10 instruction (an xblt, if you're curious).
> The transformation appears to 'lose' its knowledge of being a store,
> resulting in certain following stores being declared dead, and code
> motion that shouldn't happen (e.g. a load moved before the xblt that
> depends on the result of the xblt).
>
> I'm hoping to find someone who can help me diagnose the problem.  We want
> to use this instruction rather than the copy-word-loop currently generated
> for struct assignments.
>
> Thanks, in advance, for any assistance.
>
> -+- Sid Maxwell
>


Re: Bad interaction between gcc and glibc's handling of GNU extension [GCC PR 115724]

2024-07-02 Thread David Malcolm via Gcc
On Tue, 2024-07-02 at 21:21 +0200, Florian Weimer wrote:
> * Jakub Jelinek:
> 
> > On Tue, Jul 02, 2024 at 12:54:09PM -0400, David Malcolm via Gcc
> > wrote:
> > > Back in 2007 glibc gained some logic to implement "error" and
> > > "error_at_line" by splitting into zero and non-zero cases, with
> > > the
> > > nonzero case calling a "noreturn" function [1].
> > > 
> > > This doesn't seem to work. I tested back to 4.8.1 with Compiler
> > > Explorer [2], which seems to be the earliest GCC that supports -
> > > fdump-
> > > tree-original=stderr.
> > > 
> > > What happens is that glibc's 
> > > 
> > > __extern_always_inline void
> > > error (int __status, int __errnum, const char *__format, ...)
> > > {
> > >   if (__builtin_constant_p (__status) && __status != 0)
> > >     __error_noreturn (__status, __errnum, __format, __va_arg_pack
> > > ());
> > >   else
> > >     __error_alias (__status, __errnum, __format, __va_arg_pack
> > > ());
> > > }
> > > 
> > > comes out of GCC's C frontend as:
> > > 
> > > {
> > >   if (0)
> > >     {
> > >   __error_noreturn (__status, __errnum, __format,
> > > __builtin_va_arg_pack ());
> > >     }
> > >   else
> > >     {
> > >   __error_alias (__status, __errnum, __format,
> > > __builtin_va_arg_pack ());
> > >     }
> > > }
> > > 
> > > since __status is not a builtin constant,
> > 
> > At -O0 sure, that is how __builtin_constant_p works.
> > The above is intended for optimized compilation, and I think it
> > works just
> > fine then.
> 
> And it's generally needed with optimization only, to suppress
> warnings
> in unreachable code that only happen when optimization is turned on.

Indeed - and that's why -fanalyzer ran into it at -O0.

I'm testing a fix.

Thanks
Dave



gmplib.org Down

2024-07-02 Thread Joel Sherrill via Gcc
Hi

In the RTEMS Source Builder, we fetch GMP directly from gmplib.org. It has
been down a few hours.

We have been telling people to either fetch it from ftp.gnu.org or
http://gcc.gnu.org/pub/gcc/infrastructure/ for now.

Does anyone have any insight into gmplib.org being down? Is there any
reason to think it won't be back up soon? We can switch where the scripts
fetch packages if there is a reason to be concerned.

Thanks.

--joel
RTEMS


Re: Bad interaction between gcc and glibc's handling of GNU extension [GCC PR 115724]

2024-07-02 Thread Mark Wielaard
Hi David,

On Tue, Jul 02, 2024 at 03:57:58PM -0400, David Malcolm wrote:
> > > At -O0 sure, that is how __builtin_constant_p works.
> > > The above is intended for optimized compilation, and I think it
> > > works just fine then.
> > 
> > And it's generally needed with optimization only, to suppress
> > warnings
> > in unreachable code that only happen when optimization is turned on.
> 
> Indeed - and that's why -fanalyzer ran into it at -O0.

Various -fanalyzer sub-options say something like "optimization should
be disabled when attempting to trigger this diagnostic".

Is there an "optimal" optimization level for -fanalyzer (like having
-Og for debugging)?

Thanks,

Mark


Re: Bad interaction between gcc and glibc's handling of GNU extension [GCC PR 115724]

2024-07-02 Thread David Malcolm via Gcc
On Tue, 2024-07-02 at 22:39 +0200, Mark Wielaard wrote:
> Hi David,
> 
> On Tue, Jul 02, 2024 at 03:57:58PM -0400, David Malcolm wrote:
> > > > At -O0 sure, that is how __builtin_constant_p works.
> > > > The above is intended for optimized compilation, and I think it
> > > > works just fine then.
> > > 
> > > And it's generally needed with optimization only, to suppress
> > > warnings
> > > in unreachable code that only happen when optimization is turned
> > > on.
> > 
> > Indeed - and that's why -fanalyzer ran into it at -O0.
> 
> Various -fanalyzer sub-options say something like "optimization
> should
> be disabled when attempting to trigger this diagnostic".
> 
> Is there an "optimal" optimization level for -fanalyzer (like having
> -Og for debugging)?

There isn't, sorry.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111312 for a
discussion of this.

Dave



Re: I have questions regarding the 4.3 codebase...

2024-07-02 Thread Richard Biener via Gcc
On Tue, Jul 2, 2024 at 9:26 PM Sid Maxwell via Gcc  wrote:
>
> I have another gcc 4.3 question.  I'm trying to find where in the code base
> the instrumentation for basic block coverage is done.  I've tracked down
> where/how mcount() calls are generated, but I haven't even been able to
> determine what function(s) are called to increment a basic block's count.
> I'd also like to find more detailed information regarding profiling,
> coverage, and function instrumentation.

Look into gcc/tree-profile.c

> On Wed, Mar 22, 2023 at 6:27 PM Sid Maxwell  wrote:
>
> > Is there anyone on the list with experience with the gcc 4.3 codebase?
> > I'm currently maintaining a fork of it, with a PDP10 code generator.
> >
> > I've run into an issue involving the transformation of a movmemhi to a
> > single PDP10 instruction (an xblt, if you're curious).
> > The transformation appears to 'lose' its knowledge of being a store,
> > resulting in certain following stores being declared dead, and code
> > motion that shouldn't happen (e.g. a load moved before the xblt that
> > depends on the result of the xblt).
> >
> > I'm hoping to find someone who can help me diagnose the problem.  We want
> > to use this instruction rather than the copy-word-loop currently generated
> > for struct assignments.
> >
> > Thanks, in advance, for any assistance.
> >
> > -+- Sid Maxwell
> >