[Bug rtl-optimization/108463] [13 Regression] ICE: in cselib_subst_to_values, at cselib.cc:2148 with -O2 -fsched2-use-superblocks -g

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Jan 27 16:47:54 GMT 2023


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

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I've put a watchpoint on n_useless_values and it seems it first diverges
(assuming it should be the same between -g and -g0) when processing the
(insn:TI 1074 1073 1087 2 (set (mem/c:V4SI (plus:DI (reg/f:DI 7 sp)
                (const_int -120 [0xffffffffffffff88])) [1  S16 A128])
        (reg:V4SI 22 xmm2 [207])) "pr106746.c":27:5 1809 {movv4si_internal}
     (expr_list:REG_DEAD (reg:V4SI 22 xmm2 [207])
        (nil)))
store (I'm using --parm min-non-debug-insn=1000).
Now, this is the first store to memory after the huge debug_insn with 16 MEMs
in it.
When processing this store, cselib_invalidate_mem is called on the
(mem/c:V4SI (plus:DI (reg/f:DI 7 sp) (const_int -120 [0xffffffffffffff88])) [1 
S16 A128])
MEM, and increments n_useless_values by different number of times.

What seems very wrong that in addition to MEMs like one from:
(insn 1066 1180 1067 2 (set (reg:SI 22 xmm2 [orig:202
VIEW_CONVERT_EXPR<int[16]>(vectmp.9)[_27] ] [202])
        (mem/j:SI (plus:DI (plus:DI (mult:DI (reg:DI 4 si [200])
                        (const_int 4 [0x4]))
                    (reg/f:DI 7 sp))
                (const_int 8 [0x8])) [1
VIEW_CONVERT_EXPR<int[16]>(vectmp.9)[_27]+0 S4 A32])) "pr106746.c":27:5 83
{*movsi_internal}
     (expr_list:REG_DEAD (reg:DI 4 si [200])
        (nil)))
(where it is hard(er) to guess if they overlap or not) it invalidates tons of
MEMs which clearly can't overlap with the store MEM, like:
(mem/c:V8HI (value:DI 81:4114 @0x3958f70/0x39396d0) [3 v+32 S16 A256])
where value 81:4114 has locs->loc of
(plus:DI (value/c:DI 2:2 @0x3958808/0x3938800)
    (const_int -216 [0xffffffffffffff28]))
and
(gdb) p debug_rtx (reg_values[7]->elt->locs->loc)
(reg/f:DI 7 sp)
(gdb) p debug_rtx (reg_values[7]->elt->locs->next->loc)
(plus:DI (value/c:DI 2:2 @0x3958808/0x3938800)
    (const_int -384 [0xfffffffffffffe80]))
So, say get_addr should be able to canonicalize that
(value:DI 81:4114 @0x3958f70/0x39396d0)
not to
(plus:DI (value/c:DI 2:2 @0x3958808/0x3938800)
    (const_int -216 [0xffffffffffffff28]))
which it returns, but to
(plus:DI (reg/f:DI 7 sp)
    (const_int 168 [0xa8]))
which can then be successfully compared to the other mem.


More information about the Gcc-bugs mailing list