; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+multivalue,+tail-call | FileCheck %s ; RUN: llc < %s --filetype=obj -mattr=+multivalue,+tail-call | obj2yaml | FileCheck %s --check-prefix OBJ ; Test that the multivalue calls, 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" %pair = type { i32, i64 } %packed_pair = type <{ i32, i64 }> ; CHECK-LABEL: pair_const: ; CHECK-NEXT: .functype pair_const () -> (i32, i64) ; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 42{{$}} ; CHECK-NEXT: i64.const $push[[L1:[0-9]+]]=, 42{{$}} ; CHECK-NEXT: return $pop[[L0]], $pop[[L1]]{{$}} define %pair @pair_const() { ret %pair { i32 42, i64 42 } } ; CHECK-LABEL: packed_pair_const: ; CHECK-NEXT: .functype packed_pair_const () -> (i32, i64) ; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 42{{$}} ; CHECK-NEXT: i64.const $push[[L1:[0-9]+]]=, 42{{$}} ; CHECK-NEXT: return $pop[[L0]], $pop[[L1]]{{$}} define %packed_pair @packed_pair_const() { ret %packed_pair <{ i32 42, i64 42 }> } ; CHECK-LABEL: pair_ident: ; CHECK-NEXT: .functype pair_ident (i32, i64) -> (i32, i64) ; CHECK-NEXT: return $0, $1{{$}} define %pair @pair_ident(%pair %p) { ret %pair %p } ; CHECK-LABEL: packed_pair_ident: ; CHECK-NEXT: .functype packed_pair_ident (i32, i64) -> (i32, i64) ; CHECK-NEXT: return $0, $1{{$}} define %packed_pair @packed_pair_ident(%packed_pair %p) { ret %packed_pair %p } ;; TODO: Multivalue calls are a WIP and do not necessarily produce ;; correct output. For now, just check that they don't cause any ;; crashes. define void @pair_call() { %p = call %pair @pair_const() ret void } define void @packed_pair_call() { %p = call %packed_pair @packed_pair_const() ret void } define %pair @pair_call_return() { %p = call %pair @pair_const() ret %pair %p } define %packed_pair @packed_pair_call_return() { %p = call %packed_pair @packed_pair_const() ret %packed_pair %p } define %pair @pair_tail_call() { %p = musttail call %pair @pair_const() ret %pair %p } define %packed_pair @packed_pair_tail_call() { %p = musttail call %packed_pair @packed_pair_const() ret %packed_pair %p } define i32 @pair_call_return_first() { %p = call %pair @pair_const() %v = extractvalue %pair %p, 0 ret i32 %v } define i32 @packed_pair_call_return_first() { %p = call %packed_pair @packed_pair_const() %v = extractvalue %packed_pair %p, 0 ret i32 %v } define i64 @pair_call_return_second() { %p = call %pair @pair_const() %v = extractvalue %pair %p, 1 ret i64 %v } define i64 @packed_pair_call_return_second() { %p = call %packed_pair @packed_pair_const() %v = extractvalue %packed_pair %p, 1 ret i64 %v } define %pair @pair_pass_through(%pair %p) { %r = call %pair @pair_ident(%pair %p) ret %pair %r } define %packed_pair @packed_pair_pass_through(%packed_pair %p) { %r = call %packed_pair @packed_pair_ident(%packed_pair %p) ret %packed_pair %r } ; 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 %pair @minimal_loop(i32* %p) { entry: br label %loop loop: br label %loop } ; CHECK-LABEL: .section .custom_section.target_features ; CHECK-NEXT: .int8 2 ; CHECK-NEXT: .int8 43 ; CHECK-NEXT: .int8 10 ; CHECK-NEXT: .ascii "multivalue" ; CHECK-NEXT: .int8 43 ; CHECK-NEXT: .int8 9 ; CHECK-NEXT: .ascii "tail-call" ; OBJ-LABEL: - Type: TYPE ; OBJ-NEXT: Signatures: ; OBJ-NEXT: - Index: 0 ; OBJ-NEXT: ParamTypes: [] ; OBJ-NEXT: ReturnTypes: ; OBJ-NEXT: - I32 ; OBJ-NEXT: - I64 ; OBJ-NEXT: - Index: 1 ; OBJ-NEXT: ParamTypes: ; OBJ-NEXT: - I32 ; OBJ-NEXT: - I64 ; OBJ-NEXT: ReturnTypes: ; OBJ-NEXT: - I32 ; OBJ-NEXT: - I64 ; OBJ-NEXT: - Index: 2 ; OBJ-NEXT: ParamTypes: [] ; OBJ-NEXT: ReturnTypes: [] ; OBJ-NEXT: - Index: 3 ; OBJ-NEXT: ParamTypes: [] ; OBJ-NEXT: ReturnTypes: ; OBJ-NEXT: - I32 ; OBJ-NEXT: - Index: 4 ; OBJ-NEXT: ParamTypes: [] ; OBJ-NEXT: ReturnTypes: ; OBJ-NEXT: - I64 ; OBJ-NEXT: - Index: 5 ; OBJ-NEXT: ParamTypes: ; OBJ-NEXT: - I32 ; OBJ-NEXT: ReturnTypes: ; OBJ-NEXT: - I32 ; OBJ-NEXT: - I64