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]

[PowerPC] libgcc __floattisf


I'm in the habit of building gcc with 128-bit long double enabled by
default, and so I'm probably the only one seeing
gcc.dg/torture/fp-int-convert-timode.c fail on powerpc64-linux.  On
investigating, I found that TImode to SFmode conversions were failing,
due to double rounding in __floattisf.  This occurs on the last line of
the following (libgcc2.c:1428)

  /* Do the calculation in a wider type so that we don't lose any of
     the precision of the high word while multiplying it.  */
  FTYPE f = (Wtype) (u >> W_TYPE_SIZE);
  f *= Wtype_MAXp1_F;
  f += (UWtype)u;
  return (FSTYPE) f;

where the conversion from long double f to float goes via double.
(rs6000.md doesn't have a direct TFmode to SFmode conversion.)

Joseph added the capability to use TFmode in __floattisf in
http://gcc.gnu.org/ml/gcc-patches/2005-12/msg00253.html.  The following
patch disables use of IBM Extended Double TFmode for these functions.
Besides curing the double rounding problem, the bit shifting fallback
code happens to be faster.

$ time ./tst-floattisf

real    0m2.803s
user    0m2.797s
sys     0m0.006s
$ time ./tst-floattisf2

real    0m1.253s
user    0m1.251s
sys     0m0.002s
$

	* libgcc2.c (__floatdisf, __floatdidf): Don't use IBM Extended
	Double TFmode.
	(__floatundisf, __floatundidf): Likewise.

Regression tested powerpc64-linux.  OK mainline?  I still see
gcc.dg/torture/fp-int-convert-timode failing, but due to a different
problem.  More on that later.

Index: gcc/libgcc2.c
===================================================================
--- gcc/libgcc2.c	(revision 109034)
+++ gcc/libgcc2.c	(working copy)
@@ -1371,7 +1371,14 @@ __floatunditf (UDWtype u)
 #if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE)	\
      || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE)
 #define DI_SIZE (W_TYPE_SIZE * 2)
-#define F_MODE_OK(SIZE) (SIZE < DI_SIZE && SIZE > (DI_SIZE - SIZE + FSSIZE))
+#define F_MODE_OK(SIZE) \
+  (SIZE < DI_SIZE							\
+   && SIZE > (DI_SIZE - SIZE + FSSIZE)					\
+   /* Don't use IBM Extended Double TFmode for TI->SF calculations.	\
+      The conversion from long double to float suffers from double	\
+      rounding, because we convert via double.  In any case, the	\
+      fallback code is faster.  */					\
+   && SIZE != 106)
 #if defined(L_floatdisf)
 #define FUNC __floatdisf
 #define FSTYPE SFtype
@@ -1476,7 +1483,14 @@ FUNC (DWtype u)
 #if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE)	\
      || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE)
 #define DI_SIZE (W_TYPE_SIZE * 2)
-#define F_MODE_OK(SIZE) (SIZE < DI_SIZE && SIZE > (DI_SIZE - SIZE + FSSIZE))
+#define F_MODE_OK(SIZE) \
+  (SIZE < DI_SIZE							\
+   && SIZE > (DI_SIZE - SIZE + FSSIZE)					\
+   /* Don't use IBM Extended Double TFmode for TI->SF calculations.	\
+      The conversion from long double to float suffers from double	\
+      rounding, because we convert via double.  In any case, the	\
+      fallback code is faster.  */					\
+   && SIZE != 106)
 #if defined(L_floatundisf)
 #define FUNC __floatundisf
 #define FSTYPE SFtype

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

Attachment: tst-floattisf.c
Description: Text document


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