Ugh, attached the wrong patch that included a hunk from the other one...
This is the correct one:
Regards
Robin
PR middle-end/125390
gcc/ChangeLog:
* expmed.cc (extract_bit_field_1): Guard int-mode punning.
---
gcc/expmed.cc | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index da1b5b63287..0efc247ddba 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -1839,7 +1839,14 @@ extract_bit_field_1 (rtx str_rtx, poly_uint64 bitsize,
poly_uint64 bitnum,
if (MEM_P (op0))
op0 = adjust_bitfield_address_size (op0, op0_mode.else_blk (),
0, MEM_SIZE (op0));
- else if (op0_mode.exists (&imode))
+ /* Vectors can be punned with large integer modes that might
+ not have corresponding mov<mode> insns. The usual route
+ is then through emit_move_multi_word, but that only works if
+ the source register can be split into words. */
+ else if (op0_mode.exists (&imode)
+ && (optab_handler (mov_optab, imode) != CODE_FOR_nothing
+ || operand_subword (gen_lowpart (imode, op0),
+ 1, 0, imode)))
{
op0 = gen_lowpart (imode, op0);
@@ -1854,6 +1861,7 @@ extract_bit_field_1 (rtx str_rtx, poly_uint64 bitsize,
poly_uint64 bitnum,
rtx mem = assign_stack_temp (GET_MODE (op0), size);
emit_move_insn (mem, op0);
op0 = adjust_bitfield_address_size (mem, BLKmode, 0, size);
+ op0_mode = opt_scalar_int_mode ();
}
}
--
2.54.0