[WebAssembly] Allow multivalue types in block signature operands

Summary:
Renames `ExprType` to the more apt `BlockType` and adds a variant for
multivalue blocks. Currently non-void blocks are only generated at the
end of functions where the block return type needs to agree with the
function return type, and that remains true for multivalue
blocks. That invariant means that the actual signature does not need
to be stored in the block signature `MachineOperand` because it can be
inferred by `WebAssemblyMCInstLower` from the return type of the
parent function. `WebAssemblyMCInstLower` continues to lower block
signature operands to immediates when possible but lowers multivalue
signatures to function type symbols. The AsmParser and Disassembler
are updated to handle multivalue block types as well.

Reviewers: aheejin, dschuff, aardappel

Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374933 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Thomas Lively
2019-10-15 18:28:22 +00:00
parent 06d4c0251f
commit 569d5dbe57
15 changed files with 181 additions and 117 deletions
+19 -5
View File
@@ -1,7 +1,7 @@
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+multivalue | FileCheck %s
; Test that the multivalue attribute is accepted
; TODO(tlively): implement multivalue
; Test that the multivalue returns, function types, and block types
; work as expected.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
@@ -10,19 +10,33 @@ target triple = "wasm32-unknown-unknown"
%packed_pair = type <{ i32, i32 }>
; CHECK-LABEL: pair_ident:
; CHECK-NEXT: pair_ident (i32, i32) -> (i32, i32)
; CHECK-NEXT: .functype pair_ident (i32, i32) -> (i32, i32)
; CHECK-NEXT: return $0, $1{{$}}
define %pair @pair_ident(%pair %p) {
ret %pair %p
}
; CHECK-LABEL: packed_pair_ident:
; CHECK-NEXT: packed_pair_ident (i32, i32) -> (i32, i32)
; CHECK-nEXT: return $0, $1{{$}}
; CHECK-NEXT: .functype packed_pair_ident (i32, i32) -> (i32, i32)
; CHECK-NEXT: return $0, $1{{$}}
define %packed_pair @packed_pair_ident(%packed_pair %p) {
ret %packed_pair %p
}
; CHECK-LABEL: minimal_loop:
; CHECK-NEXT: .functype minimal_loop (i32) -> (i32, i64)
; CHECK-NEXT: .LBB{{[0-9]+}}_1:
; CHECK-NEXT: loop () -> (i32, i64)
; CHECK-NEXT: br 0{{$}}
; CHECK-NEXT: .LBB{{[0-9]+}}_2:
; CHECK-NEXT: end_loop{{$}}
define {i32, i64} @minimal_loop(i32* %p) {
entry:
br label %loop
loop:
br label %loop
}
; CHECK-LABEL: .section .custom_section.target_features
; CHECK-NEXT: .int8 1
; CHECK-NEXT: .int8 43
@@ -2,8 +2,11 @@
# CHECK: .text
# CHECK: block invalid_type
# CHECK: block unknown_type
0x02 0x00
# CHECK: block invalid_type
0x02 0xff 0x42
# CHECK: br 16 # Invalid depth argument!
0x0C 0x10
+12
View File
@@ -55,6 +55,12 @@ test0:
block i64
block f32
block f64
block () -> (i32, i32)
i32.const 1
i32.const 2
end_block
drop
drop
br_table {0, 1, 2} # 2 entries, default
end_block # first entry jumps here.
i32.const 1
@@ -162,6 +168,12 @@ test0:
# CHECK-NEXT: block i64
# CHECK-NEXT: block f32
# CHECK-NEXT: block f64
# CHECK-NEXT: block () -> (i32, i32)
# CHECK-NEXT: i32.const 1
# CHECK-NEXT: i32.const 2
# CHECK-NEXT: end_block
# CHECK-NEXT: drop
# CHECK-NEXT: drop
# CHECK-NEXT: br_table {0, 1, 2} # 1: down to label4
# CHECK-NEXT: # 2: down to label3
# CHECK-NEXT: end_block # label5: