GEP 指令:i32 与 i64

The GEP Instruction: i32 vs i64

我一直在努力理解 LLVM 的 GetElementPtr (GEP) 指令并偶然发现了这个文档:

http://llvm.org/docs/GetElementPtr.html

这很有用,但有几件事让我感到困惑。特别是,在 'What is dereferenced by GEP?' (http://llvm.org/docs/GetElementPtr.html#id6) 部分中讨论了以下代码:

%MyVar = uninitialized global { [40 x i32 ]* }
...
%idx = getelementptr { [40 x i32]* }, { [40 x i32]* }* %MyVar, i64 0, i32 0, i64 0, i64 17

%MyVar 是一个全局变量,它是一个指向结构的指针,该结构包含一个指向 40 个整数数组的指针。这很清楚。我知道 %MyVar 之后的参数是它的索引,但我不明白为什么其中一些被声明为 i64 而另一些被声明为 i32

我的理解是这段代码是为 64 位机器编写的,指针被假定为 64 位宽。 %MyVar指向的数组内容为32位宽。为什么最后一个索引是 i64 17 而不是 i32 17

我还应该指出,这个例子说明了 GEP 的非法使用(必须取消引用结构中的指针才能索引到 40 个整数的数组),我正试图很好地理解为什么是这样的

"what is dereferenced by GEP?" 问题的答案是。这意味着 GEP 永远不会解引用指针:它只会根据您传递给它的指针计算新地址。它从不读取任何内存。

看例子:

%idx = getelementptr { [40 x i32]* }, { [40 x i32]* }* %MyVar, i64 0, i32 0, i64 0, i64 17

我们从%MyVar开始,它是一个{ [40 x i32]* }*,一个指向包含数组指针的结构的指针。

在使用 i64 0 建立索引后,我们得到了对结构 { [40 x i32]* } 的引用。 %MyVar 已指向此,无需取消引用。

在使用第二个 i32 0 建立索引后,我们现在引用 [40 x i32]*,该结构的唯一成员。它与结构本身具有相同的内存位置,即 %MyVar.

第三个索引 i64 0 现在将引用 [40 x i32] 数组本身。 这是非法的。 GEP 需要取消引用上一步中获得的指针才能获得该内存地址。一般来说,GEP 永远不能索引 "through" 一个指针,明显的例外是你传递给它的初始值是 总是 一个指针。

我还要指出 i32 0i64 0 对于索引的目的是相同的,都引用 struct/array 中的第一个元素。您提到的常数 17 也是如此。