<a...@codesourcery.com> writes: > Given a pattern with a number of operands: > > (match_operand 0 "" "=&v") > (match_operand 1 "" " v0") > (match_operand 2 "" " v0") > (match_operand 3 "" " v0") > > GCC will currently increment "reject" once, for operand 0, and then decrement > it once for each of the other operands, ending with reject == -2 and an > assertion failure. If there's a conflict then it might try to decrement > reject > yet again. > > Incidentally, what these patterns are trying to achieve is an allocation in > which operand 0 may match one of the other operands, but may not partially > overlap any of them. Ideally there'd be a better way to do this. > > In any case, it will affect any pattern in which multiple operands may (or > must) match an early-clobber operand. > > The patch only allows a reject-- when one has not already occurred, for that > operand. > > 2018-09-05 Andrew Stubbs <a...@codesourcery.com> > > gcc/ > * lra-constraints.c (process_alt_operands): Check > matching_early_clobber before decrementing reject, and set > matching_early_clobber after. > * lra-int.h (struct lra_operand_data): Add matching_early_clobber. > * lra.c (setup_operand_alternative): Initialize matching_early_clobber. > --- > gcc/lra-constraints.c | 22 ++++++++++++++-------- > gcc/lra-int.h | 3 +++ > gcc/lra.c | 1 + > 3 files changed, 18 insertions(+), 8 deletions(-) > > diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c > index 8be4d46..55163f1 100644 > --- a/gcc/lra-constraints.c > +++ b/gcc/lra-constraints.c > @@ -2202,7 +2202,13 @@ process_alt_operands (int only_alternative) > " %d Matching earlyclobber alt:" > " reject--\n", > nop); > - reject--; > + if (!curr_static_id->operand[m] > + .matching_early_clobber) > + { > + reject--; > + curr_static_id->operand[m] > + .matching_early_clobber = 1; > + } > } > /* Otherwise we prefer no matching > alternatives because it gives more freedom > @@ -2948,15 +2954,11 @@ process_alt_operands (int only_alternative) > curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] > = last_conflict_j; > losers++; > - /* Early clobber was already reflected in REJECT. */ > - lra_assert (reject > 0); > if (lra_dump_file != NULL) > fprintf > (lra_dump_file, > " %d Conflict early clobber reload: reject--\n", > i); > - reject--; > - overall += LRA_LOSER_COST_FACTOR - 1; > } > else > { > @@ -2980,17 +2982,21 @@ process_alt_operands (int only_alternative) > } > curr_alt_win[i] = curr_alt_match_win[i] = false; > losers++; > - /* Early clobber was already reflected in REJECT. */ > - lra_assert (reject > 0); > if (lra_dump_file != NULL) > fprintf > (lra_dump_file, > " %d Matched conflict early clobber reloads: " > "reject--\n", > i); > + } > + /* Early clobber was already reflected in REJECT. */ > + if (!curr_static_id->operand[i].matching_early_clobber) > + { > + lra_assert (reject > 0); > reject--; > - overall += LRA_LOSER_COST_FACTOR - 1; > + curr_static_id->operand[i].matching_early_clobber = 1; > } > + overall += LRA_LOSER_COST_FACTOR - 1; > } > if (lra_dump_file != NULL) > fprintf (lra_dump_file, " > alt=%d,overall=%d,losers=%d,rld_nregs=%d\n",
The idea looks good to me FWIW, but you can't use curr_static_id for the state, since that's a static description of the .md pattern rather than data about this particular instance. Thanks, Richard