分段错误 - 访问从 LLVM IR 代码传递的数组元素

Segmentation fault - accessing array elements passed from LLVM IR code

我有一个程序,当我 运行 它使用 C++ 时工作正常,但是,当我从我的 LLVM IR 代码调用它时,它不起作用。

函数 (library/library.cpp)

extern "C" DLLEXPORT double *DOT(double A[3][3], double B[3][3]) {
  std::cout << A[0][0] << std::endl;
...
}

LLVM IR (out.ll)

declare [3 x double] @DOT([3 x [3 x double]], [3 x [3 x double]])
...
%a1 = load [3 x [3 x double]], [3 x [3 x double]]* %a
%b2 = load [3 x [3 x double]], [3 x [3 x double]]* %b
%calltmp = call [3 x double] @DOT([3 x [3 x double]] %a1, [3 x [3 x double]] %b2)

我没有包含完整的程序来保存 space 但是,如果它有用,请问我,我会更新问题。

错误(内置)

[1]    3086 segmentation fault  ./built

我使用以下命令编译代码:

clang++ library/library.cpp out.ll -o built

信息

这个有效:

std::cout << A[0] << std::endl; // 0x1

这不是:

std::cout << A[0][0] << std::endl;

你用错误的签名声明了你的函数:

首先,您的函数 return 是一个指向双精度的指针,而不是双精度数组。这很清楚,因为 C++ 代码字面意思是 double * 作为 return 类型。

不太明显的问题是您的参数类型是 "pointer to array of double",而不是 "array of array to double"。这是因为 C 和 C++ 不支持数组类型的函数参数,但相当混乱地决定在参数列表中仍然接受数组类型的语法,但只是将其视为声明了一个指针。所以 double A[3][3] 在参数列表中(并且只有那里)只是一种更令人困惑的写法 double (*A)[3].

所以最后你的声明应该是:

declare double* @DOT([3 x double]*, [3 x double]*)

因此,您还应该更改调用代码以使用正确类型的指针调用 @DOT