[14/19] middle-end testsuite: Add new 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 vect_early_break.
gcc/testsuite/ChangeLog:
* lib/target-supports.exp (vect_early_break): New.
* 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_7.c: New test.
* gcc.dg/vect/vect-early-break_8.c: New test.
* gcc.dg/vect/vect-early-break_9.c: New test.
--- inline copy of patch --
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 526020c751150cd74f766eb83eaf61de6f4374cf..090ceebd7befb3ace9b0d498b74a4e3474990b91 100644
--
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 526020c751150cd74f766eb83eaf61de6f4374cf..090ceebd7befb3ace9b0d498b74a4e3474990b91 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/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..9c7c3df59ffbaaf23292107f982fd7af31741ada
--- /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-not "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_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_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..350f02f3c7caef457adbe1be802bba51cd818393
--- /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-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++)
+ {
+ vect_a[i] = x + i;
+ if (vect_a[i] > x)
+ break;
+ vect_a[i] = x;
+
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index d79ad4be10502969209f9b13bd65ab142b92e644..5516188dc0aa86d161d67dea5a7769e3c3d72f85 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -3775,6 +3775,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.
#
@@ -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,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-not "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,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,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-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++)
+ {
+ vect_a[i] = x + i;
+ if (vect_a[i] > x)
+ break;
+ vect_a[i] = x;
+
+ }
+ return ret;
+}
@@ -3775,6 +3775,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.
#