Author: Zeyi Xu Date: 2026-09-25T10:00:10+08:00 New Revision: 4880e16f73dfc25762a857b9c08ad2bd5c14c8e0
URL: https://github.com/llvm/llvm-project/commit/4880e16f73dfc25762a857b9c08ad2bd5c14c8e0 DIFF: https://github.com/llvm/llvm-project/commit/4880e16f73dfc25762a857b9c08ad2bd5c14c8e0.diff LOG: [RISCV] Support frame pointers in SiFive CLIC preemptible handlers (#221318) This commit adds frame-pointer support for SiFive CLIC preemptible handlers by using t0 to save mcause and mepc to dedicated stack slots in both cases. Added: llvm/test/CodeGen/RISCV/sifive-interrupt-frame-pointer.ll Modified: clang/docs/ReleaseNotes.md llvm/lib/Target/RISCV/RISCVFrameLowering.cpp llvm/lib/Target/RISCV/RISCVISelLowering.cpp llvm/test/CodeGen/RISCV/sifive-interrupt-attr.ll llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll Removed: llvm/test/CodeGen/RISCV/sifive-interrupt-attr-err.ll ################################################################################ diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 344cfebe166883..f6cdca91cea103 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -872,8 +872,7 @@ features cannot lower the translation-unit ABI level; - Added a new warning when the same interrupt type is specified more than once in a RISC-V `interrupt` attribute. -- SiFive CLIC preemptible interrupt handlers now diagnose unsupported frame - pointers instead of producing a backend fatal error. +- SiFive CLIC preemptible interrupt handlers now support frame pointers. - Added `-march=native` for better compatibility with ARM, AArch64, and X86. This option will be treated like `-mcpu=native` if `-mcpu` is not present. If diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 4732b4153aae63..648df0690fa20e 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -265,9 +265,7 @@ createSiFivePreemptibleInterruptFrameEntries(MachineFunction &MF, *MF.getSubtarget<RISCVSubtarget>().getRegisterInfo(); MachineFrameInfo &MFI = MF.getFrameInfo(); - // Create two frame objects for spilling X8 and X9, which will be done in - // `emitSiFiveCLICPreemptibleSaves`. This is in addition to any other stack - // objects we might have for X8 and X9, as they might be saved twice. + // Create two frame objects for saving `mcause` and `mepc`. for (int I = 0; I < 2; ++I) { int FI = MFI.CreateStackObject(TRI.getSpillSize(RC), TRI.getSpillAlign(RC), true); @@ -275,6 +273,16 @@ createSiFivePreemptibleInterruptFrameEntries(MachineFunction &MF, } } +// The scratch register retains an ordinary CSI slot, but its save and restore +// are emitted explicitly as part of the SiFive CLIC interrupt sequence. +static int getSiFiveCLICScratchFrameIndex(const MachineFunction &MF) { + const auto &CSI = MF.getFrameInfo().getCalleeSavedInfo(); + auto ScratchCS = llvm::find_if( + CSI, [](const CalleeSavedInfo &CS) { return CS.getReg() == RISCV::X5; }); + assert(ScratchCS != CSI.end() && "Missing SiFive CLIC scratch spill slot"); + return ScratchCS->getFrameIdx(); +} + static void emitSiFiveCLICPreemptibleSaves(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, @@ -287,34 +295,30 @@ static void emitSiFiveCLICPreemptibleSaves(MachineFunction &MF, const auto &STI = MF.getSubtarget<RISCVSubtarget>(); const RISCVInstrInfo *TII = STI.getInstrInfo(); - // FIXME: CFI Information here is nonexistent/wrong. + // FIXME: CFI information for `mcause` and `mepc` is missing. - // X8 and X9 might be stored into the stack twice, initially into the - // `interruptCSRFrameIndex` here, and then maybe again into their CSI frame - // index. - // - // This is done instead of telling the register allocator that we need two - // VRegs to store the value of `mcause` and `mepc` through the instruction, - // which affects other passes. - TII->storeRegToStackSlot(MBB, MBBI, RISCV::X8, /* IsKill=*/true, - RVFI->getInterruptCSRFrameIndex(0), - &RISCV::GPRRegClass, Register(), - MachineInstr::FrameSetup); - TII->storeRegToStackSlot(MBB, MBBI, RISCV::X9, /* IsKill=*/true, - RVFI->getInterruptCSRFrameIndex(1), + // Preserve X5 before using it to save the interrupt CSRs. Other GPRs + // are saved by the ordinary spill sequence after preemption is enabled. + int ScratchFI = getSiFiveCLICScratchFrameIndex(MF); + TII->storeRegToStackSlot(MBB, MBBI, RISCV::X5, /*IsKill=*/true, ScratchFI, &RISCV::GPRRegClass, Register(), MachineInstr::FrameSetup); + if (needsDwarfCFI(MF)) + CFIInstBuilder(MBB, MBBI, MachineInstr::FrameSetup) + .buildOffset(RISCV::X5, MF.getFrameInfo().getObjectOffset(ScratchFI)); - // Put `mcause` into X8 (s0), and `mepc` into X9 (s1). If either of these are - // used in the function, then they will appear in `getUnmanagedCSI` and will - // be saved again. BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRS)) - .addReg(RISCV::X8, RegState::Define) + .addReg(RISCV::X5, RegState::Define) .addImm(RISCVSysReg::mcause) .addReg(RISCV::X0) .setMIFlag(MachineInstr::FrameSetup); + TII->storeRegToStackSlot(MBB, MBBI, RISCV::X5, /* IsKill=*/true, + RVFI->getInterruptCSRFrameIndex(0), + &RISCV::GPRRegClass, Register(), + MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRS)) - .addReg(RISCV::X9, RegState::Define) + .addReg(RISCV::X5, RegState::Define) .addImm(RISCVSysReg::mepc) .addReg(RISCV::X0) .setMIFlag(MachineInstr::FrameSetup); @@ -325,11 +329,16 @@ static void emitSiFiveCLICPreemptibleSaves(MachineFunction &MF, .addImm(RISCVSysReg::mstatus) .addImm(8) .setMIFlag(MachineInstr::FrameSetup); + TII->storeRegToStackSlot(MBB, MBBI, RISCV::X5, /* IsKill=*/true, + RVFI->getInterruptCSRFrameIndex(1), + &RISCV::GPRRegClass, Register(), + MachineInstr::FrameSetup); } static void emitSiFiveCLICPreemptibleRestores(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + CFIInstBuilder &CFIBuilder, const DebugLoc &DL) { auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); @@ -339,7 +348,14 @@ static void emitSiFiveCLICPreemptibleRestores(MachineFunction &MF, const auto &STI = MF.getSubtarget<RISCVSubtarget>(); const RISCVInstrInfo *TII = STI.getInstrInfo(); - // FIXME: CFI Information here is nonexistent/wrong. + // FIXME: CFI information for `mcause` and `mepc` is missing. + + // Load mepc while preemption is still enabled. A nested handler preserves + // X5. Interrupts only need to be disabled before writing the CSRs back. + TII->loadRegFromStackSlot(MBB, MBBI, RISCV::X5, + RVFI->getInterruptCSRFrameIndex(1), + &RISCV::GPRRegClass, Register(), + RISCV::NoSubRegister, MachineInstr::FrameDestroy); // Disable interrupts. BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRCI)) @@ -348,30 +364,32 @@ static void emitSiFiveCLICPreemptibleRestores(MachineFunction &MF, .addImm(8) .setMIFlag(MachineInstr::FrameDestroy); - // Restore `mepc` from x9 (s1), and `mcause` from x8 (s0). If either were used - // in the function, they have already been restored once, so now have the - // value stored in `emitSiFiveCLICPreemptibleSaves`. + // Restore `mepc` and `mcause` through X5, then restore the value X5 held + // on entry to the handler. BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRW)) .addReg(RISCV::X0, RegState::Define) .addImm(RISCVSysReg::mepc) - .addReg(RISCV::X9, RegState::Kill) + .addReg(RISCV::X5, RegState::Kill) .setMIFlag(MachineInstr::FrameDestroy); + + TII->loadRegFromStackSlot(MBB, MBBI, RISCV::X5, + RVFI->getInterruptCSRFrameIndex(0), + &RISCV::GPRRegClass, Register(), + RISCV::NoSubRegister, MachineInstr::FrameDestroy); BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRW)) .addReg(RISCV::X0, RegState::Define) .addImm(RISCVSysReg::mcause) - .addReg(RISCV::X8, RegState::Kill) + .addReg(RISCV::X5, RegState::Kill) .setMIFlag(MachineInstr::FrameDestroy); - // X8 and X9 need to be restored to their values on function entry, which we - // saved onto the stack in `emitSiFiveCLICPreemptibleSaves`. - TII->loadRegFromStackSlot(MBB, MBBI, RISCV::X9, - RVFI->getInterruptCSRFrameIndex(1), - &RISCV::GPRRegClass, Register(), - RISCV::NoSubRegister, MachineInstr::FrameDestroy); - TII->loadRegFromStackSlot(MBB, MBBI, RISCV::X8, - RVFI->getInterruptCSRFrameIndex(0), + // The ordinary reloads have finished. Recover the interrupted value of X5 + // only after it has restored both CSRs. + TII->loadRegFromStackSlot(MBB, MBBI, RISCV::X5, + getSiFiveCLICScratchFrameIndex(MF), &RISCV::GPRRegClass, Register(), RISCV::NoSubRegister, MachineInstr::FrameDestroy); + if (needsDwarfCFI(MF)) + CFIBuilder.buildRestore(RISCV::X5); } // Get the ID of the libcall used for spilling and restoring callee saved @@ -593,6 +611,20 @@ getUnmanagedCSI(const MachineFunction &MF, return NonLibcallCSI; } +// Exclude X5 from ordinary spills and restores for SiFive CLIC preemptible +// handlers, which save and restore it explicitly. +static SmallVector<CalleeSavedInfo, 8> +getUnmanagedInterruptCSI(const MachineFunction &MF, + const std::vector<CalleeSavedInfo> &CSI, + bool ReverseOrder = false) { + auto InterruptCSI = getUnmanagedCSI(MF, CSI, ReverseOrder); + if (MF.getInfo<RISCVMachineFunctionInfo>()->isSiFivePreemptibleInterrupt(MF)) + llvm::erase_if(InterruptCSI, [](const CalleeSavedInfo &CS) { + return CS.getReg() == RISCV::X5; + }); + return InterruptCSI; +} + static SmallVector<CalleeSavedInfo, 8> getRVVCalleeSavedInfo(const MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI) { @@ -1025,9 +1057,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // Skip to before the spills of scalar callee-saved registers // FIXME: assumes exactly one instruction is used to restore each // callee-saved register. - MBBI = - std::prev(MBBI, getRVVCalleeSavedInfo(MF, CSI).size() + - getUnmanagedCSI(MF, CSI, PreferAscendingLS).size()); + MBBI = std::prev( + MBBI, getRVVCalleeSavedInfo(MF, CSI).size() + + getUnmanagedInterruptCSI(MF, CSI, PreferAscendingLS).size()); CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::FrameSetup); bool NeedsDwarfCFI = needsDwarfCFI(MF); @@ -1146,14 +1178,15 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // to the stack, not before. // FIXME: assumes exactly one instruction is used to save each callee-saved // register. - std::advance(MBBI, getUnmanagedCSI(MF, CSI, PreferAscendingLS).size()); + std::advance(MBBI, + getUnmanagedInterruptCSI(MF, CSI, PreferAscendingLS).size()); CFIBuilder.setInsertPoint(MBBI); // Iterate over list of callee-saved registers and emit .cfi_offset // directives. if (NeedsDwarfCFI) { for (const CalleeSavedInfo &CS : - getUnmanagedCSI(MF, CSI, PreferAscendingLS)) { + getUnmanagedInterruptCSI(MF, CSI, PreferAscendingLS)) { MCRegister Reg = CS.getReg(); int64_t Offset = MFI.getObjectOffset(CS.getFrameIdx()); // Emit CFI for both sub-registers. The even register is at the base @@ -1404,8 +1437,9 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, // FIXME: assumes exactly one instruction is used to restore each // callee-saved register. MBBI = std::next(FirstScalarCSRRestoreInsn, - getUnmanagedCSI(MF, CSI, PreferAscendingLS).size()); + getUnmanagedInterruptCSI(MF, CSI, PreferAscendingLS).size()); CFIBuilder.setInsertPoint(MBBI); + emitSiFiveCLICPreemptibleRestores(MF, MBB, MBBI, CFIBuilder, DL); if (getLibCallID(MF, CSI) != -1) { // tail __riscv_restore_[0-12] instruction is considered as a terminator, @@ -1423,7 +1457,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, // Recover callee-saved registers. if (NeedsDwarfCFI) { for (const CalleeSavedInfo &CS : - getUnmanagedCSI(MF, CSI, PreferAscendingLS)) { + getUnmanagedInterruptCSI(MF, CSI, PreferAscendingLS)) { MCRegister Reg = CS.getReg(); // Emit CFI for both sub-registers. if (RISCV::GPRPairRegClass.contains(Reg)) { @@ -1468,8 +1502,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, } } - emitSiFiveCLICPreemptibleRestores(MF, MBB, MBBI, DL); - // Deallocate stack if StackSize isn't a zero yet. If this is a QCI interrupt // function, there will be a leftover offset which is deallocated by // `QC.C.MILEAVERET`, otherwise getQCIInterruptStackSize() will be 0. @@ -1650,7 +1682,10 @@ RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, MaxCSFI = std::max(CSI.front().getFrameIdx(), CSI.back().getFrameIdx()); } - if (FI >= MinCSFI && FI <= MaxCSFI) { + bool IsInterruptCSR = RVFI->isSiFivePreemptibleInterrupt(MF) && + (FI == RVFI->getInterruptCSRFrameIndex(0) || + FI == RVFI->getInterruptCSRFrameIndex(1)); + if ((FI >= MinCSFI && FI <= MaxCSFI) || IsInterruptCSR) { FrameReg = SPReg; if (FirstSPAdjustAmount) @@ -1868,8 +1903,12 @@ void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF, if (hasBP(MF)) SavedRegs.set(RISCVABI::getBPReg()); - // When using cm.push/pop we must save X27 if we save X26. auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); + // X5 is used as a temporary for saving and restoring `mcause` and `mepc`. + if (RVFI->isSiFivePreemptibleInterrupt(MF)) + SavedRegs.set(RISCV::X5); + + // When using cm.push/pop we must save X27 if we save X26. if (RVFI->isPushable(MF) && SavedRegs.test(RISCV::X26)) SavedRegs.set(RISCV::X27); @@ -2491,10 +2530,10 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters( // Manually spill values not spilled by libcall & Push/Pop. const auto &UnmanagedCSI = - getUnmanagedCSI(*MF, CSI, STI.preferAscendingLoadStore()); + getUnmanagedInterruptCSI(*MF, CSI, STI.preferAscendingLoadStore()); const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI); - auto storeRegsToStackSlots = [&](decltype(UnmanagedCSI) CSInfo) { + auto storeRegsToStackSlots = [&](ArrayRef<CalleeSavedInfo> CSInfo) { for (auto &CS : CSInfo) { // Insert the spill to the stack frame. MCRegister Reg = CS.getReg(); @@ -2585,10 +2624,10 @@ bool RISCVFrameLowering::restoreCalleeSavedRegisters( // loading RA and return by RA. loadRegFromStackSlot can insert // multiple instructions. const auto &UnmanagedCSI = - getUnmanagedCSI(*MF, CSI, STI.preferAscendingLoadStore()); + getUnmanagedInterruptCSI(*MF, CSI, STI.preferAscendingLoadStore()); const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI); - auto loadRegFromStackSlot = [&](decltype(UnmanagedCSI) CSInfo) { + auto loadRegFromStackSlot = [&](ArrayRef<CalleeSavedInfo> CSInfo) { for (auto &CS : CSInfo) { MCRegister Reg = CS.getReg(); const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 7a5905fc4b3ea5..f408f6da608215 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -27723,12 +27723,6 @@ SDValue RISCVTargetLowering::LowerFormalArguments( if (Kind == "rnmi" && !Subtarget.hasStdExtSmrnmi()) reportFatalUsageError("'rnmi' interrupt kind requires Srnmi extension"); - const TargetFrameLowering *TFI = Subtarget.getFrameLowering(); - if (Kind.starts_with("SiFive-CLIC-preemptible") && TFI->hasFP(MF)) - Func.getContext().diagnose(DiagnosticInfoUnsupported{ - Func, - "'SiFive-CLIC-preemptible' interrupt functions cannot have a frame " - "pointer"}); } EVT PtrVT = getPointerTy(DAG.getDataLayout()); diff --git a/llvm/test/CodeGen/RISCV/sifive-interrupt-attr-err.ll b/llvm/test/CodeGen/RISCV/sifive-interrupt-attr-err.ll deleted file mode 100644 index f0e1f16cf6e54b..00000000000000 --- a/llvm/test/CodeGen/RISCV/sifive-interrupt-attr-err.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: not llc -mtriple riscv32-unknown-elf -mattr=+experimental-xsfmclic -o - %s 2>&1 \ -; RUN: | FileCheck %s -; RUN: not llc -mtriple riscv64-unknown-elf -mattr=+experimental-xsfmclic -o - %s 2>&1 \ -; RUN: | FileCheck %s - -;; Test that these report regular errors. - -; CHECK: error: <unknown>:0:0: in function preemptible void (): 'SiFive-CLIC-preemptible' interrupt functions cannot have a frame pointer - -define void @preemptible() "interrupt"="SiFive-CLIC-preemptible" "frame-pointer"="all" { - ret void -} diff --git a/llvm/test/CodeGen/RISCV/sifive-interrupt-attr.ll b/llvm/test/CodeGen/RISCV/sifive-interrupt-attr.ll index a7dead74716777..7afcc28c1343d8 100644 --- a/llvm/test/CodeGen/RISCV/sifive-interrupt-attr.ll +++ b/llvm/test/CodeGen/RISCV/sifive-interrupt-attr.ll @@ -11,7 +11,7 @@ ; "preemptible" means that `mcause` and `mepc` should be saved and interrupts ; should be re-enabled by setting a bit in `mstatus`. -; FIXME: A lot of the CFI information here is wrong. +; FIXME: CFI information for the stack swap and CSRs is still missing. define void @stack_swap_empty() "interrupt"="SiFive-CLIC-stack-swap" { ; RV32-LABEL: stack_swap_empty: @@ -78,35 +78,43 @@ define void @preemptible_empty() "interrupt"="SiFive-CLIC-preemptible" { ; RV32: # %bb.0: ; RV32-NEXT: addi sp, sp, -16 ; RV32-NEXT: .cfi_def_cfa_offset 16 -; RV32-NEXT: sw s0, 12(sp) # 4-byte Folded Spill -; RV32-NEXT: sw s1, 8(sp) # 4-byte Folded Spill -; RV32-NEXT: csrr s0, mcause -; RV32-NEXT: csrr s1, mepc +; RV32-NEXT: sw t0, 4(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -12 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 12(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc ; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 8(sp) # 4-byte Folded Spill +; RV32-NEXT: lw t0, 8(sp) # 4-byte Folded Reload ; RV32-NEXT: csrci mstatus, 8 -; RV32-NEXT: csrw mepc, s1 -; RV32-NEXT: csrw mcause, s0 -; RV32-NEXT: lw s1, 8(sp) # 4-byte Folded Reload -; RV32-NEXT: lw s0, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 4(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 ; RV32-NEXT: addi sp, sp, 16 ; RV32-NEXT: .cfi_def_cfa_offset 0 ; RV32-NEXT: mret ; ; RV64-LABEL: preemptible_empty: ; RV64: # %bb.0: -; RV64-NEXT: addi sp, sp, -16 -; RV64-NEXT: .cfi_def_cfa_offset 16 -; RV64-NEXT: sd s0, 8(sp) # 8-byte Folded Spill -; RV64-NEXT: sd s1, 0(sp) # 8-byte Folded Spill -; RV64-NEXT: csrr s0, mcause -; RV64-NEXT: csrr s1, mepc +; RV64-NEXT: addi sp, sp, -32 +; RV64-NEXT: .cfi_def_cfa_offset 32 +; RV64-NEXT: sd t0, 8(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -24 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 24(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc ; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 16(sp) # 8-byte Folded Spill +; RV64-NEXT: ld t0, 16(sp) # 8-byte Folded Reload ; RV64-NEXT: csrci mstatus, 8 -; RV64-NEXT: csrw mepc, s1 -; RV64-NEXT: csrw mcause, s0 -; RV64-NEXT: ld s1, 0(sp) # 8-byte Folded Reload -; RV64-NEXT: ld s0, 8(sp) # 8-byte Folded Reload -; RV64-NEXT: addi sp, sp, 16 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 24(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: addi sp, sp, 32 ; RV64-NEXT: .cfi_def_cfa_offset 0 ; RV64-NEXT: mret ret void @@ -118,16 +126,20 @@ define void @both_empty() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV32-NEXT: csrrw sp, sf.mscratchcsw, sp ; RV32-NEXT: addi sp, sp, -16 ; RV32-NEXT: .cfi_def_cfa_offset 16 -; RV32-NEXT: sw s0, 12(sp) # 4-byte Folded Spill -; RV32-NEXT: sw s1, 8(sp) # 4-byte Folded Spill -; RV32-NEXT: csrr s0, mcause -; RV32-NEXT: csrr s1, mepc +; RV32-NEXT: sw t0, 4(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -12 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 12(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc ; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 8(sp) # 4-byte Folded Spill +; RV32-NEXT: lw t0, 8(sp) # 4-byte Folded Reload ; RV32-NEXT: csrci mstatus, 8 -; RV32-NEXT: csrw mepc, s1 -; RV32-NEXT: csrw mcause, s0 -; RV32-NEXT: lw s1, 8(sp) # 4-byte Folded Reload -; RV32-NEXT: lw s0, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 4(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 ; RV32-NEXT: addi sp, sp, 16 ; RV32-NEXT: .cfi_def_cfa_offset 0 ; RV32-NEXT: csrrw sp, sf.mscratchcsw, sp @@ -136,19 +148,23 @@ define void @both_empty() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV64-LABEL: both_empty: ; RV64: # %bb.0: ; RV64-NEXT: csrrw sp, sf.mscratchcsw, sp -; RV64-NEXT: addi sp, sp, -16 -; RV64-NEXT: .cfi_def_cfa_offset 16 -; RV64-NEXT: sd s0, 8(sp) # 8-byte Folded Spill -; RV64-NEXT: sd s1, 0(sp) # 8-byte Folded Spill -; RV64-NEXT: csrr s0, mcause -; RV64-NEXT: csrr s1, mepc +; RV64-NEXT: addi sp, sp, -32 +; RV64-NEXT: .cfi_def_cfa_offset 32 +; RV64-NEXT: sd t0, 8(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -24 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 24(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc ; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 16(sp) # 8-byte Folded Spill +; RV64-NEXT: ld t0, 16(sp) # 8-byte Folded Reload ; RV64-NEXT: csrci mstatus, 8 -; RV64-NEXT: csrw mepc, s1 -; RV64-NEXT: csrw mcause, s0 -; RV64-NEXT: ld s1, 0(sp) # 8-byte Folded Reload -; RV64-NEXT: ld s0, 8(sp) # 8-byte Folded Reload -; RV64-NEXT: addi sp, sp, 16 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 24(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: addi sp, sp, 32 ; RV64-NEXT: .cfi_def_cfa_offset 0 ; RV64-NEXT: csrrw sp, sf.mscratchcsw, sp ; RV64-NEXT: mret @@ -484,13 +500,14 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV32: # %bb.0: ; RV32-NEXT: addi sp, sp, -80 ; RV32-NEXT: .cfi_def_cfa_offset 80 -; RV32-NEXT: sw s0, 76(sp) # 4-byte Folded Spill -; RV32-NEXT: sw s1, 72(sp) # 4-byte Folded Spill -; RV32-NEXT: csrr s0, mcause -; RV32-NEXT: csrr s1, mepc +; RV32-NEXT: sw t0, 64(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 76(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc ; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 72(sp) # 4-byte Folded Spill ; RV32-NEXT: sw ra, 68(sp) # 4-byte Folded Spill -; RV32-NEXT: sw t0, 64(sp) # 4-byte Folded Spill ; RV32-NEXT: sw t1, 60(sp) # 4-byte Folded Spill ; RV32-NEXT: sw t2, 56(sp) # 4-byte Folded Spill ; RV32-NEXT: sw a0, 52(sp) # 4-byte Folded Spill @@ -506,7 +523,6 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV32-NEXT: sw t5, 12(sp) # 4-byte Folded Spill ; RV32-NEXT: sw t6, 8(sp) # 4-byte Folded Spill ; RV32-NEXT: .cfi_offset ra, -12 -; RV32-NEXT: .cfi_offset t0, -16 ; RV32-NEXT: .cfi_offset t1, -20 ; RV32-NEXT: .cfi_offset t2, -24 ; RV32-NEXT: .cfi_offset a0, -28 @@ -523,7 +539,6 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV32-NEXT: .cfi_offset t6, -72 ; RV32-NEXT: call callee ; RV32-NEXT: lw ra, 68(sp) # 4-byte Folded Reload -; RV32-NEXT: lw t0, 64(sp) # 4-byte Folded Reload ; RV32-NEXT: lw t1, 60(sp) # 4-byte Folded Reload ; RV32-NEXT: lw t2, 56(sp) # 4-byte Folded Reload ; RV32-NEXT: lw a0, 52(sp) # 4-byte Folded Reload @@ -538,8 +553,14 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV32-NEXT: lw t4, 16(sp) # 4-byte Folded Reload ; RV32-NEXT: lw t5, 12(sp) # 4-byte Folded Reload ; RV32-NEXT: lw t6, 8(sp) # 4-byte Folded Reload -; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: lw t0, 72(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 76(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 64(sp) # 4-byte Folded Reload ; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra ; RV32-NEXT: .cfi_restore t1 ; RV32-NEXT: .cfi_restore t2 ; RV32-NEXT: .cfi_restore a0 @@ -554,11 +575,6 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV32-NEXT: .cfi_restore t4 ; RV32-NEXT: .cfi_restore t5 ; RV32-NEXT: .cfi_restore t6 -; RV32-NEXT: csrci mstatus, 8 -; RV32-NEXT: csrw mepc, s1 -; RV32-NEXT: csrw mcause, s0 -; RV32-NEXT: lw s1, 72(sp) # 4-byte Folded Reload -; RV32-NEXT: lw s0, 76(sp) # 4-byte Folded Reload ; RV32-NEXT: addi sp, sp, 80 ; RV32-NEXT: .cfi_def_cfa_offset 0 ; RV32-NEXT: mret @@ -567,13 +583,14 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV64: # %bb.0: ; RV64-NEXT: addi sp, sp, -144 ; RV64-NEXT: .cfi_def_cfa_offset 144 -; RV64-NEXT: sd s0, 136(sp) # 8-byte Folded Spill -; RV64-NEXT: sd s1, 128(sp) # 8-byte Folded Spill -; RV64-NEXT: csrr s0, mcause -; RV64-NEXT: csrr s1, mepc +; RV64-NEXT: sd t0, 112(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 136(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc ; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 128(sp) # 8-byte Folded Spill ; RV64-NEXT: sd ra, 120(sp) # 8-byte Folded Spill -; RV64-NEXT: sd t0, 112(sp) # 8-byte Folded Spill ; RV64-NEXT: sd t1, 104(sp) # 8-byte Folded Spill ; RV64-NEXT: sd t2, 96(sp) # 8-byte Folded Spill ; RV64-NEXT: sd a0, 88(sp) # 8-byte Folded Spill @@ -589,7 +606,6 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV64-NEXT: sd t5, 8(sp) # 8-byte Folded Spill ; RV64-NEXT: sd t6, 0(sp) # 8-byte Folded Spill ; RV64-NEXT: .cfi_offset ra, -24 -; RV64-NEXT: .cfi_offset t0, -32 ; RV64-NEXT: .cfi_offset t1, -40 ; RV64-NEXT: .cfi_offset t2, -48 ; RV64-NEXT: .cfi_offset a0, -56 @@ -606,7 +622,6 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV64-NEXT: .cfi_offset t6, -144 ; RV64-NEXT: call callee ; RV64-NEXT: ld ra, 120(sp) # 8-byte Folded Reload -; RV64-NEXT: ld t0, 112(sp) # 8-byte Folded Reload ; RV64-NEXT: ld t1, 104(sp) # 8-byte Folded Reload ; RV64-NEXT: ld t2, 96(sp) # 8-byte Folded Reload ; RV64-NEXT: ld a0, 88(sp) # 8-byte Folded Reload @@ -621,8 +636,14 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV64-NEXT: ld t4, 16(sp) # 8-byte Folded Reload ; RV64-NEXT: ld t5, 8(sp) # 8-byte Folded Reload ; RV64-NEXT: ld t6, 0(sp) # 8-byte Folded Reload -; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: ld t0, 128(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 136(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 112(sp) # 8-byte Folded Reload ; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra ; RV64-NEXT: .cfi_restore t1 ; RV64-NEXT: .cfi_restore t2 ; RV64-NEXT: .cfi_restore a0 @@ -637,11 +658,6 @@ define void @preeemptible_caller() "interrupt"="SiFive-CLIC-preemptible" { ; RV64-NEXT: .cfi_restore t4 ; RV64-NEXT: .cfi_restore t5 ; RV64-NEXT: .cfi_restore t6 -; RV64-NEXT: csrci mstatus, 8 -; RV64-NEXT: csrw mepc, s1 -; RV64-NEXT: csrw mcause, s0 -; RV64-NEXT: ld s1, 128(sp) # 8-byte Folded Reload -; RV64-NEXT: ld s0, 136(sp) # 8-byte Folded Reload ; RV64-NEXT: addi sp, sp, 144 ; RV64-NEXT: .cfi_def_cfa_offset 0 ; RV64-NEXT: mret @@ -655,13 +671,14 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV32-NEXT: csrrw sp, sf.mscratchcsw, sp ; RV32-NEXT: addi sp, sp, -80 ; RV32-NEXT: .cfi_def_cfa_offset 80 -; RV32-NEXT: sw s0, 76(sp) # 4-byte Folded Spill -; RV32-NEXT: sw s1, 72(sp) # 4-byte Folded Spill -; RV32-NEXT: csrr s0, mcause -; RV32-NEXT: csrr s1, mepc +; RV32-NEXT: sw t0, 64(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 76(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc ; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 72(sp) # 4-byte Folded Spill ; RV32-NEXT: sw ra, 68(sp) # 4-byte Folded Spill -; RV32-NEXT: sw t0, 64(sp) # 4-byte Folded Spill ; RV32-NEXT: sw t1, 60(sp) # 4-byte Folded Spill ; RV32-NEXT: sw t2, 56(sp) # 4-byte Folded Spill ; RV32-NEXT: sw a0, 52(sp) # 4-byte Folded Spill @@ -677,7 +694,6 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV32-NEXT: sw t5, 12(sp) # 4-byte Folded Spill ; RV32-NEXT: sw t6, 8(sp) # 4-byte Folded Spill ; RV32-NEXT: .cfi_offset ra, -12 -; RV32-NEXT: .cfi_offset t0, -16 ; RV32-NEXT: .cfi_offset t1, -20 ; RV32-NEXT: .cfi_offset t2, -24 ; RV32-NEXT: .cfi_offset a0, -28 @@ -694,7 +710,6 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV32-NEXT: .cfi_offset t6, -72 ; RV32-NEXT: call callee ; RV32-NEXT: lw ra, 68(sp) # 4-byte Folded Reload -; RV32-NEXT: lw t0, 64(sp) # 4-byte Folded Reload ; RV32-NEXT: lw t1, 60(sp) # 4-byte Folded Reload ; RV32-NEXT: lw t2, 56(sp) # 4-byte Folded Reload ; RV32-NEXT: lw a0, 52(sp) # 4-byte Folded Reload @@ -709,8 +724,14 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV32-NEXT: lw t4, 16(sp) # 4-byte Folded Reload ; RV32-NEXT: lw t5, 12(sp) # 4-byte Folded Reload ; RV32-NEXT: lw t6, 8(sp) # 4-byte Folded Reload -; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: lw t0, 72(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 76(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 64(sp) # 4-byte Folded Reload ; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra ; RV32-NEXT: .cfi_restore t1 ; RV32-NEXT: .cfi_restore t2 ; RV32-NEXT: .cfi_restore a0 @@ -725,11 +746,6 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV32-NEXT: .cfi_restore t4 ; RV32-NEXT: .cfi_restore t5 ; RV32-NEXT: .cfi_restore t6 -; RV32-NEXT: csrci mstatus, 8 -; RV32-NEXT: csrw mepc, s1 -; RV32-NEXT: csrw mcause, s0 -; RV32-NEXT: lw s1, 72(sp) # 4-byte Folded Reload -; RV32-NEXT: lw s0, 76(sp) # 4-byte Folded Reload ; RV32-NEXT: addi sp, sp, 80 ; RV32-NEXT: .cfi_def_cfa_offset 0 ; RV32-NEXT: csrrw sp, sf.mscratchcsw, sp @@ -740,13 +756,14 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV64-NEXT: csrrw sp, sf.mscratchcsw, sp ; RV64-NEXT: addi sp, sp, -144 ; RV64-NEXT: .cfi_def_cfa_offset 144 -; RV64-NEXT: sd s0, 136(sp) # 8-byte Folded Spill -; RV64-NEXT: sd s1, 128(sp) # 8-byte Folded Spill -; RV64-NEXT: csrr s0, mcause -; RV64-NEXT: csrr s1, mepc +; RV64-NEXT: sd t0, 112(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 136(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc ; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 128(sp) # 8-byte Folded Spill ; RV64-NEXT: sd ra, 120(sp) # 8-byte Folded Spill -; RV64-NEXT: sd t0, 112(sp) # 8-byte Folded Spill ; RV64-NEXT: sd t1, 104(sp) # 8-byte Folded Spill ; RV64-NEXT: sd t2, 96(sp) # 8-byte Folded Spill ; RV64-NEXT: sd a0, 88(sp) # 8-byte Folded Spill @@ -762,7 +779,6 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV64-NEXT: sd t5, 8(sp) # 8-byte Folded Spill ; RV64-NEXT: sd t6, 0(sp) # 8-byte Folded Spill ; RV64-NEXT: .cfi_offset ra, -24 -; RV64-NEXT: .cfi_offset t0, -32 ; RV64-NEXT: .cfi_offset t1, -40 ; RV64-NEXT: .cfi_offset t2, -48 ; RV64-NEXT: .cfi_offset a0, -56 @@ -779,7 +795,6 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV64-NEXT: .cfi_offset t6, -144 ; RV64-NEXT: call callee ; RV64-NEXT: ld ra, 120(sp) # 8-byte Folded Reload -; RV64-NEXT: ld t0, 112(sp) # 8-byte Folded Reload ; RV64-NEXT: ld t1, 104(sp) # 8-byte Folded Reload ; RV64-NEXT: ld t2, 96(sp) # 8-byte Folded Reload ; RV64-NEXT: ld a0, 88(sp) # 8-byte Folded Reload @@ -794,8 +809,14 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV64-NEXT: ld t4, 16(sp) # 8-byte Folded Reload ; RV64-NEXT: ld t5, 8(sp) # 8-byte Folded Reload ; RV64-NEXT: ld t6, 0(sp) # 8-byte Folded Reload -; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: ld t0, 128(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 136(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 112(sp) # 8-byte Folded Reload ; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra ; RV64-NEXT: .cfi_restore t1 ; RV64-NEXT: .cfi_restore t2 ; RV64-NEXT: .cfi_restore a0 @@ -810,11 +831,6 @@ define void @both_caller() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV64-NEXT: .cfi_restore t4 ; RV64-NEXT: .cfi_restore t5 ; RV64-NEXT: .cfi_restore t6 -; RV64-NEXT: csrci mstatus, 8 -; RV64-NEXT: csrw mepc, s1 -; RV64-NEXT: csrw mcause, s0 -; RV64-NEXT: ld s1, 128(sp) # 8-byte Folded Reload -; RV64-NEXT: ld s0, 136(sp) # 8-byte Folded Reload ; RV64-NEXT: addi sp, sp, 144 ; RV64-NEXT: .cfi_def_cfa_offset 0 ; RV64-NEXT: csrrw sp, sf.mscratchcsw, sp @@ -928,57 +944,65 @@ define void @stack_swap_clobber_fp() "interrupt"="SiFive-CLIC-stack-swap" "frame define void @preemptible_clobber() "interrupt"="SiFive-CLIC-preemptible" { ; RV32-LABEL: preemptible_clobber: ; RV32: # %bb.0: -; RV32-NEXT: addi sp, sp, -16 -; RV32-NEXT: .cfi_def_cfa_offset 16 -; RV32-NEXT: sw s0, 12(sp) # 4-byte Folded Spill -; RV32-NEXT: sw s1, 8(sp) # 4-byte Folded Spill -; RV32-NEXT: csrr s0, mcause -; RV32-NEXT: csrr s1, mepc +; RV32-NEXT: addi sp, sp, -32 +; RV32-NEXT: .cfi_def_cfa_offset 32 +; RV32-NEXT: sw t0, 20(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -12 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 28(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc ; RV32-NEXT: csrsi mstatus, 8 -; RV32-NEXT: sw s0, 4(sp) # 4-byte Folded Spill -; RV32-NEXT: sw s1, 0(sp) # 4-byte Folded Spill -; RV32-NEXT: .cfi_offset s0, -12 -; RV32-NEXT: .cfi_offset s1, -16 +; RV32-NEXT: sw t0, 24(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 16(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s1, 12(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset s0, -16 +; RV32-NEXT: .cfi_offset s1, -20 ; RV32-NEXT: #APP ; RV32-NEXT: #NO_APP -; RV32-NEXT: lw s0, 4(sp) # 4-byte Folded Reload -; RV32-NEXT: lw s1, 0(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 16(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s1, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 24(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 28(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 20(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 ; RV32-NEXT: .cfi_restore s0 ; RV32-NEXT: .cfi_restore s1 -; RV32-NEXT: csrci mstatus, 8 -; RV32-NEXT: csrw mepc, s1 -; RV32-NEXT: csrw mcause, s0 -; RV32-NEXT: lw s1, 8(sp) # 4-byte Folded Reload -; RV32-NEXT: lw s0, 12(sp) # 4-byte Folded Reload -; RV32-NEXT: addi sp, sp, 16 +; RV32-NEXT: addi sp, sp, 32 ; RV32-NEXT: .cfi_def_cfa_offset 0 ; RV32-NEXT: mret ; ; RV64-LABEL: preemptible_clobber: ; RV64: # %bb.0: -; RV64-NEXT: addi sp, sp, -32 -; RV64-NEXT: .cfi_def_cfa_offset 32 -; RV64-NEXT: sd s0, 24(sp) # 8-byte Folded Spill -; RV64-NEXT: sd s1, 16(sp) # 8-byte Folded Spill -; RV64-NEXT: csrr s0, mcause -; RV64-NEXT: csrr s1, mepc +; RV64-NEXT: addi sp, sp, -48 +; RV64-NEXT: .cfi_def_cfa_offset 48 +; RV64-NEXT: sd t0, 24(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -24 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 40(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc ; RV64-NEXT: csrsi mstatus, 8 -; RV64-NEXT: sd s0, 8(sp) # 8-byte Folded Spill -; RV64-NEXT: sd s1, 0(sp) # 8-byte Folded Spill -; RV64-NEXT: .cfi_offset s0, -24 -; RV64-NEXT: .cfi_offset s1, -32 +; RV64-NEXT: sd t0, 32(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset s0, -32 +; RV64-NEXT: .cfi_offset s1, -40 ; RV64-NEXT: #APP ; RV64-NEXT: #NO_APP -; RV64-NEXT: ld s0, 8(sp) # 8-byte Folded Reload -; RV64-NEXT: ld s1, 0(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 32(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 40(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 24(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 ; RV64-NEXT: .cfi_restore s0 ; RV64-NEXT: .cfi_restore s1 -; RV64-NEXT: csrci mstatus, 8 -; RV64-NEXT: csrw mepc, s1 -; RV64-NEXT: csrw mcause, s0 -; RV64-NEXT: ld s1, 16(sp) # 8-byte Folded Reload -; RV64-NEXT: ld s0, 24(sp) # 8-byte Folded Reload -; RV64-NEXT: addi sp, sp, 32 +; RV64-NEXT: addi sp, sp, 48 ; RV64-NEXT: .cfi_def_cfa_offset 0 ; RV64-NEXT: mret call void asm sideeffect "", "~{x8},~{x9}"() #4 @@ -989,29 +1013,33 @@ define void @both_clobber() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV32-LABEL: both_clobber: ; RV32: # %bb.0: ; RV32-NEXT: csrrw sp, sf.mscratchcsw, sp -; RV32-NEXT: addi sp, sp, -16 -; RV32-NEXT: .cfi_def_cfa_offset 16 -; RV32-NEXT: sw s0, 12(sp) # 4-byte Folded Spill -; RV32-NEXT: sw s1, 8(sp) # 4-byte Folded Spill -; RV32-NEXT: csrr s0, mcause -; RV32-NEXT: csrr s1, mepc +; RV32-NEXT: addi sp, sp, -32 +; RV32-NEXT: .cfi_def_cfa_offset 32 +; RV32-NEXT: sw t0, 20(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -12 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 28(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc ; RV32-NEXT: csrsi mstatus, 8 -; RV32-NEXT: sw s0, 4(sp) # 4-byte Folded Spill -; RV32-NEXT: sw s1, 0(sp) # 4-byte Folded Spill -; RV32-NEXT: .cfi_offset s0, -12 -; RV32-NEXT: .cfi_offset s1, -16 +; RV32-NEXT: sw t0, 24(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 16(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s1, 12(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset s0, -16 +; RV32-NEXT: .cfi_offset s1, -20 ; RV32-NEXT: #APP ; RV32-NEXT: #NO_APP -; RV32-NEXT: lw s0, 4(sp) # 4-byte Folded Reload -; RV32-NEXT: lw s1, 0(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 16(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s1, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 24(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 28(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 20(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 ; RV32-NEXT: .cfi_restore s0 ; RV32-NEXT: .cfi_restore s1 -; RV32-NEXT: csrci mstatus, 8 -; RV32-NEXT: csrw mepc, s1 -; RV32-NEXT: csrw mcause, s0 -; RV32-NEXT: lw s1, 8(sp) # 4-byte Folded Reload -; RV32-NEXT: lw s0, 12(sp) # 4-byte Folded Reload -; RV32-NEXT: addi sp, sp, 16 +; RV32-NEXT: addi sp, sp, 32 ; RV32-NEXT: .cfi_def_cfa_offset 0 ; RV32-NEXT: csrrw sp, sf.mscratchcsw, sp ; RV32-NEXT: mret @@ -1019,32 +1047,223 @@ define void @both_clobber() "interrupt"="SiFive-CLIC-preemptible-stack-swap" { ; RV64-LABEL: both_clobber: ; RV64: # %bb.0: ; RV64-NEXT: csrrw sp, sf.mscratchcsw, sp -; RV64-NEXT: addi sp, sp, -32 -; RV64-NEXT: .cfi_def_cfa_offset 32 -; RV64-NEXT: sd s0, 24(sp) # 8-byte Folded Spill -; RV64-NEXT: sd s1, 16(sp) # 8-byte Folded Spill -; RV64-NEXT: csrr s0, mcause -; RV64-NEXT: csrr s1, mepc +; RV64-NEXT: addi sp, sp, -48 +; RV64-NEXT: .cfi_def_cfa_offset 48 +; RV64-NEXT: sd t0, 24(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -24 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 40(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc ; RV64-NEXT: csrsi mstatus, 8 -; RV64-NEXT: sd s0, 8(sp) # 8-byte Folded Spill -; RV64-NEXT: sd s1, 0(sp) # 8-byte Folded Spill -; RV64-NEXT: .cfi_offset s0, -24 -; RV64-NEXT: .cfi_offset s1, -32 +; RV64-NEXT: sd t0, 32(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset s0, -32 +; RV64-NEXT: .cfi_offset s1, -40 ; RV64-NEXT: #APP ; RV64-NEXT: #NO_APP -; RV64-NEXT: ld s0, 8(sp) # 8-byte Folded Reload -; RV64-NEXT: ld s1, 0(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 32(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 40(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 24(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 ; RV64-NEXT: .cfi_restore s0 ; RV64-NEXT: .cfi_restore s1 -; RV64-NEXT: csrci mstatus, 8 -; RV64-NEXT: csrw mepc, s1 -; RV64-NEXT: csrw mcause, s0 -; RV64-NEXT: ld s1, 16(sp) # 8-byte Folded Reload -; RV64-NEXT: ld s0, 24(sp) # 8-byte Folded Reload -; RV64-NEXT: addi sp, sp, 32 +; RV64-NEXT: addi sp, sp, 48 ; RV64-NEXT: .cfi_def_cfa_offset 0 ; RV64-NEXT: csrrw sp, sf.mscratchcsw, sp ; RV64-NEXT: mret call void asm sideeffect "", "~{x8},~{x9}"() #4 ret void } + +declare void @use(ptr) + +define void @large_frame() "interrupt"="SiFive-CLIC-preemptible" "frame-pointer"="none" { +; RV32-LABEL: large_frame: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -2032 +; RV32-NEXT: .cfi_def_cfa_offset 2032 +; RV32-NEXT: sw t0, 2016(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 2028(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc +; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 2024(sp) # 4-byte Folded Spill +; RV32-NEXT: sw ra, 2020(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t1, 2012(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t2, 2008(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a0, 2004(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a1, 2000(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a2, 1996(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a3, 1992(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a4, 1988(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a5, 1984(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a6, 1980(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a7, 1976(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t3, 1972(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t4, 1968(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t5, 1964(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t6, 1960(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset ra, -12 +; RV32-NEXT: .cfi_offset t1, -20 +; RV32-NEXT: .cfi_offset t2, -24 +; RV32-NEXT: .cfi_offset a0, -28 +; RV32-NEXT: .cfi_offset a1, -32 +; RV32-NEXT: .cfi_offset a2, -36 +; RV32-NEXT: .cfi_offset a3, -40 +; RV32-NEXT: .cfi_offset a4, -44 +; RV32-NEXT: .cfi_offset a5, -48 +; RV32-NEXT: .cfi_offset a6, -52 +; RV32-NEXT: .cfi_offset a7, -56 +; RV32-NEXT: .cfi_offset t3, -60 +; RV32-NEXT: .cfi_offset t4, -64 +; RV32-NEXT: .cfi_offset t5, -68 +; RV32-NEXT: .cfi_offset t6, -72 +; RV32-NEXT: addi sp, sp, -2048 +; RV32-NEXT: addi sp, sp, -112 +; RV32-NEXT: .cfi_def_cfa_offset 4192 +; RV32-NEXT: addi a0, sp, 16 +; RV32-NEXT: call use +; RV32-NEXT: addi sp, sp, 2032 +; RV32-NEXT: addi sp, sp, 128 +; RV32-NEXT: .cfi_def_cfa_offset 2032 +; RV32-NEXT: lw ra, 2020(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t1, 2012(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t2, 2008(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a0, 2004(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a1, 2000(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a2, 1996(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a3, 1992(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a4, 1988(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a5, 1984(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a6, 1980(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a7, 1976(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t3, 1972(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t4, 1968(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t5, 1964(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t6, 1960(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 2024(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 2028(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 2016(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: .cfi_restore t1 +; RV32-NEXT: .cfi_restore t2 +; RV32-NEXT: .cfi_restore a0 +; RV32-NEXT: .cfi_restore a1 +; RV32-NEXT: .cfi_restore a2 +; RV32-NEXT: .cfi_restore a3 +; RV32-NEXT: .cfi_restore a4 +; RV32-NEXT: .cfi_restore a5 +; RV32-NEXT: .cfi_restore a6 +; RV32-NEXT: .cfi_restore a7 +; RV32-NEXT: .cfi_restore t3 +; RV32-NEXT: .cfi_restore t4 +; RV32-NEXT: .cfi_restore t5 +; RV32-NEXT: .cfi_restore t6 +; RV32-NEXT: addi sp, sp, 2032 +; RV32-NEXT: .cfi_def_cfa_offset 0 +; RV32-NEXT: mret +; +; RV64-LABEL: large_frame: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -2032 +; RV64-NEXT: .cfi_def_cfa_offset 2032 +; RV64-NEXT: sd t0, 2000(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 2024(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc +; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 2016(sp) # 8-byte Folded Spill +; RV64-NEXT: sd ra, 2008(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t1, 1992(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t2, 1984(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a0, 1976(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a1, 1968(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a2, 1960(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a3, 1952(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a4, 1944(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a5, 1936(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a6, 1928(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a7, 1920(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t3, 1912(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t4, 1904(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t5, 1896(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t6, 1888(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset ra, -24 +; RV64-NEXT: .cfi_offset t1, -40 +; RV64-NEXT: .cfi_offset t2, -48 +; RV64-NEXT: .cfi_offset a0, -56 +; RV64-NEXT: .cfi_offset a1, -64 +; RV64-NEXT: .cfi_offset a2, -72 +; RV64-NEXT: .cfi_offset a3, -80 +; RV64-NEXT: .cfi_offset a4, -88 +; RV64-NEXT: .cfi_offset a5, -96 +; RV64-NEXT: .cfi_offset a6, -104 +; RV64-NEXT: .cfi_offset a7, -112 +; RV64-NEXT: .cfi_offset t3, -120 +; RV64-NEXT: .cfi_offset t4, -128 +; RV64-NEXT: .cfi_offset t5, -136 +; RV64-NEXT: .cfi_offset t6, -144 +; RV64-NEXT: addi sp, sp, -2048 +; RV64-NEXT: addi sp, sp, -176 +; RV64-NEXT: .cfi_def_cfa_offset 4256 +; RV64-NEXT: addi a0, sp, 16 +; RV64-NEXT: call use +; RV64-NEXT: addi sp, sp, 2032 +; RV64-NEXT: addi sp, sp, 192 +; RV64-NEXT: .cfi_def_cfa_offset 2032 +; RV64-NEXT: ld ra, 2008(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t1, 1992(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t2, 1984(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a0, 1976(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a1, 1968(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a2, 1960(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a3, 1952(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a4, 1944(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a5, 1936(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a6, 1928(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a7, 1920(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t3, 1912(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t4, 1904(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t5, 1896(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t6, 1888(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 2016(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 2024(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 2000(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: .cfi_restore t1 +; RV64-NEXT: .cfi_restore t2 +; RV64-NEXT: .cfi_restore a0 +; RV64-NEXT: .cfi_restore a1 +; RV64-NEXT: .cfi_restore a2 +; RV64-NEXT: .cfi_restore a3 +; RV64-NEXT: .cfi_restore a4 +; RV64-NEXT: .cfi_restore a5 +; RV64-NEXT: .cfi_restore a6 +; RV64-NEXT: .cfi_restore a7 +; RV64-NEXT: .cfi_restore t3 +; RV64-NEXT: .cfi_restore t4 +; RV64-NEXT: .cfi_restore t5 +; RV64-NEXT: .cfi_restore t6 +; RV64-NEXT: addi sp, sp, 2032 +; RV64-NEXT: .cfi_def_cfa_offset 0 +; RV64-NEXT: mret + %object = alloca [4096 x i8], align 16 + call void @use(ptr %object) + ret void +} diff --git a/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll b/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll index e014c20febfb81..3c10e87fe861f0 100644 --- a/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll +++ b/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll @@ -9,20 +9,25 @@ define void @preemptible_stack_swap() "interrupt"="SiFive-CLIC-preemptible-stack ; CHECK-LABEL: name: preemptible_stack_swap ; CHECK: body: | ; CHECK-NEXT: bb.0 -; CHECK-NEXT: $x2 = frame-setup CSRRW 840, killed $x2 -; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -16 -; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16 -; CHECK-NEXT: frame-setup {{SW|SD}} killed $x8 -; CHECK-NEXT: frame-setup {{SW|SD}} killed $x9 -; CHECK-NEXT: $x8 = frame-setup CSRRS 834, $x0 -; CHECK-NEXT: $x9 = frame-setup CSRRS 833, $x0 +; CHECK-NEXT: liveins: $x5 +; CHECK: $x2 = frame-setup CSRRW 840, killed $x2 +; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -{{16|32}} +; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset {{16|32}} +; CHECK-NEXT: frame-setup {{SW|SD}} killed $x5 +; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x5, -{{12|24}} +; CHECK-NEXT: $x5 = frame-setup CSRRS 834, $x0 +; CHECK-NEXT: frame-setup {{SW|SD}} killed $x5 +; CHECK-NEXT: $x5 = frame-setup CSRRS 833, $x0 ; CHECK-NEXT: $x0 = frame-setup CSRRSI 768, 8 +; CHECK-NEXT: frame-setup {{SW|SD}} killed $x5 +; CHECK-NEXT: $x5 = frame-destroy {{LW|LD}} ; CHECK-NEXT: $x0 = frame-destroy CSRRCI 768, 8 -; CHECK-NEXT: $x0 = frame-destroy CSRRW 833, killed $x9 -; CHECK-NEXT: $x0 = frame-destroy CSRRW 834, killed $x8 -; CHECK-NEXT: $x9 = frame-destroy {{LW|LD}} -; CHECK-NEXT: $x8 = frame-destroy {{LW|LD}} -; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 16 +; CHECK-NEXT: $x0 = frame-destroy CSRRW 833, killed $x5 +; CHECK-NEXT: $x5 = frame-destroy {{LW|LD}} +; CHECK-NEXT: $x0 = frame-destroy CSRRW 834, killed $x5 +; CHECK-NEXT: $x5 = frame-destroy {{LW|LD}} +; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x5 +; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, {{16|32}} ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0 ; CHECK-NEXT: $x2 = frame-destroy CSRRW 840, killed $x2 ; CHECK-NEXT: MRET diff --git a/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-pointer.ll b/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-pointer.ll new file mode 100644 index 00000000000000..0145c6de8924f9 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-pointer.ll @@ -0,0 +1,951 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc -mtriple riscv32-unknown-elf -mattr=+experimental-xsfmclic \ +; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV32 +; RUN: llc -mtriple riscv64-unknown-elf -mattr=+experimental-xsfmclic \ +; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV64 + +@size = external global i32 + +declare void @use(ptr) + +define void @preemptible() "interrupt"="SiFive-CLIC-preemptible" "frame-pointer"="all" { +; RV32-LABEL: preemptible: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -32 +; RV32-NEXT: .cfi_def_cfa_offset 32 +; RV32-NEXT: sw t0, 16(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 28(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc +; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 24(sp) # 4-byte Folded Spill +; RV32-NEXT: sw ra, 20(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 12(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset ra, -12 +; RV32-NEXT: .cfi_offset s0, -20 +; RV32-NEXT: addi s0, sp, 32 +; RV32-NEXT: .cfi_def_cfa s0, 0 +; RV32-NEXT: .cfi_def_cfa sp, 32 +; RV32-NEXT: lw ra, 20(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 24(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 28(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 16(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: .cfi_restore s0 +; RV32-NEXT: addi sp, sp, 32 +; RV32-NEXT: .cfi_def_cfa_offset 0 +; RV32-NEXT: mret +; +; RV64-LABEL: preemptible: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -48 +; RV64-NEXT: .cfi_def_cfa_offset 48 +; RV64-NEXT: sd t0, 16(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 40(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc +; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 32(sp) # 8-byte Folded Spill +; RV64-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 8(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset ra, -24 +; RV64-NEXT: .cfi_offset s0, -40 +; RV64-NEXT: addi s0, sp, 48 +; RV64-NEXT: .cfi_def_cfa s0, 0 +; RV64-NEXT: .cfi_def_cfa sp, 48 +; RV64-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 32(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 40(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 16(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: .cfi_restore s0 +; RV64-NEXT: addi sp, sp, 48 +; RV64-NEXT: .cfi_def_cfa_offset 0 +; RV64-NEXT: mret + ret void +} + +define void @preemptible_stack_swap() "interrupt"="SiFive-CLIC-preemptible-stack-swap" "frame-pointer"="all" { +; RV32-LABEL: preemptible_stack_swap: +; RV32: # %bb.0: +; RV32-NEXT: csrrw sp, sf.mscratchcsw, sp +; RV32-NEXT: addi sp, sp, -32 +; RV32-NEXT: .cfi_def_cfa_offset 32 +; RV32-NEXT: sw t0, 16(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 28(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc +; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 24(sp) # 4-byte Folded Spill +; RV32-NEXT: sw ra, 20(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 12(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset ra, -12 +; RV32-NEXT: .cfi_offset s0, -20 +; RV32-NEXT: addi s0, sp, 32 +; RV32-NEXT: .cfi_def_cfa s0, 0 +; RV32-NEXT: .cfi_def_cfa sp, 32 +; RV32-NEXT: lw ra, 20(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 24(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 28(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 16(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: .cfi_restore s0 +; RV32-NEXT: addi sp, sp, 32 +; RV32-NEXT: .cfi_def_cfa_offset 0 +; RV32-NEXT: csrrw sp, sf.mscratchcsw, sp +; RV32-NEXT: mret +; +; RV64-LABEL: preemptible_stack_swap: +; RV64: # %bb.0: +; RV64-NEXT: csrrw sp, sf.mscratchcsw, sp +; RV64-NEXT: addi sp, sp, -48 +; RV64-NEXT: .cfi_def_cfa_offset 48 +; RV64-NEXT: sd t0, 16(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 40(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc +; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 32(sp) # 8-byte Folded Spill +; RV64-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 8(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset ra, -24 +; RV64-NEXT: .cfi_offset s0, -40 +; RV64-NEXT: addi s0, sp, 48 +; RV64-NEXT: .cfi_def_cfa s0, 0 +; RV64-NEXT: .cfi_def_cfa sp, 48 +; RV64-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 32(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 40(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 16(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: .cfi_restore s0 +; RV64-NEXT: addi sp, sp, 48 +; RV64-NEXT: .cfi_def_cfa_offset 0 +; RV64-NEXT: csrrw sp, sf.mscratchcsw, sp +; RV64-NEXT: mret + ret void +} + +define void @preemptible_var_alloca() "interrupt"="SiFive-CLIC-preemptible" "frame-pointer"="none" { +; RV32-LABEL: preemptible_var_alloca: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -80 +; RV32-NEXT: .cfi_def_cfa_offset 80 +; RV32-NEXT: sw t0, 64(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 76(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc +; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 72(sp) # 4-byte Folded Spill +; RV32-NEXT: sw ra, 68(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t1, 60(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t2, 56(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 52(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a0, 48(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a1, 44(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a2, 40(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a3, 36(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a4, 32(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a5, 28(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a6, 24(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a7, 20(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t3, 16(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t4, 12(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t5, 8(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t6, 4(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset ra, -12 +; RV32-NEXT: .cfi_offset t1, -20 +; RV32-NEXT: .cfi_offset t2, -24 +; RV32-NEXT: .cfi_offset s0, -28 +; RV32-NEXT: .cfi_offset a0, -32 +; RV32-NEXT: .cfi_offset a1, -36 +; RV32-NEXT: .cfi_offset a2, -40 +; RV32-NEXT: .cfi_offset a3, -44 +; RV32-NEXT: .cfi_offset a4, -48 +; RV32-NEXT: .cfi_offset a5, -52 +; RV32-NEXT: .cfi_offset a6, -56 +; RV32-NEXT: .cfi_offset a7, -60 +; RV32-NEXT: .cfi_offset t3, -64 +; RV32-NEXT: .cfi_offset t4, -68 +; RV32-NEXT: .cfi_offset t5, -72 +; RV32-NEXT: .cfi_offset t6, -76 +; RV32-NEXT: addi s0, sp, 80 +; RV32-NEXT: .cfi_def_cfa s0, 0 +; RV32-NEXT: lui a0, %hi(size) +; RV32-NEXT: lw a0, %lo(size)(a0) +; RV32-NEXT: addi a0, a0, 15 +; RV32-NEXT: andi a0, a0, -16 +; RV32-NEXT: sub a0, sp, a0 +; RV32-NEXT: mv sp, a0 +; RV32-NEXT: call use +; RV32-NEXT: addi sp, s0, -80 +; RV32-NEXT: .cfi_def_cfa sp, 80 +; RV32-NEXT: lw ra, 68(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t1, 60(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t2, 56(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 52(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a0, 48(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a1, 44(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a2, 40(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a3, 36(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a4, 32(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a5, 28(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a6, 24(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a7, 20(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t3, 16(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t4, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t5, 8(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t6, 4(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 72(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 76(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 64(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: .cfi_restore t1 +; RV32-NEXT: .cfi_restore t2 +; RV32-NEXT: .cfi_restore s0 +; RV32-NEXT: .cfi_restore a0 +; RV32-NEXT: .cfi_restore a1 +; RV32-NEXT: .cfi_restore a2 +; RV32-NEXT: .cfi_restore a3 +; RV32-NEXT: .cfi_restore a4 +; RV32-NEXT: .cfi_restore a5 +; RV32-NEXT: .cfi_restore a6 +; RV32-NEXT: .cfi_restore a7 +; RV32-NEXT: .cfi_restore t3 +; RV32-NEXT: .cfi_restore t4 +; RV32-NEXT: .cfi_restore t5 +; RV32-NEXT: .cfi_restore t6 +; RV32-NEXT: addi sp, sp, 80 +; RV32-NEXT: .cfi_def_cfa_offset 0 +; RV32-NEXT: mret +; +; RV64-LABEL: preemptible_var_alloca: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -160 +; RV64-NEXT: .cfi_def_cfa_offset 160 +; RV64-NEXT: sd t0, 128(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 152(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc +; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 144(sp) # 8-byte Folded Spill +; RV64-NEXT: sd ra, 136(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t1, 120(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t2, 112(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 104(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a0, 96(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a1, 88(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a2, 80(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a3, 72(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a4, 64(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a5, 56(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a6, 48(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a7, 40(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t3, 32(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t4, 24(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t5, 16(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t6, 8(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset ra, -24 +; RV64-NEXT: .cfi_offset t1, -40 +; RV64-NEXT: .cfi_offset t2, -48 +; RV64-NEXT: .cfi_offset s0, -56 +; RV64-NEXT: .cfi_offset a0, -64 +; RV64-NEXT: .cfi_offset a1, -72 +; RV64-NEXT: .cfi_offset a2, -80 +; RV64-NEXT: .cfi_offset a3, -88 +; RV64-NEXT: .cfi_offset a4, -96 +; RV64-NEXT: .cfi_offset a5, -104 +; RV64-NEXT: .cfi_offset a6, -112 +; RV64-NEXT: .cfi_offset a7, -120 +; RV64-NEXT: .cfi_offset t3, -128 +; RV64-NEXT: .cfi_offset t4, -136 +; RV64-NEXT: .cfi_offset t5, -144 +; RV64-NEXT: .cfi_offset t6, -152 +; RV64-NEXT: addi s0, sp, 160 +; RV64-NEXT: .cfi_def_cfa s0, 0 +; RV64-NEXT: lui a0, %hi(size) +; RV64-NEXT: lwu a0, %lo(size)(a0) +; RV64-NEXT: addi a0, a0, 15 +; RV64-NEXT: andi a0, a0, -16 +; RV64-NEXT: sub a0, sp, a0 +; RV64-NEXT: mv sp, a0 +; RV64-NEXT: call use +; RV64-NEXT: addi sp, s0, -160 +; RV64-NEXT: .cfi_def_cfa sp, 160 +; RV64-NEXT: ld ra, 136(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t1, 120(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t2, 112(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 104(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a0, 96(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a1, 88(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a2, 80(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a3, 72(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a4, 64(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a5, 56(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a6, 48(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a7, 40(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t3, 32(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t4, 24(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t5, 16(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t6, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 144(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 152(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 128(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: .cfi_restore t1 +; RV64-NEXT: .cfi_restore t2 +; RV64-NEXT: .cfi_restore s0 +; RV64-NEXT: .cfi_restore a0 +; RV64-NEXT: .cfi_restore a1 +; RV64-NEXT: .cfi_restore a2 +; RV64-NEXT: .cfi_restore a3 +; RV64-NEXT: .cfi_restore a4 +; RV64-NEXT: .cfi_restore a5 +; RV64-NEXT: .cfi_restore a6 +; RV64-NEXT: .cfi_restore a7 +; RV64-NEXT: .cfi_restore t3 +; RV64-NEXT: .cfi_restore t4 +; RV64-NEXT: .cfi_restore t5 +; RV64-NEXT: .cfi_restore t6 +; RV64-NEXT: addi sp, sp, 160 +; RV64-NEXT: .cfi_def_cfa_offset 0 +; RV64-NEXT: mret + %count = load volatile i32, ptr @size + %object = alloca i8, i32 %count, align 16 + call void @use(ptr %object) + ret void +} + +define void @preemptible_realign() "interrupt"="SiFive-CLIC-preemptible" "frame-pointer"="none" { +; RV32-LABEL: preemptible_realign: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -192 +; RV32-NEXT: .cfi_def_cfa_offset 192 +; RV32-NEXT: sw t0, 176(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 188(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc +; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 184(sp) # 4-byte Folded Spill +; RV32-NEXT: sw ra, 180(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t1, 172(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t2, 168(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 164(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a0, 160(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a1, 156(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a2, 152(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a3, 148(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a4, 144(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a5, 140(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a6, 136(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a7, 132(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t3, 128(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t4, 124(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t5, 120(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t6, 116(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset ra, -12 +; RV32-NEXT: .cfi_offset t1, -20 +; RV32-NEXT: .cfi_offset t2, -24 +; RV32-NEXT: .cfi_offset s0, -28 +; RV32-NEXT: .cfi_offset a0, -32 +; RV32-NEXT: .cfi_offset a1, -36 +; RV32-NEXT: .cfi_offset a2, -40 +; RV32-NEXT: .cfi_offset a3, -44 +; RV32-NEXT: .cfi_offset a4, -48 +; RV32-NEXT: .cfi_offset a5, -52 +; RV32-NEXT: .cfi_offset a6, -56 +; RV32-NEXT: .cfi_offset a7, -60 +; RV32-NEXT: .cfi_offset t3, -64 +; RV32-NEXT: .cfi_offset t4, -68 +; RV32-NEXT: .cfi_offset t5, -72 +; RV32-NEXT: .cfi_offset t6, -76 +; RV32-NEXT: addi s0, sp, 192 +; RV32-NEXT: .cfi_def_cfa s0, 0 +; RV32-NEXT: andi sp, sp, -64 +; RV32-NEXT: mv a0, sp +; RV32-NEXT: call use +; RV32-NEXT: addi sp, s0, -192 +; RV32-NEXT: .cfi_def_cfa sp, 192 +; RV32-NEXT: lw ra, 180(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t1, 172(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t2, 168(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 164(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a0, 160(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a1, 156(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a2, 152(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a3, 148(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a4, 144(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a5, 140(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a6, 136(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a7, 132(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t3, 128(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t4, 124(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t5, 120(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t6, 116(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 184(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 188(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 176(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: .cfi_restore t1 +; RV32-NEXT: .cfi_restore t2 +; RV32-NEXT: .cfi_restore s0 +; RV32-NEXT: .cfi_restore a0 +; RV32-NEXT: .cfi_restore a1 +; RV32-NEXT: .cfi_restore a2 +; RV32-NEXT: .cfi_restore a3 +; RV32-NEXT: .cfi_restore a4 +; RV32-NEXT: .cfi_restore a5 +; RV32-NEXT: .cfi_restore a6 +; RV32-NEXT: .cfi_restore a7 +; RV32-NEXT: .cfi_restore t3 +; RV32-NEXT: .cfi_restore t4 +; RV32-NEXT: .cfi_restore t5 +; RV32-NEXT: .cfi_restore t6 +; RV32-NEXT: addi sp, sp, 192 +; RV32-NEXT: .cfi_def_cfa_offset 0 +; RV32-NEXT: mret +; +; RV64-LABEL: preemptible_realign: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -256 +; RV64-NEXT: .cfi_def_cfa_offset 256 +; RV64-NEXT: sd t0, 224(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 248(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc +; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 240(sp) # 8-byte Folded Spill +; RV64-NEXT: sd ra, 232(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t1, 216(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t2, 208(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 200(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a0, 192(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a1, 184(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a2, 176(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a3, 168(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a4, 160(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a5, 152(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a6, 144(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a7, 136(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t3, 128(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t4, 120(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t5, 112(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t6, 104(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset ra, -24 +; RV64-NEXT: .cfi_offset t1, -40 +; RV64-NEXT: .cfi_offset t2, -48 +; RV64-NEXT: .cfi_offset s0, -56 +; RV64-NEXT: .cfi_offset a0, -64 +; RV64-NEXT: .cfi_offset a1, -72 +; RV64-NEXT: .cfi_offset a2, -80 +; RV64-NEXT: .cfi_offset a3, -88 +; RV64-NEXT: .cfi_offset a4, -96 +; RV64-NEXT: .cfi_offset a5, -104 +; RV64-NEXT: .cfi_offset a6, -112 +; RV64-NEXT: .cfi_offset a7, -120 +; RV64-NEXT: .cfi_offset t3, -128 +; RV64-NEXT: .cfi_offset t4, -136 +; RV64-NEXT: .cfi_offset t5, -144 +; RV64-NEXT: .cfi_offset t6, -152 +; RV64-NEXT: addi s0, sp, 256 +; RV64-NEXT: .cfi_def_cfa s0, 0 +; RV64-NEXT: andi sp, sp, -64 +; RV64-NEXT: mv a0, sp +; RV64-NEXT: call use +; RV64-NEXT: addi sp, s0, -256 +; RV64-NEXT: .cfi_def_cfa sp, 256 +; RV64-NEXT: ld ra, 232(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t1, 216(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t2, 208(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 200(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a0, 192(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a1, 184(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a2, 176(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a3, 168(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a4, 160(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a5, 152(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a6, 144(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a7, 136(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t3, 128(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t4, 120(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t5, 112(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t6, 104(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 240(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 248(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 224(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: .cfi_restore t1 +; RV64-NEXT: .cfi_restore t2 +; RV64-NEXT: .cfi_restore s0 +; RV64-NEXT: .cfi_restore a0 +; RV64-NEXT: .cfi_restore a1 +; RV64-NEXT: .cfi_restore a2 +; RV64-NEXT: .cfi_restore a3 +; RV64-NEXT: .cfi_restore a4 +; RV64-NEXT: .cfi_restore a5 +; RV64-NEXT: .cfi_restore a6 +; RV64-NEXT: .cfi_restore a7 +; RV64-NEXT: .cfi_restore t3 +; RV64-NEXT: .cfi_restore t4 +; RV64-NEXT: .cfi_restore t5 +; RV64-NEXT: .cfi_restore t6 +; RV64-NEXT: addi sp, sp, 256 +; RV64-NEXT: .cfi_def_cfa_offset 0 +; RV64-NEXT: mret + %object = alloca [64 x i8], align 64 + call void @use(ptr %object) + ret void +} + +define void @large_frame_fp() "interrupt"="SiFive-CLIC-preemptible" "frame-pointer"="all" { +; RV32-LABEL: large_frame_fp: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -2032 +; RV32-NEXT: .cfi_def_cfa_offset 2032 +; RV32-NEXT: sw t0, 2016(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 2028(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc +; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 2024(sp) # 4-byte Folded Spill +; RV32-NEXT: sw ra, 2020(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t1, 2012(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t2, 2008(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 2004(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a0, 2000(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a1, 1996(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a2, 1992(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a3, 1988(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a4, 1984(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a5, 1980(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a6, 1976(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a7, 1972(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t3, 1968(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t4, 1964(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t5, 1960(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t6, 1956(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset ra, -12 +; RV32-NEXT: .cfi_offset t1, -20 +; RV32-NEXT: .cfi_offset t2, -24 +; RV32-NEXT: .cfi_offset s0, -28 +; RV32-NEXT: .cfi_offset a0, -32 +; RV32-NEXT: .cfi_offset a1, -36 +; RV32-NEXT: .cfi_offset a2, -40 +; RV32-NEXT: .cfi_offset a3, -44 +; RV32-NEXT: .cfi_offset a4, -48 +; RV32-NEXT: .cfi_offset a5, -52 +; RV32-NEXT: .cfi_offset a6, -56 +; RV32-NEXT: .cfi_offset a7, -60 +; RV32-NEXT: .cfi_offset t3, -64 +; RV32-NEXT: .cfi_offset t4, -68 +; RV32-NEXT: .cfi_offset t5, -72 +; RV32-NEXT: .cfi_offset t6, -76 +; RV32-NEXT: addi s0, sp, 2032 +; RV32-NEXT: .cfi_def_cfa s0, 0 +; RV32-NEXT: addi sp, sp, -2048 +; RV32-NEXT: addi sp, sp, -96 +; RV32-NEXT: mv a0, sp +; RV32-NEXT: call use +; RV32-NEXT: addi sp, sp, 2032 +; RV32-NEXT: addi sp, sp, 112 +; RV32-NEXT: .cfi_def_cfa sp, 2032 +; RV32-NEXT: lw ra, 2020(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t1, 2012(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t2, 2008(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 2004(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a0, 2000(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a1, 1996(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a2, 1992(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a3, 1988(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a4, 1984(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a5, 1980(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a6, 1976(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a7, 1972(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t3, 1968(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t4, 1964(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t5, 1960(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t6, 1956(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 2024(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 2028(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 2016(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: .cfi_restore t1 +; RV32-NEXT: .cfi_restore t2 +; RV32-NEXT: .cfi_restore s0 +; RV32-NEXT: .cfi_restore a0 +; RV32-NEXT: .cfi_restore a1 +; RV32-NEXT: .cfi_restore a2 +; RV32-NEXT: .cfi_restore a3 +; RV32-NEXT: .cfi_restore a4 +; RV32-NEXT: .cfi_restore a5 +; RV32-NEXT: .cfi_restore a6 +; RV32-NEXT: .cfi_restore a7 +; RV32-NEXT: .cfi_restore t3 +; RV32-NEXT: .cfi_restore t4 +; RV32-NEXT: .cfi_restore t5 +; RV32-NEXT: .cfi_restore t6 +; RV32-NEXT: addi sp, sp, 2032 +; RV32-NEXT: .cfi_def_cfa_offset 0 +; RV32-NEXT: mret +; +; RV64-LABEL: large_frame_fp: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -2032 +; RV64-NEXT: .cfi_def_cfa_offset 2032 +; RV64-NEXT: sd t0, 2000(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 2024(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc +; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 2016(sp) # 8-byte Folded Spill +; RV64-NEXT: sd ra, 2008(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t1, 1992(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t2, 1984(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 1976(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a0, 1968(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a1, 1960(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a2, 1952(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a3, 1944(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a4, 1936(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a5, 1928(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a6, 1920(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a7, 1912(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t3, 1904(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t4, 1896(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t5, 1888(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t6, 1880(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset ra, -24 +; RV64-NEXT: .cfi_offset t1, -40 +; RV64-NEXT: .cfi_offset t2, -48 +; RV64-NEXT: .cfi_offset s0, -56 +; RV64-NEXT: .cfi_offset a0, -64 +; RV64-NEXT: .cfi_offset a1, -72 +; RV64-NEXT: .cfi_offset a2, -80 +; RV64-NEXT: .cfi_offset a3, -88 +; RV64-NEXT: .cfi_offset a4, -96 +; RV64-NEXT: .cfi_offset a5, -104 +; RV64-NEXT: .cfi_offset a6, -112 +; RV64-NEXT: .cfi_offset a7, -120 +; RV64-NEXT: .cfi_offset t3, -128 +; RV64-NEXT: .cfi_offset t4, -136 +; RV64-NEXT: .cfi_offset t5, -144 +; RV64-NEXT: .cfi_offset t6, -152 +; RV64-NEXT: addi s0, sp, 2032 +; RV64-NEXT: .cfi_def_cfa s0, 0 +; RV64-NEXT: addi sp, sp, -2048 +; RV64-NEXT: addi sp, sp, -176 +; RV64-NEXT: mv a0, sp +; RV64-NEXT: call use +; RV64-NEXT: addi sp, sp, 2032 +; RV64-NEXT: addi sp, sp, 192 +; RV64-NEXT: .cfi_def_cfa sp, 2032 +; RV64-NEXT: ld ra, 2008(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t1, 1992(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t2, 1984(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 1976(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a0, 1968(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a1, 1960(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a2, 1952(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a3, 1944(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a4, 1936(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a5, 1928(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a6, 1920(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a7, 1912(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t3, 1904(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t4, 1896(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t5, 1888(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t6, 1880(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 2016(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 2024(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 2000(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: .cfi_restore t1 +; RV64-NEXT: .cfi_restore t2 +; RV64-NEXT: .cfi_restore s0 +; RV64-NEXT: .cfi_restore a0 +; RV64-NEXT: .cfi_restore a1 +; RV64-NEXT: .cfi_restore a2 +; RV64-NEXT: .cfi_restore a3 +; RV64-NEXT: .cfi_restore a4 +; RV64-NEXT: .cfi_restore a5 +; RV64-NEXT: .cfi_restore a6 +; RV64-NEXT: .cfi_restore a7 +; RV64-NEXT: .cfi_restore t3 +; RV64-NEXT: .cfi_restore t4 +; RV64-NEXT: .cfi_restore t5 +; RV64-NEXT: .cfi_restore t6 +; RV64-NEXT: addi sp, sp, 2032 +; RV64-NEXT: .cfi_def_cfa_offset 0 +; RV64-NEXT: mret + %object = alloca [4096 x i8], align 16 + call void @use(ptr %object) + ret void +} + +define void @realign_var_alloca() "interrupt"="SiFive-CLIC-preemptible" "frame-pointer"="none" { +; RV32-LABEL: realign_var_alloca: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -128 +; RV32-NEXT: .cfi_def_cfa_offset 128 +; RV32-NEXT: sw t0, 112(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset t0, -16 +; RV32-NEXT: csrr t0, mcause +; RV32-NEXT: sw t0, 124(sp) # 4-byte Folded Spill +; RV32-NEXT: csrr t0, mepc +; RV32-NEXT: csrsi mstatus, 8 +; RV32-NEXT: sw t0, 120(sp) # 4-byte Folded Spill +; RV32-NEXT: sw ra, 116(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t1, 108(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t2, 104(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 100(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s1, 96(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a0, 92(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a1, 88(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a2, 84(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a3, 80(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a4, 76(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a5, 72(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a6, 68(sp) # 4-byte Folded Spill +; RV32-NEXT: sw a7, 64(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t3, 60(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t4, 56(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t5, 52(sp) # 4-byte Folded Spill +; RV32-NEXT: sw t6, 48(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset ra, -12 +; RV32-NEXT: .cfi_offset t1, -20 +; RV32-NEXT: .cfi_offset t2, -24 +; RV32-NEXT: .cfi_offset s0, -28 +; RV32-NEXT: .cfi_offset s1, -32 +; RV32-NEXT: .cfi_offset a0, -36 +; RV32-NEXT: .cfi_offset a1, -40 +; RV32-NEXT: .cfi_offset a2, -44 +; RV32-NEXT: .cfi_offset a3, -48 +; RV32-NEXT: .cfi_offset a4, -52 +; RV32-NEXT: .cfi_offset a5, -56 +; RV32-NEXT: .cfi_offset a6, -60 +; RV32-NEXT: .cfi_offset a7, -64 +; RV32-NEXT: .cfi_offset t3, -68 +; RV32-NEXT: .cfi_offset t4, -72 +; RV32-NEXT: .cfi_offset t5, -76 +; RV32-NEXT: .cfi_offset t6, -80 +; RV32-NEXT: addi s0, sp, 128 +; RV32-NEXT: .cfi_def_cfa s0, 0 +; RV32-NEXT: andi sp, sp, -64 +; RV32-NEXT: mv s1, sp +; RV32-NEXT: lui a0, %hi(size) +; RV32-NEXT: lw a0, %lo(size)(a0) +; RV32-NEXT: addi a0, a0, 15 +; RV32-NEXT: andi a0, a0, -16 +; RV32-NEXT: sub a0, sp, a0 +; RV32-NEXT: andi a0, a0, -64 +; RV32-NEXT: mv sp, a0 +; RV32-NEXT: call use +; RV32-NEXT: addi sp, s0, -128 +; RV32-NEXT: .cfi_def_cfa sp, 128 +; RV32-NEXT: lw ra, 116(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t1, 108(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t2, 104(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 100(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s1, 96(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a0, 92(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a1, 88(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a2, 84(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a3, 80(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a4, 76(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a5, 72(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a6, 68(sp) # 4-byte Folded Reload +; RV32-NEXT: lw a7, 64(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t3, 60(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t4, 56(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t5, 52(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t6, 48(sp) # 4-byte Folded Reload +; RV32-NEXT: lw t0, 120(sp) # 4-byte Folded Reload +; RV32-NEXT: csrci mstatus, 8 +; RV32-NEXT: csrw mepc, t0 +; RV32-NEXT: lw t0, 124(sp) # 4-byte Folded Reload +; RV32-NEXT: csrw mcause, t0 +; RV32-NEXT: lw t0, 112(sp) # 4-byte Folded Reload +; RV32-NEXT: .cfi_restore t0 +; RV32-NEXT: .cfi_restore ra +; RV32-NEXT: .cfi_restore t1 +; RV32-NEXT: .cfi_restore t2 +; RV32-NEXT: .cfi_restore s0 +; RV32-NEXT: .cfi_restore s1 +; RV32-NEXT: .cfi_restore a0 +; RV32-NEXT: .cfi_restore a1 +; RV32-NEXT: .cfi_restore a2 +; RV32-NEXT: .cfi_restore a3 +; RV32-NEXT: .cfi_restore a4 +; RV32-NEXT: .cfi_restore a5 +; RV32-NEXT: .cfi_restore a6 +; RV32-NEXT: .cfi_restore a7 +; RV32-NEXT: .cfi_restore t3 +; RV32-NEXT: .cfi_restore t4 +; RV32-NEXT: .cfi_restore t5 +; RV32-NEXT: .cfi_restore t6 +; RV32-NEXT: addi sp, sp, 128 +; RV32-NEXT: .cfi_def_cfa_offset 0 +; RV32-NEXT: mret +; +; RV64-LABEL: realign_var_alloca: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -192 +; RV64-NEXT: .cfi_def_cfa_offset 192 +; RV64-NEXT: sd t0, 160(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset t0, -32 +; RV64-NEXT: csrr t0, mcause +; RV64-NEXT: sd t0, 184(sp) # 8-byte Folded Spill +; RV64-NEXT: csrr t0, mepc +; RV64-NEXT: csrsi mstatus, 8 +; RV64-NEXT: sd t0, 176(sp) # 8-byte Folded Spill +; RV64-NEXT: sd ra, 168(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t1, 152(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t2, 144(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 136(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s1, 128(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a0, 120(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a1, 112(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a2, 104(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a3, 96(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a4, 88(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a5, 80(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a6, 72(sp) # 8-byte Folded Spill +; RV64-NEXT: sd a7, 64(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t3, 56(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t4, 48(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t5, 40(sp) # 8-byte Folded Spill +; RV64-NEXT: sd t6, 32(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset ra, -24 +; RV64-NEXT: .cfi_offset t1, -40 +; RV64-NEXT: .cfi_offset t2, -48 +; RV64-NEXT: .cfi_offset s0, -56 +; RV64-NEXT: .cfi_offset s1, -64 +; RV64-NEXT: .cfi_offset a0, -72 +; RV64-NEXT: .cfi_offset a1, -80 +; RV64-NEXT: .cfi_offset a2, -88 +; RV64-NEXT: .cfi_offset a3, -96 +; RV64-NEXT: .cfi_offset a4, -104 +; RV64-NEXT: .cfi_offset a5, -112 +; RV64-NEXT: .cfi_offset a6, -120 +; RV64-NEXT: .cfi_offset a7, -128 +; RV64-NEXT: .cfi_offset t3, -136 +; RV64-NEXT: .cfi_offset t4, -144 +; RV64-NEXT: .cfi_offset t5, -152 +; RV64-NEXT: .cfi_offset t6, -160 +; RV64-NEXT: addi s0, sp, 192 +; RV64-NEXT: .cfi_def_cfa s0, 0 +; RV64-NEXT: andi sp, sp, -64 +; RV64-NEXT: mv s1, sp +; RV64-NEXT: lui a0, %hi(size) +; RV64-NEXT: lwu a0, %lo(size)(a0) +; RV64-NEXT: addi a0, a0, 15 +; RV64-NEXT: andi a0, a0, -16 +; RV64-NEXT: sub a0, sp, a0 +; RV64-NEXT: andi a0, a0, -64 +; RV64-NEXT: mv sp, a0 +; RV64-NEXT: call use +; RV64-NEXT: addi sp, s0, -192 +; RV64-NEXT: .cfi_def_cfa sp, 192 +; RV64-NEXT: ld ra, 168(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t1, 152(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t2, 144(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 136(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s1, 128(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a0, 120(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a1, 112(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a2, 104(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a3, 96(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a4, 88(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a5, 80(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a6, 72(sp) # 8-byte Folded Reload +; RV64-NEXT: ld a7, 64(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t3, 56(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t4, 48(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t5, 40(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t6, 32(sp) # 8-byte Folded Reload +; RV64-NEXT: ld t0, 176(sp) # 8-byte Folded Reload +; RV64-NEXT: csrci mstatus, 8 +; RV64-NEXT: csrw mepc, t0 +; RV64-NEXT: ld t0, 184(sp) # 8-byte Folded Reload +; RV64-NEXT: csrw mcause, t0 +; RV64-NEXT: ld t0, 160(sp) # 8-byte Folded Reload +; RV64-NEXT: .cfi_restore t0 +; RV64-NEXT: .cfi_restore ra +; RV64-NEXT: .cfi_restore t1 +; RV64-NEXT: .cfi_restore t2 +; RV64-NEXT: .cfi_restore s0 +; RV64-NEXT: .cfi_restore s1 +; RV64-NEXT: .cfi_restore a0 +; RV64-NEXT: .cfi_restore a1 +; RV64-NEXT: .cfi_restore a2 +; RV64-NEXT: .cfi_restore a3 +; RV64-NEXT: .cfi_restore a4 +; RV64-NEXT: .cfi_restore a5 +; RV64-NEXT: .cfi_restore a6 +; RV64-NEXT: .cfi_restore a7 +; RV64-NEXT: .cfi_restore t3 +; RV64-NEXT: .cfi_restore t4 +; RV64-NEXT: .cfi_restore t5 +; RV64-NEXT: .cfi_restore t6 +; RV64-NEXT: addi sp, sp, 192 +; RV64-NEXT: .cfi_def_cfa_offset 0 +; RV64-NEXT: mret + %count = load volatile i32, ptr @size + %object = alloca i8, i32 %count, align 64 + call void @use(ptr %object) + ret void +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
