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 ステートメントが 1 つあり、基本的にこの値を返します。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 関数は未定義でなければなりません!! このコードが削除された理由を誰か説明できますか?