aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
AgeCommit message (Collapse)AuthorFilesLines
3 days[IR] Require DataLayout for pointer cast elimination (#162279)Nikita Popov1-8/+1
isEliminableCastPair() currently tries to support elimination of ptrtoint/inttoptr cast pairs by assuming that the maximum possible pointer size is 64 bits. Of course, this is no longer the case nowadays. This PR changes isEliminableCastPair() to accept an optional DataLayout argument, which is required to eliminate pointer casts. This means that we no longer eliminate these cast pairs during ConstExpr construction, and instead only do it during DL-aware constant folding. This had a lot of annoying fallout on tests, most of which I've addressed in advance of this change.
3 days[InstSimplify] Optimize maximumnum and minimumnum (#139581)Lewis Crawford1-36/+137
Add support for the new maximumnum and minimumnum intrinsics in various optimizations in InstSimplify. Also, change the behavior of optimizing maxnum(sNaN, x) to simplify to qNaN instead of x to better match the LLVM IR spec, and add more tests for sNaN behavior for all 3 max/min intrinsic types.
5 days[InstSimplify] Simplify fcmp implied by dominating fcmp (#161090)Yingwei Zheng1-0/+4
This patch simplifies an fcmp into true/false if it is implied by a dominating fcmp. As an initial support, it only handles two cases: + `fcmp pred1, X, Y -> fcmp pred2, X, Y`: use set operations. + `fcmp pred1, X, C1 -> fcmp pred2, X, C2`: use `ConstantFPRange` and set operations. Note: It doesn't fix https://github.com/llvm/llvm-project/issues/70985, as the second fcmp in the motivating case is not dominated by the edge. We may need to adjust JumpThreading to handle this case. Comptime impact (~+0.1%): https://llvm-compile-time-tracker.com/compare.php?from=a728f213c863e4dd19f8969a417148d2951323c0&to=8ca70404fb0d66a824f39d83050ac38e2f1b25b9&stat=instructions:u IR diff: https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2848
2025-09-24[InstSimplify] Consider vscale_range for get active lane mask (#160073)Matthew Devereau1-1/+18
Scalable get_active_lane_mask intrinsic calls can be simplified to i1 splat (ptrue) when its constant range is larger than or equal to the maximum possible number of elements, which can be inferred from vscale_range(x, y)
2025-09-20[InstCombine] Generalise optimisation of redundant floating point ↵Rajveer Singh Bharadwaj1-28/+43
comparisons with `ConstantFPRange` (#159315) Follow up of #158097 Similar to `simplifyAndOrOfICmpsWithConstants`, we can do so for floating point comparisons.
2025-09-17[PatternMatch] Introduce match functor (NFC) (#159386)Ramkumar Ramachandra1-10/+6
A common idiom is the usage of the PatternMatch match function within a functional algorithm like all_of. Introduce a match functor to shorten this idiom. Co-authored-by: Luke Lau <luke@igalia.com>
2025-09-16[InstCombine] Optimize redundant floating point comparisons in `or`/`and` ↵Rajveer Singh Bharadwaj1-0/+29
inst's (#158097) Resolves #157371 We can eliminate one of the `fcmp` when we have two same `olt` or `ogt` instructions matched in `or`/`and` simplification.
2025-09-12[InstSimplify] Simplify get.active.lane.mask when 2nd arg is zero (#158018)David Sherwood1-0/+4
When the second argument passed to the get.active.lane.mask intrinsic is zero we can simplify the instruction to return an all-false mask regardless of the first operand.
2025-09-07[InstSimplify] Simplify extractvalue (umul_with_overflow(x, 1)). (#157307)Florian Hahn1-0/+13
Look through extractvalue to simplify umul_with_overflow where one of the operands is 1. This removes some redundant instructions when expanding SCEVs, which in turn makes the runtime check cost estimate more accurate, reducing the minimum iterations for which vectorization is profitable. PR: https://github.com/llvm/llvm-project/pull/157307
2025-07-27[Analysis] Remove an unnecessary cast (NFC) (#150838)Kazu Hirata1-1/+1
getOpcode() already returns Instruction::CastOps.
2025-07-07[NFC] Clean up poison folding in simplifyBinaryIntrinsic (#147259)jjasmine1-10/+0
Fixes #147116.
2025-07-04[InstCombine] Propagate poison pow[i], [us]add, [us]sub and [us]mul (#146750)jjasmine1-0/+3
Fixes #146560 as well as propagate poison for [us]add, [us]sub and [us]mul
2025-06-22[InstSimplify] Simplify 'x u>= 1' to true when x is known non-zero (#145204)Iris Shi1-4/+7
2025-06-16[InstSimplify] Add basic simplifications for vp.reverse (#144112)Philip Reames1-0/+17
Directly modeled after what we do for vector.reverse, but with restrictions on EVL and mask added.
2025-06-03[ValueTracking] Make Depth last default arg (NFC) (#142384)Ramkumar Ramachandra1-39/+33
Having a finite Depth (or recursion limit) for computeKnownBits is very limiting, but is currently a load-bearing necessity, as all KnownBits are recomputed on each call and there is no caching. As a prerequisite for an effort to remove the recursion limit altogether, either using a clever caching technique, or writing a easily-invalidable KnownBits analysis, make the Depth argument in APIs in ValueTracking uniformly the last argument with a default value. This would aid in removing the argument when the time comes, as many callers that currently pass 0 explicitly are now updated to omit the argument altogether.
2025-05-31[InstSimplify] Handle nsz when simplifying X * 0.0 (#142181)Nadharm1-0/+3
If ValueTracking can guarantee non-NaN and non-INF and the `nsz` fast-math flag is set, we can simplify X * 0.0 ==> 0.0. https://alive2.llvm.org/ce/z/XacRQZ
2025-05-22Reland [llvm] add GenericFloatingPointPredicateUtils #140254 (#141065)Tim Gymnich1-0/+1
#140254 was previously missing 2 files in the bazel build config.
2025-05-21Revert "[llvm] add GenericFloatingPointPredicateUtils (#140254)" (#140968)Kewen121-1/+0
This reverts commit d00d74bb2564103ae3cb5ac6b6ffecf7e1cc2238. The PR breaks our buildbots and blocks downstream merge.
2025-05-21[llvm] add GenericFloatingPointPredicateUtils (#140254)Tim Gymnich1-0/+1
add `GenericFloatingPointPredicateUtils` in order to generalize effects of floating point comparisons on `KnownFPClass` for both IR and MIR. --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-05-08[InstCombine] Fix `frexp(frexp(x)) -> frexp(x)` fold (#138837)Iris Shi1-9/+0
Fixes #138819 When frexp is applied twice, the second result should be zero.
2025-05-02[InstSimplify] Fold {u,s}{min,max} x, poison -> poison (#138166)Luke Lau1-0/+4
Following from the discussion in https://github.com/llvm/llvm-project/pull/138095#discussion_r2070484664, these intrinsics are poison if any of their operands are poison, and are marked as such in propagatesPoison in ValueTracking.cpp. This will help fold away leftover vectors produced by VectorCombine when scalarizing intrinsics.
2025-05-01Revert "[InstSimplify] Fold `getelementptr inbounds null, idx -> null` ↵Yingwei Zheng1-8/+0
(#130742)" (#138168) Revert #130742 for now to avoid breaking glibc failures until the workaround patches are landed.
2025-04-17[InstSimplify] Fold `getelementptr inbounds null, idx -> null` (#130742)Yingwei Zheng1-0/+8
Proof: https://alive2.llvm.org/ce/z/5ZkPx- See also https://github.com/llvm/llvm-project/pull/130734 for the motivation.
2025-03-28[Analysis][NFC] Extract KnownFPClass (#133457)Tim Gymnich1-0/+1
- extract KnownFPClass for future use inside of GISelKnownBits --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-03-01[InstSimplify] Fold `X * C >= X` to `true` (#129352)Veera1-12/+22
Proof: https://alive2.llvm.org/ce/z/T_ocLy Discovered in: https://github.com/rust-lang/rust/issues/114386 This PR folds `X * C >= X` to `true` when `C` is known to be non-zero and `mul` is `nuw`. Folds for other math operators exist already: https://llvm-ir.godbolt.org/z/GKcYEf5Kb
2025-02-27Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo ↵Nikita Popov1-3/+4
(#125880) (#128020) Relative to the previous attempt this includes two fixes: * Adjust callCapturesBefore() to not skip captures(ret: address, provenance) arguments, as these will not count as a capture at the call-site. * When visiting uses during stack slot optimization, don't skip the ModRef check for passthru captures. Calls can both modref and be passthru for captures. ------ This extends CaptureTracking to support inferring non-trivial CaptureInfos. The focus of this patch is to only support FunctionAttrs, other users of CaptureTracking will be updated in followups. The key API changes here are: * DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC component specifies what is captured at that Use and the ResultCC component specifies what may be captured via the return value of the User. Usually only one or the other will be used (corresponding to previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for call captures. * The CaptureTracking::captures() extension point is passed this UseCaptureInfo as well and then can decide what to do with it by returning an Action, which is one of: Stop: stop traversal. ContinueIgnoringReturn: continue traversal but don't follow the instruction return value. Continue: continue traversal and follow the instruction return value if it has additional CaptureComponents. For now, this patch retains the (unsound) special logic for comparison of null with a dereferenceable pointer. I'd like to switch key code to take advantage of address/address_is_null before dropping it. This PR mainly intends to introduce necessary API changes and basic inference support, there are various possible improvements marked with TODOs.
2025-02-19Revert "Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo ↵Nico Weber1-4/+3
(#125880)" This reverts commit 0fab404ee874bc5b0c442d1841c7d2005c3f8729. Seems to break LTO builds of clang on Windows, see comments on https://github.com/llvm/llvm-project/pull/125880
2025-02-14Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)Nikita Popov1-3/+4
Relative to the previous attempt, this adjusts isEscapeSource() to not treat calls with captures(ret: address, provenance) or similar arguments as escape sources. This addresses the miscompile reported at: https://github.com/llvm/llvm-project/pull/125880#issuecomment-2656632577 The implementation uses a helper function on CallBase to make this check a bit more efficient (e.g. by skipping the byval checks) as checking attributes on all arguments if fairly expensive. ------ This extends CaptureTracking to support inferring non-trivial CaptureInfos. The focus of this patch is to only support FunctionAttrs, other users of CaptureTracking will be updated in followups. The key API changes here are: * DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC component specifies what is captured at that Use and the ResultCC component specifies what may be captured via the return value of the User. Usually only one or the other will be used (corresponding to previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for call captures. * The CaptureTracking::captures() extension point is passed this UseCaptureInfo as well and then can decide what to do with it by returning an Action, which is one of: Stop: stop traversal. ContinueIgnoringReturn: continue traversal but don't follow the instruction return value. Continue: continue traversal and follow the instruction return value if it has additional CaptureComponents. For now, this patch retains the (unsound) special logic for comparison of null with a dereferenceable pointer. I'd like to switch key code to take advantage of address/address_is_null before dropping it. This PR mainly intends to introduce necessary API changes and basic inference support, there are various possible improvements marked with TODOs.
2025-02-13Revert "[CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)"Nikita Popov1-4/+3
This reverts commit ee655ca27aad466bcc54f6eba03f7e564940ad5a. A miscompilation has been reported at: https://github.com/llvm/llvm-project/pull/125880#issuecomment-2656632577
2025-02-13[CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)Nikita Popov1-3/+4
This extends CaptureTracking to support inferring non-trivial CaptureInfos. The focus of this patch is to only support FunctionAttrs, other users of CaptureTracking will be updated in followups. The key API changes here are: * DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC component specifies what is captured at that Use and the ResultCC component specifies what may be captured via the return value of the User. Usually only one or the other will be used (corresponding to previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for call captures. * The CaptureTracking::captures() extension point is passed this UseCaptureInfo as well and then can decide what to do with it by returning an Action, which is one of: Stop: stop traversal. ContinueIgnoringReturn: continue traversal but don't follow the instruction return value. Continue: continue traversal and follow the instruction return value if it has additional CaptureComponents. For now, this patch retains the (unsound) special logic for comparison of null with a dereferenceable pointer. I'd like to switch key code to take advantage of address/address_is_null before dropping it. This PR mainly intends to introduce necessary API changes and basic inference support, there are various possible improvements marked with TODOs.
2025-02-10InstSimplify: improve computePointerICmp (NFC) (#126255)Ramkumar Ramachandra1-20/+7
The comment about inbounds protecting only against unsigned wrapping is incorrect: it also protects against signed wrapping, but the issue is that it could cross the sign boundary.
2025-02-02[InstSimplify] Add additional checks when substituting pointers (#125385)Yingwei Zheng1-6/+11
Compile-time impact: https://llvm-compile-time-tracker.com/compare.php?from=d09b521624f263b5f1296f8d4771836b97e600cb&to=e437ba2cb83bb965e13ef00727671896f03ff84f&stat=instructions:u IR diff looks acceptable. Closes https://github.com/llvm/llvm-project/issues/115574
2025-02-01[InstSimplify] Handle trunc to i1 in Select with bit test folds. (#122944)Andreas Jonson1-11/+8
Proof: https://alive2.llvm.org/ce/z/Jncqb2
2025-02-01[ValueTracking] Use `SimplifyQuery` in `isKnownNonEqual` (#124942)Yingwei Zheng1-1/+1
It is needed by https://github.com/llvm/llvm-project/pull/117442.
2025-01-11[InstSimpify] Simplifying `(xor (sub C_Mask, X), C_Mask)` -> `X` (#122552)goldsteinn1-0/+16
- **[InstSimpify] Add tests for simplifying `(xor (sub C_Mask, X), C_Mask)`; NFC** - **[InstSimpify] Simplifying `(xor (sub C_Mask, X), C_Mask)` -> `X`** Helps address regressions with folding `clz(Pow2)`. Proof: https://alive2.llvm.org/ce/z/zGwUBp
2025-01-07[InstSimplify] Use multi-op replacement when simplify `select` (#121708)goldsteinn1-49/+57
- **[InstSimplify] Refactor `simplifyWithOpsReplaced` to allow multiple replacements; NFC** - **[InstSimplify] Use multi-op replacement when simplify `select`** In the case of `select X | Y == 0 :...` or `select X & Y == -1 : ...` we can do more simplifications by trying to replace both `X` and `Y` with the respective constant at once. Handles some cases for https://github.com/llvm/llvm-project/pull/121672 more generically.
2025-01-06[InstSimplify] Simplify both operands of select before comparing (#121753)Nikita Popov1-5/+13
In the simplifySelectWithEquivalence fold, simplify both operands before comparing them, instead of comparing one simplified operand with a non-simplified operand. This is slightly more powerful.
2024-12-19[InstCombine] Fold `A == MIN_INT ? B != MIN_INT : A < B` to `A < B` (#120177)Veera1-1/+0
This PR folds: `A == MIN_INT ? B != MIN_INT : A < B` to `A < B` `A == MAX_INT ? B != MAX_INT : A > B` to `A > B` Proof: https://alive2.llvm.org/ce/z/bR6E2s This helps in optimizing comparison of optional unsigned non-zero types in https://github.com/rust-lang/rust/issues/49892. Rust compiler's current output: https://rust.godbolt.org/z/9fxfq3Gn8
2024-12-17[InstSimplify] Treat float binop with identity as refining (#120098)Nikita Popov1-5/+8
If x is NaN, then fmul (x, 1) may produce a different NaN value. Our float semantics explicitly permit folding fmul (x, 1) to x, but we can't do this when we're replacing a select input, as selects are supposed to preserve the exact bitwise value. Fixes https://github.com/llvm/llvm-project/pull/115152#issuecomment-2545773114.
2024-12-13PatternMatch: migrate to CmpPredicate (#118534)Ramkumar Ramachandra1-8/+8
With the introduction of CmpPredicate in 51a895a (IR: introduce struct with CmpInst::Predicate and samesign), PatternMatch is one of the first key pieces of infrastructure that must be updated to match a CmpInst respecting samesign information. Implement this change to Cmp-matchers. This is a preparatory step in migrating the codebase over to CmpPredicate. Since we no functional changes are desired at this stage, we have chosen not to migrate CmpPredicate::operator==(CmpPredicate) calls to use CmpPredicate::getMatching(), as that would have visible impact on tests that are not yet written: instead, we call CmpPredicate::operator==(Predicate), preserving the old behavior, while also inserting a few FIXME comments for follow-ups.
2024-12-09[InstSimplify] Remove foldSelectWithBinaryOp (#118913)Yihang Liu1-45/+0
As mentioned in https://github.com/llvm/llvm-project/issues/118815, the purpose of this simplification is superseded by https://github.com/llvm/llvm-project/pull/76621, so we should have it deleted.
2024-12-03IR: introduce struct with CmpInst::Predicate and samesign (#116867)Ramkumar Ramachandra1-55/+47
Introduce llvm::CmpPredicate, an abstraction over a floating-point predicate, and a pack of an integer predicate with samesign information, in order to ease extending large portions of the codebase that take a CmpInst::Predicate to respect the samesign flag. We have chosen to demonstrate the utility of this new abstraction by migrating parts of ValueTracking, InstructionSimplify, and InstCombine from CmpInst::Predicate to llvm::CmpPredicate. There should be no functional changes, as we don't perform any extra optimizations with samesign in this patch, or use CmpPredicate::getMatching. The design approach taken by this patch allows for unaudited callers of APIs that take a llvm::CmpPredicate to silently drop the samesign information; it does not pose a correctness issue, and allows us to migrate the codebase piece-wise.
2024-12-02[InstSimplify] Generalize simplification of icmps with monotonic operands ↵Nikita Popov1-52/+71
(#69471) InstSimplify currently folds patterns like `(x | y) uge x` and `(x & y) ule x` to true. However, it cannot handle combinations of such situations, such as `(x | y) uge (x & z)` etc. To support this, recursively collect operands of monotonic instructions (that preserve either a greater-or-equal or less-or-equal relationship) and then check whether any of them match. Fixes https://github.com/llvm/llvm-project/issues/69333.
2024-11-19[InstSimplify] Generalize `simplifyAndOrOfFCmps` to handle fabs (#116590)Yingwei Zheng1-10/+14
This patch generalizes https://github.com/llvm/llvm-project/issues/81027 to handle pattern `and/or (fcmp ord/uno X, 0), (fcmp pred fabs(X), Y)`. Alive2: https://alive2.llvm.org/ce/z/tsgUrz The correctness is straightforward because `fcmp ord/uno X, 0.0` is equivalent to `fcmp ord/uno fabs(X), 0.0`. We may generalize it to handle fneg as well. Address comment https://github.com/llvm/llvm-project/pull/116065#pullrequestreview-2434796846
2024-11-15InstSimplify: support floating-point equivalences (#115152)Ramkumar Ramachandra1-33/+54
Since cd16b07 (IR: introduce CmpInst::isEquivalence), there is now an isEquivalence routine in CmpInst that we can use to determine equivalence in simplifySelectWithICmpEq. Implement this, extending the code from integer-equalities to integer and floating-point equivalences.
2024-11-14[InstSimplify] Correctly handle comparison with zero-size allocs (#115728)Nikita Popov1-2/+2
InstSimplify currently folds alloc1 == alloc2 to false, even if one of them is a zero-size allocation. A zero-size allocation may have the same address as another allocation. This also disables the fold for the case where we're comparing a zero-size alloc with the middle of another allocation. It's possible that this case is legal to fold depending on our precise zero-size allocation semantics, but LangRef currently doesn't specify this either way, so we shouldn't make assumptions here.
2024-11-07[InstSimplify] Fix incorrect poison propagation when folding phi (#96631)Nikita Popov1-1/+8
We can only replace phi(X, undef) with X, if X is known not to be poison. Otherwise, the result may be more poisonous on the undef branch. Fixes https://github.com/llvm/llvm-project/issues/68683.
2024-11-01[InstSimplify][InstCombine][ConstantFold] Move vector div/rem by zero fold ↵Yingwei Zheng1-13/+0
to InstCombine (#114280) Previously we fold `div/rem X, C` into `poison` if any element of the constant divisor `C` is zero or undef. However, it is incorrect when threading udiv over an vector select: https://alive2.llvm.org/ce/z/3Ninx5 ``` define <2 x i32> @vec_select_udiv_poison(<2 x i1> %x) { %sel = select <2 x i1> %x, <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 0, i32 1> %div = udiv <2 x i32> <i32 42, i32 -7>, %sel ret <2 x i32> %div } ``` In this case, `threadBinOpOverSelect` folds `udiv <i32 42, i32 -7>, <i32 -1, i32 -1>` and `udiv <i32 42, i32 -7>, <i32 0, i32 1>` into `zeroinitializer` and `poison`, respectively. One solution is to introduce a new flag indicating that we are threading over a vector select. But it requires to modify both `InstSimplify` and `ConstantFold`. However, this optimization doesn't provide benefits to real-world programs: https://dtcxzyw.github.io/llvm-opt-benchmark/coverage/data/zyw/opt-ci/actions-runner/_work/llvm-opt-benchmark/llvm-opt-benchmark/llvm/llvm-project/llvm/lib/IR/ConstantFold.cpp.html#L908 https://dtcxzyw.github.io/llvm-opt-benchmark/coverage/data/zyw/opt-ci/actions-runner/_work/llvm-opt-benchmark/llvm-opt-benchmark/llvm/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp.html#L1107 This patch moves the fold into InstCombine to avoid breaking numerous existing tests. Fixes #114191 and #113866 (only poison-safety issue).
2024-10-14ValueTracking: introduce llvm::isNotCrossLaneOperation (#112011)Ramkumar Ramachandra1-7/+4
Factor out and unify common code from InstSimplify and InstCombine that partially guard against cross-lane vector operations into llvm::isNotCrossLaneOperation in ValueTracking. Alive2 proofs for changed tests: https://alive2.llvm.org/ce/z/68H4ka
2024-09-25[CmpInstAnalysis] Return decomposed bit test as struct (NFC) (#109819)Nikita Popov1-6/+4
decomposeBitTestICmp() currently returns the result via two out parameters plus an in-place modification of Pred. This changes it to return an optional struct instead. The motivation here is twofold. First, I'd like to extend this code to handle cases where the comparison is against a value other than zero, which would mean yet another out parameter. Second, while doing that I was badly bitten by the in-place modification, so I'd like to get rid of it.