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

Reply via email to