1332 Commits

Author SHA1 Message Date
hanbeom
f2f5845f19
[WebAssembly][FastISel] Fold AND mask operations into ZExt load (#183743)
FastISel emits separate load and AND instructions for bitmasking.
(before) %1:i32 = LOAD_I32 %addr; %2:i32 = AND_I32 %1, 255

Fold AND masks into ZExt loads by verifying operands with
maskTrailingOnes. A getFoldedLoadOpcode wrapper is implemented
to manage dispatching logic for better extensibility.
(after) %1:i32 = LOAD8_U_I32 %addr

Fixed: https://github.com/llvm/llvm-project/issues/180783
2026-03-11 11:30:48 +09:00
Derek Schuff
e950a806f0
[WebAssembly] Look through freeze nodes when folding vector load + ext (#185143)
When folding loads with extensions, the extension operand can be a freeze node
in addition to a load. We can look through it to do the desirability check.

Fixes #184676
2026-03-10 19:15:53 -07:00
Derek Schuff
1324ea1b22
[WebAssembly] Fold any/alltrue SIMD boolean reductions with eqz (#184704)
Existing ISel patterns match setne/seteq following SIMD boolean reductions
any_true and all_true, and drop the ones that are redundant (because the
reductions always return 1 or 0). This adds patterns to also produce eqz
instructions instead of a comparison with a const.
2026-03-09 22:54:25 +00:00
Sy Brand
ae4e71241f
[MC][WebAssembly] Allow strings for import modules and names in asm (#182896)
Current tooling for the WebAssembly component model uses import modules
and names such as `$root` and `[thread-index]`. Importing these from
assembly files requires support for non-valid identifiers in
`.import_name` and `.import_module` directives. This PR adds support for
specifying those as strings, e.g.:

```asm
	.import_module __wasm_component_model_builtin_thread_index, "$root"
	.import_name __wasm_component_model_builtin_thread_index, "[thread-index]"
```
2026-03-06 12:43:09 -08:00
Nikita Popov
f90b783c3f
[WebAssembly] Do not form minnum/maxnum (#184796)
For wasm, forming minnum/maxnum style ISD nodes is non-profitable,
because (in cases where any float min/max support exists at all), it has
pmin/pmax instructions that correspond to the fcmp+select semantics, or
relaxed_fmin/relaxed_fmax (for the nnan+nsz case) with even loser
semantics.

As such, return false from isProfitableToCombineMinNumMaxNum(), and also
respect that hook in the SDAGBuilder.
2026-03-06 09:05:51 +01:00
Demetrius Kanios
0a76568db0
[WebAssembly] Reapply "[WebAssembly] Incorporate SCCs into WebAssemblyFixIrreducibleControlFlow" (#181755) (#184441)
Re-application of #181755.

Includes fixes to issues found after the original's merge.
2026-03-05 11:13:43 -08:00
Derek Schuff
ade43a54d4
[WebAssembly] MC support for acquire-release atomics (#183656)
Initial support for acquire-release atomics, specified as part of
https://github.com/WebAssembly/shared-everything-threads

This adds an ordering operand to atomic loads, stores, RMWs,
wait/notify,
and fences. It currently defaults to 0 and ISel is not updated yet, so
atomics produced by the compiler will still always be seqcst.

Asm parsing and printing, binary emission and disassembly are all
updated. Binary emission will always use the old encoding because the
encoding is smaller, and to get backwards compatibility for free.
2026-03-04 20:10:14 +00:00
hanbeom
3bb4a506c5
[WebAssembly] Print type signature and table for call_indirect (#179120)
Update WebAssemblyInstPrinter.cpp to correctly print type
and table operands for both register and stack modes.
2026-03-04 18:00:42 +09:00
Derek Schuff
87a4b36fbe
[WebAssembly] Use MVT::i32 instead of i1 in performAnyAllCombine (#183866)
The CombineSetCC helpers and performAnyAllCombine generate MVT::i1
results.
However MVT::i1 is an illegal type in WebAssembly, and this combiner can
run either before or after legalization. Directly creating the intrinsic
and negating its result using XOR instead of i1 and a NOT operation
avoids this problem.

Fixes #183842
2026-03-03 15:19:23 -08:00
hanbeom
637bb0e377
[WebAssembly][FastISel] Call materializeLoadStoreOperands in load fold (#184203)
The `tryToFoldLoadIntoMI` function omitted materializing base registers
for addresses before folding sign-extend instructions into loads. This
left `$noreg` as the base register, crashing subsequent passes.

WebAssembly memory instructions structurally require a valid base
register. Calling the existing `materializeLoadStoreOperands` function
ensures that a `CONST 0` virtual register is generated when addressing
global variables directly without a pre-existing base register.

(before) %1:i32 = LOAD8_S_I32_A32 0, @ch, $noreg ... -> CRASH (after)
%3:i32 = CONST_I32 0
         %1:i32 = LOAD8_S_I32_A32 0, @ch, %3:i32 ... -> Folded safely
2026-03-04 03:39:17 +09: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
hanbeom
ccfd59a03e
[NFC][WebAssembly] Expanding load-ext testcases for the MVP CPU target (#182864)
Some features tested in load-ext require sign-ext. 
To test this, add tests targeting the MVP CPU.
2026-02-24 11:30:51 +09: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
hanbeom
944ef9fa64
[NFC][WebAssembly] Add Fast-ISel test for load-ext (#181480)
Update load-ext.ll to enable testing of Fast-isel.

Related: #179672
2026-02-19 14:56:17 +09:00
Florian Hahn
6f253e87dd
Reapply "[VPlan] Run narrowInterleaveGroups during general VPlan optimizations. (#149706)"
This reverts commit 8d29d09309654541fb2861524276ada6a3ebf84c.

The underlying issue causing the revert has been fixed independently
as 301fa24671256734df6b7ee65f23ad885400108e.

Original message:
Move narrowInterleaveGroups to to general VPlan optimization stage.

To do so, narrowInterleaveGroups now has to find a suitable VF where all
interleave groups are consecutive and saturate the full vector width.

If such a VF is found, the original VPlan is split into 2:
 a) a new clone which contains all VFs of Plan, except VFToOptimize, and
 b) the original Plan with VFToOptimize as single VF.

The original Plan is then optimized. If a new copy for the other VFs has
been created, it is returned and the caller has to add it to the list of
candidate plans.

Together with https://github.com/llvm/llvm-project/pull/149702, this
allows to take the narrowed interleave groups into account when
computing costs to choose the best VF and interleave count.

One example where we currently miss interleaving/unrolling when
narrowing interleave groups is https://godbolt.org/z/Yz77zbacz

PR: https://github.com/llvm/llvm-project/pull/149706
2026-02-15 20:10:10 +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
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
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
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
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
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
valadaptive
cdc6a84c14
TargetLowering: Allow FMINNUM/FMAXNUM to lower to FMINIMUM/FMAXIMUM even without nsz (#177828)
This restriction was originally added in
https://reviews.llvm.org/D143256, with the given justification:

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

As far as I can tell, this was never correct. Before
https://github.com/llvm/llvm-project/pull/172012, `minnum` and `maxnum`
were nondeterministic with regards to signed zero, so it's always been
perfectly legal to lower them to operations that order signed zeroes.
2026-01-25 18:24:12 -05:00
Matt Arsenault
0d4a35d560
IR: Remove llvm.convert.to.fp16 and llvm.convert.from.fp16 intrinsics (#174484)
These are long overdue for removal. These were originally a hack
to support loading half values before there was any / decent support
for the half type through the backend. There's no reason to continue
supporting these, they're equivalent to fpext/fptrunc with a bitcast.

SelectionDAG stopped translating these directly, and used the
bitcast + fp cast since f7a02c17628e825, so there's been no reason
to use these since 2014.
2026-01-21 09:50:28 +00:00
Sam Parker
b84ffe040b
[WebAssembly] LoadLane matching with offsets (#176005) 2026-01-15 08:39:42 +00:00
Sam Parker
94913cf150
[NFC][WebAssembly] More memory interleave tests (#175918) 2026-01-14 12:26:10 +00: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
Derek Schuff
4c61843e44
[WebAssembly] Add wasm64 testing to varargs.ll [NFC] (#175102)
Looking at https://github.com/llvm/llvm-project/pull/173580 revealed
that our testing of varargs is inadequate. This is a start on improving it.
2026-01-09 08:51:06 -08: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
Derek Schuff
c99db7136e
[WebAssembly] Disable explicit-locals in the libcalls.ll test. NFC (#174811)
The keep-registers mode isn't super useful without disabling
explicit-locals,
as the local gets/sets are irrelevant noise in most cases.
Switching this test makes the output much more concise and will make
upcoming
changes easier to review.
2026-01-07 16:52:52 -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
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
Derek Schuff
6d60d3d7e4
Revert "[WebAssembly] Implement addrspacecast to funcref" (#170785)
Reverts llvm/llvm-project#166820
There was a failure in the ENABLE_EXPENSIVE_CHECKS configuration.
2025-12-04 17:24:14 -08:00
Demetrius Kanios
d3b9fd0f86
[WebAssembly] Implement addrspacecast to funcref (#166820)
Adds lowering of `addrspacecast [0 -> 20]` to allow easy conversion of
function pointers to Wasm `funcref`

When given a constant function pointer, it lowers to a direct
`ref.func`. Otherwise it lowers to a `table.get` from
`__indirect_function_table` using the provided pointer as the index.
2025-12-04 16:34:42 -08:00
Jasmine Tang
e0db7f347c
[WebAssembly] Optimize away mask of 63 for sra and srl( zext (and i32 63))) (#170128)
Follow up to #71844 after shl implementation
2025-12-02 18:23:17 +00:00
Jasmine Tang
edd1856686
[WebAssembly] Optimize away mask of 63 for shl ( zext (and i32 63))) (#152397)
Fixes https://github.com/llvm/llvm-project/issues/71844
2025-12-01 11:32:46 +00:00
hstk30-hw
a6cec3f3e5
Reland "[RegAlloc] Fix the terminal rule check for interfere with DstReg (#168661)" (#169219)
Reland d5f3ab8ec97786476a077b0c8e35c7c337dfddf2, fix testcases.
2025-11-24 09:27:25 +08:00
Aiden Grossman
d5f3ab8ec9 Revert "[RegAlloc] Fix the terminal rule check for interfere with DstReg (#168661)"
This reverts commit 0859ac5866a0228f5607dd329f83f4a9622dedcc.

This caused a couple test failures, likely due to a mid-air collision.
Reverting for now to get the tree back to green and allow the original
author to run UTC/friends and verify the output.
2025-11-23 05:17:45 +00:00
hstk30-hw
0859ac5866
[RegAlloc] Fix the terminal rule check for interfere with DstReg (#168661)
This maybe a bug which is introduced by commit
6749ae36b4a33769e7a77cf812d7cd0a908ae3b9, and has been present ever
since.
In this case, `OtherReg` always overlaps with `DstReg` cause they from
the `Copy` all.
2025-11-23 10:11:24 +08:00
Sam Parker
e44646b795
[WebAssembly] Lower ANY_EXTEND_VECTOR_INREG (#167529)
Treat it in the same manner of zero_extend_vector_inreg and generate an
extend_low_u if possible. This is to try an prevent expensive shuffles
from being generated instead. computeKnownBitsForTargetNode has also
been updated to specify known zeros on extend_low_u.
2025-11-20 08:57:08 +00:00
Jasmine Tang
672757bf55
[WebAssembly] Add patterns for extadd pairwise (#167960)
Add a few patterns for extadd pairwise.
2025-11-18 02:41:16 -08:00
Hongyu Chen
63e6373efd
[WebAssembly] Truncate extra bits of large elements in BUILD_VECTOR (#167223)
Fixes https://github.com/llvm/llvm-project/issues/165713
This patch handles out-of-bound vector elements and truncates extra
bits.
2025-11-17 10:39:18 +00:00
Matt Arsenault
dfdada1b78
CodeGen: Remove target hook for terminal rule (#165962)
Enables the terminal rule for remaining targets
2025-11-12 21:12:19 +00:00
Hongyu Chen
9697f4b9e4
[WebAssembly][FastISel] Bail out on meeting non-integer type in selectTrunc (#167165)
Fixes https://github.com/llvm/llvm-project/issues/165438
With `simd128` enabled, we may meet vector type truncation in FastISel.
To respect #138479, this patch merely bails out on non-integer IR types,
though I prefer bailing out for all non-simple types as most targets
(X86, AArch64) do.
2025-11-12 04:33:41 +08:00
Sam Parker
d47fdfec2b
[NFC][WebAssembly] Precommit test. (#167520) 2025-11-11 16:20:12 +00:00
Sam Parker
d10a85167a
[WebAssembly] Implement more of getCastInstrCost (#164612)
Fill out more information for sign and zero extend and add some truncate
information; however, the primary change is to int/fp conversions. In
particular, fp to (narrow) int appears to be relatively expensive.
2025-11-10 08:07:16 +00:00