summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-20 08:05:12 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-20 08:05:12 +0000
commitb718fe638db7f365e5c5ff86eb12b0246aee9554 (patch)
tree049852a66bb3c2b176b99851ac916058e794f7d0 /gcc
parentfdcb802df2ec636e96d2200ea957fef6045ebce6 (diff)
downloadgcc-b718fe638db7f365e5c5ff86eb12b0246aee9554.tar.gz
PR rtl-optimization/32283
* tree-ssa-loop-niter.c (scev_probably_wraps_p): Use type of the base of the induction variable to decide whether it may wrap. * tree-ssa-loop-ivopts.c (rewrite_use_compare): Emit the initialization of the bound before the loop. * simplify-rtx.c (simplify_binary_operation_1): Add two simplifications regarding AND. (simplify_plus_minus): Only fail if no simplification is possible. * loop-iv.c (simple_rhs_p): Consider reg + reg and reg << cst simple. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142035 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/loop-iv.c25
-rw-r--r--gcc/simplify-rtx.c34
-rw-r--r--gcc/tree-ssa-loop-ivopts.c8
-rw-r--r--gcc/tree-ssa-loop-niter.c2
5 files changed, 62 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 48757a5f155..8731154e131 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2008-11-19 Zdenek Dvorak <ook@ucw.cz>
+
+ PR rtl-optimization/32283
+ * tree-ssa-loop-niter.c (scev_probably_wraps_p): Use type of the base
+ of the induction variable to decide whether it may wrap.
+ * tree-ssa-loop-ivopts.c (rewrite_use_compare): Emit the initialization
+ of the bound before the loop.
+ * simplify-rtx.c (simplify_binary_operation_1): Add two simplifications
+ regarding AND.
+ (simplify_plus_minus): Only fail if no simplification is possible.
+ * loop-iv.c (simple_rhs_p): Consider reg + reg and reg << cst simple.
+
2008-11-20 Jakub Jelinek <jakub@redhat.com>
PR c++/36631
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 2523963f36d..3723dbd463a 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -1337,13 +1337,26 @@ simple_rhs_p (rtx rhs)
case MINUS:
op0 = XEXP (rhs, 0);
op1 = XEXP (rhs, 1);
- /* Allow reg + const sets only. */
- if (REG_P (op0) && !HARD_REGISTER_P (op0) && CONSTANT_P (op1))
- return true;
- if (REG_P (op1) && !HARD_REGISTER_P (op1) && CONSTANT_P (op0))
- return true;
+ /* Allow reg + const and reg + reg. */
+ if (!(REG_P (op0) && !HARD_REGISTER_P (op0))
+ && !CONSTANT_P (op0))
+ return false;
+ if (!(REG_P (op1) && !HARD_REGISTER_P (op1))
+ && !CONSTANT_P (op1))
+ return false;
- return false;
+ return true;
+
+ case ASHIFT:
+ op0 = XEXP (rhs, 0);
+ op1 = XEXP (rhs, 1);
+ /* Allow reg << const. */
+ if (!(REG_P (op0) && !HARD_REGISTER_P (op0)))
+ return false;
+ if (!CONSTANT_P (op1))
+ return false;
+
+ return true;
default:
return false;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index dd91e120d23..16d0d48688d 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2304,12 +2304,19 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
case AND:
if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
return trueop1;
- /* If we are turning off bits already known off in OP0, we need
- not do an AND. */
if (GET_CODE (trueop1) == CONST_INT
- && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
- && (nonzero_bits (trueop0, mode) & ~INTVAL (trueop1)) == 0)
- return op0;
+ && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
+ {
+ HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
+ HOST_WIDE_INT val1 = INTVAL (trueop1);
+ /* If we are turning off bits already known off in OP0, we need
+ not do an AND. */
+ if ((nzop0 & ~val1) == 0)
+ return op0;
+ /* If we are clearing all the nonzero bits, the result is zero. */
+ if ((val1 & nzop0) == 0 && !side_effects_p (op0))
+ return CONST0_RTX (mode);
+ }
if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
&& GET_MODE_CLASS (mode) != MODE_CC)
return op0;
@@ -2391,7 +2398,9 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
((A & N) + B) & M -> (A + B) & M
Similarly if (N & M) == 0,
((A | N) + B) & M -> (A + B) & M
- and for - instead of + and/or ^ instead of |. */
+ and for - instead of + and/or ^ instead of |.
+ Also, if (N & M) == 0, then
+ (A +- N) & M -> A & M. */
if (GET_CODE (trueop1) == CONST_INT
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ~INTVAL (trueop1)
@@ -2404,6 +2413,10 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
pmop[0] = XEXP (op0, 0);
pmop[1] = XEXP (op0, 1);
+ if (GET_CODE (pmop[1]) == CONST_INT
+ && (INTVAL (pmop[1]) & INTVAL (trueop1)) == 0)
+ return simplify_gen_binary (AND, mode, pmop[0], op1);
+
for (which = 0; which < 2; which++)
{
tem = pmop[which];
@@ -3591,10 +3604,6 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
ops[j + 1] = save;
}
- /* This is only useful the first time through. */
- if (!canonicalized)
- return NULL_RTX;
-
changed = 0;
for (i = n_ops - 1; i > 0; i--)
for (j = i - 1; j >= 0; j--)
@@ -3650,10 +3659,15 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
ops[i].neg = lneg;
ops[j].op = NULL_RTX;
changed = 1;
+ canonicalized = 1;
}
}
}
+ /* If nothing changed, fail. */
+ if (!canonicalized)
+ return NULL_RTX;
+
/* Pack all the operands to the lower-numbered entries. */
for (i = 0, j = 0; j < n_ops; j++)
if (ops[j].op)
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 92d9c751aab..aa0472ea364 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -5323,11 +5323,15 @@ rewrite_use_compare (struct ivopts_data *data,
{
tree var = var_at_stmt (data->current_loop, cand, use->stmt);
tree var_type = TREE_TYPE (var);
+ gimple_seq stmts;
compare = iv_elimination_compare (data, use);
bound = unshare_expr (fold_convert (var_type, bound));
- op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE,
- true, GSI_SAME_STMT);
+ op = force_gimple_operand (bound, &stmts, true, NULL_TREE);
+ if (stmts)
+ gsi_insert_seq_on_edge_immediate (
+ loop_preheader_edge (data->current_loop),
+ stmts);
gimple_cond_set_lhs (use->stmt, var);
gimple_cond_set_code (use->stmt, compare);
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 33aacae83b5..13b10c9f1c4 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -3053,7 +3053,7 @@ scev_probably_wraps_p (tree base, tree step,
/* If we can use the fact that signed and pointer arithmetics does not
wrap, we are done. */
- if (use_overflow_semantics && nowrap_type_p (type))
+ if (use_overflow_semantics && nowrap_type_p (TREE_TYPE (base)))
return false;
/* To be able to use estimates on number of iterations of the loop,