Index: lib/IR/Metadata.cpp =================================================================== --- lib/IR/Metadata.cpp +++ lib/IR/Metadata.cpp @@ -1337,17 +1337,26 @@ return false; auto *ProfDataName = dyn_cast(ProfileData->getOperand(0)); - if (!ProfDataName || !ProfDataName->getString().equals("branch_weights")) + if (!ProfDataName) return false; - TotalVal = 0; - for (unsigned i = 1; i < ProfileData->getNumOperands(); i++) { - auto *V = mdconst::dyn_extract(ProfileData->getOperand(i)); - if (!V) - return false; - TotalVal += V->getValue().getZExtValue(); + if (ProfDataName->getString().equals("branch_weights")) { + TotalVal = 0; + for (unsigned i = 1; i < ProfileData->getNumOperands(); i++) { + auto *V = mdconst::dyn_extract(ProfileData->getOperand(i)); + if (!V) + return false; + TotalVal += V->getValue().getZExtValue(); + } + return true; + } else if (ProfDataName->getString().equals("VP") && + ProfileData->getNumOperands() > 3) { + TotalVal = mdconst::dyn_extract(ProfileData->getOperand(2)) + ->getValue() + .getZExtValue(); + return true; } - return true; + return false; } void Instruction::clearMetadataHashEntries() { Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -4143,6 +4143,12 @@ CallInst *CI = cast(Caller); NC = Builder->CreateCall(Callee, Args, OpBundles); NC->takeName(CI); + // Preserve the weight metadata for the new call instruction. The metadata + // is used by SamplePGO to check callsite's hotness. + uint64_t W; + if (CI->extractProfTotalWeight(W)) + NC->setProfWeight(W); + cast(NC)->setTailCallKind(CI->getTailCallKind()); cast(NC)->setCallingConv(CI->getCallingConv()); cast(NC)->setAttributes(NewCallerPAL); Index: test/Transforms/InstCombine/cast-call-combine-prof.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/cast-call-combine-prof.ll @@ -0,0 +1,38 @@ +; RUN: opt -instcombine -inline -S -inline-threshold=0 -hot-callsite-threshold=100 < %s | FileCheck %s +; Checks if VP profile is used for hotness checks in inlining after instcombine +; converted the call to a direct call. + +declare void @bar(i16 *) + +define void @foo(i16* %a) { + call void @bar(i16* %a) + call void @bar(i16* %a) + ret void +} + +; CHECK-LABEL: @test() +; CHECK-NEXT: call void @bar +; CHECK-NEXT: call void @bar +define void @test() { + call void bitcast (void (i16*)* @foo to void (i8*)*) (i8* null), !prof !0 + ret void +} + +!0 = !{!"VP", i32 0, i64 2000, i64 -3913987384944532146, i64 2000} + +!llvm.module.flags = !{!1} + +!1 = !{i32 1, !"ProfileSummary", !2} +!2 = !{!3, !4, !5, !6, !7, !8, !9, !10} +!3 = !{!"ProfileFormat", !"InstrProf"} +!4 = !{!"TotalCount", i64 10000} +!5 = !{!"MaxCount", i64 1000} +!6 = !{!"MaxInternalCount", i64 1} +!7 = !{!"MaxFunctionCount", i64 1000} +!8 = !{!"NumCounts", i64 3} +!9 = !{!"NumFunctions", i64 3} +!10 = !{!"DetailedSummary", !11} +!11 = !{!12, !13, !14} +!12 = !{i32 10000, i64 1000, i32 1} +!13 = !{i32 999000, i64 1000, i32 1} +!14 = !{i32 999999, i64 1, i32 2}