如何让 gcc 使用 SSE4.1 pminuq/pminud/etc 操作码对代码进行矢量化?

How can I get gcc to vectorize code using the SSE4.1 pminuq/pminud/etc opcodes?

我一直在使用出色的 godbolt.org 来确定 gcc 对什么进行矢量化和不进行矢量化:但是我想不出任何方法让它对 min(X,Y) 函数进行矢量化进入 PMINUQ 等

查看 gcc 源代码中的 sse.md 机器描述语言文件,我可以看到围绕 12355 行开始的一个块提到了 p,在我看来它是虽然它应该输出 PMINUQ 等。所以我看不出有任何理由为什么用 -msse4 -msse4.1 编译这个模式不应该只是工作。

但是,md 的这一部分内部也有一个“&&”行,这似乎(?)暗示此操作码仅适用于 AVX 样式的宽目标。

所以,我无法判断这是硬件限制、compiler/md 错误、-msse4.1 的 godbolt.org 问题,还是完全是其他原因。谁能帮我缩小范围?

gcc -msse4 -msse4.1 -msse4.2 -O3 -fopt-info-vec-all

#include <stdint.h>

#define MAX_LOOPS 10000

uint64_t in_array[MAX_LOOPS];
uint64_t shift_array[MAX_LOOPS];

void do_max(uint64_t maxval)
{
    for (int i=0; i<MAX_LOOPS; i++)
        out_array[i] = (in_array[i] < maxval) ? in_array[i] : maxval;
}

godbolt.org 告诉我我正在...

    pcmpeqq xmm0, xmm1
    pandn   xmm0, xmm2

...当我希望...

    pminuq  xmm0, xmm1

vpminuq 需要 AVX512。 (https://www.felixcloutier.com/x86/pminud:pminuq)

SSE4.1 / AVX2 只有pminub/w/d。尝试使用包含 32 位元素的数组。