Commit Graph

738 Commits

Author SHA1 Message Date
Nikita Popov 68e1ba8188 [SCEV] Fold umin_seq using known predicate
Fold %x umin_seq %y to %x if %x ule %y. This also subsumes the
special handling for constant operands, as if %y is constant this
folds to umin via implied poison reasoning, and if %x is constant
then either %x is not zero and it folds to umin, or it is known
zero, in which case it is ule anything.
2022-05-09 16:35:08 +02:00
Nikita Popov 7dddf12f44 [SCEV] Add more tests for umin_seq with known predicate (NFC) 2022-05-09 16:18:09 +02:00
Nikita Popov 18eaff1510 [ScalarEvolution] Fold %x umin_seq %y if %x cannot be zero
Fold %x umin_seq %y to %x umin %y if %x cannot be zero. They only
differ in semantics for %x==0.

More generally %x *_seq %y folds to %x * %y if %x cannot be the
saturation fold (though currently we only have umin_seq).
2022-05-09 15:11:05 +02:00
Nikita Popov 33f02de5df [ScalarEvolution] Add tests for umin_seq with non-zero operand (NFC) 2022-05-09 15:03:12 +02:00
Nikita Popov 47c559d6c1 [SCEV] Fold umin_seq to umin using implied poison reasoning
Similar to how we convert logical and/or to bitwise and/or, we should
also convert umin_seq to umin based on implied poison reasoning. In
%x umin_seq %y, if %y being poison implies %x being poison, then we
don't need the sequential evaluation: Having %y contribute towards
the result will never make the result more poisonous. An important
corollary of this is that if %y is never poison, we also don't need
the sequential evaluation.

This avoids some of the regressions in D124910.

Differential Revision: https://reviews.llvm.org/D124921
2022-05-05 09:43:49 +02:00
Nikita Popov 2f64a6cf9c [SCEV] Add additional poison implication tests (NFC) 2022-05-04 15:23:39 +02:00
Nikita Popov b62e9f63bb [SCEV] Add poison implication tests for umin_seq (NFC) 2022-05-04 14:47:46 +02:00
Nikita Popov 2929c34da6 [SCEV] Regenerate test checks (NFC) 2022-05-03 17:43:05 +02:00
Roman Lebedev fd20eb55f1
[NFC][SCEV] Tests with modellable pointer `select`s 2022-04-29 02:37:05 +03:00
Dávid Bolvanský fb65aaf0be [NFCI] Fixed missing colon in CHECK directives - part 2 2022-04-03 14:42:59 +02:00
Dávid Bolvanský f02a0a69af [NFCI] Fixed missing colon in CHECK directives 2022-04-03 11:52:38 +02:00
Nikita Popov 57d57b1afd [AAEval] Make compatible with opaque pointers
With opaque pointers, we cannot use the pointer element type to
determine the LocationSize for the AA query. Instead, -aa-eval
tests are now required to have an explicit load or store for any
pointer they want to compute alias results for, and the load/store
types are used to determine the location size.

This may affect ordering of results, and sorting within one result,
as the type is not considered part of the sorted string anymore.

To somewhat minimize the churn, printing still uses faux typed
pointer notation.
2022-03-16 10:02:11 +01:00
Arthur Eubanks b81d5baa0f [test] Use new PM for -aa-eval tests 2022-03-08 14:15:53 -08:00
Arthur Eubanks f909aed671 Revert "[SCEV] Infer ranges for SCC consisting of cycled Phis"
This reverts commit fc539b0004.

Causes miscompiles, see D110620.
2022-03-04 19:52:44 -08:00
Max Kazantsev fc539b0004 [SCEV] Infer ranges for SCC consisting of cycled Phis
Our current strategy of computing ranges of SCEVUnknown Phis was to simply
compute the union of ranges of all its inputs. In order to avoid infinite recursion,
we mark Phis as pending and conservatively return full set for them. As result,
even simplest patterns of cycled phis always have a range of full set.

This patch makes this logic a bit smarter. We basically do the same, but instead
of taking inputs of single Phi we find its strongly connected component (SCC)
and compute the union of all inputs that come into this SCC from outside.

Processing entire SCC together has one more advantage: we can set range for all
of them at once, because the only thing that happens to them is the same value is
being passed between those Phis. So, despite we spend more time analyzing a
single Phi, overall we may save time by not processing other SCC members, so
amortized compile time spent should be approximately the same.

Differential Revision: https://reviews.llvm.org/D110620
Reviewed By: reames
2022-02-17 18:03:52 +07:00
Roman Lebedev ae48af582b
[NFC][SCEV] Recognize umin_seq when operand is zext'ed in zero-check
zext(umin(x,y)) == umin(zext(x),zext(y))
zext(x) == 0  ->  x == 0

While it is not a very likely scenario, we probably should not expect
that instcombine already dropped such a redundant zext,
but handle directly. Moreover, perhaps there was no ZExtInst,
and SCEV somehow managed to  pull out said zext out of the SCEV expression.
2022-02-16 22:16:02 +03:00
Roman Lebedev 3c7d48ed90
[NFC][SCEV] Recognize umin_seq when operand is zext'ed in umin but not in zero-check
zext(umin(x,y)) == umin(zext(x),zext(y))
zext(x) == 0  ->  x == 0

Extra leading zeros do not affect the result of comparison with zero,
nor do they matter for the unsigned min/max,
so we should not be dissuaded when we find a zero-extensions,
but instead we should just skip it.
2022-02-16 22:16:02 +03:00
Roman Lebedev 21c6c43e6f
[NFC][SCEV] Add tests for umin_seq recognition with interfering zext's 2022-02-16 22:16:01 +03:00
Roman Lebedev 65715ac72a
[SCEV] Generalize umin_seq matching
Since we don't greedily flatten `umin_seq(a, umin(b, c))` into `umin_seq(a, b, c)`,
just looking at the operands of the outer-level `umin` is not sufficient,
and we need to recurse into all same-typed `umin`'s.
2022-02-11 21:58:19 +03:00
Roman Lebedev c234809ff8
[SCEV] Recognize `x == 0 ? 0 : umin_seq(..., x, ...) -> umin_seq(x, umin_seq(...))` 2022-02-11 21:58:19 +03:00
Roman Lebedev 281421693b
[SCEV] Recognize `x == 0 ? 0 : umin(..., x, ...) -> umin_seq(x, umin(...))`
That is the canonical expansion for umin_seq,
so we really should roundtrip it.
2022-02-11 21:58:19 +03:00
Roman Lebedev 4d0c0e6cc2
[SCEV] `createNodeForSelectOrPHIInstWithICmpInstCond()`: generalize eq handling
The current logic was: https://alive2.llvm.org/ce/z/j8muXk
but in reality the offset to the Y in the 'true' hand
does not need to exist: https://alive2.llvm.org/ce/z/MNQ7DZ
https://alive2.llvm.org/ce/z/S2pMQD

To catch that, instead of computing the Y's in both
hands and checking their equality, compute Y and C,
and check that C is 0 or 1.
2022-02-11 21:58:19 +03:00
Roman Lebedev bfce0ca203
[NFC][SCEV] Add test more tests for umin_seq recognition 2022-02-11 21:58:18 +03:00
Roman Lebedev 93c93fd08f
[NFC][SCEV] Add some tests for select->umax recognition
Apparently we didn't have any tests for that codepath?
2022-02-11 21:58:18 +03:00
Roman Lebedev 8df8b488e3
[NFC][SCEV] Autogenerate checklines in a test to simplify further updates 2022-02-11 01:21:45 +03:00
Roman Lebedev 9766a0cca0
[SCEV] Recognize `cond ? i1 0 : i1 y` as `umin_seq ~cond, x`
By definition, `umin_seq` has the exact same
poison stopping properties the original `select` had:
https://alive2.llvm.org/ce/z/N6XwV-
2022-02-10 17:42:55 +03:00
Roman Lebedev 418604fd90
[SCEV] Recognize `cond ? i1 x : i1 1` as `~umin_seq cond, ~x`
By definition, `umin_seq` has the exact same
poison stopping properties the original `select` had:
https://alive2.llvm.org/ce/z/aqe9GK
2022-02-10 17:42:55 +03:00
Roman Lebedev 49d9acc242
[SCEV] Recognize logical `or` as `not umin_seq (not, not)`
By definition, `umin_seq` has the exact same
poison stopping properties the original `select` had:
https://alive2.llvm.org/ce/z/MUfbTL
2022-02-10 17:42:55 +03:00
Roman Lebedev 16bc24e7be
[SCEV] Recognize logical `and` as `umin_seq`
By definition, `umin_seq` has the exact same
poison stopping properties the original `select` had:
https://alive2.llvm.org/ce/z/59KuZZ
2022-02-10 17:42:55 +03:00
Roman Lebedev 73990ff8a7
[SCEV] Recognize binary `xor` as bit-wise `add`
https://alive2.llvm.org/ce/z/ULuZxB

We could transparently handle wider bitwidths,
by effectively casting iN to <N x i1> and performing the `add`
bit/element -wise, the expression will be rather large,
so let's not do that for now.
2022-02-10 17:42:55 +03:00
Roman Lebedev 503541fa93
[SCEV] Recognize binary `and` as bit-wise `umin`
https://alive2.llvm.org/ce/z/aKAr94

We could transparently handle wider bitwidths,
by effectively casting iN to <N x i1> and performing the `umin`
bit/element -wise, the expression will be rather large,
so let's not do that for now.
2022-02-10 17:42:54 +03:00
Roman Lebedev e7e0834f07
[SCEV] Recognize binary `or` as bit-wise `umax`
https://alive2.llvm.org/ce/z/SMEaoc

We could transparently handle wider bitwidths,
by effectively casting iN to <N x i1> and performing the `umax`
bit/element -wise, the expression will be rather large,
so let's not do that for now.
2022-02-10 17:42:54 +03:00
Roman Lebedev 0e6e559bf7
[NFC][SCEV] Add some tests with logical operations and whatnot 2022-02-10 17:42:54 +03:00
Arthur Eubanks f72b76cde5 [test] Replace/remove some 'opt -analyze' RUN lines 2022-02-09 15:49:53 -08:00
William S. Moses 99d2582164 [ScalarEvolution] Handle <= and >= in non infinite loops
Extend scalar evolution to handle >= and <= if a loop is known to be finite and the induction variable guards the condition. Specifically, with these assumptions lhs <= rhs is equivalent to lhs < rhs + 1 and lhs >= rhs to lhs > rhs -1.

In the case of lhs <= rhs, this is true since the only case these are not equivalent
is when rhs == unsigned/signed intmax, which would have resulted in an infinite loop.

In the case of lhs >= rhs, this is true since the only case these are not equivalent
is when rhs == unsigned/signed intmin, which would again have resulted in an infinite loop.

Reviewed By: lebedev.ri

Differential Revision: https://reviews.llvm.org/D118090
2022-01-28 17:41:08 -05:00
William S. Moses 0d04c77856 [ScalarEvolution] Mark a loop as finite if in a willreturn function
A limited version of (https://reviews.llvm.org/D118090) that only marks a loop as finite if in a willreturn function.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D118429
2022-01-28 14:17:05 -05:00
Roman Lebedev 8dcba20674
[SCEV] `getSequentialMinMaxExpr()`: relax 2-op umin_seq w/ constant to umin
Currently, `computeExitLimitFromCondFromBinOp()` does that directly.
2022-01-14 17:07:48 +03:00
Roman Lebedev f34742d7c1
[NFC][SCEV] Add test with umin_seq w/ 1op and constant 2022-01-14 17:07:48 +03:00
Roman Lebedev c86a982d7d
[SCEV] `getSequentialMinMaxExpr()`: rewrite deduplication to be fully recursive
Since we don't merge/expand non-sequential umin exprs into umin_seq exprs,
we may have umin_seq(umin(umin_seq())) chain, and the innermost umin_seq
can have duplicate operands still.
2022-01-14 15:42:26 +03:00
Roman Lebedev 2c0c619541
[NFC][SCEV] Add test where it's the innermost umin_seq that has a duplicate operand 2022-01-14 01:15:45 +03:00
Roman Lebedev 993792bd1a
[SCEV] Don't consider umin_seq scev expr to be more complex that ptrtoint scev expr
Let's consider sequential min/max expression family
to be more complex than their non-sequential counterparts,
preserving internal ordering within them.
2022-01-13 23:59:47 +03:00
Roman Lebedev f14b575194
[NFC][SCEV] Add test for umin_seq complexity ordering 2022-01-13 23:59:47 +03:00
Roman Lebedev 5ceb070bbb
[SCEV] `getSequentialMinMaxExpr()`: look into `umin` when deduplicating operands
We could just merge all umin into umin_seq, but that is likely
a pessimization, so don't do that, but pretend that we did
for the purpose of deduplication.
2022-01-11 18:51:57 +03:00
Roman Lebedev b2be7dcf5b
[NFC][SCEV] More tests with operand-wise redundant operands of umin of umin_seq 2022-01-11 18:51:56 +03:00
Roman Lebedev 138d5c750b
[NFC][SCEV] Add more tests for umin_seq with redundant operands 2022-01-11 17:51:51 +03:00
Roman Lebedev 5e16650792
[SCEV] `getSequentialMinMaxExpr()`: keep only the first instance of an operand
Having the same operand more than once doesn't change the outcome here,
neither reduction-wise nor poison-wise.
We must keep the first instance specifically though.
2022-01-11 16:51:53 +03:00
Roman Lebedev 36075942f9
[SCEV] Add test for umin_seq with duplicate operands 2022-01-11 16:51:52 +03:00
Roman Lebedev 76a0abbc13
[SCEV] Reenable umin_seq support and fix the `computeSCEVAtScope()`
This reverts commit f62f47f5e1.
2022-01-11 16:03:35 +03:00
Roman Lebedev e0772cf00f
[NFC][SCEV] Add reproducers for umin_seq crashes
As reported in https://reviews.llvm.org/D116766#3233042
2022-01-11 16:03:35 +03:00
Philip Reames f62f47f5e1 Partial revert of 82fb4f4
Two crashes have been reported.  This change disables the new logic while leaving the new node in tree.  Hopefully, that's enough to allow investigation without breakage while avoiding massive churn.
2022-01-10 18:18:34 -08:00