public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Strange expl results
@ 2020-11-26 20:20 Alex Markin
  2020-11-26 21:53 ` Stefan Ring
  0 siblings, 1 reply; 10+ messages in thread
From: Alex Markin @ 2020-11-26 20:20 UTC (permalink / raw)
  To: gcc-help

Hello.

I don't know if it is a gcc or binutils problem. I have different results
for `expl' function depending on the argument was variable or literal:

long double c, r1, r2;
r1 = expl(-1);

c = -1;
r2 = expl(c);

In this example r1 and r2 differ in the lower bits. The entire example is
here: https://godbolt.org/z/xqn4bd. The llvm does not have such a problem.

Kind regards,
Aleksey Markin

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-26 20:20 Strange expl results Alex Markin
@ 2020-11-26 21:53 ` Stefan Ring
  2020-11-27  1:27   ` Alex Markin
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Ring @ 2020-11-26 21:53 UTC (permalink / raw)
  To: Alex Markin; +Cc: gcc-help

On Thu, Nov 26, 2020 at 9:21 PM Alex Markin via Gcc-help
<gcc-help@gcc.gnu.org> wrote:
>
> Hello.
>
> I don't know if it is a gcc or binutils problem. I have different results
> for `expl' function depending on the argument was variable or literal:
>
> long double c, r1, r2;
> r1 = expl(-1);
>
> c = -1;
> r2 = expl(c);
>
> In this example r1 and r2 differ in the lower bits. The entire example is
> here: https://godbolt.org/z/xqn4bd. The llvm does not have such a problem.

The reason is that the Intel-specific 80 bit long double format is
used. So the first 80 bits of r1 and r2 contain the value, and the
rest remains uninitialized. You could memset both to 0 first, then the
comparison would check out. I'm sure there is a good reason for sizeof
producing 16, not 10.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-27  1:27   ` Alex Markin
@ 2020-11-26 22:46     ` Stefan Ring
  2020-11-27  7:54       ` Stefan Ring
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Ring @ 2020-11-26 22:46 UTC (permalink / raw)
  To: Alex Markin; +Cc: gcc-help

On Thu, Nov 26, 2020 at 11:27 PM Alex Markin <alexanius@gmail.com> wrote:
>
> memset will not help here.

True, but only because it is optimized away! :D

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-26 21:53 ` Stefan Ring
@ 2020-11-27  1:27   ` Alex Markin
  2020-11-26 22:46     ` Stefan Ring
  0 siblings, 1 reply; 10+ messages in thread
From: Alex Markin @ 2020-11-27  1:27 UTC (permalink / raw)
  To: Stefan Ring; +Cc: gcc-help

The value bits differ, memset will not help here. You can watch the values
in the gdb:

(gdb) n
43          printBits(sizeof(r1), &r1);
(gdb) info locals
c = -1
r1 = 0.36787944117144232158305751367866065
r2 = 0.36787944117144232161016256799079827

пт, 27 нояб. 2020 г. в 00:54, Stefan Ring <stefanrin@gmail.com>:

> On Thu, Nov 26, 2020 at 9:21 PM Alex Markin via Gcc-help
> <gcc-help@gcc.gnu.org> wrote:
> >
> > Hello.
> >
> > I don't know if it is a gcc or binutils problem. I have different results
> > for `expl' function depending on the argument was variable or literal:
> >
> > long double c, r1, r2;
> > r1 = expl(-1);
> >
> > c = -1;
> > r2 = expl(c);
> >
> > In this example r1 and r2 differ in the lower bits. The entire example is
> > here: https://godbolt.org/z/xqn4bd. The llvm does not have such a
> problem.
>
> The reason is that the Intel-specific 80 bit long double format is
> used. So the first 80 bits of r1 and r2 contain the value, and the
> rest remains uninitialized. You could memset both to 0 first, then the
> comparison would check out. I'm sure there is a good reason for sizeof
> producing 16, not 10.
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-26 22:46     ` Stefan Ring
@ 2020-11-27  7:54       ` Stefan Ring
  2020-11-29 16:14         ` Alex Markin
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Ring @ 2020-11-27  7:54 UTC (permalink / raw)
  To: Alex Markin; +Cc: gcc-help

On Thu, Nov 26, 2020 at 11:46 PM Stefan Ring <stefanrin@gmail.com> wrote:
>
> On Thu, Nov 26, 2020 at 11:27 PM Alex Markin <alexanius@gmail.com> wrote:
> >
> > memset will not help here.
>
> True, but only because it is optimized away! :D

With -O2, the compiler pre-computes both of them at compile time, and
they are both the same (but the upper 6 bytes stay uninitialized, even
with memset).

With -O0, the compiler pre-computes the first one and calls the
library function for the second result, which produces a different
result that differs in the last bit.

Which is slightly surprising, but nothing that I lose sleep over...

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-29 16:14         ` Alex Markin
@ 2020-11-29 15:07           ` Florian Weimer
  2020-11-29 18:54             ` Alex Markin
  2020-11-30  9:47           ` Vincent Lefevre
  1 sibling, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2020-11-29 15:07 UTC (permalink / raw)
  To: Alex Markin via Gcc-help; +Cc: Stefan Ring, Alex Markin

* Alex Markin via Gcc-help:

> The problem starts when you have a cross-platform project where on
> the second platform we have a non-gcc compiler and 80-bit float
> calculations on non-intel hardware.

What platform is this?  m68k?

Very few platforms have 80 bit long double.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-27  7:54       ` Stefan Ring
@ 2020-11-29 16:14         ` Alex Markin
  2020-11-29 15:07           ` Florian Weimer
  2020-11-30  9:47           ` Vincent Lefevre
  0 siblings, 2 replies; 10+ messages in thread
From: Alex Markin @ 2020-11-29 16:14 UTC (permalink / raw)
  To: Stefan Ring; +Cc: gcc-help

The problem starts when you have a cross-platform project where on the
second
platform we have a non-gcc compiler and 80-bit float calculations on
non-intel hardware.
That is my case where on the second platform expl calculates in the right
way
and after a sequence of evaluations we get a big error accumulation and the
program
behaviour becomes different.

To my pity I can not find an example on any widespread platform to show the
different
behaviour of expl, so that seems to stay here for a long time.

пт, 27 нояб. 2020 г. в 10:54, Stefan Ring <stefanrin@gmail.com>:

> On Thu, Nov 26, 2020 at 11:46 PM Stefan Ring <stefanrin@gmail.com> wrote:
> >
> > On Thu, Nov 26, 2020 at 11:27 PM Alex Markin <alexanius@gmail.com>
> wrote:
> > >
> > > memset will not help here.
> >
> > True, but only because it is optimized away! :D
>
> With -O2, the compiler pre-computes both of them at compile time, and
> they are both the same (but the upper 6 bytes stay uninitialized, even
> with memset).
>
> With -O0, the compiler pre-computes the first one and calls the
> library function for the second result, which produces a different
> result that differs in the last bit.
>
> Which is slightly surprising, but nothing that I lose sleep over...
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-29 15:07           ` Florian Weimer
@ 2020-11-29 18:54             ` Alex Markin
  0 siblings, 0 replies; 10+ messages in thread
From: Alex Markin @ 2020-11-29 18:54 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Alex Markin via Gcc-help, Stefan Ring

> What platform is this?

The e2k system https://en.wikipedia.org/wiki/Elbrus_2000

вс, 29 нояб. 2020 г. в 18:07, Florian Weimer <fw@deneb.enyo.de>:

> * Alex Markin via Gcc-help:
>
> > The problem starts when you have a cross-platform project where on
> > the second platform we have a non-gcc compiler and 80-bit float
> > calculations on non-intel hardware.
>
> What platform is this?  m68k?
>
> Very few platforms have 80 bit long double.
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-29 16:14         ` Alex Markin
  2020-11-29 15:07           ` Florian Weimer
@ 2020-11-30  9:47           ` Vincent Lefevre
  2020-11-30 13:17             ` Alex Markin
  1 sibling, 1 reply; 10+ messages in thread
From: Vincent Lefevre @ 2020-11-30  9:47 UTC (permalink / raw)
  To: Alex Markin; +Cc: Stefan Ring, gcc-help

On 2020-11-29 19:14:37 +0300, Alex Markin via Gcc-help wrote:
> The problem starts when you have a cross-platform project where on
> the second platform we have a non-gcc compiler and 80-bit float
> calculations on non-intel hardware. That is my case where on the
> second platform expl calculates in the right way and after a
> sequence of evaluations we get a big error accumulation and the
> program behaviour becomes different.

This is not specific to the 80-bit extended precision. Any FP format
may be affected. When the argument is known at compile time, GCC can
optimize and it normally uses GNU MPFR to compute the result with
correct rounding (which is the best possible result and the only
good way to specify the result completely). This means that if the
library does not provide correct rounding, you will get differences
with results computed at compile time (and differences with other
libraries, possibly across different versions of the same library).
You can see a summary of differences between libraries for the
double type (double precision, or binary64) and various functions:

  https://www.vinc17.net/research/testlibm/

These are tests on values that are difficult to round due to the
"Table maker's dilemma". As you can see, for a long time, glibc
was implementing correct rounding for exp and log in particular
(my tests started with glibc 2.2.5, on spe170 in the table), thus
with no differences compared to the compile-time result with GCC
(using MPFR); but this is no longer the case (e.g. with glibc 2.28,
on joooj in the table). This changed in 2018:

commit de800d83059dbedb7d151580f0a3bdc9eaf37340
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   2018-01-30 15:48:22 +0100

    Remove slow paths from exp

commit b7c83ca30ef8e85b6642151d95600a36535f8d97
Author: Wilco Dijkstra <wdijkstr@arm.com>
Date:   2018-02-07 13:24:43 +0100

    Remove slow paths from log

(BTW, reducing the precision of the slow path may have been a better
compromise, with no differences on the results, at least on exp and
log, as I say in the slides mentioned below.)

On https://www.vinc17.net/research/slides/sieste2010.pdf slides 11 to 17
you can see various differences obtained with GCC involving a same
expression.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Strange expl results
  2020-11-30  9:47           ` Vincent Lefevre
@ 2020-11-30 13:17             ` Alex Markin
  0 siblings, 0 replies; 10+ messages in thread
From: Alex Markin @ 2020-11-30 13:17 UTC (permalink / raw)
  To: Alex Markin, Stefan Ring, gcc-help

Thank you and everyone for the explanation!
I'll fix this on my side with extra rounding of the result inside my
project.

пн, 30 нояб. 2020 г. в 12:48, Vincent Lefevre <vincent+gcc@vinc17.org>:

> On 2020-11-29 19:14:37 +0300, Alex Markin via Gcc-help wrote:
> > The problem starts when you have a cross-platform project where on
> > the second platform we have a non-gcc compiler and 80-bit float
> > calculations on non-intel hardware. That is my case where on the
> > second platform expl calculates in the right way and after a
> > sequence of evaluations we get a big error accumulation and the
> > program behaviour becomes different.
>
> This is not specific to the 80-bit extended precision. Any FP format
> may be affected. When the argument is known at compile time, GCC can
> optimize and it normally uses GNU MPFR to compute the result with
> correct rounding (which is the best possible result and the only
> good way to specify the result completely). This means that if the
> library does not provide correct rounding, you will get differences
> with results computed at compile time (and differences with other
> libraries, possibly across different versions of the same library).
> You can see a summary of differences between libraries for the
> double type (double precision, or binary64) and various functions:
>
>   https://www.vinc17.net/research/testlibm/
>
> These are tests on values that are difficult to round due to the
> "Table maker's dilemma". As you can see, for a long time, glibc
> was implementing correct rounding for exp and log in particular
> (my tests started with glibc 2.2.5, on spe170 in the table), thus
> with no differences compared to the compile-time result with GCC
> (using MPFR); but this is no longer the case (e.g. with glibc 2.28,
> on joooj in the table). This changed in 2018:
>
> commit de800d83059dbedb7d151580f0a3bdc9eaf37340
> Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
> Date:   2018-01-30 15:48:22 +0100
>
>     Remove slow paths from exp
>
> commit b7c83ca30ef8e85b6642151d95600a36535f8d97
> Author: Wilco Dijkstra <wdijkstr@arm.com>
> Date:   2018-02-07 13:24:43 +0100
>
>     Remove slow paths from log
>
> (BTW, reducing the precision of the slow path may have been a better
> compromise, with no differences on the results, at least on exp and
> log, as I say in the slides mentioned below.)
>
> On https://www.vinc17.net/research/slides/sieste2010.pdf slides 11 to 17
> you can see various differences obtained with GCC involving a same
> expression.
>
> --
> Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-11-30 10:17 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-26 20:20 Strange expl results Alex Markin
2020-11-26 21:53 ` Stefan Ring
2020-11-27  1:27   ` Alex Markin
2020-11-26 22:46     ` Stefan Ring
2020-11-27  7:54       ` Stefan Ring
2020-11-29 16:14         ` Alex Markin
2020-11-29 15:07           ` Florian Weimer
2020-11-29 18:54             ` Alex Markin
2020-11-30  9:47           ` Vincent Lefevre
2020-11-30 13:17             ` Alex Markin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).