在 C 代码中使用 memcpy 并使用 wasm 目标编译时出现 llvm-link 错误
llvm-link error when using memcpy in C code and compiling with wasm target
我正在尝试通过 clang
将两个 *.c 文件编译为 LLVM 位码,link 使用 llvm-link
将它们一起编译,并从中生成一个 *.wasm 文件.我通过 https://github.com/yurydelendik/wasmception
提供的 Makefile 在我的机器上构建了 LLVM
在我在 C 代码中使用 memcpy
之前,它工作正常。然后 llvm-link
因错误停止:
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* @llvm.memcpy.p0i8.p0i8.i32
以下是重现问题的最小示例:
one.c
#define EXPORT __attribute__((visibility("default")))
#include <string.h>
char* some_str();
EXPORT void do_something() {
char* cpy_src = some_str();
char other_str[15];
memcpy(other_str, cpy_src, strlen(cpy_src));
}
two.c
char* some_str() {
return "Hello World";
}
执行以下命令:
$ clang --target=wasm32-unknown-unknown-wasm --sysroot=../wasmception/sysroot -S -emit-llvm -nostartfiles -fvisibility=hidden one.c -o one.bc
[...]
$ clang --target=wasm32-unknown-unknown-wasm --sysroot=../wasmception/sysroot -S -emit-llvm -nostartfiles -fvisibility=hidden two.c -o two.bc
[...]
请注意,没有进行任何优化,因为这会消除此处不必要的 memcpy
调用。正如我所说,这是一个脱离上下文来显示错误的最小示例。
$ llvm-link one.bc two.bc -o res.bc -v
Loading 'one.bc'
Linking in 'one.bc'
Loading 'two.bc'
Linking in 'two.bc'
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* @llvm.memcpy.p0i8.p0i8.i32
llvm-link: error: linked module is broken!
当我注释掉示例文件中的 memcpy
调用时,错误消失了。当然,这不是我正在工作的真实项目中的选项。
我是不是做错了什么?在 WebAssembly 上下文中使用 memcpy
通常是个坏主意吗?这可能是 LLVM/Clang 中的错误吗?
通读这些 github 问题,WASM 后端目前似乎不支持 memcpy
内在函数:
https://github.com/WebAssembly/design/issues/236
https://github.com/WebAssembly/design/issues/1003
作为解决方法,您可以指示 clang 使用 -fno-builtin
禁用内部扩展,以便生成的代码将调用实际的 memcpy
函数。
我正在尝试通过 clang
将两个 *.c 文件编译为 LLVM 位码,link 使用 llvm-link
将它们一起编译,并从中生成一个 *.wasm 文件.我通过 https://github.com/yurydelendik/wasmception
在我在 C 代码中使用 memcpy
之前,它工作正常。然后 llvm-link
因错误停止:
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* @llvm.memcpy.p0i8.p0i8.i32
以下是重现问题的最小示例:
one.c
#define EXPORT __attribute__((visibility("default")))
#include <string.h>
char* some_str();
EXPORT void do_something() {
char* cpy_src = some_str();
char other_str[15];
memcpy(other_str, cpy_src, strlen(cpy_src));
}
two.c
char* some_str() {
return "Hello World";
}
执行以下命令:
$ clang --target=wasm32-unknown-unknown-wasm --sysroot=../wasmception/sysroot -S -emit-llvm -nostartfiles -fvisibility=hidden one.c -o one.bc
[...]
$ clang --target=wasm32-unknown-unknown-wasm --sysroot=../wasmception/sysroot -S -emit-llvm -nostartfiles -fvisibility=hidden two.c -o two.bc
[...]
请注意,没有进行任何优化,因为这会消除此处不必要的 memcpy
调用。正如我所说,这是一个脱离上下文来显示错误的最小示例。
$ llvm-link one.bc two.bc -o res.bc -v
Loading 'one.bc'
Linking in 'one.bc'
Loading 'two.bc'
Linking in 'two.bc'
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* @llvm.memcpy.p0i8.p0i8.i32
llvm-link: error: linked module is broken!
当我注释掉示例文件中的 memcpy
调用时,错误消失了。当然,这不是我正在工作的真实项目中的选项。
我是不是做错了什么?在 WebAssembly 上下文中使用 memcpy
通常是个坏主意吗?这可能是 LLVM/Clang 中的错误吗?
通读这些 github 问题,WASM 后端目前似乎不支持 memcpy
内在函数:
https://github.com/WebAssembly/design/issues/236
https://github.com/WebAssembly/design/issues/1003
作为解决方法,您可以指示 clang 使用 -fno-builtin
禁用内部扩展,以便生成的代码将调用实际的 memcpy
函数。