diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2005-09-22 13:24:00 +0200 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2005-09-22 11:24:00 +0000 |
commit | 7b9d4f7084b377ac50df11387983c5b4e6004137 (patch) | |
tree | 76c2e159c8e6f8d8fe4ea0fdacc3a048f57fe959 /gcc | |
parent | ccdeca37fe155145a1857d13557b8dfb9eca2dd5 (diff) | |
download | gcc-7b9d4f7084b377ac50df11387983c5b4e6004137.tar.gz |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 56 |
2 files changed, 52 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 471414d45c9..5ba52fe415f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-09-21 Zdenek Dvorak <dvorakz@suse.cz> + + 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 <dberlin@dberlin.org> * 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 44ebc5ca28e..8bfbf7f8424 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: |