On Wed, Dec 09, 2015 at 10:13:34PM +0100, Eric Botcazou wrote:
> > The meaning of ZERO_EXTRACT depends on BITS_BIG_ENDIAN, not on
> > BYTES_BIG_ENDIAN.
> 
> That's correct.

> > --- a/gcc/rtlanal.c
> > +++ b/gcc/rtlanal.c
> > @@ -1534,7 +1534,7 @@ set_noop_p (const_rtx set)
> > 
> >    if (GET_CODE (dst) == ZERO_EXTRACT)
> >      return rtx_equal_p (XEXP (dst, 0), src)
> > -      && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx
> > +      && !BITS_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx
> >        && !side_effects_p (src);
> > 
> >    if (GET_CODE (dst) == STRICT_LOW_PART)
> 
> I have a hard time figuring out what a SET verifying the condition would 
> really mean.  Could you post it and explain where it comes from?

Sure!

The condition is meant to say "if you set the low part of a reg to
be equal to that reg".  And it only handles little-endian numbering
(many things with zero_extract do).

My case comes from the gcc.dg/pr65492-2.c, the "test1int2" case.
combine has made an insn
        modifying insn i3    21: zero_extract(%3:DI,0x20,0)=%3:DI
which is splatting the SImode parameter to both the high and low halves
of the dest reg.  Then, it tries to combine it with the USE of that reg
at the end of the function, giving

Failed to match this instruction:
(parallel [
        (use (ior:DI (and:DI (reg/i:DI 3 3)
                    (const_int 4294967295 [0xffffffff]))
                (ashift:DI (reg:DI 3 3 [ c ])
                    (const_int 32 [0x20]))))
        (set (zero_extract:DI (reg/i:DI 3 3)
                (const_int 32 [0x20])
                (const_int 0 [0]))
            (reg:DI 3 3 [ c ]))
    ])

and if it has a parallel of two which doesn't match, it sees if it
just needs one arm because the other is a noop set, and that ends
up with
        deleting noop move 21
because of the wrong test, making the testcase fail.
(powerpc64le has BITS_BIG_ENDIAN set, a bit unusual).


Segher

Reply via email to