762 Commits

Author SHA1 Message Date
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
Stephen Tozer
aa8a1fa6f5
[DLCov][NFC] Annotate intentionally-blank DebugLocs in existing code (#136192)
Following the work in PR #107279, this patch applies the annotative
DebugLocs, which indicate that a particular instruction is intentionally
missing a location for a given reason, to existing sites in the compiler
where their conditions apply. This is NFC in ordinary LLVM builds (each
function `DebugLoc::getFoo()` is inlined as `DebugLoc()`), but marks the
instruction in coverage-tracking builds so that it will be ignored by
Debugify, allowing only real errors to be reported. From a developer
standpoint, it also communicates the intentionality and reason for a
missing DebugLoc.

Some notes for reviewers:

- The difference between `I->dropLocation()` and
`I->setDebugLoc(DebugLoc::getDropped())` is that the former _may_ decide
to keep some debug info alive, while the latter will always be empty; in
this patch, I always used the latter (even if the former could
technically be correct), because the former could result in some
(barely) different output, and I'd prefer to keep this patch purely NFC.
- I've generally documented the uses of `DebugLoc::getUnknown()`, with
the exception of the vectorizers - in summary, they are a huge cause of
dropped source locations, and I don't have the time or the domain
knowledge currently to solve that, so I've plastered it all over them as
a form of "fixme".
2025-06-11 17:42:10 +01: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
Ramkumar Ramachandra
f07fc38a4c
[IndVars] Improve code; use SCEVPatternMatch (NFC) (#139533) 2025-05-22 19:17:22 +01:00
Kazu Hirata
e9487fed29
[llvm] Construct SmallVector with iterator ranges (NFC) (#136460) 2025-04-19 19:07:10 -07:00
Kazu Hirata
b2ba53172e
[Transforms] Construct SmallVector with iterator ranges (NFC) (#136259) 2025-04-18 10:27:05 -07:00
Sirish Pande
7f107c3019
[IndVarsSimplify] sinkUnusedInvariants is skipping instructions while sinking. (#135205)
While sinking instructions (that are loop invariant) from preheader to
the exit block, we are skipping instructions due to decrementing
instruction iterator twice.
2025-04-17 19:21:18 -05:00
Ramkumar Ramachandra
a29ed04fe6
IndVarSimplify: strip redundant getDataLayout (NFC) (#125546)
DataLayout is already available as a member variable.
2025-02-03 19:28:44 +00:00
Ramkumar Ramachandra
88f858d858
IndVarSimplify: thread CmpPredicate to SCEV (NFC) (#125240)
Relevant parts of ScalarEvolution's API accept a CmpPredicate instead of
a CmpInst::Predicate after 60dc450 (SCEV: migrate to CmpPredicate
(NFC)). After auditing the callers of these APIs, it was found that
IndVarSimplify was dropping samesign information. Fix this.
2025-01-31 18:07:44 +00:00
Yingwei Zheng
40a647fc7d
[IndVarSimplify] Drop samesign flags after narrowing compares (#116263)
Samesign flag cannot be preserved after narrowing the compare since the
position of the sign bit is changed.

Closes https://github.com/llvm/llvm-project/issues/116249.
2024-11-15 09:15:37 +08:00
Kazu Hirata
94f9cbbe49
[Scalar] Remove unused includes (NFC) (#114645)
Identified with misc-include-cleaner.
2024-11-02 08:32:26 -07:00
Rahul Joshi
6924fc0326
[LLVM] Add Intrinsic::getDeclarationIfExists (#112428)
Add `Intrinsic::getDeclarationIfExists` to lookup an existing
declaration of an intrinsic in a `Module`.
2024-10-16 07:21:10 -07:00
Mehdi Amini
6c7a3f80e7
Fix LLVM_ENABLE_ABI_BREAKING_CHECKS macro check: use #if instead of #ifdef (#110938)
This macros is always defined: either 0 or 1. The correct pattern is to
use #if.

Re-apply #110185 with more fixes for debug build with the ABI breaking
checks disabled.
2024-10-03 01:24:14 +02:00
Nikita Popov
34e16b6b9c
[IndVars] Fix strict weak ordering violation (#108947)
The sort used the block name as a tie-breaker, which will not work for
unnamed blocks and can result in a strict weak ordering violation.

Fix this by checking that all exiting blocks dominate the latch first,
which means that we have a total dominance order. This makes the code
structure here align with what optimizeLoopExits() does.

Fixes https://github.com/llvm/llvm-project/issues/108618.
2024-09-17 15:33:23 +02:00
Nikita Popov
7990a7e58f [IndVars] Use getSigned() in FP transform
This transform is working on signed integer, so this is the
logically correct API.

Split off from https://github.com/llvm/llvm-project/pull/80309.
2024-08-13 15:04:23 +02:00
Florian Hahn
edf46f365c
[SCEV] Use const SCEV * explicitly in more places.
Use const SCEV * explicitly in more places to prepare for
https://github.com/llvm/llvm-project/pull/91961. Split off as suggested.
2024-08-03 20:10:01 +01: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
Nikita Popov
2d209d964a
[IR] Add getDataLayout() helpers to BasicBlock and Instruction (#96902)
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-27 16:38:15 +02:00
Shan Huang
b452b34932
[DebugInfo][IndVarSimplify] Fix missing debug location updates (#91443)
Adds debug location updates for the newly created `phi`, `add`, `icmp` and `sitofp` instructions in `IndVarSimplify`.

Fixes #91436
2024-05-09 12:58:53 +01:00
Florian Hahn
0f82469314
[Passes] Run SimpleLoopUnswitch after introducing invariant branches. (#81271)
IndVars may be able to replace a loop dependent condition with a loop
invariant one, but loop-unswitch runs before IndVars, so the invariant
check remains in the loop.

For an example, consider a read-only loop with a bounds check:
https://godbolt.org/z/8cdj4qhbG

This patch uses a approach similar to the way extra cleanup passes are
run on demand after vectorization (added in acea6e9cfa4c4a0e8678c7).

It introduces a new ShouldRunExtraSimpleLoopUnswitch analysis marker,
which IndVars can use to indicate that extra unswitching is beneficial.

ExtraSimpleLoopUnswitchPassManager uses this analysis to determine
whether to run its passes on a loop.

Compile-time impact (geomean) ranges from +0.0% to 0.02%
https://llvm-compile-time-tracker.com/compare.php?from=138c0beb109ffe47f75a0fe8c4dc2cdabe8a6532&to=19e6e99eeb280d426907ea73a21b139ba7225627&stat=instructions%3Au

Compile-time impact (geomean) of unconditionally running
SimpleLoopUnswitch ranges from +0.05% - +0.16%

https://llvm-compile-time-tracker.com/compare.php?from=138c0beb109ffe47f75a0fe8c4dc2cdabe8a6532&to=2930dfd5accdce2e6f8d5146ae4d626add2065a2&stat=instructions:u

Unconditionally running SimpleLoopUnswitch seems to indicate that there
are multiple other scenarios where we fail to run unswitching when
opportunities remain.


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

PR: https://github.com/llvm/llvm-project/pull/81271
2024-04-12 22:07:29 +01:00
Jeremy Morse
2fe81edef6 [NFC][RemoveDIs] Insert instruction using iterators in Transforms/
As part of the RemoveDIs project we need LLVM to insert instructions using
iterators wherever possible, so that the iterators can carry a bit of
debug-info. This commit implements some of that by updating the contents of
llvm/lib/Transforms/Utils to always use iterator-versions of instruction
constructors.

There are two general flavours of update:
 * Almost all call-sites just call getIterator on an instruction
 * Several make use of an existing iterator (scenarios where the code is
   actually significant for debug-info)
The underlying logic is that any call to getFirstInsertionPt or similar
APIs that identify the start of a block need to have that iterator passed
directly to the insertion function, without being converted to a bare
Instruction pointer along the way.

Noteworthy changes:
 * FindInsertedValue now takes an optional iterator rather than an
   instruction pointer, as we need to always insert with iterators,
 * I've added a few iterator-taking versions of some value-tracking and
   DomTree methods -- they just unwrap the iterator. These are purely
   convenience methods to avoid extra syntax in some passes.
 * A few calls to getNextNode become std::next instead (to keep in the
   theme of using iterators for positions),
 * SeparateConstOffsetFromGEP has it's insertion-position field changed.
   Noteworthy because it's not a purely localised spelling change.

All this should be NFC.
2024-03-05 15:12:22 +00:00
Nikita Popov
7078993ff2 [IndVars] Check expansion safety during LFTR
Check isSafeToExpand() before expanding the exit count. Otherwise
we may incorrectly speculate a udiv.

Fixes https://github.com/llvm/llvm-project/issues/66986.
2023-09-21 14:22:01 +02:00
Bjorn Pettersson
a20f7efbc5 Remove several no longer needed includes. NFCI
Mostly removing includes of InitializePasses.h and Pass.h in
passes that no longer has support for the legacy PM.
2023-04-17 13:54:19 +02:00
Kazu Hirata
7b014a0732 [Scalar] Use range-based for loops (NFC) 2023-04-16 09:05:20 -07:00
Philip Reames
0766c1bd5c [LFTR] Simplify integer case for genLoopLimit [nfc-ish]
The integer case in genLoopLimit reduces down to a special case for narrowing the bitwidth of the limit, and then performing the same expansion we would for a pointer IV.

Differential Revision: https://reviews.llvm.org/D146638
2023-03-22 12:22:05 -07:00
Philip Reames
06006f438e [LFTR] Minor style cleanup [nfc] 2023-03-21 19:17:31 -07:00
Philip Reames
206dc54534 [LFTR] Use evaluateAtIteration in genLoopLimit [nfc]
Note that the comments being removed appear to be very out of sync with the actual code in question.

Differential Revision: https://reviews.llvm.org/D146468
2023-03-21 19:17:31 -07:00
Philip Reames
a124b4c7f9 [LFTR] Simplify another case under assumption exit counts are integers [nfc]
This invariant was introduced in 8f3d16905d75b07a933d01dc29677fe5867c1b3e.
2023-03-21 19:17:31 -07:00
Craig Topper
24caf0196d [IndVarSimplify] Remove duplicate call to getSCEV. NFC
We already did this same call on the line before.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D146444
2023-03-21 09:47:07 -07:00
Philip Reames
042783f556 [LFTR] Assert and simplify under assumption exit counts are integers [nfc]
This invariant was introduced in 8f3d16905d75b07a933d01dc29677fe5867c1b3e.

Differential Revision: https://reviews.llvm.org/D146470
2023-03-21 07:35:05 -07:00
Philip Reames
54539fa8b3 [LSR/LFTR] Move two utilities to common code for reuse [nfc]
We're working on a transform in LSR which is essentiall an inverse of LFTR (in certain sub-cases).  Move utilties so that they can be reused.
2023-03-20 09:05:38 -07:00
Max Kazantsev
c113d0b766 [NFC] Drop NDEBUG around MSSA verification
Proposed on review of https://reviews.llvm.org/D145894.
2023-03-14 17:39:54 +07:00
Max Kazantsev
47021bda64 [IndVars] Option verify-indvars is broken (and always has been), delete it
This option is switched off by default, and it seems that it has never worked correctly.
What it basically does is: it remembers current BECount SCEV, and after all transforms
tries to validate some facts for it. However, between these two points this SCEV may
become invalid (e.g. because some SCEVUnknown it references may be deleted as dead
code). So basically it may work with broken pointers.

Besides, its implementation does strange things (e.g. forgetLoop) which are invasive and
may affect behavior in other parts of the system (specifically verification), concealing some
other problems. Another issue is that it may use SCEVCouldNotCompute object without
checking this.

The option is not used in any unit tests, and if switched on by default, the following tests
fail:
```
********************
Failed Tests (14):
  LLVM :: Transforms/IndVarSimplify/2005-06-15-InstMoveCrash.ll
  LLVM :: Transforms/IndVarSimplify/2007-06-06-DeleteDanglesPtr.ll
  LLVM :: Transforms/IndVarSimplify/2008-10-03-CouldNotCompute.ll
  LLVM :: Transforms/IndVarSimplify/2009-05-24-useafterfree.ll
  LLVM :: Transforms/IndVarSimplify/2011-10-27-lftrnull.ll
  LLVM :: Transforms/IndVarSimplify/ARM/code-size.ll
  LLVM :: Transforms/IndVarSimplify/X86/deterministic-scev-verify.ll
  LLVM :: Transforms/IndVarSimplify/X86/pr57187.ll
  LLVM :: Transforms/IndVarSimplify/X86/verify-scev.ll
  LLVM :: Transforms/IndVarSimplify/bbi-63564.ll
  LLVM :: Transforms/IndVarSimplify/invalidate-modified-lcssa-phi.ll
  LLVM :: Transforms/IndVarSimplify/loop-predication.ll
  LLVM :: Transforms/IndVarSimplify/post-inc-range.ll
  LLVM :: Transforms/IndVarSimplify/turn-to-invariant.ll

********************
Unexpectedly Passed Tests (1):
  LLVM :: Transforms/IndVarSimplify/pr55689.ll
```

None of these looks like real problems found by verification, these are
bugs in the verifying code itself (such as use of deleted SCEVs and
SCEVCouldNotCompute's).

I think it all gives enough justification for its removal.

https://github.com/llvm/llvm-project/issues/61302

Differential Revision: https://reviews.llvm.org/D145894
Reviewed By: nikic
2023-03-14 17:39:54 +07:00
Arthur Eubanks
7c3c981442 [Passes] Remove some legacy passes
DFAJumpThreading
JumpThreading
LibCallsShrink
LoopVectorize
SLPVectorizer
DeadStoreElimination
AggressiveDCE
CorrelatedValuePropagation
IndVarSimplify

These are part of the optimization pipeline, of which the legacy version is deprecated and being removed.
2023-03-10 17:17:00 -08:00
Max Kazantsev
f3e2f26378 [IndVars] Expand icmp in preheader rather than in loop
The motivation is that 'createInvariantCond' unconditionally
builds icmp in the loop block,  while it could always do it
in preheader. Build it in preheader instead.

Patch by Aleksandr Popov!

Differential Revision: https://reviews.llvm.org/D141994
Reviewed By: nikic
2023-01-25 14:41:29 +07:00
Max Kazantsev
932ae48c27 [IndVars] Improve handling of multi-exit loops with known symbolic counts
This patch does two things, both related to support of multi-exit loops with
many exits that have known symbolic max exit count. They can theoretically
go independently, but I don't know how to write a test showing separate
impact.

Part 1: `SkipLastIter` can be set to `true` not when a particular exit has exit
count same as the whole loop (and therefore it must exit on the last iteration),
but when the aggregate of first few exits has umin same as whole loop exit count.
It means that it's not known which of them will exit exactly, but one of them will.

Part 2: when `SkipLastIter` is set, and exit count is `umin(a, b, c)`, instead of
`umin(a, b, c) - 1` use `umin(a - 1, b - 1, c - 1)`. We don't care about overflows
here, but the further logic knows how to deal with umin by element, but the
`SCEVAddExpr` node will confuse it.

Differential Revision: https://reviews.llvm.org/D141361
Reviewed By: nikic
2023-01-24 12:46:48 +07:00
Max Kazantsev
602916d2de [IndVars] Apply more optimistic SkipLastIter for AND/OR conditions
When exit by condition `C1` dominates exit by condition `C2`, and
max symbolic exit count for `C1` matches those for loop, we will
apply more optimistic logic to `C2` by setting `SkipLastIter` for it,
meaning that it will do 1 iteration less because the dominating branch
must exit on the last loop iteration.

But when we have a single exit by condition `C1 & C2`, we cannot
apply the same logic, because there is no dominating condition.

However, if we can prove that the symbolic max exit count of `C1 & C2`
matches those of `C1`, it means that for `C2` we can assume that it
doesn't matter on the last iteration (because the whole thing is `false`
because `C1` must be `false`). Therefore, in this situation, we can handle
`C2` as if it had `SkipLastIter`.

Differential Revision: https://reviews.llvm.org/D139934
Reviewed By: nikic
2023-01-24 12:26:22 +07:00
Joe Loser
a288d7f937 [llvm][ADT] Replace uses of makeMutableArrayRef with deduction guides
Similar to how `makeArrayRef` is deprecated in favor of deduction guides, do the
same for `makeMutableArrayRef`.

Once all of the places in-tree are using the deduction guides for
`MutableArrayRef`, we can mark `makeMutableArrayRef` as deprecated.

Differential Revision: https://reviews.llvm.org/D141814
2023-01-16 14:49:37 -07:00
Max Kazantsev
9f37ecf8fa [IndVars] Support AND/OR in optimizeLoopExitWithUnknownExitCount
This patch allows optimizeLoopExitWithUnknownExitCount to deal with
branches by conditions that are not immediately ICmp's, but aggregates
of ICmp's joined by arithmetic or logical AND/OR. Each ICmp is optimized
independently.

Differential Revision: https://reviews.llvm.org/D139832
Reviewed By: nikic
2023-01-11 11:36:02 +07:00
Max Kazantsev
ba7af0bf69 [NFC] Add missing 'static' notion in createReplacement 2023-01-09 14:13:05 +07:00
Max Kazantsev
df8cedfc3d [IndVars][NFC] Factor out condition creation in optimizeLoopExitWithUnknownExitCount
This is a preparation step to support optimization of conditions that are not immediately ICmp.
2022-12-26 15:00:27 +07:00
Florian Hahn
8a3efcd40b
[ValueTracking] Consider single poison operands in propgatesPoison.
This patch updates propgatesPoison to take a Use as argument and
propagatesPoison now returns true if the passed in operand causes the
user to yield poison if the operand is poison

This allows propagating poison if the condition of a select is poison.
This helps improve results for programUndefinedIfUndefOrPoison.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D111643
2022-12-19 11:47:51 +00:00
Max Kazantsev
d02a40b559 [IndVars][NFC] Separate creation of condition and replacement in foldExit
It is a preparatory step for further improvements.
2022-12-12 17:59:45 +07:00
Max Kazantsev
6cf7f32ab5 [IndVars][NFC] Separate invariant condition creation and cond replacement
This separation is a preparatory step for further improvements in this code.
Also simplifies this function's API.
2022-12-12 17:16:22 +07:00
Max Kazantsev
cb06b6ab00 [IndVars][NFC] Remove redundant param in optimizeLoopExitWithUnknownExitCount
There was a crippled version of this transform for Inverted predicate, so the same
query was done twice. Advanced version of this transform wasn't implemented for
inverted condition. Thus, the code was hard to read. The only real purpose of the
Inverted param was to make a simple isKnownPredicateAt query.

Instead if this, use evaluatePredicateAt to solve the task for both inverted and
non-inverted predicate. This slightly changes the order of queries, but effectively
it should save some time by avoiding duplicating queries, and simplifies the code a lot.

I also could not find any evidence that we ever eliminate anything with Inverted = true,
but conservatively preserved the current behavior. Maybe we can remove it and save
some compile time.

Differential Revision: https://reviews.llvm.org/D139814
Reviewed By: nikic
2022-12-12 16:28:04 +07:00
Max Kazantsev
262f2fed65 [IndVars] Use symbolic max block exit count to handle the last iter
Old logic: when loop symbolic max exit count matched *exact* block exit count,
assume that all subsequent blocks will do 1 iteration less.

New logic: when loop symbolic max exit count matched *symbolic max* block exit count,
assume that all subsequent blocks will do 1 iteration less.

The new logic is still legal and is more permissive in situations when exact
block exit count is not known.

Differential Revision: https://reviews.llvm.org/D139692
Reviewed By: nikic
2022-12-09 17:06:29 +07:00
Max Kazantsev
4299b24d01 [NFC] Rename variables in optimizeLoopExits 2022-12-09 16:51:02 +07:00
Fangrui Song
a996cc217c Remove unused #include "llvm/ADT/Optional.h" 2022-12-05 06:31:11 +00:00
Max Kazantsev
2a3ac7fd0c [NFC][IndVars] Add LLVM_DEBUG printout to replaceExitCond 2022-11-21 19:33:26 +07:00
luxufan
49143f9d14 [IndVars] Forget the SCEV when the instruction has been sunk.
In the past, the SCEV expression of the sunk instruction was not
forgetted. This led to the incorrect block dispositions after the
instruction be sunk.

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

Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D137060
2022-11-06 22:46:49 +08:00