aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-08-19 19:43:50 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-08-19 19:43:50 +0200
commita5d8253f7aba67d7a3e05c5e0e361c9057bc5d54 (patch)
treeefa8e5321c21db9e8b1edf44dcacc6bed954fab5 /gcc/simplify-rtx.c
parent0524d2d6623eb2ab287f464e05c206ceeb3839bf (diff)
downloadgcc-a5d8253f7aba67d7a3e05c5e0e361c9057bc5d54.zip
gcc-a5d8253f7aba67d7a3e05c5e0e361c9057bc5d54.tar.gz
gcc-a5d8253f7aba67d7a3e05c5e0e361c9057bc5d54.tar.bz2
re PR target/45336 (pextr{b,w,d}, (worse than) redundant extensions)
PR target/45336 * simplify-rtx.c (simplify_unary_operation_1): Optimize nested SIGN_EXTENDs or ZERO_EXTENDs. From-SVN: r163384
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index a7a91e5..e3acc41 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1010,6 +1010,31 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
&& 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 (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
+ is (sign_extend:M (subreg:O <X>)) if there is mode with
+ GET_MODE_BITSIZE (N) - I 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_code code, enum machine_mode mode, rtx op)
&& 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