Hi all,
I’m writting following LLVM assembly:
; ModuleID = ‘structaccess.ll’
%struct._anon0 = type <{ i32, i32, i32 }>
@s = common global %struct._anon0 zeroinitializer
define arm_aapcscc void @foo() nounwind {
L.entry:
store i32 5, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 0)
store i32 10, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 1)
%0 = load i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 0)
%1 = load i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 1)
%2 = add i32 %0, %1
store i32 %2, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 2)
ret void
}
Using ‘opt’ utility as follows :
opt -O2 structaccess.ll -S -o structaccess-opt.ll
I’ve got following code for structaccess-opt.ll file:
; ModuleID = ‘structaccess.ll’
%struct._anon0 = type <{ i32, i32, i32 }>
@s = common global %struct._anon0 zeroinitializer
define arm_aapcscc void @foo() nounwind {
L.entry:
store i32 5, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 0)
store i32 10, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 1)
%0 = load i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 0)
%1 = add i32 %0, 10
store i32 %1, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 2)
ret void
}
I would have expected constant 5 to be propagated by ‘opt’ to its use and thus LLVM assembly after opt to be :
; ModuleID = ‘structaccess.ll’
%struct._anon0 = type <{ i32, i32, i32 }>
@s = common global %struct._anon0 zeroinitializer
define arm_aapcscc void @foo() nounwind {
L.entry:
store i32 5, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 0)
store i32 10, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 1)
store i32 15, i32* getelementptr inbounds (%struct._anon0* @s, i32 0, i32 2)
ret void
}
Can someone explain me why this is not the case ?
Note that C equivalent would be something like:
struct {
int x, y, z;
} s;
void foo()
{
s.x = 5 ;
s.y = 10 ;
s.z = s.x + s.y ;
}