[clang] [llvm] [RISCV] Add support for quadruple-precision floating point ABIs (PR #195166)
Gábor Spaits via llvm-commits
llvm-commits at lists.llvm.org
Wed May 6 03:50:25 PDT 2026
https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/195166
>From 33693908c1e22ac5043b530a0ec3113e03c1b46b Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Thu, 30 Apr 2026 09:48:04 +0200
Subject: [PATCH 1/5] [RISCV][GISel] Add support for quad precision floating
point ABIs
Adding support for ilp32q and lp64q.
---
clang/lib/Basic/Targets/RISCV.cpp | 2 +
clang/lib/Basic/Targets/RISCV.h | 6 +-
llvm/lib/CodeGen/GlobalISel/CallLowering.cpp | 1 +
.../Target/RISCV/GISel/RISCVCallLowering.cpp | 39 +-
.../RISCV/MCTargetDesc/RISCVBaseInfo.cpp | 2 +
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 2 +
.../RISCV/MCTargetDesc/RISCVELFStreamer.cpp | 4 +
llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 46 +-
llvm/lib/Target/RISCV/RISCVCallingConv.td | 7 +
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 10 +
llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 10 +
llvm/lib/TargetParser/RISCVISAInfo.cpp | 4 +
...calling-conv-ilp32-ilp32f-ilp32d-common.ll | 1188 +------------
...-conv-ilp32-ilp32f-ilp32d-ilp32q-common.ll | 1531 +++++++++++++++++
.../calling-conv-ilp32d-ilp32q.ll | 555 ++++++
.../irtranslator/calling-conv-ilp32d.ll | 376 ----
...lling-conv-ilp32f-ilp32d-ilp32q-common.ll} | 308 +++-
.../irtranslator/calling-conv-ilp32q.ll | 436 +++++
.../irtranslator/calling-conv-lp64d-lp64q.ll | 415 +++++
.../irtranslator/calling-conv-lp64d.ll | 283 ---
.../irtranslator/calling-conv-lp64q.ll | 331 ++++
21 files changed, 3603 insertions(+), 1953 deletions(-)
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-ilp32q-common.ll
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32d-ilp32q.ll
delete mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32d.ll
rename llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/{calling-conv-ilp32f-ilp32d-common.ll => calling-conv-ilp32f-ilp32d-ilp32q-common.ll} (57%)
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64d-lp64q.ll
delete mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64d.ll
create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index 685925b0773dc..a531ee9302442 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -168,6 +168,8 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__riscv_float_abi_single");
else if (ABIName == "ilp32d" || ABIName == "lp64d")
Builder.defineMacro("__riscv_float_abi_double");
+ else if (ABIName == "ilp32q" || ABIName == "lp64q")
+ Builder.defineMacro("__riscv_float_abi_quad");
else
Builder.defineMacro("__riscv_float_abi_soft");
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 619d491d379d3..c02dbe11c92a4 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -189,7 +189,8 @@ class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
return true;
}
- if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
+ if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d" ||
+ Name == "ilp32q") {
ABI = Name;
return true;
}
@@ -220,7 +221,8 @@ class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
return true;
}
- if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
+ if (Name == "lp64" || Name == "lp64f" || Name == "lp64d" ||
+ Name == "lp64q") {
ABI = Name;
return true;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index 16549c1047213..b0bf4b684bf6d 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -1347,6 +1347,7 @@ Register CallLowering::ValueHandler::extendRegister(Register ValReg,
break;
case CCValAssign::Full:
case CCValAssign::BCvt:
+ case CCValAssign::Indirect:
// FIXME: bitconverting between vector types may or may not be a
// nop in big-endian situations.
return ValReg;
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
index 60743679f0685..58100331e0f3b 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
@@ -21,6 +21,7 @@
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -102,12 +103,19 @@ struct RISCVOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
assert(VA.getValNo() == VAHi.getValNo() &&
"Values belong to different arguments");
- assert(VA.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
- VA.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&
- "unexpected custom value");
-
- Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
- MRI.createGenericVirtualRegister(LLT::scalar(32))};
+ uint32_t RegWidth = 0;
+ if (VA.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
+ VA.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64)
+ RegWidth = 32;
+ else if (VA.getLocVT() == MVT::i64 && VAHi.getLocVT() == MVT::i64 &&
+ VA.getValVT() == MVT::f128 && VAHi.getValVT() == MVT::f128)
+ RegWidth = 64;
+ else
+ llvm_unreachable("Unexpected custom value");
+
+ Register NewRegs[] = {
+ MRI.createGenericVirtualRegister(LLT::scalar(RegWidth)),
+ MRI.createGenericVirtualRegister(LLT::scalar(RegWidth))};
MIRBuilder.buildUnmerge(NewRegs, Arg.Regs[0]);
if (VAHi.isMemLoc()) {
@@ -201,12 +209,19 @@ struct RISCVIncomingValueHandler : public CallLowering::IncomingValueHandler {
assert(VA.getValNo() == VAHi.getValNo() &&
"Values belong to different arguments");
- assert(VA.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
- VA.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&
- "unexpected custom value");
-
- Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
- MRI.createGenericVirtualRegister(LLT::scalar(32))};
+ uint32_t RegWidth = 0;
+ if (VA.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&
+ VA.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64)
+ RegWidth = 32;
+ else if (VA.getLocVT() == MVT::i64 && VAHi.getLocVT() == MVT::i64 &&
+ VA.getValVT() == MVT::f128 && VAHi.getValVT() == MVT::f128)
+ RegWidth = 64;
+ else
+ llvm_unreachable("Unexpected custom value");
+
+ Register NewRegs[] = {
+ MRI.createGenericVirtualRegister(LLT::scalar(RegWidth)),
+ MRI.createGenericVirtualRegister(LLT::scalar(RegWidth))};
if (VAHi.isMemLoc()) {
LLT MemTy(VAHi.getLocVT());
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
index 62cd6cca49c0e..ac083d98c8d8b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
@@ -106,10 +106,12 @@ ABI getTargetABI(StringRef ABIName) {
.Case("ilp32", ABI_ILP32)
.Case("ilp32f", ABI_ILP32F)
.Case("ilp32d", ABI_ILP32D)
+ .Case("ilp32q", ABI_ILP32Q)
.Case("ilp32e", ABI_ILP32E)
.Case("lp64", ABI_LP64)
.Case("lp64f", ABI_LP64F)
.Case("lp64d", ABI_LP64D)
+ .Case("lp64q", ABI_LP64Q)
.Case("lp64e", ABI_LP64E)
.Default(ABI_Unknown);
return TargetABI;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index b5aade96d4093..1f9c9d16e5bbd 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -666,10 +666,12 @@ enum ABI {
ABI_ILP32,
ABI_ILP32F,
ABI_ILP32D,
+ ABI_ILP32Q,
ABI_ILP32E,
ABI_LP64,
ABI_LP64F,
ABI_LP64D,
+ ABI_LP64Q,
ABI_LP64E,
ABI_Unknown
};
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 0ca07350d24a0..9f36c0549d9a8 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -133,6 +133,10 @@ void RISCVTargetELFStreamer::finish() {
case RISCVABI::ABI_LP64D:
EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
break;
+ case RISCVABI::ABI_ILP32Q:
+ case RISCVABI::ABI_LP64Q:
+ EFlags |= ELF::EF_RISCV_FLOAT_ABI_QUAD;
+ break;
case RISCVABI::ABI_ILP32E:
case RISCVABI::ABI_LP64E:
EFlags |= ELF::EF_RISCV_RVE;
diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
index 872a879dcf9c4..0fa74796d9ace 100644
--- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
+++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
@@ -11,8 +11,10 @@
//===----------------------------------------------------------------------===//
#include "RISCVCallingConv.h"
+#include "MCTargetDesc/RISCVBaseInfo.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVSubtarget.h"
+#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCRegister.h"
@@ -89,6 +91,9 @@ static const MCPhysReg ArgFPR32s[] = {RISCV::F10_F, RISCV::F11_F, RISCV::F12_F,
static const MCPhysReg ArgFPR64s[] = {RISCV::F10_D, RISCV::F11_D, RISCV::F12_D,
RISCV::F13_D, RISCV::F14_D, RISCV::F15_D,
RISCV::F16_D, RISCV::F17_D};
+static const MCPhysReg ArgFPR128s[] = {RISCV::F10_Q, RISCV::F11_Q, RISCV::F12_Q,
+ RISCV::F13_Q, RISCV::F14_Q, RISCV::F15_Q,
+ RISCV::F16_Q, RISCV::F17_Q};
// This is an interim calling convention and it may be changed in the future.
static const MCPhysReg ArgVRs[] = {
RISCV::V8, RISCV::V9, RISCV::V10, RISCV::V11, RISCV::V12, RISCV::V13,
@@ -410,6 +415,8 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
bool AllowFPRForF16_F32 = false;
// UseFPRForF64 if targeting an FLEN>=64 ABI and the argument isn't variadic.
bool AllowFPRForF64 = false;
+ // UseFPRForF64 if targeting an FLEN>=64 ABI and the argument isn't variadic.
+ bool AllowFPRForF128 = false;
RISCVABI::ABI ABI = Subtarget.getTargetABI();
switch (ABI) {
@@ -420,6 +427,10 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
case RISCVABI::ABI_LP64:
case RISCVABI::ABI_LP64E:
break;
+ case RISCVABI::ABI_ILP32Q:
+ case RISCVABI::ABI_LP64Q:
+ AllowFPRForF128 = !ArgFlags.isVarArg();
+ [[fallthrough]];
case RISCVABI::ABI_ILP32D:
case RISCVABI::ABI_LP64D:
AllowFPRForF64 = !ArgFlags.isVarArg();
@@ -451,6 +462,13 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
}
}
+ if (LocVT == MVT::f128 && AllowFPRForF128) {
+ if (MCRegister Reg = State.AllocateReg(ArgFPR128s)) {
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+ return false;
+ }
+ }
+
if (LocVT == MVT::f16 && Subtarget.hasStdExtZhinxmin()) {
if (MCRegister Reg = State.AllocateReg(getArgGPR16s(ABI))) {
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
@@ -523,9 +541,25 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
assert(PendingLocs.size() == PendingArgFlags.size() &&
"PendingLocs and PendingArgFlags out of sync");
+ // If f128 cannot be passed in an FPR on RV32, it is passed according to the
+ // integer calling convention. Since it is larger than 2*XLEN, pass it by
+ // reference.
+ if (XLen == 32 && LocVT == MVT::f128) {
+ LocVT = XLenVT;
+ LocInfo = CCValAssign::Indirect;
+ if (MCRegister Reg = State.AllocateReg(ArgGPRs))
+ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+ else {
+ int64_t StackOffset = State.AllocateStack(4, Align(4));
+ State.addLoc(
+ CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
+ }
+ return false;
+ }
+
// Handle passing f64 on RV32D with a soft float ABI or when floating point
// registers are exhausted.
- if (XLen == 32 && LocVT == MVT::f64) {
+ if ((XLen == 32 && LocVT == MVT::f64) || (XLen == 64 && LocVT == MVT::f128)) {
assert(PendingLocs.empty() && "Can't lower f64 if it is split");
// Depending on available argument GPRS, f64 may be passed in a pair of
// GPRs, split between a GPR and the stack, or passed completely on the
@@ -533,19 +567,23 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
// cases.
MCRegister Reg = State.AllocateReg(ArgGPRs);
if (!Reg) {
- int64_t StackOffset = State.AllocateStack(8, Align(8));
+ uint32_t AlignForStoredValue = LocVT.getSizeInBits() / 8;
+ int64_t StackOffset =
+ State.AllocateStack(AlignForStoredValue, Align(AlignForStoredValue));
State.addLoc(
CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
return false;
}
- LocVT = MVT::i32;
+ LocVT = XLenVT;
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
MCRegister HiReg = State.AllocateReg(ArgGPRs);
if (HiReg) {
State.addLoc(
CCValAssign::getCustomReg(ValNo, ValVT, HiReg, LocVT, LocInfo));
} else {
- int64_t StackOffset = State.AllocateStack(4, Align(4));
+ uint32_t AlignForStoredValue = LocVT.getSizeInBits() / 8;
+ int64_t StackOffset =
+ State.AllocateStack(AlignForStoredValue, Align(AlignForStoredValue));
State.addLoc(
CCValAssign::getCustomMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
}
diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.td b/llvm/lib/Target/RISCV/RISCVCallingConv.td
index da6b95da12160..843a4ac7e22b9 100644
--- a/llvm/lib/Target/RISCV/RISCVCallingConv.td
+++ b/llvm/lib/Target/RISCV/RISCVCallingConv.td
@@ -26,6 +26,10 @@ def CSR_ILP32D_LP64D
: CalleeSavedRegs<(add CSR_ILP32_LP64,
F8_D, F9_D, (sequence "F%u_D", 18, 27))>;
+def CSR_ILP32Q_LP64Q
+ : CalleeSavedRegs<(add CSR_ILP32_LP64,
+ F8_Q, F9_Q, (sequence "F%u_Q", 18, 27))>;
+
defvar CSR_V = (add (sequence "V%u", 1, 7), (sequence "V%u", 24, 31),
V2M2, V4M2, V6M2, V24M2, V26M2, V28M2, V30M2,
V4M4, V24M4, V28M4, V24M8);
@@ -39,6 +43,9 @@ def CSR_ILP32F_LP64F_V
def CSR_ILP32D_LP64D_V
: CalleeSavedRegs<(add CSR_ILP32D_LP64D, CSR_V)>;
+def CSR_ILP32Q_LP64Q_V
+ : CalleeSavedRegs<(add CSR_ILP32Q_LP64Q, CSR_V)>;
+
// Needed for implementation of RISCVRegisterInfo::getNoPreservedMask()
def CSR_NoRegs : CalleeSavedRegs<(add)>;
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index d126616312748..f178513f9b589 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -114,6 +114,12 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
"doesn't support the D instruction set extension (ignoring "
"target-abi)\n";
ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32;
+ } else if ((ABI == RISCVABI::ABI_ILP32Q || ABI == RISCVABI::ABI_LP64Q) &&
+ !Subtarget.hasStdExtQ()) {
+ errs() << "Hard-float 'q' ABI can't be used for a target that "
+ "doesn't support the Q instruction set extension (ignoring "
+ "target-abi)\n";
+ ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32;
}
switch (ABI) {
@@ -124,9 +130,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
case RISCVABI::ABI_LP64E:
case RISCVABI::ABI_ILP32F:
case RISCVABI::ABI_ILP32D:
+ case RISCVABI::ABI_ILP32Q:
case RISCVABI::ABI_LP64:
case RISCVABI::ABI_LP64F:
case RISCVABI::ABI_LP64D:
+ case RISCVABI::ABI_LP64Q:
break;
}
@@ -143,6 +151,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
addRegisterClass(MVT::f32, &RISCV::FPR32RegClass);
if (Subtarget.hasStdExtD())
addRegisterClass(MVT::f64, &RISCV::FPR64RegClass);
+ if (Subtarget.hasStdExtQ())
+ addRegisterClass(MVT::f128, &RISCV::FPR128RegClass);
if (Subtarget.hasStdExtZhinxmin())
addRegisterClass(MVT::f16, &RISCV::GPRF16RegClass);
if (Subtarget.hasStdExtZfinx())
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 6baa30cf9e6f6..c063f385f94e5 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -117,6 +117,11 @@ RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
if (HasVectorCSR)
return CSR_ILP32D_LP64D_V_SaveList;
return CSR_ILP32D_LP64D_SaveList;
+ case RISCVABI::ABI_ILP32Q:
+ case RISCVABI::ABI_LP64Q:
+ if (HasVectorCSR)
+ return CSR_ILP32Q_LP64Q_V_SaveList;
+ return CSR_ILP32Q_LP64Q_SaveList;
}
}
@@ -849,6 +854,11 @@ RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & MF,
if (CC == CallingConv::RISCV_VectorCall)
return CSR_ILP32D_LP64D_V_RegMask;
return CSR_ILP32D_LP64D_RegMask;
+ case RISCVABI::ABI_ILP32Q:
+ case RISCVABI::ABI_LP64Q:
+ if (CC == CallingConv::RISCV_VectorCall)
+ return CSR_ILP32D_LP64D_V_RegMask;
+ return CSR_ILP32Q_LP64Q_RegMask;
}
}
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 973f81d25b321..590c351fa59f7 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -1038,6 +1038,8 @@ StringRef RISCVISAInfo::computeDefaultABI() const {
return "ilp32d";
if (Exts.count("f"))
return "ilp32f";
+ if (Exts.count("q"))
+ return "ilp32q";
return "ilp32";
} else if (XLen == 64) {
if (Exts.count("e"))
@@ -1046,6 +1048,8 @@ StringRef RISCVISAInfo::computeDefaultABI() const {
return "lp64d";
if (Exts.count("f"))
return "lp64f";
+ if (Exts.count("q"))
+ return "lp64q";
return "lp64";
}
llvm_unreachable("Invalid XLEN");
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-common.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-common.ll
index 3225120219c0a..f8b5f08d02c46 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-common.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-common.ll
@@ -13,819 +13,6 @@
; ilp32f, and ilp32d ABIs. i.e. where no arguments are passed according to
; the floating point ABI.
-; Check that on RV32, i64 is passed in a pair of registers. Unlike
-; the convention for varargs, this need not be an aligned pair.
-
-define i32 @callee_i64_in_regs(i32 %a, i64 %b) nounwind {
- ; RV32I-LABEL: name: callee_i64_in_regs
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10, $x11, $x12
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
- ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[TRUNC]]
- ; RV32I-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32I-NEXT: PseudoRET implicit $x10
- %b_trunc = trunc i64 %b to i32
- %1 = add i32 %a, %b_trunc
- ret i32 %1
-}
-
-define i32 @caller_i64_in_regs() nounwind {
- ; ILP32-LABEL: name: caller_i64_in_regs
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
- ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
- ; ILP32-NEXT: $x10 = COPY [[C]](s32)
- ; ILP32-NEXT: $x11 = COPY [[UV]](s32)
- ; ILP32-NEXT: $x12 = COPY [[UV1]](s32)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
- ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: $x10 = COPY [[COPY]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_i64_in_regs
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
- ; ILP32F-NEXT: $x10 = COPY [[C]](s32)
- ; ILP32F-NEXT: $x11 = COPY [[UV]](s32)
- ; ILP32F-NEXT: $x12 = COPY [[UV1]](s32)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
- ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: $x10 = COPY [[COPY]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_i64_in_regs
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
- ; ILP32D-NEXT: $x10 = COPY [[C]](s32)
- ; ILP32D-NEXT: $x11 = COPY [[UV]](s32)
- ; ILP32D-NEXT: $x12 = COPY [[UV1]](s32)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
- ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_i64_in_regs(i32 1, i64 2)
- ret i32 %1
-}
-
-; Check the correct handling of passing of values that are larger that 2*XLen.
-
-define i64 @callee_128i_indirect_reference_in_stack(i64 %x1, i64 %x2, i64 %x3, i64 %x4, i128 %y, i128 %y2) {
- ; RV32I-LABEL: name: callee_128i_indirect_reference_in_stack
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
- ; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
- ; RV32I-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
- ; RV32I-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
- ; RV32I-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
- ; RV32I-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
- ; RV32I-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
- ; RV32I-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
- ; RV32I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
- ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.1, align 16)
- ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[LOAD]](p0) :: (load (s128), align 8)
- ; RV32I-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV32I-NEXT: [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (p0) from %fixed-stack.0)
- ; RV32I-NEXT: [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[LOAD2]](p0) :: (load (s128), align 8)
- ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s128) = G_ADD [[LOAD1]], [[LOAD3]]
- ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[ADD]](s128)
- ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[TRUNC]](s64)
- ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
- %1 = add i128 %y, %y2
- %2 = trunc i128 %1 to i64
- ret i64 %2
-}
-
-define i32 @callee_128i_indirect_refernce_in_stack( ) {
- ; ILP32-LABEL: name: callee_128i_indirect_refernce_in_stack
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
- ; ILP32-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
- ; ILP32-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s32)
- ; ILP32-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
- ; ILP32-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32-NEXT: G_STORE [[C2]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
- ; ILP32-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s32)
- ; ILP32-NEXT: G_STORE [[FRAME_INDEX1]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
- ; ILP32-NEXT: $x10 = COPY [[UV]](s32)
- ; ILP32-NEXT: $x11 = COPY [[UV1]](s32)
- ; ILP32-NEXT: $x12 = COPY [[UV2]](s32)
- ; ILP32-NEXT: $x13 = COPY [[UV3]](s32)
- ; ILP32-NEXT: $x14 = COPY [[UV4]](s32)
- ; ILP32-NEXT: $x15 = COPY [[UV5]](s32)
- ; ILP32-NEXT: $x16 = COPY [[UV6]](s32)
- ; ILP32-NEXT: $x17 = COPY [[UV7]](s32)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
- ; ILP32-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
- ; ILP32-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: callee_128i_indirect_refernce_in_stack
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
- ; ILP32F-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32F-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32F-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32F-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32F-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32F-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s32)
- ; ILP32F-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
- ; ILP32F-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32F-NEXT: G_STORE [[C2]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
- ; ILP32F-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32F-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s32)
- ; ILP32F-NEXT: G_STORE [[FRAME_INDEX1]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
- ; ILP32F-NEXT: $x10 = COPY [[UV]](s32)
- ; ILP32F-NEXT: $x11 = COPY [[UV1]](s32)
- ; ILP32F-NEXT: $x12 = COPY [[UV2]](s32)
- ; ILP32F-NEXT: $x13 = COPY [[UV3]](s32)
- ; ILP32F-NEXT: $x14 = COPY [[UV4]](s32)
- ; ILP32F-NEXT: $x15 = COPY [[UV5]](s32)
- ; ILP32F-NEXT: $x16 = COPY [[UV6]](s32)
- ; ILP32F-NEXT: $x17 = COPY [[UV7]](s32)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
- ; ILP32F-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
- ; ILP32F-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32F-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: callee_128i_indirect_refernce_in_stack
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
- ; ILP32D-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32D-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32D-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s32)
- ; ILP32D-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
- ; ILP32D-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32D-NEXT: G_STORE [[C2]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
- ; ILP32D-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32D-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s32)
- ; ILP32D-NEXT: G_STORE [[FRAME_INDEX1]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
- ; ILP32D-NEXT: $x10 = COPY [[UV]](s32)
- ; ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
- ; ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
- ; ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
- ; ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
- ; ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
- ; ILP32D-NEXT: $x16 = COPY [[UV6]](s32)
- ; ILP32D-NEXT: $x17 = COPY [[UV7]](s32)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
- ; ILP32D-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
- ; ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i64 @callee_128i_indirect_reference_in_stack(i64 1,i64 1, i64 1, i64 1, i128 2, i128 42)
- %2 = trunc i64 %1 to i32
- ret i32 %2
-}
-
-define i64 @callee_128i_indirect_reference_in_stack_not_first(i64 %x0, i64 %x1, i64 %x2, i64 %x4, i64 %x5, i64 %x6, i64 %x7, i64 %x8, i128 %y ) {
- ; RV32I-LABEL: name: callee_128i_indirect_reference_in_stack_not_first
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
- ; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
- ; RV32I-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
- ; RV32I-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
- ; RV32I-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
- ; RV32I-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
- ; RV32I-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
- ; RV32I-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
- ; RV32I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.8
- ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.8, align 16)
- ; RV32I-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
- ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.7)
- ; RV32I-NEXT: [[MV4:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD]](s32), [[LOAD1]](s32)
- ; RV32I-NEXT: [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
- ; RV32I-NEXT: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %fixed-stack.6, align 8)
- ; RV32I-NEXT: [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
- ; RV32I-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (s32) from %fixed-stack.5)
- ; RV32I-NEXT: [[MV5:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD2]](s32), [[LOAD3]](s32)
- ; RV32I-NEXT: [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
- ; RV32I-NEXT: [[LOAD4:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s32) from %fixed-stack.4, align 16)
- ; RV32I-NEXT: [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
- ; RV32I-NEXT: [[LOAD5:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (s32) from %fixed-stack.3)
- ; RV32I-NEXT: [[MV6:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD4]](s32), [[LOAD5]](s32)
- ; RV32I-NEXT: [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
- ; RV32I-NEXT: [[LOAD6:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (s32) from %fixed-stack.2, align 8)
- ; RV32I-NEXT: [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
- ; RV32I-NEXT: [[LOAD7:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (s32) from %fixed-stack.1)
- ; RV32I-NEXT: [[MV7:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD6]](s32), [[LOAD7]](s32)
- ; RV32I-NEXT: [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV32I-NEXT: [[LOAD8:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX8]](p0) :: (load (p0) from %fixed-stack.0, align 16)
- ; RV32I-NEXT: [[LOAD9:%[0-9]+]]:_(s128) = G_LOAD [[LOAD8]](p0) :: (load (s128), align 8)
- ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[LOAD9]](s128)
- ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[TRUNC]](s64)
- ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
- %2 = trunc i128 %y to i64
- ret i64 %2
-}
-
-define i32 @caller_128i_indirect_reference_in_stack_not_first() {
- ; ILP32-LABEL: name: caller_128i_indirect_reference_in_stack_not_first
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
- ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; ILP32-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
- ; ILP32-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
- ; ILP32-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
- ; ILP32-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
- ; ILP32-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 6
- ; ILP32-NEXT: [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
- ; ILP32-NEXT: [[C8:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
- ; ILP32-NEXT: ADJCALLSTACKDOWN 36, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
- ; ILP32-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
- ; ILP32-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
- ; ILP32-NEXT: [[UV8:%[0-9]+]]:_(s32), [[UV9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
- ; ILP32-NEXT: G_STORE [[UV8]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
- ; ILP32-NEXT: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s32)
- ; ILP32-NEXT: G_STORE [[UV9]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
- ; ILP32-NEXT: [[UV10:%[0-9]+]]:_(s32), [[UV11:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C5]](s64)
- ; ILP32-NEXT: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s32)
- ; ILP32-NEXT: G_STORE [[UV10]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 8, align 8)
- ; ILP32-NEXT: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32-NEXT: [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s32)
- ; ILP32-NEXT: G_STORE [[UV11]](s32), [[PTR_ADD3]](p0) :: (store (s32) into stack + 12)
- ; ILP32-NEXT: [[UV12:%[0-9]+]]:_(s32), [[UV13:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
- ; ILP32-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
- ; ILP32-NEXT: [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
- ; ILP32-NEXT: G_STORE [[UV12]](s32), [[PTR_ADD4]](p0) :: (store (s32) into stack + 16, align 16)
- ; ILP32-NEXT: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
- ; ILP32-NEXT: [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
- ; ILP32-NEXT: G_STORE [[UV13]](s32), [[PTR_ADD5]](p0) :: (store (s32) into stack + 20)
- ; ILP32-NEXT: [[UV14:%[0-9]+]]:_(s32), [[UV15:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C7]](s64)
- ; ILP32-NEXT: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
- ; ILP32-NEXT: [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
- ; ILP32-NEXT: G_STORE [[UV14]](s32), [[PTR_ADD6]](p0) :: (store (s32) into stack + 24, align 8)
- ; ILP32-NEXT: [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
- ; ILP32-NEXT: [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
- ; ILP32-NEXT: G_STORE [[UV15]](s32), [[PTR_ADD7]](p0) :: (store (s32) into stack + 28)
- ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32-NEXT: G_STORE [[C8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32-NEXT: [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
- ; ILP32-NEXT: [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
- ; ILP32-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 32, align 16)
- ; ILP32-NEXT: $x10 = COPY [[UV]](s32)
- ; ILP32-NEXT: $x11 = COPY [[UV1]](s32)
- ; ILP32-NEXT: $x12 = COPY [[UV2]](s32)
- ; ILP32-NEXT: $x13 = COPY [[UV3]](s32)
- ; ILP32-NEXT: $x14 = COPY [[UV4]](s32)
- ; ILP32-NEXT: $x15 = COPY [[UV5]](s32)
- ; ILP32-NEXT: $x16 = COPY [[UV6]](s32)
- ; ILP32-NEXT: $x17 = COPY [[UV7]](s32)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack_not_first, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
- ; ILP32-NEXT: ADJCALLSTACKUP 36, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
- ; ILP32-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_128i_indirect_reference_in_stack_not_first
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
- ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; ILP32F-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
- ; ILP32F-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
- ; ILP32F-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
- ; ILP32F-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
- ; ILP32F-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 6
- ; ILP32F-NEXT: [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
- ; ILP32F-NEXT: [[C8:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 36, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32F-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
- ; ILP32F-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
- ; ILP32F-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
- ; ILP32F-NEXT: [[UV8:%[0-9]+]]:_(s32), [[UV9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32F-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
- ; ILP32F-NEXT: G_STORE [[UV8]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
- ; ILP32F-NEXT: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32F-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s32)
- ; ILP32F-NEXT: G_STORE [[UV9]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
- ; ILP32F-NEXT: [[UV10:%[0-9]+]]:_(s32), [[UV11:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C5]](s64)
- ; ILP32F-NEXT: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32F-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s32)
- ; ILP32F-NEXT: G_STORE [[UV10]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 8, align 8)
- ; ILP32F-NEXT: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32F-NEXT: [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s32)
- ; ILP32F-NEXT: G_STORE [[UV11]](s32), [[PTR_ADD3]](p0) :: (store (s32) into stack + 12)
- ; ILP32F-NEXT: [[UV12:%[0-9]+]]:_(s32), [[UV13:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
- ; ILP32F-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
- ; ILP32F-NEXT: [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
- ; ILP32F-NEXT: G_STORE [[UV12]](s32), [[PTR_ADD4]](p0) :: (store (s32) into stack + 16, align 16)
- ; ILP32F-NEXT: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
- ; ILP32F-NEXT: [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
- ; ILP32F-NEXT: G_STORE [[UV13]](s32), [[PTR_ADD5]](p0) :: (store (s32) into stack + 20)
- ; ILP32F-NEXT: [[UV14:%[0-9]+]]:_(s32), [[UV15:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C7]](s64)
- ; ILP32F-NEXT: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
- ; ILP32F-NEXT: [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
- ; ILP32F-NEXT: G_STORE [[UV14]](s32), [[PTR_ADD6]](p0) :: (store (s32) into stack + 24, align 8)
- ; ILP32F-NEXT: [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
- ; ILP32F-NEXT: [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
- ; ILP32F-NEXT: G_STORE [[UV15]](s32), [[PTR_ADD7]](p0) :: (store (s32) into stack + 28)
- ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32F-NEXT: G_STORE [[C8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32F-NEXT: [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
- ; ILP32F-NEXT: [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
- ; ILP32F-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 32, align 16)
- ; ILP32F-NEXT: $x10 = COPY [[UV]](s32)
- ; ILP32F-NEXT: $x11 = COPY [[UV1]](s32)
- ; ILP32F-NEXT: $x12 = COPY [[UV2]](s32)
- ; ILP32F-NEXT: $x13 = COPY [[UV3]](s32)
- ; ILP32F-NEXT: $x14 = COPY [[UV4]](s32)
- ; ILP32F-NEXT: $x15 = COPY [[UV5]](s32)
- ; ILP32F-NEXT: $x16 = COPY [[UV6]](s32)
- ; ILP32F-NEXT: $x17 = COPY [[UV7]](s32)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack_not_first, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
- ; ILP32F-NEXT: ADJCALLSTACKUP 36, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
- ; ILP32F-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32F-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_128i_indirect_reference_in_stack_not_first
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
- ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
- ; ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
- ; ILP32D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
- ; ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
- ; ILP32D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 6
- ; ILP32D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
- ; ILP32D-NEXT: [[C8:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 36, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
- ; ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
- ; ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
- ; ILP32D-NEXT: [[UV8:%[0-9]+]]:_(s32), [[UV9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32D-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
- ; ILP32D-NEXT: G_STORE [[UV8]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
- ; ILP32D-NEXT: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32D-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s32)
- ; ILP32D-NEXT: G_STORE [[UV9]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
- ; ILP32D-NEXT: [[UV10:%[0-9]+]]:_(s32), [[UV11:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C5]](s64)
- ; ILP32D-NEXT: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32D-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s32)
- ; ILP32D-NEXT: G_STORE [[UV10]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 8, align 8)
- ; ILP32D-NEXT: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32D-NEXT: [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s32)
- ; ILP32D-NEXT: G_STORE [[UV11]](s32), [[PTR_ADD3]](p0) :: (store (s32) into stack + 12)
- ; ILP32D-NEXT: [[UV12:%[0-9]+]]:_(s32), [[UV13:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
- ; ILP32D-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
- ; ILP32D-NEXT: [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
- ; ILP32D-NEXT: G_STORE [[UV12]](s32), [[PTR_ADD4]](p0) :: (store (s32) into stack + 16, align 16)
- ; ILP32D-NEXT: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
- ; ILP32D-NEXT: [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
- ; ILP32D-NEXT: G_STORE [[UV13]](s32), [[PTR_ADD5]](p0) :: (store (s32) into stack + 20)
- ; ILP32D-NEXT: [[UV14:%[0-9]+]]:_(s32), [[UV15:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C7]](s64)
- ; ILP32D-NEXT: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
- ; ILP32D-NEXT: [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
- ; ILP32D-NEXT: G_STORE [[UV14]](s32), [[PTR_ADD6]](p0) :: (store (s32) into stack + 24, align 8)
- ; ILP32D-NEXT: [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
- ; ILP32D-NEXT: [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
- ; ILP32D-NEXT: G_STORE [[UV15]](s32), [[PTR_ADD7]](p0) :: (store (s32) into stack + 28)
- ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32D-NEXT: G_STORE [[C8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32D-NEXT: [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
- ; ILP32D-NEXT: [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
- ; ILP32D-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 32, align 16)
- ; ILP32D-NEXT: $x10 = COPY [[UV]](s32)
- ; ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
- ; ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
- ; ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
- ; ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
- ; ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
- ; ILP32D-NEXT: $x16 = COPY [[UV6]](s32)
- ; ILP32D-NEXT: $x17 = COPY [[UV7]](s32)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack_not_first, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
- ; ILP32D-NEXT: ADJCALLSTACKUP 36, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
- ; ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i64 @callee_128i_indirect_reference_in_stack_not_first(i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i128 42)
- %2 = trunc i64 %1 to i32
- ret i32 %2
-}
-
-
-define i64 @callee_128i_indirect_reference_in_regs(i128 %x, i128 %y ) {
- ; RV32I-LABEL: name: callee_128i_indirect_reference_in_regs
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10, $x11
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
- ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128), align 8)
- ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
- ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load (s128), align 8)
- ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s128) = G_ADD [[LOAD]], [[LOAD1]]
- ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[LOAD]](s128)
- ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[TRUNC]](s64)
- ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
- %1 = add i128 %x, %y
- %2 = trunc i128 %x to i64
- ret i64 %2
-}
-
-define i32 @caller_128i_indirect_reference_in_regs( ) {
- ; ILP32-LABEL: name: caller_128i_indirect_reference_in_regs
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
- ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
- ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32-NEXT: G_STORE [[C]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
- ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_regs, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
- ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_128i_indirect_reference_in_regs
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
- ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32F-NEXT: G_STORE [[C]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32F-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32F-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
- ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32F-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_regs, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
- ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32F-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32F-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_128i_indirect_reference_in_regs
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
- ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32D-NEXT: G_STORE [[C]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
- ; ILP32D-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32D-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
- ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32D-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
- ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i64 @callee_128i_indirect_reference_in_regs(i128 1, i128 2)
- %2 = trunc i64 %1 to i32
- ret i32 %2
-}
-
-define i64 @callee_256i_indirect_reference_in_regs(i256 %x, i256 %y ) {
-
- ; RV32I-LABEL: name: callee_256i_indirect_reference_in_regs
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10, $x11
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
- ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s256) = G_LOAD [[COPY]](p0) :: (load (s256), align 8)
- ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
- ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s256) = G_LOAD [[COPY1]](p0) :: (load (s256), align 8)
- ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s256) = G_ADD [[LOAD]], [[LOAD1]]
- ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[LOAD]](s256)
- ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[TRUNC]](s64)
- ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
- %1 = add i256 %x, %y
- %2 = trunc i256 %x to i64
- ret i64 %2
-}
-
-define i32 @caller_256i_indirect_reference_in_regs( ) {
- ; ILP32-LABEL: name: caller_256i_indirect_reference_in_regs
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
- ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s256) = G_CONSTANT i256 2
- ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32-NEXT: G_STORE [[C]](s256), [[FRAME_INDEX]](p0) :: (store (s256) into %stack.0, align 8)
- ; ILP32-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32-NEXT: G_STORE [[C1]](s256), [[FRAME_INDEX1]](p0) :: (store (s256) into %stack.1, align 8)
- ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_256i_indirect_reference_in_regs, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
- ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_256i_indirect_reference_in_regs
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
- ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s256) = G_CONSTANT i256 2
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32F-NEXT: G_STORE [[C]](s256), [[FRAME_INDEX]](p0) :: (store (s256) into %stack.0, align 8)
- ; ILP32F-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32F-NEXT: G_STORE [[C1]](s256), [[FRAME_INDEX1]](p0) :: (store (s256) into %stack.1, align 8)
- ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32F-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_256i_indirect_reference_in_regs, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
- ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32F-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32F-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_256i_indirect_reference_in_regs
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
- ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s256) = G_CONSTANT i256 2
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32D-NEXT: G_STORE [[C]](s256), [[FRAME_INDEX]](p0) :: (store (s256) into %stack.0, align 8)
- ; ILP32D-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
- ; ILP32D-NEXT: G_STORE [[C1]](s256), [[FRAME_INDEX1]](p0) :: (store (s256) into %stack.1, align 8)
- ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32D-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_256i_indirect_reference_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
- ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
- ; ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i64 @callee_256i_indirect_reference_in_regs(i256 1, i256 2)
- %2 = trunc i64 %1 to i32
- ret i32 %2
-}
-
-; Check that the stack is used once the GPRs are exhausted
-
-define i32 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i64 %d, i32 %e, i32 %f, i64 %g, i32 %h) nounwind {
- ; RV32I-LABEL: name: callee_many_scalars
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
- ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32I-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
- ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
- ; RV32I-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
- ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
- ; RV32I-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
- ; RV32I-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
- ; RV32I-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
- ; RV32I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
- ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.1, align 16)
- ; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY7]](s32), [[LOAD]](s32)
- ; RV32I-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.0)
- ; RV32I-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
- ; RV32I-NEXT: [[ZEXT1:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC1]](s16)
- ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ZEXT]], [[ZEXT1]]
- ; RV32I-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[COPY2]]
- ; RV32I-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[MV]](s64), [[MV1]]
- ; RV32I-NEXT: [[ZEXT2:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
- ; RV32I-NEXT: [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[ZEXT2]], [[ADD1]]
- ; RV32I-NEXT: [[ADD3:%[0-9]+]]:_(s32) = G_ADD [[ADD2]], [[COPY5]]
- ; RV32I-NEXT: [[ADD4:%[0-9]+]]:_(s32) = G_ADD [[ADD3]], [[COPY6]]
- ; RV32I-NEXT: [[ADD5:%[0-9]+]]:_(s32) = G_ADD [[ADD4]], [[LOAD1]]
- ; RV32I-NEXT: $x10 = COPY [[ADD5]](s32)
- ; RV32I-NEXT: PseudoRET implicit $x10
- %a_ext = zext i8 %a to i32
- %b_ext = zext i16 %b to i32
- %1 = add i32 %a_ext, %b_ext
- %2 = add i32 %1, %c
- %3 = icmp eq i64 %d, %g
- %4 = zext i1 %3 to i32
- %5 = add i32 %4, %2
- %6 = add i32 %5, %e
- %7 = add i32 %6, %f
- %8 = add i32 %7, %h
- ret i32 %8
-}
-
-define i32 @caller_many_scalars() nounwind {
- ; ILP32-LABEL: name: caller_many_scalars
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
- ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
- ; ILP32-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
- ; ILP32-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
- ; ILP32-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
- ; ILP32-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
- ; ILP32-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
- ; ILP32-NEXT: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
- ; ILP32-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
- ; ILP32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
- ; ILP32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32-NEXT: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
- ; ILP32-NEXT: G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
- ; ILP32-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
- ; ILP32-NEXT: G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
- ; ILP32-NEXT: $x10 = COPY [[ANYEXT]](s32)
- ; ILP32-NEXT: $x11 = COPY [[ANYEXT1]](s32)
- ; ILP32-NEXT: $x12 = COPY [[C2]](s32)
- ; ILP32-NEXT: $x13 = COPY [[UV]](s32)
- ; ILP32-NEXT: $x14 = COPY [[UV1]](s32)
- ; ILP32-NEXT: $x15 = COPY [[C4]](s32)
- ; ILP32-NEXT: $x16 = COPY [[C5]](s32)
- ; ILP32-NEXT: $x17 = COPY [[UV2]](s32)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
- ; ILP32-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: $x10 = COPY [[COPY1]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_many_scalars
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
- ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
- ; ILP32F-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
- ; ILP32F-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
- ; ILP32F-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
- ; ILP32F-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
- ; ILP32F-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
- ; ILP32F-NEXT: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
- ; ILP32F-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
- ; ILP32F-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
- ; ILP32F-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32F-NEXT: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
- ; ILP32F-NEXT: G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
- ; ILP32F-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32F-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
- ; ILP32F-NEXT: G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
- ; ILP32F-NEXT: $x10 = COPY [[ANYEXT]](s32)
- ; ILP32F-NEXT: $x11 = COPY [[ANYEXT1]](s32)
- ; ILP32F-NEXT: $x12 = COPY [[C2]](s32)
- ; ILP32F-NEXT: $x13 = COPY [[UV]](s32)
- ; ILP32F-NEXT: $x14 = COPY [[UV1]](s32)
- ; ILP32F-NEXT: $x15 = COPY [[C4]](s32)
- ; ILP32F-NEXT: $x16 = COPY [[C5]](s32)
- ; ILP32F-NEXT: $x17 = COPY [[UV2]](s32)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
- ; ILP32F-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: $x10 = COPY [[COPY1]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_many_scalars
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
- ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
- ; ILP32D-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
- ; ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
- ; ILP32D-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
- ; ILP32D-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
- ; ILP32D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
- ; ILP32D-NEXT: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
- ; ILP32D-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
- ; ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
- ; ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; ILP32D-NEXT: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
- ; ILP32D-NEXT: G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
- ; ILP32D-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32D-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
- ; ILP32D-NEXT: G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
- ; ILP32D-NEXT: $x10 = COPY [[ANYEXT]](s32)
- ; ILP32D-NEXT: $x11 = COPY [[ANYEXT1]](s32)
- ; ILP32D-NEXT: $x12 = COPY [[C2]](s32)
- ; ILP32D-NEXT: $x13 = COPY [[UV]](s32)
- ; ILP32D-NEXT: $x14 = COPY [[UV1]](s32)
- ; ILP32D-NEXT: $x15 = COPY [[C4]](s32)
- ; ILP32D-NEXT: $x16 = COPY [[C5]](s32)
- ; ILP32D-NEXT: $x17 = COPY [[UV2]](s32)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
- ; ILP32D-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_many_scalars(i8 1, i16 2, i32 3, i64 4, i32 5, i32 6, i64 7, i32 8)
- ret i32 %1
-}
-
-
; Check that i128 and fp128 are passed indirectly
define i32 @callee_large_scalars(i128 %a, fp128 %b) nounwind {
@@ -1055,190 +242,8 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind {
ret i32 %1
}
-; Check passing of coerced integer arrays
-
-define i32 @callee_small_coerced_struct([2 x i32] %a.coerce) nounwind {
- ; RV32I-LABEL: name: callee_small_coerced_struct
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10, $x11
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32I-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]]
- ; RV32I-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
- ; RV32I-NEXT: $x10 = COPY [[ZEXT]](s32)
- ; RV32I-NEXT: PseudoRET implicit $x10
- %1 = extractvalue [2 x i32] %a.coerce, 0
- %2 = extractvalue [2 x i32] %a.coerce, 1
- %3 = icmp eq i32 %1, %2
- %4 = zext i1 %3 to i32
- ret i32 %4
-}
-
-define i32 @caller_small_coerced_struct() nounwind {
- ; ILP32-LABEL: name: caller_small_coerced_struct
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
- ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: $x10 = COPY [[C]](s32)
- ; ILP32-NEXT: $x11 = COPY [[C1]](s32)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
- ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: $x10 = COPY [[COPY]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_small_coerced_struct
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: $x10 = COPY [[C]](s32)
- ; ILP32F-NEXT: $x11 = COPY [[C1]](s32)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
- ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: $x10 = COPY [[COPY]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_small_coerced_struct
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: $x10 = COPY [[C]](s32)
- ; ILP32D-NEXT: $x11 = COPY [[C1]](s32)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
- ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_small_coerced_struct([2 x i32] [i32 1, i32 2])
- ret i32 %1
-}
-
-; Check return of 2x xlen scalars
-define i64 @callee_small_scalar_ret() nounwind {
- ; RV32I-LABEL: name: callee_small_scalar_ret
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1234567898765
- ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
- ret i64 1234567898765
-}
-
-define i32 @caller_small_scalar_ret() nounwind {
- ; ILP32-LABEL: name: caller_small_scalar_ret
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
- ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
- ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
- ; ILP32-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
- ; ILP32-NEXT: $x10 = COPY [[ZEXT]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_small_scalar_ret
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10, implicit-def $x11
- ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32F-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
- ; ILP32F-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
- ; ILP32F-NEXT: $x10 = COPY [[ZEXT]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_small_scalar_ret
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $x10, implicit-def $x11
- ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; ILP32D-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
- ; ILP32D-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
- ; ILP32D-NEXT: $x10 = COPY [[ZEXT]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i64 @callee_small_scalar_ret()
- %2 = icmp eq i64 987654321234567, %1
- %3 = zext i1 %2 to i32
- ret i32 %3
-}
-
-; Check return of 2x xlen structs
-
-%struct.small = type { i32, ptr }
-
-define %struct.small @callee_small_struct_ret() nounwind {
- ; RV32I-LABEL: name: callee_small_struct_ret
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; RV32I-NEXT: [[C1:%[0-9]+]]:_(p0) = G_CONSTANT i32 0
- ; RV32I-NEXT: $x10 = COPY [[C]](s32)
- ; RV32I-NEXT: $x11 = COPY [[C1]](p0)
- ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
- ret %struct.small { i32 1, ptr null }
-}
-
-define i32 @caller_small_struct_ret() nounwind {
- ; ILP32-LABEL: name: caller_small_struct_ret
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
- ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
- ; ILP32-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
- ; ILP32-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
- ; ILP32-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_small_struct_ret
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10, implicit-def $x11
- ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
- ; ILP32F-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
- ; ILP32F-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
- ; ILP32F-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_small_struct_ret
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $x10, implicit-def $x11
- ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
- ; ILP32D-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
- ; ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
- ; ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call %struct.small @callee_small_struct_ret()
- %2 = extractvalue %struct.small %1, 0
- %3 = extractvalue %struct.small %1, 1
- %4 = ptrtoint ptr %3 to i32
- %5 = add i32 %2, %4
- ret i32 %5
-}
-
-; Check return of >2x xlen scalars
+; Check return of >2x xlen floating point scalars
define fp128 @callee_large_scalar_ret() nounwind {
; RV32I-LABEL: name: callee_large_scalar_ret
@@ -1286,194 +291,3 @@ define void @caller_large_scalar_ret() nounwind {
ret void
}
-; Check return of >2x xlen structs
-
-%struct.large = type { i32, i32, i32, i32 }
-
-define void @callee_large_struct_ret(ptr noalias sret(%struct.large) %agg.result) nounwind {
- ; RV32I-LABEL: name: callee_large_struct_ret
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
- ; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
- ; RV32I-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
- ; RV32I-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; RV32I-NEXT: G_STORE [[C]](s32), [[COPY]](p0) :: (store (s32) into %ir.agg.result)
- ; RV32I-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; RV32I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C4]](s32)
- ; RV32I-NEXT: G_STORE [[C1]](s32), [[PTR_ADD]](p0) :: (store (s32) into %ir.b)
- ; RV32I-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; RV32I-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C5]](s32)
- ; RV32I-NEXT: G_STORE [[C2]](s32), [[PTR_ADD1]](p0) :: (store (s32) into %ir.c)
- ; RV32I-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; RV32I-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C6]](s32)
- ; RV32I-NEXT: G_STORE [[C3]](s32), [[PTR_ADD2]](p0) :: (store (s32) into %ir.d)
- ; RV32I-NEXT: PseudoRET
- store i32 1, ptr %agg.result, align 4
- %b = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 1
- store i32 2, ptr %b, align 4
- %c = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 2
- store i32 3, ptr %c, align 4
- %d = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 3
- store i32 4, ptr %d, align 4
- ret void
-}
-
-define i32 @caller_large_struct_ret() nounwind {
- ; ILP32-LABEL: name: caller_large_struct_ret
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32_lp64, implicit-def $x1, implicit $x10
- ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
- ; ILP32-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
- ; ILP32-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
- ; ILP32-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_large_struct_ret
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10
- ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
- ; ILP32F-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
- ; ILP32F-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
- ; ILP32F-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_large_struct_ret
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10
- ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
- ; ILP32D-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
- ; ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
- ; ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = alloca %struct.large
- call void @callee_large_struct_ret(ptr sret(%struct.large) %1)
- %2 = load i32, ptr %1
- %3 = getelementptr inbounds %struct.large, ptr %1, i32 0, i32 3
- %4 = load i32, ptr %3
- %5 = add i32 %2, %4
- ret i32 %5
-}
-
-%struct.large2 = type { i32, float, i16, i32 }
-
-define %struct.large2 @callee_large_struct_ret2() nounwind {
- ; RV32I-LABEL: name: callee_large_struct_ret2
- ; RV32I: bb.1 (%ir-block.0):
- ; RV32I-NEXT: liveins: $x10
- ; RV32I-NEXT: {{ $}}
- ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
- ; RV32I-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
- ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY [[DEF]](s32)
- ; RV32I-NEXT: [[DEF1:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
- ; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
- ; RV32I-NEXT: [[C2:%[0-9]+]]:_(s16) = G_CONSTANT i16 3
- ; RV32I-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; RV32I-NEXT: G_STORE [[C]](s32), [[COPY]](p0) :: (store (s32), align 8)
- ; RV32I-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; RV32I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C4]](s32)
- ; RV32I-NEXT: G_STORE [[C1]](s32), [[PTR_ADD]](p0) :: (store (s32))
- ; RV32I-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; RV32I-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C5]](s32)
- ; RV32I-NEXT: G_STORE [[C2]](s16), [[PTR_ADD1]](p0) :: (store (s16), align 8)
- ; RV32I-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; RV32I-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C6]](s32)
- ; RV32I-NEXT: G_STORE [[C3]](s32), [[PTR_ADD2]](p0) :: (store (s32))
- ; RV32I-NEXT: PseudoRET
- %a = insertvalue %struct.large2 poison, i32 1, 0
- %b = insertvalue %struct.large2 %a, float 2.0, 1
- %c = insertvalue %struct.large2 %b, i16 3, 2
- %d = insertvalue %struct.large2 %c, i32 4, 3
- ret %struct.large2 %d
-}
-
-define i32 @caller_large_struct_ret2() nounwind {
- ; ILP32-LABEL: name: caller_large_struct_ret2
- ; ILP32: bb.1 (%ir-block.0):
- ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32_lp64, implicit-def $x1, implicit $x10
- ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0, align 8)
- ; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
- ; ILP32-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %stack.0)
- ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C1]](s32)
- ; ILP32-NEXT: [[LOAD2:%[0-9]+]]:_(s16) = G_LOAD [[PTR_ADD1]](p0) :: (load (s16) from %stack.0, align 8)
- ; ILP32-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C2]](s32)
- ; ILP32-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD2]](p0) :: (load (s32) from %stack.0)
- ; ILP32-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD3]]
- ; ILP32-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32F-LABEL: name: caller_large_struct_ret2
- ; ILP32F: bb.1 (%ir-block.0):
- ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10
- ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32F-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0, align 8)
- ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
- ; ILP32F-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %stack.0)
- ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32F-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C1]](s32)
- ; ILP32F-NEXT: [[LOAD2:%[0-9]+]]:_(s16) = G_LOAD [[PTR_ADD1]](p0) :: (load (s16) from %stack.0, align 8)
- ; ILP32F-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32F-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C2]](s32)
- ; ILP32F-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD2]](p0) :: (load (s32) from %stack.0)
- ; ILP32F-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD3]]
- ; ILP32F-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32F-NEXT: PseudoRET implicit $x10
- ;
- ; ILP32D-LABEL: name: caller_large_struct_ret2
- ; ILP32D: bb.1 (%ir-block.0):
- ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
- ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
- ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10
- ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0, align 8)
- ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
- ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
- ; ILP32D-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %stack.0)
- ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
- ; ILP32D-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C1]](s32)
- ; ILP32D-NEXT: [[LOAD2:%[0-9]+]]:_(s16) = G_LOAD [[PTR_ADD1]](p0) :: (load (s16) from %stack.0, align 8)
- ; ILP32D-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
- ; ILP32D-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C2]](s32)
- ; ILP32D-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD2]](p0) :: (load (s32) from %stack.0)
- ; ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD3]]
- ; ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
- ; ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call %struct.large2 @callee_large_struct_ret()
- %2 = extractvalue %struct.large2 %1, 0
- %3 = extractvalue %struct.large2 %1, 3
- %4 = add i32 %2, %3
- ret i32 %4
-}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-ilp32q-common.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-ilp32q-common.ll
new file mode 100644
index 0000000000000..1ed23c2301855
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-ilp32q-common.ll
@@ -0,0 +1,1531 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
+; RUN: llc -mtriple=riscv32 \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32I,ILP32 %s
+; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32I,ILP32F %s
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32I,ILP32D %s
+; RUN: llc -mtriple=riscv32 -mattr=+q -target-abi ilp32q \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32I,ILP32Q %s
+
+; Check that on RV32, i64 is passed in a pair of registers. Unlike
+; the convention for varargs, this need not be an aligned pair.
+
+define i32 @callee_i64_in_regs(i32 %a, i64 %b) nounwind {
+ ; RV32I-LABEL: name: callee_i64_in_regs
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10, $x11, $x12
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[TRUNC]]
+ ; RV32I-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10
+ %b_trunc = trunc i64 %b to i32
+ %1 = add i32 %a, %b_trunc
+ ret i32 %1
+}
+
+define i32 @caller_i64_in_regs() nounwind {
+ ; ILP32-LABEL: name: caller_i64_in_regs
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; ILP32-NEXT: $x10 = COPY [[C]](s32)
+ ; ILP32-NEXT: $x11 = COPY [[UV]](s32)
+ ; ILP32-NEXT: $x12 = COPY [[UV1]](s32)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: $x10 = COPY [[COPY]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_i64_in_regs
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; ILP32F-NEXT: $x10 = COPY [[C]](s32)
+ ; ILP32F-NEXT: $x11 = COPY [[UV]](s32)
+ ; ILP32F-NEXT: $x12 = COPY [[UV1]](s32)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: $x10 = COPY [[COPY]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_i64_in_regs
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; ILP32D-NEXT: $x10 = COPY [[C]](s32)
+ ; ILP32D-NEXT: $x11 = COPY [[UV]](s32)
+ ; ILP32D-NEXT: $x12 = COPY [[UV1]](s32)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_i64_in_regs
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; ILP32Q-NEXT: $x10 = COPY [[C]](s32)
+ ; ILP32Q-NEXT: $x11 = COPY [[UV]](s32)
+ ; ILP32Q-NEXT: $x12 = COPY [[UV1]](s32)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_i64_in_regs(i32 1, i64 2)
+ ret i32 %1
+}
+
+; Check the correct handling of passing of values that are larger that 2*XLen.
+
+define i64 @callee_128i_indirect_reference_in_stack(i64 %x1, i64 %x2, i64 %x3, i64 %x4, i128 %y, i128 %y2) {
+ ; RV32I-LABEL: name: callee_128i_indirect_reference_in_stack
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
+ ; RV32I-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32I-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32I-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
+ ; RV32I-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32I-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32I-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.1, align 16)
+ ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[LOAD]](p0) :: (load (s128), align 8)
+ ; RV32I-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32I-NEXT: [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (p0) from %fixed-stack.0)
+ ; RV32I-NEXT: [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[LOAD2]](p0) :: (load (s128), align 8)
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s128) = G_ADD [[LOAD1]], [[LOAD3]]
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[ADD]](s128)
+ ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[TRUNC]](s64)
+ ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
+ %1 = add i128 %y, %y2
+ %2 = trunc i128 %1 to i64
+ ret i64 %2
+}
+
+define i32 @callee_128i_indirect_refernce_in_stack( ) {
+ ; ILP32-LABEL: name: callee_128i_indirect_refernce_in_stack
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; ILP32-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s32)
+ ; ILP32-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
+ ; ILP32-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32-NEXT: G_STORE [[C2]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
+ ; ILP32-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s32)
+ ; ILP32-NEXT: G_STORE [[FRAME_INDEX1]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
+ ; ILP32-NEXT: $x10 = COPY [[UV]](s32)
+ ; ILP32-NEXT: $x11 = COPY [[UV1]](s32)
+ ; ILP32-NEXT: $x12 = COPY [[UV2]](s32)
+ ; ILP32-NEXT: $x13 = COPY [[UV3]](s32)
+ ; ILP32-NEXT: $x14 = COPY [[UV4]](s32)
+ ; ILP32-NEXT: $x15 = COPY [[UV5]](s32)
+ ; ILP32-NEXT: $x16 = COPY [[UV6]](s32)
+ ; ILP32-NEXT: $x17 = COPY [[UV7]](s32)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
+ ; ILP32-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; ILP32-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: callee_128i_indirect_refernce_in_stack
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; ILP32F-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32F-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32F-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32F-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32F-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32F-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s32)
+ ; ILP32F-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
+ ; ILP32F-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32F-NEXT: G_STORE [[C2]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
+ ; ILP32F-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32F-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s32)
+ ; ILP32F-NEXT: G_STORE [[FRAME_INDEX1]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
+ ; ILP32F-NEXT: $x10 = COPY [[UV]](s32)
+ ; ILP32F-NEXT: $x11 = COPY [[UV1]](s32)
+ ; ILP32F-NEXT: $x12 = COPY [[UV2]](s32)
+ ; ILP32F-NEXT: $x13 = COPY [[UV3]](s32)
+ ; ILP32F-NEXT: $x14 = COPY [[UV4]](s32)
+ ; ILP32F-NEXT: $x15 = COPY [[UV5]](s32)
+ ; ILP32F-NEXT: $x16 = COPY [[UV6]](s32)
+ ; ILP32F-NEXT: $x17 = COPY [[UV7]](s32)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
+ ; ILP32F-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; ILP32F-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32F-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: callee_128i_indirect_refernce_in_stack
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; ILP32D-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32D-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32D-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s32)
+ ; ILP32D-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
+ ; ILP32D-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32D-NEXT: G_STORE [[C2]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
+ ; ILP32D-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32D-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s32)
+ ; ILP32D-NEXT: G_STORE [[FRAME_INDEX1]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
+ ; ILP32D-NEXT: $x10 = COPY [[UV]](s32)
+ ; ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
+ ; ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
+ ; ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
+ ; ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
+ ; ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
+ ; ILP32D-NEXT: $x16 = COPY [[UV6]](s32)
+ ; ILP32D-NEXT: $x17 = COPY [[UV7]](s32)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
+ ; ILP32D-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: callee_128i_indirect_refernce_in_stack
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32Q-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s32)
+ ; ILP32Q-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
+ ; ILP32Q-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32Q-NEXT: G_STORE [[C2]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
+ ; ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32Q-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s32)
+ ; ILP32Q-NEXT: G_STORE [[FRAME_INDEX1]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
+ ; ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; ILP32Q-NEXT: $x16 = COPY [[UV6]](s32)
+ ; ILP32Q-NEXT: $x17 = COPY [[UV7]](s32)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32Q-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; ILP32Q-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32Q-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i64 @callee_128i_indirect_reference_in_stack(i64 1,i64 1, i64 1, i64 1, i128 2, i128 42)
+ %2 = trunc i64 %1 to i32
+ ret i32 %2
+}
+
+define i64 @callee_128i_indirect_reference_in_stack_not_first(i64 %x0, i64 %x1, i64 %x2, i64 %x4, i64 %x5, i64 %x6, i64 %x7, i64 %x8, i128 %y ) {
+ ; RV32I-LABEL: name: callee_128i_indirect_reference_in_stack_not_first
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
+ ; RV32I-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32I-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32I-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
+ ; RV32I-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32I-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32I-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.8
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.8, align 16)
+ ; RV32I-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
+ ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.7)
+ ; RV32I-NEXT: [[MV4:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD]](s32), [[LOAD1]](s32)
+ ; RV32I-NEXT: [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
+ ; RV32I-NEXT: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %fixed-stack.6, align 8)
+ ; RV32I-NEXT: [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
+ ; RV32I-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (s32) from %fixed-stack.5)
+ ; RV32I-NEXT: [[MV5:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD2]](s32), [[LOAD3]](s32)
+ ; RV32I-NEXT: [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
+ ; RV32I-NEXT: [[LOAD4:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s32) from %fixed-stack.4, align 16)
+ ; RV32I-NEXT: [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
+ ; RV32I-NEXT: [[LOAD5:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (s32) from %fixed-stack.3)
+ ; RV32I-NEXT: [[MV6:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD4]](s32), [[LOAD5]](s32)
+ ; RV32I-NEXT: [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+ ; RV32I-NEXT: [[LOAD6:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (s32) from %fixed-stack.2, align 8)
+ ; RV32I-NEXT: [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ ; RV32I-NEXT: [[LOAD7:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (s32) from %fixed-stack.1)
+ ; RV32I-NEXT: [[MV7:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD6]](s32), [[LOAD7]](s32)
+ ; RV32I-NEXT: [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32I-NEXT: [[LOAD8:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX8]](p0) :: (load (p0) from %fixed-stack.0, align 16)
+ ; RV32I-NEXT: [[LOAD9:%[0-9]+]]:_(s128) = G_LOAD [[LOAD8]](p0) :: (load (s128), align 8)
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[LOAD9]](s128)
+ ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[TRUNC]](s64)
+ ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
+ %2 = trunc i128 %y to i64
+ ret i64 %2
+}
+
+define i32 @caller_128i_indirect_reference_in_stack_not_first() {
+ ; ILP32-LABEL: name: caller_128i_indirect_reference_in_stack_not_first
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; ILP32-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; ILP32-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; ILP32-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; ILP32-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; ILP32-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 6
+ ; ILP32-NEXT: [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; ILP32-NEXT: [[C8:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 36, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; ILP32-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; ILP32-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; ILP32-NEXT: [[UV8:%[0-9]+]]:_(s32), [[UV9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+ ; ILP32-NEXT: G_STORE [[UV8]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; ILP32-NEXT: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s32)
+ ; ILP32-NEXT: G_STORE [[UV9]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+ ; ILP32-NEXT: [[UV10:%[0-9]+]]:_(s32), [[UV11:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C5]](s64)
+ ; ILP32-NEXT: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s32)
+ ; ILP32-NEXT: G_STORE [[UV10]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 8, align 8)
+ ; ILP32-NEXT: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32-NEXT: [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s32)
+ ; ILP32-NEXT: G_STORE [[UV11]](s32), [[PTR_ADD3]](p0) :: (store (s32) into stack + 12)
+ ; ILP32-NEXT: [[UV12:%[0-9]+]]:_(s32), [[UV13:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; ILP32-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; ILP32-NEXT: [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; ILP32-NEXT: G_STORE [[UV12]](s32), [[PTR_ADD4]](p0) :: (store (s32) into stack + 16, align 16)
+ ; ILP32-NEXT: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
+ ; ILP32-NEXT: [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
+ ; ILP32-NEXT: G_STORE [[UV13]](s32), [[PTR_ADD5]](p0) :: (store (s32) into stack + 20)
+ ; ILP32-NEXT: [[UV14:%[0-9]+]]:_(s32), [[UV15:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C7]](s64)
+ ; ILP32-NEXT: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; ILP32-NEXT: [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
+ ; ILP32-NEXT: G_STORE [[UV14]](s32), [[PTR_ADD6]](p0) :: (store (s32) into stack + 24, align 8)
+ ; ILP32-NEXT: [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
+ ; ILP32-NEXT: [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
+ ; ILP32-NEXT: G_STORE [[UV15]](s32), [[PTR_ADD7]](p0) :: (store (s32) into stack + 28)
+ ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32-NEXT: G_STORE [[C8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32-NEXT: [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
+ ; ILP32-NEXT: [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
+ ; ILP32-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 32, align 16)
+ ; ILP32-NEXT: $x10 = COPY [[UV]](s32)
+ ; ILP32-NEXT: $x11 = COPY [[UV1]](s32)
+ ; ILP32-NEXT: $x12 = COPY [[UV2]](s32)
+ ; ILP32-NEXT: $x13 = COPY [[UV3]](s32)
+ ; ILP32-NEXT: $x14 = COPY [[UV4]](s32)
+ ; ILP32-NEXT: $x15 = COPY [[UV5]](s32)
+ ; ILP32-NEXT: $x16 = COPY [[UV6]](s32)
+ ; ILP32-NEXT: $x17 = COPY [[UV7]](s32)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack_not_first, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
+ ; ILP32-NEXT: ADJCALLSTACKUP 36, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; ILP32-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_128i_indirect_reference_in_stack_not_first
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; ILP32F-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; ILP32F-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; ILP32F-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; ILP32F-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; ILP32F-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 6
+ ; ILP32F-NEXT: [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; ILP32F-NEXT: [[C8:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 36, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32F-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; ILP32F-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; ILP32F-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; ILP32F-NEXT: [[UV8:%[0-9]+]]:_(s32), [[UV9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32F-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV8]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; ILP32F-NEXT: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32F-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV9]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+ ; ILP32F-NEXT: [[UV10:%[0-9]+]]:_(s32), [[UV11:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C5]](s64)
+ ; ILP32F-NEXT: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32F-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV10]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 8, align 8)
+ ; ILP32F-NEXT: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32F-NEXT: [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV11]](s32), [[PTR_ADD3]](p0) :: (store (s32) into stack + 12)
+ ; ILP32F-NEXT: [[UV12:%[0-9]+]]:_(s32), [[UV13:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; ILP32F-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; ILP32F-NEXT: [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV12]](s32), [[PTR_ADD4]](p0) :: (store (s32) into stack + 16, align 16)
+ ; ILP32F-NEXT: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
+ ; ILP32F-NEXT: [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV13]](s32), [[PTR_ADD5]](p0) :: (store (s32) into stack + 20)
+ ; ILP32F-NEXT: [[UV14:%[0-9]+]]:_(s32), [[UV15:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C7]](s64)
+ ; ILP32F-NEXT: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; ILP32F-NEXT: [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV14]](s32), [[PTR_ADD6]](p0) :: (store (s32) into stack + 24, align 8)
+ ; ILP32F-NEXT: [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
+ ; ILP32F-NEXT: [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV15]](s32), [[PTR_ADD7]](p0) :: (store (s32) into stack + 28)
+ ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32F-NEXT: G_STORE [[C8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32F-NEXT: [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
+ ; ILP32F-NEXT: [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
+ ; ILP32F-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 32, align 16)
+ ; ILP32F-NEXT: $x10 = COPY [[UV]](s32)
+ ; ILP32F-NEXT: $x11 = COPY [[UV1]](s32)
+ ; ILP32F-NEXT: $x12 = COPY [[UV2]](s32)
+ ; ILP32F-NEXT: $x13 = COPY [[UV3]](s32)
+ ; ILP32F-NEXT: $x14 = COPY [[UV4]](s32)
+ ; ILP32F-NEXT: $x15 = COPY [[UV5]](s32)
+ ; ILP32F-NEXT: $x16 = COPY [[UV6]](s32)
+ ; ILP32F-NEXT: $x17 = COPY [[UV7]](s32)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack_not_first, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
+ ; ILP32F-NEXT: ADJCALLSTACKUP 36, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; ILP32F-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32F-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_128i_indirect_reference_in_stack_not_first
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; ILP32D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; ILP32D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 6
+ ; ILP32D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; ILP32D-NEXT: [[C8:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 36, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; ILP32D-NEXT: [[UV8:%[0-9]+]]:_(s32), [[UV9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32D-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV8]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; ILP32D-NEXT: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32D-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV9]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+ ; ILP32D-NEXT: [[UV10:%[0-9]+]]:_(s32), [[UV11:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C5]](s64)
+ ; ILP32D-NEXT: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32D-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV10]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 8, align 8)
+ ; ILP32D-NEXT: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32D-NEXT: [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV11]](s32), [[PTR_ADD3]](p0) :: (store (s32) into stack + 12)
+ ; ILP32D-NEXT: [[UV12:%[0-9]+]]:_(s32), [[UV13:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; ILP32D-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; ILP32D-NEXT: [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV12]](s32), [[PTR_ADD4]](p0) :: (store (s32) into stack + 16, align 16)
+ ; ILP32D-NEXT: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
+ ; ILP32D-NEXT: [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV13]](s32), [[PTR_ADD5]](p0) :: (store (s32) into stack + 20)
+ ; ILP32D-NEXT: [[UV14:%[0-9]+]]:_(s32), [[UV15:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C7]](s64)
+ ; ILP32D-NEXT: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; ILP32D-NEXT: [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV14]](s32), [[PTR_ADD6]](p0) :: (store (s32) into stack + 24, align 8)
+ ; ILP32D-NEXT: [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
+ ; ILP32D-NEXT: [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV15]](s32), [[PTR_ADD7]](p0) :: (store (s32) into stack + 28)
+ ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32D-NEXT: G_STORE [[C8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32D-NEXT: [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
+ ; ILP32D-NEXT: [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
+ ; ILP32D-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 32, align 16)
+ ; ILP32D-NEXT: $x10 = COPY [[UV]](s32)
+ ; ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
+ ; ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
+ ; ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
+ ; ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
+ ; ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
+ ; ILP32D-NEXT: $x16 = COPY [[UV6]](s32)
+ ; ILP32D-NEXT: $x17 = COPY [[UV7]](s32)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack_not_first, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
+ ; ILP32D-NEXT: ADJCALLSTACKUP 36, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_128i_indirect_reference_in_stack_not_first
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 6
+ ; ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 36, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; ILP32Q-NEXT: [[UV8:%[0-9]+]]:_(s32), [[UV9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32Q-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV8]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; ILP32Q-NEXT: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32Q-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV9]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+ ; ILP32Q-NEXT: [[UV10:%[0-9]+]]:_(s32), [[UV11:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C5]](s64)
+ ; ILP32Q-NEXT: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32Q-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV10]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 8, align 8)
+ ; ILP32Q-NEXT: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32Q-NEXT: [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV11]](s32), [[PTR_ADD3]](p0) :: (store (s32) into stack + 12)
+ ; ILP32Q-NEXT: [[UV12:%[0-9]+]]:_(s32), [[UV13:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; ILP32Q-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+ ; ILP32Q-NEXT: [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV12]](s32), [[PTR_ADD4]](p0) :: (store (s32) into stack + 16, align 16)
+ ; ILP32Q-NEXT: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
+ ; ILP32Q-NEXT: [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV13]](s32), [[PTR_ADD5]](p0) :: (store (s32) into stack + 20)
+ ; ILP32Q-NEXT: [[UV14:%[0-9]+]]:_(s32), [[UV15:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C7]](s64)
+ ; ILP32Q-NEXT: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+ ; ILP32Q-NEXT: [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV14]](s32), [[PTR_ADD6]](p0) :: (store (s32) into stack + 24, align 8)
+ ; ILP32Q-NEXT: [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
+ ; ILP32Q-NEXT: [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV15]](s32), [[PTR_ADD7]](p0) :: (store (s32) into stack + 28)
+ ; ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32Q-NEXT: G_STORE [[C8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32Q-NEXT: [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
+ ; ILP32Q-NEXT: [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
+ ; ILP32Q-NEXT: G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 32, align 16)
+ ; ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; ILP32Q-NEXT: $x16 = COPY [[UV6]](s32)
+ ; ILP32Q-NEXT: $x17 = COPY [[UV7]](s32)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_stack_not_first, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10, implicit-def $x11
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 36, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32Q-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; ILP32Q-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32Q-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i64 @callee_128i_indirect_reference_in_stack_not_first(i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i128 42)
+ %2 = trunc i64 %1 to i32
+ ret i32 %2
+}
+
+
+define i64 @callee_128i_indirect_reference_in_regs(i128 %x, i128 %y ) {
+ ; RV32I-LABEL: name: callee_128i_indirect_reference_in_regs
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10, $x11
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128), align 8)
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+ ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load (s128), align 8)
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s128) = G_ADD [[LOAD]], [[LOAD1]]
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[LOAD]](s128)
+ ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[TRUNC]](s64)
+ ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
+ %1 = add i128 %x, %y
+ %2 = trunc i128 %x to i64
+ ret i64 %2
+}
+
+define i32 @caller_128i_indirect_reference_in_regs( ) {
+ ; ILP32-LABEL: name: caller_128i_indirect_reference_in_regs
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32-NEXT: G_STORE [[C]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
+ ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_regs, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_128i_indirect_reference_in_regs
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32F-NEXT: G_STORE [[C]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32F-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32F-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
+ ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32F-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_regs, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32F-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32F-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_128i_indirect_reference_in_regs
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32D-NEXT: G_STORE [[C]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32D-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32D-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
+ ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32D-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_128i_indirect_reference_in_regs
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32Q-NEXT: G_STORE [[C]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
+ ; ILP32Q-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32Q-NEXT: G_STORE [[C1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1, align 8)
+ ; ILP32Q-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32Q-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_128i_indirect_reference_in_regs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32Q-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32Q-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32Q-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i64 @callee_128i_indirect_reference_in_regs(i128 1, i128 2)
+ %2 = trunc i64 %1 to i32
+ ret i32 %2
+}
+
+define i64 @callee_256i_indirect_reference_in_regs(i256 %x, i256 %y ) {
+
+ ; RV32I-LABEL: name: callee_256i_indirect_reference_in_regs
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10, $x11
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s256) = G_LOAD [[COPY]](p0) :: (load (s256), align 8)
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+ ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s256) = G_LOAD [[COPY1]](p0) :: (load (s256), align 8)
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s256) = G_ADD [[LOAD]], [[LOAD1]]
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[LOAD]](s256)
+ ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[TRUNC]](s64)
+ ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
+ %1 = add i256 %x, %y
+ %2 = trunc i256 %x to i64
+ ret i64 %2
+}
+
+define i32 @caller_256i_indirect_reference_in_regs( ) {
+ ; ILP32-LABEL: name: caller_256i_indirect_reference_in_regs
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
+ ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s256) = G_CONSTANT i256 2
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32-NEXT: G_STORE [[C]](s256), [[FRAME_INDEX]](p0) :: (store (s256) into %stack.0, align 8)
+ ; ILP32-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32-NEXT: G_STORE [[C1]](s256), [[FRAME_INDEX1]](p0) :: (store (s256) into %stack.1, align 8)
+ ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_256i_indirect_reference_in_regs, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_256i_indirect_reference_in_regs
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
+ ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s256) = G_CONSTANT i256 2
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32F-NEXT: G_STORE [[C]](s256), [[FRAME_INDEX]](p0) :: (store (s256) into %stack.0, align 8)
+ ; ILP32F-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32F-NEXT: G_STORE [[C1]](s256), [[FRAME_INDEX1]](p0) :: (store (s256) into %stack.1, align 8)
+ ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32F-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_256i_indirect_reference_in_regs, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32F-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32F-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_256i_indirect_reference_in_regs
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
+ ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s256) = G_CONSTANT i256 2
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32D-NEXT: G_STORE [[C]](s256), [[FRAME_INDEX]](p0) :: (store (s256) into %stack.0, align 8)
+ ; ILP32D-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32D-NEXT: G_STORE [[C1]](s256), [[FRAME_INDEX1]](p0) :: (store (s256) into %stack.1, align 8)
+ ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32D-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_256i_indirect_reference_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_256i_indirect_reference_in_regs
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
+ ; ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s256) = G_CONSTANT i256 2
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32Q-NEXT: G_STORE [[C]](s256), [[FRAME_INDEX]](p0) :: (store (s256) into %stack.0, align 8)
+ ; ILP32Q-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; ILP32Q-NEXT: G_STORE [[C1]](s256), [[FRAME_INDEX1]](p0) :: (store (s256) into %stack.1, align 8)
+ ; ILP32Q-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32Q-NEXT: $x11 = COPY [[FRAME_INDEX1]](p0)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_256i_indirect_reference_in_regs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10, implicit-def $x11
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32Q-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32Q-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
+ ; ILP32Q-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i64 @callee_256i_indirect_reference_in_regs(i256 1, i256 2)
+ %2 = trunc i64 %1 to i32
+ ret i32 %2
+}
+
+; Check that the stack is used once the GPRs are exhausted
+
+define i32 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i64 %d, i32 %e, i32 %f, i64 %g, i32 %h) nounwind {
+ ; RV32I-LABEL: name: callee_many_scalars
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
+ ; RV32I-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32I-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
+ ; RV32I-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32I-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32I-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ ; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.1, align 16)
+ ; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY7]](s32), [[LOAD]](s32)
+ ; RV32I-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.0)
+ ; RV32I-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
+ ; RV32I-NEXT: [[ZEXT1:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC1]](s16)
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ZEXT]], [[ZEXT1]]
+ ; RV32I-NEXT: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[COPY2]]
+ ; RV32I-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[MV]](s64), [[MV1]]
+ ; RV32I-NEXT: [[ZEXT2:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
+ ; RV32I-NEXT: [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[ZEXT2]], [[ADD1]]
+ ; RV32I-NEXT: [[ADD3:%[0-9]+]]:_(s32) = G_ADD [[ADD2]], [[COPY5]]
+ ; RV32I-NEXT: [[ADD4:%[0-9]+]]:_(s32) = G_ADD [[ADD3]], [[COPY6]]
+ ; RV32I-NEXT: [[ADD5:%[0-9]+]]:_(s32) = G_ADD [[ADD4]], [[LOAD1]]
+ ; RV32I-NEXT: $x10 = COPY [[ADD5]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10
+ %a_ext = zext i8 %a to i32
+ %b_ext = zext i16 %b to i32
+ %1 = add i32 %a_ext, %b_ext
+ %2 = add i32 %1, %c
+ %3 = icmp eq i64 %d, %g
+ %4 = zext i1 %3 to i32
+ %5 = add i32 %4, %2
+ %6 = add i32 %5, %e
+ %7 = add i32 %6, %f
+ %8 = add i32 %7, %h
+ ret i32 %8
+}
+
+define i32 @caller_many_scalars() nounwind {
+ ; ILP32-LABEL: name: caller_many_scalars
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
+ ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
+ ; ILP32-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; ILP32-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; ILP32-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; ILP32-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
+ ; ILP32-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; ILP32-NEXT: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
+ ; ILP32-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
+ ; ILP32-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; ILP32-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32-NEXT: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
+ ; ILP32-NEXT: G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; ILP32-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+ ; ILP32-NEXT: G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+ ; ILP32-NEXT: $x10 = COPY [[ANYEXT]](s32)
+ ; ILP32-NEXT: $x11 = COPY [[ANYEXT1]](s32)
+ ; ILP32-NEXT: $x12 = COPY [[C2]](s32)
+ ; ILP32-NEXT: $x13 = COPY [[UV]](s32)
+ ; ILP32-NEXT: $x14 = COPY [[UV1]](s32)
+ ; ILP32-NEXT: $x15 = COPY [[C4]](s32)
+ ; ILP32-NEXT: $x16 = COPY [[C5]](s32)
+ ; ILP32-NEXT: $x17 = COPY [[UV2]](s32)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
+ ; ILP32-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_many_scalars
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
+ ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
+ ; ILP32F-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; ILP32F-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; ILP32F-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; ILP32F-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
+ ; ILP32F-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; ILP32F-NEXT: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
+ ; ILP32F-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
+ ; ILP32F-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; ILP32F-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32F-NEXT: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
+ ; ILP32F-NEXT: G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; ILP32F-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32F-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+ ; ILP32F-NEXT: G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+ ; ILP32F-NEXT: $x10 = COPY [[ANYEXT]](s32)
+ ; ILP32F-NEXT: $x11 = COPY [[ANYEXT1]](s32)
+ ; ILP32F-NEXT: $x12 = COPY [[C2]](s32)
+ ; ILP32F-NEXT: $x13 = COPY [[UV]](s32)
+ ; ILP32F-NEXT: $x14 = COPY [[UV1]](s32)
+ ; ILP32F-NEXT: $x15 = COPY [[C4]](s32)
+ ; ILP32F-NEXT: $x16 = COPY [[C5]](s32)
+ ; ILP32F-NEXT: $x17 = COPY [[UV2]](s32)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
+ ; ILP32F-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_many_scalars
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
+ ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
+ ; ILP32D-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; ILP32D-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; ILP32D-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
+ ; ILP32D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; ILP32D-NEXT: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
+ ; ILP32D-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
+ ; ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32D-NEXT: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
+ ; ILP32D-NEXT: G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; ILP32D-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32D-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+ ; ILP32D-NEXT: G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+ ; ILP32D-NEXT: $x10 = COPY [[ANYEXT]](s32)
+ ; ILP32D-NEXT: $x11 = COPY [[ANYEXT1]](s32)
+ ; ILP32D-NEXT: $x12 = COPY [[C2]](s32)
+ ; ILP32D-NEXT: $x13 = COPY [[UV]](s32)
+ ; ILP32D-NEXT: $x14 = COPY [[UV1]](s32)
+ ; ILP32D-NEXT: $x15 = COPY [[C4]](s32)
+ ; ILP32D-NEXT: $x16 = COPY [[C5]](s32)
+ ; ILP32D-NEXT: $x17 = COPY [[UV2]](s32)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
+ ; ILP32D-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_many_scalars
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
+ ; ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
+ ; ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
+ ; ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
+ ; ILP32Q-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
+ ; ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
+ ; ILP32Q-NEXT: G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; ILP32Q-NEXT: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32Q-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+ ; ILP32Q-NEXT: G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+ ; ILP32Q-NEXT: $x10 = COPY [[ANYEXT]](s32)
+ ; ILP32Q-NEXT: $x11 = COPY [[ANYEXT1]](s32)
+ ; ILP32Q-NEXT: $x12 = COPY [[C2]](s32)
+ ; ILP32Q-NEXT: $x13 = COPY [[UV]](s32)
+ ; ILP32Q-NEXT: $x14 = COPY [[UV1]](s32)
+ ; ILP32Q-NEXT: $x15 = COPY [[C4]](s32)
+ ; ILP32Q-NEXT: $x16 = COPY [[C5]](s32)
+ ; ILP32Q-NEXT: $x17 = COPY [[UV2]](s32)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_many_scalars(i8 1, i16 2, i32 3, i64 4, i32 5, i32 6, i64 7, i32 8)
+ ret i32 %1
+}
+
+; Check passing of coerced integer arrays
+
+define i32 @callee_small_coerced_struct([2 x i32] %a.coerce) nounwind {
+ ; RV32I-LABEL: name: callee_small_coerced_struct
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10, $x11
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32I-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]]
+ ; RV32I-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
+ ; RV32I-NEXT: $x10 = COPY [[ZEXT]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10
+ %1 = extractvalue [2 x i32] %a.coerce, 0
+ %2 = extractvalue [2 x i32] %a.coerce, 1
+ %3 = icmp eq i32 %1, %2
+ %4 = zext i1 %3 to i32
+ ret i32 %4
+}
+
+define i32 @caller_small_coerced_struct() nounwind {
+ ; ILP32-LABEL: name: caller_small_coerced_struct
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: $x10 = COPY [[C]](s32)
+ ; ILP32-NEXT: $x11 = COPY [[C1]](s32)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: $x10 = COPY [[COPY]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_small_coerced_struct
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: $x10 = COPY [[C]](s32)
+ ; ILP32F-NEXT: $x11 = COPY [[C1]](s32)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: $x10 = COPY [[COPY]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_small_coerced_struct
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: $x10 = COPY [[C]](s32)
+ ; ILP32D-NEXT: $x11 = COPY [[C1]](s32)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_small_coerced_struct
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: $x10 = COPY [[C]](s32)
+ ; ILP32Q-NEXT: $x11 = COPY [[C1]](s32)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_small_coerced_struct([2 x i32] [i32 1, i32 2])
+ ret i32 %1
+}
+
+; Check return of >2x xlen scalars
+
+define i128 @calle_large_scalar() {
+ ; RV32I-LABEL: name: calle_large_scalar
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
+ ; RV32I-NEXT: G_STORE [[C]](s128), [[COPY]](p0) :: (store (s128), align 8)
+ ; RV32I-NEXT: PseudoRET
+ ret i128 42
+}
+
+define void @caller_large_scalar() {
+ ; ILP32-LABEL: name: caller_large_scalar
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @calle_large_scalar, csr_ilp32_lp64, implicit-def $x1, implicit $x10
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s128) from %stack.0, align 8)
+ ; ILP32-NEXT: PseudoRET
+ ;
+ ; ILP32F-LABEL: name: caller_large_scalar
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @calle_large_scalar, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s128) from %stack.0, align 8)
+ ; ILP32F-NEXT: PseudoRET
+ ;
+ ; ILP32D-LABEL: name: caller_large_scalar
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @calle_large_scalar, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s128) from %stack.0, align 8)
+ ; ILP32D-NEXT: PseudoRET
+ ;
+ ; ILP32Q-LABEL: name: caller_large_scalar
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @calle_large_scalar, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s128) from %stack.0, align 8)
+ ; ILP32Q-NEXT: PseudoRET
+ %1 = call i128 @calle_large_scalar()
+ ret void
+}
+
+
+; Check return of 2x xlen scalars
+
+define i64 @callee_small_scalar_ret() nounwind {
+ ; RV32I-LABEL: name: callee_small_scalar_ret
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1234567898765
+ ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32I-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32I-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
+ ret i64 1234567898765
+}
+
+define i32 @caller_small_scalar_ret() nounwind {
+ ; ILP32-LABEL: name: caller_small_scalar_ret
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
+ ; ILP32-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
+ ; ILP32-NEXT: $x10 = COPY [[ZEXT]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_small_scalar_ret
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10, implicit-def $x11
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32F-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32F-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
+ ; ILP32F-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
+ ; ILP32F-NEXT: $x10 = COPY [[ZEXT]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_small_scalar_ret
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $x10, implicit-def $x11
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32D-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
+ ; ILP32D-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
+ ; ILP32D-NEXT: $x10 = COPY [[ZEXT]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_small_scalar_ret
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit-def $x10, implicit-def $x11
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; ILP32Q-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; ILP32Q-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
+ ; ILP32Q-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
+ ; ILP32Q-NEXT: $x10 = COPY [[ZEXT]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i64 @callee_small_scalar_ret()
+ %2 = icmp eq i64 987654321234567, %1
+ %3 = zext i1 %2 to i32
+ ret i32 %3
+}
+
+; Check return of 2x xlen structs
+
+%struct.small = type { i32, ptr }
+
+define %struct.small @callee_small_struct_ret() nounwind {
+ ; RV32I-LABEL: name: callee_small_struct_ret
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV32I-NEXT: [[C1:%[0-9]+]]:_(p0) = G_CONSTANT i32 0
+ ; RV32I-NEXT: $x10 = COPY [[C]](s32)
+ ; RV32I-NEXT: $x11 = COPY [[C1]](p0)
+ ; RV32I-NEXT: PseudoRET implicit $x10, implicit $x11
+ ret %struct.small { i32 1, ptr null }
+}
+
+define i32 @caller_small_struct_ret() nounwind {
+ ; ILP32-LABEL: name: caller_small_struct_ret
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+ ; ILP32-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
+ ; ILP32-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
+ ; ILP32-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_small_struct_ret
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10, implicit-def $x11
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32F-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+ ; ILP32F-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
+ ; ILP32F-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
+ ; ILP32F-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_small_struct_ret
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $x10, implicit-def $x11
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+ ; ILP32D-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
+ ; ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
+ ; ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_small_struct_ret
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit-def $x10, implicit-def $x11
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+ ; ILP32Q-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
+ ; ILP32Q-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
+ ; ILP32Q-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call %struct.small @callee_small_struct_ret()
+ %2 = extractvalue %struct.small %1, 0
+ %3 = extractvalue %struct.small %1, 1
+ %4 = ptrtoint ptr %3 to i32
+ %5 = add i32 %2, %4
+ ret i32 %5
+}
+
+
+; Check return of >2x xlen structs
+
+%struct.large = type { i32, i32, i32, i32 }
+
+define void @callee_large_struct_ret(ptr noalias sret(%struct.large) %agg.result) nounwind {
+ ; RV32I-LABEL: name: callee_large_struct_ret
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
+ ; RV32I-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; RV32I-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; RV32I-NEXT: G_STORE [[C]](s32), [[COPY]](p0) :: (store (s32) into %ir.agg.result)
+ ; RV32I-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; RV32I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C4]](s32)
+ ; RV32I-NEXT: G_STORE [[C1]](s32), [[PTR_ADD]](p0) :: (store (s32) into %ir.b)
+ ; RV32I-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; RV32I-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C5]](s32)
+ ; RV32I-NEXT: G_STORE [[C2]](s32), [[PTR_ADD1]](p0) :: (store (s32) into %ir.c)
+ ; RV32I-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; RV32I-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C6]](s32)
+ ; RV32I-NEXT: G_STORE [[C3]](s32), [[PTR_ADD2]](p0) :: (store (s32) into %ir.d)
+ ; RV32I-NEXT: PseudoRET
+ store i32 1, ptr %agg.result, align 4
+ %b = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 1
+ store i32 2, ptr %b, align 4
+ %c = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 2
+ store i32 3, ptr %c, align 4
+ %d = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 3
+ store i32 4, ptr %d, align 4
+ ret void
+}
+
+define i32 @caller_large_struct_ret() nounwind {
+ ; ILP32-LABEL: name: caller_large_struct_ret
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32_lp64, implicit-def $x1, implicit $x10
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
+ ; ILP32-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
+ ; ILP32-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
+ ; ILP32-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_large_struct_ret
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
+ ; ILP32F-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
+ ; ILP32F-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
+ ; ILP32F-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_large_struct_ret
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
+ ; ILP32D-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
+ ; ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
+ ; ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_large_struct_ret
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
+ ; ILP32Q-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
+ ; ILP32Q-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
+ ; ILP32Q-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = alloca %struct.large
+ call void @callee_large_struct_ret(ptr sret(%struct.large) %1)
+ %2 = load i32, ptr %1
+ %3 = getelementptr inbounds %struct.large, ptr %1, i32 0, i32 3
+ %4 = load i32, ptr %3
+ %5 = add i32 %2, %4
+ ret i32 %5
+}
+
+%struct.large2 = type { i32, float, i16, i32 }
+
+define %struct.large2 @callee_large_struct_ret2() nounwind {
+ ; RV32I-LABEL: name: callee_large_struct_ret2
+ ; RV32I: bb.1 (%ir-block.0):
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32I-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY [[DEF]](s32)
+ ; RV32I-NEXT: [[DEF1:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
+ ; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
+ ; RV32I-NEXT: [[C2:%[0-9]+]]:_(s16) = G_CONSTANT i16 3
+ ; RV32I-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; RV32I-NEXT: G_STORE [[C]](s32), [[COPY]](p0) :: (store (s32), align 8)
+ ; RV32I-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; RV32I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C4]](s32)
+ ; RV32I-NEXT: G_STORE [[C1]](s32), [[PTR_ADD]](p0) :: (store (s32))
+ ; RV32I-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; RV32I-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C5]](s32)
+ ; RV32I-NEXT: G_STORE [[C2]](s16), [[PTR_ADD1]](p0) :: (store (s16), align 8)
+ ; RV32I-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; RV32I-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C6]](s32)
+ ; RV32I-NEXT: G_STORE [[C3]](s32), [[PTR_ADD2]](p0) :: (store (s32))
+ ; RV32I-NEXT: PseudoRET
+ %a = insertvalue %struct.large2 poison, i32 1, 0
+ %b = insertvalue %struct.large2 %a, float 2.0, 1
+ %c = insertvalue %struct.large2 %b, i16 3, 2
+ %d = insertvalue %struct.large2 %c, i32 4, 3
+ ret %struct.large2 %d
+}
+
+define i32 @caller_large_struct_ret2() nounwind {
+ ; ILP32-LABEL: name: caller_large_struct_ret2
+ ; ILP32: bb.1 (%ir-block.0):
+ ; ILP32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32_lp64, implicit-def $x1, implicit $x10
+ ; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0, align 8)
+ ; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
+ ; ILP32-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %stack.0)
+ ; ILP32-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C1]](s32)
+ ; ILP32-NEXT: [[LOAD2:%[0-9]+]]:_(s16) = G_LOAD [[PTR_ADD1]](p0) :: (load (s16) from %stack.0, align 8)
+ ; ILP32-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C2]](s32)
+ ; ILP32-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD2]](p0) :: (load (s32) from %stack.0)
+ ; ILP32-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD3]]
+ ; ILP32-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32F-LABEL: name: caller_large_struct_ret2
+ ; ILP32F: bb.1 (%ir-block.0):
+ ; ILP32F-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10
+ ; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32F-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0, align 8)
+ ; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32F-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
+ ; ILP32F-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %stack.0)
+ ; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32F-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C1]](s32)
+ ; ILP32F-NEXT: [[LOAD2:%[0-9]+]]:_(s16) = G_LOAD [[PTR_ADD1]](p0) :: (load (s16) from %stack.0, align 8)
+ ; ILP32F-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32F-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C2]](s32)
+ ; ILP32F-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD2]](p0) :: (load (s32) from %stack.0)
+ ; ILP32F-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD3]]
+ ; ILP32F-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32F-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32D-LABEL: name: caller_large_struct_ret2
+ ; ILP32D: bb.1 (%ir-block.0):
+ ; ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10
+ ; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0, align 8)
+ ; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
+ ; ILP32D-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %stack.0)
+ ; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32D-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C1]](s32)
+ ; ILP32D-NEXT: [[LOAD2:%[0-9]+]]:_(s16) = G_LOAD [[PTR_ADD1]](p0) :: (load (s16) from %stack.0, align 8)
+ ; ILP32D-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32D-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C2]](s32)
+ ; ILP32D-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD2]](p0) :: (load (s32) from %stack.0)
+ ; ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD3]]
+ ; ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; ILP32Q-LABEL: name: caller_large_struct_ret2
+ ; ILP32Q: bb.1 (%ir-block.0):
+ ; ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
+ ; ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10
+ ; ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; ILP32Q-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0, align 8)
+ ; ILP32Q-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
+ ; ILP32Q-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %stack.0)
+ ; ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; ILP32Q-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C1]](s32)
+ ; ILP32Q-NEXT: [[LOAD2:%[0-9]+]]:_(s16) = G_LOAD [[PTR_ADD1]](p0) :: (load (s16) from %stack.0, align 8)
+ ; ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+ ; ILP32Q-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX]], [[C2]](s32)
+ ; ILP32Q-NEXT: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD2]](p0) :: (load (s32) from %stack.0)
+ ; ILP32Q-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD3]]
+ ; ILP32Q-NEXT: $x10 = COPY [[ADD]](s32)
+ ; ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call %struct.large2 @callee_large_struct_ret()
+ %2 = extractvalue %struct.large2 %1, 0
+ %3 = extractvalue %struct.large2 %1, 3
+ %4 = add i32 %2, %3
+ ret i32 %4
+}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32d-ilp32q.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32d-ilp32q.ll
new file mode 100644
index 0000000000000..f7ebd904e4807
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32d-ilp32q.ll
@@ -0,0 +1,555 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32-ILP32DQ,RV32-ILP32D %s
+; RUN: llc -mtriple=riscv32 -mattr=+q -target-abi ilp32q \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32-ILP32DQ,RV32-ILP32Q %s
+
+; This file contains tests that will have differing output for the ilp32/ilp32f
+; and ilp32d ABIs.
+
+define i32 @callee_double_in_fpr(i32 %a, double %b) nounwind {
+ ; RV32-ILP32DQ-LABEL: name: callee_double_in_fpr
+ ; RV32-ILP32DQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32DQ-NEXT: liveins: $x10, $f10_d
+ ; RV32-ILP32DQ-NEXT: {{ $}}
+ ; RV32-ILP32DQ-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32DQ-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV32-ILP32DQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY1]](s64)
+ ; RV32-ILP32DQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[FPTOSI]]
+ ; RV32-ILP32DQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32DQ-NEXT: PseudoRET implicit $x10
+ %b_fptosi = fptosi double %b to i32
+ %1 = add i32 %a, %b_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_fpr() nounwind {
+ ; RV32-ILP32D-LABEL: name: caller_double_in_fpr
+ ; RV32-ILP32D: bb.1 (%ir-block.0):
+ ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[C]](s32)
+ ; RV32-ILP32D-NEXT: $f10_d = COPY [[C1]](s64)
+ ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $f10_d, implicit-def $x10
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_double_in_fpr
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[C]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_d = COPY [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $f10_d, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_double_in_fpr(i32 1, double 2.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, double %f) nounwind {
+ ; RV32-ILP32DQ-LABEL: name: callee_double_in_fpr_exhausted_gprs
+ ; RV32-ILP32DQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32DQ-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d
+ ; RV32-ILP32DQ-NEXT: {{ $}}
+ ; RV32-ILP32DQ-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32DQ-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32DQ-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32-ILP32DQ-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32-ILP32DQ-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32-ILP32DQ-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32-ILP32DQ-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32-ILP32DQ-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32-ILP32DQ-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32-ILP32DQ-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32-ILP32DQ-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
+ ; RV32-ILP32DQ-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV32-ILP32DQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s64)
+ ; RV32-ILP32DQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[FPTOSI]]
+ ; RV32-ILP32DQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32DQ-NEXT: PseudoRET implicit $x10
+ %f_fptosi = fptosi double %f to i32
+ %1 = add i32 %e, %f_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_fpr_exhausted_gprs() nounwind {
+ ; RV32-ILP32D-LABEL: name: caller_double_in_fpr_exhausted_gprs
+ ; RV32-ILP32D: bb.1 (%ir-block.0):
+ ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; RV32-ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; RV32-ILP32D-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; RV32-ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32-ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; RV32-ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32D-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s32)
+ ; RV32-ILP32D-NEXT: G_STORE [[C4]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32D-NEXT: $x16 = COPY [[UV6]](s32)
+ ; RV32-ILP32D-NEXT: $x17 = COPY [[UV7]](s32)
+ ; RV32-ILP32D-NEXT: $f10_d = COPY [[C5]](s64)
+ ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr_exhausted_gprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_d, implicit-def $x10
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_double_in_fpr_exhausted_gprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s32)
+ ; RV32-ILP32Q-NEXT: G_STORE [[C4]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32Q-NEXT: $x16 = COPY [[UV6]](s32)
+ ; RV32-ILP32Q-NEXT: $x17 = COPY [[UV7]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_d = COPY [[C5]](s64)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr_exhausted_gprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_d, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_double_in_fpr_exhausted_gprs(
+ i64 1, i64 2, i64 3, i64 4, i32 5, double 6.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind {
+ ; RV32-ILP32DQ-LABEL: name: callee_double_in_gpr_exhausted_fprs
+ ; RV32-ILP32DQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32DQ-NEXT: liveins: $x10, $x11, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
+ ; RV32-ILP32DQ-NEXT: {{ $}}
+ ; RV32-ILP32DQ-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV32-ILP32DQ-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f11_d
+ ; RV32-ILP32DQ-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f12_d
+ ; RV32-ILP32DQ-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $f13_d
+ ; RV32-ILP32DQ-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f14_d
+ ; RV32-ILP32DQ-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f15_d
+ ; RV32-ILP32DQ-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $f16_d
+ ; RV32-ILP32DQ-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $f17_d
+ ; RV32-ILP32DQ-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32DQ-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32DQ-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY8]](s32), [[COPY9]](s32)
+ ; RV32-ILP32DQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY7]](s64)
+ ; RV32-ILP32DQ-NEXT: [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[MV]](s64)
+ ; RV32-ILP32DQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[FPTOSI]], [[FPTOSI1]]
+ ; RV32-ILP32DQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32DQ-NEXT: PseudoRET implicit $x10
+ %h_fptosi = fptosi double %h to i32
+ %i_fptosi = fptosi double %i to i32
+ %1 = add i32 %h_fptosi, %i_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_gpr_exhausted_fprs() nounwind {
+ ; RV32-ILP32D-LABEL: name: caller_double_in_gpr_exhausted_fprs
+ ; RV32-ILP32D: bb.1 (%ir-block.0):
+ ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 3.000000e+00
+ ; RV32-ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 5.000000e+00
+ ; RV32-ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 7.000000e+00
+ ; RV32-ILP32D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32D-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C8]](s64)
+ ; RV32-ILP32D-NEXT: $f10_d = COPY [[C]](s64)
+ ; RV32-ILP32D-NEXT: $f11_d = COPY [[C1]](s64)
+ ; RV32-ILP32D-NEXT: $f12_d = COPY [[C2]](s64)
+ ; RV32-ILP32D-NEXT: $f13_d = COPY [[C3]](s64)
+ ; RV32-ILP32D-NEXT: $f14_d = COPY [[C4]](s64)
+ ; RV32-ILP32D-NEXT: $f15_d = COPY [[C5]](s64)
+ ; RV32-ILP32D-NEXT: $f16_d = COPY [[C6]](s64)
+ ; RV32-ILP32D-NEXT: $f17_d = COPY [[C7]](s64)
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_exhausted_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $f10_d, implicit $f11_d, implicit $f12_d, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x10, implicit $x11, implicit-def $x10
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_double_in_gpr_exhausted_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 3.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 5.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 7.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C8]](s64)
+ ; RV32-ILP32Q-NEXT: $f10_d = COPY [[C]](s64)
+ ; RV32-ILP32Q-NEXT: $f11_d = COPY [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: $f12_d = COPY [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: $f13_d = COPY [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: $f14_d = COPY [[C4]](s64)
+ ; RV32-ILP32Q-NEXT: $f15_d = COPY [[C5]](s64)
+ ; RV32-ILP32Q-NEXT: $f16_d = COPY [[C6]](s64)
+ ; RV32-ILP32Q-NEXT: $f17_d = COPY [[C7]](s64)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_exhausted_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $f10_d, implicit $f11_d, implicit $f12_d, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x10, implicit $x11, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_double_in_gpr_exhausted_fprs(
+ double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0,
+ double 7.0, double 8.0, double 9.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i32 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
+ ; RV32-ILP32DQ-LABEL: name: callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs
+ ; RV32-ILP32DQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32DQ-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
+ ; RV32-ILP32DQ-NEXT: {{ $}}
+ ; RV32-ILP32DQ-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32DQ-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32DQ-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV32-ILP32DQ-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32-ILP32DQ-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32-ILP32DQ-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f11_d
+ ; RV32-ILP32DQ-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32-ILP32DQ-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32-ILP32DQ-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f12_d
+ ; RV32-ILP32DQ-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32-ILP32DQ-NEXT: [[COPY10:%[0-9]+]]:_(s64) = COPY $f13_d
+ ; RV32-ILP32DQ-NEXT: [[COPY11:%[0-9]+]]:_(s64) = COPY $f14_d
+ ; RV32-ILP32DQ-NEXT: [[COPY12:%[0-9]+]]:_(s64) = COPY $f15_d
+ ; RV32-ILP32DQ-NEXT: [[COPY13:%[0-9]+]]:_(s64) = COPY $f16_d
+ ; RV32-ILP32DQ-NEXT: [[COPY14:%[0-9]+]]:_(s64) = COPY $f17_d
+ ; RV32-ILP32DQ-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32-ILP32DQ-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
+ ; RV32-ILP32DQ-NEXT: [[COPY15:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32-ILP32DQ-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY15]](s32), [[LOAD]](s32)
+ ; RV32-ILP32DQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[MV3]](s64)
+ ; RV32-ILP32DQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY9]], [[FPTOSI]]
+ ; RV32-ILP32DQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32DQ-NEXT: PseudoRET implicit $x10
+ %m_fptosi = fptosi double %m to i32
+ %1 = add i32 %g, %m_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind {
+ ; RV32-ILP32D-LABEL: name: caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs
+ ; RV32-ILP32D: bb.1 (%ir-block.0):
+ ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; RV32-ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32D-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
+ ; RV32-ILP32D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32D-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32D-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; RV32-ILP32D-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; RV32-ILP32D-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; RV32-ILP32D-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32-ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; RV32-ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C12]](s64)
+ ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32D-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; RV32-ILP32D-NEXT: G_STORE [[UV7]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32D-NEXT: $f10_d = COPY [[C1]](s64)
+ ; RV32-ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32D-NEXT: $f11_d = COPY [[C3]](s64)
+ ; RV32-ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32D-NEXT: $f12_d = COPY [[C5]](s64)
+ ; RV32-ILP32D-NEXT: $x16 = COPY [[C6]](s32)
+ ; RV32-ILP32D-NEXT: $f13_d = COPY [[C7]](s64)
+ ; RV32-ILP32D-NEXT: $f14_d = COPY [[C8]](s64)
+ ; RV32-ILP32D-NEXT: $f15_d = COPY [[C9]](s64)
+ ; RV32-ILP32D-NEXT: $f16_d = COPY [[C10]](s64)
+ ; RV32-ILP32D-NEXT: $f17_d = COPY [[C11]](s64)
+ ; RV32-ILP32D-NEXT: $x17 = COPY [[UV6]](s32)
+ ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x17, implicit-def $x10
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
+ ; RV32-ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; RV32-ILP32Q-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; RV32-ILP32Q-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; RV32-ILP32Q-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C12]](s64)
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32Q-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; RV32-ILP32Q-NEXT: G_STORE [[UV7]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_d = COPY [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32Q-NEXT: $f11_d = COPY [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32Q-NEXT: $f12_d = COPY [[C5]](s64)
+ ; RV32-ILP32Q-NEXT: $x16 = COPY [[C6]](s32)
+ ; RV32-ILP32Q-NEXT: $f13_d = COPY [[C7]](s64)
+ ; RV32-ILP32Q-NEXT: $f14_d = COPY [[C8]](s64)
+ ; RV32-ILP32Q-NEXT: $f15_d = COPY [[C9]](s64)
+ ; RV32-ILP32Q-NEXT: $f16_d = COPY [[C10]](s64)
+ ; RV32-ILP32Q-NEXT: $f17_d = COPY [[C11]](s64)
+ ; RV32-ILP32Q-NEXT: $x17 = COPY [[UV6]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x17, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(
+ i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i32 7, double 8.0,
+ double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
+ ret i32 %1
+}
+
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_on_stack_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i64 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
+ ; RV32-ILP32DQ-LABEL: name: callee_double_on_stack_exhausted_gprs_fprs
+ ; RV32-ILP32DQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32DQ-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
+ ; RV32-ILP32DQ-NEXT: {{ $}}
+ ; RV32-ILP32DQ-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32DQ-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32DQ-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV32-ILP32DQ-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32-ILP32DQ-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32-ILP32DQ-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f11_d
+ ; RV32-ILP32DQ-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32-ILP32DQ-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32-ILP32DQ-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f12_d
+ ; RV32-ILP32DQ-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32-ILP32DQ-NEXT: [[COPY10:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32-ILP32DQ-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY9]](s32), [[COPY10]](s32)
+ ; RV32-ILP32DQ-NEXT: [[COPY11:%[0-9]+]]:_(s64) = COPY $f13_d
+ ; RV32-ILP32DQ-NEXT: [[COPY12:%[0-9]+]]:_(s64) = COPY $f14_d
+ ; RV32-ILP32DQ-NEXT: [[COPY13:%[0-9]+]]:_(s64) = COPY $f15_d
+ ; RV32-ILP32DQ-NEXT: [[COPY14:%[0-9]+]]:_(s64) = COPY $f16_d
+ ; RV32-ILP32DQ-NEXT: [[COPY15:%[0-9]+]]:_(s64) = COPY $f17_d
+ ; RV32-ILP32DQ-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32-ILP32DQ-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.0, align 16)
+ ; RV32-ILP32DQ-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV3]](s64)
+ ; RV32-ILP32DQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD]](s64)
+ ; RV32-ILP32DQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[FPTOSI]]
+ ; RV32-ILP32DQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32DQ-NEXT: PseudoRET implicit $x10
+ %g_trunc = trunc i64 %g to i32
+ %m_fptosi = fptosi double %m to i32
+ %1 = add i32 %g_trunc, %m_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_on_stack_exhausted_gprs_fprs() nounwind {
+ ; RV32-ILP32D-LABEL: name: caller_double_on_stack_exhausted_gprs_fprs
+ ; RV32-ILP32D: bb.1 (%ir-block.0):
+ ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; RV32-ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; RV32-ILP32D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32D-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32D-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; RV32-ILP32D-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; RV32-ILP32D-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; RV32-ILP32D-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32-ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; RV32-ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32D-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; RV32-ILP32D-NEXT: G_STORE [[C12]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32D-NEXT: $f10_d = COPY [[C1]](s64)
+ ; RV32-ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32D-NEXT: $f11_d = COPY [[C3]](s64)
+ ; RV32-ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32D-NEXT: $f12_d = COPY [[C5]](s64)
+ ; RV32-ILP32D-NEXT: $x16 = COPY [[UV6]](s32)
+ ; RV32-ILP32D-NEXT: $x17 = COPY [[UV7]](s32)
+ ; RV32-ILP32D-NEXT: $f13_d = COPY [[C7]](s64)
+ ; RV32-ILP32D-NEXT: $f14_d = COPY [[C8]](s64)
+ ; RV32-ILP32D-NEXT: $f15_d = COPY [[C9]](s64)
+ ; RV32-ILP32D-NEXT: $f16_d = COPY [[C10]](s64)
+ ; RV32-ILP32D-NEXT: $f17_d = COPY [[C11]](s64)
+ ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_on_stack_exhausted_gprs_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $x17, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit-def $x10
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_double_on_stack_exhausted_gprs_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; RV32-ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; RV32-ILP32Q-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; RV32-ILP32Q-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; RV32-ILP32Q-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32Q-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; RV32-ILP32Q-NEXT: G_STORE [[C12]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_d = COPY [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32Q-NEXT: $f11_d = COPY [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32Q-NEXT: $f12_d = COPY [[C5]](s64)
+ ; RV32-ILP32Q-NEXT: $x16 = COPY [[UV6]](s32)
+ ; RV32-ILP32Q-NEXT: $x17 = COPY [[UV7]](s32)
+ ; RV32-ILP32Q-NEXT: $f13_d = COPY [[C7]](s64)
+ ; RV32-ILP32Q-NEXT: $f14_d = COPY [[C8]](s64)
+ ; RV32-ILP32Q-NEXT: $f15_d = COPY [[C9]](s64)
+ ; RV32-ILP32Q-NEXT: $f16_d = COPY [[C10]](s64)
+ ; RV32-ILP32Q-NEXT: $f17_d = COPY [[C11]](s64)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_on_stack_exhausted_gprs_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $x17, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_double_on_stack_exhausted_gprs_fprs(
+ i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i64 7, double 8.0,
+ double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
+ ret i32 %1
+}
+
+define double @callee_double_ret() nounwind {
+ ; RV32-ILP32DQ-LABEL: name: callee_double_ret
+ ; RV32-ILP32DQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32DQ-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; RV32-ILP32DQ-NEXT: $f10_d = COPY [[C]](s64)
+ ; RV32-ILP32DQ-NEXT: PseudoRET implicit $f10_d
+ ret double 1.0
+}
+
+define i32 @caller_double_ret() nounwind {
+ ; RV32-ILP32D-LABEL: name: caller_double_ret
+ ; RV32-ILP32D: bb.1 (%ir-block.0):
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $f10_d
+ ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV32-ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; RV32-ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_double_ret
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit-def $f10_d
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV32-ILP32Q-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call double @callee_double_ret()
+ %2 = bitcast double %1 to i64
+ %3 = trunc i64 %2 to i32
+ ret i32 %3
+}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32d.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32d.ll
deleted file mode 100644
index 4d487eb5cda23..0000000000000
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32d.ll
+++ /dev/null
@@ -1,376 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
-; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
-; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
-; RUN: | FileCheck -check-prefix=RV32-ILP32D %s
-
-; This file contains tests that will have differing output for the ilp32/ilp32f
-; and ilp32d ABIs.
-
-define i32 @callee_double_in_fpr(i32 %a, double %b) nounwind {
- ; RV32-ILP32D-LABEL: name: callee_double_in_fpr
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: liveins: $x10, $f10_d
- ; RV32-ILP32D-NEXT: {{ $}}
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV32-ILP32D-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY1]](s64)
- ; RV32-ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[FPTOSI]]
- ; RV32-ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %b_fptosi = fptosi double %b to i32
- %1 = add i32 %a, %b_fptosi
- ret i32 %1
-}
-
-define i32 @caller_double_in_fpr() nounwind {
- ; RV32-ILP32D-LABEL: name: caller_double_in_fpr
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
- ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
- ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: $x10 = COPY [[C]](s32)
- ; RV32-ILP32D-NEXT: $f10_d = COPY [[C1]](s64)
- ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $f10_d, implicit-def $x10
- ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_double_in_fpr(i32 1, double 2.0)
- ret i32 %1
-}
-
-; Must keep define on a single line due to an update_llc_test_checks.py limitation
-define i32 @callee_double_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, double %f) nounwind {
- ; RV32-ILP32D-LABEL: name: callee_double_in_fpr_exhausted_gprs
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d
- ; RV32-ILP32D-NEXT: {{ $}}
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32-ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; RV32-ILP32D-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32-ILP32D-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
- ; RV32-ILP32D-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
- ; RV32-ILP32D-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
- ; RV32-ILP32D-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
- ; RV32-ILP32D-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
- ; RV32-ILP32D-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
- ; RV32-ILP32D-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
- ; RV32-ILP32D-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
- ; RV32-ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV32-ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
- ; RV32-ILP32D-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV32-ILP32D-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s64)
- ; RV32-ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[FPTOSI]]
- ; RV32-ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %f_fptosi = fptosi double %f to i32
- %1 = add i32 %e, %f_fptosi
- ret i32 %1
-}
-
-define i32 @caller_double_in_fpr_exhausted_gprs() nounwind {
- ; RV32-ILP32D-LABEL: name: caller_double_in_fpr_exhausted_gprs
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
- ; RV32-ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
- ; RV32-ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
- ; RV32-ILP32D-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
- ; RV32-ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
- ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; RV32-ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
- ; RV32-ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
- ; RV32-ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; RV32-ILP32D-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; RV32-ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s32)
- ; RV32-ILP32D-NEXT: G_STORE [[C4]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
- ; RV32-ILP32D-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32-ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32-ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
- ; RV32-ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
- ; RV32-ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
- ; RV32-ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
- ; RV32-ILP32D-NEXT: $x16 = COPY [[UV6]](s32)
- ; RV32-ILP32D-NEXT: $x17 = COPY [[UV7]](s32)
- ; RV32-ILP32D-NEXT: $f10_d = COPY [[C5]](s64)
- ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr_exhausted_gprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_d, implicit-def $x10
- ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_double_in_fpr_exhausted_gprs(
- i64 1, i64 2, i64 3, i64 4, i32 5, double 6.0)
- ret i32 %1
-}
-
-; Must keep define on a single line due to an update_llc_test_checks.py limitation
-define i32 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind {
- ; RV32-ILP32D-LABEL: name: callee_double_in_gpr_exhausted_fprs
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: liveins: $x10, $x11, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
- ; RV32-ILP32D-NEXT: {{ $}}
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f11_d
- ; RV32-ILP32D-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f12_d
- ; RV32-ILP32D-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $f13_d
- ; RV32-ILP32D-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f14_d
- ; RV32-ILP32D-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f15_d
- ; RV32-ILP32D-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $f16_d
- ; RV32-ILP32D-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $f17_d
- ; RV32-ILP32D-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32-ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY8]](s32), [[COPY9]](s32)
- ; RV32-ILP32D-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY7]](s64)
- ; RV32-ILP32D-NEXT: [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[MV]](s64)
- ; RV32-ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[FPTOSI]], [[FPTOSI1]]
- ; RV32-ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %h_fptosi = fptosi double %h to i32
- %i_fptosi = fptosi double %i to i32
- %1 = add i32 %h_fptosi, %i_fptosi
- ret i32 %1
-}
-
-define i32 @caller_double_in_gpr_exhausted_fprs() nounwind {
- ; RV32-ILP32D-LABEL: name: caller_double_in_gpr_exhausted_fprs
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
- ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
- ; RV32-ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 3.000000e+00
- ; RV32-ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
- ; RV32-ILP32D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 5.000000e+00
- ; RV32-ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
- ; RV32-ILP32D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 7.000000e+00
- ; RV32-ILP32D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
- ; RV32-ILP32D-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
- ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C8]](s64)
- ; RV32-ILP32D-NEXT: $f10_d = COPY [[C]](s64)
- ; RV32-ILP32D-NEXT: $f11_d = COPY [[C1]](s64)
- ; RV32-ILP32D-NEXT: $f12_d = COPY [[C2]](s64)
- ; RV32-ILP32D-NEXT: $f13_d = COPY [[C3]](s64)
- ; RV32-ILP32D-NEXT: $f14_d = COPY [[C4]](s64)
- ; RV32-ILP32D-NEXT: $f15_d = COPY [[C5]](s64)
- ; RV32-ILP32D-NEXT: $f16_d = COPY [[C6]](s64)
- ; RV32-ILP32D-NEXT: $f17_d = COPY [[C7]](s64)
- ; RV32-ILP32D-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32-ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_exhausted_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $f10_d, implicit $f11_d, implicit $f12_d, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x10, implicit $x11, implicit-def $x10
- ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_double_in_gpr_exhausted_fprs(
- double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0,
- double 7.0, double 8.0, double 9.0)
- ret i32 %1
-}
-
-; Must keep define on a single line due to an update_llc_test_checks.py limitation
-define i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i32 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
- ; RV32-ILP32D-LABEL: name: callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
- ; RV32-ILP32D-NEXT: {{ $}}
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32-ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; RV32-ILP32D-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV32-ILP32D-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32-ILP32D-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x13
- ; RV32-ILP32D-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
- ; RV32-ILP32D-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f11_d
- ; RV32-ILP32D-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x14
- ; RV32-ILP32D-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x15
- ; RV32-ILP32D-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
- ; RV32-ILP32D-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f12_d
- ; RV32-ILP32D-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x16
- ; RV32-ILP32D-NEXT: [[COPY10:%[0-9]+]]:_(s64) = COPY $f13_d
- ; RV32-ILP32D-NEXT: [[COPY11:%[0-9]+]]:_(s64) = COPY $f14_d
- ; RV32-ILP32D-NEXT: [[COPY12:%[0-9]+]]:_(s64) = COPY $f15_d
- ; RV32-ILP32D-NEXT: [[COPY13:%[0-9]+]]:_(s64) = COPY $f16_d
- ; RV32-ILP32D-NEXT: [[COPY14:%[0-9]+]]:_(s64) = COPY $f17_d
- ; RV32-ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV32-ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
- ; RV32-ILP32D-NEXT: [[COPY15:%[0-9]+]]:_(s32) = COPY $x17
- ; RV32-ILP32D-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY15]](s32), [[LOAD]](s32)
- ; RV32-ILP32D-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[MV3]](s64)
- ; RV32-ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY9]], [[FPTOSI]]
- ; RV32-ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %m_fptosi = fptosi double %m to i32
- %1 = add i32 %g, %m_fptosi
- ret i32 %1
-}
-
-define i32 @caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind {
- ; RV32-ILP32D-LABEL: name: caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
- ; RV32-ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
- ; RV32-ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
- ; RV32-ILP32D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
- ; RV32-ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
- ; RV32-ILP32D-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
- ; RV32-ILP32D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
- ; RV32-ILP32D-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
- ; RV32-ILP32D-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
- ; RV32-ILP32D-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
- ; RV32-ILP32D-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
- ; RV32-ILP32D-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
- ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; RV32-ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
- ; RV32-ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
- ; RV32-ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C12]](s64)
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; RV32-ILP32D-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; RV32-ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
- ; RV32-ILP32D-NEXT: G_STORE [[UV7]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
- ; RV32-ILP32D-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32-ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32-ILP32D-NEXT: $f10_d = COPY [[C1]](s64)
- ; RV32-ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
- ; RV32-ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
- ; RV32-ILP32D-NEXT: $f11_d = COPY [[C3]](s64)
- ; RV32-ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
- ; RV32-ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
- ; RV32-ILP32D-NEXT: $f12_d = COPY [[C5]](s64)
- ; RV32-ILP32D-NEXT: $x16 = COPY [[C6]](s32)
- ; RV32-ILP32D-NEXT: $f13_d = COPY [[C7]](s64)
- ; RV32-ILP32D-NEXT: $f14_d = COPY [[C8]](s64)
- ; RV32-ILP32D-NEXT: $f15_d = COPY [[C9]](s64)
- ; RV32-ILP32D-NEXT: $f16_d = COPY [[C10]](s64)
- ; RV32-ILP32D-NEXT: $f17_d = COPY [[C11]](s64)
- ; RV32-ILP32D-NEXT: $x17 = COPY [[UV6]](s32)
- ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x17, implicit-def $x10
- ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(
- i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i32 7, double 8.0,
- double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
- ret i32 %1
-}
-
-
-; Must keep define on a single line due to an update_llc_test_checks.py limitation
-define i32 @callee_double_on_stack_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i64 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
- ; RV32-ILP32D-LABEL: name: callee_double_on_stack_exhausted_gprs_fprs
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
- ; RV32-ILP32D-NEXT: {{ $}}
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32-ILP32D-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; RV32-ILP32D-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV32-ILP32D-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32-ILP32D-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x13
- ; RV32-ILP32D-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
- ; RV32-ILP32D-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f11_d
- ; RV32-ILP32D-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x14
- ; RV32-ILP32D-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x15
- ; RV32-ILP32D-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
- ; RV32-ILP32D-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f12_d
- ; RV32-ILP32D-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x16
- ; RV32-ILP32D-NEXT: [[COPY10:%[0-9]+]]:_(s32) = COPY $x17
- ; RV32-ILP32D-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY9]](s32), [[COPY10]](s32)
- ; RV32-ILP32D-NEXT: [[COPY11:%[0-9]+]]:_(s64) = COPY $f13_d
- ; RV32-ILP32D-NEXT: [[COPY12:%[0-9]+]]:_(s64) = COPY $f14_d
- ; RV32-ILP32D-NEXT: [[COPY13:%[0-9]+]]:_(s64) = COPY $f15_d
- ; RV32-ILP32D-NEXT: [[COPY14:%[0-9]+]]:_(s64) = COPY $f16_d
- ; RV32-ILP32D-NEXT: [[COPY15:%[0-9]+]]:_(s64) = COPY $f17_d
- ; RV32-ILP32D-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV32-ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.0, align 16)
- ; RV32-ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV3]](s64)
- ; RV32-ILP32D-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD]](s64)
- ; RV32-ILP32D-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[FPTOSI]]
- ; RV32-ILP32D-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %g_trunc = trunc i64 %g to i32
- %m_fptosi = fptosi double %m to i32
- %1 = add i32 %g_trunc, %m_fptosi
- ret i32 %1
-}
-
-define i32 @caller_double_on_stack_exhausted_gprs_fprs() nounwind {
- ; RV32-ILP32D-LABEL: name: caller_double_on_stack_exhausted_gprs_fprs
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; RV32-ILP32D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
- ; RV32-ILP32D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
- ; RV32-ILP32D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
- ; RV32-ILP32D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
- ; RV32-ILP32D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
- ; RV32-ILP32D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
- ; RV32-ILP32D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
- ; RV32-ILP32D-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
- ; RV32-ILP32D-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
- ; RV32-ILP32D-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
- ; RV32-ILP32D-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
- ; RV32-ILP32D-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
- ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
- ; RV32-ILP32D-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
- ; RV32-ILP32D-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
- ; RV32-ILP32D-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; RV32-ILP32D-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; RV32-ILP32D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
- ; RV32-ILP32D-NEXT: G_STORE [[C12]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
- ; RV32-ILP32D-NEXT: $x10 = COPY [[UV]](s32)
- ; RV32-ILP32D-NEXT: $x11 = COPY [[UV1]](s32)
- ; RV32-ILP32D-NEXT: $f10_d = COPY [[C1]](s64)
- ; RV32-ILP32D-NEXT: $x12 = COPY [[UV2]](s32)
- ; RV32-ILP32D-NEXT: $x13 = COPY [[UV3]](s32)
- ; RV32-ILP32D-NEXT: $f11_d = COPY [[C3]](s64)
- ; RV32-ILP32D-NEXT: $x14 = COPY [[UV4]](s32)
- ; RV32-ILP32D-NEXT: $x15 = COPY [[UV5]](s32)
- ; RV32-ILP32D-NEXT: $f12_d = COPY [[C5]](s64)
- ; RV32-ILP32D-NEXT: $x16 = COPY [[UV6]](s32)
- ; RV32-ILP32D-NEXT: $x17 = COPY [[UV7]](s32)
- ; RV32-ILP32D-NEXT: $f13_d = COPY [[C7]](s64)
- ; RV32-ILP32D-NEXT: $f14_d = COPY [[C8]](s64)
- ; RV32-ILP32D-NEXT: $f15_d = COPY [[C9]](s64)
- ; RV32-ILP32D-NEXT: $f16_d = COPY [[C10]](s64)
- ; RV32-ILP32D-NEXT: $f17_d = COPY [[C11]](s64)
- ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_on_stack_exhausted_gprs_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $x17, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit-def $x10
- ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_double_on_stack_exhausted_gprs_fprs(
- i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i64 7, double 8.0,
- double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
- ret i32 %1
-}
-
-define double @callee_double_ret() nounwind {
- ; RV32-ILP32D-LABEL: name: callee_double_ret
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
- ; RV32-ILP32D-NEXT: $f10_d = COPY [[C]](s64)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $f10_d
- ret double 1.0
-}
-
-define i32 @caller_double_ret() nounwind {
- ; RV32-ILP32D-LABEL: name: caller_double_ret
- ; RV32-ILP32D: bb.1 (%ir-block.0):
- ; RV32-ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $f10_d
- ; RV32-ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV32-ILP32D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; RV32-ILP32D-NEXT: $x10 = COPY [[TRUNC]](s32)
- ; RV32-ILP32D-NEXT: PseudoRET implicit $x10
- %1 = call double @callee_double_ret()
- %2 = bitcast double %1 to i64
- %3 = trunc i64 %2 to i32
- ret i32 %3
-}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32f-ilp32d-common.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32f-ilp32d-ilp32q-common.ll
similarity index 57%
rename from llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32f-ilp32d-common.ll
rename to llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32f-ilp32d-ilp32q-common.ll
index a9c603bfdd743..88d90cfb44710 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32f-ilp32d-common.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32f-ilp32d-ilp32q-common.ll
@@ -1,25 +1,28 @@
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f \
; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
-; RUN: | FileCheck -check-prefixes=RV32-ILP32FD,RV32-ILP32F %s
+; RUN: | FileCheck -check-prefixes=RV32-ILP32FDQ,RV32-ILP32F %s
; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
-; RUN: | FileCheck -check-prefixes=RV32-ILP32FD,RV32-ILP32D %s
+; RUN: | FileCheck -check-prefixes=RV32-ILP32FDQ,RV32-ILP32D %s
+; RUN: llc -mtriple=riscv32 -mattr=+q -target-abi ilp32q \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32-ILP32FDQ,RV32-ILP32Q %s
; This file contains tests that should have identical output for the ilp32f
; and ilp32d ABIs.
define i32 @callee_float_in_fpr(i32 %a, float %b) nounwind {
- ; RV32-ILP32FD-LABEL: name: callee_float_in_fpr
- ; RV32-ILP32FD: bb.1 (%ir-block.0):
- ; RV32-ILP32FD-NEXT: liveins: $x10, $f10_f
- ; RV32-ILP32FD-NEXT: {{ $}}
- ; RV32-ILP32FD-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32FD-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f10_f
- ; RV32-ILP32FD-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY1]](s32)
- ; RV32-ILP32FD-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[FPTOSI]]
- ; RV32-ILP32FD-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32FD-NEXT: PseudoRET implicit $x10
+ ; RV32-ILP32FDQ-LABEL: name: callee_float_in_fpr
+ ; RV32-ILP32FDQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32FDQ-NEXT: liveins: $x10, $f10_f
+ ; RV32-ILP32FDQ-NEXT: {{ $}}
+ ; RV32-ILP32FDQ-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32FDQ-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f10_f
+ ; RV32-ILP32FDQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY1]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[FPTOSI]]
+ ; RV32-ILP32FDQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32FDQ-NEXT: PseudoRET implicit $x10
%b_fptosi = fptosi float %b to i32
%1 = add i32 %a, %b_fptosi
ret i32 %1
@@ -51,35 +54,48 @@ define i32 @caller_float_in_fpr() nounwind {
; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
; RV32-ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_float_in_fpr
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[C]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_f = COPY [[C1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_float_in_fpr, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $f10_f, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
%1 = call i32 @callee_float_in_fpr(i32 1, float 2.0)
ret i32 %1
}
; Must keep define on a single line due to an update_llc_test_checks.py limitation
define i32 @callee_float_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, float %f) nounwind {
- ; RV32-ILP32FD-LABEL: name: callee_float_in_fpr_exhausted_gprs
- ; RV32-ILP32FD: bb.1 (%ir-block.0):
- ; RV32-ILP32FD-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_f
- ; RV32-ILP32FD-NEXT: {{ $}}
- ; RV32-ILP32FD-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32FD-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32-ILP32FD-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; RV32-ILP32FD-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32-ILP32FD-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
- ; RV32-ILP32FD-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
- ; RV32-ILP32FD-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
- ; RV32-ILP32FD-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
- ; RV32-ILP32FD-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
- ; RV32-ILP32FD-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
- ; RV32-ILP32FD-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
- ; RV32-ILP32FD-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
- ; RV32-ILP32FD-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV32-ILP32FD-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
- ; RV32-ILP32FD-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $f10_f
- ; RV32-ILP32FD-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s32)
- ; RV32-ILP32FD-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[FPTOSI]]
- ; RV32-ILP32FD-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32FD-NEXT: PseudoRET implicit $x10
+ ; RV32-ILP32FDQ-LABEL: name: callee_float_in_fpr_exhausted_gprs
+ ; RV32-ILP32FDQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32FDQ-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_f
+ ; RV32-ILP32FDQ-NEXT: {{ $}}
+ ; RV32-ILP32FDQ-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32FDQ-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32FDQ-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32-ILP32FDQ-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32-ILP32FDQ-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32-ILP32FDQ-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32-ILP32FDQ-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32-ILP32FDQ-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32-ILP32FDQ-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32-ILP32FDQ-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
+ ; RV32-ILP32FDQ-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $f10_f
+ ; RV32-ILP32FDQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[FPTOSI]]
+ ; RV32-ILP32FDQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32FDQ-NEXT: PseudoRET implicit $x10
%f_fptosi = fptosi float %f to i32
%1 = add i32 %e, %f_fptosi
ret i32 %1
@@ -149,6 +165,38 @@ define i32 @caller_float_in_fpr_exhausted_gprs() nounwind {
; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
; RV32-ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_float_in_fpr_exhausted_gprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s32) = G_FCONSTANT float 6.000000e+00
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s32)
+ ; RV32-ILP32Q-NEXT: G_STORE [[C4]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32Q-NEXT: $x16 = COPY [[UV6]](s32)
+ ; RV32-ILP32Q-NEXT: $x17 = COPY [[UV7]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_f = COPY [[C5]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_float_in_fpr_exhausted_gprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_f, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
%1 = call i32 @callee_float_in_fpr_exhausted_gprs(
i64 1, i64 2, i64 3, i64 4, i32 5, float 6.0)
ret i32 %1
@@ -156,24 +204,24 @@ define i32 @caller_float_in_fpr_exhausted_gprs() nounwind {
; Must keep define on a single line due to an update_llc_test_checks.py limitation
define i32 @callee_float_in_gpr_exhausted_fprs(float %a, float %b, float %c, float %d, float %e, float %f, float %g, float %h, float %i) nounwind {
- ; RV32-ILP32FD-LABEL: name: callee_float_in_gpr_exhausted_fprs
- ; RV32-ILP32FD: bb.1 (%ir-block.0):
- ; RV32-ILP32FD-NEXT: liveins: $x10, $f10_f, $f11_f, $f12_f, $f13_f, $f14_f, $f15_f, $f16_f, $f17_f
- ; RV32-ILP32FD-NEXT: {{ $}}
- ; RV32-ILP32FD-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $f10_f
- ; RV32-ILP32FD-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f11_f
- ; RV32-ILP32FD-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $f12_f
- ; RV32-ILP32FD-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $f13_f
- ; RV32-ILP32FD-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $f14_f
- ; RV32-ILP32FD-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $f15_f
- ; RV32-ILP32FD-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $f16_f
- ; RV32-ILP32FD-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $f17_f
- ; RV32-ILP32FD-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32FD-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY7]](s32)
- ; RV32-ILP32FD-NEXT: [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s32)
- ; RV32-ILP32FD-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[FPTOSI]], [[FPTOSI1]]
- ; RV32-ILP32FD-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32FD-NEXT: PseudoRET implicit $x10
+ ; RV32-ILP32FDQ-LABEL: name: callee_float_in_gpr_exhausted_fprs
+ ; RV32-ILP32FDQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32FDQ-NEXT: liveins: $x10, $f10_f, $f11_f, $f12_f, $f13_f, $f14_f, $f15_f, $f16_f, $f17_f
+ ; RV32-ILP32FDQ-NEXT: {{ $}}
+ ; RV32-ILP32FDQ-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $f10_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f11_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $f12_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $f13_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $f14_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $f15_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $f16_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $f17_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32FDQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY7]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[FPTOSI]], [[FPTOSI1]]
+ ; RV32-ILP32FDQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32FDQ-NEXT: PseudoRET implicit $x10
%h_fptosi = fptosi float %h to i32
%i_fptosi = fptosi float %i to i32
%1 = add i32 %h_fptosi, %i_fptosi
@@ -234,6 +282,33 @@ define i32 @caller_float_in_gpr_exhausted_fprs() nounwind {
; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
; RV32-ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_float_in_gpr_exhausted_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s32) = G_FCONSTANT float 3.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s32) = G_FCONSTANT float 4.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s32) = G_FCONSTANT float 5.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s32) = G_FCONSTANT float 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s32) = G_FCONSTANT float 7.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s32) = G_FCONSTANT float 8.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s32) = G_FCONSTANT float 9.000000e+00
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: $f10_f = COPY [[C]](s32)
+ ; RV32-ILP32Q-NEXT: $f11_f = COPY [[C1]](s32)
+ ; RV32-ILP32Q-NEXT: $f12_f = COPY [[C2]](s32)
+ ; RV32-ILP32Q-NEXT: $f13_f = COPY [[C3]](s32)
+ ; RV32-ILP32Q-NEXT: $f14_f = COPY [[C4]](s32)
+ ; RV32-ILP32Q-NEXT: $f15_f = COPY [[C5]](s32)
+ ; RV32-ILP32Q-NEXT: $f16_f = COPY [[C6]](s32)
+ ; RV32-ILP32Q-NEXT: $f17_f = COPY [[C7]](s32)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[C8]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_float_in_gpr_exhausted_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $f10_f, implicit $f11_f, implicit $f12_f, implicit $f13_f, implicit $f14_f, implicit $f15_f, implicit $f16_f, implicit $f17_f, implicit $x10, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
%1 = call i32 @callee_float_in_gpr_exhausted_fprs(
float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0,
float 7.0, float 8.0, float 9.0)
@@ -242,37 +317,37 @@ define i32 @caller_float_in_gpr_exhausted_fprs() nounwind {
; Must keep define on a single line due to an update_llc_test_checks.py limitation
define i32 @callee_float_on_stack_exhausted_gprs_fprs(i64 %a, float %b, i64 %c, float %d, i64 %e, float %f, i64 %g, float %h, float %i, float %j, float %k, float %l, float %m) nounwind {
- ; RV32-ILP32FD-LABEL: name: callee_float_on_stack_exhausted_gprs_fprs
- ; RV32-ILP32FD: bb.1 (%ir-block.0):
- ; RV32-ILP32FD-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_f, $f11_f, $f12_f, $f13_f, $f14_f, $f15_f, $f16_f, $f17_f
- ; RV32-ILP32FD-NEXT: {{ $}}
- ; RV32-ILP32FD-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
- ; RV32-ILP32FD-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
- ; RV32-ILP32FD-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
- ; RV32-ILP32FD-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $f10_f
- ; RV32-ILP32FD-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x12
- ; RV32-ILP32FD-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x13
- ; RV32-ILP32FD-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
- ; RV32-ILP32FD-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $f11_f
- ; RV32-ILP32FD-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x14
- ; RV32-ILP32FD-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x15
- ; RV32-ILP32FD-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
- ; RV32-ILP32FD-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $f12_f
- ; RV32-ILP32FD-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x16
- ; RV32-ILP32FD-NEXT: [[COPY10:%[0-9]+]]:_(s32) = COPY $x17
- ; RV32-ILP32FD-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY9]](s32), [[COPY10]](s32)
- ; RV32-ILP32FD-NEXT: [[COPY11:%[0-9]+]]:_(s32) = COPY $f13_f
- ; RV32-ILP32FD-NEXT: [[COPY12:%[0-9]+]]:_(s32) = COPY $f14_f
- ; RV32-ILP32FD-NEXT: [[COPY13:%[0-9]+]]:_(s32) = COPY $f15_f
- ; RV32-ILP32FD-NEXT: [[COPY14:%[0-9]+]]:_(s32) = COPY $f16_f
- ; RV32-ILP32FD-NEXT: [[COPY15:%[0-9]+]]:_(s32) = COPY $f17_f
- ; RV32-ILP32FD-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV32-ILP32FD-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
- ; RV32-ILP32FD-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV3]](s64)
- ; RV32-ILP32FD-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD]](s32)
- ; RV32-ILP32FD-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[FPTOSI]]
- ; RV32-ILP32FD-NEXT: $x10 = COPY [[ADD]](s32)
- ; RV32-ILP32FD-NEXT: PseudoRET implicit $x10
+ ; RV32-ILP32FDQ-LABEL: name: callee_float_on_stack_exhausted_gprs_fprs
+ ; RV32-ILP32FDQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32FDQ-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_f, $f11_f, $f12_f, $f13_f, $f14_f, $f15_f, $f16_f, $f17_f
+ ; RV32-ILP32FDQ-NEXT: {{ $}}
+ ; RV32-ILP32FDQ-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32FDQ-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32FDQ-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $f10_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32-ILP32FDQ-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32-ILP32FDQ-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $f11_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32-ILP32FDQ-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32-ILP32FDQ-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $f12_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32-ILP32FDQ-NEXT: [[COPY10:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32-ILP32FDQ-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY9]](s32), [[COPY10]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[COPY11:%[0-9]+]]:_(s32) = COPY $f13_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY12:%[0-9]+]]:_(s32) = COPY $f14_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY13:%[0-9]+]]:_(s32) = COPY $f15_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY14:%[0-9]+]]:_(s32) = COPY $f16_f
+ ; RV32-ILP32FDQ-NEXT: [[COPY15:%[0-9]+]]:_(s32) = COPY $f17_f
+ ; RV32-ILP32FDQ-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32-ILP32FDQ-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
+ ; RV32-ILP32FDQ-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV3]](s64)
+ ; RV32-ILP32FDQ-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD]](s32)
+ ; RV32-ILP32FDQ-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[FPTOSI]]
+ ; RV32-ILP32FDQ-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32FDQ-NEXT: PseudoRET implicit $x10
%g_trunc = trunc i64 %g to i32
%m_fptosi = fptosi float %m to i32
%1 = add i32 %g_trunc, %m_fptosi
@@ -371,6 +446,52 @@ define i32 @caller_float_on_stack_exhausted_gprs_fprs() nounwind {
; RV32-ILP32D-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
; RV32-ILP32D-NEXT: $x10 = COPY [[COPY1]](s32)
; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_float_on_stack_exhausted_gprs_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s32) = G_FCONSTANT float 4.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s32) = G_FCONSTANT float 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; RV32-ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s32) = G_FCONSTANT float 8.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s32) = G_FCONSTANT float 9.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C9:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+01
+ ; RV32-ILP32Q-NEXT: [[C10:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.100000e+01
+ ; RV32-ILP32Q-NEXT: [[C11:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.200000e+01
+ ; RV32-ILP32Q-NEXT: [[C12:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.300000e+01
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32Q-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; RV32-ILP32Q-NEXT: G_STORE [[C12]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_f = COPY [[C1]](s32)
+ ; RV32-ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32Q-NEXT: $f11_f = COPY [[C3]](s32)
+ ; RV32-ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32Q-NEXT: $f12_f = COPY [[C5]](s32)
+ ; RV32-ILP32Q-NEXT: $x16 = COPY [[UV6]](s32)
+ ; RV32-ILP32Q-NEXT: $x17 = COPY [[UV7]](s32)
+ ; RV32-ILP32Q-NEXT: $f13_f = COPY [[C7]](s32)
+ ; RV32-ILP32Q-NEXT: $f14_f = COPY [[C8]](s32)
+ ; RV32-ILP32Q-NEXT: $f15_f = COPY [[C9]](s32)
+ ; RV32-ILP32Q-NEXT: $f16_f = COPY [[C10]](s32)
+ ; RV32-ILP32Q-NEXT: $f17_f = COPY [[C11]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_float_on_stack_exhausted_gprs_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_f, implicit $x12, implicit $x13, implicit $f11_f, implicit $x14, implicit $x15, implicit $f12_f, implicit $x16, implicit $x17, implicit $f13_f, implicit $f14_f, implicit $f15_f, implicit $f16_f, implicit $f17_f, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
%1 = call i32 @callee_float_on_stack_exhausted_gprs_fprs(
i64 1, float 2.0, i64 3, float 4.0, i64 5, float 6.0, i64 7, float 8.0,
float 9.0, float 10.0, float 11.0, float 12.0, float 13.0)
@@ -378,11 +499,11 @@ define i32 @caller_float_on_stack_exhausted_gprs_fprs() nounwind {
}
define float @callee_float_ret() nounwind {
- ; RV32-ILP32FD-LABEL: name: callee_float_ret
- ; RV32-ILP32FD: bb.1 (%ir-block.0):
- ; RV32-ILP32FD-NEXT: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+00
- ; RV32-ILP32FD-NEXT: $f10_f = COPY [[C]](s32)
- ; RV32-ILP32FD-NEXT: PseudoRET implicit $f10_f
+ ; RV32-ILP32FDQ-LABEL: name: callee_float_ret
+ ; RV32-ILP32FDQ: bb.1 (%ir-block.0):
+ ; RV32-ILP32FDQ-NEXT: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+00
+ ; RV32-ILP32FDQ-NEXT: $f10_f = COPY [[C]](s32)
+ ; RV32-ILP32FDQ-NEXT: PseudoRET implicit $f10_f
ret float 1.0
}
@@ -404,6 +525,15 @@ define i32 @caller_float_ret() nounwind {
; RV32-ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $f10_f
; RV32-ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
; RV32-ILP32D-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-ILP32Q-LABEL: name: caller_float_ret
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_float_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit-def $f10_f
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $f10_f
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
%1 = call float @callee_float_ret()
%2 = bitcast float %1 to i32
ret i32 %2
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
new file mode 100644
index 0000000000000..68990bc75ee9a
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
@@ -0,0 +1,436 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv32 -mattr=+q -target-abi ilp32q \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV32-ILP32Q %s
+
+; This file contains tests that will have differing output for the ilp32/ilp32f
+; and ilp32d ABIs.
+
+define i32 @callee_fp128_in_fpr(i32 %a, fp128 %b) nounwind {
+ ; RV32-ILP32Q-LABEL: name: callee_fp128_in_fpr
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: liveins: $x10, $f10_q
+ ; RV32-ILP32Q-NEXT: {{ $}}
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV32-ILP32Q-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY1]](s128)
+ ; RV32-ILP32Q-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[FPTOSI]]
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %b_fptosi = fptosi fp128 %b to i32
+ %1 = add i32 %a, %b_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_fp128_in_fpr() nounwind {
+ ; RV32-ILP32Q-LABEL: name: caller_fp128_in_fpr
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; RV32-ILP32Q-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[C1]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_in_fpr, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $f10_q, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = fpext double 2.0 to fp128
+ %2 = call i32 @callee_fp128_in_fpr(i32 1, fp128 %1)
+ ret i32 %2
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_fp128_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, fp128 %f) nounwind {
+ ; RV32-ILP32Q-LABEL: name: callee_fp128_in_fpr_exhausted_gprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_q
+ ; RV32-ILP32Q-NEXT: {{ $}}
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32Q-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32-ILP32Q-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32-ILP32Q-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32-ILP32Q-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32-ILP32Q-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY4]](s32), [[COPY5]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32-ILP32Q-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32-ILP32Q-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32-ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32-ILP32Q-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 16)
+ ; RV32-ILP32Q-NEXT: [[COPY8:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV32-ILP32Q-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s128)
+ ; RV32-ILP32Q-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[FPTOSI]]
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %f_fptosi = fptosi fp128 %f to i32
+ %1 = add i32 %e, %f_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
+ ; RV32-ILP32Q-LABEL: name: caller_fp128_in_fpr_exhausted_gprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; RV32-ILP32Q-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C4]](s64)
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s32)
+ ; RV32-ILP32Q-NEXT: G_STORE [[C5]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32Q-NEXT: $x16 = COPY [[UV6]](s32)
+ ; RV32-ILP32Q-NEXT: $x17 = COPY [[UV7]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_in_fpr_exhausted_gprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_q, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = fpext double 6.0 to fp128
+ %2 = call i32 @callee_fp128_in_fpr_exhausted_gprs(
+ i64 1, i64 2, i64 3, i64 4, i32 5, fp128 %1)
+ ret i32 %2
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_fp128_in_gpr_exhausted_fprs(fp128 %a, fp128 %b, fp128 %c, fp128 %d, fp128 %e, fp128 %f, fp128 %g, fp128 %h, fp128 %i) nounwind {
+ ; RV32-ILP32Q-LABEL: name: callee_fp128_in_gpr_exhausted_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: liveins: $x10, $f10_q, $f11_q, $f12_q, $f13_q, $f14_q, $f15_q, $f16_q, $f17_q
+ ; RV32-ILP32Q-NEXT: {{ $}}
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s128) = COPY $f11_q
+ ; RV32-ILP32Q-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $f12_q
+ ; RV32-ILP32Q-NEXT: [[COPY3:%[0-9]+]]:_(s128) = COPY $f13_q
+ ; RV32-ILP32Q-NEXT: [[COPY4:%[0-9]+]]:_(s128) = COPY $f14_q
+ ; RV32-ILP32Q-NEXT: [[COPY5:%[0-9]+]]:_(s128) = COPY $f15_q
+ ; RV32-ILP32Q-NEXT: [[COPY6:%[0-9]+]]:_(s128) = COPY $f16_q
+ ; RV32-ILP32Q-NEXT: [[COPY7:%[0-9]+]]:_(s128) = COPY $f17_q
+ ; RV32-ILP32Q-NEXT: [[COPY8:%[0-9]+]]:_(p0) = COPY $x10
+ ; RV32-ILP32Q-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY8]](p0) :: (load (s128))
+ ; RV32-ILP32Q-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY7]](s128)
+ ; RV32-ILP32Q-NEXT: [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD]](s128)
+ ; RV32-ILP32Q-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[FPTOSI]], [[FPTOSI1]]
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %h_fptosi = fptosi fp128 %h to i32
+ %i_fptosi = fptosi fp128 %i to i32
+ %1 = add i32 %h_fptosi, %i_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
+ ; RV32-ILP32Q-LABEL: name: caller_fp128_in_gpr_exhausted_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 3.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 5.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 7.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32Q-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT1:%[0-9]+]]:_(s128) = G_FPEXT [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT2:%[0-9]+]]:_(s128) = G_FPEXT [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT3:%[0-9]+]]:_(s128) = G_FPEXT [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT4:%[0-9]+]]:_(s128) = G_FPEXT [[C4]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT5:%[0-9]+]]:_(s128) = G_FPEXT [[C5]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT6:%[0-9]+]]:_(s128) = G_FPEXT [[C6]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT7:%[0-9]+]]:_(s128) = G_FPEXT [[C7]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT8:%[0-9]+]]:_(s128) = G_FPEXT [[C8]](s64)
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; RV32-ILP32Q-NEXT: G_STORE [[FPEXT8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
+ ; RV32-ILP32Q-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV32-ILP32Q-NEXT: $f11_q = COPY [[FPEXT1]](s128)
+ ; RV32-ILP32Q-NEXT: $f12_q = COPY [[FPEXT2]](s128)
+ ; RV32-ILP32Q-NEXT: $f13_q = COPY [[FPEXT3]](s128)
+ ; RV32-ILP32Q-NEXT: $f14_q = COPY [[FPEXT4]](s128)
+ ; RV32-ILP32Q-NEXT: $f15_q = COPY [[FPEXT5]](s128)
+ ; RV32-ILP32Q-NEXT: $f16_q = COPY [[FPEXT6]](s128)
+ ; RV32-ILP32Q-NEXT: $f17_q = COPY [[FPEXT7]](s128)
+ ; RV32-ILP32Q-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[FRAME_INDEX]](p0)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[PTRTOINT]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_in_gpr_exhausted_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $f10_q, implicit $f11_q, implicit $f12_q, implicit $f13_q, implicit $f14_q, implicit $f15_q, implicit $f16_q, implicit $f17_q, implicit $x10, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = fpext double 1.0 to fp128
+ %2 = fpext double 2.0 to fp128
+ %3 = fpext double 3.0 to fp128
+ %4 = fpext double 4.0 to fp128
+ %5 = fpext double 5.0 to fp128
+ %6 = fpext double 6.0 to fp128
+ %7 = fpext double 7.0 to fp128
+ %8 = fpext double 8.0 to fp128
+ %9 = fpext double 9.0 to fp128
+ %10 = call i32 @callee_fp128_in_gpr_exhausted_fprs(
+ fp128 %1, fp128 %2, fp128 %3, fp128 %4, fp128 %5, fp128 %6,
+ fp128 %7, fp128 %8, fp128 %9)
+ ret i32 %10
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs(i64 %a, fp128 %b, i64 %c, fp128 %d, i64 %e, fp128 %f, i32 %g, fp128 %h, fp128 %i, fp128 %j, fp128 %k, fp128 %l, fp128 %m) nounwind {
+ ; RV32-ILP32Q-LABEL: name: callee_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_q, $f11_q, $f12_q, $f13_q, $f14_q, $f15_q, $f16_q, $f17_q
+ ; RV32-ILP32Q-NEXT: {{ $}}
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32Q-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV32-ILP32Q-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32-ILP32Q-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32-ILP32Q-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY5:%[0-9]+]]:_(s128) = COPY $f11_q
+ ; RV32-ILP32Q-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32-ILP32Q-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32-ILP32Q-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY8:%[0-9]+]]:_(s128) = COPY $f12_q
+ ; RV32-ILP32Q-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32-ILP32Q-NEXT: [[COPY10:%[0-9]+]]:_(s128) = COPY $f13_q
+ ; RV32-ILP32Q-NEXT: [[COPY11:%[0-9]+]]:_(s128) = COPY $f14_q
+ ; RV32-ILP32Q-NEXT: [[COPY12:%[0-9]+]]:_(s128) = COPY $f15_q
+ ; RV32-ILP32Q-NEXT: [[COPY13:%[0-9]+]]:_(s128) = COPY $f16_q
+ ; RV32-ILP32Q-NEXT: [[COPY14:%[0-9]+]]:_(s128) = COPY $f17_q
+ ; RV32-ILP32Q-NEXT: [[COPY15:%[0-9]+]]:_(p0) = COPY $x17
+ ; RV32-ILP32Q-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY15]](p0) :: (load (s128))
+ ; RV32-ILP32Q-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD]](s128)
+ ; RV32-ILP32Q-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY9]], [[FPTOSI]]
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %m_fptosi = fptosi fp128 %m to i32
+ %1 = add i32 %g, %m_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind {
+ ; RV32-ILP32Q-LABEL: name: caller_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; RV32-ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; RV32-ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; RV32-ILP32Q-NEXT: [[C9:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32Q-NEXT: [[C10:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32Q-NEXT: [[C11:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; RV32-ILP32Q-NEXT: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
+ ; RV32-ILP32Q-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT1:%[0-9]+]]:_(s128) = G_FPEXT [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT2:%[0-9]+]]:_(s128) = G_FPEXT [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT3:%[0-9]+]]:_(s128) = G_FPEXT [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT4:%[0-9]+]]:_(s128) = G_FPEXT [[C4]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT5:%[0-9]+]]:_(s128) = G_FPEXT [[C5]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT6:%[0-9]+]]:_(s128) = G_FPEXT [[C6]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT7:%[0-9]+]]:_(s128) = G_FPEXT [[C7]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT8:%[0-9]+]]:_(s128) = G_FPEXT [[C8]](s64)
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C9]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C10]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C11]](s64)
+ ; RV32-ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; RV32-ILP32Q-NEXT: G_STORE [[FPEXT8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV32-ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32Q-NEXT: $f11_q = COPY [[FPEXT1]](s128)
+ ; RV32-ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32Q-NEXT: $f12_q = COPY [[FPEXT2]](s128)
+ ; RV32-ILP32Q-NEXT: $x16 = COPY [[C12]](s32)
+ ; RV32-ILP32Q-NEXT: $f13_q = COPY [[FPEXT3]](s128)
+ ; RV32-ILP32Q-NEXT: $f14_q = COPY [[FPEXT4]](s128)
+ ; RV32-ILP32Q-NEXT: $f15_q = COPY [[FPEXT5]](s128)
+ ; RV32-ILP32Q-NEXT: $f16_q = COPY [[FPEXT6]](s128)
+ ; RV32-ILP32Q-NEXT: $f17_q = COPY [[FPEXT7]](s128)
+ ; RV32-ILP32Q-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[FRAME_INDEX]](p0)
+ ; RV32-ILP32Q-NEXT: $x17 = COPY [[PTRTOINT]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_q, implicit $x12, implicit $x13, implicit $f11_q, implicit $x14, implicit $x15, implicit $f12_q, implicit $x16, implicit $f13_q, implicit $f14_q, implicit $f15_q, implicit $f16_q, implicit $f17_q, implicit $x17, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %2 = fpext double 2.0 to fp128
+ %4 = fpext double 4.0 to fp128
+ %6 = fpext double 6.0 to fp128
+ %8 = fpext double 8.0 to fp128
+ %9 = fpext double 9.0 to fp128
+ %10 = fpext double 10.0 to fp128
+ %11 = fpext double 11.0 to fp128
+ %12 = fpext double 12.0 to fp128
+ %13 = fpext double 13.0 to fp128
+ %14 = call i32 @callee_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs(
+ i64 1, fp128 %2, i64 3, fp128 %4, i64 5, fp128 %6, i32 7, fp128 %8,
+ fp128 %9, fp128 %10, fp128 %11, fp128 %12, fp128 %13)
+ ret i32 %14
+}
+
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_fp128_on_stack_exhausted_gprs_fprs(i64 %a, fp128 %b, i64 %c, fp128 %d, i64 %e, fp128 %f, i64 %g, fp128 %h, fp128 %i, fp128 %j, fp128 %k, fp128 %l, fp128 %m) nounwind {
+ ; RV32-ILP32Q-LABEL: name: callee_fp128_on_stack_exhausted_gprs_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_q, $f11_q, $f12_q, $f13_q, $f14_q, $f15_q, $f16_q, $f17_q
+ ; RV32-ILP32Q-NEXT: {{ $}}
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
+ ; RV32-ILP32Q-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV32-ILP32Q-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x12
+ ; RV32-ILP32Q-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $x13
+ ; RV32-ILP32Q-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY5:%[0-9]+]]:_(s128) = COPY $f11_q
+ ; RV32-ILP32Q-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $x14
+ ; RV32-ILP32Q-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $x15
+ ; RV32-ILP32Q-NEXT: [[MV2:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY6]](s32), [[COPY7]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY8:%[0-9]+]]:_(s128) = COPY $f12_q
+ ; RV32-ILP32Q-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $x16
+ ; RV32-ILP32Q-NEXT: [[COPY10:%[0-9]+]]:_(s32) = COPY $x17
+ ; RV32-ILP32Q-NEXT: [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY9]](s32), [[COPY10]](s32)
+ ; RV32-ILP32Q-NEXT: [[COPY11:%[0-9]+]]:_(s128) = COPY $f13_q
+ ; RV32-ILP32Q-NEXT: [[COPY12:%[0-9]+]]:_(s128) = COPY $f14_q
+ ; RV32-ILP32Q-NEXT: [[COPY13:%[0-9]+]]:_(s128) = COPY $f15_q
+ ; RV32-ILP32Q-NEXT: [[COPY14:%[0-9]+]]:_(s128) = COPY $f16_q
+ ; RV32-ILP32Q-NEXT: [[COPY15:%[0-9]+]]:_(s128) = COPY $f17_q
+ ; RV32-ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV32-ILP32Q-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.0, align 16)
+ ; RV32-ILP32Q-NEXT: [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[LOAD]](p0) :: (load (s128))
+ ; RV32-ILP32Q-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV3]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD1]](s128)
+ ; RV32-ILP32Q-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[FPTOSI]]
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[ADD]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %g_trunc = trunc i64 %g to i32
+ %m_fptosi = fptosi fp128 %m to i32
+ %1 = add i32 %g_trunc, %m_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_fp128_on_stack_exhausted_gprs_fprs() nounwind {
+ ; RV32-ILP32Q-LABEL: name: caller_fp128_on_stack_exhausted_gprs_fprs
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV32-ILP32Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; RV32-ILP32Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; RV32-ILP32Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; RV32-ILP32Q-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; RV32-ILP32Q-NEXT: [[C9:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV32-ILP32Q-NEXT: [[C10:%[0-9]+]]:_(s64) = G_CONSTANT i64 3
+ ; RV32-ILP32Q-NEXT: [[C11:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; RV32-ILP32Q-NEXT: [[C12:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
+ ; RV32-ILP32Q-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT1:%[0-9]+]]:_(s128) = G_FPEXT [[C1]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT2:%[0-9]+]]:_(s128) = G_FPEXT [[C2]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT3:%[0-9]+]]:_(s128) = G_FPEXT [[C3]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT4:%[0-9]+]]:_(s128) = G_FPEXT [[C4]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT5:%[0-9]+]]:_(s128) = G_FPEXT [[C5]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT6:%[0-9]+]]:_(s128) = G_FPEXT [[C6]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT7:%[0-9]+]]:_(s128) = G_FPEXT [[C7]](s64)
+ ; RV32-ILP32Q-NEXT: [[FPEXT8:%[0-9]+]]:_(s128) = G_FPEXT [[C8]](s64)
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C9]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C10]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C11]](s64)
+ ; RV32-ILP32Q-NEXT: [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C12]](s64)
+ ; RV32-ILP32Q-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; RV32-ILP32Q-NEXT: G_STORE [[FPEXT8]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV32-ILP32Q-NEXT: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; RV32-ILP32Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s32)
+ ; RV32-ILP32Q-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[FRAME_INDEX]](p0)
+ ; RV32-ILP32Q-NEXT: G_STORE [[PTRTOINT]](s32), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[UV]](s32)
+ ; RV32-ILP32Q-NEXT: $x11 = COPY [[UV1]](s32)
+ ; RV32-ILP32Q-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV32-ILP32Q-NEXT: $x12 = COPY [[UV2]](s32)
+ ; RV32-ILP32Q-NEXT: $x13 = COPY [[UV3]](s32)
+ ; RV32-ILP32Q-NEXT: $f11_q = COPY [[FPEXT1]](s128)
+ ; RV32-ILP32Q-NEXT: $x14 = COPY [[UV4]](s32)
+ ; RV32-ILP32Q-NEXT: $x15 = COPY [[UV5]](s32)
+ ; RV32-ILP32Q-NEXT: $f12_q = COPY [[FPEXT2]](s128)
+ ; RV32-ILP32Q-NEXT: $x16 = COPY [[UV6]](s32)
+ ; RV32-ILP32Q-NEXT: $x17 = COPY [[UV7]](s32)
+ ; RV32-ILP32Q-NEXT: $f13_q = COPY [[FPEXT3]](s128)
+ ; RV32-ILP32Q-NEXT: $f14_q = COPY [[FPEXT4]](s128)
+ ; RV32-ILP32Q-NEXT: $f15_q = COPY [[FPEXT5]](s128)
+ ; RV32-ILP32Q-NEXT: $f16_q = COPY [[FPEXT6]](s128)
+ ; RV32-ILP32Q-NEXT: $f17_q = COPY [[FPEXT7]](s128)
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_on_stack_exhausted_gprs_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_q, implicit $x12, implicit $x13, implicit $f11_q, implicit $x14, implicit $x15, implicit $f12_q, implicit $x16, implicit $x17, implicit $f13_q, implicit $f14_q, implicit $f15_q, implicit $f16_q, implicit $f17_q, implicit-def $x10
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 4, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[COPY1]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %2 = fpext double 2.0 to fp128
+ %4 = fpext double 4.0 to fp128
+ %6 = fpext double 6.0 to fp128
+ %8 = fpext double 8.0 to fp128
+ %9 = fpext double 9.0 to fp128
+ %10 = fpext double 10.0 to fp128
+ %11 = fpext double 11.0 to fp128
+ %12 = fpext double 12.0 to fp128
+ %13 = fpext double 13.0 to fp128
+ %14 = call i32 @callee_fp128_on_stack_exhausted_gprs_fprs(
+ i64 1, fp128 %2, i64 3, fp128 %4, i64 5, fp128 %6, i64 7, fp128 %8,
+ fp128 %9, fp128 %10, fp128 %11, fp128 %12, fp128 %13)
+ ret i32 %14
+}
+
+define fp128 @callee_fp128_ret() nounwind {
+ ; RV32-ILP32Q-LABEL: name: callee_fp128_ret
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; RV32-ILP32Q-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV32-ILP32Q-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $f10_q
+ %1 = fpext double 1.0 to fp128
+ ret fp128 %1
+}
+
+define i32 @caller_fp128_ret() nounwind {
+ ; RV32-ILP32Q-LABEL: name: caller_fp128_ret
+ ; RV32-ILP32Q: bb.1 (%ir-block.0):
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit-def $f10_q
+ ; RV32-ILP32Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32-ILP32Q-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV32-ILP32Q-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s128)
+ ; RV32-ILP32Q-NEXT: $x10 = COPY [[TRUNC]](s32)
+ ; RV32-ILP32Q-NEXT: PseudoRET implicit $x10
+ %1 = call fp128 @callee_fp128_ret()
+ %2 = bitcast fp128 %1 to i128
+ %3 = trunc i128 %2 to i32
+ ret i32 %3
+}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64d-lp64q.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64d-lp64q.ll
new file mode 100644
index 0000000000000..42632f8bed84f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64d-lp64q.ll
@@ -0,0 +1,415 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV64I,LP64D %s
+; RUN: llc -mtriple=riscv64 -mattr=+q -target-abi lp64q \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=RV64I,LP64Q %s
+
+; This file contains tests that should have identical output for the lp64 and
+; lp64f ABIs.
+
+define i64 @callee_double_in_regs(i64 %a, double %b) nounwind {
+ ; RV64I-LABEL: name: callee_double_in_regs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: liveins: $x10, $f10_d
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[COPY1]](s64)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[FPTOSI]]
+ ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %b_fptosi = fptosi double %b to i64
+ %1 = add i64 %a, %b_fptosi
+ ret i64 %1
+}
+
+define i64 @caller_double_in_regs() nounwind {
+ ; LP64D-LABEL: name: caller_double_in_regs
+ ; LP64D: bb.1 (%ir-block.0):
+ ; LP64D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; LP64D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; LP64D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: $x10 = COPY [[C]](s64)
+ ; LP64D-NEXT: $f10_d = COPY [[C1]](s64)
+ ; LP64D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $f10_d, implicit-def $x10
+ ; LP64D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; LP64D-NEXT: $x10 = COPY [[COPY]](s64)
+ ; LP64D-NEXT: PseudoRET implicit $x10
+ ;
+ ; LP64Q-LABEL: name: caller_double_in_regs
+ ; LP64Q: bb.1 (%ir-block.0):
+ ; LP64Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; LP64Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; LP64Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: $x10 = COPY [[C]](s64)
+ ; LP64Q-NEXT: $f10_d = COPY [[C1]](s64)
+ ; LP64Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_regs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $f10_d, implicit-def $x10
+ ; LP64Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; LP64Q-NEXT: $x10 = COPY [[COPY]](s64)
+ ; LP64Q-NEXT: PseudoRET implicit $x10
+ %1 = call i64 @callee_double_in_regs(i64 1, double 2.0)
+ ret i64 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i64 @callee_double_in_fpr_exhausted_gprs(i128 %a, i128 %b, i128 %c, i128 %d, i64 %e, double %f) nounwind {
+ ; RV64I-LABEL: name: callee_double_in_fpr_exhausted_gprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64)
+ ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x13
+ ; RV64I-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY2]](s64), [[COPY3]](s64)
+ ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x14
+ ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x15
+ ; RV64I-NEXT: [[MV2:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY4]](s64), [[COPY5]](s64)
+ ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x16
+ ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x17
+ ; RV64I-NEXT: [[MV3:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY6]](s64), [[COPY7]](s64)
+ ; RV64I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.0, align 16)
+ ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[COPY8]](s64)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[LOAD]], [[FPTOSI]]
+ ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %f_fptosi = fptosi double %f to i64
+ %1 = add i64 %e, %f_fptosi
+ ret i64 %1
+}
+
+define i64 @caller_double_in_fpr_exhausted_gprs() nounwind {
+ ; LP64D-LABEL: name: caller_double_in_fpr_exhausted_gprs
+ ; LP64D: bb.1 (%ir-block.0):
+ ; LP64D-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; LP64D-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; LP64D-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 3
+ ; LP64D-NEXT: [[C3:%[0-9]+]]:_(s128) = G_CONSTANT i128 4
+ ; LP64D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; LP64D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; LP64D-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C]](s128)
+ ; LP64D-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C1]](s128)
+ ; LP64D-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C2]](s128)
+ ; LP64D-NEXT: [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C3]](s128)
+ ; LP64D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; LP64D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; LP64D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s64)
+ ; LP64D-NEXT: G_STORE [[C4]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+ ; LP64D-NEXT: $x10 = COPY [[UV]](s64)
+ ; LP64D-NEXT: $x11 = COPY [[UV1]](s64)
+ ; LP64D-NEXT: $x12 = COPY [[UV2]](s64)
+ ; LP64D-NEXT: $x13 = COPY [[UV3]](s64)
+ ; LP64D-NEXT: $x14 = COPY [[UV4]](s64)
+ ; LP64D-NEXT: $x15 = COPY [[UV5]](s64)
+ ; LP64D-NEXT: $x16 = COPY [[UV6]](s64)
+ ; LP64D-NEXT: $x17 = COPY [[UV7]](s64)
+ ; LP64D-NEXT: $f10_d = COPY [[C5]](s64)
+ ; LP64D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr_exhausted_gprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_d, implicit-def $x10
+ ; LP64D-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
+ ; LP64D-NEXT: $x10 = COPY [[COPY1]](s64)
+ ; LP64D-NEXT: PseudoRET implicit $x10
+ ;
+ ; LP64Q-LABEL: name: caller_double_in_fpr_exhausted_gprs
+ ; LP64Q: bb.1 (%ir-block.0):
+ ; LP64Q-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; LP64Q-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; LP64Q-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 3
+ ; LP64Q-NEXT: [[C3:%[0-9]+]]:_(s128) = G_CONSTANT i128 4
+ ; LP64Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; LP64Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; LP64Q-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C]](s128)
+ ; LP64Q-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C1]](s128)
+ ; LP64Q-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C2]](s128)
+ ; LP64Q-NEXT: [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C3]](s128)
+ ; LP64Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; LP64Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; LP64Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s64)
+ ; LP64Q-NEXT: G_STORE [[C4]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+ ; LP64Q-NEXT: $x10 = COPY [[UV]](s64)
+ ; LP64Q-NEXT: $x11 = COPY [[UV1]](s64)
+ ; LP64Q-NEXT: $x12 = COPY [[UV2]](s64)
+ ; LP64Q-NEXT: $x13 = COPY [[UV3]](s64)
+ ; LP64Q-NEXT: $x14 = COPY [[UV4]](s64)
+ ; LP64Q-NEXT: $x15 = COPY [[UV5]](s64)
+ ; LP64Q-NEXT: $x16 = COPY [[UV6]](s64)
+ ; LP64Q-NEXT: $x17 = COPY [[UV7]](s64)
+ ; LP64Q-NEXT: $f10_d = COPY [[C5]](s64)
+ ; LP64Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr_exhausted_gprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_d, implicit-def $x10
+ ; LP64Q-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
+ ; LP64Q-NEXT: $x10 = COPY [[COPY1]](s64)
+ ; LP64Q-NEXT: PseudoRET implicit $x10
+ %1 = call i64 @callee_double_in_fpr_exhausted_gprs(
+ i128 1, i128 2, i128 3, i128 4, i64 5, double 6.0)
+ ret i64 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind {
+ ; RV64I-LABEL: name: callee_double_in_gpr_exhausted_fprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: liveins: $x10, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f11_d
+ ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f12_d
+ ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $f13_d
+ ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f14_d
+ ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f15_d
+ ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $f16_d
+ ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $f17_d
+ ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY7]](s64)
+ ; RV64I-NEXT: [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s64)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[FPTOSI]], [[FPTOSI1]]
+ ; RV64I-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ADD]](s32)
+ ; RV64I-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %h_fptosi = fptosi double %h to i32
+ %i_fptosi = fptosi double %i to i32
+ %1 = add i32 %h_fptosi, %i_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_gpr_exhausted_fprs() nounwind {
+ ; LP64D-LABEL: name: caller_double_in_gpr_exhausted_fprs
+ ; LP64D: bb.1 (%ir-block.0):
+ ; LP64D-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; LP64D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; LP64D-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 3.000000e+00
+ ; LP64D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; LP64D-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 5.000000e+00
+ ; LP64D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; LP64D-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 7.000000e+00
+ ; LP64D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; LP64D-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; LP64D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: $f10_d = COPY [[C]](s64)
+ ; LP64D-NEXT: $f11_d = COPY [[C1]](s64)
+ ; LP64D-NEXT: $f12_d = COPY [[C2]](s64)
+ ; LP64D-NEXT: $f13_d = COPY [[C3]](s64)
+ ; LP64D-NEXT: $f14_d = COPY [[C4]](s64)
+ ; LP64D-NEXT: $f15_d = COPY [[C5]](s64)
+ ; LP64D-NEXT: $f16_d = COPY [[C6]](s64)
+ ; LP64D-NEXT: $f17_d = COPY [[C7]](s64)
+ ; LP64D-NEXT: $x10 = COPY [[C8]](s64)
+ ; LP64D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_exhausted_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $f10_d, implicit $f11_d, implicit $f12_d, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x10, implicit-def $x10
+ ; LP64D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; LP64D-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; LP64D-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s32)
+ ; LP64D-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; LP64D-NEXT: PseudoRET implicit $x10
+ ;
+ ; LP64Q-LABEL: name: caller_double_in_gpr_exhausted_fprs
+ ; LP64Q: bb.1 (%ir-block.0):
+ ; LP64Q-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; LP64Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; LP64Q-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 3.000000e+00
+ ; LP64Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; LP64Q-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 5.000000e+00
+ ; LP64Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; LP64Q-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 7.000000e+00
+ ; LP64Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; LP64Q-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; LP64Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: $f10_d = COPY [[C]](s64)
+ ; LP64Q-NEXT: $f11_d = COPY [[C1]](s64)
+ ; LP64Q-NEXT: $f12_d = COPY [[C2]](s64)
+ ; LP64Q-NEXT: $f13_d = COPY [[C3]](s64)
+ ; LP64Q-NEXT: $f14_d = COPY [[C4]](s64)
+ ; LP64Q-NEXT: $f15_d = COPY [[C5]](s64)
+ ; LP64Q-NEXT: $f16_d = COPY [[C6]](s64)
+ ; LP64Q-NEXT: $f17_d = COPY [[C7]](s64)
+ ; LP64Q-NEXT: $x10 = COPY [[C8]](s64)
+ ; LP64Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_exhausted_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $f10_d, implicit $f11_d, implicit $f12_d, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x10, implicit-def $x10
+ ; LP64Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; LP64Q-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; LP64Q-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s32)
+ ; LP64Q-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; LP64Q-NEXT: PseudoRET implicit $x10
+ %1 = call i32 @callee_double_in_gpr_exhausted_fprs(
+ double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0,
+ double 7.0, double 8.0, double 9.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i64 @callee_double_on_stack_exhausted_gprs_fprs(i128 %a, double %b, i128 %c, double %d, i128 %e, double %f, i128 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
+ ; RV64I-LABEL: name: callee_double_on_stack_exhausted_gprs_fprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64)
+ ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x12
+ ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x13
+ ; RV64I-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY3]](s64), [[COPY4]](s64)
+ ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f11_d
+ ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x14
+ ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x15
+ ; RV64I-NEXT: [[MV2:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY6]](s64), [[COPY7]](s64)
+ ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f12_d
+ ; RV64I-NEXT: [[COPY9:%[0-9]+]]:_(s64) = COPY $x16
+ ; RV64I-NEXT: [[COPY10:%[0-9]+]]:_(s64) = COPY $x17
+ ; RV64I-NEXT: [[MV3:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY9]](s64), [[COPY10]](s64)
+ ; RV64I-NEXT: [[COPY11:%[0-9]+]]:_(s64) = COPY $f13_d
+ ; RV64I-NEXT: [[COPY12:%[0-9]+]]:_(s64) = COPY $f14_d
+ ; RV64I-NEXT: [[COPY13:%[0-9]+]]:_(s64) = COPY $f15_d
+ ; RV64I-NEXT: [[COPY14:%[0-9]+]]:_(s64) = COPY $f16_d
+ ; RV64I-NEXT: [[COPY15:%[0-9]+]]:_(s64) = COPY $f17_d
+ ; RV64I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.0, align 16)
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[MV3]](s128)
+ ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[LOAD]](s64)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[TRUNC]], [[FPTOSI]]
+ ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %g_trunc = trunc i128 %g to i64
+ %m_fptosi = fptosi double %m to i64
+ %1 = add i64 %g_trunc, %m_fptosi
+ ret i64 %1
+}
+
+define i64 @caller_double_on_stack_exhausted_gprs_fprs() nounwind {
+ ; LP64D-LABEL: name: caller_double_on_stack_exhausted_gprs_fprs
+ ; LP64D: bb.1 (%ir-block.0):
+ ; LP64D-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; LP64D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; LP64D-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 3
+ ; LP64D-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; LP64D-NEXT: [[C4:%[0-9]+]]:_(s128) = G_CONSTANT i128 5
+ ; LP64D-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; LP64D-NEXT: [[C6:%[0-9]+]]:_(s128) = G_CONSTANT i128 7
+ ; LP64D-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; LP64D-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; LP64D-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; LP64D-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; LP64D-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; LP64D-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; LP64D-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C]](s128)
+ ; LP64D-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C2]](s128)
+ ; LP64D-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C4]](s128)
+ ; LP64D-NEXT: [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C6]](s128)
+ ; LP64D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; LP64D-NEXT: [[C13:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; LP64D-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s64)
+ ; LP64D-NEXT: G_STORE [[C12]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+ ; LP64D-NEXT: $x10 = COPY [[UV]](s64)
+ ; LP64D-NEXT: $x11 = COPY [[UV1]](s64)
+ ; LP64D-NEXT: $f10_d = COPY [[C1]](s64)
+ ; LP64D-NEXT: $x12 = COPY [[UV2]](s64)
+ ; LP64D-NEXT: $x13 = COPY [[UV3]](s64)
+ ; LP64D-NEXT: $f11_d = COPY [[C3]](s64)
+ ; LP64D-NEXT: $x14 = COPY [[UV4]](s64)
+ ; LP64D-NEXT: $x15 = COPY [[UV5]](s64)
+ ; LP64D-NEXT: $f12_d = COPY [[C5]](s64)
+ ; LP64D-NEXT: $x16 = COPY [[UV6]](s64)
+ ; LP64D-NEXT: $x17 = COPY [[UV7]](s64)
+ ; LP64D-NEXT: $f13_d = COPY [[C7]](s64)
+ ; LP64D-NEXT: $f14_d = COPY [[C8]](s64)
+ ; LP64D-NEXT: $f15_d = COPY [[C9]](s64)
+ ; LP64D-NEXT: $f16_d = COPY [[C10]](s64)
+ ; LP64D-NEXT: $f17_d = COPY [[C11]](s64)
+ ; LP64D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_on_stack_exhausted_gprs_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $x17, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit-def $x10
+ ; LP64D-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
+ ; LP64D-NEXT: $x10 = COPY [[COPY1]](s64)
+ ; LP64D-NEXT: PseudoRET implicit $x10
+ ;
+ ; LP64Q-LABEL: name: caller_double_on_stack_exhausted_gprs_fprs
+ ; LP64Q: bb.1 (%ir-block.0):
+ ; LP64Q-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; LP64Q-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; LP64Q-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 3
+ ; LP64Q-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; LP64Q-NEXT: [[C4:%[0-9]+]]:_(s128) = G_CONSTANT i128 5
+ ; LP64Q-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; LP64Q-NEXT: [[C6:%[0-9]+]]:_(s128) = G_CONSTANT i128 7
+ ; LP64Q-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; LP64Q-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; LP64Q-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; LP64Q-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; LP64Q-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; LP64Q-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; LP64Q-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C]](s128)
+ ; LP64Q-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C2]](s128)
+ ; LP64Q-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C4]](s128)
+ ; LP64Q-NEXT: [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C6]](s128)
+ ; LP64Q-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; LP64Q-NEXT: [[C13:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; LP64Q-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s64)
+ ; LP64Q-NEXT: G_STORE [[C12]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+ ; LP64Q-NEXT: $x10 = COPY [[UV]](s64)
+ ; LP64Q-NEXT: $x11 = COPY [[UV1]](s64)
+ ; LP64Q-NEXT: $f10_d = COPY [[C1]](s64)
+ ; LP64Q-NEXT: $x12 = COPY [[UV2]](s64)
+ ; LP64Q-NEXT: $x13 = COPY [[UV3]](s64)
+ ; LP64Q-NEXT: $f11_d = COPY [[C3]](s64)
+ ; LP64Q-NEXT: $x14 = COPY [[UV4]](s64)
+ ; LP64Q-NEXT: $x15 = COPY [[UV5]](s64)
+ ; LP64Q-NEXT: $f12_d = COPY [[C5]](s64)
+ ; LP64Q-NEXT: $x16 = COPY [[UV6]](s64)
+ ; LP64Q-NEXT: $x17 = COPY [[UV7]](s64)
+ ; LP64Q-NEXT: $f13_d = COPY [[C7]](s64)
+ ; LP64Q-NEXT: $f14_d = COPY [[C8]](s64)
+ ; LP64Q-NEXT: $f15_d = COPY [[C9]](s64)
+ ; LP64Q-NEXT: $f16_d = COPY [[C10]](s64)
+ ; LP64Q-NEXT: $f17_d = COPY [[C11]](s64)
+ ; LP64Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_on_stack_exhausted_gprs_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $x17, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit-def $x10
+ ; LP64Q-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
+ ; LP64Q-NEXT: $x10 = COPY [[COPY1]](s64)
+ ; LP64Q-NEXT: PseudoRET implicit $x10
+ %1 = call i64 @callee_double_on_stack_exhausted_gprs_fprs(
+ i128 1, double 2.0, i128 3, double 4.0, i128 5, double 6.0, i128 7, double 8.0,
+ double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
+ ret i64 %1
+}
+
+define double @callee_double_ret() nounwind {
+ ; RV64I-LABEL: name: callee_double_ret
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; RV64I-NEXT: $f10_d = COPY [[C]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $f10_d
+ ret double 1.0
+}
+
+define i64 @caller_double_ret() nounwind {
+ ; LP64D-LABEL: name: caller_double_ret
+ ; LP64D: bb.1 (%ir-block.0):
+ ; LP64D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $f10_d
+ ; LP64D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; LP64D-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; LP64D-NEXT: $x10 = COPY [[COPY]](s64)
+ ; LP64D-NEXT: PseudoRET implicit $x10
+ ;
+ ; LP64Q-LABEL: name: caller_double_ret
+ ; LP64Q: bb.1 (%ir-block.0):
+ ; LP64Q-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit-def $f10_d
+ ; LP64Q-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; LP64Q-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
+ ; LP64Q-NEXT: $x10 = COPY [[COPY]](s64)
+ ; LP64Q-NEXT: PseudoRET implicit $x10
+ %1 = call double @callee_double_ret()
+ %2 = bitcast double %1 to i64
+ ret i64 %2
+}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64d.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64d.ll
deleted file mode 100644
index 3d7ae6802fc4a..0000000000000
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64d.ll
+++ /dev/null
@@ -1,283 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
-; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d \
-; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
-; RUN: | FileCheck -check-prefix=RV64I %s
-
-; This file contains tests that should have identical output for the lp64 and
-; lp64f ABIs.
-
-define i64 @callee_double_in_regs(i64 %a, double %b) nounwind {
- ; RV64I-LABEL: name: callee_double_in_regs
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: liveins: $x10, $f10_d
- ; RV64I-NEXT: {{ $}}
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
- ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[COPY1]](s64)
- ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[FPTOSI]]
- ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %b_fptosi = fptosi double %b to i64
- %1 = add i64 %a, %b_fptosi
- ret i64 %1
-}
-
-define i64 @caller_double_in_regs() nounwind {
- ; RV64I-LABEL: name: caller_double_in_regs
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
- ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: $x10 = COPY [[C]](s64)
- ; RV64I-NEXT: $f10_d = COPY [[C1]](s64)
- ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $f10_d, implicit-def $x10
- ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
- ; RV64I-NEXT: $x10 = COPY [[COPY]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %1 = call i64 @callee_double_in_regs(i64 1, double 2.0)
- ret i64 %1
-}
-
-; Must keep define on a single line due to an update_llc_test_checks.py limitation
-define i64 @callee_double_in_fpr_exhausted_gprs(i128 %a, i128 %b, i128 %c, i128 %d, i64 %e, double %f) nounwind {
- ; RV64I-LABEL: name: callee_double_in_fpr_exhausted_gprs
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d
- ; RV64I-NEXT: {{ $}}
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
- ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
- ; RV64I-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64)
- ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
- ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x13
- ; RV64I-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY2]](s64), [[COPY3]](s64)
- ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x14
- ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x15
- ; RV64I-NEXT: [[MV2:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY4]](s64), [[COPY5]](s64)
- ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x16
- ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x17
- ; RV64I-NEXT: [[MV3:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY6]](s64), [[COPY7]](s64)
- ; RV64I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.0, align 16)
- ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[COPY8]](s64)
- ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[LOAD]], [[FPTOSI]]
- ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %f_fptosi = fptosi double %f to i64
- %1 = add i64 %e, %f_fptosi
- ret i64 %1
-}
-
-define i64 @caller_double_in_fpr_exhausted_gprs() nounwind {
- ; RV64I-LABEL: name: caller_double_in_fpr_exhausted_gprs
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
- ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
- ; RV64I-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 3
- ; RV64I-NEXT: [[C3:%[0-9]+]]:_(s128) = G_CONSTANT i128 4
- ; RV64I-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
- ; RV64I-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
- ; RV64I-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C]](s128)
- ; RV64I-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C1]](s128)
- ; RV64I-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C2]](s128)
- ; RV64I-NEXT: [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C3]](s128)
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; RV64I-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
- ; RV64I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s64)
- ; RV64I-NEXT: G_STORE [[C4]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
- ; RV64I-NEXT: $x10 = COPY [[UV]](s64)
- ; RV64I-NEXT: $x11 = COPY [[UV1]](s64)
- ; RV64I-NEXT: $x12 = COPY [[UV2]](s64)
- ; RV64I-NEXT: $x13 = COPY [[UV3]](s64)
- ; RV64I-NEXT: $x14 = COPY [[UV4]](s64)
- ; RV64I-NEXT: $x15 = COPY [[UV5]](s64)
- ; RV64I-NEXT: $x16 = COPY [[UV6]](s64)
- ; RV64I-NEXT: $x17 = COPY [[UV7]](s64)
- ; RV64I-NEXT: $f10_d = COPY [[C5]](s64)
- ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_fpr_exhausted_gprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_d, implicit-def $x10
- ; RV64I-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
- ; RV64I-NEXT: $x10 = COPY [[COPY1]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %1 = call i64 @callee_double_in_fpr_exhausted_gprs(
- i128 1, i128 2, i128 3, i128 4, i64 5, double 6.0)
- ret i64 %1
-}
-
-; Must keep define on a single line due to an update_llc_test_checks.py limitation
-define i32 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind {
- ; RV64I-LABEL: name: callee_double_in_gpr_exhausted_fprs
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: liveins: $x10, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
- ; RV64I-NEXT: {{ $}}
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f11_d
- ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f12_d
- ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $f13_d
- ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f14_d
- ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f15_d
- ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $f16_d
- ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $f17_d
- ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $x10
- ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY7]](s64)
- ; RV64I-NEXT: [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY8]](s64)
- ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[FPTOSI]], [[FPTOSI1]]
- ; RV64I-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ADD]](s32)
- ; RV64I-NEXT: $x10 = COPY [[ANYEXT]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %h_fptosi = fptosi double %h to i32
- %i_fptosi = fptosi double %i to i32
- %1 = add i32 %h_fptosi, %i_fptosi
- ret i32 %1
-}
-
-define i32 @caller_double_in_gpr_exhausted_fprs() nounwind {
- ; RV64I-LABEL: name: caller_double_in_gpr_exhausted_fprs
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
- ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
- ; RV64I-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 3.000000e+00
- ; RV64I-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
- ; RV64I-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 5.000000e+00
- ; RV64I-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
- ; RV64I-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 7.000000e+00
- ; RV64I-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
- ; RV64I-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
- ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: $f10_d = COPY [[C]](s64)
- ; RV64I-NEXT: $f11_d = COPY [[C1]](s64)
- ; RV64I-NEXT: $f12_d = COPY [[C2]](s64)
- ; RV64I-NEXT: $f13_d = COPY [[C3]](s64)
- ; RV64I-NEXT: $f14_d = COPY [[C4]](s64)
- ; RV64I-NEXT: $f15_d = COPY [[C5]](s64)
- ; RV64I-NEXT: $f16_d = COPY [[C6]](s64)
- ; RV64I-NEXT: $f17_d = COPY [[C7]](s64)
- ; RV64I-NEXT: $x10 = COPY [[C8]](s64)
- ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_in_gpr_exhausted_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $f10_d, implicit $f11_d, implicit $f12_d, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit $x10, implicit-def $x10
- ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
- ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
- ; RV64I-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s32)
- ; RV64I-NEXT: $x10 = COPY [[ANYEXT]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %1 = call i32 @callee_double_in_gpr_exhausted_fprs(
- double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0,
- double 7.0, double 8.0, double 9.0)
- ret i32 %1
-}
-
-; Must keep define on a single line due to an update_llc_test_checks.py limitation
-define i64 @callee_double_on_stack_exhausted_gprs_fprs(i128 %a, double %b, i128 %c, double %d, i128 %e, double %f, i128 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
- ; RV64I-LABEL: name: callee_double_on_stack_exhausted_gprs_fprs
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_d, $f11_d, $f12_d, $f13_d, $f14_d, $f15_d, $f16_d, $f17_d
- ; RV64I-NEXT: {{ $}}
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
- ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
- ; RV64I-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64)
- ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x12
- ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x13
- ; RV64I-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY3]](s64), [[COPY4]](s64)
- ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f11_d
- ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x14
- ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x15
- ; RV64I-NEXT: [[MV2:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY6]](s64), [[COPY7]](s64)
- ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f12_d
- ; RV64I-NEXT: [[COPY9:%[0-9]+]]:_(s64) = COPY $x16
- ; RV64I-NEXT: [[COPY10:%[0-9]+]]:_(s64) = COPY $x17
- ; RV64I-NEXT: [[MV3:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY9]](s64), [[COPY10]](s64)
- ; RV64I-NEXT: [[COPY11:%[0-9]+]]:_(s64) = COPY $f13_d
- ; RV64I-NEXT: [[COPY12:%[0-9]+]]:_(s64) = COPY $f14_d
- ; RV64I-NEXT: [[COPY13:%[0-9]+]]:_(s64) = COPY $f15_d
- ; RV64I-NEXT: [[COPY14:%[0-9]+]]:_(s64) = COPY $f16_d
- ; RV64I-NEXT: [[COPY15:%[0-9]+]]:_(s64) = COPY $f17_d
- ; RV64I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.0, align 16)
- ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[MV3]](s128)
- ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[LOAD]](s64)
- ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[TRUNC]], [[FPTOSI]]
- ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %g_trunc = trunc i128 %g to i64
- %m_fptosi = fptosi double %m to i64
- %1 = add i64 %g_trunc, %m_fptosi
- ret i64 %1
-}
-
-define i64 @caller_double_on_stack_exhausted_gprs_fprs() nounwind {
- ; RV64I-LABEL: name: caller_double_on_stack_exhausted_gprs_fprs
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
- ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
- ; RV64I-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 3
- ; RV64I-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
- ; RV64I-NEXT: [[C4:%[0-9]+]]:_(s128) = G_CONSTANT i128 5
- ; RV64I-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
- ; RV64I-NEXT: [[C6:%[0-9]+]]:_(s128) = G_CONSTANT i128 7
- ; RV64I-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
- ; RV64I-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
- ; RV64I-NEXT: [[C9:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
- ; RV64I-NEXT: [[C10:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
- ; RV64I-NEXT: [[C11:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
- ; RV64I-NEXT: [[C12:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
- ; RV64I-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C]](s128)
- ; RV64I-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C2]](s128)
- ; RV64I-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C4]](s128)
- ; RV64I-NEXT: [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C6]](s128)
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
- ; RV64I-NEXT: [[C13:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
- ; RV64I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s64)
- ; RV64I-NEXT: G_STORE [[C12]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
- ; RV64I-NEXT: $x10 = COPY [[UV]](s64)
- ; RV64I-NEXT: $x11 = COPY [[UV1]](s64)
- ; RV64I-NEXT: $f10_d = COPY [[C1]](s64)
- ; RV64I-NEXT: $x12 = COPY [[UV2]](s64)
- ; RV64I-NEXT: $x13 = COPY [[UV3]](s64)
- ; RV64I-NEXT: $f11_d = COPY [[C3]](s64)
- ; RV64I-NEXT: $x14 = COPY [[UV4]](s64)
- ; RV64I-NEXT: $x15 = COPY [[UV5]](s64)
- ; RV64I-NEXT: $f12_d = COPY [[C5]](s64)
- ; RV64I-NEXT: $x16 = COPY [[UV6]](s64)
- ; RV64I-NEXT: $x17 = COPY [[UV7]](s64)
- ; RV64I-NEXT: $f13_d = COPY [[C7]](s64)
- ; RV64I-NEXT: $f14_d = COPY [[C8]](s64)
- ; RV64I-NEXT: $f15_d = COPY [[C9]](s64)
- ; RV64I-NEXT: $f16_d = COPY [[C10]](s64)
- ; RV64I-NEXT: $f17_d = COPY [[C11]](s64)
- ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_on_stack_exhausted_gprs_fprs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_d, implicit $x12, implicit $x13, implicit $f11_d, implicit $x14, implicit $x15, implicit $f12_d, implicit $x16, implicit $x17, implicit $f13_d, implicit $f14_d, implicit $f15_d, implicit $f16_d, implicit $f17_d, implicit-def $x10
- ; RV64I-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
- ; RV64I-NEXT: $x10 = COPY [[COPY1]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %1 = call i64 @callee_double_on_stack_exhausted_gprs_fprs(
- i128 1, double 2.0, i128 3, double 4.0, i128 5, double 6.0, i128 7, double 8.0,
- double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
- ret i64 %1
-}
-
-define double @callee_double_ret() nounwind {
- ; RV64I-LABEL: name: callee_double_ret
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
- ; RV64I-NEXT: $f10_d = COPY [[C]](s64)
- ; RV64I-NEXT: PseudoRET implicit $f10_d
- ret double 1.0
-}
-
-define i64 @caller_double_ret() nounwind {
- ; RV64I-LABEL: name: caller_double_ret
- ; RV64I: bb.1 (%ir-block.0):
- ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_double_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $f10_d
- ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
- ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f10_d
- ; RV64I-NEXT: $x10 = COPY [[COPY]](s64)
- ; RV64I-NEXT: PseudoRET implicit $x10
- %1 = call double @callee_double_ret()
- %2 = bitcast double %1 to i64
- ret i64 %2
-}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
new file mode 100644
index 0000000000000..cad9406049b7b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
@@ -0,0 +1,331 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
+; RUN: llc -mtriple=riscv64 -mattr=+q -target-abi lp64q \
+; RUN: -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I %s
+
+; This file contains tests that should have identical output for the lp64 and
+; lp64f ABIs.
+
+define i64 @callee_fp128_in_regs(i64 %a, fp128 %b) nounwind {
+ ; RV64I-LABEL: name: callee_fp128_in_regs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: liveins: $x10, $f10_q
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[COPY1]](s128)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[FPTOSI]]
+ ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %b_fptosi = fptosi fp128 %b to i64
+ %1 = add i64 %a, %b_fptosi
+ ret i64 %1
+}
+
+define i64 @caller_fp128_in_regs() nounwind {
+ ; RV64I-LABEL: name: caller_fp128_in_regs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; RV64I-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: $x10 = COPY [[C1]](s64)
+ ; RV64I-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_in_regs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $f10_q, implicit-def $x10
+ ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: $x10 = COPY [[COPY]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %1 = fpext double 2.0 to fp128
+ %2 = call i64 @callee_fp128_in_regs(i64 1, fp128 %1)
+ ret i64 %2
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i64 @callee_fp128_in_fpr_exhausted_gprs(i128 %a, i128 %b, i128 %c, i128 %d, i64 %e, fp128 %f) nounwind {
+ ; RV64I-LABEL: name: callee_fp128_in_fpr_exhausted_gprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_q
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64)
+ ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+ ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x13
+ ; RV64I-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY2]](s64), [[COPY3]](s64)
+ ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x14
+ ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x15
+ ; RV64I-NEXT: [[MV2:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY4]](s64), [[COPY5]](s64)
+ ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x16
+ ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x17
+ ; RV64I-NEXT: [[MV3:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY6]](s64), [[COPY7]](s64)
+ ; RV64I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.0, align 16)
+ ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[COPY8]](s128)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[LOAD]], [[FPTOSI]]
+ ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %f_fptosi = fptosi fp128 %f to i64
+ %1 = add i64 %e, %f_fptosi
+ ret i64 %1
+}
+
+define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
+ ; RV64I-LABEL: name: caller_fp128_in_fpr_exhausted_gprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; RV64I-NEXT: [[C2:%[0-9]+]]:_(s128) = G_CONSTANT i128 2
+ ; RV64I-NEXT: [[C3:%[0-9]+]]:_(s128) = G_CONSTANT i128 3
+ ; RV64I-NEXT: [[C4:%[0-9]+]]:_(s128) = G_CONSTANT i128 4
+ ; RV64I-NEXT: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; RV64I-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV64I-NEXT: ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C1]](s128)
+ ; RV64I-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C2]](s128)
+ ; RV64I-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C3]](s128)
+ ; RV64I-NEXT: [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C4]](s128)
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV64I-NEXT: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; RV64I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s64)
+ ; RV64I-NEXT: G_STORE [[C5]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+ ; RV64I-NEXT: $x10 = COPY [[UV]](s64)
+ ; RV64I-NEXT: $x11 = COPY [[UV1]](s64)
+ ; RV64I-NEXT: $x12 = COPY [[UV2]](s64)
+ ; RV64I-NEXT: $x13 = COPY [[UV3]](s64)
+ ; RV64I-NEXT: $x14 = COPY [[UV4]](s64)
+ ; RV64I-NEXT: $x15 = COPY [[UV5]](s64)
+ ; RV64I-NEXT: $x16 = COPY [[UV6]](s64)
+ ; RV64I-NEXT: $x17 = COPY [[UV7]](s64)
+ ; RV64I-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_in_fpr_exhausted_gprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit $f10_q, implicit-def $x10
+ ; RV64I-NEXT: ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: $x10 = COPY [[COPY1]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %1 = fpext double 6.0 to fp128
+ %2 = call i64 @callee_fp128_in_fpr_exhausted_gprs(
+ i128 1, i128 2, i128 3, i128 4, i64 5, fp128 %1)
+ ret i64 %2
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_fp128_in_gpr_exhausted_fprs(fp128 %a, fp128 %b, fp128 %c, fp128 %d, fp128 %e, fp128 %f, fp128 %g, fp128 %h, fp128 %i) nounwind {
+ ; RV64I-LABEL: name: callee_fp128_in_gpr_exhausted_fprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: liveins: $x10, $x11, $f10_q, $f11_q, $f12_q, $f13_q, $f14_q, $f15_q, $f16_q, $f17_q
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s128) = COPY $f11_q
+ ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $f12_q
+ ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s128) = COPY $f13_q
+ ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s128) = COPY $f14_q
+ ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s128) = COPY $f15_q
+ ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s128) = COPY $f16_q
+ ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s128) = COPY $f17_q
+ ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[COPY9:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY8]](s64), [[COPY9]](s64)
+ ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY7]](s128)
+ ; RV64I-NEXT: [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[MV]](s128)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[FPTOSI]], [[FPTOSI1]]
+ ; RV64I-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ADD]](s32)
+ ; RV64I-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %h_fptosi = fptosi fp128 %h to i32
+ %i_fptosi = fptosi fp128 %i to i32
+ %1 = add i32 %h_fptosi, %i_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
+ ; RV64I-LABEL: name: caller_fp128_in_gpr_exhausted_fprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV64I-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 3.000000e+00
+ ; RV64I-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV64I-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 5.000000e+00
+ ; RV64I-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV64I-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 7.000000e+00
+ ; RV64I-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV64I-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV64I-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV64I-NEXT: [[FPEXT1:%[0-9]+]]:_(s128) = G_FPEXT [[C1]](s64)
+ ; RV64I-NEXT: [[FPEXT2:%[0-9]+]]:_(s128) = G_FPEXT [[C2]](s64)
+ ; RV64I-NEXT: [[FPEXT3:%[0-9]+]]:_(s128) = G_FPEXT [[C3]](s64)
+ ; RV64I-NEXT: [[FPEXT4:%[0-9]+]]:_(s128) = G_FPEXT [[C4]](s64)
+ ; RV64I-NEXT: [[FPEXT5:%[0-9]+]]:_(s128) = G_FPEXT [[C5]](s64)
+ ; RV64I-NEXT: [[FPEXT6:%[0-9]+]]:_(s128) = G_FPEXT [[C6]](s64)
+ ; RV64I-NEXT: [[FPEXT7:%[0-9]+]]:_(s128) = G_FPEXT [[C7]](s64)
+ ; RV64I-NEXT: [[FPEXT8:%[0-9]+]]:_(s128) = G_FPEXT [[C8]](s64)
+ ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT8]](s128)
+ ; RV64I-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV64I-NEXT: $f11_q = COPY [[FPEXT1]](s128)
+ ; RV64I-NEXT: $f12_q = COPY [[FPEXT2]](s128)
+ ; RV64I-NEXT: $f13_q = COPY [[FPEXT3]](s128)
+ ; RV64I-NEXT: $f14_q = COPY [[FPEXT4]](s128)
+ ; RV64I-NEXT: $f15_q = COPY [[FPEXT5]](s128)
+ ; RV64I-NEXT: $f16_q = COPY [[FPEXT6]](s128)
+ ; RV64I-NEXT: $f17_q = COPY [[FPEXT7]](s128)
+ ; RV64I-NEXT: $x10 = COPY [[UV]](s64)
+ ; RV64I-NEXT: $x11 = COPY [[UV1]](s64)
+ ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_in_gpr_exhausted_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $f10_q, implicit $f11_q, implicit $f12_q, implicit $f13_q, implicit $f14_q, implicit $f15_q, implicit $f16_q, implicit $f17_q, implicit $x10, implicit $x11, implicit-def $x10
+ ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; RV64I-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s32)
+ ; RV64I-NEXT: $x10 = COPY [[ANYEXT]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %1 = fpext double 1.0 to fp128
+ %2 = fpext double 2.0 to fp128
+ %3 = fpext double 3.0 to fp128
+ %4 = fpext double 4.0 to fp128
+ %5 = fpext double 5.0 to fp128
+ %6 = fpext double 6.0 to fp128
+ %7 = fpext double 7.0 to fp128
+ %8 = fpext double 8.0 to fp128
+ %9 = fpext double 9.0 to fp128
+ %10 = call i32 @callee_fp128_in_gpr_exhausted_fprs(
+ fp128 %1, fp128 %2, fp128 %3, fp128 %4, fp128 %5, fp128 %6,
+ fp128 %7, fp128 %8, fp128 %9)
+ ret i32 %10
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i64 @callee_fp128_on_stack_exhausted_gprs_fprs(i128 %a, fp128 %b, i128 %c, fp128 %d, i128 %e, fp128 %f, i128 %g, fp128 %h, fp128 %i, fp128 %j, fp128 %k, fp128 %l, fp128 %m) nounwind {
+ ; RV64I-LABEL: name: callee_fp128_on_stack_exhausted_gprs_fprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $f10_q, $f11_q, $f12_q, $f13_q, $f14_q, $f15_q, $f16_q, $f17_q
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+ ; RV64I-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64)
+ ; RV64I-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV64I-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x12
+ ; RV64I-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x13
+ ; RV64I-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY3]](s64), [[COPY4]](s64)
+ ; RV64I-NEXT: [[COPY5:%[0-9]+]]:_(s128) = COPY $f11_q
+ ; RV64I-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x14
+ ; RV64I-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x15
+ ; RV64I-NEXT: [[MV2:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY6]](s64), [[COPY7]](s64)
+ ; RV64I-NEXT: [[COPY8:%[0-9]+]]:_(s128) = COPY $f12_q
+ ; RV64I-NEXT: [[COPY9:%[0-9]+]]:_(s64) = COPY $x16
+ ; RV64I-NEXT: [[COPY10:%[0-9]+]]:_(s64) = COPY $x17
+ ; RV64I-NEXT: [[MV3:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY9]](s64), [[COPY10]](s64)
+ ; RV64I-NEXT: [[COPY11:%[0-9]+]]:_(s128) = COPY $f13_q
+ ; RV64I-NEXT: [[COPY12:%[0-9]+]]:_(s128) = COPY $f14_q
+ ; RV64I-NEXT: [[COPY13:%[0-9]+]]:_(s128) = COPY $f15_q
+ ; RV64I-NEXT: [[COPY14:%[0-9]+]]:_(s128) = COPY $f16_q
+ ; RV64I-NEXT: [[COPY15:%[0-9]+]]:_(s128) = COPY $f17_q
+ ; RV64I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s128) from %fixed-stack.0)
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[MV3]](s128)
+ ; RV64I-NEXT: [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[LOAD]](s128)
+ ; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[TRUNC]], [[FPTOSI]]
+ ; RV64I-NEXT: $x10 = COPY [[ADD]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %g_trunc = trunc i128 %g to i64
+ %m_fptosi = fptosi fp128 %m to i64
+ %1 = add i64 %g_trunc, %m_fptosi
+ ret i64 %1
+}
+
+define i64 @caller_fp128_on_stack_exhausted_gprs_fprs() nounwind {
+ ; RV64I-LABEL: name: caller_fp128_on_stack_exhausted_gprs_fprs
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
+ ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ ; RV64I-NEXT: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 6.000000e+00
+ ; RV64I-NEXT: [[C3:%[0-9]+]]:_(s64) = G_FCONSTANT double 8.000000e+00
+ ; RV64I-NEXT: [[C4:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; RV64I-NEXT: [[C5:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+01
+ ; RV64I-NEXT: [[C6:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.100000e+01
+ ; RV64I-NEXT: [[C7:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.200000e+01
+ ; RV64I-NEXT: [[C8:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.300000e+01
+ ; RV64I-NEXT: [[C9:%[0-9]+]]:_(s128) = G_CONSTANT i128 1
+ ; RV64I-NEXT: [[C10:%[0-9]+]]:_(s128) = G_CONSTANT i128 3
+ ; RV64I-NEXT: [[C11:%[0-9]+]]:_(s128) = G_CONSTANT i128 5
+ ; RV64I-NEXT: [[C12:%[0-9]+]]:_(s128) = G_CONSTANT i128 7
+ ; RV64I-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV64I-NEXT: [[FPEXT1:%[0-9]+]]:_(s128) = G_FPEXT [[C1]](s64)
+ ; RV64I-NEXT: [[FPEXT2:%[0-9]+]]:_(s128) = G_FPEXT [[C2]](s64)
+ ; RV64I-NEXT: [[FPEXT3:%[0-9]+]]:_(s128) = G_FPEXT [[C3]](s64)
+ ; RV64I-NEXT: [[FPEXT4:%[0-9]+]]:_(s128) = G_FPEXT [[C4]](s64)
+ ; RV64I-NEXT: [[FPEXT5:%[0-9]+]]:_(s128) = G_FPEXT [[C5]](s64)
+ ; RV64I-NEXT: [[FPEXT6:%[0-9]+]]:_(s128) = G_FPEXT [[C6]](s64)
+ ; RV64I-NEXT: [[FPEXT7:%[0-9]+]]:_(s128) = G_FPEXT [[C7]](s64)
+ ; RV64I-NEXT: [[FPEXT8:%[0-9]+]]:_(s128) = G_FPEXT [[C8]](s64)
+ ; RV64I-NEXT: ADJCALLSTACKDOWN 16, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C9]](s128)
+ ; RV64I-NEXT: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C10]](s128)
+ ; RV64I-NEXT: [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C11]](s128)
+ ; RV64I-NEXT: [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C12]](s128)
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+ ; RV64I-NEXT: [[C13:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; RV64I-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s64)
+ ; RV64I-NEXT: G_STORE [[FPEXT8]](s128), [[PTR_ADD]](p0) :: (store (s128) into stack)
+ ; RV64I-NEXT: $x10 = COPY [[UV]](s64)
+ ; RV64I-NEXT: $x11 = COPY [[UV1]](s64)
+ ; RV64I-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV64I-NEXT: $x12 = COPY [[UV2]](s64)
+ ; RV64I-NEXT: $x13 = COPY [[UV3]](s64)
+ ; RV64I-NEXT: $f11_q = COPY [[FPEXT1]](s128)
+ ; RV64I-NEXT: $x14 = COPY [[UV4]](s64)
+ ; RV64I-NEXT: $x15 = COPY [[UV5]](s64)
+ ; RV64I-NEXT: $f12_q = COPY [[FPEXT2]](s128)
+ ; RV64I-NEXT: $x16 = COPY [[UV6]](s64)
+ ; RV64I-NEXT: $x17 = COPY [[UV7]](s64)
+ ; RV64I-NEXT: $f13_q = COPY [[FPEXT3]](s128)
+ ; RV64I-NEXT: $f14_q = COPY [[FPEXT4]](s128)
+ ; RV64I-NEXT: $f15_q = COPY [[FPEXT5]](s128)
+ ; RV64I-NEXT: $f16_q = COPY [[FPEXT6]](s128)
+ ; RV64I-NEXT: $f17_q = COPY [[FPEXT7]](s128)
+ ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_on_stack_exhausted_gprs_fprs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $f10_q, implicit $x12, implicit $x13, implicit $f11_q, implicit $x14, implicit $x15, implicit $f12_q, implicit $x16, implicit $x17, implicit $f13_q, implicit $f14_q, implicit $f15_q, implicit $f16_q, implicit $f17_q, implicit-def $x10
+ ; RV64I-NEXT: ADJCALLSTACKUP 16, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: $x10 = COPY [[COPY1]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+ %2 = fpext double 2.0 to fp128
+ %4 = fpext double 4.0 to fp128
+ %6 = fpext double 6.0 to fp128
+ %8 = fpext double 8.0 to fp128
+ %9 = fpext double 9.0 to fp128
+ %10 = fpext double 10.0 to fp128
+ %11 = fpext double 11.0 to fp128
+ %12 = fpext double 12.0 to fp128
+ %13 = fpext double 13.0 to fp128
+ %14 = call i64 @callee_fp128_on_stack_exhausted_gprs_fprs(
+ i128 1, fp128 %2, i128 3, fp128 %4, i128 5, fp128 %6, i128 7, fp128 %8,
+ fp128 %9, fp128 %10, fp128 %11, fp128 %12, fp128 %13)
+ ret i64 %14
+}
+
+define fp128 @callee_fp128_ret() nounwind {
+ ; RV64I-LABEL: name: callee_fp128_ret
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
+ ; RV64I-NEXT: [[FPEXT:%[0-9]+]]:_(s128) = G_FPEXT [[C]](s64)
+ ; RV64I-NEXT: $f10_q = COPY [[FPEXT]](s128)
+ ; RV64I-NEXT: PseudoRET implicit $f10_q
+ %1 = fpext double 1.0 to fp128
+ ret fp128 %1
+}
+
+define i128 @caller_fp128_ret() nounwind {
+ ; RV64I-LABEL: name: caller_fp128_ret
+ ; RV64I: bb.1 (%ir-block.0):
+ ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @callee_fp128_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit-def $f10_q
+ ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $f10_q
+ ; RV64I-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[COPY]](s128)
+ ; RV64I-NEXT: $x10 = COPY [[UV]](s64)
+ ; RV64I-NEXT: $x11 = COPY [[UV1]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10, implicit $x11
+ %1 = call fp128 @callee_fp128_ret()
+ %2 = bitcast fp128 %1 to i128
+ ret i128 %2
+}
>From f7006a4be85a6deaf01102e9461bbd84f5d6642f Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Fri, 1 May 2026 23:46:19 +0200
Subject: [PATCH 2/5] Disable quad-prec ABIs in clang
---
clang/lib/Basic/Targets/RISCV.cpp | 2 --
clang/lib/Basic/Targets/RISCV.h | 3 +--
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index a531ee9302442..685925b0773dc 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -168,8 +168,6 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__riscv_float_abi_single");
else if (ABIName == "ilp32d" || ABIName == "lp64d")
Builder.defineMacro("__riscv_float_abi_double");
- else if (ABIName == "ilp32q" || ABIName == "lp64q")
- Builder.defineMacro("__riscv_float_abi_quad");
else
Builder.defineMacro("__riscv_float_abi_soft");
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index c02dbe11c92a4..6a86ac915110a 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -221,8 +221,7 @@ class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
return true;
}
- if (Name == "lp64" || Name == "lp64f" || Name == "lp64d" ||
- Name == "lp64q") {
+ if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
ABI = Name;
return true;
}
>From b08e01a8225e07dbb0361f3b832b5ac2ac7314df Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Sat, 2 May 2026 00:18:54 +0200
Subject: [PATCH 3/5] Remove unnecessary include
---
llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
index 0fa74796d9ace..68a8439b14276 100644
--- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
+++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
@@ -14,7 +14,6 @@
#include "MCTargetDesc/RISCVBaseInfo.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVSubtarget.h"
-#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCRegister.h"
>From b85958b9399790e704d9a5ec711577030d4719e4 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Sat, 2 May 2026 00:20:04 +0200
Subject: [PATCH 4/5] I forgot about this one
---
clang/lib/Basic/Targets/RISCV.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 6a86ac915110a..619d491d379d3 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -189,8 +189,7 @@ class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
return true;
}
- if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d" ||
- Name == "ilp32q") {
+ if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
ABI = Name;
return true;
}
>From 0b0febe6eec97d88769963381a6e74904acdc99b Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Tue, 5 May 2026 12:17:33 +0200
Subject: [PATCH 5/5] Use location size for alignment and better naming for
some variables
---
llvm/lib/Target/RISCV/RISCVCallingConv.cpp | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
index 68a8439b14276..3db154e0fe140 100644
--- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
+++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
@@ -549,7 +549,9 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
if (MCRegister Reg = State.AllocateReg(ArgGPRs))
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
else {
- int64_t StackOffset = State.AllocateStack(4, Align(4));
+ uint32_t PtrSizeInBytes = LocVT.getSizeInBits() / 8;
+ int64_t StackOffset =
+ State.AllocateStack(PtrSizeInBytes, Align(PtrSizeInBytes));
State.addLoc(
CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
}
@@ -566,9 +568,9 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
// cases.
MCRegister Reg = State.AllocateReg(ArgGPRs);
if (!Reg) {
- uint32_t AlignForStoredValue = LocVT.getSizeInBits() / 8;
+ uint32_t StoredSizeInBytes = LocVT.getSizeInBits() / 8;
int64_t StackOffset =
- State.AllocateStack(AlignForStoredValue, Align(AlignForStoredValue));
+ State.AllocateStack(StoredSizeInBytes, Align(StoredSizeInBytes));
State.addLoc(
CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
return false;
@@ -580,9 +582,9 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
State.addLoc(
CCValAssign::getCustomReg(ValNo, ValVT, HiReg, LocVT, LocInfo));
} else {
- uint32_t AlignForStoredValue = LocVT.getSizeInBits() / 8;
+ uint32_t LocSizeInBytes = LocVT.getSizeInBits() / 8;
int64_t StackOffset =
- State.AllocateStack(AlignForStoredValue, Align(AlignForStoredValue));
+ State.AllocateStack(LocSizeInBytes, Align(LocSizeInBytes));
State.addLoc(
CCValAssign::getCustomMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
}
More information about the llvm-commits
mailing list