Vector LLVM-IR中矢量寄存器的子矢量提取

Vector LLVM-IR中矢量寄存器的子矢量提取,vector,llvm,simd,llvm-ir,Vector,Llvm,Simd,Llvm Ir,我正在寻找一种更简洁的方法,从(例如ymm0)寄存器中提取连续的(例如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

我正在寻找一种更简洁的方法,从
(例如
ymm0
)寄存器中提取连续的
(例如
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
%out.1=提取元素%out.0,i32 0
%out.2=提取元素%out.0,i32 1
%out.3=提取元素%out.0,i32 2
%out.4=提取元素%out.0,i32 3
%out.5=插入元素未定义,浮点%out.1,i32 0
%out.6=插入元素%out.5,浮点%out.2,i32 1
%out.7=插入元素%out.6,浮点%out.3,i32 2
%out.8=插入元素%out.7,浮点%out.4,i32 3

有没有更精简的方法来实现同样的功能?

shufflevector
将实现上述功能(前提是您只对
%out.8
感兴趣),LLVM将用一个简单的寄存器名更改来代替它(例如,如果
%out.1
ymm0
%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>
%out.8=shufflevector%out.0,未定义,

shufflevector
将实现与上述相同的功能(前提是您只对
%out.8
感兴趣),LLVM将用一个简单的寄存器名称更改来替换它(例如,如果
%out.1
ymm0
%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>
%out.8=shufflevector%out.0,未定义,

总是高4(
vextractf128
)还是低4(只是重新解释)?或者您有时需要元素2..5或其他什么,并且希望LLVM优化为
vpermpd-ymm、ymm、imm
,以在xmm中创建您想要的结果?(或者一个
vpermps
带有元素1..4或3..6的矢量控制。)我实际上不太了解LLVM-IR,但如果它可以在一条LLVM-IR指令中表达这些x86随机指令中的任何一条,请使用它。它将始终是高或低部分,不需要随机操作,只需要不同的寄存器名。但是如果LLVM用寄存器名更改来替换它,那么在IR中使用洗牌可能是一种选择。“我会试试看,然后再向你汇报。”彼得科德斯:这就是诀窍。谢谢提取高128确实需要在x86 asm中进行洗牌,例如
vextractf128
。它不像ARM32,在ARM32中,
q10
别名的高低两半可以直接访问
d21
d20
。只有YMM的下半部分被XMM reg混淆。但是无论如何,就像在你的答案中一样,你可以把它写成一个洗牌,每个元素都有一个单独的索引,LLVM会把它编译成一个摘录,或者什么都没有,或者如果你使用不同的索引,它会编译成一个
vpermps
。它总是高4(
vextractf128
)还是低4(只是一个重新解释)?或者您有时需要元素2..5或其他什么,并且希望LLVM优化为
vpermpd-ymm、ymm、imm
,以在xmm中创建您想要的结果?(或者一个
vpermps
带有元素1..4或3..6的矢量控制。)我实际上不太了解LLVM-IR,但如果它可以在一条LLVM-IR指令中表达这些x86随机指令中的任何一条,请使用它。它将始终是高或低部分,不需要随机操作,只需要不同的寄存器名。但是如果LLVM用寄存器名更改来替换它,那么在IR中使用洗牌可能是一种选择。“我会试试看,然后再向你汇报。”彼得科德斯:这就是诀窍。谢谢提取高128确实需要在x86 asm中进行洗牌,例如
vextractf128
。它不像ARM32,在ARM32中,
q10
别名的高低两半可以直接访问
d21
d20
。只有YMM的下半部分被XMM reg混淆。但是无论如何,就像在你的答案中一样,你可以把它写成一个无序排列,每个元素都有一个单独的索引,LLVM将把它编译成一个摘录,或者什么都没有,或者编译成一个
vpermps
,如果你使用不同的索引。