1
我想了解C編譯器和它產生的中間代碼。Clang C到LLVM編譯修剪「錯誤代碼」
我有一系列編譯,生成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
{}
}
當鐺編譯此,它生成完全相同的LLVM-IR。編譯器認識到身體是垃圾,並返回undefined! LLVM知道這一點的方式就是優化器。 Clang - > LLVM在定義函數時使用「返回值收集器」約定 - 將%1分配爲「返回值」。所有的返回語句都會更新這個值,並且最終在函數體的末尾有一個ret語句,它實質上返回這個值。 LLVM認爲一個變量被分配並返回而不被更新或初始化,並將其設置爲未定義。
現在的踢球!
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函數應該是undefined任何人都可以解釋爲什麼這個代碼被刪除?
該函數沒有UB。如果調用者使用返回值,則僅調用UB。 –
......這也是你可能關心'3'的唯一原因。 –
如果調用者只傳遞非負參數,那麼它可以使用返回值。 –