https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84875

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, we have a function which conditionally bypasses the prologue and epilogue
and just performs a tailcall, otherwise saves two registers (%r10 and %r11)
into %f2 and %f0 registers, clobbers one of them (%r11) and conditionally
branches to epilogue sequence that restores the two:
(insn/f 105 107 106 5 (set (reg:DI 10 %r10)
        (reg:DI 17 %f2)) "pr84875.c":18 -1
     (expr_list:REG_DEAD (reg:DI 17 %f2)
        (expr_list:REG_CFA_RESTORE (reg:DI 10 %r10)
            (nil))))
(insn/f 106 105 94 5 (set (reg:DI 11 %r11)
        (reg:DI 16 %f0)) "pr84875.c":18 -1
     (expr_list:REG_DEAD (reg:DI 16 %f0)
        (expr_list:REG_CFA_RESTORE (reg:DI 11 %r11)
            (nil))))
and falls through into the tailcall (otherwise performs some other stuff,
clobbers also the %r10 register, restores the two registers and returns).
That is fine.  Now, cprop_hardreg figures out the %r10 register isn't really
clobbered in the particular path and changes it to:
(insn/f 105 107 106 5 (set (reg:DI 10 %r10)
        (reg:DI 10 %r10 [17])) "pr84875.c":18 1270 {*movdi_64}
     (expr_list:REG_DEAD (reg:DI 17 %f2)
        (expr_list:REG_CFA_RESTORE (reg:DI 10 %r10)
            (nil))))
(insn/f 106 105 94 5 (set (reg:DI 11 %r11)
        (reg:DI 16 %f0)) "pr84875.c":18 1270 {*movdi_64}
     (expr_list:REG_DEAD (reg:DI 16 %f0)
        (expr_list:REG_CFA_RESTORE (reg:DI 11 %r11)
            (nil))))
From the POV of unwind info that is still ok, there is really no need to
actually restore the register physically, we just need to emit the .cfi_restore
because we are entering code where the register might not be really safed in
the original register anymore.

And finally rtl_dce just removes the insn 105 as a noop move and removes with
it also the REG_CFA_RESTORE note.

Reply via email to