aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-04-15 14:08:41 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-04-15 14:08:41 +0000
commit5185d248d5a554d394c80126646160abbf4f0bfa (patch)
tree52afb1966c9cc2b68285ff2632e2f574ef6e4c9d /gcc
parenta24243a0e5e09bd562eeb362c1c89ee497ea67e7 (diff)
downloadgcc-5185d248d5a554d394c80126646160abbf4f0bfa.zip
gcc-5185d248d5a554d394c80126646160abbf4f0bfa.tar.gz
gcc-5185d248d5a554d394c80126646160abbf4f0bfa.tar.bz2
re PR tree-optimization/56933 (Vectorizer missing read-write dependency for interleaved accesses)
2013-04-15 Richard Biener <rguenther@suse.de> PR tree-optimization/56933 * tree-vectorizer.h (struct _stmt_vec_info): Remove read_write_dep member. (GROUP_READ_WRITE_DEPENDENCE): Remove. (STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE): Likewise. * tree-vect-data-refs.c (vect_analyze_group_access): Move dependence check ... vect_analyze_data_ref_dependence (vect_analyze_data_ref_dependence): ... here. * tree-vect-stmts.c (new_stmt_vec_info): Do not initialize GROUP_READ_WRITE_DEPENDENCE. * gcc.dg/vect/pr56933.c: New testcase. From-SVN: r197972
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr56933.c40
-rw-r--r--gcc/tree-vect-data-refs.c47
-rw-r--r--gcc/tree-vect-stmts.c1
-rw-r--r--gcc/tree-vectorizer.h6
6 files changed, 87 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fd1731e..db1b373 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2013-04-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56933
+ * tree-vectorizer.h (struct _stmt_vec_info): Remove read_write_dep
+ member.
+ (GROUP_READ_WRITE_DEPENDENCE): Remove.
+ (STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE): Likewise.
+ * tree-vect-data-refs.c (vect_analyze_group_access): Move
+ dependence check ...
+ vect_analyze_data_ref_dependence (vect_analyze_data_ref_dependence):
+ ... here.
+ * tree-vect-stmts.c (new_stmt_vec_info): Do not initialize
+ GROUP_READ_WRITE_DEPENDENCE.
+
2013-04-15 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* emit-rtl.c (reset_all_used_flags): New function.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index efc3ded..4613593 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-04-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56933
+ * gcc.dg/vect/pr56933.c: New testcase.
+
2013-04-15 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/arm/anddi3-opt.c: New test.
diff --git a/gcc/testsuite/gcc.dg/vect/pr56933.c b/gcc/testsuite/gcc.dg/vect/pr56933.c
new file mode 100644
index 0000000..93a7da2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr56933.c
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+
+extern void abort (void);
+void __attribute__((noinline,noclone))
+foo (double *b, double *d, double *f)
+{
+ int i;
+ for (i = 0; i < 1024; i++)
+ {
+ d[2*i] = 2. * d[2*i];
+ d[2*i+1] = 4. * d[2*i+1];
+ b[i] = d[2*i] - 1.;
+ f[i] = d[2*i+1] + 2.;
+ }
+}
+int main()
+{
+ double b[1024], d[2*1024], f[1024];
+ int i;
+ for (i = 0; i < 2*1024; i++)
+ d[i] = 1.;
+ foo (b, d, f);
+ for (i = 0; i < 1024; i+= 2)
+ {
+ if (d[2*i] != 2.)
+ abort ();
+ if (d[2*i+1] != 4.)
+ abort ();
+ }
+ for (i = 0; i < 1024; i++)
+ {
+ if (b[i] != 1.)
+ abort ();
+ if (f[i] != 6.)
+ abort ();
+ }
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 64f2a8b..1fe5047 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -341,14 +341,34 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
}
- /* For interleaving, mark that there is a read-write dependency if
- necessary. We check before that one of the data-refs is store. */
- if (DR_IS_READ (dra))
- GROUP_READ_WRITE_DEPENDENCE (stmtinfo_a) = true;
- else
- {
- if (DR_IS_READ (drb))
- GROUP_READ_WRITE_DEPENDENCE (stmtinfo_b) = true;
+ /* When we perform grouped accesses and perform implicit CSE
+ by detecting equal accesses and doing disambiguation with
+ runtime alias tests like for
+ .. = a[i];
+ .. = a[i+1];
+ a[i] = ..;
+ a[i+1] = ..;
+ *p = ..;
+ .. = a[i];
+ .. = a[i+1];
+ where we will end up loading { a[i], a[i+1] } once, make
+ sure that inserting group loads before the first load and
+ stores after the last store will do the right thing. */
+ if ((STMT_VINFO_GROUPED_ACCESS (stmtinfo_a)
+ && GROUP_SAME_DR_STMT (stmtinfo_a))
+ || (STMT_VINFO_GROUPED_ACCESS (stmtinfo_b)
+ && GROUP_SAME_DR_STMT (stmtinfo_b)))
+ {
+ gimple earlier_stmt;
+ earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
+ if (DR_IS_WRITE
+ (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "READ_WRITE dependence in interleaving.");
+ return true;
+ }
}
continue;
@@ -2097,17 +2117,6 @@ vect_analyze_group_access (struct data_reference *dr)
return false;
}
- /* Check that there is no load-store dependencies for this loads
- to prevent a case of load-store-load to the same location. */
- if (GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (next))
- || GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (prev)))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "READ_WRITE dependence in interleaving.");
- return false;
- }
-
/* For load use the same data-ref load. */
GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 3590e39..bdd4d64 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -5962,7 +5962,6 @@ new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo,
GROUP_STORE_COUNT (res) = 0;
GROUP_GAP (res) = 0;
GROUP_SAME_DR_STMT (res) = NULL;
- GROUP_READ_WRITE_DEPENDENCE (res) = false;
return res;
}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 0f1a02a..8071149 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -460,10 +460,6 @@ typedef struct _stmt_vec_info {
/* Stmt is part of some pattern (computation idiom) */
bool in_pattern_p;
- /* For loads only, if there is a store with the same location, this field is
- TRUE. */
- bool read_write_dep;
-
/* The stmt to which this info struct refers to. */
gimple stmt;
@@ -589,7 +585,6 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_GROUP_STORE_COUNT(S) (S)->store_count
#define STMT_VINFO_GROUP_GAP(S) (S)->gap
#define STMT_VINFO_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt
-#define STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep
#define STMT_VINFO_GROUPED_ACCESS(S) ((S)->first_element != NULL && (S)->data_ref_info)
#define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
@@ -599,7 +594,6 @@ typedef struct _stmt_vec_info {
#define GROUP_STORE_COUNT(S) (S)->store_count
#define GROUP_GAP(S) (S)->gap
#define GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt
-#define GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep
#define STMT_VINFO_RELEVANT_P(S) ((S)->relevant != vect_unused_in_scope)