aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
AgeCommit message (Collapse)AuthorFilesLines
9 days[LVI] Handle constant value lattice in `getEdgeValueLocal` (#161410)Yingwei Zheng1-11/+17
Closes https://github.com/llvm/llvm-project/issues/161367. In https://github.com/llvm/llvm-project/pull/157614, we ignored cases where OpLatticeVal might be a constant or notconstant. Directly returning the result causes a type mismatch. I apologize for the oversight in the previous code review. This patch applies the cast op to constants. For notconstant value lattices, I'd leave it as a todo (it is similar to the constant case, except for trunc without nsw/nuw).
11 daysExtend LVI to cache ranges per BB predecessor. (#159432)Alina Sbirlea1-3/+137
Currently LVI does the union of value ranges from block predecessors. When storing the ranges per predecessor, the resulting ranges may be more restricted and enable additional optimizations. However this is costly (memory + compile time), so place this under a flag disabled by default. See: https://github.com/llvm/llvm-project/issues/158139.
2025-09-10[LVI] Support no constant range of cast value in getEdgeValueLocal. (#157614)Andreas Jonson1-0/+18
proof: https://alive2.llvm.org/ce/z/8emkHY
2025-08-17[LVI] Add support for trunc nuw range. (#154021)Andreas Jonson1-2/+7
Proof: https://alive2.llvm.org/ce/z/a5Yjb8
2025-06-28[Analysis] Remove unnecessary casts (NFC) (#146216)Kazu Hirata1-6/+2
PImpl is already of LazyValueInfoImpl *.
2025-04-30[LVI][ValueTracking] Take UB-implying attributes into account in ↵Yingwei Zheng1-1/+2
`isSafeToSpeculativelyExecute` (#137604) Closes https://github.com/llvm/llvm-project/issues/137582. In the original case, LVI uses the edge information in `%entry -> %if.end` to get a more precise result. However, since the call to `smin` has an `noundef` return attribute, an immediate UB will be triggered after optimization. Currently, `isSafeToSpeculativelyExecuteWithOpcode(%min)` returns true because https://github.com/llvm/llvm-project/commit/6a288c1e32351d4be3b7630841af078fa1c3bb8b only checks whether the function is speculatable. However, it is not enough in this case. This patch takes UB-implying attributes into account if `IgnoreUBImplyingAttrs` is set to false. If it is set to true, the caller is responsible for correctly propagating UB-implying attributes.
2025-04-21[LLVM] Cleanup pass initialization for Analysis passes (#135858)Rahul Joshi1-3/+1
- Do not call pass initialization from pass constructors. - Instead, pass initialization should happen in the `initializeAnalysis` function. - https://github.com/llvm/llvm-project/issues/111767
2025-02-23[LVI] Skip self loops in `solveBlockValueNonLocal` (#127763)Yingwei Zheng1-0/+3
We cannot infer more information from backedges in `solveBlockValueNonLocal`. However, since DT is unavailable in LVI, there is not a precise way to check whether a BB edge is a backedge. This patch only skips self loops to unblock the range analysis. The motivating case is extracted from https://github.com/llvm/llvm-project/pull/127663. Compile-time impact is high: https://llvm-compile-time-tracker.com/compare.php?from=84ddda58c870681dd12ed765e9d59d5e00567f94&to=af032f1351358f2f5b5d9f4e87c5601c23b9bd37&stat=instructions:u
2025-02-03[LVI] Handle nonnull attributes at callsite (#125377)Yingwei Zheng1-2/+11
This patch is the followup of https://github.com/llvm/llvm-project/pull/124908.
2025-02-02[LVI] Add trunc to i1 handling. (#124480)Andreas Jonson1-0/+26
Proof: https://alive2.llvm.org/ce/z/yPrRp-
2025-01-15[LVI] Learn value ranges from ctpop results (#121945)Stephen Senran Zhang1-0/+24
Fixes #115751.
2024-12-09[LVI] Thread binop over select with constant arms (#110212)Yingwei Zheng1-2/+49
Motivating case from https://github.com/delta-io/delta-rs: https://alive2.llvm.org/ce/z/3mzr4C
2024-12-02[LVI] Fix insertelement of constexprNikita Popov1-0/+7
Bail out when evaluating an insertelement of a constant expression. Unlike other ValueLattice kinds, these don't have implicit splat semantics and we end up with type mismatches. If we actually wanted to handle these, we should actually evaluate the insertion via constant folding. I'm not bothering with that, as these should get constant folded on construction already.
2024-10-18[LVI] Infer non-zero from equality icmp (#112838)Yingwei Zheng1-0/+14
This following pattern is common in loop headers: ``` %101 = sub nuw i64 %78, %98 %103 = icmp eq i64 %78, %98 br i1 %103, label %.thread.i.i, label %.preheader.preheader.i.i .preheader.preheader.i.i: %invariant.umin.i.i = call i64 @llvm.umin.i64(i64 %101, i64 9) %umax.i = call i64 @llvm.umax.i64(i64 %invariant.umin.i.i, i64 1) br label %.preheader.i.i .preheader.i.i: ... %116 = add nuw nsw i64 %.011.i.i, 1 %exitcond.not.i = icmp eq i64 %116, %umax.i br i1 %exitcond.not.i, label %.critedge.i.i, label %.preheader.i.i ``` As `%78` is not equal to `%98` in BB `.preheader.preheader.i.i`, we can prove `%101` is non-zero. Then we can simplify the loop exit condition. Addresses regression introduced by https://github.com/llvm/llvm-project/pull/112742.
2024-10-16[LLVM] Add `Intrinsic::getDeclarationIfExists` (#112428)Rahul Joshi1-1/+1
Add `Intrinsic::getDeclarationIfExists` to lookup an existing declaration of an intrinsic in a `Module`.
2024-09-19[ValueTracking] Use isSafeToSpeculativelyExecuteWithVariableReplaced() in ↵Nikita Popov1-1/+2
more places (#109149) This replaces some uses of isSafeToSpeculativelyExecute() with isSafeToSpeculativelyExecuteWithVariableReplaced(), in cases where we are guarding against operand changes rather plain speculation. I believe that this is NFC with the current implementation of the function (as it only does something different from loads), but this makes us more defensive against future generalizations.
2024-08-28[ValueLattice] Move intersect from LVI into ValueLattice API (NFC)Nikita Popov1-69/+18
So we can reuse the logic inside IPSCCP.
2024-08-24[Analysis] Copy-construct SmallVector (NFC) (#105911)Kazu Hirata1-2/+2
2024-08-14[LLVM] Fix missing includes for function declarations that will be needed ↵Thomas Fransham1-0/+1
for explicit symbol visibility (#103900) In multiple source files function definitions never sees there declaration in a header because its never included causing linker errors when explicit symbol visibility macros\dllexport are added to the declarations. Most of these were originally found by @tstellar in https://github.com/llvm/llvm-project/pull/67502 TargetRegistry.h is needed in MCExternalSymbolizer.cpp for createMCSymbolizer Analysis/Passes.h is needed in LazyValueInfo.cpp and RegionInfo.cpp for createLazyValueInfoPassin and createRegionInfoPass Transforms/Scalar.h is needed in SpeculativeExecution.cpp for createSpeculativeExecutionPass
2024-08-02[LVI][NFC] Delete an outdated comment (#101504)Piotr Fusik1-3/+1
Transitioned from inheritance to has-a relationship in 9db7948e
2024-07-19[CVP][LVI] Add support for InsertElementInst in LVI (#99368)Rajat Bajpai1-0/+23
Currently, the LVI analysis pass doesn't support InsertElementInst vector instruction. Due to this, some optimization opportunities are missed. For example, in the below example, ICMP instruction can be folded but it doesn't. ``` ... %ie1 = insertelement <2 x i32> poison, i32 10, i64 0 %ie2 = insertelement <2 x i32> %ie1, i32 20, i64 1 %icmp = icmp <2 x i1> %ie2, <i32 40, i32 40> ... ``` This change adds InsertElementInst support in the LVI analysis pass to fix the motivating example.
2024-07-08[ValueLattice] Add asConstantRange() helper (NFC)Nikita Popov1-20/+7
Move the toConstantRange() helper from LVI into ValueLattice, so it can be reused in other places like SCCP.
2024-07-05[LVI][CVP] Add support for vector comparisonsNikita Popov1-5/+1
2024-07-05[IR] Add Constant::toConstantRange() (NFC)Nikita Popov1-2/+2
The logic in llvm::getVectorConstantRange() can be a bit inconvenient to use in some cases because of the need to handle the scalar case separately. Generalize it to handle all constants, and move it to live directly on Constant.
2024-07-04[LVI] Use Constant instead of Tristate for predicate resultsNikita Popov1-56/+47
A lot of the users just end up converting it into a Constant themselves. Doing this in the API leaves less room for error with vector types, and brings getPredicateResult() closer to LatticeValueElement::getCompare(), hopefully allowing us to consolidate them.
2024-07-04[LVI] Simplify the getPredicateResult() implementation (NFC)Nikita Popov1-21/+5
By using ConstantRange::icmp().
2024-07-04[CVP][LVI] Fix incorrect scalar type when getting constant folded vec (#97682)goldsteinn1-2/+3
Fixes #97674 After #97428 added support for vectors, our constant ranges can now be from splat vectors so when they reduce to a singe constant value, we need to return the original type as opposed to just an int.
2024-07-03[LVI] Use CmpInst::Predicate in APIs (NFC)Nikita Popov1-17/+15
Unfortunately this requires including InstrTypes.h in the header, but I think that's fine given that that LazyValueInfo.h is not widely used.
2024-07-03[ValueTracking][LVI] Consolidate vector constant range calculationNikita Popov1-25/+2
Add a common helper used for computeConstantRange() and LVI. The implementation is a mix of both, with the efficient handling for ConstantDataVector taken from computeConstantRange(), and the general handling (including non-splat poison) from LVI.
2024-07-03[CVP][LVI] Add support for vectors (#97428)Nikita Popov1-4/+28
The core change here is to add support for converting vector constants into constant ranges. The rest is just relaxing isIntegerTy() checks and making sure we don't use APIs that assume vectors. There are a couple of places that don't support vectors yet, most notably the "simplest" fold (comparisons to a constant) isn't supported yet. I'll leave these to a followup.
2024-06-28[IR] Don't include Module.h in Analysis.h (NFC) (#97023)Nikita Popov1-0/+1
Replace it with a forward declaration instead. Analysis.h is pulled in by all passes, but not all passes need to access the module.
2024-06-28[IR] Add getDataLayout() helpers to Function and GlobalValue (#96919)Nikita Popov1-1/+1
Similar to https://github.com/llvm/llvm-project/pull/96902, this adds `getDataLayout()` helpers to Function and GlobalValue, replacing the current `getParent()->getDataLayout()` pattern.
2024-06-27[IR] Add getDataLayout() helpers to BasicBlock and Instruction (#96902)Nikita Popov1-3/+3
This is a helper to avoid writing `getModule()->getDataLayout()`. I regularly try to use this method only to remember it doesn't exist... `getModule()->getDataLayout()` is also a common (the most common?) reason why code has to include the Module.h header.
2024-06-21[llvm] format and terminate namespaces with closing comment (#94917)Mohammed Keyvanzadeh1-93/+94
Namespaces are terminated with a closing comment in the majority of the codebase so do the same here for consistency. Also format code within some namespaces to make clang-format happy.
2024-06-17[LVI][ConstantRange] Generalize mask not equal conditions handlingAntonio Frighetto1-7/+4
Extend `V & Mask != 0` for non-zero constants if satisfiable, when retrieving constraint value information from a non-equality comparison. Proof: https://alive2.llvm.org/ce/z/dc5BeT. Motivating example: https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.dg/tree-ssa/vrp76.c.
2024-06-10[LVI] Remove unused get of Range metadata (#94914)Andreas Jonson1-3/+0
There is no test for this code and it also do not change the result of https://github.com/dtcxzyw/llvm-opt-benchmark when I run it locally. I have not been able to make a test for this and do not know how to handle the range attribute for this so maybe it shall be removed?
2024-04-16[ValueTracking] Restore isKnownNonZero parameter order. (#88873)Harald van Dijk1-3/+2
Prior to #85863, the required parameters of llvm::isKnownNonZero were Value and DataLayout. After, they are Value, Depth, and SimplifyQuery, where SimplifyQuery is implicitly constructible from DataLayout. The change to move Depth before SimplifyQuery needed callers to be updated unnecessarily, and as commented in #85863, we actually want Depth to be after SimplifyQuery anyway so that it can be defaulted and the caller does not need to specify it.
2024-04-12[ValueTracking] Convert `isKnownNonZero` to use SimplifyQuery (#85863)Yingwei Zheng1-2/+3
This patch converts `isKnownNonZero` to use SimplifyQuery. Then we can use the context information from `DomCondCache`. Fixes https://github.com/llvm/llvm-project/issues/85823. Alive2: https://alive2.llvm.org/ce/z/QUvHVj
2024-04-04[LVI] Handle range attributes (#86413)Andreas Jonson1-4/+9
This adds handling of range attribute for return values of Call and Invoke in getFromRangeMetadata and handling of argument with range attribute in solveBlockValueNonLocal. There is one additional check of the range metadata at line 1120 in getValueFromSimpleICmpCondition that is not covered in this PR as after https://github.com/llvm/llvm-project/pull/75311 there is no test that cover that check any more and I have not been able to create a test that trigger that code.
2024-03-28[LVI] Use m_AddLike instead of m_Add when matching simple conditionNoah Goldstein1-2/+2
We have more complete logic for handling `Add`, so try to use that logic for `or disjoint` (which can definitionally be treated as `add`). Closes #86058
2024-03-08[IR] Add `getNoWrapKind` method for `OverflowingBinaryOperator` (NFC)Antonio Frighetto1-6/+1
2024-01-10[LVI] Assert that only one value is pushed (NFC)Nikita Popov1-2/+6
2024-01-02[LVI] Don't push both sides of and/or at onceNikita Popov1-1/+3
Same as the change in d5db2cdb22ab302acbb6e1a066e791f25dc612de, but for condition handling. The same issue could occur here as well.
2024-01-02[LVI] Don't push both binop operands at onceNikita Popov1-2/+4
If one of the binop operands depends on the other, this may end up evaluating them in the wrong order, producing sub-optimal results. Make sure that only one unevaluated operand gets pushed per iteration. Fixes https://github.com/llvm/llvm-project/issues/76705.
2024-01-02[LVI] Support using block values when handling conditions (#75311)Nikita Popov1-48/+107
Currently, LVI will only use conditions like "X < C" to constrain the value of X on the relevant edge. This patch extends it to handle conditions like "X < Y" by querying the known range of Y. This means that getValueFromCondition() and various related APIs can now return nullopt to indicate that they have pushed to the worklist, and need to be called again later. This behavior is currently controlled by a UseBlockValue option, and only enabled for actual edge value handling. All other places deriving constraints from conditions keep using the previous logic for now. This change was originally motivated as a fix for the regression reported in https://github.com/llvm/llvm-project/pull/73662#issuecomment-1849281758. Unfortunately, it doesn't actually fix it, because we run into another issue there (LVI currently is really bad at handling values used in loops). This change has some compile-time impact, but it's fairly small, in the 0.05% range.
2023-12-19[LVI] Remove unnecessary TLI dependencyNikita Popov1-11/+7
Only used in ConstantFoldCompareInstOperands(), which does not actually use TLI.
2023-12-12[LVI] Don't return optional from getEdgeValueLocal() (NFC)Nikita Popov1-13/+8
The general convention inside LVI is that std::nullopt means that a value has been pushed to the worklist. However, getEdgeValueLocal() used it as an additional spelling for getOverdefined() instead.
2023-12-12[LVI] Move bulk of getConstantRangeAtUse() implementation into Impl (NFC)Nikita Popov1-43/+52
Make the layering here similar to all the other methods: LazyValueInfoImpl implements the underlying API returning a ValueLatticeElement, and then LazyValueInfo exposes this as a ConstantRange publicly.
2023-12-12[LVI] Reuse LatticeValue to ConstantRange conversion moreNikita Popov1-30/+13
Use the helper in the getConstantRange() and getConstantRangeAtUse() APIs as well. For that purpose move the handling of isUnknown() into the helper as well.
2023-12-12[LVI] Don't require DataLayout in getConstantRangeOrFull() (NFC)Nikita Popov1-5/+6
We're only working on integers here, so we don't need DataLayout to determine the width.