--- /dev/null
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-funswitch-loops" } */
+
+#include "tree-vect.h"
+
+typedef int type;
+typedef type Vec2[2];
+
+struct BytesVec {
+ type d[100];
+};
+
+__attribute__((noipa)) struct BytesVec
+buildVertexBufferData(const Vec2 *origVertices, bool needsZW,
+ unsigned paddingSize, unsigned long t) {
+ const unsigned vertexCount = t;
+ struct BytesVec data = (struct BytesVec){.d = {0}};
+ type *nextVertexPtr = data.d;
+
+ for (unsigned vertexIdx = 0u; vertexIdx < vertexCount; ++vertexIdx) {
+
+ if (vertexIdx > t)
+ __builtin_trap();
+ __builtin_memcpy(nextVertexPtr, &origVertices[vertexIdx],
+ 2 * sizeof(type));
+ nextVertexPtr += 2;
+
+ if (needsZW) {
+ nextVertexPtr += 2;
+ }
+
+ nextVertexPtr += paddingSize;
+ }
+
+ return data;
+}
+Vec2 origVertices[] = {
+ {0, 1}, {2, 3}, {4, 5}, {6, 7},
+ {8, 9}, {10, 11}, {12, 13}, {14, 15},
+ {16, 17}, {18, 19}, {20, 21}, {22, 23},
+ {24, 25}, {26, 27}, {27, 28}, {29, 30},
+};
+
+int main()
+{
+ check_vect ();
+ struct BytesVec vec
+ = buildVertexBufferData(origVertices, false, 0,
+ sizeof(origVertices) / sizeof(origVertices[0]));
+
+ int errors = 0;
+ for (unsigned i = 0; i < 100; i++) {
+ if (i / 2 < sizeof(origVertices) / sizeof(origVertices[0])) {
+ int ii = i;
+ int e = origVertices[ii / 2][ii % 2];
+ if (vec.d[i] != e)
+ errors++;
+ } else {
+ if (vec.d[i] != 0)
+ errors++;
+ }
+ }
+ if (errors)
+ __builtin_abort();
+ return 0;
+}
vec<stmt_vec_info> roots = vNULL;
vec<tree> remain = vNULL;
gphi *phi = as_a<gphi *> (STMT_VINFO_STMT (stmt_info));
- stmts.create (1);
tree def = gimple_phi_arg_def_from_edge (phi, latch_e);
stmt_vec_info lc_info = loop_vinfo->lookup_def (def);
- stmts.quick_push (vect_stmt_to_vectorize (lc_info));
- vect_build_slp_instance (vinfo, slp_inst_kind_reduc_group,
- stmts, roots, remain,
- max_tree_size, &limit,
- bst_map, NULL, force_single_lane);
+ if (lc_info)
+ {
+ stmts.create (1);
+ stmts.quick_push (vect_stmt_to_vectorize (lc_info));
+ vect_build_slp_instance (vinfo, slp_inst_kind_reduc_group,
+ stmts, roots, remain,
+ max_tree_size, &limit,
+ bst_map, NULL, force_single_lane);
+ }
/* When the latch def is from a different cycle this can only
be a induction. Build a simple instance for this.
??? We should be able to start discovery from the PHI
tem.quick_push (stmt_info);
if (!bst_map->get (tem))
{
- gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info)
- == vect_induction_def);
stmts.create (1);
stmts.quick_push (stmt_info);
vect_build_slp_instance (vinfo, slp_inst_kind_reduc_group,
}
}
- /* Check if it's an induction and multiple exits. In this case there will be
- a usage later on after peeling which is needed for the alternate exit. */
+ /* Check if it's a not live PHI and multiple exits. In this case
+ there will be a usage later on after peeling which is needed for the
+ alternate exit. */
if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
- && STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
+ && is_a <gphi *> (stmt)
+ && ((! VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))
+ && ! *live_p)
+ || STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def))
{
if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "vec_stmt_relevant_p: induction forced for "
- "early break.\n");
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vec_stmt_relevant_p: PHI forced live for "
+ "early break.\n");
LOOP_VINFO_EARLY_BREAKS_LIVE_IVS (loop_vinfo).safe_push (stmt_info);
*live_p = true;
-
}
if (*live_p && *relevant == vect_unused_in_scope
bb = bbs[i];
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ if (virtual_operand_p (gimple_phi_result (gsi_stmt (si))))
+ continue;
stmt_vec_info phi_info = loop_vinfo->lookup_stmt (gsi_stmt (si));
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location, "init: phi relevant? %G",