From ce5a3d48326bd58bc9e3513ed6f277683cb97fd9 Mon Sep 17 00:00:00 2001 From: geoffk Date: Thu, 7 Oct 2004 21:16:28 +0000 Subject: [PATCH] 2004-10-07 Geoffrey Keating 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 * gcc.dg/ppc-fsel-3.c: New file. * gcc.dg/ppc-fsel-1.c: Add -fno-trapping-math, update comment. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88707 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/config/rs6000/rs6000.c | 26 +++++++++++++++++++++----- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/ppc-fsel-1.c | 4 ++-- gcc/testsuite/gcc.dg/ppc-fsel-3.c | 11 +++++++++++ 5 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ppc-fsel-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 274b882d371..01f41a23c03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-10-07 Geoffrey Keating + + 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 * 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 570357779fa..0d5c8b4d4b0 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 b181df863b1..6a0cd628625 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-10-07 Geoffrey Keating + + * 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 * 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 266b8dbd5a5..8d364352ac9 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 00000000000..1d07c528eb1 --- /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; +} -- 2.11.0