From: Zdenek Dvorak Date: Thu, 22 Sep 2005 11:24:00 +0000 (+0200) Subject: re PR tree-optimization/22438 (ICE SEGV in is_gimple_variable at tree-gimple.c:239) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7b9d4f7084b377ac50df11387983c5b4e6004137;p=platform%2Fupstream%2Fgcc.git re PR tree-optimization/22438 (ICE SEGV in is_gimple_variable at tree-gimple.c:239) PR tree-optimization/22438 * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Handle all preserved iv rhs rewriting specially. From-SVN: r104522 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 471414d..5ba52fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-09-21 Zdenek Dvorak + + PR tree-optimization/22438 + * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Handle all + preserved iv rhs rewriting specially. + 2005-09-21 Daniel Berlin * tree-data-ref.c (analyze_array_indexes): Only estimate when diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 44ebc5c..8bfbf7f 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -5331,22 +5331,58 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data, introduce a new computation (that might also need casting the variable to unsigned and back). */ if (cand->pos == IP_ORIGINAL - && TREE_CODE (use->stmt) == MODIFY_EXPR - && TREE_OPERAND (use->stmt, 0) == cand->var_after) + && cand->incremented_at == use->stmt) { + tree step, ctype, utype; + enum tree_code incr_code = PLUS_EXPR; + + gcc_assert (TREE_CODE (use->stmt) == MODIFY_EXPR); + gcc_assert (TREE_OPERAND (use->stmt, 0) == 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. */ op = TREE_OPERAND (use->stmt, 1); + if (TREE_CODE (op) == PLUS_EXPR + || TREE_CODE (op) == MINUS_EXPR) + { + if (TREE_OPERAND (op, 0) == cand->var_before) + op = TREE_OPERAND (op, 1); + else if (TREE_CODE (op) == PLUS_EXPR + && TREE_OPERAND (op, 1) == cand->var_before) + op = TREE_OPERAND (op, 0); + else + op = NULL_TREE; + } + else + op = NULL_TREE; - /* Be a bit careful. In case variable is expressed in some - complicated way, rewrite it so that we may get rid of this - complicated expression. */ - if ((TREE_CODE (op) == PLUS_EXPR - || TREE_CODE (op) == MINUS_EXPR) - && TREE_OPERAND (op, 0) == cand->var_before - && TREE_CODE (TREE_OPERAND (op, 1)) == INTEGER_CST) + if (op + && (TREE_CODE (op) == INTEGER_CST + || operand_equal_p (op, step, 0))) 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); - comp = get_computation (data->current_loop, use, cand); switch (TREE_CODE (use->stmt)) { case PHI_NODE: