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

--- Comment #4 from Ulrich Weigand <uweigand at gcc dot gnu.org> ---
The ususal test in such scenarios involves reg_overlap_mentioned_p:

/* Nonzero if modifying X will affect IN.  [...]  */
int
reg_overlap_mentioned_p (const_rtx x, const_rtx in)

which also handles cases like where the modified register is used as a base
register in a MEM in the second operand (not sure whether this can happen on
your platform).

A condition along the lines of

 "!reg_overlap_mentioned_p (msp430_subreg (HImode, operands[0], SImode, 0),
                            msp430_subreg (HImode, operands[1], SImode, 2))
  && !reg_overlap_mentioned_p (msp430_subreg (HImode, operands[0], SImode, 0),
                               msp430_subreg (HImode, operands[2], SImode, 2))"

should probably catch all invalid cases (i.e. if modifying op3 will affect op7
and/or op8, the split is invalid).

Or, to avoid the duplicate msp430_subreg computation, you might simply instead
add a FAIL at the end of the split instructions:

  if (reg_overlap_mentioned_p (operands[3], operands[7])
      || reg_overlap_mentioned_p (operands[3], operands[8]))
    FAIL;

B.t.w. is there a particular reason why the target-specific msp430_subreg is
needed instead of the usual operand_subword?

As to your predicate question, msp430_nonsubreg_operand is defined as:
(define_predicate "msp430_nonsubreg_operand"
  (match_code "reg,mem"))
so it is true if and only if the operand is a REG or a MEM, which means it
would indeed reject SUBREGs.  (Of course a register operand can still *have*
subregs, it just cannot itself *be* a subreg.)

Again, it's not completely clear to me why this special predicate is needed in
the first place; it seems to be solely used in this one splitter.  (Maybe this
is related to some restriction in msp430_subreg, which goes back to the
question what *that* is needed instead of operand_subword, which ought to
handle all general-operand cases.)

Reply via email to