GCC 12 miscompiles libm

Szabolcs Nagy szabolcs.nagy@arm.com
Wed Dec 29 14:35:52 GMT 2021


The 12/20/2021 21:49, Joseph Myers wrote:
> On Mon, 20 Dec 2021, H.J. Lu via Libc-alpha wrote:
> > Hi,
> > 
> > GCC 12 miscompiles libm:
> > 
> > https://sourceware.org/bugzilla/show_bug.cgi?id=28713
> > 
> > due to the fix for
> > 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57245
> > 
> > which changes the behavior of -frounding-math on
> > conversion from constant double and integer to float.
> > However float codes in libm compiled with -frounding-math
> > depend on the previous behavior in GCC 11. I added this
> > to the glibc 2.35 blocker list.
> > 
> > Joseph, Richard, do you have any suggestions how
> > to fix it?
> 
> 1. What specific constant conversion from double to float in the source 
> code is changed with GCC 12 so that it now occurs at runtime?
> 
> 2. Does that conversion get executed in the abstract machine in the qNaN 
> path through the function (given that the test failures you report are for 
> qNaN inputs, and I'd generally expect those only to do arithmetic with 
> qNaN operands)?
> 
> 3. If it does get executed in the abstract machine, why?  It might well be 
> better to change the functions not to execute the conversion in that case.
> 
> 4. Alternatively, maybe the conversion doesn't get executed in the 
> abstract machine in the qNaN path through the function, but the compiler 
> scheduled it to occur unconditionally because it doesn't model the side 
> effects of raising exceptions from the conversion.
> 
> 5. Whether or not the conversion gets executed in the abstract machine, in 
> any case where a double constant in the source code is immediately 
> converted to float, it probably makes sense to change the source code to 
> use a corresponding float constant instead, and so avoid the runtime 
> conversion (unless the code actually expects a rounding-mode-dependent 
> result or an exception at runtime).
> 
> 6. If M_* constants are involved, I suppose we need to add corresponding 
> float macros.

in aarch64 libm.so i see new 'fcvt s*, d*' instructions
comparing building it with gcc-11 and gcc-trunk (i.e.
new runtime conversion from double- to single-precision).

number of new 'fcvt s*, d*' per symbol (as reported by
objdump):

1 __j0f_finite@GLIBC_2.17
1 __y0f_finite@GLIBC_2.17
1 __j1f_finite@GLIBC_2.17
1 __y1f_finite@GLIBC_2.17
1 __jnf_finite@GLIBC_2.17
2 gammaf_positive
1 __gammaf_r_finite@GLIBC_2.17
1 __log1pf
1 __lgamma_negf
1 cacosf
4 cacoshf
1 casinhf
1 __kernel_casinhf
4 catanhf
4 catanf
2 clogf
3 __clog10f

i did not analysed these in detail but at least some of
them are because of code like

  (FLOAT) M_MLIT (M_*)

i.e. double precision M_* constant is used as single
precision const (that i think is supposed to be compile
time const and not rounding mode dependent).


More information about the Libc-alpha mailing list