我试图了解 C 的 clang 编译器,以及它产生的中间代码。
我有一系列编译、生成 LLVM-IR 的函数,但我不明白为什么。
这是第一个:
int f(int x){
}
这会产生 LLVM 代码
define i32 @f(i32 %x) nounwind uwtable readnone{
ret i32 undef
}
我认为这是完全可以理解的。函数体未定义!
这是下一个 C 函数:
int f(int x){
if (x < 0)
{}
else
{}
}
当 clang 编译它时,它会生成完全相同的 LLVM-IR。编译器识别出主体是垃圾,并返回未定义!!!LLVM 知道这是垃圾的方式是它的优化器。Clang --> LLVM 使用“返回值收集器”约定——在定义函数时——%1 被分配为“返回值”。所有的 return 语句都会更新这个值,最终,在 LLVM 的函数体末尾有一个 ret 语句,它本质上会返回这个值。LLVM 看到一个变量在没有更新或初始化的情况下被分配和返回,并将其设置为 undefined。
现在是踢球者!
int f(int x){
if (x<0)
{}
else
{
return 3;
}
}
转换为以下 LLVM-IR。
define i32 @f(i32 %x) nounwind uwtable readnone {
ret i32 3
}
由于某种原因,未定义的代码被剪掉了。当 (x<0)!! 时,C 函数应该是未定义的!谁能解释为什么这段代码被删掉了?