Index: llvm/include/llvm/ProfileData/InstrProf.h =================================================================== --- llvm/include/llvm/ProfileData/InstrProf.h +++ llvm/include/llvm/ProfileData/InstrProf.h @@ -1143,8 +1143,8 @@ // Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime // aware this is an ir_level profile so it can set the version flag. -void createIRLevelProfileFlagVar(Module &M, bool IsCS, - bool InstrEntryBBEnabled); +GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS, + bool InstrEntryBBEnabled); // Create the variable for the profile file name. void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput); Index: llvm/lib/ProfileData/InstrProf.cpp =================================================================== --- llvm/lib/ProfileData/InstrProf.cpp +++ llvm/lib/ProfileData/InstrProf.cpp @@ -1098,10 +1098,14 @@ bool isIRPGOFlagSet(const Module *M) { auto IRInstrVar = M->getNamedGlobal(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR)); - if (!IRInstrVar || IRInstrVar->isDeclaration() || - IRInstrVar->hasLocalLinkage()) + if (!IRInstrVar || IRInstrVar->hasLocalLinkage()) return false; + // For CSPGO, this variable might be marked as non-prevailing and we only + // have the decl. + if (IRInstrVar->isDeclaration()) + return true; + // Check if the flag is set. if (!IRInstrVar->hasInitializer()) return false; @@ -1137,8 +1141,8 @@ // Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime // aware this is an ir_level profile so it can set the version flag. -void createIRLevelProfileFlagVar(Module &M, bool IsCS, - bool InstrEntryBBEnabled) { +GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS, + bool InstrEntryBBEnabled) { const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR)); Type *IntTy64 = Type::getInt64Ty(M.getContext()); uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF); @@ -1155,6 +1159,7 @@ IRLevelVersionVariable->setLinkage(GlobalValue::ExternalLinkage); IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName)); } + return IRLevelVersionVariable; } // Create the variable for the profile file name. Index: llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -110,6 +110,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include #include #include @@ -464,7 +465,8 @@ private: bool runOnModule(Module &M) override { createProfileFileNameVar(M, InstrProfileOutput); - createIRLevelProfileFlagVar(M, /* IsCS */ true, PGOInstrumentEntry); + appendToCompilerUsed( + M, createIRLevelProfileFlagVar(M, /* IsCS */ true, PGOInstrumentEntry)); return false; } std::string InstrProfileOutput; @@ -1632,7 +1634,8 @@ PreservedAnalyses PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &AM) { createProfileFileNameVar(M, CSInstrName); - createIRLevelProfileFlagVar(M, /* IsCS */ true, PGOInstrumentEntry); + appendToCompilerUsed( + M, createIRLevelProfileFlagVar(M, /* IsCS */ true, PGOInstrumentEntry)); return PreservedAnalyses::all(); } Index: llvm/test/Transforms/PGOProfile/lto_cspgo_gen.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PGOProfile/lto_cspgo_gen.ll @@ -0,0 +1,32 @@ +; REQUIRES: x86-registered-target + +; RUN: opt -passes='thinlto-pre-link' --cs-profilegen-file=alloc -cspgo-kind=cspgo-instr-gen-pipeline -module-summary %s -o %t.bc +; RUN: llvm-dis %t.bc -o - | FileCheck %s --check-prefix=IRPGOPRE + +; RUN: llvm-lto2 run -lto-cspgo-profile-file=alloc -lto-cspgo-gen -save-temps -o %t %t.bc \ +; RUN: -r=%t.bc,f,px \ +; RUN: -r=%t.bc,__llvm_profile_filename,x \ +; RUN: -r=%t.bc,__llvm_profile_raw_version,x +; RUN: llvm-dis %t.0.0.preopt.bc -o - | FileCheck %s --check-prefix=IRPGOBE + +; IRPGOPRE: @__llvm_profile_raw_version = constant i64 +; IRPGOBE: @__llvm_profile_raw_version = external constant i64 + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +$f = comdat any + +; Function Attrs: nofree norecurse nosync nounwind readnone uwtable willreturn mustprogress +define i32 @f() local_unnamed_addr #0 { +entry: + ret i32 1 +} + +attributes #0 = { "target-cpu"="x86-64" } + +!llvm.module.flags = !{!0, !1, !2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"uwtable", i32 1} +!2 = !{i32 1, !"ThinLTO", i32 0}