LoopSimplifyPass and LoopAnalysis work incomplete

I want to write a transformation pass that first needs to detect loops in the form

for (int i = 0; i < b && c; i++)

so a canonical loop where b is a constant and an additional condition.
I need the induction variable i for my transformation. Per function f (with the FunctionAnalysisManager fam) my pass tries to enforce a canonical form and gather loop information:

LoopSimplifyPass lsp;
lsp.run(F, fam);
ScalarEvolution &se = fam.getResult<ScalarEvolutionAnalysis>(F);
auto &loop_info = fam.getResult<LoopAnalysis>(F);

However, for loops like this

int main(int argc, char **argv) {
  int n = atoi(argv[1]);
  for (int i = 7; n != 3 && i < 13; i++) {
    n = atoi(argv[1]);
    printf("%d\n", i);
  }
}

the Loop Analysis neither detects an induction variable, nor is it in canonical form (only in loop-simplify-form). If i initialize i with 0 it works flawlessly.
Why doesn’t the loop simplify pass transform this loop to:

int main(int argc, char **argv) {
  int n = atoi(argv[1]);
  for (int i = 0; n != 3 && i < 6; i++) {
    n = atoi(argv[1]);
    printf("%d\n", i + 7);
  }
}

or at least report i as an induction variable?

My pass is registered with
registerPipelineParsingCallback for opt and with registerPipelineEarlySimplificationEPCallback for clang.

There are additional passes that normalize loops other than LoopSimplifyPass, including loop rotation, LCSSA, and IndVarSimplify.

You should not rely on the existence of a specific induction variable, use ScalarEvolution instead.

https://llvm.org/docs/LoopTerminology.html#more-canonical-loops

1 Like

IndVarSimplifyPass is what i am looking for.
It has a run method that takes a loop and additional parameters.
Is there a simple way to manually invoke it in a Function pass?

Thank you very much!

You got the wrong conclusion. I recommend against using Loop::getCanonicalInductionVariable(), Loop::getInductionVariable() or IndVarSimplify. DO use ScalarEvolution SCEV expressions instead. IndVarSimplify has been severely nerfed in Disable IV rewriting by default. See PR10916. · llvm/llvm-project@061d811 · GitHub anyway.

For some background, see e.g. Missed Loop peeling and thus vectorization opportunity - #4 by Meinersbur