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

--- Comment #9 from Kewen Lin <linkw at gcc dot gnu.org> ---
(In reply to Segher Boessenkool from comment #8)
> So for which pseudo and which hard register did this ICE, and what did the
> code look like at that point?

The culprit pseudo is r133, the values of those related expressions in the
check:

lra_reg_info[i].nrefs  -> 4

reg_renumber[i] -> 97

overlaps_hard_reg_set_p(lra_reg_info[i].conflict_hard_regs, E_SImode, 97) ->
true

Before IRA, the code looks like:

(note 21 1 166 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(insn 166 21 2 2 (set (reg:SI 229)
        (reg:SI 3 3 [ foo ])) "test.f":1:23 562 {*movsi_internal1}
     (expr_list:REG_DEAD (reg:SI 3 3 [ foo ])
        (nil)))
(insn 2 166 167 2 (set (reg/v/f:SI 133 [ foo ])
        (reg:SI 229)) "test.f":1:23 562 {*movsi_internal1}
     (expr_list:REG_DEAD (reg:SI 229)
        (nil)))
....

(insn 33 32 34 4 (set (reg:SI 3 3)
        (reg/v/f:SI 137 [ g ])) "test.f":17:72 562 {*movsi_internal1}
     (nil))
(insn 34 33 35 4 (set (reg:SI 97 ctr)
        (reg/v/f:SI 133 [ foo ])) "test.f":17:72 562 {*movsi_internal1}
     (nil))      
(call_insn 35 34 38 4 (parallel [
            (call (mem:SI (reg:SI 97 ctr) [0 *foo_21(D) S4 A8])
                (const_int 0 [0]))
            (use (const_int 4 [0x4]))
            (clobber (reg:SI 96 lr))
        ]) "test.f":17:72 814 {*call_indirect_nonlocal_sysvsi}
     (expr_list:REG_DEAD (reg:SI 97 ctr)
        (expr_list:REG_DEAD (reg:SI 3 3)
            (nil)))
    (expr_list:SI (use (reg:SI 3 3))
        (nil)))

...

in IRA, the hard reg assignment is:

  125:r120 l0     9   86:r125 l0    10   13:r126 l0    29   87:r127 l0     8
   73:r128 l0    44   35:r133 l0     3   33:r134 l0     4   31:r135 l0     0
  ...

choosing r3 for r133.  As above, the r3 is redefined at insn 33, r133 is used
in insn34, so it has to try to split the live range of r133.

I didn't dig into LRA code, I don't really understand what the condition means.
:( The reason why I did the hacking by commenting gcc_unreachable() is to see
how it causes some unexpected consequence without this kind of checking. As
shown above, the resulted assembly looks inefficient, but it should work from
correctness perspective. So I guessed maybe the condition is too strict or we
miss to consider something special and punt some valid things.

Reply via email to