gcc 3.2 - float-related errors with -O -march=athlon
Jakub Bogusz
qboosh@pld.org.pl
Fri Sep 6 18:34:00 GMT 2002
On Thu, Sep 05, 2002 at 11:54:07PM +0200, Jakub Bogusz wrote:
> I get errors when trying to compile with -march=athlon and at least -O
> (-O1, -O2, -O3).
> Errors stop appearing after changing optimization to -O0, -Os or
> -march=i686.
>
> $ gcc -v
> Reading specs from /usr/lib/gcc-lib/athlon-pld-linux/3.2/specs
> Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-languages=c,c++,f77,gcov,java,objc,ksi,ada --enable-c99 --enable-long-long --enable-multilib --enable-nls --with-gnu-as --with-gnu-ld --with-system-zlib --with-slibdir=/lib --without-x athlon-pld-linux
> Thread model: posix
> gcc version 3.2
>
>
> This testcase is taken from lbreakout2, but file is cut down to less
> than 1kB (and it still triggers bug).
> It isn't rare case - I got very similar errors when trying to compile
> XFree86 4.2.1 with "-O2 -march=athlon" optimization.
> I'm using lbreakout2 code as example because it's simpler.
>
> Example command line is:
>
> $ gcc -c misc-b.i -O -march=athlon
I've done more tests, maybe this would help.
Errors occur with (shellglob-like notation):
-O{2,3} -march=athlon{,-tbird,-4,-xp,-mp}
-O{2,3} -march=pentium{2,3,4}
-O{2,3} -march=pentiumpro -mmx
-O{2,3} -march=k6{,-2,-3}
And -march=pentium-mmx does _not_ trigger bug.
> Then errors appear:
>
> misc-b.c: In function `circle_intersect':
> misc-b.c:58: unable to find a register to spill in class `FLOAT_REGS'
> misc-b.c:58: this is the insn:
> (insn 23 21 24 (set (subreg:SF (reg/v:DI 29 rmm0 [65]) 0)
> (minus:SF (subreg:SF (reg/v:DI 61) 0)
> (subreg:SF (reg/v:DI 1 rdx [59]) 0))) 533 {*fop_sf_1_nosse} (insn_list 8 (insn_list 4 (nil)))
> (nil))
> misc-b.c:58: confused by earlier errors, bailing out
And using "-O -march=athlon-xp -mfpmath=sse" changes error message to:
misc-b.c: In function `circle_intersect':
misc-b.c:58: unable to find a register to spill in class `SSE_REGS'
misc-b.c:58: this is the insn:
(insn 23 21 24 (set (subreg:SF (reg/v:DI 29 rmm0 [65]) 0)
(minus:SF (subreg:SF (reg/v:DI 61) 0)
(subreg:SF (reg/v:DI 1 rdx [59]) 0))) 535 {*fop_sf_1_sse} (insn_list 8 (insn_list 4 (nil)))
(nil))
misc-b.c:58: confused by earlier errors, bailing out
> char circle_msg[256];
>
> typedef struct {
> float x, y;
> } Vector;
> # 36 "misc-b.c"
> int circle_intersect( Vector m, int r, Vector pos, Vector v, Vector *t1, Vector *t2 )
> {
> Vector delta = { pos.x - m.x, pos.y - m.y };
> float delta_v = delta.x * v.x + delta.y * v.y;
> float dis = delta_v * delta_v + r * r - ( delta.x * delta.x + delta.y * delta.y );
> float t;
>
> if ( dis < 0 ) {
>
>
>
> return 0;
> }
>
> t = -delta_v + dis;
> t1->x = pos.x + t * v.x; t1->y = pos.y + t * v.y;
> t = -delta_v - dis;
> t2->x = pos.x + t * v.x; t2->y = pos.y + t * v.y;
>
>
>
> return 1;
> }
Shorter version that still triggers bug:
typedef struct {
float x, y;
} Vector;
float circle_intersect( Vector m, Vector pos)
{
Vector delta = { pos.x - m.x, pos.y - m.y};
return delta.x+delta.y;
}
The key seems to be that struct is initialized by "= { , }" construct,
and then both fields are used in some calculations.
After changing to "Vector delta; delta.x=pos.x-m.x; delta.y=pos.y-m.y"
errors doesn't occur.
--
Jakub Bogusz http://prioris.mini.pw.edu.pl/~qboosh/
PLD Linux http://www.pld.org.pl/
More information about the Gcc-bugs
mailing list