1766 Commits

Author SHA1 Message Date
Hiroshi Yamauchi
3233ea3a9f [WebAssembly][NFC] Fix typos.
Differential Revision: https://reviews.llvm.org/D148567
2023-04-17 14:28:33 -07:00
NAKAMURA Takumi
7d5d987e93 [CMake] Reorder and reformat deps 2023-04-17 00:32:16 +09:00
Kazu Hirata
972983539b [llvm] Apply fixes from readability-redundant-control-flow (NFC) 2023-04-16 00:13:46 -07:00
Congcong Cai
db1dac1e20 [WebAssembly] AsmTypeCheck support to br instr
This PR introduces the `BrStack` member to store the info about
`loop`, `block`, `if` and `try`. It can check whether `br` immediate number
out of range.

Reviewed By: aheejin

Differential Revision: https://reviews.llvm.org/D148054
2023-04-13 11:56:11 +02:00
Heejin Ahn
d20a1b87f6 [WebAssembly] Handle DebugLoc in DebugValueManager
According to
https://llvm.org/docs/HowToUpdateDebugInfo.html#when-to-preserve-an-instruction-location,
when moving (and in our case cloning) within the same BB, the debug
location is preserved. But when moving / cloning to a different BB, we
preserve the debug location only if the destination BB contains the same
location. Currently we preserve the debug loc unconditionally in all
cases. This CL correctly handles the debug locs in DebugValueManager.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D148115
2023-04-12 23:47:24 -07:00
Congcong Cai
d8a0dc425c [NFC] format llvm/lib/Target/WebAssembly/AsmParser
Reviewed By: aheejin

Differential Revision: https://reviews.llvm.org/D147884
2023-04-11 15:41:29 +02:00
Heejin Ahn
86c65fc4aa [WebAssembly] Correctly check end_if/end_try with else/catch
When we encounter an `else`, `catch`, or `catch_all`, we currently just
push the structure `NestingType` and don't preserve the original `if`
and `try`'s signature. So after we pass `else`/`catch`/`catch_all`, we
can't check if the values on stack have the correct types when we
encounter `end_if` or `end_try`. This CL fixes the issue, and modifies
the existing test to be correct (some of them had `try` without
`catch`).

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D147881
2023-04-11 02:07:45 -07:00
Heejin Ahn
3e9881b92b [WebAssembly] Handle block-like structures consistently in type checker
We disable type check in unreachable code, but when the unreachable code
is enclosed within a block-like structure, the block as a whole has a
valid type and we should continue type checking after the block. But it
looks we currently only do that for blocks and not other block-like
structures (`loop`s, `try`s, and `if`s). Also unreachable code within
`if`'s true body shouldn't disable type checking in `else` body, and
that in `try` body shouldn't disable type checking in `catch/catch_all`
body.

This also causes the values/types on the stack to be correctly checked
when encounterint `catch`, `catch_all`, and `delegate`.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D147852
2023-04-11 02:07:00 -07:00
Heejin Ahn
8c0798f368 [WebAssembly] Fix type index block type handling in type checker
The current code is
```
      ExpectBlockType = false;
      TC.setLastSig(*Signature.get());
      if (ExpectBlockType)
        NestingStack.back().Sig = *Signature.get();
```

Because of the first line, the third line's `if (ExpectBlockType)` is
always false and we don't get to update `NestingStack.back().Sig`. This
results in not correctly erroring out when the types of remaining values
on the stack do not match the block type if the block type is written in
the form of a function type. We should set `ExpectBlockType` to false
after the `if`.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D147837
2023-04-11 02:04:56 -07:00
Heejin Ahn
0e37487df8 [WebAssembly] Fix selection of global calls
When selecting calls, currently we unconditionally remove `Wrapper`s of
the call target. But we are supposed to do that only when the target is
a function, an external symbol (= library function), or an alias of a
function. Otherwise we end up directly calling globals that are not
functions.

Fixes https://github.com/llvm/llvm-project/issues/60003.

Reviewed By: tlively, HerrCai0907

Differential Revision: https://reviews.llvm.org/D147397
2023-04-05 01:42:36 -07:00
Sam Clegg
f56b5921d3 [MC][WebAssembly] Fix type checking for bulk memory instructions
This code currently assumes that all bulk memory operations occur on
memory 0 which who's type is determined by the wasm32 vs wasm64 target
triple.  Further improvements would be need to support multi-memory.

Differential Revision: https://reviews.llvm.org/D147540
2023-04-04 14:10:10 -07:00
Thomas Lively
62bfb0b14c [WebAssembly] Add libcall signatures for roundeven
Since clang started emitting roundeven intrinsics in a7d6593a0a17, they would
cause a crash in the WebAssembly backend because it did not know the roundeven
library function signatures. Fix the crash by adding the signatures.

Differential Revision: https://reviews.llvm.org/D147476
2023-04-04 08:32:26 -07:00
Peter Rong
3b2476910b [WASM] Prevent casting undef to CosntantSDNode
WebAssembly tries to cast an `undef` to `CosntantSDNode` during `LowerAccessVectorElement`.
These operations will trigger an assertion error in cast.
To avoid this issue, we prevent casting, and abort the lowering operation.
A unit test is also included.

This patch fixes [pr61828](https://github.com/llvm/llvm-project/issues/61828)

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D147198
2023-03-30 20:14:11 -07:00
Peter Rong
51a93828d7 [WASM] Fix legalizer for LowerBUILD_VECTOR.
Constants in BUILD_VECTOR may be down cast into a smaller value that fits LaneBits, i.e., the bit width of elements in the vector.
This cast didn't consider 2^N where it would be cast into -2^N, which still doesn't fit into LaneBits after casting.
This will cause an assertion in later legalization.

2^N should be cast into 0, and this patch reflects such behavior.
This patch also includes a test to reflect the fix.
This patch fixes [issue 61780](https://github.com/llvm/llvm-project/issues/61780)

Related patch: https://reviews.llvm.org/D108669

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D147208
2023-03-30 19:20:04 -07:00
Peter Rong
163d7bb941 [WASM] Precommit WebAssemblyISelLowering.cpp format changes for D147198
Signed-off-by: Peter Rong <PeterRong96@gmail.com>
2023-03-29 22:18:53 -07:00
Heejin Ahn
b02db1dc78 [WebAssembly] Fix SmallVector warning
Fixes a build warning caused by D146744.
2023-03-29 13:35:16 -07:00
Heejin Ahn
a4e32ae4cd [WebAssembly] Do nothing when sinking to same place
In `DebugValueManager`, if a `Def` is requested to be sunk to the same
place (i.e., `Insert` is right after `Def`, not counting `DBG_VALUE`s)
currently we still do the sink. This can result in unnecessary creation
of `DBG_VALUE $noreg`. See comments for details. This CL detects this
case and do nothing and return, so we don't end up creating unnecessary
undef `DBG_VALUE`s.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D146860
2023-03-29 12:50:39 -07:00
Heejin Ahn
5a55c9507b [WebAssembly] Redesign DebugValueManager
The current `DebugValueManager`, which is mostly used in `RegStackify`,
simply sinks `DBG_VALUE`s along when a def instruction sinks.
(`RegStackify` only does sinks; it doesn't do hoists.)

But this simple strategy can result in incorrect combinations of
variables' values which would have not been possible in the original
program. In this case, LLVM's policy is to make the value unavailable,
so they will be shown as 'optimized out', rather than showing inaccurate
debug info. Especially, when an instruction sinks, its original
`DBG_VALUE` should be set to undef. This is well illustrated in the
third example in
https://llvm.org/docs/SourceLevelDebugging.html#instruction-scheduling.

This CL rewrites `DebugValueManager` with this principle in mind. When
sinking an instruction, it sinks its eligible `DBG_VALUE`s with it, but
also leaves undef `DBG_VALUE`s in the original place to make those
variables' values undefined.

Also, unlike the current version, we sink only an eligible subset of
`DBG_VALUE`s with a def instruction. See comments in the code for
details.

In case of cloning, because the original def is still there, we don't
set its `DBG_VALUE`s to undef. But we clone only an eligible subset of
`DBG_VALUE`s here as well.

One consequence of this change is that now we do sinking and cloning of
the def instruction itself within the `DebugValueManager`'s `sink` and
`clone` methods. This is necessary because the `DebugValueManager` needs
to know the original def's location before sinking and cloning in order
to scan other interfering `DBG_VALUE`s between the original def and the
insertion point. If we want to separate these two, we need to call
`DebugValueManager`'s `sink` and `clone` methods //before//
sinking/cloning the def instruction, which I don't think is a good
design alternative either, because the user of this class needs to pay
extra attention when using it.

Because this change is fixing the existing inaccuracy of the current
debug info, this reduces the variable info coverage in debug info, but
not by a large margin. In Emscripten core benchmarks compiled with
`-O1`, the coverage goes from 56.6% down to 55.2%, which I doubt will be
a noticeable drop. The compilation time doesn't have any meaningful
difference either with this change.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D146744
2023-03-29 12:49:57 -07:00
Heejin Ahn
cfd36aa5b7 [WebAssembly] Use ArrayRef/SmallVectorImpl in parameters (NFC)
It is recommended to use `SmallVectorImpl`/`ArrayRef` over
`SmallVector<TypeName, N>` for function parameters:
https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D146841
2023-03-29 12:48:23 -07:00
Heejin Ahn
d91c9aef9b [WebAssembly] Select call_indirect for alloca calls
Currently calling stack locations is selected using `CALL` in ISel,
resulting in an invalid code and crashing in AsmPrinter. FastISel
correctly selects it will `CALL_INDIRECT`.

Fixes the problem reported in D146781.

Reviewed By: tlively, HerrCai0907

Differential Revision: https://reviews.llvm.org/D147033
2023-03-29 12:46:58 -07:00
Heejin Ahn
999643f151 [WebAssembly] Tidy up DebugValueManager (NFC)
Misc. cleanups for `WebAssemblyDebugValueManager`.
- Use `Register` for registers
- Simpler for loop iteration
- Rename a variable
- Reorder methods
- Reduce `SmallVector` size for `DBG_VALUE`s to 1; one def usually have
  a single `DBG_VALUE` attached to it in most cases
- Add a few more lines of comments

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D146743
2023-03-23 15:35:26 -07:00
Thomas Lively
dd0bbae5ef [WebAssembly] Fix epilogue insertion for indirect tail calls
Previously epilogues were incorrectly inserted after indirect tail calls because
they did not have the `isTerminator` property. Add that property and test that
they get correct epilogues. To be safe, also add other properties that were
defined for direct tail calls.

Differential Revision: https://reviews.llvm.org/D146569
2023-03-22 09:28:48 -07:00
Congcong Cai
696fdece49 [WebAssembly] Fix i64_i64_func_i64_i64_i32 type signature when multivalue feature is enabled
Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D146533
2023-03-22 06:53:54 +08:00
Congcong Cai
ec2a726a63 [Webassembly][multivalue] update libcall signature for f128 when multivalue feature enabled
further update for [D146271](https://reviews.llvm.org/D146271)

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D146499
2023-03-22 00:16:29 +08:00
Congcong Cai
ff937a82f1 [Webassembly][NFC] Fix typo in comment 2023-03-21 13:20:46 +08:00
Congcong Cai
d9661d79f4 [Webassembly][multivalue] update libcall signature when multivalue feature enabled
fixed: #59095
Update libcall signatures to use multivalue return rather than returning via a pointer
when the multivalue features is enabled in the WebAssembly backend.

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D146271
2023-03-21 12:10:51 +08:00
Heejin Ahn
6d33affac0 [WebAssembly] Add comments on local.tee transformation
We have a good comment on `TEE` transformation in `RegStackify`:
547e345666/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp (L613-L632)

And I think it can be helpful to have some more comments on how the
`TEE`s created in `RegStackify` are converted into `LOCAL_TEE`s.

Variable `OldReg` is changed to `DefReg` to be consistent with
`RegStackify`'s comment.

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D146084
2023-03-17 20:16:16 -07:00
Heejin Ahn
4f2401f4f9 [WebAssembly] Use MachineInstr::setDebugValueUndef
When making `DBG_VALUE`/`DBG_VALUE_LIST` instructions undefined, there
is a method that takes care of it so we don't need to do it manually.
This changes the test because previously we are converting
`DBG_VALUE_LIST`s into `DBG_VALUE $noreg` but now we leave
`DBG_VALUE_LIST` but set it to undef by turning all its register
operands `$noreg`. The effect is the same.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D145998
2023-03-17 20:15:01 -07:00
Heejin Ahn
4e844a1498 [WebAssembly] Replace Bugzilla links with Github issues
Reviewed By: dschuff, asb

Differential Revision: https://reviews.llvm.org/D145966
2023-03-17 20:13:00 -07:00
Kazu Hirata
398af9b43b [llvm] Use *{Map,Set}::contains (NFC) 2023-03-15 18:06:32 -07:00
Kazu Hirata
7ada7bbee1 [Target] Use *{Set,Map}::contains (NFC) 2023-03-14 18:06:55 -07:00
Jun Ma
403926aefe [WebAssembly] Skip implied bitmask operation in LowerShift
This patch skips redundant explicit masks of the shift count since
it is implied inside wasm shift instruction.

Differential Revision: https://reviews.llvm.org/D144619
2023-03-02 09:37:25 +08:00
Craig Topper
fffbfe7c0c [WebAssembly] Split WebAssemblyUtils to fix library layering for MC tools.
WebAssemblyUtils depends on CodeGen which depends on all middle end
optimization libraries.

This component is used by WebAssembly's AsmParser, Disassembler, and
MCTargetDesc libraries. Because of this, any MC layer tool built with
WebAssembly support includes a larger portion of LLVM than it should.

To fix this I've created an MC only version of WebAssemblyTypeUtilities.cpp
in MCTargetDesc to be used by the MC components.

This shrinks llvm-objdump and llvm-mc on my local release+asserts
build by 5-6 MB.

Reviewed By: MaskRay, aheejin

Differential Revision: https://reviews.llvm.org/D144354
2023-02-23 23:25:23 -08:00
Samuel Parker
28ee604071 [WebAssembly] pmin/pmax fixes
Reverse the operand ordering to ? rhs : lhs.

Differential Revision: https://reviews.llvm.org/D144466
2023-02-22 10:02:16 +00:00
Jun Ma
e9d7f96a11 [WebAssembly] Add more combine pattern for vector shift
After change with D144169, the codegen generates redundant instructions
like and and wrap. This fixes it.

Differential Revision: https://reviews.llvm.org/D144360
2023-02-22 09:53:00 +08:00
Paulo Matos
890146b192 [WebAssembly] Initial support for reference type externref in clang
This patch introduces a new type __externref_t that denotes a WebAssembly opaque
reference type. It also implements builtin __builtin_wasm_ref_null_extern(),
that returns a null value of __externref_t. This lays the ground work
for further builtins and reference types.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D122215
2023-02-17 18:48:48 -08:00
Samuel Parker
a674a12dd5 [WebAssembly] Additional patterns for pmin/pax
Each operation was missing their inverted condition using olt or ogt.
Also, as we don't need to discern +/-0, I think we should also be
able to use ole and oge.

Differential Revision: https://reviews.llvm.org/D143581
2023-02-10 09:54:45 +00:00
Archibald Elliott
62c7f035b4 [NFC][TargetParser] Remove llvm/ADT/Triple.h
I also ran `git clang-format` to get the headers in the right order for
the new location, which has changed the order of other headers in two
files.
2023-02-07 12:39:46 +00:00
Jay Foad
a07584d57d [CodeGen] Make more use of MachineOperand::getOperandNo. NFC.
Differential Revision: https://reviews.llvm.org/D143252
2023-02-07 11:50:57 +00:00
Vitaly Buka
bccf5999d3 Revert "[clang][WebAssembly] Initial support for reference type externref in clang"
Very likely breaks stage 3 of msan build bot.
Good: 764c88a50ac76a2df2d051a0eb5badc6867aabb6 https://lab.llvm.org/buildbot/#/builders/74/builds/17058
Looks unrelated: 48b5a06dfcab12cf093a1a3df42cb5b684e2be4c
Bad: 48b5a06dfcab12cf093a1a3df42cb5b684e2be4c https://lab.llvm.org/buildbot/#/builders/74/builds/17059

This reverts commit eb66833d19573df97034a81279eda31b8d19815b.
2023-02-05 21:41:48 -08:00
Paulo Matos
eb66833d19 [clang][WebAssembly] Initial support for reference type externref in clang
This patch introduces a new type __externref_t that denotes a WebAssembly opaque
reference type. It also implements builtin __builtin_wasm_ref_null_extern(),
that returns a null value of __externref_t. This lays the ground work
for further builtins and reference types.

Differential Revision: https://reviews.llvm.org/D122215
2023-01-31 17:34:01 +01:00
Jay Foad
768aed1378 [MC] Make more use of MCInstrDesc::operands. NFC.
Change MCInstrDesc::operands to return an ArrayRef so we can easily use
it everywhere instead of the (IMHO ugly) opInfo_begin and opInfo_end.
A future patch will remove opInfo_begin and opInfo_end.

Also use it instead of raw access to the OpInfo pointer. A future patch
will remove this pointer.

Differential Revision: https://reviews.llvm.org/D142213
2023-01-23 11:31:41 +00:00
ShihPo Hung
5fb3a57ea7 [Cost] Add CostKind to getVectorInstrCost and its related users
LoopUnroll estimates the loop size via getInstructionCost(),
but getInstructionCost() cannot pass CostKind to getVectorInstrCost().
And so does getShuffleCost() to getBroadcastShuffleOverhead(),
getPermuteShuffleOverhead(), getExtractSubvectorOverhead(),
and getInsertSubvectorOverhead().

To address this, this patch adds an argument CostKind to these
functions.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D142116
2023-01-21 05:29:24 -08:00
Sergei Barannikov
6ae84d668f [MC] Use MCRegister instead of unsigned in MCInstPrinter (NFC)
Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D140654
2023-01-17 22:39:39 +03:00
Craig Topper
79858d1908 [CodeGen][Target] Remove uses of Register::isPhysicalRegister/isVirtualRegister. NFC
Use isPhysical/isVirtual methods.
2023-01-13 23:12:48 -08:00
Dominik Adamski
6809af1a23 Revert "[OpenMP][OMPIRBuilder] Move SIMD alignment calculation to LLVM Frontend"
This reverts commit ed01de67433174d3157e9d239d59dd465d52c6a5.
2023-01-13 14:38:17 -06:00
Dominik Adamski
ed01de6743 [OpenMP][OMPIRBuilder] Move SIMD alignment calculation to LLVM Frontend
Currently default simd alignment is specified by Clang specific TargetInfo
class. This class cannot be reused for LLVM Flang. If we move the default
alignment field into TargetMachine class then we can create TargetMachine
objects and query them to find SIMD alignment.

Scope of changes:
  1) Added information about maximal allowed SIMD alignment to TargetMachine
     classes.
  2) Removed getSimdDefaultAlign function from Clang TargetInfo class.
  3) Refactored createTargetMachine function.

Reviewed By: jsjodin

Differential Revision: https://reviews.llvm.org/D138496
2023-01-13 14:07:29 -06:00
Heejin Ahn
d198c75e5a [WebAssembly][LiveDebugValues] Handle target index defs
This adds the missing handling for defs for target index operands, as is
already done for registers.

There are two kinds of target indices: local indices and stack operands.

- Locals are something similar to registers in Wasm-land. For local
  indices, we can check for local-defining instructions (`local.set` or
  `local.tee`).

- Wasm is a stack machine, so we have values in certain Wasm value stack
  location, which change when Wasm instructions produce or consume
  values. So basically any value-producing instrucion, i.e., instruction
  with defs, can change values in the Wasm stack. But I think we don't
  need to worry about this here, because `WebAssemblyDebugFixup`, which
  runs right before this analysis, makes sure to insert terminating
  `DBG_VALUE $noreg` instructions whenever a stack value gets popped.
  After `WebAssemblyDebugFixup`, there shouldn't be any `DBG_VALUE`s for
  stack operands that don't have a terminating `DBG_VALUE $noreg` within
  the same BB.

So this CL only works on `DBG_VALUE`s for locals. When we encounter a
`local.set` or `local.tee` instructions, we delete `DBG_VALUE`s for
those target index locations from the open range set, so they will not
be availble in `OutLocs`. For example,
```
bb.0:
  successors: %bb.1
  DBG_VALUE target-index(wasm-local) + 2, $noreg, "var", ...
  ...
  local.set 2 ...

bb.1:
; predecessors: %bb.0
  ; We shouldn't add `DBG_VALUE target (wasm-local) + 2 here because
  ; it was killed by 'local.set' in bb.0
```

After disabling register coalescing at -O1, the average PC ranges
covered for Emscripten core benchmarks is currently 20.6% in the LLVM
tot. After applying D138943 and this CL, the coverage goes up to 57%.
This also enables LiveDebugValues analysis in the Wasm pipeline by
default.

Reviewed By: dschuff, jmorse

Differential Revision: https://reviews.llvm.org/D140373
2023-01-10 09:56:25 -08:00
Heejin Ahn
78f01f69b3 [WebAssembly] Ensure 'end_function' in functions
Local info is supposed to be emitted in the start of every function.
When there are locals, `.local` section should be present, and we emit
local info according to the section.

If there is no locals, empty local info should be emitted. This empty
local info is emitted whenever a first instruction is emitted within a
function without encountering a `.local` section. If there is no
instruction, `end_function` pseudo instruction should be present and the
empty local info will be emitted when parsing the pseudo instruction.

The following assembly is malformed because the function `test` doesn't
have an `end_function` at the end, and the parser doesn't end up
emitting the empty local info needed. But currently we don't error out
and silently produce an invalid binary.
```
.functype test () -> ()
test:
```

This patch adds one extra state to the Wasm assembly parser,
`FunctionLabel` to detect whether a function label is parsed but not
ended properly when the next function starts or the file ends.

It is somewhat tricky to distinguish `FunctionLabel` and
`FunctionStart`, because it is not always possible to ensure the state
goes from `FunctionLabel` -> `FunctionStart`. `.functype` directive does
not seem to be mandated before a function label, in which case we don't
know if the label is a function at the time of parsing. But when we do
know the label is function, we would like to ensure it ends with an
`end_function` properly. Also we would like to error out when it does
not.

For example,
```
.functype test() -> ()
test:
```
We should error out for this because we know `test` is a function and it
doesn't end with an `end_function`. This PR fixes this.

```
test:
```
We don't error out for this because there is no info that `test` is a
function, so we don't know whether there should be an `end_function` or
not.

```
test:
.functype test() -> ()
```
We error out for this currently already, because we currently switch to
`FunctionStart` state when we first see `.functype` directive after its
label definition.

Fixes https://github.com/llvm/llvm-project/issues/57427.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D141103
2023-01-09 11:09:35 -08:00
Alexey Bataev
9b5f62685a [SLP]Fix cost of the broadcast buildvector/gather.
Need to include the cost of the initial insertelement to the cost of the
broadcasts. Also, need to adjust the cost of the gather/buildvector if
the element is inserted into poison/undef vector.

Differential Revision: https://reviews.llvm.org/D140498
2023-01-06 09:25:05 -08:00