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