+2007-08-16 Victor Kaplansky <victork@il.ibm.com>
+
+ * tree-vectorizer.c (new_loop_vec_info): Initialize new
+ field.
+ (destroy_loop_vec_info): Add call to VEC_free.
+ * tree-vectorizer.h (may_alias_ddrs): Define.
+ (LOOP_VINFO_MAY_ALIAS_DDRS): Define.
+ * tree-vect-analyze.c (vect_analyze_data_ref_dependence):
+ Change reporting to dump.
+ (vect_is_duplicate_ddr): New.
+ (vect_mark_for_runtime_alias_test): New.
+ (vect_analyze_data_ref_dependences) Add call to
+ vect_mark_for_runtime_alias_test.
+ (vect_enhance_data_refs_alignment): Define local variable
+ vect_versioning_for_alias_required, don't perform
+ peeling for alignment if versioning for alias is
+ required.
+ (vect_enhance_data_refs_alignment): Use
+ PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS instead of
+ PARAM_VECT_MAX_VERSION_CHECKS.
+ * tree-vect-transform.c
+ (vect_create_cond_for_alias_checks): New.
+ (vect_transform_loop): Add call to
+ vect_create_cond_for_alias_checks.
+ (vect_vfa_segment_size): New.
+ * params.def (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS):
+ Rename.
+ (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS): Define.
+ * gcc/doc/invoke.texi
+ (vect-max-version-for-alignment-checks): Document.
+ (vect-max-version-for-alias-checks): Document.
+ (vect-max-version-checks): Remove.
+
2007-08-16 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*rep_movdi_rex64): Emit "rep" prefix on
When set to 1, use expensive methods to eliminate all redundant
constraints. The default value is 0.
-@item vect-max-version-checks
-The maximum number of runtime checks that can be performed when doing
-loop versioning in the vectorizer. See option ftree-vect-loop-version
-for more information.
+@item vect-max-version-for-alignment-checks
+The maximum number of runtime checks that can be performed when
+doing loop versioning for alignment in the vectorizer. See option
+ftree-vect-loop-version for more information.
+
+@item vect-max-version-for-alias-checks
+The maximum number of runtime checks that can be performed when
+doing loop versioning for alias in the vectorizer. See option
+ftree-vect-loop-version for more information.
@item max-iterations-to-track
"When set to 1, use expensive methods to eliminate all redundant constraints",
0, 0, 1)
-DEFPARAM(PARAM_VECT_MAX_VERSION_CHECKS,
- "vect-max-version-checks",
- "Bound on number of runtime checks inserted by the vectorizer's loop versioning",
+DEFPARAM(PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
+ "vect-max-version-for-alignment-checks",
+ "Bound on number of runtime checks inserted by the vectorizer's loop versioning for alignment check",
6, 0, 0)
+DEFPARAM(PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS,
+ "vect-max-version-for-alias-checks",
+ "Bound on number of runtime checks inserted by the vectorizer's loop versioning for alias check",
+ 10, 0, 0)
+
DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIONS,
"max-cselib-memory-locations",
"The maximum memory locations recorded by cselib",
+2007-08-16 Victor Kaplansky <victork@il.ibm.com>
+
+ * gcc.dg/vect/vect-vfa-01.c: New.
+ * gcc.dg/vect/vect-vfa-02.c: New.
+ * gcc.dg/vect/vect-vfa-03.c: New.
+ * gcc.dg/vect/vect-vfa-04.c: New.
+ * gcc.dg/vect/vect-102a.c, gcc.dg/vect/vect-51.c,
+ gcc.dg/vect/pr29145.c, gcc.dg/vect/vect-43.c,
+ gcc.dg/vect/vect-61.c, gcc.dg/vect/vect-53.c,
+ gcc.dg/vect/vect-45.c, gcc.dg/vect/vect-101.c,
+ gcc.dg/vect/vect-37.c, gcc.dg/vect/vect-79.c,
+ gcc.dg/vect/vect-102.c, gcc.dg/vect/vect-dv-2.c,
+ gcc.dg/vect/vect-57.c, gcc.dg/vect/vect-49.c,
+ gfortran.dg/vect/pr19049.f90: Rename to start with
+ prefix no-vfa-.
+ * gcc.dg/vect/vect.exp: Disable versioning for alias
+ when test starts with no-vfa-.
+ * gfortran.dg/vect/vect.exp: Likewise.
+
2007-08-16 Richard Sandiford <richard@codesourcery.com>
* gcc.dg/torture/pr32897.c: New test.
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+void with_restrict(int * __restrict p)
+{
+ int i;
+ int *q = p - 2;
+
+ for (i = 0; i < 1000; ++i) {
+ p[i] = q[i];
+ }
+}
+
+void without_restrict(int * p)
+{
+ int i;
+ int *q = p - 2;
+
+ for (i = 0; i < 1000; ++i) {
+ p[i] = q[i];
+ }
+}
+
+int main(void)
+{
+ int i;
+ int a[1002];
+ int b[1002];
+
+ for (i = 0; i < 1002; ++i) {
+ a[i] = b[i] = i;
+ }
+
+ with_restrict(a + 2);
+ without_restrict(b + 2);
+
+ for (i = 0; i < 1002; ++i) {
+ if (a[i] != b[i])
+ abort();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 9
+
+struct extraction
+{
+ int a[N];
+ int b[N];
+};
+
+static int a[N] = {1,2,3,4,5,6,7,8,9};
+static int b[N] = {2,3,4,5,6,7,8,9,0};
+
+int main1 (int x, int y) {
+ int i;
+ struct extraction *p;
+ p = (struct extraction *) malloc (sizeof (struct extraction));
+
+ /* Not vectorizable: different unknown offset. */
+ for (i = 0; i < N; i++)
+ {
+ *((int *)p + x + i) = a[i];
+ *((int *)p + y + i) = b[i];
+ }
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (p->a[i] != a[i] || p->b[i] != b[i])
+ abort();
+ }
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ return main1 (0, N);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
+/* { dg-final { scan-tree-dump-times "can't determine dependence" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 9
+
+struct extraction
+{
+ int a[N];
+ int b[N];
+};
+
+static int a[N] = {1,2,3,4,5,6,7,8,9};
+static int b[N] = {2,3,4,5,6,7,8,9,9};
+volatile int foo;
+
+int main1 (int x, int y) {
+ int i;
+ struct extraction *p;
+ p = (struct extraction *) malloc (sizeof (struct extraction));
+
+ for (i = 0; i < N; i++)
+ {
+ p->a[i] = a[i];
+ if (foo == 135)
+ abort (); /* to avoid vectorization */
+ }
+
+ /* Not vectorizable: distance 1. */
+ for (i = 0; i < N - 1; i++)
+ {
+ *((int *)p + x + i) = *((int *)p + x + i + 1);
+ }
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (p->a[i] != b[i])
+ abort();
+ }
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ foo = 0;
+ return main1 (0, N);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
+/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 9
+
+struct extraction
+{
+ int a[N];
+ int b[N];
+};
+
+static int a[N] = {1,2,3,4,5,6,7,8,9};
+static int b[N] = {2,3,4,5,6,7,8,9,9};
+volatile int foo;
+
+int main1 (int x, int y) {
+ int i;
+ struct extraction *p;
+ p = (struct extraction *) malloc (sizeof (struct extraction));
+
+ for (i = 0; i < N; i++)
+ {
+ p->a[i] = a[i];
+ if (foo == 135)
+ abort (); /* to avoid vectorization */
+ }
+
+ /* Not vectorizable: distance 1. */
+ for (i = 0; i < N - 1; i++)
+ {
+ p->a[x + i] = p->a[x + i + 1];
+ }
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (p->a[i] != b[i])
+ abort();
+ }
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ foo = 0;
+ return main1 (0, N);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
+/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+char x[N] __attribute__ ((__aligned__(16)));
+
+int main1 (char *y)
+{
+ struct {
+ char *p;
+ char *q;
+ } s;
+ char cb[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+ int i;
+
+ /* Not vectorized - can't antialias the pointer s.p from the array cb. */
+ s.p = y;
+ for (i = 0; i < N; i++)
+ {
+ s.p[i] = cb[i];
+ }
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (s.p[i] != cb[i])
+ abort ();
+ }
+
+ /* Not vectorized - can't antialias the pointer s.p from the pointer s.q. */
+ s.q = cb;
+ for (i = 0; i < N; i++)
+ {
+ s.p[i] = s.q[i];
+ }
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (s.p[i] != s.q[i])
+ abort ();
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ return main1 (x);
+}
+
+/* Currently the loops fail to vectorize due to aliasing problems.
+ If/when the aliasing problems are resolved, unalignment may
+ prevent vectorization on some targets. */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "can't determine dependence between" 2 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+void bar (float *pa, float *pb, float *pc)
+{
+ int i;
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (pa[i] != (pb[i] * pc[i]))
+ abort ();
+ }
+
+ return;
+}
+
+
+int
+main1 (float *pa)
+{
+ int i;
+ float pb[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float pc[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+ /* Not vectorizable: pa may alias pb and/or pc, since their addresses escape. */
+ for (i = 0; i < N; i++)
+ {
+ pa[i] = pb[i] * pc[i];
+ }
+
+ bar (pa,pb,pc);
+
+ return 0;
+}
+
+int
+main2 (float * pa)
+{
+ int i;
+ float pb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float pc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+ /* Vectorizable: pb and pc addresses do not escape. */
+ for (i = 0; i < N; i++)
+ {
+ pa[i] = pb[i] * pc[i];
+ }
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (pa[i] != (pb[i] * pc[i]))
+ abort ();
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ int i;
+ float a[N] __attribute__ ((__aligned__(16)));
+
+ check_vect ();
+
+ main1 (a);
+ main2 (a);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target vect_no_align } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+void bar (const float *pa, const float *pb, const float *pc)
+{
+ int i;
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (pa[i] != (pb[i] * pc[i]))
+ abort ();
+ }
+
+ return;
+}
+
+/* Unaligned pointer accesses, with unknown alignment.
+ The loop bound is known and divisible by the vectorization factor.
+ Can't prove that the pointers don't alias.
+ vect-51.c is similar to this one with one difference:
+ the loop bound is unknown.
+ vect-44.c is similar to this one with one difference:
+ Aliasing is not a problem. */
+
+int
+main1 (float *pa, float *pb, float *pc)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ pa[i] = pb[i] * pc[i];
+ }
+
+ bar (pa,pb,pc);
+
+ return 0;
+}
+
+int main (void)
+{
+ int i;
+ float a[N];
+ float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+ check_vect ();
+
+ main1 (a,b,c);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+void bar (float *pa, float *pb, float *pc)
+{
+ int i;
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (pa[i] != (pb[i] * pc[i]))
+ abort ();
+ }
+
+ return;
+}
+
+/* Unaligned pointer read accesses, aligned pointer write access.
+ The loop bound is known and divisible by the vectorization factor.
+ Can't prove that the pointers don't alias.
+ vect-53.c is similar to this one with one difference:
+ the loop bound is unknown.
+ vect-48.c is similar to this one with one difference:
+ aliasing is not a problem. */
+
+int
+main1 (float *pb, float *pc)
+{
+ float pa[N] __attribute__ ((__aligned__(16)));
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ pa[i] = pb[i] * pc[i];
+ }
+
+ bar (pa,pb,pc);
+
+ return 0;
+}
+
+int main (void)
+{
+ int i;
+ float b[N+1] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60};
+ float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+ check_vect ();
+
+ main1 (b,c);
+ main1 (&b[1],c);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+void bar (const float *pa, const float *pb, const float *pc)
+{
+ int i;
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (pa[i] != (pb[i] * pc[i]))
+ abort ();
+ }
+
+ return;
+}
+
+/* Unaligned pointer accesses, with unknown alignment.
+ The loop bound is unknown.
+ Can't prove that the pointers don't alias.
+ vect-45.c is similar to this one with one difference:
+ the loop bound is known.
+ vect-50.c is similar to this one with one difference:
+ Aliasing is not a problem. */
+
+int
+main1 (int n, float *pa, float *pb, float *pc)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ pa[i] = pb[i] * pc[i];
+ }
+
+ bar (pa,pb,pc);
+
+ return 0;
+}
+
+int main (void)
+{
+ int i;
+ float a[N];
+ float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+ check_vect ();
+
+ main1 (N,a,b,c);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+void bar (const float *pa, const float *pb, const float *pc)
+{
+ int i;
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (pa[i] != (pb[i] * pc[i]))
+ abort ();
+ }
+
+ return;
+}
+
+/* Unaligned pointer read accesses, aligned pointer write access.
+ The loop bound is unknown.
+ Can't prove that the pointers don't alias.
+ vect-49.c is similar to this one with one difference:
+ the loop bound is known.
+ vect-52.c is similar to this one with one difference:
+ aliasing is not a problem. */
+
+int
+main1 (int n, float *pb, float *pc)
+{
+ float pa[N] __attribute__ ((__aligned__(16)));
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ pa[i] = pb[i] * pc[i];
+ }
+
+ bar (pa,pb,pc);
+
+ return 0;
+}
+
+int main (void)
+{
+ int i;
+ float a[N] __attribute__ ((__aligned__(16)));
+ float b[N+1] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60};
+ float c[N+1] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+
+ check_vect ();
+
+ main1 (N,&b[1],c);
+ main1 (N,&b[1],&c[1]);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+void bar (float *pa, float *pb, float *pc)
+{
+ int i;
+
+ /* check results: */
+ for (i = 0; i < N/2; i++)
+ {
+ if (pa[i] != (pb[i+1] * pc[i+1]))
+ abort ();
+ }
+
+ return;
+}
+
+/* Unaligned pointer read accesses with known alignment,
+ and an unaligned write access with unknown alignment.
+ The loop bound is known and divisible by the vectorization factor.
+ Can't prove that the pointers don't alias.
+ vect-61.c is similar to this one with one difference:
+ the loop bound is unknown.
+ vect-56.c is similar to this one with two differences:
+ aliasing is a problem, and the write access is aligned. */
+
+int
+main1 (float *pa)
+{
+ int i;
+ float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ float *pb = b;
+ float *pc = c;
+
+ for (i = 0; i < N/2; i++)
+ {
+ pa[i] = pb[i+1] * pc[i+1];
+ }
+
+ bar (pa, pb, pc);
+
+ return 0;
+}
+
+int main (void)
+{
+ int i;
+ float a[N] __attribute__ ((__aligned__(16)));
+
+ check_vect ();
+ main1 (a);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+void bar (float *pa, float *pb, float *pc)
+{
+ int i;
+
+ /* check results: */
+ for (i = 0; i < N/2; i++)
+ {
+ if (pa[i] != (pb[i+1] * pc[i+1]))
+ abort ();
+ }
+
+ return;
+}
+
+/* Unaligned pointer read accesses with known alignment,
+ and an unaligned write access with unknown alignment.
+ The loop bound is iunknown.
+ Can't prove that the pointers don't alias.
+ vect-57.c is similar to this one with one difference:
+ the loop bound is known.
+ vect-60.c is similar to this one with two differences:
+ aliasing is not a problem, and the write access is unaligned. */
+
+int
+main1 (int n , float *pa)
+{
+ int i;
+ float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ float *pb = b;
+ float *pc = c;
+
+ for (i = 0; i < n/2; i++)
+ {
+ pa[i] = pb[i+1] * pc[i+1];
+ }
+
+ bar (pa,pb,pc);
+
+ return 0;
+}
+
+int main (void)
+{
+ int i;
+ int n=N;
+ float a[N] __attribute__ ((__aligned__(16)));
+
+ check_vect ();
+ main1 (n,a);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+float fa[N] __attribute__ ((__aligned__(16)));
+float fb[N+4] __attribute__ ((__aligned__(16))) = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0};
+float fc[N] __attribute__ ((__aligned__(16))) = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 7.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5};
+
+/* Like vect-80.c but the pointers are not annotated as restricted,
+ and therefore can't be antialiased. */
+
+int
+main1 (float *pa, float *pb, float *pc)
+{
+ int i;
+ float *q = pb + 4;
+
+ for (i = 0; i < N; i++)
+ {
+ pa[i] = q[i] * pc[i];
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (pa[i] != q[i] * pc[i])
+ abort();
+ }
+
+ return 0;
+}
+
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (fa, fb, fc);
+
+ return 0;
+}
+
+/* Currently the loops fail to vectorize due to aliasing problems.
+ If/when the aliasing problems are resolved, unalignment may
+ prevent vectorization on some targets. */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "can't determine dependence between" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <signal.h>
+#include "tree-vect.h"
+
+#define N 64
+#define MAX 42
+
+extern void abort(void);
+
+int main ()
+{
+ int A[N];
+ int B[N];
+ int C[N];
+ int D[N];
+
+ int i, j;
+
+ check_vect ();
+
+ for (i = 0; i < N; i++)
+ {
+ A[i] = i;
+ B[i] = i;
+ C[i] = i;
+ D[i] = i;
+ }
+
+ /* Vectorizable */
+ for (i = 0; i < N-20; i++)
+ {
+ A[i] = A[i+20];
+ }
+
+ /* check results: */
+ for (i = 0; i < N-20; i++)
+ {
+ if (A[i] != D[i+20])
+ abort ();
+ }
+
+ /* Vectorizable */
+ for (i = 0; i < 16; i++)
+ {
+ B[i] = B[i] + 5;
+ }
+
+ /* check results: */
+ for (i = 0; i < 16; i++)
+ {
+ if (B[i] != C[i] + 5)
+ abort ();
+ }
+
+ /* Not vectorizable */
+ for (i = 0; i < 4; i++)
+ {
+ C[i] = C[i+3];
+ }
+
+ /* check results: */
+ for (i = 0; i < 4; i++)
+ {
+ if (C[i] != D[i+3])
+ abort ();
+ }
+
+ return 0;
+}
+
+
+/* The initialization induction loop (with aligned access) is also vectorized. */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_int } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-void with_restrict(int * __restrict p)
-{
- int i;
- int *q = p - 2;
-
- for (i = 0; i < 1000; ++i) {
- p[i] = q[i];
- }
-}
-
-void without_restrict(int * p)
-{
- int i;
- int *q = p - 2;
-
- for (i = 0; i < 1000; ++i) {
- p[i] = q[i];
- }
-}
-
-int main(void)
-{
- int i;
- int a[1002];
- int b[1002];
-
- for (i = 0; i < 1002; ++i) {
- a[i] = b[i] = i;
- }
-
- with_restrict(a + 2);
- without_restrict(b + 2);
-
- for (i = 0; i < 1002; ++i) {
- if (a[i] != b[i])
- abort();
- }
- return 0;
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" } } */
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_int } */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 9
-
-struct extraction
-{
- int a[N];
- int b[N];
-};
-
-static int a[N] = {1,2,3,4,5,6,7,8,9};
-static int b[N] = {2,3,4,5,6,7,8,9,0};
-
-int main1 (int x, int y) {
- int i;
- struct extraction *p;
- p = (struct extraction *) malloc (sizeof (struct extraction));
-
- /* Not vectorizable: different unknown offset. */
- for (i = 0; i < N; i++)
- {
- *((int *)p + x + i) = a[i];
- *((int *)p + y + i) = b[i];
- }
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (p->a[i] != a[i] || p->b[i] != b[i])
- abort();
- }
- return 0;
-}
-
-int main (void)
-{
- check_vect ();
-
- return main1 (0, N);
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "can't determine dependence" 1 "vect" } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
-
+++ /dev/null
-/* { dg-require-effective-target vect_int } */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 9
-
-struct extraction
-{
- int a[N];
- int b[N];
-};
-
-static int a[N] = {1,2,3,4,5,6,7,8,9};
-static int b[N] = {2,3,4,5,6,7,8,9,9};
-volatile int foo;
-
-int main1 (int x, int y) {
- int i;
- struct extraction *p;
- p = (struct extraction *) malloc (sizeof (struct extraction));
-
- for (i = 0; i < N; i++)
- {
- p->a[i] = a[i];
- if (foo == 135)
- abort (); /* to avoid vectorization */
- }
-
- /* Not vectorizable: distance 1. */
- for (i = 0; i < N - 1; i++)
- {
- *((int *)p + x + i) = *((int *)p + x + i + 1);
- }
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (p->a[i] != b[i])
- abort();
- }
- return 0;
-}
-
-int main (void)
-{
- check_vect ();
-
- foo = 0;
- return main1 (0, N);
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
-
+++ /dev/null
-/* { dg-require-effective-target vect_int } */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 9
-
-struct extraction
-{
- int a[N];
- int b[N];
-};
-
-static int a[N] = {1,2,3,4,5,6,7,8,9};
-static int b[N] = {2,3,4,5,6,7,8,9,9};
-volatile int foo;
-
-int main1 (int x, int y) {
- int i;
- struct extraction *p;
- p = (struct extraction *) malloc (sizeof (struct extraction));
-
- for (i = 0; i < N; i++)
- {
- p->a[i] = a[i];
- if (foo == 135)
- abort (); /* to avoid vectorization */
- }
-
- /* Not vectorizable: distance 1. */
- for (i = 0; i < N - 1; i++)
- {
- p->a[x + i] = p->a[x + i + 1];
- }
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (p->a[i] != b[i])
- abort();
- }
- return 0;
-}
-
-int main (void)
-{
- check_vect ();
-
- foo = 0;
- return main1 (0, N);
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
-
+++ /dev/null
-/* { dg-require-effective-target vect_int } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 16
-char x[N] __attribute__ ((__aligned__(16)));
-
-int main1 (char *y)
-{
- struct {
- char *p;
- char *q;
- } s;
- char cb[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
- int i;
-
- /* Not vectorized - can't antialias the pointer s.p from the array cb. */
- s.p = y;
- for (i = 0; i < N; i++)
- {
- s.p[i] = cb[i];
- }
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (s.p[i] != cb[i])
- abort ();
- }
-
- /* Not vectorized - can't antialias the pointer s.p from the pointer s.q. */
- s.q = cb;
- for (i = 0; i < N; i++)
- {
- s.p[i] = s.q[i];
- }
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (s.p[i] != s.q[i])
- abort ();
- }
-
- return 0;
-}
-
-int main (void)
-{
- check_vect ();
-
- return main1 (x);
-}
-
-/* Currently the loops fail to vectorize due to aliasing problems.
- If/when the aliasing problems are resolved, unalignment may
- prevent vectorization on some targets. */
-/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "can't determine dependence between" 2 "vect" } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_float } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 256
-
-void bar (float *pa, float *pb, float *pc)
-{
- int i;
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (pa[i] != (pb[i] * pc[i]))
- abort ();
- }
-
- return;
-}
-
-
-int
-main1 (float *pa)
-{
- int i;
- float pb[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float pc[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
-
- /* Not vectorizable: pa may alias pb and/or pc, since their addresses escape. */
- for (i = 0; i < N; i++)
- {
- pa[i] = pb[i] * pc[i];
- }
-
- bar (pa,pb,pc);
-
- return 0;
-}
-
-int
-main2 (float * pa)
-{
- int i;
- float pb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float pc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
-
- /* Vectorizable: pb and pc addresses do not escape. */
- for (i = 0; i < N; i++)
- {
- pa[i] = pb[i] * pc[i];
- }
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (pa[i] != (pb[i] * pc[i]))
- abort ();
- }
-
- return 0;
-}
-
-int main (void)
-{
- int i;
- float a[N] __attribute__ ((__aligned__(16)));
-
- check_vect ();
-
- main1 (a);
- main2 (a);
- return 0;
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target vect_no_align } } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_float } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 256
-
-void bar (const float *pa, const float *pb, const float *pc)
-{
- int i;
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (pa[i] != (pb[i] * pc[i]))
- abort ();
- }
-
- return;
-}
-
-/* Unaligned pointer accesses, with unknown alignment.
- The loop bound is known and divisible by the vectorization factor.
- Can't prove that the pointers don't alias.
- vect-51.c is similar to this one with one difference:
- the loop bound is unknown.
- vect-44.c is similar to this one with one difference:
- Aliasing is not a problem. */
-
-int
-main1 (float *pa, float *pb, float *pc)
-{
- int i;
-
- for (i = 0; i < N; i++)
- {
- pa[i] = pb[i] * pc[i];
- }
-
- bar (pa,pb,pc);
-
- return 0;
-}
-
-int main (void)
-{
- int i;
- float a[N];
- float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
-
- check_vect ();
-
- main1 (a,b,c);
- return 0;
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_float } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 256
-
-void bar (float *pa, float *pb, float *pc)
-{
- int i;
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (pa[i] != (pb[i] * pc[i]))
- abort ();
- }
-
- return;
-}
-
-/* Unaligned pointer read accesses, aligned pointer write access.
- The loop bound is known and divisible by the vectorization factor.
- Can't prove that the pointers don't alias.
- vect-53.c is similar to this one with one difference:
- the loop bound is unknown.
- vect-48.c is similar to this one with one difference:
- aliasing is not a problem. */
-
-int
-main1 (float *pb, float *pc)
-{
- float pa[N] __attribute__ ((__aligned__(16)));
- int i;
-
- for (i = 0; i < N; i++)
- {
- pa[i] = pb[i] * pc[i];
- }
-
- bar (pa,pb,pc);
-
- return 0;
-}
-
-int main (void)
-{
- int i;
- float b[N+1] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60};
- float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
-
- check_vect ();
-
- main1 (b,c);
- main1 (&b[1],c);
-
- return 0;
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_float } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 256
-
-void bar (const float *pa, const float *pb, const float *pc)
-{
- int i;
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (pa[i] != (pb[i] * pc[i]))
- abort ();
- }
-
- return;
-}
-
-/* Unaligned pointer accesses, with unknown alignment.
- The loop bound is unknown.
- Can't prove that the pointers don't alias.
- vect-45.c is similar to this one with one difference:
- the loop bound is known.
- vect-50.c is similar to this one with one difference:
- Aliasing is not a problem. */
-
-int
-main1 (int n, float *pa, float *pb, float *pc)
-{
- int i;
-
- for (i = 0; i < n; i++)
- {
- pa[i] = pb[i] * pc[i];
- }
-
- bar (pa,pb,pc);
-
- return 0;
-}
-
-int main (void)
-{
- int i;
- float a[N];
- float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
-
- check_vect ();
-
- main1 (N,a,b,c);
- return 0;
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_float } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 256
-
-void bar (const float *pa, const float *pb, const float *pc)
-{
- int i;
-
- /* check results: */
- for (i = 0; i < N; i++)
- {
- if (pa[i] != (pb[i] * pc[i]))
- abort ();
- }
-
- return;
-}
-
-/* Unaligned pointer read accesses, aligned pointer write access.
- The loop bound is unknown.
- Can't prove that the pointers don't alias.
- vect-49.c is similar to this one with one difference:
- the loop bound is known.
- vect-52.c is similar to this one with one difference:
- aliasing is not a problem. */
-
-int
-main1 (int n, float *pb, float *pc)
-{
- float pa[N] __attribute__ ((__aligned__(16)));
- int i;
-
- for (i = 0; i < n; i++)
- {
- pa[i] = pb[i] * pc[i];
- }
-
- bar (pa,pb,pc);
-
- return 0;
-}
-
-int main (void)
-{
- int i;
- float a[N] __attribute__ ((__aligned__(16)));
- float b[N+1] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60};
- float c[N+1] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
-
- check_vect ();
-
- main1 (N,&b[1],c);
- main1 (N,&b[1],&c[1]);
-
- return 0;
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_float } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 256
-
-void bar (float *pa, float *pb, float *pc)
-{
- int i;
-
- /* check results: */
- for (i = 0; i < N/2; i++)
- {
- if (pa[i] != (pb[i+1] * pc[i+1]))
- abort ();
- }
-
- return;
-}
-
-/* Unaligned pointer read accesses with known alignment,
- and an unaligned write access with unknown alignment.
- The loop bound is known and divisible by the vectorization factor.
- Can't prove that the pointers don't alias.
- vect-61.c is similar to this one with one difference:
- the loop bound is unknown.
- vect-56.c is similar to this one with two differences:
- aliasing is a problem, and the write access is aligned. */
-
-int
-main1 (float *pa)
-{
- int i;
- float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
- float *pb = b;
- float *pc = c;
-
- for (i = 0; i < N/2; i++)
- {
- pa[i] = pb[i+1] * pc[i+1];
- }
-
- bar (pa, pb, pc);
-
- return 0;
-}
-
-int main (void)
-{
- int i;
- float a[N] __attribute__ ((__aligned__(16)));
-
- check_vect ();
- main1 (a);
-
- return 0;
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_int } */
-/* { dg-require-effective-target vect_float } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 256
-
-void bar (float *pa, float *pb, float *pc)
-{
- int i;
-
- /* check results: */
- for (i = 0; i < N/2; i++)
- {
- if (pa[i] != (pb[i+1] * pc[i+1]))
- abort ();
- }
-
- return;
-}
-
-/* Unaligned pointer read accesses with known alignment,
- and an unaligned write access with unknown alignment.
- The loop bound is iunknown.
- Can't prove that the pointers don't alias.
- vect-57.c is similar to this one with one difference:
- the loop bound is known.
- vect-60.c is similar to this one with two differences:
- aliasing is not a problem, and the write access is unaligned. */
-
-int
-main1 (int n , float *pa)
-{
- int i;
- float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
- float *pb = b;
- float *pc = c;
-
- for (i = 0; i < n/2; i++)
- {
- pa[i] = pb[i+1] * pc[i+1];
- }
-
- bar (pa,pb,pc);
-
- return 0;
-}
-
-int main (void)
-{
- int i;
- int n=N;
- float a[N] __attribute__ ((__aligned__(16)));
-
- check_vect ();
- main1 (n,a);
-
- return 0;
-}
-
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_float } */
-
-#include <stdarg.h>
-#include "tree-vect.h"
-
-#define N 16
-
-float fa[N] __attribute__ ((__aligned__(16)));
-float fb[N+4] __attribute__ ((__aligned__(16))) = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0};
-float fc[N] __attribute__ ((__aligned__(16))) = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 7.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5};
-
-/* Like vect-80.c but the pointers are not annotated as restricted,
- and therefore can't be antialiased. */
-
-int
-main1 (float *pa, float *pb, float *pc)
-{
- int i;
- float *q = pb + 4;
-
- for (i = 0; i < N; i++)
- {
- pa[i] = q[i] * pc[i];
- }
-
- for (i = 0; i < N; i++)
- {
- if (pa[i] != q[i] * pc[i])
- abort();
- }
-
- return 0;
-}
-
-
-int main (void)
-{
- check_vect ();
-
- main1 (fa, fb, fc);
-
- return 0;
-}
-
-/* Currently the loops fail to vectorize due to aliasing problems.
- If/when the aliasing problems are resolved, unalignment may
- prevent vectorization on some targets. */
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "can't determine dependence between" 1 "vect" } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
+++ /dev/null
-/* { dg-require-effective-target vect_int } */
-
-#include <stdarg.h>
-#include <signal.h>
-#include "tree-vect.h"
-
-#define N 64
-#define MAX 42
-
-extern void abort(void);
-
-int main ()
-{
- int A[N];
- int B[N];
- int C[N];
- int D[N];
-
- int i, j;
-
- check_vect ();
-
- for (i = 0; i < N; i++)
- {
- A[i] = i;
- B[i] = i;
- C[i] = i;
- D[i] = i;
- }
-
- /* Vectorizable */
- for (i = 0; i < N-20; i++)
- {
- A[i] = A[i+20];
- }
-
- /* check results: */
- for (i = 0; i < N-20; i++)
- {
- if (A[i] != D[i+20])
- abort ();
- }
-
- /* Vectorizable */
- for (i = 0; i < 16; i++)
- {
- B[i] = B[i] + 5;
- }
-
- /* check results: */
- for (i = 0; i < 16; i++)
- {
- if (B[i] != C[i] + 5)
- abort ();
- }
-
- /* Not vectorizable */
- for (i = 0; i < 4; i++)
- {
- C[i] = C[i+3];
- }
-
- /* check results: */
- for (i = 0; i < 4; i++)
- {
- if (C[i] != D[i+3])
- abort ();
- }
-
- return 0;
-}
-
-
-/* The initialization induction loop (with aligned access) is also vectorized. */
-/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */
-/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int result[N] = {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27};
+int X[N] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
+int Y[N] = {};
+
+void
+foo (int *in, int *out)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ out[i] = in[i] + 2;
+}
+
+int
+main (void)
+{
+ int i;
+
+ check_vect ();
+
+ foo (X, Y);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (Y[i] != result[i])
+ abort ();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int resultY[N] = {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27};
+int resultZ[N] = {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28};
+int X[N] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
+int Y[N] = {};
+int Z[N] = {};
+
+void
+foo (int *in, int *out1, int *out2)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ out1[i] = in[i] + 2;
+ out2[i] = in[i] + 3;
+ }
+}
+
+int
+main (void)
+{
+ int i;
+
+ check_vect ();
+
+ foo (X, Y, Z);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (Y[i] != resultY[i])
+ abort ();
+
+ if (Z[i] != resultZ[i])
+ abort ();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+struct S
+{
+ unsigned short a;
+ unsigned short b;
+};
+
+struct S result[N] = {12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18,
+ 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24,
+ 24, 25, 25, 26, 26, 27, 27, 28};
+struct S X[N] = {10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
+ 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25};
+struct S Y[N] = {};
+
+void
+foo (struct S * in, struct S * out)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ out[i].a = in[i].a + 2;
+ out[i].b = in[i].b + 3;
+ }
+}
+
+int
+main (void)
+{
+ int i;
+
+ check_vect ();
+
+ foo (X, Y);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (Y[i].a != result[i].a)
+ abort ();
+
+ if (Y[i].b != result[i].b)
+ abort ();
+
+ }
+ return 0;
+}
+
+/* Needs interleaving support. */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { xfail { vect_interleave && vect_extract_even_odd } } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int result[] = {10, 11, 15, 16, 20, 21, 25, 26, 30, 31, 35, 36, 40, 41, 45, 46, 50, 51};
+int X[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0};
+
+void
+foo (int *in, int *out)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ out[i] = in[i] + 5;
+}
+
+int
+main (void)
+{
+ int i;
+
+ check_vect ();
+
+ foo (X, &X[2]);
+
+ /* check results: */
+ for (i = 0; i < N+2; i++)
+ {
+ if (X[i] != result[i])
+ abort ();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
global SAVED_DEFAULT_VECTCFLAGS
set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS
+# --param vect-max-version-for-alias-checks=0 tests
+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
+lappend DEFAULT_VECTCFLAGS "--param" "vect-max-version-for-alias-checks=0"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-vfa-*.\[cS\]]] \
+ "" $DEFAULT_VECTCFLAGS
+
# -ffast-math tests
set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
lappend DEFAULT_VECTCFLAGS "-ffast-math"
--- /dev/null
+! { dg-do compile }
+! { dg-require-effective-target vect_float }
+
+SUBROUTINE KEEL(RBOUND)
+ REAL, DIMENSION(0:100) :: RBOUND
+ DO N = 1, NP1
+ RBOUND(N) = RBOUND(N-1) + 1
+ END DO
+ DO N = 1, NS
+ WRITE (16,'(I5)') SRAD(N)
+ END DO
+END SUBROUTINE KEEL
+
+! { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } }
+! { dg-final { cleanup-tree-dump "vect" } }
+++ /dev/null
-! { dg-do compile }
-! { dg-require-effective-target vect_float }
-
-SUBROUTINE KEEL(RBOUND)
- REAL, DIMENSION(0:100) :: RBOUND
- DO N = 1, NP1
- RBOUND(N) = RBOUND(N-1) + 1
- END DO
- DO N = 1, NS
- WRITE (16,'(I5)') SRAD(N)
- END DO
-END SUBROUTINE KEEL
-
-! { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } }
-! { dg-final { cleanup-tree-dump "vect" } }
dg-init
# Main loop.
-gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03} ]] $DEFAULT_VECTCFLAGS
+gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vect-*.\[fF\]{,90,95,03} ]] $DEFAULT_VECTCFLAGS
+gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pr-*.\[fF\]{,90,95,03} ]] $DEFAULT_VECTCFLAGS
+
+#### Tests with special options
+global SAVED_DEFAULT_VECTCFLAGS
+set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS
+
+# --param vect-max-version-for-alias-checks=0 tests
+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
+lappend DEFAULT_VECTCFLAGS "--param" "vect-max-version-for-alias-checks=0"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-vfa-*.\[fF\]{,90,95,03} ]] \
+ "" $DEFAULT_VECTCFLAGS
# Clean up.
set dg-do-what-default ${save-dg-do-what-default}
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
fprintf (vect_dump,
- "not vectorized: can't determine dependence between ");
+ "versioning for alias required: can't determine dependence between ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
- fprintf (vect_dump, "not vectorized: bad dist vector for ");
+ fprintf (vect_dump, "versioning for alias required: bad dist vector for ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
continue;
}
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
{
fprintf (vect_dump,
- "not vectorized: possible dependence between data-refs ");
+ "versioning for alias required: possible dependence "
+ "between data-refs ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
return false;
}
+/* Return TRUE if DDR_NEW is already found in MAY_ALIAS_DDRS list. */
+
+static bool
+vect_is_duplicate_ddr (VEC (ddr_p, heap) * may_alias_ddrs, ddr_p ddr_new)
+{
+ unsigned i;
+ ddr_p ddr;
+
+ for (i = 0; VEC_iterate (ddr_p, may_alias_ddrs, i, ddr); i++)
+ {
+ tree dref_A_i, dref_B_i, dref_A_j, dref_B_j;
+
+ dref_A_i = DR_REF (DDR_A (ddr));
+ dref_B_i = DR_REF (DDR_B (ddr));
+ dref_A_j = DR_REF (DDR_A (ddr_new));
+ dref_B_j = DR_REF (DDR_B (ddr_new));
+
+ if ((operand_equal_p (dref_A_i, dref_A_j, 0)
+ && operand_equal_p (dref_B_i, dref_B_j, 0))
+ || (operand_equal_p (dref_A_i, dref_B_j, 0)
+ && operand_equal_p (dref_B_i, dref_A_j, 0)))
+ {
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "found same pair of data references ");
+ print_generic_expr (vect_dump, dref_A_i, TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, dref_B_i, TDF_SLIM);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Save DDR in LOOP_VINFO list of ddrs that may alias and need to be
+ tested at run-time. Returns false if number of run-time checks
+ inserted by vectorizer is greater than maximum defined by
+ PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS. */
+static bool
+vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
+{
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "mark for run-time aliasing test between ");
+ print_generic_expr (vect_dump, DR_REF (DDR_A (ddr)), TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, DR_REF (DDR_B (ddr)), TDF_SLIM);
+ }
+
+ /* Do not add to the list duplicate ddrs. */
+ if (vect_is_duplicate_ddr (LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), ddr))
+ return true;
+
+ if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo))
+ >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS))
+ {
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump,
+ "disable versioning for alias - max number of generated "
+ "checks exceeded.");
+ }
+
+ VEC_truncate (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), 0);
+
+ return false;
+ }
+ VEC_safe_push (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), ddr);
+ return true;
+}
/* Function vect_analyze_data_ref_dependences.
vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
{
unsigned int i;
- VEC (ddr_p, heap) *ddrs = LOOP_VINFO_DDRS (loop_vinfo);
+ VEC (ddr_p, heap) * ddrs = LOOP_VINFO_DDRS (loop_vinfo);
struct data_dependence_relation *ddr;
if (vect_print_dump_info (REPORT_DETAILS))
for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
+ {
+ /* Add to list of ddrs that need to be tested at run-time. */
+ if (!vect_mark_for_runtime_alias_test (ddr, loop_vinfo))
return false;
+ }
return true;
}
bool stat;
tree stmt;
stmt_vec_info stmt_info;
+ int vect_versioning_for_alias_required;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_enhance_data_refs_alignment ===");
}
}
- /* Often peeling for alignment will require peeling for loop-bound, which in
- turn requires that we know how to adjust the loop ivs after the loop. */
- if (!vect_can_advance_ivs_p (loop_vinfo)
+ vect_versioning_for_alias_required =
+ (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)) > 0);
+
+ /* Temporarily, if versioning for alias is required, we disable peeling
+ until we support peeling and versioning. Often peeling for alignment
+ will require peeling for loop-bound, which in turn requires that we
+ know how to adjust the loop ivs after the loop. */
+ if (vect_versioning_for_alias_required
+ || !vect_can_advance_ivs_p (loop_vinfo)
|| !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
do_peeling = false;
if (known_alignment_for_access_p (dr)
|| VEC_length (tree,
LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
- >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS))
+ >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS))
{
do_versioning = false;
break;
and_tmp_name, ptrsize_zero);
}
+/* Function vect_vfa_segment_size.
+
+ Create an expression that computes the size of segment
+ that will be accessed for a data reference. The functions takes into
+ account that realignment loads may access one more vector.
+
+ Input:
+ DR: The data reference.
+ VECT_FACTOR: vectorization factor.
+
+ Return an exrpession whose value is the size of segment which will be
+ accessed by DR. */
+
+static tree
+vect_vfa_segment_size (struct data_reference *dr, tree vect_factor)
+{
+ tree segment_length;
+
+ if (vect_supportable_dr_alignment (dr) == dr_unaligned_software_pipeline)
+ {
+ tree vector_size =
+ build_int_cst (integer_type_node,
+ GET_MODE_SIZE (TYPE_MODE (STMT_VINFO_VECTYPE
+ (vinfo_for_stmt (DR_STMT (dr))))));
+
+ segment_length =
+ fold_convert (sizetype,
+ fold_build2 (PLUS_EXPR, integer_type_node,
+ fold_build2 (MULT_EXPR, integer_type_node, DR_STEP (dr),
+ vect_factor),
+ vector_size));
+
+
+ }
+ else
+ {
+ segment_length =
+ fold_convert (sizetype,
+ fold_build2 (MULT_EXPR, integer_type_node, DR_STEP (dr),
+ vect_factor));
+ }
+
+ return segment_length;
+}
+
+/* Function vect_create_cond_for_alias_checks.
+
+ Create a conditional expression that represents the run-time checks for
+ overlapping of address ranges represented by a list of data references
+ relations passed as input.
+
+ Input:
+ COND_EXPR - input conditional expression. New conditions will be chained
+ with logical and operation.
+ LOOP_VINFO - field LOOP_VINFO_MAY_ALIAS_STMTS contains the list of ddrs
+ to be checked.
+
+ Output:
+ COND_EXPR - conditional expression.
+ COND_EXPR_STMT_LIST - statements needed to construct the conditional
+ expression.
+ The returned value is the conditional expression to be used in the if
+ statement that controls which version of the loop gets executed at runtime.
+*/
+
+static void
+vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
+ tree * cond_expr,
+ tree * cond_expr_stmt_list)
+{
+ VEC (ddr_p, heap) * may_alias_ddrs =
+ LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
+ tree vect_factor =
+ build_int_cst (integer_type_node, LOOP_VINFO_VECT_FACTOR (loop_vinfo));
+
+ ddr_p ddr;
+ unsigned int i;
+ tree part_cond_expr;
+
+ /* Create expression
+ ((store_ptr_0 + store_segment_length_0) < load_ptr_0)
+ || (load_ptr_0 + load_segment_length_0) < store_ptr_0))
+ &&
+ ...
+ &&
+ ((store_ptr_n + store_segment_length_n) < load_ptr_n)
+ || (load_ptr_n + load_segment_length_n) < store_ptr_n)) */
+
+ if (VEC_empty (ddr_p, may_alias_ddrs))
+ return;
+
+ for (i = 0; VEC_iterate (ddr_p, may_alias_ddrs, i, ddr); i++)
+ {
+ tree stmt_a = DR_STMT (DDR_A (ddr));
+ tree stmt_b = DR_STMT (DDR_B (ddr));
+
+ tree addr_base_a =
+ vect_create_addr_base_for_vector_ref (stmt_a, cond_expr_stmt_list,
+ NULL_TREE);
+ tree addr_base_b =
+ vect_create_addr_base_for_vector_ref (stmt_b, cond_expr_stmt_list,
+ NULL_TREE);
+
+ tree segment_length_a = vect_vfa_segment_size (DDR_A (ddr), vect_factor);
+ tree segment_length_b = vect_vfa_segment_size (DDR_B (ddr), vect_factor);
+
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump,
+ "create runtime check for data references ");
+ print_generic_expr (vect_dump, DR_REF (DDR_A (ddr)), TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, DR_REF (DDR_B (ddr)), TDF_SLIM);
+ }
+
+
+ part_cond_expr =
+ fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
+ fold_build2 (LT_EXPR, boolean_type_node,
+ fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr_base_a),
+ addr_base_a,
+ segment_length_a),
+ addr_base_b),
+ fold_build2 (LT_EXPR, boolean_type_node,
+ fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr_base_b),
+ addr_base_b,
+ segment_length_b),
+ addr_base_a));
+
+ if (*cond_expr)
+ *cond_expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+ *cond_expr, part_cond_expr);
+ else
+ *cond_expr = part_cond_expr;
+ }
+ if (vect_print_dump_info (REPORT_VECTORIZED_LOOPS))
+ fprintf (vect_dump, "created %u versioning for alias checks.\n",
+ VEC_length (ddr_p, may_alias_ddrs));
+
+}
/* Function vect_transform_loop.
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vec_transform_loop ===");
- /* If the loop has data references that may or may not be aligned then
+ /* If the loop has data references that may or may not be aligned or/and
+ has data reference relations whose independence was not proven then
two versions of the loop need to be generated, one which is vectorized
and one which isn't. A test is then generated to control which of the
loops is executed. The test checks for the alignment of all of the
- data references that may or may not be aligned. */
+ data references that may or may not be aligned. An additional
+ sequence of runtime tests is generated for each pairs of DDRs whose
+ independence was not proven. The vectorized version of loop is
+ executed only if both alias and alignment tests are passed. */
- if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
+ if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
+ || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
{
struct loop *nloop;
- tree cond_expr;
+ tree cond_expr = NULL_TREE;
tree cond_expr_stmt_list = NULL_TREE;
basic_block condition_bb;
block_stmt_iterator cond_exp_bsi;
edge new_exit_e, e;
tree orig_phi, new_phi, arg;
unsigned prob = 4 * REG_BR_PROB_BASE / 5;
+ tree gimplify_stmt_list;
- cond_expr = vect_create_cond_for_align_checks (loop_vinfo,
+ if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
+ cond_expr =
+ vect_create_cond_for_align_checks (loop_vinfo, &cond_expr_stmt_list);
+
+ if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
+ vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr,
&cond_expr_stmt_list);
+
+ cond_expr =
+ fold_build2 (NE_EXPR, boolean_type_node, cond_expr, integer_zero_node);
+ cond_expr =
+ force_gimple_operand (cond_expr, &gimplify_stmt_list, true,
+ NULL_TREE);
+ append_to_statement_list (gimplify_stmt_list, &cond_expr_stmt_list);
+
initialize_original_copy_tables ();
nloop = loop_version (loop, cond_expr, &condition_bb,
prob, prob, REG_BR_PROB_BASE - prob, true);
LOOP_VINFO_DATAREFS (res) = VEC_alloc (data_reference_p, heap, 10);
LOOP_VINFO_DDRS (res) = VEC_alloc (ddr_p, heap, 10 * 10);
LOOP_VINFO_UNALIGNED_DR (res) = NULL;
- LOOP_VINFO_MAY_MISALIGN_STMTS (res)
- = VEC_alloc (tree, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS));
+ LOOP_VINFO_MAY_MISALIGN_STMTS (res) =
+ VEC_alloc (tree, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS));
+ LOOP_VINFO_MAY_ALIAS_DDRS (res) =
+ VEC_alloc (ddr_p, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS));
+
return res;
}
free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
VEC_free (tree, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
+ VEC_free (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
free (loop_vinfo);
loop->aux = NULL;
/* All data dependences in the loop. */
VEC (ddr_p, heap) *ddrs;
+ /* Data Dependence Relations defining address ranges that are candidates
+ for a run-time aliasing check. */
+ VEC (ddr_p, heap) *may_alias_ddrs;
+
/* Statements in the loop that have data references that are candidates for a
runtime (loop versioning) misalignment check. */
VEC(tree,heap) *may_misalign_stmts;
#define LOOP_VINFO_UNALIGNED_DR(L) (L)->unaligned_dr
#define LOOP_VINFO_MAY_MISALIGN_STMTS(L) (L)->may_misalign_stmts
#define LOOP_VINFO_LOC(L) (L)->loop_line_number
+#define LOOP_VINFO_MAY_ALIAS_DDRS(L) (L)->may_alias_ddrs
#define NITERS_KNOWN_P(n) \
(host_integerp ((n),0) \