【问题标题】:llvm-link error when using memcpy in C code and compiling with wasm target在 C 代码中使用 memcpy 并使用 wasm 目标编译时出现 llvm-link 错误
【发布时间】: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


【解决方案1】:

通读这些 github 问题,似乎 WASM 后端当前不支持 memcpy 内在函数:

https://github.com/WebAssembly/design/issues/236
https://github.com/WebAssembly/design/issues/1003

作为一种解决方法,您可以指示 clang 使用 -fno-builtin 禁用内部扩展,以便生成的代码将调用实际的 memcpy 函数。

【讨论】:

  • 虽然变通办法确实使我的示例工作,但它并没有消除我正在摆弄的实际项目中的所有内在函数调用。我会进行更多调查,也许会发布另一个问题。目前,这个答案对我来说仍然是一个很好的答案,b/c 它解决了给定示例的问题。
  • 非常感谢!当我只想使用标准 C 库进行 C 到 WASM 编译时,这对我很有帮助;在某些情况下,当我从未添加它时,它会尝试使用 memcpy 之类的库函数进行优化,因此编译会失败(至少,我认为这是正在发生的事情)。
猜你喜欢
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多