]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/45336 (pextr{b,w,d}, (worse than) redundant extensions)
authorJakub Jelinek <jakub@redhat.com>
Thu, 19 Aug 2010 17:43:50 +0000 (19:43 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 19 Aug 2010 17:43:50 +0000 (19:43 +0200)
PR target/45336
* simplify-rtx.c (simplify_unary_operation_1): Optimize nested
SIGN_EXTENDs or ZERO_EXTENDs.

From-SVN: r163384

gcc/ChangeLog
gcc/simplify-rtx.c

index 3065cc260f51862d528bee1ee5b9b2bb86344b63..518aba1e49aa2937e3fbef447f4e8b4d0105f45c 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2010-08-19  Bernd Schmidt  <bernds@codesourcery.com>
 
        PR target/42172
index a7a91e5d50f8719701848ce6813ae3dd0da6b4fe..e3acc41a9e3cc9b8533157a59a074d3a942a1e67 100644 (file)
@@ -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