[llvm] [ReachingDefAnalysis] Track live-in registers. (PR #175966)

Mikhail Gudim via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 15 17:07:28 PST 2026


https://github.com/mgudim updated https://github.com/llvm/llvm-project/pull/175966

>From 509270a4bc4a0c6989b8289a240552f038f94f5b Mon Sep 17 00:00:00 2001
From: Mikhail Gudim <mgudim at qti.qualcomm.com>
Date: Thu, 8 Jan 2026 14:23:18 -0800
Subject: [PATCH 1/3] [ReachingDefAnalysis] Track live-in registers.

Make `getGlobalReachingDefs` set a flag `HasLiveInPath` which indicates
if there is at least one path from function entry to `MI` along which a
entry's live-in register is not modified.
---
 .../llvm/CodeGen/ReachingDefAnalysis.h        | 21 +++++--
 llvm/lib/CodeGen/ReachingDefAnalysis.cpp      | 59 +++++++++++++------
 .../ARM/ARMFixCortexA57AES1742098Pass.cpp     |  3 +-
 llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp   | 18 ++++--
 llvm/test/CodeGen/RISCV/rda-liveins.mir       | 18 +++---
 llvm/test/CodeGen/RISCV/rda-stack.mir         | 14 ++---
 6 files changed, 87 insertions(+), 46 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
index b6ca1d6e9b328..122480b892259 100644
--- a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
+++ b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
@@ -193,8 +193,10 @@ class ReachingDefInfo {
 
   /// Return the local MI that produces the live out value for Reg, or
   /// nullptr for a non-live out or non-local def.
-  MachineInstr *getLocalLiveOutMIDef(MachineBasicBlock *MBB,
-                                     Register Reg) const;
+  /// Sets IsFunctionLiveIn to `true` if `MBB` is an entry block, `Reg` is a
+  /// function live-in and it does not get defined in `MBB`.
+  MachineInstr *getLocalLiveOutMIDef(MachineBasicBlock *MBB, Register Reg,
+                                     bool &IsFunctionLiveIn) const;
 
   /// If a single MachineInstr creates the reaching definition, then return it.
   /// Otherwise return null.
@@ -230,9 +232,13 @@ class ReachingDefInfo {
 
   /// Search MBB for a definition of Reg and insert it into Defs. If no
   /// definition is found, recursively search the predecessor blocks for them.
+  /// HasLiveInPath is set to `true` if `Reg` is live-in on function entry and
+  /// there is at least one path from function entry to the end of `MBB` along
+  /// which `Reg` is not modified.
   void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs,
-                   BlockSet &VisitedBBs) const;
-  void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs) const;
+                   BlockSet &VisitedBBs, bool &HasLiveInPath) const;
+  void getLiveOuts(MachineBasicBlock *MBB, Register Reg, InstSet &Defs,
+                   bool &HasLiveInPath) const;
 
   /// For the given block, collect the instructions that use the live-in
   /// value of the provided register. Return whether the value is still
@@ -245,8 +251,11 @@ class ReachingDefInfo {
 
   /// Collect all possible definitions of the value stored in Reg, which is
   /// used by MI.
-  void getGlobalReachingDefs(MachineInstr *MI, Register Reg,
-                             InstSet &Defs) const;
+  /// HasLiveInPath set to `true` if `Reg` is live-in on function entry and
+  /// there is at least one path from function entry to MI along which `Reg` is
+  /// not modified.
+  void getGlobalReachingDefs(MachineInstr *MI, Register Reg, InstSet &Defs,
+                             bool &HasLiveInPath) const;
 
   /// Return whether From can be moved forwards to just before To.
   bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const;
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index 82374110406ff..4944b9202a145 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -313,7 +313,8 @@ void ReachingDefInfo::print(raw_ostream &OS) {
         } else
           continue;
         Defs.clear();
-        getGlobalReachingDefs(&MI, Reg, Defs);
+        bool HasLiveInPath = false;
+        getGlobalReachingDefs(&MI, Reg, Defs, HasLiveInPath);
         MO.print(OS, TRI);
         SmallVector<int, 0> Nums;
         for (MachineInstr *Def : Defs)
@@ -322,6 +323,8 @@ void ReachingDefInfo::print(raw_ostream &OS) {
         OS << ":{ ";
         for (int Num : Nums)
           OS << Num << " ";
+        if (HasLiveInPath)
+          OS << "livein ";
         OS << "}\n";
       }
       OS << Num << ": " << MI << "\n";
@@ -514,7 +517,9 @@ void ReachingDefInfo::getGlobalUses(MachineInstr *MI, Register Reg,
   getReachingLocalUses(MI, Reg, Uses);
 
   // Handle live-out values.
-  if (auto *LiveOut = getLocalLiveOutMIDef(MI->getParent(), Reg)) {
+  bool IsFunctionLiveIn = false;
+  if (auto *LiveOut =
+          getLocalLiveOutMIDef(MI->getParent(), Reg, IsFunctionLiveIn)) {
     if (LiveOut != MI)
       return;
 
@@ -532,24 +537,33 @@ void ReachingDefInfo::getGlobalUses(MachineInstr *MI, Register Reg,
 }
 
 void ReachingDefInfo::getGlobalReachingDefs(MachineInstr *MI, Register Reg,
-                                            InstSet &Defs) const {
-  if (auto *Def = getUniqueReachingMIDef(MI, Reg)) {
-    Defs.insert(Def);
+                                            InstSet &Defs,
+                                            bool &HasLiveInPath) const {
+  // If there's a local def before MI, return it.
+  int DefInstrId = getReachingDef(MI, Reg);
+  if (DefInstrId == -1) {
+    HasLiveInPath = true;
+    return;
+  }
+  if (DefInstrId >= 0) {
+    MachineInstr *LocalDef = getInstFromId(MI->getParent(), DefInstrId);
+    Defs.insert(LocalDef);
     return;
   }
 
   for (auto *MBB : MI->getParent()->predecessors())
-    getLiveOuts(MBB, Reg, Defs);
+    getLiveOuts(MBB, Reg, Defs, HasLiveInPath);
 }
 
 void ReachingDefInfo::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
-                                  InstSet &Defs) const {
+                                  InstSet &Defs, bool &HasLiveInPath) const {
   SmallPtrSet<MachineBasicBlock*, 2> VisitedBBs;
-  getLiveOuts(MBB, Reg, Defs, VisitedBBs);
+  getLiveOuts(MBB, Reg, Defs, VisitedBBs, HasLiveInPath);
 }
 
 void ReachingDefInfo::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
-                                  InstSet &Defs, BlockSet &VisitedBBs) const {
+                                  InstSet &Defs, BlockSet &VisitedBBs,
+                                  bool &HasLiveInPath) const {
   if (VisitedBBs.count(MBB))
     return;
 
@@ -559,11 +573,18 @@ void ReachingDefInfo::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
   if (Reg.isPhysical() && LiveRegs.available(Reg))
     return;
 
-  if (auto *Def = getLocalLiveOutMIDef(MBB, Reg))
+  bool IsFunctionLiveIn = false;
+  auto *Def = getLocalLiveOutMIDef(MBB, Reg, IsFunctionLiveIn);
+  HasLiveInPath = IsFunctionLiveIn;
+  if (Def)
     Defs.insert(Def);
-  else
-    for (auto *Pred : MBB->predecessors())
-      getLiveOuts(Pred, Reg, Defs, VisitedBBs);
+  else {
+    for (auto *Pred : MBB->predecessors()) {
+      bool HasLiveInPathToPred = false;
+      getLiveOuts(Pred, Reg, Defs, VisitedBBs, HasLiveInPathToPred);
+      HasLiveInPath |= HasLiveInPathToPred;
+    }
+  }
 }
 
 MachineInstr *ReachingDefInfo::getUniqueReachingMIDef(MachineInstr *MI,
@@ -575,8 +596,9 @@ MachineInstr *ReachingDefInfo::getUniqueReachingMIDef(MachineInstr *MI,
 
   SmallPtrSet<MachineInstr*, 2> Incoming;
   MachineBasicBlock *Parent = MI->getParent();
+  bool HasLiveInPath = false;
   for (auto *Pred : Parent->predecessors())
-    getLiveOuts(Pred, Reg, Incoming);
+    getLiveOuts(Pred, Reg, Incoming, HasLiveInPath);
 
   // Check that we have a single incoming value and that it does not
   // come from the same block as MI - since it would mean that the def
@@ -625,7 +647,8 @@ bool ReachingDefInfo::isRegDefinedAfter(MachineInstr *MI, Register Reg) const {
       getReachingDef(MI, Reg) != getReachingDef(&*Last, Reg))
     return true;
 
-  if (auto *Def = getLocalLiveOutMIDef(MBB, Reg))
+  bool IsFunctionLiveIn = false;
+  if (auto *Def = getLocalLiveOutMIDef(MBB, Reg, IsFunctionLiveIn))
     return Def == getReachingLocalMIDef(MI, Reg);
 
   return false;
@@ -652,8 +675,9 @@ bool ReachingDefInfo::isReachingDefLiveOut(MachineInstr *MI,
   return true;
 }
 
-MachineInstr *ReachingDefInfo::getLocalLiveOutMIDef(MachineBasicBlock *MBB,
-                                                    Register Reg) const {
+MachineInstr *
+ReachingDefInfo::getLocalLiveOutMIDef(MachineBasicBlock *MBB, Register Reg,
+                                      bool &IsFunctionLiveIn) const {
   LiveRegUnits LiveRegs(*TRI);
   LiveRegs.addLiveOuts(*MBB);
   if (Reg.isPhysical() && LiveRegs.available(Reg))
@@ -675,6 +699,7 @@ MachineInstr *ReachingDefInfo::getLocalLiveOutMIDef(MachineBasicBlock *MBB,
   }
 
   int Def = getReachingDef(&*Last, Reg);
+  IsFunctionLiveIn = (Def == FunctionLiveInMarker);
   return Def < 0 ? nullptr : getInstFromId(MBB, Def);
 }
 
diff --git a/llvm/lib/Target/ARM/ARMFixCortexA57AES1742098Pass.cpp b/llvm/lib/Target/ARM/ARMFixCortexA57AES1742098Pass.cpp
index 3f9ea3757a5ee..8845e4e9d4431 100644
--- a/llvm/lib/Target/ARM/ARMFixCortexA57AES1742098Pass.cpp
+++ b/llvm/lib/Target/ARM/ARMFixCortexA57AES1742098Pass.cpp
@@ -288,7 +288,8 @@ void ARMFixCortexA57AES1742098::analyzeMF(
       // Inspect all operands, choosing whether to insert a fixup.
       for (MachineOperand &MOp : MI.uses()) {
         SmallPtrSet<MachineInstr *, 1> AllDefs{};
-        RDI.getGlobalReachingDefs(&MI, MOp.getReg(), AllDefs);
+        bool HasLiveInPath = false;
+        RDI.getGlobalReachingDefs(&MI, MOp.getReg(), AllDefs, HasLiveInPath);
 
         // Planned Fixup: This should be added to FixupLocsForFn at most once.
         AESFixupLocation NewLoc{&MBB, &MI, &MOp};
diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
index 1719165fb6717..66f7c8fc63bd0 100644
--- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
+++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
@@ -299,7 +299,8 @@ namespace {
           return true;
 
         SmallPtrSet<MachineInstr *, 2> Defs;
-        RDI.getGlobalReachingDefs(MI, MO.getReg(), Defs);
+        bool HasLiveInPath = false;
+        RDI.getGlobalReachingDefs(MI, MO.getReg(), Defs, HasLiveInPath);
         if (Defs.empty())
           return true;
 
@@ -647,8 +648,9 @@ bool LowOverheadLoop::ValidateTailPredicate() {
 
     if (StartInsertPt != StartInsertBB->end() &&
         !RDI.isReachingDefLiveOut(&*StartInsertPt, NumElements)) {
-      if (auto *ElemDef =
-              RDI.getLocalLiveOutMIDef(StartInsertBB, NumElements)) {
+      bool IsFunctionLiveIn = false;
+      if (auto *ElemDef = RDI.getLocalLiveOutMIDef(StartInsertBB, NumElements,
+                                                   IsFunctionLiveIn)) {
         if (RDI.isSafeToMoveForwards(ElemDef, &*StartInsertPt)) {
           ElemDef->removeFromParent();
           StartInsertBB->insert(StartInsertPt, ElemDef);
@@ -890,7 +892,8 @@ static bool producesFalseLanesZero(MachineInstr &MI,
     // - If it's predicated, it only matters that it's def register already has
     //   false lane zeros, so we can ignore the uses.
     SmallPtrSet<MachineInstr *, 2> Defs;
-    RDI.getGlobalReachingDefs(&MI, MO.getReg(), Defs);
+    bool HasLiveInPath = false;
+    RDI.getGlobalReachingDefs(&MI, MO.getReg(), Defs, HasLiveInPath);
     if (Defs.empty())
       return false;
     for (auto *Def : Defs) {
@@ -1020,9 +1023,12 @@ bool LowOverheadLoop::ValidateLiveOuts() {
     }
     // Check Q-regs that are live in the exit blocks. We don't collect scalars
     // because they won't be affected by lane predication.
-    if (QPRs->contains(RegMask.PhysReg))
-      if (auto *MI = RDI.getLocalLiveOutMIDef(Header, RegMask.PhysReg))
+    if (QPRs->contains(RegMask.PhysReg)) {
+      bool IsFunctionLiveIn = false;
+      if (auto *MI = RDI.getLocalLiveOutMIDef(Header, RegMask.PhysReg,
+                                              IsFunctionLiveIn))
         LiveOutMIs.insert(MI);
+    }
   }
 
   // We've already validated that any VPT predication within the loop will be
diff --git a/llvm/test/CodeGen/RISCV/rda-liveins.mir b/llvm/test/CodeGen/RISCV/rda-liveins.mir
index ff7c9efa2de2c..f83541f7845ce 100644
--- a/llvm/test/CodeGen/RISCV/rda-liveins.mir
+++ b/llvm/test/CodeGen/RISCV/rda-liveins.mir
@@ -6,7 +6,7 @@ tracksRegLiveness: true
 body:             |
   ; CHECK-LABEL: Reaching definitions for for machine function: test0
   ; CHECK-NEXT: %bb.0:
-  ; CHECK-NEXT: implicit $x10:{ }
+  ; CHECK-NEXT: implicit $x10:{ livein }
   ; CHECK-NEXT: 0: PseudoRET implicit $x10
 
   bb.0.entry:
@@ -21,7 +21,7 @@ tracksRegLiveness: true
 body:             |
   ; CHECK-LABEL: Reaching definitions for for machine function: test1
   ; CHECK-NEXT: %bb.0:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: 0: $x10 = ADDI $x10, 1
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: implicit $x10:{ 0 }
@@ -39,19 +39,19 @@ tracksRegLiveness: true
 body:             |
   ; CHECK-LABEL: Reaching definitions for for machine function: test2
   ; CHECK-NEXT: %bb.0:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: $x0:{ }
   ; CHECK-NEXT: 0: BEQ $x10, $x0, %bb.2
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: %bb.1:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: 1: $x10 = ADDI $x10, 1
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: implicit $x10:{ 1 }
   ; CHECK-NEXT: 2: PseudoRET implicit $x10
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: %bb.2
-  ; CHECK-NEXT: implicit $x10:{ }
+  ; CHECK-NEXT: implicit $x10:{ livein }
   ; CHECK-NEXT: 3: PseudoRET implicit $x10
   bb.0.entry:
     liveins: $x10
@@ -77,25 +77,25 @@ stack:
 body:             |
   ; CHECK-LABEL: Reaching definitions for for machine function: test3
   ; CHECK-NEXT: %bb.0:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: $x0:{ }
   ; CHECK-NEXT: 0: BEQ $x10, $x0, %bb.2
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: %bb.1:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: 1: $x10 = ADDI $x10, 1
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: 2: PseudoBR %bb.3
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: %bb.2:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: %stack.0:{ }
   ; CHECK-NEXT: 3: SD $x10, %stack.0, 0 :: (store (s64))
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: 4: PseudoBR %bb.3
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: %bb.3:
-  ; CHECK-NEXT: implicit $x10:{ 1 }
+  ; CHECK-NEXT: implicit $x10:{ 1 livein }
   ; CHECK-NEXT: 5: PseudoRET implicit $x10
   bb.0.entry:
     liveins: $x10
diff --git a/llvm/test/CodeGen/RISCV/rda-stack.mir b/llvm/test/CodeGen/RISCV/rda-stack.mir
index 367c450f9b155..57a3895afad65 100644
--- a/llvm/test/CodeGen/RISCV/rda-stack.mir
+++ b/llvm/test/CodeGen/RISCV/rda-stack.mir
@@ -106,12 +106,12 @@ stack:
 body:             |
   ; CHECK-LABEL: Reaching definitions for for machine function: test3
   ; CHECK-NEXT: %bb.0:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: $x0:{ }
   ; CHECK-NEXT: 0: BEQ $x10, $x0, %bb.2
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: %bb.1:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: 1: $x10 = ADDI $x10, 1
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: $x10:{ 1 }
@@ -121,7 +121,7 @@ body:             |
   ; CHECK-NEXT: 3: PseudoBR %bb.3
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: %bb.2:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: 4: $x10 = ADDI $x10, 2
   ; CHECK-EMPTY: 
   ; CHECK-NEXT: $x10:{ 4 }
@@ -170,19 +170,19 @@ stack:
 body:             |
   ; CHECK-LABEL: Reaching definitions for for machine function: test4
   ; CHECK-NEXT: %bb.0:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: %stack.0:{ }
   ; CHECK-NEXT: 0: SD $x10, %stack.0, 0 :: (store (s64))
   ; CHECK-EMPTY:
-  ; CHECK-NEXT: $x11:{ }
+  ; CHECK-NEXT: $x11:{ livein }
   ; CHECK-NEXT: %stack.0:{ 0 }
   ; CHECK-NEXT: 1: SD $x11, %stack.0, 0 :: (store (s64))
   ; CHECK-EMPTY:
-  ; CHECK-NEXT: $x10:{ }
+  ; CHECK-NEXT: $x10:{ livein }
   ; CHECK-NEXT: %stack.1:{ }
   ; CHECK-NEXT: 2: SD $x10, %stack.1, 0 :: (store (s64))
   ; CHECK-EMPTY:
-  ; CHECK-NEXT: $x11:{ }
+  ; CHECK-NEXT: $x11:{ livein }
   ; CHECK-NEXT: %stack.1:{ 2 }
   ; CHECK-NEXT: 3: SD $x11, %stack.1, 0 :: (store (s64))
   ; CHECK-EMPTY:

>From 2d2b19b8546803aa3bec8784b049f6bf4471d8a2 Mon Sep 17 00:00:00 2001
From: Mikhail Gudim <mgudim at qti.qualcomm.com>
Date: Wed, 14 Jan 2026 13:11:38 -0800
Subject: [PATCH 2/3] use named constant

---
 llvm/lib/CodeGen/ReachingDefAnalysis.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index 4944b9202a145..f6cc2fe3772aa 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -541,7 +541,7 @@ void ReachingDefInfo::getGlobalReachingDefs(MachineInstr *MI, Register Reg,
                                             bool &HasLiveInPath) const {
   // If there's a local def before MI, return it.
   int DefInstrId = getReachingDef(MI, Reg);
-  if (DefInstrId == -1) {
+  if (DefInstrId == FunctionLiveInMarker) {
     HasLiveInPath = true;
     return;
   }

>From 5d961fb33445344fa5ff92b7a68d160f44b92393 Mon Sep 17 00:00:00 2001
From: Mikhail Gudim <mgudim at qti.qualcomm.com>
Date: Thu, 15 Jan 2026 17:07:00 -0800
Subject: [PATCH 3/3] bugfixes

---
 .../llvm/CodeGen/ReachingDefAnalysis.h        |  2 +-
 llvm/lib/CodeGen/ReachingDefAnalysis.cpp      | 11 ++---
 llvm/test/CodeGen/RISCV/rda-liveins.mir       | 40 +++++++++++++++++++
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
index 122480b892259..ed949df50c30b 100644
--- a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
+++ b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
@@ -153,7 +153,7 @@ class ReachingDefInfo {
   /// Default values are 'nothing happened a long time ago'.
   static constexpr int ReachingDefDefaultVal = -(1 << 21);
   /// Special values for function live-ins.
-  static constexpr int FunctionLiveInMarker = -1;
+  static constexpr int FunctionLiveInMarker = ReachingDefDefaultVal + 1;
 
   using InstSet = SmallPtrSetImpl<MachineInstr*>;
   using BlockSet = SmallPtrSetImpl<MachineBasicBlock*>;
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index f6cc2fe3772aa..475016cc027ff 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -541,18 +541,19 @@ void ReachingDefInfo::getGlobalReachingDefs(MachineInstr *MI, Register Reg,
                                             bool &HasLiveInPath) const {
   // If there's a local def before MI, return it.
   int DefInstrId = getReachingDef(MI, Reg);
-  if (DefInstrId == FunctionLiveInMarker) {
+  if (DefInstrId == FunctionLiveInMarker)
     HasLiveInPath = true;
-    return;
-  }
   if (DefInstrId >= 0) {
     MachineInstr *LocalDef = getInstFromId(MI->getParent(), DefInstrId);
     Defs.insert(LocalDef);
     return;
   }
 
-  for (auto *MBB : MI->getParent()->predecessors())
-    getLiveOuts(MBB, Reg, Defs, HasLiveInPath);
+  for (auto *MBB : MI->getParent()->predecessors()) {
+    bool HasLiveInPathToPred = false;
+    getLiveOuts(MBB, Reg, Defs, HasLiveInPathToPred);
+    HasLiveInPath |= HasLiveInPathToPred;
+  }
 }
 
 void ReachingDefInfo::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
diff --git a/llvm/test/CodeGen/RISCV/rda-liveins.mir b/llvm/test/CodeGen/RISCV/rda-liveins.mir
index f83541f7845ce..9296eb3deb73d 100644
--- a/llvm/test/CodeGen/RISCV/rda-liveins.mir
+++ b/llvm/test/CodeGen/RISCV/rda-liveins.mir
@@ -115,3 +115,43 @@ body:             |
     liveins: $x10
     PseudoRET implicit $x10
 ...
+
+---
+name:            test4
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    BEQ $x10, $x0, %bb.2
+
+  bb.1:
+    liveins: $x10
+    PseudoBR %bb.2, implicit-def $x10
+
+  bb.2:
+    liveins: $x10
+    PseudoRET implicit $x10
+
+---
+name:            test5
+tracksRegLiveness: true
+stack:
+  - { id: 0, name: '', type: default, offset: 0, size: 8, alignment: 8,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.0.entry:
+    liveins: $x10
+    $x10 = ADDI, $x10, 1
+    BEQ $x10, $x0, %bb.2
+
+  bb.1:
+    liveins: $x10
+    $x10 = ADDI, $x10, 2
+    SD $x10, %stack.0, 0 :: (store (s64))
+    SD $x10, %stack.0, 0 :: (store (s64))
+    SD $x10, %stack.0, 0 :: (store (s64))
+    PseudoBR %bb.2, implicit-def $x10
+
+  bb.2:
+    liveins: $x10
+    PseudoRET implicit $x10



More information about the llvm-commits mailing list