https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91109
--- Comment #6 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- with this patch the relevant part if the reload dump file looks different: (insn 3414 6591 6682 129 (set (mem/c:SI (reg/f:SI 5 r5 [5715]) [1 s.5566D.5531+0 S4 A32]) (reg:SI 6 r6 [orig:828 _821 ] [828])) "20040709-1.c":13:5 654 {*arm_movsi_vfp} (nil)) [...] (insn 6826 3453 6816 129 (parallel [ (set (reg:SI 3 r3 [4187]) (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (reg:SI 11 fp [4186])) (zero_extend:DI (reg:SI 7 r7 [4188]))) (const_int 32 [0x20])))) (clobber (reg:SI 1 r1 [5970])) ]) "20040709-1.c":108:291 70 {*umulsi3_highpart_v6} (nil)) [...] (insn 3509 3530 3531 132 (set (mem/c:SI (reg/f:SI 5 r5 [5715]) [1 s.5566D.5531+0 S4 A32]) (reg:SI 14 lr [orig:692 D.6083 ] [692])) "20040709-1.c":13:5 654 {*arm_movsi_vfp} (nil)) This time insn 6826 is able to choose a different register than r5, and most importantly the live-range info is correct, since the old register r5970 is renamed to r6374 temporarily: Creating newreg=6374 from oldreg=5970, assigning class GENERAL_REGS to scratch pseudo copy r6374 6816: r6364:SI=r4187:SI REG_DEAD r4187:SI Inserting rematerialization insn before: 6826: {r6364:SI=trunc(zero_extend(r4186:SI)*zero_extend(r4188:SI) 0>>0x20);clobber r6374:SI;} REG_UNUSED r6374:SI which is visible in the live ranges (which was not there before): r6007: [59..59] r6374: [1572..1572] Compressing live ranges: from 3802 to 75 - 1% Ranges after the compression: [...] r6007: [1..1] r6374: [40..40] However since the re-materialized instruction is able to use r1 there is no conflict any more. So I believe the patch is a straight improvement over the previous state of affairs. So, as it looks like, this is a potentially catastrophic bug, and not related to -flto at all or any specific target architecture. From my testing it is likely that was already there in gcc-9.0.1.