Olivier Hainque wrote:
> move_invariant_reg has this code:
>
> /* Replace the uses we know to be dominated.
> and we're observing a case where this updates only one of two
> match_dup related operands. This is on i386-mingwin [...]
This is causing nasty miscompilation of this very simple case:
char * volatile buf;
int size = 1024;
void foo (void)
{
int i, len = size;
for (i = 0; i < 5; i ++)
buf = __builtin_alloca (len);
}
./cc1 -O1 -fverbose-asm t.c
# GNU C (GCC) version 4.4.0 20080618 (experimental) (pentium-mingw32msv)
...
_foo:
pushl %ebp #
movl %esp, %ebp #,
pushl %edi #
pushl %esi #
pushl %ebx #
subl $12, %esp #,
movl $0, %edx #, i
movl _size, %eax # size, len
L2:
call ___chkstk
leal 15(%esp), %eax #, tmp68
andl $-16, %eax #, tmp70
movl %eax, _buf # tmp70, buf
addl $1, %edx #, i
cmpl $5, %edx #, i
jne L2 #,
...
The way eax is clobbered and reused as an argument to chkstk is
very, very wrong.