Bug #79595 [Csd]: zend_init_fpu() alters FPU precision

From: Date: Thu, 10 Jun 2021 09:33:28 +0000
Subject: Bug #79595 [Csd]: zend_init_fpu() alters FPU precision
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-234326@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=79595&edit=1

 ID:                 79595
 Updated by:         nikic@php.net
 Reported by:        v-yitam at microsoft dot com
 Summary:            zend_init_fpu() alters FPU precision
 Status:             Closed
 Type:               Bug
 Package:            Math related
 Operating System:   Alpine Linux
 PHP Version:        7.4.5
 Assigned To:        cmb
 Block user comment: N
 Private report:     N

 New Comment:

> If php/zend is really depending on having the fpu in a nonstandard precision mode, some logic
> to switch in and out of this mode when making external calls is needed; you can't just call
> external code with a state that violates the ABI that code is expecting.

I don't think that's feasible, there are too many external calls. I would expect it to
work the other way around, i.e. only switch the precision mode for code segments that need it.
I'm not sure what those are, but I expect at least the rounding implementation.

I'd be willing to review a PR in that direction, but given the irrelevance of i386 *without*
sse2 as a contemporary architecture, I have no interest in pursuing this myself.


Previous Comments:
------------------------------------------------------------------------
[2021-06-10 01:42:07] bugdal at aerifal dot cx

The fix is not a fix, or at least not a complete one; it leaves at least 32-bit x86 broken.

If php/zend is really depending on having the fpu in a nonstandard precision mode, some logic to
switch in and out of this mode when making external calls is needed; you can't just call
external code with a state that violates the ABI that code is expecting.

Also, if you're using the "64-bit" x87 precision mode and assuming it yields behavior
equivalent to IEEE double arithmetic, this is not correct. In this mode, computations and x87
registers have a 53-bit significand like IEEE double, but still have a 15-bit exponent like Intel
80-bit extended. This means that you can end up with values which are larger in magnitude than what
double can represent, or that have more precision than they should due to being in the denormal
range as double but normal with the 15-bit exponent. Such values change in unstable ways when the
compiler spills and reloads them, leading to all sorts of catastrophic dangerous bugs. These go back
to GCC issue https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
where many of them are linked, but there are a lot of newer, more specific bug reports as well,
including one whereby *integer* code can be transformed incorrectly by the optimizer.

In short, not only is it unsafe to use the nonstandard x87 precision modes; it's also unsafe to
do floating point without -fexcess-precision=standard (implied by -std=c* but not by -std=gnu*) on
targets with excess precision (32-bit x86 and m68k).

------------------------------------------------------------------------
[2020-05-26 16:23:41] v-yitam at microsoft dot com

> Note that the fix missed the deadline for PHP 7.4.7, so will have
to wait for PHP 7.4.8 (roughly mid July).

No worries. We will jot it down. A brief testing shows that the new fix works. Thank you all!

------------------------------------------------------------------------
[2020-05-26 15:24:31] cmb@php.net

Note that the fix missed the deadline for PHP 7.4.7, so will have
to wait for PHP 7.4.8 (roughly mid July).

------------------------------------------------------------------------
[2020-05-26 15:22:08] cmb@php.net

Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=879004dae325e50d3e1a8f9477e66cdfeef0d366
Log: Fix #79595: zend_init_fpu() alters FPU precision

------------------------------------------------------------------------
[2020-05-26 07:03:48] cmb@php.net

Thanks for checking, and yes, this was helpful!  I had forgotten
to add the guard to that #elif[1].

[1] <https://github.com/php/php-src/pull/5621/commits/c3fe3f7424b7e9a793ef4b55f197de9e2b6593af>

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=79595


--
Edit this bug report at https://bugs.php.net/bug.php?id=79595&edit=1


Thread (21 messages)

« previous php.bugs (#234326) next »