This patch makes process_alt_operands check that the mode sizes are ordered, so that match_reload can validly treat them as subregs of one another.
2017-10-23 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * lra-constraints.c (process_alt_operands): Reject matched operands whose sizes aren't ordered. (match_reload): Refer to this check here. Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2017-10-23 17:20:47.003797985 +0100 +++ gcc/lra-constraints.c 2017-10-23 17:25:42.597708494 +0100 @@ -933,6 +933,8 @@ match_reload (signed char out, signed ch push_to_sequence (*before); if (inmode != outmode) { + /* process_alt_operands has already checked that the mode sizes + are ordered. */ if (partial_subreg_p (outmode, inmode)) { reg = new_in_reg @@ -2112,6 +2114,13 @@ process_alt_operands (int only_alternati len = 0; lra_assert (nop > m); + /* Reject matches if we don't know which operand is + bigger. This situation would arguably be a bug in + an .md pattern, but could also occur in a user asm. */ + if (!ordered_p (GET_MODE_SIZE (biggest_mode[m]), + GET_MODE_SIZE (biggest_mode[nop]))) + break; + this_alternative_matches = m; m_hregno = get_hard_regno (*curr_id->operand_loc[m], false); /* We are supposed to match a previous operand.