[Bug rtl-optimization/92796] [10 Regression] ICE in lra_assign, at lra-assigns.c:1646 on powerpc64le-linux-gnu

bergner at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Dec 6 23:13:00 GMT 2019


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

Peter Bergner <bergner at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at gcc dot gnu.org,
                   |                            |vmakarov at gcc dot gnu.org

--- Comment #6 from Peter Bergner <bergner at gcc dot gnu.org> ---
CCing Vlad (and Jeff) for LRA questions below.

Here is a slightly smaller test case that ICEs using -O2
-fstack-protector-strong -mcpu=power8:

typedef union
{
  __ieee128 a;
  int b;
} c;

__ieee128
d (__ieee128 x)
{
  __ieee128 g;
  c h;
  h.a = x;
  g = h.b & 5;
  h.b = g;
  if (g)
    return x - x;
  return h.a;
}


After IRA, we have the following:

Disposition:
    3:r121 l0   mem    8:r133 l0    66

(insn 44 13 2 2 (set (reg:KF 133)
                     (reg:KF 66 2 [ xD.2842 ])) "pr92796.i":9:1 1112
{vsx_movkf_64bit})
(insn 2 44 37 2 (set (reg/v:KF 121 [ xD.2842 ])
                     (reg:KF 133)) "pr92796.i":9:1 1112 {vsx_movkf_64bit}
     (expr_list:REG_DEAD (reg:KF 133)))
...
<hard reg 66 is live here>

Hard reg 66 is used after insn 2, but since regs 133 and 66 are connected
via a copy, they do not conflict, which is what allows 133 to be assigned
to hard reg 66 (a good thing generally).  This is all fine up to this point.

Since pseudo 121 is spilled, LRA generates reloads for insn 2 and we end
up with the following rtl:


(insn 44 13 53 2 (set (reg:KF 133)
                      (reg:KF 66 2 [ xD.2842 ])) "pr92796.i":9:1 1112
{vsx_movkf_64bit})
(insn 53 44 2 2 (set (reg:DI 144)
                     (plus:DI (reg/f:DI 110 sfp)
                              (const_int 32 [0x20]))) "pr92796.i":9:1 66
{*adddi3})
(insn 2 53 37 2 (set (mem/c:KF (reg:DI 144) [4 %sfpD.2858+-16 S16 A128])
                     (reg:KF 133)) "pr92796.i":9:1 1094 {*vsx_le_perm_store_kf}
        (expr_list:REG_DEAD (reg:DI 144)))
...
<hard reg 66 is live here>


Here is where we run into a problem.  The pattern *vsx_le_perm_store_kf's
source operand constraint "+wa.r", marks the source operand as an
input/output operand.  That now means that pseudo 133 should now be
made to conflict with the hard registers live at that point (ie, 66).
Since pseudo 133 is assigned to hard reg 66, we somehow need to reassign
pseudo 133.  However, LRA seems to think insn 2 satisfies its constraints,
so it happily continues on until we reach the assertion at lra-assigns.c:1646
and we ICE:

    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      if (lra_reg_info[i].nrefs != 0
          && reg_renumber[i] >= 0
          && overlaps_hard_reg_set_p (lra_reg_info[i].conflict_hard_regs,
                                      PSEUDO_REGNO_MODE (i), reg_renumber[i]))
        gcc_unreachable ();

Vlad (or Jeff), can you point me to where this is supposed to be handled?
I don't think I see where LRA verifies the reg_renumber[regno] values are still
valid with respect to the new pattern constraints for the insns that are
modified by spilling.

lra_reg_info[133].conflict_hard_regs does contain 66, so LRA knows it conflicts
with reg 66, but it never seems to use that information as a sign that pseudo
133 needs reassigning.


More information about the Gcc-bugs mailing list