gpt4 book ai didi

LLVM 的 amd64 输出中向量的对齐

转载 作者:行者123 更新时间:2023-12-02 11:28:27 24 4
gpt4 key购买 nike

我正在尝试通过 LLVM 在结构内部使用向量。我的结构有以下 C 定义:

struct Foo
{
uint32_t len;
uint32_t data[32] __attribute__ ((aligned (16)));
};

下面是一些 LLVM 代码,用于将 42 添加到 data 字段的元素号 3:

%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 字节对齐,这似乎很浪费,而且也是错误的(据我所知向量应该是 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 字节(如果使用 16 字节对齐则浪费 12 字节)似乎是错误的。那么这是怎么回事?

最佳答案

我认为您的 GEP 距离最佳代码生成器还有点距离。下面是一些执行类似操作的 C 代码:

#include <stdint.h>

struct Foo
{
uint32_t len;
uint32_t data[32] __attribute__ ((aligned (16)));
};

void foo(struct Foo *F)
{
F->data[3] = 4;
}

哪个 clang 变成了这样:

; ModuleID = 'foo.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0.0"

%struct.Foo = type { i32, [12 x i8], [32 x i32] }

define void @foo(%struct.Foo* %F) nounwind ssp {
%1 = alloca %struct.Foo*, align 8
store %struct.Foo* %F, %struct.Foo** %1, align 8
%2 = load %struct.Foo** %1, align 8
%3 = getelementptr inbounds %struct.Foo* %2, i32 0, i32 2
%4 = getelementptr inbounds [32 x i32]* %3, i32 0, i64 3
store i32 4, i32* %4
ret void
}

以及您期望的相应的漂亮代码:

_foo:                                   ## @foo
Leh_func_begin0:
## BB#0:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $4, 28(%rdi)
popq %rbp
ret
Leh_func_end0:

也就是说,您的代码不正确,应该是:

_process:                               ## @process
Leh_func_begin1:
## BB#0: ## %_L1
movaps 16(%rdi), %xmm0
pextrd $3, %xmm0, %eax
addl $42, %eax
pinsrd $3, %eax, %xmm0
movaps %xmm0, 16(%rdi)
ret

在 ToT 中情况更糟,因此错误报告不会出错。

关于LLVM 的 amd64 输出中向量的对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5065800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com