2116 Commits

Author SHA1 Message Date
Sam Parker
68152f1301
[WebAssembly] v16i8 mul support (#150209)
During target DAG combine, use two i16x8.extmul_low_i8x16 and a shuffle
for v16i8 mul.

On my AArch64 machine, using V8, I observe a 3.14% geomean improvement
across 65 benchmarks, including: 9.2% for spec2017.x264, 6% for libyuv
and 1.8% for ncnn.
2025-07-29 09:23:31 +01:00
Nikita Popov
fc90685354
[WebAssemblyLowerEmscriptenEHSjLj] Avoid lifetime of phi (#150932)
After #149310 lifetime intrinsics require an alloca argument, an
invariant that this pass can break.

I've fixed this in two ways:
* First, move static allocas into the entry block. Currently, the way
the pass splits the entry block makes all allocas dynamic, which I
assume was not actually intended. This will avoid unnecessary SSA
reconstruction for allocas as well, and thus avoid the problem.
* If this fails (for dynamic allocas) drop all lifetime intrinsics if
any one of them would require a rewrite during SSA reconstruction.

Fixes https://github.com/llvm/llvm-project/issues/150498.
2025-07-29 09:58:57 +02:00
Jasmine Tang
522ac23609
[WebAssembly] Add pattern for relaxed nmadd (#150684)
Following footstep of https://github.com/llvm/llvm-project/pull/147487
(support for madd), this PR adds support for nmadd.

https://github.com/llvm/llvm-project/issues/55932 tracks this
2025-07-28 10:20:04 -07:00
Fangrui Song
c2faf6a57f MCSectionWasm: Remove classof
The object file format specific derived classes are used in context like
MCStreamer and MCObjectTargetWriter where the type is statically known.
We don't use isa/dyn_cast and we want to eliminate
MCSection::SectionVariant in the base class.
2025-07-26 09:30:02 -07:00
Hood Chatham
15b03687ff
[WebAssembly,clang] Add __builtin_wasm_test_function_pointer_signature (#150201)
Tests if the runtime type of the function pointer matches the static
type. If this returns false, calling the function pointer will trap.
Uses `@llvm.wasm.ref.test.func` added in #147486.

Also adds a "gc" wasm feature to gate the use of the ref.test
instruction.
2025-07-25 16:52:39 -07:00
Jasmine Tang
8e6a05d471
[WebAssembly] Added vectorized version of fexp10 to the supported list (#150564)
Fixes https://github.com/llvm/llvm-project/issues/117200.

The default behavior in TargetLoweringBase is only scalar floats on fexp
are supported by default, not the vectorized version. This PR adds
`ISD::FEXP10` to the supported list.
2025-07-25 12:30:59 -07:00
Nikita Popov
129a35454c [WebAssemblyOptimizeReturned] Skip lifetime intrinsic uses
Replacing an alloca with a call result in a lifetime intrinsic
will cause a verifier error.

Fixes https://github.com/llvm/llvm-project/issues/150498.
2025-07-25 12:12:26 +02:00
Hood Chatham
e3b79afa67
[WebAssembly,llvm] Fix buildbot problems with llvm.wasm.ref.test.func (#150116)
PR #147486 broke the sanitizer and expensive-checks buildbot. 

These captures were needed when toWasmValType emitted a diagnostic but
are no longer needed since we changed it to an assertion failure. This
removes the unneeded captures and should fix the sanitizer-buildbot.

I also fixed the codegen in the wasm64 target: table.get requires an i32
but in wasm64 the function pointer is an i64. We need an additional
`i32.wrap_i64` to convert it. I also added `-verify-machineinstrs` to
the tests so that the test suite validates this fix.

Finally, I noticed that #150201 uses a feature of the intrinsic that is
not covered by the tests, namely `ptr` arguments. So I added one
additional test case to ensure that it works properly.

cc @dschuff
2025-07-23 09:52:05 -07:00
Heejin Ahn
b13bca7387
[WebAssembly] Unstackify registers with no uses in ExplicitLocals (#149626)
There are cases we end up removing some intructions that use stackified
registers after RegStackify. For example,

```wasm
bb.0:
  %0 = ...    ;; %0 is stackified
  br_if %bb.1, %0
bb.1:
```

In this code, br_if will be removed in CFGSort, so we should unstackify
%0 so that it can be correctly dropped in ExplicitLocals.

Rather than handling this in case-by-case basis, this PR just
unstackifies all stackifies register with no uses in the beginning of
ExplicitLocals, so that they can be correctly dropped.

Fixes #149097.
2025-07-22 15:34:23 -07:00
Kazu Hirata
160d46d4c3 [WebAssembly] Fix warnings
This patch fixes:

  llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp:126:26:
  error: lambda capture 'DAG' is not used
  [-Werror,-Wunused-lambda-capture]

  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp:239:28:
  error: unused variable 'Info' [-Werror,-Wunused-variable]
2025-07-22 14:48:09 -07:00
Hood Chatham
15715f4089
[WebAssembly,llvm] Add llvm.wasm.ref.test.func intrinsic (#147486)
This adds an llvm intrinsic for WebAssembly to test the type of a
function. It is intended for adding a future clang builtin
` __builtin_wasm_test_function_pointer_signature` so we can test whether
calling a function pointer will fail with function signature mismatch.

Since the type of a function pointer is just `ptr` we can't figure out
the expected type from that.
The way I figured out to encode the type was by passing 0's of the
appropriate type to the intrinsic.
The first argument gives the expected type of the return type and the
later values give the expected
type of the arguments. So
```llvm
@llvm.wasm.ref.test.func(ptr %func, float 0.000000e+00, double 0.000000e+00, i32 0)
```
tests if `%func` is of type `(double, i32) -> (i32)`. It will lower to:
```wat
local.get $func
table.get $__indirect_function_table
ref.test (double, i32) -> (i32)
```
To indicate the function should be void, I somewhat arbitrarily picked
`token poison`, so the following tests for `(i32) -> ()`:
```llvm
@llvm.wasm.ref.test.func(ptr %func, token poison, i32 0)
```

To lower this intrinsic, we need some place to put the type information.
With `encodeFunctionSignature()` we encode the signature information
into an `APInt`. We decode it in `lowerEncodedFunctionSignature` in
`WebAssemblyMCInstLower.cpp`.
2025-07-22 14:07:34 -07:00
Arseny Kapoulkine
5b98992fb9
[WebAssembly] Optimize convert_iKxN_u into convert_iKxN_s (#149609)
convert_iKxN_s is canonicalized into convert_iKxN_u when the argument is
known to have sign bit 0. This results in emitting Wasm opcodes that, on
some targets (like x86_64), are dramatically slower than signed versions
on major engines.

Similarly to X86, we now fix this up in isel when the instruction has
nonneg flag from canonicalization or if we know the source has zero sign
bit.

Fixes #149457.
2025-07-21 09:17:29 -07:00
Jasmine Tang
343f7475be
[WebAssembly] Add support for memcmp expansion (#148298)
Fixes https://github.com/llvm/llvm-project/issues/61400

Added test case in llvm/test/CodeGen/WebAssembly/memcmp-expand.ll
2025-07-20 10:27:42 -07:00
Kazu Hirata
7c83d66719
[llvm] Remove unused includes (NFC) (#148768)
These are identified by misc-include-cleaner.  I've filtered out those
that break builds.  Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
2025-07-14 22:19:14 -07:00
jjasmine
6640b0a293
[WebAssembly] Add patterns for relaxed madd (#147487)
[WebAssembly] Fold fadd contract (fmul contract) to relaxed madd w/
-mattr=+simd128,+relaxed-simd

Fixes #121311

- Precommit test for #121311
- Fold fadd contract (fmul contract) to relaxed madd w/
-mattr=+simd128,+relaxed-simd
- Move PatFrag of fadd_contract in ARM.td and WebAssembly.td to
TargetSelectionDAG.td for reuse of pattern
2025-07-15 00:56:28 +08:00
Simon Pilgrim
82a276e610
[ARM][WebAssembly] Remove unused PatternMatch namespace. NFC. (#147984)
Avoid file-level "using namespace llvm::PatternMatch" to make it easier to potentially use SDPatternMatch in the future.
2025-07-11 10:24:43 +01:00
Hood Chatham
42d079e16e
[WebAssembly,MC] Add ref.test_func handling to AsmParser (#139642)
This will allow us to eliminate the hand-coded webassembly here:

https://github.com/python/cpython/blob/main/Python/emscripten_trampoline.c#L138
2025-07-07 13:31:57 -07:00
Matt Arsenault
d8ef156379
DAG: Remove verifyReturnAddressArgumentIsConstant (#147240)
The intrinsic argument is already marked with immarg so non-constant
values are rejected by the IR verifier.
2025-07-07 16:28:47 +09:00
Matt Arsenault
7b0f70a9b2
WebAssembly: Stop changing MCAsmInfo's ExceptionsType based on flags (#146343)
Currently wasm adds an extra level of options that work backwards
from the standard options, and overwrites them. The ExceptionModel
field in TM->Options is the standard user configuration option for the
exception model to use. MCAsmInfo's ExceptionsType is a constant for the
default to use for the triple if not explicitly set in the TargetOptions
ExceptionModel. This was adding 2 custom flags, changing the MCAsmInfo
default, and overwriting the ExceptionModel from the custom flags.

These comments about compiling bitcode with clang are describing a
toolchain
bug or user error. TargetOptions is bad, and we should move to
eliminating it.
It is module state not captured in the IR. Ideally the exception model
should either
come implied from the triple, or a module flag and not depend on this
side state.
Currently it is the responsibility of the toolchain and/or user to
ensure the same
command line flags are used at each phase of the compilation. It is not
the backend's
responsibilty to try to second guess these options.

-wasm-enable-eh and -wasm-enable-sjlj should also be removed in favor of
the standard
exception control. I'm a bit confused by how all of these fields are
supposed to interact,
but there are a few uses in the backend that are directly looking at
these flags instead
of the already parsed ExceptionModel which need to be cleaned up.

Additionally, this was enforcing some rules about the combinations of
flags at a random
point in the IR pass pipeline configuration. This is a module property
that should
be handled at TargetMachine construction time at the latest. This
required adding flags
to a few mir and clang tests which never got this far to avoid hitting
the errors.
2025-07-07 10:05:41 +09:00
Fangrui Song
aec88832df MC: Remove unneeded MCFixupKind casts 2025-07-05 14:43:34 -07:00
Fangrui Song
244e053b6c MC: Remove llvm/MC/MCFixupKindInfo.h
The file used to define `MCFixupKindInfo`, a simple structure,
which is now in MCAsmBackend.h.
2025-07-05 11:24:11 -07:00
Fangrui Song
20b3ab5683 MCFixup: Remove unused Loc argument
MCFixup::Loc has been removed in favor of MCExpr::Loc through
`const MCExpr *Value` (commit 777391a2164b89d2030ca013562151ca3c3676d1).
2025-07-04 12:23:04 -07:00
jjasmine
cbc2ac5db8
[WebAssembly] Fold TargetGlobalAddress with added offset (#145829)
Previously we only folded TargetGlobalAddresses into the memarg if they
were on their own, so this patch supports folding TargetGlobalAddresses
that are added to some other offset.

Previously we weren't able to do this because we didn't have nuw on the
add, but we can now that getelementptr has nuw and is plumbed through to
the add in 0564d0665b302d1c7861e03d2995612f46613a0f.

Fixes #61930
2025-07-03 11:01:36 +01:00
Fangrui Song
dd2891535d
MCAsmBackend: Merge addReloc into applyFixup (#146820)
Follow-up to #141333. Relocation generation called both addReloc and
applyFixup, with the default addReloc invoking shouldForceRelocation,
resulting in three virtual calls. This approach was also inflexible, as
targets needing additional data required extending
`shouldForceRelocation` (see #73721, resolved by #141311).

This change integrates relocation handling into applyFixup, eliminating
two virtual calls. The prior default addReloc is renamed to
maybeAddReloc. Targets overriding addReloc now call their customized
addReloc implementation.
2025-07-02 23:14:11 -07:00
Matt Arsenault
6ab7e52dd8
WebAssembly: Move validation of EH flags to TargetMachine construct time (#146634) 2025-07-03 07:25:38 +09:00
Alex Crichton
a8a9a7f95a
[WebAssembly] Fix inline assembly with vector types (#146574)
This commit fixes using inline assembly with v128 results. Previously
this failed with an internal assertion about a failure to legalize a
`CopyFromReg` where the source register was typed `v8f16`. It looks like
the type used for the destination register was whatever was listed first
in the `def V128 : WebAssemblyRegClass` listing, so the types were
shuffled around to have a default-supported type.

A small test was added as well which failed to generate previously and
should now pass in generation. This test passed on LLVM 18 additionally
and regressed by accident in #93228 which was first included in LLVM 19.
2025-07-01 20:26:30 -07:00
jjasmine
e9c9f8f374
[WebAssembly] Fold any/alltrue (setcc x, 0, eq/ne) to [not] any/alltrue x (#144741)
Fixes https://github.com/llvm/llvm-project/issues/50142, a miss of
further vectorization, where we can only achieve zext (xor (any_true),
-1).

Now in test case simd-setcc-reductions, it's converted to all_true.

Also fixes https://github.com/llvm/llvm-project/issues/145177, which is

all_true (setcc x, 0, eq) -> not any_true
any_true (setcc x, 0, ne) -> any_true
all_true (setcc x, 0, ne) -> all_true

---------

Co-authored-by: badumbatish <--show-origin>
2025-07-01 15:27:37 -07:00
jjasmine
4a8c1f7d12
[WebAssembly] [Backend] Wasm optimize illegal bitmask (#145627)
[WebAssembly] [Backend] Wasm optimize illegal bitmask for #131980.

Currently, the case for illegal bitmask (v32i8 or v64i8) is that at the
SelectionDag level, two (four) vectors of v128 will be concatenated
together, then they'll all be SETCC by the same pseudo illegal
instruction, which requires expansion later on.

I opt for SETCC-ing them seperately, bitcast and zext them and then add
them up together in the end.

---------

Co-authored-by: badumbatish <--show-origin>
2025-07-01 15:13:08 -07:00
Fangrui Song
e878b7e349 MCParsedAsmOperand::print: Add MCAsmInfo parameter
so that subclasses can provide the appropriate MCAsmInfo to print
MCExpr objects.

At present, llvm/utils/TableGen/AsmMatcherEmitter.cpp constucts a
generic MCAsmInfo.
2025-06-28 12:05:33 -07:00
Fangrui Song
d93aff42c2 MC: Migrate away from operator<< MCExpr
MCExpr::print has an optional MCAsmInfo argument, which is error-prone
when omitted. MCExpr::print and the convenience helper operator<< are
discouraged to use. Switch to MCAsmInfo::printExpr instead. Use the
target-specific MCAsmInfo if available.
2025-06-28 10:58:09 -07:00
Fangrui Song
7726103d1e WebAssembly: Merge MCExpr into MCAsmInfo
to align with targets that have made the transition.
2025-06-26 23:38:39 -07:00
Fangrui Song
56b2c7d988 MC: Rename initializeVariantKinds to initializeAtSpecifiers
We introduced VariantKinds after MCSymbolRefExpr::VariantKind and then
deprecated the VariantKind naming in favor of AtSpecifier (#133214).
Rename the function and type to use the recommended convention.
2025-06-26 22:46:20 -07:00
Sam Parker
d12fb1fc37
[WebAssembly] Refactor PerformSETCCCombine (#144875)
Extract the logic into a templated helper function.
2025-06-25 08:56:35 +01:00
SingleAccretion
cd46354dbd
[WebAssembly] Enable a limited amount of stackification for debug code (#136510)
This change is a step towards fixing one long-standing problem with
LLVM's debug WASM codegen: excessive use of locals. One local for each
temporary value in IR (roughly speaking).

This has a lot of problems:
1) It makes it easy to hit engine limitations of 50K locals with certain
code patterns and large functions.
2) It makes for larger binaries that are slower to load and slower to
compile to native code.
3) It makes certain compilation strategies (spill all WASM locals to
stack, for example) for debug code excessively expensive and makes debug
WASM code either run very slow, or be less debuggable.
4) It slows down LLVM itself.

This change addresses these partially by running a limited version of
the stackification pass for unoptimized code, one that gets rid of the
most 'obviously' unnecessary locals.

Care needs to be taken to not impact LLVM's ability to produce high
quality debug variable locations with this pass. To that end:
1) We only allow stackification when it doesn't require moving any
instructions.
2) We disable stackification of any locals that are used in
DEBUG_VALUEs, or as a frame base.
I have verified on a moderately large example that the baseline and the
diff produce the same kinds (local/global/stack) of locations, and the
only differences are due to the shifting of instruction offsets, with
many local.[get|set]s not being present anymore.

Even with this quite conservative approach, the results are pretty good:
1) 30% reduction in raw code size, up to 10x reduction in the number of
locals for select large methods (~1000 => ~100).
2) ~10% reduction in instructions retired for an "llc -O0" run on a
moderately sized input.
2025-06-24 11:40:47 -07:00
Matt Arsenault
efd42b9b1d
WebAssembly: Stop directly using RuntimeLibcalls.def (#143054)
Construct RuntimeLibcallsInfo instead of manually creating a map.
This was repeating the setting of the RETURN_ADDRESS. This removes
an obstacle to generating libcall information with tablegen.

This is also not great, since it's setting a static map which
would be broken if there were ever a triple with a different libcall
configuration.
2025-06-20 09:35:02 +09:00
Philip Reames
b96370131d
[TTI] Plumb CostKind through getPartialReductionCost (#144953)
Purely for the sake of being idiomatic with other TTI costing routines,
no direct motivation beyond that.
2025-06-19 15:29:56 -07:00
Andrew Rogers
19658d1474
[llvm] annotate interfaces in llvm/Target for DLL export (#143615)
## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public
interface for export. This patch annotates the `llvm/Target` library.
These annotations currently have no meaningful impact on the LLVM build;
however, they are a prerequisite to support an LLVM Windows DLL (shared
library) build.

## Background

This effort is tracked in #109483. Additional context is provided in
[this
discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307),
and documentation for `LLVM_ABI` and related annotations is found in the
LLVM repo
[here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).

A sub-set of these changes were generated automatically using the
[Interface Definition Scanner (IDS)](https://github.com/compnerd/ids)
tool, followed formatting with `git clang-format`.

The bulk of this change is manual additions of `LLVM_ABI` to
`LLVMInitializeX` functions defined in .cpp files under llvm/lib/Target.
Adding `LLVM_ABI` to the function implementation is required here
because they do not `#include "llvm/Support/TargetSelect.h"`, which
contains the declarations for this functions and was already updated
with `LLVM_ABI` in a previous patch. I considered patching these files
with `#include "llvm/Support/TargetSelect.h"` instead, but since
TargetSelect.h is a large file with a bunch of preprocessor x-macro
stuff in it I was concerned it would unnecessarily impact compile times.

In addition, a number of unit tests under llvm/unittests/Target required
additional dependencies to make them build correctly against the LLVM
DLL on Windows using MSVC.

## Validation

Local builds and tests to validate cross-platform compatibility. This
included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang
2025-06-17 13:28:45 -07:00
Eli Friedman
222ab28a92
[aarch64] Fix Arm64EC libcall lowering after recent refactoring. (#143977)
The refactored code accidentally tokenized a string instead of just
concatenating it.

Add a regression test and some assertions to ensure consistency.

Fixes #143890 .
2025-06-16 00:15:06 -07:00
Matt Arsenault
ba7369c49c
WebAssembly: Move runtime libcall setting out of TargetLowering (#142624)
RuntimeLibcallInfo needs to be correct outside of codegen contexts.
2025-06-16 10:46:05 +09:00
Fangrui Song
c9d511bc64 Replace deprecated MCExpr::print with MCAsmInfo::printExpr 2025-06-15 17:41:17 -07:00
Jeremy Morse
97ac6483aa
[DebugInfo][RemoveDIs] Delete debug-info-format flag (#143746)
This flag was used to let us incrementally introduce debug records
into LLVM, however everything is now using records. It serves no
purpose now, so delete it.
2025-06-12 11:51:58 +01:00
Kazu Hirata
34c011d544
[llvm] Use *Map::try_emplace (NFC) (#143002)
- try_emplace(Key) is shorter than insert(std::make_pair(Key, 0)).
- try_emplace performs value initialization without value parameters.
- We overwrite values on successful insertion anyway.
2025-06-05 16:14:31 -07:00
Kazu Hirata
89308de4b0
[llvm] Value-initialize values with *Map::try_emplace (NFC) (#141522)
try_emplace value-initializes values, so we do not need to pass
nullptr to try_emplace when the value types are raw pointers or
std::unique_ptr<T>.
2025-05-26 15:13:02 -07:00
Fangrui Song
cb7d68a77b MCParser: Replace deprecated alias MCAsmLexer with AsmLexer 2025-05-25 12:08:40 -07:00
Fangrui Song
a0901a2f87 Replace #include MCAsmLexer.h with AsmLexer.h
MCAsmLexer.h has been made a forwarder header since #134207
2025-05-25 11:57:29 -07:00
Fangrui Song
871b0a3221
MCAsmBackend: Simplify applyFixup (#141333)
Remove the MCSubtargetInfo argument from applyFixup, introduced in
https://reviews.llvm.org/D45962 , as it's only required by ARM. Instead,
add const MCFragment & so that ARMAsmBackend can retrieve
MCSubtargetInfo via a static member function.

Additionally, remove the MCAssembler argument, which is also only
required by ARM.

Additionally, make applyReloc non-const. Its arguments now fully cover
addReloc's functionality.
2025-05-23 23:09:56 -07:00
Rahul Joshi
52c2e45c11
[NFC][CodeGen] Adopt MachineFunctionProperties convenience accessors (#141101) 2025-05-23 08:30:29 -07:00
Kazu Hirata
dd702b3969
[llvm] Remove unused local variables (NFC) (#140422) 2025-05-18 07:31:51 -07:00
Max Graey
8aaac80ddd
[NFC] Use more isa and isa_and_nonnull instead dyn_cast for predicates (#137393)
Also fix some typos in comments

---------

Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2025-05-13 22:34:42 +08:00
Matthias Braun
675cb70641
Register assembly printer passes (#138348)
Register assembly printer passes in the pass registry.

This makes it possible to use `llc -start-before=<target>-asm-printer ...` in tests.

Adds a `char &ID` parameter to the AssemblyPrinter constructor to allow
targets to use the `INITIALIZE_PASS` macros and register the pass in the
pass registry. This currently has a default parameter so it won't break
any targets that have not been updated.
2025-05-06 18:01:17 -07:00