X86 我可以使用LLVM jit生成AVX矢量化代码吗?
我知道我可以在EngineBuilder中设置mcpu和mattr以生成矢量化代码。 但是我发现对于使用-mavx的AVX来说,铿锵前线必须涉及到。否则,生成的程序集仅使用xmm寄存器 有没有办法让LLVM知道8个浮点数可以放在AVX寄存器中而不涉及前端X86 我可以使用LLVM jit生成AVX矢量化代码吗?,x86,llvm,jit,avx,X86,Llvm,Jit,Avx,我知道我可以在EngineBuilder中设置mcpu和mattr以生成矢量化代码。 但是我发现对于使用-mavx的AVX来说,铿锵前线必须涉及到。否则,生成的程序集仅使用xmm寄存器 有没有办法让LLVM知道8个浮点数可以放在AVX寄存器中而不涉及前端 我的测试代码只是矢量添加: float a[N], b[N]; float c[N]; // initialize a and b for (int i = 0; i < N; ++i) c[i] = a[i] + b[i];
我的测试代码只是矢量添加:
float a[N], b[N];
float c[N];
// initialize a and b
for (int i = 0; i < N; ++i)
c[i] = a[i] + b[i];
float a[N],b[N];
浮点数c[N];
//初始化a和b
对于(int i=0;i
不涉及FE,仅涉及LLVM本身:
llc -mattr=+avx -O3 test.il
PS
您可以通过以下方式从C代码生成test.il
clang -S -emit-llvm test.c
TL;博士:是的。您只需调用
opt
,让它对代码进行矢量化
你完全可以做到不叮当作响。矢量器都是关于LLVM IR的,它们不是在叮当作响
我从你的例子中得到了这个IR,通过使用没有优化的clang(是的,我作弊了,然后加了一两条注释):(数据布局和三元组很重要!)
现在,您需要对代码进行矢量化。让我们通过循环向量器来运行它
opt a.ll -S -march=x86-64 -mcpu=btver2 -loop-vectorize
(我用-S
运行它以在控制台上获得输出)
现在我们已经用一个巨大的vector.body
矢量化了IR,还有一些支票、预读卡和额外的簿记代码。你会在文件中间看到这个:
%171 = getelementptr inbounds float* %b, i64 %98
%172 = insertelement <8 x float*> %170, float* %171, i32 7
%173 = getelementptr float* %109, i32 0
%174 = bitcast float* %173 to <8 x float>*
%wide.load18 = load <8 x float>* %174, align 4
%175 = getelementptr float* %109, i32 8
%176 = bitcast float* %175 to <8 x float>*
%wide.load19 = load <8 x float>* %176, align 4
%177 = getelementptr float* %109, i32 16
%178 = bitcast float* %177 to <8 x float>*
%wide.load20 = load <8 x float>* %178, align 4
%179 = getelementptr float* %109, i32 24
%180 = bitcast float* %179 to <8 x float>*
%wide.load21 = load <8 x float>* %180, align 4
%181 = fadd <8 x float> %wide.load, %wide.load18
%182 = fadd <8 x float> %wide.load15, %wide.load19
%183 = fadd <8 x float> %wide.load16, %wide.load20
%184 = fadd <8 x float> %wide.load17, %wide.load21
%185 = getelementptr inbounds float* %c, i64 %5
%186 = insertelement <8 x float*> undef, float* %185, i32 0
既然我们现在已经有了对向量有效的红外光谱,我们只需要发射它。让我们执行最后一步,并致电llc
:
opt a.ll -S -march=x86-64 -mcpu=core-avx2 -loop-vectorize -O3 | llc -mcpu=core-avx2
查看反汇编,您有一个紧密的内部循环(如果您的名称与我相同,这应该是labelLBB0_5
),以及一堆簿记代码
您的代码现在已矢量化。谢谢您的提示。但我以前曾在主干版本LLVM上尝试过(2014年3月21日)。如果没有clang的帮助,IR中将不会生成类似[8 x float]的内容。LLVM无法识别两个[4 x float]可以是[8 x float]。@busytypist,您需要生成并折叠向量类型。您还必须为您的目标提供正确的三重/三月值。
llc
不运行矢量化过程。如果您看到的是矢量指令,很可能是因为(我假设)您正在x86-64机器上运行代码,该机器的ABI表示使用SSE/AVX寄存器进行浮点代码。但它仍然是标量代码:它应该只使用*ss(adds、movss等)指令。@filcab,llc实际上运行矢量化过程。使用-O2
(或-Ofast
)和-debug only=loop vectorize
查看矢量器日志。同时添加-march=core-avx2
@filcab抱歉,与opt混淆。
opt a.ll -S -march=x86-64 -mcpu=btver2 -loop-vectorize -O3
opt a.ll -S -march=x86-64 -mcpu=core-avx2 -loop-vectorize -O3 | llc -mcpu=core-avx2