--- /dev/null
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_sizes_16B_8B } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+__attribute__ ((noipa))
+int f (int a[12], int b[12], int n)
+{
+#ifdef __arm__
+ a = __builtin_assume_aligned (a, 8);
+ b = __builtin_assume_aligned (b, 8);
+#else
+ a = __builtin_assume_aligned (a, 16);
+ b = __builtin_assume_aligned (b, 16);
+#endif
+ for (int i = 0; i < n; i++)
+ {
+ if (b[i] == 0)
+ return 0;
+ if (a[0] > b[i])
+ return 1;
+ }
+ return 2;
+}
+
+int main ()
+{
+ check_vect ();
+
+ int *a = 0;
+ int b[12] = {0};
+ return f (a, b, 10);
+}
+
+/* { dg-final { scan-tree-dump "not hoisting invariant load due to early break" "vect" } } */
--- /dev/null
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+__attribute__ ((noipa))
+int f (int a[12], int b[12], int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ if (b[i] == 0)
+ return 0;
+ if (a[0] > b[i])
+ return 1;
+ }
+ return 2;
+}
+
+int main ()
+{
+ check_vect ();
+
+ int *a = 0;
+ int b[12] = {0};
+ return f (a, b, 10);
+}
+
+/* { dg-final { scan-tree-dump-times "not hoisting invariant load due to early break" 0 "vect" { xfail *-*-* } } } */
--- /dev/null
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_sizes_16B_8B } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+__attribute__ ((noipa))
+int f (int a[12], int b[12], int n)
+{
+#ifdef __arm__
+ a = __builtin_assume_aligned (a, 8);
+ b = __builtin_assume_aligned (b, 8);
+#else
+ a = __builtin_assume_aligned (a, 16);
+ b = __builtin_assume_aligned (b, 16);
+#endif
+ for (int i = 0; i < n; i++)
+ {
+ if (a[0] > b[i])
+ return 0;
+ if (b[i] == 0)
+ return 1;
+ }
+ return 2;
+}
+
+int main ()
+{
+ check_vect ();
+
+ int a[12] = {1};
+ int b[12] = {0};
+ return f (a, b, 10);
+}
+
+/* { dg-final { scan-tree-dump-times "not hoisting invariant load due to early break" 0 "vect" } } */
--- /dev/null
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+__attribute__ ((noipa))
+int f (int a[12], int b[12], int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ if (a[0] > b[i])
+ return 0;
+ if (b[i] == 0)
+ return 0;
+ }
+ return 2;
+}
+
+int main ()
+{
+ check_vect ();
+
+ int a[12] = {1};
+ int b[12] = {0};
+ return f (a, b, 10);
+}
+
+/* { dg-final { scan-tree-dump-times "not hoisting invariant load due to early break" 0 "vect" } } */
transform time. */
bool hoist_p = (LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo)
&& !nested_in_vect_loop);
+
+ /* It is unsafe to hoist a conditional load over the conditions that make
+ it valid. When early break this means that any invariant load can't be
+ hoisted unless it's in the loop header or if we know something else has
+ verified the load is valid to do. Alignment peeling would do this
+ since getting through the prologue means the load was done at least
+ once and so the vector main body is free to hoist it. However today
+ GCC will hoist the load above the PFA loop. As such that makes it
+ still invalid and so we can't allow it today. */
+ auto stmt_bb
+ = gimple_bb (STMT_VINFO_STMT (
+ vect_orig_stmt (SLP_TREE_SCALAR_STMTS (slp_node)[0])));
+ if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
+ && !DR_SCALAR_KNOWN_BOUNDS (dr_info)
+ && stmt_bb != loop->header)
+ {
+ if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)
+ && dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not hoisting invariant load due to early break"
+ "constraints\n");
+ else if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "not hoisting invariant load due to early break"
+ "constraints\n");
+ hoist_p = false;
+ }
+
bool uniform_p = true;
for (stmt_vec_info sinfo : SLP_TREE_SCALAR_STMTS (slp_node))
{