Richard Biener <rguent...@suse.de> writes:
> On Tue, 7 Jan 2020, Richard Sandiford wrote:
>
>> Richard Biener <rguent...@suse.de> writes:
>> > On Tue, 7 Jan 2020, Andrew Pinski wrote:
>> >
>> >> On Mon, Jan 6, 2020 at 11:36 PM Richard Biener <rguent...@suse.de> wrote:
>> >> >
>> >> > On Mon, 16 Dec 2019, Andrew Pinski wrote:
>> >> >
>> >> > > On Thu, Nov 15, 2018 at 12:31 AM Richard Biener <rguent...@suse.de> 
>> >> > > wrote:
>> >> > > >
>> >> > > > On Thu, 15 Nov 2018, Richard Biener wrote:
>> >> > > >
>> >> > > > > So - can you fix it please?  Also note that the VECTOR_CST case
>> >> > > > > (as in BIT_FIELD_REF) seems to be inconsistent here and counts
>> >> > > > > "bits" in a different way?
>> >> > > >
>> >> > > > And bonus points for documenting BIT_FIELD_REF and BIT_INSERT_EXPR
>> >> > > > in generic.texi, together with those "details".
>> >> > >
>> >> > > This is the fix:
>> >> > > diff --git a/gcc/fold-const.c b/gcc/fold-const.c
>> >> > > index 8e9e299..a919b63 100644
>> >> > > --- a/gcc/fold-const.c
>> >> > > +++ b/gcc/fold-const.c
>> >> > > @@ -12301,6 +12301,8 @@ fold_ternary_loc (location_t loc, enum
>> >> > > tree_code code, tree type,
>> >> > >         {
>> >> > >           unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
>> >> > >           unsigned bitsize = TYPE_PRECISION (TREE_TYPE (arg1));
>> >> > > +         if (BYTES_BIG_ENDIAN)
>> >> > > +           bitpos = TYPE_PRECISION (type) - bitpos - bitsize;
>> >> > >           wide_int tem = (wi::to_wide (arg0)
>> >> > >                           & wi::shifted_mask (bitpos, bitsize, true,
>> >> > >                                               TYPE_PRECISION (type)));
>> >> >
>> >> > I guess you need to guard against BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
>> >> > as well.
>> >> 
>> >> Yes I will add that check.
>> >> 
>> >> >  Also the above only works reliably for mode-precision
>> >> > integers?  We might want to disallow BIT_FIELD_REF/BIT_INSERT_EXPR
>> >> > on non-mode-precision entities in the GIMPLE/GENERIC verifiers.
>> >> 
>> >> You added that check already for gimple in r268332 due to PR88739.
>> >> BIT_FIELD_REF around tree-cfg.c:3083
>> >> BIT_INSERT_EXPR  around tree-cfg.c:4324
>> >
>> > Ah, good ;)  Note neither BIT_FIELD_REF nor BIT_INSERT_EXPR are
>> > documented in generic.texi and BIT_FIELD_REF is documented in tree.def
>> > as operating on structs/unions (well, memory).  And for register args
>> > we interpret it as storing the register to memory and interpreting
>> > the bit positions in memory bit terms (with the store doing endian
>> > fiddling).
>> 
>> Ah, was going to ask what the semantics were. :-)  That sounds good
>> because it's essentially the same as for non-paradoxical subregs.
>> We have routines like subreg_lsb_1 and subreg_offset_from_lsb that
>> convert byte offsets to shift amounts, so maybe we should move them
>> to code that's common to both gimple and rtl.  The BYTES_BIG_ENDIAN !=
>> WORDS_BIG_ENDIAN calculation is quite subtle, so I don't think we should
>> open-code it everwhere we need it.
>> 
>> What about the subbyte part of the bit value?  Does that always count
>> from the lsb of the containing byte?  E.g. for the four bytes:
>> 
>>   0x12, 0x34, 0x56, 0x78
>> 
>> what does bit offset == 3, bit size == 7 mean for big-endian?
>> 
>> > But for vector (register only?) accesses we interpret
>> > it as specifying lane numbers but at least BIT_FIELD_REF verifying
>> > doesn't barf on bit/sizes not corresponding to exact vector lanes
>> > (and I know we introduce non-matching ones via at least VIEW_CONVERT
>> > "merging" into BIT_FIELD_REFs).
>> 
>> GCC's vector lane numbering is equivalent to array index numbering for
>> all endiannesses, so these cases should still be ok for BYTES_BIG_ENDIAN
>> == WORDS_BIG_ENDIAN, at least on byte boundaries.  Not sure about
>> subbyte boundaries -- guess it depends on the answer to the question
>> above.
>
> I was thinking about, say a SImode extract at offset == 16, size == 32 of 
> a V4SImode vector.  Is that to be interpreted as some weird shifted vector
> lane or as a memory "bit" location after storing the vector to
> memory?  The issue I see here is that once RTL expansion decides to
> spill and interpret the offset/size in non-lane terms will there ever
> be a mismatch between both?

I think they'll be the same for BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
(or even without for BITS_PER_WORD >= 64).  E.g.:

   memory:      0x01 0x23 | 0x45 0x67 | 0x89 0xab | 0xcd 0xef
                     ----   ----

   big-endian: 0x2345, little-endian: 0x4523

                                   0000111122223333 lane
   big-endian register:          0x0123456789abcdef (lsb)
                                     ----

                                   3333222211110000 lane
  little-endian register:        0xefcdab8967452301 (lsb)
                                             ----

Thanks,
Richard

Reply via email to