> My understanding is that in_code == COMPARE (as opposed to > in_code == SET) is mostly harmless, just tells make_extraction > to no longer special case zero extraction at position 0, but there is one > exception - AND with constant power of two CONST_INT. > If we have > make_compound_operation ( (subreg:SI (and:DI (reg:DI) (const_int > 0x800000000)) 0), COMPARE) then > make_compound_operation ( (and:DI (reg:DI) (const_int 0x800000000)), > COMPARE) returns extraction of the 35th bit, and subreg of that is again > either zero or one, but the original subreg is always 0. > > Fixed by passing through SET instead of in_code to the recursive > invocation, if > 1) the subreg isn't lowpart > 2) nested SUBREGs (should be usually simplified, but just in case it hasn't > been yet) 3) if subreg's operand is AND with power of two CONST_INT above > the bitsize of the outer mode
I don't see the need for the 2): wouldn't potentially problematic cases be handled by the recursive call to make_compound_operation? lowpart SUBREGs cannot mask out bit #0, can they? Otherwise this is OK modulo... > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8? > > 2013-05-02 Jakub Jelinek <ja...@redhat.com> > > PR rtl-optimization/57130 > * combine.c (make_compound_operation): For SUBREG, pass > SET instead of COMPARE as in_code to the recursive call > if needed. * combine.c (make_compound_operation) <SUBREG>: Pass... -- Eric Botcazou