--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_double } */
+
+double a[2], b[2];
+
+void foo(double x, double y)
+{
+ double breakme1 = y + 3.;
+ double a1 = b[1] + 2.;
+ double breakme0 = x;
+ double a0 = b[0] + 1.;
+ a[0] = a0 * breakme0;
+ a[1] = a1 * breakme1;
+}
+
+/* We should vectorize the SLP opportunity starting from the
+ grouped store to a[] including the load from b[] at the
+ leaf even though the multiplication requires another
+ vector invariant to be built. */
+/* { dg-final { scan-tree-dump "transform load" "slp2" } } */
!= (oprnd_info->first_dt != vect_reduction_def))))
{
/* Try swapping operands if we got a mismatch. For BB
- vectorization only in case that will improve things. */
- if (i == commutative_op && !swapped)
+ vectorization only in case it will clearly improve things. */
+ if (i == commutative_op && !swapped
+ && (!is_a <bb_vec_info> (vinfo)
+ || (!vect_def_types_match ((*oprnds_info)[i+1]->first_dt,
+ dts[i+1])
+ && (vect_def_types_match (oprnd_info->first_dt,
+ dts[i+1])
+ || vect_def_types_match
+ ((*oprnds_info)[i+1]->first_dt, dts[i])))))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
continue;
}
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "Build SLP failed: different types\n");
- return 1;
+ if (is_a <bb_vec_info> (vinfo))
+ {
+ /* Now for commutative ops we should see whether we can
+ make the other operand matching. */
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "treating operand as external\n");
+ oprnd_info->first_dt = dt = vect_external_def;
+ }
+ else
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: different types\n");
+ return 1;
+ }
}
/* Make sure to demote the overall operand to external. */