Commit 1ffe34d9 by Andrew Pinski Committed by Richard Biener

re PR tree-optimization/31358 (IV-OPTs produces a weird MEM_REF)

2008-03-11  Andrew Pinski  <andrew_pinski@playstation.sony.com>
	Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/31358
	* tree-ssa-loop-manip.c (create_iv): Call force_gimple_operand for
	the step with a NULL_TREE.
	* tree-ssa-loop-ivopts.c (find_bivs): Convert the step
	to sizetype if type is a pointer type.
	(add_candidate_1): Don't convert the base and step to
	the generic type if the orginal type is a pointer type.
	(add_iv_value_candidates): Use sizetype for the step
	if type is a pointer type.
	(cand_value_at): Likewise.
	* tree-ssa-address.c (add_to_parts): Use POINTER_PLUS_EXPR
	for pointer types.
	* tree-affine.c (tree_to_aff_combination <POINTER_PLUS_EXPR>):
	Don't convert the tem affine to the type.
	(add_elt_to_tree): Use sizetype for the step if a pointer.
	Use POINTER_PLUS_EXPR for pointers.
	(aff_combination_to_tree): Use sizetype for the step if a
	pointer.

Co-Authored-By: Richard Guenther <rguenther@suse.de>

From-SVN: r133102
parent 7f2ad78b
2008-03-11 Andrew Pinski <andrew_pinski@playstation.sony.com>
Richard Guenther <rguenther@suse.de>
PR tree-optimization/31358
* tree-ssa-loop-manip.c (create_iv): Call force_gimple_operand for
the step with a NULL_TREE.
* tree-ssa-loop-ivopts.c (find_bivs): Convert the step
to sizetype if type is a pointer type.
(add_candidate_1): Don't convert the base and step to
the generic type if the orginal type is a pointer type.
(add_iv_value_candidates): Use sizetype for the step
if type is a pointer type.
(cand_value_at): Likewise.
* tree-ssa-address.c (add_to_parts): Use POINTER_PLUS_EXPR
for pointer types.
* tree-affine.c (tree_to_aff_combination <POINTER_PLUS_EXPR>):
Don't convert the tem affine to the type.
(add_elt_to_tree): Use sizetype for the step if a pointer.
Use POINTER_PLUS_EXPR for pointers.
(aff_combination_to_tree): Use sizetype for the step if a
pointer.
2008-03-10 Vladimir Makarov <vmakarov@redhat.com> 2008-03-10 Vladimir Makarov <vmakarov@redhat.com>
* config/i386/sse.md (ssse3_pmaddubswv8hi3, ssse3_pmaddubswv4hi3): * config/i386/sse.md (ssse3_pmaddubswv8hi3, ssse3_pmaddubswv4hi3):
......
...@@ -279,7 +279,6 @@ tree_to_aff_combination (tree expr, tree type, aff_tree *comb) ...@@ -279,7 +279,6 @@ tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
case POINTER_PLUS_EXPR: case POINTER_PLUS_EXPR:
tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb); tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp); tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
aff_combination_convert (&tmp, type);
aff_combination_add (comb, &tmp); aff_combination_add (comb, &tmp);
return; return;
...@@ -350,29 +349,40 @@ add_elt_to_tree (tree expr, tree type, tree elt, double_int scale, ...@@ -350,29 +349,40 @@ add_elt_to_tree (tree expr, tree type, tree elt, double_int scale,
aff_tree *comb) aff_tree *comb)
{ {
enum tree_code code; enum tree_code code;
tree type1 = type;
if (POINTER_TYPE_P (type))
type1 = sizetype;
scale = double_int_ext_for_comb (scale, comb); scale = double_int_ext_for_comb (scale, comb);
elt = fold_convert (type, elt); elt = fold_convert (type1, elt);
if (double_int_one_p (scale)) if (double_int_one_p (scale))
{ {
if (!expr) if (!expr)
return elt; return fold_convert (type, elt);
if (POINTER_TYPE_P (type))
return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt);
return fold_build2 (PLUS_EXPR, type, expr, elt); return fold_build2 (PLUS_EXPR, type, expr, elt);
} }
if (double_int_minus_one_p (scale)) if (double_int_minus_one_p (scale))
{ {
if (!expr) if (!expr)
return fold_build1 (NEGATE_EXPR, type, elt); return fold_convert (type, fold_build1 (NEGATE_EXPR, type1, elt));
if (POINTER_TYPE_P (type))
{
elt = fold_build1 (NEGATE_EXPR, type1, elt);
return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt);
}
return fold_build2 (MINUS_EXPR, type, expr, elt); return fold_build2 (MINUS_EXPR, type, expr, elt);
} }
if (!expr) if (!expr)
return fold_build2 (MULT_EXPR, type, elt, return fold_convert (type,
double_int_to_tree (type, scale)); fold_build2 (MULT_EXPR, type1, elt,
double_int_to_tree (type1, scale)));
if (double_int_negative_p (scale)) if (double_int_negative_p (scale))
{ {
...@@ -382,8 +392,14 @@ add_elt_to_tree (tree expr, tree type, tree elt, double_int scale, ...@@ -382,8 +392,14 @@ add_elt_to_tree (tree expr, tree type, tree elt, double_int scale,
else else
code = PLUS_EXPR; code = PLUS_EXPR;
elt = fold_build2 (MULT_EXPR, type, elt, elt = fold_build2 (MULT_EXPR, type1, elt,
double_int_to_tree (type, scale)); double_int_to_tree (type1, scale));
if (POINTER_TYPE_P (type))
{
if (code == MINUS_EXPR)
elt = fold_build1 (NEGATE_EXPR, type1, elt);
return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt);
}
return fold_build2 (code, type, expr, elt); return fold_build2 (code, type, expr, elt);
} }
...@@ -396,6 +412,9 @@ aff_combination_to_tree (aff_tree *comb) ...@@ -396,6 +412,9 @@ aff_combination_to_tree (aff_tree *comb)
tree expr = comb->rest; tree expr = comb->rest;
unsigned i; unsigned i;
double_int off, sgn; double_int off, sgn;
tree type1 = type;
if (POINTER_TYPE_P (type))
type1 = sizetype;
gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE); gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE);
...@@ -415,7 +434,7 @@ aff_combination_to_tree (aff_tree *comb) ...@@ -415,7 +434,7 @@ aff_combination_to_tree (aff_tree *comb)
off = comb->offset; off = comb->offset;
sgn = double_int_one; sgn = double_int_one;
} }
return add_elt_to_tree (expr, type, double_int_to_tree (type, off), sgn, return add_elt_to_tree (expr, type, double_int_to_tree (type1, off), sgn,
comb); comb);
} }
......
...@@ -914,7 +914,12 @@ find_bivs (struct ivopts_data *data) ...@@ -914,7 +914,12 @@ find_bivs (struct ivopts_data *data)
type = TREE_TYPE (PHI_RESULT (phi)); type = TREE_TYPE (PHI_RESULT (phi));
base = fold_convert (type, base); base = fold_convert (type, base);
if (step) if (step)
{
if (POINTER_TYPE_P (type))
step = fold_convert (sizetype, step);
else
step = fold_convert (type, step); step = fold_convert (type, step);
}
set_iv (data, PHI_RESULT (phi), base, step); set_iv (data, PHI_RESULT (phi), base, step);
found = true; found = true;
...@@ -2040,7 +2045,9 @@ add_candidate_1 (struct ivopts_data *data, ...@@ -2040,7 +2045,9 @@ add_candidate_1 (struct ivopts_data *data,
{ {
orig_type = TREE_TYPE (base); orig_type = TREE_TYPE (base);
type = generic_type_for (orig_type); type = generic_type_for (orig_type);
if (type != orig_type) /* Don't convert the base to the generic type for pointers as the generic
type is an integer type with the same size as the pointer type. */
if (type != orig_type && !POINTER_TYPE_P (orig_type))
{ {
base = fold_convert (type, base); base = fold_convert (type, base);
step = fold_convert (type, step); step = fold_convert (type, step);
...@@ -2237,13 +2244,17 @@ add_iv_value_candidates (struct ivopts_data *data, ...@@ -2237,13 +2244,17 @@ add_iv_value_candidates (struct ivopts_data *data,
{ {
unsigned HOST_WIDE_INT offset; unsigned HOST_WIDE_INT offset;
tree base; tree base;
tree basetype;
add_candidate (data, iv->base, iv->step, false, use); add_candidate (data, iv->base, iv->step, false, use);
/* The same, but with initial value zero. Make such variable important, /* The same, but with initial value zero. Make such variable important,
since it is generic enough so that possibly many uses may be based since it is generic enough so that possibly many uses may be based
on it. */ on it. */
add_candidate (data, build_int_cst (TREE_TYPE (iv->base), 0), basetype = TREE_TYPE (iv->base);
if (POINTER_TYPE_P (basetype))
basetype = sizetype;
add_candidate (data, build_int_cst (basetype, 0),
iv->step, true, use); iv->step, true, use);
/* Third, try removing the constant offset. */ /* Third, try removing the constant offset. */
...@@ -3671,10 +3682,13 @@ cand_value_at (struct loop *loop, struct iv_cand *cand, tree at, tree niter, ...@@ -3671,10 +3682,13 @@ cand_value_at (struct loop *loop, struct iv_cand *cand, tree at, tree niter,
aff_tree step, delta, nit; aff_tree step, delta, nit;
struct iv *iv = cand->iv; struct iv *iv = cand->iv;
tree type = TREE_TYPE (iv->base); tree type = TREE_TYPE (iv->base);
tree steptype = type;
if (POINTER_TYPE_P (type))
steptype = sizetype;
tree_to_aff_combination (iv->step, type, &step); tree_to_aff_combination (iv->step, steptype, &step);
tree_to_aff_combination (niter, TREE_TYPE (niter), &nit); tree_to_aff_combination (niter, TREE_TYPE (niter), &nit);
aff_combination_convert (&nit, type); aff_combination_convert (&nit, steptype);
aff_combination_mult (&nit, &step, &delta); aff_combination_mult (&nit, &step, &delta);
if (stmt_after_increment (loop, cand, at)) if (stmt_after_increment (loop, cand, at))
aff_combination_add (&delta, &step); aff_combination_add (&delta, &step);
......
...@@ -104,7 +104,7 @@ create_iv (tree base, tree step, tree var, struct loop *loop, ...@@ -104,7 +104,7 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
} }
/* Gimplify the step if necessary. We put the computations in front of the /* Gimplify the step if necessary. We put the computations in front of the
loop (i.e. the step should be loop invariant). */ loop (i.e. the step should be loop invariant). */
step = force_gimple_operand (step, &stmts, true, var); step = force_gimple_operand (step, &stmts, true, NULL_TREE);
if (stmts) if (stmts)
bsi_insert_on_edge_immediate (pe, stmts); bsi_insert_on_edge_immediate (pe, stmts);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment