[llvm] [AArch64] Initial compiler support for SVE unwind on Windows. (PR #138609)

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Thu May 29 10:47:42 PDT 2025


https://github.com/efriedma-quic updated https://github.com/llvm/llvm-project/pull/138609

>From 15ef0e5dcb5aa5c49296f19682a2093a33116561 Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Tue, 25 Mar 2025 11:37:23 -0700
Subject: [PATCH 1/8] [AArch64] Initial compiler support for SVE unwind on
 Windows.

Most bits of this are straightforward: when we emit SVE instructions in
the prologue/epilogue, emit corresponding opcodes.

The unfortunately nasty bit is the handling of the frame pointer in
functions that use the SVE calling convention.  If we have SVE
callee saves, and need to restore the stack pointer from the frame
pointer, it's impossible to encode callee saves that happen after the
frame pointer. So this patch rearranges the stack to put SVE callee
saves first.  This isn't really that complicated on its own, but it
leads to a lot of tricky conditionals (see FPAfterSVECalleeSaves).
---
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp |   26 +
 .../AArch64/AArch64CallingConvention.td       |    8 +
 .../Target/AArch64/AArch64FrameLowering.cpp   |  153 ++-
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  |   32 +-
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |    3 +
 .../Target/AArch64/AArch64RegisterInfo.cpp    |    7 +
 llvm/test/CodeGen/AArch64/win-sve.ll          | 1034 +++++++++++++++++
 7 files changed, 1233 insertions(+), 30 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/win-sve.ll

diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index e9ccc35f34612..0d019bda36130 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -3273,6 +3273,32 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
                                      -MI->getOperand(2).getImm());
     return;
 
+  case AArch64::SEH_AllocZ:
+    assert(MI->getOperand(0).getImm() >= 0 &&
+           "AllocZ SEH opcode offset must be non-negative");
+    assert(MI->getOperand(0).getImm() <= 255 &&
+           "AllocZ SEH opcode offset must fit into 8 bits");
+    TS->emitARM64WinCFIAllocZ(MI->getOperand(0).getImm());
+    return;
+
+  case AArch64::SEH_SaveZReg:
+    assert(MI->getOperand(1).getImm() >= 0 &&
+           "SaveZReg SEH opcode offset must be non-negative");
+    assert(MI->getOperand(1).getImm() <= 255 &&
+           "SaveZReg SEH opcode offset must fit into 8 bits");
+    TS->emitARM64WinCFISaveZReg(MI->getOperand(0).getImm(),
+                                MI->getOperand(1).getImm());
+    return;
+
+  case AArch64::SEH_SavePReg:
+    assert(MI->getOperand(1).getImm() >= 0 &&
+           "SavePReg SEH opcode offset must be non-negative");
+    assert(MI->getOperand(1).getImm() <= 255 &&
+           "SavePReg SEH opcode offset must fit into 8 bits");
+    TS->emitARM64WinCFISavePReg(MI->getOperand(0).getImm(),
+                                MI->getOperand(1).getImm());
+    return;
+
   case AArch64::BLR:
   case AArch64::BR: {
     recordIfImportCall(MI);
diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.td b/llvm/lib/Target/AArch64/AArch64CallingConvention.td
index 7cca6d9bc6b9c..287bbbce95bd9 100644
--- a/llvm/lib/Target/AArch64/AArch64CallingConvention.td
+++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.td
@@ -606,6 +606,9 @@ def CSR_Win_AArch64_Arm64EC_Thunk : CalleeSavedRegs<(add (sequence "Q%u", 6, 15)
 def CSR_AArch64_AAVPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
                                           X25, X26, X27, X28, LR, FP,
                                           (sequence "Q%u", 8, 23))>;
+def CSR_Win_AArch64_AAVPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
+                                              X25, X26, X27, X28, FP, LR,
+                                              (sequence "Q%u", 8, 23))>;
 
 // Functions taking SVE arguments or returning an SVE type
 // must (additionally) preserve full Z8-Z23 and predicate registers P4-P15
@@ -619,6 +622,11 @@ def CSR_Darwin_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "Z%u", 8, 23),
                                                         LR, FP, X19, X20, X21, X22,
                                                         X23, X24, X25, X26, X27, X28)>;
 
+def CSR_Win_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "P%u", 4, 11),
+                                                     (sequence "Z%u", 8, 23),
+                                                     X19, X20, X21, X22, X23, X24,
+                                                     X25, X26, X27, X28, FP, LR)>;
+
 // SME ABI support routines such as __arm_tpidr2_save/restore preserve most registers.
 def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
                           : CalleeSavedRegs<(add (sequence "Z%u", 0, 31),
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 0f33e77d4eecc..a031a26b59830 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1200,7 +1200,25 @@ static MachineBasicBlock::iterator InsertSEH(MachineBasicBlock::iterator MBBI,
 
   switch (Opc) {
   default:
-    llvm_unreachable("No SEH Opcode for this instruction");
+    report_fatal_error("No SEH Opcode for this instruction");
+  case AArch64::STR_ZXI:
+  case AArch64::LDR_ZXI: {
+    unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
+    MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveZReg))
+              .addImm(Reg0)
+              .addImm(Imm)
+              .setMIFlag(Flag);
+    break;
+  }
+  case AArch64::STR_PXI:
+  case AArch64::LDR_PXI: {
+    unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
+    MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SavePReg))
+              .addImm(Reg0)
+              .addImm(Imm)
+              .setMIFlag(Flag);
+    break;
+  }
   case AArch64::LDPDpost:
     Imm = -Imm;
     [[fallthrough]];
@@ -1592,6 +1610,9 @@ static bool IsSVECalleeSave(MachineBasicBlock::iterator I) {
   case AArch64::CMPNE_PPzZI_B:
     return I->getFlag(MachineInstr::FrameSetup) ||
            I->getFlag(MachineInstr::FrameDestroy);
+  case AArch64::SEH_SavePReg:
+  case AArch64::SEH_SaveZReg:
+    return true;
   }
 }
 
@@ -1874,12 +1895,48 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
   bool IsWin64 = Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg());
   unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);
 
+  // Windows unwind can't represent the required stack adjustments if we have
+  // both SVE callee-saves and dynamic stack allocations, and the frame
+  // pointer is before the SVE spills.  The allocation of the frame pointer
+  // must be the last instruction in the prologue so the unwinder can restore
+  // the stack pointer correctly. (And there isn't any unwind opcode for
+  // `addvl sp, x29, -17`.)
+  //
+  // Because of this, we do spills in the opposite order on Windows: first SVE,
+  // then GPRs. The main side-effect of this is that it makes accessing
+  // parameters passed on the stack more expensive.
+  //
+  // We could consider rearranging the spills for simpler cases.
+  bool FPAfterSVECalleeSaves =
+      Subtarget.isTargetWindows() && AFI->getSVECalleeSavedStackSize();
+
   auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
   // All of the remaining stack allocations are for locals.
   AFI->setLocalStackSize(NumBytes - PrologueSaveSize);
   bool CombineSPBump = shouldCombineCSRLocalStackBump(MF, NumBytes);
   bool HomPrologEpilog = homogeneousPrologEpilog(MF);
-  if (CombineSPBump) {
+  if (FPAfterSVECalleeSaves) {
+    // If we're doing SVE saves first, we need to immediately allocate space
+    // for fixed objects, then space for the SVE callee saves.
+    //
+    // Windows unwind requires that the scalable size is a multiple of 16;
+    // that's handled when the callee-saved size is computed.
+    auto SaveSize =
+        StackOffset::getScalable(AFI->getSVECalleeSavedStackSize()) +
+        StackOffset::getFixed(FixedObject);
+    allocateStackSpace(MBB, MBBI, 0, SaveSize, NeedsWinCFI, &HasWinCFI,
+                       /*EmitCFI=*/false, StackOffset{},
+                       /*FollowupAllocs=*/true);
+    NumBytes -= FixedObject;
+
+    // Now allocate space for the GPR callee saves.
+    while (MBBI != End && IsSVECalleeSave(MBBI))
+      ++MBBI;
+    MBBI = convertCalleeSaveRestoreToSPPrePostIncDec(
+        MBB, MBBI, DL, TII, -AFI->getCalleeSavedStackSize(), NeedsWinCFI,
+        &HasWinCFI, EmitAsyncCFI);
+    NumBytes -= AFI->getCalleeSavedStackSize();
+  } else if (CombineSPBump) {
     assert(!SVEStackSize && "Cannot combine SP bump with SVE");
     emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
                     StackOffset::getFixed(-NumBytes), TII,
@@ -1982,6 +2039,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
           : 0;
 
   if (windowsRequiresStackProbe(MF, NumBytes + RealignmentPadding)) {
+    if (AFI->getSVECalleeSavedStackSize())
+      report_fatal_error("SVE callee saves not yet supported");
     uint64_t NumWords = (NumBytes + RealignmentPadding) >> 4;
     if (NeedsWinCFI) {
       HasWinCFI = true;
@@ -2116,9 +2175,11 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
                       << "\n");
     // Find callee save instructions in frame.
     CalleeSavesBegin = MBBI;
-    assert(IsSVECalleeSave(CalleeSavesBegin) && "Unexpected instruction");
-    while (IsSVECalleeSave(MBBI) && MBBI != MBB.getFirstTerminator())
-      ++MBBI;
+    if (!FPAfterSVECalleeSaves) {
+      assert(IsSVECalleeSave(CalleeSavesBegin) && "Unexpected instruction");
+      while (IsSVECalleeSave(MBBI) && MBBI != MBB.getFirstTerminator())
+        ++MBBI;
+    }
     CalleeSavesEnd = MBBI;
 
     SVECalleeSavesSize = StackOffset::getScalable(CalleeSavedSize);
@@ -2129,9 +2190,11 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
   StackOffset CFAOffset =
       StackOffset::getFixed((int64_t)MFI.getStackSize() - NumBytes);
   StackOffset LocalsSize = SVELocalsSize + StackOffset::getFixed(NumBytes);
-  allocateStackSpace(MBB, CalleeSavesBegin, 0, SVECalleeSavesSize, false,
-                     nullptr, EmitAsyncCFI && !HasFP, CFAOffset,
-                     MFI.hasVarSizedObjects() || LocalsSize);
+  if (!FPAfterSVECalleeSaves) {
+    allocateStackSpace(MBB, CalleeSavesBegin, 0, SVECalleeSavesSize, false,
+                       nullptr, EmitAsyncCFI && !HasFP, CFAOffset,
+                       MFI.hasVarSizedObjects() || LocalsSize);
+  }
   CFAOffset += SVECalleeSavesSize;
 
   if (EmitAsyncCFI)
@@ -2303,10 +2366,16 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
     assert(AfterCSRPopSize == 0);
     return;
   }
+
+  bool FPAfterSVECalleeSaves =
+      Subtarget.isTargetWindows() && AFI->getSVECalleeSavedStackSize();
+
   bool CombineSPBump = shouldCombineCSRLocalStackBumpInEpilogue(MBB, NumBytes);
   // Assume we can't combine the last pop with the sp restore.
   bool CombineAfterCSRBump = false;
-  if (!CombineSPBump && PrologueSaveSize != 0) {
+  if (FPAfterSVECalleeSaves) {
+    AfterCSRPopSize = FixedObject;
+  } else if (!CombineSPBump && PrologueSaveSize != 0) {
     MachineBasicBlock::iterator Pop = std::prev(MBB.getFirstTerminator());
     while (Pop->getOpcode() == TargetOpcode::CFI_INSTRUCTION ||
            AArch64InstrInfo::isSEHInstruction(*Pop))
@@ -2339,7 +2408,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
   while (LastPopI != Begin) {
     --LastPopI;
     if (!LastPopI->getFlag(MachineInstr::FrameDestroy) ||
-        IsSVECalleeSave(LastPopI)) {
+        (!FPAfterSVECalleeSaves && IsSVECalleeSave(LastPopI))) {
       ++LastPopI;
       break;
     } else if (CombineSPBump)
@@ -2415,6 +2484,9 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
   StackOffset DeallocateBefore = {}, DeallocateAfter = SVEStackSize;
   MachineBasicBlock::iterator RestoreBegin = LastPopI, RestoreEnd = LastPopI;
   if (int64_t CalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
+    if (FPAfterSVECalleeSaves)
+      RestoreEnd = MBB.getFirstTerminator();
+
     RestoreBegin = std::prev(RestoreEnd);
     while (RestoreBegin != MBB.begin() &&
            IsSVECalleeSave(std::prev(RestoreBegin)))
@@ -2430,7 +2502,31 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
   }
 
   // Deallocate the SVE area.
-  if (SVEStackSize) {
+  if (FPAfterSVECalleeSaves) {
+    // If the callee-save area is before FP, restoring the FP implicitly
+    // deallocates non-callee-save SVE allocations.  Otherwise, deallocate
+    // them explicitly.
+    if (!AFI->isStackRealigned() && !MFI.hasVarSizedObjects()) {
+      emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
+                      DeallocateBefore, TII, MachineInstr::FrameDestroy, false,
+                      NeedsWinCFI, &HasWinCFI);
+    }
+
+    // Deallocate callee-save non-SVE registers.
+    emitFrameOffset(MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
+                    StackOffset::getFixed(AFI->getCalleeSavedStackSize()), TII,
+                    MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
+
+    // Deallocate fixed objects.
+    emitFrameOffset(MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
+                    StackOffset::getFixed(FixedObject), TII,
+                    MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
+
+    // Deallocate callee-save SVE registers.
+    emitFrameOffset(MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
+                    DeallocateAfter, TII, MachineInstr::FrameDestroy, false,
+                    NeedsWinCFI, &HasWinCFI);
+  } else if (SVEStackSize) {
     // If we have stack realignment or variable sized objects on the stack,
     // restore the stack pointer from the frame pointer prior to SVE CSR
     // restoration.
@@ -2450,20 +2546,20 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
         emitFrameOffset(
             MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
             StackOffset::getFixed(NumBytes), TII, MachineInstr::FrameDestroy,
-            false, false, nullptr, EmitCFI && !hasFP(MF),
+            false, NeedsWinCFI, &HasWinCFI, EmitCFI && !hasFP(MF),
             SVEStackSize + StackOffset::getFixed(NumBytes + PrologueSaveSize));
         NumBytes = 0;
       }
 
       emitFrameOffset(MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
                       DeallocateBefore, TII, MachineInstr::FrameDestroy, false,
-                      false, nullptr, EmitCFI && !hasFP(MF),
+                      NeedsWinCFI, &HasWinCFI, EmitCFI && !hasFP(MF),
                       SVEStackSize +
                           StackOffset::getFixed(NumBytes + PrologueSaveSize));
 
       emitFrameOffset(MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
                       DeallocateAfter, TII, MachineInstr::FrameDestroy, false,
-                      false, nullptr, EmitCFI && !hasFP(MF),
+                      NeedsWinCFI, &HasWinCFI, EmitCFI && !hasFP(MF),
                       DeallocateAfter +
                           StackOffset::getFixed(NumBytes + PrologueSaveSize));
     }
@@ -2757,10 +2853,27 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
   }
 
   StackOffset ScalableOffset = {};
-  if (UseFP && !(isFixed || isCSR))
-    ScalableOffset = -SVEStackSize;
-  if (!UseFP && (isFixed || isCSR))
-    ScalableOffset = SVEStackSize;
+  bool FPAfterSVECalleeSaves =
+      isTargetWindows(MF) && AFI->getSVECalleeSavedStackSize();
+  if (FPAfterSVECalleeSaves) {
+    // In this stack layout, the FP is in between the callee saves and other
+    // SVE allocations.
+    StackOffset SVECalleeSavedStack =
+        StackOffset::getScalable(AFI->getSVECalleeSavedStackSize());
+    if (UseFP) {
+      if (!(isFixed || isCSR))
+        ScalableOffset = SVECalleeSavedStack - SVEStackSize;
+      else
+        ScalableOffset = SVECalleeSavedStack;
+    } else if (!UseFP && (isFixed || isCSR)) {
+      ScalableOffset = SVEStackSize;
+    }
+  } else {
+    if (UseFP && !(isFixed || isCSR))
+      ScalableOffset = -SVEStackSize;
+    if (!UseFP && (isFixed || isCSR))
+      ScalableOffset = SVEStackSize;
+  }
 
   if (UseFP) {
     FrameReg = RegInfo->getFrameRegister(MF);
@@ -2934,7 +3047,9 @@ static void computeCalleeSaveRegisterPairs(
     RegInc = -1;
     FirstReg = Count - 1;
   }
-  int ScalableByteOffset = AFI->getSVECalleeSavedStackSize();
+  bool FPAfterSVECalleeSaves = IsWindows && AFI->getSVECalleeSavedStackSize();
+  int ScalableByteOffset =
+      FPAfterSVECalleeSaves ? 0 : AFI->getSVECalleeSavedStackSize();
   bool NeedGapToAlignStack = AFI->hasCalleeSaveStackFreeSpace();
   Register LastReg = 0;
 
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index d6225bca233b6..128018db26a45 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -1175,6 +1175,9 @@ bool AArch64InstrInfo::isSEHInstruction(const MachineInstr &MI) {
     case AArch64::SEH_PACSignLR:
     case AArch64::SEH_SaveAnyRegQP:
     case AArch64::SEH_SaveAnyRegQPX:
+    case AArch64::SEH_AllocZ:
+    case AArch64::SEH_SaveZReg:
+    case AArch64::SEH_SavePReg:
       return true;
   }
 }
@@ -5987,10 +5990,16 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
     }
 
     if (NeedsWinCFI) {
-      assert(Sign == 1 && "SEH directives should always have a positive sign");
       int Imm = (int)(ThisVal << LocalShiftSize);
-      if ((DestReg == AArch64::FP && SrcReg == AArch64::SP) ||
-          (SrcReg == AArch64::FP && DestReg == AArch64::SP)) {
+      if (VScale != 1 && DestReg == AArch64::SP) {
+        if (HasWinCFI)
+          *HasWinCFI = true;
+        BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_AllocZ))
+            .addImm(ThisVal)
+            .setMIFlag(Flag);
+      } else if ((DestReg == AArch64::FP && SrcReg == AArch64::SP) ||
+                 (SrcReg == AArch64::FP && DestReg == AArch64::SP)) {
+        assert(VScale == 1 && "Expected non-scalable operation");
         if (HasWinCFI)
           *HasWinCFI = true;
         if (Imm == 0)
@@ -6002,6 +6011,7 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
         assert(Offset == 0 && "Expected remaining offset to be zero to "
                               "emit a single SEH directive");
       } else if (DestReg == AArch64::SP) {
+        assert(VScale == 1 && "Expected non-scalable operation");
         if (HasWinCFI)
           *HasWinCFI = true;
         assert(SrcReg == AArch64::SP && "Unexpected SrcReg for SEH_StackAlloc");
@@ -6056,14 +6066,14 @@ void llvm::emitFrameOffset(MachineBasicBlock &MBB,
 
   assert(!(SetNZCV && (NumPredicateVectors || NumDataVectors)) &&
          "SetNZCV not supported with SVE vectors");
-  assert(!(NeedsWinCFI && (NumPredicateVectors || NumDataVectors)) &&
-         "WinCFI not supported with SVE vectors");
+  assert(!(NeedsWinCFI && NumPredicateVectors) &&
+         "WinCFI can't allocate fractions of an SVE data vector");
 
   if (NumDataVectors) {
     emitFrameOffsetAdj(MBB, MBBI, DL, DestReg, SrcReg, NumDataVectors,
-                       UseSVL ? AArch64::ADDSVL_XXI : AArch64::ADDVL_XXI,
-                       TII, Flag, NeedsWinCFI, nullptr, EmitCFAOffset,
-                       CFAOffset, FrameReg);
+                       UseSVL ? AArch64::ADDSVL_XXI : AArch64::ADDVL_XXI, TII,
+                       Flag, NeedsWinCFI, HasWinCFI, EmitCFAOffset, CFAOffset,
+                       FrameReg);
     CFAOffset += StackOffset::getScalable(-NumDataVectors * 16);
     SrcReg = DestReg;
   }
@@ -6071,9 +6081,9 @@ void llvm::emitFrameOffset(MachineBasicBlock &MBB,
   if (NumPredicateVectors) {
     assert(DestReg != AArch64::SP && "Unaligned access to SP");
     emitFrameOffsetAdj(MBB, MBBI, DL, DestReg, SrcReg, NumPredicateVectors,
-                       UseSVL ? AArch64::ADDSPL_XXI : AArch64::ADDPL_XXI,
-                       TII, Flag, NeedsWinCFI, nullptr, EmitCFAOffset,
-                       CFAOffset, FrameReg);
+                       UseSVL ? AArch64::ADDSPL_XXI : AArch64::ADDPL_XXI, TII,
+                       Flag, NeedsWinCFI, HasWinCFI, EmitCFAOffset, CFAOffset,
+                       FrameReg);
   }
 }
 
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 72445172059bf..20c17e8f209a8 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -5572,6 +5572,9 @@ let isPseudo = 1 in {
   def SEH_PACSignLR : Pseudo<(outs), (ins), []>, Sched<[]>;
   def SEH_SaveAnyRegQP : Pseudo<(outs), (ins i32imm:$reg0, i32imm:$reg1, i32imm:$offs), []>, Sched<[]>;
   def SEH_SaveAnyRegQPX : Pseudo<(outs), (ins i32imm:$reg0, i32imm:$reg1, i32imm:$offs), []>, Sched<[]>;
+  def SEH_AllocZ : Pseudo<(outs), (ins i32imm:$offs), []>, Sched<[]>;
+  def SEH_SaveZReg : Pseudo<(outs), (ins i32imm:$reg, i32imm:$offs), []>, Sched<[]>;
+  def SEH_SavePReg : Pseudo<(outs), (ins i32imm:$reg, i32imm:$offs), []>, Sched<[]>;
 }
 
 // Pseudo instructions for Windows EH
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index 8caa49de0af43..c8fd45e4d9cca 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -98,6 +98,13 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
       return CSR_Win_AArch64_AAPCS_SwiftError_SaveList;
     if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
       return CSR_Win_AArch64_AAPCS_SwiftTail_SaveList;
+    if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
+      return CSR_Win_AArch64_AAVPCS_SaveList;
+    if (MF->getFunction().getCallingConv() ==
+        CallingConv::AArch64_SVE_VectorCall)
+      return CSR_Win_AArch64_SVE_AAPCS_SaveList;
+    if (MF->getInfo<AArch64FunctionInfo>()->isSVECC())
+      return CSR_Win_AArch64_SVE_AAPCS_SaveList;
     return CSR_Win_AArch64_AAPCS_SaveList;
   }
   if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
diff --git a/llvm/test/CodeGen/AArch64/win-sve.ll b/llvm/test/CodeGen/AArch64/win-sve.ll
new file mode 100644
index 0000000000000..8e0a9ad170e84
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/win-sve.ll
@@ -0,0 +1,1034 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=aarch64-windows-msvc -mattr=+sve < %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-windows-msvc -mattr=+sve -filetype=obj < %s -o /dev/null
+
+declare void @g()
+define i32 @f(<vscale x 2 x i64> %x) {
+; CHECK-LABEL: f:
+; CHECK:       .seh_proc f
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    addvl sp, sp, #-17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    str p6, [sp, #2, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    str p7, [sp, #3, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    str p8, [sp, #4, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    str p9, [sp, #5, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    str p10, [sp, #6, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr_x 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    bl g
+; CHECK-NEXT:    mov w0, #3 // =0x3
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    ldp x29, x30, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 0
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    ldr p6, [sp, #2, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    ldr p7, [sp, #3, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    ldr p8, [sp, #4, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    ldr p9, [sp, #5, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    ldr p10, [sp, #6, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    addvl sp, sp, #17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  call void @g()
+  ret i32 3
+}
+
+declare void @g2(ptr,ptr)
+define void @f2(i64 %n, <vscale x 2 x i64> %x) {
+; CHECK-LABEL: f2:
+; CHECK:       .seh_proc f2
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    addvl sp, sp, #-17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    str p6, [sp, #2, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    str p7, [sp, #3, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    str p8, [sp, #4, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    str p9, [sp, #5, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    str p10, [sp, #6, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str x19, [sp, #-32]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x19, 32
+; CHECK-NEXT:    str x28, [sp, #8] // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg x28, 8
+; CHECK-NEXT:    stp x29, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    add x29, sp, #16
+; CHECK-NEXT:    .seh_add_fp 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    sub sp, sp, #32
+; CHECK-NEXT:    lsl x8, x0, #3
+; CHECK-NEXT:    mov x19, sp
+; CHECK-NEXT:    add x8, x8, #15
+; CHECK-NEXT:    lsr x15, x8, #4
+; CHECK-NEXT:    bl __chkstk
+; CHECK-NEXT:    sub x1, sp, x15, lsl #4
+; CHECK-NEXT:    mov sp, x1
+; CHECK-NEXT:    add x0, x19, #0
+; CHECK-NEXT:    bl g2
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    sub sp, x29, #16
+; CHECK-NEXT:    .seh_add_fp 16
+; CHECK-NEXT:    ldp x29, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    ldr x28, [sp, #8] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x28, 8
+; CHECK-NEXT:    ldr x19, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x19, 0
+; CHECK-NEXT:    add sp, sp, #32
+; CHECK-NEXT:    .seh_stackalloc 32
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    ldr p6, [sp, #2, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    ldr p7, [sp, #3, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    ldr p8, [sp, #4, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    ldr p9, [sp, #5, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    ldr p10, [sp, #6, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    addvl sp, sp, #17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  %p1 = alloca [4 x i64]
+  %p2 = alloca i64, i64 %n
+  call void @g2(ptr %p1, ptr %p2)
+  ret void
+}
+
+declare void @g3(ptr,ptr)
+define void @f3(i64 %n, <vscale x 2 x i64> %x) {
+; CHECK-LABEL: f3:
+; CHECK:       .seh_proc f3
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    addvl sp, sp, #-17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    str p6, [sp, #2, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    str p7, [sp, #3, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    str p8, [sp, #4, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    str p9, [sp, #5, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    str p10, [sp, #6, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr_x 16
+; CHECK-NEXT:    sub sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    add x0, sp, #8
+; CHECK-NEXT:    mov x1, sp
+; CHECK-NEXT:    bl g3
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldp x29, x30, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 0
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    ldr p6, [sp, #2, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    ldr p7, [sp, #3, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    ldr p8, [sp, #4, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    ldr p9, [sp, #5, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    ldr p10, [sp, #6, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    addvl sp, sp, #17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  %p1 = alloca i64
+  %p2 = alloca i64
+  call void @g3(ptr %p1, ptr %p2)
+  ret void
+}
+
+declare void @g4(ptr,ptr)
+define void @f4(i64 %n, <vscale x 2 x i64> %x) {
+; CHECK-LABEL: f4:
+; CHECK:       .seh_proc f4
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    addvl sp, sp, #-17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    str p6, [sp, #2, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    str p7, [sp, #3, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    str p8, [sp, #4, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    str p9, [sp, #5, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    str p10, [sp, #6, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr_x 16
+; CHECK-NEXT:    sub sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    mov x0, sp
+; CHECK-NEXT:    add x1, sp, #16
+; CHECK-NEXT:    bl g4
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldp x29, x30, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 0
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    ldr p6, [sp, #2, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    ldr p7, [sp, #3, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    ldr p8, [sp, #4, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    ldr p9, [sp, #5, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    ldr p10, [sp, #6, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    addvl sp, sp, #17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  %p1 = alloca [2 x i64]
+  %p2 = alloca <vscale x 2 x i64>
+  call void @g4(ptr %p1, ptr %p2)
+  ret void
+}
+
+declare void @g5(ptr,ptr,ptr)
+define void @f5(i64 %n, <vscale x 2 x i64> %x) {
+; CHECK-LABEL: f5:
+; CHECK:       .seh_proc f5
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    addvl sp, sp, #-17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    str p6, [sp, #2, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    str p7, [sp, #3, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    str p8, [sp, #4, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    str p9, [sp, #5, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    str p10, [sp, #6, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str x19, [sp, #-32]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x19, 32
+; CHECK-NEXT:    str x28, [sp, #8] // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg x28, 8
+; CHECK-NEXT:    stp x29, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    add x29, sp, #16
+; CHECK-NEXT:    .seh_add_fp 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    sub sp, sp, #64
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    lsl x8, x0, #3
+; CHECK-NEXT:    mov x19, sp
+; CHECK-NEXT:    add x8, x8, #15
+; CHECK-NEXT:    lsr x15, x8, #4
+; CHECK-NEXT:    bl __chkstk
+; CHECK-NEXT:    sub x2, sp, x15, lsl #4
+; CHECK-NEXT:    mov sp, x2
+; CHECK-NEXT:    sub x1, x29, #16
+; CHECK-NEXT:    add x0, x19, #0
+; CHECK-NEXT:    addvl x1, x1, #-18
+; CHECK-NEXT:    bl g5
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    sub sp, x29, #16
+; CHECK-NEXT:    .seh_add_fp 16
+; CHECK-NEXT:    ldp x29, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    ldr x28, [sp, #8] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x28, 8
+; CHECK-NEXT:    ldr x19, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x19, 0
+; CHECK-NEXT:    add sp, sp, #32
+; CHECK-NEXT:    .seh_stackalloc 32
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    ldr p6, [sp, #2, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    ldr p7, [sp, #3, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    ldr p8, [sp, #4, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    ldr p9, [sp, #5, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    ldr p10, [sp, #6, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    addvl sp, sp, #17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  %p1 = alloca [8 x i64]
+  %p2 = alloca <vscale x 2 x i64>
+  %p3 = alloca i64, i64 %n
+  call void @g5(ptr %p1, ptr %p2, ptr %p3)
+  ret void
+}
+
+declare dso_local i32 @__CxxFrameHandler3(...)
+declare void @g6(ptr, i64)
+declare void @cleanup()
+define void @f6(<vscale x 2 x i64> %x, i64 %n1, i64 %n2, i64 %n3, i64 %n4,
+; CHECK-LABEL: f6:
+; CHECK:       .Lfunc_begin0:
+; CHECK-NEXT:  .seh_proc f6
+; CHECK-NEXT:    .seh_handler __CxxFrameHandler3, @unwind, @except
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    sub sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    addvl sp, sp, #-17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    str p6, [sp, #2, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    str p7, [sp, #3, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    str p8, [sp, #4, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    str p9, [sp, #5, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    str p10, [sp, #6, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str x19, [sp, #-32]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x19, 32
+; CHECK-NEXT:    str x28, [sp, #8] // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg x28, 8
+; CHECK-NEXT:    stp x29, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    add x29, sp, #16
+; CHECK-NEXT:    .seh_add_fp 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    sub sp, sp, #64
+; CHECK-NEXT:    mov x0, #-2 // =0xfffffffffffffffe
+; CHECK-NEXT:    addvl x8, x29, #17
+; CHECK-NEXT:    mov x19, sp
+; CHECK-NEXT:    stur x0, [x8, #16]
+; CHECK-NEXT:    addvl x8, x29, #17
+; CHECK-NEXT:    ldr x1, [x8, #32]
+; CHECK-NEXT:  .Ltmp0:
+; CHECK-NEXT:    add x0, x19, #0
+; CHECK-NEXT:    bl g6
+; CHECK-NEXT:  .Ltmp1:
+; CHECK-NEXT:  // %bb.1: // %invoke.cont
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    add sp, sp, #64
+; CHECK-NEXT:    .seh_stackalloc 64
+; CHECK-NEXT:    ldp x29, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    ldr x28, [sp, #8] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x28, 8
+; CHECK-NEXT:    ldr x19, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x19, 0
+; CHECK-NEXT:    add sp, sp, #32
+; CHECK-NEXT:    .seh_stackalloc 32
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    ldr p6, [sp, #2, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    ldr p7, [sp, #3, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    ldr p8, [sp, #4, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    ldr p9, [sp, #5, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    ldr p10, [sp, #6, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    addvl sp, sp, #17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_handlerdata
+; CHECK-NEXT:    .word $cppxdata$f6 at IMGREL
+; CHECK-NEXT:    .text
+; CHECK-NEXT:    .seh_endproc
+; CHECK-NEXT:    .def "?dtor$2@?0?f6 at 4HA";
+; CHECK-NEXT:    .scl 3;
+; CHECK-NEXT:    .type 32;
+; CHECK-NEXT:    .endef
+; CHECK-NEXT:    .p2align 2
+; CHECK-NEXT:  "?dtor$2@?0?f6 at 4HA":
+; CHECK-NEXT:  .seh_proc "?dtor$2@?0?f6 at 4HA"
+; CHECK-NEXT:  .LBB5_2: // %ehcleanup
+; CHECK-NEXT:    addvl sp, sp, #-17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    str p6, [sp, #2, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    str p7, [sp, #3, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    str p8, [sp, #4, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    str p9, [sp, #5, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    str p10, [sp, #6, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str x19, [sp, #-32]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x19, 32
+; CHECK-NEXT:    str x28, [sp, #8] // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg x28, 8
+; CHECK-NEXT:    stp x29, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    bl cleanup
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    ldp x29, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 16
+; CHECK-NEXT:    ldr x28, [sp, #8] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x28, 8
+; CHECK-NEXT:    ldr x19, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x19, 0
+; CHECK-NEXT:    add sp, sp, #32
+; CHECK-NEXT:    .seh_stackalloc 32
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    ldr p6, [sp, #2, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    ldr p7, [sp, #3, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    ldr p8, [sp, #4, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    ldr p9, [sp, #5, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    ldr p10, [sp, #6, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    addvl sp, sp, #17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+                i64 %n5, i64 %n6, i64 %n7, i64 %n8, i64 %n9) personality ptr @__CxxFrameHandler3 {
+  %p1 = alloca [8 x i64]
+  invoke void @g6(ptr %p1, i64 %n9) to label %invoke.cont unwind label %ehcleanup
+
+invoke.cont:
+  ret void
+
+ehcleanup:                                        ; preds = %entry
+  %c = cleanuppad within none []
+  call void @cleanup() [ "funclet"(token %c) ]
+  cleanupret from %c unwind to caller
+}
+
+declare void @g7(ptr)
+define void @f7(i64 %n) {
+; CHECK-LABEL: f7:
+; CHECK:       .seh_proc f7
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr_x 16
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    mov x0, sp
+; CHECK-NEXT:    bl g7
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    ldp x29, x30, [sp], #16 // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr_x 16
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  %p = alloca <vscale x 2 x i64>
+  call void @g7(ptr %p)
+  ret void
+}
+
+define void @f8(<vscale x 2 x i64> %v) {
+; CHECK-LABEL: f8:
+; CHECK:       .seh_proc f8
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    str z8, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x30, 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    ldr x30, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x30, 0
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr z8, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  call void asm "", "~{d8}"()
+  ret void
+}

>From 2a630f575b07c44250c947585dad0429509c513d Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Wed, 7 May 2025 18:08:13 -0700
Subject: [PATCH 2/8] Partially address review comments.

---
 .../Target/AArch64/AArch64FrameLowering.cpp   |  20 +-
 llvm/test/CodeGen/AArch64/win-sve.ll          | 202 +++++++++++++++++-
 2 files changed, 215 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index a031a26b59830..a1e9723f628a1 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2040,7 +2040,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
 
   if (windowsRequiresStackProbe(MF, NumBytes + RealignmentPadding)) {
     if (AFI->getSVECalleeSavedStackSize())
-      report_fatal_error("SVE callee saves not yet supported");
+      report_fatal_error("SVE callee saves not yet supported with stack probing");
     uint64_t NumWords = (NumBytes + RealignmentPadding) >> 4;
     if (NeedsWinCFI) {
       HasWinCFI = true;
@@ -2683,7 +2683,11 @@ AArch64FrameLowering::getFrameIndexReferenceFromSP(const MachineFunction &MF,
     return StackOffset::getFixed(ObjectOffset - getOffsetOfLocalArea());
 
   const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
+  bool FPAfterSVECalleeSaves =
+      isTargetWindows(MF) && AFI->getSVECalleeSavedStackSize();
   if (MFI.getStackID(FI) == TargetStackID::ScalableVector) {
+    if (FPAfterSVECalleeSaves && -ObjectOffset <= AFI->getSVECalleeSavedStackSize())
+      return StackOffset::get(0, ObjectOffset);
     return StackOffset::get(-((int64_t)AFI->getCalleeSavedStackSize()),
                             ObjectOffset);
   }
@@ -2693,8 +2697,12 @@ AArch64FrameLowering::getFrameIndexReferenceFromSP(const MachineFunction &MF,
       !IsFixed && ObjectOffset >= -((int)AFI->getCalleeSavedStackSize(MFI));
 
   StackOffset ScalableOffset = {};
-  if (!IsFixed && !IsCSR)
+  if (!IsFixed && !IsCSR) {
     ScalableOffset = -SVEStackSize;
+  } else if (FPAfterSVECalleeSaves && IsCSR) {
+    ScalableOffset =
+        -StackOffset::getScalable(AFI->getSVECalleeSavedStackSize());
+  }
 
   return StackOffset::getFixed(ObjectOffset) + ScalableOffset;
 }
@@ -2832,6 +2840,9 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
       "In the presence of dynamic stack pointer realignment, "
       "non-argument/CSR objects cannot be accessed through the frame pointer");
 
+  bool FPAfterSVECalleeSaves =
+      isTargetWindows(MF) && AFI->getSVECalleeSavedStackSize();
+
   if (isSVE) {
     StackOffset FPOffset =
         StackOffset::get(-AFI->getCalleeSaveBaseToFrameRecordOffset(), ObjectOffset);
@@ -2839,6 +2850,9 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
         SVEStackSize +
         StackOffset::get(MFI.getStackSize() - AFI->getCalleeSavedStackSize(),
                          ObjectOffset);
+    if (FPAfterSVECalleeSaves) {
+      FPOffset += StackOffset::getScalable(AFI->getSVECalleeSavedStackSize());
+    }
     // Always use the FP for SVE spills if available and beneficial.
     if (hasFP(MF) && (SPOffset.getFixed() ||
                       FPOffset.getScalable() < SPOffset.getScalable() ||
@@ -2853,8 +2867,6 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
   }
 
   StackOffset ScalableOffset = {};
-  bool FPAfterSVECalleeSaves =
-      isTargetWindows(MF) && AFI->getSVECalleeSavedStackSize();
   if (FPAfterSVECalleeSaves) {
     // In this stack layout, the FP is in between the callee saves and other
     // SVE allocations.
diff --git a/llvm/test/CodeGen/AArch64/win-sve.ll b/llvm/test/CodeGen/AArch64/win-sve.ll
index 8e0a9ad170e84..11c994a58149e 100644
--- a/llvm/test/CodeGen/AArch64/win-sve.ll
+++ b/llvm/test/CodeGen/AArch64/win-sve.ll
@@ -609,7 +609,7 @@ define void @f5(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    mov sp, x2
 ; CHECK-NEXT:    sub x1, x29, #16
 ; CHECK-NEXT:    add x0, x19, #0
-; CHECK-NEXT:    addvl x1, x1, #-18
+; CHECK-NEXT:    addvl x1, x1, #-1
 ; CHECK-NEXT:    bl g5
 ; CHECK-NEXT:    .seh_startepilogue
 ; CHECK-NEXT:    sub sp, x29, #16
@@ -686,7 +686,7 @@ define void @f5(i64 %n, <vscale x 2 x i64> %x) {
 declare dso_local i32 @__CxxFrameHandler3(...)
 declare void @g6(ptr, i64)
 declare void @cleanup()
-define void @f6(<vscale x 2 x i64> %x, i64 %n1, i64 %n2, i64 %n3, i64 %n4,
+define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr @__CxxFrameHandler3 {
 ; CHECK-LABEL: f6:
 ; CHECK:       .Lfunc_begin0:
 ; CHECK-NEXT:  .seh_proc f6
@@ -964,7 +964,6 @@ define void @f6(<vscale x 2 x i64> %x, i64 %n1, i64 %n2, i64 %n3, i64 %n4,
 ; CHECK-NEXT:    .seh_allocz 17
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
-                i64 %n5, i64 %n6, i64 %n7, i64 %n8, i64 %n9) personality ptr @__CxxFrameHandler3 {
   %p1 = alloca [8 x i64]
   invoke void @g6(ptr %p1, i64 %n9) to label %invoke.cont unwind label %ehcleanup
 
@@ -1032,3 +1031,200 @@ define void @f8(<vscale x 2 x i64> %v) {
   call void asm "", "~{d8}"()
   ret void
 }
+
+define void @f9(<vscale x 2 x i64> %v, ...) {
+; CHECK-LABEL: f9:
+; CHECK:       .seh_proc f9
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    sub sp, sp, #64
+; CHECK-NEXT:    .seh_stackalloc 64
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    str z8, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x30, 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    add x9, sp, #8
+; CHECK-NEXT:    str x2, [x8, #32]
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    str x0, [x8, #16]
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    str x1, [x8, #24]
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    str x3, [x8, #40]
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    str x4, [x8, #48]
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    str x5, [x8, #56]
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    str x6, [x8, #64]
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    str x7, [x8, #72]
+; CHECK-NEXT:    add x8, sp, #16
+; CHECK-NEXT:    addvl x8, x8, #1
+; CHECK-NEXT:    str x8, [sp, #8]
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    ldr x30, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x30, 0
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr z8, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    add sp, sp, #64
+; CHECK-NEXT:    .seh_stackalloc 64
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    add sp, sp, #64
+; CHECK-NEXT:    .seh_stackalloc 64
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  %va_list = alloca ptr
+  call void @llvm.va_start.p0(ptr %va_list)
+  call void asm "", "r,~{d8},~{memory}"(ptr %va_list)
+  ret void
+}
+
+declare void @g10(ptr,ptr)
+define void @f10(i64 %n, <vscale x 2 x i64> %x) "frame-pointer"="all" {
+; CHECK-LABEL: f10:
+; CHECK:       .seh_proc f10
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    addvl sp, sp, #-17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    str p6, [sp, #2, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    str p7, [sp, #3, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    str p8, [sp, #4, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    str p9, [sp, #5, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    str p10, [sp, #6, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str x28, [sp, #-32]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x28, 32
+; CHECK-NEXT:    stp x29, x30, [sp, #8] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr 8
+; CHECK-NEXT:    add x29, sp, #8
+; CHECK-NEXT:    .seh_add_fp 8
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    sub sp, sp, #16
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    sub x1, x29, #8
+; CHECK-NEXT:    mov x0, sp
+; CHECK-NEXT:    addvl x1, x1, #-1
+; CHECK-NEXT:    bl g10
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldp x29, x30, [sp, #8] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 8
+; CHECK-NEXT:    ldr x28, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x28, 0
+; CHECK-NEXT:    add sp, sp, #32
+; CHECK-NEXT:    .seh_stackalloc 32
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 1
+; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 2
+; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 3
+; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 4
+; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 5
+; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 6
+; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 7
+; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 8
+; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 9
+; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 10
+; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 11
+; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 12
+; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 13
+; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 14
+; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 15
+; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p4, 0
+; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p5, 1
+; CHECK-NEXT:    ldr p6, [sp, #2, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p6, 2
+; CHECK-NEXT:    ldr p7, [sp, #3, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p7, 3
+; CHECK-NEXT:    ldr p8, [sp, #4, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p8, 4
+; CHECK-NEXT:    ldr p9, [sp, #5, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p9, 5
+; CHECK-NEXT:    ldr p10, [sp, #6, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p10, 6
+; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    addvl sp, sp, #17
+; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  %p1 = alloca [2 x i64]
+  %p2 = alloca <vscale x 2 x i64>
+  call void @g10(ptr %p1, ptr %p2)
+  ret void
+}

>From 95bee438eff854d96b9306f6f78a08ec63ea655e Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Mon, 12 May 2025 22:02:33 -0700
Subject: [PATCH 3/8] More review comment fixes.

---
 .../Target/AArch64/AArch64FrameLowering.cpp   |  8 +++-
 .../AArch64/sve-stack-frame-layout-win.ll     | 40 +++++++++++++++++++
 2 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/sve-stack-frame-layout-win.ll

diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index a1e9723f628a1..da72038c5a6b2 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2040,7 +2040,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
 
   if (windowsRequiresStackProbe(MF, NumBytes + RealignmentPadding)) {
     if (AFI->getSVECalleeSavedStackSize())
-      report_fatal_error("SVE callee saves not yet supported with stack probing");
+      report_fatal_error(
+          "SVE callee saves not yet supported with stack probing");
     uint64_t NumWords = (NumBytes + RealignmentPadding) >> 4;
     if (NeedsWinCFI) {
       HasWinCFI = true;
@@ -2686,7 +2687,8 @@ AArch64FrameLowering::getFrameIndexReferenceFromSP(const MachineFunction &MF,
   bool FPAfterSVECalleeSaves =
       isTargetWindows(MF) && AFI->getSVECalleeSavedStackSize();
   if (MFI.getStackID(FI) == TargetStackID::ScalableVector) {
-    if (FPAfterSVECalleeSaves && -ObjectOffset <= AFI->getSVECalleeSavedStackSize())
+    if (FPAfterSVECalleeSaves &&
+        -ObjectOffset <= (int64_t)AFI->getSVECalleeSavedStackSize())
       return StackOffset::get(0, ObjectOffset);
     return StackOffset::get(-((int64_t)AFI->getCalleeSavedStackSize()),
                             ObjectOffset);
@@ -2844,6 +2846,8 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
       isTargetWindows(MF) && AFI->getSVECalleeSavedStackSize();
 
   if (isSVE) {
+    assert(-ObjectOffset > (int64_t)AFI->getSVECalleeSavedStackSize() &&
+          "Math isn't correct for CSRs with FPAfterSVECalleeSaves");
     StackOffset FPOffset =
         StackOffset::get(-AFI->getCalleeSaveBaseToFrameRecordOffset(), ObjectOffset);
     StackOffset SPOffset =
diff --git a/llvm/test/CodeGen/AArch64/sve-stack-frame-layout-win.ll b/llvm/test/CodeGen/AArch64/sve-stack-frame-layout-win.ll
new file mode 100644
index 0000000000000..3e226c64c2f74
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sve-stack-frame-layout-win.ll
@@ -0,0 +1,40 @@
+; RUN: llc -mtriple=aarch64-windows-msvc -mattr=+sve -pass-remarks-analysis=stack-frame-layout < %s 2>&1 -o /dev/null | FileCheck %s
+
+; CHECK: Function: f10
+; CHECK: Offset: [SP+0-16 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-32 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-48 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-64 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-80 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-96 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-112 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-128 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-144 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-160 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-176 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-192 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-208 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-224 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-240 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-256 x vscale], Type: Spill, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP+0-258 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-260 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-262 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-264 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-266 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-268 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-270 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-272 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP-16-272 x vscale], Type: Spill, Align: 16, Size: 8
+; CHECK: Offset: [SP-24-272 x vscale], Type: Spill, Align: 8, Size: 8
+; CHECK: Offset: [SP-32-272 x vscale], Type: Spill, Align: 8, Size: 8
+; CHECK: Offset: [SP-32-288 x vscale], Type: Variable, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP-48-288 x vscale], Type: Variable, Align: 8, Size: 16
+
+declare void @g10(ptr,ptr)
+define void @f10(i64 %n, <vscale x 2 x i64> %x) "frame-pointer"="all" {
+  %p1 = alloca [2 x i64]
+  %p2 = alloca <vscale x 2 x i64>
+  call void @g10(ptr %p1, ptr %p2)
+  ret void
+}

>From 54ed0b68728269ffb541e59a46e744507782e7f5 Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Thu, 15 May 2025 17:32:32 -0700
Subject: [PATCH 4/8] Fix formatting

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

diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index da72038c5a6b2..6006a09f7b7b3 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2847,7 +2847,7 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
 
   if (isSVE) {
     assert(-ObjectOffset > (int64_t)AFI->getSVECalleeSavedStackSize() &&
-          "Math isn't correct for CSRs with FPAfterSVECalleeSaves");
+           "Math isn't correct for CSRs with FPAfterSVECalleeSaves");
     StackOffset FPOffset =
         StackOffset::get(-AFI->getCalleeSaveBaseToFrameRecordOffset(), ObjectOffset);
     StackOffset SPOffset =

>From 8a233c80442bae2539771b09dbc2ea85f486668e Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Mon, 19 May 2025 13:59:29 -0700
Subject: [PATCH 5/8] Fix handling of "CSR" references.

---
 .../Target/AArch64/AArch64FrameLowering.cpp   |  8 +-
 llvm/test/CodeGen/AArch64/win-sve.ll          | 78 +++++++++++++++++++
 2 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 6006a09f7b7b3..f73a95a3d9d67 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -44,6 +44,10 @@
 // |                                   |
 // |-----------------------------------|
 // |                                   |
+// | (Win64 only) callee-saved SVE reg |
+// |                                   |
+// |-----------------------------------|
+// |                                   |
 // | callee-saved gpr registers        | <--.
 // |                                   |    | On Darwin platforms these
 // |- - - - - - - - - - - - - - - - - -|    | callee saves are swapped,
@@ -2877,11 +2881,11 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
     StackOffset SVECalleeSavedStack =
         StackOffset::getScalable(AFI->getSVECalleeSavedStackSize());
     if (UseFP) {
-      if (!(isFixed || isCSR))
+      if (!isFixed)
         ScalableOffset = SVECalleeSavedStack - SVEStackSize;
       else
         ScalableOffset = SVECalleeSavedStack;
-    } else if (!UseFP && (isFixed || isCSR)) {
+    } else if (!UseFP && isFixed) {
       ScalableOffset = SVEStackSize;
     }
   } else {
diff --git a/llvm/test/CodeGen/AArch64/win-sve.ll b/llvm/test/CodeGen/AArch64/win-sve.ll
index 11c994a58149e..017cd3cc87f92 100644
--- a/llvm/test/CodeGen/AArch64/win-sve.ll
+++ b/llvm/test/CodeGen/AArch64/win-sve.ll
@@ -1228,3 +1228,81 @@ define void @f10(i64 %n, <vscale x 2 x i64> %x) "frame-pointer"="all" {
   call void @g10(ptr %p1, ptr %p2)
   ret void
 }
+
+; Check handling of alloca allocated into CSR space, no frame pointer.
+define i32 @f11(double %d, <vscale x 4 x i32> %vs) "aarch64_pstate_sm_compatible" {
+; CHECK-LABEL: f11:
+; CHECK:       .seh_proc f11
+; CHECK-NEXT:  // %bb.0: // %entry
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    str z8, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x30, 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    mov w0, wzr
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    str d0, [sp, #8]
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    ldr x30, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x30, 0
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr z8, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+entry:
+  %a = alloca double
+  tail call void asm sideeffect "", "~{d8}"() #1
+  store double %d, ptr %a
+  ret i32 0
+}
+
+; Check handling of alloca allocated into CSR space, with frame pointer.
+define i32 @f12(double %d, <vscale x 4 x i32> %vs) "frame-pointer"="all" {
+; CHECK-LABEL: f12:
+; CHECK:       .seh_proc f12
+; CHECK-NEXT:  // %bb.0: // %entry
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    str z8, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    str x28, [sp, #-32]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x28, 32
+; CHECK-NEXT:    stp x29, x30, [sp, #8] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr 8
+; CHECK-NEXT:    add x29, sp, #8
+; CHECK-NEXT:    .seh_add_fp 8
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    mov w0, wzr
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    str d0, [x29, #16]
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    ldp x29, x30, [sp, #8] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 8
+; CHECK-NEXT:    ldr x28, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x28, 0
+; CHECK-NEXT:    add sp, sp, #32
+; CHECK-NEXT:    .seh_stackalloc 32
+; CHECK-NEXT:    ldr z8, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+entry:
+  %a = alloca double
+  tail call void asm sideeffect "", "~{d8},~{x28}"() #1
+  store double %d, ptr %a
+  ret i32 0
+}

>From e864f0ca5bd834dc3f3b1eb9b294ce2831b36c94 Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Mon, 19 May 2025 14:26:21 -0700
Subject: [PATCH 6/8] Actually fix handling of "CSR" references.

Previous version didn't non-CSR SVE allocations correctly.
---
 .../Target/AArch64/AArch64FrameLowering.cpp   | 13 ++-
 llvm/test/CodeGen/AArch64/win-sve.ll          | 95 ++++++++++++++++++-
 2 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index f73a95a3d9d67..3e6fcf59b060d 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2881,12 +2881,15 @@ StackOffset AArch64FrameLowering::resolveFrameOffsetReference(
     StackOffset SVECalleeSavedStack =
         StackOffset::getScalable(AFI->getSVECalleeSavedStackSize());
     if (UseFP) {
-      if (!isFixed)
-        ScalableOffset = SVECalleeSavedStack - SVEStackSize;
-      else
+      if (isFixed)
         ScalableOffset = SVECalleeSavedStack;
-    } else if (!UseFP && isFixed) {
-      ScalableOffset = SVEStackSize;
+      else if (!isCSR)
+        ScalableOffset = SVECalleeSavedStack - SVEStackSize;
+    } else {
+      if (isFixed)
+        ScalableOffset = SVEStackSize;
+      else if (isCSR)
+        ScalableOffset = SVEStackSize - SVECalleeSavedStack;
     }
   } else {
     if (UseFP && !(isFixed || isCSR))
diff --git a/llvm/test/CodeGen/AArch64/win-sve.ll b/llvm/test/CodeGen/AArch64/win-sve.ll
index 017cd3cc87f92..b9742d517e59a 100644
--- a/llvm/test/CodeGen/AArch64/win-sve.ll
+++ b/llvm/test/CodeGen/AArch64/win-sve.ll
@@ -1265,8 +1265,7 @@ entry:
   ret i32 0
 }
 
-; Check handling of alloca allocated into CSR space, with frame pointer.
-define i32 @f12(double %d, <vscale x 4 x i32> %vs) "frame-pointer"="all" {
+define i32 @f12(double %d, <vscale x 4 x i32> %vs) "aarch64_pstate_sm_compatible" {
 ; CHECK-LABEL: f12:
 ; CHECK:       .seh_proc f12
 ; CHECK-NEXT:  // %bb.0: // %entry
@@ -1274,6 +1273,50 @@ define i32 @f12(double %d, <vscale x 4 x i32> %vs) "frame-pointer"="all" {
 ; CHECK-NEXT:    .seh_allocz 1
 ; CHECK-NEXT:    str z8, [sp] // 16-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x30, 16
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    addvl x8, sp, #1
+; CHECK-NEXT:    mov w0, wzr
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    str d0, [x8, #8]
+; CHECK-NEXT:    str d0, [sp]
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    ldr x30, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x30, 0
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr z8, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+entry:
+  %a = alloca double
+  %b = alloca <vscale x 16 x i8>
+  tail call void asm sideeffect "", "~{d8}"() #1
+  store double %d, ptr %a
+  store double %d, ptr %b
+  ret i32 0
+}
+
+; Check handling of alloca allocated into CSR space, with frame pointer.
+define i32 @f13(double %d, <vscale x 4 x i32> %vs) "frame-pointer"="all" {
+; CHECK-LABEL: f13:
+; CHECK:       .seh_proc f13
+; CHECK-NEXT:  // %bb.0: // %entry
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    str z8, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 0
 ; CHECK-NEXT:    str x28, [sp, #-32]! // 8-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_reg_x x28, 32
 ; CHECK-NEXT:    stp x29, x30, [sp, #8] // 16-byte Folded Spill
@@ -1306,3 +1349,51 @@ entry:
   store double %d, ptr %a
   ret i32 0
 }
+
+define i32 @f14(double %d, <vscale x 4 x i32> %vs) "frame-pointer"="all" {
+; CHECK-LABEL: f14:
+; CHECK:       .seh_proc f14
+; CHECK-NEXT:  // %bb.0: // %entry
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    str z8, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    str x28, [sp, #-32]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x28, 32
+; CHECK-NEXT:    stp x29, x30, [sp, #8] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_fplr 8
+; CHECK-NEXT:    add x29, sp, #8
+; CHECK-NEXT:    .seh_add_fp 8
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    addvl x8, x29, #-1
+; CHECK-NEXT:    mov w0, wzr
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    str d0, [x29, #16]
+; CHECK-NEXT:    stur d0, [x8, #-8]
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    ldp x29, x30, [sp, #8] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_fplr 8
+; CHECK-NEXT:    ldr x28, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x28, 0
+; CHECK-NEXT:    add sp, sp, #32
+; CHECK-NEXT:    .seh_stackalloc 32
+; CHECK-NEXT:    ldr z8, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+entry:
+  %a = alloca double
+  %b = alloca <vscale x 16 x i8>
+  tail call void asm sideeffect "", "~{d8},~{x28}"() #1
+  store double %d, ptr %a
+  store double %d, ptr %b
+  ret i32 0
+}

>From 1814b3249817775c35e713e384a9568cca38c2bc Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Wed, 28 May 2025 15:47:08 -0700
Subject: [PATCH 7/8] Address review comments.

Fixed issue lower tailcc and related constructs.

Code style changes.
---
 .../Target/AArch64/AArch64FrameLowering.cpp   | 36 +++++++-------
 llvm/test/CodeGen/AArch64/win-sve.ll          | 49 +++++++++++++++++++
 2 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 3e6fcf59b060d..4cdbeee2e4862 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2171,34 +2171,34 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
   }
 
   StackOffset SVECalleeSavesSize = {}, SVELocalsSize = SVEStackSize;
-  MachineBasicBlock::iterator CalleeSavesBegin = MBBI, CalleeSavesEnd = MBBI;
+  MachineBasicBlock::iterator CalleeSavesEnd = MBBI;
+
+  StackOffset CFAOffset =
+      StackOffset::getFixed((int64_t)MFI.getStackSize() - NumBytes);
 
   // Process the SVE callee-saves to determine what space needs to be
   // allocated.
   if (int64_t CalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
     LLVM_DEBUG(dbgs() << "SVECalleeSavedStackSize = " << CalleeSavedSize
                       << "\n");
+    SVECalleeSavesSize = StackOffset::getScalable(CalleeSavedSize);
+    SVELocalsSize = SVEStackSize - SVECalleeSavesSize;
     // Find callee save instructions in frame.
-    CalleeSavesBegin = MBBI;
+    // Note: With FPAfterSVECalleeSaves the callee saves have already been
+    // allocated.
     if (!FPAfterSVECalleeSaves) {
+      MachineBasicBlock::iterator CalleeSavesBegin = MBBI;
       assert(IsSVECalleeSave(CalleeSavesBegin) && "Unexpected instruction");
       while (IsSVECalleeSave(MBBI) && MBBI != MBB.getFirstTerminator())
         ++MBBI;
-    }
-    CalleeSavesEnd = MBBI;
+      CalleeSavesEnd = MBBI;
 
-    SVECalleeSavesSize = StackOffset::getScalable(CalleeSavedSize);
-    SVELocalsSize = SVEStackSize - SVECalleeSavesSize;
-  }
-
-  // Allocate space for the callee saves (if any).
-  StackOffset CFAOffset =
-      StackOffset::getFixed((int64_t)MFI.getStackSize() - NumBytes);
-  StackOffset LocalsSize = SVELocalsSize + StackOffset::getFixed(NumBytes);
-  if (!FPAfterSVECalleeSaves) {
-    allocateStackSpace(MBB, CalleeSavesBegin, 0, SVECalleeSavesSize, false,
-                       nullptr, EmitAsyncCFI && !HasFP, CFAOffset,
-                       MFI.hasVarSizedObjects() || LocalsSize);
+      StackOffset LocalsSize = SVELocalsSize + StackOffset::getFixed(NumBytes);
+      // Allocate space for the callee saves (if any).
+      allocateStackSpace(MBB, CalleeSavesBegin, 0, SVECalleeSavesSize, false,
+                         nullptr, EmitAsyncCFI && !HasFP, CFAOffset,
+                         MFI.hasVarSizedObjects() || LocalsSize);
+    }
   }
   CFAOffset += SVECalleeSavesSize;
 
@@ -2379,7 +2379,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
   // Assume we can't combine the last pop with the sp restore.
   bool CombineAfterCSRBump = false;
   if (FPAfterSVECalleeSaves) {
-    AfterCSRPopSize = FixedObject;
+    AfterCSRPopSize += FixedObject;
   } else if (!CombineSPBump && PrologueSaveSize != 0) {
     MachineBasicBlock::iterator Pop = std::prev(MBB.getFirstTerminator());
     while (Pop->getOpcode() == TargetOpcode::CFI_INSTRUCTION ||
@@ -2693,7 +2693,7 @@ AArch64FrameLowering::getFrameIndexReferenceFromSP(const MachineFunction &MF,
   if (MFI.getStackID(FI) == TargetStackID::ScalableVector) {
     if (FPAfterSVECalleeSaves &&
         -ObjectOffset <= (int64_t)AFI->getSVECalleeSavedStackSize())
-      return StackOffset::get(0, ObjectOffset);
+      return StackOffset::getScalable(ObjectOffset);
     return StackOffset::get(-((int64_t)AFI->getCalleeSavedStackSize()),
                             ObjectOffset);
   }
diff --git a/llvm/test/CodeGen/AArch64/win-sve.ll b/llvm/test/CodeGen/AArch64/win-sve.ll
index b9742d517e59a..34ec7bd5dd510 100644
--- a/llvm/test/CodeGen/AArch64/win-sve.ll
+++ b/llvm/test/CodeGen/AArch64/win-sve.ll
@@ -1397,3 +1397,52 @@ entry:
   store double %d, ptr %b
   ret i32 0
 }
+
+define tailcc void @f15(double %d, <vscale x 4 x i32> %vs, [9 x i64]) {
+; CHECK-LABEL: f15:
+; CHECK:       .seh_proc f15
+; CHECK-NEXT:  // %bb.0:
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    str z8, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    str x28, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg_x x28, 16
+; CHECK-NEXT:    str x30, [sp, #8] // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg x30, 8
+; CHECK-NEXT:    sub sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    stp d0, d0, [sp, #8]
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr x30, [sp, #8] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x30, 8
+; CHECK-NEXT:    ldr x28, [sp] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x28, 0
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    ldr z8, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 0
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    .seh_allocz 1
+; CHECK-NEXT:    add sp, sp, #80
+; CHECK-NEXT:    .seh_stackalloc 80
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
+  %a = alloca double
+  %b = alloca <vscale x 16 x i8>
+  tail call void asm sideeffect "", "~{d8},~{x28}"() #1
+  store double %d, ptr %a
+  store double %d, ptr %b
+  ret void
+}

>From eb08324b9bdd37d7ee56ed22910af3b965971c99 Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Thu, 29 May 2025 10:22:29 -0700
Subject: [PATCH 8/8] More fixes.

Add more tests.  Correctly spill p12-p15.  Fix issue spilling an odd
number of predicates.
---
 .../AArch64/AArch64CallingConvention.td       |    2 +-
 .../Target/AArch64/AArch64FrameLowering.cpp   |    6 +
 .../CodeGen/AArch64/framelayout-sve-win.mir   |  894 ++++++++++++
 .../AArch64/sve-stack-frame-layout-win.ll     |   14 +-
 llvm/test/CodeGen/AArch64/win-sve.ll          | 1226 +++++++++--------
 5 files changed, 1589 insertions(+), 553 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/framelayout-sve-win.mir

diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.td b/llvm/lib/Target/AArch64/AArch64CallingConvention.td
index 287bbbce95bd9..920cc67273146 100644
--- a/llvm/lib/Target/AArch64/AArch64CallingConvention.td
+++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.td
@@ -622,7 +622,7 @@ def CSR_Darwin_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "Z%u", 8, 23),
                                                         LR, FP, X19, X20, X21, X22,
                                                         X23, X24, X25, X26, X27, X28)>;
 
-def CSR_Win_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "P%u", 4, 11),
+def CSR_Win_AArch64_SVE_AAPCS : CalleeSavedRegs<(add (sequence "P%u", 4, 15),
                                                      (sequence "Z%u", 8, 23),
                                                      X19, X20, X21, X22, X23, X24,
                                                      X25, X26, X27, X28, FP, LR)>;
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 4cdbeee2e4862..0899beb4a1e92 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -3184,6 +3184,12 @@ static void computeCalleeSaveRegisterPairs(
         RPI.isPaired()) // RPI.FrameIdx must be the lower index of the pair
       RPI.FrameIdx = CSI[i + RegInc].getFrameIdx();
 
+    // Realign the scalable offset if necesary.  This is relevant when
+    // spilling predicates on Windows.
+    if (RPI.isScalable() && ScalableByteOffset % Scale != 0) {
+      ScalableByteOffset = alignTo(ScalableByteOffset, Scale);
+    }
+
     int OffsetPre = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
     assert(OffsetPre % Scale == 0);
 
diff --git a/llvm/test/CodeGen/AArch64/framelayout-sve-win.mir b/llvm/test/CodeGen/AArch64/framelayout-sve-win.mir
new file mode 100644
index 0000000000000..5933c5daa67ed
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/framelayout-sve-win.mir
@@ -0,0 +1,894 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --print-fixed-stack --version 5
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 --print-fixed-stack
+# RUN: llc -mattr=+sve -mtriple=aarch64-windows-msvc -run-pass=prologepilog %s -o - | FileCheck %s
+
+--- |
+
+  define void @test_allocate_sve() uwtable { entry: unreachable }
+  define void @test_allocate_sve_gpr_callee_saves() uwtable { entry: unreachable }
+  define void @test_allocate_sve_gpr_realigned() uwtable { entry: unreachable }
+  define void @test_address_sve() uwtable { entry: unreachable }
+  define void @test_address_sve_fp() uwtable { entry: unreachable }
+  define void @test_stack_arg_sve() uwtable { entry: unreachable }
+  define void @test_address_sve_out_of_range() uwtable { entry: unreachable }
+  define void @test_address_gpr_vla() uwtable { entry: unreachable }
+  define aarch64_sve_vector_pcs void @save_restore_pregs_sve() uwtable { entry: unreachable }
+  define aarch64_sve_vector_pcs void @save_restore_zregs_sve() uwtable { entry: unreachable }
+  define aarch64_sve_vector_pcs void @save_restore_sve() uwtable { entry: unreachable }
+  define aarch64_sve_vector_pcs void @save_restore_sve_realign() uwtable { entry: unreachable }
+  define aarch64_sve_vector_pcs void @frame_layout() uwtable { entry: unreachable }
+...
+---
+name:            test_allocate_sve
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 18, alignment: 2 }
+  - { id: 1, stack-id: default, size: 16, alignment: 8 }
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: test_allocate_sve
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.2)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+    ; CHECK-NEXT: frame-setup SEH_StackAlloc 16
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 2
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 2, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 2
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.2)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    RET_ReallyLR
+...
+---
+name:            test_allocate_sve_gpr_callee_saves
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 18, alignment: 2 }
+  - { id: 1, stack-id: default, size: 16, alignment: 8 }
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: test_allocate_sve_gpr_callee_saves
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $x21, $x20, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STPXpre killed $x20, killed $x21, $sp, -4 :: (store (s64) into %stack.3), (store (s64) into %stack.4)
+    ; CHECK-NEXT: frame-setup SEH_SaveRegP_X 20, 21, -32
+    ; CHECK-NEXT: frame-setup STRXui killed $lr, $sp, 2 :: (store (s64) into %stack.2)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg 30, 16
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+    ; CHECK-NEXT: frame-setup SEH_StackAlloc 16
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 2
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $x20 = IMPLICIT_DEF
+    ; CHECK-NEXT: $x21 = IMPLICIT_DEF
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 2, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 2
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: $lr = frame-destroy LDRXui $sp, 2 :: (load (s64) from %stack.2)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg 30, 16
+    ; CHECK-NEXT: early-clobber $sp, $x20, $x21 = frame-destroy LDPXpost $sp, 4 :: (load (s64) from %stack.3), (load (s64) from %stack.4)
+    ; CHECK-NEXT: frame-destroy SEH_SaveRegP_X 20, 21, -32
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    $x20 = IMPLICIT_DEF
+    $x21 = IMPLICIT_DEF
+    RET_ReallyLR
+...
+---
+name:            test_allocate_sve_gpr_realigned
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 18, alignment: 2  }
+  - { id: 1, stack-id: default, size: 16, alignment: 32 }
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: test_allocate_sve_gpr_realigned
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 :: (store (s64) into %stack.2), (store (s64) into %stack.3)
+    ; CHECK-NEXT: frame-setup SEH_SaveFPLR_X -16
+    ; CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
+    ; CHECK-NEXT: frame-setup SEH_SetFP
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $x9 = frame-setup SUBXri $sp, 16, 0
+    ; CHECK-NEXT: $x9 = frame-setup ADDVL_XXI $x9, -2, implicit $vg
+    ; CHECK-NEXT: $sp = frame-setup ANDXri killed $x9, 7930
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
+    ; CHECK-NEXT: frame-destroy SEH_SetFP
+    ; CHECK-NEXT: early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2 :: (load (s64) from %stack.2), (load (s64) from %stack.3)
+    ; CHECK-NEXT: frame-destroy SEH_SaveFPLR_X -16
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    RET_ReallyLR
+...
+---
+name:            test_address_sve
+frameInfo:
+  maxAlignment:  16
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 16, alignment: 8 }
+  - { id: 1, stack-id: scalable-vector, size: 16, alignment: 8 }
+  - { id: 2, stack-id: scalable-vector, size:  2, alignment: 2 }
+  - { id: 3, stack-id: default, size: 16, alignment: 8 }
+body:             |
+  bb.0.entry:
+    liveins: $z0, $z1, $p0
+
+    ; CHECK-LABEL: name: test_address_sve
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $z0, $z1, $p0, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.4)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+    ; CHECK-NEXT: frame-setup SEH_StackAlloc 16
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 3
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $x8 = ADDXri $sp, 16, 0
+    ; CHECK-NEXT: STR_ZXI $z0, killed $x8, 2
+    ; CHECK-NEXT: $x8 = ADDXri $sp, 16, 0
+    ; CHECK-NEXT: STR_ZXI $z1, killed $x8, 1
+    ; CHECK-NEXT: $x8 = ADDXri $sp, 16, 0
+    ; CHECK-NEXT: STR_PXI $p0, killed $x8, 7
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 3
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.4)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    STR_ZXI $z0, %stack.0, 0
+    STR_ZXI $z1, %stack.1, 0
+    STR_PXI $p0, %stack.2, 0
+
+    RET_ReallyLR
+...
+---
+name:            test_address_sve_fp
+frameInfo:
+  maxAlignment:  16
+  isFrameAddressTaken: true
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 16, alignment: 8 }
+  - { id: 1, stack-id: scalable-vector, size: 16, alignment: 8 }
+  - { id: 2, stack-id: scalable-vector, size:  2, alignment: 2 }
+  - { id: 3, stack-id: default, size: 16, alignment: 8 }
+body:             |
+  bb.0.entry:
+    liveins: $z0, $z1, $p0
+
+    ; CHECK-LABEL: name: test_address_sve_fp
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $z0, $z1, $p0, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 :: (store (s64) into %stack.4), (store (s64) into %stack.5)
+    ; CHECK-NEXT: frame-setup SEH_SaveFPLR_X -16
+    ; CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
+    ; CHECK-NEXT: frame-setup SEH_SetFP
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3, implicit $vg
+    ; CHECK-NEXT: STR_ZXI $z0, $fp, -1
+    ; CHECK-NEXT: STR_ZXI $z1, $fp, -2
+    ; CHECK-NEXT: STR_PXI $p0, $fp, -17
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 3
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2 :: (load (s64) from %stack.4), (load (s64) from %stack.5)
+    ; CHECK-NEXT: frame-destroy SEH_SaveFPLR_X -16
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    STR_ZXI $z0, %stack.0, 0
+    STR_ZXI $z1, %stack.1, 0
+    STR_PXI $p0, %stack.2, 0
+
+    RET_ReallyLR
+...
+---
+name:             test_stack_arg_sve
+fixedStack:
+  - { id: 0, stack-id: default, size: 16, alignment: 16, offset: 0 }
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 16, alignment: 16 }
+  - { id: 1, stack-id: default, size: 16, alignment: 16 }
+body:             |
+  bb.0.entry:
+    liveins: $x0
+
+    ; CHECK-LABEL: name: test_stack_arg_sve
+    ; CHECK: fixedStack:
+    ; CHECK-NEXT:   - { id: 0, type: default, offset: 0, size: 16, alignment: 16, stack-id: default, 
+    ; CHECK-NEXT:       isImmutable: false, isAliased: false, callee-saved-register: '', 
+    ; CHECK-NEXT:       callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '', 
+    ; CHECK-NEXT:       debug-info-location: '' }
+    ; CHECK: liveins: $x0, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.2)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+    ; CHECK-NEXT: frame-setup SEH_StackAlloc 16
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 1
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $x8 = ADDVL_XXI $sp, 1, implicit $vg
+    ; CHECK-NEXT: $x0 = LDRXui killed $x8, 4
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 1, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 1
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.2)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    $x0 = LDRXui %fixed-stack.0, 0
+    RET_ReallyLR
+...
+---
+name:            test_address_sve_out_of_range
+frameInfo:
+  maxAlignment:  16
+stack:
+  - { id: 0, stack-id: scalable-vector, size:   16, alignment: 16 }
+  - { id: 1, stack-id: scalable-vector, size: 3584, alignment: 16 }
+  - { id: 2, stack-id: scalable-vector, size:  512, alignment: 16 }
+
+body:             |
+  bb.0.entry:
+    liveins: $z0, $p0
+
+    ; CHECK-LABEL: name: test_address_sve_out_of_range
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $z0, $p0, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.3)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 1
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $x8 = ADDVL_XXI $sp, 1, implicit $vg
+    ; CHECK-NEXT: STR_ZXI $z0, killed $x8, 255
+    ; CHECK-NEXT: $x8 = ADDPL_XXI $sp, 1, implicit $vg
+    ; CHECK-NEXT: STR_PXI $p0, killed $x8, 255
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 31
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 31
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 31
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 31
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 31
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 31
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 31
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 31
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 9, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 9
+    ; CHECK-NEXT: early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.3)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    STR_ZXI $z0, %stack.0, 0
+    STR_PXI $p0, %stack.1, 0
+
+    RET_ReallyLR
+...
+---
+name:            test_address_gpr_vla
+frameInfo:
+  maxAlignment:  16
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 16, alignment: 8 }
+  - { id: 1, stack-id: default, size: 16, alignment: 8 }
+  - { id: 2, stack-id: default, type: variable-sized }
+body:             |
+  bb.0.entry:
+    liveins: $xzr
+
+    ; CHECK-LABEL: name: test_address_gpr_vla
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $xzr, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $x19, $sp, -32 :: (store (s64) into %stack.5)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg_X 19, -32
+    ; CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 1 :: (store (s64) into %stack.3), (store (s64) into %stack.4)
+    ; CHECK-NEXT: frame-setup SEH_SaveFPLR 8
+    ; CHECK-NEXT: $fp = frame-setup ADDXri $sp, 8, 0
+    ; CHECK-NEXT: frame-setup SEH_AddFP 8
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1, implicit $vg
+    ; CHECK-NEXT: $x19 = ADDXri $sp, 0, 0
+    ; CHECK-NEXT: STRXui $xzr, $x19, 0
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy SUBXri $fp, 8, 0
+    ; CHECK-NEXT: frame-destroy SEH_AddFP 8
+    ; CHECK-NEXT: $fp, $lr = frame-destroy LDPXi $sp, 1 :: (load (s64) from %stack.3), (load (s64) from %stack.4)
+    ; CHECK-NEXT: frame-destroy SEH_SaveFPLR 8
+    ; CHECK-NEXT: early-clobber $sp, $x19 = frame-destroy LDRXpost $sp, 32 :: (load (s64) from %stack.5)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg_X 19, -32
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    STRXui $xzr, %stack.1, 0
+
+    RET_ReallyLR
+...
+---
+name: save_restore_pregs_sve
+stack:
+  - { id: 0, stack-id: default, size: 32, alignment: 16 }
+body:             |
+  bb.0.entry:
+
+    ; CHECK-LABEL: name: save_restore_pregs_sve
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $p4, $p5, $p6, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 1
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p4, $sp, 0 :: (store (s16) into %stack.4)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 4, 0
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p5, $sp, 1 :: (store (s16) into %stack.3)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 5, 1
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p6, $sp, 2 :: (store (s16) into %stack.2)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 6, 2
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.1)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 32, 0
+    ; CHECK-NEXT: frame-setup SEH_StackAlloc 32
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $p4 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p5 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p6 = IMPLICIT_DEF
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 32, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 32
+    ; CHECK-NEXT: $lr = frame-destroy LDRXui $sp, 0 :: (load (s64) from %stack.1)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg 30, 0
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: $p4 = frame-destroy LDR_PXI $sp, 0 :: (load (s16) from %stack.4)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 4, 0
+    ; CHECK-NEXT: $p5 = frame-destroy LDR_PXI $sp, 1 :: (load (s16) from %stack.3)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 5, 1
+    ; CHECK-NEXT: $p6 = frame-destroy LDR_PXI $sp, 2 :: (load (s16) from %stack.2)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 6, 2
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 1, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 1
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    $p4 = IMPLICIT_DEF
+    $p5 = IMPLICIT_DEF
+    $p6 = IMPLICIT_DEF
+
+    RET_ReallyLR
+...
+---
+name: save_restore_zregs_sve
+stack:
+  - { id: 0, stack-id: default, size: 32, alignment: 16 }
+body:             |
+  bb.0.entry:
+
+    ; CHECK-LABEL: name: save_restore_zregs_sve
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $z8, $z9, $z10, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 3
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z8, $sp, 0 :: (store (s128) into %stack.4)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 8, 0
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z9, $sp, 1 :: (store (s128) into %stack.3)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 9, 1
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z10, $sp, 2 :: (store (s128) into %stack.2)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 10, 2
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.1)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 32, 0
+    ; CHECK-NEXT: frame-setup SEH_StackAlloc 32
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $z8 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z9 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z10 = IMPLICIT_DEF
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 32, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 32
+    ; CHECK-NEXT: $lr = frame-destroy LDRXui $sp, 0 :: (load (s64) from %stack.1)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg 30, 0
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: $z8 = frame-destroy LDR_ZXI $sp, 0 :: (load (s128) from %stack.4)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 8, 0
+    ; CHECK-NEXT: $z9 = frame-destroy LDR_ZXI $sp, 1 :: (load (s128) from %stack.3)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 9, 1
+    ; CHECK-NEXT: $z10 = frame-destroy LDR_ZXI $sp, 2 :: (load (s128) from %stack.2)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 10, 2
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 3
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    $z8 = IMPLICIT_DEF
+    $z9 = IMPLICIT_DEF
+    $z10 = IMPLICIT_DEF
+
+    RET_ReallyLR
+...
+---
+name: save_restore_sve
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 16, alignment: 16 }
+  - { id: 1, stack-id: default, size: 32, alignment: 16 }
+body:             |
+  bb.0.entry:
+
+    ; CHECK-LABEL: name: save_restore_sve
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $p4, $p5, $p6, $p7, $p8, $p9, $p10, $p11, $p12, $p13, $p14, $p15, $z8, $z9, $z10, $z11, $z12, $z13, $z14, $z15, $z16, $z17, $z18, $z19, $z20, $z21, $z22, $z23, $x20, $x19, $lr, $x21
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -18, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 18
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p4, $sp, 0 :: (store (s16) into %stack.33)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 4, 0
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p5, $sp, 1 :: (store (s16) into %stack.32)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 5, 1
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p6, $sp, 2 :: (store (s16) into %stack.31)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 6, 2
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p7, $sp, 3 :: (store (s16) into %stack.30)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 7, 3
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p8, $sp, 4 :: (store (s16) into %stack.29)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 8, 4
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p9, $sp, 5 :: (store (s16) into %stack.28)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 9, 5
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p10, $sp, 6 :: (store (s16) into %stack.27)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 10, 6
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p11, $sp, 7 :: (store (s16) into %stack.26)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 11, 7
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p12, $sp, 8 :: (store (s16) into %stack.25)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 12, 8
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p13, $sp, 9 :: (store (s16) into %stack.24)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 13, 9
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p14, $sp, 10 :: (store (s16) into %stack.23)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 14, 10
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p15, $sp, 11 :: (store (s16) into %stack.22)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 15, 11
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z8, $sp, 2 :: (store (s128) into %stack.21)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 8, 2
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z9, $sp, 3 :: (store (s128) into %stack.20)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 9, 3
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z10, $sp, 4 :: (store (s128) into %stack.19)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 10, 4
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z11, $sp, 5 :: (store (s128) into %stack.18)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 11, 5
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z12, $sp, 6 :: (store (s128) into %stack.17)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 12, 6
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z13, $sp, 7 :: (store (s128) into %stack.16)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 13, 7
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z14, $sp, 8 :: (store (s128) into %stack.15)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 14, 8
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z15, $sp, 9 :: (store (s128) into %stack.14)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 15, 9
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z16, $sp, 10 :: (store (s128) into %stack.13)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 16, 10
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z17, $sp, 11 :: (store (s128) into %stack.12)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 17, 11
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z18, $sp, 12 :: (store (s128) into %stack.11)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 18, 12
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z19, $sp, 13 :: (store (s128) into %stack.10)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 19, 13
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z20, $sp, 14 :: (store (s128) into %stack.9)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 20, 14
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z21, $sp, 15 :: (store (s128) into %stack.8)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 21, 15
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z22, $sp, 16 :: (store (s128) into %stack.7)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 22, 16
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z23, $sp, 17 :: (store (s128) into %stack.6)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 23, 17
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STPXpre killed $x19, killed $x20, $sp, -4 :: (store (s64) into %stack.4), (store (s64) into %stack.5)
+    ; CHECK-NEXT: frame-setup SEH_SaveRegP_X 19, 20, -32
+    ; CHECK-NEXT: frame-setup STPXi killed $x21, killed $lr, $sp, 2 :: (store (s64) into %stack.2), (store (s64) into %stack.3)
+    ; CHECK-NEXT: frame-setup SEH_SaveRegP 21, 30, 16
+    ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 32, 0
+    ; CHECK-NEXT: frame-setup SEH_StackAlloc 32
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 1
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $z8_z9_z10_z11 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z12_z13_z14_z15 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z16_z17_z18_z19 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z20_z21_z22_z23 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z24_z25_z26_z27 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z28_z29_z30_z31 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p4 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p5 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p6 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p7 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p8 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p9 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p10 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p11 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p12 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p13 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p14 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p15 = IMPLICIT_DEF
+    ; CHECK-NEXT: $x19 = IMPLICIT_DEF
+    ; CHECK-NEXT: $x20 = IMPLICIT_DEF
+    ; CHECK-NEXT: $x21 = IMPLICIT_DEF
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 1, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 1
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 32, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 32
+    ; CHECK-NEXT: $x21, $lr = frame-destroy LDPXi $sp, 2 :: (load (s64) from %stack.2), (load (s64) from %stack.3)
+    ; CHECK-NEXT: frame-destroy SEH_SaveRegP 21, 30, 16
+    ; CHECK-NEXT: $x19, $x20 = frame-destroy LDPXi $sp, 0 :: (load (s64) from %stack.4), (load (s64) from %stack.5)
+    ; CHECK-NEXT: frame-destroy SEH_SaveRegP 19, 20, 0
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 32, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 32
+    ; CHECK-NEXT: $z8 = frame-destroy LDR_ZXI $sp, 2 :: (load (s128) from %stack.21)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 8, 2
+    ; CHECK-NEXT: $z9 = frame-destroy LDR_ZXI $sp, 3 :: (load (s128) from %stack.20)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 9, 3
+    ; CHECK-NEXT: $z10 = frame-destroy LDR_ZXI $sp, 4 :: (load (s128) from %stack.19)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 10, 4
+    ; CHECK-NEXT: $z11 = frame-destroy LDR_ZXI $sp, 5 :: (load (s128) from %stack.18)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 11, 5
+    ; CHECK-NEXT: $z12 = frame-destroy LDR_ZXI $sp, 6 :: (load (s128) from %stack.17)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 12, 6
+    ; CHECK-NEXT: $z13 = frame-destroy LDR_ZXI $sp, 7 :: (load (s128) from %stack.16)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 13, 7
+    ; CHECK-NEXT: $z14 = frame-destroy LDR_ZXI $sp, 8 :: (load (s128) from %stack.15)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 14, 8
+    ; CHECK-NEXT: $z15 = frame-destroy LDR_ZXI $sp, 9 :: (load (s128) from %stack.14)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 15, 9
+    ; CHECK-NEXT: $z16 = frame-destroy LDR_ZXI $sp, 10 :: (load (s128) from %stack.13)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 16, 10
+    ; CHECK-NEXT: $z17 = frame-destroy LDR_ZXI $sp, 11 :: (load (s128) from %stack.12)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 17, 11
+    ; CHECK-NEXT: $z18 = frame-destroy LDR_ZXI $sp, 12 :: (load (s128) from %stack.11)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 18, 12
+    ; CHECK-NEXT: $z19 = frame-destroy LDR_ZXI $sp, 13 :: (load (s128) from %stack.10)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 19, 13
+    ; CHECK-NEXT: $z20 = frame-destroy LDR_ZXI $sp, 14 :: (load (s128) from %stack.9)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 20, 14
+    ; CHECK-NEXT: $z21 = frame-destroy LDR_ZXI $sp, 15 :: (load (s128) from %stack.8)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 21, 15
+    ; CHECK-NEXT: $z22 = frame-destroy LDR_ZXI $sp, 16 :: (load (s128) from %stack.7)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 22, 16
+    ; CHECK-NEXT: $z23 = frame-destroy LDR_ZXI $sp, 17 :: (load (s128) from %stack.6)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 23, 17
+    ; CHECK-NEXT: $p4 = frame-destroy LDR_PXI $sp, 0 :: (load (s16) from %stack.33)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 4, 0
+    ; CHECK-NEXT: $p5 = frame-destroy LDR_PXI $sp, 1 :: (load (s16) from %stack.32)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 5, 1
+    ; CHECK-NEXT: $p6 = frame-destroy LDR_PXI $sp, 2 :: (load (s16) from %stack.31)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 6, 2
+    ; CHECK-NEXT: $p7 = frame-destroy LDR_PXI $sp, 3 :: (load (s16) from %stack.30)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 7, 3
+    ; CHECK-NEXT: $p8 = frame-destroy LDR_PXI $sp, 4 :: (load (s16) from %stack.29)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 8, 4
+    ; CHECK-NEXT: $p9 = frame-destroy LDR_PXI $sp, 5 :: (load (s16) from %stack.28)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 9, 5
+    ; CHECK-NEXT: $p10 = frame-destroy LDR_PXI $sp, 6 :: (load (s16) from %stack.27)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 10, 6
+    ; CHECK-NEXT: $p11 = frame-destroy LDR_PXI $sp, 7 :: (load (s16) from %stack.26)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 11, 7
+    ; CHECK-NEXT: $p12 = frame-destroy LDR_PXI $sp, 8 :: (load (s16) from %stack.25)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 12, 8
+    ; CHECK-NEXT: $p13 = frame-destroy LDR_PXI $sp, 9 :: (load (s16) from %stack.24)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 13, 9
+    ; CHECK-NEXT: $p14 = frame-destroy LDR_PXI $sp, 10 :: (load (s16) from %stack.23)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 14, 10
+    ; CHECK-NEXT: $p15 = frame-destroy LDR_PXI $sp, 11 :: (load (s16) from %stack.22)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 15, 11
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 18, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 18
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    $z8_z9_z10_z11   = IMPLICIT_DEF
+    $z12_z13_z14_z15 = IMPLICIT_DEF
+    $z16_z17_z18_z19 = IMPLICIT_DEF
+    $z20_z21_z22_z23 = IMPLICIT_DEF
+    $z24_z25_z26_z27 = IMPLICIT_DEF
+    $z28_z29_z30_z31 = IMPLICIT_DEF
+    $p4 = IMPLICIT_DEF
+    $p5 = IMPLICIT_DEF
+    $p6 = IMPLICIT_DEF
+    $p7 = IMPLICIT_DEF
+    $p8 = IMPLICIT_DEF
+    $p9 = IMPLICIT_DEF
+    $p10 = IMPLICIT_DEF
+    $p11 = IMPLICIT_DEF
+    $p12 = IMPLICIT_DEF
+    $p13 = IMPLICIT_DEF
+    $p14 = IMPLICIT_DEF
+    $p15 = IMPLICIT_DEF
+
+    $x19 = IMPLICIT_DEF
+    $x20 = IMPLICIT_DEF
+    $x21 = IMPLICIT_DEF
+
+    RET_ReallyLR
+...
+---
+name: save_restore_sve_realign
+stack:
+  - { id: 0, stack-id: scalable-vector, size: 16, alignment: 16 }
+  - { id: 1, stack-id: default, size: 16, alignment: 32 }
+body:             |
+  bb.0.entry:
+
+    ; CHECK-LABEL: name: save_restore_sve_realign
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $p4, $p5, $p6, $p7, $p8, $p9, $p10, $p11, $p12, $p13, $p14, $p15, $z8, $z9, $z10, $z11, $z12, $z13, $z14, $z15, $z16, $z17, $z18, $z19, $z20, $z21, $z22, $z23, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -18, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 18
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p4, $sp, 0 :: (store (s16) into %stack.31)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 4, 0
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p5, $sp, 1 :: (store (s16) into %stack.30)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 5, 1
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p6, $sp, 2 :: (store (s16) into %stack.29)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 6, 2
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p7, $sp, 3 :: (store (s16) into %stack.28)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 7, 3
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p8, $sp, 4 :: (store (s16) into %stack.27)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 8, 4
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p9, $sp, 5 :: (store (s16) into %stack.26)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 9, 5
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p10, $sp, 6 :: (store (s16) into %stack.25)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 10, 6
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p11, $sp, 7 :: (store (s16) into %stack.24)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 11, 7
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p12, $sp, 8 :: (store (s16) into %stack.23)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 12, 8
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p13, $sp, 9 :: (store (s16) into %stack.22)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 13, 9
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p14, $sp, 10 :: (store (s16) into %stack.21)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 14, 10
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p15, $sp, 11 :: (store (s16) into %stack.20)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 15, 11
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z8, $sp, 2 :: (store (s128) into %stack.19)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 8, 2
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z9, $sp, 3 :: (store (s128) into %stack.18)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 9, 3
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z10, $sp, 4 :: (store (s128) into %stack.17)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 10, 4
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z11, $sp, 5 :: (store (s128) into %stack.16)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 11, 5
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z12, $sp, 6 :: (store (s128) into %stack.15)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 12, 6
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z13, $sp, 7 :: (store (s128) into %stack.14)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 13, 7
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z14, $sp, 8 :: (store (s128) into %stack.13)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 14, 8
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z15, $sp, 9 :: (store (s128) into %stack.12)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 15, 9
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z16, $sp, 10 :: (store (s128) into %stack.11)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 16, 10
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z17, $sp, 11 :: (store (s128) into %stack.10)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 17, 11
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z18, $sp, 12 :: (store (s128) into %stack.9)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 18, 12
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z19, $sp, 13 :: (store (s128) into %stack.8)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 19, 13
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z20, $sp, 14 :: (store (s128) into %stack.7)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 20, 14
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z21, $sp, 15 :: (store (s128) into %stack.6)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 21, 15
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z22, $sp, 16 :: (store (s128) into %stack.5)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 22, 16
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z23, $sp, 17 :: (store (s128) into %stack.4)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 23, 17
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 :: (store (s64) into %stack.2), (store (s64) into %stack.3)
+    ; CHECK-NEXT: frame-setup SEH_SaveFPLR_X -16
+    ; CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
+    ; CHECK-NEXT: frame-setup SEH_SetFP
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $x9 = frame-setup SUBXri $sp, 16, 0
+    ; CHECK-NEXT: $x9 = frame-setup ADDVL_XXI $x9, -1, implicit $vg
+    ; CHECK-NEXT: $sp = frame-setup ANDXri killed $x9, 7930
+    ; CHECK-NEXT: $z8_z9_z10_z11 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z12_z13_z14_z15 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z16_z17_z18_z19 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z20_z21_z22_z23 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z24_z25_z26_z27 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z28_z29_z30_z31 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p4 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p5 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p6 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p7 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p8 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p9 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p10 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p11 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p12 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p13 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p14 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p15 = IMPLICIT_DEF
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
+    ; CHECK-NEXT: frame-destroy SEH_SetFP
+    ; CHECK-NEXT: $fp, $lr = frame-destroy LDPXi $sp, 0 :: (load (s64) from %stack.2), (load (s64) from %stack.3)
+    ; CHECK-NEXT: frame-destroy SEH_SaveFPLR 0
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: $z8 = frame-destroy LDR_ZXI $sp, 2 :: (load (s128) from %stack.19)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 8, 2
+    ; CHECK-NEXT: $z9 = frame-destroy LDR_ZXI $sp, 3 :: (load (s128) from %stack.18)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 9, 3
+    ; CHECK-NEXT: $z10 = frame-destroy LDR_ZXI $sp, 4 :: (load (s128) from %stack.17)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 10, 4
+    ; CHECK-NEXT: $z11 = frame-destroy LDR_ZXI $sp, 5 :: (load (s128) from %stack.16)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 11, 5
+    ; CHECK-NEXT: $z12 = frame-destroy LDR_ZXI $sp, 6 :: (load (s128) from %stack.15)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 12, 6
+    ; CHECK-NEXT: $z13 = frame-destroy LDR_ZXI $sp, 7 :: (load (s128) from %stack.14)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 13, 7
+    ; CHECK-NEXT: $z14 = frame-destroy LDR_ZXI $sp, 8 :: (load (s128) from %stack.13)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 14, 8
+    ; CHECK-NEXT: $z15 = frame-destroy LDR_ZXI $sp, 9 :: (load (s128) from %stack.12)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 15, 9
+    ; CHECK-NEXT: $z16 = frame-destroy LDR_ZXI $sp, 10 :: (load (s128) from %stack.11)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 16, 10
+    ; CHECK-NEXT: $z17 = frame-destroy LDR_ZXI $sp, 11 :: (load (s128) from %stack.10)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 17, 11
+    ; CHECK-NEXT: $z18 = frame-destroy LDR_ZXI $sp, 12 :: (load (s128) from %stack.9)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 18, 12
+    ; CHECK-NEXT: $z19 = frame-destroy LDR_ZXI $sp, 13 :: (load (s128) from %stack.8)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 19, 13
+    ; CHECK-NEXT: $z20 = frame-destroy LDR_ZXI $sp, 14 :: (load (s128) from %stack.7)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 20, 14
+    ; CHECK-NEXT: $z21 = frame-destroy LDR_ZXI $sp, 15 :: (load (s128) from %stack.6)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 21, 15
+    ; CHECK-NEXT: $z22 = frame-destroy LDR_ZXI $sp, 16 :: (load (s128) from %stack.5)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 22, 16
+    ; CHECK-NEXT: $z23 = frame-destroy LDR_ZXI $sp, 17 :: (load (s128) from %stack.4)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 23, 17
+    ; CHECK-NEXT: $p4 = frame-destroy LDR_PXI $sp, 0 :: (load (s16) from %stack.31)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 4, 0
+    ; CHECK-NEXT: $p5 = frame-destroy LDR_PXI $sp, 1 :: (load (s16) from %stack.30)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 5, 1
+    ; CHECK-NEXT: $p6 = frame-destroy LDR_PXI $sp, 2 :: (load (s16) from %stack.29)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 6, 2
+    ; CHECK-NEXT: $p7 = frame-destroy LDR_PXI $sp, 3 :: (load (s16) from %stack.28)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 7, 3
+    ; CHECK-NEXT: $p8 = frame-destroy LDR_PXI $sp, 4 :: (load (s16) from %stack.27)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 8, 4
+    ; CHECK-NEXT: $p9 = frame-destroy LDR_PXI $sp, 5 :: (load (s16) from %stack.26)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 9, 5
+    ; CHECK-NEXT: $p10 = frame-destroy LDR_PXI $sp, 6 :: (load (s16) from %stack.25)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 10, 6
+    ; CHECK-NEXT: $p11 = frame-destroy LDR_PXI $sp, 7 :: (load (s16) from %stack.24)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 11, 7
+    ; CHECK-NEXT: $p12 = frame-destroy LDR_PXI $sp, 8 :: (load (s16) from %stack.23)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 12, 8
+    ; CHECK-NEXT: $p13 = frame-destroy LDR_PXI $sp, 9 :: (load (s16) from %stack.22)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 13, 9
+    ; CHECK-NEXT: $p14 = frame-destroy LDR_PXI $sp, 10 :: (load (s16) from %stack.21)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 14, 10
+    ; CHECK-NEXT: $p15 = frame-destroy LDR_PXI $sp, 11 :: (load (s16) from %stack.20)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 15, 11
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 18, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 18
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    $z8_z9_z10_z11   = IMPLICIT_DEF
+    $z12_z13_z14_z15 = IMPLICIT_DEF
+    $z16_z17_z18_z19 = IMPLICIT_DEF
+    $z20_z21_z22_z23 = IMPLICIT_DEF
+    $z24_z25_z26_z27 = IMPLICIT_DEF
+    $z28_z29_z30_z31 = IMPLICIT_DEF
+    $p4 = IMPLICIT_DEF
+    $p5 = IMPLICIT_DEF
+    $p6 = IMPLICIT_DEF
+    $p7 = IMPLICIT_DEF
+    $p8 = IMPLICIT_DEF
+    $p9 = IMPLICIT_DEF
+    $p10 = IMPLICIT_DEF
+    $p11 = IMPLICIT_DEF
+    $p12 = IMPLICIT_DEF
+    $p13 = IMPLICIT_DEF
+    $p14 = IMPLICIT_DEF
+    $p15 = IMPLICIT_DEF
+
+    RET_ReallyLR
+...
+---
+name: frame_layout
+stack:
+  - { id: 0, type: default,    size:  32, alignment: 16, stack-id: scalable-vector }
+  - { id: 1, type: default,    size:   4, alignment:  2, stack-id: scalable-vector }
+  - { id: 2, type: default,    size:  16, alignment: 16, stack-id: scalable-vector }
+  - { id: 3, type: default,    size:   2, alignment:  2, stack-id: scalable-vector }
+  - { id: 4, type: spill-slot, size:  16, alignment: 16, stack-id: scalable-vector }
+  - { id: 5, type: spill-slot, size:   2, alignment:  2, stack-id: scalable-vector }
+body:             |
+  bb.0.entry:
+
+    ; Trigger some callee saves
+    ; CHECK-LABEL: name: frame_layout
+    ; CHECK: fixedStack:
+    ; CHECK: liveins: $p4, $p15, $z8, $z23, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 3
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p4, $sp, 0 :: (store (s16) into %stack.10)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 4, 0
+    ; CHECK-NEXT: frame-setup STR_PXI killed $p15, $sp, 1 :: (store (s16) into %stack.9)
+    ; CHECK-NEXT: frame-setup SEH_SavePReg 15, 1
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z8, $sp, 1 :: (store (s128) into %stack.8)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 8, 1
+    ; CHECK-NEXT: frame-setup STR_ZXI killed $z23, $sp, 2 :: (store (s128) into %stack.7)
+    ; CHECK-NEXT: frame-setup SEH_SaveZReg 23, 2
+    ; CHECK-NEXT: early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.6)
+    ; CHECK-NEXT: frame-setup SEH_SaveReg_X 30, -16
+    ; CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -7, implicit $vg
+    ; CHECK-NEXT: frame-setup SEH_AllocZ 7
+    ; CHECK-NEXT: frame-setup SEH_PrologEnd
+    ; CHECK-NEXT: $z8 = IMPLICIT_DEF
+    ; CHECK-NEXT: $z23 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p4 = IMPLICIT_DEF
+    ; CHECK-NEXT: $p15 = IMPLICIT_DEF
+    ; CHECK-NEXT: frame-destroy SEH_EpilogStart
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 7, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 7
+    ; CHECK-NEXT: $lr = frame-destroy LDRXui $sp, 0 :: (load (s64) from %stack.6)
+    ; CHECK-NEXT: frame-destroy SEH_SaveReg 30, 0
+    ; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
+    ; CHECK-NEXT: frame-destroy SEH_StackAlloc 16
+    ; CHECK-NEXT: $z8 = frame-destroy LDR_ZXI $sp, 1 :: (load (s128) from %stack.8)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 8, 1
+    ; CHECK-NEXT: $z23 = frame-destroy LDR_ZXI $sp, 2 :: (load (s128) from %stack.7)
+    ; CHECK-NEXT: frame-destroy SEH_SaveZReg 23, 2
+    ; CHECK-NEXT: $p4 = frame-destroy LDR_PXI $sp, 0 :: (load (s16) from %stack.10)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 4, 0
+    ; CHECK-NEXT: $p15 = frame-destroy LDR_PXI $sp, 1 :: (load (s16) from %stack.9)
+    ; CHECK-NEXT: frame-destroy SEH_SavePReg 15, 1
+    ; CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3, implicit $vg
+    ; CHECK-NEXT: frame-destroy SEH_AllocZ 3
+    ; CHECK-NEXT: frame-destroy SEH_EpilogEnd
+    ; CHECK-NEXT: RET_ReallyLR
+    $z8  = IMPLICIT_DEF
+    $z23 = IMPLICIT_DEF
+    $p4  = IMPLICIT_DEF
+    $p15 = IMPLICIT_DEF
+
+    RET_ReallyLR
+...
diff --git a/llvm/test/CodeGen/AArch64/sve-stack-frame-layout-win.ll b/llvm/test/CodeGen/AArch64/sve-stack-frame-layout-win.ll
index 3e226c64c2f74..8f732bd933124 100644
--- a/llvm/test/CodeGen/AArch64/sve-stack-frame-layout-win.ll
+++ b/llvm/test/CodeGen/AArch64/sve-stack-frame-layout-win.ll
@@ -25,11 +25,15 @@
 ; CHECK: Offset: [SP+0-268 x vscale], Type: Spill, Align: 2, Size: vscale x 2
 ; CHECK: Offset: [SP+0-270 x vscale], Type: Spill, Align: 2, Size: vscale x 2
 ; CHECK: Offset: [SP+0-272 x vscale], Type: Spill, Align: 2, Size: vscale x 2
-; CHECK: Offset: [SP-16-272 x vscale], Type: Spill, Align: 16, Size: 8
-; CHECK: Offset: [SP-24-272 x vscale], Type: Spill, Align: 8, Size: 8
-; CHECK: Offset: [SP-32-272 x vscale], Type: Spill, Align: 8, Size: 8
-; CHECK: Offset: [SP-32-288 x vscale], Type: Variable, Align: 16, Size: vscale x 16
-; CHECK: Offset: [SP-48-288 x vscale], Type: Variable, Align: 8, Size: 16
+; CHECK: Offset: [SP+0-274 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-276 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-278 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP+0-280 x vscale], Type: Spill, Align: 2, Size: vscale x 2
+; CHECK: Offset: [SP-16-288 x vscale], Type: Spill, Align: 16, Size: 8
+; CHECK: Offset: [SP-24-288 x vscale], Type: Spill, Align: 8, Size: 8
+; CHECK: Offset: [SP-32-288 x vscale], Type: Spill, Align: 8, Size: 8
+; CHECK: Offset: [SP-32-304 x vscale], Type: Variable, Align: 16, Size: vscale x 16
+; CHECK: Offset: [SP-48-304 x vscale], Type: Variable, Align: 8, Size: 16
 
 declare void @g10(ptr,ptr)
 define void @f10(i64 %n, <vscale x 2 x i64> %x) "frame-pointer"="all" {
diff --git a/llvm/test/CodeGen/AArch64/win-sve.ll b/llvm/test/CodeGen/AArch64/win-sve.ll
index 34ec7bd5dd510..691230af3e67d 100644
--- a/llvm/test/CodeGen/AArch64/win-sve.ll
+++ b/llvm/test/CodeGen/AArch64/win-sve.ll
@@ -7,8 +7,8 @@ define i32 @f(<vscale x 2 x i64> %x) {
 ; CHECK-LABEL: f:
 ; CHECK:       .seh_proc f
 ; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    addvl sp, sp, #-17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #-18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
@@ -25,38 +25,46 @@ define i32 @f(<vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str p12, [sp, #8, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    str p13, [sp, #9, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    str p14, [sp, #10, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    str p15, [sp, #11, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    str z8, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    str z9, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    str z10, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    str z11, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    str z12, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    str z13, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    str z14, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    str z15, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    str z16, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    str z17, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    str z18, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    str z19, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    str z20, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    str z21, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    str z22, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    str z23, [sp, #17, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_fplr_x 16
 ; CHECK-NEXT:    .seh_endprologue
@@ -67,38 +75,38 @@ define i32 @f(<vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_fplr 0
 ; CHECK-NEXT:    add sp, sp, #16
 ; CHECK-NEXT:    .seh_stackalloc 16
-; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    ldr z9, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    ldr z10, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    ldr z11, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    ldr z12, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    ldr z13, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    ldr z14, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    ldr z15, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    ldr z16, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    ldr z17, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    ldr z18, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    ldr z19, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    ldr z20, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    ldr z21, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    ldr z22, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    ldr z23, [sp, #17, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
@@ -115,8 +123,16 @@ define i32 @f(<vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    addvl sp, sp, #17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    ldr p12, [sp, #8, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    ldr p13, [sp, #9, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    ldr p14, [sp, #10, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    ldr p15, [sp, #11, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    addvl sp, sp, #18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    .seh_endfunclet
@@ -130,8 +146,8 @@ define void @f2(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-LABEL: f2:
 ; CHECK:       .seh_proc f2
 ; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    addvl sp, sp, #-17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #-18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
@@ -148,38 +164,46 @@ define void @f2(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str p12, [sp, #8, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    str p13, [sp, #9, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    str p14, [sp, #10, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    str p15, [sp, #11, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    str z8, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    str z9, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    str z10, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    str z11, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    str z12, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    str z13, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    str z14, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    str z15, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    str z16, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    str z17, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    str z18, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    str z19, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    str z20, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    str z21, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    str z22, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    str z23, [sp, #17, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    str x19, [sp, #-32]! // 8-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_reg_x x19, 32
 ; CHECK-NEXT:    str x28, [sp, #8] // 8-byte Folded Spill
@@ -210,38 +234,38 @@ define void @f2(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_reg x19, 0
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    ldr z9, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    ldr z10, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    ldr z11, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    ldr z12, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    ldr z13, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    ldr z14, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    ldr z15, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    ldr z16, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    ldr z17, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    ldr z18, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    ldr z19, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    ldr z20, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    ldr z21, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    ldr z22, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    ldr z23, [sp, #17, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
@@ -258,8 +282,16 @@ define void @f2(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    addvl sp, sp, #17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    ldr p12, [sp, #8, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    ldr p13, [sp, #9, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    ldr p14, [sp, #10, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    ldr p15, [sp, #11, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    addvl sp, sp, #18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    .seh_endfunclet
@@ -275,8 +307,8 @@ define void @f3(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-LABEL: f3:
 ; CHECK:       .seh_proc f3
 ; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    addvl sp, sp, #-17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #-18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
@@ -293,38 +325,46 @@ define void @f3(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str p12, [sp, #8, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    str p13, [sp, #9, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    str p14, [sp, #10, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    str p15, [sp, #11, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    str z8, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    str z9, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    str z10, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    str z11, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    str z12, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    str z13, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    str z14, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    str z15, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    str z16, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    str z17, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    str z18, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    str z19, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    str z20, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    str z21, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    str z22, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    str z23, [sp, #17, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_fplr_x 16
 ; CHECK-NEXT:    sub sp, sp, #16
@@ -340,38 +380,38 @@ define void @f3(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_fplr 0
 ; CHECK-NEXT:    add sp, sp, #16
 ; CHECK-NEXT:    .seh_stackalloc 16
-; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    ldr z9, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    ldr z10, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    ldr z11, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    ldr z12, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    ldr z13, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    ldr z14, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    ldr z15, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    ldr z16, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    ldr z17, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    ldr z18, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    ldr z19, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    ldr z20, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    ldr z21, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    ldr z22, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    ldr z23, [sp, #17, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
@@ -388,8 +428,16 @@ define void @f3(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    addvl sp, sp, #17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    ldr p12, [sp, #8, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    ldr p13, [sp, #9, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    ldr p14, [sp, #10, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    ldr p15, [sp, #11, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    addvl sp, sp, #18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    .seh_endfunclet
@@ -405,8 +453,8 @@ define void @f4(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-LABEL: f4:
 ; CHECK:       .seh_proc f4
 ; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    addvl sp, sp, #-17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #-18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
@@ -423,38 +471,46 @@ define void @f4(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str p12, [sp, #8, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    str p13, [sp, #9, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    str p14, [sp, #10, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    str p15, [sp, #11, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    str z8, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    str z9, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    str z10, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    str z11, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    str z12, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    str z13, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    str z14, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    str z15, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    str z16, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    str z17, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    str z18, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    str z19, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    str z20, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    str z21, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    str z22, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    str z23, [sp, #17, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_fplr_x 16
 ; CHECK-NEXT:    sub sp, sp, #16
@@ -474,38 +530,38 @@ define void @f4(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_fplr 0
 ; CHECK-NEXT:    add sp, sp, #16
 ; CHECK-NEXT:    .seh_stackalloc 16
-; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    ldr z9, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    ldr z10, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    ldr z11, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    ldr z12, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    ldr z13, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    ldr z14, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    ldr z15, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    ldr z16, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    ldr z17, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    ldr z18, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    ldr z19, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    ldr z20, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    ldr z21, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    ldr z22, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    ldr z23, [sp, #17, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
@@ -522,8 +578,16 @@ define void @f4(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    addvl sp, sp, #17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    ldr p12, [sp, #8, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    ldr p13, [sp, #9, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    ldr p14, [sp, #10, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    ldr p15, [sp, #11, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    addvl sp, sp, #18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    .seh_endfunclet
@@ -539,8 +603,8 @@ define void @f5(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-LABEL: f5:
 ; CHECK:       .seh_proc f5
 ; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    addvl sp, sp, #-17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #-18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
@@ -557,38 +621,46 @@ define void @f5(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str p12, [sp, #8, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    str p13, [sp, #9, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    str p14, [sp, #10, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    str p15, [sp, #11, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    str z8, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    str z9, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    str z10, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    str z11, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    str z12, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    str z13, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    str z14, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    str z15, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    str z16, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    str z17, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    str z18, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    str z19, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    str z20, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    str z21, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    str z22, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    str z23, [sp, #17, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    str x19, [sp, #-32]! // 8-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_reg_x x19, 32
 ; CHECK-NEXT:    str x28, [sp, #8] // 8-byte Folded Spill
@@ -622,38 +694,38 @@ define void @f5(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_reg x19, 0
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    ldr z9, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    ldr z10, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    ldr z11, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    ldr z12, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    ldr z13, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    ldr z14, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    ldr z15, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    ldr z16, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    ldr z17, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    ldr z18, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    ldr z19, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    ldr z20, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    ldr z21, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    ldr z22, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    ldr z23, [sp, #17, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
@@ -670,8 +742,16 @@ define void @f5(i64 %n, <vscale x 2 x i64> %x) {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    addvl sp, sp, #17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    ldr p12, [sp, #8, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    ldr p13, [sp, #9, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    ldr p14, [sp, #10, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    ldr p15, [sp, #11, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    addvl sp, sp, #18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    .seh_endfunclet
@@ -694,8 +774,8 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    sub sp, sp, #16
 ; CHECK-NEXT:    .seh_stackalloc 16
-; CHECK-NEXT:    addvl sp, sp, #-17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #-18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
@@ -712,38 +792,46 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str p12, [sp, #8, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    str p13, [sp, #9, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    str p14, [sp, #10, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    str p15, [sp, #11, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    str z8, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    str z9, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    str z10, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    str z11, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    str z12, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    str z13, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    str z14, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    str z15, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    str z16, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    str z17, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    str z18, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    str z19, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    str z20, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    str z21, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    str z22, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    str z23, [sp, #17, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    str x19, [sp, #-32]! // 8-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_reg_x x19, 32
 ; CHECK-NEXT:    str x28, [sp, #8] // 8-byte Folded Spill
@@ -755,10 +843,10 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    sub sp, sp, #64
 ; CHECK-NEXT:    mov x0, #-2 // =0xfffffffffffffffe
-; CHECK-NEXT:    addvl x8, x29, #17
+; CHECK-NEXT:    addvl x8, x29, #18
 ; CHECK-NEXT:    mov x19, sp
 ; CHECK-NEXT:    stur x0, [x8, #16]
-; CHECK-NEXT:    addvl x8, x29, #17
+; CHECK-NEXT:    addvl x8, x29, #18
 ; CHECK-NEXT:    ldr x1, [x8, #32]
 ; CHECK-NEXT:  .Ltmp0:
 ; CHECK-NEXT:    add x0, x19, #0
@@ -776,38 +864,38 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:    .seh_save_reg x19, 0
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    ldr z9, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    ldr z10, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    ldr z11, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    ldr z12, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    ldr z13, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    ldr z14, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    ldr z15, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    ldr z16, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    ldr z17, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    ldr z18, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    ldr z19, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    ldr z20, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    ldr z21, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    ldr z22, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    ldr z23, [sp, #17, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
@@ -824,10 +912,18 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p11, 7
+; CHECK-NEXT:    ldr p12, [sp, #8, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    ldr p13, [sp, #9, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    ldr p14, [sp, #10, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    ldr p15, [sp, #11, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p15, 11
 ; CHECK-NEXT:    add sp, sp, #16
 ; CHECK-NEXT:    .seh_stackalloc 16
-; CHECK-NEXT:    addvl sp, sp, #17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    add sp, sp, #16
 ; CHECK-NEXT:    .seh_stackalloc 16
 ; CHECK-NEXT:    .seh_endepilogue
@@ -845,8 +941,8 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:  "?dtor$2@?0?f6 at 4HA":
 ; CHECK-NEXT:  .seh_proc "?dtor$2@?0?f6 at 4HA"
 ; CHECK-NEXT:  .LBB5_2: // %ehcleanup
-; CHECK-NEXT:    addvl sp, sp, #-17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #-18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
@@ -863,38 +959,46 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str p12, [sp, #8, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    str p13, [sp, #9, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    str p14, [sp, #10, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    str p15, [sp, #11, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    str z8, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    str z9, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    str z10, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    str z11, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    str z12, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    str z13, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    str z14, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    str z15, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    str z16, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    str z17, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    str z18, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    str z19, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    str z20, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    str z21, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    str z22, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    str z23, [sp, #17, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    str x19, [sp, #-32]! // 8-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_reg_x x19, 32
 ; CHECK-NEXT:    str x28, [sp, #8] // 8-byte Folded Spill
@@ -912,38 +1016,38 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:    .seh_save_reg x19, 0
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    ldr z9, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    ldr z10, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    ldr z11, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    ldr z12, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    ldr z13, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    ldr z14, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    ldr z15, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    ldr z16, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    ldr z17, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    ldr z18, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    ldr z19, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    ldr z20, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    ldr z21, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    ldr z22, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    ldr z23, [sp, #17, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
@@ -960,8 +1064,16 @@ define void @f6(<vscale x 2 x i64> %x, [8 x i64] %pad, i64 %n9) personality ptr
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    addvl sp, sp, #17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    ldr p12, [sp, #8, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    ldr p13, [sp, #9, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    ldr p14, [sp, #10, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    ldr p15, [sp, #11, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    addvl sp, sp, #18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
   %p1 = alloca [8 x i64]
@@ -1095,8 +1207,8 @@ define void @f10(i64 %n, <vscale x 2 x i64> %x) "frame-pointer"="all" {
 ; CHECK-LABEL: f10:
 ; CHECK:       .seh_proc f10
 ; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    addvl sp, sp, #-17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    addvl sp, sp, #-18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    str p4, [sp] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    str p5, [sp, #1, mul vl] // 2-byte Folded Spill
@@ -1113,38 +1225,46 @@ define void @f10(i64 %n, <vscale x 2 x i64> %x) "frame-pointer"="all" {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    str p11, [sp, #7, mul vl] // 2-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    str z9, [sp, #2, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    str z10, [sp, #3, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    str z11, [sp, #4, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    str z12, [sp, #5, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    str z13, [sp, #6, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    str z14, [sp, #7, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    str z15, [sp, #8, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    str z17, [sp, #10, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    str z18, [sp, #11, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    str z19, [sp, #12, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    str z20, [sp, #13, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    str z21, [sp, #14, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    str z22, [sp, #15, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    str z23, [sp, #16, mul vl] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    str p12, [sp, #8, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    str p13, [sp, #9, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    str p14, [sp, #10, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    str p15, [sp, #11, mul vl] // 2-byte Folded Spill
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    str z8, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    str z9, [sp, #3, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    str z10, [sp, #4, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    str z11, [sp, #5, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    str z12, [sp, #6, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    str z13, [sp, #7, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    str z14, [sp, #8, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    str z15, [sp, #9, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    str z16, [sp, #10, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    str z17, [sp, #11, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    str z18, [sp, #12, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    str z19, [sp, #13, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    str z20, [sp, #14, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    str z21, [sp, #15, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    str z22, [sp, #16, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    str z23, [sp, #17, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    str x28, [sp, #-32]! // 8-byte Folded Spill
 ; CHECK-NEXT:    .seh_save_reg_x x28, 32
 ; CHECK-NEXT:    stp x29, x30, [sp, #8] // 16-byte Folded Spill
@@ -1169,38 +1289,38 @@ define void @f10(i64 %n, <vscale x 2 x i64> %x) "frame-pointer"="all" {
 ; CHECK-NEXT:    .seh_save_reg x28, 0
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z8, 1
-; CHECK-NEXT:    ldr z9, [sp, #2, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z9, 2
-; CHECK-NEXT:    ldr z10, [sp, #3, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z10, 3
-; CHECK-NEXT:    ldr z11, [sp, #4, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z11, 4
-; CHECK-NEXT:    ldr z12, [sp, #5, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z12, 5
-; CHECK-NEXT:    ldr z13, [sp, #6, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z13, 6
-; CHECK-NEXT:    ldr z14, [sp, #7, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z14, 7
-; CHECK-NEXT:    ldr z15, [sp, #8, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z15, 8
-; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z16, 9
-; CHECK-NEXT:    ldr z17, [sp, #10, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z17, 10
-; CHECK-NEXT:    ldr z18, [sp, #11, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z18, 11
-; CHECK-NEXT:    ldr z19, [sp, #12, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z19, 12
-; CHECK-NEXT:    ldr z20, [sp, #13, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z20, 13
-; CHECK-NEXT:    ldr z21, [sp, #14, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z21, 14
-; CHECK-NEXT:    ldr z22, [sp, #15, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z22, 15
-; CHECK-NEXT:    ldr z23, [sp, #16, mul vl] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_zreg z23, 16
+; CHECK-NEXT:    ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z8, 2
+; CHECK-NEXT:    ldr z9, [sp, #3, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z9, 3
+; CHECK-NEXT:    ldr z10, [sp, #4, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z10, 4
+; CHECK-NEXT:    ldr z11, [sp, #5, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z11, 5
+; CHECK-NEXT:    ldr z12, [sp, #6, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z12, 6
+; CHECK-NEXT:    ldr z13, [sp, #7, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z13, 7
+; CHECK-NEXT:    ldr z14, [sp, #8, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z14, 8
+; CHECK-NEXT:    ldr z15, [sp, #9, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z15, 9
+; CHECK-NEXT:    ldr z16, [sp, #10, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z16, 10
+; CHECK-NEXT:    ldr z17, [sp, #11, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z17, 11
+; CHECK-NEXT:    ldr z18, [sp, #12, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z18, 12
+; CHECK-NEXT:    ldr z19, [sp, #13, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z19, 13
+; CHECK-NEXT:    ldr z20, [sp, #14, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z20, 14
+; CHECK-NEXT:    ldr z21, [sp, #15, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z21, 15
+; CHECK-NEXT:    ldr z22, [sp, #16, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z22, 16
+; CHECK-NEXT:    ldr z23, [sp, #17, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    .seh_save_zreg z23, 17
 ; CHECK-NEXT:    ldr p4, [sp] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p4, 0
 ; CHECK-NEXT:    ldr p5, [sp, #1, mul vl] // 2-byte Folded Reload
@@ -1217,8 +1337,16 @@ define void @f10(i64 %n, <vscale x 2 x i64> %x) "frame-pointer"="all" {
 ; CHECK-NEXT:    .seh_save_preg p10, 6
 ; CHECK-NEXT:    ldr p11, [sp, #7, mul vl] // 2-byte Folded Reload
 ; CHECK-NEXT:    .seh_save_preg p11, 7
-; CHECK-NEXT:    addvl sp, sp, #17
-; CHECK-NEXT:    .seh_allocz 17
+; CHECK-NEXT:    ldr p12, [sp, #8, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p12, 8
+; CHECK-NEXT:    ldr p13, [sp, #9, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p13, 9
+; CHECK-NEXT:    ldr p14, [sp, #10, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p14, 10
+; CHECK-NEXT:    ldr p15, [sp, #11, mul vl] // 2-byte Folded Reload
+; CHECK-NEXT:    .seh_save_preg p15, 11
+; CHECK-NEXT:    addvl sp, sp, #18
+; CHECK-NEXT:    .seh_allocz 18
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    ret
 ; CHECK-NEXT:    .seh_endfunclet
@@ -1398,7 +1526,7 @@ entry:
   ret i32 0
 }
 
-define tailcc void @f15(double %d, <vscale x 4 x i32> %vs, [9 x i64]) {
+define tailcc void @f15(double %d, <vscale x 4 x i32> %vs, [9 x i64], i32 %i) {
 ; CHECK-LABEL: f15:
 ; CHECK:       .seh_proc f15
 ; CHECK-NEXT:  // %bb.0:
@@ -1415,9 +1543,12 @@ define tailcc void @f15(double %d, <vscale x 4 x i32> %vs, [9 x i64]) {
 ; CHECK-NEXT:    addvl sp, sp, #-1
 ; CHECK-NEXT:    .seh_allocz 1
 ; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    addvl x8, sp, #2
 ; CHECK-NEXT:    //APP
 ; CHECK-NEXT:    //NO_APP
 ; CHECK-NEXT:    stp d0, d0, [sp, #8]
+; CHECK-NEXT:    ldr w8, [x8, #104]
+; CHECK-NEXT:    str w8, [sp, #8]
 ; CHECK-NEXT:    .seh_startepilogue
 ; CHECK-NEXT:    addvl sp, sp, #1
 ; CHECK-NEXT:    .seh_allocz 1
@@ -1444,5 +1575,6 @@ define tailcc void @f15(double %d, <vscale x 4 x i32> %vs, [9 x i64]) {
   tail call void asm sideeffect "", "~{d8},~{x28}"() #1
   store double %d, ptr %a
   store double %d, ptr %b
+  store i32 %i, ptr %a
   ret void
 }



More information about the llvm-commits mailing list