Я пытаюсь использовать векторы внутри структур с LLVM. У меня есть следующее определение C моей структуры:
struct Foo
{
uint32_t len;
uint32_t data[32] __attribute__ ((aligned (16)));
};
и вот код LLVM для добавления 42 к элементу номер 3 поля data
:
%Foo = type { i32, <32 x i32> }
define void @process(%Foo*) {
_L1:
%data = getelementptr %Foo* %0, i32 0, i32 1
%vec = load <32 x i32>* %data
%x = extractelement <32 x i32> %vec, i32 3
%xNew = add i32 42, %x
%vecNew = insertelement <32 x i32> %vec, i32 %xNew, i32 3
store <32 x i32> %vecNew, <32 x i32>* %data
ret void
}
Однако вывод llc выглядит так, как если бы векторы должны были быть выровнены по 128 байтам, что кажется расточительным, а также неправильным (векторы AFAIK должны быть выровнены по 16 байтам):
.file "process.bc"
.text
.globl process
.align 16, 0x90
.type process,@function
process: # @process
.Leh_func_begin0:
# BB#0: # %_L1
movdqa 128(%rdi), %xmm0
pextrd $3, %xmm0, %eax
addl $42, %eax
pinsrd $3, %eax, %xmm0
movdqa %xmm0, 128(%rdi)
ret
.Ltmp0:
.size process, .Ltmp0-process
.Leh_func_end0:
Конечно, если я изменю определение C, чтобы также выровнять поле данных по 128 байтам, это сработает, но потеря 124 байтов (по сравнению с 12 при использовании выравнивания по 16 байтам) кажется неправильной. Так что же здесь происходит?