Failures in gcc.c-torture/execute/ieee/copysign1.c execution on i686

Uros Bizjak uros@kss-loka.si
Fri Jan 28 15:06:00 GMT 2005


Hello!

Newly introduced copysign1.c tests introduce these failures on i686:

FAIL: gcc.c-torture/execute/ieee/copysign1.c execution,  -O3 
-fomit-frame-pointer
FAIL: gcc.c-torture/execute/ieee/copysign1.c execution,  -O3 
-fomit-frame-pointer -funroll-loops
FAIL: gcc.c-torture/execute/ieee/copysign1.c execution,  -O3 
-fomit-frame-pointer -funroll-all-loops -finline-functions
FAIL: gcc.c-torture/execute/ieee/copysign1.c execution,  -O3 -g

This is the problematic part of copysign1.c tests:

--cut here--
#include <string.h>
#include <stdlib.h>

long double test()
{
  return 1.0;
}

struct Dl { long double x, y, z; };

static const struct Dl Tl[] = {
  { 1.0, 2.0, 1.0 }
};

int main() {
  int i;

  long double r;
  memset (&r, 0, sizeof r);

  r = test();
  if (memcmp (&r, &Tl[0].z, sizeof r) != 0)
    abort ();
  return 0;
}
--cut here--

When this code is compiled with '-O2 -ffloat-store', it will abort at 
runtime.

The problem here is, that 'sizeof r' returns 12bytes for long double, 
but long doubles are 10 bytes (80bits) on i386. -ffloat-store will 
produce following code:
       ...
       call test
       cld
       fstpt  -24(%ebp)
       movl -16(%ebp), %ecx
       movl -24(%ebp), %eax
       movl -20(%ebp), %edx
       movl %ecx, -32(%ebp)
       movl $12, %ecx
       movl %eax, -40(%ebp)
       movl %edx, -36(%ebp)
       ...

And this will move 12bytes from i387 reg-stack to stack and from there 
to location pointer by &r. This means that in addition to 10 bytes that 
are stored by fstpt to (processor) stack, additional 2 spurious 
(non-null) bytes will be transferred from (processor) stack to memory at 
the address of r. Clearing the memory to 0 has no effect in this example.

It is unclear to me, why returned value isn't stored from 387 reg-stack 
directly to memory, pointer by &r.

Uros.




More information about the Gcc mailing list