aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
AgeCommit message (Collapse)AuthorFilesLines
2023-02-22[SCEV] Remove unused alignof/offsetof print special cases (NFC)Nikita Popov1-58/+0
These shouldn't really reach SCEV without being folded away first, and we don't have any tests that hit these cases. The sizeof case does occur with scalable types.
2023-02-20Revert "[AssumptionCache] caches @llvm.experimental.guard's"Max Kazantsev1-8/+43
This reverts commit f9599bbc7a3f831e1793a549d8a7a19265f3e504. For some reason it caused us a huge compile time regression in downstream workloads. Not sure whether the source of it is in upstream code ir not. Temporarily reverting until investigated. Differential Revision: https://reviews.llvm.org/D142330
2023-02-20[SCEV] Canonicalize ext(min/max(x, y)) to min/max(ext(x), ext(y))Max Kazantsev1-0/+35
I stumbled over this while trying to improve our exit count work. These expressions are equivalent for complementary signed/unsigned ext and min/max (including umin_seq), but they are not canonicalized and SCEV cannot recognize them as the same. The benefit of this canonicalization is that SCEV can prove some new equivalences which it coudln't prove because of different forms. There is 1 test where trip count seems pessimized, I could not directly figure out why, but it just seems an unrelated issue that we can fix. Other changes seem neutral or positive to me. Differential Revision: https://reviews.llvm.org/D141481 Reviewed By: nikic
2023-02-20[SCEV] Support umin/smin in SCEVLoopGuardRewriterMax Kazantsev1-0/+14
Adds support for these SCEVs to cover more cases. Differential Revision: https://reviews.llvm.org/D143259 Reviewed By: dmakogon, fhahn
2023-02-19Use APInt::count{l,r}_{zero,one} (NFC)Kazu Hirata1-7/+7
2023-02-07[SCEV] Support sext in SCEVLoopGuardRewriterMax Kazantsev1-3/+8
There is no particular reason why it's not supported, and it is useful. Differential Revision: https://reviews.llvm.org/D143257 Reviewed By: fhahn
2023-02-07[SCEV][NFC] Remove check for rewriteable typesMax Kazantsev1-4/+0
I guess its only reason to exist is potential CT optimization, otherwise it is just creating cohesion between this code and rewriter internals. We plan to extend the rewriter. I'd rather not have this cohesion, unless there is a serious reason to have it. Differential Revision: https://reviews.llvm.org/D143246
2023-02-01[SCEV] Use fact that B >u 0 for A <u B in applyLoopGuards.Florian Hahn1-2/+6
If LHS <u RHS holds, RHS should be guaranteed to be > 0. By using using 'umax(RHS, 1) -1' instead of 'RHS - 1' the results in applyLoopGuards can be improved in some cases. Note that the TODO for the tests mentioned the max BTC being 11, but unless I am missing something 10 should be correct. https://alive2.llvm.org/ce/z/44nP7F Reviewed By: mkazantsev Differential Revision: https://reviews.llvm.org/D126503
2023-01-24[AssumptionCache] caches @llvm.experimental.guard'sJoshua Cao1-43/+8
As discussed in https://github.com/llvm/llvm-project/issues/59901 This change is not NFC. There is one SCEV and EarlyCSE test that have an improved analysis/optimization case. Rest of the tests are not failing. I've mostly only added cleanup to SCEV since that is where this issue started. As a follow up, I believe there is more cleanup opportunity in SCEV and other affected passes. There could be cases where there are missed registerAssumption of guards, but this case is not so bad because there will be no miscompilation. AssumptionCacheTracker should take care of deleted guards. Differential Revision: https://reviews.llvm.org/D142330
2023-01-22[SCEV] `getRangeRefIter()`: don't forget to recurse into castsRoman Lebedev1-6/+4
I'm not really sure the problem can be nicely exposed via a lit test, since we don't give up on range calculation for deeply nested ranges, but if i add an assertion that those opcodes are never encountered, the assertion fails in a number of existing tests. In reality, the iterative approach is still pretty partial: 1. `Seen` should not be there. We want the last instance of expression, not the first one 2. There should be a check that `getRangeRefIter()` does not self-recurse
2023-01-22[NFC][SCEV] Reflow `getRangeRefIter()` into an exhaustive switchRoman Lebedev1-17/+37
And, this shows a bug in the original code: why do we not recurse into casts? If i add an assertion that those opcodes are never encountered, the assertion fails in a number of existing tests.
2023-01-22[NFC][SCEV] `GetMinTrailingZerosImpl()`: deduplicate handlingRoman Lebedev1-6/+5
`scPtrToInt` recieves same treatment as normal n-ary ops.
2023-01-22[NFC][SCEV] Reflow `GetMinTrailingZerosImpl()` into an exhaustive switchRoman Lebedev1-22/+31
2023-01-22[NFC][SCEV] Reflow `impliesPoison()` into an exhaustive switchRoman Lebedev1-4/+54
2023-01-22[NFC][SCEV] Reflow `computeSCEVAtScope()` into an exhaustive switchRoman Lebedev1-6/+20
2023-01-22[NFC][SCEV] `getBlockDisposition()`: deduplicate handlingRoman Lebedev1-19/+6
2023-01-22[NFC][SCEV] `getLoopDisposition()`: deduplicate handlingRoman Lebedev1-17/+6
2023-01-22[NFC][SCEV] `computeSCEVAtScope()`: deduplicate handlingRoman Lebedev1-35/+26
Casts and udiv get the exactly the same handling as n-ary, there is no point in special-handling anything.
2023-01-22[NFC][SCEV] `CompareSCEVComplexity`: deduplicate handlingRoman Lebedev1-54/+12
For all but unknown/constant/recurrences, the handling is identical, there is no point in special-casing anything.
2023-01-22[NFC][SCEV] `createNodeForSelectOrPHIInstWithICmpInstCond()`: directly take ↵Roman Lebedev1-10/+10
`Type`, not `Instruction` We don't use the `Instruction` itself, only it's type anyways.
2023-01-22[NFC][SCEV] `createNodeForSelectOrPHIInstWithICmpInstCond()`: return optionalRoman Lebedev1-7/+10
We only want about the result if it succeeds, and don't want `SCEVUnknown`.
2023-01-22[NFC][SCEV] Reflow `getRangeRef()` into an exhaustive switchRoman Lebedev1-68/+79
2023-01-21[NFC][SCEV] `computeSCEVAtScope()`: reserve vector size upfrontRoman Lebedev1-2/+7
2023-01-21[NFC][SCEV] `computeSCEVAtScope()`: `scUnknown`: use early-returnsRoman Lebedev1-99/+100
2023-01-21[NFC][SCEV] Reflow `computeSCEVAtScope()` into an exhaustive switchRoman Lebedev1-95/+106
Otherwise instead of a compile-time error that you forgot to modify it, you'd get a run-time error, which happened every time i've added new expr. This is completely NFC, there are no other changes here.
2023-01-21[NFC][SCEV] `computeSCEVAtScope()`: clang-formatRoman Lebedev1-15/+19
2023-01-13[SCEV] Support all Min/Max SCEVs for GetMinTrailingZerosJoshua Cao1-27/+5
There is already support for U/SMax. No reason why Min and SequentialMin should not be supported. NFC: code in GetMinTrailingZeroes is copied for a couple node types. Refactor them into a single code block. Differential Revision: https://reviews.llvm.org/D141568
2023-01-09[SCEV] Add llvm.experimental.guard conditions to applyLoopGuards()Joshua Cao1-4/+14
Conditions for dominating branches and llvm.assumes are already collected. This also adds conditions from guards. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D141243
2022-12-28[SCEV] Properly clean up duplicated FoldCacheUser ID entries.Florian Hahn1-10/+27
The current code did not properly handled duplicated FoldCacheUser ID entries when overwriting an existing entry in the FoldCache. This triggered verification failures reported by @uabelho and #59721. The patch fixes that by removing stale IDs when overwriting an existing entry in the cache. Fixes #59721.
2022-12-21[SCEV] Help getLoopInvariantExitCondDuringFirstIterations deal with complex ↵Max Kazantsev1-0/+20
`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
2022-12-19[ValueTracking] Consider single poison operands in propgatesPoison.Florian Hahn1-2/+3
This patch updates propgatesPoison to take a Use as argument and propagatesPoison now returns true if the passed in operand causes the user to yield poison if the operand is poison This allows propagating poison if the condition of a select is poison. This helps improve results for programUndefinedIfUndefOrPoison. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D111643
2022-12-16std::optional::value => operator*/operator->Fangrui Song1-5/+4
value() has undesired exception checking semantics and calls __throw_bad_optional_access in libc++. Moreover, the API is unavailable without _LIBCPP_NO_EXCEPTIONS on older Mach-O platforms (see _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS). This commit fixes LLVMAnalysis and its dependencies.
2022-12-16[SCEV] Add SCEV::operands() method (NFC)Nikita Popov1-26/+29
Add an operands() method on SCEV, which forwards to the operands() method of individual SCEV expressions.
2022-12-16[SCEV] Return ArrayRef for SCEV operands() (NFC)Nikita Popov1-37/+29
Use a consistent type for the operands() methods of different SCEV types. Also make the API consistent by only providing operands(), rather than also providin op_begin() and op_end() for some of them.
2022-12-14[SCEV] Cache folded SExt SCEV expressions.Florian Hahn1-0/+25
Use FoldID to cache SignExtendExprs that get folded to a different SCEV. Depends on D137505. Reviewed By: mkazantsev Differential Revision: https://reviews.llvm.org/D137849
2022-12-10Don't include None.h (NFC)Kazu Hirata1-1/+0
I've converted all known uses of None to std::nullopt, so we no longer need to include None.h. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-09[SCEV] Cache ZExt SCEV expressions.Florian Hahn1-0/+61
When creating SCEV expressions for ZExt, there's quite a bit of reasoning done and in many places the reasoning in turn will try to create new SCEVs for other ZExts. This can have a huge compile-time impact. The attached test from #58402 takes an excessive amount of compile time; without the patch, the test doesn't complete in 1500+ seconds, but with the patch it completes in 1 second. To speed up this case, cache created ZExt expressions for given (SCEV, Ty) pairs. Caching just ZExts is relatively straight-forward, but it might make sense to extend it to other expressions in the future. This has a slight positive impact on CTMark: * O3: -0.03% * ReleaseThinLTO: -0.03% * ReleaseLTO-g: 0.00% https://llvm-compile-time-tracker.com/compare.php?from=bf9de7464946c65f488fe86ea61bfdecb8c654c1&to=5ac0108553992fb3d58bc27b1518e8cf06658a32&stat=instructions:u The patch also improves compile-time for some internal real-world workloads where time spent in SCEV goes from ~300 seconds to ~3 seconds. There are a few cases where computing & caching the result earlier may return more pessimistic results, but the compile-time savings seem to outweigh that. Fixes #58402. Reviewed By: mkazantsev Differential Revision: https://reviews.llvm.org/D137505
2022-12-08[SCEV] Convert Optional to std::optionalKrzysztof Parzyszek1-51/+53
2022-12-08[SCEV] Compute symbolic exit count for 'and' conditionsMax Kazantsev1-5/+14
If loop exits by condition like `A < B && X < Y`, and at least one of symbolic max exit counts for these conditions is known, it can be used as estimate of symbolic max exit count for whole branch. If both are known, then we can use their umin as the estimate. Differential Revision: https://reviews.llvm.org/D139403 Reviewed By: nikic
2022-12-08[SCEV] Track SymbolicMaxNotTaken in BECountUsersNikita Popov1-13/+21
2022-12-07[SCEV] Use umin_seq for symbolic max BE countNikita Popov1-1/+1
We were using umin_seq when computing the exact BE count, but not when computing the symbolic max BE count.
2022-12-07[SCEV] Remember blocks for which we know symbolic exit count but not exactMax Kazantsev1-1/+6
The old code didn't bother to memoize blocks for which exact exit count is not known. As result, in situation when exact isn't known but symbolic is known, this info was lost. This patch fixes the situation: now we memoize when symbolic is known (exact always implies symbolic, so this is a strict superset of what was before). Differential Revision: https://reviews.llvm.org/D139515 Reviewed By: nikic
2022-12-07[SCEV][NFC] Sink initialization of SymbolicMaxNotTaken from ExitLimit ↵Max Kazantsev1-39/+56
constructor to its callers Preserves current behavior (always select Exact if known, otherwise select Constant Max). This is the final preparation step before letting each particular computation way to decide how exactly it should be computed. Functional improvement is coming shortly as follow-up. Differential Revision: https://reviews.llvm.org/D139402 Reviewed By: nikic, fhahn
2022-12-06[llvm] Use std::nullopt instead of None in comments (NFC)Kazu Hirata1-1/+1
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-06[SCEV] `MatchBinaryOp()`: try to recognize `or` as `add`-in-disguise (w/ no ↵Roman Lebedev1-26/+29
common bits set) LLVM *loves* to convert `add` of operands with no common bits into an `or`. But SCEV really doesn't deal with `or` that well, so try extra hard to recognize this `or` as an `add`. I believe, previously this wasn't being done because of the recursive of this, but now that the `createSCEV()` is not recursive, this should be fine. Unless this is *too* costly compile-time wise... https://alive2.llvm.org/ce/z/EfapCo
2022-12-05[NFC] Rename variable MaxBECount -> ConstantMaxBECountMax Kazantsev1-9/+10
Just to distinguish it from symbolic max which we plan to compute here as well.
2022-12-04[llvm] Use std::nullopt instead of None in comments (NFC)Kazu Hirata1-10/+10
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-04Compress a few pairs using PointerIntPairsBenjamin Kramer1-16/+7
Use the uniform structured bindings interface where possible. NFCI.
2022-12-02[Analysis] Use std::nullopt instead of None (NFC)Kazu Hirata1-58/+57
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02Use CTAD on llvm::SaveAndRestoreJan Svoboda1-2/+2
Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D139229