diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index ca2f868cd4e76..19103e219cb80 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -208,12 +208,6 @@ 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 a28bf1186589d..6bb49e2bb85fe 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -124,7 +124,11 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, MCRegister Ra; if (MI.getOpcode() == RISCV::PseudoTAIL) { Func = MI.getOperand(0); - Ra = RISCVII::getTailExpandUseRegNo(STI.getFeatureBits()); + 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; } 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 47273d6bc06d6..933e776da4740 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "RISCVInstrInfo.h" -#include "MCTargetDesc/RISCVBaseInfo.h" #include "MCTargetDesc/RISCVMatInt.h" #include "RISCV.h" #include "RISCVMachineFunctionInfo.h" @@ -2928,7 +2927,6 @@ bool RISCVInstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, // Enum values indicating how an outlined call should be constructed. enum MachineOutlinerConstructionID { - MachineOutlinerTailCall, MachineOutlinerDefault }; @@ -2937,118 +2935,46 @@ 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 { - // Each RepeatedSequenceLoc is identical. - outliner::Candidate &Candidate = RepeatedSequenceLocs[0]; - auto CandidateInfo = analyzeCandidate(Candidate); - if (!CandidateInfo) - RepeatedSequenceLocs.clear(); + // 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); // If the sequence doesn't have enough candidates left, then we're done. if (RepeatedSequenceLocs.size() < MinRepeats) return std::nullopt; - 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; - } + unsigned SequenceSize = 0; + + for (auto &MI : RepeatedSequenceLocs[0]) + SequenceSize += getInstSizeInBytes(MI); + // call t0, function = 8 bytes. + unsigned CallOverhead = 8; for (auto &C : RepeatedSequenceLocs) - C.setCallInfo(MOCI, CallOverhead); + C.setCallInfo(MachineOutlinerDefault, CallOverhead); - unsigned SequenceSize = 0; - for (auto &MI : Candidate) - SequenceSize += getInstSizeInBytes(MI); + // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled. + unsigned FrameOverhead = 4; + if (RepeatedSequenceLocs[0] + .getMF() + ->getSubtarget() + .hasStdExtCOrZca()) + FrameOverhead = 2; return std::make_unique( - RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI); + RepeatedSequenceLocs, SequenceSize, FrameOverhead, + MachineOutlinerDefault); } outliner::InstrType @@ -3069,8 +2995,15 @@ RISCVInstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI, return F.needsUnwindTableEntry() ? outliner::InstrType::Illegal : outliner::InstrType::Invisible; - if (cannotInsertTailCall(*MBB) && - (MI.isReturn() || isMIModifiesReg(MI, TRI, RISCV::X5))) + // 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)) return outliner::InstrType::Illegal; // Make sure the operands don't reference something unsafe. @@ -3106,9 +3039,6 @@ void RISCVInstrInfo::buildOutlinedFrame( } } - if (OF.FrameConstructionID == MachineOutlinerTailCall) - return; - MBB.addLiveIn(RISCV::X5); // Add in a return instruction to the end of the outlined frame. @@ -3122,13 +3052,6 @@ 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/machine-outliner-call.ll b/llvm/test/CodeGen/RISCV/machine-outliner-call.ll deleted file mode 100644 index b019cfe74864b..0000000000000 --- a/llvm/test/CodeGen/RISCV/machine-outliner-call.ll +++ /dev/null @@ -1,70 +0,0 @@ -; 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 2acb1d43e01ea..6ecca6a1b18ef 100644 --- a/llvm/test/CodeGen/RISCV/machine-outliner-cfi.mir +++ b/llvm/test/CodeGen/RISCV/machine-outliner-cfi.mir @@ -22,11 +22,13 @@ body: | ; RV32I-MO-LABEL: name: func1 ; RV32I-MO: liveins: $x10, $x11 ; RV32I-MO-NEXT: {{ $}} - ; 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 + ; 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 ; RV64I-MO-LABEL: name: func1 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} - ; 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 + ; 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 $x10 = ORI $x10, 1023 CFI_INSTRUCTION offset $x1, 0 $x11 = ORI $x11, 1023 @@ -47,11 +49,13 @@ body: | ; RV32I-MO-LABEL: name: func2 ; RV32I-MO: liveins: $x10, $x11 ; RV32I-MO-NEXT: {{ $}} - ; 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 + ; 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 ; RV64I-MO-LABEL: name: func2 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} - ; 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 + ; 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 $x10 = ORI $x10, 1023 CFI_INSTRUCTION offset $x1, 0 $x11 = ORI $x11, 1023 @@ -72,11 +76,13 @@ body: | ; RV32I-MO-LABEL: name: func3 ; RV32I-MO: liveins: $x10, $x11 ; RV32I-MO-NEXT: {{ $}} - ; 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 + ; 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 ; RV64I-MO-LABEL: name: func3 ; RV64I-MO: liveins: $x10, $x11 ; RV64I-MO-NEXT: {{ $}} - ; 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 + ; 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 $x10 = ORI $x10, 1023 CFI_INSTRUCTION offset $x1, -12 $x11 = ORI $x11, 1023 @@ -90,11 +96,11 @@ body: | # OUTLINED-LABEL: name: OUTLINED_FUNCTION_0 -# OUTLINED: liveins: $x11, $x10 +# OUTLINED: liveins: $x11, $x10, $x5 # 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: PseudoRET +# OUTLINED-NEXT: $x0 = JALR $x5, 0 diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll b/llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll index 0441361b11798..8fab0aa9b6a76 100644 --- a/llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll +++ b/llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll @@ -94,8 +94,7 @@ 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: auipc t1, 0x0 -; CHECK-BASELINE-NEXT: jr t1 +; CHECK-BASELINE-NEXT: jr t0 ; CHECK-BASELINE: : ; CHECK-BASELINE-NEXT: li a0, 0x1 @@ -103,9 +102,8 @@ 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: auipc t1, 0x0 -; CHECK-BASELINE-NEXT: jr t1 +; CHECK-BASELINE-NEXT: li a5, 0x7 +; CHECK-BASELINE-NEXT: jr t0 ; CHECK-BASELINE: : ; CHECK-BASELINE-NEXT: li a0, 0x1 @@ -113,9 +111,8 @@ 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: auipc t1, 0x0 -; CHECK-BASELINE-NEXT: jr t1 +; CHECK-BASELINE-NEXT: li a5, 0x8 +; CHECK-BASELINE-NEXT: jr t0 ; 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 4a54a7289ddf2..4ef3abd241577 100644 --- a/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll +++ b/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll @@ -11,11 +11,7 @@ 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_[[BB1:[0-9]+]] -; CHECK-NEXT: call foo -; CHECK-LABEL: .LBB0_2: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB2:[0-9]+]] -; CHECK-NEXT: call foo +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 entry: br i1 %a, label %if.then, label %if.end if.then: @@ -31,11 +27,7 @@ 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_[[BB1:[0-9]+]] -; CHECK-NEXT: call foo -; CHECK-LABEL: .LBB1_2: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB2:[0-9]+]] -; CHECK-NEXT: call foo +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 entry: br i1 %a, label %if.then, label %if.end if.then: @@ -55,11 +47,7 @@ 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_[[BB1:[0-9]+]] -; CHECK-NEXT: call foo -; CHECK-LABEL: .LBB2_2: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB2:[0-9]+]] -; CHECK-NEXT: call foo +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 entry: br i1 %a, label %if.then, label %if.end if.then: @@ -77,11 +65,7 @@ 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_[[BB1:[0-9]+]] -; CHECK-NEXT: call foo -; CHECK-LABEL: .LBB3_2: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_[[BB2:[0-9]+]] -; CHECK-NEXT: call foo +; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 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 47ec447f61d09..715e212eecabb 100644 --- a/llvm/test/CodeGen/RISCV/machine-outliner-position.mir +++ b/llvm/test/CodeGen/RISCV/machine-outliner-position.mir @@ -25,14 +25,15 @@ body: | ; RV32I-MO-NEXT: {{ $}} ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV32I-MO-NEXT: EH_LABEL - ; 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 - ; + ; 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 ; 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: 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-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 $x10 = ORI $x10, 1023 EH_LABEL $x11 = ORI $x11, 1023 @@ -52,14 +53,15 @@ body: | ; RV32I-MO-NEXT: {{ $}} ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV32I-MO-NEXT: GC_LABEL - ; 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 - ; + ; 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 ; 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: 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-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 $x10 = ORI $x10, 1023 GC_LABEL $x11 = ORI $x11, 1023 @@ -79,14 +81,15 @@ body: | ; RV32I-MO-NEXT: {{ $}} ; RV32I-MO-NEXT: $x10 = ORI $x10, 1023 ; RV32I-MO-NEXT: ANNOTATION_LABEL - ; 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 - ; + ; 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 ; 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: 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-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 $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 deleted file mode 100644 index 14a9cd7f0dcff..0000000000000 --- a/llvm/test/CodeGen/RISCV/machineoutliner-x5.mir +++ /dev/null @@ -1,54 +0,0 @@ -# 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 ab12bfbe1fafc..0221257354fcf 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: 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 + ; RV32I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 ; ; RV64I-MO-LABEL: name: outline_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 + ; RV64I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 $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: 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 + ; RV32I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 ; ; RV64I-MO-LABEL: name: outline_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 $x10, implicit $x11 + ; RV64I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 $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: 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 + ; RV32I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 ; ; RV64I-MO-LABEL: name: outline_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 $x10, implicit $x11 + ; RV64I-MO: $x5 = PseudoCALLReg {{.*}} @OUTLINED_FUNCTION_0 $x11 = ORI $x11, 1023 $x12 = ADDI $x10, 17 $x11 = AND $x12, $x11 @@ -87,11 +87,9 @@ 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 @@ -108,11 +106,9 @@ 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 @@ -129,11 +125,9 @@ 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