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.)