Prerequisites for the LICM pass

Hello,

I am currently in the process of understanding what are the loop-invariant code motion (LICM) capabilities of the LLVM optimizer. Right now I am working with a very simple example:

int f() {
int a = 0;
int x = 5;
for (int i = 0; i < 10; i++) {
a += x*x;
}
return a;
}

My intuition would be that applying the loop-invariant code motion pass alone to this piece of code would store xx in a temp and then use that in the loop, instead of computing xx for every iteration. However, this doesn’t happen for unoptimized clang-generated code (attached), and after inspecting the LICM implementation and adding debug prints I managed to understand why.

Of course, in this simple example the entire result can be precomputed using constant propagation and similar techniques - which happens at any level of optimization with clang. However, I was hoping that I could still apply LICM individually and see its transformations in action.

My question is thus: Does LICM assume the IR it operates on has already been transformed by other passes (apart from the ones listed as dependencies)? And if yes, is there a place where I can find information on the preferred pass scheduling for this case? I tried searching but didn’t manage to find anything.

Thank you in advance,
Paul

singleNest.bc (2.01 KB)

My question is thus: Does LICM assume the IR it operates on has already been

transformed by other passes (apart from the ones listed as dependencies)? And if

yes, is there a place where I can find information on the preferred pass scheduling

for this case? I tried searching but didn’t manage to find anything.

I think right place for you to look into is PassManager.

You can check when LICM is getting schedule.

LICM is an independent pass, it can take transformed input from earlier passes.

Sometime transformation by earlier passes helps LICM to work.

Hope it helps.

Regards,

Ashutosh