Reputation: 12174
I'm learning LLVM IR through Clang and found out that a C function like:
int inc(int x)
{
return x+1;
}
Generates this IR (optimizations are turned off):
define i32 @inc(i32 %x) #0 {
entry:
%x.addr = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
%0 = load i32, i32* %x.addr, align 4
%add = add nsw i32 %0, 1
ret i32 %add
}
My question is to know exactly why it allocates in the first place a local (x.addr) store, then load from it.
Upvotes: 2
Views: 318
Reputation: 273546
Because this is unoptimized code. Clang (the frontend) doesn't spend much (almost any?) time figuring out how to make the code it emits optimal. It leaves it to the backend optimizations (LLVM). Local variables are "on the stack" in unoptimized mode, which means the alloca
. It also means that x
has an addressable location, which may or may not be used later. Without optimizations the compiler does not know whether it's going to be used, so it conservatively generates an addresable location anyway.
int inc(int x)
{
x = x + 1;
int* px = &x;
return x;
}
Now Clang emits:
define i32 @inc(i32 %x) #0 {
entry:
%x.addr = alloca i32, align 4
%px = alloca i32*, align 8
store i32 %x, i32* %x.addr, align 4
%0 = load i32, i32* %x.addr, align 4
%add = add nsw i32 %0, 1
store i32 %add, i32* %x.addr, align 4
store i32* %x.addr, i32** %px, align 8
%1 = load i32, i32* %x.addr, align 4
ret i32 %1
}
See the address %x.addr
being used for the pointer now?
Of course if you run this through the optimizer you get:
define i32 @inc(i32 %x) #0 {
entry:
%add = add nsw i32 %x, 1
ret i32 %add
}
Which is probably more in line with what you'd expect from a compiler.
Upvotes: 7