[2/21] middle-end testsuite: Add tests for early break vectorization
Checks
Commit Message
Hi All,
This adds new test to check for all the early break functionality.
It includes a number of codegen and runtime tests checking the values at
different needles in the array.
They also check the values on different array sizes and peeling positions,
datatypes, VL, ncopies and every other variant I could think of.
Additionally it also contains reduced cases from issues found running over
various codebases.
Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
Also regtested with:
-march=armv8.3-a+sve
-march=armv8.3-a+nosve
-march=armv9-a
Ok for master?
Thanks,
Tamar
gcc/ChangeLog:
* doc/sourcebuild.texi: Document it.
gcc/testsuite/ChangeLog:
* lib/target-supports.exp:
* g++.dg/vect/vect-early-break_1.cc: New test.
* g++.dg/vect/vect-early-break_2.cc: New test.
* g++.dg/vect/vect-early-break_3.cc: New test.
* gcc.dg/vect/vect-early-break-run_1.c: New test.
* gcc.dg/vect/vect-early-break-run_10.c: New test.
* gcc.dg/vect/vect-early-break-run_2.c: New test.
* gcc.dg/vect/vect-early-break-run_3.c: New test.
* gcc.dg/vect/vect-early-break-run_4.c: New test.
* gcc.dg/vect/vect-early-break-run_5.c: New test.
* gcc.dg/vect/vect-early-break-run_6.c: New test.
* gcc.dg/vect/vect-early-break-run_7.c: New test.
* gcc.dg/vect/vect-early-break-run_8.c: New test.
* gcc.dg/vect/vect-early-break-run_9.c: New test.
* gcc.dg/vect/vect-early-break-template_1.c: New test.
* gcc.dg/vect/vect-early-break-template_2.c: New test.
* gcc.dg/vect/vect-early-break_1.c: New test.
* gcc.dg/vect/vect-early-break_10.c: New test.
* gcc.dg/vect/vect-early-break_11.c: New test.
* gcc.dg/vect/vect-early-break_12.c: New test.
* gcc.dg/vect/vect-early-break_13.c: New test.
* gcc.dg/vect/vect-early-break_14.c: New test.
* gcc.dg/vect/vect-early-break_15.c: New test.
* gcc.dg/vect/vect-early-break_16.c: New test.
* gcc.dg/vect/vect-early-break_17.c: New test.
* gcc.dg/vect/vect-early-break_18.c: New test.
* gcc.dg/vect/vect-early-break_19.c: New test.
* gcc.dg/vect/vect-early-break_2.c: New test.
* gcc.dg/vect/vect-early-break_20.c: New test.
* gcc.dg/vect/vect-early-break_21.c: New test.
* gcc.dg/vect/vect-early-break_22.c: New test.
* gcc.dg/vect/vect-early-break_23.c: New test.
* gcc.dg/vect/vect-early-break_24.c: New test.
* gcc.dg/vect/vect-early-break_25.c: New test.
* gcc.dg/vect/vect-early-break_26.c: New test.
* gcc.dg/vect/vect-early-break_27.c: New test.
* gcc.dg/vect/vect-early-break_28.c: New test.
* gcc.dg/vect/vect-early-break_29.c: New test.
* gcc.dg/vect/vect-early-break_3.c: New test.
* gcc.dg/vect/vect-early-break_30.c: New test.
* gcc.dg/vect/vect-early-break_31.c: New test.
* gcc.dg/vect/vect-early-break_32.c: New test.
* gcc.dg/vect/vect-early-break_33.c: New test.
* gcc.dg/vect/vect-early-break_34.c: New test.
* gcc.dg/vect/vect-early-break_35.c: New test.
* gcc.dg/vect/vect-early-break_36.c: New test.
* gcc.dg/vect/vect-early-break_37.c: New test.
* gcc.dg/vect/vect-early-break_38.c: New test.
* gcc.dg/vect/vect-early-break_39.c: New test.
* gcc.dg/vect/vect-early-break_4.c: New test.
* gcc.dg/vect/vect-early-break_40.c: New test.
* gcc.dg/vect/vect-early-break_41.c: New test.
* gcc.dg/vect/vect-early-break_42.c: New test.
* gcc.dg/vect/vect-early-break_43.c: New test.
* gcc.dg/vect/vect-early-break_44.c: New test.
* gcc.dg/vect/vect-early-break_45.c: New test.
* gcc.dg/vect/vect-early-break_46.c: New test.
* gcc.dg/vect/vect-early-break_47.c: New test.
* gcc.dg/vect/vect-early-break_48.c: New test.
* gcc.dg/vect/vect-early-break_49.c: New test.
* gcc.dg/vect/vect-early-break_5.c: New test.
* gcc.dg/vect/vect-early-break_50.c: New test.
* gcc.dg/vect/vect-early-break_51.c: New test.
* gcc.dg/vect/vect-early-break_52.c: New test.
* gcc.dg/vect/vect-early-break_53.c: New test.
* gcc.dg/vect/vect-early-break_54.c: New test.
* gcc.dg/vect/vect-early-break_55.c: New test.
* gcc.dg/vect/vect-early-break_56.c: New test.
* gcc.dg/vect/vect-early-break_57.c: New test.
* gcc.dg/vect/vect-early-break_58.c: New test.
* gcc.dg/vect/vect-early-break_59.c: New test.
* gcc.dg/vect/vect-early-break_6.c: New test.
* gcc.dg/vect/vect-early-break_60.c: New test.
* gcc.dg/vect/vect-early-break_61.c: New test.
* gcc.dg/vect/vect-early-break_62.c: New test.
* gcc.dg/vect/vect-early-break_63.c: New test.
* gcc.dg/vect/vect-early-break_64.c: New test.
* gcc.dg/vect/vect-early-break_65.c: New test.
* gcc.dg/vect/vect-early-break_66.c: New test.
* gcc.dg/vect/vect-early-break_67.c: New test.
* gcc.dg/vect/vect-early-break_68.c: New test.
* gcc.dg/vect/vect-early-break_69.c: New test.
* gcc.dg/vect/vect-early-break_7.c: New test.
* gcc.dg/vect/vect-early-break_70.c: New test.
* gcc.dg/vect/vect-early-break_71.c: New test.
* gcc.dg/vect/vect-early-break_72.c: New test.
* gcc.dg/vect/vect-early-break_73.c: New test.
* gcc.dg/vect/vect-early-break_74.c: New test.
* gcc.dg/vect/vect-early-break_75.c: New test.
* gcc.dg/vect/vect-early-break_76.c: New test.
* gcc.dg/vect/vect-early-break_8.c: New test.
* gcc.dg/vect/vect-early-break_9.c: New test.
* gcc.target/aarch64/opt_mismatch_1.c: New test.
* gcc.target/aarch64/opt_mismatch_2.c: New test.
* gcc.target/aarch64/opt_mismatch_3.c: New test.
* gcc.target/aarch64/vect-early-break-cbranch_1.c: New test.
--- inline copy of patch --
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index c20af31c64237baff70f8781b1dc47f4d1a48aa9..4c351335f2bec9c6bb6856bd38d9132da7447c13 100644
--
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index c20af31c64237baff70f8781b1dc47f4d1a48aa9..4c351335f2bec9c6bb6856bd38d9132da7447c13 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 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
--- /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 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
--- /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 0000000000000000000000000000000000000000..a12e5ca434b2ac37c03dbaa12273fd8e5aa2018c
--- /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 0000000000000000000000000000000000000000..2495b36a72eae94cb7abc4a0d17a5c979fd78083
--- /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 0000000000000000000000000000000000000000..9bcd7f7e57ef9a1d4649d18569b3406050e54603
--- /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 0000000000000000000000000000000000000000..63f63101a467909f328be7f3acbc5bcb721967ff
--- /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 0000000000000000000000000000000000000000..626b95e9b8517081d41d794e9e0264d6301c8589
--- /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 0000000000000000000000000000000000000000..7e0e6426120551152a7bd800c15d9ed6ab15bada
--- /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 0000000000000000000000000000000000000000..242cf486f9c40055df0aef5fd238d1aff7a7c7da
--- /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 0000000000000000000000000000000000000000..9fe7136b7213a463ca6573c60476b7c8f531ddcb
--- /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 0000000000000000000000000000000000000000..02f93d77dba31b938f6fd9e8c7f5e4acde4aeec9
--- /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 0000000000000000000000000000000000000000..a614925465606b54c638221ffb95a5e8d3bee797
--- /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 0000000000000000000000000000000000000000..94e2b9c301456eda8f9ad7eaa67604563f0afee7
--- /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 0000000000000000000000000000000000000000..af70a8e2a5a9dc9756edb5580f2de02ddcc95de9
--- /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 0000000000000000000000000000000000000000..d0f924d904437e71567d27cc1f1089e5607dca0d
--- /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 0000000000000000000000000000000000000000..51e7d6489b99c25b9b4b3d1c839f98562b6d4dd7
--- /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 0000000000000000000000000000000000000000..9e4ad1763202dfdab3ed7961ead5114fcc61a11b
--- /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 0000000000000000000000000000000000000000..a613dd9909fb09278dd92a81a24ef854994a9890
--- /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 0000000000000000000000000000000000000000..cc10f3238f1cb8e1307e024a3ebcb5c25a39d1b2
--- /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 0000000000000000000000000000000000000000..6967b7395ed7c19e38a436d6edcfe7c1580c7113
--- /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 0000000000000000000000000000000000000000..03cce5cf6cadecb520b46be666bf608e3bc6a511
--- /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 0000000000000000000000000000000000000000..dec6872e1115ff66695f5a500ffa7ca01c0f8d3a
--- /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 0000000000000000000000000000000000000000..30812d12a39bd94b4b8a3aade6512b162697d659
--- /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 0000000000000000000000000000000000000000..510227a18435a8e47c5a754580180c6d340c0823
--- /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 0000000000000000000000000000000000000000..1372f79242b250cabbab29757b62cbc28a9064a8
--- /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 0000000000000000000000000000000000000000..677487f7da496a8f467d8c529575d47ff22c6a31
--- /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 0000000000000000000000000000000000000000..7268f6ae2485d0274fd85ea53cc1e44ef4b84d5c
--- /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 0000000000000000000000000000000000000000..ed41377d1c979bf14e0a4e80401831c09ffa463f
--- /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 0000000000000000000000000000000000000000..6415e4951cb9ef70e56b7cfb1db3d3151368666d
--- /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 0000000000000000000000000000000000000000..2ca189899fb6bd6dfdf63de7729f54e3bee06ba0
--- /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 0000000000000000000000000000000000000000..f3298656d5d67fd137c4029a96a2f9c1bae344ce
--- /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 0000000000000000000000000000000000000000..7b4b2ffb9b75db6d5ca7e313d1f18d9b51f5b566
--- /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 0000000000000000000000000000000000000000..8db9b60128b9e21529ae73ea1902afb8fa327112
--- /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 0000000000000000000000000000000000000000..5905847cc0b6b393dde728a9f4ecb44c8ab42da5
--- /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 0000000000000000000000000000000000000000..d0cfbb01667fa016d72828d098aeaa252c2c9318
--- /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 0000000000000000000000000000000000000000..a5eae81f3f5f5b7d92082f1588c6453a71e205cc
--- /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 0000000000000000000000000000000000000000..75d87e99e939fab61f751be025ca0398fa5bd078
--- /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 0000000000000000000000000000000000000000..3c6d28bd2d6e6e794146baf89e43c3b70293b7d9
--- /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 0000000000000000000000000000000000000000..e09d883db84685679e73867d83aba9900563983d
--- /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 0000000000000000000000000000000000000000..6001523162d24d140af73143435f25bcd3a217c8
--- /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 0000000000000000000000000000000000000000..73abddc267a0170c2d97a7e7c680525721455f22
--- /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 0000000000000000000000000000000000000000..29b37f70939af7fa9409edd3a1e29f718c959706
--- /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 0000000000000000000000000000000000000000..2c48e3cee33fc37f45ef59c2bbaff7bc5a76b460
--- /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 0000000000000000000000000000000000000000..3442484a81161f9bd09e30bc268fbcf66a899902
--- /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 0000000000000000000000000000000000000000..027766c51f508eab157db365a1653f3e92dcac10
--- /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 0000000000000000000000000000000000000000..8d363120898232bb1402b9cf7b4b83b38a10505b
--- /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 0000000000000000000000000000000000000000..226d55d7194ca3f676ab52976fea25b7e335bbec
--- /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 0000000000000000000000000000000000000000..554e6ec84318c600c87982ad6ef0f90e8b47af01
--- /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 0000000000000000000000000000000000000000..216c56faf330449bf1969b7e51ff1e94270dc861
--- /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 0000000000000000000000000000000000000000..f2ae372cd96e74cc06254937c2b8fa69ecdedf09
--- /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 0000000000000000000000000000000000000000..6ad9b3f17ddb953bfbf614e9331fa81f565b262f
--- /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 0000000000000000000000000000000000000000..88652f01595cb49a8736a1da6563507b607aae8f
--- /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 0000000000000000000000000000000000000000..8e3aab6e04222db8860c111af0e7977fce128dd4
--- /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 0000000000000000000000000000000000000000..8e3aab6e04222db8860c111af0e7977fce128dd4
--- /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 0000000000000000000000000000000000000000..cf1cb903b31d5fb5527bc6216c0cb9047357da96
--- /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 0000000000000000000000000000000000000000..356d971e3a1f69f5c190b49d1d108e6be8766b39
--- /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 0000000000000000000000000000000000000000..d1cca4a33a25fbf6b631d46ce3dcd3608cffa046
--- /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 0000000000000000000000000000000000000000..77043182860321a9e265a89ad8f29ec7946b17e8
--- /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 0000000000000000000000000000000000000000..bc9e5bf899a54c5b2ef67e0193d56b243ec5f043
--- /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 0000000000000000000000000000000000000000..4a36d6979db1fd1f97ba2a290f78ac3b84f6de24
--- /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 0000000000000000000000000000000000000000..e2ac8283091597f6f4776560c86f89d1f98b58ee
--- /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 0000000000000000000000000000000000000000..af036079457a7f5e50eae5a9ad4c952f33e62f87
--- /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 0000000000000000000000000000000000000000..85cdfe0938e4093c7725e7f397accf26198f6a53
--- /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 0000000000000000000000000000000000000000..f066ddcfe458ca04bb1336f832121c91d7a3e80e
--- /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 0000000000000000000000000000000000000000..9d0dd8dc5fccb05aeabcbce4014c4994bafdfb05
--- /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 0000000000000000000000000000000000000000..073cbdf614f81525975dbd188632582218e60e9e
--- /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 0000000000000000000000000000000000000000..9086e885f56974d17f8cdf2dce4c6a44e580d74b
--- /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 0000000000000000000000000000000000000000..be4a0c7426093059ce37a9f824defb7ae270094d
--- /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 0000000000000000000000000000000000000000..84ea627b4927609079297f11674bdb4c6b301140
--- /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 0000000000000000000000000000000000000000..193f14e8a4d90793f65a5902eabb8d06496bd6e1
--- /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 0000000000000000000000000000000000000000..63ff6662f5c2c93201897e43680daa580ed53867
--- /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 0000000000000000000000000000000000000000..4c523d4e714ba67e84b213c2aaf3a56231f8b7e3
--- /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 0000000000000000000000000000000000000000..a0c34f71e3bbd3516247a8e026fe513c25413252
--- /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 0000000000000000000000000000000000000000..9b94772934f75e685d71a41f3a0336fbfb7320d5
--- /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 0000000000000000000000000000000000000000..11f7fb8547b351734a964175380d1ada696011ae
--- /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 0000000000000000000000000000000000000000..32b9c087feba1780223e3aee8a2636c99990408c
--- /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 0000000000000000000000000000000000000000..577c4e96ba91d4dd4aa448233c632de508286eb9
--- /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 0000000000000000000000000000000000000000..b56a4f755f89225cedd8c156cc7385fe5e07eee5
--- /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 0000000000000000000000000000000000000000..80f23d1e2431133035895946a5d6b24bef3ca294
--- /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 0000000000000000000000000000000000000000..c9a8298a8b51e05079041ae7a05086a47b1be5dd
--- /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 0000000000000000000000000000000000000000..f99de8e1f0650a3b590ed8bd9052e18173fc97d0
--- /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 0000000000000000000000000000000000000000..10fd8b42952c42f3d3a014da103931ca394423d5
--- /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 0000000000000000000000000000000000000000..9073130197e124527f8e38c238d8f13452a7780e
--- /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 0000000000000000000000000000000000000000..c6d6eb526e618ee93547e04eaba3c6a159a18075
--- /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 0000000000000000000000000000000000000000..0f0a1f30ab95bf540027efa8c03aff8fe03a960b
--- /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 0000000000000000000000000000000000000000..5cce21cd16aa89d96cdac2b302d29ee918b67249
--- /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 0000000000000000000000000000000000000000..83676da28884e79874fb0b5cc6a434a0fe6b87cf
--- /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 0000000000000000000000000000000000000000..cc1ce4cf298ee0747f41ea4941af5a65f8a688ef
--- /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 0000000000000000000000000000000000000000..adba337b101f4d7cafaa50329a933594b0d501ad
--- /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 0000000000000000000000000000000000000000..ae706b2952cfcecf20546a67a735b8d902cbb607
--- /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 0000000000000000000000000000000000000000..4e8b5bdea5ff9aa0cadbea0af10d51707da011c5
--- /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 0000000000000000000000000000000000000000..571aec0ccfdbcdc318ba1f17de31958c16b3e9bc
--- /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 0000000000000000000000000000000000000000..cee42c84c4f762a4d4773ea4380163742b5137b0
--- /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 0000000000000000000000000000000000000000..0a05b98eedb8bd743bb5af8e4dd3c95aab001c4b
--- /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 0000000000000000000000000000000000000000..c0363c3787270507d7902bb2ac0e39faef63a852
--- /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 f0b692a2e19bae3cf3ffee8f27bd39b05aba3b9c..1e47ae84080f9908736d1c3be9c14d589e8772a7 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -3975,6 +3975,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.
#
Comments
On Mon, 6 Nov 2023, Tamar Christina wrote:
> Hi All,
>
> This adds new test to check for all the early break functionality.
> It includes a number of codegen and runtime tests checking the values at
> different needles in the array.
>
> They also check the values on different array sizes and peeling positions,
> datatypes, VL, ncopies and every other variant I could think of.
>
> Additionally it also contains reduced cases from issues found running over
> various codebases.
>
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
>
> Also regtested with:
> -march=armv8.3-a+sve
> -march=armv8.3-a+nosve
> -march=armv9-a
>
> Ok for master?
>
> Thanks,
> Tamar
>
> gcc/ChangeLog:
>
> * doc/sourcebuild.texi: Document it.
Document what?
> gcc/testsuite/ChangeLog:
>
> * lib/target-supports.exp:
?
For all runtime testcases you need to include "tree-vect.h"
and call check_vect () in main so appropriate cpuid checks
can be performed.
In vect/ you shouldn't use { dg-do run }, that's the default
and is overridden by some .exp magic. If you add dg-do run
that magic doesn't work.
x86 also can do cbranch with SSE4.1, not sure how to
auto-magically add -msse4.1 for the tests though.
There's a sse4 target but that only checks whether you
can use -msse4.1. Anyway, we can do x86 testsuite adjustments
as followup.
> * g++.dg/vect/vect-early-break_1.cc: New test.
> * g++.dg/vect/vect-early-break_2.cc: New test.
> * g++.dg/vect/vect-early-break_3.cc: New test.
> * gcc.dg/vect/vect-early-break-run_1.c: New test.
> * gcc.dg/vect/vect-early-break-run_10.c: New test.
> * gcc.dg/vect/vect-early-break-run_2.c: New test.
> * gcc.dg/vect/vect-early-break-run_3.c: New test.
> * gcc.dg/vect/vect-early-break-run_4.c: New test.
> * gcc.dg/vect/vect-early-break-run_5.c: New test.
> * gcc.dg/vect/vect-early-break-run_6.c: New test.
> * gcc.dg/vect/vect-early-break-run_7.c: New test.
> * gcc.dg/vect/vect-early-break-run_8.c: New test.
> * gcc.dg/vect/vect-early-break-run_9.c: New test.
> * gcc.dg/vect/vect-early-break-template_1.c: New test.
> * gcc.dg/vect/vect-early-break-template_2.c: New test.
> * gcc.dg/vect/vect-early-break_1.c: New test.
> * gcc.dg/vect/vect-early-break_10.c: New test.
> * gcc.dg/vect/vect-early-break_11.c: New test.
> * gcc.dg/vect/vect-early-break_12.c: New test.
> * gcc.dg/vect/vect-early-break_13.c: New test.
> * gcc.dg/vect/vect-early-break_14.c: New test.
> * gcc.dg/vect/vect-early-break_15.c: New test.
> * gcc.dg/vect/vect-early-break_16.c: New test.
> * gcc.dg/vect/vect-early-break_17.c: New test.
> * gcc.dg/vect/vect-early-break_18.c: New test.
> * gcc.dg/vect/vect-early-break_19.c: New test.
> * gcc.dg/vect/vect-early-break_2.c: New test.
> * gcc.dg/vect/vect-early-break_20.c: New test.
> * gcc.dg/vect/vect-early-break_21.c: New test.
> * gcc.dg/vect/vect-early-break_22.c: New test.
> * gcc.dg/vect/vect-early-break_23.c: New test.
> * gcc.dg/vect/vect-early-break_24.c: New test.
> * gcc.dg/vect/vect-early-break_25.c: New test.
> * gcc.dg/vect/vect-early-break_26.c: New test.
> * gcc.dg/vect/vect-early-break_27.c: New test.
> * gcc.dg/vect/vect-early-break_28.c: New test.
> * gcc.dg/vect/vect-early-break_29.c: New test.
> * gcc.dg/vect/vect-early-break_3.c: New test.
> * gcc.dg/vect/vect-early-break_30.c: New test.
> * gcc.dg/vect/vect-early-break_31.c: New test.
> * gcc.dg/vect/vect-early-break_32.c: New test.
> * gcc.dg/vect/vect-early-break_33.c: New test.
> * gcc.dg/vect/vect-early-break_34.c: New test.
> * gcc.dg/vect/vect-early-break_35.c: New test.
> * gcc.dg/vect/vect-early-break_36.c: New test.
> * gcc.dg/vect/vect-early-break_37.c: New test.
> * gcc.dg/vect/vect-early-break_38.c: New test.
> * gcc.dg/vect/vect-early-break_39.c: New test.
> * gcc.dg/vect/vect-early-break_4.c: New test.
> * gcc.dg/vect/vect-early-break_40.c: New test.
> * gcc.dg/vect/vect-early-break_41.c: New test.
> * gcc.dg/vect/vect-early-break_42.c: New test.
> * gcc.dg/vect/vect-early-break_43.c: New test.
> * gcc.dg/vect/vect-early-break_44.c: New test.
> * gcc.dg/vect/vect-early-break_45.c: New test.
> * gcc.dg/vect/vect-early-break_46.c: New test.
> * gcc.dg/vect/vect-early-break_47.c: New test.
> * gcc.dg/vect/vect-early-break_48.c: New test.
> * gcc.dg/vect/vect-early-break_49.c: New test.
> * gcc.dg/vect/vect-early-break_5.c: New test.
> * gcc.dg/vect/vect-early-break_50.c: New test.
> * gcc.dg/vect/vect-early-break_51.c: New test.
> * gcc.dg/vect/vect-early-break_52.c: New test.
> * gcc.dg/vect/vect-early-break_53.c: New test.
> * gcc.dg/vect/vect-early-break_54.c: New test.
> * gcc.dg/vect/vect-early-break_55.c: New test.
> * gcc.dg/vect/vect-early-break_56.c: New test.
> * gcc.dg/vect/vect-early-break_57.c: New test.
> * gcc.dg/vect/vect-early-break_58.c: New test.
> * gcc.dg/vect/vect-early-break_59.c: New test.
> * gcc.dg/vect/vect-early-break_6.c: New test.
> * gcc.dg/vect/vect-early-break_60.c: New test.
> * gcc.dg/vect/vect-early-break_61.c: New test.
> * gcc.dg/vect/vect-early-break_62.c: New test.
> * gcc.dg/vect/vect-early-break_63.c: New test.
> * gcc.dg/vect/vect-early-break_64.c: New test.
> * gcc.dg/vect/vect-early-break_65.c: New test.
> * gcc.dg/vect/vect-early-break_66.c: New test.
> * gcc.dg/vect/vect-early-break_67.c: New test.
> * gcc.dg/vect/vect-early-break_68.c: New test.
> * gcc.dg/vect/vect-early-break_69.c: New test.
> * gcc.dg/vect/vect-early-break_7.c: New test.
> * gcc.dg/vect/vect-early-break_70.c: New test.
> * gcc.dg/vect/vect-early-break_71.c: New test.
> * gcc.dg/vect/vect-early-break_72.c: New test.
> * gcc.dg/vect/vect-early-break_73.c: New test.
> * gcc.dg/vect/vect-early-break_74.c: New test.
> * gcc.dg/vect/vect-early-break_75.c: New test.
> * gcc.dg/vect/vect-early-break_76.c: New test.
> * gcc.dg/vect/vect-early-break_8.c: New test.
> * gcc.dg/vect/vect-early-break_9.c: New test.
> * gcc.target/aarch64/opt_mismatch_1.c: New test.
> * gcc.target/aarch64/opt_mismatch_2.c: New test.
> * gcc.target/aarch64/opt_mismatch_3.c: New test.
> * gcc.target/aarch64/vect-early-break-cbranch_1.c: New test.
>
> --- inline copy of patch --
> diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
> index c20af31c64237baff70f8781b1dc47f4d1a48aa9..4c351335f2bec9c6bb6856bd38d9132da7447c13 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 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
> --- /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 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
> --- /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 0000000000000000000000000000000000000000..a12e5ca434b2ac37c03dbaa12273fd8e5aa2018c
> --- /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 0000000000000000000000000000000000000000..2495b36a72eae94cb7abc4a0d17a5c979fd78083
> --- /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 0000000000000000000000000000000000000000..9bcd7f7e57ef9a1d4649d18569b3406050e54603
> --- /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 0000000000000000000000000000000000000000..63f63101a467909f328be7f3acbc5bcb721967ff
> --- /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 0000000000000000000000000000000000000000..626b95e9b8517081d41d794e9e0264d6301c8589
> --- /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 0000000000000000000000000000000000000000..7e0e6426120551152a7bd800c15d9ed6ab15bada
> --- /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 0000000000000000000000000000000000000000..242cf486f9c40055df0aef5fd238d1aff7a7c7da
> --- /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 0000000000000000000000000000000000000000..9fe7136b7213a463ca6573c60476b7c8f531ddcb
> --- /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 0000000000000000000000000000000000000000..02f93d77dba31b938f6fd9e8c7f5e4acde4aeec9
> --- /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 0000000000000000000000000000000000000000..a614925465606b54c638221ffb95a5e8d3bee797
> --- /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 0000000000000000000000000000000000000000..94e2b9c301456eda8f9ad7eaa67604563f0afee7
> --- /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 0000000000000000000000000000000000000000..af70a8e2a5a9dc9756edb5580f2de02ddcc95de9
> --- /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 0000000000000000000000000000000000000000..d0f924d904437e71567d27cc1f1089e5607dca0d
> --- /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 0000000000000000000000000000000000000000..51e7d6489b99c25b9b4b3d1c839f98562b6d4dd7
> --- /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 0000000000000000000000000000000000000000..9e4ad1763202dfdab3ed7961ead5114fcc61a11b
> --- /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 0000000000000000000000000000000000000000..a613dd9909fb09278dd92a81a24ef854994a9890
> --- /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 0000000000000000000000000000000000000000..cc10f3238f1cb8e1307e024a3ebcb5c25a39d1b2
> --- /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 0000000000000000000000000000000000000000..6967b7395ed7c19e38a436d6edcfe7c1580c7113
> --- /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 0000000000000000000000000000000000000000..03cce5cf6cadecb520b46be666bf608e3bc6a511
> --- /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 0000000000000000000000000000000000000000..dec6872e1115ff66695f5a500ffa7ca01c0f8d3a
> --- /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 0000000000000000000000000000000000000000..30812d12a39bd94b4b8a3aade6512b162697d659
> --- /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 0000000000000000000000000000000000000000..510227a18435a8e47c5a754580180c6d340c0823
> --- /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 0000000000000000000000000000000000000000..1372f79242b250cabbab29757b62cbc28a9064a8
> --- /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 0000000000000000000000000000000000000000..677487f7da496a8f467d8c529575d47ff22c6a31
> --- /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 0000000000000000000000000000000000000000..7268f6ae2485d0274fd85ea53cc1e44ef4b84d5c
> --- /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 0000000000000000000000000000000000000000..ed41377d1c979bf14e0a4e80401831c09ffa463f
> --- /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 0000000000000000000000000000000000000000..6415e4951cb9ef70e56b7cfb1db3d3151368666d
> --- /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 0000000000000000000000000000000000000000..2ca189899fb6bd6dfdf63de7729f54e3bee06ba0
> --- /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 0000000000000000000000000000000000000000..f3298656d5d67fd137c4029a96a2f9c1bae344ce
> --- /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 0000000000000000000000000000000000000000..7b4b2ffb9b75db6d5ca7e313d1f18d9b51f5b566
> --- /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 0000000000000000000000000000000000000000..8db9b60128b9e21529ae73ea1902afb8fa327112
> --- /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 0000000000000000000000000000000000000000..5905847cc0b6b393dde728a9f4ecb44c8ab42da5
> --- /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 0000000000000000000000000000000000000000..d0cfbb01667fa016d72828d098aeaa252c2c9318
> --- /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 0000000000000000000000000000000000000000..a5eae81f3f5f5b7d92082f1588c6453a71e205cc
> --- /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 0000000000000000000000000000000000000000..75d87e99e939fab61f751be025ca0398fa5bd078
> --- /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 0000000000000000000000000000000000000000..3c6d28bd2d6e6e794146baf89e43c3b70293b7d9
> --- /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 0000000000000000000000000000000000000000..e09d883db84685679e73867d83aba9900563983d
> --- /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 0000000000000000000000000000000000000000..6001523162d24d140af73143435f25bcd3a217c8
> --- /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 0000000000000000000000000000000000000000..73abddc267a0170c2d97a7e7c680525721455f22
> --- /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 0000000000000000000000000000000000000000..29b37f70939af7fa9409edd3a1e29f718c959706
> --- /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 0000000000000000000000000000000000000000..2c48e3cee33fc37f45ef59c2bbaff7bc5a76b460
> --- /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 0000000000000000000000000000000000000000..3442484a81161f9bd09e30bc268fbcf66a899902
> --- /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 0000000000000000000000000000000000000000..027766c51f508eab157db365a1653f3e92dcac10
> --- /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 0000000000000000000000000000000000000000..8d363120898232bb1402b9cf7b4b83b38a10505b
> --- /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 0000000000000000000000000000000000000000..226d55d7194ca3f676ab52976fea25b7e335bbec
> --- /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 0000000000000000000000000000000000000000..554e6ec84318c600c87982ad6ef0f90e8b47af01
> --- /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 0000000000000000000000000000000000000000..216c56faf330449bf1969b7e51ff1e94270dc861
> --- /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 0000000000000000000000000000000000000000..f2ae372cd96e74cc06254937c2b8fa69ecdedf09
> --- /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 0000000000000000000000000000000000000000..6ad9b3f17ddb953bfbf614e9331fa81f565b262f
> --- /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 0000000000000000000000000000000000000000..88652f01595cb49a8736a1da6563507b607aae8f
> --- /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 0000000000000000000000000000000000000000..8e3aab6e04222db8860c111af0e7977fce128dd4
> --- /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 0000000000000000000000000000000000000000..8e3aab6e04222db8860c111af0e7977fce128dd4
> --- /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 0000000000000000000000000000000000000000..cf1cb903b31d5fb5527bc6216c0cb9047357da96
> --- /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 0000000000000000000000000000000000000000..356d971e3a1f69f5c190b49d1d108e6be8766b39
> --- /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 0000000000000000000000000000000000000000..d1cca4a33a25fbf6b631d46ce3dcd3608cffa046
> --- /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 0000000000000000000000000000000000000000..77043182860321a9e265a89ad8f29ec7946b17e8
> --- /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 0000000000000000000000000000000000000000..bc9e5bf899a54c5b2ef67e0193d56b243ec5f043
> --- /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 0000000000000000000000000000000000000000..4a36d6979db1fd1f97ba2a290f78ac3b84f6de24
> --- /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 0000000000000000000000000000000000000000..e2ac8283091597f6f4776560c86f89d1f98b58ee
> --- /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 0000000000000000000000000000000000000000..af036079457a7f5e50eae5a9ad4c952f33e62f87
> --- /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 0000000000000000000000000000000000000000..85cdfe0938e4093c7725e7f397accf26198f6a53
> --- /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 0000000000000000000000000000000000000000..f066ddcfe458ca04bb1336f832121c91d7a3e80e
> --- /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 0000000000000000000000000000000000000000..9d0dd8dc5fccb05aeabcbce4014c4994bafdfb05
> --- /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 0000000000000000000000000000000000000000..073cbdf614f81525975dbd188632582218e60e9e
> --- /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 0000000000000000000000000000000000000000..9086e885f56974d17f8cdf2dce4c6a44e580d74b
> --- /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 0000000000000000000000000000000000000000..be4a0c7426093059ce37a9f824defb7ae270094d
> --- /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 0000000000000000000000000000000000000000..84ea627b4927609079297f11674bdb4c6b301140
> --- /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 0000000000000000000000000000000000000000..193f14e8a4d90793f65a5902eabb8d06496bd6e1
> --- /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 0000000000000000000000000000000000000000..63ff6662f5c2c93201897e43680daa580ed53867
> --- /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 0000000000000000000000000000000000000000..4c523d4e714ba67e84b213c2aaf3a56231f8b7e3
> --- /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 0000000000000000000000000000000000000000..a0c34f71e3bbd3516247a8e026fe513c25413252
> --- /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 0000000000000000000000000000000000000000..9b94772934f75e685d71a41f3a0336fbfb7320d5
> --- /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 0000000000000000000000000000000000000000..11f7fb8547b351734a964175380d1ada696011ae
> --- /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 0000000000000000000000000000000000000000..32b9c087feba1780223e3aee8a2636c99990408c
> --- /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 0000000000000000000000000000000000000000..577c4e96ba91d4dd4aa448233c632de508286eb9
> --- /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 0000000000000000000000000000000000000000..b56a4f755f89225cedd8c156cc7385fe5e07eee5
> --- /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 0000000000000000000000000000000000000000..80f23d1e2431133035895946a5d6b24bef3ca294
> --- /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 0000000000000000000000000000000000000000..c9a8298a8b51e05079041ae7a05086a47b1be5dd
> --- /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 0000000000000000000000000000000000000000..f99de8e1f0650a3b590ed8bd9052e18173fc97d0
> --- /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 0000000000000000000000000000000000000000..10fd8b42952c42f3d3a014da103931ca394423d5
> --- /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 0000000000000000000000000000000000000000..9073130197e124527f8e38c238d8f13452a7780e
> --- /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 0000000000000000000000000000000000000000..c6d6eb526e618ee93547e04eaba3c6a159a18075
> --- /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 0000000000000000000000000000000000000000..0f0a1f30ab95bf540027efa8c03aff8fe03a960b
> --- /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 0000000000000000000000000000000000000000..5cce21cd16aa89d96cdac2b302d29ee918b67249
> --- /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 0000000000000000000000000000000000000000..83676da28884e79874fb0b5cc6a434a0fe6b87cf
> --- /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 0000000000000000000000000000000000000000..cc1ce4cf298ee0747f41ea4941af5a65f8a688ef
> --- /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 0000000000000000000000000000000000000000..adba337b101f4d7cafaa50329a933594b0d501ad
> --- /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 0000000000000000000000000000000000000000..ae706b2952cfcecf20546a67a735b8d902cbb607
> --- /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 0000000000000000000000000000000000000000..4e8b5bdea5ff9aa0cadbea0af10d51707da011c5
> --- /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 0000000000000000000000000000000000000000..571aec0ccfdbcdc318ba1f17de31958c16b3e9bc
> --- /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 0000000000000000000000000000000000000000..cee42c84c4f762a4d4773ea4380163742b5137b0
> --- /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 0000000000000000000000000000000000000000..0a05b98eedb8bd743bb5af8e4dd3c95aab001c4b
> --- /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 0000000000000000000000000000000000000000..c0363c3787270507d7902bb2ac0e39faef63a852
> --- /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 f0b692a2e19bae3cf3ffee8f27bd39b05aba3b9c..1e47ae84080f9908736d1c3be9c14d589e8772a7 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -3975,6 +3975,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.
> #
>
>
>
>
>
On Tue, Nov 7, 2023 at 10:53 AM Richard Biener <rguenther@suse.de> wrote:
>
> On Mon, 6 Nov 2023, Tamar Christina wrote:
>
> > Hi All,
> >
> > This adds new test to check for all the early break functionality.
> > It includes a number of codegen and runtime tests checking the values at
> > different needles in the array.
> >
> > They also check the values on different array sizes and peeling positions,
> > datatypes, VL, ncopies and every other variant I could think of.
> >
> > Additionally it also contains reduced cases from issues found running over
> > various codebases.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> >
> > Also regtested with:
> > -march=armv8.3-a+sve
> > -march=armv8.3-a+nosve
> > -march=armv9-a
> >
> > Ok for master?
> >
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> > * doc/sourcebuild.texi: Document it.
>
> Document what?
>
> > gcc/testsuite/ChangeLog:
> >
> > * lib/target-supports.exp:
>
> ?
>
> For all runtime testcases you need to include "tree-vect.h"
> and call check_vect () in main so appropriate cpuid checks
> can be performed.
>
> In vect/ you shouldn't use { dg-do run }, that's the default
> and is overridden by some .exp magic. If you add dg-do run
> that magic doesn't work.
>
> x86 also can do cbranch with SSE4.1, not sure how to
> auto-magically add -msse4.1 for the tests though.
> There's a sse4 target but that only checks whether you
> can use -msse4.1. Anyway, we can do x86 testsuite adjustments
> as followup.
But it gives extra test coverage:
diff --git a/gcc/testsuite/lib/target-supports.exp
b/gcc/testsuite/lib/target-supports.exp
index 769df6cd766..1767fda36dc 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4081,6 +4081,7 @@ proc check_effective_target_vect_early_break { } {
|| [check_effective_target_arm_neon_ok]
|| ([check_effective_target_arm_v8_1m_mve_fp_ok]
&& [check_effective_target_arm_little_endian])
+ || [check_effective_target_sse4]
}}]
}
# Return 1 if the target supports hardware vectorization of complex
additions of
and running the testsuite with -msse4.1 yields
Running target unix/-msse4.1
FAIL: gcc.dg/vect/vect-early-break_2.c (internal compiler error:
verify_ssa failed)
FAIL: gcc.dg/vect/vect-early-break_2.c (test for excess errors)
FAIL: gcc.dg/vect/vect-early-break_21.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_25.c scan-tree-dump-times vect
"Vectorizing an unaligned access" 14
FAIL: gcc.dg/vect/vect-early-break_52.c scan-tree-dump vect
"vectorized 1 loops in function"
FAIL: gcc.dg/vect/vect-early-break_67.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_69.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_7.c (internal compiler error:
verify_ssa failed)
FAIL: gcc.dg/vect/vect-early-break_7.c (test for excess errors)
FAIL: gcc.dg/vect/vect-early-break_70.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_71.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_71.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_72.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_73.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_73.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_74.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_75.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_76.c scan-tree-dump vect "LOOP VECTORIZED"
FAIL: gcc.dg/vect/vect-early-break_8.c scan-tree-dump vect "LOOP VECTORIZED"
maybe we can amend check_vect_support_and_set_flags to enable more
than just -msse2 on x86_64 by default when available. To avoid too much churn
I'd not use -mavx2 but instead -msse4.1 which would not alter the set of vector
modes available.
The other option is to add dg-additional-options -msse4.1 to all early-break
tests for { target sse4 } (and as said, use check_vect () for run tests).
Richard.
>
>
> > * g++.dg/vect/vect-early-break_1.cc: New test.
> > * g++.dg/vect/vect-early-break_2.cc: New test.
> > * g++.dg/vect/vect-early-break_3.cc: New test.
> > * gcc.dg/vect/vect-early-break-run_1.c: New test.
> > * gcc.dg/vect/vect-early-break-run_10.c: New test.
> > * gcc.dg/vect/vect-early-break-run_2.c: New test.
> > * gcc.dg/vect/vect-early-break-run_3.c: New test.
> > * gcc.dg/vect/vect-early-break-run_4.c: New test.
> > * gcc.dg/vect/vect-early-break-run_5.c: New test.
> > * gcc.dg/vect/vect-early-break-run_6.c: New test.
> > * gcc.dg/vect/vect-early-break-run_7.c: New test.
> > * gcc.dg/vect/vect-early-break-run_8.c: New test.
> > * gcc.dg/vect/vect-early-break-run_9.c: New test.
> > * gcc.dg/vect/vect-early-break-template_1.c: New test.
> > * gcc.dg/vect/vect-early-break-template_2.c: New test.
> > * gcc.dg/vect/vect-early-break_1.c: New test.
> > * gcc.dg/vect/vect-early-break_10.c: New test.
> > * gcc.dg/vect/vect-early-break_11.c: New test.
> > * gcc.dg/vect/vect-early-break_12.c: New test.
> > * gcc.dg/vect/vect-early-break_13.c: New test.
> > * gcc.dg/vect/vect-early-break_14.c: New test.
> > * gcc.dg/vect/vect-early-break_15.c: New test.
> > * gcc.dg/vect/vect-early-break_16.c: New test.
> > * gcc.dg/vect/vect-early-break_17.c: New test.
> > * gcc.dg/vect/vect-early-break_18.c: New test.
> > * gcc.dg/vect/vect-early-break_19.c: New test.
> > * gcc.dg/vect/vect-early-break_2.c: New test.
> > * gcc.dg/vect/vect-early-break_20.c: New test.
> > * gcc.dg/vect/vect-early-break_21.c: New test.
> > * gcc.dg/vect/vect-early-break_22.c: New test.
> > * gcc.dg/vect/vect-early-break_23.c: New test.
> > * gcc.dg/vect/vect-early-break_24.c: New test.
> > * gcc.dg/vect/vect-early-break_25.c: New test.
> > * gcc.dg/vect/vect-early-break_26.c: New test.
> > * gcc.dg/vect/vect-early-break_27.c: New test.
> > * gcc.dg/vect/vect-early-break_28.c: New test.
> > * gcc.dg/vect/vect-early-break_29.c: New test.
> > * gcc.dg/vect/vect-early-break_3.c: New test.
> > * gcc.dg/vect/vect-early-break_30.c: New test.
> > * gcc.dg/vect/vect-early-break_31.c: New test.
> > * gcc.dg/vect/vect-early-break_32.c: New test.
> > * gcc.dg/vect/vect-early-break_33.c: New test.
> > * gcc.dg/vect/vect-early-break_34.c: New test.
> > * gcc.dg/vect/vect-early-break_35.c: New test.
> > * gcc.dg/vect/vect-early-break_36.c: New test.
> > * gcc.dg/vect/vect-early-break_37.c: New test.
> > * gcc.dg/vect/vect-early-break_38.c: New test.
> > * gcc.dg/vect/vect-early-break_39.c: New test.
> > * gcc.dg/vect/vect-early-break_4.c: New test.
> > * gcc.dg/vect/vect-early-break_40.c: New test.
> > * gcc.dg/vect/vect-early-break_41.c: New test.
> > * gcc.dg/vect/vect-early-break_42.c: New test.
> > * gcc.dg/vect/vect-early-break_43.c: New test.
> > * gcc.dg/vect/vect-early-break_44.c: New test.
> > * gcc.dg/vect/vect-early-break_45.c: New test.
> > * gcc.dg/vect/vect-early-break_46.c: New test.
> > * gcc.dg/vect/vect-early-break_47.c: New test.
> > * gcc.dg/vect/vect-early-break_48.c: New test.
> > * gcc.dg/vect/vect-early-break_49.c: New test.
> > * gcc.dg/vect/vect-early-break_5.c: New test.
> > * gcc.dg/vect/vect-early-break_50.c: New test.
> > * gcc.dg/vect/vect-early-break_51.c: New test.
> > * gcc.dg/vect/vect-early-break_52.c: New test.
> > * gcc.dg/vect/vect-early-break_53.c: New test.
> > * gcc.dg/vect/vect-early-break_54.c: New test.
> > * gcc.dg/vect/vect-early-break_55.c: New test.
> > * gcc.dg/vect/vect-early-break_56.c: New test.
> > * gcc.dg/vect/vect-early-break_57.c: New test.
> > * gcc.dg/vect/vect-early-break_58.c: New test.
> > * gcc.dg/vect/vect-early-break_59.c: New test.
> > * gcc.dg/vect/vect-early-break_6.c: New test.
> > * gcc.dg/vect/vect-early-break_60.c: New test.
> > * gcc.dg/vect/vect-early-break_61.c: New test.
> > * gcc.dg/vect/vect-early-break_62.c: New test.
> > * gcc.dg/vect/vect-early-break_63.c: New test.
> > * gcc.dg/vect/vect-early-break_64.c: New test.
> > * gcc.dg/vect/vect-early-break_65.c: New test.
> > * gcc.dg/vect/vect-early-break_66.c: New test.
> > * gcc.dg/vect/vect-early-break_67.c: New test.
> > * gcc.dg/vect/vect-early-break_68.c: New test.
> > * gcc.dg/vect/vect-early-break_69.c: New test.
> > * gcc.dg/vect/vect-early-break_7.c: New test.
> > * gcc.dg/vect/vect-early-break_70.c: New test.
> > * gcc.dg/vect/vect-early-break_71.c: New test.
> > * gcc.dg/vect/vect-early-break_72.c: New test.
> > * gcc.dg/vect/vect-early-break_73.c: New test.
> > * gcc.dg/vect/vect-early-break_74.c: New test.
> > * gcc.dg/vect/vect-early-break_75.c: New test.
> > * gcc.dg/vect/vect-early-break_76.c: New test.
> > * gcc.dg/vect/vect-early-break_8.c: New test.
> > * gcc.dg/vect/vect-early-break_9.c: New test.
> > * gcc.target/aarch64/opt_mismatch_1.c: New test.
> > * gcc.target/aarch64/opt_mismatch_2.c: New test.
> > * gcc.target/aarch64/opt_mismatch_3.c: New test.
> > * gcc.target/aarch64/vect-early-break-cbranch_1.c: New test.
> >
> > --- inline copy of patch --
> > diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
> > index c20af31c64237baff70f8781b1dc47f4d1a48aa9..4c351335f2bec9c6bb6856bd38d9132da7447c13 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 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
> > --- /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 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
> > --- /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 0000000000000000000000000000000000000000..a12e5ca434b2ac37c03dbaa12273fd8e5aa2018c
> > --- /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 0000000000000000000000000000000000000000..2495b36a72eae94cb7abc4a0d17a5c979fd78083
> > --- /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 0000000000000000000000000000000000000000..9bcd7f7e57ef9a1d4649d18569b3406050e54603
> > --- /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 0000000000000000000000000000000000000000..63f63101a467909f328be7f3acbc5bcb721967ff
> > --- /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 0000000000000000000000000000000000000000..626b95e9b8517081d41d794e9e0264d6301c8589
> > --- /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 0000000000000000000000000000000000000000..7e0e6426120551152a7bd800c15d9ed6ab15bada
> > --- /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 0000000000000000000000000000000000000000..242cf486f9c40055df0aef5fd238d1aff7a7c7da
> > --- /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 0000000000000000000000000000000000000000..9fe7136b7213a463ca6573c60476b7c8f531ddcb
> > --- /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 0000000000000000000000000000000000000000..02f93d77dba31b938f6fd9e8c7f5e4acde4aeec9
> > --- /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 0000000000000000000000000000000000000000..a614925465606b54c638221ffb95a5e8d3bee797
> > --- /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 0000000000000000000000000000000000000000..94e2b9c301456eda8f9ad7eaa67604563f0afee7
> > --- /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 0000000000000000000000000000000000000000..af70a8e2a5a9dc9756edb5580f2de02ddcc95de9
> > --- /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 0000000000000000000000000000000000000000..d0f924d904437e71567d27cc1f1089e5607dca0d
> > --- /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 0000000000000000000000000000000000000000..51e7d6489b99c25b9b4b3d1c839f98562b6d4dd7
> > --- /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 0000000000000000000000000000000000000000..9e4ad1763202dfdab3ed7961ead5114fcc61a11b
> > --- /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 0000000000000000000000000000000000000000..a613dd9909fb09278dd92a81a24ef854994a9890
> > --- /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 0000000000000000000000000000000000000000..cc10f3238f1cb8e1307e024a3ebcb5c25a39d1b2
> > --- /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 0000000000000000000000000000000000000000..6967b7395ed7c19e38a436d6edcfe7c1580c7113
> > --- /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 0000000000000000000000000000000000000000..03cce5cf6cadecb520b46be666bf608e3bc6a511
> > --- /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 0000000000000000000000000000000000000000..dec6872e1115ff66695f5a500ffa7ca01c0f8d3a
> > --- /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 0000000000000000000000000000000000000000..30812d12a39bd94b4b8a3aade6512b162697d659
> > --- /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 0000000000000000000000000000000000000000..510227a18435a8e47c5a754580180c6d340c0823
> > --- /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 0000000000000000000000000000000000000000..1372f79242b250cabbab29757b62cbc28a9064a8
> > --- /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 0000000000000000000000000000000000000000..677487f7da496a8f467d8c529575d47ff22c6a31
> > --- /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 0000000000000000000000000000000000000000..7268f6ae2485d0274fd85ea53cc1e44ef4b84d5c
> > --- /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 0000000000000000000000000000000000000000..ed41377d1c979bf14e0a4e80401831c09ffa463f
> > --- /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 0000000000000000000000000000000000000000..6415e4951cb9ef70e56b7cfb1db3d3151368666d
> > --- /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 0000000000000000000000000000000000000000..2ca189899fb6bd6dfdf63de7729f54e3bee06ba0
> > --- /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 0000000000000000000000000000000000000000..f3298656d5d67fd137c4029a96a2f9c1bae344ce
> > --- /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 0000000000000000000000000000000000000000..7b4b2ffb9b75db6d5ca7e313d1f18d9b51f5b566
> > --- /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 0000000000000000000000000000000000000000..8db9b60128b9e21529ae73ea1902afb8fa327112
> > --- /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 0000000000000000000000000000000000000000..5905847cc0b6b393dde728a9f4ecb44c8ab42da5
> > --- /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 0000000000000000000000000000000000000000..d0cfbb01667fa016d72828d098aeaa252c2c9318
> > --- /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 0000000000000000000000000000000000000000..a5eae81f3f5f5b7d92082f1588c6453a71e205cc
> > --- /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 0000000000000000000000000000000000000000..75d87e99e939fab61f751be025ca0398fa5bd078
> > --- /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 0000000000000000000000000000000000000000..3c6d28bd2d6e6e794146baf89e43c3b70293b7d9
> > --- /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 0000000000000000000000000000000000000000..e09d883db84685679e73867d83aba9900563983d
> > --- /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 0000000000000000000000000000000000000000..6001523162d24d140af73143435f25bcd3a217c8
> > --- /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 0000000000000000000000000000000000000000..73abddc267a0170c2d97a7e7c680525721455f22
> > --- /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 0000000000000000000000000000000000000000..29b37f70939af7fa9409edd3a1e29f718c959706
> > --- /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 0000000000000000000000000000000000000000..2c48e3cee33fc37f45ef59c2bbaff7bc5a76b460
> > --- /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 0000000000000000000000000000000000000000..3442484a81161f9bd09e30bc268fbcf66a899902
> > --- /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 0000000000000000000000000000000000000000..027766c51f508eab157db365a1653f3e92dcac10
> > --- /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 0000000000000000000000000000000000000000..8d363120898232bb1402b9cf7b4b83b38a10505b
> > --- /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 0000000000000000000000000000000000000000..226d55d7194ca3f676ab52976fea25b7e335bbec
> > --- /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 0000000000000000000000000000000000000000..554e6ec84318c600c87982ad6ef0f90e8b47af01
> > --- /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 0000000000000000000000000000000000000000..216c56faf330449bf1969b7e51ff1e94270dc861
> > --- /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 0000000000000000000000000000000000000000..f2ae372cd96e74cc06254937c2b8fa69ecdedf09
> > --- /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 0000000000000000000000000000000000000000..6ad9b3f17ddb953bfbf614e9331fa81f565b262f
> > --- /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 0000000000000000000000000000000000000000..88652f01595cb49a8736a1da6563507b607aae8f
> > --- /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 0000000000000000000000000000000000000000..8e3aab6e04222db8860c111af0e7977fce128dd4
> > --- /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 0000000000000000000000000000000000000000..8e3aab6e04222db8860c111af0e7977fce128dd4
> > --- /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 0000000000000000000000000000000000000000..cf1cb903b31d5fb5527bc6216c0cb9047357da96
> > --- /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 0000000000000000000000000000000000000000..356d971e3a1f69f5c190b49d1d108e6be8766b39
> > --- /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 0000000000000000000000000000000000000000..d1cca4a33a25fbf6b631d46ce3dcd3608cffa046
> > --- /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 0000000000000000000000000000000000000000..77043182860321a9e265a89ad8f29ec7946b17e8
> > --- /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 0000000000000000000000000000000000000000..bc9e5bf899a54c5b2ef67e0193d56b243ec5f043
> > --- /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 0000000000000000000000000000000000000000..4a36d6979db1fd1f97ba2a290f78ac3b84f6de24
> > --- /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 0000000000000000000000000000000000000000..e2ac8283091597f6f4776560c86f89d1f98b58ee
> > --- /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 0000000000000000000000000000000000000000..af036079457a7f5e50eae5a9ad4c952f33e62f87
> > --- /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 0000000000000000000000000000000000000000..85cdfe0938e4093c7725e7f397accf26198f6a53
> > --- /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 0000000000000000000000000000000000000000..f066ddcfe458ca04bb1336f832121c91d7a3e80e
> > --- /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 0000000000000000000000000000000000000000..9d0dd8dc5fccb05aeabcbce4014c4994bafdfb05
> > --- /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 0000000000000000000000000000000000000000..073cbdf614f81525975dbd188632582218e60e9e
> > --- /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 0000000000000000000000000000000000000000..9086e885f56974d17f8cdf2dce4c6a44e580d74b
> > --- /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 0000000000000000000000000000000000000000..be4a0c7426093059ce37a9f824defb7ae270094d
> > --- /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 0000000000000000000000000000000000000000..84ea627b4927609079297f11674bdb4c6b301140
> > --- /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 0000000000000000000000000000000000000000..193f14e8a4d90793f65a5902eabb8d06496bd6e1
> > --- /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 0000000000000000000000000000000000000000..63ff6662f5c2c93201897e43680daa580ed53867
> > --- /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 0000000000000000000000000000000000000000..4c523d4e714ba67e84b213c2aaf3a56231f8b7e3
> > --- /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 0000000000000000000000000000000000000000..a0c34f71e3bbd3516247a8e026fe513c25413252
> > --- /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 0000000000000000000000000000000000000000..9b94772934f75e685d71a41f3a0336fbfb7320d5
> > --- /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 0000000000000000000000000000000000000000..11f7fb8547b351734a964175380d1ada696011ae
> > --- /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 0000000000000000000000000000000000000000..32b9c087feba1780223e3aee8a2636c99990408c
> > --- /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 0000000000000000000000000000000000000000..577c4e96ba91d4dd4aa448233c632de508286eb9
> > --- /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 0000000000000000000000000000000000000000..b56a4f755f89225cedd8c156cc7385fe5e07eee5
> > --- /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 0000000000000000000000000000000000000000..80f23d1e2431133035895946a5d6b24bef3ca294
> > --- /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 0000000000000000000000000000000000000000..c9a8298a8b51e05079041ae7a05086a47b1be5dd
> > --- /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 0000000000000000000000000000000000000000..f99de8e1f0650a3b590ed8bd9052e18173fc97d0
> > --- /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 0000000000000000000000000000000000000000..10fd8b42952c42f3d3a014da103931ca394423d5
> > --- /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 0000000000000000000000000000000000000000..9073130197e124527f8e38c238d8f13452a7780e
> > --- /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 0000000000000000000000000000000000000000..c6d6eb526e618ee93547e04eaba3c6a159a18075
> > --- /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 0000000000000000000000000000000000000000..0f0a1f30ab95bf540027efa8c03aff8fe03a960b
> > --- /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 0000000000000000000000000000000000000000..5cce21cd16aa89d96cdac2b302d29ee918b67249
> > --- /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 0000000000000000000000000000000000000000..83676da28884e79874fb0b5cc6a434a0fe6b87cf
> > --- /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 0000000000000000000000000000000000000000..cc1ce4cf298ee0747f41ea4941af5a65f8a688ef
> > --- /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 0000000000000000000000000000000000000000..adba337b101f4d7cafaa50329a933594b0d501ad
> > --- /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 0000000000000000000000000000000000000000..ae706b2952cfcecf20546a67a735b8d902cbb607
> > --- /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 0000000000000000000000000000000000000000..4e8b5bdea5ff9aa0cadbea0af10d51707da011c5
> > --- /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 0000000000000000000000000000000000000000..571aec0ccfdbcdc318ba1f17de31958c16b3e9bc
> > --- /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 0000000000000000000000000000000000000000..cee42c84c4f762a4d4773ea4380163742b5137b0
> > --- /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 0000000000000000000000000000000000000000..0a05b98eedb8bd743bb5af8e4dd3c95aab001c4b
> > --- /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 0000000000000000000000000000000000000000..c0363c3787270507d7902bb2ac0e39faef63a852
> > --- /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 f0b692a2e19bae3cf3ffee8f27bd39b05aba3b9c..1e47ae84080f9908736d1c3be9c14d589e8772a7 100644
> > --- a/gcc/testsuite/lib/target-supports.exp
> > +++ b/gcc/testsuite/lib/target-supports.exp
> > @@ -3975,6 +3975,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.
> > #
> >
> >
> >
> >
> >
>
> --
> Richard Biener <rguenther@suse.de>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
@@ -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}.
new file mode 100644
@@ -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);
+}
+
new file mode 100644
@@ -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);
+}
+
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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 ();
+
+}
new file mode 100644
@@ -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 ();
+
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
+
new file mode 100644
@@ -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;
+}
+
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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;
+}
+
new file mode 100644
@@ -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 } } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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 ();
+ }
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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 *-*-* } } } */
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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 } } } } } */
+
new file mode 100644
@@ -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 ();
+ }
+}
new file mode 100644
@@ -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 *-*-* } } } */
new file mode 100644
@@ -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 *-*-* } } } */
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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 *-*-* } } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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 } } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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)
+ ;
+ }
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
+
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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 } */
new file mode 100644
@@ -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" } */
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=armv8-a -mcpu=neovese-n1 -Wpedentic -Werror" } */
+
+#include <arm_neon.h>
+
new file mode 100644
@@ -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;
+ }
+}
@@ -3975,6 +3975,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.
#