Index: llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
===================================================================
--- llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
+++ llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
@@ -6,12 +6,15 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/Function.h"
 #include "llvm/InitializePasses.h"
@@ -27,6 +30,7 @@
 using namespace llvm;
 
 STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
+STATISTIC(NumRemovedForward, "Number of DBG_VALUEs removed (forward scan)");
 
 namespace {
 
@@ -66,6 +70,70 @@
   initializeRemoveRedundantDebugValuesPass(*PassRegistry::getPassRegistry());
 }
 
+// This analysis aims to remove redundant DBG_VALUEs by going forward
+// in the basic block by considering the first DBG_VALUE as a valid
+// until its first (location) operand is not clobbered/modified.
+// For example:
+//   (1) DBG_VALUE $edi, !"var1", ...
+//   (2) <block of code that does affect $edi>
+//   (3) DBG_VALUE $edi, !"var1", ...
+//   ...
+// in this case, we can remove (3).
+static bool reduceDbgValsForwardScan(MachineBasicBlock &MBB) {
+  LLVM_DEBUG(dbgs() << "\n == Forward Scan == \n");
+
+  SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
+  DenseMap<DebugVariable, std::pair<MachineOperand *, const DIExpression *>>
+      VariableMap;
+  const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
+
+  for (auto &MI : MBB) {
+    if (MI.isDebugValue()) {
+      MachineOperand &Loc = MI.getDebugOperand(0);
+      if (!Loc.isReg())
+        continue;
+
+      DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
+                        MI.getDebugLoc()->getInlinedAt());
+      auto VMI = VariableMap.find(Var);
+      // We have found a new value for a variable.
+      if (VMI == VariableMap.end() ||
+          VMI->second.first->getReg() != Loc.getReg() ||
+          VMI->second.second != MI.getDebugExpression()) {
+        VariableMap[Var] = {&Loc, MI.getDebugExpression()};
+        continue;
+      }
+
+      // Found an identical DBG_VALUE, so it can be considered
+      // for later removal.
+      DbgValsToBeRemoved.push_back(&MI);
+    }
+
+    if (MI.isMetaInstruction())
+      continue;
+
+    // If this instruction modifies any of variables locations, it
+    // shouldn't be a subject for removing, since a new debug value
+    // is expected in that situtation.
+    auto stopTrackingNonRedundantDbgVals = [&TRI, &MI, &VariableMap]() {
+      for (auto &Var : VariableMap) {
+        auto &LocOp = Var.second.first;
+        if (MI.modifiesRegister(LocOp->getReg(), TRI))
+          VariableMap.erase(Var.first);
+      }
+    };
+    stopTrackingNonRedundantDbgVals();
+  }
+
+  for (auto &Instr : DbgValsToBeRemoved) {
+    LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
+    Instr->eraseFromParent();
+    ++NumRemovedForward;
+  }
+
+  return !DbgValsToBeRemoved.empty();
+}
+
 // This analysis aims to remove redundant DBG_VALUEs by going backward
 // in the basic block by considering the latest DBG_VALUE in a row of
 // consecutive DBG_VALUEs for the same variable as the one that is relevant
@@ -116,8 +184,10 @@
 
   bool Changed = false;
 
-  for (auto &MBB : MF)
+  for (auto &MBB : MF) {
     Changed |= reduceDbgValsBackwardScan(MBB);
+    Changed |= reduceDbgValsForwardScan(MBB);
+  }
 
   return Changed;
 }
Index: llvm/test/CodeGen/PowerPC/non-debug-mi-search-frspxsrsp.ll
===================================================================
--- llvm/test/CodeGen/PowerPC/non-debug-mi-search-frspxsrsp.ll
+++ llvm/test/CodeGen/PowerPC/non-debug-mi-search-frspxsrsp.ll
@@ -29,7 +29,6 @@
 ; CHECK-NEXT:          xvcvdpsp 34, 0
 ; CHECK-NEXT:          xvcvdpsp 35, 1
 ; CHECK-NEXT:          vmrgew 2, 2, 3
-; CHECK-NEXT:          #DEBUG_VALUE: test:Vptr <- $x4
 ; CHECK-NEXT:          .loc    1 3 9 is_stmt 0
 ; CHECK-NEXT:          stvx 2, 0, 4
 ; CHECK-NEXT:          .loc    1 4 1 is_stmt 1
Index: llvm/test/DebugInfo/MIR/X86/remove-redundant-dbg-vals.mir
===================================================================
--- llvm/test/DebugInfo/MIR/X86/remove-redundant-dbg-vals.mir
+++ llvm/test/DebugInfo/MIR/X86/remove-redundant-dbg-vals.mir
@@ -1,13 +1,21 @@
 # RUN: llc %s -o - -run-pass=removeredundantdebugvalues | FileCheck %s
 
 ## This checks that the RemoveRedundantDebugValues removes redundant
-## DBG_VALUEs.
+## DBG_VALUEs. The MIR was hand-written, and the foo2() is just a copy
+## of foo(), with an extra instruction that modifies the $edi register.
 
 # CHECK-LABEL: foo
 # CHECK-LABEL: bb.0.entry:
 # CHECK:      DBG_VALUE $edi
 # CHECK-NOT:  DBG_VALUE $edi
 # CHECK:      frame-setup PUSH64r
+# CHECK:      MOV32mr $rip, 1, $noreg
+# CHECK-NOT:  DBG_VALUE $edi
+
+# CHECK-LABEL: foo2
+# CHECK-LABEL: bb.0.entry:
+# CHECK:  MOV32mr $rip, 1, $noreg
+# CHECK:  DBG_VALUE $edi
 
 --- |
   ; ModuleID = 'test.ll'
@@ -29,6 +37,15 @@
     ret i32 0, !dbg !22
   }
 
+  ; Function Attrs: nounwind uwtable
+  define dso_local i32 @foo2(i32 %param) local_unnamed_addr !dbg !26 {
+  entry:
+    store i32 %param, i32* @side_effect, align 4, !dbg !27
+    %0 = load i32, i32* @value, align 4, !dbg !27
+    tail call void @bar(i32 %0), !dbg !27
+    ret i32 0, !dbg !27
+  }
+
   declare !dbg !23 dso_local void @bar(i32) local_unnamed_addr
   
   ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
@@ -60,7 +77,8 @@
   !23 = !DISubprogram(name: "bar", scope: !1, file: !1, line: 1, type: !24, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
   !24 = !DISubroutineType(types: !25)
   !25 = !{null, !11}
-
+  !26 = distinct !DISubprogram(name: "foo2", scope: !1, file: !1, line: 4, type: !9, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
+  !27 = !DILocation(line: 0, scope: !26)
 ...
 ---
 name:            foo
@@ -84,3 +102,26 @@
     RETQ killed $eax, debug-location !22
 
 ...
+---
+name:            foo2
+alignment:       16
+liveins:
+  - { reg: '$edi', virtual-reg: '' }
+body:             |
+  bb.0.entry:
+    liveins: $edi, $esi
+  
+    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !14
+    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !14
+    frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp
+    CFI_INSTRUCTION def_cfa_offset 16
+    MOV32mr $rip, 1, $noreg, @side_effect, $noreg, killed renamable $esi, debug-location !15 :: (store 4 into @side_effect)
+    renamable $edi = MOV32rm $rip, 1, $noreg, @value, $noreg, debug-location !20 :: (dereferenceable load 4 from @value)
+    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !14
+    CALL64pcrel32 @bar, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, debug-location !21
+    $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags, debug-location !22
+    $rcx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !22
+    CFI_INSTRUCTION def_cfa_offset 8, debug-location !22
+    RETQ killed $eax, debug-location !22
+
+...