Can't get an induction variable by getInductionVariable API

Dear All

I have a question about the getInductionVariable API.
I was trying to get an induction variable (indvar) in the code below using the getInductionVariable API (LoopInfo class).

C file

void test(int val) {
int sum = 0, i = 0;

for (i = 0; i < val; i++) {
sum += i;

}

}

IR (with mem2reg pass)

; Function Attrs: nounwind
define dso_local void @test(i32 %0) #0 {
br label %2
2: ; preds = %6, %1
%.01 = phi i32 [ 0, %1 ], [ %5, %6 ]
%.0 = phi i32 [ 0, %1 ], [ %7, %6 ]
%3 = icmp slt i32 %.0, %0
br i1 %3, label %4, label %8 ← Why don’t check this BranchInst ?
4: ; preds = %2
%5 = add nsw i32 %.01, %.0
br label %6
6: ; preds = %4
%7 = add nsw i32 %.0, 1
br label %2 ← checked it whether isCondition by getLatchCmpInst API(called by getInductionVariable API)
8: ; preds = %2
ret void
}

Then I got null (no indvar) because BranchInst’s number of operands was less than 2.(red block).

A CmpInst(compare with induction variable) is contained in the header of the loop.
But the getInductionVariable API checks only in a latch block(contains a branch back to the header of the loop)
is there a missing case that contains CmpInst in the header?

And if I use the getCanonicalInductionVariable API, I can get the variable ‘i’(%. 01) as an indvar.

I checked the code implementing getInductionVariable and getCanonicalInductionVariable.
It seems that indvar and canonical indvar differ only in the starting number (0 or none).
Why not use the same way to detect the indvar between getInductionVariable and getCanonicalInductionVariable.

BR
ZIN

Hi,

Thanks, I’ll check it out.

2020년 10월 23일 (금) 오후 5:49, Florian Hahn <florian_hahn@apple.com>님이 작성:

If this particular API is too restrictive for your use case, you can also consider the following two approaches:

  1. Walk the phi nodes in the header, and ask SCEV for the node representing each. For any which is an AddRec within the current loop, you’ve found an induction variable.
  2. If you’re using IVs to analyze loop behavior, consider using the exit count APIs instead. They handle all the complexities of multi exit loops which can be tedious to get right by hand.

Philip

p.s. The point Florian made about rotated loops is also spot on.