<div dir="ltr">Hey LLVMDev,<div><br></div><div>I'm working on a ModulePass that uses ScalarEvolution along with several other analyses.  After some debugging, it looks to me like ScalarEvolutionWrapperPass does not handle memory correctly for this case.  Here's my current understanding of the problem.</div><div><br></div><div>ScalarEvolutionWrapperPass maintains a unique_ptr to a ScalarEvolution.  Calling getSE() dereferences this pointer.  Meanwhile runOnFunction() resets the pointer to point to a new ScalarEvolution.  As a result, runOnFunction destructs and frees any ScalarEvolution the unique_ptr pointed to before.</div><div><br></div><div>The ModulePass I'm working on uses ScalarEvolution and several other analysis FunctionPasses, including DominatorTree, LoopInfo, OptimizationRemarkEmitter, and a custom analysis pass I'm working on, which resembles LoopInfo.  To run ScalarEvolution and these other analysis FunctionPasses in a ModulePass, the ModulePass creates lambdas to get the analysis for a particular function, e.g.,</div><div><div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><font face="monospace, monospace">auto GetSE = [this](Function &F) -> ScalarEvolution & {</font></div></div><div><div><font face="monospace, monospace">  return this->getAnalysis<ScalarEvolutionWrapperPass>(F).getSE();</font></div></div><div><div><font face="monospace, monospace">};</font></div></div></blockquote><div><br></div><div>Later, when the ModulePass examines a particular Function, it calls the appropriate lambda to get the analysis for that Function.</div><div><br></div><div>The problem seems to arise when lambdas for other analysis FunctionPasses run after calling the GetSE lambda, e.g., when evaluating a statement like this:</div><div><font face="monospace, monospace"><br></font></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><font face="monospace, monospace">for (Function &F : M)</font></div><div><font face="monospace, monospace">  Changed |= MyPassImpl(F, GetSE(F), GetDT(F), GetLI(F), GetORE(F), ...).run();</font></div></blockquote><div><br></div><div>It appears that these other analysis FunctionPasses can cause ScalarEvolutionWrapperPass::runOnFunction() to rerun after GetSE() returns a pointer to a ScalarEvolution, which changes the underlying ScalarEvolution object that the wrapper pass points to.  As a result, the pointer originally obtained from GetSE() points to invalid memory, and chaos ensues.  Running valgrind on the "opt -mypass" indicates that the ScalarEvolution object used by MyPassImpl points to freed memory.</div><div><br></div><div>I've been able to work around this problem, but I figured I should raise the issue and see if you might have more insights into this problem.  For example, I'm not totally sure why the other analysis FunctionPasses cause ScalarEvolutionWrapperPass::runOnFunction() to rerun.  I'm also concerned about other analysis FunctionPasses, that might suffer from the same problem.  MemorySSAWrapperPass, for example, uses a unique_ptr similarly to ScalarEvolution.</div><div><br></div><div>Cheers,</div><div>TB</div></div>