2136 Commits

Author SHA1 Message Date
Florian Hahn
a434a7a4f1
Reapply "[LAA,Loads] Use loop guards and max BTC if needed when checking deref. (#155672)"
This reverts commit f0df1e3dd4ec064821f673ced7d83e5a2cf6afa1.

Recommit with extra check for SCEVCouldNotCompute. Test has been added in
b16930204b.

Original message:
Remove the fall-back to constant max BTC if the backedge-taken-count
cannot be computed.

The constant max backedge-taken count is computed considering loop
guards, so to avoid regressions we need to apply loop guards as needed.

Also remove the special handling for Mul in willNotOverflow, as this
should not longer be needed after 914374624f
(https://github.com/llvm/llvm-project/pull/155300).

PR: https://github.com/llvm/llvm-project/pull/155672
2025-09-03 12:45:28 +01:00
Florian Hahn
f0df1e3dd4
Revert "[LAA,Loads] Use loop guards and max BTC if needed when checking deref. (#155672)"
This reverts commit 08001cf340185877665ee381513bf22a0fca3533.

This triggers an assertion in some build configs, e.g.
 https://lab.llvm.org/buildbot/#/builders/24/builds/12211
2025-09-02 21:44:30 +01:00
Florian Hahn
08001cf340
[LAA,Loads] Use loop guards and max BTC if needed when checking deref. (#155672)
Remove the fall-back to constant max BTC if the backedge-taken-count
cannot be computed.

The constant max backedge-taken count is computed considering loop
guards, so to avoid regressions we need to apply loop guards as needed.

Also remove the special handling for Mul in willNotOverflow, as this
should not longer be needed after 914374624f
(https://github.com/llvm/llvm-project/pull/155300).

PR: https://github.com/llvm/llvm-project/pull/155672
2025-09-02 18:58:33 +01:00
Florian Hahn
fb7c0d70a7
[SCEV] Rewrite some SCEVAdd sub-expressions using loop guards. (#156013)
Trip count expressions sometimes consist of adding 3 operands, i.e.
(Const + A + B). There may be guard info for A + B, and if so, apply it.

We can probably more generally apply this, but need to be careful w.r.t
compile-time.

Alive2 Proof for changes in miniters.ll:
https://alive2.llvm.org/ce/z/HFfXOx

Fixes https://github.com/llvm/llvm-project/issues/155941.

PR: https://github.com/llvm/llvm-project/pull/156013
2025-09-01 14:01:15 +01:00
annamthomas
00926a6db6
[SCEV][LAA] Support multiplication overflow computation (#155236)
Add support for identifying multiplication overflow in SCEV.
This is needed in LoopAccessAnalysis and that limitation was worked
around by 484417a.
This allows early-exit vectorization to work as expected in
vect.stats.ll test without needing the workaround.
2025-08-27 12:11:32 +00:00
Florian Hahn
914374624f
[SCEV] Try to push op into ZExt: C * zext (A + B) -> zext (A*C + B*C) (#155300)
Try to push constant multiply operand into a ZExt containing an add, if
possible. In general we are trying to push down ops through ZExt if
possible. This is similar to
https://github.com/llvm/llvm-project/pull/151227 which did the same for
additions.

For now this is restricted to adds with a constant operand, which is
similar to some of the logic above.

This enables some additional simplifications.

Alive2 Proof: https://alive2.llvm.org/ce/z/97pbSL

PR: https://github.com/llvm/llvm-project/pull/155300
2025-08-26 19:31:50 +01:00
Florian Hahn
5faed1ad84
[VPlan] Add VPlan-based addMinIterCheck, replace ILV for non-epilogue. (#153643)
This patch adds a new VPlan-based addMinimumIterationCheck, which
replaced the ILV version for the non-epilogue case.

The VPlan-based version constructs a SCEV expression to compute the
minimum iterations, use that to check if the check is known true or
false. Otherwise it creates a VPExpandSCEV recipe and emits a
compare-and-branch.

When using epilogue vectorization, we still need to create the minimum
trip-count-check during the legacy skeleton creation. The patch moves
the definitions out of ILV.

PR: https://github.com/llvm/llvm-project/pull/153643
2025-08-26 15:52:31 +01:00
Kazu Hirata
11b4f110e0
[llvm] Remove unused includes of SmallSet.h (NFC) (#154893)
We just replaced SmallSet<T *, N> with SmallPtrSet<T *, N>, bypassing
the redirection found in SmallSet.h.  With that, we no longer need to
include SmallSet.h in many files.
2025-08-22 10:33:46 -07:00
Kazu Hirata
07eb7b7692
[llvm] Replace SmallSet with SmallPtrSet (NFC) (#154068)
This patch replaces SmallSet<T *, N> with SmallPtrSet<T *, N>.  Note
that SmallSet.h "redirects" SmallSet to SmallPtrSet for pointer
element types:

  template <typename PointeeType, unsigned N>
class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N>
{};

We only have 140 instances that rely on this "redirection", with the
vast majority of them under llvm/. Since relying on the redirection
doesn't improve readability, this patch replaces SmallSet with
SmallPtrSet for pointer element types.
2025-08-18 07:01:29 -07:00
Florian Hahn
36be0bba2a
[SCEV] Check if predicate is known false for predicated AddRecs. (#151134)
Similarly to https://github.com/llvm/llvm-project/pull/131538, we can
also try and check if a predicate is known to wrap given the backedge
taken count.

For now, this just checks directly when we try to create predicated
AddRecs. This both helps to avoid spending compile-time on optimizations
where we know the predicate is false, and can also help to allow
additional vectorization (e.g. by deciding to scalarize memory accesses
when otherwise we would try to create a predicated AddRec with a
predicate that's always false).

The initial version is quite restricted, but can be extended in
follow-ups to cover more cases.

PR: https://github.com/llvm/llvm-project/pull/151134
2025-08-15 09:30:25 +01:00
Sushant Gokhale
e8918c318e
[SCEV] Consider non-volatile memory intrinsics as not having side-effect for forward progress (#150916)
For the attached test:
Before the loop-idiom pass, we have a store into the inner loop which is
considered simple and one that does not have any side effects on the
loop. Post loop-idiom pass, we get a memset into the outer loop that is
considered to introduce side effects on the loop. This changes the
backedge taken count before and after the pass and hence, the crash with
verify-scev.

We try to consider non-volatile memory intrinsics as not having
side-effect for forward progress to fix the issue.

Fixes #149377
2025-08-11 00:24:50 -07:00
Florian Hahn
ab9b23c446
[SCEV] Use pattern match to check ZExt(Add()). (NFC)
Follow-up to
https://github.com/llvm/llvm-project/pull/151227#pullrequestreview-3074670031
to check the inner expression is an Add before calling getTruncateExpr.

Adds a new matcher that just matches and captures SCEVAddExpr, to
support matching a SCEVAddExpr with arbitrary number of operands.
2025-07-31 12:47:14 +01:00
Florian Hahn
d74d841b65
[SECV] Try to push the op into ZExt: A + zext (-A + B) -> zext (B) (#151227)
Try to push the constant operand into a ZExt:
A + zext (-A + B) -> zext (B), if trunc (A) + -A + B does not
unsigned-wrap.

The actual code supports ZExts with arbitrary number of arguments, hence
the getAddExpr in the return.

This helps SCEV reasoning in some cases, commonly when adding an offset
to a zero-extended SCEV that subtracts the same offset.

Note that this is restricted to cases where we can fold away an operand
of the inner Add. This is needed to avoid bad interactions with patterns
when forming ZExts, which try to push to ZExt to add operands.

https://alive2.llvm.org/ce/z/q7d303

PR: https://github.com/llvm/llvm-project/pull/151227
2025-07-30 21:10:57 +01:00
Florian Hahn
6c50e2b2dd
[SCEV] Don't require NUW at first add when checking A+C1 < (A+C2)<nuw> (#149795)
Relax the NUW requirements for isKnownPredicateViaNoOverflow, if the
second operand (Y) is an ADD. The code only simplifies the condition if
C1 < C2, so if the second ADD is NUW, it doesn't matter whether the
first operand also has the NUW flag, as it cannot wrap if C1 < C2.

https://alive2.llvm.org/ce/z/b3dM7N


PR: https://github.com/llvm/llvm-project/pull/149795
2025-07-23 09:33:34 +01:00
Arthur Eubanks
1cd2165afe
[SCEV] Take global variable linkage into account when comparing values (#148071)
Current the comparator is inconsistent when we have two external globals
and one internal globals due to
```
    if (IsGVNameSemantic(LGV) && IsGVNameSemantic(RGV))
      return LGV->getName().compare(RGV->getName());
```

The internal global compares equal to (not strictly less than) the
external globals, but the external globals are not equal.

Fixes #147862.
2025-07-11 09:36:34 -07:00
Ramkumar Ramachandra
d440809f4e
[SCEV] Improve code using DenseMap::lookup (NFC) (#147507) 2025-07-08 15:35:17 +01:00
Ramkumar Ramachandra
830c0b7957
[SCEV] Improve code in isKnownPredicateViaConstantRanges (NFC) (#147335) 2025-07-07 21:33:16 +01:00
Ramkumar Ramachandra
d945cd645a
[SCEV] Improve code in isImpliedCondOperands (NFC) (#147347) 2025-07-07 21:32:49 +01:00
Florian Hahn
8f79754225
[SCEV] Better preserve wrapping info in SimplifyICmpOperands for UGE. (#144404)
Update SimplifyICmpOperands to only try subtracting 1 from RHS first, if
RHS is an op we can fold the subtract directly into. Otherwise try
adding to LHS first, as we can preserve NUW flags.

This improves results in a few cases, including the modified test case
from berkeley-abc and new code to be added in
https://github.com/llvm/llvm-project/pull/128061.

Note that there are more cases where the results can be improved by
better ordering here which I'll try to investigate as follow-up.

PR: https://github.com/llvm/llvm-project/pull/144404
2025-06-17 15:30:08 +01:00
Ramkumar Ramachandra
b40e4ceaa6
[ValueTracking] Make Depth last default arg (NFC) (#142384)
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-06-03 17:12:24 +01:00
Ramkumar Ramachandra
4bf67cdf02
[DenseMap] Fix constness issues with lookup_or (#139247)
Also demonstrate its use in ScalarEvolution.
2025-05-28 20:32:31 +02:00
Florian Hahn
bc0c4db5d9
[SCEV] Add dedicated AffineAddRec matcher + loop matchers (NFC). (#141141)
Add dedicated m_scev_AffineAddRec matcher with 
complementing m_Loop() and m_SpecificLoop matchers.

PR: https://github.com/llvm/llvm-project/pull/141141
2025-05-25 08:40:31 +01:00
Kazu Hirata
0918361d8b
[Analysis] Remove unused includes (NFC) (#141319)
These are identified by misc-include-cleaner.  I've filtered out those
that break builds.  Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
2025-05-23 23:59:56 -07:00
Kazu Hirata
cc78177e8f
[llvm] Use *Map::try_emplace (NFC) (#141190)
try_emplace can default-construct values, so we do not need to do so
on our own.  Plus, try_emplace(Key) is much simpler/shorter than
insert({Key, LongValueType()}).
2025-05-22 23:50:58 -07:00
Sebastian Pop
2c6b239cc6
[DA] handle memory accesses with different offsets and strides (#123436)
This patch corrects the behavior of the Dependence Analysis for memory
accesses that do not start at the same offset or do not have similar
strides. When offsets or strides cannot be disambiguated at compile
time, DA collects a set of runtime assumptions under which the
dependence test becomes valid. The default remains the same as before
the patch: DA rejects the dependence test as undecidable instead of
collecting runtime assumptions.

---------

Co-authored-by: Michael Kruse <github@meinersbur.de>
Co-authored-by: Ryotaro Kasuga <kasuga.ryotaro@fujitsu.com>
2025-05-19 09:08:59 -05:00
Ramkumar Ramachandra
61d3ad963c
[SCEVPatternMatch] Introduce m_scev_AffineAddRec (#140377)
Introduce m_scev_AffineAddRec to match affine AddRecs, a class_match for
SCEVConstant, and demonstrate their utility in LSR and SCEV. While at
it, rename m_Specific to m_scev_Specific for clarity.
2025-05-19 12:02:07 +01:00
Ramkumar Ramachandra
acd6294120
[SCEV] Improve code in SCEVLoopGuardRewriter (NFC) (#139257)
Prefer DenseMap::lookup over DenseMap::find.
2025-05-11 13:45:24 +01:00
Ramkumar Ramachandra
458991197d
[SCEVPatternMatch] Extend with more matchers (#138836) 2025-05-09 09:20:14 +01:00
Rahul Joshi
7245e21e89
[NFC][Support] Add llvm::uninitialized_copy (#138174)
Add `llvm::uninitialized_copy` that accepts a range instead of start/end
iterator for the source of the copy.
2025-05-07 17:37:38 -07:00
Vikram Hegde
f91a6e6dab
[SCEV] Reject comparision of pointers to different address spaces in SCEVWrapPredicate::implies (#137935) 2025-04-30 21:03:31 +05:30
Kazu Hirata
2e230f5685
[llvm] Use llvm::interleaved (NFC) (#137496) 2025-04-26 23:28:46 -07:00
Rahul Joshi
99e4b3927c
[LLVM] Cleanup pass initialization for Analysis passes (#135858)
- 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-04-21 12:36:34 -07:00
Kazu Hirata
c4e9901b5b
[llvm] Use llvm::append_range (NFC) (#135931) 2025-04-16 12:28:47 -07:00
Yingwei Zheng
bb9580a02b
[SCEV] Use ashr to adjust constant multipliers (#135534)
SCEV converts "-2 *nsw (i32 V)" into "2148473647 *nsw (i32 V)". But we
cannot preserve the nsw flag when the constant multiplier is negative.
This patch changes lshr to ashr so that we can preserve both nsw and nuw
flags.

Alive2 proof: https://alive2.llvm.org/ce/z/LZVSEa
Closes https://github.com/llvm/llvm-project/issues/135531.
2025-04-13 20:22:48 +08:00
Ramkumar Ramachandra
2ac11daf92
[SCEV] Improve code around constant TC (NFC) (#133261) 2025-04-07 21:52:36 +01:00
Yingwei Zheng
65ed35393c
[IR] Add helper CmpPredicate::dropSameSign (#134071)
Address review comment
https://github.com/llvm/llvm-project/pull/133711#discussion_r2024519641
2025-04-02 22:25:01 +08:00
Yingwei Zheng
f066d7504e
[Reland][SCEV] teach isImpliedViaOperations about samesign (#133711)
This patch relands https://github.com/llvm/llvm-project/pull/124270.
Closes https://github.com/llvm/llvm-project/issues/126409.

The root cause is that we incorrectly preserve the samesign flag after
truncating operands of an icmp:
https://alive2.llvm.org/ce/z/4NE9gS

---------

Co-authored-by: Ramkumar Ramachandra <ramkumar.ramachandra@codasip.com>
2025-04-02 18:45:33 +08:00
Arthur Eubanks
e8711436b3
[SCEV] Remove EqCacheSCEV (#133186)
This was added in https://reviews.llvm.org/D26389 to help with extremely
deep SCEV expressions.

However, this is wrong since we may cache sub-SCEVs to be equivalent
that CompareValueComplexity returned 0 due to hitting the max comparison
depth.

This also improves compile time in some compiles:

https://llvm-compile-time-tracker.com/compare.php?from=34fa037c4fd7f38faada5beedc63ad234e904247&to=e241ecf999f4dd42d4b951d4a5d4f8eabeafcff0&stat=instructions:u

Similar to #100721.

Fixes #130688.
2025-04-01 09:02:33 -07:00
Kazu Hirata
fe3e9c2b46
[Analysis] Avoid repeated hash lookups (NFC) (#133045) 2025-03-31 23:17:44 -07:00
Kazu Hirata
8f5c3deadd
[Analysis] Use llvm::append_range (NFC) (#133602) 2025-03-29 16:52:36 -07:00
Kazu Hirata
d4427f308e
[llvm] Use range constructors of *Set (NFC) (#133549) 2025-03-28 19:55:18 -07:00
Yingwei Zheng
c5a491e9ea
[SCEV] Check whether the start is non-zero in ScalarEvolution::howFarToZero (#131522)
https://github.com/llvm/llvm-project/pull/94525 assumes that the loop
will be infinite when the stride is zero. However, it doesn't hold when
the start value of addrec is also zero.

Closes https://github.com/llvm/llvm-project/issues/131465.
2025-03-17 13:59:16 +08:00
Ramkumar Ramachandra
3019e49ebf
SCEV: thread samesign in isBasicBlockEntryGuardedByCond (NFC) (#125840)
isBasicBlockEntryGuardedByCond inadvertedenly drops samesign information
when calling ICmpInst::getNonStrictPredicate. Fix this.
2025-02-10 14:47:13 +00:00
Ramkumar Ramachandra
c6b13a2871
Revert "SCEV: teach isImpliedViaOperations about samesign" (#126506)
The commit f5d24e6c is buggy, and following miscompiles have been
reported: #126409 and
https://github.com/llvm/llvm-project/pull/124270#issuecomment-2647222903

Revert it while we investigate.
2025-02-10 13:31:18 +00:00
Nikita Popov
7aed53eb19
[ScalarEvolution] Handle addrec incoming value in isImpliedViaMerge() (#126236)
The code already guards against values coming from a previous iteration
using properlyDominates(). However, addrecs are considered to properly
dominate the loop they are defined in.

Handle this special case separately, by checking for expressions that
have computable loop evolution (this should cover cases like a zext of
an addrec as well).

I considered changing the definition of properlyDominates() instead, but
decided against it. The current definition is useful in other context,
e.g. when deciding whether an expression is safe to expand in a given
block.

Fixes https://github.com/llvm/llvm-project/issues/126012.
2025-02-10 10:07:21 +01:00
Ramkumar Ramachandra
f5d24e6cbe
SCEV: teach isImpliedViaOperations about samesign (#124270)
Use CmpPredicate::getMatching in isImpliedCondBalancedTypes to pass
samesign information to isImpliedViaOperations, and teach it to call
CmpPredicate::getPreferredSignedPredicate, effectively making it
optimize with samesign information.
2025-02-06 18:14:54 +00:00
Ramkumar Ramachandra
65136a3530
SCEV: migrate LoopInvariantPredicate to CmpPredicate (NFC) (#125204)
Follow up on 60dc450 (SCEV: migrate to CmpPredicate (NFC)) to migrate
the missed ScalarEvolution::LoopInvariantPredicate to CmpPredicate.
2025-01-31 16:50:48 +00:00
Nikita Popov
07efe2c18a
[SCEV] Check correct value for UB (#124302)
This is a followup to #117152. That patch introduced a check for
UB/poison on BEValue. However, the SCEV we're actually going to use is
Shifted. In some cases, it's possible for Shifted to contain UB, while
BEValue doesn't.

In the test case the values are:

BEValue: (-1 * (zext i8 (-83 + ((-83 /u {1,+,1}<%loop>) *
{-1,+,-1}<%loop>)) to i32))<nuw><nsw>
Shifted: (-173 + (-1 * (zext i8 ((-83 /u {0,+,1}<%loop>) *
{0,+,-1}<%loop>) to i32))<nuw><nsw>)<nuw><nsw>

Fixes https://github.com/llvm/llvm-project/issues/123550.
2025-01-29 09:09:14 +01:00
Mats Jun Larsen
d7c14c8f97
[IR] Replace of PointerType::getUnqual(Type) with opaque version (NFC) (#123909)
Follow up to https://github.com/llvm/llvm-project/issues/123569
2025-01-23 18:23:05 +09:00
Julian Nagele
137d706739
[SCEV] Do not attempt to collect loop guards for loops without predecessor. (#123662)
Attempting to collect loop guards for loops without a predecessor can
lead to non-terminating recursion trying to construct a SCEV.

Fixes https://github.com/llvm/llvm-project/issues/122913.
2025-01-22 18:36:37 +00:00