gcc-2.8.0 code quality regression vs. gcc-2.7.2

Bruno Haible haible@ilog.fr
Mon Feb 2 04:26:00 GMT 1998


Although gcc-2.8.0 generates in general _much_ better code than gcc-2.7.2,
here is a case where gcc-2.8.0 code is worse. An inline function returning
a boolean expression, whose value is tested after the call. gcc-2.8.0
generates 3 superfluous instructions.

Looks like this is related to the optimization which turns
"xorl %edx,%edx" into "movl some_register_containing_0,%edx".

$ gcc -V 2.7.2 -v
Reading specs from /usr/lib/gcc-lib/i486-linuxlibc1/2.7.2/specs
gcc driver version 2.8.0 executing gcc version 2.7.2
$ gcc -V 2.8.0 -v
Reading specs from /usr/lib/gcc-lib/i486-linuxlibc1/2.8.0/specs
gcc version 2.8.0

================================= foo.c ===================================
typedef struct LONG { unsigned int length; unsigned long data[512+1]; } LONG[1];
extern void modmulmontgom (const LONG a, const LONG b, LONG z);
__inline int longiszero (const LONG a) { return (a->length == 0); }
void modpow_base16 (const LONG a, const LONG k, LONG z)
{
  int digits[512+1],i;
  if (longiszero(k))
    return;
  {
    unsigned int count = k->length;
    i = 0;
    do {
      digits[i] = k->data[i];
      i++;
    } while (--count > 0);
  }
  modmulmontgom(a,a,z);                    
}
============== gcc -V 2.7.2 -O2 -fomit-frame-pointer -S foo.c =============
	.file	"foo.c"
	.version	"01.01"
gcc2_compiled.:
.text
	.align 4
.globl longiszero
	.type	 longiszero,@function
longiszero:
	movl 4(%esp),%eax
	cmpl $0,(%eax)
	sete %al
	andl $255,%eax
	ret
.Lfe1:
	.size	 longiszero,.Lfe1-longiszero
	.align 4
.globl modpow_base16
	.type	 modpow_base16,@function
modpow_base16:
	subl $2052,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 2068(%esp),%esi
	movl 2072(%esp),%ebx
	movl 2076(%esp),%edi
	movl (%ebx),%eax
	testl %eax,%eax
	je .L3
	movl %eax,%ecx
	xorl %edx,%edx
	.align 4
.L6:
	movl 4(%ebx,%edx,4),%eax
	movl %eax,12(%esp,%edx,4)
	incl %edx
	decl %ecx
	jne .L6
	pushl %edi
	pushl %esi
	pushl %esi
	call modmulmontgom
	addl $12,%esp
.L3:
	popl %ebx
	popl %esi
	popl %edi
	addl $2052,%esp
	ret
.Lfe2:
	.size	 modpow_base16,.Lfe2-modpow_base16
	.ident	"GCC: (GNU) 2.7.2"
============== gcc -V 2.8.0 -O2 -fomit-frame-pointer -S foo.c =============
	.file	"foo.c"
	.version	"01.01"
gcc2_compiled.:
.text
	.align 16
.globl modpow_base16
	.type	 modpow_base16,@function
modpow_base16:
	subl $2052,%esp
	pushl %ebp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 2072(%esp),%ebp
	movl 2076(%esp),%edi
	movl (%edi),%edx
	testl %edx,%edx
	sete %al				;; <======= SUPERFLUOUS
	andl $255,%eax				;; <======= SUPERFLUOUS
	testl %eax,%eax				;; <======= SUPERFLUOUS
	jne .L2
	movl %edx,%ebx
	movl %eax,%ecx			;; <======= could use %edx instead
	leal 16(%esp),%esi
	.align 4
.L5:
	leal 0(,%ecx,4),%edx
	movl 4(%edx,%edi),%eax
	movl %eax,(%edx,%esi)
	incl %ecx
	decl %ebx
	jnz .L5
	movl 2080(%esp),%eax
	pushl %eax
	pushl %ebp
	pushl %ebp
	call modmulmontgom
	addl $12,%esp
.L2:
	popl %ebx
	popl %esi
	popl %edi
	popl %ebp
	addl $2052,%esp
	ret
.Lfe1:
	.size	 modpow_base16,.Lfe1-modpow_base16
	.align 16
.globl longiszero
	.type	 longiszero,@function
longiszero:
	movl 4(%esp),%eax
	cmpl $0,(%eax)
	sete %al
	andl $255,%eax
	ret
.Lfe2:
	.size	 longiszero,.Lfe2-longiszero
	.ident	"GCC: (GNU) 2.8.0"
===========================================================================



More information about the Gcc-bugs mailing list