http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57967
--- Comment #2 from Daniel Blaukopf <daniel.blaukopf at oracle dot com> ---
This code:
int f1(int x0, int y0, int z0, int x1, int y1, int z1) {
int xx = ((x0 << 16) + (x1 - x0) * 0x1234 + 0x8000) >> 16;
int yy = ((y0 << 16) + (y1 - y0) * 0x2345 + 0x8000) >> 16;
int zz = ((z0 << 16) + (z1 - z0) * 0x3456 + 0x8000) >> 16;
return (xx << 16) | (yy << 8) | zz;
}
Compiles (incorrectly) to:
f1:
@ args = 8, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
ldr r0, [sp, #4]
subs r0, r0, r2
movw r3, #13398
mul r0, r3, r0
add r2, r0, r2, lsl #16
ldr r3, [sp, #0]
subs r3, r3, r1
movw r0, #9029
mul r3, r0, r3
add r1, r3, r1, lsl #16
add r1, r1, #32768
asr r1, r1, #16
lsl r1, r1, #8
add r0, r2, #32768
orr r0, r1, r0, asr #16
bx lr
This almost identical code:
int f2(int x0, int x1, int y0, int y1, int z0, int z1) {
int xx = ((x0 << 16) + (x1 - x0) * 0x1234 + 0x8000) >> 16;
int yy = ((y0 << 16) + (y1 - y0) * 0x2345 + 0x8000) >> 16;
int zz = ((z0 << 16) + (z1 - z0) * 0x3456 + 0x8000) >> 16;
return (xx << 16) | (yy << 8) | zz;
}
Compiles (correctly) to:
f2:
@ args = 8, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
push {r4, r5}
ldr r4, [sp, #8]
subs r3, r3, r2
movw r5, #9029
mul r3, r5, r3
add r2, r3, r2, lsl #16
add r2, r2, #32768
asr r2, r2, #16
subs r1, r1, r0
movw r3, #4660
mul r1, r3, r1
add r0, r1, r0, lsl #16
add r0, r0, #32768
asr r0, r0, #16
lsl r0, r0, #16
orr r2, r0, r2, lsl #8
ldr r0, [sp, #12]
subs r0, r0, r4
movw r3, #13398
mul r0, r3, r0
add r4, r0, r4, lsl #16
add r0, r4, #32768
orr r0, r2, r0, asr #16
pop {r4, r5}
bx lr