diff options
author | Geoffrey Keating <geoffk@apple.com> | 2004-10-07 21:16:28 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@gcc.gnu.org> | 2004-10-07 21:16:28 +0000 |
commit | add2402ef09ed864788f5501ad8bfc54fd48913b (patch) | |
tree | 0a4cba33bf6409dcc3b1575e611f81b7f8fcf8dc /gcc | |
parent | 0dfa6c5eae5ef20030ee5b7ad79504ec35c6200a (diff) | |
download | gcc-add2402ef09ed864788f5501ad8bfc54fd48913b.zip gcc-add2402ef09ed864788f5501ad8bfc54fd48913b.tar.gz gcc-add2402ef09ed864788f5501ad8bfc54fd48913b.tar.bz2 |
Radar 3813796
2004-10-07 Geoffrey Keating <geoffk@apple.com>
Radar 3813796
* config/rs6000/rs6000.c (rs6000_generate_compare): When
flag_trapping_math is in effect, don't generate subtract
instructions.
Index: testsuite/ChangeLog
2004-10-07 Geoffrey Keating <geoffk@apple.com>
* gcc.dg/ppc-fsel-3.c: New file.
* gcc.dg/ppc-fsel-1.c: Add -fno-trapping-math, update comment.
From-SVN: r88707
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ppc-fsel-1.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ppc-fsel-3.c | 11 |
5 files changed, 46 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 274b882..01f41a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-10-07 Geoffrey Keating <geoffk@apple.com> + + Radar 3813796 + * config/rs6000/rs6000.c (rs6000_generate_compare): When + flag_trapping_math is in effect, don't generate subtract + instructions. + 2004-10-07 Ulrich Weigand <uweigand@de.ibm.com> * config/s390/s390-protos.h (s390_narrow_logical_operator): Add. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5703577..0d5c8b4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -11489,6 +11489,7 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) enum machine_mode compare_mode = GET_MODE (op0); enum machine_mode result_mode = GET_MODE (dest); rtx temp; + bool is_against_zero; /* These modes should always match. */ if (GET_MODE (op1) != compare_mode @@ -11513,6 +11514,17 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) && GET_MODE_CLASS (compare_mode) == MODE_FLOAT) return 0; + is_against_zero = op1 == CONST0_RTX (compare_mode); + + /* A floating-point subtract might overflow, underflow, or produce + an inexact result, thus changing the floating-point flags, so it + can't be generated if we care about that. It's safe if one side + of the construct is zero, since then no subtract will be + generated. */ + if (GET_MODE_CLASS (compare_mode) == MODE_FLOAT + && flag_trapping_math && ! is_against_zero) + return 0; + /* Eliminate half of the comparisons by switching operands, this makes the remaining code simpler. */ if (code == UNLT || code == UNGT || code == UNORDERED || code == NE @@ -11545,14 +11557,18 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) || (! rtx_equal_p (op0, true_cond) && ! rtx_equal_p (op1, true_cond)))) return 0; + /* At this point we know we can use fsel. */ /* Reduce the comparison to a comparison against zero. */ - temp = gen_reg_rtx (compare_mode); - emit_insn (gen_rtx_SET (VOIDmode, temp, - gen_rtx_MINUS (compare_mode, op0, op1))); - op0 = temp; - op1 = CONST0_RTX (compare_mode); + if (! is_against_zero) + { + temp = gen_reg_rtx (compare_mode); + emit_insn (gen_rtx_SET (VOIDmode, temp, + gen_rtx_MINUS (compare_mode, op0, op1))); + op0 = temp; + op1 = CONST0_RTX (compare_mode); + } /* If we don't care about NaNs we can reduce some of the comparisons down to faster ones. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b181df8..6a0cd62 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-10-07 Geoffrey Keating <geoffk@apple.com> + + * gcc.dg/ppc-fsel-3.c: New file. + * gcc.dg/ppc-fsel-1.c: Add -fno-trapping-math, update comment. + 2004-10-07 Paul Brook <paul@codesourcery.com> * gfortran.dg/intrinsic_verify_1.f90: New test. diff --git a/gcc/testsuite/gcc.dg/ppc-fsel-1.c b/gcc/testsuite/gcc.dg/ppc-fsel-1.c index 266b8db..8d36435 100644 --- a/gcc/testsuite/gcc.dg/ppc-fsel-1.c +++ b/gcc/testsuite/gcc.dg/ppc-fsel-1.c @@ -1,8 +1,8 @@ /* { dg-do compile { target powerpc*-*-* } } */ -/* { dg-options "-O -mpowerpc-gfxopt" } */ +/* { dg-options "-O -mpowerpc-gfxopt -fno-trapping-math" } */ /* { dg-final { scan-assembler "fsel" } } */ -/* Check that fsel can be generated even without -ffast-math. */ +/* If the user doesn't care about signals, fsel can be used in many cases. */ double foo(double a, double b, double c, double d) { diff --git a/gcc/testsuite/gcc.dg/ppc-fsel-3.c b/gcc/testsuite/gcc.dg/ppc-fsel-3.c new file mode 100644 index 0000000..1d07c52 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ppc-fsel-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-options "-O -mpowerpc-gfxopt" } */ +/* { dg-final { scan-assembler-not "fsub" } } */ + +/* Check that an fsub isn't generated when no arithmetic was requested; + such an fsub might incorrectly set floating-point exception flags. */ + +double foo(double a, double b, double c, double d) +{ + return a < b ? c : d; +} |