Commit Graph

1584 Commits

Author SHA1 Message Date
Sam Clegg 3e230d15eb Revert "[WebAssembly] Refactor and fix emission of external IR global decls"
This reverts commit 00bf4755e9.

This change broke the emscripten builder (among other things):

https://ci.chromium.org/ui/p/emscripten-releases/builders/try/linux/b8823500584349280721/overview

Sample failure:

```
test_unistd_unlink (test_core.core0) ...
wasm-ld: error: symbol type mismatch: __stdio_write
>>> defined as WASM_SYMBOL_TYPE_FUNCTION in /usr/local/google/home/sbc/dev/wasm/emscripten/cache/sysroot/lib/wasm32-emscripten/libc-debug.a(__stdio_write.o)
>>> defined as WASM_SYMBOL_TYPE_DATA in /usr/local/google/home/sbc/dev/wasm/emscripten/cache/sysroot/lib/wasm32-emscripten/libc-debug.a(stderr.o)
```
2022-01-31 12:20:56 -08:00
Paulo Matos 00bf4755e9 [WebAssembly] Refactor and fix emission of external IR global decls
This patches fixes the visibility and linkage information of symbols
referring to IR globals.

Emission of external declarations is now done in the first execution
of emitConstantPool rather than in emitLinkage (and a few other
places). This is the point where we have already gathered information
about used symbols (by running the MC Lower PrePass) and not yet
started emitting any functions so that any declarations that need to
be emitted are done so at the top of the file before any functions.

This changes the order of a few directives in the final asm file which
required an update to a few tests.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D118122
2022-01-31 11:42:21 +01:00
Simon Pilgrim 3a1fd17027 [WebAssembly] Use cast<> instead of dyn_cast<> to avoid dereference of nullptr
The pointers are dereferenced immediately, so assert the cast is correct instead of returning nullptr
2022-01-29 16:08:06 +00:00
Paulo Matos 864767ab09 [WebAssembly][NFC] Refactor WasmSymbol type setting code
This refactors some code dealing with setting Wasm symbol types.
Some of the code dealing with types was moved from
`WebAssemblyUtilities` to  `WebAssemblyTypeUtilities`.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D118121
2022-01-29 09:00:51 +01:00
Heejin Ahn 4f1244d7cc [WebAssembly] Nullify unnecessary setjmp invokes
This is similar to D116619, but now it handles `invoke`s. The reason we
didn't handle `invoke`s back then was we didn't support Wasm EH + Wasm
SjLj together, and the only case SjLj transformation will see `invoke`s
is when we are using Wasm EH. (In Emscripten EH, they would have been
transformed to `call`s to invoke wrappers.)

But after D117610 we support Wasm EH + Wasm SjLj together and we can
nullify `invoke`s to `setjmp` when there is no other longjmpable calls
within the function. Actually this is very unlikely to happen in
practice, because we treat destructors as longjmpable and also treat
`__cxa_end_catch` as longjmpable even if it is not.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D118408
2022-01-27 21:11:10 -08:00
Heejin Ahn 20c1d9ce5e [WebAssembly] Handle cleanuppad with no parent in Wasm SjLj
Wasm SjLj converts longjmpable calls into `invoke`s that unwind to
`%catch.longjmp.dispatch` BB, from where we check if the thrown
exception is a `longjmp`. But in case a call already has a `funclet`
attribute, i.e., it is within a catch scope, we have to unwind to its
unwind destination first to preserve the scoping structure. That will
eventually unwind to `%catch.longjmp.dispatch`, because all
`catchswitch` and `cleanupret` that unwind to caller are redirected to
`%catch.dispatch.longjmp` during Wasm SjLj transformation.

But the prevous code assumed `cleanuppad`'s parent pad was always an
instruction, and didn't handle when a `cleanuppad`'s parent is `none`.
This CL handles this case, and makes the `while` loop more intuitive by
removing `FromPad` condition and explicitly inserting `break`s.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D118407
2022-01-27 21:10:23 -08:00
Heejin Ahn 26d587cf0f [WebAssembly] Error out for setjmp within catch clause for Wasm SjLj
Wasm EH, used with either of Emscripten SjLj or Wasm SjLj, does not
allow `setjmp` calls to be placed within a `catch` clause, because we
don't support jumping into a `catch` block. Emscripten EH does not have
this restriction. But I think this restriction wouldn't prevent most of
use cases. This CL errors out with a clear messsage for this case.

Reviewed By: dschuff, kripken

Differential Revision: https://reviews.llvm.org/D118286
2022-01-27 21:05:43 -08:00
Heejin Ahn 786da40667 [WebAssembly] Don't copy noreturn attr to invokes
When we create an invoke wrapper call, if the original call instruction
has a `noreturn` attribute, we shouldn't copy it, because we expect
invoke wrapper calls to return. This generated incorrect `free` call
before an invoke wrapper call that calls `__cxa_throw`, because
`__cxa_throw` has `noreturn` attribute.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D118274
2022-01-27 21:04:43 -08:00
Heejin Ahn d9517efbb3 [WebAssembly] Treat __cxa_end_catch not longjmpable in Emscripten SjLj
In D117610 we treated `__cxa_end_catch` longjmpable even though it was
not to make unwind destination relationships correct. But we only need
to do this in Wasm SjLj, and doing this in Emscripten SjLj does not make
the code incorrect but add unnecessary invokes. This CL treats
`__cxa_end_catch` longjmpable only in Wasm SjLj.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D117943
2022-01-27 21:03:23 -08:00
Heejin Ahn eb675e972d [WebAssembly] Support Wasm EH + Wasm SjLj
D108960 added support for SjLj using Wasm EH instructions, which we call
Wasm SjLj going forward. (We call the old SjLj Emscripten SjLj) But it
did not support using Wasm EH and Wasm SjLj together. So far users of
Wasm EH had to use Wasm EH with Emscripten SjLj, which had a certain
limitation and it suffered from bigger code size increases as well.

This enables using Wasm EH and Wasm SjLj together.
1. This redirects `catchswitch` and `cleanupret` that unwind to caller
   to `catch.dispatch.longjmp` BB, which is a `catchswitch` BB that
   handles longjmps.
2. D108960 converted all longjmpable `call`s to `invokes` that unwind to
   `catch.dispatch.longjmp`. This CL checks if the `call` is embedded
   within another `catchpad`, and if so, makes it unwind to its nearest
   parent's unwind destination, rather than `catch.dispatch.longjmp`.
   This is necessary to preserve the scoping structure.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D117610
2022-01-19 20:13:54 -08:00
Jim Lin d6b0734837 [NFC] Use Register instead of unsigned 2022-01-19 20:17:04 +08:00
Nikita Popov d8bff13a8a [NFC] Add missing <map> includes
These were relying on a transitive include.
2022-01-19 12:29:03 +01:00
Paulo Matos 97ef15ad76 [WebAssembly] Fix reftype load/store match with idx from call
Implement support for matching an index from a WebAssembly CALL
instruction. Add test.

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D115327
2022-01-13 11:04:22 +01:00
Serge Guelton d2cc6c2d0c Use a sorted array instead of a map to store AttrBuilder string attributes
Using and std::map<SmallString, SmallString> for target dependent attributes is
inefficient: it makes its constructor slightly heavier, and involves extra
allocation for each new string attribute. Storing the attribute key/value as
strings implies extra allocation/copy step.

Use a sorted vector instead. Given the low number of attributes generally
involved, this is cheaper, as showcased by

https://llvm-compile-time-tracker.com/compare.php?from=5de322295f4ade692dc4f1823ae4450ad3c48af2&to=05bc480bf641a9e3b466619af43a2d123ee3f71d&stat=instructions

Differential Revision: https://reviews.llvm.org/D116599
2022-01-10 14:49:53 +01:00
Kazu Hirata f3a344d212 [Target] Remove redundant member initialization (NFC)
Identified with readability-redundant-member-init.
2022-01-06 22:01:44 -08:00
Heejin Ahn f2a43f06dd [WebAssembly] Use llvm utility functions in EH/SjLj
This uses `changeToCall` and `changeToInvokeAndSplitBasicBlock` from
`lib/Transforms/Utils`, replacing the custom logic. One difference of
those functions from our previous logic is they delete the original
`CallInst`/`InvokeInst`, which makes them tricky to use while iterating
through instructions/BBs. So this CL gathers the candidate calls first
and run them through `changeToInvokeAndSplitBasicBlock` later.

Also this renames some variables.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D116620
2022-01-04 17:47:20 -08:00
Heejin Ahn f178f61e1d [WebAssembly] Nullify unnecessary setjmp calls
D107530 did a small optimization that, if a function contains `setjmp`
calls but not other calls that can `longjmp`, we don't do SjLj
transformation on those `setjmp` calls, because they don't have
possibilities of returning from `longjmp`.

But we should remove those `setjmp` calls even in that case, because
Emscripten doesn't provide that function, assuming it is lowered away by
SjLj transformation. `setjmp` always returns 0 when called directly, so
this CL replaces them with `i32 0`.

Fixes https://github.com/emscripten-core/emscripten/issues/15679.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D116619
2022-01-04 17:44:32 -08:00
Kazu Hirata e5947760c2 Revert "[llvm] Remove redundant member initialization (NFC)"
This reverts commit fd4808887e.

This patch causes gcc to issue a lot of warnings like:

  warning: base class ‘class llvm::MCParsedAsmOperand’ should be
  explicitly initialized in the copy constructor [-Wextra]
2022-01-03 11:28:47 -08:00
Kazu Hirata 41bfac6aed [Target] Remove unused forward declarations (NFC) 2022-01-02 10:20:15 -08:00
Kazu Hirata fd4808887e [llvm] Remove redundant member initialization (NFC)
Identified with readability-redundant-member-init.
2022-01-01 16:18:18 -08:00
Heejin Ahn 4625b84879 [WebAssembly] Support clang -fwasm-exceptions for bitcode
This supports bitcode compilation using `clang -fwasm-exceptions`.

---

The current situation:

Currently the backend requires two options for Wasm EH:
`-wasm-enable-eh` and `-exception-model=wasm`. Wasm SjLj requires two
options as well: `-wasm-enable-sjlj` and `-exception-model=wasm`. When
using Wasm EH via Emscripten, you only need to pass `-fwasm-exceptions`,
and these options will be added within the clang driver. This
description will focus on the case of Wasm EH going forward, but Wasm
SjLj's case is similar.

When you pass `-fwasm-exceptions` to emcc and clang driver, the clang
driver adds these options to the command line that calls the clang
frontend (`clang -cc1`): `-mllvm -wasm-enable-eh` and
`-exception-model=wasm`. `-wasm-enable-eh` is prefixed with `-mllvm`, so
it is passed as is to the backend. But `-exception-model` is parsed and
processed within the clang frontend and stored in `LangOptions` class.
This info is later transferred to `TargetOptions` class, and then
eventually passed to `MCAsmInfo` class. All LLVM code queries this
`MCAsmInfo` to get the exception model.

---

Problem:

The problem is the whole `LangOptions` processing is bypassed when
compiling bitcode, so the information transfer of `LangOptions` ->
`TargetOptions` -> `MCAsmInfo` does not happen. They are all set to
`ExceptionHandling::None`, which is the default value.

---

What other targets do, and why we can't do the same:

Other targets support bitcode compilation by the clang driver, but they
can do that by using different triples. For example, X86 target supports
multiple triples, each of which has its own subclass of `MCAsmInfo`, so
it can hardcode the appropriate exception model within those subclasses'
constructors. But we don't have separate triples for each exception
mode: none, emscripten, and wasm.

---

What this CL does:

If we can figure out whether `-wasm-enable-eh` is passed to the backend,
we can programatically set the exception model from the backend, rather
than requiring it to be passed.

So we check `WasmEnableEH` and `WasmEnableSjLj` variables, which are
`cl::opt` for `-wasm-enable-eh` and `-wasm-enable-sjlj`, in
`WebAssemblyMCAsmInfo` constructor, and if either of them is set, we set
`MCAsmInfo.ExceptionType` to Wasm. `TargetOptions` cannot be updated
there, so we make sure they are the same later.

Fixes https://github.com/emscripten-core/emscripten/issues/15712.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D115893
2021-12-16 16:49:24 -08:00
Paulo Matos c92d45913c [WebAssembly] Fix typechecking for else MCInst
When hitting an else clause the type Stack should be reset to as it was at the start of the if, without taking into account the Type inserted into the Stack during the then branch of the if.

Reviewed By: aardappel

Differential Revision: https://reviews.llvm.org/D115748
2021-12-16 11:18:01 +01:00
Jing Bao 2a4a229d6d [WebAssembly] Custom optimization for truncate
When possible, optimize TRUNCATE to generate Wasm SIMD narrow
instructions (i16x8.narrow_i32x4_u, i8x16.narrow_i16x8_u), rather than generate
lots of extract_lane and replace_lane.

Closes #50350.
2021-12-14 08:42:39 -08:00
Paulo Matos b5b5f0ac77 [WebAssembly] Lower global syms representing tables with .tabletype
This patch implements a fix to recognize global symbols that represent
WebAssembly appropriately and generate the necessary .tabletype
directives.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D115511
2021-12-13 18:17:03 +01:00
Mircea Trofin 91a0da0142 [NFC] Rename MachineFunction::DeleteMachineBasicBlock
Renamed to conform to coding style
2021-12-08 18:12:51 -08:00
Paulo Matos 2fd634a5e3 [WebAssembly] Implement table instruction intrinsics
This change implements intrinsics for table.grow, table.fill,
table.size, and table.copy.

Differential Revision: https://reviews.llvm.org/D113420
2021-12-07 13:25:59 +01:00
Paulo Matos a96d828510 [WebAssembly] Implementation of intrinsic for ref.null and HeapType removal
This patch implements the intrinsic for ref.null.
In the process of implementing int_wasm_ref_null_func() and
int_wasm_ref_null_extern() intrinsics, it removes the redundant
HeapType.

This also causes the textual assembler syntax for ref.null to
change. Instead of receiving an argument: `func` or `extern`, the
instruction mnemonic is either ref.null_func or ref.null_extern,
without the need for a further operand.

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D114979
2021-12-06 09:46:15 +01:00
Zarko Todorovski 95875d246a [LLVM][NFC]Inclusive language: remove occurances of sanity check/test from llvm
Part of work to use more inclusive language in clang/llvm. Rewording
some comments and change function and variable names.
2021-11-24 17:29:55 -05:00
Zarko Todorovski 5b8bbbecfa [NFC][llvm] Inclusive language: reword and remove uses of sanity in llvm/lib/Target
Reworded removed code comments that contain `sanity check` and `sanity
test`.
2021-11-17 21:59:00 -05:00
Wouter van Oortmerssen 4a0c89a6cf [WebAssembly] Fix fixBrTableIndex removing instruction without checking uses
Fixes: https://bugs.llvm.org/show_bug.cgi?id=52352
Differential Revision: https://reviews.llvm.org/D113230
2021-11-08 15:53:44 -08:00
Nikita Popov a8c318b50e [BasicAA] Use index size instead of pointer size
When accumulating the GEP offset in BasicAA, we should use the
pointer index size rather than the pointer size.

Differential Revision: https://reviews.llvm.org/D112370
2021-11-07 18:56:11 +01:00
Kazu Hirata 22e21da47d [WebAssembly] Remove unused declaration SelectExternRefAddr (NFC) 2021-11-06 19:31:22 -07:00
Kazu Hirata 14d656b3d8 [Target] Use llvm::reverse (NFC) 2021-11-06 13:08:21 -07:00
Quinn Pham c71fbdd87b [NFC] Inclusive language: Remove instances of master in URLs
[NFC] This patch fixes URLs containing "master". Old URLs were either broken or
redirecting to the new URL.

Reviewed By: #libc, ldionne, mehdi_amini

Differential Revision: https://reviews.llvm.org/D113186
2021-11-05 08:48:41 -05:00
Wouter van Oortmerssen a320f877ce [WebAssembly] Fix debug locations for ExplicitLocals pass
This is a reworked version of the reverted patch: https://reviews.llvm.org/D112487
Note that
a) it doesn't need the test changes anymore, and
b) I checked at least locally it passes other.test_pthread_lsan_leak

Differential Revision: https://reviews.llvm.org/D113208
2021-11-04 11:38:03 -07:00
Wouter van Oortmerssen ac65366485 [WebAssembly] support "return" and unreachable code in asm type checker
To support return (it not being supported well was the ground cause for
https://github.com/WebAssembly/wasi-sdk/issues/200) we also have to have
at least a basic notion of unreachable, which in this case just means to stop
type checking until there is an end_block (an incoming control flow edge).
This is conservative (may miss on some type checking opportunities) but is
simple and an improvement over what we had before.

Differential Revision: https://reviews.llvm.org/D112953
2021-11-01 15:42:58 -07:00
Sam Clegg 3b039c68f2 Revert "[WebAssembly] Fix debug locations for ExplicitLocals pass"
This reverts commit a66451ebbe.

This caused a failure when integrated with emscripten:
https://ci.chromium.org/ui/p/emscripten-releases/builders/try/linux/b8832019855439718609/overview
2021-10-29 13:34:18 -07:00
Thomas Lively fb67f3d969 [WebAssembly] Add prototype relaxed float to int trunc instructions
Add i32x4.relaxed_trunc_f32x4_s, i32x4.relaxed_trunc_f32x4_u,
i32x4.relaxed_trunc_f64x2_s_zero, i32x4.relaxed_trunc_f64x2_u_zero.

These are only exposed as builtins, and require user opt-in.

Differential Revision: https://reviews.llvm.org/D112186
2021-10-28 14:01:53 -07:00
Wouter van Oortmerssen a66451ebbe [WebAssembly] Fix debug locations for ExplicitLocals pass
Differential Revision: https://reviews.llvm.org/D112487
2021-10-28 12:35:46 -07:00
Wouter van Oortmerssen 5694dbccc3 [WebAssembly] support Memory64 in target_features section
Differential Revision: https://reviews.llvm.org/D112266
2021-10-25 09:31:45 -07:00
Kazu Hirata 6fe949c4ed [Target, Transforms] Use StringRef::contains (NFC) 2021-10-22 08:52:33 -07:00
Zhi An Ng e1fb13401e [WebAssembly] Add prototype relaxed float min max instructions
Add relaxed. f32x4.min, f32x4.max, f64x2.min, f64x2.max. These are only
exposed as builtins, and require user opt-in.

Differential Revision: https://reviews.llvm.org/D112146
2021-10-20 09:41:51 -07:00
Craig Topper fe1f0de003 [RISCV][WebAssembly][TargetLowering] Allow expandCTLZ/expandCTTZ to rely on CTPOP expansion for vectors.
Our fallback expansion for CTLZ/CTTZ relies on CTPOP. If CTPOP
isn't legal or custom for a vector type we would scalarize the
CTLZ/CTTZ. This is different than CTPOP itself which would use a
vector expansion.

This patch teaches expandCTLZ/CTTZ to rely on the vector CTPOP
expansion instead of scalarizing. To do this I had to add additional
checks to make sure the operations used by CTPOP expansions are all
supported. Some of the operations were already needed for the CTLZ/CTTZ
expansion.

This is a huge improvement to the RISCV which doesn't have a scalar
ctlz or cttz in the base ISA.

For WebAssembly, I've added Custom lowering to keep the scalarizing
behavior. I've also extended the scalarizing to CTPOP.

Differential Revision: https://reviews.llvm.org/D111919
2021-10-20 07:46:41 -07:00
Paulo Matos 6d0c7bc17d [WebAssembly] Implementation of table.get/set for reftypes in LLVM IR
This change implements new DAG nodes TABLE_GET/TABLE_SET, and lowering
methods for load and stores of reference types from IR arrays. These
global LLVM IR arrays represent tables at the Wasm level.

Differential Revision: https://reviews.llvm.org/D111154
2021-10-20 10:31:31 +02:00
Zhi An Ng 2542bfa43a [WebAssembly] Add prototype relaxed swizzle instructions
Add i8x16 relaxed_swizzle instructions. These are only
exposed as builtins, and require user opt-in.

Differential Revision: https://reviews.llvm.org/D112022
2021-10-19 17:53:04 -07:00
Kazu Hirata 8568ca789e Use llvm::erase_if (NFC) 2021-10-18 09:33:42 -07:00
Zhi An Ng da07942834 [WebAssembly] Add prototype relaxed laneselect instructions
Add i8x16, i16x8, i32x4, i64x2 laneselect instructions. These are only
exposed as builtins, and require user opt-in.
2021-10-15 17:45:09 -07:00
Heejin Ahn 9261ee32dc [WebAssembly] Make EH work with dynamic linking
This makes Wasm EH work with dynamic linking. So far we were only able
to handle destructors, which do not use any tags or LSDA info.

1. This uses `TargetExternalSymbol` for `GCC_except_tableN` symbols,
   which points to the address of per-function LSDA info. It is more
   convenient to use than `MCSymbol` because it can take additional
   target flags.

2. When lowering `wasm_lsda` intrinsic, if PIC is enabled, make the
   symbol relative to `__memory_base` and generate the `add` node. If
   PIC is disabled, continue to use the absolute address.

3. Make tag symbols (`__cpp_exception` and `__c_longjmp`) undefined in
   the backend, because it is hard to make it work with dynamic
   linking's loading order. Instead, we make all tag symbols undefined
   in the LLVM backend and import it from JS.

4. Add support for undefined tags to the linker.

Companion patches:
- https://github.com/WebAssembly/binaryen/pull/4223
- https://github.com/emscripten-core/emscripten/pull/15266

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D111388
2021-10-12 23:28:27 -07:00
Reid Kleckner b3a6d096d7 Fix shlib builds for all lib/Target/*/TargetInfo libs
They all must depend on MC now that the target registry is in MC.
Also fix llvm-cxxdump
2021-10-08 15:21:13 -07:00
Reid Kleckner 89b57061f7 Move TargetRegistry.(h|cpp) from Support to MC
This moves the registry higher in the LLVM library dependency stack.
Every client of the target registry needs to link against MC anyway to
actually use the target, so we might as well move this out of Support.

This allows us to ensure that Support doesn't have includes from MC/*.

Differential Revision: https://reviews.llvm.org/D111454
2021-10-08 14:51:48 -07:00