diff options
| author | Thomas Lively <tlively@google.com> | 2019-02-13 22:11:16 +0000 |
|---|---|---|
| committer | Thomas Lively <tlively@google.com> | 2019-02-13 22:11:16 +0000 |
| commit | de7a0a152648d1a74cf4319920b1848aa00d1ca3 (patch) | |
| tree | 21ac82caba61168452ca310420406cbf99be99ae /llvm | |
| parent | 221c39165da51d0ee1fa3b89433f82a988c3bc3e (diff) | |
| download | bcm5719-llvm-de7a0a152648d1a74cf4319920b1848aa00d1ca3.tar.gz bcm5719-llvm-de7a0a152648d1a74cf4319920b1848aa00d1ca3.zip | |
[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
Diffstat (limited to 'llvm')
5 files changed, 102 insertions, 33 deletions
diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td index 874465e4a02..bfeb7063ced 100644 --- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -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" diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrBulkMemory.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrBulkMemory.td index 4642236366e..646b16cf7bf 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrBulkMemory.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrBulkMemory.td @@ -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>; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp index 04be3d7d21e..34d93ecafce 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblySelectionDAGInfo.cpp @@ -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( diff --git a/llvm/test/CodeGen/WebAssembly/bulk-memory-intrinsics.ll b/llvm/test/CodeGen/WebAssembly/bulk-memory-intrinsics.ll new file mode 100644 index 00000000000..dfb74b78f64 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/bulk-memory-intrinsics.ll @@ -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 +} diff --git a/llvm/test/CodeGen/WebAssembly/bulk-memory.ll b/llvm/test/CodeGen/WebAssembly/bulk-memory.ll index acece86b7b1..68ce3e40fa3 100644 --- a/llvm/test/CodeGen/WebAssembly/bulk-memory.ll +++ b/llvm/test/CodeGen/WebAssembly/bulk-memory.ll @@ -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) |

