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:
parent
a27afd3444
commit
dd6cadae89
@ -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"
|
||||
|
@ -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>;
|
||||
|
@ -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(
|
||||
|
28
test/CodeGen/WebAssembly/bulk-memory-intrinsics.ll
Normal file
28
test/CodeGen/WebAssembly/bulk-memory-intrinsics.ll
Normal 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
|
||||
}
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user