2246 Commits

Author SHA1 Message Date
Demetrius Kanios
5395d26689
Revert "[WebAssembly] Incorporate SCCs into WebAssemblyFixIrreducibleControlFlow (#181755)" (#183872)
This reverts commit c05e323be7caaadff6fdd09a2336be60e3041af1.

Changes failed Emscripten tests.
2026-02-28 01:46:08 +00:00
Aiden Grossman
c2f66f2a94 [WebAseembly] Fix -Wunused-variable in #181755
This variable ends up being unused in builds without assertions. Mark it
[[maybe_unused]] per the coding standards.
2026-02-27 21:13:04 +00:00
Demetrius Kanios
c05e323be7
[WebAssembly] Incorporate SCCs into WebAssemblyFixIrreducibleControlFlow (#181755)
Rather than mapping out full "reachability" between blocks in a region
to find loops and using `LoopBlocks` to find the bodies of said loops,
use SCCs (strongly-connected components) to provide this information.

This brings in LLVM's generic `SCCIterator` (which uses Tarjan's
algorithm) as the implementation for sorting the basic blocks of the CFG
into their SCCs.

This PR greatly reduces the compile-time footprint of the pass, making
memory use and time taken negliable where it might have previously
caused stalls and OOM before (e.g. #47793,
usagi-coffee/tree-sitter-abl#114)

------

Supersedes #179722

Fixes #47793
Fixes #165041 (probably)

Thanks to @jkbz64 for the initial investigations (w/ AI; see #179722)
into why this pass was slow and memory consuming and showing that SCCs
were the key.

Also thanks to the Cheerp compiler project for bringing `SCCIterator` to
light in this context ([blog
post](https://cheerp.io/blog/control-flow#fix-the-irreducible-control-flow),
[implementation](https://github.com/leaningtech/cheerp-compiler/blob/master/llvm/lib/CheerpUtils/FixIrreducibleControlFlow.cpp)).
2026-02-27 10:52:01 -08:00
hanbeom
4147cd29e1
[WebAssembly][FastISel] Emit signed loads for sext of i8/i16/i32 (#182767)
FastISel currently defaults to unsigned loads for i8/i16/i32 types,
leaving any sign-extension to be handled by a separate instruction. This
patch optimizes this by folding the SExtInst into the LoadInst, directly
emitting a signed load (e.g., i32.load8_s).

When a load has a single SExtInst use, selectLoad emits a signed load
and safely removes the redundantly emitted SExtInst.

Fixed: #180783
2026-02-27 18:31:33 +09:00
Folkert de Vries
90144c2df0
[WebAssembly] optimize ext + shuffle + add into addext (#182849)
cc https://github.com/llvm/llvm-project/issues/179143

This adds a second pattern: we already recognize "shuffle + extend +
add" as `addext`, this adds another pattern for "extend + shuffle +
add", which can come up when programs are optimized.
2026-02-25 14:04:42 +01:00
Demetrius Kanios
d269c36baf
[WebAssembly] Optimize WebAssemblyCFGSort's post sort verifications. (#182458)
Currently, the post-sort verifications `WebAssemblyCFGSort` does in
assertion builds is quite expensive. Given the example of
[usagi-coffee/tree-sitter-abl](https://github.com/usagi-coffee/tree-sitter-abl),
we have one MASSIVE function with nearly 120K blocks. Sorting this is
fast, but the verifications after take some 40+ seconds (on my machine).

The culprit was the manipulation of the region `OnStack`. I've tried to
replace that with interval based verifications to make sure the regions
are well formed, well nested, and that the numbers of the blocks within
a region are within the interval of the numbers of the header and bottom
of the region.

This brings the aforementioned example down to well under a second spent
in the pass in an assertions build.
2026-02-24 11:06:11 -08:00
Heejin Ahn
1bc2446c78
[WebAssembly] Use generic CPU by default in llvm-mc (#181460)
Other tools, such as `llc`, use `generic` cpu by default, if you don't
give any `-mcpu`:

75f738b0b2/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp (L38-L39)

But `llvm-mc` didn't do that. This makes `generic` also the default CPU
for `llvm-mc`.
2026-02-24 00:39:14 -08:00
Hood Chatham
7d9d392a1f
[WebAssembly] Fix SELECT_CC lowering for reference types (#181622)
SELECT_CC nodes with externref or funcref return types were not being
expanded, causing "Cannot select" errors during instruction selection.

This adds SELECT_CC to the list of operations that should be expanded
for reference types, similar to how it's already handled for scalar
types (i32, i64, f32, f64). This allows the SELECT_CC to be lowered to a
SELECT node, which already has instruction patterns defined in
WebAssemblyInstrRef.td.
2026-02-19 09:14:29 -08:00
Jay Foad
27144f4c2e
[TableGen] Return int32_t from InstrMapping table lookup functions. NFC. (#182079)
Since #182059 there is only one case in which these functions return -1,
so callers no longer need to distinguish between (int64_t)-1 and
(uint32_t)-1, so we can go back to a 32-bit return value like it was
before #180954.
2026-02-18 18:49:58 +00:00
Benjamin Maxwell
88c0a1db85
Revert "[WebAssembly] Mark extract.last.active as having invalid cost." (#181545)
The failures should have been resolved with
https://github.com/llvm/llvm-project/pull/180290 (which also added
WebAssembly tests).

This reverts commit
811fb223af.

---

This is the same as #180942, but with a `lit.local.cfg` added to the
CostModel test folder.
2026-02-16 08:55:25 +00:00
Benjamin Maxwell
0ad941a98b
Revert "Revert "[WebAssembly] Mark extract.last.active as having invalid cost."" (#181342)
Reverts llvm/llvm-project#180942

Looks like something changed the cost model. Will investigate later.
2026-02-13 09:50:30 +00:00
Benjamin Maxwell
0f8325c9a9
Revert "[WebAssembly] Mark extract.last.active as having invalid cost." (#180942)
The failures should have been resolved with #180290 (which also added
WebAssembly tests).

This reverts commit 811fb223af2b3e2d68c99b346f4b75dcf3de3417.
2026-02-13 09:21:46 +00:00
Heejin Ahn
c1e90fa663
[WebAssembly] Error on Wasm SjLj if +exception-handling is missing (#181070)
This checks every user function of `setjmp` or `longjmp` and if any of
them does not have `+exception-handling` target feature, errors out.

Hopefully this gives a clearer error message to the users in case they
do not provide consistent SjLj flags at compile time vs. link time.

Closes #178135 and closes
https://github.com/emscripten-core/emscripten/issues/26165.
2026-02-12 13:33:18 -08:00
sstipano
5ec5701db3
Reapply "[MC][TableGen] Expand Opcode field of MCInstrDesc" (#180321) (#180954)
Difference from the previous version is that this one doesn't actually
encode opcodes in matcher tables as 32 bits, but still as 16 bits.
2026-02-12 09:17:02 +01:00
Sam Clegg
11c2613342
[WebAssembly] Add initial support for compact imports proposal (#176617)
This change adds initial support to libObject for reading compact
imports and support for writing compact imports in the linker.

There is minimal testing here since to tools like lllvm-readobj, and
obj2yaml don't currently report compact imports any differently.

See https://github.com/WebAssembly/compact-import-section
2026-02-10 10:57:45 -08:00
Vladimir Vereschaka
19d681177f
Revert "[MC][TableGen] Expand Opcode field of MCInstrDesc" (#180321)
Reverts llvm/llvm-project#179652

This PR causes the out-of-memory build failures on many Windows
builders.
2026-02-06 21:58:50 -08:00
Demetrius Kanios
4919e0da50
[WebAssembly][FastISel] Make use of sign-ext proposals instructions when available (#179855)
Enables FastISel to use the dedicated sign-extension instructions
(rather than shl, shr) when available.
2026-02-06 12:41:39 -08:00
sstipano
13d8870d45
[MC][TableGen] Expand Opcode field of MCInstrDesc (#179652)
Increase width of Opcode to `int` from `short` to allow more capacity.
2026-02-06 20:21:48 +01:00
Demetrius Kanios
9976e5702f
[WebAssembly][GlobalISel] Part 1 - Setup skeleton (#178796)
This PR is the first step towards bringing GlobalISel to the Wasm
backend.

Split from #157161
2026-02-06 18:38:56 +00:00
Derek Schuff
c3db52701e
[MC][Wasm] Emit useful error message when encountering common symbols (#179586)
We don't currently support common symbols for Wasm, and we currently
emit a generic error with a backtrace. Instead, don't crash, and report
the names of the offending symbols.
2026-02-06 00:40:25 +00:00
hanbeom
22f53531d7
[WebAssembly] Combine shuffle and signed extend to extend_high (#179166)
Fold shuffles and bitcasts feeding extend_low_s into extend_high_s.
This enables i32x4.dot_i16x8_s selection and removes redundant shuffles.

Fixed: https://github.com/llvm/llvm-project/issues/179145
2026-02-03 17:02:53 +09:00
Nicolai Hähnle
6f0b873f1c
[CodeGen] Refactor targets to override the new getTgtMemIntrinsic overload (NFC) (#175844)
This is a fairly mechanical change. Instead of returning true/false,
we either keep the Infos vector empty or push one entry.
2026-02-02 17:40:02 -08:00
Anshul Nigham
85545d4c84
[NewPM] Port MachineDominanceFrontierAnalysis (#177709) 2026-02-01 22:02:45 -08:00
Demetrius Kanios
95ac9314df
[WebAssembly] Prevent FastISel from trying to select funcref calls (#178742)
Before, Wasm FastISel treated all indirect calls the same, causing
miscompilations at O0 when trying to call a funcref (`call ptr
addrspace(20)`), as it would treat the funcref as a normal `ptr`

This adds a check so it falls back to ISelDAG when encountering calls
outside addrspace 0 (which covers direct calls and indirect calls
through normal function pointers).

Related: #140933
2026-01-30 12:05:15 -08:00
Damian Heaton
762ba885f9
[LV] Add support for llvm.vector.partial.reduce.fadd (#163975)
Allows the Loop Vectorizer to generate `llvm.vector.partial.reduce.fadd`
intrinsics when sequences which match its requirements are found.
2026-01-28 15:05:34 +00:00
hanbeom
16d8d4b84e
[WebAssembly] Fix crash in ReplaceNodeResults for ANY_EXTEND_VECTOR_INREG (#178374)
Fixes a crash during type legalization by allowing
ISD::ANY_EXTEND_VECTOR_INREG to fall back to default expansion instead
of hitting llvm_unreachable.

Fixed: #177209
2026-01-28 20:45:04 +09:00
Sam Parker
1e0114c21d
[WebAssembly] Zero and NaN checks for min/max (#177968)
Custom lower FMINNUM, FMINIMUMNUM, FMAXNUM and FMAXIMUMNUM to generate
relaxed_min and relaxed_max when the inputs cannot be NaN or signed
zero.

Tablegen patterns have also been modified to check the above conditions
when trying to match relaxed min/max using the pmin/pmax pattern.
2026-01-28 09:25:41 +00:00
Florian Hahn
b794baf8e7
[TTI] Add VectorInstrContext for context-aware insert/extract costs. (#175982)
This commit introduces the VectorInstrContext (VIC) infrastructure to
improve cost estimates for insert/extracts based on the context
instruction in which the insert/extract is used.

This is similar to CastContextHint, and allows providing context on how
the insert/extract is going to be used before creating IR. This is
useful in the LoopVectorizer, where costs need to estimated before
creating IR.

The new hint currently only replaces an existing check in AArch64,
but new uses will be introduced in follow-ups, including
https://github.com/llvm/llvm-project/pull/177201.

PR: https://github.com/llvm/llvm-project/pull/175982
2026-01-27 16:30:29 +00:00
Anutosh Bhat
2503ffbdf3
[WebAssembly] Fix exception handling initialization order in TargetMachine constructor (#177542)
The WebAssemblyTargetMachine constructor had an ordering issue where
initAsmInfo() was called before basicCheckForEHAndSjLj(). This caused
problems in incremental compilation scenarios where:

1. `initAsmInfo()` sets `MCAsmInfo` exception type based on
`Options.ExceptionModel`
2. But `Options.ExceptionModel` might still be None at this point
3. `basicCheckForEHAndSjLj()` runs later and updates
`Options.ExceptionModel`
   based on command-line flags like `-wasm-enable-eh`
4. `MCAsmInfo` retains the incorrect exception type (`None` instead of
`Wasm`)
5. This prevents WebAssembly exception handling passes from running

The fix swaps the order so basicCheckForEHAndSjLj() runs first to
establish the correct exception model before initAsmInfo() configures
MCAsmInfo based on that model.

This enables WebAssembly exception handling to work correctly in
clang-repl and other incremental compilation scenarios.
2026-01-24 06:26:02 +00:00
Jameson Nash
d10b2b566a
[NFCI] replace getValueType with new getGlobalSize query (#177186)
Returns uint64_t to simplify callers. The goal is eventually replace
getValueType with this query, which should return the known minimum
reference-able size, as provided (instead of a Type) during create.
Additionally the common isSized query would be replaced with an
isExactKnownSize query to test if that size is an exact definition.
2026-01-22 13:55:53 -05:00
Jameson Nash
2458387ac1
[NFC] replace getValueType with more specific getFunctionType (#177175)
When trivially valid already, use the more specific method, instead of
casting the result of the less specific method.
2026-01-21 10:30:09 -05:00
Matt Arsenault
69df4acf33
WebAssembly: Use LibcallLoweringInfo (#176804)
Query libcalls through analysis instead of the TargetLowering
copy. This could be nicer by parsing the libcall name and checking
against the LibcallImpl, but that's probably slower for such a specific
case (alternatively, ExternalSymbol should support encoding as a
LibcallImpl).
2026-01-20 09:20:49 +01:00
Matt Arsenault
2c9cc88e25
FastISel: Thread LibcallLoweringInfo through (#176799)
Boilerplate change to prepare to take LibcallLoweringInfo from
an analysis. For now, it just sets it from the copy inside of
TargetLowering.
2026-01-19 20:44:48 +00:00
Florian Hahn
811fb223af
[WebAssembly] Mark extract.last.active as having invalid cost.
Currently the WebAssembly backend crashes when trying to lower some
extract.last.active intrinsic calls. Mark their cost as invalid
temporarily, to avoid them being introduced by the loop
vectorizer after 2abd6d6d7ac (#158088).
2026-01-17 21:21:34 +00:00
Sam Elliott
2042887709
Reland "[NFC][MI] Tidy Up RegState enum use (1/2)" (#176277)
This Change is to prepare to make RegState into an enum class. It:
- Updates documentation to match the order in the code.
- Brings the `get<>RegState` functions together and makes them
`constexpr`.
- Adopts the `get<>RegState` where RegStates were being chosen with
ternary operators in backend code.
- Introduces `hasRegState` to make querying RegState easier once it is
an enum class.
- Adopts `hasRegState` where equivalent was done with bitwise
arithmetic.
- Introduces `RegState::NoFlags`, which will be used for the lack of
flags.
- Documents that `0x1` is a reserved flag value used to detect if
someone is passing `true` instead of flags (due to implicit bool to
unsigned conversions).
- Updates two calls to `MachineInstrBuilder::addReg` which were passing
`false` to the flags operand, to no longer pass a value.
- Documents that `getRegState` seems to have forgotten a call to
`getEarlyClobberRegState`.

This PR relands llvm/llvm-project#176091 (commit
1d616cdca3aba9d22f120888bb6b09b75ca90b92) which was reverted in
llvm/llvm-project#176190 (commit
6309cd8668fc2ae589f156b23f86821f4ce5b7ea).
2026-01-16 13:05:06 -08:00
Akshay Deodhar
3860147a7f
[NFC][TargetLowering] Make shouldExpandAtomicRMWInIR and shouldExpandAtomicCmpXchgInIR take a const Instruction pointer (#176073)
Splits out change from https://github.com/llvm/llvm-project/pull/176015

Changes shouldExpandAtomicRMWInIR to take a constant argument: This is
to allow some other TargetLowering constant-argument functions to call
it. This change touches several backends. An alternative solution
exists, but to me, this seems the "right" way.
2026-01-15 14:22:57 -08:00
Sam Elliott
6309cd8668
Revert "[NFC][MI] Tidy Up RegState enum use (1/2)" (#176190)
Reverts llvm/llvm-project#176091

Reverting because some compilers were erroring on the call to
`Reg.isReg()` (which is not `constexpr`) in a `constexpr` function.
2026-01-15 07:58:05 -08:00
Sam Elliott
1d616cdca3
[NFC][MI] Tidy Up RegState enum use (1/2) (#176091)
This Change is to prepare to make RegState into an enum class. It:
- Updates documentation to match the order in the code.
- Brings the `get<>RegState` functions together and makes them
`constexpr`.
- Adopts the `get<>RegState` where RegStates were being chosen with
ternary operators in backend code.
- Introduces `hasRegState` to make querying RegState easier once it is
an enum class.
- Adopts `hasRegState` where equivalent was done with bitwise
arithmetic.
- Introduces `RegState::NoFlags`, which will be used for the lack of
flags.
- Documents that `0x1` is a reserved flag value used to detect if
someone is passing `true` instead of flags (due to implicit bool to
unsigned conversions).
- Updates two calls to `MachineInstrBuilder::addReg` which were passing
`false` to the flags operand, to no longer pass a value.
- Documents that `getRegState` seems to have forgotten a call to
`getEarlyClobberRegState`.
2026-01-15 07:47:05 -08:00
Sam Parker
b84ffe040b
[WebAssembly] LoadLane matching with offsets (#176005) 2026-01-15 08:39:42 +00:00
Austin Jiang
e6cdfb75ac
Fix typos and spelling errors across codebase (#156270)
Corrected various spelling mistakes such as 'occurred', 'receiver',
'initialized', 'length', and others in comments, variable names,
function names, and documentation throughout the project. These
changes improve code readability and maintain consistency in naming
and documentation.

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2026-01-13 11:52:46 -05:00
Sam Parker
e5b6833e49
[WebAssembly] vi8 mul cost modelling. (#175177)
We've already optimised these, so update the cost model to reflect it.
And skip the isBeforeLegalize check when lowering i8 muls, because it
then misses the cases where, say v32i8, has been type legalised into 2x
v16i8.

Also explicitly disable memory interleaving for any factor other than
two or four.
2026-01-12 09:25:54 +00:00
Trevor Gross
3920bc61ca
[TargetLowering] Change the softPromoteHalfType default to true (#175149)
The default `f16` lowering has some issues that result in incorrect
float behavior, so over time most targets have switched to use
`softPromoteHalfType`. Swap to soft promotion by default and add
overrides for SystemZ and AMDGPU, which are the two remaining backends
that still depend on this behavior.

All basic `f16` op tests now pass on all remaining experimental arches.

Fixes: https://github.com/llvm/llvm-project/issues/97981
Fixes: https://github.com/llvm/llvm-project/issues/97975
2026-01-11 12:48:26 +01:00
Derek Schuff
7a22bea512
[WebAssembly] Expand vector frem instructions (#174854)
Commit
6ad41bcc49
changed how frem is expanded during legalization and it
broke WebAssembly but we were missing test coverage. We want to maintain
our previous behavior of unrolling vectors and using a libcall to
implement scalar frem. I'm not sure why this now has to be different
(in ISelLowering) from other libcalls like fsin which work the same way
in the end, but this code does accurately describe what we want.

Fixes: https://github.com/emscripten-core/emscripten/issues/25991
2026-01-08 16:19:44 -08:00
Trevor Gross
4903c6260c
[WebAssembly] Change half to use soft promotion rather than PromoteFloat (#152833)
The default `half` legalization, which Wasm currently uses, does not
respect IEEE conventions: for example, casting to bits may invoke a lossy
libcall, meaning soft float operations cannot be correctly implemented.
Change to the soft promotion legalization which passes `f16` as an `i16`
and treats each `half` operation as an individual
f16->f32->libcall->f32->f16 sequence.

Of note in the test updates are that `from_bits` and `to_bits` are now
libcall-free, and that chained operations now round back to `f16` after
each step.

Fixes the wasm portion of
https://github.com/llvm/llvm-project/issues/97981
Fixes the wasm portion of
https://github.com/llvm/llvm-project/issues/97975
Fixes: https://github.com/llvm/llvm-project/issues/96437
Fixes: https://github.com/llvm/llvm-project/issues/96438
2026-01-08 15:07:59 +01:00
valadaptive
8da7c05933
[WebAssembly] Fold constant i8x16.swizzle and i8x16.relaxed.swizzle to shufflevector (#169110)
Resolves #169058.

This adds ~~an InstCombine pass~~ a TTI hook to the WebAssembly backend
that folds `i8x16.swizzle` and `i8x16.relaxed.swizzle` operations to
`shufflevector` operations if their mask operands are constant.

This is mainly useful for abstractions over the raw intrinsics--for
instance, in architecture-generic SIMD code that may not be able to
expose the constant shuffles due to type system limitations.

I took most of this from the x86 backend (in particular,
`simplifyX86vpermilvar` in `X86InstCombineIntrinsic`), and adapted it
for the WebAssembly backend. There wasn't any previous
`instCombineIntrinsic` method on the WebAssembly `TargetTransformInfo`,
so I added it. Right now, this swizzle optimization is the only one it
performs.

As I noted in the transform itself, the "relaxed" swizzle actually has
stricter preconditions than the non-relaxed one. If a non-negative but
still out-of-bounds index is provided, the "relaxed" swizzle can choose
between returning 0 and the lane at the index modulo 16. However, it
must make the same choice every time, and we don't know which choice the
runtime will make, so we can't constant-fold it.

The regression tests were mostly generated by Claude and adapted a bit
by me (I tried to follow the [InstCombine contributor
guide](https://llvm.org/docs/InstCombineContributorGuide.html#tests)).
There was previously no WebAssembly subdirectory within the InstCombine
tests, so I created that too; as of now, the swizzle fold test is the
only file in it. Everything else was written by myself (well, partly
copy-pasted from the x86 backend).

I'm not sure how to write an Alive2 test for this; I can't find any
examples where the input is an arbitrary constant.
2026-01-07 17:39:36 -08:00
hanbeom
1171e30cb0
[WebAssembly] Support v128.load{32,64}_zero for f32 and f64 types (#172291)
This patch extends the `load_zero` pattern matching to
support floating-point vector types (`v4f32` and `v2f64`).

Previously, the optimization to generate `v128.load32_zero` and
`v128.load64_zero` was only enabled for integer types
(`v4i32` and `v2i64`). This change adds the necessary TableGen
patterns to correctly match scalar floating-point loads inserted
into zero-initialized vectors.
2026-01-08 09:28:14 +09:00
Islam Imad
7ceecfad40
[CodeGen] Fix EVT::changeVectorElementType assertion on simple-to-extended fallback (#173413)
Fixes #171608
2025-12-28 18:51:18 +00:00
Stefan Weigl-Bosker
da8497ed08
[IR][Verifier] Verification for target-features attribute (#173119)
Fixes https://github.com/llvm/llvm-project/issues/172647

Currently, MC assumes that all `target-feature` flag attributes are well
formed and will crash otherwise. This change handles those cases more
gracefully.
2025-12-22 11:13:56 +01:00
Rahul Joshi
d921b54d93
[LLVM][Target] Use ListSeparator in lib/Target (#172919)
Use `ListSeparator` in various places in Target.
2025-12-19 10:19:57 -08:00
Frederik Harwath
6ad41bcc49
[CodeGen] expand-fp: Change frem expansion criterion (#158285)
The existing condition for checking whether or not to expand an frem
instruction in expand-fp is not sufficiently precise.
The expansion on other targets than AMDGPU - which is the only intended
user right now - is only prevented due to the interaction with the
MaxLegalFpConvertBitWidth check.  Relying on this is conceptually wrong
and limits the use of the pass for other targets and further expansions
(e.g. merging with the similar ExpandLargeDivRem pass).

Change the expansion criterion to always expand frem of a given type
for targets that use "Expand" as the legalization action for the 
underlying scalar type and use this to exit the pass early for targets 
which do not require any expansions. This requires to change the
frem legalization action for all targets which do not want frem to 
be expanded in this pass from "Expand" to "LibCall".

---------

Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-12-16 17:31:26 +01:00