https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116331

            Bug ID: 116331
           Summary: Math function non-determinism due to excessive
                    precision and constant folding
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: carl at dehlin dot com
  Target Milestone: ---

Created attachment 58901
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58901&action=edit
Preprocessed file

The following program triggers an assertion when compiled with -std=c++11 -O0
-Wall -Wextra -Wpedantic -Werror -ffloat-store -fexcess-precision=standard
-mfpmath=sse


#include <cmath>
#include <cassert>

int main()
{
    // Checked with https://www.exploringbinary.com/floating-point-converter/
    const double x = 1.2475784324341769870869711667182855308055877685546875;
    const double y = std::cos(x);
    const auto f = [x,y] {
        const double z = std::cos(x);
        return y == z;
    };
    assert(f());
}

See preprocessed file attached.

Why do I think this is a bug?
=============================
I have read through bug 323 and read through ALL of the duplicate issues and
email threads, I am quite familiar with the problem with excessive precision on
x86 now.

I have added all flags that I have found relevant for this type of issue, which
I believe should force the compiler to generate code that does not use
excessive precision at all. Yet, the program exhibits behavior which looks like
a excessive precision problem. 

Note that the constant can be stored as a double without a loss of precision
(checked online with this tool:
https://www.exploringbinary.com/floating-point-converter).

Some options are obviously unnecessary when used together, -mfpmath=sse should
be enough to force usage of SSE instead of the x87 FPU (please correct me if I
have misunderstood this).

Some initial analysis
=====================
Glancing through the generated assembly it seems that one of the calls to
std::cos is compiled as a built in, while the other as a library function call.

It could be that the bug lies in the intricate area between the compiler and
the standard library. I know that standard library bugs should not be reported
as compiler bugs, but with my current level of knowledge of the GCC ecosystem I
can not determine where the bugs really stem from. Please advice if I should
report this in another place as well.

Some ways to fix the code
=========================

1) Manually inline the lambda
2) Remove const qualifier on the x variable
3) Redefine x in the lambda
4) Define x with a macro
5) Add -fno-builtin compiler flag
6) Add -frounding-math compiler flag
7) Increase optimization level

Dependencies
============
gmp: 6.3.0
mpfr: 4.2.1
mpc: 1.3.0
flex: 2.6.4-8 (distributed with Ubuntu 23.10)

System info
===========
Target: x86_64-pc-linux-gnu
Configured with: ../gcc/configure --prefix=/home/cdeln/src/gcc-install
--disable-multilib --enable-languages=c,c++,lto
gcc version 14.2.0 (GCC)

Possibly related issues
=======================
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82318
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108742
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114746

Reply via email to