This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] combine.c: Optimize a certain field assignment.


Hi,

Attached is a patch to fix comment typos.  Committed as obvious.

Consider:

int
foo (int a, int b)
{
  a = (a & ~0xff00) | (b & 0xff00);
  return a;
}

Without this patch, gcc for i686-pc-linux-gnu with -O2
-fomit-frame-pointer -mregparm=3 generates

foo:
	andl	$65280, %edx
	movb	%dh, %ah
	ret

With this patch, I get

foo:
	movb	%dh, %ah
	ret

Note that "andl" is gone.

The reason is that combine suggests

  (set (zero_extract X CST ...)
       (zero_extract Y CST ...))

but this form is no longer canonical because of my earlier patch

  http://gcc.gnu.org/ml/gcc-patches/2003-03/msg01901.html

The patch fixes this problem by converting zero_extract in SET_SRC
into lshiftrt if the widths of the two extractions match.

Tested on i686-pc-linux-gnu.  OK to apply?

Kazu Hirata

2004-03-27  Kazu Hirata  <kazu@cs.umass.edu>

	* combine.c (simplify_set): Convert zero_extract in SET_SRC
	into lshiftrt if the widths of the two extractions match.

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.422
diff -u -r1.422 combine.c
--- combine.c	16 Mar 2004 16:14:50 -0000	1.422
+++ combine.c	26 Mar 2004 19:46:31 -0000
@@ -5276,6 +5276,33 @@
       src = SET_SRC (x);
     }
 
+  /* If X is already a field assignment of the form
+
+     (set (zero_extract X CST ...)
+          (zero_extract Y CST ...))
+
+     convert to
+
+     (set (zero_extract X CST ...)
+          (lshiftrt Y ...))
+  */
+  if (GET_CODE (dest) == ZERO_EXTRACT
+      && GET_CODE (src) == ZERO_EXTRACT
+      && GET_CODE (XEXP (dest, 1)) == CONST_INT
+      && XEXP (dest, 1) == XEXP (src, 1))
+    {
+      rtx tem = expand_compound_operation (src);
+
+      /* See if the outermost code is AND that masks off those bits
+	 beyond what we need.  */
+      if (GET_CODE (tem) == AND
+	  && GET_CODE (XEXP (tem, 1)) == CONST_INT
+	  && GET_MODE_BITSIZE (GET_MODE (tem)) <= HOST_BITS_PER_WIDE_INT
+	  && (((HOST_WIDE_INT) 1 << INTVAL (XEXP (dest, 1))) - 1
+	      == INTVAL (XEXP (tem, 1))))
+	return gen_rtx_SET (VOIDmode, dest, XEXP (tem, 0));
+    }
+
   /* If either SRC or DEST is a CLOBBER of (const_int 0), make this
      whole thing fail.  */
   if (GET_CODE (src) == CLOBBER && XEXP (src, 0) == const0_rtx)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]