【发布时间】:2018-12-28 00:28:08
【问题描述】:
我正在尝试通过clang 将两个*.c 文件编译为LLVM 位码,使用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
以下是重现该问题的最小示例:
一个.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));
}
两个.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 中的错误吗?
【问题讨论】:
-
作为一种解决方法,您可以尝试使用
-fno-builtin禁用 memcpy 内部扩展 -
读到这个 (github.com/WebAssembly/design/issues/1003),可能是 memcpy 内部还不支持,但我不确定
-
哇老兄。那成功了!
-fno-builtin使错误消失。谢谢你。 @valiano 如果您将其发布为答案,我将接受并投票。 -
感谢@Steve Beer,很高兴有帮助!
标签: clang llvm webassembly