32951 Commits

Author SHA1 Message Date
Paul Walker
7b8fd8f31b
[LLVM][SCEV] Look through common vscale multiplicand when simplifying compares. (#141798)
My usecase is simplifying the control flow generated by LoopVectorize
when vectorising loops whose tripcount is a function of the runtime
vector length. This can be problematic because:

* CSE is a pre-LoopVectorize transform and so it's common for an IR
function to include several calls to llvm.vscale(). (NOTE: Code
generation will typically remove the duplicates)
* Pre-LoopVectorize instcombines will rewrite some multiplies as shifts.
This leads to a mismatch between VL based maths of the scalar loop and
that created for the vector loop, which prevents some obvious
simplifications.

SCEV does not suffer these issues because it effectively does CSE during
construction and shifts are represented as multiplies.
2025-09-19 12:57:13 +01:00
Fabian Ritter
3cc1b7c2e0
[SeparateConstOffsetFromGEP] Check if non-extracted indices may be negative when preserving inbounds (#159515)
If we know that the initial GEP was inbounds, and we change it to a sequence of
GEPs from the same base pointer where every offset is non-negative, then the
new GEPs are inbounds. So far, the implementation only checked if the extracted
offsets are non-negative. In cases where non-extracted offsets can be negative,
this would cause the inbounds flag to be wrongly preserved.

Fixes an issue in #130617 found by nikic.
2025-09-19 09:01:14 +02:00
Wenju He
dd669c32ec
[InferAddressSpaces] Mark ConstantAggregateZero as safe to cast to a ConstantExpr addrspacecast (#159695)
This PR extends isSafeToCastConstAddrSpace to treat
ConstantAggregateZero like ConstantPointerNull.
Tests shows an extra addrspacecast instruction is removed and icmp
pointer vector operand's address space is now inferred.

This change is motivated by inspecting the test in commit f7629f5945f6.
2025-09-19 14:15:40 +08:00
Wenju He
f7629f5945
[InferAddressSpaces] Extend undef pointer operand support to phi inst (#159548)
Previously undef pointer operand is only supported for select inst,
where undef in generic AS behaves like `take the other side`.

This PR extends the support to other instructions, e.g. phi inst. Defer
joining and inferring constant pointer operand until all other operand
AS states considered.

---------

Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-09-19 09:14:00 +08:00
Florian Hahn
0c028bbf33
[LV] Always add uniform pointers to uniforms list.
Always add pointers proved to be uniform via legal/SCEV to worklist.
This extends the existing logic to handle a few more pointers known to
be uniform.
2025-09-18 22:56:19 +01:00
Alexey Bataev
8c41859a21 [SLP]Clear the operands deps of non-schedulable nodes, if previously all operands were copyable
If all operands of the non-schedulable nodes were previously only
copyables, need to clear the dependencies of the original schedule data
for such copyable operands and recalculate them to correctly handle
  number of dependecies.

Fixes #159406
2025-09-18 12:11:33 -07:00
Florian Hahn
70a7ffdc29
[LV] Add missing test cover for replicating load/store costs. 2025-09-18 19:47:06 +01:00
Florian Hahn
50b9ca4dda
[VPlan] Simplify Plan's entry in removeBranchOnConst. (#154510)
After https://github.com/llvm/llvm-project/pull/153643, there may be a
BranchOnCond with constant condition in the entry block.

Simplify those in removeBranchOnConst. This removes a number of
redundant conditional branch from entry blocks.

In some cases, it may also make the original scalar loop unreachable,
because we know it will never execute. In that case, we need to remove
the loop from LoopInfo, because all unreachable blocks may dominate each
other, making LoopInfo invalid. In those cases, we can also completely
remove the loop, for which I'll share a follow-up patch.

Depends on https://github.com/llvm/llvm-project/pull/153643.

PR: https://github.com/llvm/llvm-project/pull/154510
2025-09-18 19:25:05 +01:00
Daniel Paoliello
4fabe6ffae
Use internal linkage for __NoopCoro_ResumeDestroy (#159407)
`__NoopCoro_ResumeDestroy` currently has private linkage, which causes
[issues for
Arm64EC](https://github.com/llvm/llvm-project/issues/158341). The
Arm64EC lowering is trying to mangle and add thunks for
`__NoopCoro_ResumeDestroy`, since it sees that it's address is taken
(and, therefore, might be called from x64 code via a function pointer).
MSVC's linker requires that the function be placed in COMDAT (`LNK1361:
non COMDAT symbol '.L#__NoopCoro_ResumeDestroy' in hybrid binary`) which
trips an assert in the verifier (`comdat global value has private
linkage`) and the subsequent linking step fails since the private symbol
isn't in the symbol table.

Since there is no reason to use private linkage for
`__NoopCoro_ResumeDestroy` and other coro related functions have also
been [switched to internal linkage to improve
debugging](https://github.com/llvm/llvm-project/pull/151224), this
change switches to using internal linkage.

Fixes #158341
2025-09-18 09:24:34 -07:00
Nikita Popov
902ddda120
[DropUnnecessaryAssumes] Add pass for dropping assumes (#159403)
This adds a new pass for dropping assumes that are unlikely to be useful
for further optimization.

It works by discarding any assumes whose affected values are one-use
(which implies that they are only used by the assume, i.e. ephemeral).

This pass currently runs at the start of the module optimization
pipeline, that is post-inline and post-link. Before that point, it is
more likely for previously "useless" assumes to become useful again,
e.g. because an additional user of the value is introduced after
inlining + CSE.
2025-09-18 14:44:04 +00:00
Yingwei Zheng
e03a7c124d
[InstCombine] Generalize foldAndOrOfICmpsUsingRanges to handle more cases. (#158498)
Closes https://github.com/llvm/llvm-project/issues/158326.
Closes https://github.com/llvm/llvm-project/issues/59555.

Proof for `(X & -Pow2) == C -> (X - C) < Pow2`:
https://alive2.llvm.org/ce/z/HMgkuu
2025-09-18 10:49:42 +08:00
Yingwei Zheng
05c4681668
[SCCP] Relax two-instruction range checks (#158495)
If we know x in R1, the range check `x in R2` can be relaxed into `x in
Union(R2, Inverse(R1))`. The latter one may be more efficient if we can
represent it with one icmp.
Fixes regressions introduced by
https://github.com/llvm/llvm-project/pull/156497.

Proof for `(X & -Pow2) == C -> (X - C) < Pow2`:
https://alive2.llvm.org/ce/z/HMgkuu

Compile-time impact:
https://llvm-compile-time-tracker.com/compare.php?from=ead4f3e271fdf6918aef2ede3a7134811147d276&to=bee3d902dd505cf9b11499ba4f230e4e8ae96b92&stat=instructions%3Au
2025-09-17 23:50:38 +08:00
Hassnaa Hamdi
e8aa0b688a
[LV]: Ensure fairness when selecting epilogue VF. (#155547)
Consider IC when deciding if epilogue profitable for scalable vectors,
same as fixed-width vectors.
2025-09-17 14:48:10 +01:00
Florian Hahn
f78150d2d4
Reapply "[SCEV] Fold (C1 * A /u C2) -> A /u (C2 /u C1), if C2 > C1." (#158328)
This reverts commit fd58f235f8c5bd40d98acfd8e7fb11d41de301c7.

The recommit contains an extra check to make sure that D is a multiple of
C2, if C2 > C1. This fixes the issue causing the revert fd58f235f8c. Tests
have been added in 6a726e9a4d3d0.

Original message:
If C2 >u C1 and C1 >u 1, fold to A /u (C2 /u C1).

Depends on https://github.com/llvm/llvm-project/pull/157555.

Alive2 Proof: https://alive2.llvm.org/ce/z/BWvQYN

PR: https://github.com/llvm/llvm-project/pull/157656
2025-09-17 14:28:30 +01:00
Florian Hahn
6a726e9a4d
[SCEV] Add more tests for MUL/UDIV folds.
Add additional test coverage for
https://github.com/llvm/llvm-project/pull/157656 covering cases where
the dividend is not a multiple of the divisor, causing the revert of
70012fda631.
2025-09-17 13:05:49 +01:00
Sander de Smalen
17e008db17
[IR] NFC: Remove 'experimental' from partial.reduce.add intrinsic (#158637)
The partial reduction intrinsics are no longer experimental, because
they've been used in production for a while and are unlikely to change.
2025-09-17 11:44:47 +01:00
Nikita Popov
9690a718b8
[IR][CaptureTracking] Consider assume operand bundles captures(none) (#159083)
Something like `call void @llvm.assume(i1 true) ["align"(ptr %p, i64 8)]`
is equivalent to placing an `align 8` attribute on the parameter
and should not be considered as capturing.
2025-09-17 12:37:28 +02:00
Paul Walker
1773341f2c [NFC] Regenerate checks - llvm/test/Transforms/InstSimplify/ConstProp/bswap.ll 2025-09-17 10:20:59 +00:00
Paul Walker
152ed59a9f [NFC][LLVM][Tests] Add RUN lines to verify Constant{Int/FP} based splats.
llvm/test/Transforms/Attributor/nofpclass.ll
  llvm/test/Transforms/InstCombine/exact.ll
  llvm/test/Transforms/InstCombine/load-store-forward.ll
  llvm/test/Transforms/SCCP/overdefined-ext.ll
2025-09-17 10:20:59 +00:00
Gábor Spaits
88c64f76ed
Revert "Reland "[BasicBlockUtils] Handle funclets when detaching EH p… (#159292)
…ad blocks" (#158435)"

This reverts commit 41cef78227eb909181cb9360099b2d92de8d649f.
2025-09-17 09:44:17 +00:00
Nikita Popov
0969e2c420
[CaptureTracking] Fix handling for non-returning read-only calls (#158979)
We currently infer `captures(none)` for calls that are read-only,
nounwind and willreturn. As pointed out in
https://github.com/llvm/llvm-project/issues/129090, this is not correct
even with this set of pre-conditions, because the function could
conditionally cause UB depending on the address.

As such, change this logic to instead report `captures(address)`. This
also allows dropping the nounwind and willreturn checks, as these can
also only capture the address.
2025-09-17 11:27:06 +02:00
Gábor Spaits
41cef78227
Reland "[BasicBlockUtils] Handle funclets when detaching EH pad blocks" (#158435)
When removing EH Pad blocks, the value defined by them becomes poison. These poison values are then used by `catchret` and `cleanupret`, which is invalid. This commit replaces those unreachable `catchret` and `cleanupret` instructions with `unreachable`.
2025-09-17 09:47:29 +02:00
David Green
09966960c6
[BasicAA] Handle scalable vectors in new errno aliasing checks. (#159248)
This is a minor fixup for scalable vectors after f9f62ef4ae555a. It
handles them in the same way as other memory locations that are larger
than errno, preventing the failure on implicit conversion from a
scalable location.
2025-09-17 06:33:59 +00:00
Weibo He
a264453750
Revert "Reapply "[Coroutines] Add llvm.coro.is_in_ramp and drop return value of llvm.coro.end #153404"" (#159236)
Reverts llvm/llvm-project#155339 because of CI fail
2025-09-17 12:04:13 +08:00
Weibo He
ef45c9756a
Reapply "[Coroutines] Add llvm.coro.is_in_ramp and drop return value of llvm.coro.end #153404" (#155339)
As mentioned in #151067, current design of llvm.coro.end mixes two
functionalities: querying where we are and lowering to some code. This
patch separate these functionalities into independent intrinsics by
introducing a new intrinsic llvm.coro.is_in_ramp.
2025-09-17 11:25:31 +08:00
Craig Topper
4be1099607
[RISCV] Improve fixed vector handling in isCtpopFast. (#158380)
Previously we considered fixed vectors fast if Zvbb or Zbb is
enabled. Zbb only helps if the vector type will end up being
scalarized.
2025-09-16 09:47:09 -07:00
Antonio Frighetto
f9f62ef4ae
[AA] Refine ModRefInfo taking into account errnomem location
Ensure alias analyses mask out `errnomem` location, refining the
resulting modref info, when the given access/location does not
alias errno. This may occur either when TBAA proves there is no
alias with errno (e.g., float TBAA for the same root would be
disjoint with the int-only compatible TBAA node for errno); or
if the memory access size is larger than the integer size, or
when the underlying object is a potentially-escaping alloca.

Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972.
2025-09-16 17:59:31 +02:00
Rajveer Singh Bharadwaj
08a58b2cea
[InstCombine] Optimize redundant floating point comparisons in or/and 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-16 20:52:11 +05:30
Graham Hunter
666e4313eb
[NFC][LV] Improve ee with sideeffects legality test (#158275)
Addressing postcommit comments for
54fc5367f63cca8e011d93bbd55764b0a7ecbbd5
2025-09-16 13:04:51 +00:00
Yingwei Zheng
ea59be552f
[ValueTracking] Don't take sign bit from NaN operands (#157250)
Closes https://github.com/llvm/llvm-project/issues/157238.
2025-09-16 20:59:42 +08:00
John Brawn
8fab81121e
[LSR] Add an addressing mode that considers all addressing modes (#158110)
The way that loops strength reduction works is that the target has to
upfront decide whether it wants its addressing to be preindex,
postindex, or neither. This choice affects:
 * Which potential solutions we generate
* Whether we consider a pre/post index load/store as costing an AddRec
or not.

None of these choices are a good fit for either AArch64 or ARM, where
both preindex and postindex addressing are typically free:
* If we pick None then we count pre/post index addressing as costing one
addrec more than is correct so we don't pick them when we should.
* If we pick PreIndexed or PostIndexed then we get the correct cost for
that addressing type, but still get it wrong for the other and also
exclude potential solutions using offset addressing that could have less
cost.

This patch adds an "all" addressing mode that causes all potential
solutions to be generated and counts both pre and postindex as having
AddRecCost of zero. Unfortuntely this reveals problems elsewhere in how
we calculate the cost of things that need to be fixed before we can make
use of it.
2025-09-16 11:46:54 +01:00
Ramkumar Ramachandra
46fcece2a8
[VPlan] Extend CSE to eliminate GEPs (#156699)
The motivation for this patch is to close the gap between the
VPlan-based CSE and the legacy CSE, to make it easier to remove the
legacy CSE. Before this patch, stubbing out the legacy CSE leads to 22
test failures, and after this patch, there are only 12 failures, and all
of them seem to have a single root cause:
VPlanTransforms::createInterleaveGroups() and
VPInterleaveGroup::execute(). The improvements from this patch are of
course welcome.

While developing the patch, a miscompile was found when GEP
source-element-types differ, and this has been fixed.

Co-authored-by: Florian Hahn <flo@fhahn.com>
Co-authored-by: Luke Lau <luke@igalia.com>
2025-09-16 10:14:32 +00:00
Teresa Johnson
f74184ccc9
[MemProf] Add NodeId field to ContextNode for debugging (#158736)
This has been handy locally for debugging cloning issues. The NodeIds
are assigned sequentially on creation and included in the dumps and the
dot graphs.

No measurable memory increase was found for a large thin link.

I only changed one test
(Transforms/MemProfContextDisambiguation/basic.ll)
to actually check the emitted NodeIds, most ignore them.
2025-09-15 20:27:33 -07:00
Florian Hahn
1858532c48
[VPlan] Handle predicated UDiv in VPReplicateRecipe::computeCost.
Account for predicated UDiv,SDiv,URem,SRem in
VPReplicateRecipe::computeCost: compute costs of extra phis and apply
getPredBlockCostDivisor.

Fixes https://github.com/llvm/llvm-project/issues/158660
2025-09-15 21:46:50 +01:00
Alan Zhao
b5afe416c7
[InstCombine] Preserve profile data with select instructions and binary operators (#158375)
Tracking issue: #147390
2025-09-15 20:12:08 +00:00
Florian Hahn
4949cb4a5e
[VPlan] Track VPValues instead of VPRecipes in calculateRegisterUsage. (#155301)
Update calculateRegisterUsageForPlan to track live-ness of VPValues
instead of recipes. This gives slightly more accurate results for
recipes that define multiple values (i.e. VPInterleaveRecipe).

When tracking the live-ness of recipes, all VPValues defined by an
VPInterleaveRecipe are considered alive until the last use of any of
them. When tracking the live-ness of individual VPValues, we can
accurately track the individual values until their last use.

Note the changes in large-loop-rdx.ll and pr47437.ll. This patch
restores the original behavior before introducing VPlan-based liveness
tracking.

PR: https://github.com/llvm/llvm-project/pull/155301
2025-09-15 20:55:11 +01:00
Alexey Bataev
f2301be0e8 [SLP]Add a check if the user itself is commutable
If the commutable instruction can be represented as a non-commutable
vector instruction (like add 0, %v can be represented as a part of sub
nodes with operation sub %v, 0), its operands might still be reordered
and this should be accounted when checking for copyables in operands

Fixes #158293
2025-09-15 12:50:03 -07:00
Vigneshwar Jayakumar
d9fa0de5c8
[StructurizeCFG] bug fix in zero cost hoist (#157969)
This fixes a bug where zero cost instruction was hoisted to nearest
common dominator but the hoisted instruction's operands didn't dominate
the common dominator causing poison values.
2025-09-15 14:29:32 -05:00
Florian Hahn
985dc69a2d
[LV] Add test for missed interleaving after narrowing interleave groups.
Add extra test coverage for
https://github.com/llvm/llvm-project/pull/149706. The added loop should
be interleaved, after narrowing interleave groups, which requires moving
the transform earlier.
2025-09-15 17:33:59 +01:00
Florian Hahn
2848e28012
[LV] Add test with partial reduction without narrowing. 2025-09-15 11:56:58 +01:00
Uyiosa Iyekekpolor
994a6a39e1
[VectorCombine] Fix scalarizeExtExtract for big-endian (#157962)
The scalarizeExtExtract transform assumed little-endian lane ordering,
causing miscompiles on big-endian targets such as AIX/PowerPC under -O3
-flto.

This patch updates the shift calculation to handle endianness correctly
for big-endian targets. No functional change
for little-endian targets.

Fixes #158197.

---------

Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
2025-09-15 10:08:16 +00:00
macurtis-amd
2c091e6aec
AMDGPU: Report unaligned scratch access as fast if supported by tgt (#158036)
This enables more consecutive load folding during
aggressive-instcombine.

The original motivating example provided by Jeff Byrnes:
https://godbolt.org/z/8ebcTEjTs

Example provided by Nikita Popov: https://godbolt.org/z/Gv1j4vjqE as
part of my original attempt to fix the issue (PR
[#133301](https://github.com/llvm/llvm-project/pull/133301), see his
[comment](https://github.com/llvm/llvm-project/pull/133301#issuecomment-2984905809)).

This changes the value of `IsFast` returned by `In
SITargetLowering::allowsMisalignedMemoryAccessesImpl` to be non-zero for
private and flat addresses if the subtarget supports unaligned scratch
accesses.

This enables aggressive-instcombine to do more folding of consecutive
loads (see
[here](cbd496581f/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp (L811))).

Summary performance impact on
[composable_kernel](https://github.com/ROCm/composable_kernel):

|GPU|speedup (geomean*)|
|---|---|
|MI300A| 1.11|
|MI300X| 1.14|
|MI350X| 1.03|

[*] Just to be clear, this is the geomean across kernels which were
impacted by this change - not across all CK kernels.
2025-09-15 05:03:02 -05:00
Nikita Popov
3371375131
[InstCombine] Read-only call without return can capture (#157878)
The copied from constant memory analysis had a special case where
nocapture was not required for read-only calls without (or unused)
return. This is not correct, as the address can still be captured though
means other than memory and the return value, for example using
divergence. This code should not be trying to do its own nocapture
inference.
2025-09-15 09:34:04 +02:00
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
Weibo He
d5f58a5827
[CoroSplit] Fix use-after-free related to coro.suspend (#156572)
Fix #156444
2025-09-15 10:51:17 +08:00
Arthur Eubanks
b30c29c893
Revert "[BasicBlockUtils] Handle funclets when detaching EH pad blocks" (#158364)
Reverts llvm/llvm-project#157363

Causes crashes, see
https://github.com/llvm/llvm-project/pull/157363#issuecomment-3286783238
2025-09-14 19:58:48 +00:00
Mikhail Gudim
ee3a4f4c94
[SLPVectorizer] Test -1 stride loads. (#158358)
Add a test to generate -1 stride load and flags to force this behaviour.
2025-09-14 15:29:28 -04:00
AZero13
e07b5968d4
[InstCombine] Fold select pattern with sub and negation to abs intrinsic (#156246)
```llvm
%sub = sub nsw T %x, %y
%cmp = icmp sgt T %x, %y  ; or sge
%neg = sub T 0, %sub
%abs = select i1 %cmp, T %sub, T %neg
```
becomes:

```llvm
%sub = sub nsw T %x, %y
%abs = call T @llvm.abs.T(T %sub, i1 false)
```
Alive2: https://alive2.llvm.org/ce/z/ApdJX8

https://alive2.llvm.org/ce/z/gRTmZk
2025-09-14 20:29:37 +08:00
Florian Hahn
ef7e03a2d1
[VPlan] Limit ExtractLastElem fold to recipes guaranteed single-scalar.
vputils::isSingleScalar(A) may return true to recipes that produce only
a single scalar value, but they could still end up as vector
instruction, because the recipe could not be converted to a
single-scalar VPInstruction/VPReplicateRecipe.

For now, only apply the fold for recipes guaranteed to produce a single
value, i.e. single-scalar VPInstructions and VPReplicateRecipes.

Fixes https://github.com/llvm/llvm-project/issues/158319.
2025-09-13 18:15:38 +01:00
Teresa Johnson
0c3cf200f5
[MemProf] Optionally allow transformation of nobuiltin operator new (#158396)
For cases where we can guarantee the application does not override
operator new.
2025-09-12 21:48:41 -07:00