summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-31 12:25:04 +0000
committerwschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-31 12:25:04 +0000
commitba69439f11358421e81653d967731550671a7289 (patch)
treeb5228437c04a0ba87c454b39c628730188352ba0
parent86c98a43b4af8d90165cded55c0565a849e22050 (diff)
downloadgcc-ba69439f11358421e81653d967731550671a7289.tar.gz
gcc:
2012-07-31 Bill Schmidt <wschmidt@linux.ibm.com> PR tree-optimization/53773 * tree-vectorizer.h (struct _loop_vec_info): Add operands_swapped. (LOOP_VINFO_OPERANDS_SWAPPED): New macro. * tree-vect-loop.c (new_loop_vec_info): Initialize LOOP_VINFO_OPERANDS_SWAPPED field. (destroy_loop_vec_info): Restore canonical form. (vect_is_slp_reduction): Set LOOP_VINFO_OPERANDS_SWAPPED field. (vect_is_simple_reduction_1): Likewise. gcc/testsuite: 2012-07-31 Bill Schmidt <wschmidt@linux.ibm.com> PR tree-optimization/53773 * testsuite/gcc.dg/vect/pr53773.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190007 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr53773.c19
-rw-r--r--gcc/tree-vect-loop.c25
-rw-r--r--gcc/tree-vectorizer.h7
5 files changed, 67 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 879137aa802..0e1a0c57d9f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2012-07-31 Bill Schmidt <wschmidt@linux.ibm.com>
+
+ PR tree-optimization/53773
+ * tree-vectorizer.h (struct _loop_vec_info): Add operands_swapped.
+ (LOOP_VINFO_OPERANDS_SWAPPED): New macro.
+ * tree-vect-loop.c (new_loop_vec_info): Initialize
+ LOOP_VINFO_OPERANDS_SWAPPED field.
+ (destroy_loop_vec_info): Restore canonical form.
+ (vect_is_slp_reduction): Set LOOP_VINFO_OPERANDS_SWAPPED field.
+ (vect_is_simple_reduction_1): Likewise.
+
2012-07-31 Steven Bosscher <steven@gcc.gnu.org>
* sched-vis.c (dump_insn_slim): Print print_rtx_head at the
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 996c6d3bd34..c82f1524e17 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-31 Bill Schmidt <wschmidt@linux.ibm.com>
+
+ PR tree-optimization/53773
+ * testsuite/gcc.dg/vect/pr53773.c: New test.
+
2012-07-31 Nick Clifton <nickc@redhat.com>
* gcc.dg/stack-usage-1.c (SIZE): Define for FRV.
diff --git a/gcc/testsuite/gcc.dg/vect/pr53773.c b/gcc/testsuite/gcc.dg/vect/pr53773.c
new file mode 100644
index 00000000000..4fde3cbf658
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr53773.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+int
+foo (int integral, int decimal, int power_ten)
+{
+ while (power_ten > 0)
+ {
+ integral *= 10;
+ decimal *= 10;
+ power_ten--;
+ }
+
+ return integral+decimal;
+}
+
+/* Two occurrences in annotations, two in code. */
+/* { dg-final { scan-tree-dump-times "\\* 10" 4 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index d9094679dd2..cdd3def2974 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -853,6 +853,7 @@ new_loop_vec_info (struct loop *loop)
LOOP_VINFO_PEELING_HTAB (res) = NULL;
LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
+ LOOP_VINFO_OPERANDS_SWAPPED (res) = false;
return res;
}
@@ -873,6 +874,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
int j;
VEC (slp_instance, heap) *slp_instances;
slp_instance instance;
+ bool swapped;
if (!loop_vinfo)
return;
@@ -881,6 +883,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
bbs = LOOP_VINFO_BBS (loop_vinfo);
nbbs = loop->num_nodes;
+ swapped = LOOP_VINFO_OPERANDS_SWAPPED (loop_vinfo);
if (!clean_stmts)
{
@@ -905,6 +908,22 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
for (si = gsi_start_bb (bb); !gsi_end_p (si); )
{
gimple stmt = gsi_stmt (si);
+
+ /* We may have broken canonical form by moving a constant
+ into RHS1 of a commutative op. Fix such occurrences. */
+ if (swapped && is_gimple_assign (stmt))
+ {
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+
+ if ((code == PLUS_EXPR
+ || code == POINTER_PLUS_EXPR
+ || code == MULT_EXPR)
+ && CONSTANT_CLASS_P (gimple_assign_rhs1 (stmt)))
+ swap_tree_operands (stmt,
+ gimple_assign_rhs1_ptr (stmt),
+ gimple_assign_rhs2_ptr (stmt));
+ }
+
/* Free stmt_vec_info. */
free_stmt_vec_info (stmt);
gsi_next (&si);
@@ -1920,6 +1939,9 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
gimple_assign_rhs1_ptr (next_stmt),
gimple_assign_rhs2_ptr (next_stmt));
update_stmt (next_stmt);
+
+ if (CONSTANT_CLASS_P (gimple_assign_rhs1 (next_stmt)))
+ LOOP_VINFO_OPERANDS_SWAPPED (loop_info) = true;
}
else
return false;
@@ -2324,6 +2346,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
swap_tree_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt),
gimple_assign_rhs2_ptr (def_stmt));
+
+ if (CONSTANT_CLASS_P (gimple_assign_rhs1 (def_stmt)))
+ LOOP_VINFO_OPERANDS_SWAPPED (loop_info) = true;
}
else
{
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 96cc52e3df9..76418386e1a 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -296,6 +296,12 @@ typedef struct _loop_vec_info {
this. */
bool peeling_for_gaps;
+ /* Reductions are canonicalized so that the last operand is the reduction
+ operand. If this places a constant into RHS1, this decanonicalizes
+ GIMPLE for other phases, so we must track when this has occurred and
+ fix it up. */
+ bool operands_swapped;
+
} *loop_vec_info;
/* Access Functions. */
@@ -326,6 +332,7 @@ typedef struct _loop_vec_info {
#define LOOP_VINFO_PEELING_HTAB(L) (L)->peeling_htab
#define LOOP_VINFO_TARGET_COST_DATA(L) (L)->target_cost_data
#define LOOP_VINFO_PEELING_FOR_GAPS(L) (L)->peeling_for_gaps
+#define LOOP_VINFO_OPERANDS_SWAPPED(L) (L)->operands_swapped
#define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
VEC_length (gimple, (L)->may_misalign_stmts) > 0