diff mbox

PATCH: PR rtl-optimization/50696: [x32] Unnecessary lea

Message ID CAMe9rOoTe5fgUZ3anJCx+NceejtsaCxWUUsjhCCqth8TZnub4A@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu Oct. 13, 2011, 10:49 p.m. UTC
On Thu, Oct 13, 2011 at 3:33 PM, Richard Kenner
<kenner@vlsi1.ultra.nyu.edu> wrote:
>> I am testing this patch.  The difference is it checks nonzero
>> bits of the first operand.
>
> I would suggest moving (and expanding) the comments from the existing block
> into your new block.
>

Like ths?

Comments

Richard Kenner Oct. 13, 2011, 10:52 p.m. UTC | #1
> Like ths?

Yes, that's what I meant.  Thanks.

Again, I'd suggest doing some performance testing on this just to verify
that it doesn't pessimize things.
H.J. Lu Oct. 13, 2011, 11:04 p.m. UTC | #2
On Thu, Oct 13, 2011 at 3:52 PM, Richard Kenner
<kenner@vlsi1.ultra.nyu.edu> wrote:
>> Like ths?
>
> Yes, that's what I meant.  Thanks.
>
> Again, I'd suggest doing some performance testing on this just to verify
> that it doesn't pessimize things.
>

I will run SPEC CPU 2K/2006 on ia32, x86-64 and x32.
diff mbox

Patch

diff --git a/gcc/combine.c b/gcc/combine.c
index 6c3b17c..4b57b88 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7739,16 +7739,6 @@  make_compound_operation (rtx x, enum rtx_code in_code)
 				     XEXP (XEXP (x, 0), 1)));
 	}

-      /* If the constant is one less than a power of two, this might be
-	 representable by an extraction even if no shift is present.
-	 If it doesn't end up being a ZERO_EXTEND, we will ignore it unless
-	 we are in a COMPARE.  */
-      else if ((i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
-	new_rtx = make_extraction (mode,
-			       make_compound_operation (XEXP (x, 0),
-							next_code),
-			       0, NULL_RTX, i, 1, 0, in_code == COMPARE);
-
       /* If we are in a comparison and this is an AND with a power of two,
 	 convert this into the appropriate bit extract.  */
       else if (in_code == COMPARE
@@ -7758,6 +7748,26 @@  make_compound_operation (rtx x, enum rtx_code in_code)
 							next_code),
 			       i, NULL_RTX, 1, 1, 0, 1);

+      /* If the constant is an extraction mask with the zero bits in
+	 the first operand ignored, this might be representable by an
+	 extraction even if no shift is present.  If it doesn't end up
+	 being a ZERO_EXTEND, we will ignore it unless we are in a
+	 COMPARE.  */
+      else
+	{
+	  unsigned HOST_WIDE_INT nonzero =
+	    nonzero_bits (XEXP (x, 0), GET_MODE (XEXP (x, 0)));
+	  unsigned HOST_WIDE_INT mask = UINTVAL (XEXP (x, 1));
+	  unsigned HOST_WIDE_INT len = ceil_log2 (mask);
+	  if ((nonzero & (((unsigned HOST_WIDE_INT) 1 << len) - 1))
+	      == (nonzero & mask))
+	    {
+	      new_rtx = make_compound_operation (XEXP (x, 0), next_code);
+	      new_rtx = make_extraction (mode, new_rtx, 0, NULL_RTX,
+					 len, 1, 0, in_code == COMPARE);
+	    }
+	}
+
       break;

     case LSHIFTRT: