OSDN Git Service

2004-10-07 Geoffrey Keating <geoffk@apple.com>
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Oct 2004 21:16:28 +0000 (21:16 +0000)
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Oct 2004 21:16:28 +0000 (21:16 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88707 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ppc-fsel-1.c
gcc/testsuite/gcc.dg/ppc-fsel-3.c [new file with mode: 0644]

index 274b882..01f41a2 100644 (file)
@@ -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.
 2004-10-07  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * config/s390/s390-protos.h (s390_narrow_logical_operator): Add.
index 5703577..0d5c8b4 100644 (file)
@@ -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;
   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
 
   /* 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;
 
           && 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
   /* 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;
          || (! 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.  */
   /* 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.  */
 
   /* If we don't care about NaNs we can reduce some of the comparisons
      down to faster ones.  */
index b181df8..6a0cd62 100644 (file)
@@ -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.
 2004-10-07  Paul Brook  <paul@codesourcery.com>
 
        * gfortran.dg/intrinsic_verify_1.f90: New test.
index 266b8db..8d36435 100644 (file)
@@ -1,8 +1,8 @@
 /* { dg-do compile { target powerpc*-*-* } } */
 /* { dg-do compile { target powerpc*-*-* } } */
-/* { dg-options "-O -mpowerpc-gfxopt" } */
+/* { dg-options "-O -mpowerpc-gfxopt -fno-trapping-math" } */
 /* { dg-final { scan-assembler "fsel" } } */
 
 /* { 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)
 {
 
 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 (file)
index 0000000..1d07c52
--- /dev/null
@@ -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;
+}