Re: GCC [RFC] Whole Program Devirtualization

2021-08-21 Thread Jonathan Wakely via Gcc
On Fri, 20 Aug 2021, 13:37 Basile Starynkevitch, 
wrote:

>
> *computed gotos* or *labels as values* (see
> https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
>  for more) are
> making this difficult. But they do exist, and probably could be hidden
> in GNU glibc or libstdc++ internal code.
>

There are none in libstdc++.


On(c)e more: optimizer failure

2021-08-21 Thread Stefan Kanthak
Hi,

the following snippet is from the nextafter() function of


--- repro.c ---
#define Zero 0.0
double nextafter(double argx, double argy)
{
double z = argx;

if (isnan(argx) || isnan(argy)) return argx + argy;

if (argx == argy) return argx;

if (argx != Zero)
if (((argx < Zero) && (argx < argy))
 || ((argx > Zero) && (argx > argy)))
z += 1.0;
else
z -= 1.0;
return z;
}
--- EOF ---

I expect that GCC knows DeMorgan's rules and is able to
simplify/optimize the last if-statement to

if ((argx < Zero) == (argx < argy))

Unfortunately GCC fails to do so: see the lines from
label .L20: to label L7

$ gcc -m64 -O3 -o- -S
...
nextafter:
ucomisd %xmm1, %xmm0
jp  .L19
pxor%xmm2, %xmm2
movl$1, %edx
ucomisd %xmm2, %xmm0
setp%al
cmovne  %edx, %eax
testb   %al, %al
je  .L3
ucomisd %xmm1, %xmm0
setp%al
cmove   %eax, %edx
testb   %dl, %dl
jne .L20
.L3:
ret
.L20:
comisd  %xmm0, %xmm2
ja  .L21
.L4:
comisd  %xmm2, %xmm0
jbe .L7
comisd  %xmm1, %xmm0
jbe .L7
.L6:
addsd   .LC1(%rip), %xmm0
ret
.L21:
comisd  %xmm0, %xmm1
ja  .L6
jmp .L4
.L7:
subsd   .LC1(%rip), %xmm0
ret
.L19:
addsd   %xmm1, %xmm0
ret
.LC1:
.long   0
.long   1072693248

Stefan


Re: On(c)e more: optimizer failure

2021-08-21 Thread Matt Godbolt
I believe your example doesn't take into account that the values can be NaN
which compares false in all situations. If you allow the compiler to
optimize without supporting NaN (-ffast-math), I think it generates the
code you want: https://godbolt.org/z/1ra7zcsnd

--matt

On Sat, Aug 21, 2021 at 1:59 PM Stefan Kanthak 
wrote:

> Hi,
>
> the following snippet is from the nextafter() function of
> 
>
> --- repro.c ---
> #define Zero 0.0
> double nextafter(double argx, double argy)
> {
> double z = argx;
>
> if (isnan(argx) || isnan(argy)) return argx + argy;
>
> if (argx == argy) return argx;
>
> if (argx != Zero)
> if (((argx < Zero) && (argx < argy))
>  || ((argx > Zero) && (argx > argy)))
> z += 1.0;
> else
> z -= 1.0;
> return z;
> }
> --- EOF ---
>
> I expect that GCC knows DeMorgan's rules and is able to
> simplify/optimize the last if-statement to
>
> if ((argx < Zero) == (argx < argy))
>
> Unfortunately GCC fails to do so: see the lines from
> label .L20: to label L7
>
> $ gcc -m64 -O3 -o- -S
> ...
> nextafter:
> ucomisd %xmm1, %xmm0
> jp  .L19
> pxor%xmm2, %xmm2
> movl$1, %edx
> ucomisd %xmm2, %xmm0
> setp%al
> cmovne  %edx, %eax
> testb   %al, %al
> je  .L3
> ucomisd %xmm1, %xmm0
> setp%al
> cmove   %eax, %edx
> testb   %dl, %dl
> jne .L20
> .L3:
> ret
> .L20:
> comisd  %xmm0, %xmm2
> ja  .L21
> .L4:
> comisd  %xmm2, %xmm0
> jbe .L7
> comisd  %xmm1, %xmm0
> jbe .L7
> .L6:
> addsd   .LC1(%rip), %xmm0
> ret
> .L21:
> comisd  %xmm0, %xmm1
> ja  .L6
> jmp .L4
> .L7:
> subsd   .LC1(%rip), %xmm0
> ret
> .L19:
> addsd   %xmm1, %xmm0
> ret
> .LC1:
> .long   0
> .long   1072693248
>
> Stefan
>


-- 
Matt
(he/him)


Re: On(c)e more: optimizer failure

2021-08-21 Thread Stefan Kanthak
Matt Godbolt  wrote:

> I believe your example doesn't take into account that the values can be NaN
> which compares false in all situations.

That's a misbelief!
Please notice the first if-clause, which rules out NaNs for both arguments.
Also notice that GCC did NOT generate JP after the 4 COMISD instructions
in question, i.e. it knew that NaNs had been ruled out.
I included the 3 initial if-clauses just to give GCC enough rope to hang 
himself.

> If you allow the compiler to
> optimize without supporting NaN (-ffast-math), I think it generates the
> code you want: https://godbolt.org/z/1ra7zcsnd

Replace
 if (isnan(argx) || isnan(argy)) return argx + argy;
with
 if ((argx != argx) || (argy != argy)) return argx + argy;
then feed the changed snippet to compiler explorer again, with and without
-ffast-math

Stefan
 
> --matt
> 
> On Sat, Aug 21, 2021 at 1:59 PM Stefan Kanthak 
> wrote:
> 
>> Hi,
>>
>> the following snippet is from the nextafter() function of
>> 
>>
>> --- repro.c ---
>> #define Zero 0.0
>> double nextafter(double argx, double argy)
>> {
>> double z = argx;
>>
>> if (isnan(argx) || isnan(argy)) return argx + argy;
>>
>> if (argx == argy) return argx;
>>
>> if (argx != Zero)
>> if (((argx < Zero) && (argx < argy))
>>  || ((argx > Zero) && (argx > argy)))
>> z += 1.0;
>> else
>> z -= 1.0;
>> return z;
>> }
>> --- EOF ---
>>
>> I expect that GCC knows DeMorgan's rules and is able to
>> simplify/optimize the last if-statement to
>>
>> if ((argx < Zero) == (argx < argy))
>>
>> Unfortunately GCC fails to do so: see the lines from
>> label .L20: to label L7
>>
>> $ gcc -m64 -O3 -o- -S
>> ...
>> nextafter:
>> ucomisd %xmm1, %xmm0
>> jp  .L19
>> pxor%xmm2, %xmm2
>> movl$1, %edx
>> ucomisd %xmm2, %xmm0
>> setp%al
>> cmovne  %edx, %eax
>> testb   %al, %al
>> je  .L3
>> ucomisd %xmm1, %xmm0
>> setp%al
>> cmove   %eax, %edx
>> testb   %dl, %dl
>> jne .L20
>> .L3:
>> ret
>> .L20:
>> comisd  %xmm0, %xmm2
>> ja  .L21
>> .L4:
>> comisd  %xmm2, %xmm0
>> jbe .L7
>> comisd  %xmm1, %xmm0
>> jbe .L7
>> .L6:
>> addsd   .LC1(%rip), %xmm0
>> ret
>> .L21:
>> comisd  %xmm0, %xmm1
>> ja  .L6
>> jmp .L4
>> .L7:
>> subsd   .LC1(%rip), %xmm0
>> ret
>> .L19:
>> addsd   %xmm1, %xmm0
>> ret
>> .LC1:
>> .long   0
>> .long   1072693248
>>
>> Stefan
>>
> 
> 
> -- 
> Matt
> (he/him)
>


Re: On(c)e more: optimizer failure

2021-08-21 Thread Matt Godbolt
Ok! Thanks; sorry for the misunderstanding on my side.

--matt

On Sat, Aug 21, 2021 at 2:53 PM Stefan Kanthak 
wrote:

> Matt Godbolt  wrote:
>
> > I believe your example doesn't take into account that the values can be
> NaN
> > which compares false in all situations.
>
> That's a misbelief!
> Please notice the first if-clause, which rules out NaNs for both arguments.
> Also notice that GCC did NOT generate JP after the 4 COMISD instructions
> in question, i.e. it knew that NaNs had been ruled out.
> I included the 3 initial if-clauses just to give GCC enough rope to hang
> himself.
>
> > If you allow the compiler to
> > optimize without supporting NaN (-ffast-math), I think it generates the
> > code you want: https://godbolt.org/z/1ra7zcsnd
>
> Replace
>  if (isnan(argx) || isnan(argy)) return argx + argy;
> with
>  if ((argx != argx) || (argy != argy)) return argx + argy;
> then feed the changed snippet to compiler explorer again, with and without
> -ffast-math
>
> Stefan
>
> > --matt
> >
> > On Sat, Aug 21, 2021 at 1:59 PM Stefan Kanthak 
> > wrote:
> >
> >> Hi,
> >>
> >> the following snippet is from the nextafter() function of
> >> 
> >>
> >> --- repro.c ---
> >> #define Zero 0.0
> >> double nextafter(double argx, double argy)
> >> {
> >> double z = argx;
> >>
> >> if (isnan(argx) || isnan(argy)) return argx + argy;
> >>
> >> if (argx == argy) return argx;
> >>
> >> if (argx != Zero)
> >> if (((argx < Zero) && (argx < argy))
> >>  || ((argx > Zero) && (argx > argy)))
> >> z += 1.0;
> >> else
> >> z -= 1.0;
> >> return z;
> >> }
> >> --- EOF ---
> >>
> >> I expect that GCC knows DeMorgan's rules and is able to
> >> simplify/optimize the last if-statement to
> >>
> >> if ((argx < Zero) == (argx < argy))
> >>
> >> Unfortunately GCC fails to do so: see the lines from
> >> label .L20: to label L7
> >>
> >> $ gcc -m64 -O3 -o- -S
> >> ...
> >> nextafter:
> >> ucomisd %xmm1, %xmm0
> >> jp  .L19
> >> pxor%xmm2, %xmm2
> >> movl$1, %edx
> >> ucomisd %xmm2, %xmm0
> >> setp%al
> >> cmovne  %edx, %eax
> >> testb   %al, %al
> >> je  .L3
> >> ucomisd %xmm1, %xmm0
> >> setp%al
> >> cmove   %eax, %edx
> >> testb   %dl, %dl
> >> jne .L20
> >> .L3:
> >> ret
> >> .L20:
> >> comisd  %xmm0, %xmm2
> >> ja  .L21
> >> .L4:
> >> comisd  %xmm2, %xmm0
> >> jbe .L7
> >> comisd  %xmm1, %xmm0
> >> jbe .L7
> >> .L6:
> >> addsd   .LC1(%rip), %xmm0
> >> ret
> >> .L21:
> >> comisd  %xmm0, %xmm1
> >> ja  .L6
> >> jmp .L4
> >> .L7:
> >> subsd   .LC1(%rip), %xmm0
> >> ret
> >> .L19:
> >> addsd   %xmm1, %xmm0
> >> ret
> >> .LC1:
> >> .long   0
> >> .long   1072693248
> >>
> >> Stefan
> >>
> >
> >
> > --
> > Matt
> > (he/him)
> >
>


-- 
Matt
(he/him)


Re: On(c)e more: optimizer failure

2021-08-21 Thread Jakub Jelinek via Gcc
On Sat, Aug 21, 2021 at 09:40:16PM +0200, Stefan Kanthak wrote:
> > I believe your example doesn't take into account that the values can be NaN
> > which compares false in all situations.
> 
> That's a misbelief!
> Please notice the first if-clause, which rules out NaNs for both arguments.
> Also notice that GCC did NOT generate JP after the 4 COMISD instructions
> in question, i.e. it knew that NaNs had been ruled out.

GCC doesn't do value range propagation of floating point values, not even
the special ones like NaNs, infinities, +/- zeros etc., and without that the
earlier ifs aren't taken into account for the earlier code.

Also, as you have been told already, sending these mails to gcc mailing list
is a very bad idea, unless somebody jumps on it immediately and implements
it, they will be effectively forgotten.  You should file missed
optimizations into gcc bugzilla where they can be seen any time.

Jakub



Re: On(c)e more: optimizer failure

2021-08-21 Thread Stefan Kanthak
Jakub Jelinek  wrote:

> On Sat, Aug 21, 2021 at 09:40:16PM +0200, Stefan Kanthak wrote:
>> > I believe your example doesn't take into account that the values can be NaN
>> > which compares false in all situations.
>> 
>> That's a misbelief!
>> Please notice the first if-clause, which rules out NaNs for both arguments.
>> Also notice that GCC did NOT generate JP after the 4 COMISD instructions
>> in question, i.e. it knew that NaNs had been ruled out.
> 
> GCC doesn't do value range propagation of floating point values, not even
> the special ones like NaNs, infinities, +/- zeros etc., and without that the
> earlier ifs aren't taken into account for the earlier code.

Ouch, to bad! That was but the very least expectation I had.
And indeed, removing the 3 other if-clauses doesn't change how the
final if-clause gets translated.

Sorry Matt, we were both wrong with our assumptions.

> Also, as you have been told already, sending these mails to gcc mailing list
> is a very bad idea, unless somebody jumps on it immediately and implements
> it, they will be effectively forgotten.  You should file missed
> optimizations into gcc bugzilla where they can be seen any time.

I don't have a bugzilla account, and I don't use GCC for anything serious.

Stefan


gcc-11-20210821 is now available

2021-08-21 Thread GCC Administrator via Gcc
Snapshot gcc-11-20210821 is now available on
  https://gcc.gnu.org/pub/gcc/snapshots/11-20210821/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 11 git branch
with the following options: git://gcc.gnu.org/git/gcc.git branch 
releases/gcc-11 revision 2e90914b79dd1c591c8a4d663ae2319fbb15df2c

You'll find:

 gcc-11-20210821.tar.xz   Complete GCC

  SHA256=2a9ea34ed83fe0f32f033f0afff736f222bdc6b89d31d612f35f982f1c13a382
  SHA1=cbd897714b007d2ff0ea2cfc522f70c3e3266278

Diffs from 11-20210814 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-11
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


Re: On(c)e more: optimizer failure

2021-08-21 Thread Gabriel Ravier via Gcc

On 8/21/21 10:19 PM, Stefan Kanthak wrote:

Jakub Jelinek  wrote:


On Sat, Aug 21, 2021 at 09:40:16PM +0200, Stefan Kanthak wrote:

I believe your example doesn't take into account that the values can be NaN
which compares false in all situations.

That's a misbelief!
Please notice the first if-clause, which rules out NaNs for both arguments.
Also notice that GCC did NOT generate JP after the 4 COMISD instructions
in question, i.e. it knew that NaNs had been ruled out.

GCC doesn't do value range propagation of floating point values, not even
the special ones like NaNs, infinities, +/- zeros etc., and without that the
earlier ifs aren't taken into account for the earlier code.

Ouch, to bad! That was but the very least expectation I had.
And indeed, removing the 3 other if-clauses doesn't change how the
final if-clause gets translated.

Sorry Matt, we were both wrong with our assumptions.


Also, as you have been told already, sending these mails to gcc mailing list
is a very bad idea, unless somebody jumps on it immediately and implements
it, they will be effectively forgotten.  You should file missed
optimizations into gcc bugzilla where they can be seen any time.

I don't have a bugzilla account, and I don't use GCC for anything serious.

Stefan


It's *that* demanding for you to create a Bugzilla account ? From my 
experience, creating a Bugzilla account takes around 30 seconds (though 
I suppose you'd have to wait for a bit if automatic account creation is 
temporarily disabled), it quite honestly feels as though you've spent 
far more time writing out these e-mails and talking here on the mailing 
list than that.


On Bugzilla I've had some optimization bug reports of mine take months 
to get a response and more to get fixed, but at least something happened 
after a while: if I just went on the mailing list it's incredibly likely 
they'd have been completely and utterly lost to time (it's not that GCC 
devs don't like the mailing list, but there's a reason a *bug tracking 
system* is used...)