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]

Re: Simplify FP conversions


> > > What then?  Can we enable it at unsafe-math at least?
> 
> Hum..  Maybe.  I'd just as soon leave those out though.
Uhm, do you want me to remove the unsafe_math tests?
> 
> > > I also seem to dimply recall that certain combination of modes won't
> > > cause double rounding.
> 
> When the intermediate fp mode is large enough to hold the 
> significand without rounding.  E.g. SI->DF->SF or DI->XF->SF.

That what I test for.
> 
> > +       /* (float_truncate:SF (float_truncate:DF foo:XF)) 
> > +          = (float_truncate:SF foo:XF). 
> > + 	 This may elliminate double rounding, so it is unsafe.
> 
> "eliminate".
> 
> > +          (float_truncate:DF (float_extend:XF foo:SF)) 
> > +          = (float_extend:SF foo:DF). */
> 
> Typo in example.
> 
> > + 	      || ((unsigned)significand_size (GET_MODE (XEXP (x, 0)))
> > + 		  >= (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
> > + 		      - num_sign_bit_copies (XEXP (XEXP (x, 0), 0),
> > + 					     GET_MODE (XEXP (XEXP (x, 0), 0)))))))
> 
> Good idea about the sign bit.  I suppose that could be taken further

It was kind of must - my previous patch does sign extension of HI to SI
totally confusing rest of the code.

I am attaching the updated patch (just with the typos fixed)


/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -march=k8 -mfpmath=sse" } */
/* { dg-final { scan-assembler "cvtsi2sd" } } */
/* Check that conversions will get folded.  */
double
main(short a)
{
  float b=a;
  return b;
}

Sun Feb  9 18:29:27 CET 2003  Jan Hubicka  <jh@suse.cz>
	* combine.c (combine_simplify_rtx): Simplify using
	(float_truncate (float x)) is (float x)
	(float_extend (float_extend x)) is (float_extend x).
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.337
diff -c -3 -p -r1.337 combine.c
*** combine.c	6 Feb 2003 19:26:42 -0000	1.337
--- combine.c	9 Feb 2003 22:31:40 -0000
*************** combine_simplify_rtx (x, op0_mode, last,
*** 4167,4172 ****
--- 4167,4202 ----
  	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
  	return XEXP (XEXP (x, 0), 0);
  
+       /* (float_truncate:SF (float_truncate:DF foo:XF)) 
+          = (float_truncate:SF foo:XF). 
+ 	 This may eliminate double rounding, so it is unsafe.
+ 
+          (float_truncate:SF (float_extend:XF foo:DF)) 
+          = (float_truncate:SF foo:DF). 
+ 
+          (float_truncate:DF (float_extend:XF foo:SF)) 
+          = (float_extend:DF foo:SF). */
+       if ((GET_CODE (XEXP (x, 0)) == FLOAT_TRUNCATE
+ 	   && flag_unsafe_math_optimizations)
+ 	  || GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND)
+ 	return simplify_gen_unary (GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0),
+ 		  					    0)))
+ 	    			   > GET_MODE_SIZE (mode)
+ 				   ? FLOAT_TRUNCATE : FLOAT_EXTEND,
+ 	    			   mode,
+ 				   XEXP (XEXP (XEXP (x, 0), 0), 0), mode);
+ 
+       /*  (float_truncate (float x)) is (float x)  */
+       if (GET_CODE (XEXP (x, 0)) == FLOAT
+ 	  && (flag_unsafe_math_optimizations
+ 	      || ((unsigned)significand_size (GET_MODE (XEXP (x, 0)))
+ 		  >= (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
+ 		      - num_sign_bit_copies (XEXP (XEXP (x, 0), 0),
+ 					     GET_MODE (XEXP (XEXP (x, 0), 0)))))))
+ 	return simplify_gen_unary (FLOAT, mode,
+ 				   XEXP (XEXP (x, 0), 0),
+ 				   GET_MODE (XEXP (XEXP (x, 0), 0)));
+ 
        /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
  	 (OP:SF foo:SF) if OP is NEG or ABS.  */
        if ((GET_CODE (XEXP (x, 0)) == ABS
*************** combine_simplify_rtx (x, op0_mode, last,
*** 4183,4189 ****
--- 4213,4235 ----
  	  && GET_CODE (SUBREG_REG (XEXP (x, 0))) == FLOAT_TRUNCATE)
  	return SUBREG_REG (XEXP (x, 0));
        break;
+     case FLOAT_EXTEND:
+       /*  (float_extend (float_extend x)) is (float_extend x)
+         
+ 	  (float_extend (float x)) is (float x) assuming that double
+ 	  rounding can't happen. 
+           */
+       if (GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND
+ 	  || (GET_CODE (XEXP (x, 0)) == FLOAT
+ 	      && ((unsigned)significand_size (GET_MODE (XEXP (x, 0)))
+ 		  >= (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
+ 		      - num_sign_bit_copies (XEXP (XEXP (x, 0), 0),
+ 					     GET_MODE (XEXP (XEXP (x, 0), 0)))))))
+ 	return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode,
+ 				   XEXP (XEXP (x, 0), 0),
+ 				   GET_MODE (XEXP (XEXP (x, 0), 0)));
  
+       break;
  #ifdef HAVE_cc0
      case COMPARE:
        /* Convert (compare FOO (const_int 0)) to FOO unless we aren't


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