245 Commits

Author SHA1 Message Date
Manasij Mukherjee
0fdf9b9676
[ConstraintElim] Infer linear constraints from udiv and urem (#180689)
urem x, n: result < n (remainder is always less than divisor)
urem x, n: result <= x (remainder is at most the dividend)
udiv x, n: result <= x (quotient is at most the dividend)

https://alive2.llvm.org/ce/z/ezzsjQ
2026-02-10 22:25:13 +08:00
Ramkumar Ramachandra
d3b3940a71
[ConstraintElim] Use try_emplace to improve code (NFC) (#178186) 2026-01-27 14:13:39 +00:00
Ramkumar Ramachandra
e516dd1bf2
[ConstraintElim] Strip IsKnownNonNegative (NFC) (#177993)
The IsKnownNonNegative field is redundant, as the use of ValueTracking's
isKnownNonNegative subsumes this.

Proof: https://github.com/dtcxzyw/llvm-opt-benchmark/pull/3390
2026-01-26 19:57:13 +00:00
Victor Chernyakin
c438773432
[LLVM][ADT] Migrate users of make_scope_exit to CTAD (#174030)
This is a followup to #173131, which introduced the CTAD functionality.
2026-01-02 20:42:56 -08:00
Florian Hahn
daf0182277
[ConstraintElim] Apply add with neg constant first during decomp. (#164791)
We have dedicated decomposition logic for (add %x, -C), but if we have
(add nsw %x, -C) we will first apply the generic logic for NSWAdd, which
gives worse results for negative constants in practice.

Update the code to first apply the pattern with negative constants.

Helps to remove a number of runtime checks in practice:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2968

Alive2 proofs for the test changes: https://alive2.llvm.org/ce/z/JfR2Ma

PR: https://github.com/llvm/llvm-project/pull/164791
2025-10-23 12:50:12 +01:00
Yingwei Zheng
d91a5c33df
[ConstraintElim] Bail out on non-canonical GEPs (#156688)
In most cases, GEPs should be canonicalized by InstCombine. Bail out on
non-canonical forms for simplicity.
Fixes
https://github.com/llvm/llvm-project/pull/155253#issuecomment-3248457478.
2025-09-03 15:42:52 +00:00
Yingwei Zheng
89f53af3ff
[ConstraintElim] Use constraints from bounded memory accesses (#155253)
This patch removes bound checks that are dominated by bounded memory
accesses. For example, if we have an array `int A[5]` and `A[idx]` is
performed successfully, we know that `idx u< 5` after the load.

compile-time impact (+0.1%):
https://llvm-compile-time-tracker.com/compare.php?from=f0e9bba024d44b55d54b02025623ce4a3ba5a37c&to=5227b08a4a514159ec524d1b1ca18ed8ab5407df&stat=instructions%3Au
llvm-opt-benchmark:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2709

Proof: https://alive2.llvm.org/ce/z/JEyjA2
2025-09-02 21:41:02 +08:00
Jeremy Morse
c9ceb9b75f
[DebugInfo] Remove intrinsic-flavours of findDbgUsers (#149816)
This is one of the final remaining debug-intrinsic specific codepaths
out there, and pieces of cross-LLVM infrastructure to do with debug
intrinsics.
2025-07-21 17:49:25 +01:00
Jeremy Morse
2a1869b981
[DebugInfo] Shave even more users of DbgVariableIntrinsic from LLVM (#149136)
At this stage I'm just opportunistically deleting any code using
debug-intrinsic types, largely adjacent to calls to findDbgUsers. I'll
get to deleting that in probably one or more two commits.
2025-07-18 08:25:10 +01:00
Kazu Hirata
03f616eb3a
[llvm] Compare std::optional<T> to values directly (NFC) (#143340)
This patch transforms:

  X && *X == Y

to:

  X == Y

where X is of std::optional<T>, and Y is of T or similar.
2025-06-08 22:37:59 -07:00
Yingwei Zheng
287294d54d
[ConstraintElim] Do not allow overflows in Decomposition (#140541)
Consider the following case:
```
define i1 @pr140481(i32 %x) {
  %cond = icmp slt i32 %x, 0
  call void @llvm.assume(i1 %cond)
  %add = add nsw i32 %x, 5001000
  %mul1 = mul nsw i32 %add, -5001000
  %mul2 = mul nsw i32 %mul1, 5001000
  %cmp2 = icmp sgt i32 %mul2, 0
  ret i1 %cmp2
}
```
Before this patch, `decompose(%mul2)` returns `-25010001000000 * %x +
4052193514966861312`.
Therefore, `%cmp2` will be simplified into true because `%x s< 0 &&
-25010001000000 * %x + 4052193514966861312 s<= 0` is unsat.

It is incorrect since the offset `-25010001000000 * 5001000 ->
4052193514966861312` signed wraps.
This patch treats a decomposition as invalid if overflows occur when
computing coefficients.

Closes https://github.com/llvm/llvm-project/issues/140481.
2025-05-22 11:31:04 +08:00
Yingwei Zheng
aa054c6810
[ConstraintElim] Simplify and/or instead of replacing its operand (#139874)
In `checkOrAndOpImpliedByOther`, replacing an operand of a disjoint or
is unsafe: https://alive2.llvm.org/ce/z/4R4hxN
This patch performs the simplification directly, to avoid miscompilation
and unnecessary canonicalization.

Closes https://github.com/llvm/llvm-project/issues/137937.
2025-05-14 23:37:41 +08:00
Shan Huang
f49ee00ec4
[DebugInfo][ConstraintElimination] Fix debug value loss in replacing comparisons with the speculated constants (#136839)
Fix #135736
2025-05-05 21:08:58 +08:00
Iris Shi
b54b3e81f2
Recommit "[ConstraintElim] Simplify cmp after uadd.sat/usub.sat (#135603)" (#136467) 2025-04-30 21:49:18 +08:00
Kazu Hirata
b2ba53172e
[Transforms] Construct SmallVector with iterator ranges (NFC) (#136259) 2025-04-18 10:27:05 -07:00
Arthur Eubanks
be9f72cf37 Revert "[ConstraintElim] Simplify cmp after uadd.sat/usub.sat (#135603)"
This reverts commit fe54d1afcca055f464840654dd2ec3fd83aea688.

Causes miscompiles, see #135603.
2025-04-18 15:37:37 +00:00
Iris
5307040473
[NFC] Fix auto* warning (#135765) 2025-04-15 17:14:39 +08:00
Iris
fe54d1afcc
[ConstraintElim] Simplify cmp after uadd.sat/usub.sat (#135603)
- Closes #135557
2025-04-14 20:15:55 +08:00
Lee Wei
f7cc213d58
[ConstraintSystem] Update comments (#127351)
It took me some time to fully understand the implementation of
Fourier–Motzkin elimination in the Constraint System, so I added an
example in the comments. Hopefully future developers can understand the
algorithm more easily with the example.
2025-04-08 00:22:47 +08:00
Andreas Jonson
4b29c28564
[ConstraintElim] Preserve analyses when IR is unchanged. (#128588) 2025-02-25 14:22:55 +01:00
Marina Taylor
72768d9bb8
[ConstraintElim] Teach checkAndReplaceCondition about samesign (#128168)
`samesign upred` is equivalent to `spred`:
https://alive2.llvm.org/ce/z/57iaEC
2025-02-24 13:07:47 +00:00
Lee Wei
edc8c35247
[ConstraintElimination] Fix comment (#125375)
Remove unused header and fix a comment.
2025-02-03 10:21:33 +08:00
Jeremy Morse
8e70273509
[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)
As part of the "RemoveDIs" project, BasicBlock::iterator now carries a
debug-info bit that's needed when getFirstNonPHI and similar feed into
instruction insertion positions. Call-sites where that's necessary were
updated a year ago; but to ensure some type safety however, we'd like to
have all calls to moveBefore use iterators.

This patch adds a (guaranteed dereferenceable) iterator-taking
moveBefore, and changes a bunch of call-sites where it's obviously safe
to change to use it by just calling getIterator() on an instruction
pointer. A follow-up patch will contain less-obviously-safe changes.

We'll eventually deprecate and remove the instruction-pointer
insertBefore, but not before adding concise documentation of what
considerations are needed (very few).
2025-01-24 10:53:11 +00:00
Stephen Senran Zhang
7fb97bee92
[ConstraintElimination] Add eq/ne facts to signed constraint system (#121423)
Facts of eq/ne were added to unsigned system only, causing some missing
optimizations. This patch adds eq/ne facts to both signed & unsigned
constraint system.

Fixes #117961.
2025-01-23 11:00:31 +01:00
Stephen Senran Zhang
2a90efd854
[NFC][ConstraintElimination] Optimize code styles (#121422)
This patch does following things,

- prefer early exits;
- add missing std::move;
- avoid duplicate map lookups;
- prefer emplace_back to avoid unnecessary copies.
2025-01-01 09:53:31 -08:00
Yingwei Zheng
003fb2aeb4
[ConstraintElim] Decompose sub nsw (#118219)
Closes https://github.com/llvm/llvm-project/issues/118211.
2024-12-16 16:41:04 +08:00
Ramkumar Ramachandra
a22578d38c
ConstraintElim: teach fact-transfer about samesign (#115893)
When the samesign flag is present on an icmp, we can transfer all the
facts on the unsigned system to the signed system, and vice-versa: we do
this by specializing transferToOtherSystem when samesign is present.
2024-12-15 17:31:58 +00:00
Ramkumar Ramachandra
4a0d53a0b0
PatternMatch: migrate to CmpPredicate (#118534)
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-13 14:18:33 +00:00
Yingwei Zheng
5fa59edfa7
[ConstraintElim] Add support for trunc nsw/nuw (#118745)
Proof for `trunc nsw nneg X -> trunc nuw X`:
https://alive2.llvm.org/ce/z/ooP6Mt
2024-12-06 23:15:31 +08:00
Nikita Popov
a608607fd7
[ConstraintElim] Add support for decomposing gep nuw (#118639)
ConstraintElimination currently only supports decomposing gep nusw with
non-negative indices (with "non-negative" possibly being enforced via
pre-condition).

Add support for gep nuw, which directly gives us the necessary
guarantees for the decomposition.
2024-12-04 16:27:31 +01:00
Nikita Popov
10223c72a9 [ConstraintElim] Use nusw flag for GEP decomposition
Check for nusw instead of inbounds when decomposing GEPs.

In this particular case, we can also look through multiple nusw
flags, because we will ultimately be working in the unsigned
constraint system.
2024-12-03 15:56:29 +01:00
Yingwei Zheng
0f0c0c36e3
[ConstraintElim] Extend checkOrAndOpImpliedByOther to handle and/or expr trees. (#117123)
This patch extends `checkOrAndOpImpliedByOther` to handle and/or trees.
Limitation: At least one of the operands of root and/or instruction
should be an icmp. That is, this patch doesn't support expressions like
`(cmp1 & cmp2) & (cmp3 & cmp4)`.

Closes https://github.com/llvm/llvm-project/issues/117107.
Compile-time impact:
http://llvm-compile-time-tracker.com/compare.php?from=69cc3f096ccbdef526bbd5a065a25c95122e87ee&to=919416d2c4c71e3b9fe533af2c168a36c7893be5&stat=instructions%3Au
2024-11-27 09:04:52 +08:00
Ramkumar Ramachandra
2b5214b9e1
IR: de-duplicate two CmpInst routines (NFC) (#116866)
De-duplicate the functions getSignedPredicate and getUnsignedPredicate,
nearly identical versions of which were present in CmpInst and ICmpInst,
creating less confusion.
2024-11-20 09:30:35 +00:00
Yingwei Zheng
52361d0368
[ConstraintElim] Bail out on non-dedicated exits when adding exiting conditions (#116627)
This patch bails out non-dedicated exits to avoid adding exiting
conditions to invalid context.
Closes https://github.com/llvm/llvm-project/issues/116553.
2024-11-18 23:41:04 +08:00
Ramkumar Ramachandra
856c47b884
ConstraintElim: assert on invalid union field (NFC) (#115898)
getContextInst currently returns an invalid union field, when it is
called with a ConditionFact, although existing callers don't do this. In
order to error out early and serve as documentation for future callers,
add an assert forbidding the behavior.
2024-11-13 12:05:53 +00:00
Jeremy Morse
96f37ae453
[NFC] Use initial-stack-allocations for more data structures (#110544)
This replaces some of the most frequent offenders of using a DenseMap that
cause a malloc, where the typical element-count is small enough to fit in
an initial stack allocation.

Most of these are fairly obvious, one to highlight is the collectOffset
method of GEP instructions: if there's a GEP, of course it's going to have
at least one offset, but every time we've called collectOffset we end up
calling malloc as well for the DenseMap in the MapVector.
2024-09-30 23:15:18 +01:00
Youngsuk Kim
d31e314131 [llvm] Don't call raw_string_ostream::flush() (NFC)
Don't call raw_string_ostream::flush(), which is essentially a no-op.
As specified in the docs, raw_string_ostream is always unbuffered.
( 65b13610a5226b84889b923bae884ba395ad084d for further reference )
2024-09-20 12:19:59 -05:00
Yingwei Zheng
85b6aac7c2
[ConstraintElim] Fix miscompilation caused by PR97974 (#105790)
Fixes https://github.com/llvm/llvm-project/issues/105785.
2024-08-23 16:06:00 +08:00
Nikita Popov
73d835ccec [ConstraintElimination] Use getAllOnesValue()
Split out from https://github.com/llvm/llvm-project/pull/80309.
2024-08-12 16:37:42 +02:00
Poseydon42
d18ca43edc
[ConstraintElimination] Add support for UCMP/SCMP intrinsics (#97974)
This adds checks to fold calls to `ucmp`/`scmp` where a comparative
relationship between the arguments can be established.
2024-07-10 21:59:59 +02:00
Florian Hahn
5b927130b0
[ConstraintElim] Use cond from header as upper bound on IV in exit BB. (#94610)
For loops, we can use the condition in the loop header as upper bound on
the compared induction in the unique exit block, if it exists. This can
be done even if there are multiple in-loop edges to the unique exit
block, as any other exit may only exit earlier.

More generally, we could add the OR of all exit conditions to the exit,
but that's a possible future extension.

PR: https://github.com/llvm/llvm-project/pull/94610
2024-07-09 19:37:38 +01:00
Nikita Popov
74deadf196
[IRBuilder] Don't include Module.h (NFC) (#97159)
This used to be necessary to fetch the DataLayout, but isn't anymore.
2024-06-29 15:05:04 +02:00
Nikita Popov
9df71d7673
[IR] Add getDataLayout() helpers to Function and GlobalValue (#96919)
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-28 08:36:49 +02:00
Stephen Tozer
d75f9dd1d2 Revert "[IR][NFC] Update IRBuilder to use InsertPosition (#96497)"
Reverts the above commit, as it updates a common header function and
did not update all callsites:

  https://lab.llvm.org/buildbot/#/builders/29/builds/382

This reverts commit 6481dc57612671ebe77fe9c34214fba94e1b3b27.
2024-06-24 18:00:22 +01:00
Stephen Tozer
6481dc5761
[IR][NFC] Update IRBuilder to use InsertPosition (#96497)
Uses the new InsertPosition class (added in #94226) to simplify some of
the IRBuilder interface, and removes the need to pass a BasicBlock
alongside a BasicBlock::iterator, using the fact that we can now get the
parent basic block from the iterator even if it points to the sentinel.
This patch removes the BasicBlock argument from each constructor or call
to setInsertPoint.

This has no functional effect, but later on as we look to remove the
`Instruction *InsertBefore` argument from instruction-creation
(discussed
[here](https://discourse.llvm.org/t/psa-instruction-constructors-changing-to-iterator-only-insertion/77845)),
this will simplify the process by allowing us to deprecate the
InsertPosition constructor directly and catch all the cases where we use
instructions rather than iterators.
2024-06-24 17:27:43 +01:00
Florian Hahn
ba0e871db8
[ConstraintElim] Look through SExt with precond Op sge 0.
Look through SExt with a precondition that the operand is signed
positive.

https://alive2.llvm.org/ce/z/zvVVHj
2024-05-22 13:11:04 +01:00
Florian Hahn
8a5d51b039
[ConstraintElim] Use default depth for most calls of isNonNegative.
Helps to improve resuls in some cases, while being overall neutral with
respect to compile-time,
https://llvm-compile-time-tracker.com/compare.php?from=2c9b6c1b36b8185299de083c3058e0c1e7760442&to=5984b1649dc12741308089de235647cf036df95f&stat=instructions:u
2024-02-28 13:14:40 +00:00
Yingwei Zheng
87b1e735b2
[ConstraintElim] Decompose sext-like insts for signed predicates (#82344)
Alive2: https://alive2.llvm.org/ce/z/A8dtGp
Fixes #82271.
2024-02-23 01:16:39 +08:00
Alexander Shaposhnikov
4d8e849dfb
[ConstraintElim] Add facts for llvm.abs >= 0 (#79070)
Add facts for llvm.abs >= 0.

https://alive2.llvm.org/ce/z/GXnMHu
2024-02-06 15:16:41 -08:00
Yingwei Zheng
bc9c2be357
[ConstraintElim] Simplify MinMaxIntrinsic (#75306)
This patch replaces min/max intrinsic with one of its operands if
possible.
Alive2: https://alive2.llvm.org/ce/z/LoHfYf
Fixes #75155.
2024-02-04 21:07:40 +08:00