aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
AgeCommit message (Collapse)AuthorFilesLines
2021-10-03Fixed more warnings in LLVM produced by -Wbitwise-instead-of-logicalDávid Bolvanský1-2/+2
2021-09-09[APInt] Normalize naming on keep constructors / predicate methods.Chris Lattner1-2/+2
This renames the primary methods for creating a zero value to `getZero` instead of `getNullValue` and renames predicates like `isAllOnesValue` to simply `isAllOnes`. This achieves two things: 1) This starts standardizing predicates across the LLVM codebase, following (in this case) ConstantInt. The word "Value" doesn't convey anything of merit, and is missing in some of the other things. 2) Calling an integer "null" doesn't make any sense. The original sin here is mine and I've regretted it for years. This moves us to calling it "zero" instead, which is correct! APInt is widely used and I don't think anyone is keen to take massive source breakage on anything so core, at least not all in one go. As such, this doesn't actually delete any entrypoints, it "soft deprecates" them with a comment. Included in this patch are changes to a bunch of the codebase, but there are more. We should normalize SelectionDAG and other APIs as well, which would make the API change more mechanical. Differential Revision: https://reviews.llvm.org/D109483
2021-06-24[LVI] Remove recursion from getValueForCondition (NFCI)Carl Ritson1-36/+55
Convert getValueForCondition to a worklist model instead of using recursion. In pathological cases getValueForCondition recurses heavily. Stack frames are quite expensive on x86-64, and some operating systems (e.g. Windows) have relatively low stack size limits. Using a worklist avoids potential failures from stack overflow. Differential Revision: https://reviews.llvm.org/D104191
2021-05-15[IR] Add BasicBlock::isEntryBlock() (NFC)Nikita Popov1-1/+1
This is a recurring and somewhat awkward pattern. Add a helper method for it.
2021-05-07[LazyValueInfo] Insert an Overdefined placeholder to prevent infinite recursionPeilin Guo1-10/+8
getValueFromCondition() uses a Visited set to record the intermediate value. However, it uses a postorder way to compute the value first and update the Visited set later. Thus it will be trapped into an infinite recursion if there exists IRs that use no dominated by its def as in this example: %tmp3 = or i1 undef, %tmp4 %tmp4 = or i1 undef, %tmp3 To prevent this, we can insert an Overdefined placeholder into the set before computing the actual value. Reviewed by: nikic Differential Revision: https://reviews.llvm.org/D101273
2021-05-01[LVI] Handle mask not equal zero conditionsNikita Popov1-9/+19
If V & Mask != 0, we know that at least one of the bits in Mask must be set, so the value must be >= the lowest bit in Mask.
2021-04-11[CVP] @llvm.[us]{min,max}() intrinsics handlingRoman Lebedev1-0/+18
If we can tell that either one of the arguments is taken, bypass the intrinsic. Notably, we are indeed fine with non-strict predicate: * UL: https://alive2.llvm.org/ce/z/69qVW9 https://alive2.llvm.org/ce/z/kNFTKf https://alive2.llvm.org/ce/z/AvaPw2 https://alive2.llvm.org/ce/z/oxo53i * UG: https://alive2.llvm.org/ce/z/wxHeGH https://alive2.llvm.org/ce/z/Lf76qx * SL: https://alive2.llvm.org/ce/z/hkeTGS https://alive2.llvm.org/ce/z/eR_b-W * SG: https://alive2.llvm.org/ce/z/wEqRm7 https://alive2.llvm.org/ce/z/FpAsVr Much like with all other comparison handling in CVP, while we could sort-of handle two Value's, at least for plain ICmpInst it does not appear to be worthwhile. This only fires 78 times on test-suite + dt + rs, but we don't canonicalize to these yet. (only SCEV produces them)
2021-04-09For non-null pointer checks, do not descend through out-of-bounds GEPsMomchil Velikov1-1/+1
In LazyValueInfoImpl::isNonNullAtEndOfBlock we populate a set of pointers, known to be non-null at the end of a block (e.g. because we did a load through them). We then infer that any pointer, based on an element of this set is non-null as well ("based" here meaning a non-null pointer is the underlying object). This is incorrect, even if the base pointer was non-null, the value of a GEP, that lacks the inbounds` attribute, may be null. This issue appeared as miscompilation of the following test case: int puts(const char *); typedef struct iter { int *val; } iter_t; static long distance(iter_t first, iter_t last) { long r = 0; for (; first.val != last.val; first.val++) ++r; return r; } int main() { int arr[2] = {0}; iter_t i, j; i.val = arr; j.val = arr + 1; if (distance(i, j) >= 2) puts("failed"); else puts("passed"); } This fixes PR49662. Differential Revision: https://reviews.llvm.org/D99642
2021-04-04[LVI] Don't bail on overdefined value in selectNikita Popov1-10/+0
Even if one of the operands is overdefined, we may still produce a non-overdefined result, e.g. due to a min/max operation. This matches our handling elsewhere, e.g. for binary operators. The slot poisoning comment refers to a much older LVI cache implementation.
2021-04-02[LVI] Use range metadata on intrinsicsNikita Popov1-2/+2
If we don't know how to handle an intrinsic, we should still make use of normal call range metadata.
2021-03-06[LVI] Simplify and generalize handling of clamp patternsNikita Popov1-42/+7
Instead of handling a number of special cases for selects, handle this generally when inferring ranges from conditions. We already infer ranges from `x + C pred C2` to `x`, so doing the same for `x pred C2` to `x + C` is straightforward.
2021-03-06[LVI] Pass offset by reference (NFC)Nikita Popov1-10/+10
Instead of by pointer. This allows us to use offsets that are not materialized in the IR.
2021-02-06[Analysis] Use range-based for loops (NFC)Kazu Hirata1-2/+2
2021-01-01[LVI] Handle unions of conditionsNikita Popov1-6/+18
LVI previously handled "if (L && R)" conditions, but not "if (L || R)" conditions. The latter case can still produce useful information if L and R both constrain the same variable. This adds support for handling the "if (L || R)" case as well. The only difference is that we take the union instead of the intersection of the lattice values.
2020-12-29[Analysis] Use llvm::append_range (NFC)Kazu Hirata1-1/+1
2020-12-27[PatternMatch][LVI] Handle select-form and/or in LVINikita Popov1-8/+6
Following the discussion in D93065, this adds m_LogicalAnd() and m_LogicalOr() matchers, that match A && B and A || B logical operations, either as bitwise operations or select expressions. As an example usage, LVI is adapted to use these matchers for its condition reasoning. The plan here is to switch other parts of LLVM that reason about and/or of conditions to also support the select forms, and then merge D93065 (or a variant thereof) to disable the poison-unsafe select to and/or transform. Differential Revision: https://reviews.llvm.org/D93827
2020-12-11[Analysis] Use is_contained (NFC)Kazu Hirata1-1/+1
2020-09-27[LVI][CVP] Use block value when simplifying icmpsNikita Popov1-2/+5
Add a flag to getPredicateAt() that allows making use of the block value. This allows us to take into account range information from the current block, rather than only information that is threaded over edges, making the icmp simplification in CVP a lot more powerful. I'm not changing getPredicateAt() to use the block value unconditionally to avoid any impact on the JumpThreading pass, which is somewhat picky about LVI query order. Most test changes here are just icmps that now get dropped (while previously only a result used in a return was replaced). The three tests in icmp.ll show some representative improvements. Some of the folds this enables have been covered by IPSCCP in the meantime, but LVI can reason about some cases which are hard to support in IPSCCP, such as in test_br_cmp_with_offset. The compile-time time cost of doing this is fairly minimal, with a ~0.05% CTMark regression for ReleaseThinLTO: https://llvm-compile-time-tracker.com/compare.php?from=709d03f8af4da4204849a70f01798e7cebba2e32&to=6236fd503761f43c99f4537121e057a01056f185&stat=instructions This is because the block values will typically already be queried and cached by other CVP optimizations anyway. Differential Revision: https://reviews.llvm.org/D69686
2020-09-27[LVI] Clarify getValueAt/getValueInBlock doc comments (NFC)Nikita Popov1-5/+7
The lattice value returned by getValueInBlock() holds at the start of the block, not at the end. Also make it clearer what the difference between getValueInBlock() and getValueAt() is.
2020-09-27[LVI] Require context instruction in external API (NFCI)Nikita Popov1-4/+4
Require CxtI in getConstant() and getConstantRange() APIs. Accordingly drop the BB parameter, as it is implied by CxtI->getParent(). This makes sure we don't forget to pass the context instruction, and makes the API contract clearer (also clean up the comments to that effect -- the value holds at the context instruction, not the end of the block).
2020-09-20[LVI] Get value range from mask comparisonNikita Popov1-0/+14
InstCombine likes to canonicalize comparisons of the form X == C || X == C+1 into (X & -2) == C'. Make sure LVI can still recover the value range from this. Can of course also be useful for proper mask comparisons. For the sake of clarity, the implementation goes through KnownBits to compute the range.
2020-09-20[LVI] Refactor getValueFromICmpCondition (NFC)Nikita Popov1-22/+26
Rewrite this in a way where the core logic is in a separate function, that is invoked with swapped operands. This makes it easier to add handling for additional icmp patterns.
2020-08-29[LVI] Remove unnecessary lambda capture (NFC)Nikita Popov1-1/+1
2020-08-29Reapply [LVI] Normalize pointer behaviorNikita Popov1-59/+66
This got reverted because a dependency was reverted. It has since been reapplied, so reapply this as well. ----- Related to D69686. As noted there, LVI currently behaves differently for integer and pointer values: For integers, the block value is always valid inside the basic block, while for pointers it is only valid at the end of the basic block. I believe the integer behavior is the correct one, and CVP relies on it via its getConstantRange() uses. The reason for the special pointer behavior is that LVI checks whether a pointer is dereferenced in a given basic block and marks it as non-null in that case. Of course, this information is valid only after the dereferencing instruction, or in conservative approximation, at the end of the block. This patch changes the treatment of dereferencability: Instead of including it inside the block value, we instead treat it as something similar to an assume (it essentially is a non-nullness assume) and incorporate this information in intersectAssumeOrGuardBlockValueConstantRange() if the context instruction is the terminator of the basic block. This happens either when determining an edge-value internally in LVI, or when a terminator was explicitly passed to getValueAt(). The latter case makes this more powerful than the previous implementation as a side-effect, and this does actually seem benefitial in practice. Of course, we do not want to recompute dereferencability on each intersectAssume call, so we need a new cache for this. The dereferencability analysis requires walking the entire basic block and computing underlying objects of all memory operands. This was previously done separately for each queried pointer value. In the new implementation (both because this makes the caching simpler, and because it is faster), I instead only walk the full BB once and cache all the dereferenced pointers. So the traversal is now performed only once per BB, instead of once per queried pointer value. I think the overall model now makes more sense than before, and there will be no more pitfalls due to differing integer/pointer behavior. Differential Revision: https://reviews.llvm.org/D69914
2020-08-13Fix unused variable warning. NFC.Simon Pilgrim1-2/+2
Reduce the dyn_cast<> to a isa<> as that's all non-assert builds require, and move the cast<> inside the assert.
2020-08-11[LazyValueInfo] Let getEdgeValueLocal look into freeze instructionsJuneyoung Lee1-4/+7
This patch makes getEdgeValueLocal more precise when a freeze instruction is given, by adding support for freeze into constantFoldUser Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D84629
2020-07-31[NFC] Remove unused GetUnderlyingObject paramenterVitaly Buka1-11/+6
Depends on D84617. Differential Revision: https://reviews.llvm.org/D84621
2020-07-30[NFC] GetUnderlyingObject -> getUnderlyingObjectVitaly Buka1-7/+7
I am going to touch them in the next patch anyway
2020-07-29[ConstantRange] Add API for intrinsics (NFC)Nikita Popov1-36/+15
This adds a common API for compute constant ranges of intrinsics. The intention here is that a) we can reuse the same code across different passes that handle constant ranges, i.e. this can be reused in SCCP b) we only have to add knowledge about supported intrinsics to ConstantRange, not any consumers. Differential Revision: https://reviews.llvm.org/D84587
2020-07-25[LVI] Don't require operand number for range (NFC)Nikita Popov1-12/+11
Pass the Value* instead of the operand number, rename I to CxtI. This makes the function a bit more generally useful.
2020-07-14[NFC] Add 'override' keyword where missing in include/ and lib/.Logan Smith1-4/+4
This fixes warnings raised by Clang's new -Wsuggest-override, in preparation for enabling that warning in the LLVM build. This patch also removes the virtual keyword where redundant, but only in places where doing so improves consistency within a given file. It also removes a couple unnecessary virtual destructor declarations in derived classes where the destructor inherited from the base class is already virtual. Differential Revision: https://reviews.llvm.org/D83709
2020-07-01[LVI][CVP] Handle (x | y) < C style conditionsNikita Popov1-3/+14
InstCombine may convert conditions like (x < C) && (y < C) into (x | y) < C (for some C). This patch teaches LVI to recognize that in this case, it can infer either x < C or y < C along the edge. This fixes the issue reported at https://github.com/rust-lang/rust/issues/73827. Differential Revision: https://reviews.llvm.org/D82715
2020-06-28[LVI] Refactor value from icmp cond handling (NFC)Nikita Popov1-41/+38
Rewrite this in a way that is more amenable to extension.
2020-06-20[LVI] Extract addValueHandle() method (NFC)Nikita Popov1-3/+7
There will be more places registering value handles.
2020-06-20[LVI] Use find_as() where possible (NFC)Nikita Popov1-4/+4
This prevents us from creating temporary PoisoningVHs and AssertingVHs while performing hashmap lookups. As such, it only matters in assertion-enabled builds.
2020-06-14[LVI] Fix class indentation (NFC)Nikita Popov1-70/+70
This class uses a mix of different indentation levels, normalize it.
2020-06-14[LVI] Cache lookup of experimental.guard intrinsic (NFC)Nikita Popov1-27/+30
When LVI is performing assume intersections, it also checks for llvm.experimental.guard intrinsics. To avoid unnecessary block scans, it first checks whether this intrinsic is declared in the module at all. I've noticed that we end up spending quite a lot of time looking up that function again and again... Avoid this by only looking it up once when LazyValueInfo is constructed. This of course assumes that we don't introduce new guard intrinsics (which is the case for all existing uses of LVI -- and even if it weren't, it would not introduce miscompiles, just potentially lose optimization power.) Differential Revision: https://reviews.llvm.org/D81796
2020-06-13Reapply [LVI] Restructure caching to fix non-determinismNikita Popov1-87/+58
This was reverted due to a reported memory usage increase. However, a test case was never provided, and I wasn't able to reproduce it myself. Relative to the original patch, I have moved the block cache structure behind a unique_ptr, to avoid storing a huge structure inside a DenseMap. --- Variant on D70103 to fix https://bugs.llvm.org/show_bug.cgi?id=43909. The caching is switched to always use a BB to cache entry map, which then contains per-value caches. A separate set contains value handles with a deletion callback. This allows us to properly invalidate overdefined values. A possible alternative would be to always cache by value first and have per-BB maps/sets in the each cache entry. In that case we could use a ValueMap and would avoid the separate value handle set. I went with the BB indexing at the top level to make it easier to integrate D69914, but possibly that's not the right choice. Differential Revision: https://reviews.llvm.org/D70376
2020-05-19[LVI] Don't require DominatorTree in LVI (NFC)Nikita Popov1-56/+17
After D76797 the dominator tree is no longer used in LVI, so we can remove it as a pass dependency, and also get rid of the dominator tree enabling/disabling logic in JumpThreading. Apart from cleaning up the code, this also clarifies LVI cache consistency, in that the LVI cache can no longer depend on whether the DT was or wasn't enabled due to pending DT updates at any given time. Differential Revision: https://reviews.llvm.org/D76985
2020-05-17[LVI] Don't use dominator tree in isValidAssumeForContext()Nikita Popov1-3/+8
LVI and its consumers currently have quite a bit of complexity related to dominator tree management. However, it doesn't look like it is actually needed... The only use of the dominator tree is inside isValidAssumeForContext(). However, due to the way LVI queries work, it is not needed: If we query a value for some block, we will first get the edge values from all predecessor blocks, which also includes an intersection with assumptions that apply to the terminator of the predecessor. As such, we will already have processed all assumptions from predecessor blocks (this is actually stronger than what isValidAssumeForContext() does with a DT, because this is capable of combining non-dominating assumptions). The only additional assumptions we need to take into account are those in the block being queried. And we don't need a dominator tree for that. This patch only removes the use of DT, I will drop the machinery around it in a followup. Differential Revision: https://reviews.llvm.org/D76797
2020-04-25[ValueLattice] Merging unknown with empty CR is unknown.Florian Hahn1-3/+2
Currently an unknown/undef value is marked as overdefined when merged with an empty range. An empty range can occur in unreachable/dead code. When merging the new unknown state (= no value known yet) with an empty range, there still isn't any information about the value yet and we can stay in unknown. This gives a few nice improvements on the number of instructions removed by IPSCCP: Same hash: 170 (filtered out) Remaining: 67 Metric: sccp.IPNumInstRemoved Program base patch diff test-suite...rks/FreeBench/mason/mason.test 3.00 6.00 100.0% test-suite...nchmarks/McCat/18-imp/imp.test 3.00 5.00 66.7% test-suite...C/CFP2000/179.art/179.art.test 2.00 3.00 50.0% test-suite...ijndael/security-rijndael.test 2.00 3.00 50.0% test-suite...ks/Prolangs-C/agrep/agrep.test 40.00 58.00 45.0% test-suite...ce/Applications/Burg/burg.test 26.00 37.00 42.3% test-suite...cCat/03-testtrie/testtrie.test 3.00 4.00 33.3% test-suite...Source/Benchmarks/sim/sim.test 29.00 36.00 24.1% test-suite.../Applications/spiff/spiff.test 9.00 11.00 22.2% test-suite...s/FreeBench/neural/neural.test 5.00 6.00 20.0% test-suite...pplications/treecc/treecc.test 66.00 79.00 19.7% test-suite...langs-C/football/football.test 85.00 101.00 18.8% test-suite...ce/Benchmarks/PAQ8p/paq8p.test 90.00 105.00 16.7% test-suite...oxyApps-C++/miniFE/miniFE.test 37.00 43.00 16.2% test-suite...rks/FreeBench/pifft/pifft.test 26.00 30.00 15.4% test-suite...lications/sqlite3/sqlite3.test 481.00 548.00 13.9% test-suite...marks/7zip/7zip-benchmark.test 4875.00 5522.00 13.3% test-suite.../CINT2000/176.gcc/176.gcc.test 1117.00 1197.00 7.2% test-suite...0.perlbench/400.perlbench.test 1618.00 1732.00 7.0% Reviewers: efriedma, nikic, davide Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D78667
2020-04-19[LVI] Use Optional instead of out parameter (NFC)Nikita Popov1-245/+193
As suggested on D76788, this switches the LVI implementation to return Optional<ValueLatticeElement> from various methods, instead of passing in a ValueLatticeElement reference and returning a boolean. Differential Revision: https://reviews.llvm.org/D78383
2020-04-17[LVI] Cleanup/unify cache accessNikita Popov1-77/+58
This patch combines the "has" and "get" parts of the cache access. getCachedValueInfo() now both sets the BBLV return argument, and returns whether the value was found. Additionally, the management of the work stack is now integrated into getBlockValue(). If the value is not cached yet, we try to push to the stack (and return false, indicating that we need to solve first), or return overdefined in case of a cycle. These changes a) avoid a duplicate cache lookup for has & get and b) ensure that the logic is uniform everywhere. For this reason this change is also not quite NFC, because previously overdefined values from the cache, and overdefined values from a cycle received different treatment when it came to assumption intersection. Differential Revision: https://reviews.llvm.org/D76788
2020-04-14[ValueLattice] Remove unused DataLayout parameter of mergeIn, NFCAaron Puchert1-4/+4
Reviewed By: fhahn, echristo Differential Revision: https://reviews.llvm.org/D78061
2020-03-31[ValueLattice] Distinguish between constant ranges with/without undef.Florian Hahn1-10/+19
This patch updates ValueLattice to distinguish between ranges that are guaranteed to not include undef and ranges that may include undef. A constant range guaranteed to not contain undef can be used to simplify instructions to arbitrary values. A constant range that may contain undef can only be used to simplify to a constant. If the value can be undef, it might take a value outside the range. For example, consider the snipped below define i32 @f(i32 %a, i1 %c) { br i1 %c, label %true, label %false true: %a.255 = and i32 %a, 255 br label %exit false: br label %exit exit: %p = phi i32 [ %a.255, %true ], [ undef, %false ] %f.1 = icmp eq i32 %p, 300 call void @use(i1 %f.1) %res = and i32 %p, 255 ret i32 %res } In the exit block, %p would be a constant range [0, 256) including undef as %p could be undef. We can use the range information to replace %f.1 with false because we remove the compare, effectively forcing the use of the constant to be != 300. We cannot replace %res with %p however, because if %a would be undef %cond may be true but the second use might not be < 256. Currently LazyValueInfo uses the new behavior just when simplifying AND instructions and does not distinguish between constant ranges with and without undef otherwise. I think we should address the remaining issues in LVI incrementally. Reviewers: efriedma, reames, aqjune, jdoerfert, sstefan1 Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D76931
2020-03-24[LVI] Convert some checks to assertions; NFCNikita Popov1-13/+3
solveBlockValue() should only be called if the value isn't cached yet. Similarly, it does not make sense to "solve" a constant.
2020-03-22[LVI] Use SmallDenseMap for getValueFromCondition(); NFCNikita Popov1-4/+4
For the common case, we will only insert one value into this map.
2020-03-14[ValueLattice] Add new state for undef constants.Florian Hahn1-6/+6
This patch adds a new undef lattice state, which is used to represent UndefValue constants or instructions producing undef. The main difference to the unknown state is that merging undef values with constants (or single element constant ranges) produces the constant/constant range, assuming all uses of the merge result will be replaced by the found constant. Contrary, merging non-single element ranges with undef needs to go to overdefined. Using unknown for UndefValues currently causes mis-compiles in CVP/LVI (PR44949) and will become problematic once we use ValueLatticeElement for SCCP. Reviewers: efriedma, reames, davide, nikic Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D75120
2019-12-20Temporarily revert "Reapply [LVI] Normalize pointer behavior" and "[LVI] ↵Jordan Rupprecht1-134/+174
Restructure caching" This reverts commits 7e18aeba5062cd4324a9efb7bc25c9dbc4a34c2c (D70376) 21fbd5587cdfa11dabb3aeb0ead2d3d5fd0b490d (D69914) due to increased memory usage.
2019-12-13Reapply [LVI] Normalize pointer behaviorNikita Popov1-79/+88
This is a rebase of the change over D70376, which fixes an LVI cache invalidation issue that also affected this patch. ----- Related to D69686. As noted there, LVI currently behaves differently for integer and pointer values: For integers, the block value is always valid inside the basic block, while for pointers it is only valid at the end of the basic block. I believe the integer behavior is the correct one, and CVP relies on it via its getConstantRange() uses. The reason for the special pointer behavior is that LVI checks whether a pointer is dereferenced in a given basic block and marks it as non-null in that case. Of course, this information is valid only after the dereferencing instruction, or in conservative approximation, at the end of the block. This patch changes the treatment of dereferencability: Instead of including it inside the block value, we instead treat it as something similar to an assume (it essentially is a non-nullness assume) and incorporate this information in intersectAssumeOrGuardBlockValueConstantRange() if the context instruction is the terminator of the basic block. This happens either when determining an edge-value internally in LVI, or when a terminator was explicitly passed to getValueAt(). The latter case makes this change not fully NFC, because we can now fold terminator icmps based on the dereferencability information in the same block. This is the reason why I changed one JumpThreading test (it would optimize the condition away without the change). Of course, we do not want to recompute dereferencability on each intersectAssume call, so we need a new cache for this. The dereferencability analysis requires walking the entire basic block and computing underlying objects of all memory operands. This was previously done separately for each queried pointer value. In the new implementation (both because this makes the caching simpler, and because it is faster), I instead only walk the full BB once and cache all the dereferenced pointers. So the traversal is now performed only once per BB, instead of once per queried pointer value. I think the overall model now makes more sense than before, and there will be no more pitfalls due to differing integer/pointer behavior. Differential Revision: https://reviews.llvm.org/D69914