This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PPC] Fix 16796


This is a partial fix for 16796 where we emit a load into rA
and then copy rA to rB.  It is partial, because this patch fixes
SF and DF mode regs, but not the integer mode registers.

What is happening is that flow2 replaces conditional branches
to the exit block with conditional return instructions.  After this,
the only path to the exit block is merged, and the load and the
move are now in the same bb.  It is not entirely the fault of the
register allocator -- we shouldn't really be changing cfg so
significantly after register allocation.

This adds two peepholes to spot SF and DF mode moves.  Unfortunately
I couldn't have a modeless peephole, because some single set patterns
expand to multi instruction sequences that early-clobber their output.
If the dest of the second move is an operand of such a first move, we
cannot merge.  To detect such situations I tried using get_attr_length
to see if the first set was a single instruction, but this clobbers the
operands array that the peepholer is using :(

booted & tested on powerpc64-unknown-linux-gnu, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2004-11-10  Nathan Sidwell  <nathan@codesourcery.com>

	PR rtl-optimization/16966
	* config/rs6000/rs6000.md: Add DF & SF reg move peepholes.

Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.329
diff -c -3 -p -r1.329 rs6000.md
*** config/rs6000/rs6000.md	8 Nov 2004 04:42:36 -0000	1.329
--- config/rs6000/rs6000.md	10 Nov 2004 17:28:26 -0000
***************
*** 9689,9694 ****
--- 9689,9717 ----
  	(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))])
+ 
  
  ;; TLS support.
  
/* { 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;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]