On Tue, Nov 10, 2015 at 12:16:09PM +0100, Bernd Schmidt wrote: > On 11/09/2015 08:33 AM, Segher Boessenkool wrote: > >If we have > > > > (truncate:M1 (and:M2 (lshiftrt:M2 (x:M2) C) C2)) > > > >we can write it instead as > > > > (and:M1 (lshiftrt:M1 (truncate:M1 (x:M2)) C) C2) > > > > > >+ /* Likewise (truncate:QI (and:SI (lshiftrt:SI (x:SI) C) C2)) into > >+ (and:QI (lshiftrt:QI (truncate:QI (x:SI)) C) C2) for suitable C > >+ and C2. */ > >+ if (GET_CODE (op) == AND > >+ && (GET_CODE (XEXP (op, 0)) == LSHIFTRT > >+ || GET_CODE (XEXP (op, 0)) == ASHIFTRT) > >+ && CONST_INT_P (XEXP (XEXP (op, 0), 1)) > >+ && CONST_INT_P (XEXP (op, 1)) > >+ && UINTVAL (XEXP (XEXP (op, 0), 1)) < precision > >+ && ((GET_MODE_MASK (mode) >> UINTVAL (XEXP (XEXP (op, 0), 1))) > >+ & UINTVAL (XEXP (op, 1))) > >+ == ((GET_MODE_MASK (op_mode) >> UINTVAL (XEXP (XEXP (op, 0), 1))) > >+ & UINTVAL (XEXP (op, 1)))) > > In general this would be easier to read if there were intermediate > variables called shift_amount and mask.
Yes I know. All the rest of the code around is it like this though. Do you want this written in a saner way? > I'm not entirely sure what the > last condition here is supposed to test. It tests whether moving the truncate inside will give the same result. It essentially looks if it works for an x with all bits set; if that works, it works for any x. > Is it related to... > > >+ return simplify_gen_binary (AND, mode, op0, XEXP (op, 1)); > > ... the fact that here I think you'd have to trunc_int_for_mode the AND > amount for the smaller mode? Ugh yes, I still have to do that for it to be valid RTL in all cases. Thanks for catching it. Segher