有人可以解释一下这段代码有什么问题吗?
我认为这应该从全局数组中获取第二个参数,但实际上它会在JIT编译例程中的某个地方静默地压缩。
我的假设:
似乎我错过了一些基本的东西,但是我应该放弃寻找答案的时间点已经消失,我不得不寻求帮助。
@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
}
答案 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>