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] | |
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] |