[gn build] Port 077cc3deeebe
[llvm-project.git] / llvm / lib / Target / WebAssembly / WebAssemblySelectionDAGInfo.cpp
blob6f37dab409534987309c1c47b715f37195444f3d
1 //===-- WebAssemblySelectionDAGInfo.cpp - WebAssembly SelectionDAG Info ---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements the WebAssemblySelectionDAGInfo class.
11 ///
12 //===----------------------------------------------------------------------===//
14 #include "WebAssemblyTargetMachine.h"
15 using namespace llvm;
17 #define DEBUG_TYPE "wasm-selectiondag-info"
19 WebAssemblySelectionDAGInfo::~WebAssemblySelectionDAGInfo() = default; // anchor
21 SDValue WebAssemblySelectionDAGInfo::EmitTargetCodeForMemcpy(
22 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Src,
23 SDValue Size, Align Alignment, bool IsVolatile, bool AlwaysInline,
24 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
25 auto &ST = DAG.getMachineFunction().getSubtarget<WebAssemblySubtarget>();
26 if (!ST.hasBulkMemoryOpt())
27 return SDValue();
29 SDValue MemIdx = DAG.getConstant(0, DL, MVT::i32);
30 auto LenMVT = ST.hasAddr64() ? MVT::i64 : MVT::i32;
32 // Use `MEMCPY` here instead of `MEMORY_COPY` because `memory.copy` traps
33 // if the pointers are invalid even if the length is zero. `MEMCPY` gets
34 // extra code to handle this in the way that LLVM IR expects.
35 return DAG.getNode(
36 WebAssemblyISD::MEMCPY, DL, MVT::Other,
37 {Chain, MemIdx, MemIdx, Dst, Src, DAG.getZExtOrTrunc(Size, DL, LenMVT)});
40 SDValue WebAssemblySelectionDAGInfo::EmitTargetCodeForMemmove(
41 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Op1, SDValue Op2,
42 SDValue Op3, Align Alignment, bool IsVolatile,
43 MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
44 return EmitTargetCodeForMemcpy(DAG, DL, Chain, Op1, Op2, Op3,
45 Alignment, IsVolatile, false,
46 DstPtrInfo, SrcPtrInfo);
49 SDValue WebAssemblySelectionDAGInfo::EmitTargetCodeForMemset(
50 SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Val,
51 SDValue Size, Align Alignment, bool IsVolatile, bool AlwaysInline,
52 MachinePointerInfo DstPtrInfo) const {
53 auto &ST = DAG.getMachineFunction().getSubtarget<WebAssemblySubtarget>();
54 if (!ST.hasBulkMemoryOpt())
55 return SDValue();
57 SDValue MemIdx = DAG.getConstant(0, DL, MVT::i32);
58 auto LenMVT = ST.hasAddr64() ? MVT::i64 : MVT::i32;
60 // Use `MEMSET` here instead of `MEMORY_FILL` because `memory.fill` traps
61 // if the pointers are invalid even if the length is zero. `MEMSET` gets
62 // extra code to handle this in the way that LLVM IR expects.
64 // Only low byte matters for val argument, so anyext the i8
65 return DAG.getNode(WebAssemblyISD::MEMSET, DL, MVT::Other, Chain, MemIdx, Dst,
66 DAG.getAnyExtOrTrunc(Val, DL, MVT::i32),
67 DAG.getZExtOrTrunc(Size, DL, LenMVT));