[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
Thu May 7 11:00:51 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 01/12] [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 02/12] 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 03/12] 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 04/12] 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 05/12] 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));
     }

>From 0eeb193b4a2e828a0c9a67c994f518f645d0fce0 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Wed, 6 May 2026 16:51:33 +0200
Subject: [PATCH 06/12] Temp. Disable Q in RV target lowering

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  18 +-
 .../irtranslator/calling-conv-ilp32q.ll       | 396 ++++++++++++------
 .../irtranslator/calling-conv-lp64q.ll        | 336 +++++++++++----
 3 files changed, 534 insertions(+), 216 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index f178513f9b589..e7a02efd23b45 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -151,8 +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.hasStdExtQ())
+  //  addRegisterClass(MVT::f128, &RISCV::FPR128RegClass);
   if (Subtarget.hasStdExtZhinxmin())
     addRegisterClass(MVT::f16, &RISCV::GPRF16RegClass);
   if (Subtarget.hasStdExtZfinx())
@@ -24579,6 +24579,20 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
       Chain = RetValue2.getValue(1);
       Glue = RetValue2.getValue(2);
 
+      // For big-endian, swap the order when building the pair.
+      SDValue Lo = RetValue;
+      SDValue Hi = RetValue2;
+      if (!Subtarget.isLittleEndian())
+        std::swap(Lo, Hi);
+
+      RetValue = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
+    } else if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f128) {
+      assert(VA.needsCustom());
+      SDValue RetValue2 = DAG.getCopyFromReg(Chain, DL, RVLocs[++i].getLocReg(),
+                                             MVT::i32, Glue);
+      Chain = RetValue2.getValue(1);
+      Glue = RetValue2.getValue(2);
+
       // For big-endian, swap the order when building the pair.
       SDValue Lo = RetValue;
       SDValue Hi = RetValue2;
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
index 68990bc75ee9a..0021ece1baea0 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
@@ -9,11 +9,12 @@
 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:   liveins: $x10, $x11
   ; 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:   [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD]](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
@@ -29,9 +30,11 @@ define i32 @caller_fp128_in_fpr() nounwind {
   ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
   ; 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:   $x11 = COPY [[FRAME_INDEX]](p0)
+  ; RV32-ILP32Q-NEXT:   PseudoCALL target-flags(riscv-call) @callee_fp128_in_fpr, csr_ilp32q_lp64q, implicit-def $x1, 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)
@@ -45,7 +48,7 @@ define i32 @caller_fp128_in_fpr() nounwind {
 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:   liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
   ; RV32-ILP32Q-NEXT: {{  $}}
   ; RV32-ILP32Q-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
   ; RV32-ILP32Q-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
@@ -59,10 +62,12 @@ define i32 @callee_fp128_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i
   ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.1, align 16)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; RV32-ILP32Q-NEXT:   [[LOAD1:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (p0) from %fixed-stack.0)
+  ; RV32-ILP32Q-NEXT:   [[LOAD2:%[0-9]+]]:_(s128) = G_LOAD [[LOAD1]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD2]](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
@@ -81,7 +86,7 @@ define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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:   ADJCALLSTACKDOWN 8, 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)
@@ -90,6 +95,11 @@ define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
+  ; RV32-ILP32Q-NEXT:   [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C7]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
   ; RV32-ILP32Q-NEXT:   $x10 = COPY [[UV]](s32)
   ; RV32-ILP32Q-NEXT:   $x11 = COPY [[UV1]](s32)
   ; RV32-ILP32Q-NEXT:   $x12 = COPY [[UV2]](s32)
@@ -98,9 +108,8 @@ define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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:   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-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
@@ -114,20 +123,29 @@ define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
 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:   liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
   ; 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:   [[COPY:%[0-9]+]]:_(p0) = COPY $x10
+  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
+  ; RV32-ILP32Q-NEXT:   [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY2:%[0-9]+]]:_(p0) = COPY $x12
+  ; RV32-ILP32Q-NEXT:   [[LOAD2:%[0-9]+]]:_(s128) = G_LOAD [[COPY2]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY3:%[0-9]+]]:_(p0) = COPY $x13
+  ; RV32-ILP32Q-NEXT:   [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[COPY3]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY4:%[0-9]+]]:_(p0) = COPY $x14
+  ; RV32-ILP32Q-NEXT:   [[LOAD4:%[0-9]+]]:_(s128) = G_LOAD [[COPY4]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY5:%[0-9]+]]:_(p0) = COPY $x15
+  ; RV32-ILP32Q-NEXT:   [[LOAD5:%[0-9]+]]:_(s128) = G_LOAD [[COPY5]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY6:%[0-9]+]]:_(p0) = COPY $x16
+  ; RV32-ILP32Q-NEXT:   [[LOAD6:%[0-9]+]]:_(s128) = G_LOAD [[COPY6]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY7:%[0-9]+]]:_(p0) = COPY $x17
+  ; RV32-ILP32Q-NEXT:   [[LOAD7:%[0-9]+]]:_(s128) = G_LOAD [[COPY7]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; RV32-ILP32Q-NEXT:   [[LOAD8:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.0, align 16)
+  ; RV32-ILP32Q-NEXT:   [[LOAD9:%[0-9]+]]:_(s128) = G_LOAD [[LOAD8]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD7]](s128)
+  ; RV32-ILP32Q-NEXT:   [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD9]](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
@@ -158,23 +176,41 @@ define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
   ; 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:   ADJCALLSTACKDOWN 4, 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:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT2]](s128), [[FRAME_INDEX2]](p0) :: (store (s128) into %stack.2)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT3]](s128), [[FRAME_INDEX3]](p0) :: (store (s128) into %stack.3)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.4
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT4]](s128), [[FRAME_INDEX4]](p0) :: (store (s128) into %stack.4)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.5
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT5]](s128), [[FRAME_INDEX5]](p0) :: (store (s128) into %stack.5)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.6
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT6]](s128), [[FRAME_INDEX6]](p0) :: (store (s128) into %stack.6)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.7
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT7]](s128), [[FRAME_INDEX7]](p0) :: (store (s128) into %stack.7)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.8
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT8]](s128), [[FRAME_INDEX8]](p0) :: (store (s128) into %stack.8)
+  ; RV32-ILP32Q-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+  ; RV32-ILP32Q-NEXT:   [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX8]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
+  ; RV32-ILP32Q-NEXT:   $x10 = COPY [[FRAME_INDEX]](p0)
+  ; RV32-ILP32Q-NEXT:   $x11 = COPY [[FRAME_INDEX1]](p0)
+  ; RV32-ILP32Q-NEXT:   $x12 = COPY [[FRAME_INDEX2]](p0)
+  ; RV32-ILP32Q-NEXT:   $x13 = COPY [[FRAME_INDEX3]](p0)
+  ; RV32-ILP32Q-NEXT:   $x14 = COPY [[FRAME_INDEX4]](p0)
+  ; RV32-ILP32Q-NEXT:   $x15 = COPY [[FRAME_INDEX5]](p0)
+  ; RV32-ILP32Q-NEXT:   $x16 = COPY [[FRAME_INDEX6]](p0)
+  ; RV32-ILP32Q-NEXT:   $x17 = COPY [[FRAME_INDEX7]](p0)
+  ; RV32-ILP32Q-NEXT:   PseudoCALL target-flags(riscv-call) @callee_fp128_in_gpr_exhausted_fprs, 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
+  ; 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 1.0 to fp128
   %2 = fpext double 2.0 to fp128
@@ -195,30 +231,46 @@ define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
 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:   liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
   ; 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:   [[COPY2:%[0-9]+]]:_(p0) = COPY $x12
+  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY2]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+  ; RV32-ILP32Q-NEXT:   [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
   ; 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:   [[COPY5:%[0-9]+]]:_(p0) = COPY $x15
+  ; RV32-ILP32Q-NEXT:   [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[COPY5]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
+  ; RV32-ILP32Q-NEXT:   [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
   ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
+  ; RV32-ILP32Q-NEXT:   [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.7, align 16)
+  ; RV32-ILP32Q-NEXT:   [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[LOAD2]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
+  ; RV32-ILP32Q-NEXT:   [[LOAD4:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.6)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
+  ; RV32-ILP32Q-NEXT:   [[LOAD5:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (p0) from %fixed-stack.5, align 8)
+  ; RV32-ILP32Q-NEXT:   [[LOAD6:%[0-9]+]]:_(s128) = G_LOAD [[LOAD5]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
+  ; RV32-ILP32Q-NEXT:   [[LOAD7:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (p0) from %fixed-stack.4)
+  ; RV32-ILP32Q-NEXT:   [[LOAD8:%[0-9]+]]:_(s128) = G_LOAD [[LOAD7]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
+  ; RV32-ILP32Q-NEXT:   [[LOAD9:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (p0) from %fixed-stack.3, align 16)
+  ; RV32-ILP32Q-NEXT:   [[LOAD10:%[0-9]+]]:_(s128) = G_LOAD [[LOAD9]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+  ; RV32-ILP32Q-NEXT:   [[LOAD11:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (p0) from %fixed-stack.2)
+  ; RV32-ILP32Q-NEXT:   [[LOAD12:%[0-9]+]]:_(s128) = G_LOAD [[LOAD11]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; RV32-ILP32Q-NEXT:   [[LOAD13:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (p0) from %fixed-stack.1, align 8)
+  ; RV32-ILP32Q-NEXT:   [[LOAD14:%[0-9]+]]:_(s128) = G_LOAD [[LOAD13]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; RV32-ILP32Q-NEXT:   [[LOAD15:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (p0) from %fixed-stack.0)
+  ; RV32-ILP32Q-NEXT:   [[LOAD16:%[0-9]+]]:_(s128) = G_LOAD [[LOAD15]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD16]](s128)
+  ; RV32-ILP32Q-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD4]], [[FPTOSI]]
   ; RV32-ILP32Q-NEXT:   $x10 = COPY [[ADD]](s32)
   ; RV32-ILP32Q-NEXT:   PseudoRET implicit $x10
   %m_fptosi = fptosi fp128 %m to i32
@@ -251,33 +303,65 @@ define i32 @caller_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind
   ; 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:   ADJCALLSTACKDOWN 32, 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
   ; RV32-ILP32Q-NEXT:   [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C10]](s64)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1)
   ; 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:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT2]](s128), [[FRAME_INDEX2]](p0) :: (store (s128) into %stack.2)
+  ; 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 [[FRAME_INDEX2]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
+  ; RV32-ILP32Q-NEXT:   [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[C12]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT3]](s128), [[FRAME_INDEX3]](p0) :: (store (s128) into %stack.3)
+  ; RV32-ILP32Q-NEXT:   [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX3]](p0), [[PTR_ADD2]](p0) :: (store (p0) into stack + 8, align 8)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.4
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT4]](s128), [[FRAME_INDEX4]](p0) :: (store (s128) into %stack.4)
+  ; RV32-ILP32Q-NEXT:   [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX4]](p0), [[PTR_ADD3]](p0) :: (store (p0) into stack + 12)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.5
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT5]](s128), [[FRAME_INDEX5]](p0) :: (store (s128) into %stack.5)
+  ; RV32-ILP32Q-NEXT:   [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX5]](p0), [[PTR_ADD4]](p0) :: (store (p0) into stack + 16, align 16)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.6
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT6]](s128), [[FRAME_INDEX6]](p0) :: (store (s128) into %stack.6)
+  ; RV32-ILP32Q-NEXT:   [[C18:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C18]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX6]](p0), [[PTR_ADD5]](p0) :: (store (p0) into stack + 20)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.7
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT7]](s128), [[FRAME_INDEX7]](p0) :: (store (s128) into %stack.7)
+  ; RV32-ILP32Q-NEXT:   [[C19:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C19]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX7]](p0), [[PTR_ADD6]](p0) :: (store (p0) into stack + 24, align 8)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.8
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT8]](s128), [[FRAME_INDEX8]](p0) :: (store (s128) into %stack.8)
+  ; RV32-ILP32Q-NEXT:   [[C20:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C20]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX8]](p0), [[PTR_ADD7]](p0) :: (store (p0) into stack + 28)
   ; 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:   $x12 = COPY [[FRAME_INDEX]](p0)
+  ; RV32-ILP32Q-NEXT:   $x13 = COPY [[UV2]](s32)
+  ; RV32-ILP32Q-NEXT:   $x14 = COPY [[UV3]](s32)
+  ; RV32-ILP32Q-NEXT:   $x15 = COPY [[FRAME_INDEX1]](p0)
+  ; RV32-ILP32Q-NEXT:   $x16 = COPY [[UV4]](s32)
+  ; RV32-ILP32Q-NEXT:   $x17 = COPY [[UV5]](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 $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
+  ; RV32-ILP32Q-NEXT:   ADJCALLSTACKUP 32, 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
@@ -299,33 +383,49 @@ define i32 @caller_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind
 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:   liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
   ; 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:   [[COPY2:%[0-9]+]]:_(p0) = COPY $x12
+  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY2]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
+  ; RV32-ILP32Q-NEXT:   [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
   ; 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:   [[COPY5:%[0-9]+]]:_(p0) = COPY $x15
+  ; RV32-ILP32Q-NEXT:   [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[COPY5]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
+  ; RV32-ILP32Q-NEXT:   [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
   ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.8
+  ; RV32-ILP32Q-NEXT:   [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.8, align 16)
+  ; RV32-ILP32Q-NEXT:   [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[LOAD2]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
+  ; RV32-ILP32Q-NEXT:   [[LOAD4:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.7, align 8)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
+  ; RV32-ILP32Q-NEXT:   [[LOAD5:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %fixed-stack.6)
+  ; RV32-ILP32Q-NEXT:   [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD4]](s32), [[LOAD5]](s32)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
+  ; RV32-ILP32Q-NEXT:   [[LOAD6:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (p0) from %fixed-stack.5, align 16)
+  ; RV32-ILP32Q-NEXT:   [[LOAD7:%[0-9]+]]:_(s128) = G_LOAD [[LOAD6]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
+  ; RV32-ILP32Q-NEXT:   [[LOAD8:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (p0) from %fixed-stack.4)
+  ; RV32-ILP32Q-NEXT:   [[LOAD9:%[0-9]+]]:_(s128) = G_LOAD [[LOAD8]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
+  ; RV32-ILP32Q-NEXT:   [[LOAD10:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (p0) from %fixed-stack.3, align 8)
+  ; RV32-ILP32Q-NEXT:   [[LOAD11:%[0-9]+]]:_(s128) = G_LOAD [[LOAD10]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+  ; RV32-ILP32Q-NEXT:   [[LOAD12:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (p0) from %fixed-stack.2)
+  ; RV32-ILP32Q-NEXT:   [[LOAD13:%[0-9]+]]:_(s128) = G_LOAD [[LOAD12]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; RV32-ILP32Q-NEXT:   [[LOAD14:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (p0) from %fixed-stack.1, align 16)
+  ; RV32-ILP32Q-NEXT:   [[LOAD15:%[0-9]+]]:_(s128) = G_LOAD [[LOAD14]](p0) :: (load (s128))
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; RV32-ILP32Q-NEXT:   [[LOAD16:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX8]](p0) :: (load (p0) from %fixed-stack.0)
+  ; RV32-ILP32Q-NEXT:   [[LOAD17:%[0-9]+]]:_(s128) = G_LOAD [[LOAD16]](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:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD17]](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
@@ -360,36 +460,67 @@ define i32 @caller_fp128_on_stack_exhausted_gprs_fprs() nounwind {
   ; 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:   ADJCALLSTACKDOWN 40, 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
   ; RV32-ILP32Q-NEXT:   [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C10]](s64)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1)
   ; 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:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT2]](s128), [[FRAME_INDEX2]](p0) :: (store (s128) into %stack.2)
   ; 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:   G_STORE [[FRAME_INDEX2]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
+  ; RV32-ILP32Q-NEXT:   [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C12]](s64)
+  ; RV32-ILP32Q-NEXT:   [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[UV6]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 8, align 8)
+  ; RV32-ILP32Q-NEXT:   [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[UV7]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 12)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT3]](s128), [[FRAME_INDEX3]](p0) :: (store (s128) into %stack.3)
+  ; RV32-ILP32Q-NEXT:   [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX3]](p0), [[PTR_ADD3]](p0) :: (store (p0) into stack + 16, align 16)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.4
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT4]](s128), [[FRAME_INDEX4]](p0) :: (store (s128) into %stack.4)
+  ; RV32-ILP32Q-NEXT:   [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX4]](p0), [[PTR_ADD4]](p0) :: (store (p0) into stack + 20)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.5
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT5]](s128), [[FRAME_INDEX5]](p0) :: (store (s128) into %stack.5)
+  ; RV32-ILP32Q-NEXT:   [[C18:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C18]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX5]](p0), [[PTR_ADD5]](p0) :: (store (p0) into stack + 24, align 8)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.6
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT6]](s128), [[FRAME_INDEX6]](p0) :: (store (s128) into %stack.6)
+  ; RV32-ILP32Q-NEXT:   [[C19:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C19]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX6]](p0), [[PTR_ADD6]](p0) :: (store (p0) into stack + 28)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.7
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT7]](s128), [[FRAME_INDEX7]](p0) :: (store (s128) into %stack.7)
+  ; RV32-ILP32Q-NEXT:   [[C20:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C20]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX7]](p0), [[PTR_ADD7]](p0) :: (store (p0) into stack + 32, align 16)
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.8
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT8]](s128), [[FRAME_INDEX8]](p0) :: (store (s128) into %stack.8)
+  ; RV32-ILP32Q-NEXT:   [[C21:%[0-9]+]]:_(s32) = G_CONSTANT i32 36
+  ; RV32-ILP32Q-NEXT:   [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C21]](s32)
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX8]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 36)
   ; 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:   $x12 = COPY [[FRAME_INDEX]](p0)
+  ; RV32-ILP32Q-NEXT:   $x13 = COPY [[UV2]](s32)
+  ; RV32-ILP32Q-NEXT:   $x14 = COPY [[UV3]](s32)
+  ; RV32-ILP32Q-NEXT:   $x15 = COPY [[FRAME_INDEX1]](p0)
+  ; RV32-ILP32Q-NEXT:   $x16 = COPY [[UV4]](s32)
+  ; RV32-ILP32Q-NEXT:   $x17 = COPY [[UV5]](s32)
+  ; 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 $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
+  ; RV32-ILP32Q-NEXT:   ADJCALLSTACKUP 40, 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
@@ -411,10 +542,13 @@ define i32 @caller_fp128_on_stack_exhausted_gprs_fprs() nounwind {
 define fp128 @callee_fp128_ret() nounwind {
   ; RV32-ILP32Q-LABEL: name: callee_fp128_ret
   ; RV32-ILP32Q: bb.1 (%ir-block.0):
+  ; RV32-ILP32Q-NEXT:   liveins: $x10
+  ; RV32-ILP32Q-NEXT: {{  $}}
+  ; RV32-ILP32Q-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x10
   ; 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
+  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[COPY]](p0) :: (store (s128))
+  ; RV32-ILP32Q-NEXT:   PseudoRET
   %1 = fpext double 1.0 to fp128
   ret fp128 %1
 }
@@ -422,11 +556,13 @@ define fp128 @callee_fp128_ret() nounwind {
 define i32 @caller_fp128_ret() nounwind {
   ; RV32-ILP32Q-LABEL: name: caller_fp128_ret
   ; RV32-ILP32Q: bb.1 (%ir-block.0):
+  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.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:   $x10 = COPY [[FRAME_INDEX]](p0)
+  ; RV32-ILP32Q-NEXT:   PseudoCALL target-flags(riscv-call) @callee_fp128_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10
   ; 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:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s128) from %stack.0)
+  ; RV32-ILP32Q-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LOAD]](s128)
   ; RV32-ILP32Q-NEXT:   $x10 = COPY [[TRUNC]](s32)
   ; RV32-ILP32Q-NEXT:   PseudoRET implicit $x10
   %1 = call fp128 @callee_fp128_ret()
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
index cad9406049b7b..404a3a383010b 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
@@ -9,11 +9,13 @@
 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:   liveins: $x10, $x11, $x12
   ; 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:   [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
+  ; RV64I-NEXT:   [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
+  ; RV64I-NEXT:   [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY1]](s64), [[COPY2]](s64)
+  ; RV64I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[MV]](s128)
   ; RV64I-NEXT:   [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[FPTOSI]]
   ; RV64I-NEXT:   $x10 = COPY [[ADD]](s64)
   ; RV64I-NEXT:   PseudoRET implicit $x10
@@ -29,9 +31,11 @@ define i64 @caller_fp128_in_regs() nounwind {
   ; 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:   [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
   ; 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:   $x11 = COPY [[UV]](s64)
+  ; RV64I-NEXT:   $x12 = COPY [[UV1]](s64)
+  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @callee_fp128_in_regs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, 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)
@@ -45,7 +49,7 @@ define i64 @caller_fp128_in_regs() nounwind {
 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:   liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
   ; RV64I-NEXT: {{  $}}
   ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
   ; RV64I-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
@@ -59,10 +63,14 @@ define i64 @callee_fp128_in_fpr_exhausted_gprs(i128 %a, i128 %b, i128 %c, i128 %
   ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+  ; RV64I-NEXT:   [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.2, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; RV64I-NEXT:   [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %fixed-stack.1, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; RV64I-NEXT:   [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %fixed-stack.0)
+  ; RV64I-NEXT:   [[MV4:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD1]](s64), [[LOAD2]](s64)
+  ; RV64I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[MV4]](s128)
   ; RV64I-NEXT:   [[ADD:%[0-9]+]]:_(s64) = G_ADD [[LOAD]], [[FPTOSI]]
   ; RV64I-NEXT:   $x10 = COPY [[ADD]](s64)
   ; RV64I-NEXT:   PseudoRET implicit $x10
@@ -81,7 +89,7 @@ define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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:   ADJCALLSTACKDOWN 32, 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)
@@ -90,6 +98,13 @@ define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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:   [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
+  ; RV64I-NEXT:   [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
+  ; RV64I-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C7]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV8]](s64), [[PTR_ADD1]](p0) :: (store (s64) into stack + 16, align 16)
+  ; RV64I-NEXT:   [[C8:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
+  ; RV64I-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV9]](s64), [[PTR_ADD2]](p0) :: (store (s64) into stack + 24)
   ; RV64I-NEXT:   $x10 = COPY [[UV]](s64)
   ; RV64I-NEXT:   $x11 = COPY [[UV1]](s64)
   ; RV64I-NEXT:   $x12 = COPY [[UV2]](s64)
@@ -98,9 +113,8 @@ define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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:   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-def $x10
+  ; RV64I-NEXT:   ADJCALLSTACKUP 32, 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
@@ -114,21 +128,47 @@ define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
 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:   liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
   ; 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:   [[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.9
+  ; RV64I-NEXT:   [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.9, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.8
+  ; RV64I-NEXT:   [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %fixed-stack.8)
+  ; RV64I-NEXT:   [[MV4:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD]](s64), [[LOAD1]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
+  ; RV64I-NEXT:   [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %fixed-stack.7, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
+  ; RV64I-NEXT:   [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (s64) from %fixed-stack.6)
+  ; RV64I-NEXT:   [[MV5:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD2]](s64), [[LOAD3]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
+  ; RV64I-NEXT:   [[LOAD4:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s64) from %fixed-stack.5, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
+  ; RV64I-NEXT:   [[LOAD5:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (s64) from %fixed-stack.4)
+  ; RV64I-NEXT:   [[MV6:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD4]](s64), [[LOAD5]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
+  ; RV64I-NEXT:   [[LOAD6:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (s64) from %fixed-stack.3, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+  ; RV64I-NEXT:   [[LOAD7:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (s64) from %fixed-stack.2)
+  ; RV64I-NEXT:   [[MV7:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD6]](s64), [[LOAD7]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; RV64I-NEXT:   [[LOAD8:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX8]](p0) :: (load (s64) from %fixed-stack.1, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX9:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; RV64I-NEXT:   [[LOAD9:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX9]](p0) :: (load (s64) from %fixed-stack.0)
+  ; RV64I-NEXT:   [[MV8:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD8]](s64), [[LOAD9]](s64)
+  ; RV64I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[MV7]](s128)
+  ; RV64I-NEXT:   [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[MV8]](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)
@@ -160,22 +200,59 @@ define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
   ; 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:   ADJCALLSTACKDOWN 80, 0, implicit-def $x2, implicit $x2
+  ; RV64I-NEXT:   [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
+  ; RV64I-NEXT:   [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT1]](s128)
+  ; RV64I-NEXT:   [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT2]](s128)
+  ; RV64I-NEXT:   [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT3]](s128)
+  ; RV64I-NEXT:   [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT4]](s128)
+  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x2
+  ; RV64I-NEXT:   [[C9:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+  ; RV64I-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV8]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+  ; RV64I-NEXT:   [[C10:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
+  ; RV64I-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV9]](s64), [[PTR_ADD1]](p0) :: (store (s64) into stack + 8)
+  ; RV64I-NEXT:   [[UV10:%[0-9]+]]:_(s64), [[UV11:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT5]](s128)
+  ; RV64I-NEXT:   [[C11:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
+  ; RV64I-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV10]](s64), [[PTR_ADD2]](p0) :: (store (s64) into stack + 16, align 16)
+  ; RV64I-NEXT:   [[C12:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
+  ; RV64I-NEXT:   [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV11]](s64), [[PTR_ADD3]](p0) :: (store (s64) into stack + 24)
+  ; RV64I-NEXT:   [[UV12:%[0-9]+]]:_(s64), [[UV13:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT6]](s128)
+  ; RV64I-NEXT:   [[C13:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
+  ; RV64I-NEXT:   [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV12]](s64), [[PTR_ADD4]](p0) :: (store (s64) into stack + 32, align 16)
+  ; RV64I-NEXT:   [[C14:%[0-9]+]]:_(s64) = G_CONSTANT i64 40
+  ; RV64I-NEXT:   [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV13]](s64), [[PTR_ADD5]](p0) :: (store (s64) into stack + 40)
+  ; RV64I-NEXT:   [[UV14:%[0-9]+]]:_(s64), [[UV15:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT7]](s128)
+  ; RV64I-NEXT:   [[C15:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
+  ; RV64I-NEXT:   [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV14]](s64), [[PTR_ADD6]](p0) :: (store (s64) into stack + 48, align 16)
+  ; RV64I-NEXT:   [[C16:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+  ; RV64I-NEXT:   [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV15]](s64), [[PTR_ADD7]](p0) :: (store (s64) into stack + 56)
+  ; RV64I-NEXT:   [[UV16:%[0-9]+]]:_(s64), [[UV17:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT8]](s128)
+  ; RV64I-NEXT:   [[C17:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
+  ; RV64I-NEXT:   [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV16]](s64), [[PTR_ADD8]](p0) :: (store (s64) into stack + 64, align 16)
+  ; RV64I-NEXT:   [[C18:%[0-9]+]]:_(s64) = G_CONSTANT i64 72
+  ; RV64I-NEXT:   [[PTR_ADD9:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C18]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV17]](s64), [[PTR_ADD9]](p0) :: (store (s64) into stack + 72)
   ; 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:   $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:   PseudoCALL target-flags(riscv-call) @callee_fp128_in_gpr_exhausted_fprs, 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
+  ; RV64I-NEXT:   ADJCALLSTACKUP 80, 0, implicit-def $x2, implicit $x2
+  ; RV64I-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
+  ; RV64I-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
   ; RV64I-NEXT:   [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]](s32)
   ; RV64I-NEXT:   $x10 = COPY [[ANYEXT]](s64)
   ; RV64I-NEXT:   PseudoRET implicit $x10
@@ -198,32 +275,67 @@ define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
 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:   liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
   ; 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:   [[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.17
+  ; RV64I-NEXT:   [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.17, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.16
+  ; RV64I-NEXT:   [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %fixed-stack.16)
+  ; RV64I-NEXT:   [[MV4:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD]](s64), [[LOAD1]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.15
+  ; RV64I-NEXT:   [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %fixed-stack.15, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.14
+  ; RV64I-NEXT:   [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (s64) from %fixed-stack.14)
+  ; RV64I-NEXT:   [[MV5:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD2]](s64), [[LOAD3]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.13
+  ; RV64I-NEXT:   [[LOAD4:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s64) from %fixed-stack.13, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.12
+  ; RV64I-NEXT:   [[LOAD5:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (s64) from %fixed-stack.12)
+  ; RV64I-NEXT:   [[MV6:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD4]](s64), [[LOAD5]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.11
+  ; RV64I-NEXT:   [[LOAD6:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (s64) from %fixed-stack.11, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.10
+  ; RV64I-NEXT:   [[LOAD7:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (s64) from %fixed-stack.10)
+  ; RV64I-NEXT:   [[MV7:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD6]](s64), [[LOAD7]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.9
+  ; RV64I-NEXT:   [[LOAD8:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX8]](p0) :: (load (s64) from %fixed-stack.9, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX9:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.8
+  ; RV64I-NEXT:   [[LOAD9:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX9]](p0) :: (load (s64) from %fixed-stack.8)
+  ; RV64I-NEXT:   [[MV8:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD8]](s64), [[LOAD9]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX10:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
+  ; RV64I-NEXT:   [[LOAD10:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX10]](p0) :: (load (s64) from %fixed-stack.7, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX11:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
+  ; RV64I-NEXT:   [[LOAD11:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX11]](p0) :: (load (s64) from %fixed-stack.6)
+  ; RV64I-NEXT:   [[MV9:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD10]](s64), [[LOAD11]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX12:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
+  ; RV64I-NEXT:   [[LOAD12:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX12]](p0) :: (load (s64) from %fixed-stack.5, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX13:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
+  ; RV64I-NEXT:   [[LOAD13:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX13]](p0) :: (load (s64) from %fixed-stack.4)
+  ; RV64I-NEXT:   [[MV10:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD12]](s64), [[LOAD13]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX14:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
+  ; RV64I-NEXT:   [[LOAD14:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX14]](p0) :: (load (s64) from %fixed-stack.3, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX15:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
+  ; RV64I-NEXT:   [[LOAD15:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX15]](p0) :: (load (s64) from %fixed-stack.2)
+  ; RV64I-NEXT:   [[MV11:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD14]](s64), [[LOAD15]](s64)
+  ; RV64I-NEXT:   [[FRAME_INDEX16:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+  ; RV64I-NEXT:   [[LOAD16:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX16]](p0) :: (load (s64) from %fixed-stack.1, align 16)
+  ; RV64I-NEXT:   [[FRAME_INDEX17:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+  ; RV64I-NEXT:   [[LOAD17:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX17]](p0) :: (load (s64) from %fixed-stack.0)
+  ; RV64I-NEXT:   [[MV12:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD16]](s64), [[LOAD17]](s64)
+  ; RV64I-NEXT:   [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[MV6]](s128)
+  ; RV64I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[MV12]](s128)
   ; RV64I-NEXT:   [[ADD:%[0-9]+]]:_(s64) = G_ADD [[TRUNC]], [[FPTOSI]]
   ; RV64I-NEXT:   $x10 = COPY [[ADD]](s64)
   ; RV64I-NEXT:   PseudoRET implicit $x10
@@ -258,33 +370,85 @@ define i64 @caller_fp128_on_stack_exhausted_gprs_fprs() nounwind {
   ; 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:   ADJCALLSTACKDOWN 144, 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:   [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
+  ; RV64I-NEXT:   [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C10]](s128)
+  ; RV64I-NEXT:   [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT1]](s128)
+  ; RV64I-NEXT:   [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C11]](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:   G_STORE [[UV8]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
+  ; RV64I-NEXT:   [[C14:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
+  ; RV64I-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV9]](s64), [[PTR_ADD1]](p0) :: (store (s64) into stack + 8)
+  ; RV64I-NEXT:   [[UV10:%[0-9]+]]:_(s64), [[UV11:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT2]](s128)
+  ; RV64I-NEXT:   [[C15:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
+  ; RV64I-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV10]](s64), [[PTR_ADD2]](p0) :: (store (s64) into stack + 16, align 16)
+  ; RV64I-NEXT:   [[C16:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
+  ; RV64I-NEXT:   [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV11]](s64), [[PTR_ADD3]](p0) :: (store (s64) into stack + 24)
+  ; RV64I-NEXT:   [[UV12:%[0-9]+]]:_(s64), [[UV13:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C12]](s128)
+  ; RV64I-NEXT:   [[C17:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
+  ; RV64I-NEXT:   [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV12]](s64), [[PTR_ADD4]](p0) :: (store (s64) into stack + 32, align 16)
+  ; RV64I-NEXT:   [[C18:%[0-9]+]]:_(s64) = G_CONSTANT i64 40
+  ; RV64I-NEXT:   [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C18]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV13]](s64), [[PTR_ADD5]](p0) :: (store (s64) into stack + 40)
+  ; RV64I-NEXT:   [[UV14:%[0-9]+]]:_(s64), [[UV15:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT3]](s128)
+  ; RV64I-NEXT:   [[C19:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
+  ; RV64I-NEXT:   [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C19]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV14]](s64), [[PTR_ADD6]](p0) :: (store (s64) into stack + 48, align 16)
+  ; RV64I-NEXT:   [[C20:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
+  ; RV64I-NEXT:   [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C20]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV15]](s64), [[PTR_ADD7]](p0) :: (store (s64) into stack + 56)
+  ; RV64I-NEXT:   [[UV16:%[0-9]+]]:_(s64), [[UV17:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT4]](s128)
+  ; RV64I-NEXT:   [[C21:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
+  ; RV64I-NEXT:   [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C21]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV16]](s64), [[PTR_ADD8]](p0) :: (store (s64) into stack + 64, align 16)
+  ; RV64I-NEXT:   [[C22:%[0-9]+]]:_(s64) = G_CONSTANT i64 72
+  ; RV64I-NEXT:   [[PTR_ADD9:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C22]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV17]](s64), [[PTR_ADD9]](p0) :: (store (s64) into stack + 72)
+  ; RV64I-NEXT:   [[UV18:%[0-9]+]]:_(s64), [[UV19:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT5]](s128)
+  ; RV64I-NEXT:   [[C23:%[0-9]+]]:_(s64) = G_CONSTANT i64 80
+  ; RV64I-NEXT:   [[PTR_ADD10:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C23]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV18]](s64), [[PTR_ADD10]](p0) :: (store (s64) into stack + 80, align 16)
+  ; RV64I-NEXT:   [[C24:%[0-9]+]]:_(s64) = G_CONSTANT i64 88
+  ; RV64I-NEXT:   [[PTR_ADD11:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C24]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV19]](s64), [[PTR_ADD11]](p0) :: (store (s64) into stack + 88)
+  ; RV64I-NEXT:   [[UV20:%[0-9]+]]:_(s64), [[UV21:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT6]](s128)
+  ; RV64I-NEXT:   [[C25:%[0-9]+]]:_(s64) = G_CONSTANT i64 96
+  ; RV64I-NEXT:   [[PTR_ADD12:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C25]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV20]](s64), [[PTR_ADD12]](p0) :: (store (s64) into stack + 96, align 16)
+  ; RV64I-NEXT:   [[C26:%[0-9]+]]:_(s64) = G_CONSTANT i64 104
+  ; RV64I-NEXT:   [[PTR_ADD13:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C26]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV21]](s64), [[PTR_ADD13]](p0) :: (store (s64) into stack + 104)
+  ; RV64I-NEXT:   [[UV22:%[0-9]+]]:_(s64), [[UV23:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT7]](s128)
+  ; RV64I-NEXT:   [[C27:%[0-9]+]]:_(s64) = G_CONSTANT i64 112
+  ; RV64I-NEXT:   [[PTR_ADD14:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C27]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV22]](s64), [[PTR_ADD14]](p0) :: (store (s64) into stack + 112, align 16)
+  ; RV64I-NEXT:   [[C28:%[0-9]+]]:_(s64) = G_CONSTANT i64 120
+  ; RV64I-NEXT:   [[PTR_ADD15:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C28]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV23]](s64), [[PTR_ADD15]](p0) :: (store (s64) into stack + 120)
+  ; RV64I-NEXT:   [[UV24:%[0-9]+]]:_(s64), [[UV25:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT8]](s128)
+  ; RV64I-NEXT:   [[C29:%[0-9]+]]:_(s64) = G_CONSTANT i64 128
+  ; RV64I-NEXT:   [[PTR_ADD16:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C29]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV24]](s64), [[PTR_ADD16]](p0) :: (store (s64) into stack + 128, align 16)
+  ; RV64I-NEXT:   [[C30:%[0-9]+]]:_(s64) = G_CONSTANT i64 136
+  ; RV64I-NEXT:   [[PTR_ADD17:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C30]](s64)
+  ; RV64I-NEXT:   G_STORE [[UV25]](s64), [[PTR_ADD17]](p0) :: (store (s64) into stack + 136)
   ; 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:   PseudoCALL target-flags(riscv-call) @callee_fp128_on_stack_exhausted_gprs_fprs, 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
+  ; RV64I-NEXT:   ADJCALLSTACKUP 144, 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
@@ -308,8 +472,10 @@ define fp128 @callee_fp128_ret() nounwind {
   ; 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
+  ; RV64I-NEXT:   [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
+  ; RV64I-NEXT:   $x10 = COPY [[UV]](s64)
+  ; RV64I-NEXT:   $x11 = COPY [[UV1]](s64)
+  ; RV64I-NEXT:   PseudoRET implicit $x10, implicit $x11
   %1 = fpext double 1.0 to fp128
   ret fp128 %1
 }
@@ -318,10 +484,12 @@ 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:   PseudoCALL target-flags(riscv-call) @callee_fp128_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit-def $x10, implicit-def $x11
   ; 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:   [[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:   [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV]](s128)
   ; RV64I-NEXT:   $x10 = COPY [[UV]](s64)
   ; RV64I-NEXT:   $x11 = COPY [[UV1]](s64)
   ; RV64I-NEXT:   PseudoRET implicit $x10, implicit $x11

>From a8f773c5d80571206bee67bca76222c46dbe26dd Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Wed, 6 May 2026 21:15:08 +0200
Subject: [PATCH 07/12] Revert "Temp. Disable Q in RV target lowering"

This reverts commit 0eeb193b4a2e828a0c9a67c994f518f645d0fce0.
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  18 +-
 .../irtranslator/calling-conv-ilp32q.ll       | 396 ++++++------------
 .../irtranslator/calling-conv-lp64q.ll        | 336 ++++-----------
 3 files changed, 216 insertions(+), 534 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index e7a02efd23b45..f178513f9b589 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -151,8 +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.hasStdExtQ())
+    addRegisterClass(MVT::f128, &RISCV::FPR128RegClass);
   if (Subtarget.hasStdExtZhinxmin())
     addRegisterClass(MVT::f16, &RISCV::GPRF16RegClass);
   if (Subtarget.hasStdExtZfinx())
@@ -24579,20 +24579,6 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
       Chain = RetValue2.getValue(1);
       Glue = RetValue2.getValue(2);
 
-      // For big-endian, swap the order when building the pair.
-      SDValue Lo = RetValue;
-      SDValue Hi = RetValue2;
-      if (!Subtarget.isLittleEndian())
-        std::swap(Lo, Hi);
-
-      RetValue = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
-    } else if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f128) {
-      assert(VA.needsCustom());
-      SDValue RetValue2 = DAG.getCopyFromReg(Chain, DL, RVLocs[++i].getLocReg(),
-                                             MVT::i32, Glue);
-      Chain = RetValue2.getValue(1);
-      Glue = RetValue2.getValue(2);
-
       // For big-endian, swap the order when building the pair.
       SDValue Lo = RetValue;
       SDValue Hi = RetValue2;
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
index 0021ece1baea0..68990bc75ee9a 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32q.ll
@@ -9,12 +9,11 @@
 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, $x11
+  ; 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]+]]:_(p0) = COPY $x11
-  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD]](s128)
+  ; 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
@@ -30,11 +29,9 @@ define i32 @caller_fp128_in_fpr() nounwind {
   ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
   ; RV32-ILP32Q-NEXT:   $x10 = COPY [[C1]](s32)
-  ; RV32-ILP32Q-NEXT:   $x11 = COPY [[FRAME_INDEX]](p0)
-  ; RV32-ILP32Q-NEXT:   PseudoCALL target-flags(riscv-call) @callee_fp128_in_fpr, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+  ; 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)
@@ -48,7 +45,7 @@ define i32 @caller_fp128_in_fpr() nounwind {
 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
+  ; 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
@@ -62,12 +59,10 @@ define i32 @callee_fp128_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i
   ; 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.1
-  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.1, align 16)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
-  ; RV32-ILP32Q-NEXT:   [[LOAD1:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (p0) from %fixed-stack.0)
-  ; RV32-ILP32Q-NEXT:   [[LOAD2:%[0-9]+]]:_(s128) = G_LOAD [[LOAD1]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD2]](s128)
+  ; 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
@@ -86,7 +81,7 @@ define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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 8, 0, implicit-def $x2, implicit $x2
+  ; 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)
@@ -95,11 +90,6 @@ define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
-  ; RV32-ILP32Q-NEXT:   [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C7]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX]](p0), [[PTR_ADD1]](p0) :: (store (p0) into stack + 4)
   ; RV32-ILP32Q-NEXT:   $x10 = COPY [[UV]](s32)
   ; RV32-ILP32Q-NEXT:   $x11 = COPY [[UV1]](s32)
   ; RV32-ILP32Q-NEXT:   $x12 = COPY [[UV2]](s32)
@@ -108,8 +98,9 @@ define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; RV32-ILP32Q-NEXT:   $x15 = COPY [[UV5]](s32)
   ; RV32-ILP32Q-NEXT:   $x16 = COPY [[UV6]](s32)
   ; RV32-ILP32Q-NEXT:   $x17 = COPY [[UV7]](s32)
-  ; 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-def $x10
-  ; RV32-ILP32Q-NEXT:   ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
+  ; 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
@@ -123,29 +114,20 @@ define i32 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
 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, $x11, $x12, $x13, $x14, $x15, $x16, $x17
+  ; 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]+]]:_(p0) = COPY $x10
-  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
-  ; RV32-ILP32Q-NEXT:   [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY2:%[0-9]+]]:_(p0) = COPY $x12
-  ; RV32-ILP32Q-NEXT:   [[LOAD2:%[0-9]+]]:_(s128) = G_LOAD [[COPY2]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY3:%[0-9]+]]:_(p0) = COPY $x13
-  ; RV32-ILP32Q-NEXT:   [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[COPY3]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY4:%[0-9]+]]:_(p0) = COPY $x14
-  ; RV32-ILP32Q-NEXT:   [[LOAD4:%[0-9]+]]:_(s128) = G_LOAD [[COPY4]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY5:%[0-9]+]]:_(p0) = COPY $x15
-  ; RV32-ILP32Q-NEXT:   [[LOAD5:%[0-9]+]]:_(s128) = G_LOAD [[COPY5]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY6:%[0-9]+]]:_(p0) = COPY $x16
-  ; RV32-ILP32Q-NEXT:   [[LOAD6:%[0-9]+]]:_(s128) = G_LOAD [[COPY6]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY7:%[0-9]+]]:_(p0) = COPY $x17
-  ; RV32-ILP32Q-NEXT:   [[LOAD7:%[0-9]+]]:_(s128) = G_LOAD [[COPY7]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
-  ; RV32-ILP32Q-NEXT:   [[LOAD8:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.0, align 16)
-  ; RV32-ILP32Q-NEXT:   [[LOAD9:%[0-9]+]]:_(s128) = G_LOAD [[LOAD8]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD7]](s128)
-  ; RV32-ILP32Q-NEXT:   [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD9]](s128)
+  ; 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
@@ -176,41 +158,23 @@ define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
   ; 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:   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 [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT2]](s128), [[FRAME_INDEX2]](p0) :: (store (s128) into %stack.2)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT3]](s128), [[FRAME_INDEX3]](p0) :: (store (s128) into %stack.3)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.4
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT4]](s128), [[FRAME_INDEX4]](p0) :: (store (s128) into %stack.4)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.5
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT5]](s128), [[FRAME_INDEX5]](p0) :: (store (s128) into %stack.5)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.6
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT6]](s128), [[FRAME_INDEX6]](p0) :: (store (s128) into %stack.6)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.7
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT7]](s128), [[FRAME_INDEX7]](p0) :: (store (s128) into %stack.7)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.8
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT8]](s128), [[FRAME_INDEX8]](p0) :: (store (s128) into %stack.8)
-  ; RV32-ILP32Q-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x2
-  ; RV32-ILP32Q-NEXT:   [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX8]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
-  ; RV32-ILP32Q-NEXT:   $x10 = COPY [[FRAME_INDEX]](p0)
-  ; RV32-ILP32Q-NEXT:   $x11 = COPY [[FRAME_INDEX1]](p0)
-  ; RV32-ILP32Q-NEXT:   $x12 = COPY [[FRAME_INDEX2]](p0)
-  ; RV32-ILP32Q-NEXT:   $x13 = COPY [[FRAME_INDEX3]](p0)
-  ; RV32-ILP32Q-NEXT:   $x14 = COPY [[FRAME_INDEX4]](p0)
-  ; RV32-ILP32Q-NEXT:   $x15 = COPY [[FRAME_INDEX5]](p0)
-  ; RV32-ILP32Q-NEXT:   $x16 = COPY [[FRAME_INDEX6]](p0)
-  ; RV32-ILP32Q-NEXT:   $x17 = COPY [[FRAME_INDEX7]](p0)
-  ; RV32-ILP32Q-NEXT:   PseudoCALL target-flags(riscv-call) @callee_fp128_in_gpr_exhausted_fprs, 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
-  ; 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:   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
@@ -231,46 +195,30 @@ define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
 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
+  ; 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]+]]:_(p0) = COPY $x12
-  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY2]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
-  ; RV32-ILP32Q-NEXT:   [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+  ; 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]+]]:_(p0) = COPY $x15
-  ; RV32-ILP32Q-NEXT:   [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[COPY5]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
-  ; RV32-ILP32Q-NEXT:   [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
+  ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
-  ; RV32-ILP32Q-NEXT:   [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.7, align 16)
-  ; RV32-ILP32Q-NEXT:   [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[LOAD2]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
-  ; RV32-ILP32Q-NEXT:   [[LOAD4:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.6)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
-  ; RV32-ILP32Q-NEXT:   [[LOAD5:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (p0) from %fixed-stack.5, align 8)
-  ; RV32-ILP32Q-NEXT:   [[LOAD6:%[0-9]+]]:_(s128) = G_LOAD [[LOAD5]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
-  ; RV32-ILP32Q-NEXT:   [[LOAD7:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (p0) from %fixed-stack.4)
-  ; RV32-ILP32Q-NEXT:   [[LOAD8:%[0-9]+]]:_(s128) = G_LOAD [[LOAD7]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
-  ; RV32-ILP32Q-NEXT:   [[LOAD9:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (p0) from %fixed-stack.3, align 16)
-  ; RV32-ILP32Q-NEXT:   [[LOAD10:%[0-9]+]]:_(s128) = G_LOAD [[LOAD9]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
-  ; RV32-ILP32Q-NEXT:   [[LOAD11:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (p0) from %fixed-stack.2)
-  ; RV32-ILP32Q-NEXT:   [[LOAD12:%[0-9]+]]:_(s128) = G_LOAD [[LOAD11]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
-  ; RV32-ILP32Q-NEXT:   [[LOAD13:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (p0) from %fixed-stack.1, align 8)
-  ; RV32-ILP32Q-NEXT:   [[LOAD14:%[0-9]+]]:_(s128) = G_LOAD [[LOAD13]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
-  ; RV32-ILP32Q-NEXT:   [[LOAD15:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (p0) from %fixed-stack.0)
-  ; RV32-ILP32Q-NEXT:   [[LOAD16:%[0-9]+]]:_(s128) = G_LOAD [[LOAD15]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[LOAD16]](s128)
-  ; RV32-ILP32Q-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD4]], [[FPTOSI]]
+  ; 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
@@ -303,65 +251,33 @@ define i32 @caller_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind
   ; 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 32, 0, implicit-def $x2, implicit $x2
+  ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
   ; RV32-ILP32Q-NEXT:   [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C10]](s64)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1)
   ; RV32-ILP32Q-NEXT:   [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C11]](s64)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT2]](s128), [[FRAME_INDEX2]](p0) :: (store (s128) into %stack.2)
-  ; 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 [[FRAME_INDEX2]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
-  ; RV32-ILP32Q-NEXT:   [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[C12]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT3]](s128), [[FRAME_INDEX3]](p0) :: (store (s128) into %stack.3)
-  ; RV32-ILP32Q-NEXT:   [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX3]](p0), [[PTR_ADD2]](p0) :: (store (p0) into stack + 8, align 8)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.4
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT4]](s128), [[FRAME_INDEX4]](p0) :: (store (s128) into %stack.4)
-  ; RV32-ILP32Q-NEXT:   [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX4]](p0), [[PTR_ADD3]](p0) :: (store (p0) into stack + 12)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.5
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT5]](s128), [[FRAME_INDEX5]](p0) :: (store (s128) into %stack.5)
-  ; RV32-ILP32Q-NEXT:   [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX5]](p0), [[PTR_ADD4]](p0) :: (store (p0) into stack + 16, align 16)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.6
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT6]](s128), [[FRAME_INDEX6]](p0) :: (store (s128) into %stack.6)
-  ; RV32-ILP32Q-NEXT:   [[C18:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C18]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX6]](p0), [[PTR_ADD5]](p0) :: (store (p0) into stack + 20)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.7
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT7]](s128), [[FRAME_INDEX7]](p0) :: (store (s128) into %stack.7)
-  ; RV32-ILP32Q-NEXT:   [[C19:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C19]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX7]](p0), [[PTR_ADD6]](p0) :: (store (p0) into stack + 24, align 8)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.8
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT8]](s128), [[FRAME_INDEX8]](p0) :: (store (s128) into %stack.8)
-  ; RV32-ILP32Q-NEXT:   [[C20:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C20]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX8]](p0), [[PTR_ADD7]](p0) :: (store (p0) into stack + 28)
+  ; 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:   $x12 = COPY [[FRAME_INDEX]](p0)
-  ; RV32-ILP32Q-NEXT:   $x13 = COPY [[UV2]](s32)
-  ; RV32-ILP32Q-NEXT:   $x14 = COPY [[UV3]](s32)
-  ; RV32-ILP32Q-NEXT:   $x15 = COPY [[FRAME_INDEX1]](p0)
-  ; RV32-ILP32Q-NEXT:   $x16 = COPY [[UV4]](s32)
-  ; RV32-ILP32Q-NEXT:   $x17 = COPY [[UV5]](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 $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
-  ; RV32-ILP32Q-NEXT:   ADJCALLSTACKUP 32, 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:   $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
@@ -383,49 +299,33 @@ define i32 @caller_fp128_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind
 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
+  ; 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]+]]:_(p0) = COPY $x12
-  ; RV32-ILP32Q-NEXT:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY2]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
-  ; RV32-ILP32Q-NEXT:   [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
+  ; 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]+]]:_(p0) = COPY $x15
-  ; RV32-ILP32Q-NEXT:   [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[COPY5]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
-  ; RV32-ILP32Q-NEXT:   [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
+  ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.8
-  ; RV32-ILP32Q-NEXT:   [[LOAD2:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (load (p0) from %fixed-stack.8, align 16)
-  ; RV32-ILP32Q-NEXT:   [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[LOAD2]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
-  ; RV32-ILP32Q-NEXT:   [[LOAD4:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.7, align 8)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
-  ; RV32-ILP32Q-NEXT:   [[LOAD5:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %fixed-stack.6)
-  ; RV32-ILP32Q-NEXT:   [[MV3:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD4]](s32), [[LOAD5]](s32)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
-  ; RV32-ILP32Q-NEXT:   [[LOAD6:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (p0) from %fixed-stack.5, align 16)
-  ; RV32-ILP32Q-NEXT:   [[LOAD7:%[0-9]+]]:_(s128) = G_LOAD [[LOAD6]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
-  ; RV32-ILP32Q-NEXT:   [[LOAD8:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (p0) from %fixed-stack.4)
-  ; RV32-ILP32Q-NEXT:   [[LOAD9:%[0-9]+]]:_(s128) = G_LOAD [[LOAD8]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
-  ; RV32-ILP32Q-NEXT:   [[LOAD10:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (p0) from %fixed-stack.3, align 8)
-  ; RV32-ILP32Q-NEXT:   [[LOAD11:%[0-9]+]]:_(s128) = G_LOAD [[LOAD10]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
-  ; RV32-ILP32Q-NEXT:   [[LOAD12:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (p0) from %fixed-stack.2)
-  ; RV32-ILP32Q-NEXT:   [[LOAD13:%[0-9]+]]:_(s128) = G_LOAD [[LOAD12]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
-  ; RV32-ILP32Q-NEXT:   [[LOAD14:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (p0) from %fixed-stack.1, align 16)
-  ; RV32-ILP32Q-NEXT:   [[LOAD15:%[0-9]+]]:_(s128) = G_LOAD [[LOAD14]](p0) :: (load (s128))
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
-  ; RV32-ILP32Q-NEXT:   [[LOAD16:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX8]](p0) :: (load (p0) from %fixed-stack.0)
-  ; RV32-ILP32Q-NEXT:   [[LOAD17:%[0-9]+]]:_(s128) = G_LOAD [[LOAD16]](p0) :: (load (s128))
+  ; 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 [[LOAD17]](s128)
+  ; 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
@@ -460,67 +360,36 @@ define i32 @caller_fp128_on_stack_exhausted_gprs_fprs() nounwind {
   ; 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 40, 0, implicit-def $x2, implicit $x2
+  ; 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:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0)
   ; RV32-ILP32Q-NEXT:   [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C10]](s64)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT1]](s128), [[FRAME_INDEX1]](p0) :: (store (s128) into %stack.1)
   ; RV32-ILP32Q-NEXT:   [[UV4:%[0-9]+]]:_(s32), [[UV5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C11]](s64)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT2]](s128), [[FRAME_INDEX2]](p0) :: (store (s128) into %stack.2)
+  ; 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:   G_STORE [[FRAME_INDEX2]](p0), [[PTR_ADD]](p0) :: (store (p0) into stack, align 16)
-  ; RV32-ILP32Q-NEXT:   [[UV6:%[0-9]+]]:_(s32), [[UV7:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C12]](s64)
-  ; RV32-ILP32Q-NEXT:   [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[UV6]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 8, align 8)
-  ; RV32-ILP32Q-NEXT:   [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[UV7]](s32), [[PTR_ADD2]](p0) :: (store (s32) into stack + 12)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT3]](s128), [[FRAME_INDEX3]](p0) :: (store (s128) into %stack.3)
-  ; RV32-ILP32Q-NEXT:   [[C16:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX3]](p0), [[PTR_ADD3]](p0) :: (store (p0) into stack + 16, align 16)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.4
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT4]](s128), [[FRAME_INDEX4]](p0) :: (store (s128) into %stack.4)
-  ; RV32-ILP32Q-NEXT:   [[C17:%[0-9]+]]:_(s32) = G_CONSTANT i32 20
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX4]](p0), [[PTR_ADD4]](p0) :: (store (p0) into stack + 20)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.5
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT5]](s128), [[FRAME_INDEX5]](p0) :: (store (s128) into %stack.5)
-  ; RV32-ILP32Q-NEXT:   [[C18:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C18]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX5]](p0), [[PTR_ADD5]](p0) :: (store (p0) into stack + 24, align 8)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.6
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT6]](s128), [[FRAME_INDEX6]](p0) :: (store (s128) into %stack.6)
-  ; RV32-ILP32Q-NEXT:   [[C19:%[0-9]+]]:_(s32) = G_CONSTANT i32 28
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C19]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX6]](p0), [[PTR_ADD6]](p0) :: (store (p0) into stack + 28)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.7
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT7]](s128), [[FRAME_INDEX7]](p0) :: (store (s128) into %stack.7)
-  ; RV32-ILP32Q-NEXT:   [[C20:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C20]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX7]](p0), [[PTR_ADD7]](p0) :: (store (p0) into stack + 32, align 16)
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.8
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FPEXT8]](s128), [[FRAME_INDEX8]](p0) :: (store (s128) into %stack.8)
-  ; RV32-ILP32Q-NEXT:   [[C21:%[0-9]+]]:_(s32) = G_CONSTANT i32 36
-  ; RV32-ILP32Q-NEXT:   [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C21]](s32)
-  ; RV32-ILP32Q-NEXT:   G_STORE [[FRAME_INDEX8]](p0), [[PTR_ADD8]](p0) :: (store (p0) into stack + 36)
+  ; 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:   $x12 = COPY [[FRAME_INDEX]](p0)
-  ; RV32-ILP32Q-NEXT:   $x13 = COPY [[UV2]](s32)
-  ; RV32-ILP32Q-NEXT:   $x14 = COPY [[UV3]](s32)
-  ; RV32-ILP32Q-NEXT:   $x15 = COPY [[FRAME_INDEX1]](p0)
-  ; RV32-ILP32Q-NEXT:   $x16 = COPY [[UV4]](s32)
-  ; RV32-ILP32Q-NEXT:   $x17 = COPY [[UV5]](s32)
-  ; 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 $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
-  ; RV32-ILP32Q-NEXT:   ADJCALLSTACKUP 40, 0, implicit-def $x2, implicit $x2
+  ; 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
@@ -542,13 +411,10 @@ define i32 @caller_fp128_on_stack_exhausted_gprs_fprs() nounwind {
 define fp128 @callee_fp128_ret() nounwind {
   ; RV32-ILP32Q-LABEL: name: callee_fp128_ret
   ; RV32-ILP32Q: bb.1 (%ir-block.0):
-  ; RV32-ILP32Q-NEXT:   liveins: $x10
-  ; RV32-ILP32Q-NEXT: {{  $}}
-  ; RV32-ILP32Q-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x10
   ; 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:   G_STORE [[FPEXT]](s128), [[COPY]](p0) :: (store (s128))
-  ; RV32-ILP32Q-NEXT:   PseudoRET
+  ; 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
 }
@@ -556,13 +422,11 @@ define fp128 @callee_fp128_ret() nounwind {
 define i32 @caller_fp128_ret() nounwind {
   ; RV32-ILP32Q-LABEL: name: caller_fp128_ret
   ; RV32-ILP32Q: bb.1 (%ir-block.0):
-  ; RV32-ILP32Q-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
   ; RV32-ILP32Q-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
-  ; RV32-ILP32Q-NEXT:   $x10 = COPY [[FRAME_INDEX]](p0)
-  ; RV32-ILP32Q-NEXT:   PseudoCALL target-flags(riscv-call) @callee_fp128_ret, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10
+  ; 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:   [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s128) from %stack.0)
-  ; RV32-ILP32Q-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LOAD]](s128)
+  ; 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()
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
index 404a3a383010b..cad9406049b7b 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64q.ll
@@ -9,13 +9,11 @@
 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, $x11, $x12
+  ; RV64I-NEXT:   liveins: $x10, $f10_q
   ; RV64I-NEXT: {{  $}}
   ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
-  ; RV64I-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
-  ; RV64I-NEXT:   [[COPY2:%[0-9]+]]:_(s64) = COPY $x12
-  ; RV64I-NEXT:   [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY1]](s64), [[COPY2]](s64)
-  ; RV64I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[MV]](s128)
+  ; 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
@@ -31,11 +29,9 @@ define i64 @caller_fp128_in_regs() nounwind {
   ; 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:   [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
   ; RV64I-NEXT:   $x10 = COPY [[C1]](s64)
-  ; RV64I-NEXT:   $x11 = COPY [[UV]](s64)
-  ; RV64I-NEXT:   $x12 = COPY [[UV1]](s64)
-  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @callee_fp128_in_regs, csr_ilp32q_lp64q, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
+  ; 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)
@@ -49,7 +45,7 @@ define i64 @caller_fp128_in_regs() nounwind {
 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
+  ; 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
@@ -63,14 +59,10 @@ define i64 @callee_fp128_in_fpr_exhausted_gprs(i128 %a, i128 %b, i128 %c, i128 %
   ; 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.2
-  ; RV64I-NEXT:   [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.2, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
-  ; RV64I-NEXT:   [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %fixed-stack.1, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
-  ; RV64I-NEXT:   [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %fixed-stack.0)
-  ; RV64I-NEXT:   [[MV4:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD1]](s64), [[LOAD2]](s64)
-  ; RV64I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[MV4]](s128)
+  ; 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
@@ -89,7 +81,7 @@ define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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 32, 0, implicit-def $x2, implicit $x2
+  ; 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)
@@ -98,13 +90,6 @@ define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; 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:   [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
-  ; RV64I-NEXT:   [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
-  ; RV64I-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C7]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV8]](s64), [[PTR_ADD1]](p0) :: (store (s64) into stack + 16, align 16)
-  ; RV64I-NEXT:   [[C8:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
-  ; RV64I-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV9]](s64), [[PTR_ADD2]](p0) :: (store (s64) into stack + 24)
   ; RV64I-NEXT:   $x10 = COPY [[UV]](s64)
   ; RV64I-NEXT:   $x11 = COPY [[UV1]](s64)
   ; RV64I-NEXT:   $x12 = COPY [[UV2]](s64)
@@ -113,8 +98,9 @@ define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
   ; RV64I-NEXT:   $x15 = COPY [[UV5]](s64)
   ; RV64I-NEXT:   $x16 = COPY [[UV6]](s64)
   ; RV64I-NEXT:   $x17 = COPY [[UV7]](s64)
-  ; 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-def $x10
-  ; RV64I-NEXT:   ADJCALLSTACKUP 32, 0, implicit-def $x2, implicit $x2
+  ; 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
@@ -128,47 +114,21 @@ define i64 @caller_fp128_in_fpr_exhausted_gprs() nounwind {
 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, $x12, $x13, $x14, $x15, $x16, $x17
+  ; 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]+]]:_(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.9
-  ; RV64I-NEXT:   [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.9, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.8
-  ; RV64I-NEXT:   [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %fixed-stack.8)
-  ; RV64I-NEXT:   [[MV4:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD]](s64), [[LOAD1]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
-  ; RV64I-NEXT:   [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %fixed-stack.7, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
-  ; RV64I-NEXT:   [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (s64) from %fixed-stack.6)
-  ; RV64I-NEXT:   [[MV5:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD2]](s64), [[LOAD3]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
-  ; RV64I-NEXT:   [[LOAD4:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s64) from %fixed-stack.5, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
-  ; RV64I-NEXT:   [[LOAD5:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (s64) from %fixed-stack.4)
-  ; RV64I-NEXT:   [[MV6:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD4]](s64), [[LOAD5]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
-  ; RV64I-NEXT:   [[LOAD6:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (s64) from %fixed-stack.3, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
-  ; RV64I-NEXT:   [[LOAD7:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (s64) from %fixed-stack.2)
-  ; RV64I-NEXT:   [[MV7:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD6]](s64), [[LOAD7]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
-  ; RV64I-NEXT:   [[LOAD8:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX8]](p0) :: (load (s64) from %fixed-stack.1, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX9:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
-  ; RV64I-NEXT:   [[LOAD9:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX9]](p0) :: (load (s64) from %fixed-stack.0)
-  ; RV64I-NEXT:   [[MV8:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD8]](s64), [[LOAD9]](s64)
-  ; RV64I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[MV7]](s128)
-  ; RV64I-NEXT:   [[FPTOSI1:%[0-9]+]]:_(s32) = G_FPTOSI [[MV8]](s128)
+  ; 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)
@@ -200,59 +160,22 @@ define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
   ; 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 80, 0, implicit-def $x2, implicit $x2
-  ; RV64I-NEXT:   [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
-  ; RV64I-NEXT:   [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT1]](s128)
-  ; RV64I-NEXT:   [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT2]](s128)
-  ; RV64I-NEXT:   [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT3]](s128)
-  ; RV64I-NEXT:   [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT4]](s128)
-  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x2
-  ; RV64I-NEXT:   [[C9:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
-  ; RV64I-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV8]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
-  ; RV64I-NEXT:   [[C10:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
-  ; RV64I-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C10]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV9]](s64), [[PTR_ADD1]](p0) :: (store (s64) into stack + 8)
-  ; RV64I-NEXT:   [[UV10:%[0-9]+]]:_(s64), [[UV11:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT5]](s128)
-  ; RV64I-NEXT:   [[C11:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
-  ; RV64I-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C11]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV10]](s64), [[PTR_ADD2]](p0) :: (store (s64) into stack + 16, align 16)
-  ; RV64I-NEXT:   [[C12:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
-  ; RV64I-NEXT:   [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C12]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV11]](s64), [[PTR_ADD3]](p0) :: (store (s64) into stack + 24)
-  ; RV64I-NEXT:   [[UV12:%[0-9]+]]:_(s64), [[UV13:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT6]](s128)
-  ; RV64I-NEXT:   [[C13:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
-  ; RV64I-NEXT:   [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C13]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV12]](s64), [[PTR_ADD4]](p0) :: (store (s64) into stack + 32, align 16)
-  ; RV64I-NEXT:   [[C14:%[0-9]+]]:_(s64) = G_CONSTANT i64 40
-  ; RV64I-NEXT:   [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV13]](s64), [[PTR_ADD5]](p0) :: (store (s64) into stack + 40)
-  ; RV64I-NEXT:   [[UV14:%[0-9]+]]:_(s64), [[UV15:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT7]](s128)
-  ; RV64I-NEXT:   [[C15:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
-  ; RV64I-NEXT:   [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV14]](s64), [[PTR_ADD6]](p0) :: (store (s64) into stack + 48, align 16)
-  ; RV64I-NEXT:   [[C16:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
-  ; RV64I-NEXT:   [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV15]](s64), [[PTR_ADD7]](p0) :: (store (s64) into stack + 56)
-  ; RV64I-NEXT:   [[UV16:%[0-9]+]]:_(s64), [[UV17:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT8]](s128)
-  ; RV64I-NEXT:   [[C17:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
-  ; RV64I-NEXT:   [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV16]](s64), [[PTR_ADD8]](p0) :: (store (s64) into stack + 64, align 16)
-  ; RV64I-NEXT:   [[C18:%[0-9]+]]:_(s64) = G_CONSTANT i64 72
-  ; RV64I-NEXT:   [[PTR_ADD9:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C18]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV17]](s64), [[PTR_ADD9]](p0) :: (store (s64) into stack + 72)
+  ; 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:   $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:   PseudoCALL target-flags(riscv-call) @callee_fp128_in_gpr_exhausted_fprs, 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
-  ; RV64I-NEXT:   ADJCALLSTACKUP 80, 0, implicit-def $x2, implicit $x2
-  ; RV64I-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY $x10
-  ; RV64I-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](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
@@ -275,67 +198,32 @@ define i32 @caller_fp128_in_gpr_exhausted_fprs() nounwind {
 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
+  ; 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]+]]:_(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.17
-  ; RV64I-NEXT:   [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %fixed-stack.17, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.16
-  ; RV64I-NEXT:   [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %fixed-stack.16)
-  ; RV64I-NEXT:   [[MV4:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD]](s64), [[LOAD1]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.15
-  ; RV64I-NEXT:   [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %fixed-stack.15, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.14
-  ; RV64I-NEXT:   [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX3]](p0) :: (load (s64) from %fixed-stack.14)
-  ; RV64I-NEXT:   [[MV5:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD2]](s64), [[LOAD3]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.13
-  ; RV64I-NEXT:   [[LOAD4:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s64) from %fixed-stack.13, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.12
-  ; RV64I-NEXT:   [[LOAD5:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX5]](p0) :: (load (s64) from %fixed-stack.12)
-  ; RV64I-NEXT:   [[MV6:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD4]](s64), [[LOAD5]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX6:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.11
-  ; RV64I-NEXT:   [[LOAD6:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX6]](p0) :: (load (s64) from %fixed-stack.11, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX7:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.10
-  ; RV64I-NEXT:   [[LOAD7:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX7]](p0) :: (load (s64) from %fixed-stack.10)
-  ; RV64I-NEXT:   [[MV7:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD6]](s64), [[LOAD7]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX8:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.9
-  ; RV64I-NEXT:   [[LOAD8:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX8]](p0) :: (load (s64) from %fixed-stack.9, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX9:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.8
-  ; RV64I-NEXT:   [[LOAD9:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX9]](p0) :: (load (s64) from %fixed-stack.8)
-  ; RV64I-NEXT:   [[MV8:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD8]](s64), [[LOAD9]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX10:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.7
-  ; RV64I-NEXT:   [[LOAD10:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX10]](p0) :: (load (s64) from %fixed-stack.7, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX11:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.6
-  ; RV64I-NEXT:   [[LOAD11:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX11]](p0) :: (load (s64) from %fixed-stack.6)
-  ; RV64I-NEXT:   [[MV9:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD10]](s64), [[LOAD11]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX12:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.5
-  ; RV64I-NEXT:   [[LOAD12:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX12]](p0) :: (load (s64) from %fixed-stack.5, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX13:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.4
-  ; RV64I-NEXT:   [[LOAD13:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX13]](p0) :: (load (s64) from %fixed-stack.4)
-  ; RV64I-NEXT:   [[MV10:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD12]](s64), [[LOAD13]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX14:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.3
-  ; RV64I-NEXT:   [[LOAD14:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX14]](p0) :: (load (s64) from %fixed-stack.3, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX15:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.2
-  ; RV64I-NEXT:   [[LOAD15:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX15]](p0) :: (load (s64) from %fixed-stack.2)
-  ; RV64I-NEXT:   [[MV11:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD14]](s64), [[LOAD15]](s64)
-  ; RV64I-NEXT:   [[FRAME_INDEX16:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
-  ; RV64I-NEXT:   [[LOAD16:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX16]](p0) :: (load (s64) from %fixed-stack.1, align 16)
-  ; RV64I-NEXT:   [[FRAME_INDEX17:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
-  ; RV64I-NEXT:   [[LOAD17:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX17]](p0) :: (load (s64) from %fixed-stack.0)
-  ; RV64I-NEXT:   [[MV12:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[LOAD16]](s64), [[LOAD17]](s64)
-  ; RV64I-NEXT:   [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[MV6]](s128)
-  ; RV64I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s64) = G_FPTOSI [[MV12]](s128)
+  ; 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
@@ -370,85 +258,33 @@ define i64 @caller_fp128_on_stack_exhausted_gprs_fprs() nounwind {
   ; 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 144, 0, implicit-def $x2, implicit $x2
+  ; 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 [[FPEXT]](s128)
-  ; RV64I-NEXT:   [[UV4:%[0-9]+]]:_(s64), [[UV5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C10]](s128)
-  ; RV64I-NEXT:   [[UV6:%[0-9]+]]:_(s64), [[UV7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT1]](s128)
-  ; RV64I-NEXT:   [[UV8:%[0-9]+]]:_(s64), [[UV9:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C11]](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 [[UV8]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 16)
-  ; RV64I-NEXT:   [[C14:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
-  ; RV64I-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C14]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV9]](s64), [[PTR_ADD1]](p0) :: (store (s64) into stack + 8)
-  ; RV64I-NEXT:   [[UV10:%[0-9]+]]:_(s64), [[UV11:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT2]](s128)
-  ; RV64I-NEXT:   [[C15:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
-  ; RV64I-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C15]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV10]](s64), [[PTR_ADD2]](p0) :: (store (s64) into stack + 16, align 16)
-  ; RV64I-NEXT:   [[C16:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
-  ; RV64I-NEXT:   [[PTR_ADD3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C16]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV11]](s64), [[PTR_ADD3]](p0) :: (store (s64) into stack + 24)
-  ; RV64I-NEXT:   [[UV12:%[0-9]+]]:_(s64), [[UV13:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[C12]](s128)
-  ; RV64I-NEXT:   [[C17:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
-  ; RV64I-NEXT:   [[PTR_ADD4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C17]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV12]](s64), [[PTR_ADD4]](p0) :: (store (s64) into stack + 32, align 16)
-  ; RV64I-NEXT:   [[C18:%[0-9]+]]:_(s64) = G_CONSTANT i64 40
-  ; RV64I-NEXT:   [[PTR_ADD5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C18]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV13]](s64), [[PTR_ADD5]](p0) :: (store (s64) into stack + 40)
-  ; RV64I-NEXT:   [[UV14:%[0-9]+]]:_(s64), [[UV15:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT3]](s128)
-  ; RV64I-NEXT:   [[C19:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
-  ; RV64I-NEXT:   [[PTR_ADD6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C19]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV14]](s64), [[PTR_ADD6]](p0) :: (store (s64) into stack + 48, align 16)
-  ; RV64I-NEXT:   [[C20:%[0-9]+]]:_(s64) = G_CONSTANT i64 56
-  ; RV64I-NEXT:   [[PTR_ADD7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C20]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV15]](s64), [[PTR_ADD7]](p0) :: (store (s64) into stack + 56)
-  ; RV64I-NEXT:   [[UV16:%[0-9]+]]:_(s64), [[UV17:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT4]](s128)
-  ; RV64I-NEXT:   [[C21:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
-  ; RV64I-NEXT:   [[PTR_ADD8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C21]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV16]](s64), [[PTR_ADD8]](p0) :: (store (s64) into stack + 64, align 16)
-  ; RV64I-NEXT:   [[C22:%[0-9]+]]:_(s64) = G_CONSTANT i64 72
-  ; RV64I-NEXT:   [[PTR_ADD9:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C22]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV17]](s64), [[PTR_ADD9]](p0) :: (store (s64) into stack + 72)
-  ; RV64I-NEXT:   [[UV18:%[0-9]+]]:_(s64), [[UV19:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT5]](s128)
-  ; RV64I-NEXT:   [[C23:%[0-9]+]]:_(s64) = G_CONSTANT i64 80
-  ; RV64I-NEXT:   [[PTR_ADD10:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C23]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV18]](s64), [[PTR_ADD10]](p0) :: (store (s64) into stack + 80, align 16)
-  ; RV64I-NEXT:   [[C24:%[0-9]+]]:_(s64) = G_CONSTANT i64 88
-  ; RV64I-NEXT:   [[PTR_ADD11:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C24]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV19]](s64), [[PTR_ADD11]](p0) :: (store (s64) into stack + 88)
-  ; RV64I-NEXT:   [[UV20:%[0-9]+]]:_(s64), [[UV21:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT6]](s128)
-  ; RV64I-NEXT:   [[C25:%[0-9]+]]:_(s64) = G_CONSTANT i64 96
-  ; RV64I-NEXT:   [[PTR_ADD12:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C25]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV20]](s64), [[PTR_ADD12]](p0) :: (store (s64) into stack + 96, align 16)
-  ; RV64I-NEXT:   [[C26:%[0-9]+]]:_(s64) = G_CONSTANT i64 104
-  ; RV64I-NEXT:   [[PTR_ADD13:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C26]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV21]](s64), [[PTR_ADD13]](p0) :: (store (s64) into stack + 104)
-  ; RV64I-NEXT:   [[UV22:%[0-9]+]]:_(s64), [[UV23:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT7]](s128)
-  ; RV64I-NEXT:   [[C27:%[0-9]+]]:_(s64) = G_CONSTANT i64 112
-  ; RV64I-NEXT:   [[PTR_ADD14:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C27]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV22]](s64), [[PTR_ADD14]](p0) :: (store (s64) into stack + 112, align 16)
-  ; RV64I-NEXT:   [[C28:%[0-9]+]]:_(s64) = G_CONSTANT i64 120
-  ; RV64I-NEXT:   [[PTR_ADD15:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C28]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV23]](s64), [[PTR_ADD15]](p0) :: (store (s64) into stack + 120)
-  ; RV64I-NEXT:   [[UV24:%[0-9]+]]:_(s64), [[UV25:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT8]](s128)
-  ; RV64I-NEXT:   [[C29:%[0-9]+]]:_(s64) = G_CONSTANT i64 128
-  ; RV64I-NEXT:   [[PTR_ADD16:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C29]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV24]](s64), [[PTR_ADD16]](p0) :: (store (s64) into stack + 128, align 16)
-  ; RV64I-NEXT:   [[C30:%[0-9]+]]:_(s64) = G_CONSTANT i64 136
-  ; RV64I-NEXT:   [[PTR_ADD17:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C30]](s64)
-  ; RV64I-NEXT:   G_STORE [[UV25]](s64), [[PTR_ADD17]](p0) :: (store (s64) into stack + 136)
+  ; 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:   PseudoCALL target-flags(riscv-call) @callee_fp128_on_stack_exhausted_gprs_fprs, 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
-  ; RV64I-NEXT:   ADJCALLSTACKUP 144, 0, implicit-def $x2, implicit $x2
+  ; 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
@@ -472,10 +308,8 @@ define fp128 @callee_fp128_ret() nounwind {
   ; 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:   [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[FPEXT]](s128)
-  ; RV64I-NEXT:   $x10 = COPY [[UV]](s64)
-  ; RV64I-NEXT:   $x11 = COPY [[UV1]](s64)
-  ; RV64I-NEXT:   PseudoRET implicit $x10, implicit $x11
+  ; RV64I-NEXT:   $f10_q = COPY [[FPEXT]](s128)
+  ; RV64I-NEXT:   PseudoRET implicit $f10_q
   %1 = fpext double 1.0 to fp128
   ret fp128 %1
 }
@@ -484,12 +318,10 @@ 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 $x10, implicit-def $x11
+  ; 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]+]]:_(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:   [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV]](s128)
+  ; 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

>From 4243ed608e06906684a07e154c3008da85f3357a Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Thu, 7 May 2026 18:54:06 +0200
Subject: [PATCH 08/12] Basic code gen

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   | 151 +++++++++++++++++-
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp      |   4 +
 llvm/lib/Target/RISCV/RISCVInstrInfoQ.td      |  42 +++++
 .../Target/RISCV/RISCVMachineFunctionInfo.h   |   8 +
 4 files changed, 199 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index f178513f9b589..c6a1e4ea5c2f5 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -759,7 +759,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::SELECT, MVT::f64, Custom);
     setOperationAction(ISD::BR_CC, MVT::f64, Expand);
     setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
+    // TODO: Check if needed for lp64q
+    //setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f64, Expand);
     setTruncStoreAction(MVT::f64, MVT::f32, Expand);
+    // TODO: Check if needed for lp64q
+    //setTruncStoreAction(MVT::f128, MVT::f64, Expand);
     setOperationAction(FPOpToExpand, MVT::f64, Expand);
     setOperationAction(FPOpToLibCall, MVT::f64, LibCall);
     setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
@@ -23202,6 +23206,91 @@ static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
   return BB;
 }
 
+static MachineBasicBlock *emitSplitF128Pseudo(MachineInstr &MI,
+                                             MachineBasicBlock *BB,
+                                             const RISCVSubtarget &Subtarget) {
+  assert(MI.getOpcode() == RISCV::SplitF128Pseudo && "Unexpected instruction");
+
+  MachineFunction &MF = *BB->getParent();
+  DebugLoc DL = MI.getDebugLoc();
+  const RISCVInstrInfo &TII = *MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
+  Register LoReg = MI.getOperand(0).getReg();
+  Register HiReg = MI.getOperand(1).getReg();
+  Register SrcReg = MI.getOperand(2).getReg();
+
+  const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass;
+  int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF128FrameIndex(MF);
+
+  TII.storeRegToStackSlot(*BB, MI, SrcReg, MI.getOperand(2).isKill(), FI, SrcRC,
+                          Register());
+  MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI);
+  MachineMemOperand *MMOLo =
+      MF.getMachineMemOperand(MPI, MachineMemOperand::MOLoad, 8, Align(16));
+  MachineMemOperand *MMOHi = MF.getMachineMemOperand(
+      MPI.getWithOffset(8), MachineMemOperand::MOLoad, 8, Align(16));
+
+  // For big-endian, the high part is at offset 0 and the low part at offset 4.
+  if (!Subtarget.isLittleEndian())
+    std::swap(LoReg, HiReg);
+
+  BuildMI(*BB, MI, DL, TII.get(RISCV::LD), LoReg)
+      .addFrameIndex(FI)
+      .addImm(0)
+      .addMemOperand(MMOLo);
+  BuildMI(*BB, MI, DL, TII.get(RISCV::LD), HiReg)
+      .addFrameIndex(FI)
+      .addImm(8)
+      .addMemOperand(MMOHi);
+  MI.eraseFromParent(); // The pseudo instruction is gone now.
+  return BB;
+}
+
+static MachineBasicBlock *emitBuildPairF128Pseudo(MachineInstr &MI,
+                                                 MachineBasicBlock *BB,
+                                                 const RISCVSubtarget &Subtarget) {
+  assert(MI.getOpcode() == RISCV::BuildPairF128Pseudo &&
+         "Unexpected instruction");
+
+  MachineFunction &MF = *BB->getParent();
+  DebugLoc DL = MI.getDebugLoc();
+  const RISCVInstrInfo &TII = *MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
+  Register DstReg = MI.getOperand(0).getReg();
+  Register LoReg = MI.getOperand(1).getReg();
+  Register HiReg = MI.getOperand(2).getReg();
+  bool KillLo = MI.getOperand(1).isKill();
+  bool KillHi = MI.getOperand(2).isKill();
+
+  const TargetRegisterClass *DstRC = &RISCV::FPR128RegClass;
+  int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF128FrameIndex(MF);
+
+  MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI);
+  MachineMemOperand *MMOLo =
+      MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 8, Align(16));
+  MachineMemOperand *MMOHi = MF.getMachineMemOperand(
+      MPI.getWithOffset(8), MachineMemOperand::MOStore, 8, Align(16));
+
+  // For big-endian, store the high part at offset 0 and the low part at
+  // offset 4.
+  if (!Subtarget.isLittleEndian()) {
+    std::swap(LoReg, HiReg);
+    std::swap(KillLo, KillHi);
+  }
+
+  BuildMI(*BB, MI, DL, TII.get(RISCV::SD))
+      .addReg(LoReg, getKillRegState(KillLo))
+      .addFrameIndex(FI)
+      .addImm(0)
+      .addMemOperand(MMOLo);
+  BuildMI(*BB, MI, DL, TII.get(RISCV::SD))
+      .addReg(HiReg, getKillRegState(KillHi))
+      .addFrameIndex(FI)
+      .addImm(8)
+      .addMemOperand(MMOHi);
+  TII.loadRegFromStackSlot(*BB, MI, DstReg, FI, DstRC, Register());
+  MI.eraseFromParent(); // The pseudo instruction is gone now.
+  return BB;
+}
+
 static MachineBasicBlock *emitQuietFCMP(MachineInstr &MI, MachineBasicBlock *BB,
                                         unsigned RelOpcode, unsigned EqOpcode,
                                         const RISCVSubtarget &Subtarget) {
@@ -23734,6 +23823,10 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
     return emitBuildPairF64Pseudo(MI, BB, Subtarget);
   case RISCV::SplitF64Pseudo:
     return emitSplitF64Pseudo(MI, BB, Subtarget);
+  case RISCV::BuildPairF128Pseudo:
+    return emitBuildPairF128Pseudo(MI, BB, Subtarget);
+  case RISCV::SplitF128Pseudo:
+    return emitSplitF128Pseudo(MI, BB, Subtarget);
   case RISCV::PseudoQuietFLE_H:
     return emitQuietFCMP(MI, BB, RISCV::FLE_H, RISCV::FEQ_H, Subtarget);
   case RISCV::PseudoQuietFLE_H_INX:
@@ -23847,6 +23940,7 @@ static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
       return DAG.getNode(RISCVISD::FMV_W_X_RV64, DL, MVT::f32, Val);
     if (VA.getValVT().isFixedLengthVector() && VA.getLocVT().isScalableVector())
       return convertFromScalableVector(VA.getValVT(), Val, DAG, Subtarget);
+    DAG.dumpDotGraph("/tmp/sdag.dot","SDag");
     llvm_unreachable("Unexpected Custom handling.");
   }
 
@@ -23985,6 +24079,44 @@ static SDValue unpackF64OnRV32DSoftABI(SelectionDAG &DAG, SDValue Chain,
   return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
 }
 
+static SDValue unpackF128OnRV64DSoftABI(SelectionDAG &DAG, SDValue Chain,
+                                       const CCValAssign &VA,
+                                       const CCValAssign &HiVA,
+                                       const SDLoc &DL) {
+  assert(VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f128 &&
+         "Unexpected VA");
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  MachineRegisterInfo &RegInfo = MF.getRegInfo();
+
+  assert(VA.isRegLoc() && "Expected register VA assignment");
+
+  Register LoVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
+  RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
+  SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i64);
+  SDValue Hi;
+  if (HiVA.isMemLoc()) {
+    // Second half of f64 is passed on the stack.
+    int FI = MFI.CreateFixedObject(4, HiVA.getLocMemOffset(),
+                                   /*IsImmutable=*/true);
+    SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
+    Hi = DAG.getLoad(MVT::i64, DL, Chain, FIN,
+                     MachinePointerInfo::getFixedStack(MF, FI));
+  } else {
+    // Second half of f64 is passed in another GPR.
+    Register HiVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
+    RegInfo.addLiveIn(HiVA.getLocReg(), HiVReg);
+    Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i64);
+  }
+
+  // For big-endian, swap the order of Lo and Hi when building the pair.
+  const RISCVSubtarget &Subtarget = DAG.getSubtarget<RISCVSubtarget>();
+  if (!Subtarget.isLittleEndian())
+    std::swap(Lo, Hi);
+
+  return DAG.getNode(RISCVISD::BuildPairF128, DL, MVT::f128, Lo, Hi);
+}
+
 // Transform physical registers into virtual registers.
 SDValue RISCVTargetLowering::LowerFormalArguments(
     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
@@ -24080,10 +24212,14 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
     SDValue ArgValue;
     // Passing f64 on RV32D with a soft float ABI must be handled as a special
     // case.
+    // unpackF128OnRV64DSoftABI
     if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
       assert(VA.needsCustom());
       ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, ArgLocs[++i], DL);
-    } else if (VA.isRegLoc())
+    } else if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f128) {
+      assert(VA.needsCustom());
+      ArgValue = unpackF128OnRV64DSoftABI(DAG, Chain, VA, ArgLocs[++i], DL);
+    }else if (VA.isRegLoc())
       ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, Ins[InsIdx], *this);
     else
       ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL, *this);
@@ -24633,12 +24769,15 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
     CCValAssign &VA = RVLocs[i];
     assert(VA.isRegLoc() && "Can only return in registers!");
 
-    if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
+    const MVT &LocVT = VA.getLocVT();
+    const MVT &ValVT = VA.getValVT();
+    if ((LocVT == MVT::i32 && ValVT == MVT::f64) || (LocVT == MVT::i64 && ValVT == MVT::f128)) {
       // Handle returning f64 on RV32D with a soft float ABI.
       assert(VA.isRegLoc() && "Expected return via registers");
       assert(VA.needsCustom());
-      SDValue SplitF64 = DAG.getNode(RISCVISD::SplitF64, DL,
-                                     DAG.getVTList(MVT::i32, MVT::i32), Val);
+      auto SplitNode = ValVT == MVT::f64 ? RISCVISD::SplitF64 : RISCVISD::SplitF128;
+      SDValue SplitF64 = DAG.getNode(SplitNode, DL,
+                                     DAG.getVTList(LocVT, LocVT), Val);
       SDValue Lo = SplitF64.getValue(0);
       SDValue Hi = SplitF64.getValue(1);
 
@@ -24657,10 +24796,10 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
 
       Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);
       Glue = Chain.getValue(1);
-      RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));
+      RetOps.push_back(DAG.getRegister(RegLo, LocVT));
       Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue);
       Glue = Chain.getValue(1);
-      RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));
+      RetOps.push_back(DAG.getRegister(RegHi, LocVT));
     } else {
       // Handle a 'normal' return.
       Val = convertValVTToLocVT(DAG, Val, VA, DL, Subtarget);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 93512842712df..6a91da0215a3c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -689,6 +689,8 @@ void RISCVInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
     Opcode = RISCV::FSW;
   } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::FSD;
+  } else if (RISCV::FPR128RegClass.hasSubClassEq(RC)) {
+    Opcode = RISCV::FSQ;
   } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::VS1R_V;
   } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
@@ -781,6 +783,8 @@ void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
     Opcode = RISCV::FLW;
   } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::FLD;
+  } else if (RISCV::FPR128RegClass.hasSubClassEq(RC)) {
+    Opcode = RISCV::FLQ;
   } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
     Opcode = RISCV::VL1RE8_V;
   } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoQ.td b/llvm/lib/Target/RISCV/RISCVInstrInfoQ.td
index da78c13c0edcc..90a018b238e63 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoQ.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoQ.td
@@ -20,6 +20,16 @@ def QExt : ExtInfo<"", "", [HasStdExtQ], f128, FPR128, FPR32, FPR64, ?>;
 defvar QExts = [QExt];
 defvar QExtsRV64 = [QExt];
 
+def SDT_RISCVBuildPairF128 : SDTypeProfile<1, 2, [SDTCisVT<0, f128>,
+                                                  SDTCisVT<1, i64>,
+                                                  SDTCisSameAs<1, 2>]>;
+def SDT_RISCVSplitF128     : SDTypeProfile<2, 1, [SDTCisVT<0, i64>,
+                                                  SDTCisVT<1, i64>,
+                                                  SDTCisVT<2, f128>]>;
+
+def RISCVBuildPairF128 : SDNode<"RISCVISD::BuildPairF128", SDT_RISCVBuildPairF128>;
+def RISCVSplitF128     : SDNode<"RISCVISD::SplitF128", SDT_RISCVSplitF128>;
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -165,3 +175,35 @@ let Predicates = [HasStdExtQ] in {
   def PseudoFLQ : PseudoFloatLoad<"flq", FPR128>;
   def PseudoFSQ : PseudoStore<"fsq", FPR128>;
 } // Predicates = [HasStdExtQ]
+
+let Predicates = [HasStdExtQ] in {
+// Moves two GPRs to an FPR.
+let usesCustomInserter = 1 in
+def BuildPairF128Pseudo
+    : Pseudo<(outs FPR128:$dst), (ins GPR:$src1, GPR:$src2),
+             [(set FPR128:$dst, (RISCVBuildPairF128 GPR:$src1, GPR:$src2))]>;
+
+// Moves an FPR to two GPRs.
+let usesCustomInserter = 1 in
+def SplitF128Pseudo
+    : Pseudo<(outs GPR:$dst1, GPR:$dst2), (ins FPR128:$src),
+             [(set GPR:$dst1, GPR:$dst2, (RISCVSplitF128 FPR128:$src))]>;
+
+foreach Ext = QExts in {
+  defm : PatFprFprDynFrm_m<any_fadd, FADD_Q, Ext>;
+  defm : PatFprFprDynFrm_m<any_fsub, FSUB_Q, Ext>;
+  defm : PatFprFprDynFrm_m<any_fmul, FMUL_Q, Ext>;
+  defm : PatFprFprDynFrm_m<any_fdiv, FDIV_Q, Ext>;
+}
+
+} // Predicates = [HasStdExtQ]
+
+let Predicates = [HasStdExtQ] in {
+/// Loads
+
+def : LdPat<load, FLQ, f128>;
+
+/// Stores
+
+def : StPat<store, FSQ, FPR128, f128>;
+} // Predicates = [HasStdExtQ]
diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
index 854f2714d9599..55f3143258972 100644
--- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
@@ -53,6 +53,7 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo {
   /// FrameIndex used for transferring values between 64-bit FPRs and a pair
   /// of 32-bit GPRs via the stack.
   int MoveF64FrameIndex = -1;
+  int MoveF128FrameIndex = -1;
   /// FrameIndex of the spill slot for the scratch register in BranchRelaxation.
   int BranchRelaxationScratchFrameIndex = -1;
   /// Size of any opaque stack adjustment due to save/restore libcalls.
@@ -110,6 +111,13 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo {
     return MoveF64FrameIndex;
   }
 
+  int getMoveF128FrameIndex(MachineFunction &MF) {
+    if (MoveF128FrameIndex == -1)
+      MoveF128FrameIndex =
+          MF.getFrameInfo().CreateStackObject(16, Align(16), false);
+    return MoveF128FrameIndex;
+  }
+
   int getBranchRelaxationScratchFrameIndex() const {
     return BranchRelaxationScratchFrameIndex;
   }

>From ff3032d4568db396fd19ce6bac6c21b0601620ec Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Thu, 7 May 2026 19:16:42 +0200
Subject: [PATCH 09/12] Generalize builds

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 164 ++++++--------------
 1 file changed, 51 insertions(+), 113 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c6a1e4ea5c2f5..83baaaaefd88d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -23121,96 +23121,15 @@ static MachineBasicBlock *emitReadCounterWidePseudo(MachineInstr &MI,
   return DoneMBB;
 }
 
-static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
-                                             MachineBasicBlock *BB,
-                                             const RISCVSubtarget &Subtarget) {
-  assert(MI.getOpcode() == RISCV::SplitF64Pseudo && "Unexpected instruction");
-
-  MachineFunction &MF = *BB->getParent();
-  DebugLoc DL = MI.getDebugLoc();
-  const RISCVInstrInfo &TII = *MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
-  Register LoReg = MI.getOperand(0).getReg();
-  Register HiReg = MI.getOperand(1).getReg();
-  Register SrcReg = MI.getOperand(2).getReg();
-
-  const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass;
-  int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
-
-  TII.storeRegToStackSlot(*BB, MI, SrcReg, MI.getOperand(2).isKill(), FI, SrcRC,
-                          Register());
-  MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI);
-  MachineMemOperand *MMOLo =
-      MF.getMachineMemOperand(MPI, MachineMemOperand::MOLoad, 4, Align(8));
-  MachineMemOperand *MMOHi = MF.getMachineMemOperand(
-      MPI.getWithOffset(4), MachineMemOperand::MOLoad, 4, Align(8));
-
-  // For big-endian, the high part is at offset 0 and the low part at offset 4.
-  if (!Subtarget.isLittleEndian())
-    std::swap(LoReg, HiReg);
-
-  BuildMI(*BB, MI, DL, TII.get(RISCV::LW), LoReg)
-      .addFrameIndex(FI)
-      .addImm(0)
-      .addMemOperand(MMOLo);
-  BuildMI(*BB, MI, DL, TII.get(RISCV::LW), HiReg)
-      .addFrameIndex(FI)
-      .addImm(4)
-      .addMemOperand(MMOHi);
-  MI.eraseFromParent(); // The pseudo instruction is gone now.
-  return BB;
-}
-
-static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
-                                                 MachineBasicBlock *BB,
-                                                 const RISCVSubtarget &Subtarget) {
-  assert(MI.getOpcode() == RISCV::BuildPairF64Pseudo &&
+static MachineBasicBlock *
+emitSplitF2XLenPseudo(MachineInstr &MI, MachineBasicBlock *BB,
+                      const RISCVSubtarget &Subtarget) {
+  unsigned XLen = Subtarget.getXLen();
+  assert(((MI.getOpcode() == RISCV::SplitF64Pseudo && XLen == 32) ||
+          (MI.getOpcode() == RISCV::SplitF128Pseudo && XLen == 64)) &&
          "Unexpected instruction");
 
-  MachineFunction &MF = *BB->getParent();
-  DebugLoc DL = MI.getDebugLoc();
-  const RISCVInstrInfo &TII = *MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
-  Register DstReg = MI.getOperand(0).getReg();
-  Register LoReg = MI.getOperand(1).getReg();
-  Register HiReg = MI.getOperand(2).getReg();
-  bool KillLo = MI.getOperand(1).isKill();
-  bool KillHi = MI.getOperand(2).isKill();
-
-  const TargetRegisterClass *DstRC = &RISCV::FPR64RegClass;
-  int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
-
-  MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI);
-  MachineMemOperand *MMOLo =
-      MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 4, Align(8));
-  MachineMemOperand *MMOHi = MF.getMachineMemOperand(
-      MPI.getWithOffset(4), MachineMemOperand::MOStore, 4, Align(8));
-
-  // For big-endian, store the high part at offset 0 and the low part at
-  // offset 4.
-  if (!Subtarget.isLittleEndian()) {
-    std::swap(LoReg, HiReg);
-    std::swap(KillLo, KillHi);
-  }
-
-  BuildMI(*BB, MI, DL, TII.get(RISCV::SW))
-      .addReg(LoReg, getKillRegState(KillLo))
-      .addFrameIndex(FI)
-      .addImm(0)
-      .addMemOperand(MMOLo);
-  BuildMI(*BB, MI, DL, TII.get(RISCV::SW))
-      .addReg(HiReg, getKillRegState(KillHi))
-      .addFrameIndex(FI)
-      .addImm(4)
-      .addMemOperand(MMOHi);
-  TII.loadRegFromStackSlot(*BB, MI, DstReg, FI, DstRC, Register());
-  MI.eraseFromParent(); // The pseudo instruction is gone now.
-  return BB;
-}
-
-static MachineBasicBlock *emitSplitF128Pseudo(MachineInstr &MI,
-                                             MachineBasicBlock *BB,
-                                             const RISCVSubtarget &Subtarget) {
-  assert(MI.getOpcode() == RISCV::SplitF128Pseudo && "Unexpected instruction");
-
+  unsigned XLenInBytes = XLen / 8;
   MachineFunction &MF = *BB->getParent();
   DebugLoc DL = MI.getDebugLoc();
   const RISCVInstrInfo &TII = *MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
@@ -23218,39 +23137,51 @@ static MachineBasicBlock *emitSplitF128Pseudo(MachineInstr &MI,
   Register HiReg = MI.getOperand(1).getReg();
   Register SrcReg = MI.getOperand(2).getReg();
 
-  const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass;
-  int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF128FrameIndex(MF);
+  const TargetRegisterClass *SrcRC = nullptr;
+  int FI = 0;
+  if (XLen == 32) {
+    SrcRC = &RISCV::FPR64RegClass;
+    FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
+  } else {
+    SrcRC = &RISCV::FPR128RegClass;
+    FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF128FrameIndex(MF);
+  }
 
   TII.storeRegToStackSlot(*BB, MI, SrcReg, MI.getOperand(2).isKill(), FI, SrcRC,
                           Register());
   MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI);
-  MachineMemOperand *MMOLo =
-      MF.getMachineMemOperand(MPI, MachineMemOperand::MOLoad, 8, Align(16));
+  MachineMemOperand *MMOLo = MF.getMachineMemOperand(
+      MPI, MachineMemOperand::MOLoad, XLenInBytes, Align(XLenInBytes * 2));
   MachineMemOperand *MMOHi = MF.getMachineMemOperand(
-      MPI.getWithOffset(8), MachineMemOperand::MOLoad, 8, Align(16));
+      MPI.getWithOffset(XLenInBytes), MachineMemOperand::MOLoad, XLenInBytes,
+      Align(XLenInBytes * 2));
 
   // For big-endian, the high part is at offset 0 and the low part at offset 4.
   if (!Subtarget.isLittleEndian())
     std::swap(LoReg, HiReg);
 
-  BuildMI(*BB, MI, DL, TII.get(RISCV::LD), LoReg)
+  auto LoadOpCode = XLen == 32 ? RISCV::LW : RISCV::LD;
+  BuildMI(*BB, MI, DL, TII.get(LoadOpCode), LoReg)
       .addFrameIndex(FI)
       .addImm(0)
       .addMemOperand(MMOLo);
-  BuildMI(*BB, MI, DL, TII.get(RISCV::LD), HiReg)
+  BuildMI(*BB, MI, DL, TII.get(LoadOpCode), HiReg)
       .addFrameIndex(FI)
-      .addImm(8)
+      .addImm(XLenInBytes)
       .addMemOperand(MMOHi);
   MI.eraseFromParent(); // The pseudo instruction is gone now.
   return BB;
 }
 
-static MachineBasicBlock *emitBuildPairF128Pseudo(MachineInstr &MI,
-                                                 MachineBasicBlock *BB,
-                                                 const RISCVSubtarget &Subtarget) {
-  assert(MI.getOpcode() == RISCV::BuildPairF128Pseudo &&
+static MachineBasicBlock *
+emitBuildPairF2XLenPseudo(MachineInstr &MI, MachineBasicBlock *BB,
+                          const RISCVSubtarget &Subtarget) {
+  unsigned XLen = Subtarget.getXLen();
+  assert(((MI.getOpcode() == RISCV::BuildPairF64Pseudo && XLen == 32) ||
+          (MI.getOpcode() == RISCV::BuildPairF128Pseudo && XLen == 64)) &&
          "Unexpected instruction");
 
+  unsigned XLenInBytes = XLen / 8;
   MachineFunction &MF = *BB->getParent();
   DebugLoc DL = MI.getDebugLoc();
   const RISCVInstrInfo &TII = *MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
@@ -23260,14 +23191,22 @@ static MachineBasicBlock *emitBuildPairF128Pseudo(MachineInstr &MI,
   bool KillLo = MI.getOperand(1).isKill();
   bool KillHi = MI.getOperand(2).isKill();
 
-  const TargetRegisterClass *DstRC = &RISCV::FPR128RegClass;
-  int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF128FrameIndex(MF);
+  const TargetRegisterClass *DstRC = nullptr;
+  int FI = 0;
+  if (XLen == 32) {
+    DstRC = &RISCV::FPR64RegClass;
+    FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
+  } else {
+    DstRC = &RISCV::FPR128RegClass;
+    FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF128FrameIndex(MF);
+  }
 
   MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI);
-  MachineMemOperand *MMOLo =
-      MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 8, Align(16));
+  MachineMemOperand *MMOLo = MF.getMachineMemOperand(
+      MPI, MachineMemOperand::MOStore, XLenInBytes, Align(XLenInBytes * 2));
   MachineMemOperand *MMOHi = MF.getMachineMemOperand(
-      MPI.getWithOffset(8), MachineMemOperand::MOStore, 8, Align(16));
+      MPI.getWithOffset(XLenInBytes), MachineMemOperand::MOStore, XLenInBytes,
+      Align(XLenInBytes * 2));
 
   // For big-endian, store the high part at offset 0 and the low part at
   // offset 4.
@@ -23276,15 +23215,16 @@ static MachineBasicBlock *emitBuildPairF128Pseudo(MachineInstr &MI,
     std::swap(KillLo, KillHi);
   }
 
-  BuildMI(*BB, MI, DL, TII.get(RISCV::SD))
+  auto StoreOpCode = XLen == 32 ? RISCV::SW : RISCV::SD;
+  BuildMI(*BB, MI, DL, TII.get(StoreOpCode))
       .addReg(LoReg, getKillRegState(KillLo))
       .addFrameIndex(FI)
       .addImm(0)
       .addMemOperand(MMOLo);
-  BuildMI(*BB, MI, DL, TII.get(RISCV::SD))
+  BuildMI(*BB, MI, DL, TII.get(StoreOpCode))
       .addReg(HiReg, getKillRegState(KillHi))
       .addFrameIndex(FI)
-      .addImm(8)
+      .addImm(XLenInBytes)
       .addMemOperand(MMOHi);
   TII.loadRegFromStackSlot(*BB, MI, DstReg, FI, DstRC, Register());
   MI.eraseFromParent(); // The pseudo instruction is gone now.
@@ -23820,13 +23760,11 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
   case RISCV::Select_FPR64IN32X_Using_CC_GPR:
     return emitSelectPseudo(MI, BB, Subtarget);
   case RISCV::BuildPairF64Pseudo:
-    return emitBuildPairF64Pseudo(MI, BB, Subtarget);
-  case RISCV::SplitF64Pseudo:
-    return emitSplitF64Pseudo(MI, BB, Subtarget);
   case RISCV::BuildPairF128Pseudo:
-    return emitBuildPairF128Pseudo(MI, BB, Subtarget);
+    return emitBuildPairF2XLenPseudo(MI, BB, Subtarget);
   case RISCV::SplitF128Pseudo:
-    return emitSplitF128Pseudo(MI, BB, Subtarget);
+  case RISCV::SplitF64Pseudo:
+    return emitSplitF2XLenPseudo(MI, BB, Subtarget);
   case RISCV::PseudoQuietFLE_H:
     return emitQuietFCMP(MI, BB, RISCV::FLE_H, RISCV::FEQ_H, Subtarget);
   case RISCV::PseudoQuietFLE_H_INX:

>From 886c15225086bb2c44f33ef6ba5fdbd46eca2991 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Thu, 7 May 2026 19:43:33 +0200
Subject: [PATCH 10/12] Generalize unpackF2XLenOnSoftABI

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 91 ++++++++-------------
 1 file changed, 34 insertions(+), 57 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 83baaaaefd88d..83adbb734e40a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -34,6 +34,7 @@
 #include "llvm/CodeGen/SelectionDAGAddressAnalysis.h"
 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
 #include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGenTypes/MachineValueType.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/IRBuilder.h"
@@ -23979,80 +23980,57 @@ static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain,
   return convertLocVTToValVT(DAG, Val, VA, DL, TLI.getSubtarget());
 }
 
-static SDValue unpackF64OnRV32DSoftABI(SelectionDAG &DAG, SDValue Chain,
+static SDValue unpackF2XLenOnSoftABI(SelectionDAG &DAG, SDValue Chain,
                                        const CCValAssign &VA,
                                        const CCValAssign &HiVA,
                                        const SDLoc &DL) {
-  assert(VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64 &&
-         "Unexpected VA");
+  const RISCVSubtarget &Subtarget = DAG.getSubtarget<RISCVSubtarget>();
+  unsigned XLen = Subtarget.getXLen();
+  assert(
+      ((XLen == 32 && VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) ||
+       (XLen == 64 && VA.getLocVT() == MVT::i64 &&
+        VA.getValVT() == MVT::f128)) &&
+      "Unexpected VA");
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo &MFI = MF.getFrameInfo();
   MachineRegisterInfo &RegInfo = MF.getRegInfo();
 
   assert(VA.isRegLoc() && "Expected register VA assignment");
 
+  MVT RegMVT = XLen == 32 ? MVT::i32 : MVT::i64;
   Register LoVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
   RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
-  SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i32);
+  SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, RegMVT);
   SDValue Hi;
   if (HiVA.isMemLoc()) {
-    // Second half of f64 is passed on the stack.
+    // Second half of float is passed on the stack.
     int FI = MFI.CreateFixedObject(4, HiVA.getLocMemOffset(),
                                    /*IsImmutable=*/true);
-    SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
-    Hi = DAG.getLoad(MVT::i32, DL, Chain, FIN,
+    SDValue FIN = DAG.getFrameIndex(FI, RegMVT);
+    Hi = DAG.getLoad(RegMVT, DL, Chain, FIN,
                      MachinePointerInfo::getFixedStack(MF, FI));
   } else {
-    // Second half of f64 is passed in another GPR.
+    // Second half of float is passed in another GPR.
     Register HiVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
     RegInfo.addLiveIn(HiVA.getLocReg(), HiVReg);
-    Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32);
+    Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, RegMVT);
   }
 
   // For big-endian, swap the order of Lo and Hi when building the pair.
-  const RISCVSubtarget &Subtarget = DAG.getSubtarget<RISCVSubtarget>();
   if (!Subtarget.isLittleEndian())
     std::swap(Lo, Hi);
 
-  return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
-}
-
-static SDValue unpackF128OnRV64DSoftABI(SelectionDAG &DAG, SDValue Chain,
-                                       const CCValAssign &VA,
-                                       const CCValAssign &HiVA,
-                                       const SDLoc &DL) {
-  assert(VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f128 &&
-         "Unexpected VA");
-  MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo &MFI = MF.getFrameInfo();
-  MachineRegisterInfo &RegInfo = MF.getRegInfo();
-
-  assert(VA.isRegLoc() && "Expected register VA assignment");
-
-  Register LoVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
-  RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
-  SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i64);
-  SDValue Hi;
-  if (HiVA.isMemLoc()) {
-    // Second half of f64 is passed on the stack.
-    int FI = MFI.CreateFixedObject(4, HiVA.getLocMemOffset(),
-                                   /*IsImmutable=*/true);
-    SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
-    Hi = DAG.getLoad(MVT::i64, DL, Chain, FIN,
-                     MachinePointerInfo::getFixedStack(MF, FI));
+  unsigned BuildPairOP = 0;
+  MVT FPType;
+  if (XLen == 32) {
+    BuildPairOP = RISCVISD::BuildPairF64;
+    FPType = MVT::f64;
   } else {
-    // Second half of f64 is passed in another GPR.
-    Register HiVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
-    RegInfo.addLiveIn(HiVA.getLocReg(), HiVReg);
-    Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i64);
+    BuildPairOP = RISCVISD::BuildPairF128;
+    FPType = MVT::f128;
   }
 
-  // For big-endian, swap the order of Lo and Hi when building the pair.
-  const RISCVSubtarget &Subtarget = DAG.getSubtarget<RISCVSubtarget>();
-  if (!Subtarget.isLittleEndian())
-    std::swap(Lo, Hi);
-
-  return DAG.getNode(RISCVISD::BuildPairF128, DL, MVT::f128, Lo, Hi);
+  return DAG.getNode(BuildPairOP, DL, FPType, Lo, Hi);
 }
 
 // Transform physical registers into virtual registers.
@@ -24150,14 +24128,11 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
     SDValue ArgValue;
     // Passing f64 on RV32D with a soft float ABI must be handled as a special
     // case.
-    // unpackF128OnRV64DSoftABI
-    if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
-      assert(VA.needsCustom());
-      ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, ArgLocs[++i], DL);
-    } else if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f128) {
+    if ((VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) ||
+        (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f128)) {
       assert(VA.needsCustom());
-      ArgValue = unpackF128OnRV64DSoftABI(DAG, Chain, VA, ArgLocs[++i], DL);
-    }else if (VA.isRegLoc())
+      ArgValue = unpackF2XLenOnSoftABI(DAG, Chain, VA, ArgLocs[++i], DL);
+    } else if (VA.isRegLoc())
       ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, Ins[InsIdx], *this);
     else
       ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL, *this);
@@ -24709,13 +24684,15 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
 
     const MVT &LocVT = VA.getLocVT();
     const MVT &ValVT = VA.getValVT();
-    if ((LocVT == MVT::i32 && ValVT == MVT::f64) || (LocVT == MVT::i64 && ValVT == MVT::f128)) {
+    if ((LocVT == MVT::i32 && ValVT == MVT::f64) ||
+        (LocVT == MVT::i64 && ValVT == MVT::f128)) {
       // Handle returning f64 on RV32D with a soft float ABI.
       assert(VA.isRegLoc() && "Expected return via registers");
       assert(VA.needsCustom());
-      auto SplitNode = ValVT == MVT::f64 ? RISCVISD::SplitF64 : RISCVISD::SplitF128;
-      SDValue SplitF64 = DAG.getNode(SplitNode, DL,
-                                     DAG.getVTList(LocVT, LocVT), Val);
+      auto SplitNode =
+          ValVT == MVT::f64 ? RISCVISD::SplitF64 : RISCVISD::SplitF128;
+      SDValue SplitF64 =
+          DAG.getNode(SplitNode, DL, DAG.getVTList(LocVT, LocVT), Val);
       SDValue Lo = SplitF64.getValue(0);
       SDValue Hi = SplitF64.getValue(1);
 

>From 7dc0e807c1f9963d1573266edd859fc34c5a550b Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Thu, 7 May 2026 19:57:58 +0200
Subject: [PATCH 11/12] Remove debug SDAG dumps

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 83adbb734e40a..0f1fcecab955a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -23879,7 +23879,6 @@ static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
       return DAG.getNode(RISCVISD::FMV_W_X_RV64, DL, MVT::f32, Val);
     if (VA.getValVT().isFixedLengthVector() && VA.getLocVT().isScalableVector())
       return convertFromScalableVector(VA.getValVT(), Val, DAG, Subtarget);
-    DAG.dumpDotGraph("/tmp/sdag.dot","SDag");
     llvm_unreachable("Unexpected Custom handling.");
   }
 

>From d760e2ffce0d4058e8e20db91cd67d2bc6edc1fc Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Thu, 7 May 2026 20:00:29 +0200
Subject: [PATCH 12/12] Adjust comment

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 0f1fcecab955a..3ab7b11b2e68b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -24125,7 +24125,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
   for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
     CCValAssign &VA = ArgLocs[i];
     SDValue ArgValue;
-    // Passing f64 on RV32D with a soft float ABI must be handled as a special
+    // Passing 2XLen fp with a soft float ABI must be handled as a special
     // case.
     if ((VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) ||
         (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f128)) {



More information about the llvm-commits mailing list