public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/60413] New: extra precision not properly removed on assignment of return value
@ 2014-03-04 15:16 desrt at desrt dot ca
  2014-03-04 16:14 ` [Bug c/60413] " jakub at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: desrt at desrt dot ca @ 2014-03-04 15:16 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60413

            Bug ID: 60413
           Summary: extra precision not properly removed on assignment of
                    return value
           Product: gcc
           Version: 4.8.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: desrt at desrt dot ca

This problem has been seen with at least:

  gcc version 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC) 

and

  gcc version 4.8.2 (Ubuntu 4.8.2-16ubuntu4)

so I believe it to be an upstream problem.

This problem has only been observed to happen on 32bit compilations.  There
doesn't seem to be a problem with 64bit.

Consider this code:

==> get-value.h <==
double get_value (void);

==> get-value.c <==
#include "get-value.h"

#include <stdint.h>

int x = 1;

double
get_value (void)
{
  return x / 1e6;
}

==> main.c <==
#include "get-value.h"

#include <stdlib.h>

int
main (void)
{
  double a, b;

  a = get_value ();
  b = get_value ();

  if (a != b)
    abort ();

  return 0;
}

and build it with -O2 -m32.

You will get an abort.

The reason for this is because the return value of the get_value() function
comes via a floating point register.  These registers have a higher precision
than IEEE double.  The spec permits "extra range and precision":


"""

8  Except for assignment and cast (which remove all extra range and precision),
the values of operations with floating operands and values subject to the usual
arithmetic conversions and of floating constants are evaluated to a format
whose range and precision may be greater than required by the type.

"""


It seems that GCC is failing to remove the extra precision on the assignment "b
= get_value();".

Indeed, looking at the code that is output:

        call    get_value
        movsd   %xmm0, 8(%rsp)
        call    get_value
        movsd   8(%rsp), %xmm1
        ucomisd %xmm0, %xmm1

we see that the first call has the return value stored in memory, but the
comparison uses the value from the second call directly, without truncating the
precision.

Adding 'volatile' to the local variables involved is an effective workaround
for the problem.


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

* [Bug c/60413] extra precision not properly removed on assignment of return value
  2014-03-04 15:16 [Bug c/60413] New: extra precision not properly removed on assignment of return value desrt at desrt dot ca
@ 2014-03-04 16:14 ` jakub at gcc dot gnu.org
  2014-03-04 16:24 ` desrt at desrt dot ca
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-03-04 16:14 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60413

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
                 CC|                            |jakub at gcc dot gnu.org
         Resolution|---                         |INVALID

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Use -fexcess-precision=standard or -std=c99 if you want the slower, but
standard conforming, rounds to get rid of excess precision.


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

* [Bug c/60413] extra precision not properly removed on assignment of return value
  2014-03-04 15:16 [Bug c/60413] New: extra precision not properly removed on assignment of return value desrt at desrt dot ca
  2014-03-04 16:14 ` [Bug c/60413] " jakub at gcc dot gnu.org
@ 2014-03-04 16:24 ` desrt at desrt dot ca
  2014-03-04 16:28 ` jakub at gcc dot gnu.org
  2014-03-04 16:43 ` desrt at desrt dot ca
  3 siblings, 0 replies; 5+ messages in thread
From: desrt at desrt dot ca @ 2014-03-04 16:24 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60413

--- Comment #2 from Ryan Lortie <desrt at desrt dot ca> ---
Why is this violation of standards treated in a special way?

Quoting from gcc's manpage:

       -ffast-math
           Sets -fno-math-errno, -funsafe-math-optimizations,
           -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans
           and -fcx-limited-range.

           This option causes the preprocessor macro "__FAST_MATH__"
           to be defined.

           This option is not turned on by any -O option besides
           -Ofast since it can result in incorrect output for programs
           that depend on an exact implementation of IEEE or ISO
           rules/specifications for math functions. It may, however,
           yield faster code for programs that do not require the
           guarantees of these specifications.

It seems that the logic about "since it can result in incorrect output for
programs that depend on an exact implementation of IEEE or ISO
rules/specifications" should be equally applied here.

ie: default should be to follow the standards, and maybe have 'fast' mode
enabled if the user gives -ffast-math.


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

* [Bug c/60413] extra precision not properly removed on assignment of return value
  2014-03-04 15:16 [Bug c/60413] New: extra precision not properly removed on assignment of return value desrt at desrt dot ca
  2014-03-04 16:14 ` [Bug c/60413] " jakub at gcc dot gnu.org
  2014-03-04 16:24 ` desrt at desrt dot ca
@ 2014-03-04 16:28 ` jakub at gcc dot gnu.org
  2014-03-04 16:43 ` desrt at desrt dot ca
  3 siblings, 0 replies; 5+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-03-04 16:28 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60413

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Ryan Lortie from comment #2)
> Why is this violation of standards treated in a special way?

Because it slows down things way too much.  Much better is just to use -msse2
-mfpmath=sse if you really need to use 32-bit programs and have at least SSE2
capable CPU, i387 floating point stack has tons of issues.


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

* [Bug c/60413] extra precision not properly removed on assignment of return value
  2014-03-04 15:16 [Bug c/60413] New: extra precision not properly removed on assignment of return value desrt at desrt dot ca
                   ` (2 preceding siblings ...)
  2014-03-04 16:28 ` jakub at gcc dot gnu.org
@ 2014-03-04 16:43 ` desrt at desrt dot ca
  3 siblings, 0 replies; 5+ messages in thread
From: desrt at desrt dot ca @ 2014-03-04 16:43 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60413

--- Comment #4 from Ryan Lortie <desrt at desrt dot ca> ---
It seems like a good solution to this problem might be to enable -mfpmath=sse
by default on arches where SSE is known to be supported and
-fexcess-precision=standard otherwise.  If people want their binaries to be
backwards compatible to machines before the pentium3 then they can pay the
price in performance -- at least we would not be violating the standard.

This would be nicely mixed with an appeal to distributions to bring their
default -march= flag a bit more up to date...


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

end of thread, other threads:[~2014-03-04 16:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-04 15:16 [Bug c/60413] New: extra precision not properly removed on assignment of return value desrt at desrt dot ca
2014-03-04 16:14 ` [Bug c/60413] " jakub at gcc dot gnu.org
2014-03-04 16:24 ` desrt at desrt dot ca
2014-03-04 16:28 ` jakub at gcc dot gnu.org
2014-03-04 16:43 ` desrt at desrt dot ca

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).