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