https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101188
Ulrich Weigand <uweigand at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |uweigand at gcc dot gnu.org --- Comment #12 from Ulrich Weigand <uweigand at gcc dot gnu.org> --- Sorry for not responding earlier, I've been out on vacation. I think your root cause analysis is correct. In this part of code: if (success) delete_insn (insn); changed |= success; insn = next; move2add_record_mode (reg); reg_offset[regno] = trunc_int_for_mode (added_offset + base_offset, mode); continue; the intent seems to be to manually update the move2add data structures to account for the effects of "next", because the default logic is now skipped for the "next" insn. That's why in particular the reg mode and offset are manually calculated. This manual logic however is really only correct if "next" is actually just a simple SET. Reading the comment before the whole loop: /* For simplicity, we only perform this optimization on straightforward SETs. */ makes me suspect the original author assumed that "next" is in fact a straightforward SET here as well. This is however not true due to behavior of the "single_set" extractor. (I'm wondering if "single_set" used to be defined differently back in the days?) Your fix does look correct to me as far as handling parallel CLOBBERs go. However, looking at "single_set", it seems there is yet another case: the extractor also accepts a parallel of two or more SETs, as long as all except one of those SETs have destinations that are dead. These cases would still not be handled correctly with your patch, I think. I'm wondering whether it is even worthwhile to attempt to cover those cases. Maybe a more straightforward fix would be to keep in line with the above-mentioned comment about "straightforward SETs" and just check for a single SET directly instead of using "single_set" here. Do you think this would miss any important optimizations?