Bug #79595 [Opn]: zend_init_fpu() alters FPU precision
| From: | cmb@php.net | Date: | Wed, 20 May 2020 15:50:03 +0000 |
| Subject: | Bug #79595 [Opn]: zend_init_fpu() alters FPU precision | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-227095@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: cmb@php.net
Reported by: v-yitam at microsoft dot com
Summary: zend_init_fpu() alters FPU precision
Status: Open
Type: Bug
Package: Math related
Operating System: Alpine Linux
PHP Version: 7.4.5
Block user comment: N
Private report: N
New Comment:
A possible fix might be <https://github.com/php/php-src/pull/5602>.
Could you please try that, @yitam?
Previous Comments:
------------------------------------------------------------------------
[2020-05-20 15:20:01] v-yitam at microsoft dot com
This floating point calculation issue happens in Alpine Linux only, so we are targeting 64-bit
builds for Linux only. Thanks for considering!
------------------------------------------------------------------------
[2020-05-20 11:09:56] nikic@php.net
Are you interested in this for 32-bit or 64-bit builds?
I think we can safely disable this code if compiling under __SSE__, because we know that PHP itself
will not use x87 FPU in that case.
For 32-bit builds targeting x87 FPU, I don't think we want to change this, as we do want normal
floating point operations to be based on double precision.
------------------------------------------------------------------------
[2020-05-19 17:20:16] v-yitam at microsoft dot com
Thanks for getting back to us. Indeed, I suspect so:
/* NOTE: This only sets internal precision. MSVC does NOT support double-
extended precision! */
# define XPFPA_SWITCH_DOUBLE_EXTENDED()
If I changed the macro XPFPA_SWITCH_DOUBLE() to XPFPA_SWITCH_DOUBLE_EXTENDED(), the problem was
resolved in Alpine Linux.
Hence, please investigate further why using XPFPA_SWITCH_DOUBLE() is necessary. On Linux the FPU
should be left at 80-bit precision, especially Alpine, as musl libc's strtod() requires it to
work properly, not to mention it also breaks any functions that expect the standard ABI on Linux.
------------------------------------------------------------------------
[2020-05-18 07:26:35] cmb@php.net
From a comment in zend_float.h:
| This header file defines several platform-dependent macros that
| ensure equal and deterministic floating point behaviour across
| several platforms, compilers and architectures.
So, apparently, this is done deliberately. I'm not sure that this
is a good idea, though.
------------------------------------------------------------------------
[2020-05-14 17:40:43] v-yitam at microsoft dot com
I wanted to modify my original bug report but it didn't seem possible. Anyway, below is a more
accurate example to illustrate the issue. It was copied when running the debugger and stepping
through zend_init_fpu() in Zend/zend_float.c:
24 {
(gdb) s
28 if (!EG(saved_fpu_cw_ptr)) {
(gdb) n
29 EG(saved_fpu_cw_ptr) = (void*)&EG(saved_fpu_cw);
(gdb) n
31 XPFPA_STORE_CW(EG(saved_fpu_cw_ptr));
(gdb) n
32 long double n = 1;
(gdb) n
33 printf("Before %.17Le\n", n/100000);
(gdb) n
Before 1.00000000000000000e-05
35 XPFPA_SWITCH_DOUBLE();
(gdb) n
36 printf("After %.17Le\n", n/100000);
(gdb) n
After 1.00000000000000008e-05
40 }
(gdb)
------------------------------------------------------------------------
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