I discovered a gcc bug in the -ffloat-store option.

This program:

#include <stdio.h>

int main(void) {

  float reale = 1.0f;
  int i = 0;

  for (; (reale + 1.0f) != 1.0f; i++) {
    reale=(float)reale/2.0f;
  }
  printf("\ni volte = %d\n",i);
}

This program must output 24 instead of 64 if compiled with -ffloat-store. 

This other program instead workaround the gcc 2.7.2 bug:

#include <stdio.h>

int main(void)
{
        float my_float = 1, result;
        int i = 0;

        do {
                my_float /= 2;
                result = my_float + 1;
                i++;
        } while ((float)(result != 1));

        printf("i times = %d\n",i);
}

If I compile this program with gcc 2.8.1 and -ffloat-store and -O, instead
the bug is shown again and I get 64.

I started fixing the 2.7.2 to 2.8.1 inserted bug but gcc sources are a
mess. houndrid of lines per file functions very very long. All in the same
directory. It' s very very difficult to understand the gcc code for me.

The assembler code of the second program generated by gcc-2.8.1 -O2
-ffloat-store -S is this:
-------------------------------------
        .file   "p1.c"
        .version        "01.01"
gcc2_compiled.:
.section        .rodata
.LC1:
        .string "i times = %d\n"
        .align 4
.LC0:
        .long 0x3f000000
.text
        .align 16
.globl main
        .type    main,@function
main:
        pushl %ebp
        movl %esp,%ebp
        subl $8,%esp
        movl $1065353216,-4(%ebp)
        xorl %edx,%edx
        flds .LC0
        fld1
        .align 4
.L2:
        flds -4(%ebp)
        fmul %st(2),%st
        fsts -4(%ebp)
        fadd %st(1),%st
        fsts -8(%ebp)
        ^^^^^^^^^^^^^
        incl %edx
        fucomp %st(1)
        fnstsw %ax
        andb $68,%ah
        xorb $64,%ah
        jne .L2
        fstp %st(0)
        fstp %st(0)
        pushl %edx
        pushl $.LC1
        call printf
        movl %ebp,%esp
        popl %ebp
        ret
.Lfe1:
        .size    main,.Lfe1-main
        .ident  "GCC: (GNU) 2.8.1"
-------------------------------------

As you can see after the underlined line gcc run a test without reload the
register from memory and so it run the test with a very more precise data.

The assembler patch that fix the bug is this:
===================================================================
RCS file: p1.s,v
retrieving revision 1.1
diff -u -r1.1 p1.s
--- p1.s        1998/06/07 16:01:13     1.1
+++ p1.s        1998/06/07 16:17:42
@@ -25,7 +25,8 @@
        fmul %st(2),%st
        fsts -4(%ebp)
        fadd %st(1),%st
-       fsts -8(%ebp)
+       fstps -8(%ebp)
+       flds -8(%ebp)
        incl %edx
        fucomp %st(1)
        fnstsw %ax

Does anybody known very well the gcc code to try to collaborate with me to
fix this bug? The problem should be in the file reload*.c.

I just sent the report to the gcc-bugs mailing-list but I got no answer
except from a guy that said me that he got the same problem in the past. 

Andrea[s] Arcangeli

Reply via email to