This is the mail archive of the gcc@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]

fp-int-convert-timode, TImode and Darwin


    I recently discovered an apparent latent bug in float to integer conversion
which is exposed on Darwin PPC by addition of Geoff Keating's proposed TImode
support patch...

http://gcc.gnu.org/ml/gcc-patches/2006-08/msg00581.html

With this patch in place, the 64-bit testsuite results show that the
fp-int-convert-timode testcase fails at all optimization levels. Interestingly
the failures are not due to the long or long double sections of the testcase
but rather the float section. I was able to reduce this to smaller testcase
by reducing the fp-int-convert-timode testcase to calls to...

TEST_I_F(TItype, UTItype, float, FLT_MANT_DIG)

which then only calls one of the six possible failing tests...

  TEST_I_F_VAL (I, F, HVAL0S (P, I) + 1, P_OK (P, I));          

This shortened testcase when processed with -E in gcc can be
recasted as the expanded macros in the following testcase...

#include <limits.h>
#include <stdio.h>

extern void abort (void);
extern void exit (int);
typedef int TItype __attribute__ ((mode (TI)));
typedef unsigned int UTItype __attribute__ ((mode (TI)));

int
main (void)
{
  do {
      do {
          static volatile TItype ivin, ivout;
          static volatile float fv1, fv2;
          ivin = ((TItype)(((24) >= sizeof(TItype) * 8 - 1) ? (TItype)1 : (((TItype)1 << (sizeof(TItype) * 8 - 2)) + ((TItype)1 << (sizeof(TItype) * 8 - 2 - 24)))) + 1);
          fv1 = ((TItype)(((24) >= sizeof(TItype) * 8 - 1) ? (TItype)1 : (((TItype)1 << (sizeof(TItype) * 8 - 2)) + ((TItype)1 << (sizeof(TItype) * 8 - 2 - 24)))) + 1);
          fv2 = ivin; ivout = fv2;
          if (ivin != ((TItype)(((24) >= sizeof(TItype) * 8 - 1) ? (TItype)1 : (((TItype)1 << (sizeof(TItype) * 8 - 2)) + ((TItype)1 << (sizeof(TItype) * 8 - 2 - 24)))) + 1) || ((((24) >= sizeof(TItype) * 8)) && ivout != ivin) || ((((24) >= sizeof(TItype) * 8)) && ivout != ((TItype)(((24) >= sizeof(TItype) * 8 - 1) ? (TItype)1 : (((TItype)1 << (sizeof(TItype) * 8 - 2)) + ((TItype)1 << (sizeof(TItype) * 8 - 2 - 24)))) + 1)) || fv1 != ((TItype)(((24) >= sizeof(TItype) * 8 - 1) ? (TItype)1 : (((TItype)1 << (sizeof(TItype) * 8 - 2)) + ((TItype)1 << (sizeof(TItype) * 8 - 2 - 24)))) + 1) || fv2 != ((TItype)(((24) >= sizeof(TItype) * 8 - 1) ? (TItype)1 : (((TItype)1 << (sizeof(TItype) * 8 - 2)) + ((TItype)1 << (sizeof(TItype) * 8 - 2 - 24)))) + 1) || fv1 != fv2) printf("fv1 %f fv2 %f ivin %d ivout %d\n",fv1,fv2,(int)ivin,(int)ivout);
         } while (0);
  } while (0);
  exit (0);
}

...where I have replaced the abort() call with a printf() on Darwin. This test compiled
as 'gcc -O3 -g -m64' produces the following output when executed on a G5...

fv1 85070601871439417691678863831567695872.000000 fv2 85070591730234615865843651857942052864.000000 ivin 1 ivout 0

which compares to the correct result obtained on Linux x86_64 (with the printf() placed after the if statement of
course) of...

fv1 85070601871439417691678863831567695872.000000 fv2 85070601871439417691678863831567695872.000000 ivin 1 ivout 0

So the problem on Darwin seems to be with conversion of the float results to integer results.
Geoff has said he has done all he intends to with TImode for now so perhaps someone else more
interested might take a look at this bug (which may well be independent of, but exposed by the
TImode support).
            Jack


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