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

             Bug #: 54414
           Summary: ARM:mis-compiled prologue/epilogue on cortex-m0 when
                    optimizing with -Os
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: amker.ch...@gmail.com


For the case of pr45070.c as below:

/* PR45070 */
extern void abort(void);

struct packed_ushort {
    unsigned short ucs;
} __attribute__((packed));

struct source {
    int pos, length;
    int flag;
};

static void __attribute__((noinline)) fetch(struct source *p)
{
    p->length = 128;
}

static struct packed_ushort __attribute__((noinline)) next(struct source *p)
{
    struct packed_ushort rv;

    if (p->pos >= p->length) {
    if (p->flag) {
        p->flag = 0;
        fetch(p);
        return next(p);
    }
    p->flag = 1;
    rv.ucs = 0xffff;
    return rv;
    }
    rv.ucs = 0;
    return rv;
}

int main(void)
{
    struct source s;
    int i;

    s.pos = 0;
    s.length = 0;
    s.flag = 0;

    for (i = 0; i < 16; i++) {
    struct packed_ushort rv = next(&s);
    if ((i == 0 && rv.ucs != 0xffff)
        || (i > 0 && rv.ucs != 0))
        abort();
    }
    return 0;
}
Compile with below options:
$ arm-none-eabi-gcc -mthumb -mcpu=cortex-m0 -Os pr45070.c -o pr45070.S
The generated assembly code for function next is like:

next:
    push    {r0, r1, r2, r3, r4, lr}
    ldr    r2, [r0]
    ldr    r3, [r0, #4]
    mov    r4, r0
    cmp    r2, r3
    blt    .L3
    ldr    r2, [r0, #8]
    cmp    r2, #0
    beq    .L4
    mov    r3, #0
    str    r3, [r0, #8]
    add    r0, r0, #4
    bl    fetch.isra.0
    mov    r0, r4
    bl    next
    mov    r3, sp
    sxth    r0, r0
    strb    r0, [r3]
    lsr    r0, r0, #8
    strb    r0, [r3, #1]
    mov    r3, sp
    ldrh    r2, [r3]
    b    .L6
.L4:
    mov    r3, #1
    str    r3, [r0, #8]
    neg    r2, r3
    b    .L6
.L3:
    mov    r2, #0
.L6:
    add    r3, sp, #12
    strh    r2, [r3]
    add    r3, sp, #12
    ldrb    r0, [r3, #1]
    ldrb    r2, [r3]
    lsl    r0, r0, #8
    orr    r0, r2
    @ sp needed for prologue
    pop    {r1, r2, r3, r4, pc}

The pc register is restored with wong value.

Reply via email to