summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-12-02 16:23:20 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-12-02 16:23:20 +0000
commit0185abae1d7274f87137b388a54a1bd7b8c77889 (patch)
tree9731011d784b5a20bbfc11e4a58be14bb690acd5
parent33fb6a59d3daa98dc701897b1946516427c6ae06 (diff)
downloadgcc-0185abae1d7274f87137b388a54a1bd7b8c77889.tar.gz
2010-12-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46723 * tree-vect-loop.c (get_initial_def_for_induction): Strip conversions from the induction evolution and apply it to the result instead. * tree-vect-stmts.c (vect_get_vec_def_for_operand): Handle assigns for induction defs. * gcc.dg/torture/pr46723.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167377 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr46723.c10
-rw-r--r--gcc/tree-vect-loop.c62
-rw-r--r--gcc/tree-vect-stmts.c6
5 files changed, 70 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1b942af3b01..bde5e915515 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2010-12-02 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/46723
+ * tree-vect-loop.c (get_initial_def_for_induction): Strip
+ conversions from the induction evolution and apply it to
+ the result instead.
+ * tree-vect-stmts.c (vect_get_vec_def_for_operand): Handle
+ assigns for induction defs.
+
+2010-12-02 Richard Guenther <rguenther@suse.de>
+
* value-prof.c (gimple_ic): Use stmt_ends_bb_p to detect
the case we need to split the edge and not the block.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b0e2553f12f..43f1768ecd8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2010-12-02 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/46723
+ * gcc.dg/torture/pr46723.c: New testcase.
+
+2010-12-02 Richard Guenther <rguenther@suse.de>
+
PR lto/44871
* g++.dg/lto/20101126-1_0.C: New testcase.
* g++.dg/lto/20101126-1_1.c: Likewise.
diff --git a/gcc/testsuite/gcc.dg/torture/pr46723.c b/gcc/testsuite/gcc.dg/torture/pr46723.c
new file mode 100644
index 00000000000..40c6e8cd690
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr46723.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+short *m;
+void test()
+{
+ short x = 128;
+ unsigned int i;
+ for (i = 0; i < 128; ++i, x = (unsigned short)x + 1)
+ m[i] = x;
+}
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 87d5ae80596..7a562b124c0 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2594,7 +2594,7 @@ get_initial_def_for_induction (gimple iv_phi)
stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- tree scalar_type = TREE_TYPE (gimple_phi_result (iv_phi));
+ tree scalar_type;
tree vectype;
int nunits;
edge pe = loop_preheader_edge (loop);
@@ -2623,24 +2623,7 @@ get_initial_def_for_induction (gimple iv_phi)
gimple_stmt_iterator si;
basic_block bb = gimple_bb (iv_phi);
tree stepvectype;
-
- vectype = get_vectype_for_scalar_type (scalar_type);
- gcc_assert (vectype);
- nunits = TYPE_VECTOR_SUBPARTS (vectype);
- ncopies = vf / nunits;
-
- gcc_assert (phi_info);
- gcc_assert (ncopies >= 1);
-
- /* Find the first insertion point in the BB. */
- si = gsi_after_labels (bb);
-
- if (INTEGRAL_TYPE_P (scalar_type))
- step_expr = build_int_cst (scalar_type, 0);
- else if (POINTER_TYPE_P (scalar_type))
- step_expr = size_zero_node;
- else
- step_expr = build_real (scalar_type, dconst0);
+ tree resvectype;
/* Is phi in an inner-loop, while vectorizing an enclosing outer-loop? */
if (nested_in_vect_loop_p (loop, iv_phi))
@@ -2657,11 +2640,25 @@ get_initial_def_for_induction (gimple iv_phi)
access_fn = analyze_scalar_evolution (iv_loop, PHI_RESULT (iv_phi));
gcc_assert (access_fn);
+ STRIP_NOPS (access_fn);
ok = vect_is_simple_iv_evolution (iv_loop->num, access_fn,
&init_expr, &step_expr);
gcc_assert (ok);
pe = loop_preheader_edge (iv_loop);
+ scalar_type = TREE_TYPE (init_expr);
+ vectype = get_vectype_for_scalar_type (scalar_type);
+ resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi)));
+ gcc_assert (vectype);
+ nunits = TYPE_VECTOR_SUBPARTS (vectype);
+ ncopies = vf / nunits;
+
+ gcc_assert (phi_info);
+ gcc_assert (ncopies >= 1);
+
+ /* Find the first insertion point in the BB. */
+ si = gsi_after_labels (bb);
+
/* Create the vector that holds the initial_value of the induction. */
if (nested_in_vect_loop)
{
@@ -2687,7 +2684,7 @@ get_initial_def_for_induction (gimple iv_phi)
}
t = NULL_TREE;
- t = tree_cons (NULL_TREE, init_expr, t);
+ t = tree_cons (NULL_TREE, new_name, t);
for (i = 1; i < nunits; i++)
{
/* Create: new_name_i = new_name + step_expr */
@@ -2802,6 +2799,19 @@ get_initial_def_for_induction (gimple iv_phi)
gimple_assign_set_lhs (new_stmt, vec_def);
gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
+ if (!useless_type_conversion_p (resvectype, vectype))
+ {
+ new_stmt = gimple_build_assign_with_ops
+ (VIEW_CONVERT_EXPR,
+ vect_get_new_vect_var (resvectype, vect_simple_var,
+ "vec_iv_"),
+ build1 (VIEW_CONVERT_EXPR, resvectype,
+ gimple_assign_lhs (new_stmt)), NULL_TREE);
+ gimple_assign_set_lhs (new_stmt,
+ make_ssa_name
+ (gimple_assign_lhs (new_stmt), new_stmt));
+ gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
+ }
set_vinfo_for_stmt (new_stmt,
new_stmt_vec_info (new_stmt, loop_vinfo, NULL));
STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt;
@@ -2849,6 +2859,18 @@ get_initial_def_for_induction (gimple iv_phi)
}
STMT_VINFO_VEC_STMT (phi_info) = induction_phi;
+ if (!useless_type_conversion_p (resvectype, vectype))
+ {
+ new_stmt = gimple_build_assign_with_ops
+ (VIEW_CONVERT_EXPR,
+ vect_get_new_vect_var (resvectype, vect_simple_var, "vec_iv_"),
+ build1 (VIEW_CONVERT_EXPR, resvectype, induc_def), NULL_TREE);
+ induc_def = make_ssa_name (gimple_assign_lhs (new_stmt), new_stmt);
+ gimple_assign_set_lhs (new_stmt, induc_def);
+ si = gsi_start_bb (bb);
+ gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
+ }
+
return induc_def;
}
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index b1650d2ee59..e5bfcbe81ac 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1102,8 +1102,10 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
/* Get the def from the vectorized stmt. */
def_stmt_info = vinfo_for_stmt (def_stmt);
vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
- gcc_assert (vec_stmt && gimple_code (vec_stmt) == GIMPLE_PHI);
- vec_oprnd = PHI_RESULT (vec_stmt);
+ if (gimple_code (vec_stmt) == GIMPLE_PHI)
+ vec_oprnd = PHI_RESULT (vec_stmt);
+ else
+ vec_oprnd = gimple_get_lhs (vec_stmt);
return vec_oprnd;
}