Llvm如何访问全局数组元素

时间:2013-05-17 16:52:06

标签: llvm

有人可以解释一下这段代码有什么问题吗?

我认为这应该从全局数组中获取第二个参数,但实际上它会在JIT编译例程中的某个地方静默地压缩。

我的假设:

  1. GEP指令通过应用偏移量并返回指针来计算元素的内存地址。
  2. load指令加载由给定指针引用的值(换句话说,它取消引用指针)。
  3. ret指令退出函数并将给定值传递给调用者。
  4. 似乎我错过了一些基本的东西,但是我应该放弃寻找答案的时间点已经消失,我不得不寻求帮助。

    @arr = common global [256 x i64], align 8
    
    define i64 @iterArray() {
    entry:
      %0 = load i64* getelementptr inbounds ([256 x i64]* @arr, i32 1, i32 0)
      ret i64 %0
    }
    

1 个答案:

答案 0 :(得分:1)

您在256项数组中请求了第257项,这是一个问题。

给gep指令的第一个索引意味着通过值操作数进行了多少步骤 - 这里的值操作数不是数组而是指向数组的指针。这意味着每一步都会向前跳过整个阵列的大小 - 这就是为什么gep实际上要求第257项。使用0作为第一个gep索引可能会解决问题。然后使用1作为第二个索引将获得数组中的第二项,这是你想要的。在此处阅读更多相关信息:http://llvm.org/docs/GetElementPtr.html#what-is-the-first-index-of-the-gep-instruction

或者,这里使用extractvalue指令更合适,类似于gep,隐含地对第一个索引使用0(还有其他一些差异)。

关于为什么编译器崩溃,我不确定 - 我猜测通常这样的内存访问会编译正常(并且在运行时生成段错误或只返回错误的值),在这里你特别要求gep为inbounds,这意味着边界检查已完成 - 此处将失败 - 因此返回poison value,这意味着您的函数现在有效load undef。我不确定LLVM对load undef做了什么 - 它可能应该被优化掉,而且函数只能用return undef - 但它可能会做一些不同的事情导致你的代码被拒绝。 / p>