https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94614
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- #1 0x0000000000cecacc in emit_move_multi_word (mode=E_TImode, x=0x7ffff69f66c0, y=0x7ffff69f64e0) at /space/rguenther/src/gcc/gcc/expr.c:3716 (gdb) p debug_rtx (x) (subreg:TI (reg/v:DI 113 [ res ]) 0) $3 = void (gdb) p debug_rtx (y) (reg/v:TI 115 [ v ]) $4 = void so this is another part not expecting the "invalid" source writing outside the bounds of a register. We have /* Do not generate code for a move if it would come entirely from the undefined bits of a paradoxical subreg. */ if (undefined_operand_subword_p (y, i)) continue; but lack the same check for the x parts. The following fixes it: diff --git a/gcc/expr.c b/gcc/expr.c index b97c217e86d..dfbeae71518 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -3692,6 +3692,11 @@ emit_move_multi_word (machine_mode mode, rtx x, rtx y) need_clobber = false; for (i = 0; i < CEIL (mode_size, UNITS_PER_WORD); i++) { + /* Do not generate code for a move if it would go entirely + to the non-existing bits of a paradoxical subreg. */ + if (undefined_operand_subword_p (x, i)) + continue; + rtx xpart = operand_subword (x, i, 1, mode); rtx ypart;