http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54816



             Bug #: 54816

           Summary: [avr] shift is better than widening mul

    Classification: Unclassified

           Product: gcc

           Version: 4.8.0

            Status: UNCONFIRMED

          Keywords: missed-optimization

          Severity: normal

          Priority: P3

         Component: target

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: g...@gcc.gnu.org

                CC: eric.wedding...@atmel.com

            Target: avr





The following C test case 



int wmul (char a, char b)

{

    return a * (char) (b << 3);

}



$ avr-gcc wmul.c -S -Os -mmcu=atmega8 -dp



produces with current avr-gcc:





wmul:

    ldi r25,lo8(8)     ;  25    movqi_insn/2    [length = 1]

    muls r22,r25     ;  26    mulqihi3    [length = 3]

    movw r22,r0

    clr __zero_reg__

    muls r24,r22     ;  17    mulqihi3    [length = 3]

    movw r24,r0

    clr __zero_reg__

    ret     ;  29    return    [length = 1]

    .ident    "GCC: (GNU) 4.8.0 20121004 (experimental)"





avr-gcc-4.7 was smarter with its code:



wmul:

    lsl r22     ;  10    *ashlqi3/5    [length = 3]

    lsl r22

    lsl r22

    muls r24,r22     ;  12    mulqihi3    [length = 3]

    movw r22,r0

    clr __zero_reg__

    movw r24,r22     ;  31    *movhi/1    [length = 1]

    ret     ;  30    return    [length = 1]

    .ident    "GCC: (GNU) 4.7.2"





The 4.7 code is faster, smaller and has smaller register pressure.

Reply via email to