This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR19405: Don't fold inexact long doubles on Darwin
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 26 Jan 2005 18:24:07 -0700 (MST)
- Subject: [PATCH] PR19405: Don't fold inexact long doubles on Darwin
The following patch resolves PR middle-end/19405 which is a wrong code
bug on platforms using double pairs to represent long doubles, which
includes Darwin 8.0. This resolves the current unexpected failure of
18_support/numeric_limits.cc in the libstdc++-v3 testsuite on Darwin.
The problem is caused by the fact that IBM's extended long double
representation of floating point values can represent non-consecutive
mantissa bits. Unfortunately, this encoding wasn't envisioned and
can't accurately be modeled by GCC's software emulation which assumes
floating point representations with consecutive mantissa bits. The
patch below adds a new predicate macro REAL_MODE_FORMAT_COMPOSITE_P
to identify these unsual encodings, and prevents constant folding FP
operations that overflow at compile-time for these modes. Except
for -ffast-math, i.e. flag_unsafe_math_optimizations, where we still
still evaluate approximate results at compile-time and thereby avoid
any potential performance issues.
The following patch has been tested on both i686-pc-linux-gnu and
powerpc-apple-darwin8.0.0b3 with a full "make bootstrap", all default
languages, and regression tested with a top-level "make -k check"
with no new failures.
Ok for mainline?
2005-01-26 Roger Sayle <roger@eyesopen.com>
PR middle-end/19405
* real.h (REAL_MODE_FORMAT_COMPOSITE_P): New macro.
* fold-const.c (const_binop): Avoid constant folding floating
point operations in modes that use composite representations.
* simplify-rtx.c (simplify_binary_operation): Likewise.
Index: real.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.h,v
retrieving revision 1.81
diff -c -3 -p -r1.81 real.h
*** real.h 22 Jan 2005 12:53:20 -0000 1.81
--- real.h 26 Jan 2005 22:10:17 -0000
*************** extern const struct real_format *
*** 157,162 ****
--- 157,168 ----
#define REAL_MODE_FORMAT(MODE) (real_format_for_mode[(MODE) - MIN_MODE_FLOAT])
+ /* The following macro determines whether the floating point format is
+ composite, i.e. may contain non-consecutive mantissa bits, in which
+ case compile-time FP overflow may not model run-time overflow. */
+ #define REAL_MODE_FORMAT_COMPOSITE_P(MODE) \
+ ((REAL_MODE_FORMAT(MODE))->pnan < (REAL_MODE_FORMAT (MODE))->p)
+
/* Declare functions in real.c. */
/* Binary or unary arithmetic on tree_code. */
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.497
diff -c -3 -p -r1.497 fold-const.c
*** fold-const.c 23 Jan 2005 15:05:29 -0000 1.497
--- fold-const.c 26 Jan 2005 22:10:22 -0000
*************** const_binop (enum tree_code code, tree a
*** 1517,1525 ****
/* Don't constant fold this floating point operation if the
result may dependent upon the run-time rounding mode and
! flag_rounding_math is set. */
! if (flag_rounding_math
&& (inexact || !real_identical (&result, &value)))
return NULL_TREE;
--- 1517,1528 ----
/* Don't constant fold this floating point operation if the
result may dependent upon the run-time rounding mode and
! flag_rounding_math is set, or if GCC's software emulation
! is unable to accurately represent the result. */
! if ((flag_rounding_math
! || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
! && !flag_unsafe_math_optimizations))
&& (inexact || !real_identical (&result, &value)))
return NULL_TREE;
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.223
diff -c -3 -p -r1.223 simplify-rtx.c
*** simplify-rtx.c 21 Jan 2005 17:54:26 -0000 1.223
--- simplify-rtx.c 26 Jan 2005 22:10:23 -0000
*************** simplify_binary_operation (enum rtx_code
*** 1346,1353 ****
/* Don't constant fold this floating point operation if the
result may dependent upon the run-time rounding mode and
! flag_rounding_math is set. */
! if (flag_rounding_math
&& (inexact || !real_identical (&result, &value)))
return NULL_RTX;
--- 1346,1357 ----
/* Don't constant fold this floating point operation if the
result may dependent upon the run-time rounding mode and
! flag_rounding_math is set, or if GCC's software emulation
! is unable to accurately represent the result. */
!
! if ((flag_rounding_math
! || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
! && !flag_unsafe_math_optimizations))
&& (inexact || !real_identical (&result, &value)))
return NULL_RTX;
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833