Andreas Krebbel wrote:
when cse replaces registers in an insn it tries to avoid calls to
validate_change, what causes trouble in some situations.
From validate_canon_reg:
/* If replacing pseudo with hard reg or vice versa, ensure the
insn remains valid. Likewise if the insn has MATCH_DUPs. */
if (insn != 0 && new != 0
&& REG_P (new) && REG_P (*xloc)
&& (((REGNO (new) < FIRST_PSEUDO_REGISTER)
!= (REGNO (*xloc) < FIRST_PSEUDO_REGISTER))
|| GET_MODE (new) != GET_MODE (*xloc)
|| (insn_code = recog_memoized (insn)) < 0
|| insn_data[insn_code].n_dups > 0))
validate_change (insn, xloc, new, 1);
else
*xloc = new;
Hard to say whether the backend's use of the insn condition is valid or
not. The documentation could be clearer. I'm tempted to say that if
two operands must be identical at all times, match_dup is the way to
tell the compiler about it rather than sneaking the requirement in
behind its back through an insn condition. But then, this kind of thing
does seem pervasive in the x86 backend, and the code above is an
eyesore. On those grounds, please submit a change to fix both places in
cse.c. If we run into further problems of this kind, we'll have to
rethink whether such patterns are valid.
Bernd