aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr66856-1.c24
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr66856-2.c26
-rw-r--r--gcc/tree-vect-loop.c7
-rw-r--r--gcc/tree-vect-slp.c74
-rw-r--r--gcc/tree-vect-stmts.c2
-rw-r--r--gcc/tree-vectorizer.h3
8 files changed, 142 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 675893e..067fb07 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,19 @@
2016-01-15 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/66856
+ * tree-vect-loop.c (vect_transform_loop): Free SLP instances here.
+ * tree-vect-slp.c (vect_free_slp_tree): Decrement stmt reference count.
+ (vect_create_new_slp_node): Increment stmt reference count.
+ (vect_get_and_check_slp_defs): Make sure stmts are nor already in
+ an SLP tree before swapping operands.
+ (vect_build_slp_tree): Likewise.
+ (destroy_bb_vec_info): Free stmt info after SLP instances.
+ * tree-vect-stmts.c (new_stmt_vec_info): Initialize reference count.
+ * tree-vectorizer.h (struct _stmt_vec_info): Add num_slp_uses field.
+ (STMT_VINFO_NUM_SLP_USES): New macro.
+
+2016-01-15 Richard Biener <rguenther@suse.de>
+
PR debug/69137
* dwarf2out.c (add_linkage_name_raw): New function split out from ...
(add_linkage_name): ... here.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a093585..bc6105d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2016-01-15 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/66856
+ * gcc.dg/torture/pr66856-1.c: New testcase.
+ * gcc.dg/torture/pr66856-2.c: Likewise.
+
+2016-01-15 Richard Biener <rguenther@suse.de>
+
PR debug/69137
* g++.dg/lto/pr69137_0.C: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr66856-1.c b/gcc/testsuite/gcc.dg/torture/pr66856-1.c
new file mode 100644
index 0000000..9da89fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr66856-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mavx2" { target x86_64-*-* i?86-*-* } } */
+
+short c;
+int d;
+int fn1(int p1, int p2) {
+ int a, b;
+ a = p1 >> 3 & p2;
+ b = p1 & 072;
+ a |= a >> 5;
+ a |= b >> 5;
+ return a;
+}
+void fn2() {
+ short *e = &c;
+ int *f;
+ int g;
+ while (d -= 4) {
+ fn1(1, 1);
+ fn1(1, 1) * fn1(1, 1) * fn1(1, 1);
+ *e++ = fn1(*f++, g);
+ *e++ = fn1(*f++, g);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr66856-2.c b/gcc/testsuite/gcc.dg/torture/pr66856-2.c
new file mode 100644
index 0000000..5089085
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr66856-2.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+
+typedef int uint32_t;
+int c, e, f, g, h;
+short *d;
+uint32_t fn1(uint32_t p1, uint32_t p2)
+{
+ uint32_t a, b;
+ a = p1 >> 3 & p2;
+ b = p1 & 072;
+ a |= a >> 5;
+ a |= b >> 5;
+ return a;
+}
+
+void fn2()
+{
+ uint32_t *i;
+ uint32_t j;
+ while (c -= 4) {
+ fn1(e, j);
+ fn1(f, j) * fn1(g, j) * fn1(h, j);
+ *d++ = fn1(*i++, j);
+ *d++ = fn1(*i++, j);
+ }
+}
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 83ded8b..6034672 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -6930,4 +6930,11 @@ vect_transform_loop (loop_vec_info loop_vinfo)
"OUTER LOOP VECTORIZED\n");
dump_printf (MSG_NOTE, "\n");
}
+
+ /* Free SLP instances here because otherwise stmt reference counting
+ won't work. */
+ slp_instance instance;
+ FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), i, instance)
+ vect_free_slp_instance (instance);
+ LOOP_VINFO_SLP_INSTANCES (loop_vinfo).release ();
}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index fe422f8..5767e19 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -54,6 +54,15 @@ vect_free_slp_tree (slp_tree node)
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
vect_free_slp_tree (child);
+ gimple *stmt;
+ FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
+ /* After transform some stmts are removed and thus their vinfo is gone. */
+ if (vinfo_for_stmt (stmt))
+ {
+ gcc_assert (STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt)) > 0);
+ STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt))--;
+ }
+
SLP_TREE_CHILDREN (node).release ();
SLP_TREE_SCALAR_STMTS (node).release ();
SLP_TREE_VEC_STMTS (node).release ();
@@ -102,6 +111,10 @@ vect_create_new_slp_node (vec<gimple *> scalar_stmts)
SLP_TREE_TWO_OPERATORS (node) = false;
SLP_TREE_DEF_TYPE (node) = vect_internal_def;
+ unsigned i;
+ FOR_EACH_VEC_ELT (scalar_stmts, i, stmt)
+ STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt))++;
+
return node;
}
@@ -401,6 +414,20 @@ again:
/* Swap operands. */
if (swapped)
{
+ /* If there are already uses of this stmt in a SLP instance then
+ we've committed to the operand order and can't swap it. */
+ if (STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt)) != 0)
+ {
+ if (dump_enabled_p ())
+ {
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: cannot swap operands of "
+ "shared stmt ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+ }
+ return -1;
+ }
+
if (first_op_cond)
{
tree cond = gimple_assign_rhs1 (stmt);
@@ -411,6 +438,12 @@ again:
else
swap_ssa_operands (stmt, gimple_assign_rhs1_ptr (stmt),
gimple_assign_rhs2_ptr (stmt));
+ if (dump_enabled_p ())
+ {
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "swapped operands to match def types in ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
+ }
}
return 0;
@@ -1007,6 +1040,23 @@ vect_build_slp_tree (vec_info *vinfo,
behavior. */
&& *npermutes < 4)
{
+ /* Verify if we can safely swap or if we committed to a specific
+ operand order already. */
+ for (j = 0; j < group_size; ++j)
+ if (!matches[j]
+ && STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmts[j])) != 0)
+ {
+ if (dump_enabled_p ())
+ {
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: cannot swap operands "
+ "of shared stmt ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ stmts[j], 0);
+ }
+ goto fail;
+ }
+
/* Swap mismatched definition stmts. */
dump_printf_loc (MSG_NOTE, vect_location,
"Re-trying with swapped operands of stmts ");
@@ -1095,6 +1145,7 @@ vect_build_slp_tree (vec_info *vinfo,
++*npermutes;
}
+fail:
gcc_assert (child == NULL);
FOR_EACH_VEC_ELT (children, j, child)
vect_free_slp_tree (child);
@@ -2186,18 +2237,21 @@ new_bb_vec_info (gimple_stmt_iterator region_begin,
static void
destroy_bb_vec_info (bb_vec_info bb_vinfo)
{
- vec<slp_instance> slp_instances;
slp_instance instance;
- basic_block bb;
- gimple_stmt_iterator si;
unsigned i;
if (!bb_vinfo)
return;
- bb = BB_VINFO_BB (bb_vinfo);
+ vect_destroy_datarefs (bb_vinfo);
+ free_dependence_relations (BB_VINFO_DDRS (bb_vinfo));
+ BB_VINFO_GROUPED_STORES (bb_vinfo).release ();
+ FOR_EACH_VEC_ELT (BB_VINFO_SLP_INSTANCES (bb_vinfo), i, instance)
+ vect_free_slp_instance (instance);
+ BB_VINFO_SLP_INSTANCES (bb_vinfo).release ();
+ destroy_cost_data (BB_VINFO_TARGET_COST_DATA (bb_vinfo));
- for (si = bb_vinfo->region_begin;
+ for (gimple_stmt_iterator si = bb_vinfo->region_begin;
gsi_stmt (si) != gsi_stmt (bb_vinfo->region_end); gsi_next (&si))
{
gimple *stmt = gsi_stmt (si);
@@ -2211,16 +2265,8 @@ destroy_bb_vec_info (bb_vec_info bb_vinfo)
gimple_set_uid (stmt, -1);
}
- vect_destroy_datarefs (bb_vinfo);
- free_dependence_relations (BB_VINFO_DDRS (bb_vinfo));
- BB_VINFO_GROUPED_STORES (bb_vinfo).release ();
- slp_instances = BB_VINFO_SLP_INSTANCES (bb_vinfo);
- FOR_EACH_VEC_ELT (slp_instances, i, instance)
- vect_free_slp_instance (instance);
- BB_VINFO_SLP_INSTANCES (bb_vinfo).release ();
- destroy_cost_data (BB_VINFO_TARGET_COST_DATA (bb_vinfo));
+ BB_VINFO_BB (bb_vinfo)->aux = NULL;
free (bb_vinfo);
- bb->aux = NULL;
}
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 872fa07..635c797 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -8391,6 +8391,8 @@ new_stmt_vec_info (gimple *stmt, vec_info *vinfo)
STMT_VINFO_SAME_ALIGN_REFS (res).create (0);
STMT_SLP_TYPE (res) = loop_vect;
+ STMT_VINFO_NUM_SLP_USES (res) = 0;
+
GROUP_FIRST_ELEMENT (res) = NULL;
GROUP_NEXT_ELEMENT (res) = NULL;
GROUP_SIZE (res) = 0;
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 1465070..0a3f5d7 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -601,6 +601,8 @@ typedef struct _stmt_vec_info {
/* For reduction loops, this is the type of reduction. */
enum vect_reduction_type v_reduc_type;
+ /* The number of scalar stmt references from active SLP instances. */
+ unsigned int num_slp_uses;
} *stmt_vec_info;
/* Access Functions. */
@@ -653,6 +655,7 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo)
#define STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED(S) (S)->loop_phi_evolution_base_unchanged
#define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
#define STMT_VINFO_MIN_NEG_DIST(S) (S)->min_neg_dist
+#define STMT_VINFO_NUM_SLP_USES(S) (S)->num_slp_uses
#define GROUP_FIRST_ELEMENT(S) (S)->first_element
#define GROUP_NEXT_ELEMENT(S) (S)->next_element