diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h
--- a/llvm/lib/Target/AMDGPU/AMDGPU.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.h
@@ -39,6 +39,7 @@
 FunctionPass *createSIOptimizeExecMaskingPreRAPass();
 FunctionPass *createSIOptimizeVGPRLiveRangePass();
 FunctionPass *createSIFixSGPRCopiesPass();
+FunctionPass *createSIFixSGPRLivenessPass();
 FunctionPass *createSIMemoryLegalizerPass();
 FunctionPass *createSIInsertWaitcntsPass();
 FunctionPass *createSIPreAllocateWWMRegsPass();
@@ -174,6 +175,9 @@
 void initializeSIFixSGPRCopiesPass(PassRegistry &);
 extern char &SIFixSGPRCopiesID;
 
+void initializeSIFixSGPRLivenessPass(PassRegistry &);
+extern char &SIFixSGPRLivenessID;
+
 void initializeSIFixVGPRCopiesPass(PassRegistry &);
 extern char &SIFixVGPRCopiesID;
 
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -348,6 +348,7 @@
   initializeGCNDPPCombinePass(*PR);
   initializeSILowerI1CopiesPass(*PR);
   initializeSILowerSGPRSpillsPass(*PR);
+  initializeSIFixSGPRLivenessPass(*PR);
   initializeSIFixSGPRCopiesPass(*PR);
   initializeSIFixVGPRCopiesPass(*PR);
   initializeSIFoldOperandsPass(*PR);
@@ -1241,6 +1242,7 @@
 
 bool GCNPassConfig::addInstSelector() {
   AMDGPUPassConfig::addInstSelector();
+  addPass(&SIFixSGPRLivenessID);
   addPass(&SIFixSGPRCopiesID);
   addPass(createSILowerI1CopiesPass());
   return false;
diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt
--- a/llvm/lib/Target/AMDGPU/CMakeLists.txt
+++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt
@@ -132,6 +132,7 @@
   R600TargetTransformInfo.cpp
   SIAnnotateControlFlow.cpp
   SIFixSGPRCopies.cpp
+  SIFixSGPRLiveness.cpp
   SIFixVGPRCopies.cpp
   SIFoldOperands.cpp
   SIFormMemoryClauses.cpp
diff --git a/llvm/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp b/llvm/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp
new file mode 100644
--- /dev/null
+++ b/llvm/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp
@@ -0,0 +1,140 @@
+//===- SIFixSGPRLiveness.cpp - Fix SGPR Liveness --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Consider a simple example:
+///     BB1: %1:SGPR = COPY 1
+///     | \
+///     |  BB2: %2:SGPR = IMPLICIT_DEF
+///     | /
+///     BB3: %3 = phi (%2, BB2), (%1, BB1)
+///
+/// BB1 ends with a divergent branch. The virtual registers shown in above
+/// example are dead in BB2. After register allocation, they may end up
+/// being put in the same physical register, and the liveness of the register
+/// does not cover the range of BB2. If the corresponding physical register
+/// is reused in BB2, the content of the physical register will be overwritten.
+/// The idea in this pass is to extend the liveness of %1 through BB2.
+///
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPU.h"
+#include "GCNSubtarget.h"
+#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
+#include "llvm/ADT/SetOperations.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Target/TargetMachine.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "si-fix-sgpr-liveness"
+
+namespace {
+
+class SIFixSGPRLiveness : public MachineFunctionPass {
+  MachineDominatorTree *MDT;
+
+public:
+  static char ID;
+
+  MachineRegisterInfo *MRI;
+  const SIRegisterInfo *TRI;
+
+  SIFixSGPRLiveness() : MachineFunctionPass(ID) {}
+
+  bool extendSGPRLiveRangeForPHI(MachineFunction &MF);
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+  StringRef getPassName() const override { return "SI Fix SGPR Liveness"; }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.addRequired<MachineDominatorTree>();
+    AU.addPreserved<MachineDominatorTree>();
+    AU.setPreservesCFG();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+};
+
+} // end anonymous namespace
+
+INITIALIZE_PASS_BEGIN(SIFixSGPRLiveness, DEBUG_TYPE, "SI Fix SGPR Liveness",
+                      false, false)
+INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_END(SIFixSGPRLiveness, DEBUG_TYPE, "SI Fix SGPR Liveness",
+                    false, false)
+
+char SIFixSGPRLiveness::ID = 0;
+
+char &llvm::SIFixSGPRLivenessID = SIFixSGPRLiveness::ID;
+
+FunctionPass *llvm::createSIFixSGPRLivenessPass() {
+  return new SIFixSGPRLiveness();
+}
+
+bool SIFixSGPRLiveness::extendSGPRLiveRangeForPHI(MachineFunction &MF) {
+  bool Changed = false;
+  for (auto &MBB : MF) {
+    for (auto &MI : MBB.phis()) {
+      Register DstReg = MI.getOperand(0).getReg();
+      if (!TRI->isSGPRClass(MRI->getRegClass(DstReg)))
+        continue;
+      SmallVector<std::pair<MachineOperand *, MachineBasicBlock *>, 4> Undefs;
+      // Register SingleValue = AMDGPU::NoRegister;
+      MachineOperand *SingleOp = nullptr;
+      MachineBasicBlock *SingleMBB = nullptr;
+      for (unsigned i = 1, e = MI.getNumOperands(); i != e; i += 2) {
+        MachineOperand *SrcOp = &MI.getOperand(i);
+        if (!SrcOp->isReg() || !SrcOp->getReg().isVirtual())
+          continue;
+
+        MachineInstr *Def = MRI->getVRegDef(SrcOp->getReg());
+        if (Def && Def->isImplicitDef()) {
+          Undefs.push_back(
+              std::make_pair(SrcOp, MI.getOperand(i + 1).getMBB()));
+        } else {
+          if (!SingleOp) {
+            SingleOp = SrcOp;
+            SingleMBB = MI.getOperand(i + 1).getMBB();
+          } else if (SrcOp->getReg() != SingleOp->getReg() ||
+                     SrcOp->getSubReg() != SingleOp->getSubReg()) {
+            SingleOp = nullptr;
+            break;
+          }
+        }
+      }
+
+      if (!SingleOp || Undefs.empty())
+        continue;
+
+      // We have an single non-undef incoming value, make it alive
+      // through all paths from the SingleMBB to MBB.
+      if (all_of(Undefs, [&](auto UD) {
+            return MDT->dominates(SingleMBB, UD.second);
+          })) {
+        for (auto UndefOp : Undefs) {
+          UndefOp.first->setIsUndef(false);
+          UndefOp.first->setReg(SingleOp->getReg());
+          UndefOp.first->setSubReg(SingleOp->getSubReg());
+        }
+        Changed = true;
+      }
+      continue;
+    }
+  }
+  return Changed;
+}
+
+bool SIFixSGPRLiveness::runOnMachineFunction(MachineFunction &MF) {
+  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
+  MRI = &MF.getRegInfo();
+  TRI = ST.getRegisterInfo();
+  MDT = &getAnalysis<MachineDominatorTree>();
+
+  return extendSGPRLiveRangeForPHI(MF);
+}
diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
--- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
+++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
@@ -93,6 +93,7 @@
 ; GCN-O0-NEXT:        Legacy Divergence Analysis
 ; GCN-O0-NEXT:        AMDGPU DAG->DAG Pattern Instruction Selection
 ; GCN-O0-NEXT:        MachineDominator Tree Construction
+; GCN-O0-NEXT:        SI Fix SGPR Liveness
 ; GCN-O0-NEXT:        SI Fix SGPR copies
 ; GCN-O0-NEXT:        MachinePostDominator Tree Construction
 ; GCN-O0-NEXT:        SI Lower i1 Copies
@@ -276,6 +277,7 @@
 ; GCN-O1-NEXT:        Lazy Block Frequency Analysis
 ; GCN-O1-NEXT:        AMDGPU DAG->DAG Pattern Instruction Selection
 ; GCN-O1-NEXT:        MachineDominator Tree Construction
+; GCN-O1-NEXT:        SI Fix SGPR Liveness
 ; GCN-O1-NEXT:        SI Fix SGPR copies
 ; GCN-O1-NEXT:        MachinePostDominator Tree Construction
 ; GCN-O1-NEXT:        SI Lower i1 Copies
@@ -557,6 +559,7 @@
 ; GCN-O1-OPTS-NEXT:        Lazy Block Frequency Analysis
 ; GCN-O1-OPTS-NEXT:        AMDGPU DAG->DAG Pattern Instruction Selection
 ; GCN-O1-OPTS-NEXT:        MachineDominator Tree Construction
+; GCN-O1-OPTS-NEXT:        SI Fix SGPR Liveness
 ; GCN-O1-OPTS-NEXT:        SI Fix SGPR copies
 ; GCN-O1-OPTS-NEXT:        MachinePostDominator Tree Construction
 ; GCN-O1-OPTS-NEXT:        SI Lower i1 Copies
@@ -847,6 +850,7 @@
 ; GCN-O2-NEXT:        Lazy Block Frequency Analysis
 ; GCN-O2-NEXT:        AMDGPU DAG->DAG Pattern Instruction Selection
 ; GCN-O2-NEXT:        MachineDominator Tree Construction
+; GCN-O2-NEXT:        SI Fix SGPR Liveness
 ; GCN-O2-NEXT:        SI Fix SGPR copies
 ; GCN-O2-NEXT:        MachinePostDominator Tree Construction
 ; GCN-O2-NEXT:        SI Lower i1 Copies
@@ -1151,6 +1155,7 @@
 ; GCN-O3-NEXT:        Lazy Block Frequency Analysis
 ; GCN-O3-NEXT:        AMDGPU DAG->DAG Pattern Instruction Selection
 ; GCN-O3-NEXT:        MachineDominator Tree Construction
+; GCN-O3-NEXT:        SI Fix SGPR Liveness
 ; GCN-O3-NEXT:        SI Fix SGPR copies
 ; GCN-O3-NEXT:        MachinePostDominator Tree Construction
 ; GCN-O3-NEXT:        SI Lower i1 Copies
diff --git a/llvm/test/CodeGen/AMDGPU/sgpr-liveness.ll b/llvm/test/CodeGen/AMDGPU/sgpr-liveness.ll
new file mode 100644
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/sgpr-liveness.ll
@@ -0,0 +1,54 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -march=amdgcn -mcpu=gfx1010 -verify-machineinstrs < %s | FileCheck %s -check-prefix=GCN
+;
+; This is a test to show that we need to extend the liveness of SGPR register to
+; stop being overwritten. The example IR has a divergent if-then, and the phi %c2
+; only has meaningful incoming value from %entry. To achieve the goal of keeping
+; more values as uniform, the divergence/uniform analysis will mark %c2 as uniform.
+; For AMDGPU backend, we will assign SGPR for %c2 and its incoming values. Without
+; making the value alive in block %if, it might be overwritten in block %if.
+; Usually this issued does not happend because middle-end optimization tends to
+; simplify %c2 as %c. But this case happens after subsequent structurizer change.
+;
+define amdgpu_ps float @sgpr_live_through_all_paths(float inreg %c, float %v, i32 %x, i32 %y) #0 {
+; GCN-LABEL: sgpr_live_through_all_paths:
+; GCN:       ; %bb.0: ; %entry
+; GCN-NEXT:    v_cmp_lt_i32_e64 s2, v2, v1
+; GCN-NEXT:    s_mov_b32 s1, exec_lo
+; GCN-NEXT:    s_and_b32 s2, s1, s2
+; GCN-NEXT:    s_mov_b32 exec_lo, s2
+; GCN-NEXT:    s_cbranch_execz .LBB0_2
+; GCN-NEXT:  ; %bb.1: ; %if
+; GCN-NEXT:    s_mov_b32 s2, 2.0
+; GCN-NEXT:    v_div_scale_f32 v1, s3, s2, s2, v0
+; GCN-NEXT:    v_rcp_f32_e64 v2, v1
+; GCN-NEXT:    s_mov_b32 s3, 1.0
+; GCN-NEXT:    v_fma_f32 v3, -v1, v2, s3
+; GCN-NEXT:    v_fmac_f32_e64 v2, v3, v2
+; GCN-NEXT:    v_div_scale_f32 v3, vcc_lo, v0, s2, v0
+; GCN-NEXT:    v_mul_f32_e64 v4, v3, v2
+; GCN-NEXT:    v_fma_f32 v5, -v1, v4, v3
+; GCN-NEXT:    v_fmac_f32_e64 v4, v5, v2
+; GCN-NEXT:    v_fma_f32 v1, -v1, v4, v3
+; GCN-NEXT:    v_div_fmas_f32 v1, v1, v2, v4
+; GCN-NEXT:    v_div_fixup_f32 v0, v1, s2, v0
+; GCN-NEXT:  .LBB0_2: ; %end
+; GCN-NEXT:    s_or_b32 exec_lo, exec_lo, s1
+; GCN-NEXT:    v_add_f32_e64 v0, v0, s0
+; GCN-NEXT:    ; return to shader part epilog
+entry:
+  %cc = icmp slt i32 %y, %x
+  br i1 %cc, label %if, label %end
+
+if:
+  %v.if = fdiv float %v, 2.0
+  br label %end
+
+end:
+  %v2 = phi float [ %v.if, %if ], [ %v, %entry ]
+  %c2 = phi float [ undef, %if ], [ %c, %entry ]
+  %r = fadd float %v2, %c2
+  ret float %r
+}
+
+attributes #0 = { nounwind optnone noinline }