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