所以,我有一些生成 LLVM IR 的代码。仔细阅读手册后,我设法编写了一个函数,其代码如下:
define [1 x i32] @topLevel([3 x i32] %inputArray,
[1 x i32] %returnArray) {
bb0:
%node_1 = extractvalue [3 x i32] %inputArray, 0
%node_2 = extractvalue [3 x i32] %inputArray, 1
%node_3 = extractvalue [3 x i32] %inputArray, 2
%node_8 = and i32 %node_1, %node_2
%0 = xor i32 %node_8, 1
%node_7 = and i32 %node_3, %0
%1 = xor i32 %node_3, 1
%node_6 = and i32 %1, %node_8
%2 = xor i32 %node_6, 1
%3 = xor i32 %node_7, 1
%node_5 = and i32 %2, %3
%node_4 = xor i32 %node_5, 1
%4 = insertvalue [1 x i32] %returnArray, i32 %node_4, 0
ret [1 x i32] %4
}
但是,我得到了一些非常随机的输出,我不知道为什么。
所以我用 C 写了一些测试代码,并尝试使用 clang 将它与之前的函数一起编译。
#include <stdio.h>
int * topLevel(int*, int*);
int main() {
int i[3] = {0, 0, 0};
int o[1] = {0};
int *r;
printf("sizeof(int) = %lu\n", sizeof(int));
int a =0, b = 0,c=0;
for (a=0; a < 2; ++a) {
for(b=0; b < 2; ++b) {
for(c=0; c < 2; ++c) {
i[0] = a;
i[1] = b;
i[2] = c;
r = topLevel(i, o);
printf("i={%d, %d, %d} o={%d}\n", i[0], i[1], i[2], o[0]);
}
}
}
}
我真的很乐观,我会得到正确的输出。男孩,我错了。
我期望的输出是:
sizeof(int) = 4
i={0, 0, 0} o={0}
i={0, 0, 1} o={1}
i={0, 1, 0} o={0}
i={0, 1, 1} o={1}
i={1, 0, 0} o={0}
i={1, 0, 1} o={1}
i={1, 1, 0} o={1}
i={1, 1, 1} o={0}
然而,输出是这个,这是伪造的:
sizeof(int) = 4
i={0, 0, 0} o={0}
i={0, 0, 1} o={0}
i={0, 1, 0} o={0}
i={0, 1, 1} o={0}
i={1, 0, 0} o={0}
i={1, 0, 1} o={0}
i={1, 1, 0} o={0}
i={1, 1, 1} o={0}
我做错了什么?对不起。我想问一个更具体的问题,但我迷路了。我不知道从哪里开始寻找错误。
最佳答案
事实证明,问题不在于将我的代码与 LLVM IR 代码链接起来。
答案更简单:extractvalue 和 insert value 指令不打算处理内存中的数组。它们用于处理寄存器中的数组。
为了说明(和测试)我遇到的问题,我编写了 2 个更简单的代码。
第一个用于寄存器中的数组,不适用于 C 数组。当被C代码调用时,会产生垃圾:
define [1 x i32] @workWithRegisterArrays([1 x i32] %inputArray,
[1 x i32] %returnArray) {
bb0:
%0 = extractvalue [1 x i32] %inputArray, 0
%1 = insertvalue [1 x i32] %returnArray, i32 %0, 0
ret [1 x i32] %1
}
这第二个代码,将数组的第一个元素从第一个参数复制到数组的第一个元素从第二个参数。 要在 C 中使用数组,您需要使用 getelementptr 来查找索引,并使用加载和存储操作来实际执行内存访问。
define void @workWithMemoryArrays(i32* %inputArray,
i32* %returnArray) {
bb0:
%elem_in = getelementptr inbounds i32, i32* %inputArray, i32 0
%elem_ret = getelementptr inbounds i32, i32* %returnArray, i32 0
%val = load i32, i32* %elem_in
store i32 %val, i32* %elem_ret
ret void
}
关于c - 将 LLVM 代码与 C 代码集成的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36070261/