"Joseph Myers" <jos...@codesourcery.com> wrote:

> On Fri, 30 Jul 2021, Stefan Kanthak wrote:
> 
>> Joseph Myers <jos...@codesourcery.com> wrote:
>> 
>> > None of these are valid constant expressions as defined by the standard 
>> > (constant expressions cannot involve evaluated function calls).
>> 
>> That's why I ask specifically why GCC bugs on log(log(...)), but not on
>> log(sqrt(...) ...)!
> 
> The log(log(1.0)) example you gave would raise divide-by-zero.

ARGH, my SILLY fault: I named the first constant "euler" since it should
of course be set to 2.71..., i.e. this line should have read

const double euler = exp(1.0);

Unfortunately I wrote but log(1.0) there and introduced the divide-by-zero.
Sorry for the confusion.

JFTR; in order to provide a short repro, I stripped down a larger program
      where the values of a

static const double table[] = {log2(0.0), ...};

      were to be initialized with several logarithms, which but failed.
      And while stripping it down, I introduced this bug.-(

>> > Some might be accepted as an extension, but I expect that since the 
>> > optimization for constant arguments is intended for valid calls that
>> > would otherwise be executed at runtime, not for static initializers,
>> > it's avoiding optimizations that would result in the loss of floating-
>> > point exception flag raising.
>> 
>> That's no valid excuse: by the standard, the compiler is free to execute
>> static initializers during runtime, before calling the main() routine.
> 
> The point of this extension isn't to accept as much as possible.

I expected it the other way 'round.

> Rather, it turned out when I implemented standard constant expression rules 
> for GCC 4.5 that lots of existing code was using just about anything GCC 
> could fold into a constant in just about any context requiring a constant 
> expression.  So for compatibility with existing, questionable, pre-GCC-4.5 
> code, we still allow "expressions that can be folded into a constant" in 
> various such contexts, with a pedwarn-if-pedantic.  But because this 
> isn't a designed, documented extension or something it's actually considered 
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OK. I searched the docs of course before I wrote in, and only asked because
I couldn't find anything about this (non-standard) feature.

> good practice to use, the semantics remain "expressions that can be folded 
> into a constant", with all the dependence that implies on the folding GCC 
> does for optimization purposes - and that folding is designed for 
> optimizing code outside of static initializers, not for use in this 
> extension, with all the corresponding implications for its design.
> 
> So if some expression doesn't get folded to a constant outside of static 
> initializers (or for that matter, if it does get so folded, but previous 
> GCC versions didn't accept it in static initializers, since this extension 
> is about compatibility with existing code), it's not a bug for it not to 
> be accepted in a static initializer.

Thanks for the clarification.

> If, outside of static initializers, some of these expressions don't get 
> folded to a constant *even with -fno-trapping-math*, that's a missed 
> optimization and it would make sense to improve the compiler to fold them 
> given -fno-trapping-math.

In order to get the larger program compiled, I defined the table inside
the function which consumed it:

double function(...)
{
    const double table[] = {log2(0.0), ...};

    ...
}

GCC evaluated almost all logarithms during compile time and placed them
in the .rodata section.

BUT: instead to transfer these precomputed constants in the prolog of
     this function with a call to memcpy() from .rodata to the stack,
     GCC created a whole lot of

     movq  .LC1...(%rip), %xmm0
     movq  %xmm0, offset(%rsp)

     instruction pairs ... one for each precomputed constant.
     I expected GCC to be a LITTLE smarter there...

> Executing static initializers at runtime seems more like a C++ thing; it's 
> not within the conventional concept of how C maps to object files.

regards
Stefan

Reply via email to