diff mbox

Fix __GCC_IEC_559 determination for 32-bit x86

Message ID Pine.LNX.4.64.1311050113380.9883@digraph.polyomino.org.uk
State New
Headers show

Commit Message

Joseph Myers Nov. 5, 2013, 1:14 a.m. UTC
HJ's regression tester shows the new test gcc.dg/iec-559-macros-9.c
failing for 32-bit x86.  It turns out the excess precision handling
for determining the value of __GCC_IEC_559 has two problems:
flag_excess_precision hasn't been initialized at the point it's
tested, so flag_excess_precision_cmdline (which *has* been updated
based on flag_iso) needs testing instead, and on x86 with standard
excess precision enabled there is no adddf3 pattern (because all x87
arithmetic is in XFmode) so the default hook wrongly thinks it's a
soft-float target.  This can be fixed by adding an x86-specific hook
implementation; the issue doesn't affect any other target defining
TARGET_FLT_EVAL_METHOD, because only x86 makes sure to disable the
problematic insn patterns for -fexcess-precision=standard.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
commit (the x86 target hook addition)?

2013-11-05  Joseph Myers  <joseph@codesourcery.com>

	* config/i386/i386.c (ix86_float_exceptions_rounding_supported_p):
	New function.
	(TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P): Define.

c-family:
2013-11-05  Joseph Myers  <joseph@codesourcery.com>

	* c-cppbuiltin.c (cpp_iec_559_value): Test
	flag_excess_precision_cmdline not flag_excess_precision.

Comments

Jakub Jelinek Nov. 5, 2013, 7:11 a.m. UTC | #1
On Tue, Nov 05, 2013 at 01:14:46AM +0000, Joseph S. Myers wrote:
> HJ's regression tester shows the new test gcc.dg/iec-559-macros-9.c
> failing for 32-bit x86.  It turns out the excess precision handling
> for determining the value of __GCC_IEC_559 has two problems:
> flag_excess_precision hasn't been initialized at the point it's
> tested, so flag_excess_precision_cmdline (which *has* been updated
> based on flag_iso) needs testing instead, and on x86 with standard
> excess precision enabled there is no adddf3 pattern (because all x87
> arithmetic is in XFmode) so the default hook wrongly thinks it's a
> soft-float target.  This can be fixed by adding an x86-specific hook
> implementation; the issue doesn't affect any other target defining
> TARGET_FLT_EVAL_METHOD, because only x86 makes sure to disable the
> problematic insn patterns for -fexcess-precision=standard.
> 
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
> commit (the x86 target hook addition)?
> 
> 2013-11-05  Joseph Myers  <joseph@codesourcery.com>
> 
> 	* config/i386/i386.c (ix86_float_exceptions_rounding_supported_p):
> 	New function.
> 	(TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P): Define.
> 
> c-family:
> 2013-11-05  Joseph Myers  <joseph@codesourcery.com>
> 
> 	* c-cppbuiltin.c (cpp_iec_559_value): Test
> 	flag_excess_precision_cmdline not flag_excess_precision.

Ok.

Besides:
+FAIL: gcc.dg/iec-559-macros-9.c (test for excess errors)

that this patch supposedly fixes on i686-linux I'm also seeing:

+FAIL: gcc.dg/pch/save-temps-1.c  -O0 -g -I. -Dwith_PCH (test for excess errors)
+FAIL: gcc.dg/pch/save-temps-1.c -O0 -g assembly comparison
+FAIL: gcc.dg/pch/save-temps-1.c   -O0  -I. -Dwith_PCH (test for excess errors)
+FAIL: gcc.dg/pch/save-temps-1.c  -O0  assembly comparison
+FAIL: gcc.dg/pch/save-temps-1.c   -O1  -I. -Dwith_PCH (test for excess errors)
+FAIL: gcc.dg/pch/save-temps-1.c  -O1  assembly comparison
+FAIL: gcc.dg/pch/save-temps-1.c   -O2  -I. -Dwith_PCH (test for excess errors)
+FAIL: gcc.dg/pch/save-temps-1.c  -O2  assembly comparison
+FAIL: gcc.dg/pch/save-temps-1.c   -O3 -fomit-frame-pointer  -I. -Dwith_PCH (test for excess errors)
+FAIL: gcc.dg/pch/save-temps-1.c  -O3 -fomit-frame-pointer  assembly comparison
+FAIL: gcc.dg/pch/save-temps-1.c   -O3 -g  -I. -Dwith_PCH (test for excess errors)
+FAIL: gcc.dg/pch/save-temps-1.c  -O3 -g  assembly comparison
+FAIL: gcc.dg/pch/save-temps-1.c   -Os  -I. -Dwith_PCH (test for excess errors)
+FAIL: gcc.dg/pch/save-temps-1.c  -Os  assembly comparison

and

+FAIL: g++.dg/pch/pch.C  -g -I. -Dwith_PCH (test for excess errors)
+FAIL: g++.dg/pch/pch.C -g assembly comparison
+FAIL: g++.dg/pch/pch.C  -O2 -g -I. -Dwith_PCH (test for excess errors)
+FAIL: g++.dg/pch/pch.C -O2 -g assembly comparison
+FAIL: g++.dg/pch/pch.C  -O2 -I. -Dwith_PCH (test for excess errors)
+FAIL: g++.dg/pch/pch.C -O2 assembly comparison

(but not on x86_64-linux).  Is that going to be fixed by this change too, or is it
something else?  This was about 7h30m later than the previous build that didn't
have these failures, so there is a possibility some different change caused it, but
not very likely.

	Jakub
Joseph Myers Nov. 5, 2013, 1:26 p.m. UTC | #2
On Tue, 5 Nov 2013, Jakub Jelinek wrote:

> Besides:
> +FAIL: gcc.dg/iec-559-macros-9.c (test for excess errors)
> 
> that this patch supposedly fixes on i686-linux I'm also seeing:
> 
> +FAIL: gcc.dg/pch/save-temps-1.c  -O0 -g -I. -Dwith_PCH (test for excess errors)

I see no obvious reason for PCH issues connected with my patch or this fix 
- I'd expect PCH to care only at most about whether the predefined macros 
are consistent between different compilations for which they should be 
consistent, not whether they are correct - but I suppose that if whether 
flag_excess_precision was initialized at the relevant time depended on 
compiler options, that could have resulted in an inconsistency affecting 
PCH.
diff mbox

Patch

Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 204351)
+++ gcc/config/i386/i386.c	(working copy)
@@ -43375,6 +43375,18 @@  ix86_memmodel_check (unsigned HOST_WIDE_INT val)
   return val;
 }
 
+/* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P.  */
+
+static bool
+ix86_float_exceptions_rounding_supported_p (void)
+{
+  /* For x87 floating point with standard excess precision handling,
+     there is no adddf3 pattern (since x87 floating point only has
+     XFmode operations) so the default hook implementation gets this
+     wrong.  */
+  return TARGET_80387 || TARGET_SSE_MATH;
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
@@ -43747,6 +43759,10 @@  ix86_memmodel_check (unsigned HOST_WIDE_INT val)
 #undef TARGET_SPILL_CLASS
 #define TARGET_SPILL_CLASS ix86_spill_class
 
+#undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
+#define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
+  ix86_float_exceptions_rounding_supported_p
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-i386.h"
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c	(revision 204351)
+++ gcc/c-family/c-cppbuiltin.c	(working copy)
@@ -734,7 +734,7 @@  cpp_iec_559_value (void)
   if (flag_iso
       && !c_dialect_cxx ()
       && TARGET_FLT_EVAL_METHOD != 0
-      && flag_excess_precision != EXCESS_PRECISION_STANDARD)
+      && flag_excess_precision_cmdline != EXCESS_PRECISION_STANDARD)
     ret = 0;
 
   /* Various options are contrary to IEEE 754 semantics.  */