public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/tnfchris/heads/gcc-14-early-break)] testsuite: Add tests for early break vectorization
@ 2023-11-15 14:54 Tamar Christina
  0 siblings, 0 replies; only message in thread
From: Tamar Christina @ 2023-11-15 14:54 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:141d62bc73198935a90765284b282ebb53a83ec9

commit 141d62bc73198935a90765284b282ebb53a83ec9
Author: Tamar Christina <tamar.christina@arm.com>
Date:   Thu Nov 2 15:16:15 2023 +0000

    testsuite: Add tests for early break vectorization

Diff:
---
 gcc/doc/sourcebuild.texi                           |   4 +
 gcc/testsuite/g++.dg/vect/vect-early-break_1.cc    |  60 ++++++
 gcc/testsuite/g++.dg/vect/vect-early-break_2.cc    |  60 ++++++
 gcc/testsuite/g++.dg/vect/vect-early-break_3.cc    |  16 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c |  11 +
 .../gcc.dg/vect/vect-early-break-run_10.c          |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c |  11 +
 .../gcc.dg/vect/vect-early-break-template_1.c      |  47 +++++
 .../gcc.dg/vect/vect-early-break-template_2.c      |  50 +++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_1.c     |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_10.c    |  28 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_11.c    |  31 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_12.c    |  31 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_13.c    |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_14.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_15.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_16.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_17.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_18.c    |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_19.c    |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_2.c     |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_20.c    |  37 ++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_21.c    |  37 ++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_22.c    |  45 ++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_23.c    |  61 ++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_24.c    |  46 +++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_25.c    |  11 +
 gcc/testsuite/gcc.dg/vect/vect-early-break_26.c    |  44 ++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_27.c    |  18 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_28.c    |  15 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_29.c    |  16 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_3.c     |  20 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_30.c    |  28 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_31.c    |  29 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_32.c    |  29 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_33.c    |  28 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_34.c    |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_35.c    |  28 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_36.c    |  28 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_37.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_38.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_39.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_4.c     |  23 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_40.c    |  26 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_41.c    |  24 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_42.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_43.c    |  29 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_44.c    |  29 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_45.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_46.c    |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_47.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_48.c    |  13 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_49.c    |  24 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_5.c     |  24 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_50.c    |  17 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_51.c    |  25 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_52.c    |  20 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_53.c    |  17 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_54.c    |  29 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_55.c    |  28 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_56.c    | 101 +++++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_57.c    |  30 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_58.c    |  18 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_59.c    |  17 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_6.c     |  26 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_60.c    |  17 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_61.c    |  17 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_62.c    |  20 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_63.c    |  28 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_64.c    |  17 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_65.c    |  19 ++
 gcc/testsuite/gcc.dg/vect/vect-early-break_66.c    |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_67.c    |  41 ++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_68.c    |  41 ++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_69.c    |  76 +++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_7.c     |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_70.c    |  68 ++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_71.c    |  68 ++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_72.c    | 147 +++++++++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_73.c    |  68 ++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_74.c    | 161 +++++++++++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_75.c    | 230 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_76.c    | 165 +++++++++++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_8.c     |  27 +++
 gcc/testsuite/gcc.dg/vect/vect-early-break_9.c     |  27 +++
 gcc/testsuite/gcc.target/aarch64/opt_mismatch_1.c  |   6 +
 gcc/testsuite/gcc.target/aarch64/opt_mismatch_2.c  |   6 +
 gcc/testsuite/gcc.target/aarch64/opt_mismatch_3.c  |   5 +
 .../aarch64/vect-early-break-cbranch_1.c           | 124 +++++++++++
 gcc/testsuite/lib/target-supports.exp              |  11 +
 97 files changed, 3359 insertions(+)

diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 51ca735ebeb..9f967855dde 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1636,6 +1636,10 @@ Target supports hardware vectors of @code{float} when
 @option{-funsafe-math-optimizations} is not in effect.
 This implies @code{vect_float}.
 
+@item vect_early_break
+Target supports hardware vectorization of loops with early breaks.
+This requires an implementation of the cbranch optab for vectors.
+
 @item vect_int
 Target supports hardware vectors of @code{int}.
 
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc
new file mode 100644
index 00000000000..810d990e3ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+void fancy_abort(char *, int, const char *) __attribute__((__noreturn__));
+template <unsigned N, typename> struct poly_int_pod { int coeffs[N]; };
+template <unsigned N, typename> class poly_int : public poly_int_pod<N, int> {
+public:
+  template <typename Ca> poly_int &operator+=(const poly_int_pod<N, Ca> &);
+};
+template <unsigned N, typename C>
+template <typename Ca>
+poly_int<N, C> &poly_int<N, C>::operator+=(const poly_int_pod<N, Ca> &a) {
+  for (int i = 0; i < N; i++)
+    this->coeffs[i] += a.coeffs[i];
+  return *this;
+}
+template <unsigned N, typename Ca, typename Cb>
+poly_int<N, long> exact_div(poly_int_pod<N, Ca>, Cb) {
+  poly_int<N, long> r;
+  return r;
+}
+struct vec_prefix {
+  unsigned m_num;
+};
+struct vl_ptr;
+struct va_heap {
+  typedef vl_ptr default_layout;
+};
+template <typename, typename A, typename = typename A::default_layout>
+struct vec;
+template <typename T, typename A> struct vec<T, A, int> {
+  T &operator[](unsigned);
+  vec_prefix m_vecpfx;
+  T m_vecdata[];
+};
+template <typename T, typename A> T &vec<T, A, int>::operator[](unsigned ix) {
+  m_vecpfx.m_num ? fancy_abort("", 9, __FUNCTION__), 0 : 0;
+  return m_vecdata[ix];
+}
+template <typename T> struct vec<T, va_heap> {
+  T &operator[](unsigned ix) { return m_vec[ix]; }
+  vec<T, va_heap, int> m_vec;
+};
+class auto_vec : public vec<poly_int<2, long>, va_heap> {};
+template <typename> class vector_builder : public auto_vec {};
+class int_vector_builder : public vector_builder<int> {
+public:
+  int_vector_builder(poly_int<2, long>, int, int);
+};
+bool vect_grouped_store_supported() {
+  int i;
+  poly_int<2, long> nelt;
+  int_vector_builder sel(nelt, 2, 3);
+  for (i = 0; i < 6; i++)
+    sel[i] += exact_div(nelt, 2);
+}
+
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc
new file mode 100644
index 00000000000..810d990e3ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+void fancy_abort(char *, int, const char *) __attribute__((__noreturn__));
+template <unsigned N, typename> struct poly_int_pod { int coeffs[N]; };
+template <unsigned N, typename> class poly_int : public poly_int_pod<N, int> {
+public:
+  template <typename Ca> poly_int &operator+=(const poly_int_pod<N, Ca> &);
+};
+template <unsigned N, typename C>
+template <typename Ca>
+poly_int<N, C> &poly_int<N, C>::operator+=(const poly_int_pod<N, Ca> &a) {
+  for (int i = 0; i < N; i++)
+    this->coeffs[i] += a.coeffs[i];
+  return *this;
+}
+template <unsigned N, typename Ca, typename Cb>
+poly_int<N, long> exact_div(poly_int_pod<N, Ca>, Cb) {
+  poly_int<N, long> r;
+  return r;
+}
+struct vec_prefix {
+  unsigned m_num;
+};
+struct vl_ptr;
+struct va_heap {
+  typedef vl_ptr default_layout;
+};
+template <typename, typename A, typename = typename A::default_layout>
+struct vec;
+template <typename T, typename A> struct vec<T, A, int> {
+  T &operator[](unsigned);
+  vec_prefix m_vecpfx;
+  T m_vecdata[];
+};
+template <typename T, typename A> T &vec<T, A, int>::operator[](unsigned ix) {
+  m_vecpfx.m_num ? fancy_abort("", 9, __FUNCTION__), 0 : 0;
+  return m_vecdata[ix];
+}
+template <typename T> struct vec<T, va_heap> {
+  T &operator[](unsigned ix) { return m_vec[ix]; }
+  vec<T, va_heap, int> m_vec;
+};
+class auto_vec : public vec<poly_int<2, long>, va_heap> {};
+template <typename> class vector_builder : public auto_vec {};
+class int_vector_builder : public vector_builder<int> {
+public:
+  int_vector_builder(poly_int<2, long>, int, int);
+};
+bool vect_grouped_store_supported() {
+  int i;
+  poly_int<2, long> nelt;
+  int_vector_builder sel(nelt, 2, 3);
+  for (i = 0; i < 6; i++)
+    sel[i] += exact_div(nelt, 2);
+}
+
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc
new file mode 100644
index 00000000000..a12e5ca434b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+int aarch64_advsimd_valid_immediate_hs_val32;
+bool aarch64_advsimd_valid_immediate_hs() {
+  for (int shift = 0; shift < 32; shift += 8)
+    if (aarch64_advsimd_valid_immediate_hs_val32 & shift)
+      return aarch64_advsimd_valid_immediate_hs_val32;
+  for (;;)
+    ;
+}
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c
new file mode 100644
index 00000000000..2495b36a72e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 803
+#define P 0
+#include "vect-early-break-template_1.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c
new file mode 100644
index 00000000000..9bcd7f7e57e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 800
+#define P 799
+#include "vect-early-break-template_2.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c
new file mode 100644
index 00000000000..63f63101a46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 803
+#define P 802
+#include "vect-early-break-template_1.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c
new file mode 100644
index 00000000000..626b95e9b85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 803
+#define P 5
+#include "vect-early-break-template_1.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c
new file mode 100644
index 00000000000..7e0e6426120
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 803
+#define P 278
+#include "vect-early-break-template_1.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c
new file mode 100644
index 00000000000..242cf486f9c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 800
+#define P 799
+#include "vect-early-break-template_1.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c
new file mode 100644
index 00000000000..9fe7136b721
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 803
+#define P 0
+#include "vect-early-break-template_2.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c
new file mode 100644
index 00000000000..02f93d77dba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 803
+#define P 802
+#include "vect-early-break-template_2.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c
new file mode 100644
index 00000000000..a6149254656
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 803
+#define P 5
+#include "vect-early-break-template_2.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c
new file mode 100644
index 00000000000..94e2b9c3014
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast -save-temps" } */
+
+#define N 803
+#define P 278
+#include "vect-early-break-template_2.c"
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-template_1.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-template_1.c
new file mode 100644
index 00000000000..af70a8e2a5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-template_1.c
@@ -0,0 +1,47 @@
+#ifndef N
+#define N 803
+#endif
+
+#ifndef P
+#define P 0
+#endif
+
+unsigned vect_a[N] = {0};
+unsigned vect_b[N] = {0};
+  
+__attribute__((noipa, noinline))
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+extern void abort ();
+
+int main ()
+{
+
+  int x = 1;
+  int idx = P;
+  vect_a[idx] = x + 1;
+
+  test4(x);
+
+  if (vect_b[idx] != (x + idx))
+    abort ();
+
+  if (vect_a[idx] != x + 1)
+    abort ();
+
+  if (idx > 0 && vect_a[idx-1] != x)
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-template_2.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-template_2.c
new file mode 100644
index 00000000000..d0f924d9044
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-template_2.c
@@ -0,0 +1,50 @@
+#ifndef N
+#define N 803
+#endif
+
+#ifndef P
+#define P 0
+#endif
+
+unsigned vect_a[N] = {0};
+unsigned vect_b[N] = {0};
+  
+__attribute__((noipa, noinline))
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return i;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+extern void abort ();
+
+int main ()
+{
+
+  int x = 1;
+  int idx = P;
+  vect_a[idx] = x + 1;
+
+  unsigned res = test4(x);
+
+  if (res != idx)
+    abort ();
+
+  if (vect_b[idx] != (x + idx))
+    abort ();
+
+  if (vect_a[idx] != x + 1)
+    abort ();
+
+  if (idx > 0 && vect_a[idx-1] != x)
+    abort ();
+
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_1.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_1.c
new file mode 100644
index 00000000000..51e7d6489b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_10.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_10.c
new file mode 100644
index 00000000000..9e4ad176320
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_10.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x,int y, int z)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+ }
+
+ ret = x + y * z;
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_11.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_11.c
new file mode 100644
index 00000000000..a613dd9909f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_11.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x, int y)
+{
+ unsigned ret = 0;
+for (int o = 0; o < y; o++)
+{
+ ret += o;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+}
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_12.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_12.c
new file mode 100644
index 00000000000..cc10f3238f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_12.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x, int y)
+{
+ unsigned ret = 0;
+for (int o = 0; o < y; o++)
+{
+ ret += o;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return vect_a[i];
+   vect_a[i] = x;
+   
+ }
+}
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_13.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_13.c
new file mode 100644
index 00000000000..6967b7395ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_13.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return vect_a[i] * x;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_14.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_14.c
new file mode 100644
index 00000000000..03cce5cf6ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_14.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#define N 803
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+int test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return i;
+   vect_a[i] += x * vect_b[i];
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_15.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_15.c
new file mode 100644
index 00000000000..dec6872e111
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_15.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#define N 803
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+int test4(unsigned x)
+{
+ int ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return i;
+   vect_a[i] += x * vect_b[i];
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_16.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_16.c
new file mode 100644
index 00000000000..30812d12a39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_16.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#define N 1024
+unsigned vect_a[N];
+unsigned vect_b[N];
+ 
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return vect_a[i];
+   vect_a[i] = x;
+   ret += vect_a[i] + vect_b[i];
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_17.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_17.c
new file mode 100644
index 00000000000..510227a1843
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_17.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#define N 1024
+unsigned vect_a[N];
+unsigned vect_b[N];
+ 
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return vect_a[i];
+   vect_a[i] = x;
+   ret = vect_a[i] + vect_b[i];
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_18.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_18.c
new file mode 100644
index 00000000000..1372f79242b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_18.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i+=2)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_19.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_19.c
new file mode 100644
index 00000000000..677487f7da4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_19.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x, unsigned step)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i+=step)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_2.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_2.c
new file mode 100644
index 00000000000..7268f6ae248
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <complex.h>
+
+#define N 1024
+complex double vect_a[N];
+complex double vect_b[N];
+  
+complex double test4(complex double x)
+{
+ complex double ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] += x + i;
+   if (vect_a[i] == x)
+     return i;
+   vect_a[i] += x * vect_b[i];
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_20.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_20.c
new file mode 100644
index 00000000000..ed41377d1c9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_20.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <stdbool.h>
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_b[N];
+struct testStruct {
+ long e;
+ long f;
+ bool a : 1;
+ bool b : 1;
+ int c : 14;
+ int d;
+};
+struct testStruct vect_a[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i].a > x)
+     return true;
+   vect_a[i].e = x;
+ }
+ return ret;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_21.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_21.c
new file mode 100644
index 00000000000..6415e4951cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_21.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <stdbool.h>
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_b[N];
+struct testStruct {
+ long e;
+ long f;
+ bool a : 1;
+ bool b : 1;
+ int c : 14;
+ int d;
+};
+struct testStruct vect_a[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i].a)
+     return true;
+   vect_a[i].e = x;
+ }
+ return ret;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_22.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_22.c
new file mode 100644
index 00000000000..2ca189899fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_22.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_perm } */
+/* { dg-require-effective-target vect_early_break } */
+
+#include "tree-vect.h"
+
+void __attribute__((noipa))
+foo (int * __restrict__ a, short * __restrict__ b, int * __restrict__ c)
+{
+  int t1 = *c;
+  int t2 = *c;
+  for (int i = 0; i < 64; i+=2)
+    {
+      b[i] = a[i] - t1;
+      t1 = a[i];
+      b[i+1] = a[i+1] - t2;
+      t2 = a[i+1];
+    }
+}
+
+int a[64];
+short b[64];
+
+int
+main ()
+{
+  check_vect ();
+  for (int i = 0; i < 64; ++i)
+    {
+      a[i] = i;
+      __asm__ volatile ("" ::: "memory");
+    }
+  int c = 7;
+  foo (a, b, &c);
+  for (int i = 2; i < 64; i+=2)
+    if (b[i] != a[i] - a[i-2]
+	|| b[i+1] != a[i+1] - a[i-1])
+      abort ();
+  if (b[0] != -7 || b[1] != -6)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_23.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_23.c
new file mode 100644
index 00000000000..f3298656d5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_23.c
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#define N 200
+#define M 4
+
+typedef signed char sc;
+typedef unsigned char uc;
+typedef signed short ss;
+typedef unsigned short us;
+typedef int si;
+typedef unsigned int ui;
+typedef signed long long sll;
+typedef unsigned long long ull;
+
+#define FOR_EACH_TYPE(M) \
+  M (sc) M (uc) \
+  M (ss) M (us) \
+  M (si) M (ui) \
+  M (sll) M (ull) \
+  M (float) M (double)
+
+#define TEST_VALUE(I) ((I) * 17 / 2)
+
+#define ADD_TEST(TYPE)				\
+  void __attribute__((noinline, noclone))	\
+  test_##TYPE (TYPE *a, TYPE *b)		\
+  {						\
+    for (int i = 0; i < N; i += 2)		\
+      {						\
+	a[i + 0] = b[i + 0] + 2;		\
+	a[i + 1] = b[i + 1] + 3;		\
+      }						\
+  }
+
+#define DO_TEST(TYPE)					\
+  for (int j = 1; j < M; ++j)				\
+    {							\
+      TYPE a[N + M];					\
+      for (int i = 0; i < N + M; ++i)			\
+	a[i] = TEST_VALUE (i);				\
+      test_##TYPE (a + j, a);				\
+      for (int i = 0; i < N; i += 2)			\
+	if (a[i + j] != (TYPE) (a[i] + 2)		\
+	    || a[i + j + 1] != (TYPE) (a[i + 1] + 3))	\
+	  __builtin_abort ();				\
+    }
+
+FOR_EACH_TYPE (ADD_TEST)
+
+int
+main (void)
+{
+  FOR_EACH_TYPE (DO_TEST)
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump {flags: [^\n]*ARBITRARY\n} "vect" { target vect_int } } } */
+/* { dg-final { scan-tree-dump "using an address-based overlap test" "vect" } } */
+/* { dg-final { scan-tree-dump-not "using an index-based" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_24.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_24.c
new file mode 100644
index 00000000000..7b4b2ffb9b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_24.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_double } */
+/* { dg-require-effective-target vect_early_break } */
+
+#include "tree-vect.h"
+
+extern void abort (void);
+void __attribute__((noinline,noclone))
+foo (double *b, double *d, double *f)
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    {
+      d[2*i] = 2. * d[2*i];
+      d[2*i+1] = 4. * d[2*i+1];
+      b[i] = d[2*i] - 1.;
+      f[i] = d[2*i+1] + 2.;
+    }
+}
+int main()
+{
+  double b[1024], d[2*1024], f[1024];
+  int i;
+
+  check_vect ();
+
+  for (i = 0; i < 2*1024; i++)
+    d[i] = 1.;
+  foo (b, d, f);
+  for (i = 0; i < 1024; i+= 2)
+    {
+      if (d[2*i] != 2.)
+	abort ();
+      if (d[2*i+1] != 4.)
+	abort ();
+    }
+  for (i = 0; i < 1024; i++)
+    {
+      if (b[i] != 1.)
+	abort ();
+      if (f[i] != 6.)
+	abort ();
+    }
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_25.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_25.c
new file mode 100644
index 00000000000..8db9b60128b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_25.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* Disabling epilogues until we find a better way to deal with scans.  */
+/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
+/* { dg-require-effective-target vect_int } */
+
+#include "vect-peel-1-src.c"
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 14 "vect" { target { { vect_element_align } && { vect_aligned_arrays } } xfail { ! vect_unaligned_possible } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_element_align_preferred } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_26.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_26.c
new file mode 100644
index 00000000000..5905847cc0b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_26.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_perm } */
+
+#include "tree-vect.h"
+
+void __attribute__((noipa))
+foo (int * __restrict__ a, int * __restrict__ b, int * __restrict__ c)
+{
+  int t1 = *c;
+  int t2 = *c;
+  for (int i = 0; i < 64; i+=2)
+    {
+      b[i] = a[i] - t1;
+      t1 = a[i];
+      b[i+1] = a[i+1] - t2;
+      t2 = a[i+1];
+    }
+}
+
+int a[64], b[64];
+
+int
+main ()
+{
+  check_vect ();
+  for (int i = 0; i < 64; ++i)
+    {
+      a[i] = i;
+      __asm__ volatile ("" ::: "memory");
+    }
+  int c = 7;
+  foo (a, b, &c);
+  for (int i = 2; i < 64; i+=2)
+    if (b[i] != a[i] - a[i-2]
+	|| b[i+1] != a[i+1] - a[i-1])
+      abort ();
+  if (b[0] != -7 || b[1] != -6)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_27.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_27.c
new file mode 100644
index 00000000000..d0cfbb01667
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_27.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+void abort ();
+int a[128];
+
+int main ()
+{
+  int i;
+  for (i = 1; i < 128; i++)
+    if (a[i] != i%4 + 1)
+      abort ();
+  if (a[0] != 5)
+    abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_28.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_28.c
new file mode 100644
index 00000000000..a5eae81f3f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_28.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+void abort ();
+int a[128];
+int main ()
+{
+  int i;
+  for (i = 1; i < 128; i++)
+    if (a[i] != i%4 + 1)
+    abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_29.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_29.c
new file mode 100644
index 00000000000..75d87e99e93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_29.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+int in[100];
+int out[100 * 2];
+
+int main (void)
+{
+  if (out[0] != in[100 - 1])
+  for (int i = 1; i <= 100; ++i)
+    if (out[i] != 2)
+      __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_3.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_3.c
new file mode 100644
index 00000000000..3c6d28bd2d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" } } */
+
+unsigned test4(char x, char *vect, int n)
+{  
+ unsigned ret = 0;
+ for (int i = 0; i < n; i++)
+ {
+   if (vect[i] > x)
+     return 1;
+
+   vect[i] = x;
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_30.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_30.c
new file mode 100644
index 00000000000..e09d883db84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_30.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+int x[100];
+int choose1(int);
+int choose2();
+void consume(int);
+void f() {
+    for (int i = 0; i < 100; ++i) {
+        if (x[i] == 11) {
+            if (choose1(i))
+                goto A;
+            else
+                goto B;
+        }
+    }
+    if (choose2())
+        goto B;
+A:
+    for (int i = 0; i < 100; ++i)
+        consume(i);
+B:
+    for (int i = 0; i < 100; ++i)
+        consume(i * i);
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_31.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_31.c
new file mode 100644
index 00000000000..6001523162d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_31.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 1025
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+ 
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return vect_a[i];
+   vect_a[i] = x;
+   ret += vect_a[i] + vect_b[i];
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_32.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_32.c
new file mode 100644
index 00000000000..73abddc267a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_32.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 1024
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+ 
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return vect_a[i];
+   vect_a[i] = x;
+   ret = vect_a[i] + vect_b[i];
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_33.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_33.c
new file mode 100644
index 00000000000..29b37f70939
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_33.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a2[N];
+unsigned vect_a1[N];
+unsigned vect_b[N];
+
+unsigned test4(unsigned x, int z)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a1[i]*2 > x)
+     {
+       for (int y = 0; y < z; y++)
+	 vect_a2 [y] *= vect_a1[i];
+       break;
+     }
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 2 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_34.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_34.c
new file mode 100644
index 00000000000..2c48e3cee33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_34.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+
+unsigned vect_a[N] __attribute__ ((aligned (4)));;
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ 
+ for (int i = 1; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i]*2 > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_35.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_35.c
new file mode 100644
index 00000000000..3442484a811
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_35.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a2[N];
+unsigned vect_a1[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a1[i]*2 > x)
+     break;
+   vect_a1[i] = x;
+   if (vect_a2[i]*4 > x)
+     break;
+   vect_a2[i] = x*x;
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_36.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_36.c
new file mode 100644
index 00000000000..027766c51f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_36.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a2[N];
+unsigned vect_a1[N];
+unsigned vect_b[N];
+
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a1[i]*2 > x)
+     break;
+   vect_a1[i] = x;
+   if (vect_a2[i]*4 > x)
+     return i;
+   vect_a2[i] = x*x;
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_37.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_37.c
new file mode 100644
index 00000000000..8d363120898
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_37.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 4
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i]*2 != x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_38.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_38.c
new file mode 100644
index 00000000000..226d55d7194
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_38.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i+=2)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i]*2 > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_39.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_39.c
new file mode 100644
index 00000000000..554e6ec8431
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_39.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x, unsigned n)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i+= (N % 4))
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i]*2 > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_4.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_4.c
new file mode 100644
index 00000000000..216c56faf33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_4.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" } } */
+
+#define N 1024
+unsigned vect[N];
+
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   if (i > 16 && vect[i] > x)
+     break;
+
+   vect[i] = x;
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c
new file mode 100644
index 00000000000..f2ae372cd96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i*=3)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i]*2 > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+/* SCEV can't currently analyze this loop bounds.  */
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail *-*-* } } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_41.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_41.c
new file mode 100644
index 00000000000..6ad9b3f17dd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_41.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+#pragma GCC novector
+#pragma GCC unroll 4
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] += vect_a[i] + x;
+ }
+ return ret;
+}
+
+/* novector should have blocked vectorization.  */
+/* { dg-final { scan-tree-dump-not "vectorized \d loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_42.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_42.c
new file mode 100644
index 00000000000..88652f01595
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_42.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 800
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i]*2 > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_43.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_43.c
new file mode 100644
index 00000000000..8e3aab6e042
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_43.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 802
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i+=2)
+ {
+   vect_b[i] = x + i;
+   vect_b[i+1] = x + i + 1;
+   if (vect_a[i]*2 > x)
+     break;
+   if (vect_a[i+1]*2 > x)
+     break;
+   vect_a[i] = x;
+   vect_a[i+1] = x;
+   
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_44.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_44.c
new file mode 100644
index 00000000000..8e3aab6e042
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_44.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 802
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i+=2)
+ {
+   vect_b[i] = x + i;
+   vect_b[i+1] = x + i + 1;
+   if (vect_a[i]*2 > x)
+     break;
+   if (vect_a[i+1]*2 > x)
+     break;
+   vect_a[i] = x;
+   vect_a[i+1] = x;
+   
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_45.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_45.c
new file mode 100644
index 00000000000..cf1cb903b31
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_45.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i]*2 > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_46.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_46.c
new file mode 100644
index 00000000000..356d971e3a1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_46.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_float } */
+
+#include <complex.h>
+
+#define N 1024
+complex double vect_a[N];
+complex double vect_b[N];
+  
+complex double test4(complex double x)
+{
+ complex double ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] += x + i;
+   if (vect_a[i] == x)
+     return i;
+   vect_a[i] += x * vect_b[i];
+   
+ }
+ return ret;
+}
+
+/* At -O2 we can't currently vectorize this because of the libcalls not being
+   lowered.  */
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect"  { xfail *-*-* } } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_47.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_47.c
new file mode 100644
index 00000000000..d1cca4a33a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_47.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_float } */
+
+void abort ();
+
+float results1[16] = {192.00,240.00,288.00,336.00,384.00,432.00,480.00,528.00,0.00};
+float results2[16] = {0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,54.00,120.00,198.00,288.00,390.00,504.00,630.00};
+float a[16] = {0};
+float e[16] = {0};
+float b[16] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+int main1 ()
+{
+  int i;
+  for (i=0; i<16; i++)
+    {
+      if (a[i] != results1[i] || e[i] != results2[i])
+        abort();
+    }
+
+  if (a[i+3] != b[i-1])
+    abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_48.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_48.c
new file mode 100644
index 00000000000..77043182860
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_48.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+int main (void)
+{
+  signed char a[50], b[50], c[50];
+  for (int i = 0; i < 50; ++i)
+    if (a[i] != ((((signed int) -1 < 0 ? -126 : 4) + ((signed int) -1 < 0 ? -101 : 26) + i * 9 + 0) >> 1))
+      __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_49.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_49.c
new file mode 100644
index 00000000000..bc9e5bf899a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_49.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+void abort();
+struct foostr {
+  _Complex short f1;
+  _Complex short f2;
+};
+struct foostr a[16] __attribute__ ((__aligned__(16))) = {};
+struct foostr c[16] __attribute__ ((__aligned__(16)));
+struct foostr res[16] = {};
+void
+foo (void)
+{
+  int i;
+  for (i = 0; i < 16; i++)
+    {
+      if (c[i].f1 != res[i].f1)
+ abort ();
+      if (c[i].f2 != res[i].f2)
+ abort ();
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_5.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_5.c
new file mode 100644
index 00000000000..4a36d6979db
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_5.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#define N 1024
+unsigned vect_a[N];
+unsigned vect_b[N];
+ 
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] = x + i;
+   if (vect_a[i] > x)
+     return vect_a[i];
+   vect_a[i] = x;
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_50.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_50.c
new file mode 100644
index 00000000000..e2ac8283091
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_50.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_float } */
+
+extern void abort();
+float a[1024], b[1024], c[1024], d[1024];
+_Bool k[1024];
+
+int main ()
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    if (k[i] != ((i % 3) == 0 && ((i / 9) % 3) == 0))
+      abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_51.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_51.c
new file mode 100644
index 00000000000..af036079457
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_51.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+int x_in[32];
+int x_out_a[32], x_out_b[32];
+int c[16] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2};
+int a[16 +1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024};
+int b[16 +1] = {17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
+
+void foo ()
+{
+  int j, i, x;
+  int curr_a, flag, next_a, curr_b, next_b;
+    {
+      for (i = 0; i < 16; i++)
+        {
+          next_b = b[i+1];
+          curr_b = flag ? next_b : curr_b;
+        }
+      x_out_b[j] = curr_b;
+    }
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c
new file mode 100644
index 00000000000..85cdfe0938e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+void abort();
+int main1 (short X)
+{
+  unsigned char a[128];
+  unsigned short b[128];
+  unsigned int c[128];
+  short myX = X;
+  int i;
+  for (i = 0; i < 128; i++)
+    {
+      if (a[i] != (unsigned char)myX || b[i] != myX || c[i] != (unsigned int)myX++)
+        abort ();
+    }
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c
new file mode 100644
index 00000000000..f066ddcfe45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+void abort ();
+int a[64], b[64];
+int main ()
+{
+  int c = 7;
+  for (int i = 1; i < 64; ++i)
+    if (b[i] != a[i] - a[i-1])
+      abort ();
+  if (b[0] != -7)
+    abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_54.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_54.c
new file mode 100644
index 00000000000..9d0dd8dc5fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_54.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ unsigned tmp[N];
+ for (int i = 0; i < N; i++)
+ {
+   tmp[i] = x + i;
+   vect_b[i] = tmp[i];
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_55.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_55.c
new file mode 100644
index 00000000000..073cbdf614f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_55.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   volatile unsigned tmp = x + i;
+   vect_b[i] = tmp;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_56.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_56.c
new file mode 100644
index 00000000000..9086e885f56
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_56.c
@@ -0,0 +1,101 @@
+/* Disabling epilogues until we find a better way to deal with scans.  */
+/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-add-options bind_pic_locally } */
+/* { dg-require-effective-target vect_early_break } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 32
+
+unsigned short sa[N];
+unsigned short sc[N] = {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,28,29,30,31};
+unsigned short sb[N] = {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,28,29,30,31};
+unsigned int ia[N];
+unsigned int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,
+	       0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+unsigned int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,
+	       0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+/* Current peeling-for-alignment scheme will consider the 'sa[i+7]'
+   access for peeling, and therefore will examine the option of
+   using a peeling factor = VF-7%VF. This will result in a peeling factor 1,
+   which will also align the access to 'ia[i+3]', and the loop could be
+   vectorized on all targets that support unaligned loads.
+   Without cost model on targets that support misaligned stores, no peeling
+   will be applied since we want to keep the four loads aligned.  */
+
+__attribute__ ((noinline))
+int main1 ()
+{
+  int i;
+  int n = N - 7;
+
+  /* Multiple types with different sizes, used in independent
+     copmutations. Vectorizable.  */
+  for (i = 0; i < n; i++)
+    {
+      sa[i+7] = sb[i] + sc[i];
+      ia[i+3] = ib[i] + ic[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < n; i++)
+    {
+      if (sa[i+7] != sb[i] + sc[i] || ia[i+3] != ib[i] + ic[i])
+	abort ();
+    }
+
+  return 0;
+}
+
+/* Current peeling-for-alignment scheme will consider the 'ia[i+3]'
+   access for peeling, and therefore will examine the option of
+   using a peeling factor = VF-3%VF. This will result in a peeling factor
+   1 if VF=4,2. This will not align the access to 'sa[i+3]', for which we 
+   need to peel 5,1 iterations for VF=4,2 respectively, so the loop can not 
+   be vectorized.  However, 'ia[i+3]' also gets aligned if we peel 5
+   iterations, so the loop is vectorizable on all targets that support
+   unaligned loads.
+   Without cost model on targets that support misaligned stores, no peeling
+   will be applied since we want to keep the four loads aligned.  */
+
+__attribute__ ((noinline))
+int main2 ()
+{
+  int i;
+  int n = N-3;
+
+  /* Multiple types with different sizes, used in independent
+     copmutations. Vectorizable.  */
+  for (i = 0; i < n; i++)
+    {
+      ia[i+3] = ib[i] + ic[i];
+      sa[i+3] = sb[i] + sc[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < n; i++)
+    {
+      if (sa[i+3] != sb[i] + sc[i] || ia[i+3] != ib[i] + ic[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  main1 ();
+  main2 ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 2 "vect" { xfail { vect_early_break && { ! vect_hw_misalign } } } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_57.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_57.c
new file mode 100644
index 00000000000..be4a0c74260
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_57.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+void abort ();
+
+unsigned short sa[32];
+unsigned short sc[32] = {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,28,29,30,31};
+unsigned short sb[32] = {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,28,29,30,31};
+unsigned int ia[32];
+unsigned int ic[32] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,
+        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+unsigned int ib[32] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,
+        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+int main2 (int n)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    {
+      if (sa[i+3] != sb[i] + sc[i] || ia[i+3] != ib[i] + ic[i])
+        abort ();
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_58.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_58.c
new file mode 100644
index 00000000000..84ea627b492
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_58.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_float } */
+
+extern void abort();
+float a[1024], b[1024], c[1024], d[1024];
+_Bool k[1024];
+
+int main ()
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    if (k[i] != ((i % 3) == 0))
+      abort ();
+}
+
+/* Pattern didn't match inside gcond.  */
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_59.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_59.c
new file mode 100644
index 00000000000..193f14e8a4d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_59.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_float } */
+
+extern void abort();
+float a[1024], b[1024], c[1024], d[1024];
+_Bool k[1024];
+
+int main ()
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    if (k[i] != (i == 0))
+      abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_6.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_6.c
new file mode 100644
index 00000000000..63ff6662f5c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_6.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#define N 1024
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < (N/2); i+=2)
+ {
+   vect_b[i] = x + i;
+   vect_b[i+1] = x + i+1;
+   if (vect_a[i] > x || vect_a[i+1] > x)
+     break;
+   vect_a[i] += x * vect_b[i];
+   vect_a[i+1] += x * vect_b[i+1]; 
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_60.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_60.c
new file mode 100644
index 00000000000..4c523d4e714
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_60.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_float } */
+
+extern void abort();
+float a[1024], b[1024], c[1024], d[1024];
+_Bool k[1024];
+
+int main ()
+{
+  char i;
+  for (i = 0; i < 1024; i++)
+    if (k[i] != (i == 0))
+      abort ();
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c
new file mode 100644
index 00000000000..a0c34f71e3b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_float } */
+
+typedef float real_t;
+__attribute__((aligned(64))) real_t a[32000], b[32000], c[32000];
+real_t s482()
+{
+    for (int nl = 0; nl < 10000; nl++) {
+        for (int i = 0; i < 32000; i++) {
+            a[i] += b[i] * c[i];
+            if (c[i] > b[i]) break;
+        }
+    }
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_62.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_62.c
new file mode 100644
index 00000000000..9b94772934f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_62.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+int a, b;
+int e() {
+  int d, c;
+  d = 0;
+  for (; d < b; d++)
+    a = 0;
+  d = 0;
+  for (; d < b; d++)
+    if (d)
+      c++;
+  for (;;)
+    if (c)
+      break;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_63.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_63.c
new file mode 100644
index 00000000000..11f7fb8547b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_63.c
@@ -0,0 +1,28 @@
+/* Disabling epilogues until we find a better way to deal with scans.  */
+/* { dg-do compile } */
+/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
+/* { dg-require-effective-target vect_long } */
+/* { dg-require-effective-target vect_shift } */
+/* { dg-additional-options "-fno-tree-scev-cprop" } */
+
+/* Statement used outside the loop.
+   NOTE: SCEV disabled to ensure the live operation is not removed before
+   vectorization.  */
+__attribute__ ((noinline)) int
+liveloop (int start, int n, int *x, int *y)
+{
+  int i = start;
+  int j;
+  int ret;
+
+  for (j = 0; j < n; ++j)
+    {
+      i += 1;
+      x[j] = i;
+      ret = y[j];
+    }
+  return ret;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vec_stmt_relevant_p: stmt live but not relevant" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c
new file mode 100644
index 00000000000..32b9c087feb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fdump-tree-vect-all" } */
+
+int d(unsigned);
+
+void a() {
+  char b[8];
+  unsigned c = 0;
+  while (c < 7 && b[c])
+    ++c;
+  if (d(c))
+    return;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_partial_vectors } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_65.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_65.c
new file mode 100644
index 00000000000..577c4e96ba9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_65.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-options "-Ofast -fno-vect-cost-model -fdump-tree-vect-details" } */
+
+enum a { b };
+
+struct {
+  enum a c;
+} d[10], *e;
+
+void f() {
+  int g;
+  for (g = 0, e = d; g < sizeof(1); g++, e++)
+    if (e->c)
+      return;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_66.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_66.c
new file mode 100644
index 00000000000..b56a4f755f8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_66.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+int a[0];
+int b;
+
+void g();
+
+void f() {
+  int d, e;
+  for (; e; e++) {
+    int c;
+    switch (b)
+    case '9': {
+      for (; d < 1; d++)
+        if (a[d])
+          c = 1;
+      break;
+    case '<':
+      g();
+      c = 0;
+    }
+      while (c)
+        ;
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c
new file mode 100644
index 00000000000..80f23d1e243
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+
+
+int main()
+{
+  int var6 = -1267827473;
+  do {
+      ++var6;
+      double s1_115[4], s2_108[4];
+      int var8 = -161498264;
+      do {
+	  ++var8;
+	  int var12 = 1260960076;
+	  for (; var12 <= 1260960080; ++var12) {
+	      int var13 = 1960990937;
+	      do {
+		  ++var13;
+		  int var14 = 2128638723;
+		  for (; var14 <= 2128638728; ++var14) {
+		      int var22 = -1141190839;
+		      do {
+			  ++var22;
+			  if (s2_108 > s1_115) {
+			      int var23 = -890798748;
+			      do {
+				  long long e_119[4];
+			      } while (var23 <= -890798746);
+			  }
+		      } while (var22 <= -1141190829);
+		  }
+	      } while (var13 <= 1960990946);
+	  }
+      } while (var8 <= -161498254);
+  } while (var6 <= -1267827462);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c
new file mode 100644
index 00000000000..c9a8298a8b5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 800
+#endif
+unsigned vect_a1[N];
+unsigned vect_b1[N];
+unsigned vect_c1[N];
+unsigned vect_d1[N];
+  
+unsigned vect_a2[N];
+unsigned vect_b2[N];
+unsigned vect_c2[N];
+unsigned vect_d2[N];
+
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b1[i] += x + i;
+   vect_c1[i] += x + i;
+   vect_d1[i] += x + i;
+   if (vect_a1[i]*2 != x)
+     break;
+   vect_a1[i] = x;
+
+   vect_b2[i] += x + i;
+   vect_c2[i] += x + i;
+   vect_d2[i] += x + i;
+   if (vect_a2[i]*2 != x)
+     break;
+   vect_a2[i] = x;
+
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c
new file mode 100644
index 00000000000..f99de8e1f06
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c
@@ -0,0 +1,76 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+#include <limits.h>
+#include <assert.h>
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}									\
+									\
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_ffs (ints[i]) != my_ffs (ints[i]))
+	abort ();
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	abort ();
+    }
+
+  exit (0);
+}
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_7.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_7.c
new file mode 100644
index 00000000000..10fd8b42952
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_7.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <complex.h>
+
+#define N 1024
+complex double vect_a[N];
+complex double vect_b[N];
+  
+complex double test4(complex double x)
+{
+ complex double ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] += x + i;
+   if (vect_a[i] == x)
+     break;
+   vect_a[i] += x * vect_b[i];
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c
new file mode 100644
index 00000000000..9073130197e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c
@@ -0,0 +1,68 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c
new file mode 100644
index 00000000000..c6d6eb526e6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c
@@ -0,0 +1,68 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_ffs (ints[i]) != my_ffs (ints[i]))
+	abort ();
+    }
+
+  exit (0);
+}
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c
new file mode 100644
index 00000000000..0f0a1f30ab9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c
@@ -0,0 +1,147 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ctz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i;								\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_ctz (ints[i]) != my_ctz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c
new file mode 100644
index 00000000000..5cce21cd16a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c
@@ -0,0 +1,68 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+}
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c
new file mode 100644
index 00000000000..83676da2888
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c
@@ -0,0 +1,161 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
+    abort ();								
+
+#if BITSIZEOF_INT == 32
+  TEST(0x00000000UL,);
+  TEST(0x00000001UL,);
+  TEST(0x80000000UL,);
+  TEST(0x40000000UL,);
+  TEST(0x00010000UL,);
+  TEST(0x00008000UL,);
+  TEST(0xa5a5a5a5UL,);
+  TEST(0x5a5a5a5aUL,);
+  TEST(0xcafe0000UL,);
+  TEST(0x00cafe00UL,);
+  TEST(0x0000cafeUL,);
+  TEST(0xffffffffUL,);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c
new file mode 100644
index 00000000000..cc1ce4cf298
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c
@@ -0,0 +1,230 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}									\
+									\
+int my_ctz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i;								\
+}									\
+									\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}									\
+									\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}									\
+									\
+__attribute__((noinline)) \
+int my_popcount##suffix(type x) {					\
+    int i;								\
+    int count = 0;							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << i))					\
+	    count++;							\
+    return count;							\
+}									\
+									\
+__attribute__((noinline)) \
+int my_parity##suffix(type x) {						\
+    int i;								\
+    int count = 0;							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << i))					\
+	    count++;							\
+    return count & 1;							\
+}
+
+MAKE_FUNS (ll, unsigned long long);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+#pragma GCC novector
+  for (i = 0; i < N(longlongs); i++)
+    {
+      if (__builtin_ffsll (longlongs[i]) != my_ffsll (longlongs[i]))
+	abort ();
+      if (longlongs[i] != 0
+	  && __builtin_clzll (longlongs[i]) != my_clzll (longlongs[i]))
+	abort ();
+      if (longlongs[i] != 0
+	  && __builtin_ctzll (longlongs[i]) != my_ctzll (longlongs[i]))
+	abort ();
+      if (__builtin_clrsbll (longlongs[i]) != my_clrsbll (longlongs[i]))
+	abort ();
+      if (__builtin_popcountll (longlongs[i]) != my_popcountll (longlongs[i]))
+	abort ();
+      if (__builtin_parityll (longlongs[i]) != my_parityll (longlongs[i]))
+	abort ();
+    }
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_ffs##suffix (x) != my_ffs##suffix (x))			\
+    abort ();								\
+
+#if BITSIZEOF_LONG_LONG == 64
+  TEST(0x0000000000000000ULL, ll);
+  TEST(0x0000000000000001ULL, ll);
+  TEST(0x8000000000000000ULL, ll);
+  TEST(0x0000000000000002ULL, ll);
+  TEST(0x4000000000000000ULL, ll);
+  TEST(0x0000000100000000ULL, ll);
+  TEST(0x0000000080000000ULL, ll);
+  TEST(0xa5a5a5a5a5a5a5a5ULL, ll);
+  TEST(0x5a5a5a5a5a5a5a5aULL, ll);
+  TEST(0xcafecafe00000000ULL, ll);
+  TEST(0x0000cafecafe0000ULL, ll);
+  TEST(0x00000000cafecafeULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c
new file mode 100644
index 00000000000..adba337b101
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c
@@ -0,0 +1,165 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}									\
+									\
+
+MAKE_FUNS (, unsigned);
+MAKE_FUNS (ll, unsigned long long);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_clrsb (ints[i]) != my_clrsb (ints[i]))
+	abort ();
+    }
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
+    abort ();								
+
+#if BITSIZEOF_LONG_LONG == 64
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_8.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_8.c
new file mode 100644
index 00000000000..ae706b2952c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_8.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <complex.h>
+
+#define N 1024
+char vect_a[N];
+char vect_b[N];
+  
+char test4(char x, char * restrict res)
+{
+ char ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] += x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] += x * vect_b[i];
+   res[i] *= vect_b[i];
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_9.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_9.c
new file mode 100644
index 00000000000..4e8b5bdea5f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_9.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_a[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/opt_mismatch_1.c b/gcc/testsuite/gcc.target/aarch64/opt_mismatch_1.c
new file mode 100644
index 00000000000..571aec0ccfd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/opt_mismatch_1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=armv8.3-a -mcpu=neoverse-n1" } */
+
+#include <arm_neon.h>
+
+/* { dg-warning "switch ‘-mcpu=neoverse-n1’ conflicts with ‘-march=armv8.3-a’ switch and would result in options \\+fp16\\+dotprod\\+profile\\+nopauth" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/opt_mismatch_2.c b/gcc/testsuite/gcc.target/aarch64/opt_mismatch_2.c
new file mode 100644
index 00000000000..cee42c84c4f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/opt_mismatch_2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=armv8-a+sve -mcpu=neoverse-n1" } */
+
+#include <arm_neon.h>
+
+/* { dg-warning "switch ‘-mcpu=neoverse-n1’ conflicts with ‘-march=armv8-a+sve’ switch and would result in options \\+lse\\+rcpc\\+rdma\\+dotprod\\+profile\\+nosve" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/opt_mismatch_3.c b/gcc/testsuite/gcc.target/aarch64/opt_mismatch_3.c
new file mode 100644
index 00000000000..0a05b98eedb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/opt_mismatch_3.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=armv8-a -mcpu=neovese-n1 -Wpedentic -Werror" } */
+
+#include <arm_neon.h>
+
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_1.c b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_1.c
new file mode 100644
index 00000000000..c0363c37872
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_1.c
@@ -0,0 +1,124 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
+
+#pragma GCC target "+nosve"
+
+#define N 640
+int a[N] = {0};
+int b[N] = {0};
+
+
+/*
+** f1:
+**	...
+**	cmgt	v[0-9]+.4s, v[0-9]+.4s, #0
+**	umaxp	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+**	fmov	x[0-9]+, d[0-9]+
+**	cbnz	x[0-9]+, \.L[0-9]+
+**	...
+*/
+void f1 ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      b[i] += a[i];
+      if (a[i] > 0)
+	break;
+    }
+}
+
+/*
+** f2:
+**	...
+**	cmge	v[0-9]+.4s, v[0-9]+.4s, #0
+**	umaxp	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+**	fmov	x[0-9]+, d[0-9]+
+**	cbnz	x[0-9]+, \.L[0-9]+
+**	...
+*/
+void f2 ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      b[i] += a[i];
+      if (a[i] >= 0)
+	break;
+    }
+}
+
+/*
+** f3:
+**	...
+**	cmeq	v[0-9]+.4s, v[0-9]+.4s, #0
+**	umaxp	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+**	fmov	x[0-9]+, d[0-9]+
+**	cbnz	x[0-9]+, \.L[0-9]+
+**	...
+*/
+void f3 ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      b[i] += a[i];
+      if (a[i] == 0)
+	break;
+    }
+}
+
+/*
+** f4:
+**	...
+**	cmtst	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+**	umaxp	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+**	fmov	x[0-9]+, d[0-9]+
+**	cbnz	x[0-9]+, \.L[0-9]+
+**	...
+*/
+void f4 ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      b[i] += a[i];
+      if (a[i] != 0)
+	break;
+    }
+}
+
+/*
+** f5:
+**	...
+**	cmlt	v[0-9]+.4s, v[0-9]+.4s, #0
+**	umaxp	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+**	fmov	x[0-9]+, d[0-9]+
+**	cbnz	x[0-9]+, \.L[0-9]+
+**	...
+*/
+void f5 ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      b[i] += a[i];
+      if (a[i] < 0)
+	break;
+    }
+}
+
+/*
+** f6:
+**	...
+**	cmle	v[0-9]+.4s, v[0-9]+.4s, #0
+**	umaxp	v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
+**	fmov	x[0-9]+, d[0-9]+
+**	cbnz	x[0-9]+, \.L[0-9]+
+**	...
+*/
+void f6 ()
+{
+  for (int i = 0; i < N; i++)
+    {
+      b[i] += a[i];
+      if (a[i] <= 0)
+	break;
+    }
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 6ef53e07a45..051eb48ca69 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4069,6 +4069,17 @@ proc check_effective_target_vect_int { } {
 	}}]
 }
 
+# Return 1 if the target supports hardware vectorization of early breaks,
+# 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_early_break { } {
+    return [check_cached_effective_target_indexed vect_early_break {
+      expr {
+	[istarget aarch64*-*-*]
+	}}]
+}
 # Return 1 if the target supports hardware vectorization of complex additions of
 # byte, 0 otherwise.
 #

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-15 14:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-15 14:54 [gcc(refs/users/tnfchris/heads/gcc-14-early-break)] testsuite: Add tests for early break vectorization Tamar Christina

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).