Fix #79595: zend_init_fpu() alters FPU precision

On startup, PHP deliberately changes the floating point control word to
enforce binary64 format for the calculations for best consistency
across platforms.  However, this is unnessary for x86_64 architectures,
because in this case SSE instructions are used by default, and there is
no good reason to pass `-mfpmath=i387` or such.

Therefore, we can skip the modification, which has the benefit that
system libraries are free to work in the mode of their liking.
This commit is contained in:
Christoph M. Becker 2020-05-26 08:57:31 +02:00
parent c6fc400e8b
commit 879004dae3
2 changed files with 11 additions and 13 deletions

3
NEWS
View File

@ -2,7 +2,8 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2020, PHP 7.4.8
- Core:
. Fixed bug #79595 (zend_init_fpu() alters FPU precision). (cmb, Nikita)
11 Jun 2020, PHP 7.4.7

View File

@ -55,10 +55,9 @@ END_EXTERN_C()
Implementation notes:
x86_64:
- Since all x86_64 compilers use SSE by default, it is probably unnecessary
to use these macros there. We define them anyway since we are too lazy
to differentiate the architecture. Also, the compiler option -mfpmath=i387
justifies this decision.
- Since all x86_64 compilers use SSE by default, we do not define these
macros there. We ignore the compiler option -mfpmath=i387, because there is
no reason to use it on x86_64.
General:
- It would be nice if one could detect whether SSE if used for math via some
@ -67,9 +66,7 @@ END_EXTERN_C()
MS Visual C:
- Since MSVC users typically don't use autoconf or CMake, we will detect
MSVC via compile time define. Floating point precision change isn't
supported on 64 bit platforms, so it's NOP. See
http://msdn.microsoft.com/en-us/library/c9676k6h(v=vs.110).aspx
MSVC via compile time define.
*/
/* MSVC detection (MSVC people usually don't use autoconf) */
@ -77,7 +74,7 @@ END_EXTERN_C()
# define HAVE__CONTROLFP_S
#endif /* _MSC_VER */
#ifdef HAVE__CONTROLFP_S
#if defined(HAVE__CONTROLFP_S) && !defined(__x86_64__)
/* float.h defines _controlfp_s */
# include <float.h>
@ -141,7 +138,7 @@ END_EXTERN_C()
return _xpfpa_result; \
} while (0)
#elif defined(HAVE__CONTROLFP)
#elif defined(HAVE__CONTROLFP) && !defined(__x86_64__)
/* float.h defines _controlfp */
# include <float.h>
@ -200,7 +197,7 @@ END_EXTERN_C()
return _xpfpa_result; \
} while (0)
#elif defined(HAVE__FPU_SETCW) /* glibc systems */
#elif defined(HAVE__FPU_SETCW) && !defined(__x86_64__) /* glibc systems */
/* fpu_control.h defines _FPU_[GS]ETCW */
# include <fpu_control.h>
@ -259,7 +256,7 @@ END_EXTERN_C()
return _xpfpa_result; \
} while (0)
#elif defined(HAVE_FPSETPREC) /* FreeBSD */
#elif defined(HAVE_FPSETPREC) && !defined(__x86_64__) /* FreeBSD */
/* fpu_control.h defines _FPU_[GS]ETCW */
# include <machine/ieeefp.h>
@ -315,7 +312,7 @@ END_EXTERN_C()
return _xpfpa_result; \
} while (0)
#elif defined(HAVE_FPU_INLINE_ASM_X86)
#elif defined(HAVE_FPU_INLINE_ASM_X86) && !defined(__x86_64__)
/*
Custom x86 inline assembler implementation.