summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2005-09-22 13:24:00 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2005-09-22 11:24:00 +0000
commit7b9d4f7084b377ac50df11387983c5b4e6004137 (patch)
tree76c2e159c8e6f8d8fe4ea0fdacc3a048f57fe959 /gcc
parentccdeca37fe155145a1857d13557b8dfb9eca2dd5 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/tree-ssa-loop-ivopts.c56
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: