This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, committed] PowerPC compress_float_constant
- From: David Edelsohn <dje at watson dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 24 Mar 2005 18:23:27 -0500
- Subject: [PATCH, committed] PowerPC compress_float_constant
This patch changes the behavior of the rs6000 port to force
floating point constants to memory early. Because of other constraint
changes, most floating point constants are being forced to memory anyway.
Committing to memory earlier allows the expr.c:compress_float_constant()
functionality to work.
Compressing floating point constants and loading through
float_extend runs afoul of a dubious unsafe-math "optimization" in the
RDIV expander that always splits FP divides into multiplication with the
reciprocal, with the hopes of hoisting the reciprocal out of loops. The
combine pass is suppose to reconstitute the divide, but float_extend
interferes. The end result is an unnecessary loss of precision that
causes failures in applications, such as SPEC CPU2000 perlbmk. Until the
optimization is restructured, as has been suggested many times, constants
are not compressed when flag_unsafe_math_optimizations is enabled.
This change improves SPEC CPU2000 252.eon by 15% at -O2 in my
testing.
Bootstrapped on powerpc-ibm-aix5.2.0.0 and powerpc-apple-darwin.
The only testsuite regression is gcc.c-torture/execute/20020720-1.c, which
fails on most platforms. The test will be XFAILed.
David
* config/rs6000/predicates.md (easy_fp_constant): Return 0 for
SFmode and DFmode before reload when
flag_unsafe_math_optimizations not enabled.
Index: predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/predicates.md,v
retrieving revision 1.7
diff -c -p -r1.7 predicates.md
*** predicates.md 13 Mar 2005 20:28:29 -0000 1.7
--- predicates.md 24 Mar 2005 23:03:57 -0000
***************
*** 219,226 ****
long k[2];
REAL_VALUE_TYPE rv;
! if (TARGET_E500_DOUBLE)
! return 0;
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
--- 219,233 ----
long k[2];
REAL_VALUE_TYPE rv;
! /* Force constants to memory before reload to utilize
! compress_float_constant.
! Avoid this when flag_unsafe_math_optimizations is enabled
! because RDIV division to reciprocal optimization is not able
! to regenerate the division. */
! if (TARGET_E500_DOUBLE
! || (!reload_in_progress && !reload_completed
! && !flag_unsafe_math_optimizations))
! return 0;
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
***************
*** 234,239 ****
--- 241,255 ----
long l;
REAL_VALUE_TYPE rv;
+ /* Force constants to memory before reload to utilize
+ compress_float_constant.
+ Avoid this when flag_unsafe_math_optimizations is enabled
+ because RDIV division to reciprocal optimization is not able
+ to regenerate the division. */
+ if (!reload_in_progress && !reload_completed
+ && !flag_unsafe_math_optimizations)
+ return 0;
+
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_SINGLE (rv, l);