如何将 AVX 矢量与 clang 本机矢量语法(无内在函数)混合?

How do I do AVX vector blending with clang native vector syntax (no intrinsics)?

令我高兴的是,我发现 clang 可以让您使用 extended vectors.

编写显式矢量代码,而无需诉诸内在函数

例如,这段代码:

typedef float floatx16 __attribute__((ext_vector_type(16)));

floatx16 add( floatx16 a, floatx16 b )
{
    return a+b;
}

...将直接转换为带有 clang -march=skylake-avx512 调用的单个指令:

vaddps  zmm0, zmm0, zmm1

为了编写无分支代码,我想混合 avx512 向量。 对于内在函数,您将使用 _mm512_mask_blend_ps 内在函数。 (对了,为什么AVX512使用mask,a,b顺序,而AVX使用a,b,mask顺序?)

尝试使用三元运算符进行混合无效:

typedef float floatx16 __attribute__((ext_vector_type(16)));

floatx16 minimum( floatx16 a, floatx16 b )
{
    return a < b ? a : b;
}

...结果...

error: used type 'int __attribute__((ext_vector_type(16)))' (vector of 16 'int' values) where arithmetic or pointer type is required

是否可以在 C 中使用 ext_vector_type(16) 变量来执行 vector blendingvblendmps zmm {k}, zmm, zmm

(这是@chtz在回答形式下的评论:)

至少有两种不同的方法来做矢量类型:

表格 A:

__attribute__ ( ( ext_vector_type(numelements) ) );

表格 B:

__attribute__( ( vector_size(numbytes) ) );

当使用形式A时,表达式c ? x : y会导致编译错误,clang 11。

更糟糕的是,gcc 10 只会默默地假装 ext_vector_type(N) 有 4 个元素,即使 N 是 8 或 16。

当使用形式 B 时,表达式 c ? x : yproperly translated 到 clang 11 的向量混合中。Clang 10 和 gcc 10 将它翻译成不同的东西,但它们都能够编译它。

我不清楚 ext_vector_type 形式存在的原因,尤其是考虑到它的效果有多糟糕。

更新 呃...这只适用于 C++,但不适用于 C。为什么???