c/1994: gcc 2.96 optimisation bug
Ben Caradoc-Davies
ben.caradoc-davies@perth.wni.com
Wed Feb 14 23:26:00 GMT 2001
>Number: 1994
>Category: c
>Synopsis: gcc 2.96 optimisation bug
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Feb 14 23:26:03 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Ben Caradoc-Davies <ben.caradoc-davies@perth.wni.com>
>Release: gcc version 2.96 20000731 (Red Hat Linux 7.0)
>Organization:
>Environment:
Red Hat Linux 7.0 i386
>Description:
See attached file (swapfloat.c) for complete documentation
and example.
>How-To-Repeat:
See attached file (swapfloat.c) for complete documentation
and example.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="swapfloat.c"
Content-Disposition: inline; filename="swapfloat.c"
/*
* swapfloat.c - a demo of a gcc optimisation bug
*
* Ben Caradoc-Davies <ben.caradoc-davies@perth.wni.com>
* WNI Science and Engineering, 31 Bishop St, Jolimont, Western Australia.
*
* 15 February 2001
*/
/*******************************************************************************
Bug report
==========
Using -O2 with gcc 2.96 (Red Hat Linux 7.0 i386) reveals a bug.
> gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.0)
Correct output
--------------
> gcc swapfloat.c -o swapfloat
> ./swapfloat
Input as unsigned: 0xf08c8e3d
Output as unsigned: 0x3d8e8cf0 (should have byte order reversed)
Incorrect output
----------------
> gcc -O2 swapfloat.c -o swapfloat
> ./swapfloat
Input as unsigned: 0xf08c8e3d
Output as unsigned: 0x000000f0 (should have byte order reversed)
Analysis
--------
Notice that all but the first byte of the output have been corrupted. In a
larger program, these are filled with garbage (and a different and also wrong
float is returned).
This is not an alignment problem as "array" is in practice aligned suitably
for conversion to a float.
This bug is *not* present in either of the following versions (i386):
gcc version 2.95.2 19991024 (release)
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
*******************************************************************************/
#include <stdio.h>
/*
* swapfloat swaps the byte order of a float
*
* This function was originally written by
* Jason R. Waring
* CSIRO Division of Marine Research
*/
float swapfloat(float f) {
unsigned char *bp = (unsigned char *)&f;
unsigned char array[sizeof(float)];
array[0] = bp[3];
array[1] = bp[2];
array[2] = bp[1];
array[3] = bp[0];
return (*(float *)array);
}
int main() {
float f_in, f_out;
/* Raw binary float (from a big-endian machine) */
unsigned raw_in = 0xf08c8e3d;
f_in = *((float*)(&raw_in)); /* Read binary into float */
printf( "Input as unsigned:\t%#.8x\n", *((unsigned**)&f_in) );
f_out = swapfloat( f_in ); /* Swap byte order */
printf( "Output as unsigned:\t%#.8x\t(should have byte order reversed)\n",
*((unsigned**)&f_out) );
return 0;
}
More information about the Gcc-bugs
mailing list