On Mon, Jun 15, 2015 at 12:14 PM, Mikhail Maltsev <malts...@gmail.com> wrote:
> Hi.
>
> The attached patch adds new match-and-simplify patterns, which fold
> ~((~a) >> b) into (a >> b) for arithmetic shifts (i.e. when A is signed)
> and perform similar folds for rotations. It also fixes PR
> tree-optimization/54579 (because we already fold (-a - 1) into ~a).
>
> A couple of questions:
> 1. Should we limit folding to this special case or rather introduce some
> canonical order of bitnot and shifts (when they are commutative)? In the
> latter case, which order is better: bitnot as shift/rotate operand or
> vise-versa?

That's a good question.  Both positions can enable simplifications, either
of a containing or a contained expression.  So ideally when you have
operators that distribute you'd have to always check both forms...

> 2. I noticed that some rotation patterns are folded on tree, while other
> are folded rather late (during second forward propagation). For example
> on LP64:
>
> #define INT_BITS  (sizeof (int) * 8)
>
> unsigned int
> rol(unsigned int a, unsigned int b)
> {
>   return a << b | a >> (INT_BITS - b);
> }
>
> INT_BITS has type unsigned long, so b and (INT_BITS - b) have different
> types and tree folding fails (if I change int to long, everything is
> OK). Should this be addressed somehow?

probably.

> 3. Do the new patterns require any special handling of nop-conversions?

In theory you can handle ~(unsigned)((singed)(~x) >> n), so yes.  Same
for rotates.  Canonicalization of ~ vs. a sign-changing conversion may
"fix" this as well, with the same caveats as any such canonicalizations
(see above).

Thanks,
Richard.

>
> --
> Regards,
>     Mikhail Maltsev

Reply via email to