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;

Reply via email to