aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2007-02-19 00:54:29 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2007-02-19 00:54:29 +0000
commit49e7a9d4b821c982a55f9783b7c15cb4bedc5548 (patch)
tree0df33a267eac0cd5b69159ce8812e9f705957b24 /gcc/simplify-rtx.c
parent1b16dad6f4447d60879db3809d934836260cedf8 (diff)
downloadgcc-49e7a9d4b821c982a55f9783b7c15cb4bedc5548.zip
gcc-49e7a9d4b821c982a55f9783b7c15cb4bedc5548.tar.gz
gcc-49e7a9d4b821c982a55f9783b7c15cb4bedc5548.tar.bz2
re PR rtl-optimization/28173 (misses constant folding)
PR rtl-optimization/28173 * simplify-rtx.c (simplify_binary_operation_1) <IOR>: Optimize (X & C1) | C2 as C2 when (C1 & C2) == C1 and X has no side-effects. Optimize (X & C1) | C2 as X | C2 when (C1 | C2) == ~0. Canonicalize (X & C1) | C2 as (X & (C1 & ~C2)) | C2. <AND>: Canonicalize (X | C1) & C2 as (X & C2) | (C1 & C2). * gcc.target/i386/andor-1.c: New test case. From-SVN: r122116
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index cb1c4f6..4251df5 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2072,6 +2072,33 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
&& (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
return op1;
+ /* Canonicalize (X & C1) | C2. */
+ if (GET_CODE (op0) == AND
+ && GET_CODE (trueop1) == CONST_INT
+ && GET_CODE (XEXP (op0, 1)) == CONST_INT)
+ {
+ HOST_WIDE_INT mask = GET_MODE_MASK (mode);
+ HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
+ HOST_WIDE_INT c2 = INTVAL (trueop1);
+
+ /* If (C1&C2) == C1, then (X&C1)|C2 becomes X. */
+ if ((c1 & c2) == c1
+ && !side_effects_p (XEXP (op0, 0)))
+ return trueop1;
+
+ /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
+ if (((c1|c2) & mask) == mask)
+ return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
+
+ /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2. */
+ if (((c1 & ~c2) & mask) != (c1 & mask))
+ {
+ tem = simplify_gen_binary (AND, mode, XEXP (op0, 0),
+ gen_int_mode (c1 & ~c2, mode));
+ return simplify_gen_binary (IOR, mode, tem, op1);
+ }
+ }
+
/* Convert (A & B) | A to A. */
if (GET_CODE (op0) == AND
&& (rtx_equal_p (XEXP (op0, 0), op1)
@@ -2312,6 +2339,18 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
}
+ /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
+ if (GET_CODE (op0) == IOR
+ && GET_CODE (trueop1) == CONST_INT
+ && GET_CODE (XEXP (op0, 1)) == CONST_INT)
+ {
+ HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
+ return simplify_gen_binary (IOR, mode,
+ simplify_gen_binary (AND, mode,
+ XEXP (op0, 0), op1),
+ gen_int_mode (tmp, mode));
+ }
+
/* Convert (A ^ B) & A to A & (~B) since the latter is often a single
insn (and may simplify more). */
if (GET_CODE (op0) == XOR