9731 Commits

Author SHA1 Message Date
David Green
4dc4abc094 [AArch64][GlobalISel] Add test coverage for arm64-neon-2velem-high.ll and mla_mls_merge.ll. NFC 2026-02-10 13:59:51 +00:00
Kerry McLaughlin
e043195ef4
[AArch64] Add support for intent to read prefetch intrinsic (#179709)
This patch adds support in Clang for the PRFM IR instruction, by adding
the following builtin:

  void __pldir(void const *addr);

This builtin is described in the following ACLE proposal:
https://github.com/ARM-software/acle/pull/406
2026-02-10 10:12:52 +00:00
Benjamin Maxwell
b91eb9b4e5
[SDAG] Implement missing legalization for ISD::VECTOR_FIND_LAST_ACTIVE (#180290)
This lowers the splitting as:
```
any_active(hi_mask)
  ? (find_last_active(hi_mask) + lo_mask.getVectorElementCount())
  : find_last_active(lo_mask)
```

And trivially lowers `<1 x i1>` scalarization to returning zero. Which
is a natural result of the splitting (and the lack of a sentinel
"none-active" result value).

The lowerings likely can be improved. This patch is for completeness.

Should fix:
https://github.com/llvm/llvm-project/pull/178862#issuecomment-3862310334
Fixes #180212
2026-02-10 09:01:13 +00:00
Daniel Paoliello
853a39043e
[win][aarch64] The Windows Control Flow Guard Check function also preserves X15 (#179738)
The target function to be checked by the Control Flow Guard Check
function is stored in `X15` on AArch64. This register is guaranteed to
be preserved by that function (on success), thus after it returns `X15`
can be used to branch to the target function instead of having to load
it from another register or the stack.
2026-02-09 15:35:20 -08:00
Alexey Merzlyakov
4136d3f248
[AArch64] Inline asm v0-v31 are scalar when having less than 64-bit capacity (#169930)
If 32-bit (or less) "v0" registers coming from inline asm are treated as
vector ones, codegen might produce incorrect vector<->scalar
conversions. This causes types mismatch assertion failures later during
compile-time. The fix treats 32-bit or less v0-v31 AArch64 registers as
scalar, along with 64-bit ones.

Fixes #153442
2026-02-09 13:26:31 -08:00
John Brawn
77cb666078
[AArch64] Add support for B and H loads/stores in LoadStoreOptimizer (#180535)
This means the load/store optimizer can generate pre and post increment
versions of these instructions.
2026-02-09 17:48:31 +00:00
Gergo Stomfai
2298b8606d
[GISel] computeKnownBits - add CTLS handling (#178063)
Closes llvm/llvm-project#174370
2026-02-09 09:30:45 +00: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
Moritz Zielke
b0cc73d00c
[GlobalISel] add G_ROTL, G_ROTR to computeKnownBits (#166365)
Adresses one of the subtasks of #150515.

The code is ported from `SelectionDAG::computeKnownBits` and tests are
loosely based on `AArch64/GlobalISel/knownbits-shl.mir`.
2026-02-07 15:32:09 +00:00
Kyungwoo Lee
8e17489026
[CGData][GMF] Preserve Profile Data (#180126)
Profile data for instructions (e.g., branch weights) is automatically
preserved via `splice()` which moves the basic blocks along with their
instruction metadata. However, entry count is stored as function
metadata, which was dropped when creating merged function and thunks.

The fix is to explicitly set entry count for both merged function (.Tgm)
and thunks via `setEntryCount()`.
2026-02-06 10:03:39 -08:00
David Green
08cf3e62b4
[AArch64][GlobalISel] Add GISel handling for FCVT fixed. (#178903)
This uses the generalized code from #178603 to allow GISel to
select fixed-point fcvt in the same way as SDAG.
2026-02-05 22:25:38 +00:00
Folkert de Vries
9639e9669e
[AArch64] fix copy from GPR32 to FPR16 (#176594)
fixes https://github.com/llvm/llvm-project/issues/79822
cc https://github.com/rust-lang/rust/issues/120374

The example fails on nightly https://godbolt.org/z/zEojPzqWc.
2026-02-05 21:13:03 +01:00
Jameson Nash
d762cc2f03
[GlobalISel] Add SVE support for alloca (#178976)
Complementary to the same handling code in SelectionDAG:

f3d81d4110/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (L160-L165)

f3d81d4110/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (L4613-L4623)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 14:00:34 -05:00
Matthew Devereau
3ee7a2f62b
Add clmul zext AArch64 lowering tests (#179641) 2026-02-05 13:48:36 +00: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
Graham Hunter
ad86f7dda3
[AArch64] Use brk{a,b} for a lane mask from cttz.elts (#178674)
cttz.elts is usually lowered (for SVE) to a brkb followed by a cntp. If
we then want a mask based on that (say, for early exit masking) then we
would use a whilelo from 0 to the result of cntp. But that just gives us
the same mask as the initial brkb, so we can just remove the cntp and
the whilelo.

Brka matches the extra +1 in the pattern.
2026-02-05 10:19:22 +00:00
Cullen Rhodes
135ec4eb25
[AArch64] Add test coverage for funnel shift with undef amount. NFC (#179888)
Precommit tests for #57256 showing inconsistencies between SDAG and
GISel for funnel shift with undef amount. GISel is wrong and should
match SDAG.
2026-02-05 10:00:32 +00:00
Benjamin Maxwell
c7dd96e6f2
[AArch64][SME] Add missing ZT0 transition (#179193)
This transition was missed off the switch, but is already supported (see
the test for the expected behavior).
2026-02-05 08:57:23 +00:00
Ryotaro Kasuga
2ca54b41a4
[MachinePipeliner] Remove isLoopCarriedDep calls in computeStart (#174393)
When computing the viable cycles for scheduling an instruction,
`computeStart` used to include special-case logic to handle loop-carried
dependencies. This special handling was necessary because loop-carried
dependencies were represented by reversed forward-direction edges in the
DAG. Now that we have the DDG, which explicitly models loop-carried
dependencies, this special handling is no longer required. As a first
step towards completely removing `isLoopCarriedDep`, this patch
eliminates the special-case logic from `computeStart` and some related
functions.

Split off from https://github.com/llvm/llvm-project/pull/135148
2026-02-05 06:05:48 +00:00
Ryotaro Kasuga
82c0607ffd
[MachinePipeliner] Add loop-carried dependences for FPExceptions (#174392)
As with loads and stores, instructions that may trigger floating‑point
exceptions must not be reordered across a barrier instruction. This
patch adds the missing loop‑carried dependencies between such
instructions and the barrier, preventing reordering that could
previously occur. Same as #174391, the implementation is based on that
of `ScheduleDAGInstrs::buildSchedGraph`.

Split off from #135148
2026-02-05 05:32:10 +00:00
Ryotaro Kasuga
dfdc3b72d2
[MachinePipelner] Add loop-carried dependencies for global barriers (#174391)
The loads/stores must not be reordered across barrier instructions.
However, in MachinePipeliner, it potentially could happen since
loop-carried dependencies from loads/stores to a barrier instruction
were not considered. The same problem exists for barrier-to-barrier
dependencies. This patch adds the handling for those cases. The
implementation is based on that of `ScheduleDAGInstrs::buildSchedGraph`.

Split off from https://github.com/llvm/llvm-project/pull/135148
2026-02-05 04:17:26 +00:00
weiguozhi
9a47c3bcba
[RegAlloc] Change the computation of CSRCost (#177226)
This patch fixes https://github.com/llvm/llvm-project/issues/150737.

The original computed CSRCost is too small, so the optimization of
spilling instead of using CSR is rarely triggered.
    
Also the original cost model is too difficult to be understood and too
hard to be tuned by backend developers and users.
    
So this patch changes the CSRCost to be

        CSRCost = TRI->getCSRFirstUseCost() * EntryFreq * Scale
    
TRI->getCSRFirstUseCost() is the raw cost of save/restore a CSR. Usually
we don't need to tune this number.
   EntryFreq is the BlockFrequency of the entry block.
Scale is used to scale down the CSRCost, because we usually prefer a CSR
register instead of spilling if we have similar CSRCost and spill cost,
so it should be less than 100%. We usually tune this number.
    
Another problem is the original function RAGreedy::calcSpillCost()
actually computes a cost for block split, so this patch also implements
a correct RAGreedy::calcSpillCost() function.

This new behavior is not enabled by default. This optimization is used
by 3 targets (AArch64 / AMDGPU / RISCV), I will change them one by one
in following patches.
2026-02-04 10:08:57 -08:00
Jay Foad
7ea33e6848
[CodeGen] Remove unused first operand of SUBREG_TO_REG (#179690)
The first input operand of SUBREG_TO_REG was an immediate that most
targets set to 0. In practice it had no effect on codegen. Remove it.
2026-02-04 17:35:21 +00:00
Matthew Devereau
974b768999
[AArch64] Add clmul AArch64 lowering tests (#179495) 2026-02-04 09:46:31 +00:00
Abhay Kanhere
e39d2822bc
[CodeGen][AArch64] ptrauth intrinsic to safely construct relative ptr (#142047)
ptrauth intrinsic to safely construct relative ptr for swift coroutines.

A ptrauth intrinsic for swift co-routine support that allows creation of
signed pointer
 from offset stored at address relative to the pointer.

Following C-like pseudo code (ignoring keys,discriminators) explains its
operation:
      let rawptr = PACauth(inputptr);
return PACsign( rawptr + signextend64( *(int32*)(rawptr+addend) ))

What: Authenticate a signed pointer, load a 32bit value at offset
'addend' from pointer,
       add this value to pointer, sign this new pointer.
 builtin: __builtin_ptrauth_auth_load_relative_and_sign
 intrinsic: ptrauth_auth_resign_load_relative
2026-02-03 18:03:37 +01:00
Anatoly Trosinenko
a47f3802bf
[AArch64][PAC] Mark $Scratch operand of AUTxMxN as earlyclobber (#173999)
This fixes an assertions when emitting code at `-O0`.
2026-02-03 14:18:55 +00:00
Benjamin Maxwell
79eb804954
[AArch64][SME] Limit where SME ABI optimizations apply (#179273)
These were added recently with a fairly complex propagation step,
however, these optimizations can cause regressions in some cases.
    
This patch limits the cross-block optimizations to the simple case
picking a state that matches all incoming blocks. If any block doesn't
match, we fallback to using "ACTIVE", the default state.
2026-02-03 11:19:08 +00:00
Graham Hunter
51217804f2
[AArch64] Fix cttz.elts codegen for fixed-length vectors (#178902)
When lowering cttz.elts for fixed-length vectors when SVE is available,
we use scalable container types for the predicate types since NEON
doesn't have dedicated predicate registers. Unfortunately, this also
discards the actual length of the vector to look at if it's shorter than a
full vector.
Example codegen, for a llvm.experimental.cttz.elts.i64.v4i1

  shl v0.4h, v0.4h, 15
  ptrue p0.h, vl4
  ptrue p1.h
  cmpne p0.h, p0/z, z0.h, #0
  brkb p0.b, p1/z, p0.b
  cntp x8, p0, p0.h

The 'ptrue p1.h' is where we went wrong -- if p0 is empty, we should
only set 4 lanes active at most, but since brkb's pg operand is all
active, it sets all available lanes (e.g. 8 .h lanes on a 128b SVE
implementation).

We need to use the 'vl4' mask for brkb's pg operand instead. So I've
added an extra parameter to AArch64ISD::CTTZ_ELTS to carry the
appropriate pattern from where it's lowered to ISel.

Fixes #178644
2026-02-03 10:22:54 +00:00
Philip Ginsbach-Chen
5d5b4aaa0e
[SelectionDAG][NFC] Rename isConstantSequence to isArithmeticSequence (#179108)
The previous name was misleading: the method checks for an arithmetic
progression `(start, start+stride, start+2*stride, ...)`, not just any
constant sequence. The new name uses precise mathematical terminology.

https://github.com/llvm/llvm-project/pull/176671#discussion_r2735571479
2026-02-02 17:19:57 +00:00
DaKnig
fbda30607c
[SDAG] (abs (add nsw a, -b)) -> (abds a, b) (#175801)
This is beneficial for bv of constants.

alive2: https://alive2.llvm.org/ce/z/e3GsWZ
2026-02-02 15:11:16 +00:00
Cullen Rhodes
f288f463ad
[AArch64][GlobalISel] Constrain G_CONSTANT_FOLD_BARRIER operand register classes (#177997)
[AArch64][GlobalISel] Constrain G_CONSTANT_FOLD_BARRIER operand

Instruction selection is lowering:

  bb.1:
    %6:gpr(s64) = G_CONSTANT i64 457873110
    ...
  bb.2:
    %12:gpr(s64) = G_CONSTANT_FOLD_BARRIER %6
    %24:gpr(s64) = G_CONSTANT i64 0
    %13:gpr(s64) = G_AND %24, %12
    ...

to:

  %13:gpr64 = ANDXrr %24:gpr64, %6:gpr64sp'

which is causing the verifier to fail with:

  Expected a GPR64 register, but got a GPR64sp register

the reason for this is there are multiple G_CONSTANT_FOLD_BARRIER ops
with the same input register:

  Select:  %14:gpr64sp(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr
  Erasing:   %14:gpr64sp(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64sp
  --
  Select:  %12:gpr64(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64sp
  Erasing:   %12:gpr64(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64
  --
  Select:  %7:gpr64sp(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64
  Erasing:   %7:gpr64sp(s64) = G

and the middle one used by the AND gets overridden by last and becomes
invalid.

this patch fixes this by constraining the register class such that the
middle one gets constrained to the subset of gpr64sp and gpr64, i.e.
gpr64common:

  Select:  %14:gpr64sp(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr
  Erasing:   %14:gpr64sp(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64sp
  --
  Select:  %12:gpr64(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64sp
  Erasing:   %12:gpr64(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64common
  --
  Select:  %7:gpr64sp(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64common
  Erasing:   %7:gpr64sp(s64) = G_CONSTANT_FOLD_BARRIER %6:gpr64common

canReplaceReg doesnt handle when both regs already have classes so the
assert is removed.

Fixes #166563.
2026-02-02 10:04:12 +00:00
Hari Limaye
23f9e42480
[AArch64] Support SHUFFLE of ANY_EXTEND in performBuildShuffleExtendCombine (#178408)
Currently performBuildShuffleExtendCombine only supports ANY_EXTEND
operands for BUILD_VECTOR inputs, and will bail if it encounters a
VECTOR_SHUFFLE with ANY_EXTEND operands. Update the logic so that we
support shuffles with ANY_EXTEND operands, which brings the code in line
with the comment.
2026-02-02 09:32:17 +00:00
David Green
0321f3eeee
[AArch64][GlobalISel] Do no skip zext in getTestBitReg. (#177991)
We can, when attempting to lower to tbz, skip a zext that is then not
accounted for elsewhere. The attached test ends up with a tbz from an
extract that then does not properly zext the value extracted from the
vector. This patch fixes that by only looking through a G_ZEXT if the
bit checked is in the low part of the value, lining up the code with the
comment.

Fixes #173895
2026-02-02 09:13:09 +00:00
Nikita Popov
a667526e7f
[MachineFunctionPass] Preserve more IR analyses (#178871)
Preserve, PDT, BPI, LazyBPI and LazyBFI. These are all IR analysis that
are not invalidated by machine passes.

This partially mitigates the compile-time regression from
https://github.com/llvm/llvm-project/pull/174746.
2026-02-02 09:25:30 +01:00
Benjamin Maxwell
1818b23a99
[SDAG] Check for nsz in DAG.canIgnoreSignBitOfZero() (#178905)
Follow up to #174423
2026-02-01 15:58:38 +00:00
Hamza Hassanain
7639d21e9d
[AArch64] Convert CLS intrinsics to use ISD::CTLS (#178885)
This patch converts AArch64 CLS intrinsics (aarch64_neon_cls) to use the
generic ISD::CTLS node.

- aarch64_neon_cls: Lowered to ISD::CTLS, pattern-matched to CLS
instruction
- Set ISD::CTLS as Legal for NEON vector types (v8i8, v16i8, v4i16,
v8i16, v2i32, v4i32)

Also adds generic CTLS expansion support:
- ExpandIntRes_CTLS in LegalizeIntegerTypes for i64->i32 type expansion
- expandCTLS in TargetLowering for targets without native CLS
instruction

Part of: https://github.com/llvm/llvm-project/issues/174337
2026-01-30 13:08:58 -08:00
Philip Ginsbach-Chen
e345976e04
[SelectionDAG] Handle undef at any position in isConstantSequence (#176671)
This patch extends `BuildVectorSDNode::isConstantSequence` to recognize
constant sequences that contain undef elements at any position.

The new implementation finds the first two non-undef constant elements,
computes the stride from their difference, then verifies all other
defined elements match the sequence. This enables SVE's INDEX
instruction to be used in more cases.

This change particularly benefits ZIP1/ZIP2 patterns where one operand
is a constant sequence. When a smaller constant vector like `<0, 1, 2,
3>` is used in a ZIP1 shuffle producing a wider result, it gets expanded
with trailing undefs. Similarly, for ZIP2 patterns, the DAG combiner
transforms the constant to have leading undefs since ZIP2 only uses the
upper half of its operands.

In particular, these patterns arise naturally from `VectorCombine`'s
`compactShuffleOperands` optimization (see #176074) that I am suggesting
as a fix for #137447.
2026-01-30 19:57:11 +00:00
陈子昂
a994198906
[DAG] Reland: Enable bitcast STLF for Constant/Undef (#178890)
This is a reland of #172523.

The original patch caused an assertion failure on RISC-V because it
attempted to create a bitcast from an illegal type (i32 on RV64) during
the post-type-legalization DAGCombine stage.

Added a `TLI.isTypeLegal(Val.getValueType())` check to ensure we only
proceed with the bitcast STLF optimization when the source value's type
is legal for the target.
2026-01-30 18:21:32 +01:00
Alex Bradbury
41f453efe2
Revert "[DAG] Enable bitcast STLF for Constant/Undef" (#178872)
Reverts llvm/llvm-project#172523

As explained in
https://github.com/llvm/llvm-project/pull/172523#issuecomment-3823234270
(along with reproducer), this causes compiler crashes building
llvm-test-suite for RVV targets.
2026-01-30 12:18:38 +00:00
陈子昂
d3c64633c3
[DAG] Enable bitcast STLF for Constant/Undef (#172523)
This patch introduces support for Store-to-Load Forwarding (STLF) in
`DAGCombiner::ForwardStoreValueToDirectLoad` when the store and load
have **different types but equal memory size** (e.g., storing an `i32`
then loading a `float` from the same location).

### What this patch does:
**Enables Optimization:** It allows for the safe forwarding of the
stored value as a Bitcast when the value is:
* A **Constant** (`ConstantSDNode`, `ConstantFPSDNode`,
`ConstantPoolSDNode`).
    * **Undef**.
    * And the memory sizes (`LdMemSize` == `StMemSize`) match.

### Scope and Next Steps:

This patch **only implements forwarding for constant and undef values
that has the same memory size** so far.

**I am submitting this initial patch to get early review feedback on the
core logic and fix the immediate crashes before tackling the more
complex scenarios.**

For the simple case:
```llvm
; Case Handled by this PR so far (e.g., zeroinitializer is a constant)
define float @test_stlf_integer(ptr %p, float %v) {
  store i32 0, ptr %p, align 4 
  %f = load float, ptr %p, align 4 
  ; ...
}
```
Fixes: #151683
2026-01-30 10:11:59 +01:00
Sander de Smalen
ffb7a9f0ec
[AArch64] Fix sign-extend-inreg combine for i1 types (#177976)
This fixes https://github.com/llvm/llvm-project/issues/177925
2026-01-30 08:26:35 +00:00
David Green
2bd441cff2
[AArch64] Add FCVT fixed patterns for fptoi(fadd(a, a)) (#178536)
This can be seen as a special-case of the existing fptoi(fmul(a, 2.0))
combine that will be moved to tablegen, which can generate a FCVT_shift
instruction.
2026-01-30 08:21:56 +00:00
Osama Abdelkader
aad7259ff6
[AArch64] Optimize memset to use NEON DUP instruction for more sizes (#166030)
This change improves memset code generation for non-zero values on
AArch64 by using NEON's DUP instruction instead of
the less efficient multiplication with 0x01010101 pattern.

For small sizes, the value is extracted from a larger DUP. For
non-power-of-two sizes, overlapping stores are used in some cases.

TargetLowering::findOptimalMemOpLowering is modified to allow explicitly
specifying the size of the constant in cases where the constant is
larger than the store operations.

Fixes #165949
2026-01-29 13:03:38 -08:00
Osman Yasar
a5e388def7
[GlobalISel] Fold Add Shift combine from SelectionDAG (#177371)
This PR adds the combine rule `fold (add x, shl(0 - y, n)) -> sub(x,
shl(y, n))` to GlobalISel, corresponding to an existing SelectionDAG
combine in
[DAGCombiner::visitADDLikeCommutative](fcba304010/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (L3367)).

Co-authored-by: Sarah Kuhn <sarahlinhkuhn@gmail.com>

---------

Co-authored-by: Sarah Kuhn <sarahlinhkuhn@gmail.com>
Co-authored-by: Luisa Cicolini <48860705+luisacicolini@users.noreply.github.com>
2026-01-29 21:41:54 +01:00
Osman Yasar
2a76621276
[GlobalISel] Add integer_reassoc_combines from SelectionDAG (#177931)
This PR converts two DAGCombiner fold patterns to GlobalISel MIR
patterns:
- `((A + (B - C)) - B) -> A - C`
- `((A - (B - C)) - C) -> A - B`

Original patterns:
5b4811eddb/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (L4359)

The patterns do not include hasOneUse checks since the instruction count
remains the same even when both intermediate results have other uses (3
ops → 3 ops).
2026-01-29 17:28:53 +00:00
Ryan Cowan
ad1a45b903
[AArch64] Use GISel for optnone functions (#174746)
Currently, when SDAG is run on AArch64 and an `optnone` function is
encountered, the selector is chosen as FastISel. AArch64 makes use of
GlobalISel at O0 and this patch aims to align `optnone` with this
functionality.

A flag is exposed to enable this functionality for a given backend but,
as AArch64 is currently the only backend I could find using GlobalISel
at O0 this is the only one with it implemented. This flag is set when
the target supports GlobalISel & GlobalISel hasn't been forced by the
user, the target machine or by being at an optimisation level lower than
`EnableGlobalISelAtO`.

If this happens, the GlobalISel passes are included as shown in
`llvm/test/CodeGen/AArch64/O3-pipeline.ll` and skipped by IRTranslator
for functions not marked as `optnone`.

In updating the tests based on this functionality, I found some unused
check lines or run lines that mixed SDAG with GlobalISel pass names
which have been fixed.

---------

Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2026-01-29 16:30:22 +00:00
Kerry McLaughlin
162267ee90
[AArch64][SME2] Allow lowering to whilelo.x2 in non-streaming mode (#178399)
Since #145322 relaxed the SME predicate for the multi-register while
instructions, these instructions are allowed in non-streaming mode
when SME2 is available.

This patch removes the isStreaming() restriction from both
performActiveLaneMaskCombine & ReplaceGetActiveLaneMaskResults,
allowing the whilelo.x2 intrinsic to be used if SVE or streaming
SVE is available.
2026-01-29 13:58:24 +00:00
David Sherwood
73c7c562dd
[LLVM][DAGCombiner] Look through freeze when combining extensions of loads (#175022)
Following on from https://github.com/llvm/llvm-project/pull/172484 I
have added support to tryToFoldExtOfLoad for looking through freezes, in
order to catch more cases of extending loads. This type of code is
sometimes seen being generated by the loop vectoriser. For now I've
limited this to cases where the load is only used by the freeze, since
otherwise it leads to worse code in some X86 tests.
2026-01-29 12:01:43 +00:00
Usama Hameed
28e980fbdd
[MTE][Darwin] This patch extends support for the stack frame history buffer to Darwin. (#178049)
Darwin reserves slot 231 for storing a pointer to the history ring
buffer. It also uses bits 60-62 to store the size of the ring buffer

rdar://168176496
2026-01-28 12:23:32 -08:00
Jonathan Cohen
7cf11edd53
[EarlyIfConversion] Add analysis for data-dependent conditional branches(#174457)
Add infrastructure to identify conditional branches on values loaded from 
memory.  Such branches are likely to be harder to predict accurately since 
branch  history (probably) provides little useful information.

This analysis walks the def-use chain from the branch condition to find
loads that feed into it. Several cases are excluded from consideration:
- Loads from constant pools (predictable values)
- Dereferenceable invariant loads (loop-invariant)
- Branches with biased probability (null checks, etc.)
- Loads not "close in program time" to the branch (must be in the same
  basic block with no intervening calls)

The analysis is disabled by default behind -enable-early-ifcvt-data-dependent.
2026-01-28 21:43:44 +02:00