https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114184

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |uros at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, one way to fix this or work around that would be to
--- gcc/config/i386/i386-expand.cc.jj   2024-02-26 07:29:27.695974161 +0100
+++ gcc/config/i386/i386-expand.cc      2024-03-01 12:48:59.678574710 +0100
@@ -451,6 +451,12 @@ ix86_expand_move (machine_mode mode, rtx
          && GET_MODE (SUBREG_REG (op1)) == DImode
          && SUBREG_BYTE (op1) == 0)
        op1 = gen_rtx_ZERO_EXTEND (TImode, SUBREG_REG (op1));
+      /* As not all values in XFmode are representable in real_value,
+        we might be called with non-general_operand SUBREGs.  */
+      if (mode == XFmode
+         && !general_operand (op1, XFmode)
+         && can_create_pseudo_p ())
+       op1 = force_reg (XFmode, op1);
       break;
     }

Though, e.g. md.texi suggests against using force_reg in the mov optab (though,
perhaps it is meant just that it shouldn't be used during reload).
Of course, one could argue it is middle-end's fault for not honoring the mov
optab predicate, and that emit_move_insn_1's
  code = optab_handler (mov_optab, mode);
  if (code != CODE_FOR_nothing)
    return emit_insn (GEN_FCN (code) (x, y));
should verify the predicate there.  Changing that feels very risky in stage4 or
on release branches, moves are really quite special.  Or check it in
emit_move_insn callers where there are risks the predicates aren't satisfied
(though, there are almost 500 callers of that just in middle-end code).

Reply via email to