From 49e7a9d4b821c982a55f9783b7c15cb4bedc5548 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 19 Feb 2007 00:54:29 +0000 Subject: [PATCH] re PR rtl-optimization/28173 (misses constant folding) PR rtl-optimization/28173 * simplify-rtx.c (simplify_binary_operation_1) : 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. : Canonicalize (X | C1) & C2 as (X & C2) | (C1 & C2). * gcc.target/i386/andor-1.c: New test case. From-SVN: r122116 --- gcc/ChangeLog | 9 ++++++ gcc/simplify-rtx.c | 39 +++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/i386/andor-1.c | 10 +++++++ 4 files changed, 63 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/andor-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff24358403d..dada5813567 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2007-02-18 Roger Sayle + + PR rtl-optimization/28173 + * simplify-rtx.c (simplify_binary_operation_1) : 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. + : Canonicalize (X | C1) & C2 as (X & C2) | (C1 & C2). + 2007-02-18 Kaveh R. Ghazi * builtins.c (fold_builtin_load_exponent): New. diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index cb1c4f62a36..4251df520c8 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 06f560e7c77..bf4845f9c36 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-02-18 Roger Sayle + + PR rtl-optimization/28173 + * gcc.target/i386/andor-1.c: New test case. + 2007-02-18 Kaveh R. Ghazi * gcc.dg/torture/builtin-ldexp-1.c: New. diff --git a/gcc/testsuite/gcc.target/i386/andor-1.c b/gcc/testsuite/gcc.target/i386/andor-1.c new file mode 100644 index 00000000000..6cc12b34833 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/andor-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "andl" } } */ + +unsigned int foo(unsigned int x) +{ + unsigned int t = x & ~1; + return t | 1; +} +