CLang++ 在 LLVM_IR 中生成虚假变量

CLang++ generating spurious vars in LLVM_IR

请考虑以下方案:

int main() {
    int test = 17;
    return test;
}

编译为 LLVM_IR:clang++ -S -emit-llvm test.cpp

查看IR,函数main定义如下:

; Function Attrs: noinline norecurse nounwind optnone uwtable
define dso_local i32 @main() #0 {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  store i32 17, i32* %2, align 4
  %3 = load i32, i32* %2, align 4
  ret i32 %3
}

我们可以看到%2是我们test变量的分配,加载17进去,%3使用那个变量作为函数的return 值(与我们编写的代码保持一致)。然而,我们看到 %1 定义了另一个 int 大小的变量,并将其初始化为 0,尽管从未使用过它。这个额外的变量在 C++ 源代码中是看不到的。

我应该注意到,当我使用 clang 而不是 clang++ 编译时,我看到生成了相同的内容。

这个额外的变量是什么?

我假设您使用的是旧版本的 clang。在新版本中(我指的是 v7.0 及更高版本),默认打印值名称。但要明确打印,您可能 -fno-discard-value-names。使用此选项,您将获得以下 IR:

define dso_local i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  %test = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  store i32 17, i32* %test, align 4
  %0 = load i32, i32* %test, align 4
  ret i32 %0
}

现在很清楚 store 0 的来源了。在未优化的代码中,编译器将 retval 初始化为 0