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

--- Comment #6 from Xi Ruoyao <xry111 at gcc dot gnu.org> ---
I'm testing this:

diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index e813cf9b215..0dbee1b53e5 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -439,6 +439,7 @@ expand_vector_broadcast (machine_mode vmode, rtx op)
   rtvec vec;

   gcc_checking_assert (VECTOR_MODE_P (vmode));
+  gcc_checking_assert (GET_MODE_INNER (vmode) == GET_MODE (op));

   if (valid_for_const_vector_p (vmode, op))
     return gen_const_vec_duplicate (vmode, op);
@@ -1629,15 +1630,25 @@ expand_binop (machine_mode mode, optab binoptab, rtx
op0, rtx op1,
       if (otheroptab
          && (icode = optab_handler (otheroptab, mode)) != CODE_FOR_nothing)
        {
-         /* The scalar may have been extended to be too wide.  Truncate
-            it back to the proper size to fit in the broadcast vector.  */
+         /* The scalar may be wider or narrower than the vector element.
+            Truncate or extend it to the proper size to fit in the
+            broadcast vector.  */
          scalar_mode inner_mode = GET_MODE_INNER (mode);
-         if (!CONST_INT_P (op1)
-             && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
-                 > GET_MODE_BITSIZE (inner_mode)))
-           op1 = force_reg (inner_mode,
-                            simplify_gen_unary (TRUNCATE, inner_mode, op1,
-                                                GET_MODE (op1)));
+         if (!CONST_INT_P (op1))
+           {
+             auto mode1 = as_a <scalar_int_mode> (GET_MODE (op1));
+             int size1 = GET_MODE_BITSIZE (mode1);
+             int inner_size = GET_MODE_BITSIZE (inner_mode);
+
+             if (size1 != inner_size)
+               {
+                 auto unary = size1 > inner_size ? TRUNCATE : ZERO_EXTEND;
+                 op1 = force_reg (inner_mode,
+                                  simplify_gen_unary (unary, inner_mode,
+                                                      op1, mode1));
+               }
+           }
+
          rtx vop1 = expand_vector_broadcast (mode, op1);
          if (vop1)
            {

Reply via email to