Bug 2050736 - NaN regression between gcc-12.0.1-0.4.fc36 and gcc-12.0.1-0.5.fc36
Summary: NaN regression between gcc-12.0.1-0.4.fc36 and gcc-12.0.1-0.5.fc36
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 2050761
TreeView+ depends on / blocked
 
Reported: 2022-02-04 14:37 UTC by Miro Hrončok
Modified: 2022-02-07 12:55 UTC (History)
14 users (show)

Fixed In Version: gcc-12.0.1-0.6.fc36
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-02-06 18:11:52 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
GNU Compiler Collection 104389 0 P3 UNCONFIRMED HUGE_VAL * 0.0 is no longer a NaN 2022-02-04 19:03:28 UTC

Description Miro Hrončok 2022-02-04 14:37:08 UTC
Description of problem:
With the update from gcc-12.0.1-0.4.fc36 to gcc-12.0.1-0.5.fc36 suddenly Python 3.11 fails cmath tests during the build on all 6 architectures.

The failures look like this:


test_abs (test.test_cmath.CMathTests) ... FAIL
test_phase (test.test_cmath.CMathTests) ... FAIL
test_polar (test.test_cmath.CMathTests) ... FAIL
test_polar_errno (test.test_cmath.CMathTests) ... FAIL
test_specific_values (test.test_cmath.CMathTests) ... FAIL
test_inf_ninf_nan (test.test_cmath.IsCloseTests) ... FAIL
======================================================================
FAIL: test_abs (test.test_cmath.CMathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 516, in test_abs
    self.assertTrue(math.isnan(abs(complex(NAN, -2.3))))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true
======================================================================
FAIL: test_phase (test.test_cmath.CMathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 503, in test_phase
    self.assertTrue(math.isnan(phase(z)))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true
======================================================================
FAIL: test_polar (test.test_cmath.CMathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 450, in test_polar
    self.check_polar(polar)
    ^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 441, in check_polar
    check(complex(nan, 0), (nan, nan))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 425, in check
    self.rAssertAlmostEqual(e, g)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 116, in rAssertAlmostEqual
    self.fail(msg or '{!r} should be nan'.format(b))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 0.0 should be nan
======================================================================
FAIL: test_polar_errno (test.test_cmath.CMathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 462, in test_polar_errno
    self.check_polar(polar_with_errno_set)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 441, in check_polar
    check(complex(nan, 0), (nan, nan))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 425, in check
    self.rAssertAlmostEqual(e, g)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 116, in rAssertAlmostEqual
    self.fail(msg or '{!r} should be nan'.format(b))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 0.0 should be nan
======================================================================
FAIL: test_specific_values (test.test_cmath.CMathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 418, in test_specific_values
    self.rAssertAlmostEqual(expected.imag, actual.imag,
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_cmath.py", line 116, in rAssertAlmostEqual
    self.fail(msg or '{!r} should be nan'.format(b))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: acos1004: acos(complex(0.0, nan))
Expected: complex(1.5707963267948966, nan)
Received: complex(1.5707963267948966, 0.0)
Received value insufficiently close to expected value.
======================================================================
FAIL: test_inf_ninf_nan (test.test_cmath.IsCloseTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_math.py", line 2196, in test_inf_ninf_nan
    self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_math.py", line 2139, in assertAllNotClose
    self.assertIsNotClose(a, b, *args, **kwargs)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_math.py", line 2130, in assertIsNotClose
    self.assertFalse(self.isclose(a, b, *args, **kwargs),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: True is not false : nan and nan should not be close!
----------------------------------------------------------------------
Ran 6 tests in 0.008s
FAILED (failures=6)
test test_cmath failed
0:02:52 load avg: 1.79 Re-running test_complex in verbose mode (matching: test_truediv)
test_truediv (test.test_complex.ComplexTest) ... FAIL
======================================================================
FAIL: test_truediv (test.test_complex.ComplexTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_complex.py", line 115, in test_truediv
    self.assertTrue(isnan(z.real))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true
----------------------------------------------------------------------
Ran 1 test in 0.051s
FAILED (failures=1)
test test_complex failed
0:02:52 load avg: 1.79 Re-running test_math in verbose mode (matching: testAtan2, testDist, testHypot, testRemainder)
testAtan2 (test.test_math.MathTests) ... FAIL
testDist (test.test_math.MathTests) ... FAIL
testHypot (test.test_math.MathTests) ... FAIL
testRemainder (test.test_math.MathTests) ... FAIL
======================================================================
FAIL: testAtan2 (test.test_math.MathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_math.py", line 334, in testAtan2
    self.assertTrue(math.isnan(math.atan2(0., NAN)))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true
======================================================================
FAIL: testDist (test.test_math.MathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_math.py", line 991, in testDist
    self.assertTrue(math.isnan(dist(p, q)))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true
======================================================================
FAIL: testHypot (test.test_math.MathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_math.py", line 815, in testHypot
    self.assertTrue(math.isnan(hypot(NAN)))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not true
======================================================================
FAIL: testRemainder (test.test_math.MathTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/Python-3.11.0a5/Lib/test/test_math.py", line 1495, in testRemainder
    with self.assertRaises(ValueError):
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: ValueError not raised
----------------------------------------------------------------------


Version-Release number of selected component: gcc-12.0.1-0.5.fc36


How reproducible: 100%


Steps to Reproduce (either one of them works):
a. Build python3.11 from https://src.fedoraproject.org/rpms/python3.11/pull-request/19 e.g. in rawhide Koji or mock with --enablerepo=local
b. Build python3.11 from rawhide branch e.g. in rawhide Koji or mock with --enablerepo=local
c. Build python3.10 from rawhide branch e.g. in rawhide Koji or mock with --enablerepo=local
... possibly more reproducers with different Python versions...


Actual results:
Fails, see e.g. https://koji.fedoraproject.org/koji/taskinfo?taskID=82370954 or https://koji.fedoraproject.org/koji/taskinfo?taskID=82373925 or https://koji.fedoraproject.org/koji/taskinfo?taskID=82373916

Expected results:
Succeeds, see e.g. https://koji.fedoraproject.org/koji/taskinfo?taskID=82367006

Comment 1 Jakub Jelinek 2022-02-04 17:57:30 UTC
I see one NaN related change in the -0.4.fc36 to -0.5.fc36 diff, in particular https://gcc.gnu.org/PR95115
fix.
But it has been backported into gcc 11 and 10 already.

Comment 2 Jakub Jelinek 2022-02-04 18:08:31 UTC
My python is a little bit rusty, does the above mean that also say
import cmath, math
NAN = float('nan')
print(math.isnan(abs(complex(NAN, -2.3))))
now prints False instead of True?

Comment 3 Miro Hrončok 2022-02-04 18:36:10 UTC
(In reply to Jakub Jelinek from comment #2)
> My python is a little bit rusty, does the above mean that also say
> import cmath, math
> NAN = float('nan')
> print(math.isnan(abs(complex(NAN, -2.3))))
> now prints False instead of True?


Yes.


In order to tell, I've rebuilt python3.11-3.11.0~a5-1.fc36 --without tests with gcc-12.0.1-0.5.fc36:

<mock-chroot> sh-5.1$ python3.11
Python 3.11.0a5 (main, Feb  4 2022, 00:00:00) [GCC 12.0.1 20220202 (Red Hat 12.0.1-0)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath, math
>>> NAN = float('nan')
>>> math.isnan(abs(complex(NAN, -2.3)))
False


The previous build, with gcc-12.0.1-0.4.fc36:

<mock-chroot> sh-5.1$ python3.11
Python 3.11.0a5 (main, Feb  4 2022, 00:00:00) [GCC 12.0.1 20220129 (Red Hat 12.0.1-0)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath, math
>>> NAN = float('nan')
>>> math.isnan(abs(complex(NAN, -2.3)))
True

Comment 4 Miro Hrončok 2022-02-04 18:37:32 UTC
gcc-12.0.1-0.4.fc36:

>>> abs(complex(NAN, -2.3))
nan


gcc-12.0.1-0.5.fc36:

>>> abs(complex(NAN, -2.3))
0.0

Comment 5 Miro Hrončok 2022-02-04 18:46:59 UTC
gcc-12.0.1-0.4.fc36:

>>> NAN = float("nan")
>>> 0j/complex(NAN, NAN)
(nan+nanj)


gcc-12.0.1-0.5.fc36:

>>> NAN = float("nan")
>>> 0j/complex(NAN, NAN)
0j

Comment 6 Miro Hrončok 2022-02-04 18:53:10 UTC
There is also:

>>> math.atan2(0., NAN)
0.0
>>> math.hypot(NAN)
0.0
>>> math.hypot(NAN, NAN)
0.0


But I was unable to reproduce the math.isclose(NAN, NAN) == True thing :/

Comment 7 Victor Stinner 2022-02-04 19:03:29 UTC
I reported the issue to GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104389

Comment 8 Jakub Jelinek 2022-02-04 19:45:10 UTC
Thanks, I'll test the fix and if all goes well, will include it in tomorrow's rawhide gcc build.

Comment 9 Jakub Jelinek 2022-02-05 10:51:27 UTC
Note, as mentioned on the gcc-patches mailing list, you still should change python too, because unlike before GCC will no longer fold that Inf * 0. to NaN at compile time (in order to raise an exception, except for -ffast-math or -fno-trapping-math).
So in
#if !defined(Py_NAN) && !defined(Py_NO_NAN)
#  if !defined(__INTEL_COMPILER)
#    define Py_NAN (Py_HUGE_VAL * 0.)
...
better try something like:
#  ifdef __has_builtin
#    if __has_builtin (__builtin_nan)
#      define Py_NAN __builtin_nan ("")
#    endif
#  endif
#  ifdef Py_NAN
#  elif !defined(__INTEL_COMPILER)
#    define Py_NAN (Py_HUGE_VAL * 0.)
...
(untested).

Comment 10 Victor Stinner 2022-02-05 11:59:42 UTC
> You still should change python too, because unlike before GCC will no longer fold that Inf * 0. to NaN at compile time

Was it the case previously?

Anyway, because of this bug, I already proposed a PR to modify PY_NAN to implement it as:

    // Use C99 "NAN" constant: quiet Not-A-Number (when supported)
    #define Py_NAN NAN

=> https://github.com/python/cpython/pull/31134

Comment 11 Fedora Update System 2022-02-06 17:40:17 UTC
FEDORA-2022-fba9d09417 has been submitted as an update to Fedora 36. https://bodhi.fedoraproject.org/updates/FEDORA-2022-fba9d09417

Comment 12 Fedora Update System 2022-02-06 18:11:52 UTC
FEDORA-2022-fba9d09417 has been pushed to the Fedora 36 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 13 Miro Hrončok 2022-02-07 08:42:59 UTC
Building python3.11-3.11.0~a5-1.fc36 for rawhide
Created task: 82493152
Task info: https://koji.fedoraproject.org/koji/taskinfo?taskID=82493152

Comment 14 Miro Hrončok 2022-02-07 09:15:45 UTC
Thanks, it appears fixed.

Comment 15 Jakub Jelinek 2022-02-07 09:33:44 UTC
As for #define Py_NAN NAN, yeah, that is certainly an option, but depends on if it would be the only reason why python requires a C99 compiler.
If it already uses e.g. declarations in for loop inits, then it is reasonable to assume even NAN, but if the whole codebase is C89 compilable,
then one choice is also define Py_NAN to NAN if NAN is defined and fallback to what it has been doing previously.  Your choice...

Comment 16 Victor Stinner 2022-02-07 12:55:56 UTC
> https://github.com/python/cpython/pull/31134

I merged my PR: https://github.com/python/cpython/commit/54842e4311bb0e34012d1984b42eab41eeeaea6a

My final change also prefers __builtin_nan("") if it's available, since NAN must be casted to (double): Py_NAN must be a double.

I don't plan to backport my change since it adds new requirements to build Python and that's not acceptable in a bugfix (3.9.x and 3.10.x) release. It's ok if Python computes HUGE_VAL*0 at runtime, Python is not very efficient for floating point operations, because of boxing/unboxing in PyObject (PyFloatObject) and the the slow bytecode evaluation. I mean HUGE_VAL*0 is not going to be *the* performance bottleneck of Python ;-)


> As for #define Py_NAN NAN, yeah, that is certainly an option, but depends on if it would be the only reason why python requires a C99 compiler.

Python requires a C99 compiler to build since Python 3.6: https://www.python.org/dev/peps/pep-0007/#c-dialect


Note You need to log in before you can comment on or make changes to this bug.