This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Optimize nested SIGN_EXTENDs/ZERO_EXTENDs (PR target/45336)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 19 Aug 2010 18:33:30 +0200
- Subject: [PATCH] Optimize nested SIGN_EXTENDs/ZERO_EXTENDs (PR target/45336)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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