使用LLVM编译此代码时:
struct bar {
int int1;
int int2;
char char1;
char char2;
char char3;
};
struct foo {
struct bar array[16];
};
int func(struct foo *f, int num) {
for(int i = 0; i < num; i++){
f->array[i].int1 = 1;
f->array[i].int2 = 2;
f->array[i].char1 = 'a';
f->array[i].char2 = 'b';
f->array[i].char3 = 'c';
}
return num;
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,编译器决定以奇怪的方式迭代这个数组.首先,它在结构的中间或末尾选择一个看似任意的点,然后使用相对于任意点的immediates存储适当的值.
我发现从这个IR代码中选择了任意点:
%scevgep = getelementptr %struct.foo* %f, i32 0, i32 0, i32 0, i32 4
Run Code Online (Sandbox Code Playgroud)
其中4是char3的偏移量.
在这个例子中,int1,int2,char1,char2的存储将具有负的immediates,char3将立即为0.
似乎使用结构条的不同排列,您可以得到不同的偏移量,但始终在结构体的内部或末尾.
例如,将struct bar更改为:
struct bar {
char …Run Code Online (Sandbox Code Playgroud)