[WebAssembly][GlobalISel] CallLowering lowerFormalArguments (#180263)
Implements `WebAssemblyCallLowering::lowerFormalArguments` Split from #157161
This commit is contained in:
@@ -14,11 +14,17 @@
|
||||
|
||||
#include "WebAssemblyCallLowering.h"
|
||||
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
|
||||
#include "Utils/WasmAddressSpaces.h"
|
||||
#include "WebAssemblyISelLowering.h"
|
||||
#include "WebAssemblyMachineFunctionInfo.h"
|
||||
#include "WebAssemblyRegisterInfo.h"
|
||||
#include "WebAssemblySubtarget.h"
|
||||
#include "WebAssemblyUtilities.h"
|
||||
#include "llvm/CodeGen/Analysis.h"
|
||||
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
||||
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/RegisterBankInfo.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
@@ -27,6 +33,21 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// Test whether the given calling convention is supported.
|
||||
static bool callingConvSupported(CallingConv::ID CallConv) {
|
||||
// We currently support the language-independent target-independent
|
||||
// conventions. We don't yet have a way to annotate calls with properties like
|
||||
// "cold", and we don't have any call-clobbered registers, so these are mostly
|
||||
// all handled the same.
|
||||
return CallConv == CallingConv::C || CallConv == CallingConv::Fast ||
|
||||
CallConv == CallingConv::Cold ||
|
||||
CallConv == CallingConv::PreserveMost ||
|
||||
CallConv == CallingConv::PreserveAll ||
|
||||
CallConv == CallingConv::CXX_FAST_TLS ||
|
||||
CallConv == CallingConv::WASM_EmscriptenInvoke ||
|
||||
CallConv == CallingConv::Swift;
|
||||
}
|
||||
|
||||
WebAssemblyCallLowering::WebAssemblyCallLowering(
|
||||
const WebAssemblyTargetLowering &TLI)
|
||||
: CallLowering(&TLI) {}
|
||||
@@ -50,13 +71,222 @@ bool WebAssemblyCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned getWASMArgumentOpcode(MVT ArgType) {
|
||||
switch (ArgType.SimpleTy) {
|
||||
case MVT::i32:
|
||||
return WebAssembly::ARGUMENT_i32;
|
||||
case MVT::i64:
|
||||
return WebAssembly::ARGUMENT_i64;
|
||||
case MVT::f32:
|
||||
return WebAssembly::ARGUMENT_f32;
|
||||
case MVT::f64:
|
||||
return WebAssembly::ARGUMENT_f64;
|
||||
|
||||
case MVT::funcref:
|
||||
return WebAssembly::ARGUMENT_funcref;
|
||||
case MVT::externref:
|
||||
return WebAssembly::ARGUMENT_externref;
|
||||
case MVT::exnref:
|
||||
return WebAssembly::ARGUMENT_exnref;
|
||||
|
||||
case MVT::v16i8:
|
||||
return WebAssembly::ARGUMENT_v16i8;
|
||||
case MVT::v8i16:
|
||||
return WebAssembly::ARGUMENT_v8i16;
|
||||
case MVT::v4i32:
|
||||
return WebAssembly::ARGUMENT_v4i32;
|
||||
case MVT::v2i64:
|
||||
return WebAssembly::ARGUMENT_v2i64;
|
||||
case MVT::v8f16:
|
||||
return WebAssembly::ARGUMENT_v8f16;
|
||||
case MVT::v4f32:
|
||||
return WebAssembly::ARGUMENT_v4f32;
|
||||
case MVT::v2f64:
|
||||
return WebAssembly::ARGUMENT_v2f64;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Found unexpected type for WASM argument");
|
||||
}
|
||||
|
||||
static LLT getLLTForWasmMVT(MVT Ty, const DataLayout &DL) {
|
||||
if (Ty == MVT::externref) {
|
||||
return LLT::pointer(
|
||||
WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF,
|
||||
DL.getPointerSizeInBits(
|
||||
WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF));
|
||||
}
|
||||
|
||||
if (Ty == MVT::funcref) {
|
||||
return LLT::pointer(
|
||||
WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF,
|
||||
DL.getPointerSizeInBits(
|
||||
WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF));
|
||||
}
|
||||
|
||||
return llvm::getLLTForMVT(Ty);
|
||||
}
|
||||
|
||||
bool WebAssemblyCallLowering::lowerFormalArguments(
|
||||
MachineIRBuilder &MIRBuilder, const Function &F,
|
||||
ArrayRef<ArrayRef<Register>> VRegs, FunctionLoweringInfo &FLI) const {
|
||||
if (VRegs.empty())
|
||||
return true; // allow only empty signatures for now
|
||||
MachineFunction &MF = MIRBuilder.getMF();
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
WebAssemblyFunctionInfo *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
|
||||
const DataLayout &DL = F.getDataLayout();
|
||||
const WebAssemblyTargetLowering &TLI = *getTLI<WebAssemblyTargetLowering>();
|
||||
const WebAssemblySubtarget &Subtarget =
|
||||
MF.getSubtarget<WebAssemblySubtarget>();
|
||||
const WebAssemblyRegisterInfo &TRI = *Subtarget.getRegisterInfo();
|
||||
const WebAssemblyInstrInfo &TII = *Subtarget.getInstrInfo();
|
||||
const RegisterBankInfo &RBI = *Subtarget.getRegBankInfo();
|
||||
|
||||
return false;
|
||||
LLVMContext &Ctx = MIRBuilder.getContext();
|
||||
const CallingConv::ID CallConv = F.getCallingConv();
|
||||
|
||||
if (!callingConvSupported(CallConv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
|
||||
MF.front().addLiveIn(WebAssembly::ARGUMENTS);
|
||||
|
||||
SmallVector<ArgInfo, 8> SplitArgs;
|
||||
|
||||
if (!FLI.CanLowerReturn) {
|
||||
insertSRetIncomingArgument(F, SplitArgs, FLI.DemoteRegister, MRI, DL);
|
||||
}
|
||||
|
||||
unsigned ArgIdx = 0;
|
||||
bool HasSwiftErrorArg = false;
|
||||
bool HasSwiftSelfArg = false;
|
||||
for (const Argument &Arg : F.args()) {
|
||||
ArgInfo OrigArg{VRegs[ArgIdx], Arg.getType(), ArgIdx};
|
||||
setArgFlags(OrigArg, ArgIdx + AttributeList::FirstArgIndex, DL, F);
|
||||
|
||||
HasSwiftSelfArg |= Arg.hasSwiftSelfAttr();
|
||||
HasSwiftErrorArg |= Arg.hasSwiftErrorAttr();
|
||||
if (Arg.hasInAllocaAttr()) {
|
||||
return false;
|
||||
}
|
||||
if (Arg.hasNestAttr()) {
|
||||
return false;
|
||||
}
|
||||
splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
|
||||
++ArgIdx;
|
||||
}
|
||||
|
||||
unsigned FinalArgIdx = 0;
|
||||
for (ArgInfo &Arg : SplitArgs) {
|
||||
const EVT OrigVT = TLI.getValueType(DL, Arg.Ty);
|
||||
const MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CallConv, OrigVT);
|
||||
const LLT OrigLLT =
|
||||
getLLTForType(*OrigVT.getTypeForEVT(F.getContext()), DL);
|
||||
const LLT NewLLT = getLLTForWasmMVT(NewVT, DL);
|
||||
|
||||
// If we need to split the type over multiple regs, check it's a scenario
|
||||
// we currently support.
|
||||
const unsigned NumParts =
|
||||
TLI.getNumRegistersForCallingConv(Ctx, CallConv, OrigVT);
|
||||
|
||||
const ISD::ArgFlagsTy OrigFlags = Arg.Flags[0];
|
||||
Arg.Flags.clear();
|
||||
|
||||
for (unsigned Part = 0; Part < NumParts; ++Part) {
|
||||
ISD::ArgFlagsTy Flags = OrigFlags;
|
||||
if (Part == 0) {
|
||||
Flags.setSplit();
|
||||
} else {
|
||||
Flags.setOrigAlign(Align(1));
|
||||
if (Part == NumParts - 1)
|
||||
Flags.setSplitEnd();
|
||||
}
|
||||
|
||||
Arg.Flags.push_back(Flags);
|
||||
}
|
||||
|
||||
Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
|
||||
if (NumParts != 1 || OrigLLT != NewLLT) {
|
||||
// If we can't directly assign the register, we need one or more
|
||||
// intermediate values.
|
||||
Arg.Regs.resize(NumParts);
|
||||
|
||||
// For each split register, create and assign a vreg that will store
|
||||
// the incoming component of the larger value. These will later be
|
||||
// merged to form the final vreg.
|
||||
for (unsigned Part = 0; Part < NumParts; ++Part) {
|
||||
Arg.Regs[Part] = MRI.createGenericVirtualRegister(NewLLT);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned Part = 0; Part < NumParts; ++Part) {
|
||||
MachineInstrBuilder ArgInst =
|
||||
MIRBuilder.buildInstr(getWASMArgumentOpcode(NewVT))
|
||||
.addDef(Arg.Regs[Part])
|
||||
.addImm(FinalArgIdx);
|
||||
|
||||
constrainOperandRegClass(MF, TRI, MRI, TII, RBI, *ArgInst,
|
||||
ArgInst->getDesc(), ArgInst->getOperand(0), 0);
|
||||
MFI->addParam(NewVT);
|
||||
++FinalArgIdx;
|
||||
}
|
||||
|
||||
if (OrigVT != NewVT) {
|
||||
buildCopyFromRegs(MIRBuilder, Arg.OrigRegs, Arg.Regs, OrigLLT, NewLLT,
|
||||
Arg.Flags[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// For swiftcc, emit additional swiftself and swifterror arguments
|
||||
// if there aren't. These additional arguments are also added for callee
|
||||
// signature They are necessary to match callee and caller signature for
|
||||
// indirect call.
|
||||
if (CallConv == CallingConv::Swift) {
|
||||
const MVT PtrVT = TLI.getPointerTy(DL);
|
||||
|
||||
if (!HasSwiftSelfArg) {
|
||||
MFI->addParam(PtrVT);
|
||||
}
|
||||
if (!HasSwiftErrorArg) {
|
||||
MFI->addParam(PtrVT);
|
||||
}
|
||||
}
|
||||
|
||||
// Varargs are copied into a buffer allocated by the caller, and a pointer to
|
||||
// the buffer is passed as an argument.
|
||||
if (F.isVarArg()) {
|
||||
const MVT PtrVT = TLI.getPointerTy(DL, 0);
|
||||
const LLT PtrLLT = LLT::pointer(0, DL.getPointerSizeInBits(0));
|
||||
Register VarargVreg = MF.getRegInfo().createGenericVirtualRegister(PtrLLT);
|
||||
|
||||
MFI->setVarargBufferVreg(VarargVreg);
|
||||
|
||||
MachineInstrBuilder ArgInst =
|
||||
MIRBuilder.buildInstr(getWASMArgumentOpcode(PtrVT))
|
||||
.addDef(VarargVreg)
|
||||
.addImm(FinalArgIdx);
|
||||
|
||||
constrainOperandRegClass(MF, TRI, MRI, TII, RBI, *ArgInst,
|
||||
ArgInst->getDesc(), ArgInst->getOperand(0), 0);
|
||||
|
||||
MFI->addParam(PtrVT);
|
||||
++FinalArgIdx;
|
||||
}
|
||||
|
||||
// Record the number and types of arguments and results.
|
||||
SmallVector<MVT, 4> Params;
|
||||
SmallVector<MVT, 4> Results;
|
||||
computeSignatureVTs(MF.getFunction().getFunctionType(), &MF.getFunction(),
|
||||
MF.getFunction(), MF.getTarget(), Params, Results);
|
||||
for (MVT VT : Results)
|
||||
MFI->addResult(VT);
|
||||
|
||||
// TODO: Use signatures in WebAssemblyMachineFunctionInfo too and unify
|
||||
// the param logic here with ComputeSignatureVTs
|
||||
assert(MFI->getParams().size() == Params.size() &&
|
||||
std::equal(MFI->getParams().begin(), MFI->getParams().end(),
|
||||
Params.begin()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebAssemblyCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: llc -mtriple=wasm32 -mattr=-simd128 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck %s -check-prefixes=NO-SIMD
|
||||
; RUN: llc -mtriple=wasm32 -mattr=+simd128,-fp16 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck %s -check-prefixes=SIMD,SIMD-NO-F16
|
||||
; RUN: llc -mtriple=wasm32 -mattr=+simd128,+fp16 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck %s -check-prefixes=SIMD,SIMD-F16
|
||||
|
||||
define void @test_v16i8_arg(<16 x i8> %arg) {
|
||||
; NO-SIMD-LABEL: name: test_v16i8_arg
|
||||
; NO-SIMD: bb.1 (%ir-block.0):
|
||||
; NO-SIMD-NEXT: liveins: $arguments
|
||||
; NO-SIMD-NEXT: {{ $}}
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_3:%[0-9]+]]:i32(s32) = ARGUMENT_i32 3, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_4:%[0-9]+]]:i32(s32) = ARGUMENT_i32 4, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_5:%[0-9]+]]:i32(s32) = ARGUMENT_i32 5, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_6:%[0-9]+]]:i32(s32) = ARGUMENT_i32 6, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_7:%[0-9]+]]:i32(s32) = ARGUMENT_i32 7, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_8:%[0-9]+]]:i32(s32) = ARGUMENT_i32 8, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_9:%[0-9]+]]:i32(s32) = ARGUMENT_i32 9, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_10:%[0-9]+]]:i32(s32) = ARGUMENT_i32 10, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_11:%[0-9]+]]:i32(s32) = ARGUMENT_i32 11, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_12:%[0-9]+]]:i32(s32) = ARGUMENT_i32 12, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_13:%[0-9]+]]:i32(s32) = ARGUMENT_i32 13, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_14:%[0-9]+]]:i32(s32) = ARGUMENT_i32 14, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_15:%[0-9]+]]:i32(s32) = ARGUMENT_i32 15, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<16 x s32>) = G_BUILD_VECTOR [[ARGUMENT_i32_]](s32), [[ARGUMENT_i32_1]](s32), [[ARGUMENT_i32_2]](s32), [[ARGUMENT_i32_3]](s32), [[ARGUMENT_i32_4]](s32), [[ARGUMENT_i32_5]](s32), [[ARGUMENT_i32_6]](s32), [[ARGUMENT_i32_7]](s32), [[ARGUMENT_i32_8]](s32), [[ARGUMENT_i32_9]](s32), [[ARGUMENT_i32_10]](s32), [[ARGUMENT_i32_11]](s32), [[ARGUMENT_i32_12]](s32), [[ARGUMENT_i32_13]](s32), [[ARGUMENT_i32_14]](s32), [[ARGUMENT_i32_15]](s32)
|
||||
; NO-SIMD-NEXT: [[TRUNC:%[0-9]+]]:_(<16 x s8>) = G_TRUNC [[BUILD_VECTOR]](<16 x s32>)
|
||||
;
|
||||
; SIMD-LABEL: name: test_v16i8_arg
|
||||
; SIMD: bb.1 (%ir-block.0):
|
||||
; SIMD-NEXT: liveins: $arguments
|
||||
; SIMD-NEXT: {{ $}}
|
||||
; SIMD-NEXT: [[ARGUMENT_v16i8_:%[0-9]+]]:v128(<16 x s8>) = ARGUMENT_v16i8 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_v8i16_arg(<8 x i16> %arg) {
|
||||
; NO-SIMD-LABEL: name: test_v8i16_arg
|
||||
; NO-SIMD: bb.1 (%ir-block.0):
|
||||
; NO-SIMD-NEXT: liveins: $arguments
|
||||
; NO-SIMD-NEXT: {{ $}}
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_3:%[0-9]+]]:i32(s32) = ARGUMENT_i32 3, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_4:%[0-9]+]]:i32(s32) = ARGUMENT_i32 4, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_5:%[0-9]+]]:i32(s32) = ARGUMENT_i32 5, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_6:%[0-9]+]]:i32(s32) = ARGUMENT_i32 6, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_7:%[0-9]+]]:i32(s32) = ARGUMENT_i32 7, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<8 x s32>) = G_BUILD_VECTOR [[ARGUMENT_i32_]](s32), [[ARGUMENT_i32_1]](s32), [[ARGUMENT_i32_2]](s32), [[ARGUMENT_i32_3]](s32), [[ARGUMENT_i32_4]](s32), [[ARGUMENT_i32_5]](s32), [[ARGUMENT_i32_6]](s32), [[ARGUMENT_i32_7]](s32)
|
||||
; NO-SIMD-NEXT: [[TRUNC:%[0-9]+]]:_(<8 x s16>) = G_TRUNC [[BUILD_VECTOR]](<8 x s32>)
|
||||
;
|
||||
; SIMD-LABEL: name: test_v8i16_arg
|
||||
; SIMD: bb.1 (%ir-block.0):
|
||||
; SIMD-NEXT: liveins: $arguments
|
||||
; SIMD-NEXT: {{ $}}
|
||||
; SIMD-NEXT: [[ARGUMENT_v8i16_:%[0-9]+]]:v128(<8 x s16>) = ARGUMENT_v8i16 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_v4i32_arg(<4 x i32> %arg) {
|
||||
; NO-SIMD-LABEL: name: test_v4i32_arg
|
||||
; NO-SIMD: bb.1 (%ir-block.0):
|
||||
; NO-SIMD-NEXT: liveins: $arguments
|
||||
; NO-SIMD-NEXT: {{ $}}
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_3:%[0-9]+]]:i32(s32) = ARGUMENT_i32 3, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[ARGUMENT_i32_]](s32), [[ARGUMENT_i32_1]](s32), [[ARGUMENT_i32_2]](s32), [[ARGUMENT_i32_3]](s32)
|
||||
;
|
||||
; SIMD-LABEL: name: test_v4i32_arg
|
||||
; SIMD: bb.1 (%ir-block.0):
|
||||
; SIMD-NEXT: liveins: $arguments
|
||||
; SIMD-NEXT: {{ $}}
|
||||
; SIMD-NEXT: [[ARGUMENT_v4i32_:%[0-9]+]]:v128(<4 x s32>) = ARGUMENT_v4i32 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_v2i64_arg(<2 x i64> %arg) {
|
||||
; NO-SIMD-LABEL: name: test_v2i64_arg
|
||||
; NO-SIMD: bb.1 (%ir-block.0):
|
||||
; NO-SIMD-NEXT: liveins: $arguments
|
||||
; NO-SIMD-NEXT: {{ $}}
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[ARGUMENT_i64_]](s64), [[ARGUMENT_i64_1]](s64)
|
||||
;
|
||||
; SIMD-LABEL: name: test_v2i64_arg
|
||||
; SIMD: bb.1 (%ir-block.0):
|
||||
; SIMD-NEXT: liveins: $arguments
|
||||
; SIMD-NEXT: {{ $}}
|
||||
; SIMD-NEXT: [[ARGUMENT_v2i64_:%[0-9]+]]:v128(<2 x s64>) = ARGUMENT_v2i64 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_v8f16_arg(<8 x half> %arg) {
|
||||
; NO-SIMD-LABEL: name: test_v8f16_arg
|
||||
; NO-SIMD: bb.1 (%ir-block.0):
|
||||
; NO-SIMD-NEXT: liveins: $arguments
|
||||
; NO-SIMD-NEXT: {{ $}}
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_3:%[0-9]+]]:i32(s32) = ARGUMENT_i32 3, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_4:%[0-9]+]]:i32(s32) = ARGUMENT_i32 4, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_5:%[0-9]+]]:i32(s32) = ARGUMENT_i32 5, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_6:%[0-9]+]]:i32(s32) = ARGUMENT_i32 6, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_i32_7:%[0-9]+]]:i32(s32) = ARGUMENT_i32 7, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<8 x s32>) = G_BUILD_VECTOR [[ARGUMENT_i32_]](s32), [[ARGUMENT_i32_1]](s32), [[ARGUMENT_i32_2]](s32), [[ARGUMENT_i32_3]](s32), [[ARGUMENT_i32_4]](s32), [[ARGUMENT_i32_5]](s32), [[ARGUMENT_i32_6]](s32), [[ARGUMENT_i32_7]](s32)
|
||||
; NO-SIMD-NEXT: [[TRUNC:%[0-9]+]]:_(<8 x s16>) = G_TRUNC [[BUILD_VECTOR]](<8 x s32>)
|
||||
;
|
||||
; SIMD-NO-F16-LABEL: name: test_v8f16_arg
|
||||
; SIMD-NO-F16: bb.1 (%ir-block.0):
|
||||
; SIMD-NO-F16-NEXT: liveins: $arguments
|
||||
; SIMD-NO-F16-NEXT: {{ $}}
|
||||
; SIMD-NO-F16-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; SIMD-NO-F16-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
|
||||
; SIMD-NO-F16-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; SIMD-NO-F16-NEXT: [[ARGUMENT_i32_3:%[0-9]+]]:i32(s32) = ARGUMENT_i32 3, implicit $arguments
|
||||
; SIMD-NO-F16-NEXT: [[ARGUMENT_i32_4:%[0-9]+]]:i32(s32) = ARGUMENT_i32 4, implicit $arguments
|
||||
; SIMD-NO-F16-NEXT: [[ARGUMENT_i32_5:%[0-9]+]]:i32(s32) = ARGUMENT_i32 5, implicit $arguments
|
||||
; SIMD-NO-F16-NEXT: [[ARGUMENT_i32_6:%[0-9]+]]:i32(s32) = ARGUMENT_i32 6, implicit $arguments
|
||||
; SIMD-NO-F16-NEXT: [[ARGUMENT_i32_7:%[0-9]+]]:i32(s32) = ARGUMENT_i32 7, implicit $arguments
|
||||
; SIMD-NO-F16-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<8 x s32>) = G_BUILD_VECTOR [[ARGUMENT_i32_]](s32), [[ARGUMENT_i32_1]](s32), [[ARGUMENT_i32_2]](s32), [[ARGUMENT_i32_3]](s32), [[ARGUMENT_i32_4]](s32), [[ARGUMENT_i32_5]](s32), [[ARGUMENT_i32_6]](s32), [[ARGUMENT_i32_7]](s32)
|
||||
; SIMD-NO-F16-NEXT: [[TRUNC:%[0-9]+]]:_(<8 x s16>) = G_TRUNC [[BUILD_VECTOR]](<8 x s32>)
|
||||
;
|
||||
; SIMD-F16-LABEL: name: test_v8f16_arg
|
||||
; SIMD-F16: bb.1 (%ir-block.0):
|
||||
; SIMD-F16-NEXT: liveins: $arguments
|
||||
; SIMD-F16-NEXT: {{ $}}
|
||||
; SIMD-F16-NEXT: [[ARGUMENT_v8f16_:%[0-9]+]]:v128(<8 x s16>) = ARGUMENT_v8f16 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_v4f32_arg(<4 x float> %arg) {
|
||||
; NO-SIMD-LABEL: name: test_v4f32_arg
|
||||
; NO-SIMD: bb.1 (%ir-block.0):
|
||||
; NO-SIMD-NEXT: liveins: $arguments
|
||||
; NO-SIMD-NEXT: {{ $}}
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 0, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_f32_1:%[0-9]+]]:f32(s32) = ARGUMENT_f32 1, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_f32_2:%[0-9]+]]:f32(s32) = ARGUMENT_f32 2, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_f32_3:%[0-9]+]]:f32(s32) = ARGUMENT_f32 3, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[ARGUMENT_f32_]](s32), [[ARGUMENT_f32_1]](s32), [[ARGUMENT_f32_2]](s32), [[ARGUMENT_f32_3]](s32)
|
||||
;
|
||||
; SIMD-LABEL: name: test_v4f32_arg
|
||||
; SIMD: bb.1 (%ir-block.0):
|
||||
; SIMD-NEXT: liveins: $arguments
|
||||
; SIMD-NEXT: {{ $}}
|
||||
; SIMD-NEXT: [[ARGUMENT_v4f32_:%[0-9]+]]:v128(<4 x s32>) = ARGUMENT_v4f32 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_v2f64_arg(<2 x double> %arg) {
|
||||
; NO-SIMD-LABEL: name: test_v2f64_arg
|
||||
; NO-SIMD: bb.1 (%ir-block.0):
|
||||
; NO-SIMD-NEXT: liveins: $arguments
|
||||
; NO-SIMD-NEXT: {{ $}}
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_f64_:%[0-9]+]]:f64(s64) = ARGUMENT_f64 0, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[ARGUMENT_f64_1:%[0-9]+]]:f64(s64) = ARGUMENT_f64 1, implicit $arguments
|
||||
; NO-SIMD-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[ARGUMENT_f64_]](s64), [[ARGUMENT_f64_1]](s64)
|
||||
;
|
||||
; SIMD-LABEL: name: test_v2f64_arg
|
||||
; SIMD: bb.1 (%ir-block.0):
|
||||
; SIMD-NEXT: liveins: $arguments
|
||||
; SIMD-NEXT: {{ $}}
|
||||
; SIMD-NEXT: [[ARGUMENT_v2f64_:%[0-9]+]]:v128(<2 x s64>) = ARGUMENT_v2f64 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
; RUN: llc -mtriple=wasm32 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck %s -check-prefixes=CHECK,WASM32
|
||||
; RUN: llc -mtriple=wasm64 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck %s -check-prefixes=CHECK,WASM64
|
||||
|
||||
define swiftcc void @test_implicit_self_and_error(float %arg) {
|
||||
; CHECK-LABEL: name: test_implicit_self_and_error
|
||||
|
||||
; CHECK: machineFunctionInfo:
|
||||
; WASM32-NEXT: params: [ f32, i32, i32 ]
|
||||
; WASM64-NEXT: params: [ f32, i64, i64 ]
|
||||
; CHECK-NEXT: results: [ ]
|
||||
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define swiftcc void @test_explicit_self_and_implicit_error(ptr swiftself %self, float %arg) {
|
||||
; CHECK-LABEL: name: test_explicit_self_and_implicit_error
|
||||
|
||||
|
||||
; CHECK: machineFunctionInfo:
|
||||
; WASM32-NEXT: params: [ i32, f32, i32 ]
|
||||
; WASM64-NEXT: params: [ i64, f32, i64 ]
|
||||
; CHECK-NEXT: results: [ ]
|
||||
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; WASM32-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(p0) = ARGUMENT_i32 0, implicit $arguments
|
||||
; WASM64-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(p0) = ARGUMENT_i64 0, implicit $arguments
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 1, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define swiftcc void @test_implicit_self_and_explicit_error(ptr swifterror %error, float %arg) {
|
||||
; CHECK-LABEL: name: test_implicit_self_and_explicit_error
|
||||
|
||||
|
||||
; CHECK: machineFunctionInfo:
|
||||
; WASM32-NEXT: params: [ i32, f32, i32 ]
|
||||
; WASM64-NEXT: params: [ i64, f32, i64 ]
|
||||
; CHECK-NEXT: results: [ ]
|
||||
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; WASM32-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(p0) = ARGUMENT_i32 0, implicit $arguments
|
||||
; WASM64-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(p0) = ARGUMENT_i64 0, implicit $arguments
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 1, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define swiftcc void @test_explicit_self_and_error(ptr swiftself %self, ptr swifterror %error, float %arg) {
|
||||
; CHECK-LABEL: name: test_explicit_self_and_error
|
||||
|
||||
|
||||
; CHECK: machineFunctionInfo:
|
||||
; WASM32-NEXT: params: [ i32, i32, f32 ]
|
||||
; WASM64-NEXT: params: [ i64, i64, f32 ]
|
||||
; CHECK-NEXT: results: [ ]
|
||||
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; WASM32-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(p0) = ARGUMENT_i32 0, implicit $arguments
|
||||
; WASM32-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(p0) = ARGUMENT_i32 1, implicit $arguments
|
||||
; WASM64-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(p0) = ARGUMENT_i64 0, implicit $arguments
|
||||
; WASM64-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(p0) = ARGUMENT_i64 1, implicit $arguments
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 2, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
209
llvm/test/CodeGen/WebAssembly/GlobalISel/irtranslator/args.ll
Normal file
209
llvm/test/CodeGen/WebAssembly/GlobalISel/irtranslator/args.ll
Normal file
@@ -0,0 +1,209 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: llc -mtriple=wasm32 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck %s -check-prefixes=CHECK,WASM32
|
||||
; RUN: llc -mtriple=wasm64 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck %s -check-prefixes=CHECK,WASM64
|
||||
|
||||
define void @test_i8_arg(i8 %arg) {
|
||||
; CHECK-LABEL: name: test_i8_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ARGUMENT_i32_]](s32)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_i8_zeroext_arg(i8 zeroext %arg) {
|
||||
; CHECK-LABEL: name: test_i8_zeroext_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[ARGUMENT_i32_]], 8
|
||||
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_ZEXT]](s32)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_i8_signext_arg(i8 signext %arg) {
|
||||
; CHECK-LABEL: name: test_i8_signext_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[ARGUMENT_i32_]], 8
|
||||
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_SEXT]](s32)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_i16_arg(i16 %arg) {
|
||||
; CHECK-LABEL: name: test_i16_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[ARGUMENT_i32_]](s32)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
define void @test_i32_arg(i32 %arg) {
|
||||
; CHECK-LABEL: name: test_i32_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
define void @test_i64_arg(i64 %arg) {
|
||||
; CHECK-LABEL: name: test_i64_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_ptr_arg(ptr %arg) {
|
||||
; WASM32-LABEL: name: test_ptr_arg
|
||||
; WASM32: bb.1 (%ir-block.0):
|
||||
; WASM32-NEXT: liveins: $arguments
|
||||
; WASM32-NEXT: {{ $}}
|
||||
; WASM32-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(p0) = ARGUMENT_i32 0, implicit $arguments
|
||||
;
|
||||
; WASM64-LABEL: name: test_ptr_arg
|
||||
; WASM64: bb.1 (%ir-block.0):
|
||||
; WASM64-NEXT: liveins: $arguments
|
||||
; WASM64-NEXT: {{ $}}
|
||||
; WASM64-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(p0) = ARGUMENT_i64 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_i128_arg(i128 %arg) {
|
||||
; CHECK-LABEL: name: test_i128_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
|
||||
; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
|
||||
; CHECK-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[ARGUMENT_i64_]](s64), [[ARGUMENT_i64_1]](s64)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_f16_arg(half %arg) {
|
||||
; CHECK-LABEL: name: test_f16_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[ARGUMENT_i32_]](s32)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
define void @test_f32_arg(float %arg) {
|
||||
; CHECK-LABEL: name: test_f32_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
define void @test_f64_arg(double %arg) {
|
||||
; CHECK-LABEL: name: test_f64_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_f64_:%[0-9]+]]:f64(s64) = ARGUMENT_f64 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_f128_arg(fp128 %arg) {
|
||||
; CHECK-LABEL: name: test_f128_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 0, implicit $arguments
|
||||
; CHECK-NEXT: [[ARGUMENT_i64_1:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
|
||||
; CHECK-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[ARGUMENT_i64_]](s64), [[ARGUMENT_i64_1]](s64)
|
||||
ret void
|
||||
}
|
||||
|
||||
%externref = type ptr addrspace(10)
|
||||
define void @test_externref_arg(%externref %arg) {
|
||||
; CHECK-LABEL: name: test_externref_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_externref:%[0-9]+]]:externref(p10) = ARGUMENT_externref 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
%funcref = type ptr addrspace(20)
|
||||
define void @test_funcref_arg(%funcref %arg) {
|
||||
; CHECK-LABEL: name: test_funcref_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_funcref:%[0-9]+]]:funcref(p20) = ARGUMENT_funcref 0, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_multiple_args(ptr %arg1, float %arg2, i1 %arg3) {
|
||||
; WASM32-LABEL: name: test_multiple_args
|
||||
; WASM32: bb.1 (%ir-block.0):
|
||||
; WASM32-NEXT: liveins: $arguments
|
||||
; WASM32-NEXT: {{ $}}
|
||||
; WASM32-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(p0) = ARGUMENT_i32 0, implicit $arguments
|
||||
; WASM32-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 1, implicit $arguments
|
||||
; WASM32-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; WASM32-NEXT: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ARGUMENT_i32_1]](s32)
|
||||
;
|
||||
; WASM64-LABEL: name: test_multiple_args
|
||||
; WASM64: bb.1 (%ir-block.0):
|
||||
; WASM64-NEXT: liveins: $arguments
|
||||
; WASM64-NEXT: {{ $}}
|
||||
; WASM64-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(p0) = ARGUMENT_i64 0, implicit $arguments
|
||||
; WASM64-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 1, implicit $arguments
|
||||
; WASM64-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; WASM64-NEXT: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ARGUMENT_i32_]](s32)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_array_arg([5 x i16] %arg) {
|
||||
; CHECK-LABEL: name: test_array_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[ARGUMENT_i32_]](s32)
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 1, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[ARGUMENT_i32_1]](s32)
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s16) = G_TRUNC [[ARGUMENT_i32_2]](s32)
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_3:%[0-9]+]]:i32(s32) = ARGUMENT_i32 3, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s16) = G_TRUNC [[ARGUMENT_i32_3]](s32)
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_4:%[0-9]+]]:i32(s32) = ARGUMENT_i32 4, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC4:%[0-9]+]]:_(s16) = G_TRUNC [[ARGUMENT_i32_4]](s32)
|
||||
ret void
|
||||
}
|
||||
|
||||
%StructTy = type { i8, i64, i16, i1, float }
|
||||
|
||||
define void @test_struct_arg(%StructTy %arg) {
|
||||
; CHECK-LABEL: name: test_struct_arg
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK-NEXT: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_:%[0-9]+]]:i32(s32) = ARGUMENT_i32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ARGUMENT_i32_]](s32)
|
||||
; CHECK-NEXT: [[ARGUMENT_i64_:%[0-9]+]]:i64(s64) = ARGUMENT_i64 1, implicit $arguments
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_1:%[0-9]+]]:i32(s32) = ARGUMENT_i32 2, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[ARGUMENT_i32_1]](s32)
|
||||
; CHECK-NEXT: [[ARGUMENT_i32_2:%[0-9]+]]:i32(s32) = ARGUMENT_i32 3, implicit $arguments
|
||||
; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s1) = G_TRUNC [[ARGUMENT_i32_2]](s32)
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32(s32) = ARGUMENT_f32 4, implicit $arguments
|
||||
ret void
|
||||
}
|
||||
Reference in New Issue
Block a user