PR rtl-optimization/28173
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Feb 2007 00:54:29 +0000 (00:54 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Feb 2007 00:54:29 +0000 (00:54 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122116 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/andor-1.c [new file with mode: 0644]

index ff24358..dada581 100644 (file)
@@ -1,3 +1,12 @@
+2007-02-18  Roger Sayle  <roger@eyesopen.com>
+
+       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).
+
 2007-02-18  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * builtins.c (fold_builtin_load_exponent): New.
index cb1c4f6..4251df5 100644 (file)
@@ -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
index 06f560e..bf4845f 100644 (file)
@@ -1,3 +1,8 @@
+2007-02-18  Roger Sayle  <roger@eyesopen.com>
+
+       PR rtl-optimization/28173
+       * gcc.target/i386/andor-1.c: New test case.
+
 2007-02-18  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * 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 (file)
index 0000000..6cc12b3
--- /dev/null
@@ -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;
+}
+