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).