[PATCH] Fix up make_compound_operation (PR rtl-optimization/57130)

Jakub Jelinek jakub@redhat.com
Fri May 3 09:22:00 GMT 2013


On Fri, May 03, 2013 at 10:13:17AM +0200, Eric Botcazou wrote:
> > 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...

Consider for whatever reason still unsimplified:
(ne (subreg:QI (subreg:SI (and:DI (reg:DI) (const_int 0x08000000)) 0) 0) (const_int 0))
We'll call
make_compound_operation ( subreg:QI , COMPARE )
here and if 2) isn't there, we'll call
make_compound_operation ( subreg:SI , COMPARE )
and as 0x08000000 is a SImode power-of-two, we call
make_compound_operation ( and:DI , COMPARE )
and thus return (lshiftrt:DI (reg:DI) (const_int 27)), afterwards subregged
to SI mode (still fine), but then to QI mode (wrong).
If there is just simplified
(ne (subreg:QI (and:DI (reg:DI) (const_int 0x08000000)) 0) (const_int 0))
we'd call
make_compound_operation ( subreg:QI , COMPARE )
and, as 0x08000000 is not a QImode power-of-two, we'd just
make_compound_operation ( and:DI , SET )
and all would be fine.

Does it hurt to punt on nested SUBREG (it isn't really punting, just passing
SET instead of COMPARE, which means avoiding the and with power of two and
some make_extraction details), when usually the nested subregs should be
already simplified and thus the reason I want it there is just to be safe?

> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8?
> > 
> > 2013-05-02  Jakub Jelinek  <jakub@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...

Ok, will tweak that.

	Jakub



More information about the Gcc-patches mailing list