ira_get_dup_out_num punted on operands that are matched to earlyclobber outputs:
/* It is better ignore an alternative with early clobber. */ else if (*str == '&') goto fail; But I'm not sure why this is the right thing to do. At this stage we've established that *all* alternatives of interest require the input to match the output, so (a) the earlyclobber can only affect other operands and (b) not tying the registers is bound to introduce a move The code was part of the initial commit and so isn't obviously related to a specific testcase. Also, I can imagine LRA makes a much better job of this situation than reload did. (Certainly SVE uses matched earlyclobbers extensively and I haven't seen any problems.) In case this turns out to regress something important: the main case that matters for SVE is the one in which all alternatives are earlyclobber. 2019-06-21 Richard Sandiford <richard.sandif...@arm.com> gcc/ * ira.c (ira_get_dup_out_num): Don't punt for earlyclobbers. Use recog_data to test for an output operand. Index: gcc/ira.c =================================================================== --- gcc/ira.c 2019-06-21 14:34:13.239653892 +0100 +++ gcc/ira.c 2019-06-21 14:34:15.947631377 +0100 @@ -1999,26 +1999,8 @@ ira_get_dup_out_num (int op_num, alterna } if (original == -1) goto fail; - dup = -1; - for (ignore_p = false, str = recog_data.constraints[original - '0']; - *str != 0; - str++) - if (ignore_p) - { - if (*str == ',') - ignore_p = false; - } - else if (*str == '#') - ignore_p = true; - else if (! ignore_p) - { - if (*str == '=') - dup = original - '0'; - /* It is better ignore an alternative with early clobber. */ - else if (*str == '&') - goto fail; - } - if (dup >= 0) + dup = original - '0'; + if (recog_data.operand_type[dup] == OP_OUT) return dup; fail: if (use_commut_op_p)