From c0b52952216a0842127004659615eb48e5f8e730 Mon Sep 17 00:00:00 2001 From: rakdver Date: Thu, 22 Sep 2005 11:24:00 +0000 Subject: PR tree-optimization/22438 * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Handle all preserved iv rhs rewriting specially. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104522 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-ssa-loop-ivopts.c | 56 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 10 deletions(-) (limited to 'gcc/tree-ssa-loop-ivopts.c') 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: -- cgit v1.2.1