public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/99234] New: Regression: wrong result for 1.0/3.0 when -fno-omit-frame-pointer -frounding-math used together
@ 2021-02-24  1:07 vz-gcc at zeitlins dot org
  2021-02-24 15:54 ` [Bug target/99234] " jakub at gcc dot gnu.org
                   ` (30 more replies)
  0 siblings, 31 replies; 32+ messages in thread
From: vz-gcc at zeitlins dot org @ 2021-02-24  1:07 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 99234
           Summary: Regression: wrong result for 1.0/3.0 when
                    -fno-omit-frame-pointer -frounding-math used together
           Product: gcc
           Version: 10.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vz-gcc at zeitlins dot org
  Target Milestone: ---

Please see the following test case minimized by cvise:
---------------------------------- >8 --------------------------------------
// When compiled with
//
//  g++ -Wall -O2 -fno-omit-frame-pointer -frounding-math test.cpp
//
// using x86_64-w64-mingw32-g++ version 10-win32 20210110 (GCC) from Debian
// g++-mingw-w64-x86-64-win32 10.2.1-6+24.1 package or gcc version 10.2.0
// (Rev6, Built by MSYS2 project) this test case computes a wrong result for
// the second division below.
#include <cmath>
#include <cstdio>
#include <stdexcept>
#include <string>

double numeric_io_cast(const std::string& from)
{
    char* rendptr;
    double value = std::strtod(from.c_str(), &rendptr);
    if('\0' != *rendptr)
        throw std::logic_error("");

    return value;
}

double numeric_io_cast(char const* from)
{
    return numeric_io_cast(std::string(from));
}

int main(int, char* [])
{
    std::printf("1.0 / 3.0 = %f\n", 1.0 / 3.0); // => 1.0 / 3.0 = 0.333333

    try {
        numeric_io_cast("");
        numeric_io_cast("1e");
    } catch(std::logic_error const&) {
    }

    std::printf("1.0 / 3.0 = %f\n", 1.0 / 3.0); // => 1.0 / 3.0 = 0.000000

    return 0;
}
---------------------------------- >8 --------------------------------------

The comments in the code indicate the output produced when using MinGW gcc
10.2. The same code worked fine with different versions of gcc 8 and also works
when using native Linux gcc 10.2.1. It always works fine for 32 bit compiler
(which produces completely different code).

Also, just in case it can be helpful (even though I'm afraid it isn't...), it
the problem disappears when using the 10.x compilers mentioned above if either
of the following is true:

1. You use -O0 or -O3 (but it gives the same results with -O1 and -O2).
2. You don't use -fno-omit-frame-pointer.
3. You don't use -frounding-math.
4. You use 2.0, 4.0 or 8.0 instead of 3.0 (but it fails similarly with 5.0, 7.0
etc).
5. You use something other than std::logic_error (or a class derived from it
such as std::invalid_argument), i.e. throwing a simple class, even deriving
from std::exception, makes the problem disappear.
6. You remove the (clearly unnecessary!) numeric_io_cast() overload taking
char* and rely on implicit conversion doing the same thing.

Looking at the generated code the problem seems relatively clear: the compiler
assumes the xmm register containing the result is preserved when it's
clobbered. But I have no idea where to start looking in gcc to find why does it
assume this and how to fix this.

I'd also like to note that IMO it's a pretty bad bug because it silently
results in completely wrong behaviour in the code which worked perfectly well
before and, of course, it took quite some time before we actually found what
was going on and why did the tests suddenly start failing in "impossible" ways
after upgrading to MinGW 10.

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

end of thread, other threads:[~2021-05-05 21:01 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-24  1:07 [Bug c++/99234] New: Regression: wrong result for 1.0/3.0 when -fno-omit-frame-pointer -frounding-math used together vz-gcc at zeitlins dot org
2021-02-24 15:54 ` [Bug target/99234] " jakub at gcc dot gnu.org
2021-02-24 16:19 ` vz-gcc at zeitlins dot org
2021-02-24 16:19 ` vz-gcc at zeitlins dot org
2021-02-24 16:23 ` vz-gcc at zeitlins dot org
2021-02-24 16:25 ` vz-gcc at zeitlins dot org
2021-02-25  8:56 ` jakub at gcc dot gnu.org
2021-02-25  9:34 ` ebotcazou at gcc dot gnu.org
2021-02-25  9:36 ` [Bug target/99234] [10/11 regression] wrong result for 1.0/3.0 with -O2 -fno-omit-frame-pointer -frounding-math ebotcazou at gcc dot gnu.org
2021-02-25  9:36 ` ebotcazou at gcc dot gnu.org
2021-02-25 12:07 ` jyong at gcc dot gnu.org
2021-02-25 12:35 ` ebotcazou at gcc dot gnu.org
2021-02-25 14:25 ` lh_mouse at 126 dot com
2021-02-25 18:18 ` ebotcazou at gcc dot gnu.org
2021-02-26  0:36 ` ebotcazou at gcc dot gnu.org
2021-02-26  6:00 ` lh_mouse at 126 dot com
2021-02-26  8:27 ` lh_mouse at 126 dot com
2021-02-26  9:17 ` ebotcazou at gcc dot gnu.org
2021-02-26 10:18 ` jakub at gcc dot gnu.org
2021-02-26 11:04 ` lh_mouse at 126 dot com
2021-03-01  6:59 ` cvs-commit at gcc dot gnu.org
2021-03-01  7:00 ` cvs-commit at gcc dot gnu.org
2021-03-01  7:12 ` cvs-commit at gcc dot gnu.org
2021-03-01  7:13 ` ebotcazou at gcc dot gnu.org
2021-03-01 11:49 ` vz-gcc at zeitlins dot org
2021-03-03 11:30 ` cvs-commit at gcc dot gnu.org
2021-03-03 11:31 ` cvs-commit at gcc dot gnu.org
2021-03-03 11:34 ` cvs-commit at gcc dot gnu.org
2021-05-05 20:55 ` cvs-commit at gcc dot gnu.org
2021-05-05 20:56 ` cvs-commit at gcc dot gnu.org
2021-05-05 20:58 ` cvs-commit at gcc dot gnu.org
2021-05-05 21:01 ` cvs-commit at gcc dot gnu.org

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