1

我试图了解 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 函数应该是未定义的!谁能解释为什么这段代码被删掉了?

4

1 回答 1

5

3对于具有未定义行为的函数来说,是一个完全合理的返回值。从字面上看,任何返回值都是允许的。

于 2013-07-25T23:49:33.097 回答