Message ID | patch-17962-tamar@arm.com |
---|---|
State | New |
Headers | show |
Series | None | expand |
> Am 21.12.2023 um 16:32 schrieb Tamar Christina <tamar.christina@arm.com>: > > 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? Please remove the -save-temps extra arguments, those look spurious. What’s the difference between vect_early_break and _hw? I didn’t see runtime tests using check_vect(), but the mail is too long to view on my smartphone… I think with my comments in the first iteration addressed this should be fine. We can fix tests later if problems appear. Thanks, Richard > 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. > # > > > > > -- > <rb17962.patch>
--- 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. #