New submission from STINNER Victor <vstin...@redhat.com>:
The bug was first reported on Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=1540995 ====================================================================== FAIL: test_memoryview_struct_module (test.test_buffer.TestBufferProtocol) ---------------------------------------------------------------------- Traceback (most recent call last): File "/builddir/build/BUILD/Python-3.6.4/Lib/test/test_buffer.py", line 2540, in test_memoryview_struct_module self.assertEqual(m[1], nd[1]) AssertionError: -21.099998474121094 != -21.100000381469727 The problem is the conversion from C double (64-bit float) and C float (32-bit float). There are 2 implementations: * Objects/memoryobject.c: pack_single() and unpack_single() * Modules/_struct.c: nu_float() and np_float() Attached ppc64_float32_bug.py is the simplified test case to trigger the bug. The result depends on the compiler optimization level: * gcc -O0: -21.100000381469727 == -21.100000381469727, OK * gcc -O1: -21.099998474121094 != -21.100000381469727, ERROR * (I guess that higher optimization level also trigger the bug) The problem is that the pack_single() function is "miscompiled" (or "too optimized"). Adding "volatile" to PACK_SINGLE() prevents the unsafe compiler optimization and fix the issue for me: try attached pack_single_volatile.patch. === -O1 assembler code with the bug === PACK_SINGLE(ptr, d, float); r30 = ptr (gdb) p $vs63.v2_double $17 = {0, -21.100000000000001} => 0x00000000100a1178 <pack_single+1988>: stxsspx vs63,0,r30 (gdb) p /x (*ptr)@4 $10 = {0xcc, 0xcc, 0xa8, 0xc1} The first byte is 0xcc: WRONG. === -O1 assembler code without the bug (volatile) === r30 = ptr (gdb) p $f31 $1 = -21.100000000000001 => 0x00000000100a11e4 <pack_single+2096>: frsp f31,f31 (gdb) p $f31 $2 = -21.100000381469727 0x00000000100a11e8 <pack_single+2100>: stfs f31,152(r1) 0x00000000100a11ec <pack_single+2104>: lwz r9,152(r1) (gdb) p /x $r9 $8 = 0xc1a8cccd 0x00000000100a11f0 <pack_single+2108>: stw r9,0(r30) (gdb) p /x (*ptr)@4 $9 = {0xcd, 0xcc, 0xa8, 0xc1} 0x00000000100a11f4 <pack_single+2112>: li r3,0 0x00000000100a11f8 <pack_single+2116>: lfd f31,216(r1) 0x00000000100a11fc <pack_single+2120>: ld r30,200(r1) The first byte is 0xcd: GOOD. ---------- components: Library (Lib) files: ppc64_float32_bug.py messages: 333774 nosy: mark.dickinson, skrah, vstinner priority: normal severity: normal status: open title: test_buffer fails on ppc64le: memoryview pack_single() is miscompiled versions: Python 3.7, Python 3.8 Added file: https://bugs.python.org/file48060/ppc64_float32_bug.py _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue35752> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com