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