Optimizer bug in 2.95.1

Greg Wolodkin gregATmathworks.com
Wed Sep 15 19:57:00 GMT 1999


Hope this is useful in finding and fixing this bug -- let me know
if I can do more.

Cheers-
Greg

/*
 * The following is a simplified example of the problem found when
 * compiling dtoa.c using gcc 2.95.1 on my Linux box.  I'm using H.J.
 * Lu's build, though I found the same problem on a build of my own
 * using straight GNU sources.  The bug doesn't occur in egcs 1.1.x.
 *
 * dtoa.c can be found at http://www.cs.bell-labs.com/netlib/fp/dtoa.c.gz
 * H.J. Lu's gcc from     ftp://ftp.varesearch.com/pub/support/hjl/gcc
 *
 * I suspect the word0(x) macro is confusing the optimizer, and it doesn't
 * expect me to be doing integer manipulations on a double.  When compiled
 * with -O2, the value of d2 is stored *after* the bit fiddling, so the
 * subtraction takes place before the data is valid, and the output is
 * then the unsubtracted version.
 *
 * Try running compiled with -O and it works fine.  With -O2 it's wrong.
 * Here you can see that the high bit subtraction happens before the 
 * floating point value is actually stored:
 *
 *    .stabn 68,0,43,.LM3-foo
 *    .LM3:
 *    	      xorl %edx,%edx
 *    	      movl %eax,-8(%ebp)                 <--- load up x
 *    	      movl %edx,-4(%ebp)
 *    	      fildll -8(%ebp)
 *    .stabn 68,0,46,.LM4-foo
 *    .LM4:
 *    	      addl $-32505856,-12(%ebp)          <--- subtraction fiddling
 *    .stabn 68,0,43,.LM5-foo
 *    .LM5:
 *    	      fstl -16(%ebp)                     <--- store d2
 */

#define word0(x) ((unsigned long *)&x)[1]
#define word1(x) ((unsigned long *)&x)[0]

double foo(double d)
{
    unsigned long x = word1(d)<<20;
    double d2;

    /* Assign a (double) value to d2 */
    d2 = x;
 
    /* Fiddle with the bits */
    word0(d2) -= 31*0x100000;

    return d2;
}    

int main(void) {
    double x = 1.12345678e-320;
    printf("%f (should be 1.110352)\n", foo(x));
}

/*
 *  # GNU C version 2.95.1 19990816/Linux (release) (i386-pc-linux) compiled by GNU 
 *  C version 2.95.1 19990816/Linux (release).
 *  # options passed:  -g -O2 -fverbose-asm
 *  # options enabled:  -fdefer-pop -fcse-follow-jumps -fcse-skip-blocks
 *  # -fexpensive-optimizations -fthread-jumps -fstrength-reduce -fpeephole
 *  # -fforce-mem -ffunction-cse -finline -fkeep-static-consts -fcaller-saves
 *  # -fpcc-struct-return -fgcse -frerun-cse-after-loop -frerun-loop-opt
 *  # -fschedule-insns2 -fcommon -fverbose-asm -fgnu-linker -fregmove
 *  # -foptimize-register-move -fargument-alias -fstrict-aliasing -fident
 *  # -m80387 -mhard-float -mno-soft-float -mieee-fp -mfp-ret-in-387
 *  # -mschedule-prologue -mcpu=i386 -march=pentium
 *  
 * * -------------------------------------------------------
 * Greg Wolodkin                 The MathWorks
 * greg@mathworks.com            3 Apple Hill 
 * (508) 647-7000, ext.7637      Natick, MA 01760-1500
 * (508) 647-7012, FAX           http://www.mathworks.com
 * -------------------------------------------------------
 */


More information about the Gcc-bugs mailing list