[all-commits] [llvm/llvm-project] 9a7286: [SCEV] Help getLoopInvariantExitCondDuringFirstIte...
Max Kazantsev via All-commits
all-commits at lists.llvm.org
Wed Dec 21 03:12:31 PST 2022
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 9a7286b61f61b78db1197fdedcaaa4cac1b04fe3
https://github.com/llvm/llvm-project/commit/9a7286b61f61b78db1197fdedcaaa4cac1b04fe3
Author: Max Kazantsev <mkazantsev at azul.com>
Date: 2022-12-21 (Wed, 21 Dec 2022)
Changed paths:
M llvm/include/llvm/Analysis/ScalarEvolution.h
M llvm/lib/Analysis/ScalarEvolution.cpp
M llvm/test/Transforms/IndVarSimplify/X86/pr59615.ll
Log Message:
-----------
[SCEV] Help getLoopInvariantExitCondDuringFirstIterations deal with complex `umin` exit counts. PR59615
Recent improvements in symbolic exit count computation revealed some problems with
SCEV's ability to find invariant predicate during first iterations. Ultimately it is based on its
ability to prove some facts for value on the last iteration. This last value, when it includes
`umin` as part of exit count, isn't always simplified enough. The motivating example is following:
https://github.com/llvm/llvm-project/issues/59615
Could not prove:
```
Pred = 36, LHS = (-1 + (-1 * (2147483645 umin (-1 + %var)<nsw>))<nsw> + %var), RHS = %var
FoundPred = 36, FoundLHS = {1,+,1}<nuw><nsw><%bb3>, FoundRHS = %var
```
Can prove:
```
Pred = 36, LHS = (-1 + (-1 * (-1 + %var)<nsw>)<nsw> + %var), RHS = %var
FoundPred = 36, FoundLHS = {1,+,1}<nuw><nsw><%bb3>, FoundRHS = %var
```
Here ` (2147483645 umin (-1 + %var)<nsw>)` is exit count composed of two parts from
two different exits: `2147483645 ` and `(-1 + %var)<nsw>`. When it was only one (latter)
analyzeable exit, for it everything was easily provable. Unfortunately, in general case `umin`
in one of `add`'s operands doesn't guarantee that the whole sum reduces, especially in presence
of negative steps and lack of `nuw`. I don't think there is a generic legal way to somehow play
around this `umin`.
So the ad-hoc solution is following: if we failed to find an equivalent predicate that is invariant
during first `MaxIter` iterations, and `MaxIter = umin(a, b, c...)`, try to find solution for at least one
of `a`, `b`, `c`... Because they all are `uge` than `MaxIter`, whatever is true during `a (b, c)` iterations
is also true during `MaxIter` iterations.
Differential Revision: https://reviews.llvm.org/D140456
Reviewed By: nikic
More information about the All-commits
mailing list