[LLVMdev] Alignment of vectors

Benedict Gaster benedict.gaster at amd.com
Fri Jul 18 10:12:11 PDT 2008


Hi,

Comments inline.

Ben


On 18/07/2008 16:30, "Eli Friedman" <eli.friedman at gmail.com> wrote:

> On Fri, Jul 18, 2008 at 6:45 AM, Benedict Gaster
> <benedict.gaster at amd.com> wrote:
>> Consider the following C code:
>> 
>> typedef __attribute__(( ext_vector_type(2) )) float float2;
>> typedef __attribute__(( ext_vector_type(2) )) __attribute__(( aligned(4) ))
> 
> AFAIK, the aligned attribute doesn't do anything on a typedef of
> anything other than a struct/union type in either gcc or clang.  It
> would be possible to implement something like this, but someone would
> need to spec out exactly what it would do in various situations and
> send the proposal past the gcc devs.
> 
[bg] Thanks, I missed that.

>> float float2_align2;
>> 
>> void foo(void)
>> {
>>   const float * p;
>>   size_t offset;
>>   float2 tmp = *((float2_align2 *)(p+offset));
>> }
>> 
>> When compiled with clang ‹emit-llvm I get:
>> 
>> define void @foo() {
>> entry:
>>     %p = alloca float*, align 4        ; <float**> [#uses=1]
>>     %offset = alloca i32, align 4        ; <i32*> [#uses=1]
>>     %tmp = alloca <2 x float>, align 8        ; <<2 x float>*> [#uses=1]
>>     %tmp1 = load float** %p        ; <float*> [#uses=1]
>>     %tmp2 = load i32* %offset        ; <i32> [#uses=1]
>>     %add.ptr = getelementptr float* %tmp1, i32 %tmp2        ; <float*>
>> [#uses=1]
>>     %conv = bitcast float* %add.ptr to <2 x float>*        ; <<2 x float>*>
>> [#uses=1]
>>     %tmp3 = load <2 x float>* %conv        ; <<2 x float>> [#uses=1]
>>     store <2 x float> %tmp3, <2 x float>* %tmp
>>     ret void
>> }
>> 
>> The problem is that the load into tmp3 seems to have lost any information
>> that %conv should not be aligned to 8 bytes but rather 4. Of course, GCC
>> only states that the alignment attribute will try and enforce a minimal
>> alignment and so the above code generated by clang is valid
> 
> Right.
> 
>> but what about
>> if the following code had been generated:
>> 
>> define void @foo() {
>> entry:
>>     %p = alloca float*, align 4        ; <float**> [#uses=1]
>>     %offset = alloca i32, align 4        ; <i32*> [#uses=1]
>>     %tmp = alloca <2 x float>, align 4        ; <<2 x float>*> [#uses=1]
>>     %tmp1 = load float** %p        ; <float*> [#uses=1]
>>     %tmp2 = load i32* %offset        ; <i32> [#uses=1]
>>     %add.ptr = getelementptr float* %tmp1, i32 %tmp2        ; <float*>
>> [#uses=1]
>>     %conv = bitcast float* %add.ptr to <2 x float>*        ; <<2 x float>*>
>> [#uses=1]
>>     %tmp3 = load <2 x float>* %conv        ; <<2 x float>> [#uses=1]
>>     store <2 x float> %tmp3, <2 x float>* %tmp
>>     ret void
>> }
> 
> clang shouldn't be generating code like that.  Per the current gcc
> documentation, the aligned attribute isn't allowed to decrease
> alignment.  What would happen if the code subsequently passed a
> pointer to the variable with the aligned attribute to another
> function?
> 

[bg] Sorry I did not mean to imply that Clang generated this code, it was
written by hand. What I was trying to understand was: is if it is valid LLVM
IL? I agree that any frontend generating this code must carefully enforce
that restricted alignment pointers are not passed to functions that don't
expect them.

>> Of course, it is now up to the backend to assure that an unaligned load is
>> handled correctly in hardware, but assuming this is ok, then is this
>> correct?
> 
> Unaligned loads should codegen correctly in LLVM; if they don't,
> please file a bug.
>
> -Eli
> 
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> 






More information about the llvm-dev mailing list