Combine clue requested - missed ia32 optimization
Zack Weinberg
zack@wolery.cumb.org
Fri Jul 14 16:49:00 GMT 2000
In C, a negated string compare is quite common. For example:
int memeq (void *a, void *b, size_t c)
{
return !memcmp(a, b, c)
}
More likely, the !memcmp expression would be inside an if somewhere.
Anyway, the above function generates rather bad code:
(-O2 -fomit-frame-pointer)
memeq:
pushl %edi
pushl %esi
movl 20(%esp), %ecx
cld
movl 16(%esp), %edi
movl 12(%esp), %esi
cmpl %ecx, %ecx
repz
cmpsb
popl %esi
* setb %al
* seta %dl
* xorl %ecx, %ecx
popl %edi
* cmpb %al, %dl
* sete %cl
* movl %ecx, %eax
ret
The starred instructions are generating the tristate result of memcmp,
then converting it back into a true/false equality result. We'd
really like to see something more like
memeq:
pushl %edi
pushl %esi
movl 20(%esp), %ecx
cld
movl 16(%esp), %edi
xorl %eax, %eax
movl 12(%esp), %esi
cmpl %ecx, %ecx
repz
cmpsb
popl %esi
sete %al
popl %edi
ret
I've traced this to a missed combination. We have RTL like so:
(set (reg:QI 50)
(gtu:QI (reg:CC 17 flags)
(const_int 0 [0x0])))
(set (reg:QI 51)
(ltu:QI (reg:CC 17 flags)
(const_int 0 [0x0])))
(set (reg:CC 17 flags)
(compare:CC (reg:QI 50)
(reg:QI 51)))
(set (strict_low_part (subreg:QI (reg:SI 52) 0))
(eq:QI (reg:CC 17 flags)
(const_int 0 [0x0])))
-- combine ought to be able to recognize that the first three insns
can simply be deleted. But I do not know where in combine to add the
logic to do it. combine.c is 13000 lines long and I have never tried
to modify it before.
Any suggestions would be appreciated.
zw
More information about the Gcc
mailing list