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