https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81012
Bug ID: 81012 Summary: ARM: Spill instead of register copy / dead store on int-to-double conversion Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: gergo.barany at inria dot fr Target Milestone: --- Created attachment 41496 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41496&action=edit Input C file for triggering the issue Input file (also in attachment): double fn2(int p1, int p2) { double a = p1; if (744073425321881 * p2 + 5) a = 2; return a; } Generated code on ARMv7 for VFPv3: $ gcc tst.c -Wall -Wextra -O3 -fomit-frame-pointer -S -o - [...] fn2: @ args = 0, pretend = 0, frame = 8 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. movw r3, #42171 movt r3, 2 push {r4, r5} movw r2, #65433 sub sp, sp, #8 asr r5, r1, #31 movt r2, 6195 mvn r4, #4 mul r3, r3, r1 str r0, [sp, #4] // SPILL mla r0, r2, r5, r3 mvn r5, #0 umull r2, r3, r1, r2 add r3, r0, r3 cmp r3, r5 cmpeq r2, r4 vldreq.32 s15, [sp, #4] @ int vmovne.f64 d0, #2.0e+0 vcvteq.f64.s32 d0, s15 add sp, sp, #8 @ sp needed pop {r4, r5} bx lr .size fn2, .-fn2 .ident "GCC: (GNU) 8.0.0 20170606 (experimental)" Note the store I marked "SPILL". It is a store of the integer register r0 which is reloaded on the line marked "@ int" into a floating-point register for subsequent int-to-double conversion. The spill frees r0 for other use, but it would be better to just replace the spill/reload sequence with vmov s15, r0 since the register is available. Also, if the large constant 744073425321881 in the if condition is changed to something smaller like 1881 (that fits into a mov's immediate field), GCC generates this code: fn2: @ args = 0, pretend = 0, frame = 8 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. movw r3, #1881 sub sp, sp, #8 mul r1, r3, r1 str r0, [sp, #4] // DEAD STORE cmn r1, #5 vmovne.f64 d0, #2.0e+0 vmoveq s15, r0 @ int vcvteq.f64.s32 d0, s15 add sp, sp, #8 @ sp needed bx lr This does perform a conditional move from r0 to s15, but it also generates a dead store to the stack. Clang and CompCert both just do a copy and don't touch the stack for this value. $ gcc -v [...] Target: armv7a-eabihf Configured with: --target=armv7a-eabihf --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float-abi=hard --with-float=hard Thread model: single gcc version 8.0.0 20170510 (experimental) (GCC) Not sure if this is related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80861 which also the stack for a float-to-char conversion. But that's the other direction, and if I understand correctly, there the problem is related to the final sign extension.