[PATCH] Fix unaligned access when predictive commoning (PR 71083)

Bernd Edlinger bernd.edlinger@hotmail.de
Tue Aug 9 22:23:00 GMT 2016


On 08/09/16 22:48, Eric Botcazou wrote:
>> I think from Eric's comment in get_inner_ref it can be possible
>> in Ada that the outer object is accidentally byte-aligned
>> but the inner reference is not.  In that case I think it is
>> better to generate a BIT_FIELD_REF instead of a COMPONENT_REF.
>
> The patch says get_bit_range instead...  The comment therein means that
> bitfields can be nested in Ada: you can have a bitfield in a record which is
> itself a bitfield in another record.
>
>> Eric do you agree?  Are there any Ada test cases where the
>> pcom optimization jumps in?
>
> According to the comment, data-ref analysis punts on bit offsets so I'm not
> sure how boff can be not byte-aligned.
>

I mean in dr_analyze_innermost, we have:

   base = get_inner_reference (ref, &pbitsize, &pbitpos, &poffset, &pmode,
                               &punsignedp, &preversep, &pvolatilep);
   gcc_assert (base != NULL_TREE);

   if (pbitpos % BITS_PER_UNIT != 0)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
         fprintf (dump_file, "failed: bit offset alignment.\n");
       return false;
     }

   if (preversep)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
         fprintf (dump_file, "failed: reverse storage order.\n");
       return false;
     }


and that means that get_inner_reference on the outermost ref
returns a byte-aligned bit-offset, and from there I would
think it has the knowledge, when to punt on reversep and
when the offset is not byte-aligned.

But in get_bit_range we have a bit-field with arbitrary
bit-offset, but surprisingly the
get_inner_reference (TREE_OPERAND (exp, 0)) did not return
byte-aligned bit-offset.  I doubt that data-ref ananlysis
ever cares about the byte-alignment of intermediate
refs.

We know that the difference between the innermost ref
and the outer ref is byte-aligned, but we do not know
that the same is true for offset between the COMPONENT_REF
and the outer ref.

I mean boff is essentially the difference between
bitpos of get_inner_reference(exp) and
bitpos of get_inner_reference(TREE_OPERAND (exp, 0))

This would be exposed by my patch, because previously
we always generated BIT_FIELD_REFS, with bit-offset 0,
but the MEM_REF at the byte-offset there is in all likelihood
pretty much unaligned, the MEM_REF at the COMPONENT_REF
is likely more aligned and allows better code for ARM processors,
but only if the MEM_REF is at a byte-aligned offset at all,
otherwise the whole transformation would be wrong.



Thanks
Bernd.



More information about the Gcc-patches mailing list