On 27/10/2020 17:31, Segher Boessenkool wrote: > On Tue, Oct 27, 2020 at 10:35:59AM +0000, Alex Coplan wrote: > > On 26/10/2020 12:43, Segher Boessenkool wrote: > > > I do not like handling both mult and ashift in one case like this, it > > > complicates things for no good reason. Write it as two cases, and it > > > should be good. > > > > OK, the attached patch rewrites (mult x 2^n) to (ashift x n) at the top > > of make_extraction so that the existing ASHIFT block can do the work for > > us. We remember if we did it and then convert it back if necessary. > > > > I'm not convinced that it's an improvement. What do you think? > > Restoring it like that is just yuck. That can be okay if it is as the > start and end of a smallish function, importantly some self-contained > piece of code, but this is not. > > Just write it as two blocks? One handling the shift, that is already > there; and add one block adding the mult case. That should not > increase the complexity of this already way too complex code.
OK, how about the attached? Bootstrap and regtest in progress on aarch64-none-linux-gnu. Thanks, Alex --- gcc/ChangeLog: * combine.c (make_extraction): Also handle shfits written as (mult x 2^n), avoid creating an extract rtx for these.
diff --git a/gcc/combine.c b/gcc/combine.c index 4782e1d9dcc..5040dabff98 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7665,6 +7665,24 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, if (new_rtx != 0) return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1)); } + else if (GET_CODE (inner) == MULT + && CONST_INT_P (XEXP (inner, 1)) + && pos_rtx == 0 && pos == 0) + { + /* We're extracting the least significant bits of an rtx + (mult X (const_int 2^C)), where LEN > C. Extract the + least significant (LEN - C) bits of X, giving an rtx + whose mode is MODE, then multiply it by 2^C. */ + const HOST_WIDE_INT shift_amt = exact_log2 (INTVAL (XEXP (inner, 1))); + if (shift_amt > 0 && len > shift_amt) + { + new_rtx = make_extraction (mode, XEXP (inner, 0), + 0, 0, len - shift_amt, + unsignedp, in_dest, in_compare); + if (new_rtx) + return gen_rtx_MULT (mode, new_rtx, XEXP (inner, 1)); + } + } else if (GET_CODE (inner) == TRUNCATE /* If trying or potentionally trying to extract bits outside of is_mode, don't look through