[backport gcc-4.8/r194444, fixes PR55481 regression from PR53676 patch ] Date: Wed, 12 Dec 2012 14:03:36 +0100 (CET) From: Richard Biener Subject: [PATCH] Fix PR55481 List-Archive: This patch from Zdenek removes special code handling the forced rewrite of the original BIV definition. The code was broken, so simply fallback to the general rewriting code which works fine. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk (the issue is latent on the branches). Thanks Zdenek for the fix, Richard. gcc/ 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. gcc/testsuite/ 2012-12-12 Zdenek Dvorak PR tree-optimization/55481 * gcc.dg/torture/pr55481.c: New testcase. --- gcc-4.7.2/gcc/testsuite/gcc.dg/torture/pr55481.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.2/gcc/testsuite/gcc.dg/torture/pr55481.c 2012-12-23 12:33:41.000000000 +0100 @@ -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; +} --- gcc-4.7.2/gcc/tree-ssa-loop-ivopts.c.~1~ 2012-02-06 14:43:03.000000000 +0100 +++ gcc-4.7.2/gcc/tree-ssa-loop-ivopts.c 2012-12-23 12:33:41.000000000 +0100 @@ -6170,35 +6170,24 @@ rewrite_use_nonlinear_expr (struct ivopt 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; @@ -6206,24 +6195,13 @@ rewrite_use_nonlinear_expr (struct ivopt 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)) { case GIMPLE_PHI: