aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@apple.com>2004-10-07 21:16:28 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2004-10-07 21:16:28 +0000
commitadd2402ef09ed864788f5501ad8bfc54fd48913b (patch)
tree0a4cba33bf6409dcc3b1575e611f81b7f8fcf8dc /gcc
parent0dfa6c5eae5ef20030ee5b7ad79504ec35c6200a (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/rs6000/rs6000.c26
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/ppc-fsel-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/ppc-fsel-3.c11
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;
+}