diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 334a3ca384b..d9630ed7414 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-12-12 Zdenek Dvorak + + PR tree-optimization/55481 + * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Fall + back to general rewriting if we cannot leave an original biv + definition alone. + 2012-12-12 Jakub Jelinek PR target/55659 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f9a68a5be6b..35e21d682d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-12-12 Zdenek Dvorak + + PR tree-optimization/55481 + * gcc.dg/torture/pr55481.c: New testcase. + 2012-12-12 Steven Bosscher Jakub Jelinek diff --git a/gcc/testsuite/gcc.dg/torture/pr55481.c b/gcc/testsuite/gcc.dg/torture/pr55481.c new file mode 100644 index 00000000000..26ba9ff7d99 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr55481.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ + +int main() +{ + signed char result = 0; + int n; + for (n = 0; n < 13; ++n) + { + int tem = result; + tem = tem + 31; + result = tem; + } + if (result != -109) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 1e41fa94a73..c33fc7c6b8f 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -6088,35 +6088,24 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data, if (cand->pos == IP_ORIGINAL && cand->incremented_at == use->stmt) { - tree step, ctype, utype; - enum tree_code incr_code = PLUS_EXPR, old_code; + enum tree_code stmt_code; gcc_assert (is_gimple_assign (use->stmt)); gcc_assert (gimple_assign_lhs (use->stmt) == cand->var_after); - step = cand->iv->step; - ctype = TREE_TYPE (step); - utype = TREE_TYPE (cand->var_after); - if (TREE_CODE (step) == NEGATE_EXPR) - { - incr_code = MINUS_EXPR; - step = TREE_OPERAND (step, 0); - } - /* Check whether we may leave the computation unchanged. This is the case only if it does not rely on other computations in the loop -- otherwise, the computation we rely upon may be removed in remove_unused_ivs, thus leading to ICE. */ - old_code = gimple_assign_rhs_code (use->stmt); - if (old_code == PLUS_EXPR - || old_code == MINUS_EXPR - || old_code == POINTER_PLUS_EXPR) + stmt_code = gimple_assign_rhs_code (use->stmt); + if (stmt_code == PLUS_EXPR + || stmt_code == MINUS_EXPR + || stmt_code == POINTER_PLUS_EXPR) { if (gimple_assign_rhs1 (use->stmt) == cand->var_before) op = gimple_assign_rhs2 (use->stmt); - else if (old_code != MINUS_EXPR - && gimple_assign_rhs2 (use->stmt) == cand->var_before) + else if (gimple_assign_rhs2 (use->stmt) == cand->var_before) op = gimple_assign_rhs1 (use->stmt); else op = NULL_TREE; @@ -6124,23 +6113,12 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data, else op = NULL_TREE; - if (op - && (TREE_CODE (op) == INTEGER_CST - || operand_equal_p (op, step, 0))) + if (op && expr_invariant_in_loop_p (data->current_loop, op)) return; + } - /* Otherwise, add the necessary computations to express - the iv. */ - op = fold_convert (ctype, cand->var_before); - comp = fold_convert (utype, - build2 (incr_code, ctype, op, - unshare_expr (step))); - } - else - { - comp = get_computation (data->current_loop, use, cand); - gcc_assert (comp != NULL_TREE); - } + comp = get_computation (data->current_loop, use, cand); + gcc_assert (comp != NULL_TREE); switch (gimple_code (use->stmt)) {