On Sat, Nov 26, 2016 at 11:22:44PM +0100, Paolo Bonzini wrote: > The combine.c hunk instead is needed to simplify cases that do not use the > ternary operator (the "h" and "i" functions in the testcases) like this: > > return ((x >> 9) & 1) << 7; > > Normally this is simplified just fine to a single shift and an AND. > Here, however, the bit to preserve after (x >> 9 << 7) is the QImode > sign bit, and if_then_else_cond produces a complicated concoction > involving (ne:SI (subreg:QI ...)). simplify_if_then_else cannot then > reduce it back to the original. In fact, simplify_if_then_else does > have a similar pattern, but it cannot deal with the subreg. This is > easily done by ZERO_EXTENDing the result from QImode back to the > comparison's mode. The shift/shift/and or shift/and/shift combination > can then be reduced to shift+and just like for any other bit position.
The combine part is fine, thanks for the patch. Segher > 2016-11-26 Paolo Bonzini <bonz...@gnu.org> > > * combine.c (simplify_if_then_else): Simplify IF_THEN_ELSE > that isolates a single bit, even if the condition involves > subregs. > * match.pd: Simplify X ? C : 0 where C is a power of 2 and > X tests a single bit. > > 2016-11-26 Paolo Bonzini <bonz...@gnu.org> > > * gcc.dg/fold-and-lshift.c, gcc.dg/fold-and-rshift-1.c, > gcc.dg/fold-and-rshift-2.c: New testcases.