Open bjope opened 6 months ago
I suspect the issue here is nowrap flags on one of the AddRecs: either we're setting incorrect flags on an AddRec, or the presence of flags is confusing the trip count computation.
It looks like forgetAllLoops is slightly broken; it doesn't properly throw away old AddRecs.
I suspect the issue here is nowrap flags on one of the AddRecs: either we're setting incorrect flags on an AddRec, or the presence of flags is confusing the trip count computation.
It looks like forgetAllLoops is slightly broken; it doesn't properly throw away old AddRecs.
ScalarEvolution::forgetAllLoops() is doing HasRecMap.clear();
so that map is cleared.
I did however find some other data structure that I'm not sure if/when they are being cleared: LoopPropertiesCache, SCEVUsers, LoopUsers, UnsignedWrapViaInductionTried, SignedWrapViaInductionTried
I think that we should clear UnsignedWrapViaInductionTried, SignedWrapViaInductionTried in forgetAllLoops(), given that we do not use forgetMemoizedResults when doing forgetAllLoops(). I think that those maps would be cleared if doing forgetLoop on one loop at a time.
Not sure about the rest. I can't for example see that LoopUsers is cleared anywhere. So only way to get things removed from that map is to invalidate ScalarEvolution.
Hi,
I'm hitting on the same issue during IndVarSimplify
with origin/main
. It seems when a SCEVConstant
is put in a ExitLimit.ExactNotTaken
it won't be invalidated by SE->forgetValue(UseInst)
in SimplifyIndVar
. computeBackedgeTakenCount
ignores SCEVConstant
purposely.
I can get something that "works" by removing the if(!isa<ConstantSCEV>)
and adding a registerUser(EL.ExactNotTaken, getSCEV(ExitCond))
in computeExitLimitFromICmp
. Of course it's too hacky to be relevant.
BTW the following test case fails:
opt -S -passes='loop(indvars)' -verify-scev llvm/test/Transforms/IndVarSimplify/pr55689.ll
Given this input
when running
opt -passes="print<scalar-evolution>,no-op-loop,print<scalar-evolution>,verify<scalar-evolution>" -o /dev/null
the first print says:and then the second one says:
So we can for example see that Exsits has changed for
%phi3
and%step.3
, and the max backedge-taken counts for %for.cond3 goes from 14 to 13.Then the verification complains:
Some things that I've noticed: 1) no-op-loop will result in running LoopSimplify, which will add a pre-header for the for.cond1 loop. This should not really change anything from the perspective of SCEV, but I figure we do forget some SCEV values/dispositions in the process.
2) If modifying LoopSimplify like this
we can see that doing forgetAllLoops() and then re-calculating SCEV gives the same behavior. So this is not really related to LoopSimplify or the pass manager. But it seems a bit weird that the SCEV result changes after doing forgetAllLoops!?!?
3) When doing the second
print<scalar-evolution>
the function ScalarEvolution::howManyGreaterThans is involved. But it isn't involved the first time.4) ( @fhahn : Bi-secting pointed at this starting to happen after commit 7019624ee124 "[SCEV] Strengthen nowrap flags via ranges for ARs on construction.". But maybe that is a co-incidence. )