LLVM中的SIMD向量内存加载

6
在LLVM中,从内存加载数据到SIMD向量的“正确”(即可移植)方法是什么?
通过查看LLVM自动向量化器生成的用于x86目标的典型IR,似乎模式如下:
将指针强制转换为标量类型(例如,将double *强制转换为相应的矢量类型<4 x double>*), 在考虑对齐方面载入转换后的指针(即不使用矢量类型的自然对齐方式,而使用相应标量类型的对齐方式)。
在AVX的情况下,这种模式可以很好地映射到SIMD指令,如_mm256_loadu_pd()和友军。但是,我不知道这种策略是否也适用于其他ISA(例如Neon,AltiVec)。
我无法在LLVM文档中找到有关此主题的信息。 我错过了一些明显的东西吗?

我认为这取决于硬件:https://dev59.com/g1cO5IYBdhLWcg3wgRsG#45938112 不确定编译器是否意识到这些细微差别。 - Soonts
1个回答

1

在更多时间的思考后,我认为一种可移植的解决方案可能是:

  • 以通常(非SIMD)方式逐个从内存中加载标量值,
  • 立即使用重复的insertelement指令构建向量。

同样,在将SIMD向量中的值存储到内存位置时,通过extractelement指令将向量元素提取为标量,并逐个存储它们。

在我的实验中,LLVM优化器总是成功地识别这些模式并将它们融合成直接的SIMD加载/存储指令。

然而,这种策略也会导致生成的IR大小明显膨胀,并且编译时间下降。因此,暂时我将坚持直接位转换方法,如果特定设置上位转换方法失败,也许会实现这种其他方法作为备选方案。


我正在考虑研究IRBuilder中的CreateMaskedLoad()指令以达到这个目的。你认为这值得研究吗?这是掩码加载/存储指令的正确使用方式,还是它们用于其他用途? - Sanket_Diwale

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接