https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81012
--- Comment #2 from Gergö Barany <gergo.barany at inria dot fr> --- Created attachment 41672 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41672&action=edit Smaller test case Added a smaller test case: int fn3(int p1, int p2) { int a = p2; if (p1) a *= 10.0; return a; } It compiles to the following: fn3: @ args = 0, pretend = 0, frame = 8 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. sub sp, sp, #8 cmp r0, #0 str r1, [sp, #4] beq .L2 vmov.f64 d6, #1.0e+1 vmov s15, r1 @ int vcvt.f64.s32 d7, s15 vmul.f64 d7, d7, d6 vcvt.s32.f64 s15, d7 vstr.32 s15, [sp, #4] @ int .L2: ldr r0, [sp, #4] add sp, sp, #8 @ sp needed bx lr .size fn3, .-fn3 .ident "GCC: (GNU) 8.0.0 20170626 (experimental)" Instead of the first store, r1 should be moved to r0. The second store should then be a vmov r0, s15. No spills needed. This is done correctly on x86-64: fn3: .LFB0: .cfi_startproc testl %edi, %edi movl %esi, %eax je .L2 pxor %xmm0, %xmm0 cvtsi2sd %esi, %xmm0 mulsd .LC0(%rip), %xmm0 cvttsd2si %xmm0, %eax .L2: rep ret