https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124271
--- Comment #3 from Hongtao Liu <liuhongt at gcc dot gnu.org> ---
(In reply to Hongtao Liu from comment #2)
> I think middle-end should simplify
>
> vect__15.12_21 = vect__4.11_22 & { 4294967295, 4294967295, 4294967295,
> 4294967295 };
> vect__12.8_25 = vect__6.7_26 & { 4294967295, 4294967295, 4294967295,
> 4294967295 };
> vect__16.13_18 = vect__15.12_21 * vect__12.8_25;
>
> to
>
> op1 = VIEW_CONVERT_EXPR <V8USI> vect__15.12_21;
> op2 = VIEW_CONVERT_EXPR <V8USI> vect__12.8_25;
> vect__16.13_18 = VEC_WIDEN_MULT_EVEN(op1, op2);
[liuhongt@gkel-spr-799574 gcc]$ git diff
diff --git a/gcc/match.pd b/gcc/match.pd
index 7f16fd4e081..dd8ecad51b7 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -436,6 +436,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ zeros; })
{ ones; } { zeros; })))))))))
+#if GIMPLE
+/* (x & lowhalf_mask) * (y & lowhalf_mask)
+ -> VEC_WIDEN_MULT_EVEN (VIEW_CONVERT (x), VIEW_CONVERT (y)). */
+(simplify
+ (mult (bit_and @0 VECTOR_CST@2)
+ (bit_and @1 @2))
+ (if (uniform_vector_p (@2)
+ && TYPE_VECTOR_SUBPARTS (type).is_constant ()
+ && TYPE_VECTOR_SUBPARTS (type).to_constant () > 1)
+ (with
+ {
+ tree elem = uniform_vector_p (@2);
+ unsigned int outer_prec = element_precision (TREE_TYPE (type));
+ unsigned int inner_prec = outer_prec / 2;
+ poly_uint64 outer_nelts = TYPE_VECTOR_SUBPARTS (type);
+ tree inner_scalar = build_nonstandard_integer_type (inner_prec, 1);
+ tree inner_type = build_vector_type (inner_scalar, outer_nelts * 2);
+ }
+ (if (wi::eq_p (wi::to_wide (elem), wi::mask (inner_prec, false,
outer_prec))
+ && optab_handler (vec_widen_umult_even_optab,
+ TYPE_MODE (inner_type)) != CODE_FOR_nothing)
+ (vec_widen_mult_even (view_convert:inner_type @0)
+ (view_convert:inner_type @1))))))
+#endif
+
(for cmp (gt ge lt le)
outp (convert convert negate negate)
outn (negate negate convert convert)
I'm testing this.