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

Reply via email to