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