summaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
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/simplify-rtx.c
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/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c34
1 files changed, 24 insertions, 10 deletions
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)