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

From: 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

« previous php.bugs (#227095) next »