将LLVM代码与C代码集成的正确方法是什么?

将LLVM代码与C代码集成的正确方法是什么?,c,llvm,jit,C,Llvm,Jit,所以,我有一些生成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

所以,我有一些生成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={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指令不是用来处理内存中的数组的。它们用于处理寄存器中的数组

为了说明(并测试)我遇到的问题,我编写了两个更简单的代码

第一个用于处理寄存器中的数组,而不用于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
}        
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
}