public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v5 0/19] Support early break/return auto-vectorization
@ 2023-06-28 13:40 Tamar Christina
  2023-06-28 13:41 ` [PATCH 1/19]middle-end ifcvt: Support bitfield lowering of multiple-exit loops Tamar Christina
                   ` (42 more replies)
  0 siblings, 43 replies; 202+ messages in thread
From: Tamar Christina @ 2023-06-28 13:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: nd, rguenther, jlaw

[-- Attachment #1: Type: text/plain, Size: 10897 bytes --]

Hi All,

This patch adds initial support for early break vectorization in GCC.
The support is added for any target that implements a vector cbranch optab,
this includes both fully masked and non-masked targets.

Depending on the operation, the vectorizer may also require support for boolean
mask reductions using Inclusive OR.  This is however only checked then the
comparison would produce multiple statements.

Concretely the kind of loops supported are of the forms:

 for (int i = 0; i < N; i++)
 {
   <statements1>
   if (<condition>)
     {
       ...
       <action>;
     }
   <statements2>
 }

where <action> can be:
 - break
 - return
 - goto

Any number of statements can be used before the <action> occurs.

Since this is an initial version for GCC 14 it has the following limitations and
features:

- Only fixed sized iterations and buffers are supported.  That is to say any
  vectors loaded or stored must be to statically allocated arrays with known
  sizes. N must also be known.  This limitation is because our primary target
  for this optimization is SVE.  For VLA SVE we can't easily do cross page
  iteraion checks. The result is likely to also not be beneficial. For that
  reason we punt support for variable buffers till we have First-Faulting
  support in GCC.
- any stores in <statements1> should not be to the same objects as in
  <condition>.  Loads are fine as long as they don't have the possibility to
  alias.  More concretely, we block RAW dependencies when the intermediate value
  can't be separated fromt the store, or the store itself can't be moved.
- The number of loop iterations must be known,  this is just a temporarily
  limitation that I intend to address in GCC 14 itself as follow on patches.
- Prologue peeling, alignment peelinig and loop versioning are supported.
- Fully masked loops, unmasked loops and partially masked loops are supported
- Any number of loop early exits are supported.
- The early exit must be before the natural loop exit/latch.  The vectorizer is
  designed in way to propage phi-nodes downwards.  As such supporting this
  inverted control flow is hard.
- No support for epilogue vectorization.  The only epilogue supported is the
  scalar final one.  Epilogue vectorization would also not be profitable.
- Early breaks are only supported for inner loop vectorization.

I have pushed a branch to refs/users/tnfchris/heads/gcc-14-early-break

With the help of IPA and LTO this still gets hit quite often.  During bootstrap
it hit rather frequently.  Additionally TSVC s332, s481 and s482 all pass now
since these are tests for support for early exit vectorization.

This implementation does not support completely handling the early break inside
the vector loop itself but instead supports adding checks such that if we know
that we have to exit in the current iteration then we branch to scalar code to
actually do the final VF iterations which handles all the code in <action>.

niters analysis and the majority of the vectorizer with hardcoded single_exit
have been updated with the use of a new function vec_loop_iv value which returns
the exit the vectorizer wants to use as the main IV exit.

for niters the this exit is what determines the overall iterations as
that is the O(iters) for the loop.

For the scalar loop we know that whatever exit you take you have to perform at
most VF iterations.  For vector code we only case about the state of fully
performed iteration and reset the scalar code to the (partially) remaining loop.

This new version of the patch does the majority of the work in a new rewritten
loop peeling.  This new function maintains LCSSA all the way through and no
longer requires the touch up functions the vectorized used to incrementally
adjust them later on.  This means that aside from IV updates and guard edge
updates the early exit code is identical to the single exit cases.

When the loop is peeled during the copying I have to go through great lengths to
keep the dominators up to date.  All exits from the first loop are rewired to the
loop header of the second loop.  But this can change the immediate dominator.

The dominators can change again when we wire in the loop guard, as such peeling
now returns a list of dominators that need to be updated if a new guard edge is
added.

For the loop peeling we rewrite the loop form:


                     Header
                      ---
                      |x|
                       2
                       |
                       v
                -------3<------
     early exit |      |      |
                v      v      | latch
                7      4----->6
                |      |
                |      v
                |      8
                |      |
                |      v
                ------>5

into

                     Header
                      ---
                      |x|
                       2
                       |
                       v
                -------3<------
     early exit |      |      |
                v      v      | latch
                7      4----->6
                |      |
                |      v
                |      8
                |      |
                |      v
                |  New Header
                |     ---
                ----->|x|
                       9
                       |
                       v
                ------10<-----
     early exit |      |      |
                v      v      | latch
                14     11---->13
                |      |
                |      v
                |      12
                |      |
                |      v
                ------> 5

That is to say, the first vector loop executes so long as the early exit isn't
needed.  Once the exit is taken, the scalar code will perform at most VF extra
iterations.  The exact number depending on peeling and iteration start and which
exit was taken (natural or early).   For this scalar loop, all early exits are
treated the same.

When we vectorize we move any statement not related to the early break itself
and that would be incorrect to execute before the break (i.e. has side effects)
to after the break.  If this is not possible we decline to vectorize.

This means that we check at the start of iterations whether we are going to exit
or not.  During the analyis phase we check whether we are allowed to do this
moving of statements.  Also note that we only move the scalar statements, but
only do so after peeling but just before we start transforming statements.

Codegen:

for e.g.

#define N 803
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;
}

We generate for Adv. SIMD:

test4:
        adrp    x2, .LC0
        adrp    x3, .LANCHOR0
        dup     v2.4s, w0
        add     x3, x3, :lo12:.LANCHOR0
        movi    v4.4s, 0x4
        add     x4, x3, 3216
        ldr     q1, [x2, #:lo12:.LC0]
        mov     x1, 0
        mov     w2, 0
        .p2align 3,,7
.L3:
        ldr     q0, [x3, x1]
        add     v3.4s, v1.4s, v2.4s
        add     v1.4s, v1.4s, v4.4s
        cmhi    v0.4s, v0.4s, v2.4s
        umaxp   v0.4s, v0.4s, v0.4s
        fmov    x5, d0
        cbnz    x5, .L6
        add     w2, w2, 1
        str     q3, [x1, x4]
        str     q2, [x3, x1]
        add     x1, x1, 16
        cmp     w2, 200
        bne     .L3
        mov     w7, 3
.L2:
        lsl     w2, w2, 2
        add     x5, x3, 3216
        add     w6, w2, w0
        sxtw    x4, w2
        ldr     w1, [x3, x4, lsl 2]
        str     w6, [x5, x4, lsl 2]
        cmp     w0, w1
        bcc     .L4
        add     w1, w2, 1
        str     w0, [x3, x4, lsl 2]
        add     w6, w1, w0
        sxtw    x1, w1
        ldr     w4, [x3, x1, lsl 2]
        str     w6, [x5, x1, lsl 2]
        cmp     w0, w4
        bcc     .L4
        add     w4, w2, 2
        str     w0, [x3, x1, lsl 2]
        sxtw    x1, w4
        add     w6, w1, w0
        ldr     w4, [x3, x1, lsl 2]
        str     w6, [x5, x1, lsl 2]
        cmp     w0, w4
        bcc     .L4
        str     w0, [x3, x1, lsl 2]
        add     w2, w2, 3
        cmp     w7, 3
        beq     .L4
        sxtw    x1, w2
        add     w2, w2, w0
        ldr     w4, [x3, x1, lsl 2]
        str     w2, [x5, x1, lsl 2]
        cmp     w0, w4
        bcc     .L4
        str     w0, [x3, x1, lsl 2]
.L4:
        mov     w0, 0
        ret
        .p2align 2,,3
.L6:
        mov     w7, 4
        b       .L2

and for SVE:

test4:
        adrp    x2, .LANCHOR0
        add     x2, x2, :lo12:.LANCHOR0
        add     x5, x2, 3216
        mov     x3, 0
        mov     w1, 0
        cntw    x4
        mov     z1.s, w0
        index   z0.s, #0, #1
        ptrue   p1.b, all
        ptrue   p0.s, all
        .p2align 3,,7
.L3:
        ld1w    z2.s, p1/z, [x2, x3, lsl 2]
        add     z3.s, z0.s, z1.s
        cmplo   p2.s, p0/z, z1.s, z2.s
        b.any   .L2
        st1w    z3.s, p1, [x5, x3, lsl 2]
        add     w1, w1, 1
        st1w    z1.s, p1, [x2, x3, lsl 2]
        add     x3, x3, x4
        incw    z0.s
        cmp     w3, 803
        bls     .L3
.L5:
        mov     w0, 0
        ret
        .p2align 2,,3
.L2:
        cntw    x5
        mul     w1, w1, w5
        cbz     w5, .L5
        sxtw    x1, w1
        sub     w5, w5, #1
        add     x5, x5, x1
        add     x6, x2, 3216
        b       .L6
        .p2align 2,,3
.L14:
        str     w0, [x2, x1, lsl 2]
        cmp     x1, x5
        beq     .L5
        mov     x1, x4
.L6:
        ldr     w3, [x2, x1, lsl 2]
        add     w4, w0, w1
        str     w4, [x6, x1, lsl 2]
        add     x4, x1, 1
        cmp     w0, w3
        bcs     .L14
        mov     w0, 0
        ret

On the workloads this work is based on we see between 2-3x performance uplift
using this patch.

Follow up plan:
 - Boolean vectorization has several shortcomings.  I've filed PR110223 with the
   bigger ones that cause vectorization to fail with this patch.
 - SLP support.  This is planned for GCC 15 as for majority of the cases build
   SLP itself fails.  This means I'll need to spend time in making this more
   robust first.  Additionally it requires:
     * Adding support for vectorizing CFG (gconds)
     * Support for CFG to differ between vector and scalar loops.
   Both of which would be disruptive to the tree and I suspect I'll be handling
   fallouts from this patch for a while.  So I plan to work on the surrounding
   building blocks first for the remainder of the year.

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
Also ran across various workloads and no issues.

When closer to acceptance I will run on other targets as well and clean up
related testsuite fallouts there.

--- inline copy of patch -- 

-- 

[-- Attachment #2: rb17494.patch --]
[-- Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 202+ messages in thread
* [PATCH 2/21]middle-end testsuite: Add tests for early break vectorization
@ 2023-12-21 15:30 Tamar Christina
  2023-12-21 19:46 ` Richard Biener
  0 siblings, 1 reply; 202+ messages in thread
From: Tamar Christina @ 2023-12-21 15:30 UTC (permalink / raw)
  To: gcc-patches; +Cc: nd, rguenther, jlaw

[-- Attachment #1: Type: text/plain, Size: 128997 bytes --]

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

Bootstrapped Regtested x86_64-pc-linux-gnu and no issues.

On the tests I have disabled x86_64 on it's because the target is missing
cbranch for all types.  I think it should be possible to add them for the
missing type since all we care about is if a bit is set or not.

Bootstrap and Regtest on arm-none-linux-gnueabihf still running
and test on arm-none-eabi -march=armv8.1-m.main+mve -mfpu=auto running.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

	* doc/sourcebuild.texi (check_effective_target_vect_early_break_hw,
	check_effective_target_vect_early_break): Document.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp (add_options_for_vect_early_break,
	check_effective_target_vect_early_break_hw,
	check_effective_target_vect_early_break): New.
	* g++.dg/vect/vect-early-break_1.cc: New test.
	* g++.dg/vect/vect-early-break_2.cc: New test.
	* g++.dg/vect/vect-early-break_3.cc: New test.
	* gcc.dg/vect/vect-early-break-run_1.c: New test.
	* gcc.dg/vect/vect-early-break-run_10.c: New test.
	* gcc.dg/vect/vect-early-break-run_2.c: New test.
	* gcc.dg/vect/vect-early-break-run_3.c: New test.
	* gcc.dg/vect/vect-early-break-run_4.c: New test.
	* gcc.dg/vect/vect-early-break-run_5.c: New test.
	* gcc.dg/vect/vect-early-break-run_6.c: New test.
	* gcc.dg/vect/vect-early-break-run_7.c: New test.
	* gcc.dg/vect/vect-early-break-run_8.c: New test.
	* gcc.dg/vect/vect-early-break-run_9.c: New test.
	* gcc.dg/vect/vect-early-break-template_1.c: New test.
	* gcc.dg/vect/vect-early-break-template_2.c: New test.
	* gcc.dg/vect/vect-early-break_1.c: New test.
	* gcc.dg/vect/vect-early-break_10.c: New test.
	* gcc.dg/vect/vect-early-break_11.c: New test.
	* gcc.dg/vect/vect-early-break_12.c: New test.
	* gcc.dg/vect/vect-early-break_13.c: New test.
	* gcc.dg/vect/vect-early-break_14.c: New test.
	* gcc.dg/vect/vect-early-break_15.c: New test.
	* gcc.dg/vect/vect-early-break_16.c: New test.
	* gcc.dg/vect/vect-early-break_17.c: New test.
	* gcc.dg/vect/vect-early-break_18.c: New test.
	* gcc.dg/vect/vect-early-break_19.c: New test.
	* gcc.dg/vect/vect-early-break_2.c: New test.
	* gcc.dg/vect/vect-early-break_20.c: New test.
	* gcc.dg/vect/vect-early-break_21.c: New test.
	* gcc.dg/vect/vect-early-break_22.c: New test.
	* gcc.dg/vect/vect-early-break_23.c: New test.
	* gcc.dg/vect/vect-early-break_24.c: New test.
	* gcc.dg/vect/vect-early-break_25.c: New test.
	* gcc.dg/vect/vect-early-break_26.c: New test.
	* gcc.dg/vect/vect-early-break_27.c: New test.
	* gcc.dg/vect/vect-early-break_28.c: New test.
	* gcc.dg/vect/vect-early-break_29.c: New test.
	* gcc.dg/vect/vect-early-break_3.c: New test.
	* gcc.dg/vect/vect-early-break_30.c: New test.
	* gcc.dg/vect/vect-early-break_31.c: New test.
	* gcc.dg/vect/vect-early-break_32.c: New test.
	* gcc.dg/vect/vect-early-break_33.c: New test.
	* gcc.dg/vect/vect-early-break_34.c: New test.
	* gcc.dg/vect/vect-early-break_35.c: New test.
	* gcc.dg/vect/vect-early-break_36.c: New test.
	* gcc.dg/vect/vect-early-break_37.c: New test.
	* gcc.dg/vect/vect-early-break_38.c: New test.
	* gcc.dg/vect/vect-early-break_39.c: New test.
	* gcc.dg/vect/vect-early-break_4.c: New test.
	* gcc.dg/vect/vect-early-break_40.c: New test.
	* gcc.dg/vect/vect-early-break_41.c: New test.
	* gcc.dg/vect/vect-early-break_42.c: New test.
	* gcc.dg/vect/vect-early-break_43.c: New test.
	* gcc.dg/vect/vect-early-break_44.c: New test.
	* gcc.dg/vect/vect-early-break_45.c: New test.
	* gcc.dg/vect/vect-early-break_46.c: New test.
	* gcc.dg/vect/vect-early-break_47.c: New test.
	* gcc.dg/vect/vect-early-break_48.c: New test.
	* gcc.dg/vect/vect-early-break_49.c: New test.
	* gcc.dg/vect/vect-early-break_5.c: New test.
	* gcc.dg/vect/vect-early-break_50.c: New test.
	* gcc.dg/vect/vect-early-break_51.c: New test.
	* gcc.dg/vect/vect-early-break_52.c: New test.
	* gcc.dg/vect/vect-early-break_53.c: New test.
	* gcc.dg/vect/vect-early-break_54.c: New test.
	* gcc.dg/vect/vect-early-break_55.c: New test.
	* gcc.dg/vect/vect-early-break_56.c: New test.
	* gcc.dg/vect/vect-early-break_57.c: New test.
	* gcc.dg/vect/vect-early-break_58.c: New test.
	* gcc.dg/vect/vect-early-break_59.c: New test.
	* gcc.dg/vect/vect-early-break_6.c: New test.
	* gcc.dg/vect/vect-early-break_60.c: New test.
	* gcc.dg/vect/vect-early-break_61.c: New test.
	* gcc.dg/vect/vect-early-break_62.c: New test.
	* gcc.dg/vect/vect-early-break_63.c: New test.
	* gcc.dg/vect/vect-early-break_64.c: New test.
	* gcc.dg/vect/vect-early-break_65.c: New test.
	* gcc.dg/vect/vect-early-break_66.c: New test.
	* gcc.dg/vect/vect-early-break_67.c: New test.
	* gcc.dg/vect/vect-early-break_68.c: New test.
	* gcc.dg/vect/vect-early-break_69.c: New test.
	* gcc.dg/vect/vect-early-break_7.c: New test.
	* gcc.dg/vect/vect-early-break_70.c: New test.
	* gcc.dg/vect/vect-early-break_71.c: New test.
	* gcc.dg/vect/vect-early-break_72.c: New test.
	* gcc.dg/vect/vect-early-break_73.c: New test.
	* gcc.dg/vect/vect-early-break_74.c: New test.
	* gcc.dg/vect/vect-early-break_75.c: New test.
	* gcc.dg/vect/vect-early-break_76.c: New test.
	* gcc.dg/vect/vect-early-break_77.c: New test.
	* gcc.dg/vect/vect-early-break_78.c: New test.
	* gcc.dg/vect/vect-early-break_79.c: New test.
	* gcc.dg/vect/vect-early-break_8.c: New test.
	* gcc.dg/vect/vect-early-break_80.c: New test.
	* gcc.dg/vect/vect-early-break_81.c: New test.
	* gcc.dg/vect/vect-early-break_82.c: New test.
	* gcc.dg/vect/vect-early-break_83.c: New test.
	* gcc.dg/vect/vect-early-break_84.c: New test.
	* gcc.dg/vect/vect-early-break_85.c: New test.
	* gcc.dg/vect/vect-early-break_86.c: New test.
	* gcc.dg/vect/vect-early-break_87.c: New test.
	* gcc.dg/vect/vect-early-break_88.c: New test.
	* gcc.dg/vect/vect-early-break_89.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 4be67daedb20d394857c02739389cabf23c0d533..dee59041d7bc3fd63b61cc52ff171e844ed7bc1c 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1636,6 +1636,14 @@ 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 vectorization codegen of loops with early breaks.
+This requires an implementation of the cbranch optab for vectors.
+
+@item vect_early_break_hw
+Target supports hardware vectorization and running of loops with early breaks.
+This requires an implementation of the cbranch optab for vectors.
+
 @item vect_int
 Target supports hardware vectors of @code{int}.
 
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc
new file mode 100644
index 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+void fancy_abort(char *, int, const char *) __attribute__((__noreturn__));
+template <unsigned N, typename> struct poly_int_pod { int coeffs[N]; };
+template <unsigned N, typename> class poly_int : public poly_int_pod<N, int> {
+public:
+  template <typename Ca> poly_int &operator+=(const poly_int_pod<N, Ca> &);
+};
+template <unsigned N, typename C>
+template <typename Ca>
+poly_int<N, C> &poly_int<N, C>::operator+=(const poly_int_pod<N, Ca> &a) {
+  for (int i = 0; i < N; i++)
+    this->coeffs[i] += a.coeffs[i];
+  return *this;
+}
+template <unsigned N, typename Ca, typename Cb>
+poly_int<N, long> exact_div(poly_int_pod<N, Ca>, Cb) {
+  poly_int<N, long> r;
+  return r;
+}
+struct vec_prefix {
+  unsigned m_num;
+};
+struct vl_ptr;
+struct va_heap {
+  typedef vl_ptr default_layout;
+};
+template <typename, typename A, typename = typename A::default_layout>
+struct vec;
+template <typename T, typename A> struct vec<T, A, int> {
+  T &operator[](unsigned);
+  vec_prefix m_vecpfx;
+  T m_vecdata[];
+};
+template <typename T, typename A> T &vec<T, A, int>::operator[](unsigned ix) {
+  m_vecpfx.m_num ? fancy_abort("", 9, __FUNCTION__), 0 : 0;
+  return m_vecdata[ix];
+}
+template <typename T> struct vec<T, va_heap> {
+  T &operator[](unsigned ix) { return m_vec[ix]; }
+  vec<T, va_heap, int> m_vec;
+};
+class auto_vec : public vec<poly_int<2, long>, va_heap> {};
+template <typename> class vector_builder : public auto_vec {};
+class int_vector_builder : public vector_builder<int> {
+public:
+  int_vector_builder(poly_int<2, long>, int, int);
+};
+bool vect_grouped_store_supported() {
+  int i;
+  poly_int<2, long> nelt;
+  int_vector_builder sel(nelt, 2, 3);
+  for (i = 0; i < 6; i++)
+    sel[i] += exact_div(nelt, 2);
+}
+
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc
new file mode 100644
index 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+void fancy_abort(char *, int, const char *) __attribute__((__noreturn__));
+template <unsigned N, typename> struct poly_int_pod { int coeffs[N]; };
+template <unsigned N, typename> class poly_int : public poly_int_pod<N, int> {
+public:
+  template <typename Ca> poly_int &operator+=(const poly_int_pod<N, Ca> &);
+};
+template <unsigned N, typename C>
+template <typename Ca>
+poly_int<N, C> &poly_int<N, C>::operator+=(const poly_int_pod<N, Ca> &a) {
+  for (int i = 0; i < N; i++)
+    this->coeffs[i] += a.coeffs[i];
+  return *this;
+}
+template <unsigned N, typename Ca, typename Cb>
+poly_int<N, long> exact_div(poly_int_pod<N, Ca>, Cb) {
+  poly_int<N, long> r;
+  return r;
+}
+struct vec_prefix {
+  unsigned m_num;
+};
+struct vl_ptr;
+struct va_heap {
+  typedef vl_ptr default_layout;
+};
+template <typename, typename A, typename = typename A::default_layout>
+struct vec;
+template <typename T, typename A> struct vec<T, A, int> {
+  T &operator[](unsigned);
+  vec_prefix m_vecpfx;
+  T m_vecdata[];
+};
+template <typename T, typename A> T &vec<T, A, int>::operator[](unsigned ix) {
+  m_vecpfx.m_num ? fancy_abort("", 9, __FUNCTION__), 0 : 0;
+  return m_vecdata[ix];
+}
+template <typename T> struct vec<T, va_heap> {
+  T &operator[](unsigned ix) { return m_vec[ix]; }
+  vec<T, va_heap, int> m_vec;
+};
+class auto_vec : public vec<poly_int<2, long>, va_heap> {};
+template <typename> class vector_builder : public auto_vec {};
+class int_vector_builder : public vector_builder<int> {
+public:
+  int_vector_builder(poly_int<2, long>, int, int);
+};
+bool vect_grouped_store_supported() {
+  int i;
+  poly_int<2, long> nelt;
+  int_vector_builder sel(nelt, 2, 3);
+  for (i = 0; i < 6; i++)
+    sel[i] += exact_div(nelt, 2);
+}
+
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a12e5ca434b2ac37c03dbaa12273fd8e5aa2018c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+int aarch64_advsimd_valid_immediate_hs_val32;
+bool aarch64_advsimd_valid_immediate_hs() {
+  for (int shift = 0; shift < 32; shift += 8)
+    if (aarch64_advsimd_valid_immediate_hs_val32 & shift)
+      return aarch64_advsimd_valid_immediate_hs_val32;
+  for (;;)
+    ;
+}
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..fb8faea3221f140ab84e0e9a5d4bde6c464830af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..2fc8551db41e9bfd34e9feb28b9031fd2fec1c2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..8c6d4cebb1901e0882911717f1b6faa66cf8c9ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..ad25db4e6e224703ff2dabdf1f757f09be254f78
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..804d640cd10b34a335f5a35361e32faa1a1f7adc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..fd8086aab0ded1990b896bdd0d3a24f3567c33ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..3b4490df0ebd22f2706a66c56eb7e56a842cd6be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..ab9ff90c3d09f65539689a5a3420facd18fc0938
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..c2ea839d71673957f41c4b77270c31ea2acfd1e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..a221c879387b5a3462f8ebb2cb496f796e84e2f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..acc088282ad0b82574d43251942e5cbba630c295
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-template_1.c
@@ -0,0 +1,50 @@
+#include "tree-vect.h"
+
+#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 ()
+{
+  check_vect ();
+
+  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..dce852e760a24355baa6c1c50040554709e7ef4b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-template_2.c
@@ -0,0 +1,53 @@
+#include "tree-vect.h"
+
+#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 ()
+{
+  check_vect ();
+
+  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..c1da23e691cf0b8f978e2aa5b079dfafb0489033
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_1.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..49bae484967f6293d3b14138ee5bad5fc0358d96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_10.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..8085383a5687804086eec7e243ba0f7813d33621
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_11.c
@@ -0,0 +1,32 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..8eeec820be5cf2372040644c946417c90073de70
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_12.c
@@ -0,0 +1,32 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..58f5f0ae7e2eace4653e2d6788db80624b714ff5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_13.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..3f0a61fe8b7141afa4ab4d2c147f56e14542711c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_14.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..08e7faf240238376df180cae1177a25cc00e19ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_15.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..6bb71555be2079c3f45092d1f3e604226ba271e3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_16.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..264031874eedc72fc28500baeb8ec267517d908a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_17.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..babc79c74c39b5beedd293f2138f0c46846543b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_18.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..9555c16a0821fac9e2fa00aebe92447335b09ceb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_19.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..5c32bf94409e9743e72429985ab3bf13aab8f2c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_2.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..039aac7fd84cf6131e1ea401b87385a32b545e67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_20.c
@@ -0,0 +1,38 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..dbe3f8265115fabd0bd26a166ea60318b0be5377
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_21.c
@@ -0,0 +1,38 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#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..b3f5984f682f30f79331d48a264c2cc4af3e2503
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_22.c
@@ -0,0 +1,45 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_perm } */
+/* { dg-require-effective-target vect_early_break_hw } */
+
+#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..3e435af44471b0db2c02e2aaab4c3c48ffc9b763
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_23.c
@@ -0,0 +1,65 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+#include "tree-vect.h"
+
+#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)
+{
+  check_vect ();
+
+  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..fa2a17ed96f1afd81c3425b70ab2720044334e8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_24.c
@@ -0,0 +1,46 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_double } */
+/* { dg-require-effective-target vect_early_break_hw } */
+
+#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..4d8b47ed9aaae995945830955e242b713f48b786
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_25.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { 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 "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..47d2a50218bd1b32fe43edcaaabb1079d0b26223
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_26.c
@@ -0,0 +1,44 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..ed7b31757a0ccdede020e36f5a64aaaa1e94a5c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_27.c
@@ -0,0 +1,19 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..9c980b8453d9cca8319aef41a2cd3cdda47b3c32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_28.c
@@ -0,0 +1,16 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..b66fe204caee6a5b143c670e07de9a4a3b77455a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_29.c
@@ -0,0 +1,17 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..4afbc7266765fc4639b2554c6361e0825411f148
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_3.c
@@ -0,0 +1,21 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..3f6e802ae8f0714c321e62fc7412e8047fe7557a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_30.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..1eaf52aaa8528189ab0c0b961e662d3bc4518adc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_31.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..038be402c2b8ce4c797465214217788cb2f50b17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_32.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..74116143b2609e23df42ddc740360f6b33bcd93c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_33.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..63f1bb4254c60190e690002f6546d160a8f3ffde
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_34.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..4c0078fbc6758fec7db9562ba51f2cd733d97d41
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_35.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..a83994035b9d074b57349bb9063e80dbb65020d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_36.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..b7559a9adc7ce28e3ef6851c0d934170ea5878b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_37.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..8062fbbf6422af6a2e42de9574e88d411a8fb917
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_38.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..9d3c6a5dffe3be4a7759b150e330d18144ab5ce5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_39.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..bd7107c1736cdc21dc6b9e35e0293286c18299ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_4.c
@@ -0,0 +1,24 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..428f6249fa68f00bd70fa660dd9c1bb508181f4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c
@@ -0,0 +1,27 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..31a8ed2d3e2f33978aae04c1ac02b104896c6151
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_41.c
@@ -0,0 +1,25 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..f1ee2f7e9a667968810f4ef28091a1e26c357a30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_42.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..7e9f635a0b5a8f6fb5da5d7cc6a426f343af4b56
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_43.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..7e9f635a0b5a8f6fb5da5d7cc6a426f343af4b56
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_44.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..7031f237ecceb45057098989aaf12e68e33c1f5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_45.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..c9aad909ffd80aee247e2f2803990167aea7cddd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_46.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..ef90380ea197fdec549ab3f6ea95a8ed2f07278e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_47.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..0efbb2836bfdd6acc5a9b45a362cc99d3a7e5d97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_48.c
@@ -0,0 +1,14 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..6c4ee40fd5d36782ad77c7ae98daf9a7998198d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_49.c
@@ -0,0 +1,25 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..1468c795b6201f347fe53bc85ddc46bc96c73821
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_5.c
@@ -0,0 +1,25 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..b3cf2d7f05f0445cdc2d6a3961c4c6f955f92220
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_50.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..c06eff5a385f4309ee3a03d2bb697a12976537fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_51.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..86a632f2a82291b3063a57cd62f2310ed6d5c747
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c
@@ -0,0 +1,21 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" { target { ! "x86_64-*-* i?86-*-*" } } } } */
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..a02d5986ba3cfc117b19305c5e96711299996931
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..bfc78c262751065e4204babb907deb2366974f2b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_54.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..c2a823bff7a40932e9cec6aad5a19ac42c517eb0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_55.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..9096f66647c7b3cb430562d35f8ce076244f7c11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_56.c
@@ -0,0 +1,102 @@
+/* { dg-add-options 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 } */
+/* { dg-add-options bind_pic_locally } */
+/* { dg-require-effective-target vect_early_break_hw } */
+
+#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..319bd125c3156f13c300ff2b94d269bb9ec29e97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_57.c
@@ -0,0 +1,32 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+/* { dg-final { scan-tree-dump "epilog loop required" "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..5f18f06d423f495af9331d353fd4e42ae3d59d7c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_58.c
@@ -0,0 +1,19 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..aec4ee457d7862099b13d5c6b3c04d0405379a18
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_59.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..7b870e9c60dcac6164d879dd70c1fc07ec0221fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_6.c
@@ -0,0 +1,27 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..75b35f8d423f7a389e85e8b51e8e579ee4d07cf1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_60.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..c789ec01f32c6b958c6a3663531a7b7517b94477
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..aaad62ef8d789ea611824e64eca41b45c850a41c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_62.c
@@ -0,0 +1,21 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..1d9ff4ad6bacd6e80264dadf797c345f51c57299
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_63.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* 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..aaa2a46fb67e0e50644e1f8f78cf8f2c175931cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..23a8341b529d8edef38b12f110a9ae7ce51edf09
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_65.c
@@ -0,0 +1,20 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" 0 "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..e54cc5e1260e3c7efc245987e754f4fc60e0e0ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_66.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+int a[0];
+int b;
+
+void g();
+
+void f() {
+  int d, e;
+  for (; e; e++) {
+    int c;
+    switch (b)
+    case '9': {
+      for (; d < 1; d++)
+        if (a[d])
+          c = 1;
+      break;
+    case '<':
+      g();
+      c = 0;
+    }
+      while (c)
+        ;
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c
new file mode 100644
index 0000000000000000000000000000000000000000..e9da46439f274781d37ab0b2ce4aabd48a98778d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c
@@ -0,0 +1,42 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+
+
+int main()
+{
+  int var6 = -1267827473;
+  do {
+      ++var6;
+      double s1_115[4], s2_108[4];
+      int var8 = -161498264;
+      do {
+	  ++var8;
+	  int var12 = 1260960076;
+	  for (; var12 <= 1260960080; ++var12) {
+	      int var13 = 1960990937;
+	      do {
+		  ++var13;
+		  int var14 = 2128638723;
+		  for (; var14 <= 2128638728; ++var14) {
+		      int var22 = -1141190839;
+		      do {
+			  ++var22;
+			  if (s2_108 > s1_115) {
+			      int var23 = -890798748;
+			      do {
+				  long long e_119[4];
+			      } while (var23 <= -890798746);
+			  }
+		      } while (var22 <= -1141190829);
+		  }
+	      } while (var13 <= 1960990946);
+	  }
+      } while (var8 <= -161498254);
+  } while (var6 <= -1267827462);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c
new file mode 100644
index 0000000000000000000000000000000000000000..dfa90b557e87ca67d3d7a66d23084a4fff6fd4b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c
@@ -0,0 +1,42 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 800
+#endif
+unsigned vect_a1[N];
+unsigned vect_b1[N];
+unsigned vect_c1[N];
+unsigned vect_d1[N];
+  
+unsigned vect_a2[N];
+unsigned vect_b2[N];
+unsigned vect_c2[N];
+unsigned vect_d2[N];
+
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b1[i] += x + i;
+   vect_c1[i] += x + i;
+   vect_d1[i] += x + i;
+   if (vect_a1[i]*2 != x)
+     break;
+   vect_a1[i] = x;
+
+   vect_b2[i] += x + i;
+   vect_c2[i] += x + i;
+   vect_d2[i] += x + i;
+   if (vect_a2[i]*2 != x)
+     break;
+   vect_a2[i] = x;
+
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c
new file mode 100644
index 0000000000000000000000000000000000000000..916351a14ab4c4509d9f291805ed35ebf2396639
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c
@@ -0,0 +1,80 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}									\
+									\
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_ffs (ints[i]) != my_ffs (ints[i]))
+	abort ();
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	abort ();
+    }
+
+  exit (0);
+}
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
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..8c86c5034d7522b3733543fb384a23c5d6ed0fcf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_7.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <complex.h>
+
+#define N 1024
+complex double vect_a[N];
+complex double vect_b[N];
+  
+complex double test4(complex double x)
+{
+ complex double ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] += x + i;
+   if (vect_a[i] == x)
+     break;
+   vect_a[i] += x * vect_b[i];
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c
new file mode 100644
index 0000000000000000000000000000000000000000..3dbedf610406e222253636aa84c68b6544c2fdbb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c
@@ -0,0 +1,69 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c
new file mode 100644
index 0000000000000000000000000000000000000000..b15c8de3ed752e54eecc6b7c2d364b2d2acba25b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c
@@ -0,0 +1,71 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_ffs (ints[i]) != my_ffs (ints[i]))
+	abort ();
+    }
+
+  exit (0);
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c
new file mode 100644
index 0000000000000000000000000000000000000000..c6d1e9f5fd26d1348db9287a3adcc57ee4c2fc37
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c
@@ -0,0 +1,151 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ctz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i;								\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_ctz (ints[i]) != my_ctz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f40dd07e54316b1f97a12914dfce9b815c6215f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c
@@ -0,0 +1,71 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c
new file mode 100644
index 0000000000000000000000000000000000000000..afd238618b30ed905ca2f790bc94d019d7bf8019
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c
@@ -0,0 +1,165 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
+    abort ();								
+
+#if BITSIZEOF_INT == 32
+  TEST(0x00000000UL,);
+  TEST(0x00000001UL,);
+  TEST(0x80000000UL,);
+  TEST(0x40000000UL,);
+  TEST(0x00010000UL,);
+  TEST(0x00008000UL,);
+  TEST(0xa5a5a5a5UL,);
+  TEST(0x5a5a5a5aUL,);
+  TEST(0xcafe0000UL,);
+  TEST(0x00cafe00UL,);
+  TEST(0x0000cafeUL,);
+  TEST(0xffffffffUL,);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed27f8635730ff0d8803517c72693625a2feddef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c
@@ -0,0 +1,234 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}									\
+									\
+int my_ctz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i;								\
+}									\
+									\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}									\
+									\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}									\
+									\
+__attribute__((noinline)) \
+int my_popcount##suffix(type x) {					\
+    int i;								\
+    int count = 0;							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << i))					\
+	    count++;							\
+    return count;							\
+}									\
+									\
+__attribute__((noinline)) \
+int my_parity##suffix(type x) {						\
+    int i;								\
+    int count = 0;							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << i))					\
+	    count++;							\
+    return count & 1;							\
+}
+
+MAKE_FUNS (ll, unsigned long long);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(longlongs); i++)
+    {
+      if (__builtin_ffsll (longlongs[i]) != my_ffsll (longlongs[i]))
+	abort ();
+      if (longlongs[i] != 0
+	  && __builtin_clzll (longlongs[i]) != my_clzll (longlongs[i]))
+	abort ();
+      if (longlongs[i] != 0
+	  && __builtin_ctzll (longlongs[i]) != my_ctzll (longlongs[i]))
+	abort ();
+      if (__builtin_clrsbll (longlongs[i]) != my_clrsbll (longlongs[i]))
+	abort ();
+      if (__builtin_popcountll (longlongs[i]) != my_popcountll (longlongs[i]))
+	abort ();
+      if (__builtin_parityll (longlongs[i]) != my_parityll (longlongs[i]))
+	abort ();
+    }
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_ffs##suffix (x) != my_ffs##suffix (x))			\
+    abort ();								\
+
+#if BITSIZEOF_LONG_LONG == 64
+  TEST(0x0000000000000000ULL, ll);
+  TEST(0x0000000000000001ULL, ll);
+  TEST(0x8000000000000000ULL, ll);
+  TEST(0x0000000000000002ULL, ll);
+  TEST(0x4000000000000000ULL, ll);
+  TEST(0x0000000100000000ULL, ll);
+  TEST(0x0000000080000000ULL, ll);
+  TEST(0xa5a5a5a5a5a5a5a5ULL, ll);
+  TEST(0x5a5a5a5a5a5a5a5aULL, ll);
+  TEST(0xcafecafe00000000ULL, ll);
+  TEST(0x0000cafecafe0000ULL, ll);
+  TEST(0x00000000cafecafeULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7d8e279c67008bf4e35c802ab48f1b373827392
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c
@@ -0,0 +1,169 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}									\
+									\
+
+MAKE_FUNS (, unsigned);
+MAKE_FUNS (ll, unsigned long long);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_clrsb (ints[i]) != my_clrsb (ints[i]))
+	abort ();
+    }
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
+    abort ();								
+
+#if BITSIZEOF_LONG_LONG == 64
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_77.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_77.c
new file mode 100644
index 0000000000000000000000000000000000000000..225106aab0a3efc7536de6f6e45bc6ff16210ea8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_77.c
@@ -0,0 +1,34 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+double x[1024];
+int a[1024];
+double __attribute__((noipa)) foo  ()
+{
+  double sum = 0.0;
+  for (int i = 0 ; i < 1023; ++i)
+    {
+      sum += x[i];
+      if (a[i])
+        break;
+    }
+  return sum;
+}
+
+int main()
+{
+  check_vect ();
+
+  for (int i = 0; i < 1024; ++i)
+    x[i] = i;
+  a[19] = 1;
+  if (foo () != 190.)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_78.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_78.c
new file mode 100644
index 0000000000000000000000000000000000000000..f93babc069e10b4709b138115c6576c3f43bb29c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_78.c
@@ -0,0 +1,77 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+
+int
+main (void)
+{
+  check_vect ();
+
+#define TEST(x, suffix)							\
+  if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
+    abort ();								
+
+#if BITSIZEOF_INT == 32
+  TEST(0xffffffffUL,);
+#endif
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_79.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_79.c
new file mode 100644
index 0000000000000000000000000000000000000000..3f21be7625149dd476c15e5fa7ea9899d6a42f43
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_79.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+
+#undef N
+#define N 32
+
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < 1024; 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_8.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_8.c
new file mode 100644
index 0000000000000000000000000000000000000000..84e19423e2e61144cc575fb992b5f23d480ab89d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_8.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+
+#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_80.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_80.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f563b788ac7037adc7c629fb708e9a6885a6e93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_80.c
@@ -0,0 +1,49 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+extern void abort ();
+
+int x;
+__attribute__ ((noinline, noipa))
+void foo (int *a, int *b)
+{
+  int local_x = x;
+  for (int i = 0; i < 1024; ++i)
+    {
+      if (i + local_x == 13)
+        break;
+      a[i] = 2 * b[i];
+    }
+}
+
+int main ()
+{
+
+  check_vect ();
+
+  int a[1024] = {0};
+  int b[1024] = {0};
+
+  for (int i = 0; i < 1024; i++)
+    b[i] = i;
+
+  x = -512;
+  foo (a, b);
+
+  if (a[524] != 1048)
+    abort ();
+
+  if (a[525] != 0)
+    abort ();
+
+  if (a[1023] != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_81.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_81.c
new file mode 100644
index 0000000000000000000000000000000000000000..8a8c076ba92ca6fef419cb23b457a23555c61c64
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_81.c
@@ -0,0 +1,31 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+/* { dg-final { scan-tree-dump "epilog loop required" "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 - 3; 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_82.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_82.c
new file mode 100644
index 0000000000000000000000000000000000000000..0e9b2d8d385c556063a3c6fcb14383317b056a79
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_82.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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 t)
+{
+ complex double ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_a[i] = t + i;
+   if (vect_a[i] == x)
+     return i;
+   vect_a[i] += x * vect_a[i];
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_83.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_83.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b0e3fd6c5f5430b9139e34d1913acc329e5bc4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_83.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+
+#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++)
+ {
+   volatile complex double z = vect_b[i];
+   vect_b[i] = x + i + z;
+   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_84.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_84.c
new file mode 100644
index 0000000000000000000000000000000000000000..242ba453533e40f23dd29d27cbc419ca98e2b77c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_84.c
@@ -0,0 +1,44 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <stdbool.h>
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 17
+#endif
+bool vect_a[N] = { false, false, true, false, false, false,
+                   false, false, false, false, false, false,
+                   false, false, false, false, false };
+unsigned vect_b[N] = { 0 };
+
+__attribute__ ((noinline, noipa))
+unsigned test4(bool x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   if (vect_a[i] == x)
+     return 1;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+extern void abort ();
+
+int main ()
+{
+  check_vect ();
+
+  if (test4 (true) != 1)
+    abort ();
+
+  if (vect_b[2] != 0 && vect_b[1] == 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_85.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_85.c
new file mode 100644
index 0000000000000000000000000000000000000000..3df376935735bc3ad60cb5762962380e0627174a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_85.c
@@ -0,0 +1,40 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 5
+#endif
+int vect_a[N] = { 5, 4, 8, 4, 6 };
+unsigned vect_b[N] = { 0 };
+
+__attribute__ ((noinline, noipa))
+unsigned test4(int x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   if (vect_a[i] > x)
+     return 1;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+extern void abort ();
+
+int main ()
+{
+  check_vect ();
+
+  if (test4 (7) != 1)
+    abort ();
+
+  if (vect_b[2] != 0 && vect_b[1] == 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_86.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_86.c
new file mode 100644
index 0000000000000000000000000000000000000000..85c0d3a927727359e625d97763f426a885c51072
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_86.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-std=gnu89" } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include "tree-vect.h"
+
+extern void abort ();
+extern void exit (int);
+
+__attribute__((noinline, noipa))
+int f(x) {
+  int i;
+  for (i = 0; i < 8 && (x & 1) == 1; i++)
+    x >>= 1;
+  return i;
+}
+main() {
+  check_vect ();
+
+  if (f(4) != 0)
+    abort();
+  exit(0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_87.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_87.c
new file mode 100644
index 0000000000000000000000000000000000000000..3dce0c439bff2e84dad66f384df499bc096ec904
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_87.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-std=gnu89" } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include "tree-vect.h"
+
+extern void abort ();
+extern void exit (int);
+
+__attribute__((noinline, noipa))
+int f(x) {
+  int i;
+  for (i = 0; i < 8 && (x & 1) == 0; i++)
+    x >>= 1;
+  return i;
+}
+main() {
+  check_vect ();
+
+  if (f(4) != 2)
+    abort();
+  exit(0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_88.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_88.c
new file mode 100644
index 0000000000000000000000000000000000000000..b392dd46553994d813761da41c42989a79b90119
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_88.c
@@ -0,0 +1,41 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast --param vect-partial-vector-usage=2" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 5
+#endif
+float vect_a[N] = { 5.1f, 4.2f, 8.0f, 4.25f, 6.5f };
+unsigned vect_b[N] = { 0 };
+
+__attribute__ ((noinline, noipa))
+unsigned test4(double x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+extern void abort ();
+
+int main ()
+{
+  check_vect ();
+
+  if (test4 (7.0) != 0)
+    abort ();
+
+  if (vect_b[2] != 0 && vect_b[1] == 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_89.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_89.c
new file mode 100644
index 0000000000000000000000000000000000000000..39b6313b3a15be335a27ae5b90edb125bdccaee3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_89.c
@@ -0,0 +1,21 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-w" } */
+
+char *a;
+extern void d();
+void b() {
+  int c = 0;
+  while (c < 16) {
+    switch (a[c]) {
+    case '"':
+    case '\'':
+      c++;
+      continue;
+    }
+    break;
+  }
+  if (c)
+    d();
+}
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..12f09c61c331d1d0a66623da171804c10cea2051
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_9.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_a[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 7f13ff0ca565efdf19065811f3301db897329073..1fcb2da53b469d0f19782ace6c9539dbe269b793 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4050,6 +4050,58 @@ proc check_effective_target_vect_int { } {
 	}}]
 }
 
+# Return 1 if the target supports 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*-*-*]
+	|| [check_effective_target_arm_v8_neon_ok]
+	|| ([check_effective_target_arm_v8_1m_mve_fp_ok]
+	     && [check_effective_target_arm_little_endian])
+	|| [check_effective_target_sse4]
+	}}]
+}
+
+# Return 1 if the target supports hardware execution of early breaks,
+# 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_early_break_hw { } {
+    return [check_cached_effective_target_indexed vect_early_break_hw {
+      expr {
+	[istarget aarch64*-*-*]
+	|| [check_effective_target_arm_v8_neon_hw]
+	|| ([check_effective_target_arm_mve_hw]
+	     && [check_effective_target_arm_little_endian])
+	|| [check_sse4_hw_available]
+	}}]
+}
+
+proc add_options_for_vect_early_break { flags } {
+    if { ! [check_effective_target_vect_early_break] } {
+	return "$flags"
+    }
+
+    if { [check_effective_target_arm_v8_neon_ok] } {
+	global et_arm_v8_neon_flags
+	return "$flags $et_arm_v8_neon_flags -march=armv8-a"
+    }
+
+    if { [check_effective_target_arm_v8_1m_mve_fp_ok] } {
+	global et_arm_v8_1m_mve_fp_flags
+	return "$flags $et_arm_v8_1m_mve_fp_flags"
+    }
+
+    if { [check_effective_target_sse4] } {
+	return "$flags -msse4.1"
+    }
+}
+
 # Return 1 if the target supports hardware vectorization of complex additions of
 # byte, 0 otherwise.
 #




-- 

[-- Attachment #2: rb17962.patch --]
[-- Type: text/plain, Size: 122605 bytes --]

diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 4be67daedb20d394857c02739389cabf23c0d533..dee59041d7bc3fd63b61cc52ff171e844ed7bc1c 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1636,6 +1636,14 @@ 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 vectorization codegen of loops with early breaks.
+This requires an implementation of the cbranch optab for vectors.
+
+@item vect_early_break_hw
+Target supports hardware vectorization and running of loops with early breaks.
+This requires an implementation of the cbranch optab for vectors.
+
 @item vect_int
 Target supports hardware vectors of @code{int}.
 
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc
new file mode 100644
index 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_1.cc
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+void fancy_abort(char *, int, const char *) __attribute__((__noreturn__));
+template <unsigned N, typename> struct poly_int_pod { int coeffs[N]; };
+template <unsigned N, typename> class poly_int : public poly_int_pod<N, int> {
+public:
+  template <typename Ca> poly_int &operator+=(const poly_int_pod<N, Ca> &);
+};
+template <unsigned N, typename C>
+template <typename Ca>
+poly_int<N, C> &poly_int<N, C>::operator+=(const poly_int_pod<N, Ca> &a) {
+  for (int i = 0; i < N; i++)
+    this->coeffs[i] += a.coeffs[i];
+  return *this;
+}
+template <unsigned N, typename Ca, typename Cb>
+poly_int<N, long> exact_div(poly_int_pod<N, Ca>, Cb) {
+  poly_int<N, long> r;
+  return r;
+}
+struct vec_prefix {
+  unsigned m_num;
+};
+struct vl_ptr;
+struct va_heap {
+  typedef vl_ptr default_layout;
+};
+template <typename, typename A, typename = typename A::default_layout>
+struct vec;
+template <typename T, typename A> struct vec<T, A, int> {
+  T &operator[](unsigned);
+  vec_prefix m_vecpfx;
+  T m_vecdata[];
+};
+template <typename T, typename A> T &vec<T, A, int>::operator[](unsigned ix) {
+  m_vecpfx.m_num ? fancy_abort("", 9, __FUNCTION__), 0 : 0;
+  return m_vecdata[ix];
+}
+template <typename T> struct vec<T, va_heap> {
+  T &operator[](unsigned ix) { return m_vec[ix]; }
+  vec<T, va_heap, int> m_vec;
+};
+class auto_vec : public vec<poly_int<2, long>, va_heap> {};
+template <typename> class vector_builder : public auto_vec {};
+class int_vector_builder : public vector_builder<int> {
+public:
+  int_vector_builder(poly_int<2, long>, int, int);
+};
+bool vect_grouped_store_supported() {
+  int i;
+  poly_int<2, long> nelt;
+  int_vector_builder sel(nelt, 2, 3);
+  for (i = 0; i < 6; i++)
+    sel[i] += exact_div(nelt, 2);
+}
+
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc
new file mode 100644
index 0000000000000000000000000000000000000000..810d990e3efab0cf0363a3b76481f2cb649ad3ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_2.cc
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+void fancy_abort(char *, int, const char *) __attribute__((__noreturn__));
+template <unsigned N, typename> struct poly_int_pod { int coeffs[N]; };
+template <unsigned N, typename> class poly_int : public poly_int_pod<N, int> {
+public:
+  template <typename Ca> poly_int &operator+=(const poly_int_pod<N, Ca> &);
+};
+template <unsigned N, typename C>
+template <typename Ca>
+poly_int<N, C> &poly_int<N, C>::operator+=(const poly_int_pod<N, Ca> &a) {
+  for (int i = 0; i < N; i++)
+    this->coeffs[i] += a.coeffs[i];
+  return *this;
+}
+template <unsigned N, typename Ca, typename Cb>
+poly_int<N, long> exact_div(poly_int_pod<N, Ca>, Cb) {
+  poly_int<N, long> r;
+  return r;
+}
+struct vec_prefix {
+  unsigned m_num;
+};
+struct vl_ptr;
+struct va_heap {
+  typedef vl_ptr default_layout;
+};
+template <typename, typename A, typename = typename A::default_layout>
+struct vec;
+template <typename T, typename A> struct vec<T, A, int> {
+  T &operator[](unsigned);
+  vec_prefix m_vecpfx;
+  T m_vecdata[];
+};
+template <typename T, typename A> T &vec<T, A, int>::operator[](unsigned ix) {
+  m_vecpfx.m_num ? fancy_abort("", 9, __FUNCTION__), 0 : 0;
+  return m_vecdata[ix];
+}
+template <typename T> struct vec<T, va_heap> {
+  T &operator[](unsigned ix) { return m_vec[ix]; }
+  vec<T, va_heap, int> m_vec;
+};
+class auto_vec : public vec<poly_int<2, long>, va_heap> {};
+template <typename> class vector_builder : public auto_vec {};
+class int_vector_builder : public vector_builder<int> {
+public:
+  int_vector_builder(poly_int<2, long>, int, int);
+};
+bool vect_grouped_store_supported() {
+  int i;
+  poly_int<2, long> nelt;
+  int_vector_builder sel(nelt, 2, 3);
+  for (i = 0; i < 6; i++)
+    sel[i] += exact_div(nelt, 2);
+}
+
diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc b/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a12e5ca434b2ac37c03dbaa12273fd8e5aa2018c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/vect-early-break_3.cc
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-w -O2" } */
+
+int aarch64_advsimd_valid_immediate_hs_val32;
+bool aarch64_advsimd_valid_immediate_hs() {
+  for (int shift = 0; shift < 32; shift += 8)
+    if (aarch64_advsimd_valid_immediate_hs_val32 & shift)
+      return aarch64_advsimd_valid_immediate_hs_val32;
+  for (;;)
+    ;
+}
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..fb8faea3221f140ab84e0e9a5d4bde6c464830af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_1.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..2fc8551db41e9bfd34e9feb28b9031fd2fec1c2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_10.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..8c6d4cebb1901e0882911717f1b6faa66cf8c9ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_2.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..ad25db4e6e224703ff2dabdf1f757f09be254f78
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_3.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..804d640cd10b34a335f5a35361e32faa1a1f7adc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_4.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..fd8086aab0ded1990b896bdd0d3a24f3567c33ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_5.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..3b4490df0ebd22f2706a66c56eb7e56a842cd6be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_6.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..ab9ff90c3d09f65539689a5a3420facd18fc0938
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_7.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..c2ea839d71673957f41c4b77270c31ea2acfd1e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_8.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..a221c879387b5a3462f8ebb2cb496f796e84e2f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-run_9.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..acc088282ad0b82574d43251942e5cbba630c295
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-template_1.c
@@ -0,0 +1,50 @@
+#include "tree-vect.h"
+
+#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 ()
+{
+  check_vect ();
+
+  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..dce852e760a24355baa6c1c50040554709e7ef4b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break-template_2.c
@@ -0,0 +1,53 @@
+#include "tree-vect.h"
+
+#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 ()
+{
+  check_vect ();
+
+  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..c1da23e691cf0b8f978e2aa5b079dfafb0489033
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_1.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..49bae484967f6293d3b14138ee5bad5fc0358d96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_10.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..8085383a5687804086eec7e243ba0f7813d33621
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_11.c
@@ -0,0 +1,32 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..8eeec820be5cf2372040644c946417c90073de70
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_12.c
@@ -0,0 +1,32 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..58f5f0ae7e2eace4653e2d6788db80624b714ff5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_13.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..3f0a61fe8b7141afa4ab4d2c147f56e14542711c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_14.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..08e7faf240238376df180cae1177a25cc00e19ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_15.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..6bb71555be2079c3f45092d1f3e604226ba271e3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_16.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..264031874eedc72fc28500baeb8ec267517d908a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_17.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..babc79c74c39b5beedd293f2138f0c46846543b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_18.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..9555c16a0821fac9e2fa00aebe92447335b09ceb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_19.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..5c32bf94409e9743e72429985ab3bf13aab8f2c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_2.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..039aac7fd84cf6131e1ea401b87385a32b545e67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_20.c
@@ -0,0 +1,38 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..dbe3f8265115fabd0bd26a166ea60318b0be5377
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_21.c
@@ -0,0 +1,38 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#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..b3f5984f682f30f79331d48a264c2cc4af3e2503
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_22.c
@@ -0,0 +1,45 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_perm } */
+/* { dg-require-effective-target vect_early_break_hw } */
+
+#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..3e435af44471b0db2c02e2aaab4c3c48ffc9b763
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_23.c
@@ -0,0 +1,65 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+#include "tree-vect.h"
+
+#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)
+{
+  check_vect ();
+
+  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..fa2a17ed96f1afd81c3425b70ab2720044334e8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_24.c
@@ -0,0 +1,46 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_double } */
+/* { dg-require-effective-target vect_early_break_hw } */
+
+#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..4d8b47ed9aaae995945830955e242b713f48b786
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_25.c
@@ -0,0 +1,11 @@
+/* { dg-add-options vect_early_break } */
+/* { 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 "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..47d2a50218bd1b32fe43edcaaabb1079d0b26223
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_26.c
@@ -0,0 +1,44 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { 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..ed7b31757a0ccdede020e36f5a64aaaa1e94a5c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_27.c
@@ -0,0 +1,19 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..9c980b8453d9cca8319aef41a2cd3cdda47b3c32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_28.c
@@ -0,0 +1,16 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..b66fe204caee6a5b143c670e07de9a4a3b77455a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_29.c
@@ -0,0 +1,17 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..4afbc7266765fc4639b2554c6361e0825411f148
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_3.c
@@ -0,0 +1,21 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..3f6e802ae8f0714c321e62fc7412e8047fe7557a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_30.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..1eaf52aaa8528189ab0c0b961e662d3bc4518adc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_31.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..038be402c2b8ce4c797465214217788cb2f50b17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_32.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..74116143b2609e23df42ddc740360f6b33bcd93c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_33.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..63f1bb4254c60190e690002f6546d160a8f3ffde
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_34.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..4c0078fbc6758fec7db9562ba51f2cd733d97d41
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_35.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..a83994035b9d074b57349bb9063e80dbb65020d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_36.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..b7559a9adc7ce28e3ef6851c0d934170ea5878b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_37.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..8062fbbf6422af6a2e42de9574e88d411a8fb917
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_38.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..9d3c6a5dffe3be4a7759b150e330d18144ab5ce5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_39.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..bd7107c1736cdc21dc6b9e35e0293286c18299ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_4.c
@@ -0,0 +1,24 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..428f6249fa68f00bd70fa660dd9c1bb508181f4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_40.c
@@ -0,0 +1,27 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..31a8ed2d3e2f33978aae04c1ac02b104896c6151
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_41.c
@@ -0,0 +1,25 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..f1ee2f7e9a667968810f4ef28091a1e26c357a30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_42.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..7e9f635a0b5a8f6fb5da5d7cc6a426f343af4b56
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_43.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..7e9f635a0b5a8f6fb5da5d7cc6a426f343af4b56
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_44.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..7031f237ecceb45057098989aaf12e68e33c1f5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_45.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..c9aad909ffd80aee247e2f2803990167aea7cddd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_46.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..ef90380ea197fdec549ab3f6ea95a8ed2f07278e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_47.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..0efbb2836bfdd6acc5a9b45a362cc99d3a7e5d97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_48.c
@@ -0,0 +1,14 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..6c4ee40fd5d36782ad77c7ae98daf9a7998198d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_49.c
@@ -0,0 +1,25 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..1468c795b6201f347fe53bc85ddc46bc96c73821
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_5.c
@@ -0,0 +1,25 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..b3cf2d7f05f0445cdc2d6a3961c4c6f955f92220
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_50.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..c06eff5a385f4309ee3a03d2bb697a12976537fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_51.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..86a632f2a82291b3063a57cd62f2310ed6d5c747
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_52.c
@@ -0,0 +1,21 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" { target { ! "x86_64-*-* i?86-*-*" } } } } */
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..a02d5986ba3cfc117b19305c5e96711299996931
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_53.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
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..bfc78c262751065e4204babb907deb2366974f2b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_54.c
@@ -0,0 +1,30 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..c2a823bff7a40932e9cec6aad5a19ac42c517eb0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_55.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..9096f66647c7b3cb430562d35f8ce076244f7c11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_56.c
@@ -0,0 +1,102 @@
+/* { dg-add-options 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 } */
+/* { dg-add-options bind_pic_locally } */
+/* { dg-require-effective-target vect_early_break_hw } */
+
+#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..319bd125c3156f13c300ff2b94d269bb9ec29e97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_57.c
@@ -0,0 +1,32 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+/* { dg-final { scan-tree-dump "epilog loop required" "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..5f18f06d423f495af9331d353fd4e42ae3d59d7c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_58.c
@@ -0,0 +1,19 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..aec4ee457d7862099b13d5c6b3c04d0405379a18
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_59.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..7b870e9c60dcac6164d879dd70c1fc07ec0221fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_6.c
@@ -0,0 +1,27 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..75b35f8d423f7a389e85e8b51e8e579ee4d07cf1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_60.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..c789ec01f32c6b958c6a3663531a7b7517b94477
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..aaad62ef8d789ea611824e64eca41b45c850a41c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_62.c
@@ -0,0 +1,21 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..1d9ff4ad6bacd6e80264dadf797c345f51c57299
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_63.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* 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..aaa2a46fb67e0e50644e1f8f78cf8f2c175931cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_64.c
@@ -0,0 +1,18 @@
+/* { dg-add-options vect_early_break } */
+/* { 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..23a8341b529d8edef38b12f110a9ae7ce51edf09
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_65.c
@@ -0,0 +1,20 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" 0 "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..e54cc5e1260e3c7efc245987e754f4fc60e0e0ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_66.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+int a[0];
+int b;
+
+void g();
+
+void f() {
+  int d, e;
+  for (; e; e++) {
+    int c;
+    switch (b)
+    case '9': {
+      for (; d < 1; d++)
+        if (a[d])
+          c = 1;
+      break;
+    case '<':
+      g();
+      c = 0;
+    }
+      while (c)
+        ;
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c
new file mode 100644
index 0000000000000000000000000000000000000000..e9da46439f274781d37ab0b2ce4aabd48a98778d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_67.c
@@ -0,0 +1,42 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+
+
+int main()
+{
+  int var6 = -1267827473;
+  do {
+      ++var6;
+      double s1_115[4], s2_108[4];
+      int var8 = -161498264;
+      do {
+	  ++var8;
+	  int var12 = 1260960076;
+	  for (; var12 <= 1260960080; ++var12) {
+	      int var13 = 1960990937;
+	      do {
+		  ++var13;
+		  int var14 = 2128638723;
+		  for (; var14 <= 2128638728; ++var14) {
+		      int var22 = -1141190839;
+		      do {
+			  ++var22;
+			  if (s2_108 > s1_115) {
+			      int var23 = -890798748;
+			      do {
+				  long long e_119[4];
+			      } while (var23 <= -890798746);
+			  }
+		      } while (var22 <= -1141190829);
+		  }
+	      } while (var13 <= 1960990946);
+	  }
+      } while (var8 <= -161498254);
+  } while (var6 <= -1267827462);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c
new file mode 100644
index 0000000000000000000000000000000000000000..dfa90b557e87ca67d3d7a66d23084a4fff6fd4b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_68.c
@@ -0,0 +1,42 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 800
+#endif
+unsigned vect_a1[N];
+unsigned vect_b1[N];
+unsigned vect_c1[N];
+unsigned vect_d1[N];
+  
+unsigned vect_a2[N];
+unsigned vect_b2[N];
+unsigned vect_c2[N];
+unsigned vect_d2[N];
+
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b1[i] += x + i;
+   vect_c1[i] += x + i;
+   vect_d1[i] += x + i;
+   if (vect_a1[i]*2 != x)
+     break;
+   vect_a1[i] = x;
+
+   vect_b2[i] += x + i;
+   vect_c2[i] += x + i;
+   vect_d2[i] += x + i;
+   if (vect_a2[i]*2 != x)
+     break;
+   vect_a2[i] = x;
+
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c
new file mode 100644
index 0000000000000000000000000000000000000000..916351a14ab4c4509d9f291805ed35ebf2396639
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_69.c
@@ -0,0 +1,80 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}									\
+									\
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_ffs (ints[i]) != my_ffs (ints[i]))
+	abort ();
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	abort ();
+    }
+
+  exit (0);
+}
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
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..8c86c5034d7522b3733543fb384a23c5d6ed0fcf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_7.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include <complex.h>
+
+#define N 1024
+complex double vect_a[N];
+complex double vect_b[N];
+  
+complex double test4(complex double x)
+{
+ complex double ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_b[i] += x + i;
+   if (vect_a[i] == x)
+     break;
+   vect_a[i] += x * vect_b[i];
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c
new file mode 100644
index 0000000000000000000000000000000000000000..3dbedf610406e222253636aa84c68b6544c2fdbb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_70.c
@@ -0,0 +1,69 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c
new file mode 100644
index 0000000000000000000000000000000000000000..b15c8de3ed752e54eecc6b7c2d364b2d2acba25b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_71.c
@@ -0,0 +1,71 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_ffs (ints[i]) != my_ffs (ints[i]))
+	abort ();
+    }
+
+  exit (0);
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c
new file mode 100644
index 0000000000000000000000000000000000000000..c6d1e9f5fd26d1348db9287a3adcc57ee4c2fc37
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_72.c
@@ -0,0 +1,151 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ctz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i;								\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_ctz (ints[i]) != my_ctz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f40dd07e54316b1f97a12914dfce9b815c6215f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_73.c
@@ -0,0 +1,71 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#  define BITSIZEOF_INT 32
+#  define BITSIZEOF_LONG 64
+#  define BITSIZEOF_LONG_LONG 64
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}
+
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS32					\
+  {                                             \
+    0x00000000UL,                               \
+    0x00000001UL,                               \
+    0x80000000UL,                               \
+    0x00000002UL,                               \
+    0x40000000UL,                               \
+    0x00010000UL,                               \
+    0x00008000UL,                               \
+    0xa5a5a5a5UL,                               \
+    0x5a5a5a5aUL,                               \
+    0xcafe0000UL,                               \
+    0x00cafe00UL,                               \
+    0x0000cafeUL,                               \
+    0xffffffffUL                                \
+  }
+
+
+unsigned int ints[] = NUMS32;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (ints[i] != 0
+	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
+	  abort ();
+    }
+
+  exit (0);
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c
new file mode 100644
index 0000000000000000000000000000000000000000..afd238618b30ed905ca2f790bc94d019d7bf8019
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_74.c
@@ -0,0 +1,165 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
+    abort ();								
+
+#if BITSIZEOF_INT == 32
+  TEST(0x00000000UL,);
+  TEST(0x00000001UL,);
+  TEST(0x80000000UL,);
+  TEST(0x40000000UL,);
+  TEST(0x00010000UL,);
+  TEST(0x00008000UL,);
+  TEST(0xa5a5a5a5UL,);
+  TEST(0x5a5a5a5aUL,);
+  TEST(0xcafe0000UL,);
+  TEST(0x00cafe00UL,);
+  TEST(0x0000cafeUL,);
+  TEST(0xffffffffUL,);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed27f8635730ff0d8803517c72693625a2feddef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_75.c
@@ -0,0 +1,234 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+__attribute__((noinline)) \
+int my_ffs##suffix(type x) {						\
+    int i;								\
+    if (x == 0)								\
+	 return 0; 							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i + 1;							\
+}									\
+									\
+int my_ctz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1  << i))					\
+	    break;							\
+    return i;								\
+}									\
+									\
+__attribute__((noinline)) \
+int my_clz##suffix(type x) {						\
+    int i;								\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
+	    break;							\
+    return i;								\
+}									\
+									\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}									\
+									\
+__attribute__((noinline)) \
+int my_popcount##suffix(type x) {					\
+    int i;								\
+    int count = 0;							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << i))					\
+	    count++;							\
+    return count;							\
+}									\
+									\
+__attribute__((noinline)) \
+int my_parity##suffix(type x) {						\
+    int i;								\
+    int count = 0;							\
+    for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
+	if (x & ((type) 1 << i))					\
+	    count++;							\
+    return count & 1;							\
+}
+
+MAKE_FUNS (ll, unsigned long long);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(longlongs); i++)
+    {
+      if (__builtin_ffsll (longlongs[i]) != my_ffsll (longlongs[i]))
+	abort ();
+      if (longlongs[i] != 0
+	  && __builtin_clzll (longlongs[i]) != my_clzll (longlongs[i]))
+	abort ();
+      if (longlongs[i] != 0
+	  && __builtin_ctzll (longlongs[i]) != my_ctzll (longlongs[i]))
+	abort ();
+      if (__builtin_clrsbll (longlongs[i]) != my_clrsbll (longlongs[i]))
+	abort ();
+      if (__builtin_popcountll (longlongs[i]) != my_popcountll (longlongs[i]))
+	abort ();
+      if (__builtin_parityll (longlongs[i]) != my_parityll (longlongs[i]))
+	abort ();
+    }
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_ffs##suffix (x) != my_ffs##suffix (x))			\
+    abort ();								\
+
+#if BITSIZEOF_LONG_LONG == 64
+  TEST(0x0000000000000000ULL, ll);
+  TEST(0x0000000000000001ULL, ll);
+  TEST(0x8000000000000000ULL, ll);
+  TEST(0x0000000000000002ULL, ll);
+  TEST(0x4000000000000000ULL, ll);
+  TEST(0x0000000100000000ULL, ll);
+  TEST(0x0000000080000000ULL, ll);
+  TEST(0xa5a5a5a5a5a5a5a5ULL, ll);
+  TEST(0x5a5a5a5a5a5a5a5aULL, ll);
+  TEST(0xcafecafe00000000ULL, ll);
+  TEST(0x0000cafecafe0000ULL, ll);
+  TEST(0x00000000cafecafeULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7d8e279c67008bf4e35c802ab48f1b373827392
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_76.c
@@ -0,0 +1,169 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}									\
+									\
+
+MAKE_FUNS (, unsigned);
+MAKE_FUNS (ll, unsigned long long);
+
+extern void abort (void);
+extern void exit (int);
+
+#define NUMS16					\
+  {						\
+    0x0000U,					\
+    0x0001U,					\
+    0x8000U,					\
+    0x0002U,					\
+    0x4000U,					\
+    0x0100U,					\
+    0x0080U,					\
+    0xa5a5U,					\
+    0x5a5aU,					\
+    0xcafeU,					\
+    0xffffU					\
+  }
+
+#define NUMS32					\
+  {						\
+    0x00000000UL,				\
+    0x00000001UL,				\
+    0x80000000UL,				\
+    0x00000002UL,				\
+    0x40000000UL,				\
+    0x00010000UL,				\
+    0x00008000UL,				\
+    0xa5a5a5a5UL,				\
+    0x5a5a5a5aUL,				\
+    0xcafe0000UL,				\
+    0x00cafe00UL,				\
+    0x0000cafeUL,				\
+    0xffffffffUL				\
+  }
+
+#define NUMS64					\
+  {						\
+    0x0000000000000000ULL,			\
+    0x0000000000000001ULL,			\
+    0x8000000000000000ULL,			\
+    0x0000000000000002ULL,			\
+    0x4000000000000000ULL,			\
+    0x0000000100000000ULL,			\
+    0x0000000080000000ULL,			\
+    0xa5a5a5a5a5a5a5a5ULL,			\
+    0x5a5a5a5a5a5a5a5aULL,			\
+    0xcafecafe00000000ULL,			\
+    0x0000cafecafe0000ULL,			\
+    0x00000000cafecafeULL,			\
+    0xffffffffffffffffULL			\
+  }
+
+unsigned int ints[] =
+#if BITSIZEOF_INT == 64
+NUMS64;
+#elif BITSIZEOF_INT == 32
+NUMS32;
+#else
+NUMS16;
+#endif
+
+unsigned long longs[] =
+#if BITSIZEOF_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+unsigned long long longlongs[] =
+#if BITSIZEOF_LONG_LONG == 64
+NUMS64;
+#else
+NUMS32;
+#endif
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+  int i;
+
+  check_vect ();
+
+#pragma GCC novector
+  for (i = 0; i < N(ints); i++)
+    {
+      if (__builtin_clrsb (ints[i]) != my_clrsb (ints[i]))
+	abort ();
+    }
+
+  /* Test constant folding.  */
+
+#define TEST(x, suffix)							\
+  if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
+    abort ();								
+
+#if BITSIZEOF_LONG_LONG == 64
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+  TEST(0xffffffffffffffffULL, ll);
+#endif
+
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_77.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_77.c
new file mode 100644
index 0000000000000000000000000000000000000000..225106aab0a3efc7536de6f6e45bc6ff16210ea8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_77.c
@@ -0,0 +1,34 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+double x[1024];
+int a[1024];
+double __attribute__((noipa)) foo  ()
+{
+  double sum = 0.0;
+  for (int i = 0 ; i < 1023; ++i)
+    {
+      sum += x[i];
+      if (a[i])
+        break;
+    }
+  return sum;
+}
+
+int main()
+{
+  check_vect ();
+
+  for (int i = 0; i < 1024; ++i)
+    x[i] = i;
+  a[19] = 1;
+  if (foo () != 190.)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_78.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_78.c
new file mode 100644
index 0000000000000000000000000000000000000000..f93babc069e10b4709b138115c6576c3f43bb29c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_78.c
@@ -0,0 +1,77 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-O3" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <limits.h>
+#include <assert.h>
+
+#include "tree-vect.h"
+
+#if __INT_MAX__ > 2147483647L
+# if __INT_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_INT 64
+# else
+#  define BITSIZEOF_INT 32
+# endif
+#else
+# if __INT_MAX__ >= 2147483647L
+#  define BITSIZEOF_INT 32
+# else
+#  define BITSIZEOF_INT 16
+# endif
+#endif
+
+#if __LONG_MAX__ > 2147483647L
+# if __LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG 64
+# else
+#  define BITSIZEOF_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG 32
+#endif
+
+#if __LONG_LONG_MAX__ > 2147483647L
+# if __LONG_LONG_MAX__ >= 9223372036854775807L
+#  define BITSIZEOF_LONG_LONG 64
+# else
+#  define BITSIZEOF_LONG_LONG 32
+# endif
+#else
+# define BITSIZEOF_LONG_LONG 32
+#endif
+
+#define MAKE_FUNS(suffix, type)						\
+int my_clrsb##suffix(type x) {						\
+    int i;								\
+    int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
+    for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
+	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
+	    != leading)							\
+	    break;							\
+    return i - 1;							\
+}
+
+MAKE_FUNS (, unsigned);
+
+extern void abort (void);
+extern void exit (int);
+
+
+int
+main (void)
+{
+  check_vect ();
+
+#define TEST(x, suffix)							\
+  if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
+    abort ();								
+
+#if BITSIZEOF_INT == 32
+  TEST(0xffffffffUL,);
+#endif
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_79.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_79.c
new file mode 100644
index 0000000000000000000000000000000000000000..3f21be7625149dd476c15e5fa7ea9899d6a42f43
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_79.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+
+#undef N
+#define N 32
+
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < 1024; 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_8.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_8.c
new file mode 100644
index 0000000000000000000000000000000000000000..84e19423e2e61144cc575fb992b5f23d480ab89d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_8.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+
+#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_80.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_80.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f563b788ac7037adc7c629fb708e9a6885a6e93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_80.c
@@ -0,0 +1,49 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+extern void abort ();
+
+int x;
+__attribute__ ((noinline, noipa))
+void foo (int *a, int *b)
+{
+  int local_x = x;
+  for (int i = 0; i < 1024; ++i)
+    {
+      if (i + local_x == 13)
+        break;
+      a[i] = 2 * b[i];
+    }
+}
+
+int main ()
+{
+
+  check_vect ();
+
+  int a[1024] = {0};
+  int b[1024] = {0};
+
+  for (int i = 0; i < 1024; i++)
+    b[i] = i;
+
+  x = -512;
+  foo (a, b);
+
+  if (a[524] != 1048)
+    abort ();
+
+  if (a[525] != 0)
+    abort ();
+
+  if (a[1023] != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_81.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_81.c
new file mode 100644
index 0000000000000000000000000000000000000000..8a8c076ba92ca6fef419cb23b457a23555c61c64
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_81.c
@@ -0,0 +1,31 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+/* { dg-final { scan-tree-dump "epilog loop required" "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 - 3; 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_82.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_82.c
new file mode 100644
index 0000000000000000000000000000000000000000..0e9b2d8d385c556063a3c6fcb14383317b056a79
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_82.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { 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 t)
+{
+ complex double ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_a[i] = t + i;
+   if (vect_a[i] == x)
+     return i;
+   vect_a[i] += x * vect_a[i];
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_83.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_83.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b0e3fd6c5f5430b9139e34d1913acc329e5bc4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_83.c
@@ -0,0 +1,29 @@
+/* { dg-add-options vect_early_break } */
+/* { 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" } } */
+
+#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++)
+ {
+   volatile complex double z = vect_b[i];
+   vect_b[i] = x + i + z;
+   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_84.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_84.c
new file mode 100644
index 0000000000000000000000000000000000000000..242ba453533e40f23dd29d27cbc419ca98e2b77c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_84.c
@@ -0,0 +1,44 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include <stdbool.h>
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 17
+#endif
+bool vect_a[N] = { false, false, true, false, false, false,
+                   false, false, false, false, false, false,
+                   false, false, false, false, false };
+unsigned vect_b[N] = { 0 };
+
+__attribute__ ((noinline, noipa))
+unsigned test4(bool x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   if (vect_a[i] == x)
+     return 1;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+extern void abort ();
+
+int main ()
+{
+  check_vect ();
+
+  if (test4 (true) != 1)
+    abort ();
+
+  if (vect_b[2] != 0 && vect_b[1] == 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_85.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_85.c
new file mode 100644
index 0000000000000000000000000000000000000000..3df376935735bc3ad60cb5762962380e0627174a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_85.c
@@ -0,0 +1,40 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 5
+#endif
+int vect_a[N] = { 5, 4, 8, 4, 6 };
+unsigned vect_b[N] = { 0 };
+
+__attribute__ ((noinline, noipa))
+unsigned test4(int x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   if (vect_a[i] > x)
+     return 1;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+extern void abort ();
+
+int main ()
+{
+  check_vect ();
+
+  if (test4 (7) != 1)
+    abort ();
+
+  if (vect_b[2] != 0 && vect_b[1] == 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_86.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_86.c
new file mode 100644
index 0000000000000000000000000000000000000000..85c0d3a927727359e625d97763f426a885c51072
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_86.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-std=gnu89" } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include "tree-vect.h"
+
+extern void abort ();
+extern void exit (int);
+
+__attribute__((noinline, noipa))
+int f(x) {
+  int i;
+  for (i = 0; i < 8 && (x & 1) == 1; i++)
+    x >>= 1;
+  return i;
+}
+main() {
+  check_vect ();
+
+  if (f(4) != 0)
+    abort();
+  exit(0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_87.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_87.c
new file mode 100644
index 0000000000000000000000000000000000000000..3dce0c439bff2e84dad66f384df499bc096ec904
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_87.c
@@ -0,0 +1,26 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-additional-options "-std=gnu89" } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { ! "x86_64-*-* i?86-*-*" } } } } */
+
+#include "tree-vect.h"
+
+extern void abort ();
+extern void exit (int);
+
+__attribute__((noinline, noipa))
+int f(x) {
+  int i;
+  for (i = 0; i < 8 && (x & 1) == 0; i++)
+    x >>= 1;
+  return i;
+}
+main() {
+  check_vect ();
+
+  if (f(4) != 2)
+    abort();
+  exit(0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_88.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_88.c
new file mode 100644
index 0000000000000000000000000000000000000000..b392dd46553994d813761da41c42989a79b90119
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_88.c
@@ -0,0 +1,41 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast --param vect-partial-vector-usage=2" } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 5
+#endif
+float vect_a[N] = { 5.1f, 4.2f, 8.0f, 4.25f, 6.5f };
+unsigned vect_b[N] = { 0 };
+
+__attribute__ ((noinline, noipa))
+unsigned test4(double x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
+
+extern void abort ();
+
+int main ()
+{
+  check_vect ();
+
+  if (test4 (7.0) != 0)
+    abort ();
+
+  if (vect_b[2] != 0 && vect_b[1] == 0)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_89.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_89.c
new file mode 100644
index 0000000000000000000000000000000000000000..39b6313b3a15be335a27ae5b90edb125bdccaee3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_89.c
@@ -0,0 +1,21 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-w" } */
+
+char *a;
+extern void d();
+void b() {
+  int c = 0;
+  while (c < 16) {
+    switch (a[c]) {
+    case '"':
+    case '\'':
+      c++;
+      continue;
+    }
+    break;
+  }
+  if (c)
+    d();
+}
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..12f09c61c331d1d0a66623da171804c10cea2051
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_9.c
@@ -0,0 +1,28 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-additional-options "-Ofast" } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+#ifndef N
+#define N 803
+#endif
+unsigned vect_a[N];
+unsigned vect_b[N];
+  
+unsigned test4(unsigned x)
+{
+ unsigned ret = 0;
+ for (int i = 0; i < N; i++)
+ {
+   vect_a[i] = x + i;
+   if (vect_a[i] > x)
+     break;
+   vect_a[i] = x;
+   
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 7f13ff0ca565efdf19065811f3301db897329073..1fcb2da53b469d0f19782ace6c9539dbe269b793 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4050,6 +4050,58 @@ proc check_effective_target_vect_int { } {
 	}}]
 }
 
+# Return 1 if the target supports 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*-*-*]
+	|| [check_effective_target_arm_v8_neon_ok]
+	|| ([check_effective_target_arm_v8_1m_mve_fp_ok]
+	     && [check_effective_target_arm_little_endian])
+	|| [check_effective_target_sse4]
+	}}]
+}
+
+# Return 1 if the target supports hardware execution of early breaks,
+# 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_early_break_hw { } {
+    return [check_cached_effective_target_indexed vect_early_break_hw {
+      expr {
+	[istarget aarch64*-*-*]
+	|| [check_effective_target_arm_v8_neon_hw]
+	|| ([check_effective_target_arm_mve_hw]
+	     && [check_effective_target_arm_little_endian])
+	|| [check_sse4_hw_available]
+	}}]
+}
+
+proc add_options_for_vect_early_break { flags } {
+    if { ! [check_effective_target_vect_early_break] } {
+	return "$flags"
+    }
+
+    if { [check_effective_target_arm_v8_neon_ok] } {
+	global et_arm_v8_neon_flags
+	return "$flags $et_arm_v8_neon_flags -march=armv8-a"
+    }
+
+    if { [check_effective_target_arm_v8_1m_mve_fp_ok] } {
+	global et_arm_v8_1m_mve_fp_flags
+	return "$flags $et_arm_v8_1m_mve_fp_flags"
+    }
+
+    if { [check_effective_target_sse4] } {
+	return "$flags -msse4.1"
+    }
+}
+
 # Return 1 if the target supports hardware vectorization of complex additions of
 # byte, 0 otherwise.
 #




^ permalink raw reply	[flat|nested] 202+ messages in thread

end of thread, other threads:[~2023-12-21 19:46 UTC | newest]

Thread overview: 202+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-28 13:40 [PATCH v5 0/19] Support early break/return auto-vectorization Tamar Christina
2023-06-28 13:41 ` [PATCH 1/19]middle-end ifcvt: Support bitfield lowering of multiple-exit loops Tamar Christina
2023-07-04 11:29   ` Richard Biener
2023-06-28 13:41 ` [PATCH 2/19][front-end] C/C++ front-end: add pragma GCC novector Tamar Christina
2023-06-29 22:17   ` Jason Merrill
2023-06-30 16:18     ` Tamar Christina
2023-06-30 16:44       ` Jason Merrill
2023-06-28 13:42 ` [PATCH 3/19]middle-end clean up vect testsuite using pragma novector Tamar Christina
2023-06-28 13:54   ` Tamar Christina
2023-07-04 11:31   ` Richard Biener
2023-06-28 13:43 ` [PATCH 4/19]middle-end: Fix scale_loop_frequencies segfault on multiple-exits Tamar Christina
2023-07-04 11:52   ` Richard Biener
2023-07-04 14:57     ` Jan Hubicka
2023-07-06 14:34       ` Jan Hubicka
2023-07-07  5:59         ` Richard Biener
2023-07-07 12:20           ` Jan Hubicka
2023-07-07 12:27             ` Tamar Christina
2023-07-07 14:10               ` Jan Hubicka
2023-07-10  7:07             ` Richard Biener
2023-07-10  8:33               ` Jan Hubicka
2023-07-10  9:24                 ` Richard Biener
2023-07-10  9:23               ` Jan Hubicka
2023-07-10  9:29                 ` Richard Biener
2023-07-11  9:28                   ` Jan Hubicka
2023-07-11 10:31                     ` Richard Biener
2023-07-11 12:40                       ` Jan Hubicka
2023-07-11 13:04                         ` Richard Biener
2023-06-28 13:43 ` [PATCH 5/19]middle-end: Enable bit-field vectorization to work correctly when we're vectoring inside conds Tamar Christina
2023-07-04 12:05   ` Richard Biener
2023-07-10 15:32     ` Tamar Christina
2023-07-11 11:03       ` Richard Biener
2023-06-28 13:44 ` [PATCH 6/19]middle-end: Don't enter piecewise expansion if VF is not constant Tamar Christina
2023-07-04 12:10   ` Richard Biener
2023-07-06 10:37     ` Tamar Christina
2023-07-06 10:51       ` Richard Biener
2023-06-28 13:44 ` [PATCH 7/19]middle-end: Refactor vectorizer loop conditionals and separate out IV to new variables Tamar Christina
2023-07-13 11:32   ` Richard Biener
2023-07-13 11:54     ` Tamar Christina
2023-07-13 12:10       ` Richard Biener
2023-06-28 13:45 ` [PATCH 8/19]middle-end: updated niters analysis to handle multiple exits Tamar Christina
2023-07-13 11:49   ` Richard Biener
2023-07-13 12:03     ` Tamar Christina
2023-07-14  9:09     ` Richard Biener
2023-06-28 13:45 ` [PATCH 9/19]AArch64 middle-end: refactor vectorizable_comparison to make the main body re-usable Tamar Christina
2023-06-28 13:55   ` [PATCH 9/19] " Tamar Christina
2023-07-13 16:23     ` Richard Biener
2023-06-28 13:46 ` [PATCH 10/19]middle-end: implement vectorizable_early_break Tamar Christina
2023-06-28 13:46 ` [PATCH 11/19]middle-end: implement code motion for early break Tamar Christina
2023-06-28 13:47 ` [PATCH 12/19]middle-end: implement loop peeling and IV updates " Tamar Christina
2023-07-13 17:31   ` Richard Biener
2023-07-13 19:05     ` Tamar Christina
2023-07-14 13:34       ` Richard Biener
2023-07-17 10:56         ` Tamar Christina
2023-07-17 12:48           ` Richard Biener
2023-08-18 11:35         ` Tamar Christina
2023-08-18 12:53           ` Richard Biener
2023-08-18 13:12             ` Tamar Christina
2023-08-18 13:15               ` Richard Biener
2023-10-23 20:21         ` Tamar Christina
2023-06-28 13:47 ` [PATCH 13/19]middle-end testsuite: un-xfail TSVC loops that check for exit control flow vectorization Tamar Christina
2023-06-28 13:47 ` [PATCH 14/19]middle-end testsuite: Add new tests for early break vectorization Tamar Christina
2023-06-28 13:48 ` [PATCH 15/19]AArch64: Add implementation for vector cbranch for Advanced SIMD Tamar Christina
2023-06-28 13:48 ` [PATCH 16/19]AArch64 Add optimization for vector != cbranch fed into compare with 0 " Tamar Christina
2023-06-28 13:48 ` [PATCH 17/19]AArch64 Add optimization for vector cbranch combining SVE and " Tamar Christina
2023-06-28 13:49 ` [PATCH 18/19]Arm: Add Advanced SIMD cbranch implementation Tamar Christina
2023-06-28 13:50 ` [PATCH 19/19]Arm: Add MVE " Tamar Christina
     [not found] ` <MW5PR11MB5908414D8B2AB0580A888ECAA924A@MW5PR11MB5908.namprd11.prod.outlook.com>
2023-06-28 14:49   ` FW: [PATCH v5 0/19] Support early break/return auto-vectorization 钟居哲
2023-06-28 16:00     ` Tamar Christina
2023-11-06  7:36 ` [PATCH v6 0/21]middle-end: " Tamar Christina
2023-11-06  7:37 ` [PATCH 1/21]middle-end testsuite: Add more pragma novector to new tests Tamar Christina
2023-11-07  9:46   ` Richard Biener
2023-11-06  7:37 ` [PATCH 2/21]middle-end testsuite: Add tests for early break vectorization Tamar Christina
2023-11-07  9:52   ` Richard Biener
2023-11-16 10:53     ` Richard Biener
2023-11-06  7:37 ` [PATCH 3/21]middle-end: Implement code motion and dependency analysis for early breaks Tamar Christina
2023-11-07 10:53   ` Richard Biener
2023-11-07 11:34     ` Tamar Christina
2023-11-07 14:23       ` Richard Biener
2023-12-19 10:11         ` Tamar Christina
2023-12-19 14:05           ` Richard Biener
2023-12-20 10:51             ` Tamar Christina
2023-12-20 12:24               ` Richard Biener
2023-11-06  7:38 ` [PATCH 4/21]middle-end: update loop peeling code to maintain LCSSA form " Tamar Christina
2023-11-15  0:00   ` Tamar Christina
2023-11-15 12:40     ` Richard Biener
2023-11-20 21:51       ` Tamar Christina
2023-11-24 10:16         ` Tamar Christina
2023-11-24 12:38           ` Richard Biener
2023-11-06  7:38 ` [PATCH 5/21]middle-end: update vectorizer's control update to support picking an exit other than loop latch Tamar Christina
2023-11-07 15:04   ` Richard Biener
2023-11-07 23:10     ` Tamar Christina
2023-11-13 20:11     ` Tamar Christina
2023-11-14  7:56       ` Richard Biener
2023-11-14  8:07         ` Tamar Christina
2023-11-14 23:59           ` Tamar Christina
2023-11-15 12:14             ` Richard Biener
2023-11-06  7:38 ` [PATCH 6/21]middle-end: support multiple exits in loop versioning Tamar Christina
2023-11-07 14:54   ` Richard Biener
2023-11-06  7:39 ` [PATCH 7/21]middle-end: update IV update code to support early breaks and arbitrary exits Tamar Christina
2023-11-15  0:03   ` Tamar Christina
2023-11-15 13:01     ` Richard Biener
2023-11-15 13:09       ` Tamar Christina
2023-11-15 13:22         ` Richard Biener
2023-11-15 14:14           ` Tamar Christina
2023-11-16 10:40             ` Richard Biener
2023-11-16 11:08               ` Tamar Christina
2023-11-16 11:27                 ` Richard Biener
2023-11-16 12:01                   ` Tamar Christina
2023-11-16 12:30                     ` Richard Biener
2023-11-16 13:22                       ` Tamar Christina
2023-11-16 13:35                         ` Richard Biener
2023-11-16 14:14                           ` Tamar Christina
2023-11-16 14:17                             ` Richard Biener
2023-11-16 15:19                               ` Tamar Christina
2023-11-16 18:41                                 ` Tamar Christina
2023-11-17 10:40                                   ` Tamar Christina
2023-11-17 12:13                                     ` Richard Biener
2023-11-20 21:54                                       ` Tamar Christina
2023-11-24 10:18                                         ` Tamar Christina
2023-11-24 12:41                                           ` Richard Biener
2023-11-06  7:39 ` [PATCH 8/21]middle-end: update vectorizable_live_reduction with support for multiple exits and different exits Tamar Christina
2023-11-15  0:05   ` Tamar Christina
2023-11-15 13:41     ` Richard Biener
2023-11-15 14:26       ` Tamar Christina
2023-11-16 11:16         ` Richard Biener
2023-11-20 21:57           ` Tamar Christina
2023-11-24 10:20             ` Tamar Christina
2023-11-24 13:23               ` Richard Biener
2023-11-27 22:47                 ` Tamar Christina
2023-11-29 13:28                   ` Richard Biener
2023-11-29 21:22                     ` Tamar Christina
2023-11-30 13:23                       ` Richard Biener
2023-12-06  4:21                         ` Tamar Christina
2023-12-06  9:33                           ` Richard Biener
2023-11-06  7:39 ` [PATCH 9/21]middle-end: implement vectorizable_early_exit for codegen of exit code Tamar Christina
2023-11-27 22:49   ` Tamar Christina
2023-11-29 13:50     ` Richard Biener
2023-12-06  4:37       ` Tamar Christina
2023-12-06  9:37         ` Richard Biener
2023-12-08  8:58           ` Tamar Christina
2023-12-08 10:28             ` Richard Biener
2023-12-08 13:45               ` Tamar Christina
2023-12-08 13:59                 ` Richard Biener
2023-12-08 15:01                   ` Tamar Christina
2023-12-11  7:09                   ` Tamar Christina
2023-12-11  9:36                     ` Richard Biener
2023-12-11 23:12                       ` Tamar Christina
2023-12-12 10:10                         ` Richard Biener
2023-12-12 10:27                           ` Tamar Christina
2023-12-12 10:59                           ` Richard Sandiford
2023-12-12 11:30                             ` Richard Biener
2023-12-13 14:13                               ` Tamar Christina
2023-12-14 13:12                                 ` Richard Biener
2023-12-14 18:44                                   ` Tamar Christina
2023-11-06  7:39 ` [PATCH 10/21]middle-end: implement relevancy analysis support for control flow Tamar Christina
2023-11-27 22:49   ` Tamar Christina
2023-11-29 14:47     ` Richard Biener
2023-12-06  4:10       ` Tamar Christina
2023-12-06  9:44         ` Richard Biener
2023-11-06  7:40 ` [PATCH 11/21]middle-end: wire through peeling changes and dominator updates after guard edge split Tamar Christina
2023-11-06  7:40 ` [PATCH 12/21]middle-end: Add remaining changes to peeling and vectorizer to support early breaks Tamar Christina
2023-11-27 22:48   ` Tamar Christina
2023-12-06  8:31   ` Richard Biener
2023-12-06  9:10     ` Tamar Christina
2023-12-06  9:27       ` Richard Biener
2023-11-06  7:40 ` [PATCH 13/21]middle-end: Update loop form analysis to support early break Tamar Christina
2023-11-27 22:48   ` Tamar Christina
2023-12-06  4:00     ` Tamar Christina
2023-12-06  8:18   ` Richard Biener
2023-12-06  8:52     ` Tamar Christina
2023-12-06  9:15       ` Richard Biener
2023-12-06  9:29         ` Tamar Christina
2023-11-06  7:41 ` [PATCH 14/21]middle-end: Change loop analysis from looking at at number of BB to actual cfg Tamar Christina
2023-11-06 14:44   ` Richard Biener
2023-11-06  7:41 ` [PATCH 15/21]middle-end: [RFC] conditionally support forcing final edge for debugging Tamar Christina
2023-12-09 10:38   ` Richard Sandiford
2023-12-11  7:38     ` Richard Biener
2023-12-11  8:49       ` Tamar Christina
2023-12-11  9:00         ` Richard Biener
2023-11-06  7:41 ` [PATCH 16/21]middle-end testsuite: un-xfail TSVC loops that check for exit control flow vectorization Tamar Christina
2023-11-06  7:41 ` [PATCH 17/21]AArch64: Add implementation for vector cbranch for Advanced SIMD Tamar Christina
2023-11-28 16:37   ` Richard Sandiford
2023-11-28 17:55     ` Richard Sandiford
2023-12-06 16:25       ` Tamar Christina
2023-12-07  0:56         ` Richard Sandiford
2023-12-14 18:40           ` Tamar Christina
2023-12-14 19:34             ` Richard Sandiford
2023-11-06  7:42 ` [PATCH 18/21]AArch64: Add optimization for vector != cbranch fed into compare with 0 " Tamar Christina
2023-11-06  7:42 ` [PATCH 19/21]AArch64: Add optimization for vector cbranch combining SVE and " Tamar Christina
2023-11-06  7:42 ` [PATCH 20/21]Arm: Add Advanced SIMD cbranch implementation Tamar Christina
2023-11-27 12:48   ` Kyrylo Tkachov
2023-11-06  7:43 ` [PATCH 21/21]Arm: Add MVE " Tamar Christina
2023-11-27 12:47   ` Kyrylo Tkachov
2023-11-06 14:25 ` [PATCH v6 0/21]middle-end: Support early break/return auto-vectorization Richard Biener
2023-11-06 15:17   ` Tamar Christina
2023-11-07  9:42     ` Richard Biener
2023-11-07 10:47       ` Tamar Christina
2023-11-07 13:58         ` Richard Biener
2023-11-27 18:30           ` Richard Sandiford
2023-11-28  8:11             ` Richard Biener
2023-12-21 15:30 [PATCH 2/21]middle-end testsuite: Add tests for early break vectorization Tamar Christina
2023-12-21 19:46 ` Richard Biener

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