From: Victor Kaplansky <VICTORK@il.ibm.com>
To: gcc-patches@gnu.org
Subject: [PATCH] [4.3 projects] Verctorizer - versioning for alias
Date: Tue, 14 Aug 2007 11:02:00 -0000 [thread overview]
Message-ID: <OFFD346E44.D15F9B49-ONC2257337.00301C78-C2257337.003C743B@il.ibm.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 3093 bytes --]
Often it is impossible to alias analysis to prove dependency or
independency. In such cases vectorizer is bound to be conservative.
However in many cases at run-time we can validate the independence
by testing that data reference ranges are not overlapped.
This patch enhances the vectorizer by introducing run-time checks
and loop versioning to take advantage of vectorized loop in case when
data reference independence can be proved at run-time. The number
of added data reference test can be controlled by
"vect-max-version-for-alias-checks" parameter. The value of 0 will
disable the versioning for alias. Then maximum number of checks
produced for versioning for alignment can now be controlled by
"vect-max-version-for-alignment-checks".
Bootstrapped and regtested on ppc64 and x86_64.
Bootstrapped with vectorization enabled on x86_64.
Okay for mainline?
2007-08-14 Victor Kaplansky <victork@il.ibm.com>
ChangeLog:
* 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
versioning 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.
* params.def (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS):
Rename.
(PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS): Define.
testsuite/ChangeLog:
* 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-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.
(See attached file: vfa.txt)
[-- Attachment #2: vfa.txt --]
[-- Type: text/plain, Size: 68243 bytes --]
Index: testsuite/gcc.dg/vect/vect-vfa-01.c
===================================================================
--- testsuite/gcc.dg/vect/vect-vfa-01.c (revision 0)
+++ testsuite/gcc.dg/vect/vect-vfa-01.c (revision 0)
@@ -0,0 +1,39 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-vfa-02.c
===================================================================
--- testsuite/gcc.dg/vect/vect-vfa-02.c (revision 0)
+++ testsuite/gcc.dg/vect/vect-vfa-02.c (revision 0)
@@ -0,0 +1,47 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-vfa-03.c
===================================================================
--- testsuite/gcc.dg/vect/vect-vfa-03.c (revision 0)
+++ testsuite/gcc.dg/vect/vect-vfa-03.c (revision 0)
@@ -0,0 +1,58 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect.exp
===================================================================
--- testsuite/gcc.dg/vect/vect.exp (revision 127316)
+++ testsuite/gcc.dg/vect/vect.exp (working copy)
@@ -113,6 +113,12 @@
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"
Index: testsuite/gfortran.dg/vect/vect.exp
===================================================================
--- testsuite/gfortran.dg/vect/vect.exp (revision 127316)
+++ testsuite/gfortran.dg/vect/vect.exp (working copy)
@@ -90,8 +90,19 @@
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}
Index: tree-vectorizer.c
===================================================================
--- tree-vectorizer.c (revision 127316)
+++ tree-vectorizer.c (working copy)
@@ -1414,9 +1414,12 @@
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;
}
@@ -1495,6 +1498,7 @@
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;
Index: tree-vectorizer.h
===================================================================
--- tree-vectorizer.h (revision 127316)
+++ tree-vectorizer.h (working copy)
@@ -133,6 +133,10 @@
/* 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;
@@ -157,6 +161,7 @@
#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) \
Index: tree-vect-analyze.c
===================================================================
--- tree-vect-analyze.c (revision 127316)
+++ tree-vect-analyze.c (working copy)
@@ -1039,10 +1039,10 @@
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);
@@ -1052,9 +1052,9 @@
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);
@@ -1108,10 +1108,10 @@
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);
@@ -1123,7 +1123,76 @@
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
+ iserted 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 exeeded.");
+ }
+
+ 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.
Examine all the data references in the loop, and make sure there do not
@@ -1133,7 +1202,7 @@
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))
@@ -1141,7 +1210,11 @@
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;
}
@@ -1554,6 +1627,7 @@
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 ===");
@@ -1619,9 +1693,15 @@
}
}
- /* 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;
@@ -1749,7 +1829,7 @@
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;
Index: tree-vect-transform.c
===================================================================
--- tree-vect-transform.c (revision 127316)
+++ tree-vect-transform.c (working copy)
@@ -5805,7 +5805,111 @@
and_tmp_name, ptrsize_zero);
}
+/* Function vect_create_cond_for_alias_checks.
+ Create a conditional expression that represents the run-time checks for
+ overlapping of adress ranges represented by a list of data references
+ relations passed as input.
+
+ Input:
+ COND_EXPR - input conditional expression. New conditions will be chained
+ logical and operation.
+ LOOP_VINFO - fields of the loop information are used.
+ 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;
+ tree addr_base_b;
+
+ tree step_a = DR_STEP (DDR_A (ddr));
+ tree segment_length_a =
+ fold_build2 (MULT_EXPR, integer_type_node, step_a, vect_factor);
+
+ tree step_b = DR_STEP (DDR_B (ddr));
+ tree segment_length_b =
+ fold_build2 (MULT_EXPR, integer_type_node, step_b, 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);
+ }
+
+ addr_base_a =
+ vect_create_addr_base_for_vector_ref (stmt_a, cond_expr_stmt_list,
+ NULL_TREE);
+ addr_base_b =
+ vect_create_addr_base_for_vector_ref (stmt_b, cond_expr_stmt_list,
+ NULL_TREE);
+
+ part_cond_expr =
+ fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
+ fold_build2 (LT_EXPR, boolean_type_node,
+ fold_build2 (PLUS_EXPR, ptr_type_node,
+ addr_base_a,
+ segment_length_a),
+ addr_base_b),
+ fold_build2 (LT_EXPR, boolean_type_node,
+ fold_build2 (PLUS_EXPR, ptr_type_node,
+ 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.
The analysis phase has determined that the loop is vectorizable.
@@ -5827,16 +5931,21 @@
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 vectorised 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;
@@ -5845,9 +5954,23 @@
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);
Index: params.def
===================================================================
--- params.def (revision 127316)
+++ params.def (working copy)
@@ -485,11 +485,16 @@
"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",
Index: testsuite/gcc.dg/vect/no-vfa-vect-53.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-53.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-53.c (revision 0)
@@ -0,0 +1,62 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-102a.c
===================================================================
--- testsuite/gcc.dg/vect/vect-102a.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-102a.c (working copy)
@@ -1,57 +0,0 @@
-/* { 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" } } */
-
Index: testsuite/gcc.dg/vect/no-vfa-vect-45.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-45.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-45.c (revision 0)
@@ -0,0 +1,59 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-37.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-37.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-37.c (revision 0)
@@ -0,0 +1,61 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-79.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-79.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-79.c (revision 0)
@@ -0,0 +1,50 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-51.c
===================================================================
--- testsuite/gcc.dg/vect/vect-51.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-51.c (working copy)
@@ -1,59 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/pr29145.c
===================================================================
--- testsuite/gcc.dg/vect/pr29145.c (revision 127316)
+++ testsuite/gcc.dg/vect/pr29145.c (working copy)
@@ -1,48 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-102a.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-102a.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-102a.c (revision 0)
@@ -0,0 +1,57 @@
+/* { 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" } } */
+
Index: testsuite/gcc.dg/vect/vect-43.c
===================================================================
--- testsuite/gcc.dg/vect/vect-43.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-43.c (working copy)
@@ -1,78 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-101.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-101.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-101.c (revision 0)
@@ -0,0 +1,49 @@
+/* { 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" } } */
+
Index: testsuite/gcc.dg/vect/vect-61.c
===================================================================
--- testsuite/gcc.dg/vect/vect-61.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-61.c (working copy)
@@ -1,64 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-53.c
===================================================================
--- testsuite/gcc.dg/vect/vect-53.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-53.c (working copy)
@@ -1,62 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-102.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-102.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-102.c (revision 0)
@@ -0,0 +1,57 @@
+/* { 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" } } */
+
Index: testsuite/gcc.dg/vect/vect-45.c
===================================================================
--- testsuite/gcc.dg/vect/vect-45.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-45.c (working copy)
@@ -1,59 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-101.c
===================================================================
--- testsuite/gcc.dg/vect/vect-101.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-101.c (working copy)
@@ -1,49 +0,0 @@
-/* { 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" } } */
-
Index: testsuite/gcc.dg/vect/no-vfa-vect-57.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-57.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-57.c (revision 0)
@@ -0,0 +1,62 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-37.c
===================================================================
--- testsuite/gcc.dg/vect/vect-37.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-37.c (working copy)
@@ -1,61 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-79.c
===================================================================
--- testsuite/gcc.dg/vect/vect-79.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-79.c (working copy)
@@ -1,50 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-49.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-49.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-49.c (revision 0)
@@ -0,0 +1,61 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-102.c
===================================================================
--- testsuite/gcc.dg/vect/vect-102.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-102.c (working copy)
@@ -1,57 +0,0 @@
-/* { 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" } } */
-
Index: testsuite/gcc.dg/vect/no-vfa-vect-51.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-51.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-51.c (revision 0)
@@ -0,0 +1,59 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-pr29145.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-pr29145.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-pr29145.c (revision 0)
@@ -0,0 +1,48 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-dv-2.c
===================================================================
--- testsuite/gcc.dg/vect/vect-dv-2.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-dv-2.c (working copy)
@@ -1,77 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-43.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-43.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-43.c (revision 0)
@@ -0,0 +1,78 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-57.c
===================================================================
--- testsuite/gcc.dg/vect/vect-57.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-57.c (working copy)
@@ -1,62 +0,0 @@
-/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c (revision 0)
@@ -0,0 +1,77 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/no-vfa-vect-61.c
===================================================================
--- testsuite/gcc.dg/vect/no-vfa-vect-61.c (revision 0)
+++ testsuite/gcc.dg/vect/no-vfa-vect-61.c (revision 0)
@@ -0,0 +1,64 @@
+/* { 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" } } */
Index: testsuite/gcc.dg/vect/vect-49.c
===================================================================
--- testsuite/gcc.dg/vect/vect-49.c (revision 127316)
+++ testsuite/gcc.dg/vect/vect-49.c (working copy)
@@ -1,61 +0,0 @@
-/* { 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" } } */
Index: testsuite/gfortran.dg/vect/pr19049.f90
===================================================================
--- testsuite/gfortran.dg/vect/pr19049.f90 (revision 127316)
+++ testsuite/gfortran.dg/vect/pr19049.f90 (working copy)
@@ -1,24 +0,0 @@
-! { dg-do compile }
-! { dg-require-effective-target vect_float }
-
-subroutine s111 (ntimes,ld,n,ctime,dtime,a,b,c,d,e,aa,bb,cc)
-! linear dependence testing
-! no dependence - vectorizable
-! but not consecutive access
-
- integer ntimes, ld, n, i, nl
- real a(n), b(n), c(n), d(n), e(n), aa(ld,n), bb(ld,n), cc(ld,n)
- real t1, t2, second, chksum, ctime, dtime, cs1d
- do 1 nl = 1,2*ntimes
- do 10 i = 2,n,2
- a(i) = a(i-1) + b(i)
- 10 continue
- call dummy(ld,n,a,b,c,d,e,aa,bb,cc,1.)
- 1 continue
- return
- end
-
-! { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } }
-! { dg-final { scan-tree-dump-times "complicated access pattern" 1 "vect" } }
-! { dg-final { cleanup-tree-dump "vect" } }
-
Index: testsuite/gfortran.dg/vect/no-vfa-pr19049.f90
===================================================================
--- testsuite/gfortran.dg/vect/no-vfa-pr19049.f90 (revision 0)
+++ testsuite/gfortran.dg/vect/no-vfa-pr19049.f90 (revision 0)
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-require-effective-target vect_float }
+
+subroutine s111 (ntimes,ld,n,ctime,dtime,a,b,c,d,e,aa,bb,cc)
+! linear dependence testing
+! no dependence - vectorizable
+! but not consecutive access
+
+ integer ntimes, ld, n, i, nl
+ real a(n), b(n), c(n), d(n), e(n), aa(ld,n), bb(ld,n), cc(ld,n)
+ real t1, t2, second, chksum, ctime, dtime, cs1d
+ do 1 nl = 1,2*ntimes
+ do 10 i = 2,n,2
+ a(i) = a(i-1) + b(i)
+ 10 continue
+ call dummy(ld,n,a,b,c,d,e,aa,bb,cc,1.)
+ 1 continue
+ return
+ end
+
+! { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } }
+! { dg-final { scan-tree-dump-times "complicated access pattern" 1 "vect" } }
+! { dg-final { cleanup-tree-dump "vect" } }
+
next reply other threads:[~2007-08-14 11:02 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-14 11:02 Victor Kaplansky [this message]
2007-08-14 11:38 ` Zdenek Dvorak
2007-08-14 12:23 ` Victor Kaplansky
2007-08-14 17:07 ` Dorit Nuzman
[not found] <OF128D770D.7C095078-ONC2257337.00562B23-C2257337.005E3D6E@LocalDomain>
2007-08-16 11:07 ` Victor Kaplansky
2007-08-16 13:09 ` Dorit Nuzman
[not found] <OF531586B8.1BD86F22-ONC2257339.0046568C-C2257339.00487D11@LocalDomain>
2007-08-16 13:49 ` Victor Kaplansky
[not found] <OFD8F5F2C8.37DFE3DF-ONC2257339.004A59E3-C2257339.004BD2B1@LocalDomain>
2007-08-18 7:54 ` Dorit Nuzman
2007-08-19 9:20 ` Dorit Nuzman
2007-08-19 15:13 ` Dorit Nuzman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=OFFD346E44.D15F9B49-ONC2257337.00301C78-C2257337.003C743B@il.ibm.com \
--to=victork@il.ibm.com \
--cc=gcc-patches@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).