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)