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