理解LLVM-IR中的比特广播 我试图理解C++程序生成的LLVM IR。 int add(int *x); int func() { int T; T=25; return add(&T); }

理解LLVM-IR中的比特广播 我试图理解C++程序生成的LLVM IR。 int add(int *x); int func() { int T; T=25; return add(&T); },llvm,llvm-ir,Llvm,Llvm Ir,生成的IR为: define i32 @_Z4funcv() local_unnamed_addr #0 { entry: %T = alloca i32, align 4 %0 = bitcast i32* %T to i8* call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #3 store i32 25, i32* %T, align 4, !tbaa !2 %call = call i32 @_Z3a

生成的IR为:

define i32 @_Z4funcv() local_unnamed_addr #0 {
entry:
  %T = alloca i32, align 4
  %0 = bitcast i32* %T to i8*
  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #3
  store i32 25, i32* %T, align 4, !tbaa !2
  %call = call i32 @_Z3addPi(i32* nonnull %T)
  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #3
  ret i32 %call
}

我不明白这一行
%0=bitcast i32*%T到i8*
。将
%T
i32
转换为
i8
的目的是什么?

假设您了解本质

llvm.lifety.start/llvm.lifety.end

它作为内存的使用使用使用标记进行内存依赖性分析

关于指针(变量地址)的选择,i8是为了使其更通用,作为字节可寻址内存区域,第一个参数是字节数,与我们在malloc中使用的相同

因此,要生成内部调用,我们需要一个内存字节地址和字节数,即sizeof(T)。这就是为什么我们需要将i32*转换为i8*

顺便说一下,您的示例中使用的签名if life intrinsic是

声明void@llvm.lifety.start(i64,i8*nocapture)

声明void@llvm.lifety.end(i64,i8*nocapture)


查看更多信息。

之所以这样做,是因为指针的值(即内存地址)被传递到
@llvm.life.start
内部,这意味着直到函数中的该点(即在下面的
存储
之前)指针都是死的。您可以查看和在LLVM源代码中的示例用法。