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