c/805: gcc 2.95.2 reorders subexpressions of boolean operators
felix@anu.ie
felix@anu.ie
Tue Nov 14 14:36:00 GMT 2000
>Number: 805
>Category: c
>Synopsis: gcc 2.95.2 reorders subexpressions of boolean operators
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Tue Nov 14 14:36:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator: Felix Winkelmann
>Release: gcc version 2.95.2 19991024 (release)
>Organization:
>Environment:
Windows98, Cygwin B20, Pentium II/350 MMX
>Description:
Complex boolean expressions are reordered in a procedure
declared as "noreturn".
>How-To-Repeat:
/*
% gcc -O3 -fomit-frame-pointer gccbug.c -S
--------------------------------------------------------------------------------
*/
typedef struct C_block_struct
{
unsigned int header;
int data[ 1 ];
} BLOCK;
typedef void (*PROC)(int,int,int) __attribute__ ((noreturn));
void C_memv(int c, int closure, int k, int x, int lst) __attribute__ ((noreturn));
void C_memv(int c, int closure, int k, int x, int lst)
{
int y;
while(!(lst & 0x3) && (((BLOCK *)lst)->header & 0xff000000) == 0x03000000) {
y = ((BLOCK *)lst)->data[ 0 ];
if(x == y ||
(!(x & 0x3) && !(y & 0x3) &&
(((BLOCK *)x)->header & 0xff000000) == 0x55000000 &&
(((BLOCK *)y)->header & 0xff000000) == 0x55000000 &&
*((double *)(((BLOCK *)x)->data)) == *((double *)(((BLOCK *)y)->data)) ) )
((PROC)(void *)((BLOCK *)k)->data[ 0 ])(2, k, lst);
else lst = ((BLOCK *)lst)->data[ 1 ];
}
((PROC)(void *)((BLOCK *)k)->data[ 0 ])(2, k, 0x6);
}
/*
--------------------------------------------------------------------------------
.file "gccbug.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
.align 4
.globl _C_memv
.def _C_memv; .scl 2; .type 32; .endef
_C_memv:
subl $12,%esp
pushl %ebp
pushl %edi
pushl %esi
pushl %ebx
movl 40(%esp),%edi
movl 44(%esp),%esi
movl 48(%esp),%ecx
testb $3,%cl
jne L4
movl (%ecx),%eax
movl (%esi),%ebp <- word header is fetched, but we still don't know wether 'x' is a non-immediate
fldl 4(%esi) <- double is fetched, ...
andl $-16777216,%eax
movl %esi,%ebx
andl $3,%ebx
cmpl $50331648,%eax
jne L11
.p2align 4,,7
L5:
movl 4(%ecx),%edx
cmpl %edx,%esi
je L12
testl %ebx,%ebx <- here 'x' is checked for being an immediate
jne L7
testb $3,%dl
jne L7
movl %ebp,%eax
andl $-16777216,%eax
cmpl $1426063360,%eax
jne L7
movl (%edx),%eax
andl $-16777216,%eax
cmpl $1426063360,%eax
jne L7
fldl 4(%edx)
fucomp %st(1)
fnstsw %ax
andb $68,%ah
xorb $64,%ah
jne L7
L12:
fstp %st(0)
addl $-4,%esp
pushl %ecx
pushl %edi
pushl $2
movl 4(%edi),%eax
call *%eax
.p2align 4,,7
L7:
movl 8(%ecx),%ecx
testb $3,%cl
jne L13
movl (%ecx),%eax
andl $-16777216,%eax
cmpl $50331648,%eax
je L5
L11:
L13:
fstp %st(0)
L4:
addl $-4,%esp
pushl $6
pushl %edi
pushl $2
movl 4(%edi),%eax
call *%eax
*/
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the Gcc-bugs
mailing list