This is then transformed by subst_reloads to the final broken form:(insn 171 170 172 5 .../pr34330.c:17 (set (reg:SI 9 r9) (plus:SI (reg:SI 8 r8) (reg:SI 0 r0 [orig:243 ivtmp.11 ] [243]))) -1 (nil)) This is logically correct as r9 genuinely does contain the result of the substituted expression, but it does not satisfy the constraints. And here's where I get stuck. I don't know where in the code it's supposed to check that the code will be correct after the substitution. The (plus (plus ...) ...) rtl is generated by find_reloads_subreg_address using make_memloc and plus_constant, and it seems correct in itself.
This used to be 'handled' by reload register allocation which would use the same reload register for RELOAD_FOR_INPUT_ADDRESS as for RELOAD_FOR_INPADDR_ADDREESS if both are for the same operand. It is strange that you have two RELOAD_FOR_INPUT_ADDRESS reloads instead. Although, in terms of ensuring correctness, it would be saner if gen_reload would make sure it generates valid code even for unusual reload register allocations. Unfortunately, that'll require it to make a guess if a two-address add is required; you can scan the insn pattern for matching constraints, but that is somewhat hit-and-miss (obviously you can't use constrain_operands there unless you want to save / restore all the extraction data); you'll end up generating some unneeded register-register moves on some architectures. But you could make sure they get removed in postreload.
