diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td --- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -44,6 +44,12 @@ def int_wasm_table_grow : Intrinsic<[llvm_i32_ty], [llvm_table_ty, llvm_anyref_ty, llvm_i32_ty], []>; +def int_wasm_table_fill : Intrinsic<[], + [llvm_table_ty, llvm_i32_ty, llvm_anyref_ty, llvm_i32_ty], + []>; +def int_wasm_table_copy : Intrinsic<[], + [llvm_table_ty, llvm_table_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + []>; //===----------------------------------------------------------------------===// // Trapping float-to-int conversions diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td @@ -46,7 +46,7 @@ defm TABLE_FILL_#rc : I<(outs), (ins table32_op:$table, I32:$i, rc:$val, I32:$n), (outs), (ins table32_op:$table), - [], + [(int_wasm_table_fill (WebAssemblyWrapper tglobaladdr:$table), I32:$i, rc:$val, I32:$n)], "table.fill\t$table, $i, $val, $n", "table.fill\t$table", 0xfc11>; @@ -80,7 +80,9 @@ defm TABLE_COPY : I<(outs), (ins table32_op:$table1, table32_op:$table2, I32:$d, I32:$s, I32:$n), (outs), (ins table32_op:$table1, table32_op:$table2), - [], + [(int_wasm_table_copy (WebAssemblyWrapper tglobaladdr:$table1), + (WebAssemblyWrapper tglobaladdr:$table2), + I32:$d, I32:$s, I32:$n)], "table.copy\t$table1, $table2, $d, $s, $n", "table.copy\t$table1, $table2", 0xfc0e>, diff --git a/llvm/test/CodeGen/WebAssembly/table-copy.ll b/llvm/test/CodeGen/WebAssembly/table-copy.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/table-copy.ll @@ -0,0 +1,25 @@ +; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s + +%extern = type opaque +%externref = type %extern addrspace(10)* ;; addrspace 10 is nonintegral + +@externref_table1 = local_unnamed_addr addrspace(1) global [0 x %externref] undef +@externref_table2 = local_unnamed_addr addrspace(1) global [0 x %externref] undef + +declare void @llvm.wasm.table.copy(i8 addrspace(1)*, i8 addrspace(1)*, i32, i32, i32) nounwind readonly + +define void @table_copy(i32 %dst, i32 %src, i32 %len) { +; CHECK-LABEL: table_copy: +; CHECK-NEXT: .functype table_copy (i32, i32, i32) -> () +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: local.get 2 +; CHECK-NEXT: table.copy externref_table1, externref_table2 +; CHECK-NEXT: end_function + %tableptr1 = getelementptr [0 x %externref], [0 x %externref] addrspace(1)* @externref_table1, i32 0, i32 0 + %tb1 = bitcast %externref addrspace(1)* %tableptr1 to i8 addrspace(1)* + %tableptr2 = getelementptr [0 x %externref], [0 x %externref] addrspace(1)* @externref_table2, i32 0, i32 0 + %tb2 = bitcast %externref addrspace(1)* %tableptr2 to i8 addrspace(1)* + call void @llvm.wasm.table.copy(i8 addrspace(1)* %tb1, i8 addrspace(1)* %tb2, i32 %dst, i32 %src, i32 %len) + ret void +} diff --git a/llvm/test/CodeGen/WebAssembly/table-fill.ll b/llvm/test/CodeGen/WebAssembly/table-fill.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/table-fill.ll @@ -0,0 +1,22 @@ +; RUN: llc --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types < %s | FileCheck %s + +%extern = type opaque +%externref = type %extern addrspace(10)* ;; addrspace 10 is nonintegral + +@externref_table = local_unnamed_addr addrspace(1) global [0 x %externref] undef + +declare void @llvm.wasm.table.fill.externref(i8 addrspace(1)*, i32, %externref, i32) nounwind readonly + +define void @table_fill(i32 %start, i32 %len, %externref %val) { +; CHECK-LABEL: table_fill: +; CHECK-NEXT: .functype table_fill (i32, i32, externref) -> () +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 2 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: table.fill externref_table +; CHECK-NEXT: end_function + %tableptr = getelementptr [0 x %externref], [0 x %externref] addrspace(1)* @externref_table, i32 0, i32 0 + %tb = bitcast %externref addrspace(1)* %tableptr to i8 addrspace(1)* + call void @llvm.wasm.table.fill.externref(i8 addrspace(1)* %tb, i32 %start, %externref %val, i32 %len) + ret void +}