čt 18. 12. 2025 v 1:16 odesílatel Sam James <[email protected]> napsal: > > > > [1] Built with a patch disabling late combine by default on IA-64 as > > that was shown to produce incorrect code in some cases. > > What's this about? >
I saw this with GCC 15.2.0 when building Python 3.14: tglozar@epic-t2 /tmp/tglozar $ Python-3.14.0/python -c 'print(5 ** 2.0)' 1.0 # with -O2 tglozar@epic-t2 /tmp/tglozar $ Python-3.14.0/python -c 'print(5 ** 2.0)' 25.0 # with -O1 GDB reveals that the second operand to ** is read as zero: $ gdb --args Python-3.14.0/python -c '5 ** 2.0' ... (gdb) b Objects/floatobject.c:810 Breakpoint 3 at 0x4000000000153590: file Objects/floatobject.c, line 810. (gdb) r Starting program: /tmp/tglozar/Python-3.14.0/python -c 5\ \*\*\ 2.0 ... Breakpoint 3, float_pow (v=<optimized out>, w=<optimized out>, z=0x6000000000071110 <_Py_NoneStruct>) at Objects/floatobject.c:810 810 ix = pow(iv, iw); (gdb) p iv $1 = 5 (gdb) p iw $2 = 0 Here, v is supposed to be decoded into iv, and w into iw (it's an offset read from the object pointer). I did some investigation and it seems like it gets loaded from memory into floating-point register, but never gets stored into the local variable on the stack; yet, the uninitialized variable gets used, not the register for passing the value to pow() (e.g. when I initialize iw with 42, 42 stays there). The other variable (v/iv) is not affected, as the same floating-point register is re-used to load iw, which triggers a store onto the stack. Adding -fnolate-combine-instructions gets rid of the issue. For this particular reproducer at least, it also needs -fcaller-saves to reproduce. I wanted to report or fix this but got sidetracked (maybe I can post a variant of this writeup). Tomas
