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] Optimize nested SIGN_EXTENDs/ZERO_EXTENDs (PR target/45336)


Hi!

This patch optimizes
 	pextrw	$3, %xmm0, %eax
-	cwtl
-	cltq
+	movswq	%ax, %rax
 	ret
and
 	pextrb	$4, %xmm0, %eax
-	movsbl	%al, %eax
-	cltq
+	movsbq	%al, %rax
 	ret
in the testcase from the PR.  While H.J. said he is working on something
for the intrinsics, the patch below attempts to simplify the generic case
of nested SIGN or ZERO_EXTENDs.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2010-08-19  Jakub Jelinek  <jakub@redhat.com>

	PR target/45336
	* simplify-rtx.c (simplify_unary_operation_1): Optimize nested
	SIGN_EXTENDs or ZERO_EXTENDs.

--- gcc/simplify-rtx.c.jj	2010-08-11 21:08:06.000000000 +0200
+++ gcc/simplify-rtx.c	2010-08-19 14:49:20.000000000 +0200
@@ -1010,6 +1010,31 @@ simplify_unary_operation_1 (enum rtx_cod
 	  && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
 	return rtl_hooks.gen_lowpart_no_emit (mode, op);
 
+      /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).  */
+      if (GET_CODE (op) == SIGN_EXTEND)
+	return simplify_gen_unary (SIGN_EXTEND, mode, XEXP (op, 0),
+				   GET_MODE (XEXP (op, 0)));
+
+      /* (sign_extend:M (ashirtrt:O (ashift <X> (const_int N)) (const_int N)))
+	 is (sign_extend:M (subreg:P <X>)) if there is mode with
+	 GET_MODE_BITSIZE (O) - N bits.  */
+      if (GET_CODE (op) == ASHIFTRT
+	  && GET_CODE (XEXP (op, 0)) == ASHIFT
+	  && CONST_INT_P (XEXP (op, 1))
+	  && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
+	  && GET_MODE_BITSIZE (GET_MODE (op)) > INTVAL (XEXP (op, 1)))
+	{
+	  enum machine_mode tmode
+	    = mode_for_size (GET_MODE_BITSIZE (GET_MODE (op))
+			     - INTVAL (XEXP (op, 1)), MODE_INT, 1);
+	  if (tmode != BLKmode)
+	    {
+	      rtx inner =
+		rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
+	      return simplify_gen_unary (SIGN_EXTEND, mode, inner, tmode);
+	    }
+	}
+
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
       /* As we do not know which address space the pointer is refering to,
 	 we can do this only if the target does not support different pointer
@@ -1036,6 +1061,11 @@ simplify_unary_operation_1 (enum rtx_cod
 	  && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
 	return rtl_hooks.gen_lowpart_no_emit (mode, op);
 
+      /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
+      if (GET_CODE (op) == ZERO_EXTEND)
+	return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
+				   GET_MODE (XEXP (op, 0)));
+
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
       /* As we do not know which address space the pointer is refering to,
 	 we can do this only if the target does not support different pointer

	Jakub


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