[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