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

--- Comment #8 from Oleg Endo <olegendo at gcc dot gnu.org> ---
I've got a similar case on SH that looks related (didn't want to start yet
another PR for this)

void test_8(char *dst, char *src, int len)
{
    for (int i = 0; i < len; ++i) 
        *dst++ = *src++;
}

with -O2 -m2 -ml gets compiled to:

test_8(char*, char*, int):
        cmp/pl  r6
        bf      .L1
.L3:
        add     #1,r5
        mov     r5,r0
        add     #-16,r0         // r0 = r5 - 15
        add     #1,r4
        mov.b   @(15,r0),r0     // @(15 + r0) = @(15 + r5 - 15)
        mov     r4,r1
        add     #-16,r1
        dt      r6
        bf.s    .L3
        mov.b   r0,@(15,r1)
.L1:
        rts     
        nop


On the other hand, on ARM with -O2 -mtune=cortex-m0:

test_8(char*, char*, int):
        cmp     r2, #0
        ble     .L1
        add     r2, r2, r0
.L3:
        ldrb    r3, [r1], #1    @ zero_extendqisi2
        strb    r3, [r0], #1
        cmp     r2, r0
        bne     .L3
.L1:
        bx      lr


The ideal minimal code on SH2+ would be something like this:
        cmp/pl  r6
        bf      .L1
.L3:
        mov.b   @r5+,r0
        dt      r6
        mov.b   @r4,r0
        bf/s    .L3
        add     #1,r4


Something must be going terribly wrong to make it beat around the bush so much
and produce 

// @(15 + r0) = @(15 + r5 - 15)

Reply via email to