Bug#131454: gcc -O2 produces wrong code on PPC (gnuchess example)
Package: gcc
Version: 2:2.95.4-9
Severity: important
Compiling the current gnuchess source fails with this gcc (current woody)
and optimization set to -O2. The reason seems to be that statements are
not correctly serialized. Unfortunately I am not an expert in PPC
assembler but here is the code which breaks (modified from gnuchess source
file src/move.c, somewhat shortened). Removing the "inline" keyword
generates correct code with -O2. However, in the original source,
clear_and_set_bit() is just part of UnmakeMove(), as well as of
MakeMove(). So, the following should be (even more than) the relevant
part.
typedef unsigned long long BitBoard;
#define SETBIT(b,i) ((b) |= BitPosArray[i])
#define CLEARBIT(b,i) ((b) &= NotBitPosArray[i])
#define TOSQ(a) ((a) & 0x003F)
#define FROMSQ(a) ((a >> 6) & 0x003F)
inline void clear_and_set_bit(BitBoard *a, short f, short t)
{
CLEARBIT (*a, f);
SETBIT (*a, t);
}
void UnmakeMove (short side, int *move)
{
BitBoard *a;
short f, t, fpiece, cpiece;
short xside;
side = 1^side;
xside = 1^side;
f = FROMSQ(*move);
t = TOSQ(*move);
fpiece = cboard[t];
a = &board.b[side][fpiece];
clear_and_set_bit(a, t, f);
/* continues... */
}
So MakeMove() has about the same structure, except of course it switches
the roles of t and f. Now the gnuchess move generation algorithm generates
all possible moves, makes them, and unmakes them again. With inlining and
-O2 however, it seems that making and unmaking of moves is not serialized,
so that after trying out all pawn moves from the beginning position, white
has a pawn on every square between the second and fourth row. If someone
really wants, I can supply the assembler files move.s for -O1 (correct
code) and -O2 (incorrect), together with the C source.
Lukas
Reply to: