39361 Commits

Author SHA1 Message Date
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
Craig Topper
0afc30f8d5
[TargetLowering] Add helper to create FSHR like operation in expandDIVREMByConstant. NFC (#187979) 2026-03-23 08:49:38 -07:00
Craig Topper
c75b8a1649
[TargetLowering] Avoid unnecessary nodes in the chunk loop in expandDIVREMByConstant (#187967)
We don't need an AND on the last iteration. If we shifted the dividend
due to trailing zeros in the divisor, we don't need a chunk that only
contains shifted in zeros.
2026-03-23 08:48:59 -07:00
Nikita Popov
61b3b20fd9 [AsmPrinter] Fix some issues with instruction size verification
If the instruction is part of a bundle, then emitInstruction() will
emit the entire bundle. As such, we should be summing up the sizes
of all instructions in the bundle.

Additionally, do not run the verification if an error has already
occurred. In that case, there may be a size mismatch as a result
of the error.

These came up when trying to enable the verification on additional
targets.
2026-03-23 14:46:53 +01:00
Abdullah Sarkar
364f8d4239
[DAG] isKnownNeverZero - add ISD::VECTOR_SHUFFLE handling (#187855)
Fixes #183351
2026-03-23 12:53:49 +00:00
Max Graey
7c6996fc8f
[ValueType][NFC] Add widenIntegerElementType method (#187816)
Fixes #187805
2026-03-23 09:43:47 +00:00
Nikita Popov
85ab2a9706
[AsmPrinter] Add generic support for verifying instruction sizes (#187703)
Many backends rely on TII reporting correct instruction sizes for MIR
level branch relaxation passes. Reporting a too small size can result in
MC fixup failures (or silent miscompiles for unvalidated fixups).

Some time ago I added validation to the PPC asm printer to verify that
the TII instruction size matches the actually emitted size. This was
very helpful to systematically fix all incorrectly reported instruction
sizes.

However, the same problem also exists in lots of other backends, so this
moves the validation into AsmPrinter, controlled by a new
getInstSizeVerifyMode() hook in TII, which is disabled by default.

The intention here is to gradually enable this validation for more
backends (which requires fixing them first).
2026-03-23 09:40:37 +00:00
Craig Topper
f146677396
[TargetLowering] Refactor expandDIVREMByConstant to share more code. NFC (#187582)
Make the (1 << HBitWidth) % Divisor == 1 path a special case within
the recently added chunk summing algorithm. This allows us to
share the trailing zero shifting code.

While there make some comment improvements and avoid creating
unnecessary nodes.
2026-03-21 11:23:16 -07:00
Craig Topper
c1df6937ba
[TargetLowering] Use legally typed shifts to split chunks in expandDIVREMByConstant. (#187567)
This replaces LegalVT with HiLoVT and LegalWidth with HBitWidth as
they are the same for all current uses.
    
Then we rewrite the shifts to operate on LL and LH.
    
There's a slight regression on RISC-V due to different node creation
order leading to different DAG combine order. I have other refactoring
I'd like to explore then I may try to fix that.
2026-03-21 09:31:20 -07:00
Craig Topper
343b566b57
[TargetLowering] Move the MULH/MUL_LOHI legality checks to the beginning of BuildSDIV/UDIV. NFCI (#187780)
This groups the type and operation legality checks to the beginning. The
rest of the code can focus on the transformation.
2026-03-20 14:52:28 -07:00
Craig Topper
3eecb98b37
[TargetLowering] Separate some of the control for the i32->i64 optimization out of BuildUDIVPattern. (#187739)
Check the type before we call getOperationAction. Give BuildUDIVPattern
only AllowWiden and a WideSVT.

Update variable names and comments to avoid spreading "64" to too many
places.
2026-03-20 14:52:09 -07:00
Dhruva
68a9e9ca3e
[GlobalISel] Add G_ABDU and G_ABDS to computeKnownBits. (#186822)
This code is adapted from `SelectionDAG::computeKnownBits`
part of #150515 
ticks off ABDS & ABDU
2026-03-20 17:08:14 +00:00
Osman Yasar
8cbf3f3c39
[GlobalISel] Fold a bitwiseop (~b +/- c) -> a bitwiseop ~(b -/+ c) (#181725)
Based on the suggestions in #140639, this PR adds the rewrite pattern `a
bitwiseop (~b +/- c)` -> `a bitwiseop ~(b -/+ c)` for AND, OR, and XOR
operations. This rewrite enables lowering to `ANDN`, `ORN`, and `XORN`
operations.

Added new MIR tests in `combine-binop-neg.mir` for AArch64 to verify the
new combine works for various commuted and uncommuted forms with AND,
OR, and XOR and added new LLVM IR tests for RISC-V in `rv32zbb-zbkb.ll`
to ensure the combine produces the expected `ANDN`, `ORN`, and `XORN`
operations.
2026-03-20 15:53:07 +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
Romanov Vlad
a704195054
[AMDGPU] Shrink S_MOV_B64 to S_MOV_B32 during rematerialization (#184333)
When rematerializing S_MOV_B64 or S_MOV_B64_IMM_PSEUDO and only a single
32-bit lane of the result is used at the remat point, emit S_MOV_B32
with the appropriate half of the 64-bit immediate instead.

This reduces register pressure by defining a 32-bit register instead of
a 64-bit pair when the other half is unused.
2026-03-20 15:09:13 +01:00
Nikita Popov
ab28384cd3
[ExpandMemCmp] Remove unused TM/TLI dependency (#187660)
This pass does not actually use TargetMachine/TargetLoweringInfo.
2026-03-20 08:59:20 +00:00
Tomer Shafir
69cd746bd2
[llc] Add -mtune option (#186998)
This patch adds a Clang-compatible -mtune option to llc, to enable
decoupled ISA and microarchitecture targeting, which is especially
important for backend development. For example, it can enable to easily
test a subtarget feature or scheduling model effects on codegen across a
variaty of workloads on the IR corpus benchmark:
https://github.com/dtcxzyw/llvm-codegen-benchmark.

The implementation adds an isolated generic codegen flag, to establish a
base for wider usage - the plan is to add it to `opt` as well in a
followup patch. Then `llc` consumes it, and sets `tune-cpu` attributes
for functions, which are further consumed by the backend.
2026-03-20 10:20:40 +02:00
Akshay Deodhar
9e54ca12e9
[AtomicExpandPass] Remove AtomicExpandUtils.h (NFC) (#187609)
The purpose of AtomicExpandUtils.h was to allow code reuse with [PNaCl
](https://en.wikipedia.org/wiki/Google_Native_Client)which has since
been deprecated. This PR removes the file, and migrates the declarations
to be visible only in the necessary scopes.
2026-03-20 00:31:34 +00:00
Changpeng Fang
edf0fb8132
[GISEL][NFC] Remove a useless assert in constrainSelectedInstRegOperands (#187592) 2026-03-19 17:20:25 -07:00
Craig Topper
b6543c98d7 [TargetLowering] Make sure LL/LH are always initialized in expandDIVREMByConstant
This is quick fix to fix some reported failures.
2026-03-19 11:48:07 -07:00
jeanPerier
76f7252571
[FastISel] generate FAKE_USE for llvm.fake.use (#187116)
FastISel was dropping llvm.fake.use because they are not meant to be
generated at O0 with clang.

This patch adds support in FastISel to generate FAKE_USE for llvm.fake.use.
The handling is simpler than in SelectionDagBuilder because no attempt is made to
get rid of useless FAKE_USE (e.g. for constant SSA values) to keep FastISel simple.

The motivation is that flang will generate llvm.fake.use for function arguments under
`-g` (and O0) because Fortran arguments are not copied to the stack (they are
reference like arguments in most cases) and one should be able to access these
variables from the debugger at any point of the function, even after their last use in the
function.
2026-03-19 14:06:26 +01:00
Shivam Gupta
796b218edd
[LegalizeTypes] Expand UDIV/UREM by constant via chunk summation (#146238)
This patch improves the lowering of 128-bit unsigned division and
remainder by constants (UDIV/UREM) by avoiding a fallback to libcall
(__udivti3/uremti3) for specific divisors.

When a divisor D satisfies the condition (1 << ChunkWidth) % D == 1, the
128-bit value is split into fixed-width chunks (e.g., 30-bit) and summed
before applying a smaller UDIV/UREM. This transformation is based on the
"remainder by summing digits" trick described in Hacker’s Delight.

This fixes #137514 for some constants.
2026-03-19 17:58:54 +05:30
Paul Walker
7663802125
[LLVM][DAGCombiner] Limit extract_subvec(extract_subvec()) combine to vectors of the same type. (#187334)
The index operand of ISD::EXTRACT_SUBVECTOR is implicitly scaled by
vscale, which is effectively always one for fixed-length vectors. When
combining nested extracts we must ensure all use the same implicit
scaling otherwise the transform is not equivalent.

Fixes https://github.com/llvm/llvm-project/issues/186563
2026-03-19 11:14:30 +00:00
Alexis Engelke
0d05c882ce
[Support] Use block numbers for LoopInfo BBMap (#103400)
Replace the DenseMap from blocks to their innermost loop a vector
indexed by block numbers, when possible. Supporting number updates is
not trivial as we don't store a list of basic blocks, so this is not
implemented.

NB: I'm generally not happy with the way loops are stored. As I think
that there's room for improvement, I don't want to touch the
representation at this point.

Pull Request: https://github.com/llvm/llvm-project/pull/103400
2026-03-19 11:18:06 +01:00
Shivam Kunwar
4262045ba9
[DebugInfo] Fix segfault in constructSubprogramScopeDIE with null subprogram type (#184299)
Guard against null DISubroutineType when checking for variadic
parameters in `constructSubprogramScopeDIE`. `DISubprograms` may lack a
type field when using LineTablesOnly emission, causing a null pointer
dereference.

Fixes #184003

Co-authored-by: Shivam Kunwar <phyBrackets@users.noreply.github.com>
2026-03-19 15:27:04 +05:30
Craig Topper
291359be68
[SelectionDAG] Move the call to BuildExactSDIV and BuildExactUDIV to the top of BuildSDIV/BuildUDIV. (#187378)
This moves it above the type legality check. The legality check we use
for the main division by constant algorithm is probably not right for
BuildExactSDIV and BuildExactSDIV. These checks are largely about the
legality of MUL_LOHI/MULH which are not used for the exact case.

This patch removes the legal type check for the exact case. If we do
need a check it's probably better to have a specific version in
BuildExactSDIV and BuildExactSDIV.

I'm hoping to do some refactoring of the legality checks in
BuildSDIV/BuildUDIV so separating them makes this easier.
2026-03-18 19:54:47 -07:00
Tobias Stadler
3f36e7030f
[AsmPrinter] Only warn about unsupported remarks section if requested (#187362)
Remarks sections are no longer necessary for basic functioning of
bitstream remarks, so only fire a warning if remarks sections are
force-enabled.

Pull Request: https://github.com/llvm/llvm-project/pull/187362
2026-03-18 15:53:46 -07:00
Elia Geretto
03f488a002
[AsmPrinter][MTE] Support memtag-globals for all AArch64 targets (#187065)
This change ensures that all AArch64 targets can use memtag globals, not
only Android.
2026-03-18 12:22:55 -07:00
Craig Topper
9dd2e3792a
[DAGCombiner] Move the XORHandle in rebuildSetCC inside the while loop. (#187189)
If N was changed on the previous loop iteration, we need the handle to
point at the new N.

Fixes #186969.
2026-03-18 09:30:05 -07:00
Pengcheng Wang
2734c46153
[DAG] Add back SelectionDAG::dump() without parameter (#187001)
Usually `dump()`s are without parameter, so the practice is calling
`XXX::dump()` when debugging.

But we will get an error like below after #161097:

```
error: <user expression 128>:1:10: too few arguments to function call,
expected 1, have 0
    1 | DAG.dump()
      | ~~~~~~~~ ^
```

So to not surprise users, I added back the `SelectionDAG::dump()`
without parameter.
2026-03-18 18:34:03 +08:00
gonzalobg
ea8fb06f24
[atomicrmw] fminimumnum/fmaximumnum support (#187030)
Adds support for `atomicrmw` `fminimumnum`/`fmaximumnum` operations.
These were added to C++ in P3008, and are exposed in libc++ in #186716 .
Adding LLVM IR support for these unblocks work in both backends with HW
support, and frontends.
2026-03-18 09:35:49 +01:00
Demetrius Kanios
351501799a
[CodeGen] Improve getLoadExtAction and friends (#181104)
Alternative approach to the same goals as #162407

This takes `TargetLoweringBase::getLoadExtAction`, renames it to
`TargetLoweringBase::getLoadAction`, merges `getAtomicLoadExtAction`
into it, and adds more inputs for relavent information (alignment,
address space).

The `isLoadExtLegal[OrCustom]` helpers are also modified in a matching
manner.

This is fully backwards compatible, with the existing `setLoadExtAction`
working as before. But this allows targets to override a new hook to
allow the query to make more use of the information. The hook
`getCustomLoadAction` is called with all the parameters whenever the
table lookup yields `LegalizeAction::Custom`, and can return any other
action it wants.
2026-03-17 23:40:19 -07:00
Alexis Engelke
9a2f23e1a4
[CodeGen] Use separate MBB number for analyses (#187086)
Block numbers are updated too frequently, which makes it difficult to
keep analyses up to date. Therefore, introduce a second number per basic
block that is used for analyses and is renumbered less often. This frees
analyses from providing somewhat efficient facilities for dealing with
changed block numbers, making it simpler to implement in e.g. LoopInfo
or CycleInfo.

(Currently, "less often" means not at all, but we might want to renumber
after certain passes if the numbering gets too sparse and no analyses
are preserved anyway.)

When we introduced a more general use of block numbers some time ago,
using the existing numbers seemed to be a somewhat obvious choice, but I
now think that this was a bad decision, as it conflates a number that is
used for ordering with a number that should be more stable.

MachineBasicBlock isn't particularly size-optimized and there's a fair
amount of padding where we can add another number.

There should be no performance impact,
2026-03-18 07:35:36 +01:00
Gergo Stomfai
e8a03bb043
[CodGen] Port UnpackMachineBundles to new pass manager (#184918) 2026-03-17 09:01:37 -07:00
Ivan Kosarev
f1a7c7e772
[MIR] Support symbolic INLINEASM extra-info flags (#186818) 2026-03-17 11:08:28 +00:00
Ivan Kosarev
df03e1a372
[MIR] Fix printing INLINEASM dialects. (#186797) 2026-03-17 10:07:14 +00:00
Craig Topper
ded656b467
[TargetLowering][X86] Directly emit FSHR from expandDIVREMByConstant when Legal. (#186863) 2026-03-16 16:48:34 -07:00
Pedro Lobo
57568c288d
[Reland][IR] Add initial support for the byte type (#186888)
This patch relands https://github.com/llvm/llvm-project/pull/178666. The
original version caused CI failures due to the missing target triple in
`llvm/test/CodeGen/X86/byte-constants.ll`. CI should be green now.
2026-03-16 23:32:24 +00:00
Tomer Shafir
d8386dbe7d
[CodeGen] Call getMCPU once instead of commonly twice (NFC) (#186581) 2026-03-16 10:28:33 +02:00
Luke Lau
7a8903566d
[SelectionDAG] Add CTTZ_ELTS[_ZERO_POISON] nodes. NFCI (#185600)
Currently llvm.experimental.cttz.elts are directly lowered from the
intrinsic.

If the type isn't legal then the target tells SelectionDAGBuilder to
expand it into a reduction, but this means we can't split the operation.
E.g. it's possible to split a cttz.elts nxv32i1 into two nxv16i1,
instead of expanding it into a nxv32i64 reduction.

vp.cttz.elts can be split because it has a dedicated SelectionDAG node.

This adds CTTZ_ELTS and CTTZ_ELTS[_ZERO_POISON] nodes and just enough
legalization to get tests passing. A follow up patch will add splitting
and move the expansion into LegalizeDAG.
2026-03-16 14:39:35 +08:00
Pedro Lobo
70cd2acbd3
Revert "[IR] Add initial support for the byte type" (#186713)
Reverts llvm/llvm-project#178666 to unblock CI.
`CodeGen/X86/byte-constants.ll` is at fault. 
Will look into it and hopefully fix it by tomorrow.
2026-03-15 23:29:21 +00:00
Pedro Lobo
80f2ef70f5
[IR] Add initial support for the byte type (#178666)
Following the [byte type RFC](https://discourse.llvm.org/t/rfc-add-a-new-byte-type-to-llvm-ir/89522)
and the discussions within the [LLVM IR Formal Specification WG](https://discourse.llvm.org/t/rfc-forming-a-working-group-on-formal-specification-for-llvm/89056), this PR introduces initial support for the byte type in LLVM. This PR:
- Adds the byte type to LLVM's type system
- Extends the `bitcast` instruction to accept the byte operands
- Adds parsing tests for all new functionality
- Fixes failing regressions tests (IR2Vec and IRNormalizer)

---------

Co-authored-by: George Mitenkov <georgemitenk0v@gmail.com>
2026-03-15 21:56:06 +00: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
Iasonaskrpr
b44434474e
Improved ISD::SRL handling in isKnownToBeAPowerOfTwo (#182562)
Fixes #181651

Added DemandedElts argument to isConstOrConstSplat and to
isKnowTobePowerOfTwo calls and OrZero || isKnownNeverZero(Val, Depth) is
checked before isKnowTobePowerOfTwo. Also added unit tests.
2026-03-14 18:49:08 +00:00
Alexis Engelke
01571f1b4a
[CodeGen] Drop uses of BranchInst (#186391)
Largely a straight-forward replacement with occasional simplifcations.

For AMDGPU, I assumed that unconditional branches are always uniform and
therefore "simplified"/changed AMDGPUAnnotateUniformValues to only
annotate conditional branches.

Target-specific FastISel only selects conditional branches,
unconditional branches are already handled by the non-target-specific
code.
2026-03-13 21:51:38 +00:00
vporpo
40ea2f3513
[MIR][MachineInstr] Update MachineInstr::eraseFromParent() to return an iterator (#179787)
Unlike LLVM IR `Instruction::eraseFromParent()`,
`MachineInstr::eraseFromParent()` is void and does not return the
iterator following the erased instruction. Returning an iterator can be
very helpful for example when we are erasing MachineInstrs while
iterating, as it provides a convenient way to get a valid iterator.

This patch updates `MachineInstr::eraseFromParent()` to return a
`MachineBlock::iterator` (which is a
`MachineInstrBundleIterator<MachineInstr>`). If the erased instruction
is the head of a bundle, then the returned iterator points to the next
bundle (see unittest).
2026-03-13 13:39:13 -07:00
Ivan Kosarev
c272252bbd
[MIR] Support symbolic inline asm tiedto constraints (#186397)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 16:18:58 +00:00
Ivan Kosarev
991fd93780
[MIR] Support symbolic inline asm operands (#185893)
Support parsing and printing inline assembly operands in MIR using the
symbolic form instead of numeric register class IDs, thus removing the
need to update tests when the numbers change.

The numeric form remains supported.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:50:16 +00:00
Alexis Engelke
94da4039cb
[Analysis][NFC] Drop use of BranchInst (#186374)
Largely straight-forward replacement.
2026-03-13 13:42:19 +00:00
Fabian Ritter
f2749f6645
[LowerMemIntrinsics][AMDGPU] Optimize memset.pattern lowering (#185901)
This patch changes the lowering of the [experimental.memset.pattern intrinsic](https://llvm.org/docs/LangRef.html#llvm-experimental-memset-pattern-intrinsic)
to match the optimized memset and memcpy lowering when possible. (The tl;dr of
memset.pattern is that it is like memset, except that you can use it to set
values that are wider than a single byte.)

The memset.pattern lowering now queries `TTI::getMemcpyLoopLoweringType` for a
preferred memory access type. If the size of that type is a multiple of the set
value's type, and if both types have consistent store and alloc sizes (since
memset.pattern behaves in a way that is not well suitable for access widening
if store and alloc size differ), the memset.pattern is lowered into two loops:
a main loop that stores a sufficiently wide vector splat of the SetValue with
the preferred memory access type and a residual loop that covers the remaining
set values individually.

In contrast to the memset lowering, this patch doesn't include a specialized
lowering for residual loops with known constant lengths. Loops that are
statically known to be unreachable will not be emitted.

For backends that don't override `TTI::getMemcpyLoopLoweringType`, the
generated code is mostly unchanged except for more consistent basic block
names, no more `br i1 false` for memset.patterns with known size, and a flipped
loop condition for memset.patterns with known size (see test changes).

This is a follow-up to a similar patch for memset: #169040
2026-03-13 10:37:33 +01:00