https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125687

            Bug ID: 125687
           Summary: [avr] Superfluous register moves due to hard-reg
                    constraints
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

typedef __UINT32_TYPE__ uint32_t;

uint32_t div7 (uint32_t x)
{
    return x / 7;
}

$ avr-gcc x.c -S -Os -mmcu=avr4 -dp && cat x.s

generates the following code:

div7:
        push r28                 ;  26  [c=4 l=1]  pushqi1/0
        push r29                 ;  27  [c=4 l=1]  pushqi1/0
        ldi r26,lo8(7)   ;  38  [c=4 l=1]  movqi_insn/1
        ldi r27,0                ;  39  [c=4 l=1]  movqi_insn/0
        ldi r28,0                ;  40  [c=4 l=1]  movqi_insn/0
        ldi r29,0                ;  41  [c=4 l=1]  movqi_insn/0
        movw r20,r28     ;  46  [c=4 l=1]  *movhi/0
        movw r18,r26     ;  47  [c=4 l=1]  *movhi/0
        rcall __udivmodsi4       ;  24  [c=0 l=1]  *udivmodsi4_call
        movw r22,r18     ;  56  [c=4 l=1]  *movhi/0
        movw r24,r20     ;  57  [c=4 l=1]  *movhi/0
        pop r29          ;  30  [c=4 l=1]  popqi
        pop r28          ;  31  [c=4 l=1]  popqi
        ret              ;  32  [c=0 l=1]  return_from_epilogue

That is: The constant of 7 is loaded into registers R26..R29 (insns 38..41)
just to move it into R18..R21 afterwards (insns 46..47).  To make things even
worse, two of the registers used to load the constant are callee-saved regs,
requiring push/pop (insns 26, 27, 30, 31).

This is caused by using hard-reg constraints in https://gcc.gnu.org/r17-891

Going one git revision prior to that, the generated code loads the constant
into R18..R21 without any further ado:

div7:
        ldi r18,lo8(7)   ;  29  [c=4 l=1]  movqi_insn/1
        ldi r19,0                ;  30  [c=4 l=1]  movqi_insn/0
        ldi r20,0                ;  31  [c=4 l=1]  movqi_insn/0
        ldi r21,0                ;  32  [c=4 l=1]  movqi_insn/0
        rcall __udivmodsi4       ;  23  [c=0 l=1]  *udivmodsi4_call
        movw r22,r18     ;  37  [c=4 l=1]  *movhi/0
        movw r24,r20     ;  38  [c=4 l=1]  *movhi/0
        ret              ;  27  [c=0 l=1]  return

Reply via email to