diff --git a/llvm/lib/IR/StructuralHash.cpp b/llvm/lib/IR/StructuralHash.cpp --- a/llvm/lib/IR/StructuralHash.cpp +++ b/llvm/lib/IR/StructuralHash.cpp @@ -60,8 +60,7 @@ void update(const GlobalVariable &GV) { // used/compiler.used don't affect analyses. // Same for llvm.embedded.object, which is always a metadata section. - if (GV.getName() == "llvm.compiler.used" || GV.getName() == "llvm.used" || - GV.getName() == "llvm.embedded.object") + if (GV.getName().starts_with("llvm.")) return; hash(23456); // Global header hash(GV.getValueType()->getTypeID()); diff --git a/llvm/unittests/IR/PassManagerTest.cpp b/llvm/unittests/IR/PassManagerTest.cpp --- a/llvm/unittests/IR/PassManagerTest.cpp +++ b/llvm/unittests/IR/PassManagerTest.cpp @@ -10,6 +10,7 @@ #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/AsmParser/Parser.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/LLVMContext.h" @@ -18,6 +19,7 @@ #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Transforms/Scalar/SimplifyCFG.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include "gtest/gtest.h" using namespace llvm; @@ -1070,5 +1072,44 @@ "Module changed by WrongModulePass2 without invalidating analyses"); } +struct InsertMetadataPass : PassInfoMixin { + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) { + StringRef Data = "foo"; + MemoryBufferRef Buf(Data, "ModuleData"); + Constant *ModuleConstant = ConstantDataArray::get( + M.getContext(), ArrayRef(Buf.getBufferStart(), Buf.getBufferSize())); + GlobalVariable *GV = new GlobalVariable( + M, ModuleConstant->getType(), true, GlobalValue::PrivateLinkage, + ModuleConstant, "llvm.foo"); + appendToCompilerUsed(M, GV); + return PreservedAnalyses::all(); + } + static StringRef name() { return "InsertMetadataPass"; } +}; + +TEST_F(PassManagerTest, ModulePassNoAnalysisInvalidation) { + LLVMContext Context; + auto M = parseIR(Context, "define void @foo() {\n" + " %a = add i32 0, 0\n" + " ret void\n" + "}\n"); + + FunctionAnalysisManager FAM; + ModuleAnalysisManager MAM; + PassInstrumentationCallbacks PIC; + StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ false); + SI.registerCallbacks(PIC, &MAM); + MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); + MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); + FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); + FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); + + ModulePassManager MPM; + MPM.addPass(InsertMetadataPass()); + EXPECT_TRUE(MPM.run(*M, MAM).areAllPreserved()); + +} + + #endif }