Bug 6893 - gcc generates invalid code for x86 subarches.
Summary: gcc generates invalid code for x86 subarches.
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2002-06-01 06:16 UTC by warp
Modified: 2005-06-05 09:52 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description glen 2002-06-01 05:48:44 UTC
From: Glen Nakamura <glen@imodulo.com>
To: warp@debian.org
Cc: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org
Subject: Re: c/6893: gcc generates invalid code for x86 subarches.
Date: Sat, 1 Jun 2002 05:48:44 -1000

 --vkogqOf2sHV7VnPd
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6893
 
 Aloha,
 
 Looks like the testcase you provided has an aliasing problem:
 icolor = (int *) tmp;
 
 Strict aliasing does not allow casting from (float *) to (int *)...
 You will need to fix your code or compile w/ -fno-strict-aliasing.
 See the GCC documentation on -fstrict-aliasing for more information.
 
 Please check if your problem persists with the attached testcase.
 
 - Glen Nakamura
 
 
 --vkogqOf2sHV7VnPd
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="6893.c"
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #define min(a,b) ((a) < (b) ? (a) : (b))
 
 typedef union {
     float f;
     int   i;
 } tmp_t;
 
 float source[4];
 tmp_t tmp[4];
 unsigned char out[4];
 
 extern void inline FtoUB (float *in, char *out, int num)
 {
     int         i;
     tmp_t       *icolor;
     tmp_t       *fcolor_to;
 
     fcolor_to = tmp;
 
     // shift float to have 8bit fraction at base of number
     for (i = 0; i < num; i += 4) {
         fcolor_to[i    ].f = in[i    ] + 32768.0f;
         fcolor_to[i + 1].f = in[i + 1] + 32768.0f;
         fcolor_to[i + 2].f = in[i + 2] + 32768.0f;
         fcolor_to[i + 3].f = in[i + 3] + 32768.0f;
     }
 
     icolor = tmp;
 
     // then read as integer and kill float bits...
     for (i = 0; i < num; i += 4) {
         out[i    ] = (char) min(icolor[i    ].i & 0x7FFFFF, 255);
         out[i + 1] = (char) min(icolor[i + 1].i & 0x7FFFFF, 255);
         out[i + 2] = (char) min(icolor[i + 2].i & 0x7FFFFF, 255);
         out[i + 3] = (char) min(icolor[i + 3].i & 0x7FFFFF, 255);
     }
 }
 
 int
 main (int argc, char *argv[])
 {
     source[0] = atof(argv[1]);
     source[1] = atof(argv[2]);
     source[2] = atof(argv[3]);
     source[3] = atof(argv[4]);
 
     FtoUB(source, out, 4);
 
     printf("in: %f %f %f %f\n", source[0], source[1], source[2], source[3]);
     printf("out: %d %d %d %d\n", out[0], out[1], out[2], out[3]);
     exit (0);
 }
 
 --vkogqOf2sHV7VnPd--

Comment 1 warp 2002-06-01 06:16:01 UTC
gcc generates code which does not seem to behave correctly for the source below when using -march=pentium, pentium-mmx, pentium2, athlon, and athlon-tbird.

It may also generate bad code for other flags but I have not been able to test such yet.

Release:
3.0 and 3.1

Environment:
Debian SID, 1GHz Athlon Thunderbird

How-To-Repeat:
Compile with 'gcc-3.1 -o bad_gcc bad_gcc.c -Wall -O2 -march=athlon' or the like, use with './bad_gcc 0.5 0.2 0.3 0.5'.
The program should covert four floats given on the command line, which should be in the 0-1 range, to bytes in the 0-255 range.

Source starts here:

#include <stdio.h>
#include <stdlib.h>

#define min(a,b) ((a) < (b) ? (a) : (b))

float source[4];
float tmp[4];
unsigned char out[4];

extern void inline FtoUB (float *in, char *out, int num)
{
    int         i, *icolor;
    float       *fcolor_to;

    fcolor_to = tmp;

    // shift float to have 8bit fraction at base of number
    for (i = 0; i < num; i += 4) {
        fcolor_to[i    ] = in[i    ] + 32768.0f;
        fcolor_to[i + 1] = in[i + 1] + 32768.0f;
        fcolor_to[i + 2] = in[i + 2] + 32768.0f;
        fcolor_to[i + 3] = in[i + 3] + 32768.0f;
    }

    icolor = (int *) tmp;

    // then read as integer and kill float bits...
    for (i = 0; i < num; i += 4) {
        out[i    ] = (char) min(icolor[i    ] & 0x7FFFFF, 255);
        out[i + 1] = (char) min(icolor[i + 1] & 0x7FFFFF, 255);
        out[i + 2] = (char) min(icolor[i + 2] & 0x7FFFFF, 255);
        out[i + 3] = (char) min(icolor[i + 3] & 0x7FFFFF, 255);
    }
}

int
main (int argc, char *argv[])
{
    source[0] = atof(argv[1]);
    source[1] = atof(argv[2]);
    source[2] = atof(argv[3]);
    source[3] = atof(argv[4]);

    FtoUB(source, out, 4);

    printf("in: %f %f %f %f\n", source[0], source[1], source[2], source[3]);
    printf("out: %d %d %d %d\n", out[0], out[1], out[2], out[3]);
    exit (0);
}
Comment 2 warp 2002-06-01 06:16:01 UTC
Fix:
Work around is to either use gcc 2.95 or to not use -march.
Comment 3 warp 2002-06-01 14:30:28 UTC
From: "Zephaniah E\. Hull" <warp@babylon.d2dc.net>
To: Glen Nakamura <glen@imodulo.com>
Cc: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org
Subject: Re: c/6893: gcc generates invalid code for x86 subarches.
Date: Sat, 1 Jun 2002 14:30:28 -0400

 --/04w6evG8XlLl3ft
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 On Sat, Jun 01, 2002 at 05:48:44AM -1000, Glen Nakamura wrote:
 > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=3Dview%20audit-trail&database=
 =3Dgcc&pr=3D6893
 >=20
 > Aloha,
 >=20
 > Looks like the testcase you provided has an aliasing problem:
 > icolor =3D (int *) tmp;
 >=20
 > Strict aliasing does not allow casting from (float *) to (int *)...
 > You will need to fix your code or compile w/ -fno-strict-aliasing.
 > See the GCC documentation on -fstrict-aliasing for more information.
 
 Ah, thank you.
 
 Caught by changes in what is activated by -O2.
 
 Now if I can isolate what is getting killed by -fregmove I'll have this
 actually working properly with gcc 3.1.
 >=20
 > Please check if your problem persists with the attached testcase.
 
 Seems to be gone.
 >=20
 > - Glen Nakamura
 
 Zephaniah E. Hull.
 
 --=20
 	1024D/E65A7801 Zephaniah E. Hull <warp@babylon.d2dc.net>
 	   92ED 94E4 B1E6 3624 226D  5727 4453 008B E65A 7801
 	    CCs of replies from mailing lists are requested.
 
 Well, of course.  That's what Unix sysadmins do.  We make things
 work.  Even if they're things which are outside our job description
 or supposed area of expertise.
 
 As to the other proposal of breaking them for 6 months first, I
 will offer a quote from an MCSE I once met:
 
 "You're a Unix sysadmin?  You're the bad guys.  You keep things
 working."
 
 Pretty obvious who gets paid when things break, and who gets paid
 when they don't.
   -- Dan Birchall in the Scary Devil Monastery.
 
 --/04w6evG8XlLl3ft
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.0.7 (GNU/Linux)
 
 iD8DBQE8+RLDRFMAi+ZaeAERArtVAKDQ1NymIFmXH0l1qylBVTCF5YbwhACfQBcc
 nBrvH6UBcKsmBXqOOd8ZJz4=
 =rXBJ
 -----END PGP SIGNATURE-----
 
 --/04w6evG8XlLl3ft--
Comment 4 Richard Henderson 2002-06-01 23:55:14 UTC
State-Changed-From-To: open->closed
State-Changed-Why: Aliasing bug in test case.
Comment 5 Andrew Pinski 2005-06-05 09:50:26 UTC
Reopening to ...
Comment 6 Andrew Pinski 2005-06-05 09:52:08 UTC
Mark as a dup of bug 21920

*** This bug has been marked as a duplicate of 21920 ***