diff --git a/llvm/lib/Transforms/Utils/ProfileVerify.cpp b/llvm/lib/Transforms/Utils/ProfileVerify.cpp index c7cf8256d393c..ca6bd91b1f530 100644 --- a/llvm/lib/Transforms/Utils/ProfileVerify.cpp +++ b/llvm/lib/Transforms/Utils/ProfileVerify.cpp @@ -65,11 +65,26 @@ class ProfileInjector { ProfileInjector(Function &F, FunctionAnalysisManager &FAM) : F(F), FAM(FAM) {} bool inject(); }; + +bool isAsmOnly(const Function &F) { + if (!F.hasFnAttribute(Attribute::AttrKind::Naked)) + return false; + for (const auto &BB : F) + for (const auto &I : drop_end(BB.instructionsWithoutDebug())) { + const auto *CB = dyn_cast(&I); + if (!CB || !CB->isInlineAsm()) + return false; + } + return true; +} } // namespace // FIXME: currently this injects only for terminators. Select isn't yet // supported. bool ProfileInjector::inject() { + // skip purely asm functions + if (isAsmOnly(F)) + return false; // Get whatever branch probability info can be derived from the given IR - // whether it has or not metadata. The main intention for this pass is to // ensure that other passes don't drop or "forget" to update MD_prof. We do @@ -176,6 +191,10 @@ PreservedAnalyses ProfileInjectorPass::run(Function &F, PreservedAnalyses ProfileVerifierPass::run(Function &F, FunctionAnalysisManager &FAM) { + // skip purely asm functions + if (isAsmOnly(F)) + return PreservedAnalyses::all(); + const auto EntryCount = F.getEntryCount(/*AllowSynthetic=*/true); if (!EntryCount) { auto *MD = F.getMetadata(LLVMContext::MD_prof); diff --git a/llvm/test/Transforms/PGOProfile/profcheck-exclusions.ll b/llvm/test/Transforms/PGOProfile/profcheck-exclusions.ll new file mode 100644 index 0000000000000..a2420be4fac30 --- /dev/null +++ b/llvm/test/Transforms/PGOProfile/profcheck-exclusions.ll @@ -0,0 +1,10 @@ +; RUN: opt -passes=prof-inject %s -S -o - | FileCheck %s +; RUN: opt -passes=prof-verify %s --disable-output + + +define void @bar(i1 %c) #0 { + ret void +} + +attributes #0 = { naked } +; CHECK-NOT: !prof