From 8e1fe13c2fdf0be06048d329710bf8ccee571fe1 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 17 Apr 2025 02:48:33 +0300 Subject: [PATCH] [RISCV] Guard CFI emission code with MF.needsFrameMoves() Currently, AsmPrinter skips CFI instructions if they are not needed. I'd like to change that so that it prints/encodes CFI instructions unconditionally. If a backend doesn't want them to be printed/encoded, it shouldn't create them. Apart from that, this change should slightly improve compile time as post-PEI passes no longer need to skip over these instructions in no-exceptions no-debug builds. The changes in a test seem to be caused by slightly different post-RA scheduling in the absence of CFI instructions. --- llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 122 +++++++++++------- .../CodeGen/RISCV/short-forward-branch-opt.ll | 32 ++--- llvm/test/CodeGen/RISCV/zdinx-spill.ll | 26 ---- 3 files changed, 92 insertions(+), 88 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 6c8e3da80b932..23b4554349003 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -95,6 +95,11 @@ static const std::pair FixedCSRFIQCIInterruptMap[] = { /* -21, -22, -23, -24 are reserved */ }; +/// Returns true if DWARF CFI instructions ("frame moves") should be emitted. +static bool needsDwarfCFI(const MachineFunction &MF) { + return MF.needsFrameMoves(); +} + // For now we use x3, a.k.a gp, as pointer to shadow call stack. // User should not use x3 in their asm. static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, @@ -141,6 +146,9 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, .addImm(-SlotSize) .setMIFlag(MachineInstr::FrameSetup); + if (!needsDwarfCFI(MF)) + return; + // Emit a CFI instruction that causes SlotSize to be subtracted from the value // of the shadow stack pointer when unwinding past this frame. char DwarfSCSReg = TRI->getDwarfRegNum(SCSPReg, /*IsEH*/ true); @@ -199,8 +207,10 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, .addReg(SCSPReg) .addImm(-SlotSize) .setMIFlag(MachineInstr::FrameDestroy); - // Restore the SCS pointer - CFIInstBuilder(MBB, MI, MachineInstr::FrameDestroy).buildRestore(SCSPReg); + if (needsDwarfCFI(MF)) { + // Restore the SCS pointer + CFIInstBuilder(MBB, MI, MachineInstr::FrameDestroy).buildRestore(SCSPReg); + } } // Insert instruction to swap mscratchsw with sp @@ -935,6 +945,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, MBBI = std::prev(MBBI, getRVVCalleeSavedInfo(MF, CSI).size() + getUnmanagedCSI(MF, CSI).size()); CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::FrameSetup); + bool NeedsDwarfCFI = needsDwarfCFI(MF); // If libcalls are used to spill and restore callee-saved registers, the frame // has two sections; the opaque section managed by the libcalls, and the @@ -962,10 +973,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign()); RVFI->setLibCallStackSize(LibCallFrameSize); - CFIBuilder.buildDefCFAOffset(LibCallFrameSize); - for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI)) - CFIBuilder.buildOffset(CS.getReg(), - MFI.getObjectOffset(CS.getFrameIdx())); + if (NeedsDwarfCFI) { + CFIBuilder.buildDefCFAOffset(LibCallFrameSize); + for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI)) + CFIBuilder.buildOffset(CS.getReg(), + MFI.getObjectOffset(CS.getFrameIdx())); + } } // FIXME (note copied from Lanai): This appears to be overallocating. Needs @@ -996,14 +1009,17 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // could only be the next instruction. ++PossiblePush; - // Insert the CFI metadata before where we think the `(QC.)CM.PUSH(FP)` - // could be. The PUSH will also get its own CFI metadata for its own - // modifications, which should come after the PUSH. - CFIInstBuilder PushCFIBuilder(MBB, PossiblePush, MachineInstr::FrameSetup); - PushCFIBuilder.buildDefCFAOffset(QCIInterruptPushAmount); - for (const CalleeSavedInfo &CS : getQCISavedInfo(MF, CSI)) - PushCFIBuilder.buildOffset(CS.getReg(), - MFI.getObjectOffset(CS.getFrameIdx())); + if (NeedsDwarfCFI) { + // Insert the CFI metadata before where we think the `(QC.)CM.PUSH(FP)` + // could be. The PUSH will also get its own CFI metadata for its own + // modifications, which should come after the PUSH. + CFIInstBuilder PushCFIBuilder(MBB, PossiblePush, + MachineInstr::FrameSetup); + PushCFIBuilder.buildDefCFAOffset(QCIInterruptPushAmount); + for (const CalleeSavedInfo &CS : getQCISavedInfo(MF, CSI)) + PushCFIBuilder.buildOffset(CS.getReg(), + MFI.getObjectOffset(CS.getFrameIdx())); + } } if (RVFI->isPushable(MF) && PossiblePush != MBB.end() && @@ -1017,10 +1033,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, PossiblePush->getOperand(1).setImm(StackAdj); StackSize -= StackAdj; - CFIBuilder.buildDefCFAOffset(RealStackSize - StackSize); - for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI)) - CFIBuilder.buildOffset(CS.getReg(), - MFI.getObjectOffset(CS.getFrameIdx())); + if (NeedsDwarfCFI) { + CFIBuilder.buildDefCFAOffset(RealStackSize - StackSize); + for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI)) + CFIBuilder.buildOffset(CS.getReg(), + MFI.getObjectOffset(CS.getFrameIdx())); + } } // Allocate space on the stack if necessary. @@ -1031,7 +1049,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, bool DynAllocation = MF.getInfo()->hasDynamicAllocation(); if (StackSize != 0) - allocateStack(MBB, MBBI, MF, StackSize, RealStackSize, /*EmitCFI=*/true, + allocateStack(MBB, MBBI, MF, StackSize, RealStackSize, NeedsDwarfCFI, NeedProbe, ProbeSize, DynAllocation, MachineInstr::FrameSetup); @@ -1049,8 +1067,10 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // Iterate over list of callee-saved registers and emit .cfi_offset // directives. - for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI)) - CFIBuilder.buildOffset(CS.getReg(), MFI.getObjectOffset(CS.getFrameIdx())); + if (NeedsDwarfCFI) + for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI)) + CFIBuilder.buildOffset(CS.getReg(), + MFI.getObjectOffset(CS.getFrameIdx())); // Generate new FP. if (hasFP(MF)) { @@ -1069,7 +1089,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, MachineInstr::FrameSetup, getStackAlign()); } - CFIBuilder.buildDefCFA(FPReg, RVFI->getVarArgsSaveSize()); + if (NeedsDwarfCFI) + CFIBuilder.buildDefCFA(FPReg, RVFI->getVarArgsSaveSize()); } uint64_t SecondSPAdjustAmount = 0; @@ -1080,15 +1101,16 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, "SecondSPAdjustAmount should be greater than zero"); allocateStack(MBB, MBBI, MF, SecondSPAdjustAmount, - getStackSizeWithRVVPadding(MF), !hasFP(MF), NeedProbe, - ProbeSize, DynAllocation, MachineInstr::FrameSetup); + getStackSizeWithRVVPadding(MF), NeedsDwarfCFI && !hasFP(MF), + NeedProbe, ProbeSize, DynAllocation, + MachineInstr::FrameSetup); } if (RVVStackSize) { if (NeedProbe) { allocateAndProbeStackForRVV(MF, MBB, MBBI, DL, RVVStackSize, - MachineInstr::FrameSetup, !hasFP(MF), - DynAllocation); + MachineInstr::FrameSetup, + NeedsDwarfCFI && !hasFP(MF), DynAllocation); } else { // We must keep the stack pointer aligned through any intermediate // updates. @@ -1097,14 +1119,15 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, MachineInstr::FrameSetup, getStackAlign()); } - if (!hasFP(MF)) { + if (NeedsDwarfCFI && !hasFP(MF)) { // Emit .cfi_def_cfa_expression "sp + StackSize + RVVStackSize * vlenb". CFIBuilder.insertCFIInst(createDefCFAExpression( *RI, SPReg, getStackSizeWithRVVPadding(MF), RVVStackSize / 8)); } std::advance(MBBI, getRVVCalleeSavedInfo(MF, CSI).size()); - emitCalleeSavedRVVPrologCFI(MBB, MBBI, hasFP(MF)); + if (NeedsDwarfCFI) + emitCalleeSavedRVVPrologCFI(MBB, MBBI, hasFP(MF)); } if (hasFP(MF)) { @@ -1171,8 +1194,9 @@ void RISCVFrameLowering::deallocateStack(MachineFunction &MF, MachineInstr::FrameDestroy, getStackAlign()); StackSize = 0; - CFIInstBuilder(MBB, MBBI, MachineInstr::FrameDestroy) - .buildDefCFAOffset(CFAOffset); + if (needsDwarfCFI(MF)) + CFIInstBuilder(MBB, MBBI, MachineInstr::FrameDestroy) + .buildDefCFAOffset(CFAOffset); } void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, @@ -1212,6 +1236,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, std::next(MBBI, getRVVCalleeSavedInfo(MF, CSI).size()); CFIInstBuilder CFIBuilder(MBB, FirstScalarCSRRestoreInsn, MachineInstr::FrameDestroy); + bool NeedsDwarfCFI = needsDwarfCFI(MF); uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount @@ -1232,10 +1257,11 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, StackOffset::getScalable(RVVStackSize), MachineInstr::FrameDestroy, getStackAlign()); - if (!hasFP(MF)) - CFIBuilder.buildDefCFA(SPReg, RealStackSize); - - emitCalleeSavedRVVEpilogCFI(MBB, FirstScalarCSRRestoreInsn); + if (NeedsDwarfCFI) { + if (!hasFP(MF)) + CFIBuilder.buildDefCFA(SPReg, RealStackSize); + emitCalleeSavedRVVEpilogCFI(MBB, FirstScalarCSRRestoreInsn); + } } if (FirstSPAdjustAmount) { @@ -1251,7 +1277,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, StackOffset::getFixed(SecondSPAdjustAmount), MachineInstr::FrameDestroy, getStackAlign()); - if (!hasFP(MF)) + if (NeedsDwarfCFI && !hasFP(MF)) CFIBuilder.buildDefCFAOffset(FirstSPAdjustAmount); } @@ -1272,7 +1298,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, getStackAlign()); } - if (hasFP(MF)) + if (NeedsDwarfCFI && hasFP(MF)) CFIBuilder.buildDefCFA(SPReg, RealStackSize); // Skip to after the restores of scalar callee-saved registers @@ -1295,8 +1321,9 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, } // Recover callee-saved registers. - for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI)) - CFIBuilder.buildRestore(CS.getReg()); + if (NeedsDwarfCFI) + for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI)) + CFIBuilder.buildRestore(CS.getReg()); if (RVFI->isPushable(MF) && MBBI != MBB.end() && isPop(MBBI->getOpcode())) { // Use available stack adjustment in pop instruction to deallocate stack @@ -1315,15 +1342,17 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, auto NextI = next_nodbg(MBBI, MBB.end()); if (NextI == MBB.end() || NextI->getOpcode() != RISCV::PseudoRET) { ++MBBI; - CFIBuilder.setInsertPoint(MBBI); + if (NeedsDwarfCFI) { + CFIBuilder.setInsertPoint(MBBI); - for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI)) - CFIBuilder.buildRestore(CS.getReg()); + for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI)) + CFIBuilder.buildRestore(CS.getReg()); - // Update CFA Offset. 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. - CFIBuilder.buildDefCFAOffset(RVFI->getQCIInterruptStackSize()); + // Update CFA Offset. 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. + CFIBuilder.buildDefCFAOffset(RVFI->getQCIInterruptStackSize()); + } } } @@ -1812,7 +1841,8 @@ MachineBasicBlock::iterator RISCVFrameLowering::eliminateCallFramePseudoInstr( // allocateStack. bool DynAllocation = MF.getInfo()->hasDynamicAllocation(); - allocateStack(MBB, MI, MF, -Amount, -Amount, !hasFP(MF), + allocateStack(MBB, MI, MF, -Amount, -Amount, + needsDwarfCFI(MF) && !hasFP(MF), /*NeedProbe=*/true, ProbeSize, DynAllocation, MachineInstr::NoFlags); } else { diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll index 061435c45ad0e..59a702ab6b17f 100644 --- a/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll +++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll @@ -798,12 +798,12 @@ define void @sextw_removal_ccor(i1 %c, i32 signext %arg, i32 signext %arg1, i32 ; RV64SFBSIFIVEU74-LABEL: sextw_removal_ccor: ; RV64SFBSIFIVEU74: # %bb.0: # %bb ; RV64SFBSIFIVEU74-NEXT: addi sp, sp, -32 -; RV64SFBSIFIVEU74-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; RV64SFBSIFIVEU74-NEXT: sd s0, 16(sp) # 8-byte Folded Spill -; RV64SFBSIFIVEU74-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64SFBSIFIVEU74-NEXT: mv s0, a3 +; RV64SFBSIFIVEU74-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64SFBSIFIVEU74-NEXT: andi a0, a0, 1 ; RV64SFBSIFIVEU74-NEXT: mv s1, a2 +; RV64SFBSIFIVEU74-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; RV64SFBSIFIVEU74-NEXT: beqz a0, .LBB15_4 ; RV64SFBSIFIVEU74-NEXT: # %bb.3: # %bb ; RV64SFBSIFIVEU74-NEXT: or s0, a3, a1 @@ -824,11 +824,11 @@ define void @sextw_removal_ccor(i1 %c, i32 signext %arg, i32 signext %arg1, i32 ; RV64SFBANDESAX45-LABEL: sextw_removal_ccor: ; RV64SFBANDESAX45: # %bb.0: # %bb ; RV64SFBANDESAX45-NEXT: addi sp, sp, -32 -; RV64SFBANDESAX45-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; RV64SFBANDESAX45-NEXT: sd s0, 16(sp) # 8-byte Folded Spill -; RV64SFBANDESAX45-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64SFBANDESAX45-NEXT: mv s0, a3 +; RV64SFBANDESAX45-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64SFBANDESAX45-NEXT: mv s1, a2 +; RV64SFBANDESAX45-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; RV64SFBANDESAX45-NEXT: nds.bbc a0, 0, .LBB15_2 ; RV64SFBANDESAX45-NEXT: # %bb.1: ; RV64SFBANDESAX45-NEXT: or s0, s0, a1 @@ -848,12 +848,12 @@ define void @sextw_removal_ccor(i1 %c, i32 signext %arg, i32 signext %arg1, i32 ; ZICOND-LABEL: sextw_removal_ccor: ; ZICOND: # %bb.0: # %bb ; ZICOND-NEXT: addi sp, sp, -32 -; ZICOND-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; ZICOND-NEXT: sd s0, 16(sp) # 8-byte Folded Spill -; ZICOND-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; ZICOND-NEXT: mv s0, a3 +; ZICOND-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; ZICOND-NEXT: andi a0, a0, 1 ; ZICOND-NEXT: mv s1, a2 +; ZICOND-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; ZICOND-NEXT: beqz a0, .LBB15_4 ; ZICOND-NEXT: # %bb.3: # %bb ; ZICOND-NEXT: or s0, a3, a1 @@ -874,12 +874,12 @@ define void @sextw_removal_ccor(i1 %c, i32 signext %arg, i32 signext %arg1, i32 ; RV32SFB-LABEL: sextw_removal_ccor: ; RV32SFB: # %bb.0: # %bb ; RV32SFB-NEXT: addi sp, sp, -16 -; RV32SFB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32SFB-NEXT: sw s0, 8(sp) # 4-byte Folded Spill -; RV32SFB-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32SFB-NEXT: mv s0, a3 +; RV32SFB-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32SFB-NEXT: andi a0, a0, 1 ; RV32SFB-NEXT: mv s1, a2 +; RV32SFB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32SFB-NEXT: beqz a0, .LBB15_4 ; RV32SFB-NEXT: # %bb.3: # %bb ; RV32SFB-NEXT: or s0, a3, a1 @@ -941,11 +941,11 @@ define void @sextw_removal_ccaddw(i1 %c, i32 signext %arg, i32 signext %arg1, i3 ; RV64SFBSIFIVEU74-LABEL: sextw_removal_ccaddw: ; RV64SFBSIFIVEU74: # %bb.0: # %bb ; RV64SFBSIFIVEU74-NEXT: addi sp, sp, -32 -; RV64SFBSIFIVEU74-NEXT: sd ra, 24(sp) # 8-byte Folded Spill -; RV64SFBSIFIVEU74-NEXT: sd s0, 16(sp) # 8-byte Folded Spill ; RV64SFBSIFIVEU74-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64SFBSIFIVEU74-NEXT: mv s1, a1 ; RV64SFBSIFIVEU74-NEXT: andi a0, a0, 1 +; RV64SFBSIFIVEU74-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64SFBSIFIVEU74-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; RV64SFBSIFIVEU74-NEXT: mv s0, a2 ; RV64SFBSIFIVEU74-NEXT: beqz a0, .LBB16_4 ; RV64SFBSIFIVEU74-NEXT: # %bb.3: # %bb @@ -967,11 +967,11 @@ define void @sextw_removal_ccaddw(i1 %c, i32 signext %arg, i32 signext %arg1, i3 ; RV64SFBANDESAX45-LABEL: sextw_removal_ccaddw: ; RV64SFBANDESAX45: # %bb.0: # %bb ; RV64SFBANDESAX45-NEXT: addi sp, sp, -32 -; RV64SFBANDESAX45-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; RV64SFBANDESAX45-NEXT: sd s0, 16(sp) # 8-byte Folded Spill -; RV64SFBANDESAX45-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64SFBANDESAX45-NEXT: mv s0, a2 +; RV64SFBANDESAX45-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64SFBANDESAX45-NEXT: mv s1, a1 +; RV64SFBANDESAX45-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; RV64SFBANDESAX45-NEXT: nds.bbc a0, 0, .LBB16_2 ; RV64SFBANDESAX45-NEXT: # %bb.1: ; RV64SFBANDESAX45-NEXT: addw s1, s1, a3 @@ -991,11 +991,11 @@ define void @sextw_removal_ccaddw(i1 %c, i32 signext %arg, i32 signext %arg1, i3 ; ZICOND-LABEL: sextw_removal_ccaddw: ; ZICOND: # %bb.0: # %bb ; ZICOND-NEXT: addi sp, sp, -32 -; ZICOND-NEXT: sd ra, 24(sp) # 8-byte Folded Spill -; ZICOND-NEXT: sd s0, 16(sp) # 8-byte Folded Spill ; ZICOND-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; ZICOND-NEXT: mv s1, a1 ; ZICOND-NEXT: andi a0, a0, 1 +; ZICOND-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; ZICOND-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; ZICOND-NEXT: mv s0, a2 ; ZICOND-NEXT: beqz a0, .LBB16_4 ; ZICOND-NEXT: # %bb.3: # %bb @@ -1017,11 +1017,11 @@ define void @sextw_removal_ccaddw(i1 %c, i32 signext %arg, i32 signext %arg1, i3 ; RV32SFB-LABEL: sextw_removal_ccaddw: ; RV32SFB: # %bb.0: # %bb ; RV32SFB-NEXT: addi sp, sp, -16 -; RV32SFB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32SFB-NEXT: sw s0, 8(sp) # 4-byte Folded Spill ; RV32SFB-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32SFB-NEXT: mv s1, a1 ; RV32SFB-NEXT: andi a0, a0, 1 +; RV32SFB-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32SFB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32SFB-NEXT: mv s0, a2 ; RV32SFB-NEXT: beqz a0, .LBB16_4 ; RV32SFB-NEXT: # %bb.3: # %bb diff --git a/llvm/test/CodeGen/RISCV/zdinx-spill.ll b/llvm/test/CodeGen/RISCV/zdinx-spill.ll index d7a700622bf8c..6f206fe571c17 100644 --- a/llvm/test/CodeGen/RISCV/zdinx-spill.ll +++ b/llvm/test/CodeGen/RISCV/zdinx-spill.ll @@ -9,7 +9,6 @@ define double @foo(double %x) nounwind { ; CHECK-NEXT: liveins: $x10, $x11, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -64 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 64 ; CHECK-NEXT: frame-setup SW killed $x8, $x2, 60 :: (store (s32) into %stack.1) ; CHECK-NEXT: frame-setup SW killed $x9, $x2, 56 :: (store (s32) into %stack.2) ; CHECK-NEXT: frame-setup SW killed $x18, $x2, 52 :: (store (s32) into %stack.3) @@ -22,18 +21,6 @@ define double @foo(double %x) nounwind { ; CHECK-NEXT: frame-setup SW killed $x25, $x2, 24 :: (store (s32) into %stack.10) ; CHECK-NEXT: frame-setup SW killed $x26, $x2, 20 :: (store (s32) into %stack.11) ; CHECK-NEXT: frame-setup SW killed $x27, $x2, 16 :: (store (s32) into %stack.12) - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x8, -4 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x9, -8 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x18, -12 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x19, -16 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x20, -20 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x21, -24 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x22, -28 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x23, -32 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x24, -36 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x25, -40 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x26, -44 - ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $x27, -48 ; CHECK-NEXT: renamable $x10_x11 = nofpexcept FADD_D_IN32X killed renamable $x10_x11, renamable $x10_x11, 7, implicit $frm ; CHECK-NEXT: PseudoRV32ZdinxSD killed renamable $x10_x11, $x2, 8 :: (store (s64) into %stack.0, align 4) ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $x6, 12 /* clobber */, implicit-def dead early-clobber $x7, 12 /* clobber */, implicit-def dead early-clobber $x8, 12 /* clobber */, implicit-def dead early-clobber $x9, 12 /* clobber */, implicit-def dead early-clobber $x10, 12 /* clobber */, implicit-def dead early-clobber $x11, 12 /* clobber */, implicit-def dead early-clobber $x12, 12 /* clobber */, implicit-def dead early-clobber $x13, 12 /* clobber */, implicit-def dead early-clobber $x14, 12 /* clobber */, implicit-def dead early-clobber $x15, 12 /* clobber */, implicit-def dead early-clobber $x16, 12 /* clobber */, implicit-def dead early-clobber $x17, 12 /* clobber */, implicit-def dead early-clobber $x18, 12 /* clobber */, implicit-def dead early-clobber $x19, 12 /* clobber */, implicit-def dead early-clobber $x20, 12 /* clobber */, implicit-def dead early-clobber $x21, 12 /* clobber */, implicit-def dead early-clobber $x22, 12 /* clobber */, implicit-def dead early-clobber $x23, 12 /* clobber */, implicit-def dead early-clobber $x24, 12 /* clobber */, implicit-def dead early-clobber $x25, 12 /* clobber */, implicit-def dead early-clobber $x26, 12 /* clobber */, implicit-def dead early-clobber $x27, 12 /* clobber */, implicit-def dead early-clobber $x28, 12 /* clobber */, implicit-def dead early-clobber $x29, 12 /* clobber */, implicit-def dead early-clobber $x31 @@ -50,20 +37,7 @@ define double @foo(double %x) nounwind { ; CHECK-NEXT: $x25 = frame-destroy LW $x2, 24 :: (load (s32) from %stack.10) ; CHECK-NEXT: $x26 = frame-destroy LW $x2, 20 :: (load (s32) from %stack.11) ; CHECK-NEXT: $x27 = frame-destroy LW $x2, 16 :: (load (s32) from %stack.12) - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x8 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x9 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x18 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x19 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x20 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x21 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x22 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x23 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x24 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x25 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x26 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $x27 ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 64 - ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0 ; CHECK-NEXT: PseudoRET implicit $x10, implicit $x11 %a = fadd double %x, %x call void asm sideeffect "", "~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15},~{x16},~{x17},~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{x29},~{xr0},~{x31}"()