[llvm] 4b42944 - [profcheck] Don't verify generated global ctors/dtors (#170597)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 4 13:01:51 PST 2025
Author: Mircea Trofin
Date: 2025-12-04T13:01:46-08:00
New Revision: 4b4294473280a8e37d818a9362e33544799cb4e4
URL: https://github.com/llvm/llvm-project/commit/4b4294473280a8e37d818a9362e33544799cb4e4
DIFF: https://github.com/llvm/llvm-project/commit/4b4294473280a8e37d818a9362e33544799cb4e4.diff
LOG: [profcheck] Don't verify generated global ctors/dtors (#170597)
Functions listed in `llvm.global_ctors` or `llvm.global_dtors` aren't too interesting for performance. Passes like LowerTypeTests synthesize some of these, and, while we could add a "0" entry count explicitly, we can also just not bother verifying in the first place.
Added:
llvm/test/Transforms/PGOProfile/profcheck-llvm.global_ctors.ll
Modified:
llvm/include/llvm/Transforms/Utils/ProfileVerify.h
llvm/lib/Passes/PassRegistry.def
llvm/lib/Transforms/Utils/ProfileVerify.cpp
llvm/test/Transforms/PGOProfile/prof-verify-known-cold.ll
llvm/test/Transforms/PGOProfile/prof-verify.ll
llvm/tools/opt/NewPMDriver.cpp
llvm/utils/profcheck-xfail.txt
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Utils/ProfileVerify.h b/llvm/include/llvm/Transforms/Utils/ProfileVerify.h
index 5c9c44c23bc01..bf953b529b80c 100644
--- a/llvm/include/llvm/Transforms/Utils/ProfileVerify.h
+++ b/llvm/include/llvm/Transforms/Utils/ProfileVerify.h
@@ -13,6 +13,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_PROFILEVERIFY_H
#define LLVM_TRANSFORMS_UTILS_PROFILEVERIFY_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/Analysis.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Compiler.h"
@@ -29,8 +30,15 @@ class ProfileInjectorPass : public PassInfoMixin<ProfileInjectorPass> {
/// in conjunction with the ProfileInjectorPass. MD_prof "unknown" is considered
/// valid (i.e. !{!"unknown"})
class ProfileVerifierPass : public PassInfoMixin<ProfileVerifierPass> {
+ DenseSet<const Function *> IgnoreList;
+ // This pass is mostly a function pass but we want to initialize the
+ // IngoreList once, which is why we present it as a module-level pass. We make
+ // the function-level run private to avoid accidentally hooking up the pass as
+ // a function pass.
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+
public:
- LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+ LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
};
} // namespace llvm
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index e9874ecd553ee..cf998f29ef38c 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -149,6 +149,7 @@ MODULE_PASS("print<ir2vec>", IR2VecPrinterPass(errs()))
MODULE_PASS("print<ir2vec-vocab>", IR2VecVocabPrinterPass(errs()))
MODULE_PASS("print<module-debuginfo>", ModuleDebugInfoPrinterPass(errs()))
MODULE_PASS("print<reg-usage>", PhysicalRegisterUsageInfoPrinterPass(errs()))
+MODULE_PASS("prof-verify", ProfileVerifierPass())
MODULE_PASS("pseudo-probe", SampleProfileProbePass(TM))
MODULE_PASS("pseudo-probe-update", PseudoProbeUpdatePass())
MODULE_PASS("recompute-globalsaa", RecomputeGlobalsAAPass())
@@ -526,7 +527,6 @@ FUNCTION_PASS("print<scev-division>", SCEVDivisionPrinterPass(errs()))
FUNCTION_PASS("print<stack-safety-local>", StackSafetyPrinterPass(errs()))
FUNCTION_PASS("print<uniformity>", UniformityInfoPrinterPass(errs()))
FUNCTION_PASS("prof-inject", ProfileInjectorPass())
-FUNCTION_PASS("prof-verify", ProfileVerifierPass())
FUNCTION_PASS("reassociate", ReassociatePass())
FUNCTION_PASS("redundant-dbg-inst-elim", RedundantDbgInstEliminationPass())
FUNCTION_PASS("replace-with-veclib", ReplaceWithVeclib())
diff --git a/llvm/lib/Transforms/Utils/ProfileVerify.cpp b/llvm/lib/Transforms/Utils/ProfileVerify.cpp
index ca6bd91b1f530..69e03f01245db 100644
--- a/llvm/lib/Transforms/Utils/ProfileVerify.cpp
+++ b/llvm/lib/Transforms/Utils/ProfileVerify.cpp
@@ -11,13 +11,19 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/IR/Analysis.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/ProfDataUtils.h"
#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
@@ -189,11 +195,43 @@ PreservedAnalyses ProfileInjectorPass::run(Function &F,
return PreservedAnalyses::none();
}
+PreservedAnalyses ProfileVerifierPass::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+ auto PopulateIgnoreList = [&](StringRef GVName) {
+ if (const auto *CT = M.getGlobalVariable(GVName))
+ if (const auto *CA =
+ dyn_cast_if_present<ConstantArray>(CT->getInitializer()))
+ for (const auto &Elt : CA->operands())
+ if (const auto *CS = dyn_cast<ConstantStruct>(Elt))
+ if (CS->getNumOperands() >= 2 && CS->getOperand(1))
+ if (const auto *F = dyn_cast<Function>(
+ CS->getOperand(1)->stripPointerCasts()))
+ IgnoreList.insert(F);
+ };
+ PopulateIgnoreList("llvm.global_ctors");
+ PopulateIgnoreList("llvm.global_dtors");
+
+ // expose the function-level run as public through a wrapper, so we can use
+ // pass manager mechanisms dealing with declarations and with composing the
+ // returned PreservedAnalyses values.
+ struct Wrapper : PassInfoMixin<Wrapper> {
+ ProfileVerifierPass &PVP;
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
+ return PVP.run(F, FAM);
+ }
+ explicit Wrapper(ProfileVerifierPass &PVP) : PVP(PVP) {}
+ };
+
+ return createModuleToFunctionPassAdaptor(Wrapper(*this)).run(M, MAM);
+}
+
PreservedAnalyses ProfileVerifierPass::run(Function &F,
FunctionAnalysisManager &FAM) {
// skip purely asm functions
if (isAsmOnly(F))
return PreservedAnalyses::all();
+ if (IgnoreList.contains(&F))
+ return PreservedAnalyses::all();
const auto EntryCount = F.getEntryCount(/*AllowSynthetic=*/true);
if (!EntryCount) {
diff --git a/llvm/test/Transforms/PGOProfile/prof-verify-known-cold.ll b/llvm/test/Transforms/PGOProfile/prof-verify-known-cold.ll
index 7875300006761..9fa2732fbc6b5 100644
--- a/llvm/test/Transforms/PGOProfile/prof-verify-known-cold.ll
+++ b/llvm/test/Transforms/PGOProfile/prof-verify-known-cold.ll
@@ -1,6 +1,6 @@
; Test prof-verify for functions explicitly marked as cold
-; RUN: opt -passes=prof-inject,prof-verify %s -o - 2>&1 | FileCheck %s
+; RUN: opt -passes=function(prof-inject),module(prof-verify) %s -o - 2>&1 | FileCheck %s
define void @foo(i32 %i) !prof !0 {
%c = icmp eq i32 %i, 0
diff --git a/llvm/test/Transforms/PGOProfile/prof-verify.ll b/llvm/test/Transforms/PGOProfile/prof-verify.ll
index 75d1e6a3db571..90a20b68ab23c 100644
--- a/llvm/test/Transforms/PGOProfile/prof-verify.ll
+++ b/llvm/test/Transforms/PGOProfile/prof-verify.ll
@@ -6,7 +6,7 @@
; RUN: opt -passes=prof-inject %s -S -o - | FileCheck %s --check-prefix=INJECT
; RUN: not opt -passes=prof-verify %s -S -o - 2>&1 | FileCheck %s --check-prefix=VERIFY
-; RUN: opt -passes=prof-inject,prof-verify %s --disable-output
+; RUN: opt -passes=function(prof-inject),module(prof-verify) %s --disable-output
; RUN: opt -enable-profcheck %s -S -o - | FileCheck %s --check-prefix=INJECT
define void @foo(i32 %i) !prof !0 {
diff --git a/llvm/test/Transforms/PGOProfile/profcheck-llvm.global_ctors.ll b/llvm/test/Transforms/PGOProfile/profcheck-llvm.global_ctors.ll
new file mode 100644
index 0000000000000..84c680fc158ac
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/profcheck-llvm.global_ctors.ll
@@ -0,0 +1,13 @@
+; RUN: opt -passes=prof-verify %s -o - 2>&1 | FileCheck %s
+ at llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @ctor, ptr null }]
+ at llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @dtor, ptr null }]
+
+define internal void @ctor() {
+ ret void
+}
+
+define internal void @dtor() {
+ ret void
+}
+
+; CHECK-NOT: Profile verification failed: function entry count missing
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index 3209b652b44b4..eaa1d8f958a4d 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -520,7 +520,7 @@ bool llvm::runPassPipeline(
false, "", nullptr, DebugifyMode::OriginalDebugInfo,
&DebugInfoBeforePass, VerifyDIPreserveExport));
if (EnableProfcheck)
- MPM.addPass(createModuleToFunctionPassAdaptor(ProfileVerifierPass()));
+ MPM.addPass(ProfileVerifierPass());
// Add any relevant output pass at the end of the pipeline.
switch (OK) {
diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt
index 980f99687c4cc..3cde50de7d0c1 100644
--- a/llvm/utils/profcheck-xfail.txt
+++ b/llvm/utils/profcheck-xfail.txt
@@ -20,7 +20,6 @@ CodeGen/X86/masked_gather_scatter.ll
DebugInfo/AArch64/ir-outliner.ll
DebugInfo/assignment-tracking/X86/hotcoldsplit.ll
DebugInfo/Generic/block-asan.ll
-DebugInfo/X86/asan_debug_info.ll
LTO/X86/diagnostic-handler-remarks-with-hotness.ll
Other/optimization-remarks-auto.ll
Transforms/AtomicExpand/ARM/atomic-expansion-v7.ll
@@ -475,10 +474,6 @@ Transforms/LowerConstantIntrinsics/objectsize_basic.ll
Transforms/LowerGlobalDestructors/lower-global-dtors-existing-dos_handle.ll
Transforms/LowerGlobalDestructors/lower-global-dtors.ll
Transforms/LowerGlobalDestructors/non-literal-type.ll
-Transforms/LowerIFunc/ifunc-alias.ll
-Transforms/LowerIFunc/ifunc-nonsense-resolvers.ll
-Transforms/LowerIFunc/ifunc-program-addrspace.ll
-Transforms/LowerIFunc/lower-ifunc.ll
Transforms/LowerMatrixIntrinsics/data-layout-multiply-fused.ll
Transforms/LowerMatrixIntrinsics/multiply-fused-dominance.ll
Transforms/LowerMatrixIntrinsics/multiply-fused.ll
@@ -498,9 +493,6 @@ Transforms/LowerSwitch/do-not-handle-impossible-values.ll
Transforms/LowerSwitch/feature.ll
Transforms/LowerSwitch/fold-popular-case-to-unreachable-default.ll
Transforms/LowerSwitch/pr59316.ll
-Transforms/LowerTypeTests/cfi-coff-comdat-rename.ll
-Transforms/LowerTypeTests/function.ll
-Transforms/LowerTypeTests/function-weak.ll
Transforms/LowerTypeTests/import.ll
Transforms/LowerTypeTests/simple.ll
Transforms/MergeFunc/2011-02-08-RemoveEqual.ll
More information about the llvm-commits
mailing list