Index: llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -71,6 +71,7 @@
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DebugLoc.h"
@@ -1441,41 +1442,85 @@
     const DbgValueInst *DI = cast<DbgValueInst>(II);
     const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);
     const Value *V = DI->getValue();
+    const DIExpression *DE = DI->getExpression();
+    DILocalVariable *Var = DI->getVariable();
+    DILocalVariable *PtrVar = nullptr;
+    unsigned Level = DE->implicitPointerCount();
     assert(DI->getVariable()->isValidLocationForIntrinsic(DbgLoc) &&
            "Expected inlined-at fields to agree");
+
+    Module *Mod = const_cast<Module *>(DI->getModule());
+    DIBuilder DIB(*Mod, /*AllowUnresolved*/ false);
+
+    SmallVector<DILocalVariable *, 1> PtrVars;
+    if (Level > 0) {
+      DIScope *Scope = DI->getDebugLoc()->getScope();
+      DIType *Type = DI->getVariable()->getType();
+      PtrVars.push_back(Var);
+      unsigned Count = 0;
+      while (Count++ < Level) {
+        if (DIDerivedType *DT = dyn_cast<DIDerivedType>(Type))
+          Type = DT->getBaseType();
+        uint32_t AlignInBits = DI->getVariable()->getAlignInBytes();
+
+        PtrVar = DIB.createImplicitTempVariable(Scope, Type, AlignInBits);
+        PtrVars.push_back(PtrVar);
+      }
+
+      Var = PtrVars[Level];
+      DE = DIExpression::get(DE->getContext(), {});
+    } else {
+      Var = DI->getVariable();
+      DE = DI->getExpression();
+    }
+
     if (!V || isa<UndefValue>(V)) {
       // Currently the optimizer can produce this; insert an undef to
       // help debugging.
-      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, false, 0U,
-              DI->getVariable(), DI->getExpression());
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, false, 0U, Var, DE);
     } else if (const auto *CI = dyn_cast<ConstantInt>(V)) {
       if (CI->getBitWidth() > 64)
         BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
             .addCImm(CI)
             .addImm(0U)
-            .addMetadata(DI->getVariable())
-            .addMetadata(DI->getExpression());
+            .addMetadata(Var)
+            .addMetadata(DE);
       else
         BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
             .addImm(CI->getZExtValue())
             .addImm(0U)
-            .addMetadata(DI->getVariable())
-            .addMetadata(DI->getExpression());
+            .addMetadata(Var)
+            .addMetadata(DE);
     } else if (const auto *CF = dyn_cast<ConstantFP>(V)) {
       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
           .addFPImm(CF)
           .addImm(0U)
-          .addMetadata(DI->getVariable())
-          .addMetadata(DI->getExpression());
+          .addMetadata(Var)
+          .addMetadata(DE);
     } else if (Register Reg = lookUpRegForValue(V)) {
       // FIXME: This does not handle register-indirect values at offset 0.
       bool IsIndirect = false;
       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, IsIndirect, Reg,
-              DI->getVariable(), DI->getExpression());
+              Var, DE);
     } else {
       // We don't know how to handle other cases, so we drop.
       LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
     }
+
+    if (!PtrVars.empty()) {
+      unsigned Count = Level;
+      while (Count-- > 0) {
+        SmallVector<uint64_t, 3> Ops;
+        Ops.push_back(dwarf::DW_OP_LLVM_implicit_pointer);
+        DIExpression *DIExprNew = DIExpression::get(DE->getContext(), Ops);
+
+        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
+            .addImplicitPtrMetadata(PtrVars[Count + 1])
+            .addReg(0U)
+            .addMetadata(PtrVars[Count])
+            .addMetadata(DIExprNew);
+      }
+    }
     return true;
   }
   case Intrinsic::dbg_label: {
Index: llvm/test/DebugInfo/X86/implicit_pointer_fast.ll
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/X86/implicit_pointer_fast.ll
@@ -0,0 +1,99 @@
+; RUN: llc %s -fast-isel -O2 -filetype=obj -o %t.o
+; RUN: llvm-dwarfdump  %t.o | FileCheck %s
+
+; CHECK-LABEL:       DW_TAG_inlined_subroutine
+
+; Test if More than 2 member location list is printed (for pointer pointing to aggregate)
+; CHECK-LABEL:   DW_TAG_formal_parameter
+; CHECK-NEXT:    DW_AT_location
+; CHECK-NEXT:     : DW_OP_implicit_pointer [[DIE1:0x.+]] +0
+; CHECK-NEXT:     : DW_OP_implicit_pointer [[DIE2:0x.+]] +0)
+; CHECK-NEXT:    DW_AT_abstract_origin       ({{0x.+}} "ptr")
+
+; Below is the original test case this IR is generated from
+;---------------------------
+;static const char *b = "opq";
+;volatile int v;
+;static inline void foo(int *ptr) {
+;  (*ptr)++;
+;  v++;
+;  ptr++;
+;  (*ptr)++;
+;  v++;
+;}
+;
+;int main() {
+;  int arr[2] = {1, 2};
+;  v++;
+;  foo(arr);
+;  return arr[0] + arr[1] - 5;
+;}
+;---------------------------
+
+; ModuleID = 'dwarfdump-implicit_pointer_sroa_inline.c'
+source_filename = "dwarfdump-implicit_pointer_sroa_inline.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@v = common dso_local global i32 0, align 4, !dbg !0
+
+; Function Attrs: nounwind uwtable
+define dso_local i32 @main() local_unnamed_addr #0 !dbg !12 {
+entry:
+  %0 = load volatile i32, i32* @v, align 4, !dbg !20
+  %inc = add nsw i32 %0, 1, !dbg !20
+  store volatile i32 %inc, i32* @v, align 4, !dbg !20
+  call void @llvm.dbg.value(metadata i32 2, metadata !25, metadata !DIExpression(DW_OP_LLVM_implicit_pointer)), !dbg !31
+  %1 = load volatile i32, i32* @v, align 4, !dbg !33
+  %inc1.i = add nsw i32 %1, 1, !dbg !33
+  store volatile i32 %inc1.i, i32* @v, align 4, !dbg !33
+  call void @llvm.dbg.value(metadata i32 3, metadata !25, metadata !DIExpression(DW_OP_LLVM_implicit_pointer)), !dbg !34
+  %2 = load volatile i32, i32* @v, align 4, !dbg !34
+  %inc3.i = add nsw i32 %2, 1, !dbg !34
+  store volatile i32 %inc3.i, i32* @v, align 4, !dbg !34
+  ret i32 0, !dbg !35
+}
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!8, !9, !10}
+!llvm.ident = !{!11}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "v", scope: !2, file: !3, line: 14, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None)
+!3 = !DIFile(filename: "dwarfdump-implicit_pointer_sroa_inline.c", directory: "/dir", checksumkind: CSK_MD5, checksum: "f9bbaee6b152b3bc05125796b573408a")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !7)
+!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!8 = !{i32 2, !"Dwarf Version", i32 5}
+!9 = !{i32 2, !"Debug Info Version", i32 3}
+!10 = !{i32 1, !"wchar_size", i32 4}
+!11 = !{!"clang version 10.0.0"}
+!12 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 23, type: !13, scopeLine: 23, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !15)
+!13 = !DISubroutineType(types: !14)
+!14 = !{!7}
+!15 = !{!16}
+!16 = !DILocalVariable(name: "arr", scope: !12, file: !3, line: 24, type: !17)
+!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 64, elements: !18)
+!18 = !{!19}
+!19 = !DISubrange(count: 2)
+!20 = !DILocation(line: 25, column: 4, scope: !12)
+!21 = !{!22, !22, i64 0}
+!22 = !{!"int", !23, i64 0}
+!23 = !{!"omnipotent char", !24, i64 0}
+!24 = !{!"Simple C/C++ TBAA"}
+!25 = !DILocalVariable(name: "ptr", arg: 1, scope: !26, file: !3, line: 15, type: !29)
+!26 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 15, type: !27, scopeLine: 15, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !30)
+!27 = !DISubroutineType(types: !28)
+!28 = !{null, !29}
+!29 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
+!30 = !{!25}
+!31 = !DILocation(line: 0, scope: !26, inlinedAt: !32)
+!32 = distinct !DILocation(line: 26, column: 3, scope: !12)
+!33 = !DILocation(line: 17, column: 4, scope: !26, inlinedAt: !32)
+!34 = !DILocation(line: 20, column: 4, scope: !26, inlinedAt: !32)
+!35 = !DILocation(line: 27, column: 3, scope: !12)