1470 Commits

Author SHA1 Message Date
William Moses
c44e015b49
[SimplifyCFG] Refine metadata handling during instruction hoisting (#158448)
Co-authored-by: Nikita Popov <npopov@redhat.com>
2025-09-14 22:50:42 -05:00
Kazu Hirata
2491dc3d6f [Utils] Fix a warning
This patch fixes:

  llvm/lib/Transforms/Utils/SimplifyCFG.cpp:338:6: error: unused
  function 'isSelectInRoleOfConjunctionOrDisjunction'
  [-Werror,-Wunused-function]
2025-09-12 09:13:16 -07:00
Mircea Trofin
889c289a40
[SimplfyCFG] Set MD_prof for select used for certain conditional simplifications (#154426)
There’s a pattern where a branch is conditioned on a conjunction or disjunction that ends up being modeled as a `select`​ where the first operand is set to `true`​ or the second to `false`​. If the branch has known branch weights, they can be copied to the `select`​. This is worth doing in case later the `select`​ gets transformed to something else (i.e. if we know the profile, we should propagate it).

Issue #147390
2025-09-12 07:50:44 -07:00
Mircea Trofin
3097688a47
[SimplifyCFG] Set branch weights when merging conditional store to address (#154841) 2025-09-11 13:21:59 -07:00
Jessica Del
89d86b626c
SimplifyCFG: Enable switch replacements in more cases (#156477)
In some cases, we can replace a switch with simpler instructions or a
lookup table.
For instance, if every case results in the same value, we can simply
replace the switch
with that single value.

However, lookup tables are not always supported. 
Targets, function attributes and compiler options can deactivate lookup
table creation.
Currently, even simpler switch replacements like the single value
optimization do not
get applied, because we only enable these transformations if lookup
tables are enabled.

This PR enables the other kinds of replacements, even if lookup tables
are not supported.
First, it checks if the potential replacements are lookup tables.
If they are, then check if lookup tables are supported and whether to
continue.
If they are not, then we can apply the other transformations.

Originally, lookup table creation was delayed until late stages of the
compilation pipeline, because
it can result in difficult-to-analyze code and prevent other
optimizations.
As a side effect of this change, we can also enable the simpler
optimizations much earlier in the
compilation process.
2025-09-09 16:24:52 +02:00
Andreas Jonson
e11f93e9fd
[SimplifyCFG] Support not in chain of comparisons. (#156497)
Proof: https://alive2.llvm.org/ce/z/cpXuCb
2025-09-08 19:16:41 +02:00
Mircea Trofin
91952f1758
[SimplifyCFG] Probabilities associated with same condition are constant (#155734)
The branch weights capture probability. The probability has everything to do with the (SSA) value the condition is predicated on, and nothing to do with the position in the CFG.
2025-09-04 14:37:35 -07:00
Jessica Del
af80969b81
[NFC] SimplifyCFG: Detect switch replacement earlier in switchToLookup (#155602)
This PR is the first part to solve the issue in #149937.

The end goal is enabling more switch optimizations on targets that do
not support lookup tables.

SimplifyCFG has the ability to replace switches with either a few simple
calculations, a single value, or a lookup table.
However, it only considers these options if the target supports lookup
tables, even if the final result is not a LUT, but a few simple
instructions like muls, adds and shifts.

To enable more targets to use these other kinds of optimization, this PR
restructures the code in `switchToLookup`.
Previously, code was generated even before choosing what kind of
replacement to do. However, we need to know if we actually want to
create a true LUT or not before generating anything. Then we can check
for target support only if any LUT would be created.

This PR moves the code so it first determines the replacement kind and
then generates the instructions.

A later PR will insert the target support check after determining the
kind of replacement. If the result is not a LUT, then even targets
without LUT support can replace the switch with something else.
2025-09-01 14:42:18 +02:00
Andreas Jonson
c5f0b8bf32
[SimplifyCFG] Support trunc nuw in chain of comparisons. (#155087)
proof: https://alive2.llvm.org/ce/z/5PNCds
2025-08-31 10:14:28 +02:00
Nikita Popov
24924a8be1 [SimplifyCFG] Move token type check into canReplaceOperandWithVariable()
We cannot form phis/selects of token type, so this should be checked
inside canReplaceOperandWithVariable().
2025-08-28 15:53:37 +02:00
Mircea Trofin
3af4597ac9
[NFC][SimplifyCFG] Simplify operators for the combined predicate in mergeConditionalStoreToAddress (#155058)
This is about code readability. The operands in the disjunction forming the combined predicate in `mergeConditionalStoreToAddress` could sometimes be negated twice. This patch addresses that.

2 tests needed updating because they exposed the double negation and now they don’t.
2025-08-26 07:07:59 -07:00
Yingwei Zheng
feac561478
[NFC][SimplifyCFG] Fix a return value in ConstantComparesGatherer (#155154)
`ICI->getOperand(0)` is non-null.
2025-08-24 19:40:40 +08:00
Andreas Jonson
ed742f88eb
[SimplifyCFG] Handle that first matched eq cond in if chain can be Extra condition. (#154007)
Proof: https://alive2.llvm.org/ce/z/TozSD6
2025-08-23 09:09:01 +02:00
Andreas Jonson
1b60236200
[SimplifyCFG] Avoid redundant calls in gather. (NFC) (#154133)
Split out from https://github.com/llvm/llvm-project/pull/154007 as it
showed compile time improvements

NFC as there needs to be at least two icmps that is part of the chain.
2025-08-18 18:45:52 +02:00
Arne Stenkrona
ea2f5395b1
[SimplifyCFG] Avoid threading for loop headers (#151142)
Updates SimplifyCFG to avoid jump threading through loop headers if
-keep-loops is requested. Canonical loop form requires a loop header
that dominates all blocks in the loop. If we thread through a header, we
risk breaking its domination of the loop. This change avoids this issue
by conservatively avoiding threading through headers entirely.

Fixes: https://github.com/llvm/llvm-project/issues/151144
2025-08-18 09:46:55 +00:00
Andreas Jonson
5ae8a9b8ce
[SimplifyCfg] Handle trunc nuw i1 condition in Equality comparison. (#153051)
proof: https://alive2.llvm.org/ce/z/WVt4-F
2025-08-17 09:53:40 +02:00
Orlando Cazalet-Hyams
d13341db26
[RemoveDIs][NFC] Remove getAssignmentMarkers (#153214)
getAssignmentMarkers was for debug intrinsics. getDVRAssignmentMarkers
is used for DbgRecords.
2025-08-13 10:56:19 +01:00
Andreas Jonson
c6fd3d32c3
[SimplifyCfg] Add nneg to zext for switch to table conversion (#147180) 2025-08-04 16:18:05 +02:00
LU-JOHN
a757f23404
[SimplifyCFG] Extend jump-threading to allow live local defs (#135079)
Extend jump-threading to allow local defs that are live outside of the
threaded block. Allow threading to destinations where the local defs are
not live.

---------

Signed-off-by: John Lu <John.Lu@amd.com>
2025-07-31 09:44:14 -04:00
Nikita Popov
307256ecbd
[GVNSink] Do not sink lifetimes of different allocas (#149818)
This was always undesirable, and after #149310 it is illegal and will
result in a verifier error.

Fix this by moving SimplifyCFG's check for this into
canReplaceOperandWithVariable(), so it's shared with GVNSink.
2025-07-22 09:44:03 +02:00
Antonio Frighetto
c435cd1730 [SimplifyCFG] Cache unique predecessors in simplifyDuplicateSwitchArms
Avoid repeatedly querying `getUniquePredecessor` for already-visited
switch successors so as not to incur quadratic runtime.

Fixes: https://github.com/llvm/llvm-project/issues/147239.
2025-07-18 08:33:42 +02:00
Gábor Spaits
338fd8b12c
[SimplifyCFG] Transform switch to select when common bits uniquely identify one case (#145233)
Fix #141753 .

This patch introduces a new check, that tries to decide if the
conjunction of all the values uniquely identify the accepted values by
the switch.
2025-07-02 18:16:12 +02:00
Andreas Jonson
33c265ddf7
[SimplifyCFG] Use indexType from data layout in switch to table conversion (#146207)
Generate the GEP with the index type that InstCombine will cast it to but use the knowledge that the index is unsigned.
2025-06-28 21:00:34 +02:00
Antonio Frighetto
1247fddf36 [SimplifyCFG] Relax cttz cost check in simplifySwitchOfPowersOfTwo
We should be able to allow `simplifySwitchOfPowersOfTwo` transform
to take place, as, on recent X86 targets, the weighted latency-size
appears to be 2. This favours computing trailing zeroes and indexing
into a smaller value table, over generating a jump table with an
indirect branch, which overall should be more efficient.
2025-06-24 09:06:18 +02:00
Jeremy Morse
9eb0020555
[DebugInfo][RemoveDIs] Remove a swathe of debug-intrinsic code (#144389)
Seeing how we can't generate any debug intrinsics any more: delete a
variety of codepaths where they're handled. For the most part these are
plain deletions, in others I've tweaked comments to remain coherent, or
added a type to (what was) type-generic-lambdas.

This isn't all the DbgInfoIntrinsic call sites but it's most of the
simple scenarios.

Co-authored-by: Nikita Popov <github@npopov.com>
2025-06-17 15:55:14 +01:00
Stephen Tozer
a08a831515
[DLCov][NFC] Propagate annotated DebugLocs through transformations (#138047)
Part of the coverage-tracking feature, following #107279.

In order for DebugLoc coverage testing to work, we firstly have to set
annotations for intentionally-empty DebugLocs, and secondly we have to
ensure that we do not drop these annotations as we propagate DebugLocs
throughout compilation. As the annotations exist as part of the DebugLoc
class, and not the underlying DILocation, they will not survive a
DebugLoc->DILocation->DebugLoc roundtrip. Therefore this patch modifies
a number of places in the compiler to propagate DebugLocs directly
rather than via the underlying DILocation. This has no effect on the
output of normal builds; it only ensures that during coverage builds, we
do not drop incorrectly annotations and therefore create false
positives.

The bulk of these changes are in replacing
DILocation::getMergedLocation(s) with a DebugLoc equivalent, and in
changing the IRBuilder to store a DebugLoc directly rather than storing
DILocations in its general Metadata array. We also use a new function,
`DebugLoc::orElse`, which selects the "best" DebugLoc out of a pair
(valid location > annotated > empty), preferring the current DebugLoc on
a tie - this encapsulates the existing behaviour at a few sites where we
_may_ assign a DebugLoc to an existing instruction, while extending the
logic to handle annotation DebugLocs at the same time.
2025-06-12 14:06:27 +01:00
Jeremy Morse
97ac6483aa
[DebugInfo][RemoveDIs] Delete debug-info-format flag (#143746)
This flag was used to let us incrementally introduce debug records
into LLVM, however everything is now using records. It serves no
purpose now, so delete it.
2025-06-12 11:51:58 +01: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
Yingwei Zheng
7e1fa09ce2
[SimplifyCFG] Bail out on vector GEPs in passingValueIsAlwaysUndefined (#142526)
Closes https://github.com/llvm/llvm-project/issues/142522.
2025-06-04 12:37:30 +08: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
Kazu Hirata
54d836a080
[llvm] Use *Set::insert_range (NFC) (#138237) 2025-06-02 19:48:13 -07:00
Yingwei Zheng
1e08febf0a
[SimplifyCFG] Switch to use paramHasNonNullAttr (#125383) 2025-06-02 12:20:13 +08:00
Nikita Popov
eee958285b
[SimplifyCFG] Only consider provenance capture in store speculation (#138548)
The capture check here is to protect against concurrent accesses from
other threads. This requires the provenance to escape.
2025-05-22 17:01:37 +02:00
Ellis Hoag
78f0af5d89
[SimplifyCFG][swifterror] Don't sink calls with swifterror params (#139015)
We've encountered an LLVM verification failure when building Swift with
the SimplifyCFG pass enabled. I found that
https://reviews.llvm.org/D158083 fixed this pass by preventing sinking
loads or stores of swifterror values, but it did not implement the same
protection for call or invokes.
In `Verifier.cpp`
[here](c685355811/llvm/lib/IR/Verifier.cpp (L4360-L4364))
and
[here](c685355811/llvm/lib/IR/Verifier.cpp (L3661-L3662))
we can see that swifterror values must also be used directly by call
instructions.
2025-05-12 14:37:26 -07:00
Kazu Hirata
85f3d60d81
[Utils] Use range-based for loops (NFC) (#139426) 2025-05-10 22:50:46 -07:00
Orlando Cazalet-Hyams
74c3025dd5
[KeyInstr][SimplifyCFG] Remap atoms after duplication for threading (#133484)
Given the same branch condition in `a` and `c` SimplifyCFG converts:

        +> b -+
        |     v
    --> a --> c --> e -->
              |     ^
              +> d -+
into:

        +--> bcd ---+
        |           v
    --> a --> c --> e -->

Remap source atoms on instructions duplicated from `c` into `bcd`.

RFC:
https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668
2025-05-07 09:56:30 +01:00
Orlando Cazalet-Hyams
f8de1618cc
[KeyInstr][SimplifyCFG] Remap atoms when folding br to common succ into pred (#133482)
SimplifyCFG folds `d` into preds `b` and `c`.

              +---------------+
              |               |
         +--> b --+           |
         |        v           v
     --> a        d --> e --> f -->
         |        ^           ^
         +--> c --+           |
              |               |
              +---------------+
    
Remap source atoms so that the duplicated instructions are analysed
independently to determine is_stmt positions.

The pull request contains a discussion covering various edge cases here:
https://github.com/llvm/llvm-project/pull/133482/files#r2039519348

The summary of the discussion is that we could avoid remapping when there's a
single pred, but we decided that it's still a trade off, and not worth the
additional complexity right now.

RFC:
https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668
2025-05-06 15:03:20 +01:00
Kazu Hirata
26d71f9ef2
[Transforms] Use range-based for loops (NFC) (#138476) 2025-05-04 16:08:31 -07:00
Kazu Hirata
5cfd81b0cc
[llvm] Use range constructors of *Set (NFC) (#137552) 2025-04-27 15:59:57 -07:00
David Green
e183459b8b
[CostModel] Make sure getCmpSelInstrCost is passed a CondTy (#135535)
It is already required along certain code paths that the CondTy is
valid. Fix some of the uses to make sure it is passed.
2025-04-21 05:33:30 +01:00
Kazu Hirata
b01e25deba
[llvm] Call hash_combine_range with ranges (NFC) (#136511) 2025-04-20 16:36:03 -07:00
Andreas Jonson
ed43207306
[SimplifyCFG] Handle trunc condition in foldBranchToCommonDest. (#135490)
proof: https://alive2.llvm.org/ce/z/v32Aof
2025-04-13 13:16:15 +02:00
Yingwei Zheng
73e1710a4d
[SimplifyCFG] Remove unused variable. NFC. (#134211) 2025-04-03 15:22:51 +08:00
Yingwei Zheng
b6c0ce0bb6
[IR][NFC] Use SwitchInst::defaultDestUnreachable (#134199) 2025-04-03 14:47:47 +08:00
Kazu Hirata
f915015a3e
[llvm] Remove extraneous calls to make_range (NFC) (#133551) 2025-03-28 19:56:02 -07:00
Kazu Hirata
cde58bfc16
[Transforms] Use range constructors of *Set (NFC) (#133203) 2025-03-27 07:51:58 -07:00
Phoebe Wang
369be311a7
[X86,SimplifyCFG] Support conditional faulting load or store only (#132032)
This is to fix a bug when a target only support conditional faulting
load, see test case hoist_store_without_cstore.

Split `-simplifycfg-hoist-loads-stores-with-cond-faulting` into
`-simplifycfg-hoist-loads-with-cond-faulting` and
`-simplifycfg-hoist-stores-with-cond-faulting` to control conditional
faulting load and store respectively.
2025-03-21 21:19:46 +08:00
Phoebe Wang
64555e3d48
[X86][NFCI] Add IsStore parameter to hasConditionalLoadStoreForType (#132153)
Address
https://github.com/llvm/llvm-project/pull/132032#issuecomment-2736936769
2025-03-20 18:25:09 +08:00
Kazu Hirata
0dcc201ac4
[Transforms] Use *Set::insert_range (NFC) (#132056)
DenseSet, SmallPtrSet, SmallSet, SetVector, and StringSet recently
gained C++23-style insert_range.  This patch replaces:

  Dest.insert(Src.begin(), Src.end());

with:

  Dest.insert_range(Src);

This patch does not touch custom begin like succ_begin for now.
2025-03-19 15:35:01 -07:00
Kazu Hirata
1b42be6fe8
[Utils] Avoid repeated hash lookups (NFC) (#131267)
It's safe to use try_emplace instead of operator[] here because:

- PhiPredIVs is empty at the beginning of the loop, and

- The elements we are inserting into PhiPredIVs are unique.
2025-03-14 07:22:17 -07:00