[llvm] [RISCV] Support MachineOutlinerRegSave for RISCV (PR #191351)
Piyou Chen via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 23:12:33 PDT 2026
https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/191351
>From 7d1f90a024a8ac93a8a2947594bf1b5521dddf77 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Thu, 9 Apr 2026 20:04:45 -0700
Subject: [PATCH 1/7] [RISCV] Support MachineOutlinerRegSave for RISCV
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 95 +++++++++-
.../RISCV/machine-outliner-reserved-regs.mir | 166 ++++++++++++++++++
.../RISCV/machine-outliner-x5-regsave.mir | 116 ++++++++++++
3 files changed, 373 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/CodeGen/RISCV/machine-outliner-reserved-regs.mir
create mode 100644 llvm/test/CodeGen/RISCV/machine-outliner-x5-regsave.mir
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index db559f4949904..516054b63a902 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -64,6 +64,11 @@ static cl::opt<MachineTraceStrategy> ForceMachineCombinerStrategy(
clEnumValN(MachineTraceStrategy::TS_MinInstrCount, "min-instr",
"MinInstrCount strategy.")));
+static cl::opt<bool> OutlinerEnableRegSave(
+ "riscv-outliner-regsave", cl::init(false), cl::Hidden,
+ cl::desc("Enable RegSave strategy in machine outliner (save X5 to a "
+ "temporary register when X5 is live across outlined calls)."));
+
namespace llvm::RISCVVPseudosTable {
using namespace RISCV;
@@ -3634,7 +3639,8 @@ bool RISCVInstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
// Enum values indicating how an outlined call should be constructed.
enum MachineOutlinerConstructionID {
MachineOutlinerTailCall,
- MachineOutlinerDefault
+ MachineOutlinerDefault,
+ MachineOutlinerRegSave
};
bool RISCVInstrInfo::shouldOutlineFromFunctionByDefault(
@@ -3682,6 +3688,34 @@ static bool cannotInsertTailCall(const MachineBasicBlock &MBB) {
return false;
}
+static Register findRegisterToSaveX5To(outliner::Candidate &C,
+ const TargetRegisterInfo &TRI) {
+ // Candidate registers for saving X5: t1-t6
+ static const MCPhysReg TempRegs[] = {
+ RISCV::X6, // t1
+ RISCV::X7, // t2
+ RISCV::X28, // t3
+ RISCV::X29, // t4
+ RISCV::X30, // t5
+ RISCV::X31 // t6
+ };
+
+ const MachineFunction *MF = C.getMF();
+ const MachineRegisterInfo &MRI = MF->getRegInfo();
+
+ for (MCPhysReg Reg : TempRegs) {
+ if (MRI.isReserved(Reg))
+ continue;
+
+ if (C.isAvailableAcrossAndOutOfSeq(Reg, TRI) &&
+ C.isAvailableInsideSeq(Reg, TRI)) {
+ return Reg;
+ }
+ }
+
+ return Register();
+}
+
bool RISCVInstrInfo::analyzeCandidate(outliner::Candidate &C) const {
// If the expansion register for tail calls is live across the candidate
// outlined call site, we cannot outline that candidate as the expansion
@@ -3714,7 +3748,16 @@ bool RISCVInstrInfo::analyzeCandidate(outliner::Candidate &C) const {
}))
return true;
- return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo);
+ bool X5Available = C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo);
+
+ if (X5Available)
+ return false;
+
+ // Save X5 into t1-t6
+ if (OutlinerEnableRegSave && findRegisterToSaveX5To(C, RegInfo))
+ return false;
+
+ return true;
}
std::optional<std::unique_ptr<outliner::OutlinedFunction>>
@@ -3779,8 +3822,26 @@ RISCVInstrInfo::getOutliningCandidateInfo(
if (MOCI != MachineOutlinerTailCall && CFICount > 0)
return std::nullopt;
- for (auto &C : RepeatedSequenceLocs)
- C.setCallInfo(MOCI, CallOverhead);
+ if (OutlinerEnableRegSave && MOCI == MachineOutlinerDefault) {
+ // Set per-candidate overhead based on X5 availability
+ for (auto &C : RepeatedSequenceLocs) {
+ unsigned CandCallOverhead;
+
+ if (C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo)) {
+ // X5 is available, just need the call
+ CandCallOverhead = 8;
+ C.setCallInfo(MachineOutlinerDefault, CandCallOverhead);
+ } else {
+ // X5 unavailable, need save + call + restore
+ // Save (2-4) + Call (8) + Restore (2-4)
+ CandCallOverhead = InstrSizeCExt + 8 + InstrSizeCExt;
+ C.setCallInfo(MachineOutlinerRegSave, CandCallOverhead);
+ }
+ }
+ } else {
+ for (auto &C : RepeatedSequenceLocs)
+ C.setCallInfo(MOCI, CallOverhead);
+ }
unsigned SequenceSize = 0;
for (auto &MI : Candidate)
@@ -3854,6 +3915,32 @@ MachineBasicBlock::iterator RISCVInstrInfo::insertOutlinedCall(
return It;
}
+ if (C.CallConstructionID == MachineOutlinerRegSave) {
+ Register SaveReg = findRegisterToSaveX5To(C, RegInfo);
+ assert(SaveReg && "Cannot find an available register to save/restore X5.");
+
+ // Save: ADDI SaveReg, X5, 0 (equivalent to MV SaveReg, X5)
+ It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::ADDI), SaveReg)
+ .addReg(RISCV::X5)
+ .addImm(0));
+ It++;
+
+ // Call: PseudoCALLReg X5
+ It = MBB.insert(
+ It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
+ .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
+ RISCVII::MO_CALL));
+ MachineBasicBlock::iterator CallPt = It;
+ It++;
+
+ // Restore: ADDI X5, SaveReg, 0 (equivalent to MV X5, SaveReg)
+ It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::ADDI), RISCV::X5)
+ .addReg(SaveReg)
+ .addImm(0));
+
+ return CallPt;
+ }
+
// 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-reserved-regs.mir b/llvm/test/CodeGen/RISCV/machine-outliner-reserved-regs.mir
new file mode 100644
index 0000000000000..5d6a5363d19fd
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/machine-outliner-reserved-regs.mir
@@ -0,0 +1,166 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+reserve-x6 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs \
+# RUN: -riscv-outliner-regsave=true < %s | FileCheck -check-prefixes=CHECK-X6-RESERVED %s
+# RUN: llc -mtriple=riscv32 -mattr=+reserve-x6,+reserve-x7 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs \
+# RUN: -riscv-outliner-regsave=true < %s | FileCheck -check-prefixes=CHECK-X6-X7-RESERVED %s
+
+--- |
+ define i32 @outline_x5_live_reserved_0(i32 %a, i32 %b) { ret i32 0 }
+ define i32 @outline_x5_live_reserved_1(i32 %a, i32 %b) { ret i32 0 }
+ define i32 @outline_x5_live_reserved_2(i32 %a, i32 %b) { ret i32 0 }
+...
+---
+name: outline_x5_live_reserved_0
+tracksRegLiveness: true
+body: |
+ ; CHECK-X6-RESERVED-LABEL: name: outline_x5_live_reserved_0
+ ; CHECK-X6-RESERVED: bb.0:
+ ; CHECK-X6-RESERVED-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: $x7 = ADDI $x5, 0
+ ; CHECK-X6-RESERVED-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x7, implicit $x10, implicit $x11
+ ; CHECK-X6-RESERVED-NEXT: $x5 = ADDI $x7, 0
+ ; CHECK-X6-RESERVED-NEXT: PseudoBR %bb.1
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: bb.1:
+ ; CHECK-X6-RESERVED-NEXT: liveins: $x5, $x14
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-X6-RESERVED-NEXT: PseudoRET implicit $x10
+ ;
+ ; CHECK-X6-X7-RESERVED-LABEL: name: outline_x5_live_reserved_0
+ ; CHECK-X6-X7-RESERVED: bb.0:
+ ; CHECK-X6-X7-RESERVED-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: $x28 = ADDI $x5, 0
+ ; CHECK-X6-X7-RESERVED-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x10, implicit $x11, implicit $x28
+ ; CHECK-X6-X7-RESERVED-NEXT: $x5 = ADDI $x28, 0
+ ; CHECK-X6-X7-RESERVED-NEXT: PseudoBR %bb.1
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: bb.1:
+ ; CHECK-X6-X7-RESERVED-NEXT: liveins: $x5, $x14
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-X6-X7-RESERVED-NEXT: PseudoRET implicit $x10
+
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
+---
+name: outline_x5_live_reserved_1
+tracksRegLiveness: true
+body: |
+ ; CHECK-X6-RESERVED-LABEL: name: outline_x5_live_reserved_1
+ ; CHECK-X6-RESERVED: bb.0:
+ ; CHECK-X6-RESERVED-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: $x7 = ADDI $x5, 0
+ ; CHECK-X6-RESERVED-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x7, implicit $x10, implicit $x11
+ ; CHECK-X6-RESERVED-NEXT: $x5 = ADDI $x7, 0
+ ; CHECK-X6-RESERVED-NEXT: PseudoBR %bb.1
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: bb.1:
+ ; CHECK-X6-RESERVED-NEXT: liveins: $x5, $x14
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-X6-RESERVED-NEXT: PseudoRET implicit $x10
+ ;
+ ; CHECK-X6-X7-RESERVED-LABEL: name: outline_x5_live_reserved_1
+ ; CHECK-X6-X7-RESERVED: bb.0:
+ ; CHECK-X6-X7-RESERVED-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: $x28 = ADDI $x5, 0
+ ; CHECK-X6-X7-RESERVED-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x10, implicit $x11, implicit $x28
+ ; CHECK-X6-X7-RESERVED-NEXT: $x5 = ADDI $x28, 0
+ ; CHECK-X6-X7-RESERVED-NEXT: PseudoBR %bb.1
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: bb.1:
+ ; CHECK-X6-X7-RESERVED-NEXT: liveins: $x5, $x14
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-X6-X7-RESERVED-NEXT: PseudoRET implicit $x10
+
+
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
+---
+name: outline_x5_live_reserved_2
+tracksRegLiveness: true
+body: |
+ ; CHECK-X6-RESERVED-LABEL: name: outline_x5_live_reserved_2
+ ; CHECK-X6-RESERVED: bb.0:
+ ; CHECK-X6-RESERVED-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: $x7 = ADDI $x5, 0
+ ; CHECK-X6-RESERVED-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x7, implicit $x10, implicit $x11
+ ; CHECK-X6-RESERVED-NEXT: $x5 = ADDI $x7, 0
+ ; CHECK-X6-RESERVED-NEXT: PseudoBR %bb.1
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: bb.1:
+ ; CHECK-X6-RESERVED-NEXT: liveins: $x5, $x14
+ ; CHECK-X6-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-RESERVED-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-X6-RESERVED-NEXT: PseudoRET implicit $x10
+ ;
+ ; CHECK-X6-X7-RESERVED-LABEL: name: outline_x5_live_reserved_2
+ ; CHECK-X6-X7-RESERVED: bb.0:
+ ; CHECK-X6-X7-RESERVED-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: $x28 = ADDI $x5, 0
+ ; CHECK-X6-X7-RESERVED-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x10, implicit $x11, implicit $x28
+ ; CHECK-X6-X7-RESERVED-NEXT: $x5 = ADDI $x28, 0
+ ; CHECK-X6-X7-RESERVED-NEXT: PseudoBR %bb.1
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: bb.1:
+ ; CHECK-X6-X7-RESERVED-NEXT: liveins: $x5, $x14
+ ; CHECK-X6-X7-RESERVED-NEXT: {{ $}}
+ ; CHECK-X6-X7-RESERVED-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-X6-X7-RESERVED-NEXT: PseudoRET implicit $x10
+
+
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-x5-regsave.mir b/llvm/test/CodeGen/RISCV/machine-outliner-x5-regsave.mir
new file mode 100644
index 0000000000000..e473c9408d154
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/machine-outliner-x5-regsave.mir
@@ -0,0 +1,116 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs \
+# RUN: -riscv-outliner-regsave=true < %s | FileCheck -check-prefixes=CHECK %s
+# RUN: llc -mtriple=riscv64 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs \
+# RUN: -riscv-outliner-regsave=true < %s | FileCheck -check-prefixes=CHECK %s
+
+--- |
+ define i32 @outline_x5_live_0(i32 %a, i32 %b) { ret i32 0 }
+ define i32 @outline_x5_live_1(i32 %a, i32 %b) { ret i32 0 }
+ define i32 @outline_x5_live_2(i32 %a, i32 %b) { ret i32 0 }
+...
+---
+name: outline_x5_live_0
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_x5_live_0
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x6 = ADDI $x5, 0
+ ; CHECK-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x6, implicit $x10, implicit $x11
+ ; CHECK-NEXT: $x5 = ADDI $x6, 0
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
+---
+name: outline_x5_live_1
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_x5_live_1
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x6 = ADDI $x5, 0
+ ; CHECK-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x6, implicit $x10, implicit $x11
+ ; CHECK-NEXT: $x5 = ADDI $x6, 0
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
+---
+name: outline_x5_live_2
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_x5_live_2
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x6 = ADDI $x5, 0
+ ; CHECK-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x6, implicit $x10, implicit $x11
+ ; CHECK-NEXT: $x5 = ADDI $x6, 0
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
>From 865f0ade83ef82cb3dfba8751feea3dc4a2e3051 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Fri, 10 Apr 2026 00:12:05 -0700
Subject: [PATCH 2/7] Default enable
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 2 +-
.../RISCV/machine-outliner-call-x5-liveout.mir | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 516054b63a902..0998929945bb1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -65,7 +65,7 @@ static cl::opt<MachineTraceStrategy> ForceMachineCombinerStrategy(
"MinInstrCount strategy.")));
static cl::opt<bool> OutlinerEnableRegSave(
- "riscv-outliner-regsave", cl::init(false), cl::Hidden,
+ "riscv-outliner-regsave", cl::init(true), cl::Hidden,
cl::desc("Enable RegSave strategy in machine outliner (save X5 to a "
"temporary register when X5 is live across outlined calls)."));
diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir b/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
index f7bea33e52885..4858a9b2dbaac 100644
--- a/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
+++ b/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
@@ -50,9 +50,9 @@ body: |
; RV32I-MO-NEXT: BEQ $x10, $x11, %bb.1
; RV32I-MO-NEXT: {{ $}}
; RV32I-MO-NEXT: bb.1:
- ; RV32I-MO-NEXT: liveins: $x10, $x5
+ ; RV32I-MO-NEXT: liveins: $x10, $x5, $x6, $x7, $x28, $x29, $x30, $x31
; RV32I-MO-NEXT: {{ $}}
- ; RV32I-MO-NEXT: PseudoRET implicit $x10, implicit $x5
+ ; RV32I-MO-NEXT: PseudoRET implicit $x10, implicit $x5, implicit $x6, implicit $x7, implicit $x28, implicit $x29, implicit $x30, implicit $x31
;
; RV64I-MO-LABEL: name: dont_outline
; RV64I-MO: bb.0:
@@ -65,9 +65,9 @@ body: |
; RV64I-MO-NEXT: BEQ $x10, $x11, %bb.1
; RV64I-MO-NEXT: {{ $}}
; RV64I-MO-NEXT: bb.1:
- ; RV64I-MO-NEXT: liveins: $x10, $x5
+ ; RV64I-MO-NEXT: liveins: $x10, $x5, $x6, $x7, $x28, $x29, $x30, $x31
; RV64I-MO-NEXT: {{ $}}
- ; RV64I-MO-NEXT: PseudoRET implicit $x10, implicit $x5
+ ; RV64I-MO-NEXT: PseudoRET implicit $x10, implicit $x5, implicit $x6, implicit $x7, implicit $x28, implicit $x29, implicit $x30, implicit $x31
bb.0:
liveins: $x10, $x11
@@ -78,8 +78,8 @@ body: |
BEQ $x10, $x11, %bb.1
bb.1:
- liveins: $x10, $x5
- PseudoRET implicit $x10, implicit $x5
+ liveins: $x10, $x5, $x6, $x7, $x28, $x29, $x30, $x31
+ PseudoRET implicit $x10, implicit $x5, implicit $x6, implicit $x7, implicit $x28, implicit $x29, implicit $x30, implicit $x31
...
---
>From b36f205e8dd88360265472b819b886c0bc07d8b3 Mon Sep 17 00:00:00 2001
From: Piyou Chen <gccbg04538 at gmail.com>
Date: Wed, 15 Apr 2026 10:53:23 +0800
Subject: [PATCH 3/7] Update llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Move the X5Available into condition
Co-authored-by: Craig Topper <craig.topper at sifive.com>
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 0998929945bb1..a4e2b464bb82f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3748,9 +3748,7 @@ bool RISCVInstrInfo::analyzeCandidate(outliner::Candidate &C) const {
}))
return true;
- bool X5Available = C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo);
-
- if (X5Available)
+ if (C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo))
return false;
// Save X5 into t1-t6
>From b42e703f750d25ea64962e0d63a22879fc89bf67 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Tue, 14 Apr 2026 19:57:04 -0700
Subject: [PATCH 4/7] Move CandCallOverhead define before it use
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index a4e2b464bb82f..a44a2af0f08a4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3823,16 +3823,15 @@ RISCVInstrInfo::getOutliningCandidateInfo(
if (OutlinerEnableRegSave && MOCI == MachineOutlinerDefault) {
// Set per-candidate overhead based on X5 availability
for (auto &C : RepeatedSequenceLocs) {
- unsigned CandCallOverhead;
if (C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo)) {
// X5 is available, just need the call
- CandCallOverhead = 8;
+ unsigned CandCallOverhead = 8;
C.setCallInfo(MachineOutlinerDefault, CandCallOverhead);
} else {
// X5 unavailable, need save + call + restore
// Save (2-4) + Call (8) + Restore (2-4)
- CandCallOverhead = InstrSizeCExt + 8 + InstrSizeCExt;
+ unsigned CandCallOverhead = InstrSizeCExt + 8 + InstrSizeCExt;
C.setCallInfo(MachineOutlinerRegSave, CandCallOverhead);
}
}
>From e33d42da49d1a52494b9631e64ebf9f9fce81693 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Tue, 14 Apr 2026 20:11:40 -0700
Subject: [PATCH 5/7] Add the commnet for make it more clearer
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 3 ++-
llvm/lib/Target/RISCV/RISCVInstrInfo.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index a44a2af0f08a4..60159a872608a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3748,10 +3748,11 @@ bool RISCVInstrInfo::analyzeCandidate(outliner::Candidate &C) const {
}))
return true;
+ // If X5 is available in the region, use X5 directly (MachineOutlinerDefault).
if (C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo))
return false;
- // Save X5 into t1-t6
+ // Otherwise, try to save X5 into t1-t6 (MachineOutlinerRegSave).
if (OutlinerEnableRegSave && findRegisterToSaveX5To(C, RegInfo))
return false;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 5c36ff7525200..050ca200b0ae1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -232,6 +232,7 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
+ // Return true if the candidate should be discarded from outlining.
bool analyzeCandidate(outliner::Candidate &C) const;
// Calculate target-specific information for a set of outlining candidates.
std::optional<std::unique_ptr<outliner::OutlinedFunction>>
>From 51a26af90c8ca5043bfa2f01900e79331054d34a Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Tue, 14 Apr 2026 22:52:08 -0700
Subject: [PATCH 6/7] Use isAvailableInsideSeq instead of any_of
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 60159a872608a..0be48acff2e21 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3743,9 +3743,7 @@ bool RISCVInstrInfo::analyzeCandidate(outliner::Candidate &C) const {
// Filter out candidates where the X5 register (t0) can't be used to setup
// the function call.
- if (llvm::any_of(C, [this](const MachineInstr &MI) {
- return isMIModifiesReg(MI, &RegInfo, RISCV::X5);
- }))
+ if (!C.isAvailableInsideSeq(RISCV::X5, RegInfo))
return true;
// If X5 is available in the region, use X5 directly (MachineOutlinerDefault).
>From 053684f1718fbbb4564a17e257a23c52ef6daf62 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Tue, 14 Apr 2026 23:12:14 -0700
Subject: [PATCH 7/7] Add the rv32e regsave test
---
.../machine-outliner-x5-regsave-rv32e.mir | 250 ++++++++++++++++++
1 file changed, 250 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/machine-outliner-x5-regsave-rv32e.mir
diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-x5-regsave-rv32e.mir b/llvm/test/CodeGen/RISCV/machine-outliner-x5-regsave-rv32e.mir
new file mode 100644
index 0000000000000..8935c302cfde1
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/machine-outliner-x5-regsave-rv32e.mir
@@ -0,0 +1,250 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+e -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs \
+# RUN: -riscv-outliner-regsave=true < %s | FileCheck -check-prefixes=CHECK %s
+
+--- |
+ define i32 @outline_x5_live_0(i32 %a, i32 %b) { ret i32 0 }
+ define i32 @outline_x5_live_1(i32 %a, i32 %b) { ret i32 0 }
+ define i32 @outline_x5_live_2(i32 %a, i32 %b) { ret i32 0 }
+
+ define i32 @outline_no_temp_0(i32 %a, i32 %b) { ret i32 0 }
+ define i32 @outline_no_temp_1(i32 %a, i32 %b) { ret i32 0 }
+ define i32 @outline_no_temp_2(i32 %a, i32 %b) { ret i32 0 }
+...
+---
+name: outline_x5_live_0
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_x5_live_0
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x6 = ADDI $x5, 0
+ ; CHECK-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x6, implicit $x10, implicit $x11
+ ; CHECK-NEXT: $x5 = ADDI $x6, 0
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
+---
+name: outline_x5_live_1
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_x5_live_1
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x6 = ADDI $x5, 0
+ ; CHECK-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x6, implicit $x10, implicit $x11
+ ; CHECK-NEXT: $x5 = ADDI $x6, 0
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
+---
+name: outline_x5_live_2
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_x5_live_2
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x6 = ADDI $x5, 0
+ ; CHECK-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x11, implicit-def $x12, implicit-def $x14, implicit $x6, implicit $x10, implicit $x11
+ ; CHECK-NEXT: $x5 = ADDI $x6, 0
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x14
+ $x10 = ADD $x14, $x5
+ PseudoRET implicit $x10
+...
+---
+name: outline_no_temp_0
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_no_temp_0
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5, $x6, $x7
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x11 = ANDI $x11, 1023
+ ; CHECK-NEXT: $x12 = ADDI $x10, 17
+ ; CHECK-NEXT: $x11 = AND $x12, $x11
+ ; CHECK-NEXT: $x14 = SUB $x10, $x11
+ ; CHECK-NEXT: $x11 = ANDI $x11, 1023
+ ; CHECK-NEXT: $x12 = ADDI $x10, 17
+ ; CHECK-NEXT: $x11 = AND $x12, $x11
+ ; CHECK-NEXT: $x14 = SUB $x10, $x11
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x6, $x7, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: $x10 = ADD $x10, $x6
+ ; CHECK-NEXT: $x10 = ADD $x10, $x7
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5, $x6, $x7
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x6, $x7, $x14
+ $x10 = ADD $x14, $x5
+ $x10 = ADD $x10, $x6
+ $x10 = ADD $x10, $x7
+ PseudoRET implicit $x10
+...
+---
+name: outline_no_temp_1
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_no_temp_1
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5, $x6, $x7
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x11 = ANDI $x11, 1023
+ ; CHECK-NEXT: $x12 = ADDI $x10, 17
+ ; CHECK-NEXT: $x11 = AND $x12, $x11
+ ; CHECK-NEXT: $x14 = SUB $x10, $x11
+ ; CHECK-NEXT: $x11 = ANDI $x11, 1023
+ ; CHECK-NEXT: $x12 = ADDI $x10, 17
+ ; CHECK-NEXT: $x11 = AND $x12, $x11
+ ; CHECK-NEXT: $x14 = SUB $x10, $x11
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x6, $x7, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: $x10 = ADD $x10, $x6
+ ; CHECK-NEXT: $x10 = ADD $x10, $x7
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5, $x6, $x7
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x6, $x7, $x14
+ $x10 = ADD $x14, $x5
+ $x10 = ADD $x10, $x6
+ $x10 = ADD $x10, $x7
+ PseudoRET implicit $x10
+...
+---
+name: outline_no_temp_2
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: outline_no_temp_2
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x10, $x11, $x5, $x6, $x7
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x11 = ANDI $x11, 1023
+ ; CHECK-NEXT: $x12 = ADDI $x10, 17
+ ; CHECK-NEXT: $x11 = AND $x12, $x11
+ ; CHECK-NEXT: $x14 = SUB $x10, $x11
+ ; CHECK-NEXT: $x11 = ANDI $x11, 1023
+ ; CHECK-NEXT: $x12 = ADDI $x10, 17
+ ; CHECK-NEXT: $x11 = AND $x12, $x11
+ ; CHECK-NEXT: $x14 = SUB $x10, $x11
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: liveins: $x5, $x6, $x7, $x14
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x10 = ADD $x14, $x5
+ ; CHECK-NEXT: $x10 = ADD $x10, $x6
+ ; CHECK-NEXT: $x10 = ADD $x10, $x7
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.0:
+ liveins: $x10, $x11, $x5, $x6, $x7
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ $x11 = ANDI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x14 = SUB $x10, $x11
+ PseudoBR %bb.1
+
+ bb.1:
+ liveins: $x5, $x6, $x7, $x14
+ $x10 = ADD $x14, $x5
+ $x10 = ADD $x10, $x6
+ $x10 = ADD $x10, $x7
+ PseudoRET implicit $x10
+...
More information about the llvm-commits
mailing list