39354 Commits

Author SHA1 Message Date
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
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
vangthao95
53956753fc
AMDGPU/GlobalISel: Lower G_EXTRACT/INSERT in legalizer (#181036)
Lower G_EXTRACT/INSERT in legalizer by using custom lowering for simple
32-bit aligned cases and calling generic extract/insert lowering for all
other cases.
2026-03-12 10:03:44 -07:00
Shivam Kunwar
839fd9177e
[DebugInfo][AT] Treat escaping calls as untagged stores in assignment tracking (#183979)
When a pointer to a tracked alloca is passed to a call that may write
through it (e.g. foo(&x)), the callee can modify the variable's stack
home. The assignment tracking analysis didn't account for this, which
could cause the debugger to show stale values after such calls.

Consider:

```
  int x = 1;
  foo(&x);    // might set x to 99
  x = 2;      // store deleted by DSE
```

Without this patch, the analysis still thinks the stack home holds
assignment `!id1` after the call. When it later sees the `dbg_assign`
for the deleted store, the mismatch causes it to fall back to the old
debug value (1) , which is wrong.

Fix this by detecting calls where a tracked `alloca` escapes as an
argument and treating them the same way we already treat untagged
stores, set both `StackHome` and `Debug` to NoneOrPhi (unknown
assignment) and keep `LocKind` as Mem (the stack slot is still the right
place to look). This causes a `DBG_VALUE` with `DW_OP_deref` to be
emitted after
the call, telling the debugger to read whatever is actually in memory.

Pointer arguments with readonly, readnone, or byval attributes are
skipped since the callee either cannot modify the original memory or
receives a copy. Intrinsics are also skipped since their memory effects
are already modeled individually (e.g. memset/memcpy as stores, lifetime
markers as no-ops).

---------

Co-authored-by: Shivam Kunwar <phyBrackets@users.noreply.github.com>
2026-03-12 20:47:53 +05:30
Brox Chen
641ab6ef83
[CodeGen] check artificial subregister before propagate copy (#185751)
In machine copy propagation pass, do not propagate the subregister copy
if the subreg is artificial
2026-03-12 11:16:36 -04:00
Gergo Stomfai
0fb8f7f9c3
[DAG] Fold away identity FSHL and FSHR patterns (#185667)
Fold away identity FSHL and FSHR patterns

Came up in #185175, this seems to be the cleanest way to get rid of this
pattern

Alive2 proofs:
`fshl(lshr(x, amnt), shl(c, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/AEzthY
`fshl(lshr(x, amnt), fshl(x, _, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/oDpaqF
`fshl(lshr(x, amnt), fshr(x, _, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/aCxQch
`fshl(fshr(_, x, amnt), shl(c, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/89NQME
`fshl(fshr(_, x, amnt), fshl(x, _, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/KdR3Mp
`fshl(fshr(_, x, amnt), fshr(x, _, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/2Gkc7m
`fshl(fshl(_, x, BW - amnt), shl(c, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/LNjr_R
`fshl(fshl(_, x, BW - amnt), fshl(x, _, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/cwGjhL
`fshl(fshl(_, x, BW - amnt), fshr(x, _, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/UChZW4
`fshr(lshr(x, BW - amnt), shl(c, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/uiSBEQ
`fshr(lshr(x, BW - amnt), fshl(x, _, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/11pXpJ
`fshr(lshr(x, BW - amnt), fshr(x, _, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/7mvxH7
`fshr(fshr(_, x, BW - amnt), shl(c, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/ybswip
`fshr(fshr(_, x, BW - amnt), fshl(x, _, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/fNUQQv
`fshr(fshr(_, x, BW - amnt), fshr(x, _, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/9bFnec
`fshr(fshl(_, x, amnt), shl(c, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/vuYAYn
`fshr(fshl(_, x, amnt), fshl(x, _, amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/kP94MG
`fshr(fshl(_, x, amnt), fshr(x, _, BW - amnt), amnt) -> x`:
✓ https://alive2.llvm.org/ce/z/X8u__v
2026-03-12 11:21:29 +00:00
Simon Pilgrim
9a8147b553
Revert "[SDAG] (abs (add nsw a, -b)) -> (abds a, b)" (#17580) (#186068)
Reverts llvm/llvm-project#175801 while #185467 miscompilation is being investigated
2026-03-12 10:35:24 +00:00
Igor Gorban
3a8a43f224
[AArch64][GlobalISel] Fix matchUseVectorTruncate to check element order before folding (#185834)
matchUseVectorTruncate incorrectly folded a
G_UNMERGE_VALUES + G_TRUNC + G_BUILD_VECTOR sequence into a single
vector G_TRUNC even when the BUILD_VECTOR operand order did not match
the UNMERGE_VALUES result order. This silently dropped element
reordering, producing a miscompile.

Add an element-ordering check: BUILD_VECTOR position I must use
UNMERGE_VALUES result I, otherwise the fold is rejected.
2026-03-11 15:33:09 +00:00