Message ID | 20100819163330.GX702@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On 08/19/2010 06:33 PM, Jakub Jelinek wrote: > + /* (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. */ Why not do the same with zero_extend and lshiftrt? Otherwise ok. Bernd
> 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. OK modulo: > + /* (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. */ ashiftrt instead of ashirtrt. Please keep using N as a mode like in the 2 other comments, use I or Y for the CONST_INT, thanks.
On Thu, Aug 19, 2010 at 07:23:24PM +0200, Bernd Schmidt wrote: > On 08/19/2010 06:33 PM, Jakub Jelinek wrote: > > + /* (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. */ > > Why not do the same with zero_extend and lshiftrt? Otherwise ok. ZERO_EXTEND is expanded into AND instead of LSHIFTRT/ASHIFT by combine, and two nested ANDs should be easily optimized. If you really want, I can handle the ZERO_EXTEND (AND <X> mask) case as a follow-up. Jakub
On 08/19/2010 07:32 PM, Jakub Jelinek wrote: > On Thu, Aug 19, 2010 at 07:23:24PM +0200, Bernd Schmidt wrote: >> On 08/19/2010 06:33 PM, Jakub Jelinek wrote: >>> + /* (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. */ >> >> Why not do the same with zero_extend and lshiftrt? Otherwise ok. > > ZERO_EXTEND is expanded into AND instead of LSHIFTRT/ASHIFT by combine, and > two nested ANDs should be easily optimized. If you really want, I can > handle the ZERO_EXTEND (AND <X> mask) case as a follow-up. Oh, in expand_compound_operation? I was thinking about finding such shifts in a pair of insns (happens on Thumb). Also, what about callers other than combine? Bernd
On 08/19/2010 06:33 PM, Jakub Jelinek wrote: > + /* (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))); Maybe /* (sign_extend:M (sign_extend:N<X>)) is (sign_extend:M<X>). (sign_extend:M (zero_extend:N<X>)) is (zero_extend:M<X>). */ if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND) { gcc_assert (GET_MODE (op) != mode); return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0), GET_MODE (XEXP (op, 0))); } ? Paolo
--- 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