diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 19103e219cb80..ca2f868cd4e76 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -208,6 +208,12 @@ static inline unsigned getVLOpNum(const MCInstrDesc &Desc) { return Desc.getNumOperands() - Offset; } +static inline unsigned getTailExpandUseRegNo(const FeatureBitset &FeatureBits) { + // For Zicfilp, PseudoTAIL should be expanded to a software guarded branch. + // It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL. + return FeatureBits[RISCV::FeatureStdExtZicfilp] ? RISCV::X7 : RISCV::X6; +} + static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) { const uint64_t TSFlags = Desc.TSFlags; assert(hasSEWOp(TSFlags)); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 6bb49e2bb85fe..a28bf1186589d 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -124,11 +124,7 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, MCRegister Ra; if (MI.getOpcode() == RISCV::PseudoTAIL) { Func = MI.getOperand(0); - Ra = RISCV::X6; - // For Zicfilp, PseudoTAIL should be expanded to a software guarded branch. - // It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL. - if (STI.hasFeature(RISCV::FeatureStdExtZicfilp)) - Ra = RISCV::X7; + Ra = RISCVII::getTailExpandUseRegNo(STI.getFeatureBits()); } else if (MI.getOpcode() == RISCV::PseudoCALLReg) { Func = MI.getOperand(1); Ra = MI.getOperand(0).getReg(); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 933e776da4740..47273d6bc06d6 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "RISCVInstrInfo.h" +#include "MCTargetDesc/RISCVBaseInfo.h" #include "MCTargetDesc/RISCVMatInt.h" #include "RISCV.h" #include "RISCVMachineFunctionInfo.h" @@ -2927,6 +2928,7 @@ bool RISCVInstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, // Enum values indicating how an outlined call should be constructed. enum MachineOutlinerConstructionID { + MachineOutlinerTailCall, MachineOutlinerDefault }; @@ -2935,46 +2937,118 @@ bool RISCVInstrInfo::shouldOutlineFromFunctionByDefault( return MF.getFunction().hasMinSize(); } +static bool isCandidatePatchable(const MachineBasicBlock &MBB) { + const MachineFunction *MF = MBB.getParent(); + const Function &F = MF->getFunction(); + return F.getFnAttribute("fentry-call").getValueAsBool() || + F.hasFnAttribute("patchable-function-entry"); +} + +static bool isMIReadsReg(const MachineInstr &MI, const TargetRegisterInfo *TRI, + unsigned RegNo) { + return MI.readsRegister(RegNo, TRI) || + MI.getDesc().hasImplicitUseOfPhysReg(RegNo); +} + +static bool isMIModifiesReg(const MachineInstr &MI, + const TargetRegisterInfo *TRI, unsigned RegNo) { + return MI.modifiesRegister(RegNo, TRI) || + MI.getDesc().hasImplicitDefOfPhysReg(RegNo); +} + +static bool cannotInsertTailCall(const MachineBasicBlock &MBB) { + if (!MBB.back().isReturn()) + return true; + if (isCandidatePatchable(MBB)) + return true; + + // If the candidate reads the pre-set register + // that can be used for expanding PseudoTAIL instruction, + // then we cannot insert tail call. + const TargetSubtargetInfo &STI = MBB.getParent()->getSubtarget(); + unsigned TailExpandUseRegNo = + RISCVII::getTailExpandUseRegNo(STI.getFeatureBits()); + for (const MachineInstr &MI : MBB) { + if (isMIReadsReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo)) + return true; + if (isMIModifiesReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo)) + break; + } + return false; +} + +static std::optional +analyzeCandidate(outliner::Candidate &C) { + // If last instruction is return then we can rely on + // the verification already performed in the getOutliningTypeImpl. + if (C.back().isReturn()) { + assert(!cannotInsertTailCall(*C.getMBB()) && + "The candidate who uses return instruction must be outlined " + "using tail call"); + return MachineOutlinerTailCall; + } + + auto CandidateUsesX5 = [](outliner::Candidate &C) { + const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo(); + if (std::any_of(C.begin(), C.end(), [TRI](const MachineInstr &MI) { + return isMIModifiesReg(MI, TRI, RISCV::X5); + })) + return true; + return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI); + }; + + if (!CandidateUsesX5(C)) + return MachineOutlinerDefault; + + return std::nullopt; +} + std::optional> RISCVInstrInfo::getOutliningCandidateInfo( const MachineModuleInfo &MMI, std::vector &RepeatedSequenceLocs, unsigned MinRepeats) const { - // First we need to filter out candidates where the X5 register (IE t0) can't - // be used to setup the function call. - auto CannotInsertCall = [](outliner::Candidate &C) { - const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo(); - return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI); - }; - - llvm::erase_if(RepeatedSequenceLocs, CannotInsertCall); + // Each RepeatedSequenceLoc is identical. + outliner::Candidate &Candidate = RepeatedSequenceLocs[0]; + auto CandidateInfo = analyzeCandidate(Candidate); + if (!CandidateInfo) + RepeatedSequenceLocs.clear(); // If the sequence doesn't have enough candidates left, then we're done. if (RepeatedSequenceLocs.size() < MinRepeats) return std::nullopt; - unsigned SequenceSize = 0; - - for (auto &MI : RepeatedSequenceLocs[0]) - SequenceSize += getInstSizeInBytes(MI); + unsigned InstrSizeCExt = + Candidate.getMF()->getSubtarget().hasStdExtCOrZca() ? 2 + : 4; + unsigned CallOverhead = 0, FrameOverhead = 0; + + MachineOutlinerConstructionID MOCI = CandidateInfo.value(); + switch (MOCI) { + case MachineOutlinerDefault: + // call t0, function = 8 bytes. + CallOverhead = 8; + // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled. + FrameOverhead = InstrSizeCExt; + break; + case MachineOutlinerTailCall: + // tail call = auipc + jalr in the worst case without linker relaxation. + CallOverhead = 4 + InstrSizeCExt; + // Using tail call we move ret instruction from caller to callee. + FrameOverhead = 0; + break; + } - // call t0, function = 8 bytes. - unsigned CallOverhead = 8; for (auto &C : RepeatedSequenceLocs) - C.setCallInfo(MachineOutlinerDefault, CallOverhead); + C.setCallInfo(MOCI, CallOverhead); - // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled. - unsigned FrameOverhead = 4; - if (RepeatedSequenceLocs[0] - .getMF() - ->getSubtarget() - .hasStdExtCOrZca()) - FrameOverhead = 2; + unsigned SequenceSize = 0; + for (auto &MI : Candidate) + SequenceSize += getInstSizeInBytes(MI); return std::make_unique( - RepeatedSequenceLocs, SequenceSize, FrameOverhead, - MachineOutlinerDefault); + RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI); } outliner::InstrType @@ -2995,15 +3069,8 @@ RISCVInstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI, return F.needsUnwindTableEntry() ? outliner::InstrType::Illegal : outliner::InstrType::Invisible; - // We need support for tail calls to outlined functions before return - // statements can be allowed. - if (MI.isReturn()) - return outliner::InstrType::Illegal; - - // Don't allow modifying the X5 register which we use for return addresses for - // these outlined functions. - if (MI.modifiesRegister(RISCV::X5, TRI) || - MI.getDesc().hasImplicitDefOfPhysReg(RISCV::X5)) + if (cannotInsertTailCall(*MBB) && + (MI.isReturn() || isMIModifiesReg(MI, TRI, RISCV::X5))) return outliner::InstrType::Illegal; // Make sure the operands don't reference something unsafe. @@ -3039,6 +3106,9 @@ void RISCVInstrInfo::buildOutlinedFrame( } } + if (OF.FrameConstructionID == MachineOutlinerTailCall) + return; + MBB.addLiveIn(RISCV::X5); // Add in a return instruction to the end of the outlined frame. @@ -3052,6 +3122,13 @@ MachineBasicBlock::iterator RISCVInstrInfo::insertOutlinedCall( Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const { + if (C.CallConstructionID == MachineOutlinerTailCall) { + It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoTAIL)) + .addGlobalAddress(M.getNamedValue(MF.getName()), + /*Offset=*/0, RISCVII::MO_CALL)); + return It; + } + // Add in a call instruction to the outlined function at the given location. It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5) diff --git a/llvm/test/CodeGen/RISCV/compress-opt-select.ll b/llvm/test/CodeGen/RISCV/compress-opt-select.ll index f9333a45016a0..733c84ac23613 100644 --- a/llvm/test/CodeGen/RISCV/compress-opt-select.ll +++ b/llvm/test/CodeGen/RISCV/compress-opt-select.ll @@ -13,11 +13,9 @@ define i32 @ne_small_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: c.li a1, 20 ; RV32IFDC-NEXT: bne a0, a1, .LBB0_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB0_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_small_pos: ; RV32IFD: # %bb.0: @@ -41,11 +39,9 @@ define i32 @ne_small_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: c.li a1, -20 ; RV32IFDC-NEXT: bne a0, a1, .LBB1_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB1_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_small_neg: ; RV32IFD: # %bb.0: @@ -69,11 +65,9 @@ define i32 @ne_small_edge_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: c.li a1, 31 ; RV32IFDC-NEXT: bne a0, a1, .LBB2_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB2_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_small_edge_pos: ; RV32IFD: # %bb.0: @@ -97,11 +91,9 @@ define i32 @ne_small_edge_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: c.li a1, -32 ; RV32IFDC-NEXT: bne a0, a1, .LBB3_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB3_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_small_edge_neg: ; RV32IFD: # %bb.0: @@ -126,11 +118,9 @@ define i32 @ne_medium_ledge_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, -33 ; RV32IFDC-NEXT: c.bnez a0, .LBB4_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB4_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_medium_ledge_pos: ; RV32IFD: # %bb.0: @@ -155,11 +145,9 @@ define i32 @ne_medium_ledge_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, 33 ; RV32IFDC-NEXT: c.bnez a0, .LBB5_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB5_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_medium_ledge_neg: ; RV32IFD: # %bb.0: @@ -184,11 +172,9 @@ define i32 @ne_medium_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, -63 ; RV32IFDC-NEXT: c.bnez a0, .LBB6_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB6_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_medium_pos: ; RV32IFD: # %bb.0: @@ -213,11 +199,9 @@ define i32 @ne_medium_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, 63 ; RV32IFDC-NEXT: c.bnez a0, .LBB7_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB7_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_medium_neg: ; RV32IFD: # %bb.0: @@ -242,11 +226,9 @@ define i32 @ne_medium_bedge_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, -2047 ; RV32IFDC-NEXT: c.bnez a0, .LBB8_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB8_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_medium_bedge_pos: ; RV32IFD: # %bb.0: @@ -271,11 +253,9 @@ define i32 @ne_medium_bedge_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, 2047 ; RV32IFDC-NEXT: c.bnez a0, .LBB9_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB9_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_medium_bedge_neg: ; RV32IFD: # %bb.0: @@ -300,11 +280,9 @@ define i32 @ne_big_ledge_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: c.slli a1, 11 ; RV32IFDC-NEXT: bne a0, a1, .LBB10_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB10_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_big_ledge_pos: ; RV32IFD: # %bb.0: @@ -329,11 +307,9 @@ define i32 @ne_big_ledge_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a1, zero, -2048 ; RV32IFDC-NEXT: bne a0, a1, .LBB11_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB11_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: ne_big_ledge_neg: ; RV32IFD: # %bb.0: @@ -360,11 +336,9 @@ define i32 @eq_small_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: c.li a1, 20 ; RV32IFDC-NEXT: beq a0, a1, .LBB12_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB12_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_small_pos: ; RV32IFD: # %bb.0: @@ -388,11 +362,9 @@ define i32 @eq_small_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: c.li a1, -20 ; RV32IFDC-NEXT: beq a0, a1, .LBB13_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB13_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_small_neg: ; RV32IFD: # %bb.0: @@ -416,11 +388,9 @@ define i32 @eq_small_edge_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: c.li a1, 31 ; RV32IFDC-NEXT: beq a0, a1, .LBB14_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB14_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_small_edge_pos: ; RV32IFD: # %bb.0: @@ -444,11 +414,9 @@ define i32 @eq_small_edge_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: c.li a1, -32 ; RV32IFDC-NEXT: beq a0, a1, .LBB15_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB15_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_small_edge_neg: ; RV32IFD: # %bb.0: @@ -473,11 +441,9 @@ define i32 @eq_medium_ledge_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, -33 ; RV32IFDC-NEXT: c.beqz a0, .LBB16_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB16_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_medium_ledge_pos: ; RV32IFD: # %bb.0: @@ -502,11 +468,9 @@ define i32 @eq_medium_ledge_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, 33 ; RV32IFDC-NEXT: c.beqz a0, .LBB17_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB17_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_medium_ledge_neg: ; RV32IFD: # %bb.0: @@ -531,11 +495,9 @@ define i32 @eq_medium_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, -63 ; RV32IFDC-NEXT: c.beqz a0, .LBB18_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB18_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_medium_pos: ; RV32IFD: # %bb.0: @@ -560,11 +522,9 @@ define i32 @eq_medium_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, 63 ; RV32IFDC-NEXT: c.beqz a0, .LBB19_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB19_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_medium_neg: ; RV32IFD: # %bb.0: @@ -589,11 +549,9 @@ define i32 @eq_medium_bedge_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, -2047 ; RV32IFDC-NEXT: c.beqz a0, .LBB20_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB20_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_medium_bedge_pos: ; RV32IFD: # %bb.0: @@ -618,11 +576,9 @@ define i32 @eq_medium_bedge_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a0, a0, 2047 ; RV32IFDC-NEXT: c.beqz a0, .LBB21_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB21_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_medium_bedge_neg: ; RV32IFD: # %bb.0: @@ -647,11 +603,9 @@ define i32 @eq_big_ledge_pos(i32 %in0) minsize { ; RV32IFDC-NEXT: c.slli a1, 11 ; RV32IFDC-NEXT: beq a0, a1, .LBB22_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB22_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_big_ledge_pos: ; RV32IFD: # %bb.0: @@ -676,11 +630,9 @@ define i32 @eq_big_ledge_neg(i32 %in0) minsize { ; RV32IFDC-NEXT: addi a1, zero, -2048 ; RV32IFDC-NEXT: beq a0, a1, .LBB23_2 ; RV32IFDC-NEXT: # %bb.1: -; RV32IFDC-NEXT: addi a0, zero, 42 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_1 ; RV32IFDC-NEXT: .LBB23_2: -; RV32IFDC-NEXT: addi a0, zero, -99 -; RV32IFDC-NEXT: c.jr ra +; RV32IFDC-NEXT: tail OUTLINED_FUNCTION_0 ; ; RV32IFD-LABEL: eq_big_ledge_neg: ; RV32IFD: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-call.ll b/llvm/test/CodeGen/RISCV/machine-outliner-call.ll new file mode 100644 index 0000000000000..b019cfe74864b --- /dev/null +++ b/llvm/test/CodeGen/RISCV/machine-outliner-call.ll @@ -0,0 +1,70 @@ +; RUN: llc < %s -verify-machineinstrs -enable-machine-outliner | FileCheck %s + +target triple = "riscv64-unknown-linux-gnu" + +declare void @foo(i32, i32, i32, i32) minsize + +define void @fentry0(i1 %a) nounwind { +; CHECK-LABEL: fentry0: +; CHECK: # %bb.1: +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB1:[0-9]+]] +; CHECK-NEXT: call foo +; CHECK-LABEL: .LBB0_2: +; CHECK-NEXT: tail OUTLINED_FUNCTION_[[BB2:[0-9]+]] +entry: + br i1 %a, label %if.then, label %if.end +if.then: + call void @foo(i32 1, i32 2, i32 3, i32 4) + br label %if.end +if.end: + call void @foo(i32 5, i32 6, i32 7, i32 8) + ret void +} + +define void @fentry1(i1 %a) nounwind { +; CHECK-LABEL: fentry1: +; CHECK: # %bb.1: +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB1:[0-9]+]] +; CHECK-NEXT: call foo +; CHECK-LABEL: .LBB1_2: +; CHECK-NEXT: tail OUTLINED_FUNCTION_[[BB2:[0-9]+]] +entry: + br i1 %a, label %if.then, label %if.end +if.then: + call void @foo(i32 1, i32 2, i32 3, i32 4) + br label %if.end +if.end: + call void @foo(i32 5, i32 6, i32 7, i32 8) + ret void +} + +define void @fentry2(i1 %a) nounwind { +; CHECK-LABEL: fentry2: +; CHECK: # %bb.1: +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB1:[0-9]+]] +; CHECK-NEXT: call foo +; CHECK-LABEL: .LBB2_2: +; CHECK-NEXT: tail OUTLINED_FUNCTION_[[BB2:[0-9]+]] +entry: + br i1 %a, label %if.then, label %if.end +if.then: + call void @foo(i32 1, i32 2, i32 3, i32 4) + br label %if.end +if.end: + call void @foo(i32 5, i32 6, i32 7, i32 8) + ret void +} + +; CHECK: OUTLINED_FUNCTION_[[BB2]]: +; CHECK: li a0, 5 +; CHECK-NEXT: li a1, 6 +; CHECK-NEXT: li a2, 7 +; CHECK-NEXT: li a3, 8 +; CHECK-NEXT: call foo + +; CHECK: OUTLINED_FUNCTION_[[BB1]]: +; CHECK: li a0, 1 +; CHECK-NEXT: li a1, 2 +; CHECK-NEXT: li a2, 3 +; CHECK-NEXT: li a3, 4 +; CHECK-NEXT: jr t0 diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-cfi.mir b/llvm/test/CodeGen/RISCV/machine-outliner-cfi.mir index 6ecca6a1b18ef..2acb1d43e01ea 100644 --- a/llvm/test/CodeGen/RISCV/machine-outliner-cfi.mir +++ b/llvm/test/CodeGen/RISCV/machine-outliner-cfi.mir @@ -22,13 +22,11 @@ body: | ; RV32I-MO-LABEL: name: func1 ; RV32I-MO: liveins: $x10, $x11 ; RV32I-MO-NEXT: {{ $}} - ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV32I-MO-NEXT: PseudoRET + ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; RV64I-MO-LABEL: name: func1 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} - ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV64I-MO-NEXT: PseudoRET + ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x10 = ORI $x10, 1023 CFI_INSTRUCTION offset $x1, 0 $x11 = ORI $x11, 1023 @@ -49,13 +47,11 @@ body: | ; RV32I-MO-LABEL: name: func2 ; RV32I-MO: liveins: $x10, $x11 ; RV32I-MO-NEXT: {{ $}} - ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV32I-MO-NEXT: PseudoRET + ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; RV64I-MO-LABEL: name: func2 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} - ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV64I-MO-NEXT: PseudoRET + ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x10 = ORI $x10, 1023 CFI_INSTRUCTION offset $x1, 0 $x11 = ORI $x11, 1023 @@ -76,13 +72,11 @@ body: | ; RV32I-MO-LABEL: name: func3 ; RV32I-MO: liveins: $x10, $x11 ; RV32I-MO-NEXT: {{ $}} - ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV32I-MO-NEXT: PseudoRET + ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; RV64I-MO-LABEL: name: func3 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} - ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV64I-MO-NEXT: PseudoRET + ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x10 = ORI $x10, 1023 CFI_INSTRUCTION offset $x1, -12 $x11 = ORI $x11, 1023 @@ -96,11 +90,11 @@ body: | # OUTLINED-LABEL: name: OUTLINED_FUNCTION_0 -# OUTLINED: liveins: $x11, $x10, $x5 +# OUTLINED: liveins: $x11, $x10 # OUTLINED-NEXT: {{ $}} # OUTLINED-NEXT: $x10 = ORI $x10, 1023 # OUTLINED-NEXT: $x11 = ORI $x11, 1023 # OUTLINED-NEXT: $x12 = ADDI $x10, 17 # OUTLINED-NEXT: $x11 = AND $x12, $x11 # OUTLINED-NEXT: $x10 = SUB $x10, $x11 -# OUTLINED-NEXT: $x0 = JALR $x5, 0 +# OUTLINED-NEXT: PseudoRET diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll b/llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll index 8fab0aa9b6a76..0441361b11798 100644 --- a/llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll +++ b/llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll @@ -94,7 +94,8 @@ define i32 @_Z2f6v() minsize { ; CHECK-BASELINE-NEXT: li a3, 0x4 ; CHECK-BASELINE-NEXT: li a4, 0x5 ; CHECK-BASELINE-NEXT: li a5, 0x6 -; CHECK-BASELINE-NEXT: jr t0 +; CHECK-BASELINE-NEXT: auipc t1, 0x0 +; CHECK-BASELINE-NEXT: jr t1 ; CHECK-BASELINE: : ; CHECK-BASELINE-NEXT: li a0, 0x1 @@ -102,8 +103,9 @@ define i32 @_Z2f6v() minsize { ; CHECK-BASELINE-NEXT: li a2, 0x3 ; CHECK-BASELINE-NEXT: li a3, 0x4 ; CHECK-BASELINE-NEXT: li a4, 0x5 -; CHECK-BASELINE-NEXT: li a5, 0x7 -; CHECK-BASELINE-NEXT: jr t0 +; CHECK-BASELINE-NEXT: li a5, 0x8 +; CHECK-BASELINE-NEXT: auipc t1, 0x0 +; CHECK-BASELINE-NEXT: jr t1 ; CHECK-BASELINE: : ; CHECK-BASELINE-NEXT: li a0, 0x1 @@ -111,8 +113,9 @@ define i32 @_Z2f6v() minsize { ; CHECK-BASELINE-NEXT: li a2, 0x3 ; CHECK-BASELINE-NEXT: li a3, 0x4 ; CHECK-BASELINE-NEXT: li a4, 0x5 -; CHECK-BASELINE-NEXT: li a5, 0x8 -; CHECK-BASELINE-NEXT: jr t0 +; CHECK-BASELINE-NEXT: li a5, 0x7 +; CHECK-BASELINE-NEXT: auipc t1, 0x0 +; CHECK-BASELINE-NEXT: jr t1 ; CHECK-LEAF-DESCENDANTS: : ; CHECK-LEAF-DESCENDANTS-NEXT: li a0, 0x1 diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll b/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll index 4ef3abd241577..4a54a7289ddf2 100644 --- a/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll +++ b/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll @@ -11,7 +11,11 @@ define void @fentry0(i1 %a) nounwind "fentry-call"="true" { ; CHECK-NEXT: # %bb.0: ; CHECK-NEXT: # FEntry call ; CHECK: # %bb.1: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB1:[0-9]+]] +; CHECK-NEXT: call foo +; CHECK-LABEL: .LBB0_2: +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB2:[0-9]+]] +; CHECK-NEXT: call foo entry: br i1 %a, label %if.then, label %if.end if.then: @@ -27,7 +31,11 @@ define void @fentry1(i1 %a) nounwind "fentry-call"="true" { ; CHECK-NEXT: # %bb.0: ; CHECK-NEXT: # FEntry call ; CHECK: # %bb.1: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB1:[0-9]+]] +; CHECK-NEXT: call foo +; CHECK-LABEL: .LBB1_2: +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB2:[0-9]+]] +; CHECK-NEXT: call foo entry: br i1 %a, label %if.then, label %if.end if.then: @@ -47,7 +55,11 @@ define void @patchable0(i1 %a) nounwind "patchable-function-entry"="2" { ; CHECK-NEXT: nop ; CHECK-NEXT: nop ; CHECK: # %bb.1: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB1:[0-9]+]] +; CHECK-NEXT: call foo +; CHECK-LABEL: .LBB2_2: +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB2:[0-9]+]] +; CHECK-NEXT: call foo entry: br i1 %a, label %if.then, label %if.end if.then: @@ -65,7 +77,11 @@ define void @patchable1(i1 %a) nounwind "patchable-function-entry"="2" { ; CHECK-NEXT: nop ; CHECK-NEXT: nop ; CHECK: # %bb.1: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB1:[0-9]+]] +; CHECK-NEXT: call foo +; CHECK-LABEL: .LBB3_2: +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB2:[0-9]+]] +; CHECK-NEXT: call foo entry: br i1 %a, label %if.then, label %if.end if.then: diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-position.mir b/llvm/test/CodeGen/RISCV/machine-outliner-position.mir index 715e212eecabb..47ec447f61d09 100644 --- a/llvm/test/CodeGen/RISCV/machine-outliner-position.mir +++ b/llvm/test/CodeGen/RISCV/machine-outliner-position.mir @@ -25,15 +25,14 @@ body: | ; RV32I-MO-NEXT: {{ $}} ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV32I-MO-NEXT: EH_LABEL - ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV32I-MO-NEXT: PseudoRET + ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 + ; ; RV64I-MO-LABEL: name: func1 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} ; RV64I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV64I-MO-NEXT: EH_LABEL - ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV64I-MO-NEXT: PseudoRET + ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x10 = ORI $x10, 1023 EH_LABEL $x11 = ORI $x11, 1023 @@ -53,15 +52,14 @@ body: | ; RV32I-MO-NEXT: {{ $}} ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV32I-MO-NEXT: GC_LABEL - ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV32I-MO-NEXT: PseudoRET + ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 + ; ; RV64I-MO-LABEL: name: func2 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} ; RV64I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV64I-MO-NEXT: GC_LABEL - ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV64I-MO-NEXT: PseudoRET + ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x10 = ORI $x10, 1023 GC_LABEL $x11 = ORI $x11, 1023 @@ -81,15 +79,14 @@ body: | ; RV32I-MO-NEXT: {{ $}} ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV32I-MO-NEXT: ANNOTATION_LABEL - ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV32I-MO-NEXT: PseudoRET + ; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 + ; ; RV64I-MO-LABEL: name: func3 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} ; RV64I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV64I-MO-NEXT: ANNOTATION_LABEL - ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11 - ; RV64I-MO-NEXT: PseudoRET + ; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x10 = ORI $x10, 1023 ANNOTATION_LABEL $x11 = ORI $x11, 1023 diff --git a/llvm/test/CodeGen/RISCV/machineoutliner-x5.mir b/llvm/test/CodeGen/RISCV/machineoutliner-x5.mir new file mode 100644 index 0000000000000..14a9cd7f0dcff --- /dev/null +++ b/llvm/test/CodeGen/RISCV/machineoutliner-x5.mir @@ -0,0 +1,54 @@ +# Check that modifying X5 register is not a problem for machine outliner + +# RUN: llc -mtriple=riscv32 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs < %s \ +# RUN: | FileCheck -check-prefixes=CHECK,RV32I-MO %s +# RUN: llc -mtriple=riscv64 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs < %s \ +# RUN: | FileCheck -check-prefixes=CHECK,RV64I-MO %s + +--- | + define i32 @outline_tail_1(i32 %a, i32 %b) { ret i32 0 } + + define i32 @outline_tail_2(i32 %a, i32 %b) { ret i32 0 } +... +--- +name: outline_tail_1 +tracksRegLiveness: true +isOutlined: false +body: | + bb.0: + liveins: $x10, $x11, $x5 + ; RV32I-MO-LABEL: name: outline_tail_1 + ; RV32I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x5, implicit $x10, implicit $x11 + ; + ; RV64I-MO-LABEL: name: outline_tail_1 + ; RV64I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x5, implicit $x10, implicit $x11 + $x11 = ORI $x11, 1023 + $x12 = ADDI $x10, 17 + $x10 = ADD $x10, $x5 + $x11 = AND $x12, $x11 + $x10 = SUB $x10, $x11 + PseudoRET implicit $x10 +... +--- +name: outline_tail_2 +tracksRegLiveness: true +isOutlined: false +body: | + bb.0: + liveins: $x10, $x11, $x5 + ; RV32I-MO-LABEL: name: outline_tail_2 + ; RV32I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x5, implicit $x10, implicit $x11 + ; + ; RV64I-MO-LABEL: name: outline_tail_2 + ; RV64I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x5, implicit $x10, implicit $x11 + $x11 = ORI $x11, 1023 + $x12 = ADDI $x10, 17 + $x10 = ADD $x10, $x5 + $x11 = AND $x12, $x11 + $x10 = SUB $x10, $x11 + PseudoRET implicit $x10 +... + + +# CHECK-LABEL: name: OUTLINED_FUNCTION_0 +# CHECK: isOutlined: true diff --git a/llvm/test/CodeGen/RISCV/machineoutliner.mir b/llvm/test/CodeGen/RISCV/machineoutliner.mir index 0221257354fcf..ab12bfbe1fafc 100644 --- a/llvm/test/CodeGen/RISCV/machineoutliner.mir +++ b/llvm/test/CodeGen/RISCV/machineoutliner.mir @@ -29,10 +29,10 @@ body: | bb.0: liveins: $x10, $x11 ; RV32I-MO-LABEL: name: outline_0 - ; RV32I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV32I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; ; RV64I-MO-LABEL: name: outline_0 - ; RV64I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV64I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x11 = ORI $x11, 1023 $x12 = ADDI $x10, 17 $x11 = AND $x12, $x11 @@ -48,10 +48,10 @@ body: | bb.0: liveins: $x10, $x11 ; RV32I-MO-LABEL: name: outline_1 - ; RV32I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV32I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; ; RV64I-MO-LABEL: name: outline_1 - ; RV64I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV64I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x11 = ORI $x11, 1023 $x12 = ADDI $x10, 17 $x11 = AND $x12, $x11 @@ -67,10 +67,10 @@ body: | bb.0: liveins: $x10, $x11 ; RV32I-MO-LABEL: name: outline_2 - ; RV32I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV32I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; ; RV64I-MO-LABEL: name: outline_2 - ; RV64I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV64I-MO: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x11 = ORI $x11, 1023 $x12 = ADDI $x10, 17 $x11 = AND $x12, $x11 @@ -87,9 +87,11 @@ body: | liveins: $x10, $x11 ; RV32I-MO-LABEL: name: dont_outline_0 ; RV32I-MO-NOT: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV32I-MO-NOT: PseudoTAIL @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; ; RV64I-MO-LABEL: name: dont_outline_0 ; RV64I-MO-NOT: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV64I-MO-NOT: PseudoTAIL @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x11 = ORI $x11, 1023 $x12 = ADDI $x10, 17 $x11 = AND $x12, $x11 @@ -106,9 +108,11 @@ body: | liveins: $x10, $x11 ; RV32I-MO-LABEL: name: dont_outline_1 ; RV32I-MO-NOT: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV32I-MO-NOT: PseudoTAIL @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; ; RV64I-MO-LABEL: name: dont_outline_1 ; RV64I-MO-NOT: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV64I-MO-NOT: PseudoTAIL @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x11 = ORI $x11, 1023 $x12 = ADDI $x10, 17 $x11 = AND $x12, $x11 @@ -125,9 +129,11 @@ body: | liveins: $x10, $x11, $x5 ; RV32I-MO-LABEL: name: dont_outline_2 ; RV32I-MO-NOT: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV32I-MO-NOT: PseudoTAIL @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 ; ; RV64I-MO-LABEL: name: dont_outline_2 ; RV64I-MO-NOT: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 + ; RV64I-MO-NOT: PseudoTAIL @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11 $x11 = ORI $x11, 1023 $x12 = ADDI $x10, 17 $x11 = AND $x12, $x11