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

--- Comment #30 from Vladimir Makarov <vmakarov at gcc dot gnu.org> ---
(In reply to Dominik Vogt from comment #29)
> I think I understand what's going on:
> 
> Consider the patched code in match_reloads():
> 
> +       = (ins[1] < 0 && REG_P (in_rtx)
> +          && (int) REGNO (in_rtx) < lra_new_regno_start
> +          && find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx))
> +          ? lra_create_new_reg (inmode, in_rtx, goal_class, "")
> +          : lra_create_new_reg_with_unique_value (outmode, out_rtx,
> +                                                  goal_class, ""));
> 
> (1) This code normally makes a unique copy of the register in in_rtx, but if
> the register is marked as REG_DEAD in the curr_insn, it just makes a copy of
> the register using lra_create_new_reg(), with the same .val and .offset in
> the reg_info structure.
> 
> (2) Further down in match_reloads, new insns are generated and stored in
> *before and *after.  However, the new "after" insn still references the old
> register.  In other words, in step (1) the code has made the assumption that
> the old register is no longer used, then generates an insn that uses it
> after it was marked as REG_DEAD.
> 
> (3) Based on the bogus decision in (1), the condition in lra-lives.c decides
> that the two registers are identical copies and can be mapped to the same
> hard register:
> 
> +         && (((src_regno >= FIRST_PSEUDO_REGISTER
> +               && (! sparseset_bit_p (pseudos_live, src_regno)
> +                   || (dst_regno >= FIRST_PSEUDO_REGISTER
> +                       && lra_reg_val_equal_p (src_regno,
> +                                               lra_reg_info[dst_regno].val,
> +                                              
> lra_reg_info[dst_regno].offset))

Sorry for breaking s390 port and thanks for the analysis.  I'll try to fix it
on this week.

Reply via email to