Search code examples
clangclang++llvm-clangllvm-ir

CLang++ generating spurious vars in LLVM_IR


Please consider the following program:

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

Compile to LLVM_IR: clang++ -S -emit-llvm test.cpp

Looking at the IR, the function main is defined as so:

; 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
}

We can see that %2 is the allocation of our test variable, loading 17 into it, and %3 uses that variable as the funcition's return value (in keep with the code as we wrote it). However, we see that %1 defines another int sized variable, and initializes it to 0, despite never using it. This extra variable is nowhere to be seen in the C++ source.

I should note that I see the same being generated when I compile using clang rather than clang++.

What is this extra variable?


Solution

  • I assume you are using an old version of clang. In the new version ( I mean v7.0 and later), value names are printed by default. But to be explicitly print, you might you -fno-discard-value-names. With this option you'll get the following 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
    }
    

    Now it is quiet clear where store 0 comes from. In an unoptimized code, the compiler initializes the retval to 0.