OSDN Git Service

PR rtl-optimization/45617
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 13 Sep 2010 21:00:03 +0000 (21:00 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 13 Sep 2010 21:00:03 +0000 (21:00 +0000)
* combine.c (simplify_comparison): Optimize (X >> N) {>,>=,<,<=} C
even if low N bits of X aren't known to be zero.

* gcc.target/i386/pr45617.c: New test.

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

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr45617.c [new file with mode: 0644]

index 6bd3b74..5c0c731 100644 (file)
@@ -1,3 +1,9 @@
+2010-09-13  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/45617
+       * combine.c (simplify_comparison): Optimize (X >> N) {>,>=,<,<=} C
+       even if low N bits of X aren't known to be zero.
+
 2010-09-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/i386-protos.h (ix86_units_per_simd_word): New.
index bed5768..618e07d 100644 (file)
@@ -11773,13 +11773,14 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
          /* If we have (compare (xshiftrt FOO N) (const_int C)) and
             the low order N bits of FOO are known to be zero, we can do this
             by comparing FOO with C shifted left N bits so long as no
-            overflow occurs.  */
+            overflow occurs.  Even if the low order N bits of FOO aren't known
+            to be zero, if the comparison is >= or < we can use the same
+            optimization and for > or <= by setting all the low
+            order N bits in the comparison constant.  */
          if (CONST_INT_P (XEXP (op0, 1))
-             && INTVAL (XEXP (op0, 1)) >= 0
+             && INTVAL (XEXP (op0, 1)) > 0
              && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
              && mode_width <= HOST_BITS_PER_WIDE_INT
-             && (nonzero_bits (XEXP (op0, 0), mode)
-                 & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0
              && (((unsigned HOST_WIDE_INT) const_op
                   + (GET_CODE (op0) != LSHIFTRT
                      ? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1)
@@ -11787,15 +11788,27 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
                      : 0))
                  <= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1))))
            {
-             /* If the shift was logical, then we must make the condition
-                unsigned.  */
-             if (GET_CODE (op0) == LSHIFTRT)
-               code = unsigned_condition (code);
-
-             const_op <<= INTVAL (XEXP (op0, 1));
-             op1 = GEN_INT (const_op);
-             op0 = XEXP (op0, 0);
-             continue;
+             unsigned HOST_WIDE_INT low_bits
+               = (nonzero_bits (XEXP (op0, 0), mode)
+                  & (((unsigned HOST_WIDE_INT) 1
+                      << INTVAL (XEXP (op0, 1))) - 1));
+             if (low_bits == 0 || !equality_comparison_p)
+               {
+                 /* If the shift was logical, then we must make the condition
+                    unsigned.  */
+                 if (GET_CODE (op0) == LSHIFTRT)
+                   code = unsigned_condition (code);
+
+                 const_op <<= INTVAL (XEXP (op0, 1));
+                 if (low_bits != 0
+                     && (code == GT || code == GTU
+                         || code == LE || code == LEU))
+                   const_op
+                     |= (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1);
+                 op1 = GEN_INT (const_op);
+                 op0 = XEXP (op0, 0);
+                 continue;
+               }
            }
 
          /* If we are using this shift to extract just the sign bit, we
index d1b690a..c663a4b 100644 (file)
@@ -1,3 +1,8 @@
+2010-09-13  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/45617
+       * gcc.target/i386/pr45617.c: New test.
+
 2010-09-13  Dave Korn  <dave.korn.cygwin@gmail.com>
 
        * gcc.target/i386/volatile-2.c: Allow underscores before symbols.
diff --git a/gcc/testsuite/gcc.target/i386/pr45617.c b/gcc/testsuite/gcc.target/i386/pr45617.c
new file mode 100644 (file)
index 0000000..58f9772
--- /dev/null
@@ -0,0 +1,22 @@
+/* PR rtl-optimization/45617 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int f1 (int x)
+{
+  return (x >> 23) > 12;
+}
+int f2 (int x)
+{
+  return x > ((13 << 23) - 1);
+}
+int f3 (int x)
+{
+  return (x >> 23) >= 12;
+}
+int f4 (int x)
+{
+  return x >= (12 << 23);
+}
+
+/* { dg-final { scan-assembler-not "sarl" } } */