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

--- Comment #10 from Jeevitha <jeevitha at gcc dot gnu.org> ---
The following instructions [in basic block 4] were removed in sched2 DCE, which
makes r3 unused [populated in call_insn 26], but they were not deleted in this
pass itself:

(insn 28 26 29 4 (set (reg:DI 9 9 [132])
        (unspec:DI [
                (reg:DI 3 3 [142])
                (symbol_ref:DI ("_ZL8sMemPool") [flags 0x1a]  <var_decl
0x7ffff54d0ab0 sMemPool>)
            ] UNSPEC_TLSDTPRELHA)) "test.cc":27:7 740 {tls_dtprel_ha_64}
     (expr_list:REG_DEAD (reg:DI 3 3 [142])
        (nil)))
(insn 29 28 35 4 (set (reg:DI 9 9 [130])
        (unspec:DI [
                (reg:DI 9 9 [132])
                (symbol_ref:DI ("_ZL8sMemPool") [flags 0x1a]  <var_decl
0x7ffff54d0ab0 sMemPool>)
            ] UNSPEC_TLSDTPRELLO)) "test.cc":27:7 741 {tls_dtprel_lo_64}
     (nil))
(insn 31 35 32 4 (set (reg/f:DI 9 9 [orig:133 sMemPool ] [133])
        (mem/f/c:DI (reg:DI 9 9 [130]) [1 sMemPool+0 S8 A64])) "test.cc":27:3
683 {*movdi_internal64}
     (nil))
(insn 32 31 44 4 (set (reg:CC 100 0 [134])
        (compare:CC (reg/f:DI 9 9 [orig:133 sMemPool ] [133])
            (const_int 0 [0]))) "test.cc":27:3 799 {*cmpdi_signed}
     (expr_list:REG_DEAD (reg/f:DI 9 9 [orig:133 sMemPool ] [133])
        (nil)))

The following are the instructions that were not removed in sched2 DCE because
they are avoiding call deletion [call_insn 26] with this flag [df_in_progress].

(insn 72 23 53 4 (set (reg:DI 3 3)
        (reg:DI 28 28 [139])) "test.cc":27:7 683 {*movdi_internal64}
     (nil))
(call_insn/u 26 53 35 4 (parallel [
            (set (reg:DI 3 3)
                (call (mem:SI (symbol_ref:DI ("__tls_get_addr") [flags 0x41] 
<function_decl 0x7ffff576df00 __tls_get_addr>) [0  S4 A8])
                    (unspec:DI [
                            (reg:DI 2 2)
                        ] UNSPEC_TLSLD)))
            (use (const_int 0 [0]))
            (clobber (reg:DI 96 lr))
        ]) "test.cc":27:7 776 {*call_value_nonlocal_aixdi}
     (expr_list:REG_UNUSED (reg:DI 3 3)
        (expr_list:REG_CALL_DECL (symbol_ref:DI ("__tls_get_addr") [flags 0x41]
 <function_decl 0x7ffff576df00 __tls_get_addr>)
            (expr_list:REG_EH_REGION (const_int -2147483648
[0xffffffff80000000])
                (nil))))
    (expr_list (use (reg:DI 2 2))
        (expr_list (use (reg:DI 3 3))
            (nil))))

Here, call_insn 26 becomes dead after deleting insn 28, but it is not removed.
If call_insn 26 is removed, insn 72 can be removed. If insn 72 is removed, the
following insns in basic block 3 can also be removed:

(insn 80 136 81 3 (set (reg:DI 28 28 [145])
        (high:DI (unspec:DI [
                    (reg:DI 2 2)
                ] UNSPEC_TLSLD))) "test.cc":27:7 737 {*tls_ld_high64}
     (expr_list:REG_EQUIV (high:DI (unspec:DI [
                    (reg:DI 2 2)
                ] UNSPEC_TLSLD))
        (nil)))
(insn 81 80 54 3 (set (reg:DI 28 28 [139])
        (lo_sum:DI (reg:DI 28 28 [145])
            (unspec:DI [
                    (reg:DI 2 2)
                ] UNSPEC_TLSLD))) "test.cc":27:7 738 {*tls_ld_low64}
     (expr_list:REG_DEAD (reg:DI 2 2)
        (nil)))

Currently, we are encountering an ICE in insn 80 and 81. These two instructions
are dead but remain unremoved until the final pass. They are attempting to
retrieve a symbol that was present in insn 28, yet this insn has already been
removed in sched2.

When allowing sched2 to process call deletion, it successfully removed
call_insn/u 26 and insn 72 in bb4, but not insn 80 and 81 because live
registers are not updated for bb3 in same pass. It requires another DCE, but
our GCC does not have DCE after sched2.

Reply via email to