[New-bugs-announce] [issue35752] test_buffer fails on ppc64le: memoryview pack_single() is miscompiled
STINNER Victor
report at bugs.python.org
Wed Jan 16 11:51:18 EST 2019
New submission from STINNER Victor <vstinner at 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 <report at bugs.python.org>
<https://bugs.python.org/issue35752>
_______________________________________
More information about the New-bugs-announce
mailing list