从 LLVM IR 中的向量寄存器中提取子向量

Extracting Subvector from Vector Register in LLVM IR

我正在寻找一种更紧凑的方法来从<8 x float>(例如ymm0)寄存器中提取连续的<4 x float>(例如xmm0),最终将使用 SIMD 矢量宽度命名。

这按预期工作,但相当复杂:

%out.1 = extractelement <8 x float> %out.0, i32 0
%out.2 = extractelement <8 x float> %out.0, i32 1
%out.3 = extractelement <8 x float> %out.0, i32 2
%out.4 = extractelement <8 x float> %out.0, i32 3
%out.5 = insertelement <4 x float> undef, float %out.1, i32 0
%out.6 = insertelement <4 x float> %out.5, float %out.2, i32 1
%out.7 = insertelement <4 x float> %out.6, float %out.3, i32 2
%out.8 = insertelement <4 x float> %out.7, float %out.4, i32 3

有没有更精简的方法来完成同样的事情?

shufflevector 将完成与上面相同的事情(前提是您只对 %out.8 感兴趣)并且 LLVM 将用简单的寄存器名称更改来替换它(例如,如果 %out.1ymm0%out.8 将是 xmm0)。

单行替换八行:

%out.8 = shufflevector <8 x float> %out.0, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>