Revert "[WebAssembly][InstrEmitter] Foundation for multivalue call lowering"
Summary:
This reverts commit 3ef169e586f4d14efe690c23c878d5aa92a80eb5. The
purpose of this commit was to allow stack machines to perform
instruction selection for instructions with variadic defs. However,
MachineInstrs fundamentally cannot support variadic defs right now, so
this change does not turn out to be useful.
Depends on D73927.
Reviewers: aheejin
Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D73928
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index 67afbee..176ae39 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -361,13 +361,11 @@
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
MCContext &Context);
- /// True if the target uses physical regs (as nearly all targets do). False
- /// for stack machines such as WebAssembly and other virtual-register
- /// machines. If true, all vregs must be allocated before PEI. If false, then
- /// callee-save register spilling and scavenging are not needed or used. If
- /// false, implicitly defined registers will still be assumed to be physical
- /// registers, except that variadic defs will be allocated vregs.
- virtual bool usesPhysRegsForValues() const { return true; }
+ /// True if the target uses physical regs at Prolog/Epilog insertion
+ /// time. If true (most machines), all vregs must be allocated before
+ /// PEI. If false (virtual-register machines), then callee-save register
+ /// spilling and scavenging are not needed or used.
+ virtual bool usesPhysRegsForPEI() const { return true; }
/// True if the target wants to use interprocedural register allocation by
/// default. The -enable-ipra flag can be used to override this.
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index 889d026..d583643 100644
--- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -237,7 +237,7 @@
stashEntryDbgValues(*SaveBlock, EntryDbgValues);
// Handle CSR spilling and restoring, for targets that need it.
- if (MF.getTarget().usesPhysRegsForValues())
+ if (MF.getTarget().usesPhysRegsForPEI())
spillCalleeSavedRegs(MF);
// Allow the target machine to make final modifications to the function
diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index dc78bba..90ff762 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -195,10 +195,7 @@
"IMPLICIT_DEF should have been handled as a special case elsewhere!");
unsigned NumResults = CountResults(Node);
- bool HasVRegVariadicDefs = !MF->getTarget().usesPhysRegsForValues() &&
- II.isVariadic() && II.variadicOpsAreDefs();
- unsigned NumVRegs = HasVRegVariadicDefs ? NumResults : II.getNumDefs();
- for (unsigned i = 0; i < NumVRegs; ++i) {
+ for (unsigned i = 0; i < II.getNumDefs(); ++i) {
// If the specific node value is only used by a CopyToReg and the dest reg
// is a vreg in the same register class, use the CopyToReg'd destination
// register instead of creating a new vreg.
@@ -219,7 +216,7 @@
RC = VTRC;
}
- if (II.OpInfo != nullptr && II.OpInfo[i].isOptionalDef()) {
+ if (II.OpInfo[i].isOptionalDef()) {
// Optional def must be a physical register.
VRBase = cast<RegisterSDNode>(Node->getOperand(i-NumResults))->getReg();
assert(Register::isPhysicalRegister(VRBase));
@@ -831,10 +828,7 @@
unsigned NumImpUses = 0;
unsigned NodeOperands =
countOperands(Node, II.getNumOperands() - NumDefs, NumImpUses);
- bool HasVRegVariadicDefs = !MF->getTarget().usesPhysRegsForValues() &&
- II.isVariadic() && II.variadicOpsAreDefs();
- bool HasPhysRegOuts = NumResults > NumDefs &&
- II.getImplicitDefs() != nullptr && !HasVRegVariadicDefs;
+ bool HasPhysRegOuts = NumResults > NumDefs && II.getImplicitDefs()!=nullptr;
#ifndef NDEBUG
unsigned NumMIOperands = NodeOperands + NumResults;
if (II.isVariadic())
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index f7d1aeb..b339860 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -509,8 +509,8 @@
/// Returns the operand number of a callee, assuming the argument is a call
/// instruction.
-inline const MachineOperand &getCalleeOp(const MachineInstr &MI) {
- switch (MI.getOpcode()) {
+inline unsigned getCalleeOpNo(unsigned Opc) {
+ switch (Opc) {
case WebAssembly::CALL_VOID:
case WebAssembly::CALL_VOID_S:
case WebAssembly::CALL_INDIRECT_VOID:
@@ -519,7 +519,7 @@
case WebAssembly::RET_CALL_S:
case WebAssembly::RET_CALL_INDIRECT:
case WebAssembly::RET_CALL_INDIRECT_S:
- return MI.getOperand(0);
+ return 0;
case WebAssembly::CALL_i32:
case WebAssembly::CALL_i32_S:
case WebAssembly::CALL_i64:
@@ -564,10 +564,7 @@
case WebAssembly::CALL_INDIRECT_v2f64_S:
case WebAssembly::CALL_INDIRECT_exnref:
case WebAssembly::CALL_INDIRECT_exnref_S:
- return MI.getOperand(1);
- case WebAssembly::CALL:
- case WebAssembly::CALL_S:
- return MI.getOperand(MI.getNumDefs());
+ return 1;
default:
llvm_unreachable("Not a call instruction");
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def
index f9cb87f..ba04fd4 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def
@@ -15,7 +15,6 @@
HANDLE_NODETYPE(CALL1)
HANDLE_NODETYPE(CALL0)
-HANDLE_NODETYPE(CALL)
HANDLE_NODETYPE(RET_CALL)
HANDLE_NODETYPE(RETURN)
HANDLE_NODETYPE(ARGUMENT)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
index a451040..531a07b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
@@ -206,25 +206,6 @@
}
break;
}
- case WebAssemblyISD::CALL: {
- // CALL has both variable operands and variable results, but ISel only
- // supports one or the other. Split calls into two nodes glued together, one
- // for the operands and one for the results. These two nodes will be
- // recombined in a custom inserter hook.
- // TODO: Split CALL
- SmallVector<SDValue, 16> Ops;
- for (size_t i = 1; i < Node->getNumOperands(); ++i) {
- SDValue Op = Node->getOperand(i);
- if (Op->getOpcode() == WebAssemblyISD::Wrapper)
- Op = Op->getOperand(0);
- Ops.push_back(Op);
- }
- Ops.push_back(Node->getOperand(0));
- MachineSDNode *Call =
- CurDAG->getMachineNode(WebAssembly::CALL, DL, Node->getVTList(), Ops);
- ReplaceNode(Node, Call);
- return;
- }
default:
break;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 417b6b5..e712906 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -680,6 +680,9 @@
}
SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ if (Ins.size() > 1)
+ fail(DL, DAG, "WebAssembly doesn't support more than 1 returned value yet");
+
SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
@@ -825,27 +828,18 @@
}
InTys.push_back(MVT::Other);
- unsigned Opc;
- // TODO: Remove CALL0 and CALL1 in favor of CALL
- switch (Ins.size()) {
- case 0:
- Opc = WebAssemblyISD::CALL0;
- break;
- case 1:
- Opc = WebAssemblyISD::CALL1;
- break;
- default:
- Opc = WebAssemblyISD::CALL;
- break;
- }
SDVTList InTyList = DAG.getVTList(InTys);
- SDValue Res = DAG.getNode(Opc, DL, InTyList, Ops);
+ SDValue Res =
+ DAG.getNode(Ins.empty() ? WebAssemblyISD::CALL0 : WebAssemblyISD::CALL1,
+ DL, InTyList, Ops);
+ if (Ins.empty()) {
+ Chain = Res;
+ } else {
+ InVals.push_back(Res);
+ Chain = Res.getValue(1);
+ }
- for (size_t I = 0; I < Ins.size(); ++I)
- InVals.push_back(Res.getValue(I));
-
- // Return the chain
- return Res.getValue(Ins.size());
+ return Chain;
}
bool WebAssemblyTargetLowering::CanLowerReturn(
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
index 98a4f43..703c15d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
@@ -55,15 +55,6 @@
}
let Uses = [SP32, SP64], isCall = 1 in {
-
-// TODO: Split CALL into separate nodes for operands and results.
-// TODO: Add an indirect version of the variadic call, delete CALL_*
-let variadicOpsAreDefs = 1 in
-defm CALL :
- I<(outs), (ins function32_op:$callee, variable_ops),
- (outs), (ins function32_op:$callee), [],
- "call \t$callee", "call\t$callee", 0x10>;
-
defm "" : CALL<i32, I32, "i32.">;
defm "" : CALL<i64, I64, "i64.">;
defm "" : CALL<f32, F32, "f32.">;
@@ -77,7 +68,6 @@
defm "" : CALL<v2f64, V128, "v128.", [HasSIMD128]>;
let IsCanonical = 1 in {
-
defm CALL_VOID :
I<(outs), (ins function32_op:$callee, variable_ops),
(outs), (ins function32_op:$callee),
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
index e490344..7d54bf0 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
@@ -135,12 +135,12 @@
// Determine whether a call to the callee referenced by
// MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
// effects.
-static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write,
- bool &Effects, bool &StackPointer) {
+static void queryCallee(const MachineInstr &MI, unsigned CalleeOpNo, bool &Read,
+ bool &Write, bool &Effects, bool &StackPointer) {
// All calls can use the stack pointer.
StackPointer = true;
- const MachineOperand &MO = WebAssembly::getCalleeOp(MI);
+ const MachineOperand &MO = MI.getOperand(CalleeOpNo);
if (MO.isGlobal()) {
const Constant *GV = MO.getGlobal();
if (const auto *GA = dyn_cast<GlobalAlias>(GV))
@@ -252,7 +252,8 @@
// Analyze calls.
if (MI.isCall()) {
- queryCallee(MI, Read, Write, Effects, StackPointer);
+ unsigned CalleeOpNo = WebAssembly::getCalleeOpNo(MI.getOpcode());
+ queryCallee(MI, CalleeOpNo, Read, Write, Effects, StackPointer);
}
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h
index dd5b397..850e6b9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h
@@ -47,7 +47,7 @@
TargetTransformInfo getTargetTransformInfo(const Function &F) override;
- bool usesPhysRegsForValues() const override { return false; }
+ bool usesPhysRegsForPEI() const override { return false; }
yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const override;
yaml::MachineFunctionInfo *
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
index 5b77798..a237da8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
@@ -49,7 +49,7 @@
if (!MI.isCall())
return false;
- const MachineOperand &MO = getCalleeOp(MI);
+ const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI.getOpcode()));
assert(MO.isGlobal() || MO.isSymbol());
if (MO.isSymbol()) {
@@ -79,67 +79,3 @@
// original LLVm IR? (Even when the callee may throw)
return true;
}
-
-inline const MachineOperand &getCalleeOp(const MachineInstr &MI) {
- switch (MI.getOpcode()) {
- case WebAssembly::CALL_VOID:
- case WebAssembly::CALL_VOID_S:
- case WebAssembly::CALL_INDIRECT_VOID:
- case WebAssembly::CALL_INDIRECT_VOID_S:
- case WebAssembly::RET_CALL:
- case WebAssembly::RET_CALL_S:
- case WebAssembly::RET_CALL_INDIRECT:
- case WebAssembly::RET_CALL_INDIRECT_S:
- return MI.getOperand(0);
- case WebAssembly::CALL_i32:
- case WebAssembly::CALL_i32_S:
- case WebAssembly::CALL_i64:
- case WebAssembly::CALL_i64_S:
- case WebAssembly::CALL_f32:
- case WebAssembly::CALL_f32_S:
- case WebAssembly::CALL_f64:
- case WebAssembly::CALL_f64_S:
- case WebAssembly::CALL_v16i8:
- case WebAssembly::CALL_v16i8_S:
- case WebAssembly::CALL_v8i16:
- case WebAssembly::CALL_v8i16_S:
- case WebAssembly::CALL_v4i32:
- case WebAssembly::CALL_v4i32_S:
- case WebAssembly::CALL_v2i64:
- case WebAssembly::CALL_v2i64_S:
- case WebAssembly::CALL_v4f32:
- case WebAssembly::CALL_v4f32_S:
- case WebAssembly::CALL_v2f64:
- case WebAssembly::CALL_v2f64_S:
- case WebAssembly::CALL_exnref:
- case WebAssembly::CALL_exnref_S:
- case WebAssembly::CALL_INDIRECT_i32:
- case WebAssembly::CALL_INDIRECT_i32_S:
- case WebAssembly::CALL_INDIRECT_i64:
- case WebAssembly::CALL_INDIRECT_i64_S:
- case WebAssembly::CALL_INDIRECT_f32:
- case WebAssembly::CALL_INDIRECT_f32_S:
- case WebAssembly::CALL_INDIRECT_f64:
- case WebAssembly::CALL_INDIRECT_f64_S:
- case WebAssembly::CALL_INDIRECT_v16i8:
- case WebAssembly::CALL_INDIRECT_v16i8_S:
- case WebAssembly::CALL_INDIRECT_v8i16:
- case WebAssembly::CALL_INDIRECT_v8i16_S:
- case WebAssembly::CALL_INDIRECT_v4i32:
- case WebAssembly::CALL_INDIRECT_v4i32_S:
- case WebAssembly::CALL_INDIRECT_v2i64:
- case WebAssembly::CALL_INDIRECT_v2i64_S:
- case WebAssembly::CALL_INDIRECT_v4f32:
- case WebAssembly::CALL_INDIRECT_v4f32_S:
- case WebAssembly::CALL_INDIRECT_v2f64:
- case WebAssembly::CALL_INDIRECT_v2f64_S:
- case WebAssembly::CALL_INDIRECT_exnref:
- case WebAssembly::CALL_INDIRECT_exnref_S:
- return MI.getOperand(1);
- case WebAssembly::CALL:
- case WebAssembly::CALL_S:
- return MI.getOperand(MI.getNumDefs());
- default:
- llvm_unreachable("Not a call instruction");
- }
-}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.h b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.h
index 4f0ed43..26cf84d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.h
@@ -44,10 +44,6 @@
return Bottom;
}
-/// Returns the operand number of a callee, assuming the argument is a call
-/// instruction.
-const MachineOperand &getCalleeOp(const MachineInstr &MI);
-
} // end namespace WebAssembly
} // end namespace llvm
diff --git a/llvm/test/CodeGen/WebAssembly/multivalue.ll b/llvm/test/CodeGen/WebAssembly/multivalue.ll
index af601f7..ee32852 100644
--- a/llvm/test/CodeGen/WebAssembly/multivalue.ll
+++ b/llvm/test/CodeGen/WebAssembly/multivalue.ll
@@ -1,116 +1,29 @@
-; 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
+; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+multivalue | FileCheck %s
+; RUN: llc < %s --filetype=obj -mattr=+multivalue | obj2yaml | FileCheck %s --check-prefix OBJ
-; Test that the multivalue calls, returns, function types, and block
-; types work as expected.
+; 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"
-%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 }>
-}
+%pair = type { i32, i32 }
+%packed_pair = type <{ i32, i32 }>
; CHECK-LABEL: pair_ident:
-; CHECK-NEXT: .functype pair_ident (i32, i64) -> (i32, i64)
+; 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: .functype packed_pair_ident (i32, i64) -> (i32, i64)
+; 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
}
-;; 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:
@@ -118,7 +31,7 @@
; CHECK-NEXT: br 0{{$}}
; CHECK-NEXT: .LBB{{[0-9]+}}_2:
; CHECK-NEXT: end_loop{{$}}
-define %pair @minimal_loop(i32* %p) {
+define {i32, i64} @minimal_loop(i32* %p) {
entry:
br label %loop
loop:
@@ -126,40 +39,21 @@
}
; CHECK-LABEL: .section .custom_section.target_features
-; CHECK-NEXT: .int8 2
+; CHECK-NEXT: .int8 1
; 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: - I32
; 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: - Index: 1
; OBJ-NEXT: ParamTypes:
; OBJ-NEXT: - I32
; OBJ-NEXT: ReturnTypes: