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

            Bug ID: 88236
           Summary: [avr] Invalid code generated for __memx deference for
                    avr5 arch
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: saaadhu at gcc dot gnu.org
  Target Milestone: ---

Compiling the below code with  -mmcu=avr5 -Os (trunk gcc version 9.0.0 20181127
(experimental) (GCC))

void foo (char *a, const __memx char *b)
{
        const __memx char *q;
        char d;

        while (*a++) {
            q = b;
            do{
                d = *q++;
            }while(d);
        } ;
}

results in incorrect code that looks like this (full code pasted below)

        lpm r30,Z
        sbrc r23,7
        ld r30,Z

Note that the LPM instruction clobbers R30, yet the same reg is used in the
subsequent LD instruction (as part of the Z pointer reg). This is generated for
a __memx char pointer dereference, and will work if the pointee is in program
memory space (sbrc will skip the LD). If the pointee lives in the data address
space though, the LD instruction will execute and yield incorrect results


Generated code:
        push r28
/* prologue: function */
/* frame size = 0 */
/* stack size = 1 */
        movw r18,r24
.LVL1:
.L2:
        movw r30,r18
        ld r24,Z
        subi r18,-1
        sbci r19,-1
.LVL2:
        cpse r24,__zero_reg__
        rjmp .L4
/* epilogue start */
        pop r28
        ret
.L4:
        movw r24,r20
        mov r26,r22
.LVL3:
.L3:
        mov r23,r26
        mov r30,r24
        mov r31,r25
        adiw r24,1
        adc r26,__zero_reg__
.LVL4:
        lpm r30,Z
        sbrc r23,7
        ld r30,Z
        cpse r30,__zero_reg__
        rjmp .L3
        rjmp .L2

Reply via email to