aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
AgeCommit message (Collapse)AuthorFilesLines
2023-12-05[SCEV] Use or disjoint flag (#74467)Nikita Popov1-5/+2
Use the disjoint flag to convert or to add instead of calling the haveNoCommonBitsSet() ValueTracking query. This ensures that we can reliably undo add -> or canonicalization, even in cases where the necessary information has been lost or is too complex to reinfer in SCEV. I have updated the bulk of the test coverage to add the necessary disjoint flags in advance.
2023-11-17[SCEV][LV] Invalidate LCSSA exit phis more thoroughly (#69909)Nikita Popov1-0/+38
This an alternative to #69886. The basic problem is that SCEV can look through trivial LCSSA phis. When the phi node later becomes non-trivial, we do invalidate it, but this doesn't catch uses that are not covered by the IR use-def walk, such as those in BECounts. Fix this by adding a special invalidation method for LCSSA phis, which will also invalidate all the SCEVUnknowns/SCEVAddRecExprs used by the LCSSA phi node and defined in the loop. We should probably also use this invalidation method in other places that add predecessors to exit blocks, such as loop unrolling and loop peeling. Fixes #69097. Fixes #66616. Fixes #63970.
2023-11-08[SCEV] Support larger than 64-bit types in ashr(add(shl(x, n), c), m) (#71600)Björn Pettersson1-2/+1
In commit 5a9a02f67b771fb2edcf06 scalar evolution got support for computing SCEV:s for (ashr(add(shl(x, n), c), m)) constructs. The code however used APInt::getZExtValue without first checking that the APInt would fit inside an uint64_t. When for example using 128-bit types we ended up in assertion failures (or maybe miscompiles in non-assert builds). This patch simply avoid converting from APInt to uint64_t when creating the truncated constant. We can just truncate the APInt instead.
2023-11-07[SCEV] Extend isImpliedCondOperandsViaRanges to independent predicates (#71110)Philip Reames1-4/+8
As far as I can tell, there's nothing in this code which actually assumes the two predicates in (FoundLHS FoundPred FoundRHS) => (LHS Pred RHS) are the same. Noticed while investigating something else, this is purely an oppurtunistic optimization while I'm looking at the code. Unfortunately, this doesn't solve my original problem. :)
2023-11-06[SCEV] Remove mul handling from BuildConstantFromSCEV()Nikita Popov1-12/+1
We can't support this once mul constant expressions are removed, and this is not useful in any practical sense (as this code is primarily intended for GEP expressions).
2023-11-03[SCEV] Remove newline after predicates in dumpNikita Popov1-2/+1
update_analyze_test_checks.py will now insert check lines for empty lines, which means that all the existing test coverage will have a spurious change to check for the newline after "Predicates:". I don't think we actually want to have that newline, so drop it before it gets into more test coverage.
2023-10-31[SCEV] Fix incorrect NUW inference (#70521)Daniil Suchkov1-0/+5
This patch fixes a miscompile in LSR caused by incorrect inference of NUW flag for AddRec: we shouldn't infer no-wrap flags based on a comparison which doesn't fully control the loop exit.
2023-10-31[SCEV] Fix "quick and dirty" difference that could lead to assert (#70688)Danila Malyutin1-5/+8
The old algorithm would remove all operands matching %step SCEV when it intended to only remove a single one. This lead to assert when SCEVAddExpr was of the form %step + %step and potential miscompiles in similar cases. Such SCEVs could be created when construction reached depth thresholds. Fixes #70348
2023-10-24[ADT] Rename llvm::erase_value to llvm::erase (NFC) (#70156)Kazu Hirata1-2/+2
C++20 comes with std::erase to erase a value from std::vector. This patch renames llvm::erase_value to llvm::erase for consistency with C++20. We could make llvm::erase more similar to std::erase by having it return the number of elements removed, but I'm not doing that for now because nobody seems to care about that in our code base. Since there are only 50 occurrences of erase_value in our code base, this patch replaces all of them with llvm::erase and deprecates llvm::erase_value.
2023-10-16Revert "[ValueTracking] Remove by-ref computeKnownBits() overloads (NFC)"Nikita Popov1-2/+3
This reverts commit b5743d4798b250506965e07ebab806a3c2d767cc. This causes some minor compile-time impact. Revert for now, better to do the change more gradually.
2023-10-16[ValueTracking] Remove by-ref computeKnownBits() overloads (NFC)Nikita Popov1-3/+2
Remove the old overloads that accept KnownBits by reference, in favor of those that return it by value.
2023-10-10[ValueTracking] Use SimplifyQuery in haveNoCommonBitsSet() (NFC)Nikita Popov1-2/+2
Pass SimplifyQuery instead of unpacked list of arguments.
2023-10-10[SCEV] Make invalidation in SCEVCallbackVH more thorough (#68316)Nikita Popov1-20/+1
When a SCEVCallbackVH is RAUWed, we currently do a def-use walk and remove dependent instructions from the ValueExprMap. However, unlike SCEVs usual invalidation, this does not forget memoized values. The end result is that we might end up removing a SCEVUnknown from the map, while that expression still has users. Due to that, we may later fail to invalide those expressions. In particular, invalidation of loop dispositions only does something if there is an expression for the value, which would not be the case here. Fix this by using the standard forgetValue() API, instead of rolling a custom variant. Fixes https://github.com/llvm/llvm-project/issues/68285.
2023-10-09Revert "[SCEV] Don't invalidate past dependency-breaking instructions"Nikita Popov1-19/+1
Unforuntately, the assumption underlying this optimization is incorrect for getSCEVAtScope(): A SCEVUnknown instruction with operands that have constant loop exit values can evaluate to a constant, thus creating a dependency from an "always unknown" instruction. Losing this optimization is quite unfortunate, but it doesn't seem like there is any simple workaround for this. Fixes #68260. This reverts commit 3ddd1ffb721dd0ac3faa4a53c76b6904e862b7ab.
2023-10-09[SCEV] Don't require positive BTC when non-zero is sufficientNikita Popov1-1/+1
The only thing we care about here is that we don't exit on the first iteration. Whether the BTC is large enough to overflow the signed integer space is not relevant.
2023-09-29[SCEV] Remove unnecessary cast code (NFC)Nikita Popov1-4/+1
The types should always match here. Possibly this is a leftover from pre-opaque-pointers times.
2023-09-28[SCEV] Remove zext/sext from BuildConstantForSCEVNikita Popov1-13/+3
In preparation for removing these constant expressions.
2023-09-28[SCEV] Work on APInt instead of ConstantExpr (NFC)Nikita Popov1-4/+2
Avoid an unnecessary use of ConstantExpr::getZExt() when APInt::zext() is sufficient.
2023-09-22[Analysis] Use drop_begin (NFC)Kazu Hirata1-2/+1
2023-09-22[SCEV] Require that addrec operands dominate the loopNikita Popov1-2/+2
SCEVExpander currently has special handling for the case where the start or the step of an addrec do not dominate the loop header, which is not used by any lit test. Initially I thought that this is entirely dead code, because addrec operands are required to be loop invariant. However, SCEV currently allows creating an addrec with operands that are loop invariant but defined *after* the loop. This doesn't seem like a useful case to allow, and we don't appear to be using this outside a single easy to adjust unit test.
2023-09-18[SCEV] Fix incorrect nsw inference for multiply of addrec (#66500)Nikita Popov1-9/+19
SCEV currently preserves the nsw flag when performing an nsw multiply of an nsw addrec. While this is legal for nuw, this is not generally the case for nsw. This is because nsw mul does not distribute over nsw add: https://alive2.llvm.org/ce/z/mergCt Instead, we need either both nuw and nsw to be set (https://alive2.llvm.org/ce/z/7wpgGc) or explicitly prove that the distributed multiplications are also nsw (https://alive2.llvm.org/ce/z/wef9su). Fixes https://github.com/llvm/llvm-project/issues/66066.
2023-09-04[SCEV] Fix potentially empty set for unsigned rangesTejas Joshi1-1/+1
The following commit enabled the analysis of ranges for heap allocations: 22ca38da25e19a7c5fcfeb3f22159aba92ec381e The range turns out to be empty in cases such as the one in test (which is [1,1)), leading to an assertion failure. This patch fixes for the same case. Fixes https://github.com/llvm/llvm-project/issues/63856 Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D159160
2023-08-25[SCEV] Compute SCEV for ashr(add(shl(x, n), c), m) instr tripletVedant Paranjape1-23/+55
%x = shl i64 %w, n %y = add i64 %x, c %z = ashr i64 %y, m The above given instruction triplet is seen many times in the generated LLVM IR, but SCEV model is not able to compute the SCEV value of AShr instruction in this case. This patch models the two cases of the above instruction pattern using the following expression: => sext(add(mul(trunc(w), 2^(n-m)), c >> m)) 1) when n = m the expression reduces to sext(add(trunc(w), c >> n)) as n-m=0, and multiplying with 2^0 gives the same result. 2) when n > m the expression works as given above. It also adds several unittest to verify that SCEV is able to compute the value. $ opt sext-add-inreg.ll -passes="print<scalar-evolution>" Comparing the snippets of the result of SCEV analysis: * SCEV of ashr before change ---------------------------- %idxprom = ashr exact i64 %sext, 32 --> %idxprom U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: 8 LoopDispositions: { %for.body: Variant } * SCEV of ashr after change --------------------------- %idxprom = ashr exact i64 %sext, 32 --> {0,+,1}<nuw><nsw><%for.body> U: [0,9) S: [0,9) Exits: 8 LoopDispositions: { %for.body: Computable } LoopDisposition of the given SCEV was LoopVariant before, after adding the new way to model the instruction, the LoopDisposition becomes LoopComputable as it is able to compute the SCEV of the instruction. Differential Revision: https://reviews.llvm.org/D152278
2023-08-22[SCEVExpander] Fix incorrect reuse of more poisonous instructions (PR63763)Nikita Popov1-0/+8
SCEVExpander tries to reuse existing instruction with the same SCEV expression. However, doing this replacement blindly is not safe, because the instruction might be more poisonous. What we were already doing is to drop poison-generating flags on the reused instruction. But this is not the only way that more poison can be introduced. The poison-generating flag might not be directly on the reused instruction, or the poison contribution might come from something like 0 * %var, which folds to 0 but can still introduce poison. This patch fixes the issue in a principled way, by determining which values can contribute poison to the SCEV expression, and then checking whether any additional values can contribute poison to the instruction being reused. Poison-generating flags are dropped if doing that enables reuse. This is a pretty big hammer and does cause some regressions in tests, but less than I would have expected. I wasn't able to come up with a less intrusive fix that still satisfies the correctness requirements. Fixes https://github.com/llvm/llvm-project/issues/63763. Fixes https://github.com/llvm/llvm-project/issues/63926. Fixes https://github.com/llvm/llvm-project/issues/64333. Fixes https://github.com/llvm/llvm-project/issues/63727. Differential Revision: https://reviews.llvm.org/D158181
2023-08-11[SCEV] Move SCEVPoisonCollector outside function (NFC)Nikita Popov1-29/+32
To allow reusing it. Also switch it to store SCEVUnknown rather than SCEV, as only these can produce poison.
2023-08-09[SCEV] Remove unnecessary bitcast (NFC)Nikita Popov1-6/+3
2023-07-31[ScalarEvolution][NFC] Typo fixMaksim Kita1-7/+6
Fix typo in ScalarEvolution public method. Differential Revision: https://reviews.llvm.org/D156621
2023-07-26[ADT] Support iterating size-based integer ranges.Ivan Kosarev1-1/+1
It seems the ranges start with 0 in most cases. Reviewed By: dblaikie, gchatelet Differential Revision: https://reviews.llvm.org/D156135
2023-06-29[NFC] Update stale comment after D154001Arthur Eubanks1-2/+2
2023-06-29[ScalarEvolution] Analyze ranges for heap allocationsArthur Eubanks1-1/+2
Followup to D153624. Allows for better exit count calculations for loops checking heap allocations against null. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D154001
2023-06-29Revert "[ScalarEvolution] Infer loop max trip count from array accesses"Liren Peng1-120/+0
This reverts commit 57e093162e27334730d8ed8f7b25b1b6f65ec8c8.
2023-06-29[SCEV] Make use of non-null pointers for range calculationNikita Popov1-1/+4
We know that certain pointers (e.g. non-extern-weak globals or allocas in default address space) are not null, in which case the lowest address they can be allocated at is their alignment. This allows us to calculate better exit counts for loops that have an additional null check in the guarding condition (see alloca_icmp_null_exit_count). Differential Revision: https://reviews.llvm.org/D153624
2023-06-27[SCEV] Optimize FoldIDVitaly Buka1-8/+2
Improve compile time https://llvm-compile-time-tracker.com/compare.php?from=773e5dfbc6bf4d4c5be568a039661e9baad80d15&to=7ba15f3a4b59181110e73dc397a9fe56165a2b73&stat=instructions:u Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D144335
2023-06-26[SCEV] Print block dispositions on mismatch (NFC)Nikita Popov1-11/+31
2023-06-25[llvm] Add missing StringExtras.h includesElliot Goodrich1-0/+1
In preparation for removing the `#include "llvm/ADT/StringExtras.h"` from the header to source file of `llvm/Support/Error.h`, first add in all the missing includes that were previously included transitively through this header.
2023-06-23[SCEV] Use object size for allocas as wellNikita Popov1-5/+5
The object size and alignment based restriction on the possible allocation range also applies to allocas, not just globals, so handle them as well. We shouldn't really need any type restriction here at all, but for now stay conservative.
2023-06-23[SCEV] Store getValue() result in variable (NFC)Nikita Popov1-8/+8
2023-06-22[SCEV] Don't store AddRec loop when simplifying multiplication of AddRecsDmitry Makogon1-5/+4
When multiplying several AddRecs, we do the following simplification: {A1,+,A2,+,...,+,An}<L> * {B1,+,B2,+,...,+,Bn}<L> = {x=1 in [ sum y=x..2x [ sum z=max(y-x, y-n)..min(x,n) [ choose(x, 2x)*choose(2x-y, x-z)*A_{y-z}*B_z]] ],+,...up to x=2n} This is done iteratively, pair by pair. So if we try to multiply three AddRecs A1, A2, A3, then we'd try to simplify A1 * A2 to A1' and then try to simplify A1' * A3 if A1' is also an AddRec. The transform is only legal if the loops of the two AddRecs are the same. It is checked in the code, but the loop of one of the AddRecs is stored in a local variable and doesn't get updated when we simplify a pair to a new AddRec. In the motivating test the new AddRec A1' was created for a different loop and, as the loop variable didn't get updated, the check for different loops passed and the transform worked for two AddRecs from different loops. So it created a wrong SCEV. And it caused LSR to replace an instruction with another one that had the same SCEV as the incorrectly computed one. Differential Revision: https://reviews.llvm.org/D153254
2023-06-09[SCEV] Try smaller ZExts when using loop guard info.Florian Hahn1-1/+17
If we didn't find the extact ZExt expr in the rewrite map, check if there's an entry for a smaller ZExt we can use instead. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D149786
2023-06-09[SCEV] Remove -verify-scev-maps flagNikita Popov1-11/+0
This is now checked as part of the usual SCEV verification. There is little value in checking this on each lookup. These two maps are strictly synchronized nowadays, which was not the case historically.
2023-05-31[SCEV] Compute AddRec range computations using different type BECountJoshua Cao1-1/+8
Before this patch, we can only use the MaxBECount for an AddRec's range computation if the MaxBECount has <= bit width of the AddRec. This patch reasons that if a MaxBECount has > bit width, and is <= the max value of AddRec's bit width, we can still use the MaxBECount. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D151698
2023-05-31[SCEV][NFC] Refactor range computation for AddRec to pass around APIntJoshua Cao1-34/+39
2023-05-31[SCEV] Fix verification of SCEV multiples.Joshua Cao1-9/+9
2023-05-25Reapply [SCEV] Replace IsAvailableOnEntry with block dispositionNikita Popov1-88/+2
This exposed an issue in SCEVExpander/LCSSA, which has been fixed in D150681. ----- As far as I understand, the IsAvailableOnEntry() function basically implements the same functionality as the properlyDominates() block disposition. The primary difference (apart from a weaker implementation) seems to be in this comment at the top: // Checks if the SCEV S is available at BB. S is considered available at BB // if S can be materialized at BB without introducing a fault. However, I don't really understand why there would be such a requirement. It's my understanding that SCEV explicitly does not care about trapping udiv instructions itself, and it's the job of SCEVExpander's isSafeToExpand() to make sure these don't get expanded if they may trap. Differential Revision: https://reviews.llvm.org/D149344
2023-05-24LLVM_FALLTHROUGH => [[fallthrough]]. NFCCraig Topper1-1/+1
Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D150996
2023-05-22[SCEV] Replace NumTripCountsComputed stat with NumExitCountsComputedDmitry Makogon1-23/+10
This fixes assertion crash in https://github.com/llvm/llvm-project/issues/62380. In the beginning of ScalarEvolution::getBackedgeTakenInfo we make sure that BackedgeTakenCounts contains an entry for the given loop. Then we call computeBackedgeTakenCount which computes the result, and in the end we insert it in the map like so: return BackedgeTakenCounts.find(L)->second = std::move(Result); So we expect that the entry for L still exists in the cache. However, it can get deleted. When it has computed the result, getBackedgeTakenInfo clears all the cached SCEVs that use the AddRecs in the loop. In the crashing example, getBackedgeTakenInfo first gets called on an inner loop, and during this call it gets called again on its parent loop. This recursion happens after the call to computeBackedgeTakenCount. And it happens so that some SCEV from the BTI of the child loop uses an AddRec of the parent loop. So when we successfully compute BTI for the parent loop, we erase already computed result for the child one. The recursion happens in some debug only code that updates statistics. The algorithm itself is non-recursive. Namely the recursive call happens in BackedgeTakenInfo::getExact function and its return value is only used to compare it against SCEVCouldNotCompute. As suggested by nikic I replaced the NumTripCountsComputed and NumTripCountsNotComputed with NumExitCountsComputed and NumExitCountsNotComputed respectively. They are updated during computations made for single exits. It relieves us of the need to compute exact exit count for the loop just to update the named statistic and thus the recursion cannot happen anymore. Differential Revision: https://reviews.llvm.org/D149251
2023-05-19[1/11][IR] Permit load/store/alloca for struct of the same scalable vector typeeopXD1-2/+4
This patch-set aims to simplify the existing RVV segment load/store intrinsics to use a type that represents a tuple of vectors instead. To achieve this, first we need to relax the current limitation for an aggregate type to be a target of load/store/alloca when the aggregate type contains homogeneous scalable vector types. Then to adjust the prolog of an LLVM function during lowering to clang. Finally we re-define the RVV segment load/store intrinsics to use the tuple types. The pull request under the RVV intrinsic specification is riscv-non-isa/rvv-intrinsic-doc#198 --- This is the 1st patch of the patch-set. This patch is originated from D98169. This patch allows aggregate type (StructType) that contains homogeneous scalable vector types to be a target of load/store/alloca. The RFC of this patch was posted in LLVM Discourse. https://discourse.llvm.org/t/rfc-ir-permit-load-store-alloca-for-struct-of-the-same-scalable-vector-type/69527 The main changes in this patch are: Extend `StructLayout::StructSize` from `uint64_t` to `TypeSize` to accommodate an expression of scalable size. Allow `StructType:isSized` to also return true for homogeneous scalable vector types. Let `Type::isScalableTy` return true when `Type` is `StructType` and contains scalable vectors Extra description is added in the LLVM Language Reference Manual on the relaxation of this patch. Authored-by: Hsiangkai Wang <kai.wang@sifive.com> Co-Authored-by: eop Chen <eop.chen@sifive.com> Reviewed By: craig.topper, nikic Differential Revision: https://reviews.llvm.org/D146872
2023-05-17Fix MSVC "result of 32-bit shift implicitly converted to 64 bits" warning. NFC.Simon Pilgrim1-2/+2
2023-05-16[SCEV][NFC-mostly] Remove constant handling in TripMultiple computationJoshua Cao1-21/+4
After landing more precise trip multiples in https://reviews.llvm.org/D149529, the SCEV multiple computation handles constants, so there is no longer any need for special constant handling in getSmallConstantTripMultiple. This patch can improve the multiple of a non-constant SCEV that is huge (>=2**32). This is very rare in practice. Differential Revision: https://reviews.llvm.org/D150541
2023-05-10Revert "[SCEV] Replace IsAvailableOnEntry with block disposition"Manoj Gupta1-2/+88
This reverts commit 103fc0f629aa6218783f65dff0197f257137cade. Causes a clang crash in ChromeOS builds. Testcase provided at D149344.