On Mon, Jul 25, 2011 at 3:24 PM, Richard Guenther
<richard.guent...@gmail.com> wrote:
> On Mon, Jul 25, 2011 at 3:22 PM, Ulrich Weigand <uweig...@de.ibm.com> wrote:
>> Richard Guenther wrote:
>>
>>> >>>>>> Well, the back-end assumes a pointer to vector type is always
>>> >>>>>> naturally aligned, and therefore the data it points to can be
>>> >>>>>> accessed via a simple load, with no extra rotate needed.
>>> >>>>>
>>> >>>>> I can't see any use of VECTOR_TYPE in config/spu/, and assuming
>>> >>>>> anything about alignment just because of the kind of the pointer
>>> >>>>> is bogus - the scalar code does a scalar read using that pointer.
>>> >>>>> So the backend better should look at the memory operation, not
>>> >>>>> at the pointer type.  That said, I can't find any code that looks
>>> >>>>> suspicious in the spu backend.
>>> >>>>>
>>> >>>>>> It seems what happened here is that somehow, a pointer to int
>>> >>>>>> gets replaced by a pointer to vector, even though their alignment
>>> >>>>>> properties are different.
>>> >>>>>
>>> >>>>> No, they are not.  They get replaced if they are value-equivalent
>>> >>>>> in which case they are also alignment-equivalent.  But well, the
>>> >>>>> dump snippet wasn't complete and I don't feel like building a
>>> >>>>> SPU cross to verify myself.
>>
>>> > Seems perfectly valid to me.  Or well - I suppose we might run into
>>> > the issue that the vectorizer sets alignment data at the wrong spot?
>>> > You can check alignment info when dumping with the -alias flag.
>>> > Building a spu cross now.
>>>
>>> Nope, all perfectly valid.
>>
>> Ah, I guess I see what's happening here.  When the SPU back-end is called
>> to expand the load, the source operand is passed as:
>>
>> (mem:SI (reg/f:SI 226 [ vect_pa.9 ])
>>        [2 MEM[base: vect_pa.9_44, offset: 0B]+0 S4 A32])
>>
>> Now this does say the MEM is only guaranteed to be aligned to 32 bits.
>>
>> However, spu_expand_load then goes and looks at the components of the
>> address in detail, in order to figure out how to best perform the access.
>> In doing so, it looks at the REGNO_POINTER_ALIGN values of the base
>> registers involved in the address.
>>
>> In this case, REGNO_POINTER_ALIGN (226) is set to 128, and therefore
>> the back-end thinks it can use an aligned access after all.
>>
>> Now, the reason why REGNO_POINTER_ALIGN (226) is 128 is that the register
>> is the DECL_RTL for the variable vect_pa.9, and that variable has a
>> pointer-to-vector type (with target alignment 128).
>>
>> When expanding that variable, expand_one_register_var does:
>>
>>  if (POINTER_TYPE_P (type))
>>    mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (type)));
>>
>> All this is normally completely correct -- a variable of type pointer
>> to vector type *must* hold only properly aligned values.
>
> No, this is indeed completely bogus code ;)  it should instead
> use get_pointer_alignment.

Btw, as pseudos do not have a single def site how can the above
ever be correct in the face of coalescing?  For example on trees we
can have

 p_1 = &a; // align 256
 p_2 = p_1 + 4; // align 32

but we'll coalesce the thing and thus would have to use the weaker
alignment of both SSA names.  expand_one_register_var expands
the decl, not the SSA name, so using get_pointer_alignment on
the decl would probably be fine, though also pointless as it always
will return 8.

At least I don't see any code that would prevent a temporary variable
of type int * of being coalesced with a temporary variable of type vector int *.

Why should REGNO_POINTER_ALIGN be interesting to anyone?
Proper alignment information is (should be) attached to every
MEM already.

Richard.

Reply via email to