1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[WebAssembly] Bulk memory intrinsics and builtins

Summary:
implements llvm intrinsics and clang intrinsics for
memory.init and data.drop.

Reviewers: aheejin

Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57736

llvm-svn: 353983
This commit is contained in:
Thomas Lively 2019-02-13 22:11:16 +00:00
parent a27afd3444
commit dd6cadae89
5 changed files with 102 additions and 33 deletions

View File

@ -110,4 +110,18 @@ def int_wasm_alltrue :
[llvm_anyvector_ty],
[IntrNoMem, IntrSpeculatable]>;
//===----------------------------------------------------------------------===//
// Bulk memory intrinsics
//===----------------------------------------------------------------------===//
def int_wasm_memory_init :
Intrinsic<[],
[llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
[IntrWriteMem, IntrInaccessibleMemOrArgMemOnly, WriteOnly<2>,
IntrHasSideEffects]>;
def int_wasm_data_drop :
Intrinsic<[],
[llvm_i32_ty],
[IntrNoDuplicate, IntrHasSideEffects]>;
} // TargetPrefix = "wasm"

View File

@ -21,19 +21,48 @@ multiclass BULK_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
}
// Bespoke types and nodes for bulk memory ops
def wasm_memcpy_t : SDTypeProfile<0, 3,
[SDTCisPtrTy<0>, SDTCisPtrTy<1>, SDTCisInt<2>]
def wasm_memcpy_t : SDTypeProfile<0, 5,
[SDTCisInt<0>, SDTCisInt<1>, SDTCisPtrTy<2>, SDTCisPtrTy<3>, SDTCisInt<4>]
>;
def wasm_memcpy : SDNode<"WebAssemblyISD::MEMORY_COPY", wasm_memcpy_t,
[SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
//===----------------------------------------------------------------------===//
// memory.init
//===----------------------------------------------------------------------===//
let mayStore = 1 in
defm MEMORY_INIT :
BULK_I<(outs),
(ins i32imm_op:$seg, i32imm_op:$idx, I32:$dest,
I32:$offset, I32:$size),
(outs), (ins i32imm_op:$seg, i32imm_op:$idx),
[(int_wasm_memory_init (i32 imm:$seg), (i32 imm:$idx), I32:$dest,
I32:$offset, I32:$size
)],
"memory.init\t$seg, $idx, $dest, $offset, $size",
"memory.init\t$seg, $idx", 0x08>;
//===----------------------------------------------------------------------===//
// data.drop
//===----------------------------------------------------------------------===//
defm DATA_DROP :
BULK_I<(outs), (ins i32imm_op:$seg), (outs), (ins i32imm_op:$seg),
[(int_wasm_data_drop (i32 imm:$seg))],
"data.drop\t$seg", "data.drop\t$seg", 0x09>;
//===----------------------------------------------------------------------===//
// memory.copy
//===----------------------------------------------------------------------===//
let mayLoad = 1, mayStore = 1 in
defm MEMORY_COPY : BULK_I<(outs), (ins I32:$dst, I32:$src, I32:$len),
(outs), (ins),
[(wasm_memcpy I32:$dst, I32:$src, I32:$len)],
"memory.copy\t$dst, $src, $len",
"memory.copy", 0x0a>;
defm MEMORY_COPY :
BULK_I<(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx,
I32:$dst, I32:$src, I32:$len),
(outs), (ins i32imm_op:$src_idx, i32imm_op:$dst_idx),
[(wasm_memcpy (i32 imm:$src_idx), (i32 imm:$dst_idx),
I32:$dst, I32:$src, I32:$len
)],
"memory.copy\t$src_idx, $dst_idx, $dst, $src, $len",
"memory.copy\t$src_idx, $dst_idx", 0x0a>;

View File

@ -19,16 +19,18 @@ using namespace llvm;
WebAssemblySelectionDAGInfo::~WebAssemblySelectionDAGInfo() = default; // anchor
SDValue WebAssemblySelectionDAGInfo::EmitTargetCodeForMemcpy(
SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Op1, SDValue Op2,
SDValue Op3, unsigned Align, bool IsVolatile, bool AlwaysInline,
SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, SDValue Src,
SDValue Size, unsigned Align, bool IsVolatile, bool AlwaysInline,
MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
if (!DAG.getMachineFunction()
.getSubtarget<WebAssemblySubtarget>()
.hasBulkMemory())
return SDValue();
return DAG.getNode(WebAssemblyISD::MEMORY_COPY, DL, MVT::Other, Chain, Op1,
Op2, Op3);
SDValue MemIdx = DAG.getConstant(0, DL, MVT::i32);
return DAG.getNode(WebAssemblyISD::MEMORY_COPY, DL, MVT::Other,
{Chain, MemIdx, MemIdx, Dst, Src,
DAG.getZExtOrTrunc(Size, DL, MVT::i32)});
}
SDValue WebAssemblySelectionDAGInfo::EmitTargetCodeForMemmove(

View File

@ -0,0 +1,28 @@
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+bulk-memory | FileCheck %s
; Test that bulk memory intrinsics lower correctly
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: memory_init:
; CHECK-NEXT: .functype memory_init (i32, i32, i32) -> ()
; CHECK-NEXT: memory.init 3, 0, $0, $1, $2
; CHECK-NEXT: return
declare void @llvm.wasm.memory.init(i32, i32, i8*, i32, i32)
define void @memory_init(i8* %dest, i32 %offset, i32 %size) {
call void @llvm.wasm.memory.init(
i32 3, i32 0, i8* %dest, i32 %offset, i32 %size
)
ret void
}
; CHECK-LABEL: data_drop:
; CHECK-NEXT: .functype data_drop () -> ()
; CHECK-NEXT: data.drop 3
; CHECK-NEXT: return
declare void @llvm.wasm.data.drop(i32)
define void @data_drop() {
call void @llvm.wasm.data.drop(i32 3)
ret void
}

View File

@ -6,40 +6,39 @@
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
declare void @llvm.memcpy.p0i8.p0i8.i8(i8*, i8*, i8, i1)
declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
declare void @llvm.memcpy.p0i32.p0i32.i32(i32*, i32*, i32, i1)
declare void @llvm.memmove.p0i8.p0i8.i8(i8*, i8*, i8, i1)
declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i1)
declare void @llvm.memmove.p0i32.p0i32.i32(i32*, i32*, i32, i1)
; CHECK-LABEL: memcpy_i8:
; NO-BULK-MEM-NOT: memory.copy
; BULK-MEM-NEXT: .functype memcpy_i8 (i32, i32, i32) -> ()
; BULK-MEM-NEXT: memory.copy $0, $1, $2
; BULK-MEM-NEXT: memory.copy 0, 0, $0, $1, $2
; BULK-MEM-NEXT: return
declare void @llvm.memcpy.p0i8.p0i8.i32(
i8* %dest, i8* %src, i32 %len, i1 %volatile
)
define void @memcpy_i8(i8* %dest, i8* %src, i32 %len) {
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 0)
define void @memcpy_i8(i8* %dest, i8* %src, i8 zeroext %len) {
call void @llvm.memcpy.p0i8.p0i8.i8(i8* %dest, i8* %src, i8 %len, i1 0)
ret void
}
; CHECK-LABEL: memmove_i8:
; NO-BULK-MEM-NOT: memory.copy
; BULK-MEM-NEXT: .functype memmove_i8 (i32, i32, i32) -> ()
; BULK-MEM-NEXT: memory.copy $0, $1, $2
; BULK-MEM-NEXT: memory.copy 0, 0, $0, $1, $2
; BULK-MEM-NEXT: return
declare void @llvm.memmove.p0i8.p0i8.i32(
i8* %dest, i8* %src, i32 %len, i1 %volatile
)
define void @memmove_i8(i8* %dest, i8* %src, i32 %len) {
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 0)
define void @memmove_i8(i8* %dest, i8* %src, i8 zeroext %len) {
call void @llvm.memmove.p0i8.p0i8.i8(i8* %dest, i8* %src, i8 %len, i1 0)
ret void
}
; CHECK-LABEL: memcpy_i32:
; NO-BULK-MEM-NOT: memory.copy
; BULK-MEM-NEXT: .functype memcpy_i32 (i32, i32, i32) -> ()
; BULK-MEM-NEXT: memory.copy $0, $1, $2
; BULK-MEM-NEXT: memory.copy 0, 0, $0, $1, $2
; BULK-MEM-NEXT: return
declare void @llvm.memcpy.p0i32.p0i32.i32(
i32* %dest, i32* %src, i32 %len, i1 %volatile
)
define void @memcpy_i32(i32* %dest, i32* %src, i32 %len) {
call void @llvm.memcpy.p0i32.p0i32.i32(i32* %dest, i32* %src, i32 %len, i1 0)
ret void
@ -48,11 +47,8 @@ define void @memcpy_i32(i32* %dest, i32* %src, i32 %len) {
; CHECK-LABEL: memmove_i32:
; NO-BULK-MEM-NOT: memory.copy
; BULK-MEM-NEXT: .functype memmove_i32 (i32, i32, i32) -> ()
; BULK-MEM-NEXT: memory.copy $0, $1, $2
; BULK-MEM-NEXT: memory.copy 0, 0, $0, $1, $2
; BULK-MEM-NEXT: return
declare void @llvm.memmove.p0i32.p0i32.i32(
i32* %dest, i32* %src, i32 %len, i1 %volatile
)
define void @memmove_i32(i32* %dest, i32* %src, i32 %len) {
call void @llvm.memmove.p0i32.p0i32.i32(i32* %dest, i32* %src, i32 %len, i1 0)
ret void
@ -82,7 +78,7 @@ define void @memmove_1(i8* %dest, i8* %src) {
; NO-BULK-MEM-NOT: memory.copy
; BULK-MEM-NEXT: .functype memcpy_1024 (i32, i32) -> ()
; BULK-MEM-NEXT: i32.const $push[[L0:[0-9]+]]=, 1024
; BULK-MEM-NEXT: memory.copy $0, $1, $pop[[L0]]
; BULK-MEM-NEXT: memory.copy 0, 0, $0, $1, $pop[[L0]]
; BULK-MEM-NEXT: return
define void @memcpy_1024(i8* %dest, i8* %src) {
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1024, i1 0)
@ -93,7 +89,7 @@ define void @memcpy_1024(i8* %dest, i8* %src) {
; NO-BULK-MEM-NOT: memory.copy
; BULK-MEM-NEXT: .functype memmove_1024 (i32, i32) -> ()
; BULK-MEM-NEXT: i32.const $push[[L0:[0-9]+]]=, 1024
; BULK-MEM-NEXT: memory.copy $0, $1, $pop[[L0]]
; BULK-MEM-NEXT: memory.copy 0, 0, $0, $1, $pop[[L0]]
; BULK-MEM-NEXT: return
define void @memmove_1024(i8* %dest, i8* %src) {
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1024, i1 0)