[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