summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
AgeCommit message (Collapse)Author
2025-07-01[WebAssembly] Fold any/alltrue (setcc x, 0, eq/ne) to [not] any/alltrue x ↵jjasmine
(#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[WebAssembly] [Backend] Wasm optimize illegal bitmask (#145627)jjasmine
[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-06-25[WebAssembly] Refactor PerformSETCCCombine (#144875)Sam Parker
Extract the logic into a templated helper function.
2025-06-16WebAssembly: Move runtime libcall setting out of TargetLowering (#142624)Matt Arsenault
RuntimeLibcallInfo needs to be correct outside of codegen contexts.
2025-05-18[llvm] Remove unused local variables (NFC) (#140422)Kazu Hirata
2025-05-01[Target] Use llvm::max_element (NFC) (#137926)Kazu Hirata
2025-03-31[WebAssembly] Add a missing `break` statement (#133783)Alex Crichton
This fixes an issue introduced in #132430 where a `break;` statement was accidentally missing causing unintended fall-through.
2025-03-31[WebAssembly] Add more lowerings for wide-arithmetic (#132430)Alex Crichton
This commit is the result of investigation and discussion on WebAssembly/wide-arithmetic#6 where alternatives to the `i64.add128` instruction were discussed but ultimately deferred to a future proposal. In spite of this though I wanted to apply a few changes to the LLVM backend here with `wide-arithmetic` enabled for a few minor changes: * A lowering for the `ISD::UADDO` node is added which uses `add128` where the upper bits of the two operands are constant zeros and the result of the 128-bit addition is the result of the overflowing addition. * The high bits of a `I64_ADD128` node are now flagged as "known zero" if the upper bits of the inputs are also zero, assisting this `UADDO` lowering to ensure the backend knows that the carry result is a 1-bit result. A few tests were then added to showcase various lowerings for various operations that can be done with wide-arithmetic. They don't all optimize super well at this time but I wanted to add them as a reference here regardless to have them on-hand for future evaluations if necessary.
2025-03-21[WebAssembly] Lower wide SIMD i8 muls (#130785)Sam Parker
Currently, 'wide' i32 simd multiplication, with extended i8 elements, will perform the multiplication with i32 So, for IR like the following: ``` %wide.a = sext <8 x i8> %a to <8 x i32> %wide.b = sext <8 x i8> %a to <8 x i32> %mul = mul <8 x i32> %wide.a, %wide.b ret <8 x i32> %mul ``` We would generate the following sequence: ``` i16x8.extend_low_i8x16_s $push6=, $1 local.tee $push5=, $3=, $pop6 i32x4.extmul_low_i16x8_s $push0=, $pop5, $3 v128.store 0($0), $pop0 i8x16.shuffle $push1=, $1, $1, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 i16x8.extend_low_i8x16_s $push4=, $pop1 local.tee $push3=, $1=, $pop4 i32x4.extmul_low_i16x8_s $push2=, $pop3, $1 v128.store 16($0), $pop2 return ``` But now we perform the multiplication with i16, resulting in: ``` i16x8.extmul_low_i8x16_s $push3=, $1, $1 local.tee $push2=, $1=, $pop3 i32x4.extend_high_i16x8_s $push0=, $pop2 v128.store 16($0), $pop0 i32x4.extend_low_i16x8_s $push1=, $1 v128.store 0($0), $pop1 return ```
2025-02-25[WebAssembly] Use the same lowerings for f16x8 as other float vectors. (#127897)Brendan Dahl
This fixes failures to select the various compare operations that weren't being expanded for f16x8.
2025-02-25[WebAssembly] Support shuffle for F16x8 vectors. (#127857)Brendan Dahl
2025-02-19[CodeGen] Use __extendhfsf2 and __truncsfhf2 by default (#126880)Nikita Popov
The standard libcalls for half to float and float to half conversion are __extendhfsf2 and __truncsfhf2. However, LLVM currently uses __gnu_h2f_ieee and __gnu_f2h_ieee instead. As far as I can tell, these libcalls are an ARM-ism and only provided by libgcc on that platform. compiler-rt always provides both libcalls. Use the standard libcalls by default, and only use the __gnu libcalls on ARM.
2025-02-17[WebAssembly] Recognise EXTEND_HIGH (#123325)Sam Parker
When lowering EXTEND_VECTOR_INREG, check whether the operand is a shuffle that is moving the top half of a vector into the lower half. If so, we can EXTEND_HIGH the input to the shuffle instead.
2025-02-03[WebAssembly] Autovec support for dot (#123207)Sam Parker
Enable the use of partial.reduce.add that we can lower to dot or a tree of (add (extmul_low_u, extmul_high_u)) for the unsigned case. We support both v8i16 and v16i8 inputs.
2025-01-20[Mips] Fix compiler crash when returning fp128 after calling a functi… ↵yingopq
(#117525) …on returning { i8, i128 } Fixes https://github.com/llvm/llvm-project/issues/96432.
2024-12-21[SelectionDAG] Virtualize isTargetStrictFPOpcode / isTargetMemoryOpcode ↵Sergei Barannikov
(#119969) With this change, targets are no longer required to put memory / strict-fp opcodes after special `ISD::FIRST_TARGET_MEMORY_OPCODE`/`ISD::FIRST_TARGET_STRICTFP_OPCODE` markers. This will also allow autogenerating `isTargetMemoryOpcode`/`isTargetStrictFPOpcode (#119709). Pull Request: https://github.com/llvm/llvm-project/pull/119969
2024-12-09Reapply "[DAGCombiner] Add support for scalarising extracts of a vector ↵David Sherwood
setcc (#117566)" (#118823) [Reverts d57892a2a153ab71a796f07e39d939eae6910c21] For IR like this: %icmp = icmp ult <4 x i32> %a, splat (i32 5) %res = extractelement <4 x i1> %icmp, i32 1 where there is only one use of %icmp we can take a similar approach to what we already do for binary ops such add, sub, etc. and convert this into %ext = extractelement <4 x i32> %a, i32 1 %res = icmp ult i32 %ext, 5 For AArch64 targets at least the scalar boolean result will almost certainly need to be in a GPR anyway, since it will probably be used by branches for control flow. I've tried to reuse existing code in scalarizeExtractedBinop to also work for setcc. NOTE: The optimisations don't apply for tests such as extract_icmp_v4i32_splat_rhs in the file CodeGen/AArch64/extract-vector-cmp.ll because scalarizeExtractedBinOp only works if one of the input operands is a constant. --------- Co-authored-by: Paul Walker <paul.walker@arm.com>
2024-12-04Revert "[DAGCombiner] Add support for scalarising extracts of a vector ↵Vitaly Buka
setcc" (#118693) Reverts llvm/llvm-project#117566 Breaks libc++ tests with HWASAN https://lab.llvm.org/buildbot/#/builders/55/builds/3959
2024-12-04[DAGCombiner] Add support for scalarising extracts of a vector setcc (#117566)David Sherwood
For IR like this: %icmp = icmp ult <4 x i32> %a, splat (i32 5) %res = extractelement <4 x i1> %icmp, i32 1 where there is only one use of %icmp we can take a similar approach to what we already do for binary ops such add, sub, etc. and convert this into %ext = extractelement <4 x i32> %a, i32 1 %res = icmp ult i32 %ext, 5 For AArch64 targets at least the scalar boolean result will almost certainly need to be in a GPR anyway, since it will probably be used by branches for control flow. I've tried to reuse existing code in scalarizeExtractedBinop to also work for setcc. NOTE: The optimisations don't apply for tests such as extract_icmp_v4i32_splat_rhs in the file CodeGen/AArch64/extract-vector-cmp.ll because scalarizeExtractedBinOp only works if one of the input operands is a constant.
2024-12-02[WebAssembly] Define call-indirect-overlong and bulk-memory-opt features ↵Dan Gohman
(#117087) This defines some new target features. These are subsets of existing features that reflect implementation concerns: - "call-indirect-overlong" - implied by "reference-types"; just the overlong encoding for the `call_indirect` immediate, and not the actual reference types. - "bulk-memory-opt" - implied by "bulk-memory": just `memory.copy` and `memory.fill`, and not the other instructions in the bulk-memory proposal. This is split out from https://github.com/llvm/llvm-project/pull/112035. --------- Co-authored-by: Heejin Ahn <aheejin@gmail.com>
2024-11-26[WebAssembly] Implement %llvm.thread.pointer intrinsic (#117817)Sam Clegg
We can simply use the `__tls_base` global for this which is guaranteed to be non-zero and unique per thread. Fixes: #117433
2024-11-25Revert "[DAGCombiner] Add support for scalarising extracts of a vector setcc ↵David Sherwood
(#116031)" (#117556) This reverts commit 22ec44f509ff266b581dbb490d7b040473b7c31a.
2024-11-25[DAGCombiner] Add support for scalarising extracts of a vector setcc (#116031)David Sherwood
For IR like this: %icmp = icmp ult <4 x i32> %a, splat (i32 5) %res = extractelement <4 x i1> %icmp, i32 1 where there is only one use of %icmp we can take a similar approach to what we already do for binary ops such add, sub, etc. and convert this into %ext = extractelement <4 x i32> %a, i32 1 %res = icmp ult i32 %ext, 5 For AArch64 targets at least the scalar boolean result will almost certainly need to be in a GPR anyway, since it will probably be used by branches for control flow. I've tried to reuse existing code in scalarizeExtractedBinop to also work for setcc. NOTE: The optimisations don't apply for tests such as extract_icmp_v4i32_splat_rhs in the file CodeGen/AArch64/extract-vector-cmp.ll because scalarizeExtractedBinOp only works if one of the input operands is a constant.
2024-11-15[WebAssembly] Remove unused includes (NFC) (#116318)Kazu Hirata
Identified with misc-include-cleaner.
2024-10-24[WebAssembly] Protect memory.fill and memory.copy from zero-length ranges. ↵Dan Gohman
(#112617) WebAssembly's `memory.fill` and `memory.copy` instructions trap if the pointers are out of bounds, even if the length is zero. This is different from LLVM, which expects that it can call `memcpy` on arbitrary invalid pointers if the length is zero. To avoid spurious traps, branch around `memory.fill` and `memory.copy` when the length is zero. --------- Co-authored-by: Heejin Ahn <aheejin@gmail.com>
2024-10-23[NFC][WebAssembly] Inline var only used in assertion (#113507)Jordan Rupprecht
2024-10-23[WebAssembly] Implement the wide-arithmetic proposal (#111598)Alex Crichton
This commit implements the [wide-arithmetic] proposal which has recently reached phase 2 in the WebAssembly proposals process. The goal here is to implement support in LLVM for emitting these instructions which are gated behind a new feature flag by default. A new `wide-arithmetic` feature flag is introduced which gates these four new instructions from being emitted. Emission of each instruction itself is relatively simple given LLVM's preexisting lowering rules and infrastructure. The main gotcha is that due to the multi-result nature of all of these instructions it needed the lowerings to be implemented in C++ rather than in TableGen. [wide-arithmetic]: https://github.com/WebAssembly/wide-arithmetic
2024-10-09[TTI] NFC: Port TLI.shouldSinkOperands to TTI (#110564)Jeffrey Byrnes
Porting to TTI provides direct access to the instruction cost model, which can enable instruction cost based sinking without introducing code duplication.
2024-09-22[clang][wasm] Replace the target integer sub saturate intrinsics with the ↵Simon Pilgrim
equivalent generic `__builtin_elementwise_sub_sat` intrinsics (#109405) Remove the Intrinsic::wasm_sub_sat_signed/wasm_sub_sat_unsigned entries and just use sub_sat_s/sub_sat_u directly
2024-09-11[WebAssembly] Support BUILD_VECTOR with F16x8. (#108117)Brendan Dahl
Convert BUILD_VECTORS with FP16x8 to I16x8 since there's no FP16 scalar value to intialize v128.const.
2024-09-11[WebAssembly] Add load and store patterns for V8F16. (#108119)Brendan Dahl
2024-08-30[WebAssembly] Add intrinsics to wasm_simd128.h for all FP16 instructions ↵Brendan Dahl
(#106465) Getting this to work required a few additional changes: - Add builtins for any instructions that can't be done with plain C currently. - Add support for the saturating version of fp_to_<s,i>_I16x8. Other vector sizes supported this already. - Support bitcast of f16x8 to v128. Needed to return a __f16x8 as v128_t.
2024-08-27[DataLayout] Change return type of `getStackAlignment` to `MaybeAlign` (#105478)Sergei Barannikov
Currently, `getStackAlignment` asserts if the stack alignment wasn't specified. This makes it inconvenient to use and complicates testing. This change also makes `exceedsNaturalStackAlignment` method redundant.
2024-08-22[WebAssembly] Change half-precision feature name to fp16. (#105434)Brendan Dahl
This better aligns with how the feature is being referred to and what runtimes (V8) are calling it.
2024-08-05[WebAssembly] Fix assertion in LowerBUILD_VECTOR (#101961)Sam Parker
The assertion was failing in the case where we were trying to lower to loadxx_zero, but lane zero was undef.
2024-08-02[WebAssembly] load_zero to initialise build_vector (#100610)Sam Parker
Instead of splatting a single lane, to initialise a build_vector, lower to scalar_to_vector which can be selected to load_zero. Also add load_zero and load_lane patterns for f32x4 and f64x2.
2024-07-17[AArch64] Don't tail call memset if it would convert to a bzero. (#98969)Amara Emerson
Well, not quite that simple. We can tc memset since it returns the first argument but bzero doesn't do that and therefore we can end up miscompiling. This patch also refactors the logic out of isInTailCallPosition() into the callers. As a result memcpy and memmove are also modified to do the same thing for consistency. rdar://131419786
2024-05-30[SelectionDAG] Add an ISD::CLEAR_CACHE node to lower llvm.clear_cache (#93795)Roger Ferrer Ibáñez
The current way of lowering `llvm.clear_cache` is a bit unusual. As suggested by Matt Arsenault we are better off using an ISD node. This change introduces a new `ISD::CLEAR_CACHE`, registers a new libcall by default named `__clear_cache` and the default legalisation is a libcall. This is preparatory work for a custom lowering of `ISD::CLEAR_CACHE` needed by RISC-V on some platforms.
2024-05-28[WebAssembly] Implement all f16x8 binary instructions. (#93360)Brendan Dahl
This reuses most of the code that was created for f32x4 and f64x2 binary instructions and tries to follow how they were implemented. add/sub/mul/div - use regular LL instructions min/max - use the minimum/maximum intrinsic, and also have builtins pmin/pmax - use the wasm.pmax/pmin intrinsics and also have builtins Specified at: https://github.com/WebAssembly/half-precision/blob/29a9b9462c9285d4ccc1a5dc39214ddfd1892658/proposals/half-precision/Overview.md
2024-05-28[WebAssembly] Add exnref type (#93586)Heejin Ahn
This adds (back) the exnref type restored in the new EH proposal adopted in Oct 2023 CG meeting: https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md:x
2024-05-23[WebAssembly] Implement prototype f16x8.splat instruction. (#93228)Brendan Dahl
Adds a builtin and intrinsic for the f16x8.splat instruction. Specified at: https://github.com/WebAssembly/half-precision/blob/29a9b9462c9285d4ccc1a5dc39214ddfd1892658/proposals/half-precision/Overview.md Note: the current spec has f16x8.splat as opcode 0x123, but this is incorrect and will be changed to 0x120 soon.
2024-05-23[WebAssembly] Use 64-bit table when targeting wasm64 (#92042)Sam Clegg
See https://github.com/WebAssembly/memory64/issues/51
2024-05-09[WebAssembly] Implement prototype f32.store_f16 instruction. (#91545)Brendan Dahl
Adds a builtin and intrinsic for the f32.store_f16 instruction. The instruction stores an f32 value as an f16 memory. Specified at: https://github.com/WebAssembly/half-precision/blob/29a9b9462c9285d4ccc1a5dc39214ddfd1892658/proposals/half-precision/Overview.md Note: the current spec has f32.store_f16 as opcode 0xFD0121, but this is incorrect and will be changed to 0xFC31 soon.
2024-05-07[WebAssembly] Implement prototype f32.load_f16 instruction. (#90906)Brendan Dahl
Adds a builtin and intrinsic for the f32.load_f16 instruction. The instruction loads an f16 value from memory and puts it in an f32. Specified at: https://github.com/WebAssembly/half-precision/blob/29a9b9462c9285d4ccc1a5dc39214ddfd1892658/proposals/half-precision/Overview.md Note: the current spec has f32.load_f16 as opcode 0xFD0120, but this is incorrect and will be changed to 0xFC30 soon.
2024-04-23[WebAssembly] Enable multivalue return when multivalue ABI is used (#88492)Heejin Ahn
Multivalue feature of WebAssembly has been standardized for several years now. I think it makes sense to be able to enable it in the feature section by default for our clang/llvm-produced binaries so that the multivalue feature can be used as necessary when necessary within our toolchain and also when running other optimizers (e.g. wasm-opt) after the LLVM code generation. But some WebAssembly toolchains, such as Emscripten, do not provide both mulvalue-returning and not-multivalue-returning versions of libraries. Also allowing the uses of multivalue in the features section does not necessarily mean we generate them whenever we can to the fullest, which is a different code generation / optimization option. So this makes the lowering of multivalue returns conditional on the use of 'experimental-mv' target ABI. This ABI is turned off by default and turned on by passing `-Xclang -target-abi -Xclang experimental-mv` to `clang`, or `-target-abi experimental-mv` to `clang -cc1` or `llc`. But the purpose of this PR is not tying the multivalue lowering to this specific 'experimental-mv'. 'experimental-mv' is just one multivalue ABI we currently have, and it is still experimental, meaning it is not very well optimized or tuned for performance. (e.g. it does not have the limitation of the max number of multivalue-lowered values, which can be detrimental to performance.) We may change the name of this ABI, or improve it, or add a new multivalue ABI in the future. Also I heard that WASI is planning to add their multivalue ABI soon. So the plan is, whenever any one of multivalue ABIs is enabled, we enable the lowering of multivalue returns in the backend. We currently have only 'experimental-mv' in the repo so we only check for that in this PR. Related past discussions: #82714 https://github.com/WebAssembly/tool-conventions/pull/223#issuecomment-2008298652
2024-03-11[NFC] Remove unused parameter from shouldAssumeDSOLocal()Arthur Eubanks
2024-02-28Revert "[WebAssembly] Disable multivalue emission temporarily (#82714)"Heejin Ahn
This reverts commit 6e6bf9f81756ba6655b4eea8dc45469a47f89b39. It turned out the multivalue feature had active outside users and it could cause some disruptions to them, so I'd like to investigate more about the workarounds before doing this.
2024-02-22[WebAssembly] Disable multivalue emission temporarily (#82714)Heejin Ahn
We plan to enable multivalue in the features section soon (#80923) for other reasons, such as the feature having been standardized for many years and other features being developed (e.g. EH) depending on it. This is separate from enabling Clang experimental multivalue ABI (`-Xclang -target-abi -Xclang experimental-mv`), but it turned out we generate some multivalue code in the backend as well if it is enabled in the features section. Given that our backend multivalue generation still has not been much used nor tested, and enabling the feature in the features section can be a separate decision from how much multialue (including none) we decide to generate for now, I'd like to temporarily disable the actual generation of multivalue in our backend. To do that, this adds an internal flag `-wasm-emit-multivalue` that defaults to false. All our existing multivalue tests can use this to test multivalue code. This flag can be removed later when we are confident the multivalue generation is well tested.
2024-01-09[RFC][SelectionDAG] Add and use SDNode::getAsZExtVal() helper (#76710)Alex Bradbury
This follows on from #76708, allowing `cast<ConstantSDNode>(N)->getZExtValue()` to be replaced with just `N->getAsZextVal();` Introduced via `git grep -l "cast<ConstantSDNode>\(.*\).*getZExtValue" | xargs sed -E -i 's/cast<ConstantSDNode>\((.*)\)->getZExtValue/\1->getAsZExtVal/'` and then using `git clang-format` on the result.
2023-10-24[wasm] Don't crash on non-simple value types during shuffle combineBenjamin Kramer
These still exist during the DAGCombine phase.