https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67756
--- Comment #16 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- (In reply to Vladimir Makarov from comment #13) > (In reply to Bernd Edlinger from comment #11) > > I must admit, that I don't know what I am doing here, > > ... but this (completely untested) patch seems to fix the ICE: > > (and at least my linux kernel compiles without ICE now) > > > > This is a wrong fix. If the pseudos has the same value, they should not > conflict if they start with the same register. This part of code concerns > exactly about the pseudos with the same value. > > The root of the problem is in that the pseudos should not have the same > value. > OK, now I see the problem. How about this? --- lra-constraints.c.jj 2015-09-25 23:06:08.000000000 +0200 +++ lra-constraints.c 2015-10-02 12:18:51.346267777 +0200 @@ -160,6 +160,8 @@ static machine_mode curr_operand_mode[MA (e.g. constant) and whose subreg is given operand of the current insn. VOIDmode in all other cases. */ static machine_mode original_subreg_reg_mode[MAX_RECOG_OPERANDS]; +/* True if the operand is early clobber. */ +static bool goal_alt_early_clobber[MAX_RECOG_OPERANDS]; @@ -949,8 +951,10 @@ match_reload (signed char out, signed ch in the output, e.g. as an address part in memory, becuase output reload will actually extend the pseudo liveness. We don't care about eliminable hard regs here - as we are interesting only in pseudos. */ - && (out < 0 || regno_use_in (REGNO (in_rtx), out_rtx) == NULL_RTX) + as we are interesting only in pseudos. This does not work + for early clobber outputs. */ + && (out < 0 || (regno_use_in (REGNO (in_rtx), out_rtx) == NULL_RTX + && ! goal_alt_early_clobber[out])) ? lra_create_new_reg (inmode, in_rtx, goal_class, "") : lra_create_new_reg_with_unique_value (outmode, out_rtx, goal_class, "")); @@ -1693,6 +1697,7 @@ process_alt_operands (int only_alternati bool curr_alt_win[MAX_RECOG_OPERANDS]; bool curr_alt_offmemok[MAX_RECOG_OPERANDS]; int curr_alt_matches[MAX_RECOG_OPERANDS]; + bool curr_alt_early_clobber[MAX_RECOG_OPERANDS]; /* The number of elements in the following array. */ int curr_alt_dont_inherit_ops_num; /* Numbers of operands whose reload pseudos should not be inherited. */ @@ -1803,6 +1808,7 @@ process_alt_operands (int only_alternati curr_alt_match_win[nop] = false; curr_alt_offmemok[nop] = false; curr_alt_matches[nop] = -1; + curr_alt_early_clobber[nop] = false; continue; } @@ -2483,6 +2489,7 @@ process_alt_operands (int only_alternati curr_alt_match_win[nop] = this_alternative_match_win; curr_alt_offmemok[nop] = this_alternative_offmemok; curr_alt_matches[nop] = this_alternative_matches; + curr_alt_early_clobber[nop] = early_clobber_p; if (this_alternative_matches >= 0 && !did_match && !this_alternative_win) @@ -2642,6 +2649,7 @@ process_alt_operands (int only_alternati goal_alt_win[nop] = curr_alt_win[nop]; goal_alt_match_win[nop] = curr_alt_match_win[nop]; goal_alt_matches[nop] = curr_alt_matches[nop]; + goal_alt_early_clobber[nop] = curr_alt_early_clobber[nop]; goal_alt[nop] = curr_alt[nop]; goal_alt_offmemok[nop] = curr_alt_offmemok[nop]; } @@ -3366,6 +3374,7 @@ curr_insn_transform (bool check_only_p) { goal_alt_matched[i][0] = -1; goal_alt_matches[i] = -1; + goal_alt_early_clobber[i] = false; } commutative = curr_static_id->commutative;