[gcc r11-9035] i386: Don't emit fldpi etc. if -frounding-math [PR102498]
Jakub Jelinek
jakub@gcc.gnu.org
Tue Sep 28 11:07:24 GMT 2021
https://gcc.gnu.org/g:6de756d7a7a72ad67eaba33e6102c2e4874bf6e6
commit r11-9035-g6de756d7a7a72ad67eaba33e6102c2e4874bf6e6
Author: Jakub Jelinek <jakub@redhat.com>
Date: Tue Sep 28 13:02:51 2021 +0200
i386: Don't emit fldpi etc. if -frounding-math [PR102498]
i387 has instructions to store some transcedental numbers into the top of
stack. The problem is that what exact bit in the last place one gets for
those depends on the current rounding mode, the CPU knows the number with
slightly higher precision. The compiler assumes rounding to nearest when
comparing them against constants in the IL, but at runtime the rounding
can be different and so some of these depending on rounding mode and the
constant could be 1 ulp higher or smaller than expected.
We only support changing the rounding mode at runtime if the non-default
-frounding-mode option is used, so the following patch just disables
using those constants if that flag is on.
2021-09-28 Jakub Jelinek <jakub@redhat.com>
PR target/102498
* config/i386/i386.c (standard_80387_constant_p): Don't recognize
special 80387 instruction XFmode constants if flag_rounding_math.
* gcc.target/i386/pr102498.c: New test.
(cherry picked from commit 3b7041e8345c2f1030e58620f28e22d64b2c196b)
Diff:
---
gcc/config/i386/i386.c | 3 +-
gcc/testsuite/gcc.target/i386/pr102498.c | 59 ++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 527d493ecae..f991e07f232 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4963,7 +4963,8 @@ standard_80387_constant_p (rtx x)
/* For XFmode constants, try to find a special 80387 instruction when
optimizing for size or on those CPUs that benefit from them. */
if (mode == XFmode
- && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS))
+ && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS)
+ && !flag_rounding_math)
{
int i;
diff --git a/gcc/testsuite/gcc.target/i386/pr102498.c b/gcc/testsuite/gcc.target/i386/pr102498.c
new file mode 100644
index 00000000000..44161c5730b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102498.c
@@ -0,0 +1,59 @@
+/* PR target/102498 */
+/* { dg-do run { target fenv } } */
+/* { dg-options "-frounding-math" } */
+
+#include <fenv.h>
+#include <stdlib.h>
+
+__attribute__((noipa)) long double
+fldlg2 (void)
+{
+ return 0.3010299956639811952256464283594894482L;
+}
+
+__attribute__((noipa)) long double
+fldln2 (void)
+{
+ return 0.6931471805599453094286904741849753009L;
+}
+
+__attribute__((noipa)) long double
+fldl2e (void)
+{
+ return 1.4426950408889634073876517827983434472L;
+}
+
+__attribute__((noipa)) long double
+fldl2t (void)
+{
+ return 3.3219280948873623478083405569094566090L;
+}
+
+__attribute__((noipa)) long double
+fldpi (void)
+{
+ return 3.1415926535897932385128089594061862044L;
+}
+
+int
+main ()
+{
+ long double a = fldlg2 ();
+ long double b = fldln2 ();
+ long double c = fldl2e ();
+ long double d = fldl2t ();
+ long double e = fldpi ();
+ static int f[] = { FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD, FE_DOWNWARD };
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ fesetround (f[i]);
+ if (a != fldlg2 ()
+ || b != fldln2 ()
+ || c != fldl2e ()
+ || d != fldl2t ()
+ || e != fldpi ())
+ abort ();
+ }
+ return 0;
+}
More information about the Gcc-cvs
mailing list