Reputation: 6403
I have a program that works fine when I run it using C++ however, when I call it from my LLVM IR code it does not work.
extern "C" DLLEXPORT double *DOT(double A[3][3], double B[3][3]) {
std::cout << A[0][0] << std::endl;
...
}
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)
I did not include the full program to save space but, if it is useful just ask and I will update the question.
[1] 3086 segmentation fault ./built
I use the following command to compile the code:
clang++ library/library.cpp out.ll -o built
This works:
std::cout << A[0] << std::endl; // 0x1
This does not:
std::cout << A[0][0] << std::endl;
Upvotes: 1
Views: 111
Reputation: 370172
You declared your function with the wrong signature:
First, your function returns a pointer to double, not an array of doubles. This is pretty clear to see as the C++ code literally says double *
as the return type.
The less obvious problem is that the types of your arguments are "pointer to array of double", not "array of array to double". This is because C and C++ do not support function parameters of array types, but decided, quite confusingly, to still accept the syntax for array types in parameter lists, but simply treat it as if it declared a pointer. So double A[3][3]
in a parameter list (and only there) is just a more confusing way to write double (*A)[3]
.
So in conclusion your declaration should be:
declare double* @DOT([3 x double]*, [3 x double]*)
Accordingly, you should also change your calling code to call @DOT
with pointers of the right type.
Upvotes: 2