elliminate more float extensions

Jan Hubicka jh@suse.cz
Sat Jan 11 13:52:00 GMT 2003


Hi,
I've been looking for reasons of cvtss2sd (that is slow) in mesa sources and it
looks like that after installing floor conversion patches to hammer branch most
of these come from testcases like this:

/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -msse2 -march=athlon" } */
/* { dg-final { scan-assembler-not "cvtss2sd" } } */
float a,b;
main()
{
  a=b*3.0;
}

We can optimize the cvtss2sd away.  I am doing this by teaching strip_float_extensions
to find narrowest mode holding the FP constant so the rest of code will choose
narrowest mode holding the operands and result of the operation.

This deals with many conversions present in Mesa.  However there are still few remaining.
Most notably:
float a,b;
main()
{
  a=b*2.0;
}
where multiplication is converted into a=b+save_expr(b).
What is the proper way to deal with save expr in this case?  Is it needed at all?

Regtested/bootstrapped i386.  OK for mainline?
Honza

Sat Jan 11 14:42:31 CET 2003  Jan Hubicka  <jh@suse.cz>
	* convert.c (strip_float_extensions):  Look for narrowest type handling
	FP constants.

Index: convert.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/convert.c,v
retrieving revision 1.19.12.3
diff -c -3 -p -r1.19.12.3 convert.c
*** convert.c	11 Jan 2003 11:25:07 -0000	1.19.12.3
--- convert.c	11 Jan 2003 13:40:15 -0000
*************** Software Foundation, 59 Temple Place - S
*** 30,35 ****
--- 30,36 ----
  #include "convert.h"
  #include "toplev.h"
  #include "langhooks.h"
+ #include "real.h"
  
  /* Convert EXPR to some pointer or reference type TYPE.
  
*************** strip_float_extensions (exp)
*** 78,83 ****
--- 79,105 ----
  {
    tree sub, expt, subt;
  
+   /*  For floatingg point constant look up the narrowest type that can hold
+       it properly and handle it like (type)(narrowest_type)constant.
+       This way we can optimize for instance a=a*2.0 where "a" is float
+       but 2.0 is double constant.  */
+   if (TREE_CODE (exp) == REAL_CST)
+     {
+       REAL_VALUE_TYPE orig;
+       tree type = NULL;
+ 
+       orig = TREE_REAL_CST (exp);
+       if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node)
+ 	  && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
+ 	type = float_type_node;
+       else if (TYPE_PRECISION (TREE_TYPE (exp))
+ 	       > TYPE_PRECISION (double_type_node)
+ 	       && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
+ 	type = double_type_node;
+       if (type)
+ 	return build_real (type, real_value_truncate (TYPE_MODE (type), orig));
+     }
+ 
    if (TREE_CODE (exp) != NOP_EXPR)
      return exp;
  



More information about the Gcc-patches mailing list