X86 我可以使用LLVM jit生成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];

我知道我可以在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];
浮点数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
查看反汇编,您有一个紧密的内部循环(如果您的名称与我相同,这应该是label
LBB0_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