Bug#301746: gcc-3.4: Redundant reloading from stack frame
Package: gcc-3.4
Version: 3.4.3-6
Severity: wishlist
This is a regression from gcc-3.2 in that gcc-3.2 does not have this
problem bug gcc-3.3 does.
The attached program generates the following code on i386 with
gcc -S -O2:
...
.L2:
movl -16(%ebp), %eax
xorl %esi, %esi
testl %eax, %eax
je .L8
As you can see %eax now contains the value in -16(%ebp).
subl $12, %esp
movl -16(%ebp), %eax
gcc-3.4 decides to reload for no reason at all.
pushl %eax
call strlen
movl %eax, %esi
addl $16, %esp
.L5:
pushl %eax
pushl %edi
pushl %ebx
leal 2(%edi,%esi), %eax
pushl %eax
call malloc
movl %eax, (%esp)
movl %eax, %ebx
call mempcpy
movl -16(%ebp), %edi
Again the value of -16(%ebp) is in %edi.
addl $16, %esp
testl %edi, %edi
je .L6
movb $61, (%eax)
pushl %ecx
pushl %esi
movl -16(%ebp), %edx
gcc-3.4 decides to reload it yet again.
pushl %edx
incl %eax
pushl %eax
call mempcpy
addl $16, %esp
...
Cheers,
-- System Information
Debian Release: 3.1
Kernel Version: Linux gondolin 2.4.27-hx-1-686-smp #3 SMP Tue Oct 5 20:01:26 EST 2004 i686 GNU/Linux
Versions of the packages gcc-3.4 depends on:
ii binutils 2.15-5 The GNU assembler, linker and binary utiliti
ii cpp-3.4 3.4.3-6 The GNU C preprocessor
ii gcc-3.4-base 3.4.3-6 The GNU Compiler Collection (base package)
ii libc6 2.3.2.ds1-20 GNU C Library: Shared libraries and Timezone
ii libgcc1 3.4.3-6 GCC support library
--
typedef unsigned int size_t;
extern size_t strlen (__const char *__s) __attribute__ ((__pure__));
extern char *strchrnul (__const char *__s, int __c) __attribute__ ((__pure__));
extern void *mempcpy (void *__restrict __dest,
__const void *__restrict __src, size_t __n) ;
extern void *malloc(size_t);
extern void setvareq(char *s, int flags);
extern char *endofname(const char *);
extern void sh_error(const char *, ...) __attribute__ ((__noreturn__));
void
setvar(const char *name, const char *val, int flags)
{
char *p, *q;
size_t namelen;
char *nameeq;
size_t vallen;
q = endofname(name);
p = strchrnul(q, '=');
namelen = p - name;
if (!namelen || p != q)
sh_error("%.*s: bad variable name", namelen, name);
vallen = 0;
if (val == ((void *)0)) {
flags |= 2;
} else {
vallen = strlen(val);
}
p = mempcpy(nameeq = malloc(namelen + vallen + 2), name, namelen);
if (val) {
*p++ = '=';
p = mempcpy(p, val, vallen);
}
*p = '\0';
setvareq(nameeq, flags | 1);
}
Reply to: