Я не знаю ни одного хорошего решения с использованием общих arm_neon.h
встроенных функций, но, по крайней мере, с Clang, возможно, используя встроенные Clang Speci c, чтобы создать вектор, в котором некоторые элементы установлены как неопределенные, поэтому кодегену не нужно заполнять их каким-либо конкретным значением.
Установка, которая использует такой вид:
$ cat test.c
#include <arm_neon.h>
int32_t narrow_saturate(int32x2_t stuff32) {
int16x4_t stuff16 = vqmovn_s32(__builtin_shufflevector(stuff32, stuff32, 0, 1, -1, -1));
return vget_lane_s32(vreinterpret_s32_s16(stuff16), 0);
}
$ clang -target aarch64-linux-gnu test.c -S -o - -O2
[...]
narrow_saturate:
sqxtn v0.4h, v0.4s
fmov w0, s0
ret
https://godbolt.org/z/N_NsSE
См. https://clang.llvm.org/docs/LanguageExtensions.html#builtin -shufflevector для документации по __builtin_shufflevector
.
РЕДАКТИРОВАТЬ: кажется также возможно достичь того же с Clang с помощью неинициализированной переменной ( хотя это может генерировать предупреждения с помощью `-Wuninitialized):
$ cat test.c
#include <arm_neon.h>
int32_t narrow_saturate(int32x2_t stuff32) {
int32x2_t uninitialized;
int16x4_t stuff16 = vqmovn_s32(vcombine_s32(stuff32, uninitialized));
return vget_lane_s32(vreinterpret_s32_s16(stuff16), 0);
}
Clang выдает то же самое для этого (https://godbolt.org/z/TzHuon), в то время как G CC все еще включает mov v0.8b, v0.8b
(https://godbolt.org/z/wZTAU9).