false passes for c-torture bf64-1.c

Franz Sirl Franz.Sirl-kernel@lauterbach.com
Thu Jul 2 17:54:00 GMT 1998


Am Thu, 02 Jul 1998 schrieb David S. Miller:
>I was playing around with some sparc mov pattern rewrites, and killing
>all the regressions I created in the process, and was left with 2
>straggler cases.  Of note was the bfd64-1.c execute test in
>c-torture.
>
>It turns out this thing passes eroneously in the current cvs tree
>without my changes in there, yet my changes expose the problem and
>cause the failure.  It passed eroneously due to values that "happened"
>by chance to be in the incoming argument registers to main on my
>sparc-linux devel machine.
>
>I believe it will show up on any target which is 32-bit and utilizes
>post reload SI mode splits to perform operations on DI mode objects.
>
>Can someone on such an existing target (rs6000 32bit, hint hint)
>compile the following with what is in cvs right now and check the
>output for sanity?
>
>static __inline__ int frob_di(unsigned long long a,
>			      unsigned long long b)
>{
>  return (int) ((a >> 24) | (b << 18));
>}
>
>extern unsigned long long x, y;
>
>int main(void)
>{
>  int x = frob_di(x, y);
>  exit(x);
>}

What are you trying to prove here? On powerpc-unknow-linux-gnu this code will
never produce a correct result cause frob_di is handed the local "int x", which
is still uninitialized. If you are trying to say that the compiler should use
the global x til the local x is initialized, then yes, this could be a bug,
depending on the C standard.
If I rename the local x to z (see code below) everything works fine for me.

Franz.

static __inline__ int frob_di(unsigned long long a,
                              unsigned long long b)
{
  return (int) ((a >> 24) | (b << 16));
}

static unsigned long long x=0x0102030405060708ULL, 
                          y=0x1122334455667788ULL;

int main(void)
{
  int z=frob_di(x, y);

  if (z != (0x77880000|0x02030405))
     abort();
  exit(0);
}



More information about the Gcc-bugs mailing list