Date: Wed, 19 Aug 1998 12:11:31 +0200 (WET) From: Andris Pavenis To: Eli Zaretskii cc: djgpp-workers AT delorie DOT com, egcs-bugs AT cygnus DOT com, bug-gcc AT gnu DOT org Subject: Re: Strange code generated by GCC (for i[34567]86 related bug) In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk On Tue, 18 Aug 1998, Eli Zaretskii wrote: > Can anybody please explain why does GCC generates such a strange code, as > described below? It is not an idle question: a couple of functions in the > new libm (from v2.02) fail because of this. > > Here's the deal. The program below attempts to generate a float NaN by > using the old trick of a union with float and unsigned int members. > 0x7fc00000 is the bit pattern for a float NaN. The problem is that, as > the comment says, the program prints 0xffc00000 instead (which is a > negative NaN). > > I can solve the problem by using memcpy instead of the last assignment in > SET_FLOAT_WORD macro, but I'd like to understand why is GCC generate such > code, and why optimizations change that. > > Thanks in advance for any help. > It is NOT DJGPP related problem in gcc. I tested it in following systems (I removed call to _control87() for non MSDOS systems): Results with -O2 (for i[34567]86 compiler optimizes code to plain call to printf) 1) RS6000 running AIX-4.1.5 : all is Ok, no problems (got NaN and 0x7FC00000 as required) 2) DJGPP (gcc-2.8.1) : test failed (got 0xffc00000) 3) i586-pc-linux-gnulibc1 + gcc-2.7.2.3 : test failed 4) i586-pc-linux-gnulibc1 + egcs-2.91.53 19980804: test failed 5) i586-pc-linux-gnulibc to i586-pc-msdosdjgpp crosscompiler (gcc-2.8.1) : test failed 6) i586-pc-msdosdjgpp + egcs-2.91.53 19980804 : test failed (the last test maybe not so reliable as I used alpha version of C library for DJGPP) Without optimization I didn't get any failures (I always got 0x7FC00000) It looks the problem is only for i[34567]86. Andris > /* This program prints the bit pattern of the NaN (Not-a-Number) > which is 0x7fc00000. Compiled without optimizations it indeed > does so, but even -O1 causes it to print 0xffc00000 instead. */ > > #include > #include > #include > > typedef union > { > float value; > unsigned word; > } float_shape_type; > > /* Get a 32 bit int from a float. */ > > #define GET_FLOAT_WORD(i,d) \ > do { \ > float_shape_type gf_u; \ > gf_u.value = (d); \ > (i) = gf_u.word; \ > } while (0) > > /* Set a float from a 32 bit int. */ > > #define SET_FLOAT_WORD(d,i) \ > do { \ > float_shape_type sf_u; \ > sf_u.word = (i); \ > (d) = sf_u.value; \ > } while (0) > > int main (void) > { > unsigned iv; > float fv; > > _control87(0x033f, 0xffff); /* mask all numeric exceptions */ > SET_FLOAT_WORD(fv, 0x7fc00000U); > GET_FLOAT_WORD(iv, fv); > printf ("SET_FLOAT_WORD: %f, GET_FLOAT_WORD: %x\n", fv, iv); > return 0; > } >