diff --git a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
index 5cde52637248..1a55021c5d3f 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
@@ -702,8 +702,14 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
for (auto &StackFrame : CS.Frames) {
uint64_t StackId = computeStackId(StackFrame);
ArrayRef FrameSlice = ArrayRef(CS.Frames).drop_front(Idx++);
- ArrayRef CalleeGuids(CS.CalleeGuids);
- LocHashToCallSites[StackId].push_back({FrameSlice, CalleeGuids});
+ // The callee guids for the slice containing all frames (due to the
+ // increment above Idx is now 1) comes from the CalleeGuids recorded in
+ // the CallSite. For the slices not containing the leaf-most frame, the
+ // callee guid is simply the function GUID of the prior frame.
+ LocHashToCallSites[StackId].push_back(
+ {FrameSlice, (Idx == 1 ? CS.CalleeGuids
+ : ArrayRef(
+ CS.Frames[Idx - 2].Function))});
ProfileHasColumns |= StackFrame.Column;
// Once we find this function, we can stop recording.
diff --git a/llvm/test/Transforms/PGOProfile/memprof_annotate_indirect_call.test b/llvm/test/Transforms/PGOProfile/memprof_annotate_indirect_call.test
index 15a315543056..4677eebff3cf 100644
--- a/llvm/test/Transforms/PGOProfile/memprof_annotate_indirect_call.test
+++ b/llvm/test/Transforms/PGOProfile/memprof_annotate_indirect_call.test
@@ -30,6 +30,17 @@ HeapProfileRecords:
- { Function: _Z3barv, LineOffset: 3, Column: 5, IsInlineFrame: true }
- { Function: _Z3foov, LineOffset: 10, Column: 7, IsInlineFrame: false }
CalleeGuids: [0x3456, 0x4567]
+ # This set of frames is for the second indirect call below. We should match
+ # the interior non-leaf frame with the call. In this case the synthesized
+ # VP metadata should have _Z3xyzv (GUID 15367485273663173088 aka
+ # -3079258800046378528) as the target, not the one from CalleeGuids which
+ # is the callee of the leafmost frame. This simulates the case where sample
+ # PGO performed ICP during matching in the profiled compile, without using
+ # VP metadata.
+ - Frames:
+ - { Function: _Z3xyzv, LineOffset: 1, Column: 1, IsInlineFrame: true }
+ - { Function: _Z3barv, LineOffset: 4, Column: 10, IsInlineFrame: false }
+ CalleeGuids: [0x5678]
...
;--- basic.ll
@@ -38,12 +49,17 @@ entry:
%fp = alloca ptr, align 8
%0 = load ptr, ptr %fp, align 8
call void %0(), !dbg !5
-; CHECK-ENABLE: call void %0(), {{.*}} !prof !6
+; CHECK-ENABLE: call void %0(), {{.*}} !prof ![[VP1:[0-9]+]]
; CHECK-DISABLE-NOT: !prof
+ call void %0(), !dbg !6
+; CHECK-ENABLE: call void %0(), {{.*}} !prof ![[VP2:[0-9]+]]
ret void
}
-; CHECK-ENABLE: !6 = !{!"VP", i32 0, i64 6, i64 1311768467463790320, i64 1, i64 2541551405711093505, i64 1, i64 4660, i64 1, i64 9029, i64 1, i64 13398, i64 1, i64 17767, i64 1}
+; CHECK-ENABLE: ![[VP1]] = !{!"VP", i32 0, i64 6, i64 1311768467463790320, i64 1, i64 2541551405711093505, i64 1, i64 4660, i64 1, i64 9029, i64 1, i64 13398, i64 1, i64 17767, i64 1}
+;; The second call above gets a single target synthesized from the callee frame,
+;; to the GUID of _Z3xyzv, see comments in the profile above.
+; CHECK-ENABLE: ![[VP2]] = !{!"VP", i32 0, i64 1, i64 -3079258800046378528, i64 1}
!llvm.module.flags = !{!2, !3}
@@ -53,6 +69,7 @@ entry:
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 1, unit: !0)
!5 = !DILocation(line: 4, column: 5, scope: !4)
+!6 = !DILocation(line: 5, column: 10, scope: !4)
;--- fdo_conflict.yaml
---