re PR rtl-optimization/16796 (PowerPC - Unnecessary Floating Point Register Copy)
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 11 Nov 2004 08:49:17 +0000 (08:49 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 11 Nov 2004 08:49:17 +0000 (08:49 +0000)
.: PR target/16796
* config/rs6000/rs6000.md: Add DF & SF reg move peepholes.
testsuite:
PR target/16796
* gcc.dg/ppc-mov-1.c: New.

From-SVN: r90476

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

index 195080d25de330493c759a14e5ac174cffeb3fe2..3f4b7a361ea2fb96645f973623aaf73923d504ae 100644 (file)
@@ -1,5 +1,8 @@
 2004-11-11  Nathan Sidwell  <nathan@codesourcery.com>
 
+       PR target/16796
+       * config/rs6000/rs6000.md: Add DF & SF reg move peepholes.
+
        PR target/16458
        * config/rs6000/rs6000.c (rs6000_generate_compare): Generate an
        unsigned equality compare when we know the operands are unsigned.
index 9c6f08847af8101422db3038a6b039c4c00386fa..6b1c0b656ccf7b91b13093fdb3aa6f84c96ef6ed 100644 (file)
        (match_dup 1))]
   "operands[0] = widen_memory_access (operands[0], TFmode, 0);
    operands[1] = gen_rtx_REG (TFmode, REGNO (operands[1]));")
+
+;; after inserting conditional returns we can sometimes have
+;; unnecessary register moves.  Unfortunately we cannot have a
+;; modeless peephole here, because some single SImode sets have early
+;; clobber outputs.  Although those sets expand to multi-ppc-insn
+;; sequences, using get_attr_length here will smash the operands
+;; array.  Neither is there an early_cobbler_p predicate.
+(define_peephole2
+  [(set (match_operand:DF 0 "gpc_reg_operand" "")
+       (match_operand:DF 1 "any_operand" ""))
+   (set (match_operand:DF 2 "gpc_reg_operand" "")
+       (match_dup 0))]
+  "peep2_reg_dead_p (2, operands[0])"
+  [(set (match_dup 2) (match_dup 1))])
+
+(define_peephole2
+  [(set (match_operand:SF 0 "gpc_reg_operand" "")
+       (match_operand:SF 1 "any_operand" ""))
+   (set (match_operand:SF 2 "gpc_reg_operand" "")
+       (match_dup 0))]
+  "peep2_reg_dead_p (2, operands[0])"
+  [(set (match_dup 2) (match_dup 1))])
+
 \f
 ;; TLS support.
 
index 814b05b8e204ebceaab5bb6c96389d9d198235e4..64da733025fb6ad5bed2888c50bdd72314eec342 100644 (file)
@@ -1,5 +1,8 @@
 2004-11-11  Nathan Sidwell  <nathan@codesourcery.com>
 
+       PR target/16796
+       * gcc.dg/ppc-mov-1.c: New.
+
        PR target/16458
        * gcc.dg/ppc-compare-1.c: New.
 
diff --git a/gcc/testsuite/gcc.dg/ppc-mov-1.c b/gcc/testsuite/gcc.dg/ppc-mov-1.c
new file mode 100644 (file)
index 0000000..4256b60
--- /dev/null
@@ -0,0 +1,52 @@
+/* { dg-do compile { target powerpc64-*-* } } */
+/* { dg-options "-m64 -O2" } */
+
+/* { dg-final { scan-assembler-not "fmr \[0-9\]+,\[0-9\]+" } }
+
+/* Origin:Pete Steinmetz <steinmtz@us.ibm.com> */
+
+/* PR 16796: Extraneous move.  */
+
+static const double huge = 1.0e300;
+typedef int int64_t __attribute__ ((__mode__ (__DI__)));
+typedef unsigned int u_int64_t __attribute__ ((__mode__ (__DI__)));
+
+double __floor(double x)
+{
+  union {
+    double dbl_val;
+    long int long_val;
+  } temp;
+
+  int64_t i0,j0;
+  u_int64_t i;
+  temp.dbl_val = x;
+  i0 = temp.long_val;
+
+  j0 = ((i0>>52)&0x7ff)-0x3ff;
+  if(j0<52) {
+    if(j0<0) {
+      if(huge+x>0.0) {
+        if(i0>=0) {i0=0;}
+        else if((i0&0x7fffffffffffffff)!=0)
+        { i0=0xbff0000000000000;}
+      }
+    } else {
+      i = (0x000fffffffffffff)>>j0;
+      if((i0&i)==0) return x;
+      if(huge+x>0.0) {
+        if(i0<0) i0 += (0x0010000000000000)>>j0;
+        i0 &= (~i);
+      }
+    }
+  } else {
+    if (j0==0x400)
+      return x+x;
+    else
+      return x;
+  }
+  temp.long_val = i0;
+  x = temp.dbl_val;
+  return x;
+}
+