5230 Commits

Author SHA1 Message Date
Marina Taylor
55322f2d43
[ObjCARC] Run ObjCARCContract before PreISelIntrinsicLowering (#184149)
74e4694 moved ObjCARCContract from running before the codegen pipeline
into addISelPrepare(), which runs after PreISelIntrinsicLowering.

This broke ObjCARCContract's retainRV-to-claimRV optimization because
ObjCARCContract identifies ARC calls via intrinsics, not their lowered
counterparts.

This patch restores the pre-74e4694 ordering by moving ObjCARCContract
to addISelPasses.

The IntrinsicInst.cpp change looks extraneous but is required here:
ObjCARCContract may now rewrite the bundle operand from retainRV to
claimRV. When PreISelIntrinsicLowering then encounters this new
intrinsic use, lowerObjCCall asserts mayLowerToFunctionCall.

Assisted-by: claude

rdar://137997453
2026-03-27 15:37:47 +00:00
David Green
5012b76ae2
[ARM] Fix incorrect post increment from Or (#188036)
If a Or is detected by findPointerConstIncrement but not by
getPointerConstIncrement it could use an invalid increment for the
offset. Protect against cases where getPointerConstIncrement cannot
return a valid offset.

Fixes #185677
2026-03-25 08:34:18 +00:00
Xinlong Chen
b670265b58
[DAG] ComputeKnownBits - set low bit to zero for ADD(X,X) (#186461)
ADD(X,X) is equivalent to SHL(X,1), so bit[0] is always zero.

This allows downstream folds like `and(add(x,x), 1) -> 0`.

Fixes #186091
2026-03-23 16:10:36 +00:00
David Green
bcdb7d3c8f [ARM] Regenerate vld2.ll test. NFC 2026-03-23 13:14:17 +00:00
Nikita Popov
f064a9979f
[DAGCombine] Optimize away cond ? 1 : 0 post-legalization (#186771)
Selects of the form `cond ? 1 : 0` are created during unrolling of
setcc+vselect. Currently these are not optimized away post-legalization
even if fully redundant. Having these extra selects sitting between
things can prevent other folds from applying.

Enabling this requires some mitigations in the ARM backend, in
particular in the interaction with MVE support. There's two changes
here:

* Form CSINV/CSNEG/CSINC from CMOV, rather than only creating it during
SELECT_CC lowering. (After this change, the lowering in SELECT_CC can be
dropped without test changes, let me know if I should do that.)
* Support pushing negations through CMOV in more cases, in particular if
the operands are constant or the negation can be handled by flipping
lshr/ashr.

Additionally, in the X86 backend, try to simplify CMOV to SETCC if only the
low bit is demanded.
2026-03-20 16:23:18 +01:00
Nikita Popov
f894e8e92d
[ARM] Try to lower sign bit SELECT_CC to shift (#186349)
Lower a `x < 0 ? 1 : 0` style SELECT_CC to `x>>(bw-1)`. This will become
more important with an upcoming change, but also appears to be somewhat
useful by itself.
2026-03-16 09:32:43 +01:00
Alexis Engelke
211279d11c
[CodeGenPrepare][NFC] Get BPI/BFI from pass/analysis manager (#186651)
BranchProbabilityInfo will compute it's own dominator tree and
post-dominator tree if none is specified; avoid this by using the
analysis manager/pass manager to get the analysis, which will reuse the
previously computed DomTree.
2026-03-15 17:41:22 +01:00
paperchalice
26ac669101
[LLVM] Remove "no-nans-fp-math" attribute support (#186285)
Now all `NoNaNsFPMath` uses have been removed, remove this attribute.
2026-03-13 09:29:28 +00:00
David Green
f7ab364f5e
[ARM] Add basic NPM support for LoadStoreOptimizer (#184139)
This is similar to #184090 for ARM, porting the LoadStoreOptimizer to
the new pass manager. The time there are both a pre-ra and post-ra
variant that are ported.
2026-03-08 19:28:27 +00:00
Nikita Popov
0418700f04
[SDAGBuilder] Fix incorrect fcmp+select to minnum/maxnum transform (#184590)
minnum/maxnum don't have the correct sNaN semantics, we must convert to
minimumnum/maximumnum instead.

To avoid an NVPTX regression, make it handle fmaximmumnum in one
TableGen pattern.

This is intended as a targeted fix for the miscompile, as the complete
removal of this transform (#93575) appears to be blocked.

Fixes https://github.com/llvm/llvm-project/issues/176624.
2026-03-05 08:47:01 +00:00
Nikita Popov
1a7502592f
[ARM] Generate test checks (NFC) (#184574)
I had to rename some functions to make them UTC compatible.
2026-03-04 10:38:22 +01:00
Lewis Crawford
fa6eef8378
Revert "Avoid maxnum(sNaN, x) optimizations / folds (#170181)" (#184125)
This reverts commit ea3fdc5972db7f2d459e543307af05c357f2be26.

Re-enable const-folding for maxnum/minnum in the middle-end, GlobalISel,
and SelectionDAG.

Re-enable optimizations that depend on maxnum/minnum sNaN semantics in
InstCombine and DAGCombiner.

Now that maxnum(x, sNaN) is specified to non-deterministically produce
either NaN or x, these constant-foldings and optimizations are now valid
again according to the newly clarified semantics in #172012 .
2026-03-03 12:45:26 +00:00
David Sherwood
0b36d4265e
[AArch64] Add vector expansion support for ISD::FCBRT when using ArmPL (#183750)
This patch teaches the backend how to lower the FCBRT DAG node to the
vector math library function when using ArmPL. This is similar to what
we already do for llvm.pow/FPOW, however the only way to expose this is
via a DAG combine that converts

  FPOW(<2 x double> %x, <2 x double> <double 1.0/3.0, double 1.0/3.0>)

into

  FCBRT(<2 x double> %x)

when the appropriate fast math flags are present on the node. I've
updated the DAG combine to handle vector types and only perform the
transformation if there exists a vector library variant of cbrt.
2026-03-03 10:39:21 +00:00
David Green
d68d47db7b
[ARM] Explicitly mark certain instructions as having no side effects. (#182771)
This goes through some Arm instructions and adds hasSideEffects = 0 to
ones where it was not already implied. This should help with scheduling
and instruction movement.
2026-03-01 09:33:58 +00:00
Serge Pavlov
4a93b9a1b1
[ARM] Lower strictfp vector fp16 rounding operations similar to default mode (#183700)
Previously the strictfp rounding nodes were lowered using unrolling to
scalar operations, which has negative impact on performance. Partially
this issue was fixed in #180480, this change continues that work and
implements optimized lowering for v4f16 and v8f16.
2026-02-28 22:44:22 +07:00
Serge Pavlov
2f7c947946
Precommit tests: strictfp rounding vector f16 intrinsics (#183699) 2026-02-28 20:10:24 +07:00
Folkert de Vries
2acb24eb95
[ARM] optimize to vsri/vsli (#182051)
fixes https://github.com/llvm/llvm-project/issues/181495
2026-02-26 00:33:21 +01:00
Nikita Popov
cfca635efc
[SelectionDAG] Fix fptoui.sat expansion using minnum/maxnum (#180178)
fptoui.sat can currently use a minnum/maxnum based expansion, which
relies on NaNs not being propagated. Specifically, it relies on
minnum(maxnum(NaN, 0), MAX) to return 0. However, if the input is sNaN,
then maxnum(sNaN, 0) is allowed to return qNaN, in which case the final
result will be MAX rather than 0.

This PR does the following changes:

* Support the fold for minimumnum/maximumnum, which guarantees that NaN
is not propagated even for sNaN, so it can use the old lowering. Test
this using Hexagon which has legal minimumnum but illegal minnum.
* For the minnum/maxnum case, remove the special unsigned case and
instead always insert the explicit NaN check. In that case the NaN
propagation semantics don't matter.
* This also means that we can support this expansion for
minimum/maximum.
2026-02-25 12:23:42 +00:00
Björn Pettersson
5e5e300d07
[SelectionDAG] Fix bug related to demanded bits/elts for BITCAST (#145902)
When we have a BITCAST and the source type is a vector with smaller
elements compared to the destination type, then we need to demand all
the source elements that make up the demanded elts for the result when
doing recursive calls to SimplifyDemandedBits,
SimplifyDemandedVectorElts and SimplifyMultipleUseDemandedBits. Problem
is that those simplifications are allowed to turn non-demanded elements
of a vector into POISON, so unless we demand all source elements that
make up the result there is a risk that the result would be more
poisonous (even for demanded elts) after the simplification.

The patch fixes some bugs in SimplifyMultipleUseDemandedBits and
SimplifyDemandedBits for situations when we did not consider the problem
described above. Now we make sure that we also demand vector elements
that "must not be turned into poison" even if those elements correspond
to bits that does not need to be defined according to the DemandedBits
mask.

Fixes #138513
2026-02-23 14:38:07 +01:00
David Green
37a32d47fb [ARM] Regenerate bfx.ll and pr35836.ll tests. NFC 2026-02-22 21:36:29 +00:00
Folkert de Vries
f1bfed10ad
[ARM] support r14 as an alias for lr in inline assembly (#179740)
In rustc (and I suspect Clang and Zig) there is some special logic to
rewrite `r14` into `lr` when used in inline assembly. LLVM should
probably support `r14` directly.


https://developer.arm.com/documentation/ddi0211/i/programmer-s-model/registers/the-arm-state-register-set

> You can treat r14 as a general-purpose register at all other times.

This heavily suggests that we should be able to use it as a clobber and
read its value.

This is the arm analogue to
https://github.com/llvm/llvm-project/pull/167783.
2026-02-21 14:16:14 +01:00
Serge Pavlov
19ebb0ae7f
[ARM] Treat strictfp vector rounding operations as legal (#180480)
Previously, the strictfp variants of rounding operations (FLOOR, ROUND,
etc) were handled in SelectionDAG via the default expansion, which
splits vector operation into scalar ones. This results in less efficient
code.

This change declares the strictfp counterparts of the vector rounding
operations as legal and modifies existing rules in tablegen descriptions
accordingly.
2026-02-20 12:37:10 +07:00
Jay Foad
13f659c21d
[ARM] Fix duplicate RUN lines in tests (#182280) 2026-02-19 23:48:22 +00:00
Jay Foad
ac16ce3157
[ARM] Regenerate checks in machine-sink-multidef.mir (#182314) 2026-02-19 17:24:32 +00:00
Hamza Hassanain
ca77001a1a
[ARM] Replace manual CLS expansion with ISD::CTLS (#178430)
Converts ARM scalar CLS intrinsics to use the unified ISD::CTLS node
instead of custom manual expansion. This addresses the issue
[#174337](https://github.com/llvm/llvm-project/issues/174337).

Co-authored-by: Craig Topper <craig.topper@sifive.com>
2026-02-19 07:49:26 -08:00
Alex MacLean
3e3713c2f5
[GlobalIsel] Use aext in ctlz_zero_undef widenScalar expansion (#181506)
Use `G_ANYEXT` instead of `G_ZEXT` when widening the source of
`G_CTLZ_ZERO_UNDEF`. The extended upper bits are immediately shifted out
by the subsequent left-shift, so zero-extending is unnecessarily
constraining.

Before:
```
    %wide = G_ZEXT %src
    %shifted = G_SHL %wide, sizeDiff
    %result = G_CTLZ_ZERO_UNDEF %shifted
```
After:
```
    %wide = G_ANYEXT %src
    %shifted = G_SHL %wide, sizeDiff
    %result = G_CTLZ_ZERO_UNDEF %shifted
```
2026-02-18 21:38:17 -08:00
Bill Wendling
9a0d65cdfd
[NFC][CodeGen] Rename CallBrPrepare pass to InlineAsmPrepare (#181547)
This is an NFC change to make room for a more generalized "prepare" pass
for inline assembly beyond CallBrInsts. In particular, changing how we
generate code for inline assembly with "rm" constraints.
2026-02-17 15:37:35 -08:00
Nikita Popov
c4721872af Revert "[Clang][inlineasm] Add special support for "rm" output constraints (#92040)"
This change landed without approval.

This reverts commit 45e666a8531c1148bdb170b9a120f99e1500c427.
This reverts commit a636dd4c37f12594275de2fe180ca35bc04d76ea.
2026-02-14 15:59:04 +01:00
Bill Wendling
45e666a853
[Clang][inlineasm] Add special support for "rm" output constraints (#92040)
Clang isn't able to support multiple constraints on inputs and outputs,
like "rm". Instead, it picks the "safest" one to use, i.e. the memory
constraint for "rm". This leads to obviously horrible code:

  asm __volatile__ ("pushf\n\t"
                    "popq %0"
                    : "=rm" (x));

is compiled to:

        pushf
	popq -8(%rsp)
	movq	-8(%rsp), %rax

It gets worse when inlined into other functions, because it may
introduce
a stack where none is needed.

With this change, Clang now generates IR for the more optimistic choice
("r"). All but the fast register allocator are able to fold registers if
it turns out that register pressure is too high.

This leaves the fast register allocator. The fast register allocator, as
the name suggests, is built for execution speed, not code quality. Thus,
we add special processing to convert the "optimistic" IR into the
"conservative" choice (again at the IR level), which we know it can
handle.

We focus on "rm" for the initial commit, but that can be expanded in the
future for other constraints where Clang generates ++ungood code (like
"g").

Fixes: https://github.com/llvm/llvm-project/issues/20571
2026-02-14 05:02:24 -08:00
Serge Pavlov
5ab9cbe41b
[ARM] Precommit tests: strictfp rounding vector intrinsics (#180479) 2026-02-13 13:20:40 +07:00
陈子昂
6117bdd903
[DAGCombiner] Fix subvector extraction index for big-endian STLF (#180795)
This PR fixes a big-endian regression in `ForwardStoreValueToDirectLoad`
where the wrong subvector was being extracted. In big-endian, memory
offset 0 corresponds to the high bits, so the extraction index needs to
be adjusted.

As suggested by @KennethHilmersson, calculate the extraction index as
the difference between the number of elements in the intermediate vector
and the load vector when in big-endian mode.

Special thanks to Kenneth Hilmersson for providing the fix logic and the
ARM regression test.
https://github.com/llvm/llvm-project/pull/172523#issuecomment-3878065191
https://github.com/llvm/llvm-project/pull/172523#issuecomment-3879575092
2026-02-12 17:42:13 +08:00
paperchalice
c53acf0443
[SelectionDAGBuilder] Remove NoNaNsFPMath uses (#169904)
Replaced by checking fast-math flags or value tracking results.
2026-02-09 09:48:07 +08:00
Jay Foad
48619c8ab2
[ARM] Autogenerate checks for crypto intrinsics (#180147) 2026-02-06 14:33:22 +00:00
SiliconA-Z
37aba1b5d4
[ARM] Set operation action for UMULO and SMULO as Custom if not Thumb1 (#154253)
We should specify a custom lowering for SMULO and UMULO like we do for
AArch64, but only if not Thumb 1 obviously.
2026-02-05 08:47:56 -08:00
Matt Arsenault
2502e3b7ba
IR: Promote "denormal-fp-math" to a first class attribute (#174293)
Convert "denormal-fp-math" and "denormal-fp-math-f32" into a first
class denormal_fpenv attribute. Previously the query for the effective
denormal mode involved two string attribute queries with parsing. I'm
introducing more uses of this, so it makes sense to convert this
to a more efficient encoding. The old representation was also awkward
since it was split across two separate attributes. The new encoding
just stores the default and float modes as bitfields, largely avoiding
the need to consider if the other mode is set.

The syntax in the common cases looks like this:
  `denormal_fpenv(preservesign,preservesign)`
  `denormal_fpenv(float: preservesign,preservesign)`
  `denormal_fpenv(dynamic,dynamic float: preservesign,preservesign)`

I wasn't sure about reusing the float type name instead of adding a
new keyword. It's parsed as a type but only accepts float. I'm also
debating switching the name to subnormal to match the current
preferred IEEE terminology (also used by nofpclass and other
contexts).

This has a behavior change when using the command flag debug
options to set the denormal mode. The behavior of the flag
ignored functions with an explicit attribute set, per
the default and f32 version. Now that these are one attribute,
the flag logic can't distinguish which of the two components
were explicitly set on the function. Only one test appeared to
rely on this behavior, so I just avoided using the flags in it.

This also does not perform all the code cleanups this enables.
In particular the attributor handling could be cleaned up.

I also guessed at how to support this in MLIR. I followed
MemoryEffects as a reference; it appears bitfields are expanded
into arguments to attributes, so the representation there is
a bit uglier with the 2 2-element fields flattened into 4 arguments.
2026-02-05 13:31:26 +00:00
paperchalice
d1598c96e0
[ARM] Recognize abi tag module flags (#161306)
Recognize abi tag hints from frontend rather than from architecture and
options.
Frontend part: #161106.
2026-02-05 12:08:22 +00:00
Simi Pallipurath
09a68427ff
[ARM] Lower unaligned loads/stores to aeabi functions. (#172672)
When targeting architectures that do not support unaligned memory
accesses or when explictly pass -mno-unaligned-access, it requires the
compiler to expand each unaligned load/store into an inline sequences.
For 32-bit operations this typically involves:

	1. 4× LDRB (or 2× LDRH),
	2. multiple shift/or instructions

These sequences are emitted at every unaligned access site, and
therefore contribute significant code size in workloads that touch
packed or misaligned structures.

When compiling with -Oz and in combination with -mno-unaligned-access,
this patch lowers unaligned 32 bit and 64 bit loads and stores to below
AEABI heper calls:
```
         __aeabi_uread4
	__aeabi_uread8
	__aeabi_uwrite4
	__aeabi_uwrite8
```

And it provide a way to perform unaligned memory accesses on targets
that do not support them, such as ARMv6-M or when compiling with
-mno-unaligned-access. Although each use introduces a function call
making it less straightforward than using raw loads and stores the call
itself is often much smaller than the compiler emitted sequence of
multiple ldrb/strb operations. As a result, these helpers can greatly
reduce code-size providing they are invoked more than once across a
program.

1. Functions become smaller in AEABI mode once they contain more than a
few unaligned accesses.
2. The total image .text size becomes smaller whenever multiple
functions call the same helpers.

This PR is derived from https://reviews.llvm.org/D57595, with some minor
changes.
 Co-authored-by: David Green
2026-02-02 16:32:12 +00:00
David Green
1bc655f52b [ARM] Expand and regenerate llvm/test/CodeGen/ARM/cls.ll. NFC 2026-02-02 11:28:07 +00:00
Nikita Popov
1bad00adc4
[SDAG] Remove non-canonical fabs libcall handling (#177967)
This is a followup to https://github.com/llvm/llvm-project/pull/171288,
which removed lowering of libcalls to SDAG nodes for most libcalls that
get unconditionally canonicalized to intrinsics. This handles the
remaining fabs case, which I originally skipped due to larger test
impact.
2026-01-26 15:11:17 +00:00
Simon Tatham
0921542e3b
[ARM] Count register copies when estimating function size (#175763)
`EstimateFunctionSizeInBytes`, in `ARMFrameLowering.cpp`, provides an
early estimate of the compiled size of a function, in a context that
wants to overestimate rather than underestimate.

In some cases it was underestimating severely, by over 20%. The
discrepancy was entirely accounted for by the fact that `COPY`
operations were not being counted at all, even though each one (or at
least each one that survives any post-regalloc optimizations) takes 2
bytes in Thumb or 4 in Arm. This could lead to a compile failure, if the
underestimated function size led frame lowering to not stack LR, but
later, `ARMConstantIslandsPass` needed to insert an intra-function
branch long enough to require a `bl` instruction, needing LR to have
been stacked.

The result of `EstimateFunctionSizeInBytes` was not directly available
for testing, so I added an `LLVM_DEBUG` at the end of the function. That
way, the test file doesn't need to try to make a >2048 byte function
estimated at <2048 bytes; it just needs to exhibit a function with a
single `COPY` and make sure it's counted.

At the moment, `EstimateFunctionSizeInBytes` is only used at all in
Thumb-1 compilations, to decide whether the function is large enough to
justify stacking LR as a precaution. However, the subroutine
`ARMBaseInstrInfo::getInstSizeInBytes` which counts each individual
`MachineInstr` is called from other contexts too, so I've made it return
a sensible answer for `COPY` nodes in both of Arm and Thumb.
2026-01-26 09:28:38 +00:00
valadaptive
cdc6a84c14
TargetLowering: Allow FMINNUM/FMAXNUM to lower to FMINIMUM/FMAXIMUM even without nsz (#177828)
This restriction was originally added in
https://reviews.llvm.org/D143256, with the given justification:

> Currently, in TargetLowering, if the target does not support fminnum,
we lower to fminimum if neither operand could be a NaN. But this isn't
quite correct because fminnum and fminimum treat +/-0 differently; so,
we need to prove that one of the operands isn't a zero.

As far as I can tell, this was never correct. Before
https://github.com/llvm/llvm-project/pull/172012, `minnum` and `maxnum`
were nondeterministic with regards to signed zero, so it's always been
perfectly legal to lower them to operations that order signed zeroes.
2026-01-25 18:24:12 -05:00
Tony Linthicum
15b9109bc7
Make MachineBlockFrequencyInfo a required pass for the MachineScheduler pass. (#176172)
This is needed to support functionality in the AMDGPU scheduler. Various
passes have been modified to preserve MBFI to ensure that this change
does not introduce new invocations of MBFI. Some targets have passes
reordered, but there are no new runs of MBFI.
2026-01-15 20:26:51 +00:00
Usman Nadeem
c49c7e72b3
[ARM] Add size to tLDRLIT_ga_pcrel|abs Pseudo Instructions (#175663)
Compiling OpenSSL for Thumb was giving a crash in `ARMConstantIslands`
with error message: "underestimated function size". Adding a size for
`tLDRLIT_ga_pcrel` pseudo instruction fixes the issue. Also added a
size for `tLDRLIT_ga_abs` as per review comments.
2026-01-15 11:27:13 -08:00
David Green
2f43659011
[ARM] Add tablegen patterns for vsdot and vudot high index. (#174728)
The index on a vsdot and vudot instruction can be 0/1 from a D-reg, not 0/1/2/3
from a Q reg as would be expected. Add a pattern to allow extracting from the
high half of the input vector.

Fixes #174688
2026-01-14 10:26:05 +00:00
moorabbit
a5fa246435
[Clang] Add __builtin_stack_address (#148281)
Add support for `__builtin_stack_address` builtin. The semantics match
those of GCC's builtin with the same name.

`__builtin_stack_address` returns the starting address of the stack
region that may be used by called functions. It may or may not include
the space used for on-stack arguments passed to a callee (See [GCC
Bug/121013](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121013)).

Fixes #82632.
2026-01-12 10:01:57 +01:00
David Green
7635474d26 [ARM] Update and extend neon-dot-product.ll. NFC 2026-01-07 10:18:27 +00:00
Frederik Harwath
5c05824d2b
[CodeGen] Rename expand-fp to expand-ir-insts (#172681)
The pass now contains a non-fp expansion and should
be used for any similar expansions regardless of the
types involved. Hence a generic name seems apt.

Rename the source files, pass, and adjust the pass
description. Move all tests for the expansions
that have previously been merged into the pass
to a single directory.
2025-12-18 11:15:04 +00:00
Frederik Harwath
71760f324f
[CodeGen] Merge ExpandLargeDivRem into ExpandFp (#172680)
Both passes expand instructions at the IR level.
They use the same kind of instruction visitation
logic and contain significant code duplication e.g.
for scalarization.
2025-12-18 09:22:47 +01:00
Folkert de Vries
a587ccd87d
fix llvm.fma.f16 double rounding issue when there is no native support (#171904)
fixes https://github.com/llvm/llvm-project/issues/98389

As the issue describes, promoting `llvm.fma.f16` to `llvm.fma.f32` does
not work, because there is not enough precision to handle the repeated
rounding. `f64` does have sufficient space. So this PR explicitly
promotes the 16-bit fma to a 64-bit fma.

I could not find examples of a libcall being used for fma, but that's
something that could be looked in separately to work around code size
issues.
2025-12-17 22:03:01 +01:00
Craig Topper
0cdc1b6dd4
[SelectionDAG] Support integer types with multiple registers in ComputePHILiveOutRegInfo. (#172081)
PHIs that are larger than a legal integer type are split into multiple
virtual registers that are numbered sequentially. We can propagate the
known bits for each of these registers individually.

Big endian is not supported yet because the register order needs to be
reversed.

Fixes #171671
2025-12-13 13:24:41 -08:00