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: rs6000 LDBL_MAX converts to infinity


On Wed, Mar 03, 2004 at 12:22:37AM -0300, Alexandre Oliva wrote:
> On Mar  2, 2004, Alan Modra <amodra@bigpond.net.au> wrote:
> 
> > While looking at this code, I noticed that the value is rounded to
> > double after the high double has been subtracted.  I think this is
> > unnecessary since real_to_target_fmt rounds before calling the
> > encode function.
> 
> The fact that the incoming long double is properly rounded doesn't
> imply the result of additional arithmetic is properly rounded,
> especially considering that the result might not be representable as a
> double.
> 
> What you're doing seems to work, but I don't see that it's correct.
> It violates the invariant that encode functions are always passed
> values that are already rounded.  This is clearly not the case if you
> pass it something that overflows after rounding.
> 
> > No other encode_* function does this rounding.
> 
> No other encode_* function performs (emulated) FP arithmetic on incoming
> values, and no other encode_* function has to represent the value it
> gets using narrower FP formats.

Your reply doesn't really address rounding of 'v', which is what I was
talking about in the paragraph quoted above.  You do have a point that
I'm possibly passing encode_ieee_double values that would not normally
be passed, but I happen to know that encode_ieee_double works for the
range I'm interested in.  :)

> What we used to do was to
> 
>   clear_significand_below (&u, SIGNIFICAND_BITS - 53);
> 
> so it wouldn't overflow.  Geoff significantly simplified this function
> on Jan 9, but this presumably LDBL_MAX on powerpc-ibm-aix,
> mips-sgi-irix6 and powerpc64-linux.
> 
> Geoff, how come this doesn't break Darwin?  What does LDBL_MAX look
> like for you?  How about LDBL_MIN?

I bet Darwin LDBL_MAX is broken, but nobody has noticed yet.  Or perhaps
it's just not at the top of Geoff's list of bugs needing fixes..

> It appears to me that the right solution is to attempt rounding, like
> we have now, but, if that turns out to be an infinity while the
> incoming value was not, we clear the significand as above, and use
> that as `u' instead.  This should work for aix and irix6.

Yes, that would work too, and would save the necessity of setting 'u' to
DBL_MAX via decode_ieee_double.  It also makes the conversion cheaper,
so it's a better idea.  Thanks!

	* real.c (encode_ibm_extended): Handle LDBL_MAX and other large
	numbers.  Don't round before converting low double.

Index: gcc/real.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.c,v
retrieving revision 1.138
diff -u -p -r1.138 real.c
--- gcc/real.c	10 Feb 2004 23:05:58 -0000	1.138
+++ gcc/real.c	3 Mar 2004 04:19:18 -0000
@@ -3243,12 +3243,19 @@ encode_ibm_extended (const struct real_f
   /* u = IEEE double precision portion of significand.  */
   u = normr;
   round_for_format (base_fmt, &u);
+
+  if (normr.class == rvc_normal && u.class == rvc_inf)
+    {
+      /* Rounding caused an overflow.  Convert without rounding so
+	 we can handle LDBL_MAX.  */
+      u = normr;
+      clear_significand_below (&u, SIGNIFICAND_BITS - 53);
+    }
   encode_ieee_double (base_fmt, &buf[0], &u);
 
   if (u.class == rvc_normal)
     {
       do_add (&v, &normr, &u, 1);
-      round_for_format (base_fmt, &v);
       encode_ieee_double (base_fmt, &buf[2], &v);
     }
   else

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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