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.