Emscripten SIMD 内部函数“无效转换”错误
Emscripten SIMD intrinsics `invalid conversion` error
根据 https://emscripten.org/docs/porting/simd.html,GCC/Clang 可以使用 SIMD 矢量扩展。但是,我无法编译以下内容:
#include <emmintrin.h>
#include <stdint.h>
int stub_sse(void) {
__m128i v1 = _mm_set1_epi32(42);
__m128i v2 = _mm_set1_epi32(86);
union { __m128i v; int32_t x[4]; } v3;
v3.v = _mm_add_epi32(v1, v2);
return (int) v3.x[0];
}
int main(void) { if (stub_sse() != 128) return 1; else return 0; }
运行 emcc -msimd128 simd.c
给出很多错误,例如
/emsdk/upstream/lib/clang/10.0.0/include/mmintrin.h:525:12: error:
invalid conversion between vector type '__m64' (vector of 1 'long long' value)
and integer type 'int' of different size
return (__m64)__builtin_ia32_psubw((__v4hi)__m1, (__v4hi)__m2);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
我在 Linux 上使用 emcc upstream 1.39.1、clang 10.0.0、gcc 9.2.0。
我错过了什么吗?
此处提到 GCC/Clang SIMD 向量扩展 link 的文档:https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html。这些文档解释了如何使用 __attribute__((vector_size(16)))
来命名向量类型,并解释了可用于处理这些类型的操作。这些操作通常与您可以在 +
、-
、*
等普通标量类型上使用的操作以及逻辑操作和下标 ([]
) 相同。值得注意的是,使用这些扩展不需要包含任何 header 或调用任何特殊函数,例如 _mm_set1_epi32
.
您的代码尝试使用 emmintrin.h
,它是 x86 的 platform-specific SIMD 内在函数 header。如果您查看 emmintrin.h 内部,您会发现它根据 GCC/Clang SIMD 向量扩展实现了 __m128i
等类型和 _mm_set1_epi32
等功能,但 header本身不是矢量扩展的一部分。当前使用 Emscripten 时唯一可用的 SIMD 内在函数 header 是 wasm_simd128.h
.
根据 https://emscripten.org/docs/porting/simd.html,GCC/Clang 可以使用 SIMD 矢量扩展。但是,我无法编译以下内容:
#include <emmintrin.h>
#include <stdint.h>
int stub_sse(void) {
__m128i v1 = _mm_set1_epi32(42);
__m128i v2 = _mm_set1_epi32(86);
union { __m128i v; int32_t x[4]; } v3;
v3.v = _mm_add_epi32(v1, v2);
return (int) v3.x[0];
}
int main(void) { if (stub_sse() != 128) return 1; else return 0; }
运行 emcc -msimd128 simd.c
给出很多错误,例如
/emsdk/upstream/lib/clang/10.0.0/include/mmintrin.h:525:12: error:
invalid conversion between vector type '__m64' (vector of 1 'long long' value)
and integer type 'int' of different size
return (__m64)__builtin_ia32_psubw((__v4hi)__m1, (__v4hi)__m2);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
我在 Linux 上使用 emcc upstream 1.39.1、clang 10.0.0、gcc 9.2.0。 我错过了什么吗?
此处提到 GCC/Clang SIMD 向量扩展 link 的文档:https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html。这些文档解释了如何使用 __attribute__((vector_size(16)))
来命名向量类型,并解释了可用于处理这些类型的操作。这些操作通常与您可以在 +
、-
、*
等普通标量类型上使用的操作以及逻辑操作和下标 ([]
) 相同。值得注意的是,使用这些扩展不需要包含任何 header 或调用任何特殊函数,例如 _mm_set1_epi32
.
您的代码尝试使用 emmintrin.h
,它是 x86 的 platform-specific SIMD 内在函数 header。如果您查看 emmintrin.h 内部,您会发现它根据 GCC/Clang SIMD 向量扩展实现了 __m128i
等类型和 _mm_set1_epi32
等功能,但 header本身不是矢量扩展的一部分。当前使用 Emscripten 时唯一可用的 SIMD 内在函数 header 是 wasm_simd128.h
.