dead store elimination with external functions

Here is an llvm ir of a module. It seems that “b1” should be eliminated by dead store elimination. But it did not.

Could anyone explain why and how “b1” can be eliminated?

Thanks,
-Peng

%0 = type { [3 x [1 x i32]] }

declare %0 @external_fcn3(i32, i32, i32, i32, [3 x [1 x i32]]*)

define i32 @f3(i32 %a) readnone {
entry:
%b1 = alloca [3 x [1 x i32]]
%b2 = alloca [3 x [1 x i32]]
%c = alloca %0
%0 = getelementptr [3 x [1 x i32]]* %b1, i32 0, i32 0, i32 0
store i32 0, i32* %0
%1 = getelementptr [3 x [1 x i32]]* %b1, i32 0, i32 1, i32 0
store i32 1, i32* %1
%2 = getelementptr [3 x [1 x i32]]* %b1, i32 0, i32 2, i32 0
store i32 2, i32* %2
%3 = call %0 @external_fcn3(i32 100, i32 200, i32 %a, i32 200, [3 x [1 x i32]]* %b1)
%4 = add i32 %a, 100
%5 = getelementptr [3 x [1 x i32]]* %b2, i32 0, i32 0, i32 0
store i32 3, i32* %5
%6 = getelementptr [3 x [1 x i32]]* %b2, i32 0, i32 1, i32 0
store i32 4, i32* %6
%7 = getelementptr [3 x [1 x i32]]* %b2, i32 0, i32 2, i32 0
store i32 5, i32* %7
%8 = call %0 @external_fcn3(i32 %4, i32 200, i32 %a, i32 200, [3 x [1 x i32]]* %b2)
store %0 %8, %0* %c
%9 = getelementptr %0* %c, i32 0, i32 0, i32 %a, i32 0
%10 = load i32* %9
ret i32 %10
}

Here is an llvm ir of a module. It seems that "b1" should be eliminated
by dead store elimination. But it did not.

You're passing b1 as an argument to a function call after the stores:

   %3 = call %0 @external_fcn3(i32 100, i32 200, i32 %a, i32 200, [3 x
[1 x i32]]* %b1)

-K

Hi Peng,

Here is an llvm ir of a module. It seems that "b1" should be eliminated by dead
store elimination. But it did not.

Could anyone explain why and how "b1" can be eliminated?

Thanks,
-Peng

%0 = type { [3 x [1 x i32]] }

declare %0 @external_fcn3(i32, i32, i32, i32, [3 x [1 x i32]]*)

define i32 @f3(i32 %a) readnone {
entry:
   %b1 = alloca [3 x [1 x i32]]
   %b2 = alloca [3 x [1 x i32]]
   %c = alloca %0
   %0 = getelementptr [3 x [1 x i32]]* %b1, i32 0, i32 0, i32 0
   store i32 0, i32* %0
   %1 = getelementptr [3 x [1 x i32]]* %b1, i32 0, i32 1, i32 0
   store i32 1, i32* %1
   %2 = getelementptr [3 x [1 x i32]]* %b1, i32 0, i32 2, i32 0
   store i32 2, i32* %2
   %3 = call %0 @external_fcn3(i32 100, i32 200, i32 %a, i32 200, [3 x [1 x
i32]]* %b1)

here %b1 is passed to external_fcn3, thus %b1 can't be eliminated.

Ciao, Duncan.

Maybe I should say b2 should be eliminated.

Since b1 and b2 are same type and b1 is not used any more after the function call, b2 can be replaced by b1. This will save an alloca.

In my test, if the function is not external, b1 is eliminated. But with external function, it did not.

Since the ir is generated, I cannot manually update b2 with b1. I would like the optim pass do it.

That cannot be proven. The address in b1 may have escaped.

-K