[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