https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61078
--- Comment #4 from Andreas Krebbel <krebbel at gcc dot gnu.org> --- While the patch fixes this particular case the problem appears to be more fundamental. The S/390 backend only considers GPR register pairs starting with an even register to be valid (REGNO_PAIR_OK in s390.h). However, thanks to our ABI we might encounter invalid pairs with hard regs during parameter passing. This used to be resolved by the call preparation code which loads the parameter into a pseudo first. That's why our move patterns are capable of dealing with overlapping register pairs. However, the other patterns aren't. In that case it was the negdi pattern but there might be similar issues with add, sub, ... . In this example the invalid register pair in the negdi pattern comes from combining the move which has been generated during call preparation (insn 18) with the negdi pattern: before combine: (insn 17 16 18 5 (parallel [ (set (reg:DI 49 [ D.1409 ]) (neg:DI (reg:DI 44 [ D.1409 ]))) (clobber (reg:CC 33 %cc)) ]) t.c:20 491 {*negdi2_31} (expr_list:REG_DEAD (reg:DI 44 [ D.1409 ]) (expr_list:REG_UNUSED (reg:CC 33 %cc) (nil)))) (insn 18 17 19 5 (set (reg:DI 3 %r3) (reg:DI 49 [ D.1409 ])) t.c:20 64 {*movdi_31} (expr_list:REG_DEAD (reg:DI 49 [ D.1409 ]) (nil))) after combine: (insn 18 17 19 5 (parallel [ (set (reg:DI 3 %r3) (neg:DI (reg:DI 44 [ D.1409 ]))) (clobber (reg:CC 33 %cc)) ]) t.c:20 491 {*negdi2_31} (expr_list:REG_UNUSED (reg:CC 33 %cc) (expr_list:REG_DEAD (reg:DI 44 [ D.1409 ]) (nil)))) r44 then is assigned to hard reg r2 creating the problematic overlap: (insn 18 20 19 5 (parallel [ (set (reg:DI 3 %r3) (neg:DI (reg:DI 2 %r2 [orig:44 D.1409 ] [44]))) (clobber (reg:CC 33 %cc)) ]) t.c:20 491 {*negdi2_31} (nil)) I'm not sure what the best way is to fix this. Instead of implementing splitters for all these cases the easiest might to mark the destination operands as early clobber in the split patterns. That way reload is forced to repair the situation.