public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Simplify floating point conversions
@ 2002-11-05  9:14 Jan Hubicka
  2002-11-05  9:38 ` Richard Henderson
  2002-11-05 11:14 ` Simplify floating point conversions Geoff Keating
  0 siblings, 2 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-05  9:14 UTC (permalink / raw)
  To: gcc-patches, rth, aj

Hi,
this patch makes us to simplify some of the floating point operations to
narrower mode when conversions are present.  This include
+,-,/,*,abs,neg,sqrt/sin/cos/exp.
I believe it is IEEE safe, but some expert would be welcome.

The sqrt/sin/cos/exp conversion does not work in fortran mode, since
built_in_decls is not initialized.  I was trying to get around but never
suceeded to produce working call there.

Honza

Tue Nov  5 02:06:18 PST 2002  Jan Hubicka  <jh@suse.cz>
	* convert.c (convert_to_real): Simplify some special cases.
Index: convert.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/convert.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 convert.c
*** convert.c	4 Jul 2002 06:38:54 -0000	1.19
--- convert.c	5 Nov 2002 17:09:53 -0000
*************** tree
*** 80,85 ****
--- 80,203 ----
  convert_to_real (type, expr)
       tree type, expr;
  {
+   enum built_in_function fcode = builtin_mathfn_code (expr);
+   tree itype = TREE_TYPE (expr);
+ 
+   if ((fcode == BUILT_IN_SQRT
+        || fcode == BUILT_IN_SQRTL
+        || fcode == BUILT_IN_SIN
+        || fcode == BUILT_IN_SINL
+        || fcode == BUILT_IN_COS
+        || fcode == BUILT_IN_COSL
+        || fcode == BUILT_IN_EXP
+        || fcode == BUILT_IN_EXPL)
+       && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+           || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+     {
+       tree arg0 = TREE_VALUE (TREE_OPERAND (expr, 1));
+       tree newtype = type;
+ 
+       if (TREE_CODE (arg0) == NOP_EXPR)
+ 	arg0 = TREE_OPERAND (arg0, 0);
+ 
+       if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
+ 	newtype = TREE_TYPE (arg0);
+       if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 	  && TYPE_PRECISION (newtype) <= TYPE_PRECISION (itype)
+ 	  && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
+ 	      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
+ 	{
+ 	  tree arglist, decl;
+ 	  if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRTF;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SINF;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COSF;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXPF;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 	  else
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRT;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SIN;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COS;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXP;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 
+ 	  if (built_in_decls [fcode])
+ 	    {
+ 	      decl = build_function_call_expr (built_in_decls [fcode], arglist);
+ 	      return decl;
+ 	    }
+ 	}
+     }
+   if (itype != type && FLOAT_TYPE_P (type))
+     switch (TREE_CODE (expr))
+       {
+ 	case ABS_EXPR:
+ 	case NEGATE_EXPR:
+ 	  return build1 (TREE_CODE (expr), type,
+ 			 fold (convert_to_real (type,
+ 						TREE_OPERAND (expr, 0))));
+ 	case PLUS_EXPR:
+ 	case MINUS_EXPR:
+ 	case MULT_EXPR:
+ 	case RDIV_EXPR:
+ 	   {
+ 	     tree arg0 = TREE_OPERAND (expr, 0);
+ 	     tree arg1 = TREE_OPERAND (expr, 1);
+ 	     if (TREE_CODE (arg0) == NOP_EXPR)
+ 	       arg0 = TREE_OPERAND (arg0, 0);
+ 	     if (TREE_CODE (arg1) == NOP_EXPR)
+ 	       arg1 = TREE_OPERAND (arg1, 0);
+ 	     if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 		 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
+ 	       {
+ 		  tree newtype = type;
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg0);
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg1);
+ 		  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
+ 		    return build (TREE_CODE (expr), newtype,
+ 				  fold (convert_to_real (newtype, arg0)),
+ 				  fold (convert_to_real (newtype, arg1)));
+ 	       }
+ 	   }
+ 	  break;
+ 	default:
+ 	  break;
+       }
+ 
    switch (TREE_CODE (TREE_TYPE (expr)))
      {
      case REAL_TYPE:

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions
  2002-11-05  9:14 Simplify floating point conversions Jan Hubicka
@ 2002-11-05  9:38 ` Richard Henderson
  2002-11-05  9:42   ` Jan Hubicka
  2002-11-06  1:23   ` Simplify floating point conversions II Jan Hubicka
  2002-11-05 11:14 ` Simplify floating point conversions Geoff Keating
  1 sibling, 2 replies; 41+ messages in thread
From: Richard Henderson @ 2002-11-05  9:38 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, aj

On Tue, Nov 05, 2002 at 06:14:00PM +0100, Jan Hubicka wrote:
> Hi,
> this patch makes us to simplify some of the floating point operations to
> narrower mode when conversions are present.  This include
> +,-,/,*,abs,neg,sqrt/sin/cos/exp.
> I believe it is IEEE safe, but some expert would be welcome.

You should have commented this.  It should not take someone 5
minutes to even figure out what's going on here.  To be sure, it's

	(float)sqrtl(x)   ->  sqrtf((float)x)

correct?  Well, clearly this fails for X = 2**(127 * 2), since
X is not representable as a float, but its square root is.  It
would not be hard to identify similar problems with every other
operation on your list except for ABS/NEG.


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions
  2002-11-05  9:38 ` Richard Henderson
@ 2002-11-05  9:42   ` Jan Hubicka
  2002-11-06  1:23   ` Simplify floating point conversions II Jan Hubicka
  1 sibling, 0 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-05  9:42 UTC (permalink / raw)
  To: Richard Henderson, Jan Hubicka, gcc-patches, aj

> On Tue, Nov 05, 2002 at 06:14:00PM +0100, Jan Hubicka wrote:
> > Hi,
> > this patch makes us to simplify some of the floating point operations to
> > narrower mode when conversions are present.  This include
> > +,-,/,*,abs,neg,sqrt/sin/cos/exp.
> > I believe it is IEEE safe, but some expert would be welcome.
> 
> You should have commented this.  It should not take someone 5
Oops...
> minutes to even figure out what's going on here.  To be sure, it's
> 
> 	(float)sqrtl(x)   ->  sqrtf((float)x)

It does just (float)sqrt((float)x)->sqrtf(x)

This is common in C code when you call sqrt on float value.

Honza
> 
> correct?  Well, clearly this fails for X = 2**(127 * 2), since
> X is not representable as a float, but its square root is.  It
> would not be hard to identify similar problems with every other
> operation on your list except for ABS/NEG.
> 
> 
> r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions
  2002-11-05  9:14 Simplify floating point conversions Jan Hubicka
  2002-11-05  9:38 ` Richard Henderson
@ 2002-11-05 11:14 ` Geoff Keating
  2002-11-06  1:09   ` Jan Hubicka
  1 sibling, 1 reply; 41+ messages in thread
From: Geoff Keating @ 2002-11-05 11:14 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

Jan Hubicka <jh@suse.cz> writes:

> Hi,
> this patch makes us to simplify some of the floating point operations to
> narrower mode when conversions are present.  This include
> +,-,/,*,abs,neg,sqrt/sin/cos/exp.
> I believe it is IEEE safe, but some expert would be welcome.

It's not safe, except for 'abs' and 'neg'.  For example,
(float)sqrt(2.0 * FLT_MAX) != sqrtf(2.0 * FLT_MAX).
I think it would be OK for -ffast-math, though.

-- 
- Geoffrey Keating <geoffk@geoffk.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions
  2002-11-05 11:14 ` Simplify floating point conversions Geoff Keating
@ 2002-11-06  1:09   ` Jan Hubicka
  0 siblings, 0 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06  1:09 UTC (permalink / raw)
  To: Geoff Keating; +Cc: Jan Hubicka, gcc-patches

> Jan Hubicka <jh@suse.cz> writes:
> 
> > Hi,
> > this patch makes us to simplify some of the floating point operations to
> > narrower mode when conversions are present.  This include
> > +,-,/,*,abs,neg,sqrt/sin/cos/exp.
> > I believe it is IEEE safe, but some expert would be welcome.
> 
> It's not safe, except for 'abs' and 'neg'.  For example,
> (float)sqrt(2.0 * FLT_MAX) != sqrtf(2.0 * FLT_MAX).
> I think it would be OK for -ffast-math, though.

I am doing only (float)sqrt((double)float)
that commonly results from C code that uses floats but calls math
functions.  I can add fast-math code for weaker checks later, but first
I would like to know whether this transformation is valid.

I will add the comments :)  I usually write the automatically and
ididn't noticed there are none..

Honza
> 
> -- 
> - Geoffrey Keating <geoffk@geoffk.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Simplify floating point conversions II
  2002-11-05  9:38 ` Richard Henderson
  2002-11-05  9:42   ` Jan Hubicka
@ 2002-11-06  1:23   ` Jan Hubicka
  2002-11-06  3:08     ` Michael Matz
  2002-11-06  9:54     ` Jan Hubicka
  1 sibling, 2 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06  1:23 UTC (permalink / raw)
  To: Richard Henderson, Jan Hubicka, gcc-patches, aj

> On Tue, Nov 05, 2002 at 06:14:00PM +0100, Jan Hubicka wrote:
> > Hi,
> > this patch makes us to simplify some of the floating point operations to
> > narrower mode when conversions are present.  This include
> > +,-,/,*,abs,neg,sqrt/sin/cos/exp.
> > I believe it is IEEE safe, but some expert would be welcome.
> 
> You should have commented this.  It should not take someone 5
> minutes to even figure out what's going on here.  To be sure, it's
> 
> 	(float)sqrtl(x)   ->  sqrtf((float)x)
> 
> correct?  Well, clearly this fails for X = 2**(127 * 2), since
> X is not representable as a float, but its square root is.  It
> would not be hard to identify similar problems with every other
> operation on your list except for ABS/NEG.

Hi,
here is updated version with the comments.  Even when the cases it shoots for
looks incommon, they are not.  In mesa (real one, not spec2000) I get 110
conversions removed with this patch.  I get matches in most of code using
floats extensivly because of C conventions to implicitly cast to double in some
cases.

Interestingly enought I get matches in fortran code too in spec2000, so it may
be wortwhile to resolve the builtins problems.

Wed Nov  6 10:17:44 CET 2002  Jan Hubicka  <jh@suse.cz>
	* convert.c (convert_to_real):  Simplify some special cases.
Index: convert.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/convert.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 convert.c
*** convert.c	4 Jul 2002 06:38:54 -0000	1.19
--- convert.c	6 Nov 2002 09:16:56 -0000
*************** tree
*** 80,85 ****
--- 80,223 ----
  convert_to_real (type, expr)
       tree type, expr;
  {
+   enum built_in_function fcode = builtin_mathfn_code (expr);
+   tree itype = TREE_TYPE (expr);
+ 
+   /* Convert (float)sqrt((double)x) into sqrtf(x)
+      For fast math it would be safe probably to convert (float)sqrt(x)
+      into sqrt((float)x), but in strict mode the argument can overflow.  */
+   if ((fcode == BUILT_IN_SQRT
+        || fcode == BUILT_IN_SQRTL
+        || fcode == BUILT_IN_SIN
+        || fcode == BUILT_IN_SINL
+        || fcode == BUILT_IN_COS
+        || fcode == BUILT_IN_COSL
+        || fcode == BUILT_IN_EXP
+        || fcode == BUILT_IN_EXPL)
+       && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+           || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+     {
+       tree arg0 = TREE_VALUE (TREE_OPERAND (expr, 1));
+       tree newtype = type;
+ 
+       /* Wind away possible cast.  */
+       if (TREE_CODE (arg0) == NOP_EXPR)
+ 	arg0 = TREE_OPERAND (arg0, 0);
+ 
+       /* We have (outertype)sqrt((innertype)x).  Choose the wider mode from
+ 	 the both as the safe type for operation.  */
+       if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
+ 	newtype = TREE_TYPE (arg0);
+ 
+       /* Be curefull about integer to fp conversions.
+ 	 These may overflow still.  */
+       if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 	  && TYPE_PRECISION (newtype) <= TYPE_PRECISION (itype)
+ 	  && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
+ 	      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
+ 	{
+ 	  tree arglist, decl;
+ 	  if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRTF;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SINF;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COSF;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXPF;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 	  else
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRT;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SIN;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COS;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXP;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 
+ 	  /* ??? Fortran frontend does not initialize built_in_decls.
+ 	     For some reason creating the decl using builtin_function does not
+ 	     work as it should.   */
+ 	  if (built_in_decls [fcode])
+ 	    {
+ 	      decl = build_function_call_expr (built_in_decls [fcode], arglist);
+ 	      return decl;
+ 	    }
+ 	}
+     }
+ 
+   /* Propagate the cast into the operation.  */
+   if (itype != type && FLOAT_TYPE_P (type))
+     switch (TREE_CODE (expr))
+       {
+ 	/* convert (float)-x into -(float)x.  This is always safe.  */
+ 	case ABS_EXPR:
+ 	case NEGATE_EXPR:
+ 	  return build1 (TREE_CODE (expr), type,
+ 			 fold (convert_to_real (type,
+ 						TREE_OPERAND (expr, 0))));
+ 	/* convert (outertype)((innertype0)a+(innertype1)b)
+ 	   into ((newtype)a+(newtype)b) where newtype
+ 	   is the widest mode from all of these.  */
+ 	case PLUS_EXPR:
+ 	case MINUS_EXPR:
+ 	case MULT_EXPR:
+ 	case RDIV_EXPR:
+ 	   {
+ 	     tree arg0 = TREE_OPERAND (expr, 0);
+ 	     tree arg1 = TREE_OPERAND (expr, 1);
+ 
+ 	     /* Unwind possible casts.  */
+ 	     if (TREE_CODE (arg0) == NOP_EXPR)
+ 	       arg0 = TREE_OPERAND (arg0, 0);
+ 	     if (TREE_CODE (arg1) == NOP_EXPR)
+ 	       arg1 = TREE_OPERAND (arg1, 0);
+ 	     if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 		 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
+ 	       {
+ 		  tree newtype = type;
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg0);
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg1);
+ 		  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
+ 		    return build (TREE_CODE (expr), newtype,
+ 				  fold (convert_to_real (newtype, arg0)),
+ 				  fold (convert_to_real (newtype, arg1)));
+ 	       }
+ 	   }
+ 	  break;
+ 	default:
+ 	  break;
+       }
+ 
    switch (TREE_CODE (TREE_TYPE (expr)))
      {
      case REAL_TYPE:

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06  1:23   ` Simplify floating point conversions II Jan Hubicka
@ 2002-11-06  3:08     ` Michael Matz
  2002-11-06  4:36       ` Jan Hubicka
  2002-11-06  9:54     ` Jan Hubicka
  1 sibling, 1 reply; 41+ messages in thread
From: Michael Matz @ 2002-11-06  3:08 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

Hi,

On Wed, 6 Nov 2002, Jan Hubicka wrote:

> +   /* Convert (float)sqrt((double)x) into sqrtf(x)

You probably want to say that you do this when x is float, which is
exactly the crucial point in your patch.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06  3:08     ` Michael Matz
@ 2002-11-06  4:36       ` Jan Hubicka
  0 siblings, 0 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06  4:36 UTC (permalink / raw)
  To: Michael Matz; +Cc: Jan Hubicka, Richard Henderson, gcc-patches, aj

> Hi,
> 
> On Wed, 6 Nov 2002, Jan Hubicka wrote:
> 
> > +   /* Convert (float)sqrt((double)x) into sqrtf(x)
> 
> You probably want to say that you do this when x is float, which is
> exactly the crucial point in your patch.
It is writen in the next comment, but you are right, I should do that.

Honza
> 
> 
> Ciao,
> Michael.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06  1:23   ` Simplify floating point conversions II Jan Hubicka
  2002-11-06  3:08     ` Michael Matz
@ 2002-11-06  9:54     ` Jan Hubicka
  2002-11-06 10:09       ` Richard Henderson
  1 sibling, 1 reply; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06  9:54 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

Hi,
I've noticed that one line of patch got lost for some reason.

Honza
Wed Nov  6 10:17:44 CET 2002  Jan Hubicka  <jh@suse.cz>
	* convert.c (convert_to_real):  Simplify some special cases.

Index: convert.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/convert.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 convert.c
*** convert.c	4 Jul 2002 06:38:54 -0000	1.19
--- convert.c	6 Nov 2002 17:53:09 -0000
*************** tree
*** 80,85 ****
--- 80,223 ----
  convert_to_real (type, expr)
       tree type, expr;
  {
+   enum built_in_function fcode = builtin_mathfn_code (expr);
+   tree itype = TREE_TYPE (expr);
+ 
+   /* Convert (float)sqrt((double)x) into sqrtf(x)
+      For fast math it would be safe probably to convert (float)sqrt(x)
+      into sqrt((float)x), but in strict mode the argument can overflow.  */
+   if ((fcode == BUILT_IN_SQRT
+        || fcode == BUILT_IN_SQRTL
+        || fcode == BUILT_IN_SIN
+        || fcode == BUILT_IN_SINL
+        || fcode == BUILT_IN_COS
+        || fcode == BUILT_IN_COSL
+        || fcode == BUILT_IN_EXP
+        || fcode == BUILT_IN_EXPL)
+       && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+           || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+     {
+       tree arg0 = TREE_VALUE (TREE_OPERAND (expr, 1));
+       tree newtype = type;
+ 
+       /* Wind away possible cast.  */
+       if (TREE_CODE (arg0) == NOP_EXPR)
+ 	arg0 = TREE_OPERAND (arg0, 0);
+ 
+       /* We have (outertype)sqrt((innertype)x).  Choose the wider mode from
+ 	 the both as the safe type for operation.  */
+       if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
+ 	newtype = TREE_TYPE (arg0);
+ 
+       /* Be curefull about integer to fp conversions.
+ 	 These may overflow still.  */
+       if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 	  && TYPE_PRECISION (newtype) <= TYPE_PRECISION (itype)
+ 	  && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
+ 	      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
+ 	{
+ 	  tree arglist, decl;
+ 	  if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRTF;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SINF;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COSF;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXPF;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 	  else
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRT;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SIN;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COS;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXP;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 
+ 	  /* ??? Fortran frontend does not initialize built_in_decls.
+ 	     For some reason creating the decl using builtin_function does not
+ 	     work as it should.   */
+ 	  if (built_in_decls [fcode])
+ 	    {
+ 	      arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
+ 	      return build_function_call_expr (built_in_decls [fcode], arglist);
+ 	    }
+ 	}
+     }
+ 
+   /* Propagate the cast into the operation.  */
+   if (itype != type && FLOAT_TYPE_P (type))
+     switch (TREE_CODE (expr))
+       {
+ 	/* convert (float)-x into -(float)x.  This is always safe.  */
+ 	case ABS_EXPR:
+ 	case NEGATE_EXPR:
+ 	  return build1 (TREE_CODE (expr), type,
+ 			 fold (convert_to_real (type,
+ 						TREE_OPERAND (expr, 0))));
+ 	/* convert (outertype)((innertype0)a+(innertype1)b)
+ 	   into ((newtype)a+(newtype)b) where newtype
+ 	   is the widest mode from all of these.  */
+ 	case PLUS_EXPR:
+ 	case MINUS_EXPR:
+ 	case MULT_EXPR:
+ 	case RDIV_EXPR:
+ 	   {
+ 	     tree arg0 = TREE_OPERAND (expr, 0);
+ 	     tree arg1 = TREE_OPERAND (expr, 1);
+ 
+ 	     /* Unwind possible casts.  */
+ 	     if (TREE_CODE (arg0) == NOP_EXPR)
+ 	       arg0 = TREE_OPERAND (arg0, 0);
+ 	     if (TREE_CODE (arg1) == NOP_EXPR)
+ 	       arg1 = TREE_OPERAND (arg1, 0);
+ 	     if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 		 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
+ 	       {
+ 		  tree newtype = type;
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg0);
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg1);
+ 		  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
+ 		    return build (TREE_CODE (expr), newtype,
+ 				  fold (convert_to_real (newtype, arg0)),
+ 				  fold (convert_to_real (newtype, arg1)));
+ 	       }
+ 	   }
+ 	  break;
+ 	default:
+ 	  break;
+       }
+ 
    switch (TREE_CODE (TREE_TYPE (expr)))
      {
      case REAL_TYPE:

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06  9:54     ` Jan Hubicka
@ 2002-11-06 10:09       ` Richard Henderson
  2002-11-06 13:11         ` Jan Hubicka
  2002-11-06 13:48         ` Simplify floating point conversions III Jan Hubicka
  0 siblings, 2 replies; 41+ messages in thread
From: Richard Henderson @ 2002-11-06 10:09 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, aj

On Wed, Nov 06, 2002 at 06:54:41PM +0100, Jan Hubicka wrote:
> +      For fast math it would be safe probably to convert (float)sqrt(x)
> +      into sqrt((float)x), but in strict mode the argument can overflow.  */

I don't believe this to be true.

> +       /* Wind away possible cast.  */
> +       if (TREE_CODE (arg0) == NOP_EXPR)
> + 	arg0 = TREE_OPERAND (arg0, 0);

Why would you do this?  This might be casting down to double from
long double.  You should only strip casts when they widen the type.

> + 	/* convert (outertype)((innertype0)a+(innertype1)b)
> + 	   into ((newtype)a+(newtype)b) where newtype
> + 	   is the widest mode from all of these.  */

This changes overflow characteristics of +.  Consider

	(double)((float)a + (float)b)

where A = B = 2**127.  The result should be +Inf, not 2**128.

Finally, I think it is alarmingly incorrect that

	(float)((double)a + (double)b))

does not result in a quantity of type float, as requested.


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06 10:09       ` Richard Henderson
@ 2002-11-06 13:11         ` Jan Hubicka
  2002-11-06 13:19           ` Jan Hubicka
  2002-11-06 13:35           ` Gabriel Dos Reis
  2002-11-06 13:48         ` Simplify floating point conversions III Jan Hubicka
  1 sibling, 2 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06 13:11 UTC (permalink / raw)
  To: Richard Henderson, Jan Hubicka, gcc-patches, aj

> On Wed, Nov 06, 2002 at 06:54:41PM +0100, Jan Hubicka wrote:
> > +      For fast math it would be safe probably to convert (float)sqrt(x)
> > +      into sqrt((float)x), but in strict mode the argument can overflow.  */
> 
> I don't believe this to be true.

What you don't believe? That in ffast-math we can do the transformation?
Right, that is possible.  I am not sure whehter we can afford the
possible overflow there.  So I can drop the comment.
> 
> > +       /* Wind away possible cast.  */
> > +       if (TREE_CODE (arg0) == NOP_EXPR)
> > + 	arg0 = TREE_OPERAND (arg0, 0);
> 
> Why would you do this?  This might be casting down to double from
> long double.  You should only strip casts when they widen the type.

Right, I will add that.  For some reason I believed that these are
CONVERT.
> 
> > + 	/* convert (outertype)((innertype0)a+(innertype1)b)
> > + 	   into ((newtype)a+(newtype)b) where newtype
> > + 	   is the widest mode from all of these.  */
> 
> This changes overflow characteristics of +.  Consider
> 
> 	(double)((float)a + (float)b)
> 
> where A = B = 2**127.  The result should be +Inf, not 2**128.

I am doing that only when the mode of + is wider.
> 
> Finally, I think it is alarmingly incorrect that
> 
> 	(float)((double)a + (double)b))
> 
> does not result in a quantity of type float, as requested.

Here I do that.  When a and b are floats, I will produce
(a+b)
is that wrong?

Honza
> 
> 
> r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06 13:11         ` Jan Hubicka
@ 2002-11-06 13:19           ` Jan Hubicka
  2002-11-06 13:35           ` Gabriel Dos Reis
  1 sibling, 0 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06 13:19 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

> > On Wed, Nov 06, 2002 at 06:54:41PM +0100, Jan Hubicka wrote:
> > > +      For fast math it would be safe probably to convert (float)sqrt(x)
> > 	(double)((float)a + (float)b)
> > 
> > where A = B = 2**127.  The result should be +Inf, not 2**128.
> 
> I am doing that only when the mode of + is wider.
> > 
> > Finally, I think it is alarmingly incorrect that
> > 
> > 	(float)((double)a + (double)b))
> > 
> > does not result in a quantity of type float, as requested.
> 
> Here I do that.  When a and b are floats, I will produce
> (a+b)
> is that wrong?

I see, you were shooting for something like
(float)((long double)a + (long double)b)
for a and b being double.  That will result in (a+b) not casted to float
that is wrong.  I am adding recursive call to convert_to_real when this
ahppends.

Honza
> 
> Honza
> > 
> > 
> > r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06 13:11         ` Jan Hubicka
  2002-11-06 13:19           ` Jan Hubicka
@ 2002-11-06 13:35           ` Gabriel Dos Reis
  2002-11-06 13:36             ` Jan Hubicka
  2002-11-06 14:29             ` Converting floor to rint Jan Hubicka
  1 sibling, 2 replies; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-06 13:35 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

Jan Hubicka <jh@suse.cz> writes:

| > On Wed, Nov 06, 2002 at 06:54:41PM +0100, Jan Hubicka wrote:
| > > +      For fast math it would be safe probably to convert (float)sqrt(x)
| > > +      into sqrt((float)x), but in strict mode the argument can overflow.  */
| > 
| > I don't believe this to be true.
| 
| What you don't believe?

Likew RTH, I, skeptical that your assertion is right.

| That in ffast-math we can do the transformation?

Do we really need to do that transformation?  That is is there any
real evidence that it brings any real benefit?
I would be reluctant to include it even in -funsafe-math.

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06 13:35           ` Gabriel Dos Reis
@ 2002-11-06 13:36             ` Jan Hubicka
  2002-11-06 14:06               ` Gabriel Dos Reis
  2002-11-06 14:29             ` Converting floor to rint Jan Hubicka
  1 sibling, 1 reply; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06 13:36 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Jan Hubicka, Richard Henderson, gcc-patches, aj

> Jan Hubicka <jh@suse.cz> writes:
> 
> | > On Wed, Nov 06, 2002 at 06:54:41PM +0100, Jan Hubicka wrote:
> | > > +      For fast math it would be safe probably to convert (float)sqrt(x)
> | > > +      into sqrt((float)x), but in strict mode the argument can overflow.  */
> | > 
> | > I don't believe this to be true.
> | 
> | What you don't believe?
> 
> Likew RTH, I, skeptical that your assertion is right.
> 
> | That in ffast-math we can do the transformation?
> 
> Do we really need to do that transformation?  That is is there any
> real evidence that it brings any real benefit?
> I would be reluctant to include it even in -funsafe-math.
I am not implementing that transformation, so I am not sure.
Doing the cases I do right now and I believe to be safe brings quite
considerable amount of matches in standard C 3d graphics code that does
a lot of float and some casts to double coming from implicit C stuff.

Honza
> 
> -- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Simplify floating point conversions III
  2002-11-06 10:09       ` Richard Henderson
  2002-11-06 13:11         ` Jan Hubicka
@ 2002-11-06 13:48         ` Jan Hubicka
  2002-11-06 14:55           ` Richard Henderson
  1 sibling, 1 reply; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06 13:48 UTC (permalink / raw)
  To: Richard Henderson, Jan Hubicka, gcc-patches, aj

> On Wed, Nov 06, 2002 at 06:54:41PM +0100, Jan Hubicka wrote:
> > +      For fast math it would be safe probably to convert (float)sqrt(x)
> > +      into sqrt((float)x), but in strict mode the argument can overflow.  */
> 
> I don't believe this to be true.
> 
> > +       /* Wind away possible cast.  */
> > +       if (TREE_CODE (arg0) == NOP_EXPR)
> > + 	arg0 = TREE_OPERAND (arg0, 0);
> 
> Why would you do this?  This might be casting down to double from
> long double.  You should only strip casts when they widen the type.
> 
> > + 	/* convert (outertype)((innertype0)a+(innertype1)b)
> > + 	   into ((newtype)a+(newtype)b) where newtype
> > + 	   is the widest mode from all of these.  */
> 
> This changes overflow characteristics of +.  Consider
> 
> 	(double)((float)a + (float)b)
> 
> where A = B = 2**127.  The result should be +Inf, not 2**128.
> 
> Finally, I think it is alarmingly incorrect that
> 
> 	(float)((double)a + (double)b))
> 
> does not result in a quantity of type float, as requested.
Hi,
this patch fixes the two problems and removes the comment.

Honza

Wed Nov  6 10:17:44 CET 2002  Jan Hubicka  <jh@suse.cz>
	* convert.c (convert_to_real):  Simplify some special cases.

Index: convert.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/convert.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 convert.c
*** convert.c	4 Jul 2002 06:38:54 -0000	1.19
--- convert.c	6 Nov 2002 21:45:01 -0000
*************** tree
*** 80,85 ****
--- 80,233 ----
  convert_to_real (type, expr)
       tree type, expr;
  {
+   enum built_in_function fcode = builtin_mathfn_code (expr);
+   tree itype = TREE_TYPE (expr);
+ 
+   /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
+   if ((fcode == BUILT_IN_SQRT
+        || fcode == BUILT_IN_SQRTL
+        || fcode == BUILT_IN_SIN
+        || fcode == BUILT_IN_SINL
+        || fcode == BUILT_IN_COS
+        || fcode == BUILT_IN_COSL
+        || fcode == BUILT_IN_EXP
+        || fcode == BUILT_IN_EXPL)
+       && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+           || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+     {
+       tree arg0 = TREE_VALUE (TREE_OPERAND (expr, 1));
+       tree newtype = type;
+ 
+       /* Wind away possible cast.  */
+       if (TREE_CODE (arg0) == NOP_EXPR
+ 	  && (TYPE_PRECISION (TREE_TYPE (arg0))
+ 	      > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
+ 	arg0 = TREE_OPERAND (arg0, 0);
+ 
+       /* We have (outertype)sqrt((innertype)x).  Choose the wider mode from
+ 	 the both as the safe type for operation.  */
+       if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
+ 	newtype = TREE_TYPE (arg0);
+ 
+       /* Be curefull about integer to fp conversions.
+ 	 These may overflow still.  */
+       if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 	  && TYPE_PRECISION (newtype) <= TYPE_PRECISION (itype)
+ 	  && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
+ 	      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
+ 	{
+ 	  tree arglist;
+ 	  if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRTF;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SINF;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COSF;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXPF;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 	  else
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRT;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SIN;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COS;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXP;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 
+ 	  /* ??? Fortran frontend does not initialize built_in_decls.
+ 	     For some reason creating the decl using builtin_function does not
+ 	     work as it should.   */
+ 	  if (built_in_decls [fcode])
+ 	    {
+ 	      arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
+ 	      expr = build_function_call_expr (built_in_decls [fcode], arglist);
+ 	      if (newtype == type)
+ 		return expr;
+ 	    }
+ 	}
+     }
+ 
+   /* Propagate the cast into the operation.  */
+   if (itype != type && FLOAT_TYPE_P (type))
+     switch (TREE_CODE (expr))
+       {
+ 	/* convert (float)-x into -(float)x.  This is always safe.  */
+ 	case ABS_EXPR:
+ 	case NEGATE_EXPR:
+ 	  return build1 (TREE_CODE (expr), type,
+ 			 fold (convert_to_real (type,
+ 						TREE_OPERAND (expr, 0))));
+ 	/* convert (outertype)((innertype0)a+(innertype1)b)
+ 	   into ((newtype)a+(newtype)b) where newtype
+ 	   is the widest mode from all of these.  */
+ 	case PLUS_EXPR:
+ 	case MINUS_EXPR:
+ 	case MULT_EXPR:
+ 	case RDIV_EXPR:
+ 	   {
+ 	     tree arg0 = TREE_OPERAND (expr, 0);
+ 	     tree arg1 = TREE_OPERAND (expr, 1);
+ 
+ 	     /* Unwind possible casts.  */
+ 	     if (TREE_CODE (arg0) == NOP_EXPR
+ 		 && (TYPE_PRECISION (TREE_TYPE (arg0))
+ 		     > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
+ 	       arg0 = TREE_OPERAND (arg0, 0);
+ 	     if (TREE_CODE (arg1) == NOP_EXPR
+ 		 && (TYPE_PRECISION (TREE_TYPE (arg1))
+ 		     > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)))))
+ 	       arg1 = TREE_OPERAND (arg1, 0);
+ 	     if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 		 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
+ 	       {
+ 		  tree newtype = type;
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg0);
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg1);
+ 		  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
+ 		    {
+ 		      expr = build (TREE_CODE (expr), newtype,
+ 				    fold (convert_to_real (newtype, arg0)),
+ 				    fold (convert_to_real (newtype, arg1)));
+ 		      if (newtype == type)
+ 			return expr;
+ 		    }
+ 	       }
+ 	   }
+ 	  break;
+ 	default:
+ 	  break;
+       }
+ 
    switch (TREE_CODE (TREE_TYPE (expr)))
      {
      case REAL_TYPE:

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions II
  2002-11-06 13:36             ` Jan Hubicka
@ 2002-11-06 14:06               ` Gabriel Dos Reis
  0 siblings, 0 replies; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-06 14:06 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

Jan Hubicka <jh@suse.cz> writes:

| I am not implementing that transformation, so I am not sure.

Well, OK then I don't think I have any further comment on that side.

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Converting floor to rint
  2002-11-06 13:35           ` Gabriel Dos Reis
  2002-11-06 13:36             ` Jan Hubicka
@ 2002-11-06 14:29             ` Jan Hubicka
  2002-11-06 14:47               ` Richard Henderson
  2002-11-06 14:55               ` Gabriel Dos Reis
  1 sibling, 2 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06 14:29 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Jan Hubicka, Richard Henderson, gcc-patches, aj

> Jan Hubicka <jh@suse.cz> writes:
> 
> | > On Wed, Nov 06, 2002 at 06:54:41PM +0100, Jan Hubicka wrote:
> | > > +      For fast math it would be safe probably to convert (float)sqrt(x)
> | > > +      into sqrt((float)x), but in strict mode the argument can overflow.  */
> | > 
> | > I don't believe this to be true.
> | 
> | What you don't believe?
> 
> Likew RTH, I, skeptical that your assertion is right.
> 
> | That in ffast-math we can do the transformation?
> 
> Do we really need to do that transformation?  That is is there any
> real evidence that it brings any real benefit?
> I would be reluctant to include it even in -funsafe-math.

On the related note.  How bad would you consider converting
floor(x) into rint(x-0.5) in the fast-math mode?
That transformation would do a miracles for i386, where rint is faster
than floor by quite a lot and should suffice for 3D application in
reliablility.  I can imagine it to fail only for very large numbers...

Honza
> 
> -- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-06 14:29             ` Converting floor to rint Jan Hubicka
@ 2002-11-06 14:47               ` Richard Henderson
  2002-11-06 14:53                 ` Jan Hubicka
  2002-11-06 14:55               ` Gabriel Dos Reis
  1 sibling, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2002-11-06 14:47 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Gabriel Dos Reis, gcc-patches, aj

On Wed, Nov 06, 2002 at 11:29:22PM +0100, Jan Hubicka wrote:
> On the related note.  How bad would you consider converting
> floor(x) into rint(x-0.5) in the fast-math mode?

Well, let's see...

If the current rounding mode is FE_UPWARD, then

	rint(1.7 - 0.5) = rint(1.2) = 2.0

I.e.  we'd be computing CEIL instead of FLOOR.

If the current rounding mode is FE_TONEAREST, which is the case
I assume you were thinking about, we round ties to even, so

	rint(5.0 - 0.5) = rint(4.5) = 4.0

instead of the expected value 5.0.

So, I think this would be a very bad idea, even for -ffast-math.



r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-06 14:47               ` Richard Henderson
@ 2002-11-06 14:53                 ` Jan Hubicka
  0 siblings, 0 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-06 14:53 UTC (permalink / raw)
  To: Richard Henderson, Jan Hubicka, Gabriel Dos Reis, gcc-patches, aj

> On Wed, Nov 06, 2002 at 11:29:22PM +0100, Jan Hubicka wrote:
> > On the related note.  How bad would you consider converting
> > floor(x) into rint(x-0.5) in the fast-math mode?
> 
> Well, let's see...
> 
> If the current rounding mode is FE_UPWARD, then
> 
> 	rint(1.7 - 0.5) = rint(1.2) = 2.0
> 
> I.e.  we'd be computing CEIL instead of FLOOR.
> 
> If the current rounding mode is FE_TONEAREST, which is the case
> I assume you were thinking about, we round ties to even, so
> 
> 	rint(5.0 - 0.5) = rint(4.5) = 4.0
> 
> instead of the expected value 5.0.
> 
> So, I think this would be a very bad idea, even for -ffast-math.
Hmmm... OK then :(

Honza
> 
> 
> 
> r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions III
  2002-11-06 13:48         ` Simplify floating point conversions III Jan Hubicka
@ 2002-11-06 14:55           ` Richard Henderson
  2002-11-07  2:54             ` Simplify floating point conversions IV Jan Hubicka
  0 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2002-11-06 14:55 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, aj

On Wed, Nov 06, 2002 at 10:48:03PM +0100, Jan Hubicka wrote:
> +       /* Wind away possible cast.  */
> +       if (TREE_CODE (arg0) == NOP_EXPR
> + 	  && (TYPE_PRECISION (TREE_TYPE (arg0))
> + 	      > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
> + 	arg0 = TREE_OPERAND (arg0, 0);
[...]
> +       /* Be curefull about integer to fp conversions.
> + 	 These may overflow still.  */
> +       if (FLOAT_TYPE_P (TREE_TYPE (arg0))

I'd rather something like

static tree
strip_float_extensions (exp)
     tree exp;
{
  tree sub, expt, subt;

  if (TREE_CODE (exp) != NOP_EXPR)
    return exp;

  sub = TREE_OPERAND (exp, 0);
  subt = TREE_TYPE (sub);
  expt = TREE_TYPE (exp);

  if (!FLOAT_TYPE_P (subt))
    return exp;

  if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
    return exp;

  return strip_float_extensions (sub);
}

> + 	case RDIV_EXPR:
> + 	   {
> + 	     tree arg0 = TREE_OPERAND (expr, 0);
> + 	     tree arg1 = TREE_OPERAND (expr, 1);
> + 
> + 	     /* Unwind possible casts.  */

Useful here as well.


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-06 14:29             ` Converting floor to rint Jan Hubicka
  2002-11-06 14:47               ` Richard Henderson
@ 2002-11-06 14:55               ` Gabriel Dos Reis
  2002-11-07  1:21                 ` Jan Hubicka
  1 sibling, 1 reply; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-06 14:55 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

Jan Hubicka <jh@suse.cz> writes:

| On the related note.  How bad would you consider converting
| floor(x) into rint(x-0.5) in the fast-math mode?

If you think you do want to do that transformation, then I would
prefer this

  floor(x) -> nearbyint(x-0.5)

| That transformation would do a miracles for i386, where rint is faster
| than floor by quite a lot and should suffice for 3D application in
| reliablility.  I can imagine it to fail only for very large numbers...

Not really.  floor(1) == 1 and rint(1 - 0.5) maybe be 0 or 1 depending
on the current rounding mode.

I don't think that I really like that transformation, even under
-funsafe-math.  But I would like to hear other people opinons.

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-06 14:55               ` Gabriel Dos Reis
@ 2002-11-07  1:21                 ` Jan Hubicka
  2002-11-07  1:32                   ` Jakub Jelinek
  2002-11-07  1:33                   ` Gabriel Dos Reis
  0 siblings, 2 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-07  1:21 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Jan Hubicka, Richard Henderson, gcc-patches, aj

> Jan Hubicka <jh@suse.cz> writes:
> 
> | On the related note.  How bad would you consider converting
> | floor(x) into rint(x-0.5) in the fast-math mode?
> 
> If you think you do want to do that transformation, then I would
> prefer this
> 
>   floor(x) -> nearbyint(x-0.5)
> 
> | That transformation would do a miracles for i386, where rint is faster
> | than floor by quite a lot and should suffice for 3D application in
> | reliablility.  I can imagine it to fail only for very large numbers...
> 
> Not really.  floor(1) == 1 and rint(1 - 0.5) maybe be 0 or 1 depending
> on the current rounding mode.
Hmm, is rint really expected to be dependent on the rouding mode?
Man page claims:
       The nearbyint functions round their argument to an integer value
       in floating point format, using the current
       rounding direction and without raising the inexact
       exception.

       The rint functions do the same, but will raise the
       inexact exception when the result differs in  value
       from the argument.

I can builtinize nearbyint too if it makes sense.  I am bit confused by
rint.  Does it imply that rint will raise exception for any non-integral
arugment?

Honza
> 
> I don't think that I really like that transformation, even under
> -funsafe-math.  But I would like to hear other people opinons.
> 
> -- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  1:21                 ` Jan Hubicka
@ 2002-11-07  1:32                   ` Jakub Jelinek
  2002-11-07  1:33                   ` Gabriel Dos Reis
  1 sibling, 0 replies; 41+ messages in thread
From: Jakub Jelinek @ 2002-11-07  1:32 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Gabriel Dos Reis, Richard Henderson, gcc-patches, aj

On Thu, Nov 07, 2002 at 10:21:12AM +0100, Jan Hubicka wrote:
> > | On the related note.  How bad would you consider converting
> > | floor(x) into rint(x-0.5) in the fast-math mode?
> > 
> > If you think you do want to do that transformation, then I would
> > prefer this
> > 
> >   floor(x) -> nearbyint(x-0.5)
> > 
> > | That transformation would do a miracles for i386, where rint is faster
> > | than floor by quite a lot and should suffice for 3D application in
> > | reliablility.  I can imagine it to fail only for very large numbers...
> > 
> > Not really.  floor(1) == 1 and rint(1 - 0.5) maybe be 0 or 1 depending
> > on the current rounding mode.
> Hmm, is rint really expected to be dependent on the rouding mode?
> Man page claims:
>        The nearbyint functions round their argument to an integer value
>        in floating point format, using the current
>        rounding direction and without raising the inexact
>        exception.
> 
>        The rint functions do the same, but will raise the
>        inexact exception when the result differs in  value
>        from the argument.
> 
> I can builtinize nearbyint too if it makes sense.  I am bit confused by
> rint.  Does it imply that rint will raise exception for any non-integral
> arugment?

If FE_INEXACT is enabled, yes.

	Jakub

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  1:21                 ` Jan Hubicka
  2002-11-07  1:32                   ` Jakub Jelinek
@ 2002-11-07  1:33                   ` Gabriel Dos Reis
  2002-11-07  1:44                     ` Jan Hubicka
  2002-11-07  2:04                     ` Jan Hubicka
  1 sibling, 2 replies; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-07  1:33 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

Jan Hubicka <jh@suse.cz> writes:

| > Jan Hubicka <jh@suse.cz> writes:
| > 
| > | On the related note.  How bad would you consider converting
| > | floor(x) into rint(x-0.5) in the fast-math mode?
| > 
| > If you think you do want to do that transformation, then I would
| > prefer this
| > 
| >   floor(x) -> nearbyint(x-0.5)
| > 
| > | That transformation would do a miracles for i386, where rint is faster
| > | than floor by quite a lot and should suffice for 3D application in
| > | reliablility.  I can imagine it to fail only for very large numbers...
| > 
| > Not really.  floor(1) == 1 and rint(1 - 0.5) maybe be 0 or 1 depending
| > on the current rounding mode.
| Hmm, is rint really expected to be dependent on the rouding mode?
| Man page claims:
|        The nearbyint functions round their argument to an integer value
|        in floating point format, using the current
|        rounding direction and without raising the inexact
|        exception.
| 
|        The rint functions do the same, but will raise the
|        inexact exception when the result differs in  value
|        from the argument.

The C definition says:

       7.12.9.3  The nearbyint functions

       Synopsis

       [#1]

               #include <math.h>
               double nearbyint(double x);
               float nearbyintf(float x);
               long double nearbyintl(long double x);

       Description

       [#2]  The  nearbyint  functions  round  their argument to an
       integer value in floating-point format,  using  the  current
       rounding  direction  and  without  raising  the  ``inexact''
       floating-point exception.

       Returns

       [#3] The nearbyint  functions  return  the  rounded  integer
       value.

       7.12.9.4  The rint functions

       Synopsis

       [#1]

               #include <math.h>
               double rint(double x);
               float rintf(float x);
               long double rintl(long double x);

       Description

       [#2]  The rint functions differ from the nearbyint functions
       (7.12.9.3) only in that the rint  functions  may  raise  the
       ``inexact''  floating-point  exception if the result differs
       in value from the argument.

       Returns

       [#3] The rint functions return the rounded integer value.

| I can builtinize nearbyint too if it makes sense.

Do we have framework to deal correctly with current rounding mode?
I not, I would say, leave it as is until we have the appropriate
machinery. 

| I am bit confused by
| rint.  Does it imply that rint will raise exception for any non-integral
| arugment?

And depending on the rounding mode.

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  1:33                   ` Gabriel Dos Reis
@ 2002-11-07  1:44                     ` Jan Hubicka
  2002-11-07  1:52                       ` Jakub Jelinek
  2002-11-07  2:04                     ` Jan Hubicka
  1 sibling, 1 reply; 41+ messages in thread
From: Jan Hubicka @ 2002-11-07  1:44 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Jan Hubicka, Richard Henderson, gcc-patches, aj

> Jan Hubicka <jh@suse.cz> writes:
> 
> | > Jan Hubicka <jh@suse.cz> writes:
> | > 
> | > | On the related note.  How bad would you consider converting
> | > | floor(x) into rint(x-0.5) in the fast-math mode?
> | > 
> | > If you think you do want to do that transformation, then I would
> | > prefer this
> | > 
> | >   floor(x) -> nearbyint(x-0.5)
> | > 
> | > | That transformation would do a miracles for i386, where rint is faster
> | > | than floor by quite a lot and should suffice for 3D application in
> | > | reliablility.  I can imagine it to fail only for very large numbers...
> | > 
> | > Not really.  floor(1) == 1 and rint(1 - 0.5) maybe be 0 or 1 depending
> | > on the current rounding mode.
> | Hmm, is rint really expected to be dependent on the rouding mode?
> | Man page claims:
> |        The nearbyint functions round their argument to an integer value
> |        in floating point format, using the current
> |        rounding direction and without raising the inexact
> |        exception.
> | 
> |        The rint functions do the same, but will raise the
> |        inexact exception when the result differs in  value
> |        from the argument.
> 
> The C definition says:
> 
>        7.12.9.3  The nearbyint functions
> 
>        Synopsis
> 
>        [#1]
> 
>                #include <math.h>
>                double nearbyint(double x);
>                float nearbyintf(float x);
>                long double nearbyintl(long double x);
> 
>        Description
> 
>        [#2]  The  nearbyint  functions  round  their argument to an
>        integer value in floating-point format,  using  the  current
>        rounding  direction  and  without  raising  the  ``inexact''
>        floating-point exception.
> 
>        Returns
> 
>        [#3] The nearbyint  functions  return  the  rounded  integer
>        value.
> 
>        7.12.9.4  The rint functions
> 
>        Synopsis
> 
>        [#1]
> 
>                #include <math.h>
>                double rint(double x);
>                float rintf(float x);
>                long double rintl(long double x);
> 
>        Description
> 
>        [#2]  The rint functions differ from the nearbyint functions
>        (7.12.9.3) only in that the rint  functions  may  raise  the
>        ``inexact''  floating-point  exception if the result differs
>        in value from the argument.

I see, that is quite different than what I have in manpage.  I will
check the standard for other differences
> 
>        Returns
> 
>        [#3] The rint functions return the rounded integer value.
> 
> | I can builtinize nearbyint too if it makes sense.
> 
> Do we have framework to deal correctly with current rounding mode?
> I not, I would say, leave it as is until we have the appropriate
> machinery. 

RTL truncating expressions are underfined for nonintegral FP values, so
we don't have problems with the compiler, only we can't fold at compile
time for non-integral constats, since the results depends on runtime
conditions.
> 
> | I am bit confused by
> | rint.  Does it imply that rint will raise exception for any non-integral
> | arugment?
> 
> And depending on the rounding mode.
Bad :(
I will check whether frndint will do the exception.  If not, I guess the
current glibc rint builtin is wrong and it really should be rint
builtin.  The other functions (floor and friends) are not throwing
inexact I guess, but we can safely mask this out of rounding mode of
course.

Honza
> 
> -- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  1:44                     ` Jan Hubicka
@ 2002-11-07  1:52                       ` Jakub Jelinek
  2002-11-07  1:54                         ` Jan Hubicka
  0 siblings, 1 reply; 41+ messages in thread
From: Jakub Jelinek @ 2002-11-07  1:52 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Gabriel Dos Reis, Richard Henderson, gcc-patches, aj

On Thu, Nov 07, 2002 at 10:44:01AM +0100, Jan Hubicka wrote:
> I will check whether frndint will do the exception.  If not, I guess the
> current glibc rint builtin is wrong and it really should be rint
> builtin.

Why?
It is __FAST_MATH__ only.

	Jakub

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  1:52                       ` Jakub Jelinek
@ 2002-11-07  1:54                         ` Jan Hubicka
  0 siblings, 0 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-07  1:54 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Jan Hubicka, Gabriel Dos Reis, Richard Henderson, gcc-patches, aj

> On Thu, Nov 07, 2002 at 10:44:01AM +0100, Jan Hubicka wrote:
> > I will check whether frndint will do the exception.  If not, I guess the
> > current glibc rint builtin is wrong and it really should be rint
> > builtin.
> 
> Why?
> It is __FAST_MATH__ only.
Hmm, I see then.
Would be safe to use same builtin for nearbyint in non-ffast-math mode?

Honza
> 
> 	Jakub

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  1:33                   ` Gabriel Dos Reis
  2002-11-07  1:44                     ` Jan Hubicka
@ 2002-11-07  2:04                     ` Jan Hubicka
  2002-11-07  4:47                       ` Gabriel Dos Reis
  1 sibling, 1 reply; 41+ messages in thread
From: Jan Hubicka @ 2002-11-07  2:04 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Jan Hubicka, Richard Henderson, gcc-patches, aj

> Jan Hubicka <jh@suse.cz> writes:
> 
> | > Jan Hubicka <jh@suse.cz> writes:
> | > 
> | > | On the related note.  How bad would you consider converting
> | > | floor(x) into rint(x-0.5) in the fast-math mode?
> | > 
> | > If you think you do want to do that transformation, then I would
> | > prefer this
> | > 
> | >   floor(x) -> nearbyint(x-0.5)
> | > 
> | > | That transformation would do a miracles for i386, where rint is faster
> | > | than floor by quite a lot and should suffice for 3D application in
> | > | reliablility.  I can imagine it to fail only for very large numbers...
> | > 
> | > Not really.  floor(1) == 1 and rint(1 - 0.5) maybe be 0 or 1 depending
> | > on the current rounding mode.
> | Hmm, is rint really expected to be dependent on the rouding mode?
> | Man page claims:
> |        The nearbyint functions round their argument to an integer value
> |        in floating point format, using the current
> |        rounding direction and without raising the inexact
> |        exception.
> | 
> |        The rint functions do the same, but will raise the
> |        inexact exception when the result differs in  value
> |        from the argument.
> 
> The C definition says:
> 
>        7.12.9.3  The nearbyint functions
> 
>        Synopsis
> 
>        [#1]
> 
>                #include <math.h>
>                double nearbyint(double x);
>                float nearbyintf(float x);
>                long double nearbyintl(long double x);
> 
>        Description
> 
>        [#2]  The  nearbyint  functions  round  their argument to an
>        integer value in floating-point format,  using  the  current
>        rounding  direction  and  without  raising  the  ``inexact''
>        floating-point exception.
> 
>        Returns
> 
>        [#3] The nearbyint  functions  return  the  rounded  integer
>        value.
> 
>        7.12.9.4  The rint functions
> 
>        Synopsis
> 
>        [#1]
> 
>                #include <math.h>
>                double rint(double x);
>                float rintf(float x);
>                long double rintl(long double x);
> 
>        Description
> 
>        [#2]  The rint functions differ from the nearbyint functions
>        (7.12.9.3) only in that the rint  functions  may  raise  the
						      ^^^
Does this imply that I can implement rint as nearbyint call and never
cause the exception and always use frndint instruction for it that does
not trap?

Honza
>        ``inexact''  floating-point  exception if the result differs
>        in value from the argument.
> 
>        Returns
> 
>        [#3] The rint functions return the rounded integer value.
> 
> | I can builtinize nearbyint too if it makes sense.
> 
> Do we have framework to deal correctly with current rounding mode?
> I not, I would say, leave it as is until we have the appropriate
> machinery. 
> 
> | I am bit confused by
> | rint.  Does it imply that rint will raise exception for any non-integral
> | arugment?
> 
> And depending on the rounding mode.
> 
> -- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Simplify floating point conversions IV
  2002-11-06 14:55           ` Richard Henderson
@ 2002-11-07  2:54             ` Jan Hubicka
  2002-11-18 15:01               ` Richard Henderson
  0 siblings, 1 reply; 41+ messages in thread
From: Jan Hubicka @ 2002-11-07  2:54 UTC (permalink / raw)
  To: Richard Henderson, Jan Hubicka, gcc-patches, aj

> On Wed, Nov 06, 2002 at 10:48:03PM +0100, Jan Hubicka wrote:
> > +       /* Wind away possible cast.  */
> > +       if (TREE_CODE (arg0) == NOP_EXPR
> > + 	  && (TYPE_PRECISION (TREE_TYPE (arg0))
> > + 	      > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
> > + 	arg0 = TREE_OPERAND (arg0, 0);
> [...]
> > +       /* Be curefull about integer to fp conversions.
> > + 	 These may overflow still.  */
> > +       if (FLOAT_TYPE_P (TREE_TYPE (arg0))
> 
> I'd rather something like
> 
> static tree
> strip_float_extensions (exp)
>      tree exp;
> {
>   tree sub, expt, subt;
> 
>   if (TREE_CODE (exp) != NOP_EXPR)
>     return exp;
> 
>   sub = TREE_OPERAND (exp, 0);
>   subt = TREE_TYPE (sub);
>   expt = TREE_TYPE (exp);
> 
>   if (!FLOAT_TYPE_P (subt))
>     return exp;
> 
>   if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
>     return exp;
> 
>   return strip_float_extensions (sub);
> }
> 
> > + 	case RDIV_EXPR:
> > + 	   {
> > + 	     tree arg0 = TREE_OPERAND (expr, 0);
> > + 	     tree arg1 = TREE_OPERAND (expr, 1);
> > + 
> > + 	     /* Unwind possible casts.  */
> 
> Useful here as well.
Nice.  I've added that and suppressed the builtin transformation
when not optimizing.

OK now?

Wed Nov  6 19:48:32 PST 2002  Jan Hubicka  <jh@suse.cz>
	* convert.c (strip_float_extensions): New function.
	(convert_to_real): Optimize some cases.
Index: convert.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/convert.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 convert.c
*** convert.c	4 Jul 2002 06:38:54 -0000	1.19
--- convert.c	7 Nov 2002 10:53:27 -0000
*************** Software Foundation, 59 Temple Place - S
*** 30,35 ****
--- 30,36 ----
  #include "convert.h"
  #include "toplev.h"
  #include "langhooks.h"
+ static tree strip_float_extensions PARAMS ((tree));
  
  /* Convert EXPR to some pointer or reference type TYPE.
  
*************** convert_to_pointer (type, expr)
*** 71,76 ****
--- 72,101 ----
      }
  }
  
+ /* Avoid any floating point extensions from EXP.  */
+ static tree
+ strip_float_extensions (exp)
+      tree exp;
+ {
+   tree sub, expt, subt;
+ 
+   if (TREE_CODE (exp) != NOP_EXPR)
+     return exp;
+ 
+   sub = TREE_OPERAND (exp, 0);
+   subt = TREE_TYPE (sub);
+   expt = TREE_TYPE (exp);
+ 
+   if (!FLOAT_TYPE_P (subt))
+     return exp;
+ 
+   if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
+     return exp;
+ 
+   return strip_float_extensions (sub);
+ }
+ 
+ 
  /* Convert EXPR to some floating-point type TYPE.
  
     EXPR must be float, integer, or enumeral;
*************** tree
*** 80,85 ****
--- 105,244 ----
  convert_to_real (type, expr)
       tree type, expr;
  {
+   enum built_in_function fcode = builtin_mathfn_code (expr);
+   tree itype = TREE_TYPE (expr);
+ 
+   /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
+   if ((fcode == BUILT_IN_SQRT
+        || fcode == BUILT_IN_SQRTL
+        || fcode == BUILT_IN_SIN
+        || fcode == BUILT_IN_SINL
+        || fcode == BUILT_IN_COS
+        || fcode == BUILT_IN_COSL
+        || fcode == BUILT_IN_EXP
+        || fcode == BUILT_IN_EXPL)
+       && optimize
+       && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+           || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+     {
+       tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
+       tree newtype = type;
+ 
+       /* We have (outertype)sqrt((innertype)x).  Choose the wider mode from
+ 	 the both as the safe type for operation.  */
+       if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
+ 	newtype = TREE_TYPE (arg0);
+ 
+       /* Be curefull about integer to fp conversions.
+ 	 These may overflow still.  */
+       if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 	  && TYPE_PRECISION (newtype) <= TYPE_PRECISION (itype)
+ 	  && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
+ 	      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
+ 	{
+ 	  tree arglist;
+ 	  if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRTF;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SINF;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COSF;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXPF;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 	  else
+ 	    switch (fcode)
+ 	      {
+ 	      case BUILT_IN_SQRT:
+ 	      case BUILT_IN_SQRTL:
+ 		fcode = BUILT_IN_SQRT;
+ 		break;
+ 	      case BUILT_IN_SIN:
+ 	      case BUILT_IN_SINL:
+ 		fcode = BUILT_IN_SIN;
+ 		break;
+ 	      case BUILT_IN_COS:
+ 	      case BUILT_IN_COSL:
+ 		fcode = BUILT_IN_COS;
+ 		break;
+ 	      case BUILT_IN_EXP:
+ 	      case BUILT_IN_EXPL:
+ 		fcode = BUILT_IN_EXP;
+ 		break;
+ 	      default:
+ 		abort ();
+ 	      }
+ 
+ 	  /* ??? Fortran frontend does not initialize built_in_decls.
+ 	     For some reason creating the decl using builtin_function does not
+ 	     work as it should.   */
+ 	  if (built_in_decls [fcode])
+ 	    {
+ 	      arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
+ 	      expr = build_function_call_expr (built_in_decls [fcode], arglist);
+ 	      if (newtype == type)
+ 		return expr;
+ 	    }
+ 	}
+     }
+ 
+   /* Propagate the cast into the operation.  */
+   if (itype != type && FLOAT_TYPE_P (type))
+     switch (TREE_CODE (expr))
+       {
+ 	/* convert (float)-x into -(float)x.  This is always safe.  */
+ 	case ABS_EXPR:
+ 	case NEGATE_EXPR:
+ 	  return build1 (TREE_CODE (expr), type,
+ 			 fold (convert_to_real (type,
+ 						TREE_OPERAND (expr, 0))));
+ 	/* convert (outertype)((innertype0)a+(innertype1)b)
+ 	   into ((newtype)a+(newtype)b) where newtype
+ 	   is the widest mode from all of these.  */
+ 	case PLUS_EXPR:
+ 	case MINUS_EXPR:
+ 	case MULT_EXPR:
+ 	case RDIV_EXPR:
+ 	   {
+ 	     tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
+ 	     tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
+ 
+ 	     if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ 		 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
+ 	       {
+ 		  tree newtype = type;
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg0);
+ 		  if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
+ 		    newtype = TREE_TYPE (arg1);
+ 		  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
+ 		    {
+ 		      expr = build (TREE_CODE (expr), newtype,
+ 				    fold (convert_to_real (newtype, arg0)),
+ 				    fold (convert_to_real (newtype, arg1)));
+ 		      if (newtype == type)
+ 			return expr;
+ 		    }
+ 	       }
+ 	   }
+ 	  break;
+ 	default:
+ 	  break;
+       }
+ 
    switch (TREE_CODE (TREE_TYPE (expr)))
      {
      case REAL_TYPE:

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  2:04                     ` Jan Hubicka
@ 2002-11-07  4:47                       ` Gabriel Dos Reis
  2002-11-07  4:56                         ` Jan Hubicka
  0 siblings, 1 reply; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-07  4:47 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

Jan Hubicka <jh@suse.cz> writes:

[...]

| >        [#2]  The rint functions differ from the nearbyint functions
| >        (7.12.9.3) only in that the rint  functions  may  raise  the
| 						      ^^^
| Does this imply that I can implement rint as nearbyint call and never
| cause the exception and always use frndint instruction for it that does
| not trap?

If FE_INEXACT is on, that is incorrect.

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  4:47                       ` Gabriel Dos Reis
@ 2002-11-07  4:56                         ` Jan Hubicka
  2002-11-07  5:14                           ` Andreas Schwab
  2002-11-07  5:22                           ` Gabriel Dos Reis
  0 siblings, 2 replies; 41+ messages in thread
From: Jan Hubicka @ 2002-11-07  4:56 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Jan Hubicka, Richard Henderson, gcc-patches, aj

> Jan Hubicka <jh@suse.cz> writes:
> 
> [...]
> 
> | >        [#2]  The rint functions differ from the nearbyint functions
> | >        (7.12.9.3) only in that the rint  functions  may  raise  the
> | 						      ^^^
> | Does this imply that I can implement rint as nearbyint call and never
> | cause the exception and always use frndint instruction for it that does
> | not trap?
> 
> If FE_INEXACT is on, that is incorrect.
But why the standard don't say that rint function will raise the
interrupt?  I would interpred may as it can behave that way or don't
have to.
I've switched to nearbyint in my patch, but would like to understand
this detail.

Honza
> 
> -- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  4:56                         ` Jan Hubicka
@ 2002-11-07  5:14                           ` Andreas Schwab
  2002-11-07  5:27                             ` Gabriel Dos Reis
  2002-11-07  5:22                           ` Gabriel Dos Reis
  1 sibling, 1 reply; 41+ messages in thread
From: Andreas Schwab @ 2002-11-07  5:14 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Gabriel Dos Reis, Richard Henderson, gcc-patches, aj

Jan Hubicka <jh@suse.cz> writes:

|> > Jan Hubicka <jh@suse.cz> writes:
|> > 
|> > [...]
|> > 
|> > | >        [#2]  The rint functions differ from the nearbyint functions
|> > | >        (7.12.9.3) only in that the rint  functions  may  raise  the
|> > | 						      ^^^
|> > | Does this imply that I can implement rint as nearbyint call and never
|> > | cause the exception and always use frndint instruction for it that does
|> > | not trap?
|> > 
|> > If FE_INEXACT is on, that is incorrect.
|> But why the standard don't say that rint function will raise the
|> interrupt?  I would interpred may as it can behave that way or don't
|> have to.

Yes, rint is the weaker function.  The implementation of nearbyint must
make sure that no inexact exception is raised, whereas for rint this is
not necessary.  That means that if you have a round instruction that never
raises the exception it can be used to implement both functions.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  4:56                         ` Jan Hubicka
  2002-11-07  5:14                           ` Andreas Schwab
@ 2002-11-07  5:22                           ` Gabriel Dos Reis
  2002-11-07  5:43                             ` Andreas Schwab
  1 sibling, 1 reply; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-07  5:22 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches, aj

Jan Hubicka <jh@suse.cz> writes:

| > Jan Hubicka <jh@suse.cz> writes:
| > 
| > [...]
| > 
| > | >        [#2]  The rint functions differ from the nearbyint functions
| > | >        (7.12.9.3) only in that the rint  functions  may  raise  the
| > | 						      ^^^
| > | Does this imply that I can implement rint as nearbyint call and never
| > | cause the exception and always use frndint instruction for it that does
| > | not trap?
| > 
| > If FE_INEXACT is on, that is incorrect.
| But why the standard don't say that rint function will raise the
| interrupt?

Sorry for having been unclear.

"may" part refers to the fact  whether the programmer might want
to run rint() under a particular floating-point control mode that
would permit rint() to raise the inexact exception.
rint() cannot unconditionally set it. If FENV_ACCESS is on and
FE_INEXACT is supported then rint() should raise the exception if
appropriate. That is my understanding.

Am I still unclear?

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  5:14                           ` Andreas Schwab
@ 2002-11-07  5:27                             ` Gabriel Dos Reis
  2002-11-07  5:31                               ` Jan Hubicka
  0 siblings, 1 reply; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-07  5:27 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jan Hubicka, Richard Henderson, gcc-patches, aj

Andreas Schwab <schwab@suse.de> writes:

| |> But why the standard don't say that rint function will raise the
| |> interrupt?  I would interpred may as it can behave that way or don't
| |> have to.
| 
| Yes, rint is the weaker function.

Thanks.  I didn't understand Jan's question in that way.  Thanks
for clarifying.

| The implementation of nearbyint must
| make sure that no inexact exception is raised, whereas for rint this is
| not necessary.  That means that if you have a round instruction that never
| raises the exception it can be used to implement both functions.

Yes.  Or said differently, rint() may be implemented in terms of
nearbyint() (+ raising exception where appropriate).

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  5:27                             ` Gabriel Dos Reis
@ 2002-11-07  5:31                               ` Jan Hubicka
  2002-11-07  5:35                                 ` Andreas Schwab
  0 siblings, 1 reply; 41+ messages in thread
From: Jan Hubicka @ 2002-11-07  5:31 UTC (permalink / raw)
  To: Gabriel Dos Reis
  Cc: Andreas Schwab, Jan Hubicka, Richard Henderson, gcc-patches, aj

> Andreas Schwab <schwab@suse.de> writes:
> 
> | |> But why the standard don't say that rint function will raise the
> | |> interrupt?  I would interpred may as it can behave that way or don't
> | |> have to.
> | 
> | Yes, rint is the weaker function.
> 
> Thanks.  I didn't understand Jan's question in that way.  Thanks
> for clarifying.
> 
> | The implementation of nearbyint must
> | make sure that no inexact exception is raised, whereas for rint this is
> | not necessary.  That means that if you have a round instruction that never
> | raises the exception it can be used to implement both functions.
> 
> Yes.  Or said differently, rint() may be implemented in terms of
> nearbyint() (+ raising exception where appropriate).

Question is whether I am required to raise it when standard say "may
raise"

Honza
> 
> -- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  5:31                               ` Jan Hubicka
@ 2002-11-07  5:35                                 ` Andreas Schwab
  0 siblings, 0 replies; 41+ messages in thread
From: Andreas Schwab @ 2002-11-07  5:35 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

Jan Hubicka <jh@suse.cz> writes:

|> Question is whether I am required to raise it when standard say "may
|> raise"

No, it would only be required if it said "shall raise".

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  5:22                           ` Gabriel Dos Reis
@ 2002-11-07  5:43                             ` Andreas Schwab
  2002-11-07  6:23                               ` Gabriel Dos Reis
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Schwab @ 2002-11-07  5:43 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Jan Hubicka, gcc-patches

Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

|> "may" part refers to the fact  whether the programmer might want
|> to run rint() under a particular floating-point control mode that
|> would permit rint() to raise the inexact exception.
|> rint() cannot unconditionally set it. If FENV_ACCESS is on and
|> FE_INEXACT is supported then rint() should raise the exception if
|> appropriate. That is my understanding.

If the implementation defines __STDC_IEC_559__ then F.9.6.4 applies.  I
have no copy of IEC 60559, but if it states that rint must raise the
exception then it must do it independent of FENV_ACCESS.  Otherwise, if
__STDC_IEC_559__ is not defined, then no requirements on the exceptions
are stated for rint, since 7.12.9.4 does not have a "shall".

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  5:43                             ` Andreas Schwab
@ 2002-11-07  6:23                               ` Gabriel Dos Reis
  2002-11-07  7:01                                 ` Jan Hubicka
  0 siblings, 1 reply; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-07  6:23 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jan Hubicka, gcc-patches

Andreas Schwab <schwab@suse.de> writes:

| Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
| 
| |> "may" part refers to the fact  whether the programmer might want
| |> to run rint() under a particular floating-point control mode that
| |> would permit rint() to raise the inexact exception.
| |> rint() cannot unconditionally set it. If FENV_ACCESS is on and
| |> FE_INEXACT is supported then rint() should raise the exception if
| |> appropriate. That is my understanding.
| 
| If the implementation defines __STDC_IEC_559__ then F.9.6.4 applies.  I
| have no copy of IEC 60559, but if it states that rint must raise the
| exception then it must do it independent of FENV_ACCESS.

My concern is this:

       F.7.1  Environment management

       [#1]   IEC 60559  requires  that  floating-point  operations
       implicitly raise floating-point exception status flags,  and
       that  rounding control modes can be set explicitly to affect
       result values of floating-point operations.  When the  state
       for  the FENV_ACCESS pragma (defined in <fenv.h>) is ``on'',
       these changes to the floating-point  state  are  treated  as
       *side effects* which respect sequence points.304)

(my emphasis)

| Otherwise, if
| __STDC_IEC_559__ is not defined, then no requirements on the exceptions
| are stated for rint, since 7.12.9.4 does not have a "shall".

Agreed.

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  6:23                               ` Gabriel Dos Reis
@ 2002-11-07  7:01                                 ` Jan Hubicka
  2002-11-07  7:18                                   ` Gabriel Dos Reis
  0 siblings, 1 reply; 41+ messages in thread
From: Jan Hubicka @ 2002-11-07  7:01 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Andreas Schwab, Jan Hubicka, gcc-patches

> Andreas Schwab <schwab@suse.de> writes:
> 
> | Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
> | 
> | |> "may" part refers to the fact  whether the programmer might want
> | |> to run rint() under a particular floating-point control mode that
> | |> would permit rint() to raise the inexact exception.
> | |> rint() cannot unconditionally set it. If FENV_ACCESS is on and
> | |> FE_INEXACT is supported then rint() should raise the exception if
> | |> appropriate. That is my understanding.
> | 
> | If the implementation defines __STDC_IEC_559__ then F.9.6.4 applies.  I
> | have no copy of IEC 60559, but if it states that rint must raise the
> | exception then it must do it independent of FENV_ACCESS.

Yes, IEC seems to be clear about the trap:
       [#1] The rint functions differ from the nearbyint  functions
       only  in  that  they do raise the ``inexact'' floating-point
       exception if the result differs in value from the argument.

I would love to be enlightened about when this feature is usefull :) I
can't think of any use for it.  Sadly most people use rint/lrint and not
nearbyint/lrint that are more consistent.
> 
> My concern is this:
> 
>        F.7.1  Environment management
> 
>        [#1]   IEC 60559  requires  that  floating-point  operations
>        implicitly raise floating-point exception status flags,  and
>        that  rounding control modes can be set explicitly to affect
>        result values of floating-point operations.  When the  state
>        for  the FENV_ACCESS pragma (defined in <fenv.h>) is ``on'',
>        these changes to the floating-point  state  are  treated  as
>        *side effects* which respect sequence points.304)
> 
> (my emphasis)

So one can not consider rint as "attribute((const))" function and we can
not do that in strict mode.
> 
> | Otherwise, if
> | __STDC_IEC_559__ is not defined, then no requirements on the exceptions
> | are stated for rint, since 7.12.9.4 does not have a "shall".
Can I detect somehow the cases when __STDC_IEC_559__ is not defined?
This seems to be done by glibc in all cases, even with -ffast-math.
Perhaps I can do the rint folding only with -ffast-math that would be
enought for majority of 3D software that is about the only case where we
get some oppurtunities for speedup from this transformations?

Honza
> 
> Agreed.
> 
> -- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Converting floor to rint
  2002-11-07  7:01                                 ` Jan Hubicka
@ 2002-11-07  7:18                                   ` Gabriel Dos Reis
  0 siblings, 0 replies; 41+ messages in thread
From: Gabriel Dos Reis @ 2002-11-07  7:18 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Andreas Schwab, gcc-patches

Jan Hubicka <jh@suse.cz> writes:

[...]

| >        F.7.1  Environment management
| > 
| >        [#1]   IEC 60559  requires  that  floating-point  operations
| >        implicitly raise floating-point exception status flags,  and
| >        that  rounding control modes can be set explicitly to affect
| >        result values of floating-point operations.  When the  state
| >        for  the FENV_ACCESS pragma (defined in <fenv.h>) is ``on'',
| >        these changes to the floating-point  state  are  treated  as
| >        *side effects* which respect sequence points.304)
| > 
| > (my emphasis)
| 
| So one can not consider rint as "attribute((const))" function and we can
| not do that in strict mode.

That is exact.

| > 
| > | Otherwise, if
| > | __STDC_IEC_559__ is not defined, then no requirements on the exceptions
| > | are stated for rint, since 7.12.9.4 does not have a "shall".
| Can I detect somehow the cases when __STDC_IEC_559__ is not defined?

Also one would need to access thye value of FENV_ACCESS.  That is all
that I loosenely called "propriate FE exception machinary".

| This seems to be done by glibc in all cases, even with -ffast-math.
| Perhaps I can do the rint folding only with -ffast-math that would be
| enought for majority of 3D software that is about the only case where we
| get some oppurtunities for speedup from this transformations?

I won't oppose to having it in -funsafe-math.

-- Gaby

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Simplify floating point conversions IV
  2002-11-07  2:54             ` Simplify floating point conversions IV Jan Hubicka
@ 2002-11-18 15:01               ` Richard Henderson
  0 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2002-11-18 15:01 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, aj

On Thu, Nov 07, 2002 at 11:54:55AM +0100, Jan Hubicka wrote:
> 	* convert.c (strip_float_extensions): New function.
> 	(convert_to_real): Optimize some cases.

Ok.


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2002-11-18 23:01 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-05  9:14 Simplify floating point conversions Jan Hubicka
2002-11-05  9:38 ` Richard Henderson
2002-11-05  9:42   ` Jan Hubicka
2002-11-06  1:23   ` Simplify floating point conversions II Jan Hubicka
2002-11-06  3:08     ` Michael Matz
2002-11-06  4:36       ` Jan Hubicka
2002-11-06  9:54     ` Jan Hubicka
2002-11-06 10:09       ` Richard Henderson
2002-11-06 13:11         ` Jan Hubicka
2002-11-06 13:19           ` Jan Hubicka
2002-11-06 13:35           ` Gabriel Dos Reis
2002-11-06 13:36             ` Jan Hubicka
2002-11-06 14:06               ` Gabriel Dos Reis
2002-11-06 14:29             ` Converting floor to rint Jan Hubicka
2002-11-06 14:47               ` Richard Henderson
2002-11-06 14:53                 ` Jan Hubicka
2002-11-06 14:55               ` Gabriel Dos Reis
2002-11-07  1:21                 ` Jan Hubicka
2002-11-07  1:32                   ` Jakub Jelinek
2002-11-07  1:33                   ` Gabriel Dos Reis
2002-11-07  1:44                     ` Jan Hubicka
2002-11-07  1:52                       ` Jakub Jelinek
2002-11-07  1:54                         ` Jan Hubicka
2002-11-07  2:04                     ` Jan Hubicka
2002-11-07  4:47                       ` Gabriel Dos Reis
2002-11-07  4:56                         ` Jan Hubicka
2002-11-07  5:14                           ` Andreas Schwab
2002-11-07  5:27                             ` Gabriel Dos Reis
2002-11-07  5:31                               ` Jan Hubicka
2002-11-07  5:35                                 ` Andreas Schwab
2002-11-07  5:22                           ` Gabriel Dos Reis
2002-11-07  5:43                             ` Andreas Schwab
2002-11-07  6:23                               ` Gabriel Dos Reis
2002-11-07  7:01                                 ` Jan Hubicka
2002-11-07  7:18                                   ` Gabriel Dos Reis
2002-11-06 13:48         ` Simplify floating point conversions III Jan Hubicka
2002-11-06 14:55           ` Richard Henderson
2002-11-07  2:54             ` Simplify floating point conversions IV Jan Hubicka
2002-11-18 15:01               ` Richard Henderson
2002-11-05 11:14 ` Simplify floating point conversions Geoff Keating
2002-11-06  1:09   ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).