LLVM中无需额外值或BitCast获取指针的指针?类型疑惑
LLVM IR中指针存储指令的类型匹配问题解析
原C++代码
int main() { int* k = new int(0); int* j = k; return 0; }
生成的LLVM IR
define dso_local i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32*, align 8 %3 = alloca i32*, align 8 store i32 0, i32 *%1, align 4 %4 = call i8* @_Znwm(i64 4) #2 %5 = bitcast i8* %4 to i32* store i32 0, i32* %5, align 4 store i32* %5, i32** %2, align 8 %6 = load i32*, i32** %2, align 8 store i32 *%6, i32** %3, align 8 ret i32 0 }
疑问
聚焦于指令 store i32* %5, i32** %2, align 8:%2 是通过 alloca i32*, align 8 分配的存储空间,却被当作i32**使用,既未生成额外LLVM值(如伪代码 %starstar = alloca(i32**); store(%2, %starstar)),也未使用BitCast转换,想了解该实现方式的原理。
原理解析
这是LLVM类型系统的固有特性,核心在于**alloca指令的返回值类型规则**:
alloca T指令的作用是在栈上分配一块能容纳T类型数据的内存,返回的是指向这块内存的指针,其类型为T*。- 具体到案例中,
%2 = alloca i32*, align 8表示分配一块可存储i32*类型数据的栈内存,返回的%2本身就是i32**类型——因为它指向的是一个存放i32*的地址。
所以后续的store i32* %5, i32** %2, align 8完全符合类型规则:%2的本质就是i32**,不需要额外的类型转换或中间变量。直白来说,要在栈上存一个int*(对应LLVM的i32*),用来存储它的变量本身必然是int**(LLVM的i32**),alloca指令直接返回了这个正确类型的指针。
内容的提问来源于stack exchange,提问作者Vladimir Tsyshnatiy
相关产品推荐
相关产品推荐

