[llvm] [BOLT] Add support for safe-icf (PR #116275)
Alexander Yermolovich via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 13 11:47:39 PST 2024
https://github.com/ayermolo updated https://github.com/llvm/llvm-project/pull/116275
>From 03ca42cce937fc7a85104e80fc271095e998b472 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Mon, 11 Nov 2024 19:19:02 -0800
Subject: [PATCH 01/34] safe-icf
Summary:
Test Plan:
Reviewers:
Subscribers:
Tasks:
Tags:
Differential Revision: https://phabricator.intern.facebook.com/D65799965
---
bolt/include/bolt/Core/BinaryContext.h | 9 +
bolt/include/bolt/Core/BinaryFunction.h | 9 +
.../bolt/Passes/IdenticalCodeFolding.h | 14 +-
bolt/lib/Core/BinaryContext.cpp | 86 +++++
bolt/lib/Core/BinaryFunction.cpp | 2 +
bolt/lib/Passes/IdenticalCodeFolding.cpp | 85 +++-
bolt/lib/Rewrite/BinaryPassManager.cpp | 15 +-
bolt/lib/Rewrite/BoltDiff.cpp | 3 +-
bolt/lib/Rewrite/RewriteInstance.cpp | 64 +--
bolt/test/X86/Inputs/helperSafeICF.s | 39 ++
bolt/test/X86/Inputs/helperSafeICFICPTest.s | 40 ++
bolt/test/X86/Inputs/mainSafeICFICPTest.s | 331 ++++++++++++++++
bolt/test/X86/Inputs/mainSafeICFTest1.s | 345 +++++++++++++++++
.../X86/Inputs/mainSafeICFTest2GlobalVarO0.s | 363 ++++++++++++++++++
.../X86/Inputs/mainSafeICFTest2GlobalVarO3.s | 293 ++++++++++++++
.../X86/Inputs/mainSafeICFTest3LocalVarO0.s | 359 +++++++++++++++++
.../X86/Inputs/mainSafeICFTest3LocalVarO3.s | 286 ++++++++++++++
bolt/test/X86/icf-safe-icp.test | 20 +
bolt/test/X86/icf-safe-test1-no-cfg.test | 21 +
bolt/test/X86/icf-safe-test1-no-relocs.test | 16 +
bolt/test/X86/icf-safe-test1.test | 21 +
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 21 +
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 21 +
bolt/test/X86/icf-safe-test3LocalVarO0.test | 21 +
bolt/test/X86/icf-safe-test3LocalVarO3.test | 21 +
25 files changed, 2431 insertions(+), 74 deletions(-)
create mode 100644 bolt/test/X86/Inputs/helperSafeICF.s
create mode 100644 bolt/test/X86/Inputs/helperSafeICFICPTest.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFICPTest.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFTest1.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
create mode 100644 bolt/test/X86/icf-safe-icp.test
create mode 100644 bolt/test/X86/icf-safe-test1-no-cfg.test
create mode 100644 bolt/test/X86/icf-safe-test1-no-relocs.test
create mode 100644 bolt/test/X86/icf-safe-test1.test
create mode 100644 bolt/test/X86/icf-safe-test2GlobalVarO0.test
create mode 100644 bolt/test/X86/icf-safe-test2GlobalVarO3.test
create mode 100644 bolt/test/X86/icf-safe-test3LocalVarO0.test
create mode 100644 bolt/test/X86/icf-safe-test3LocalVarO3.test
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 08ce892054874c..92889ffe162ae1 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -282,6 +282,12 @@ class BinaryContext {
std::unique_ptr<DWARFContext> DwCtx,
JournalingStreams Logger);
+ /// Returns addend of a relocation.
+ static int64_t getRelocationAddend(const ELFObjectFileBase *Obj,
+ const RelocationRef &Rel);
+ /// Returns symbol of a relocation.
+ static uint32_t getRelocationSymbol(const ELFObjectFileBase *Obj,
+ const RelocationRef &Rel);
/// Superset of compiler units that will contain overwritten code that needs
/// new debug info. In a few cases, functions may end up not being
/// overwritten, but it is okay to re-generate debug info for them.
@@ -1350,6 +1356,9 @@ class BinaryContext {
return Code.size();
}
+ /// Processes .text section to identify function references.
+ void processInstructionForFuncReferences(const MCInst &Inst);
+
/// Compute the native code size for a range of instructions.
/// Note: this can be imprecise wrt the final binary since happening prior to
/// relaxation, as well as wrt the original binary because of opcode
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index 0b3682353f736e..5e1ddcc6bff9a2 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -428,6 +428,9 @@ class BinaryFunction {
/// Function order for streaming into the destination binary.
uint32_t Index{-1U};
+ /// Indicates if the function is safe to fold.
+ bool IsSafeToICF{true};
+
/// Get basic block index assuming it belongs to this function.
unsigned getIndex(const BinaryBasicBlock *BB) const {
assert(BB->getIndex() < BasicBlocks.size());
@@ -817,6 +820,12 @@ class BinaryFunction {
return nullptr;
}
+ /// Indicates if the function is safe to fold.
+ bool isSafeToICF() const { return IsSafeToICF; }
+
+ /// Sets the function is not safe to fold.
+ void setUnsetToICF() { IsSafeToICF = false; }
+
/// Returns the raw binary encoding of this function.
ErrorOr<ArrayRef<uint8_t>> getData() const;
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index b4206fa3607445..75d5f19ddfc7be 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -31,11 +31,21 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
}
public:
- explicit IdenticalCodeFolding(const cl::opt<bool> &PrintPass)
- : BinaryFunctionPass(PrintPass) {}
+ explicit IdenticalCodeFolding(const cl::opt<bool> &PrintPass, bool IsSafeICF)
+ : BinaryFunctionPass(PrintPass), IsSafeICF(IsSafeICF) {}
const char *getName() const override { return "identical-code-folding"; }
Error runOnFunctions(BinaryContext &BC) override;
+
+private:
+ /// Create a skip list of functions that should not be folded.
+ Error createFoldSkipList(BinaryContext &BC);
+ /// Processes relocations in the .data section to identify function
+ /// references.
+ void processDataRelocations(BinaryContext &BC,
+ const SectionRef &SecRefRelData);
+
+ bool IsSafeICF;
};
} // namespace bolt
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index f246750209d6c4..31352bed6fdab7 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -75,8 +75,63 @@ cl::opt<std::string> CompDirOverride(
"location, which is used with DW_AT_dwo_name to construct a path "
"to *.dwo files."),
cl::Hidden, cl::init(""), cl::cat(BoltCategory));
+
+cl::opt<bool> ICF("icf", cl::desc("fold functions with identical code"),
+ cl::cat(BoltOptCategory));
+
+cl::opt<bool> SafeICF("safe-icf",
+ cl::desc("Enable safe identical code folding"),
+ cl::cat(BoltOptCategory));
} // namespace opts
+namespace {
+template <typename ELFT>
+int64_t getRelocationAddend(const ELFObjectFile<ELFT> *Obj,
+ const RelocationRef &RelRef) {
+ using ELFShdrTy = typename ELFT::Shdr;
+ using Elf_Rela = typename ELFT::Rela;
+ int64_t Addend = 0;
+ const ELFFile<ELFT> &EF = Obj->getELFFile();
+ DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
+ switch (RelocationSection->sh_type) {
+ default:
+ llvm_unreachable("unexpected relocation section type");
+ case ELF::SHT_REL:
+ break;
+ case ELF::SHT_RELA: {
+ const Elf_Rela *RelA = Obj->getRela(Rel);
+ Addend = RelA->r_addend;
+ break;
+ }
+ }
+
+ return Addend;
+}
+
+template <typename ELFT>
+uint32_t getRelocationSymbol(const ELFObjectFile<ELFT> *Obj,
+ const RelocationRef &RelRef) {
+ using ELFShdrTy = typename ELFT::Shdr;
+ uint32_t Symbol = 0;
+ const ELFFile<ELFT> &EF = Obj->getELFFile();
+ DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
+ switch (RelocationSection->sh_type) {
+ default:
+ llvm_unreachable("unexpected relocation section type");
+ case ELF::SHT_REL:
+ Symbol = Obj->getRel(Rel)->getSymbol(EF.isMips64EL());
+ break;
+ case ELF::SHT_RELA:
+ Symbol = Obj->getRela(Rel)->getSymbol(EF.isMips64EL());
+ break;
+ }
+
+ return Symbol;
+}
+} // anonymous namespace
+
namespace llvm {
namespace bolt {
@@ -156,6 +211,16 @@ BinaryContext::~BinaryContext() {
clearBinaryData();
}
+uint32_t BinaryContext::getRelocationSymbol(const ELFObjectFileBase *Obj,
+ const RelocationRef &Rel) {
+ return ::getRelocationSymbol(cast<ELF64LEObjectFile>(Obj), Rel);
+}
+
+int64_t BinaryContext::getRelocationAddend(const ELFObjectFileBase *Obj,
+ const RelocationRef &Rel) {
+ return ::getRelocationAddend(cast<ELF64LEObjectFile>(Obj), Rel);
+}
+
/// Create BinaryContext for a given architecture \p ArchName and
/// triple \p TripleName.
Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
@@ -1945,6 +2010,27 @@ static void printDebugInfo(raw_ostream &OS, const MCInst &Instruction,
OS << " discriminator:" << Row.Discriminator;
}
+static bool skipInstruction(const MCInst &Inst, const BinaryContext &BC) {
+ const bool IsX86 = BC.isX86();
+ return (BC.MIB->isPseudo(Inst) || BC.MIB->isUnconditionalBranch(Inst) ||
+ (IsX86 && BC.MIB->isConditionalBranch(Inst)) ||
+ BC.MIB->isCall(Inst) || BC.MIB->isBranch(Inst));
+}
+void BinaryContext::processInstructionForFuncReferences(const MCInst &Inst) {
+ if (!opts::SafeICF || skipInstruction(Inst, *this))
+ return;
+ for (const MCOperand &Op : MCPlus::primeOperands(Inst)) {
+ if (Op.isExpr()) {
+ const MCExpr &Expr = *Op.getExpr();
+ if (Expr.getKind() == MCExpr::SymbolRef) {
+ const MCSymbol &Symbol = cast<MCSymbolRefExpr>(Expr).getSymbol();
+ if (BinaryFunction *BF = getFunctionForSymbol(&Symbol))
+ BF->setUnsetToICF();
+ }
+ }
+ }
+}
+
void BinaryContext::printInstruction(raw_ostream &OS, const MCInst &Instruction,
uint64_t Offset,
const BinaryFunction *Function,
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index c12217d549479b..07d386efb26ec5 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1626,6 +1626,8 @@ bool BinaryFunction::scanExternalRefs() {
if (!BC.HasRelocations)
continue;
+ BC.processInstructionForFuncReferences(Instruction);
+
if (BranchTargetSymbol) {
BC.MIB->replaceBranchTarget(Instruction, BranchTargetSymbol,
Emitter.LocalCtx.get());
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 38e080c9dd6213..f09482dc08c212 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -11,8 +11,10 @@
//===----------------------------------------------------------------------===//
#include "bolt/Passes/IdenticalCodeFolding.h"
+#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/HashUtilities.h"
#include "bolt/Core/ParallelUtilities.h"
+#include "bolt/Rewrite/RewriteInstance.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ThreadPool.h"
@@ -31,6 +33,7 @@ using namespace bolt;
namespace opts {
extern cl::OptionCategory BoltOptCategory;
+extern cl::opt<unsigned> Verbosity;
static cl::opt<bool>
ICFUseDFS("icf-dfs", cl::desc("use DFS ordering when using -icf option"),
@@ -341,6 +344,75 @@ typedef std::unordered_map<BinaryFunction *, std::vector<BinaryFunction *>,
namespace llvm {
namespace bolt {
+void IdenticalCodeFolding::processDataRelocations(
+ BinaryContext &BC, const SectionRef &SecRefRelData) {
+ for (const RelocationRef &Rel : SecRefRelData.relocations()) {
+ symbol_iterator SymbolIter = Rel.getSymbol();
+ const ObjectFile *OwningObj = Rel.getObject();
+ assert(SymbolIter != OwningObj->symbol_end() &&
+ "relocation Symbol expected");
+ const SymbolRef &Symbol = *SymbolIter;
+ const uint64_t SymbolAddress = cantFail(Symbol.getAddress());
+ const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(OwningObj);
+ if (!ELFObj)
+ assert(false && "Only ELFObjectFileBase is supported");
+ const int64_t Addend = BinaryContext::getRelocationAddend(ELFObj, Rel);
+ BinaryFunction *BF = BC.getBinaryFunctionAtAddress(SymbolAddress + Addend);
+ if (!BF)
+ continue;
+ BF->setUnsetToICF();
+ }
+}
+
+Error IdenticalCodeFolding::createFoldSkipList(BinaryContext &BC) {
+ Error ErrorStatus = Error::success();
+ ErrorOr<BinarySection &> SecRelData = BC.getUniqueSectionByName(".rela.data");
+ if (!BC.HasRelocations)
+ ErrorStatus = joinErrors(
+ std::move(ErrorStatus),
+ createFatalBOLTError(Twine("BOLT-ERROR: Binary built without "
+ "relocations. Safe ICF is not supported")));
+ if (ErrorStatus)
+ return ErrorStatus;
+ if (SecRelData) {
+ SectionRef SecRefRelData = SecRelData->getSectionRef();
+ processDataRelocations(BC, SecRefRelData);
+ }
+
+ ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
+ if (BF.getState() == BinaryFunction::State::CFG) {
+ for (const BinaryBasicBlock *BB : BF.getLayout().blocks())
+ for (const MCInst &Inst : *BB)
+ BC.processInstructionForFuncReferences(Inst);
+ }
+ };
+ ParallelUtilities::PredicateTy SkipFunc =
+ [&](const BinaryFunction &BF) -> bool { return (bool)ErrorStatus; };
+ ParallelUtilities::runOnEachFunction(
+ BC, ParallelUtilities::SchedulingPolicy::SP_TRIVIAL, WorkFun, SkipFunc,
+ "markUnsafe", /*ForceSequential*/ false, 2);
+
+ LLVM_DEBUG({
+ std::vector<StringRef> Vect;
+ std::mutex PrintMutex;
+ ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
+ if (BF.isSafeToICF())
+ return;
+ std::lock_guard<std::mutex> Lock(PrintMutex);
+ Vect.push_back(BF.getOneName());
+ };
+ ParallelUtilities::PredicateTy SkipFunc =
+ [&](const BinaryFunction &BF) -> bool { return false; };
+ ParallelUtilities::runOnEachFunction(
+ BC, ParallelUtilities::SchedulingPolicy::SP_TRIVIAL, WorkFun, SkipFunc,
+ "markUnsafe", /*ForceSequential*/ false, 2);
+ llvm::sort(Vect);
+ for (const auto &FuncName : Vect)
+ dbgs() << "BOLT-DEBUG: skipping function " << FuncName << '\n';
+ });
+ return ErrorStatus;
+}
+
Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
const size_t OriginalFunctionCount = BC.getBinaryFunctions().size();
uint64_t NumFunctionsFolded = 0;
@@ -350,6 +422,9 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
std::atomic<uint64_t> NumFoldedLastIteration{0};
CongruentBucketsMap CongruentBuckets;
+ auto SkipFuncShared = [&](const BinaryFunction &BF) {
+ return !shouldOptimize(BF) || !BF.isSafeToICF();
+ };
// Hash all the functions
auto hashFunctions = [&]() {
NamedRegionTimer HashFunctionsTimer("hashing", "hashing", "ICF breakdown",
@@ -369,7 +444,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
};
ParallelUtilities::PredicateTy SkipFunc = [&](const BinaryFunction &BF) {
- return !shouldOptimize(BF);
+ return SkipFuncShared(BF);
};
ParallelUtilities::runOnEachFunction(
@@ -385,7 +460,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
"ICF breakdown", opts::TimeICF);
for (auto &BFI : BC.getBinaryFunctions()) {
BinaryFunction &BF = BFI.second;
- if (!this->shouldOptimize(BF))
+ if (SkipFuncShared(BF))
continue;
CongruentBuckets[&BF].emplace(&BF);
}
@@ -475,7 +550,11 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
LLVM_DEBUG(SinglePass.stopTimer());
};
-
+ if (IsSafeICF) {
+ if (Error Err = createFoldSkipList(BC)) {
+ return Err;
+ }
+ }
hashFunctions();
createCongruentBuckets();
diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp
index b0906041833484..df612c0a8f2e51 100644
--- a/bolt/lib/Rewrite/BinaryPassManager.cpp
+++ b/bolt/lib/Rewrite/BinaryPassManager.cpp
@@ -54,6 +54,8 @@ extern cl::opt<bool> PrintDynoStats;
extern cl::opt<bool> DumpDotAll;
extern cl::opt<std::string> AsmDump;
extern cl::opt<bolt::PLTCall::OptType> PLT;
+extern cl::opt<bool> ICF;
+extern cl::opt<bool> SafeICF;
static cl::opt<bool>
DynoStatsAll("dyno-stats-all",
@@ -65,9 +67,6 @@ static cl::opt<bool>
cl::desc("eliminate unreachable code"), cl::init(true),
cl::cat(BoltOptCategory));
-cl::opt<bool> ICF("icf", cl::desc("fold functions with identical code"),
- cl::cat(BoltOptCategory));
-
static cl::opt<bool> JTFootprintReductionFlag(
"jt-footprint-reduction",
cl::desc("make jump tables size smaller at the cost of using more "
@@ -397,8 +396,9 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
Manager.registerPass(std::make_unique<StripRepRet>(NeverPrint),
opts::StripRepRet);
- Manager.registerPass(std::make_unique<IdenticalCodeFolding>(PrintICF),
- opts::ICF);
+ Manager.registerPass(
+ std::make_unique<IdenticalCodeFolding>(PrintICF, opts::SafeICF),
+ opts::ICF || opts::SafeICF);
Manager.registerPass(
std::make_unique<SpecializeMemcpy1>(NeverPrint, opts::SpecializeMemcpy1),
@@ -422,8 +422,9 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
Manager.registerPass(std::make_unique<Inliner>(PrintInline));
- Manager.registerPass(std::make_unique<IdenticalCodeFolding>(PrintICF),
- opts::ICF);
+ Manager.registerPass(
+ std::make_unique<IdenticalCodeFolding>(PrintICF, opts::SafeICF),
+ opts::ICF || opts::SafeICF);
Manager.registerPass(std::make_unique<PLTCall>(PrintPLT));
diff --git a/bolt/lib/Rewrite/BoltDiff.cpp b/bolt/lib/Rewrite/BoltDiff.cpp
index 74b5ca18abce42..1a8eb5cd2ce39d 100644
--- a/bolt/lib/Rewrite/BoltDiff.cpp
+++ b/bolt/lib/Rewrite/BoltDiff.cpp
@@ -29,6 +29,7 @@ namespace opts {
extern cl::OptionCategory BoltDiffCategory;
extern cl::opt<bool> NeverPrint;
extern cl::opt<bool> ICF;
+extern cl::opt<bool> SafeICF;
static cl::opt<bool> IgnoreLTOSuffix(
"ignore-lto-suffix",
@@ -698,7 +699,7 @@ void RewriteInstance::compare(RewriteInstance &RI2) {
// Pre-pass ICF
if (opts::ICF) {
- IdenticalCodeFolding ICF(opts::NeverPrint);
+ IdenticalCodeFolding ICF(opts::NeverPrint, opts::SafeICF);
outs() << "BOLT-DIFF: Starting ICF pass for binary 1";
BC->logBOLTErrorsAndQuitOnFatal(ICF.runOnFunctions(*BC));
outs() << "BOLT-DIFF: Starting ICF pass for binary 2";
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index a4c50cbc3e2bbf..70c9eeef3cdc57 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2111,64 +2111,6 @@ void RewriteInstance::adjustCommandLineOptions() {
}
}
-namespace {
-template <typename ELFT>
-int64_t getRelocationAddend(const ELFObjectFile<ELFT> *Obj,
- const RelocationRef &RelRef) {
- using ELFShdrTy = typename ELFT::Shdr;
- using Elf_Rela = typename ELFT::Rela;
- int64_t Addend = 0;
- const ELFFile<ELFT> &EF = Obj->getELFFile();
- DataRefImpl Rel = RelRef.getRawDataRefImpl();
- const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
- switch (RelocationSection->sh_type) {
- default:
- llvm_unreachable("unexpected relocation section type");
- case ELF::SHT_REL:
- break;
- case ELF::SHT_RELA: {
- const Elf_Rela *RelA = Obj->getRela(Rel);
- Addend = RelA->r_addend;
- break;
- }
- }
-
- return Addend;
-}
-
-int64_t getRelocationAddend(const ELFObjectFileBase *Obj,
- const RelocationRef &Rel) {
- return getRelocationAddend(cast<ELF64LEObjectFile>(Obj), Rel);
-}
-
-template <typename ELFT>
-uint32_t getRelocationSymbol(const ELFObjectFile<ELFT> *Obj,
- const RelocationRef &RelRef) {
- using ELFShdrTy = typename ELFT::Shdr;
- uint32_t Symbol = 0;
- const ELFFile<ELFT> &EF = Obj->getELFFile();
- DataRefImpl Rel = RelRef.getRawDataRefImpl();
- const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
- switch (RelocationSection->sh_type) {
- default:
- llvm_unreachable("unexpected relocation section type");
- case ELF::SHT_REL:
- Symbol = Obj->getRel(Rel)->getSymbol(EF.isMips64EL());
- break;
- case ELF::SHT_RELA:
- Symbol = Obj->getRela(Rel)->getSymbol(EF.isMips64EL());
- break;
- }
-
- return Symbol;
-}
-
-uint32_t getRelocationSymbol(const ELFObjectFileBase *Obj,
- const RelocationRef &Rel) {
- return getRelocationSymbol(cast<ELF64LEObjectFile>(Obj), Rel);
-}
-} // anonymous namespace
-
bool RewriteInstance::analyzeRelocation(
const RelocationRef &Rel, uint64_t &RType, std::string &SymbolName,
bool &IsSectionRelocation, uint64_t &SymbolAddress, int64_t &Addend,
@@ -2196,7 +2138,7 @@ bool RewriteInstance::analyzeRelocation(
return true;
ExtractedValue = Relocation::extractValue(RType, *Value, Rel.getOffset());
- Addend = getRelocationAddend(InputFile, Rel);
+ Addend = BinaryContext::getRelocationAddend(InputFile, Rel);
const bool IsPCRelative = Relocation::isPCRelative(RType);
const uint64_t PCRelOffset = IsPCRelative && !IsAArch64 ? Rel.getOffset() : 0;
@@ -2396,7 +2338,7 @@ void RewriteInstance::readDynamicRelocations(const SectionRef &Section,
StringRef SymbolName = "<none>";
MCSymbol *Symbol = nullptr;
uint64_t SymbolAddress = 0;
- const uint64_t Addend = getRelocationAddend(InputFile, Rel);
+ const uint64_t Addend = BinaryContext::getRelocationAddend(InputFile, Rel);
symbol_iterator SymbolIter = Rel.getSymbol();
if (SymbolIter != InputFile->symbol_end()) {
@@ -2421,7 +2363,7 @@ void RewriteInstance::readDynamicRelocations(const SectionRef &Section,
IsJmpRelocation[RType] = true;
if (Symbol)
- SymbolIndex[Symbol] = getRelocationSymbol(InputFile, Rel);
+ SymbolIndex[Symbol] = BinaryContext::getRelocationSymbol(InputFile, Rel);
BC->addDynamicRelocation(Rel.getOffset(), Symbol, RType, Addend);
}
diff --git a/bolt/test/X86/Inputs/helperSafeICF.s b/bolt/test/X86/Inputs/helperSafeICF.s
new file mode 100644
index 00000000000000..8ab47324454cbc
--- /dev/null
+++ b/bolt/test/X86/Inputs/helperSafeICF.s
@@ -0,0 +1,39 @@
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
+# }
+ .text
+ .file "helper.cpp"
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end0:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end0-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
diff --git a/bolt/test/X86/Inputs/helperSafeICFICPTest.s b/bolt/test/X86/Inputs/helperSafeICFICPTest.s
new file mode 100644
index 00000000000000..ae62b4f292656f
--- /dev/null
+++ b/bolt/test/X86/Inputs/helperSafeICFICPTest.s
@@ -0,0 +1,40 @@
+# clang++ -O2 helper.cpp -c -o helperProf.o
+# int returnFive() {
+# return 5;
+# }
+# int returnFourOrFive(int val) {
+# return val == 1 ? 4 : 5;
+# }
+
+ .text
+ .file "helper.cpp"
+ .globl _Z10returnFivev # -- Begin function _Z10returnFivev
+ .p2align 4, 0x90
+ .type _Z10returnFivev, at function
+_Z10returnFivev: # @_Z10returnFivev
+ .cfi_startproc
+# %bb.0: # %entry
+ movl $5, %eax
+ retq
+.Lfunc_end0:
+ .size _Z10returnFivev, .Lfunc_end0-_Z10returnFivev
+ .cfi_endproc
+ # -- End function
+ .globl _Z16returnFourOrFivei # -- Begin function _Z16returnFourOrFivei
+ .p2align 4, 0x90
+ .type _Z16returnFourOrFivei, at function
+_Z16returnFourOrFivei: # @_Z16returnFourOrFivei
+ .cfi_startproc
+# %bb.0: # %entry
+ xorl %eax, %eax
+ cmpl $1, %edi
+ sete %al
+ xorl $5, %eax
+ retq
+.Lfunc_end1:
+ .size _Z16returnFourOrFivei, .Lfunc_end1-_Z16returnFourOrFivei
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
diff --git a/bolt/test/X86/Inputs/mainSafeICFICPTest.s b/bolt/test/X86/Inputs/mainSafeICFICPTest.s
new file mode 100644
index 00000000000000..4b12acdeae0995
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFICPTest.s
@@ -0,0 +1,331 @@
+# generate profile
+# clang++ -O2 -fprofile-generate=. main.cpp -c -o mainProf.o
+# PROF=test.profdata
+# clang++ -m64 -fprofile-use=$PROF \
+# -mllvm -disable-icp=true -mllvm -print-after-all \
+# -g0 -flto=thin -fwhole-program-vtables -fno-split-lto-unit -O2 \
+# -fdebug-types-section \
+# main.cpp -c -o mainProfLTO.bc
+# PASS='pgo-icall-prom'
+# clang++ -m64 -fprofile-use=$PROF \
+# -O3 -Rpass=$PASS \
+# -mllvm -print-before=$PASS \
+# -mllvm -print-after=$PASS \
+# -mllvm -filter-print-funcs=main \
+# -mllvm -debug-only=$PASS \
+# -x ir \
+# mainProfLTO.bc -c -o mainProfFinal.o
+
+# class Base {
+# public:
+# virtual int func(int a, int b) const = 0;
+#
+# virtual ~Base() {};
+# };
+#
+# //namespace {
+# class Derived2 : public Base {
+# int c = 5;
+# public:
+# __attribute__((noinline)) int func(int a, int b)const override { return a * (a - b) + this->c; }
+#
+# ~Derived2() {}
+# };
+#
+# class Derived3 : public Base {
+# int c = 500;
+# public:
+# __attribute__((noinline)) int func(int a, int b) const override { return a * (a - b) + this->c; }
+# ~Derived3() {}
+# };
+# //} // namespace//
+#
+# __attribute__((noinline)) Base *createType(int a) {
+# Base *base = nullptr;
+# if (a == 4)
+# base = new Derived2();
+# else
+# base = new Derived3();
+# return base;
+# }
+#
+# extern int returnFive();
+# extern int returnFourOrFive(int val);
+# int main(int argc, char **argv) {
+# int sum = 0;
+# int a = returnFourOrFive(argc);
+# int b = returnFive();
+# Base *ptr = createType(a);
+# Base *ptr2 = createType(b);
+# sum += ptr->func(b, a) + ptr2->func(b, a);
+# return 0;
+# }
+ .text
+ .file "main.cpp"
+ .section .text.hot.,"ax", at progbits
+ .globl _Z10createTypei # -- Begin function _Z10createTypei
+ .p2align 4, 0x90
+ .type _Z10createTypei, at function
+_Z10createTypei: # @_Z10createTypei
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbx
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbx, -16
+ movl %edi, %ebx
+ movl $16, %edi
+ callq _Znwm at PLT
+ cmpl $4, %ebx
+ xorps %xmm0, %xmm0
+ leaq _ZTV8Derived2+16(%rip), %rcx
+ leaq _ZTV8Derived3+16(%rip), %rdx
+ cmoveq %rcx, %rdx
+ movl $5, %ecx
+ movl $500, %esi # imm = 0x1F4
+ cmovel %ecx, %esi
+ movaps %xmm0, (%rax)
+ movq %rdx, (%rax)
+ movl %esi, 8(%rax)
+ popq %rbx
+ .cfi_def_cfa_offset 8
+ retq
+.Lfunc_end0:
+ .size _Z10createTypei, .Lfunc_end0-_Z10createTypei
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ pushq %r15
+ .cfi_def_cfa_offset 24
+ pushq %r14
+ .cfi_def_cfa_offset 32
+ pushq %rbx
+ .cfi_def_cfa_offset 40
+ pushq %rax
+ .cfi_def_cfa_offset 48
+ .cfi_offset %rbx, -40
+ .cfi_offset %r14, -32
+ .cfi_offset %r15, -24
+ .cfi_offset %rbp, -16
+ callq _Z16returnFourOrFivei at PLT
+ movl %eax, %ebx
+ callq _Z10returnFivev at PLT
+ movl %eax, %ebp
+ movl %ebx, %edi
+ callq _Z10createTypei
+ movq %rax, %r15
+ movl %ebp, %edi
+ callq _Z10createTypei
+ movq %rax, %r14
+ movq (%r15), %rax
+ movq (%rax), %rax
+ leaq _ZNK8Derived24funcEii(%rip), %rcx
+ movq %r15, %rdi
+ movl %ebp, %esi
+ movl %ebx, %edx
+ cmpq %rcx, %rax
+ jne .LBB1_2
+# %bb.1: # %if.true.direct_targ
+ callq _ZNK8Derived24funcEii
+.LBB1_3: # %if.end.icp
+ movq (%r14), %rax
+ movq (%rax), %rax
+ leaq _ZNK8Derived34funcEii(%rip), %rcx
+ movq %r14, %rdi
+ movl %ebp, %esi
+ movl %ebx, %edx
+ cmpq %rcx, %rax
+ jne .LBB1_5
+# %bb.4: # %if.true.direct_targ1
+ callq _ZNK8Derived34funcEii
+.LBB1_6: # %if.end.icp3
+ xorl %eax, %eax
+ addq $8, %rsp
+ .cfi_def_cfa_offset 40
+ popq %rbx
+ .cfi_def_cfa_offset 32
+ popq %r14
+ .cfi_def_cfa_offset 24
+ popq %r15
+ .cfi_def_cfa_offset 16
+ popq %rbp
+ .cfi_def_cfa_offset 8
+ retq
+.LBB1_2: # %if.false.orig_indirect
+ .cfi_def_cfa_offset 48
+ callq *%rax
+ jmp .LBB1_3
+.LBB1_5: # %if.false.orig_indirect2
+ callq *%rax
+ jmp .LBB1_6
+.Lfunc_end1:
+ .size main, .Lfunc_end1-main
+ .cfi_endproc
+ # -- End function
+ .section .text.hot._ZNK8Derived24funcEii,"axG", at progbits,_ZNK8Derived24funcEii,comdat
+ .weak _ZNK8Derived24funcEii # -- Begin function _ZNK8Derived24funcEii
+ .p2align 4, 0x90
+ .type _ZNK8Derived24funcEii, at function
+_ZNK8Derived24funcEii: # @_ZNK8Derived24funcEii
+ .cfi_startproc
+# %bb.0: # %entry
+ movl %esi, %eax
+ subl %edx, %eax
+ imull %esi, %eax
+ addl 8(%rdi), %eax
+ retq
+.Lfunc_end2:
+ .size _ZNK8Derived24funcEii, .Lfunc_end2-_ZNK8Derived24funcEii
+ .cfi_endproc
+ # -- End function
+ .section .text.unlikely._ZN8Derived2D0Ev,"axG", at progbits,_ZN8Derived2D0Ev,comdat
+ .weak _ZN8Derived2D0Ev # -- Begin function _ZN8Derived2D0Ev
+ .p2align 4, 0x90
+ .type _ZN8Derived2D0Ev, at function
+_ZN8Derived2D0Ev: # @_ZN8Derived2D0Ev
+ .cfi_startproc
+# %bb.0: # %entry
+ movl $16, %esi
+ jmp _ZdlPvm at PLT # TAILCALL
+.Lfunc_end3:
+ .size _ZN8Derived2D0Ev, .Lfunc_end3-_ZN8Derived2D0Ev
+ .cfi_endproc
+ # -- End function
+ .section .text.hot._ZNK8Derived34funcEii,"axG", at progbits,_ZNK8Derived34funcEii,comdat
+ .weak _ZNK8Derived34funcEii # -- Begin function _ZNK8Derived34funcEii
+ .p2align 4, 0x90
+ .type _ZNK8Derived34funcEii, at function
+_ZNK8Derived34funcEii: # @_ZNK8Derived34funcEii
+ .cfi_startproc
+# %bb.0: # %entry
+ movl %esi, %eax
+ subl %edx, %eax
+ imull %esi, %eax
+ addl 8(%rdi), %eax
+ retq
+.Lfunc_end4:
+ .size _ZNK8Derived34funcEii, .Lfunc_end4-_ZNK8Derived34funcEii
+ .cfi_endproc
+ # -- End function
+ .section .text.unlikely._ZN4BaseD2Ev,"axG", at progbits,_ZN4BaseD2Ev,comdat
+ .weak _ZN4BaseD2Ev # -- Begin function _ZN4BaseD2Ev
+ .p2align 4, 0x90
+ .type _ZN4BaseD2Ev, at function
+_ZN4BaseD2Ev: # @_ZN4BaseD2Ev
+ .cfi_startproc
+# %bb.0: # %entry
+ retq
+.Lfunc_end5:
+ .size _ZN4BaseD2Ev, .Lfunc_end5-_ZN4BaseD2Ev
+ .cfi_endproc
+ # -- End function
+ .section .text.unlikely._ZN8Derived3D0Ev,"axG", at progbits,_ZN8Derived3D0Ev,comdat
+ .weak _ZN8Derived3D0Ev # -- Begin function _ZN8Derived3D0Ev
+ .p2align 4, 0x90
+ .type _ZN8Derived3D0Ev, at function
+_ZN8Derived3D0Ev: # @_ZN8Derived3D0Ev
+ .cfi_startproc
+# %bb.0: # %entry
+ movl $16, %esi
+ jmp _ZdlPvm at PLT # TAILCALL
+.Lfunc_end6:
+ .size _ZN8Derived3D0Ev, .Lfunc_end6-_ZN8Derived3D0Ev
+ .cfi_endproc
+ # -- End function
+ .type _ZTV8Derived2, at object # @_ZTV8Derived2
+ .section .data.rel.ro._ZTV8Derived2,"awG", at progbits,_ZTV8Derived2,comdat
+ .weak _ZTV8Derived2
+ .p2align 3, 0x0
+_ZTV8Derived2:
+ .quad 0
+ .quad _ZTI8Derived2
+ .quad _ZNK8Derived24funcEii
+ .quad _ZN4BaseD2Ev
+ .quad _ZN8Derived2D0Ev
+ .size _ZTV8Derived2, 40
+
+ .type _ZTS8Derived2, at object # @_ZTS8Derived2
+ .section .rodata._ZTS8Derived2,"aG", at progbits,_ZTS8Derived2,comdat
+ .weak _ZTS8Derived2
+_ZTS8Derived2:
+ .asciz "8Derived2"
+ .size _ZTS8Derived2, 10
+
+ .type _ZTS4Base, at object # @_ZTS4Base
+ .section .rodata._ZTS4Base,"aG", at progbits,_ZTS4Base,comdat
+ .weak _ZTS4Base
+_ZTS4Base:
+ .asciz "4Base"
+ .size _ZTS4Base, 6
+
+ .type _ZTI4Base, at object # @_ZTI4Base
+ .section .data.rel.ro._ZTI4Base,"awG", at progbits,_ZTI4Base,comdat
+ .weak _ZTI4Base
+ .p2align 3, 0x0
+_ZTI4Base:
+ .quad _ZTVN10__cxxabiv117__class_type_infoE+16
+ .quad _ZTS4Base
+ .size _ZTI4Base, 16
+
+ .type _ZTI8Derived2, at object # @_ZTI8Derived2
+ .section .data.rel.ro._ZTI8Derived2,"awG", at progbits,_ZTI8Derived2,comdat
+ .weak _ZTI8Derived2
+ .p2align 3, 0x0
+_ZTI8Derived2:
+ .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
+ .quad _ZTS8Derived2
+ .quad _ZTI4Base
+ .size _ZTI8Derived2, 24
+
+ .type _ZTV8Derived3, at object # @_ZTV8Derived3
+ .section .data.rel.ro._ZTV8Derived3,"awG", at progbits,_ZTV8Derived3,comdat
+ .weak _ZTV8Derived3
+ .p2align 3, 0x0
+_ZTV8Derived3:
+ .quad 0
+ .quad _ZTI8Derived3
+ .quad _ZNK8Derived34funcEii
+ .quad _ZN4BaseD2Ev
+ .quad _ZN8Derived3D0Ev
+ .size _ZTV8Derived3, 40
+
+ .type _ZTS8Derived3, at object # @_ZTS8Derived3
+ .section .rodata._ZTS8Derived3,"aG", at progbits,_ZTS8Derived3,comdat
+ .weak _ZTS8Derived3
+_ZTS8Derived3:
+ .asciz "8Derived3"
+ .size _ZTS8Derived3, 10
+
+ .type _ZTI8Derived3, at object # @_ZTI8Derived3
+ .section .data.rel.ro._ZTI8Derived3,"awG", at progbits,_ZTI8Derived3,comdat
+ .weak _ZTI8Derived3
+ .p2align 3, 0x0
+_ZTI8Derived3:
+ .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
+ .quad _ZTS8Derived3
+ .quad _ZTI4Base
+ .size _ZTI8Derived3, 24
+
+ .cg_profile _Z10createTypei, _Znwm, 2
+ .cg_profile main, _Z16returnFourOrFivei, 1
+ .cg_profile main, _Z10returnFivev, 1
+ .cg_profile main, _Z10createTypei, 2
+ .cg_profile main, _ZNK8Derived24funcEii, 1
+ .cg_profile main, _ZNK8Derived34funcEii, 1
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _ZTVN10__cxxabiv120__si_class_type_infoE
+ .addrsig_sym _ZTS8Derived2
+ .addrsig_sym _ZTVN10__cxxabiv117__class_type_infoE
+ .addrsig_sym _ZTS4Base
+ .addrsig_sym _ZTI4Base
+ .addrsig_sym _ZTI8Derived2
+ .addrsig_sym _ZTS8Derived3
+ .addrsig_sym _ZTI8Derived3
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest1.s b/bolt/test/X86/Inputs/mainSafeICFTest1.s
new file mode 100644
index 00000000000000..7d38f0bd190fd8
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFTest1.s
@@ -0,0 +1,345 @@
+# clang++ -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# int main(int argc, char **argv) {
+# int temp = helper1(barAdd, FooVar, BarVar) +
+# helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $32, %rsp
+ movq %rdi, -16(%rbp)
+ movl %esi, -20(%rbp)
+ movl %edx, -24(%rbp)
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+# %bb.1:
+ movl $1, -4(%rbp)
+ jmp .LBB6_3
+.LBB6_2:
+ movq -16(%rbp), %rax
+ movl -20(%rbp), %edi
+ movl -24(%rbp), %esi
+ callq *%rax
+ subl $4, %eax
+ movl %eax, -4(%rbp)
+.LBB6_3:
+ movl -4(%rbp), %eax
+ addq $32, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movq %rdi, -16(%rbp)
+ movq %rsi, -24(%rbp)
+ movl %edx, -28(%rbp)
+ movl %ecx, -32(%rbp)
+ movq -16(%rbp), %rax
+ cmpq -24(%rbp), %rax
+ jne .LBB7_2
+# %bb.1:
+ movl $2, -4(%rbp)
+ jmp .LBB7_3
+.LBB7_2:
+ movq -16(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq -24(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -4(%rbp)
+.LBB7_3:
+ movl -4(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFiiiEii
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %ecx
+ leaq _Z6fooMulii(%rip), %rdi
+ leaq _Z6barMulii(%rip), %rsi
+ callq _Z7helper2PFiiiES0_ii
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -32(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooSubii
+ movl %eax, %ecx
+ movl -32(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -28(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6barSubii
+ movl %eax, %ecx
+ movl -28(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -24(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooAddii
+ movl %eax, %ecx
+ movl -24(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -20(%rbp)
+ movl -20(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooSubii
+ .addrsig_sym _Z6barSubii
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6barMulii
+ .addrsig_sym _Z6fooAddii
+ .addrsig_sym _Z6barAddii
+ .addrsig_sym _Z7helper1PFiiiEii
+ .addrsig_sym _Z7helper2PFiiiES0_ii
+ .addrsig_sym FooVar
+ .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
new file mode 100644
index 00000000000000..5d5d00c12320be
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
@@ -0,0 +1,363 @@
+# clang++ -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# static int (*funcGlobalBarAdd)(int, int) = barAdd;
+# int (*funcGlobalBarMul)(int, int) = barMul;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $32, %rsp
+ movq %rdi, -16(%rbp)
+ movl %esi, -20(%rbp)
+ movl %edx, -24(%rbp)
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+# %bb.1:
+ movl $1, -4(%rbp)
+ jmp .LBB6_3
+.LBB6_2:
+ movq -16(%rbp), %rax
+ movl -20(%rbp), %edi
+ movl -24(%rbp), %esi
+ callq *%rax
+ subl $4, %eax
+ movl %eax, -4(%rbp)
+.LBB6_3:
+ movl -4(%rbp), %eax
+ addq $32, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movq %rdi, -16(%rbp)
+ movq %rsi, -24(%rbp)
+ movl %edx, -28(%rbp)
+ movl %ecx, -32(%rbp)
+ movq -16(%rbp), %rax
+ cmpq -24(%rbp), %rax
+ jne .LBB7_2
+# %bb.1:
+ movl $2, -4(%rbp)
+ jmp .LBB7_3
+.LBB7_2:
+ movq -16(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq -24(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -4(%rbp)
+.LBB7_3:
+ movl -4(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+ movq _ZL16funcGlobalBarAdd(%rip), %rdi
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ callq _Z7helper1PFiiiEii
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq funcGlobalBarMul(%rip), %rsi
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %ecx
+ leaq _Z6fooMulii(%rip), %rdi
+ callq _Z7helper2PFiiiES0_ii
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -32(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooSubii
+ movl %eax, %ecx
+ movl -32(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -28(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6barSubii
+ movl %eax, %ecx
+ movl -28(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -24(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooAddii
+ movl %eax, %ecx
+ movl -24(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -20(%rbp)
+ movl -20(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .type funcGlobalBarMul, at object # @funcGlobalBarMul
+ .data
+ .globl funcGlobalBarMul
+ .p2align 3, 0x0
+funcGlobalBarMul:
+ .quad _Z6barMulii
+ .size funcGlobalBarMul, 8
+
+ .type _ZL16funcGlobalBarAdd, at object # @_ZL16funcGlobalBarAdd
+ .p2align 3, 0x0
+_ZL16funcGlobalBarAdd:
+ .quad _Z6barAddii
+ .size _ZL16funcGlobalBarAdd, 8
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooSubii
+ .addrsig_sym _Z6barSubii
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6barMulii
+ .addrsig_sym _Z6fooAddii
+ .addrsig_sym _Z6barAddii
+ .addrsig_sym _Z7helper1PFiiiEii
+ .addrsig_sym _Z7helper2PFiiiES0_ii
+ .addrsig_sym funcGlobalBarMul
+ .addrsig_sym _ZL16funcGlobalBarAdd
+ .addrsig_sym FooVar
+ .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
new file mode 100644
index 00000000000000..3579fa2eae293b
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
@@ -0,0 +1,293 @@
+# clang++ -O3 -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# static int (*funcGlobalBarAdd)(int, int) = barAdd;
+# int (*funcGlobalBarMul)(int, int) = barMul;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ movl %edi, %eax
+ subl %esi, %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ movl %edi, %eax
+ subl %esi, %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ movl %edi, %eax
+ imull %esi, %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ movl %edi, %eax
+ imull %esi, %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ # kill: def $esi killed $esi def $rsi
+ # kill: def $edi killed $edi def $rdi
+ leal (%rdi,%rsi), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ # kill: def $esi killed $esi def $rsi
+ # kill: def $edi killed $edi def $rdi
+ leal (%rdi,%rsi), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+# %bb.0:
+ leaq _Z6barAddii(%rip), %rcx
+ cmpq %rcx, %rdi
+ je .LBB6_1
+# %bb.2:
+ pushq %rax
+ .cfi_def_cfa_offset 16
+ movq %rdi, %rax
+ movl %esi, %edi
+ movl %edx, %esi
+ callq *%rax
+ addl $-4, %eax
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ retq
+.LBB6_1:
+ movl $1, %eax
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+# %bb.0:
+ cmpq %rsi, %rdi
+ je .LBB7_1
+# %bb.2:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ pushq %r15
+ .cfi_def_cfa_offset 24
+ pushq %r14
+ .cfi_def_cfa_offset 32
+ pushq %rbx
+ .cfi_def_cfa_offset 40
+ pushq %rax
+ .cfi_def_cfa_offset 48
+ .cfi_offset %rbx, -40
+ .cfi_offset %r14, -32
+ .cfi_offset %r15, -24
+ .cfi_offset %rbp, -16
+ movl %ecx, %ebx
+ movl %edx, %ebp
+ movq %rsi, %r14
+ movq %rdi, %rax
+ movl %edx, %edi
+ movl %ecx, %esi
+ callq *%rax
+ movl %eax, %r15d
+ movl %ebp, %edi
+ movl %ebx, %esi
+ callq *%r14
+ addl %r15d, %eax
+ addq $8, %rsp
+ .cfi_def_cfa_offset 40
+ popq %rbx
+ .cfi_def_cfa_offset 32
+ popq %r14
+ .cfi_def_cfa_offset 24
+ popq %r15
+ .cfi_def_cfa_offset 16
+ popq %rbp
+ .cfi_def_cfa_offset 8
+ .cfi_restore %rbx
+ .cfi_restore %r14
+ .cfi_restore %r15
+ .cfi_restore %rbp
+ retq
+.LBB7_1:
+ movl $2, %eax
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ pushq %r15
+ .cfi_def_cfa_offset 24
+ pushq %r14
+ .cfi_def_cfa_offset 32
+ pushq %r12
+ .cfi_def_cfa_offset 40
+ pushq %rbx
+ .cfi_def_cfa_offset 48
+ .cfi_offset %rbx, -48
+ .cfi_offset %r12, -40
+ .cfi_offset %r14, -32
+ .cfi_offset %r15, -24
+ .cfi_offset %rbp, -16
+ movq FooVar at GOTPCREL(%rip), %r14
+ movl (%r14), %esi
+ movq BarVar at GOTPCREL(%rip), %r15
+ movl (%r15), %edx
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFiiiEii
+ movl %eax, %ebx
+ movq funcGlobalBarMul(%rip), %rsi
+ movl (%r14), %edx
+ movl (%r15), %ecx
+ leaq _Z6fooMulii(%rip), %rdi
+ callq _Z7helper2PFiiiES0_ii
+ movl %eax, %ebp
+ addl %ebx, %ebp
+ movl (%r14), %ebx
+ movl (%r15), %r14d
+ movl %ebx, %edi
+ movl %r14d, %esi
+ callq _Z6fooSubii
+ movl %eax, %r15d
+ movl %ebx, %edi
+ movl %r14d, %esi
+ callq _Z6barSubii
+ movl %eax, %r12d
+ addl %r15d, %r12d
+ addl %ebp, %r12d
+ movl %ebx, %edi
+ movl %r14d, %esi
+ callq _Z6fooAddii
+ addl %r12d, %eax
+ popq %rbx
+ .cfi_def_cfa_offset 40
+ popq %r12
+ .cfi_def_cfa_offset 32
+ popq %r14
+ .cfi_def_cfa_offset 24
+ popq %r15
+ .cfi_def_cfa_offset 16
+ popq %rbp
+ .cfi_def_cfa_offset 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .type funcGlobalBarMul, at object # @funcGlobalBarMul
+ .data
+ .globl funcGlobalBarMul
+ .p2align 3, 0x0
+funcGlobalBarMul:
+ .quad _Z6barMulii
+ .size funcGlobalBarMul, 8
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6barMulii
+ .addrsig_sym _Z6barAddii
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
new file mode 100644
index 00000000000000..56036d1b14e2b9
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
@@ -0,0 +1,359 @@
+
+# clang++ -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# int main(int argc, char **argv) {
+# static int (*funcGlobalBarAdd)(int, int) = barAdd;
+# int (*funcGlobalBarMul)(int, int) = barMul;
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $32, %rsp
+ movq %rdi, -16(%rbp)
+ movl %esi, -20(%rbp)
+ movl %edx, -24(%rbp)
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+# %bb.1:
+ movl $1, -4(%rbp)
+ jmp .LBB6_3
+.LBB6_2:
+ movq -16(%rbp), %rax
+ movl -20(%rbp), %edi
+ movl -24(%rbp), %esi
+ callq *%rax
+ subl $4, %eax
+ movl %eax, -4(%rbp)
+.LBB6_3:
+ movl -4(%rbp), %eax
+ addq $32, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movq %rdi, -16(%rbp)
+ movq %rsi, -24(%rbp)
+ movl %edx, -28(%rbp)
+ movl %ecx, -32(%rbp)
+ movq -16(%rbp), %rax
+ cmpq -24(%rbp), %rax
+ jne .LBB7_2
+# %bb.1:
+ movl $2, -4(%rbp)
+ jmp .LBB7_3
+.LBB7_2:
+ movq -16(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq -24(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -4(%rbp)
+.LBB7_3:
+ movl -4(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+ leaq _Z6barMulii(%rip), %rax
+ movq %rax, -24(%rbp)
+ movq _ZZ4mainE16funcGlobalBarAdd(%rip), %rdi
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ callq _Z7helper1PFiiiEii
+ movl %eax, -44(%rbp) # 4-byte Spill
+ movq -24(%rbp), %rsi
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %ecx
+ leaq _Z6fooMulii(%rip), %rdi
+ callq _Z7helper2PFiiiES0_ii
+ movl %eax, %ecx
+ movl -44(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -40(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooSubii
+ movl %eax, %ecx
+ movl -40(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6barSubii
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -32(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooAddii
+ movl %eax, %ecx
+ movl -32(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -28(%rbp)
+ movl -28(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .type _ZZ4mainE16funcGlobalBarAdd, at object # @_ZZ4mainE16funcGlobalBarAdd
+ .data
+ .p2align 3, 0x0
+_ZZ4mainE16funcGlobalBarAdd:
+ .quad _Z6barAddii
+ .size _ZZ4mainE16funcGlobalBarAdd, 8
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooSubii
+ .addrsig_sym _Z6barSubii
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6barMulii
+ .addrsig_sym _Z6fooAddii
+ .addrsig_sym _Z6barAddii
+ .addrsig_sym _Z7helper1PFiiiEii
+ .addrsig_sym _Z7helper2PFiiiES0_ii
+ .addrsig_sym _ZZ4mainE16funcGlobalBarAdd
+ .addrsig_sym FooVar
+ .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
new file mode 100644
index 00000000000000..aedad906912654
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
@@ -0,0 +1,286 @@
+# clang++ -O3 -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# int main(int argc, char **argv) {
+# static int (*funcGlobalBarAdd)(int, int) = barAdd;
+# int (*funcGlobalBarMul)(int, int) = barMul;
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ movl %edi, %eax
+ subl %esi, %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ movl %edi, %eax
+ subl %esi, %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ movl %edi, %eax
+ imull %esi, %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ movl %edi, %eax
+ imull %esi, %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ # kill: def $esi killed $esi def $rsi
+ # kill: def $edi killed $edi def $rdi
+ leal (%rdi,%rsi), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ # kill: def $esi killed $esi def $rsi
+ # kill: def $edi killed $edi def $rdi
+ leal (%rdi,%rsi), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+# %bb.0:
+ leaq _Z6barAddii(%rip), %rcx
+ cmpq %rcx, %rdi
+ je .LBB6_1
+# %bb.2:
+ pushq %rax
+ .cfi_def_cfa_offset 16
+ movq %rdi, %rax
+ movl %esi, %edi
+ movl %edx, %esi
+ callq *%rax
+ addl $-4, %eax
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ retq
+.LBB6_1:
+ movl $1, %eax
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+# %bb.0:
+ cmpq %rsi, %rdi
+ je .LBB7_1
+# %bb.2:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ pushq %r15
+ .cfi_def_cfa_offset 24
+ pushq %r14
+ .cfi_def_cfa_offset 32
+ pushq %rbx
+ .cfi_def_cfa_offset 40
+ pushq %rax
+ .cfi_def_cfa_offset 48
+ .cfi_offset %rbx, -40
+ .cfi_offset %r14, -32
+ .cfi_offset %r15, -24
+ .cfi_offset %rbp, -16
+ movl %ecx, %ebx
+ movl %edx, %ebp
+ movq %rsi, %r14
+ movq %rdi, %rax
+ movl %edx, %edi
+ movl %ecx, %esi
+ callq *%rax
+ movl %eax, %r15d
+ movl %ebp, %edi
+ movl %ebx, %esi
+ callq *%r14
+ addl %r15d, %eax
+ addq $8, %rsp
+ .cfi_def_cfa_offset 40
+ popq %rbx
+ .cfi_def_cfa_offset 32
+ popq %r14
+ .cfi_def_cfa_offset 24
+ popq %r15
+ .cfi_def_cfa_offset 16
+ popq %rbp
+ .cfi_def_cfa_offset 8
+ .cfi_restore %rbx
+ .cfi_restore %r14
+ .cfi_restore %r15
+ .cfi_restore %rbp
+ retq
+.LBB7_1:
+ movl $2, %eax
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ pushq %r15
+ .cfi_def_cfa_offset 24
+ pushq %r14
+ .cfi_def_cfa_offset 32
+ pushq %r12
+ .cfi_def_cfa_offset 40
+ pushq %rbx
+ .cfi_def_cfa_offset 48
+ .cfi_offset %rbx, -48
+ .cfi_offset %r12, -40
+ .cfi_offset %r14, -32
+ .cfi_offset %r15, -24
+ .cfi_offset %rbp, -16
+ movq FooVar at GOTPCREL(%rip), %r14
+ movl (%r14), %esi
+ movq BarVar at GOTPCREL(%rip), %r15
+ movl (%r15), %edx
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFiiiEii
+ movl %eax, %ebx
+ movl (%r14), %edx
+ movl (%r15), %ecx
+ leaq _Z6fooMulii(%rip), %rdi
+ leaq _Z6barMulii(%rip), %rsi
+ callq _Z7helper2PFiiiES0_ii
+ movl %eax, %ebp
+ addl %ebx, %ebp
+ movl (%r14), %ebx
+ movl (%r15), %r14d
+ movl %ebx, %edi
+ movl %r14d, %esi
+ callq _Z6fooSubii
+ movl %eax, %r15d
+ movl %ebx, %edi
+ movl %r14d, %esi
+ callq _Z6barSubii
+ movl %eax, %r12d
+ addl %r15d, %r12d
+ addl %ebp, %r12d
+ movl %ebx, %edi
+ movl %r14d, %esi
+ callq _Z6fooAddii
+ addl %r12d, %eax
+ popq %rbx
+ .cfi_def_cfa_offset 40
+ popq %r12
+ .cfi_def_cfa_offset 32
+ popq %r14
+ .cfi_def_cfa_offset 24
+ popq %r15
+ .cfi_def_cfa_offset 16
+ popq %rbp
+ .cfi_def_cfa_offset 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6barMulii
+ .addrsig_sym _Z6barAddii
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
new file mode 100644
index 00000000000000..efeaf469eedeea
--- /dev/null
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -0,0 +1,20 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+# The compare is generated by the ICP path with instrumentation profiling.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFICPTest.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFICPTest.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
+# ICFCHECK-NEXT: folding _ZNK8Derived34funcEii into _ZNK8Derived24funcEii
+
+# SAFEICFCHECK: skipping function _ZNK8Derived24funcEii
+# SAFEICFCHECK-NEXT: skipping function _ZNK8Derived34funcEii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
new file mode 100644
index 00000000000000..37c5debe8c814b
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -0,0 +1,21 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf --skip-funcs=_Z7helper1PFiiiEii,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
new file mode 100644
index 00000000000000..3b5d7400d85115
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -0,0 +1,16 @@
+## Checks that BOLT handles correctly with no relocations with --safe-icf option.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: not llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: BOLT-ERROR: Binary built without relocations. Safe ICF is not supported
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
new file mode 100644
index 00000000000000..2b41633d07bf93
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -0,0 +1,21 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
new file mode 100644
index 00000000000000..904d792e225b9c
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -0,0 +1,21 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest2GlobalVarO0.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
new file mode 100644
index 00000000000000..288faf252ad745
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -0,0 +1,21 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest2GlobalVarO3.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
new file mode 100644
index 00000000000000..56a329b2f7a598
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -0,0 +1,21 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest3LocalVarO0.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
new file mode 100644
index 00000000000000..d0782e46b17e06
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -0,0 +1,21 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest3LocalVarO3.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
>From 237c02e48825e2e42ec7cee62ef4a83ad0a8c4b1 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Thu, 14 Nov 2024 17:38:10 -0800
Subject: [PATCH 02/34] Changed icf option
---
bolt/include/bolt/Core/BinaryContext.h | 11 ++++++++++
.../bolt/Passes/IdenticalCodeFolding.h | 6 ++----
bolt/lib/Core/BinaryContext.cpp | 21 ++++++++++++-------
bolt/lib/Passes/IdenticalCodeFolding.cpp | 2 +-
bolt/lib/Rewrite/BinaryPassManager.cpp | 12 ++++-------
bolt/lib/Rewrite/BoltDiff.cpp | 4 ++--
bolt/test/X86/icf-safe-icp.test | 2 +-
bolt/test/X86/icf-safe-test1-no-cfg.test | 4 ++--
bolt/test/X86/icf-safe-test1-no-relocs.test | 4 ++--
bolt/test/X86/icf-safe-test1.test | 2 +-
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 2 +-
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 2 +-
bolt/test/X86/icf-safe-test3LocalVarO0.test | 2 +-
bolt/test/X86/icf-safe-test3LocalVarO3.test | 2 +-
14 files changed, 44 insertions(+), 32 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 92889ffe162ae1..3e58ec502acd09 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -276,6 +276,12 @@ class BinaryContext {
void deregisterSectionName(const BinarySection &Section);
public:
+ enum class ICFLevel {
+ None,
+ Safe, // Safe ICF for all sections.
+ All, // Aggressive ICF for code, but safe ICF for data, similar to MSVC's
+ // behavior.
+ };
static Expected<std::unique_ptr<BinaryContext>>
createBinaryContext(Triple TheTriple, StringRef InputFileName,
SubtargetFeatures *Features, bool IsPIC,
@@ -666,6 +672,9 @@ class BinaryContext {
std::unique_ptr<MCAsmBackend> MAB;
+ /// ICF level to use for this binary.
+ ICFLevel ICFLevelVar{ICFLevel::None};
+
/// Allows BOLT to print to log whenever it is necessary (with or without
/// const references)
mutable JournalingStreams Logger;
@@ -1485,6 +1494,8 @@ class BinaryContext {
return *IOAddressMap;
}
+ ICFLevel getICFLevel() const { return ICFLevelVar; }
+
raw_ostream &outs() const { return Logger.Out; }
raw_ostream &errs() const { return Logger.Err; }
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index 75d5f19ddfc7be..41fb17408d5876 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -31,8 +31,8 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
}
public:
- explicit IdenticalCodeFolding(const cl::opt<bool> &PrintPass, bool IsSafeICF)
- : BinaryFunctionPass(PrintPass), IsSafeICF(IsSafeICF) {}
+ explicit IdenticalCodeFolding(const cl::opt<bool> &PrintPass)
+ : BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "identical-code-folding"; }
Error runOnFunctions(BinaryContext &BC) override;
@@ -44,8 +44,6 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
/// references.
void processDataRelocations(BinaryContext &BC,
const SectionRef &SecRefRelData);
-
- bool IsSafeICF;
};
} // namespace bolt
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 31352bed6fdab7..6cf1562735eb45 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -76,12 +76,8 @@ cl::opt<std::string> CompDirOverride(
"to *.dwo files."),
cl::Hidden, cl::init(""), cl::cat(BoltCategory));
-cl::opt<bool> ICF("icf", cl::desc("fold functions with identical code"),
- cl::cat(BoltOptCategory));
-
-cl::opt<bool> SafeICF("safe-icf",
- cl::desc("Enable safe identical code folding"),
- cl::cat(BoltOptCategory));
+cl::opt<std::string> ICF("icf", cl::desc("fold functions with identical code"),
+ cl::ValueOptional, cl::cat(BoltOptCategory));
} // namespace opts
namespace {
@@ -175,6 +171,16 @@ void BinaryContext::logBOLTErrorsAndQuitOnFatal(Error E) {
});
}
+static BinaryContext::ICFLevel parseICFLevel() {
+ if (!opts::ICF.getNumOccurrences())
+ return BinaryContext::ICFLevel::None;
+ std::string Str = StringRef(opts::ICF).lower();
+ return StringSwitch<BinaryContext::ICFLevel>(Str)
+ .Case("all", BinaryContext::ICFLevel::All)
+ .Case("safe", BinaryContext::ICFLevel::Safe)
+ .Default(BinaryContext::ICFLevel::All);
+}
+
BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
std::unique_ptr<DWARFContext> DwCtx,
std::unique_ptr<Triple> TheTriple,
@@ -199,6 +205,7 @@ BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
Logger(Logger), InitialDynoStats(isAArch64()) {
RegularPageSize = isAArch64() ? RegularPageSizeAArch64 : RegularPageSizeX86;
PageAlign = opts::NoHugePages ? RegularPageSize : HugePageSize;
+ ICFLevelVar = parseICFLevel();
}
BinaryContext::~BinaryContext() {
@@ -2017,7 +2024,7 @@ static bool skipInstruction(const MCInst &Inst, const BinaryContext &BC) {
BC.MIB->isCall(Inst) || BC.MIB->isBranch(Inst));
}
void BinaryContext::processInstructionForFuncReferences(const MCInst &Inst) {
- if (!opts::SafeICF || skipInstruction(Inst, *this))
+ if (ICFLevelVar != ICFLevel::Safe || skipInstruction(Inst, *this))
return;
for (const MCOperand &Op : MCPlus::primeOperands(Inst)) {
if (Op.isExpr()) {
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index f09482dc08c212..6e00ccda338556 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -550,7 +550,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
LLVM_DEBUG(SinglePass.stopTimer());
};
- if (IsSafeICF) {
+ if (BC.getICFLevel() == BinaryContext::ICFLevel::Safe) {
if (Error Err = createFoldSkipList(BC)) {
return Err;
}
diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp
index df612c0a8f2e51..e5fb1f5b257850 100644
--- a/bolt/lib/Rewrite/BinaryPassManager.cpp
+++ b/bolt/lib/Rewrite/BinaryPassManager.cpp
@@ -54,8 +54,6 @@ extern cl::opt<bool> PrintDynoStats;
extern cl::opt<bool> DumpDotAll;
extern cl::opt<std::string> AsmDump;
extern cl::opt<bolt::PLTCall::OptType> PLT;
-extern cl::opt<bool> ICF;
-extern cl::opt<bool> SafeICF;
static cl::opt<bool>
DynoStatsAll("dyno-stats-all",
@@ -396,9 +394,8 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
Manager.registerPass(std::make_unique<StripRepRet>(NeverPrint),
opts::StripRepRet);
- Manager.registerPass(
- std::make_unique<IdenticalCodeFolding>(PrintICF, opts::SafeICF),
- opts::ICF || opts::SafeICF);
+ Manager.registerPass(std::make_unique<IdenticalCodeFolding>(PrintICF),
+ BC.getICFLevel() != BinaryContext::ICFLevel::None);
Manager.registerPass(
std::make_unique<SpecializeMemcpy1>(NeverPrint, opts::SpecializeMemcpy1),
@@ -422,9 +419,8 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
Manager.registerPass(std::make_unique<Inliner>(PrintInline));
- Manager.registerPass(
- std::make_unique<IdenticalCodeFolding>(PrintICF, opts::SafeICF),
- opts::ICF || opts::SafeICF);
+ Manager.registerPass(std::make_unique<IdenticalCodeFolding>(PrintICF),
+ BC.getICFLevel() != BinaryContext::ICFLevel::None);
Manager.registerPass(std::make_unique<PLTCall>(PrintPLT));
diff --git a/bolt/lib/Rewrite/BoltDiff.cpp b/bolt/lib/Rewrite/BoltDiff.cpp
index 1a8eb5cd2ce39d..5d3021ea845e7e 100644
--- a/bolt/lib/Rewrite/BoltDiff.cpp
+++ b/bolt/lib/Rewrite/BoltDiff.cpp
@@ -698,8 +698,8 @@ void RewriteInstance::compare(RewriteInstance &RI2) {
}
// Pre-pass ICF
- if (opts::ICF) {
- IdenticalCodeFolding ICF(opts::NeverPrint, opts::SafeICF);
+ if (BC->getICFLevel() != BinaryContext::ICFLevel::None) {
+ IdenticalCodeFolding ICF(opts::NeverPrint);
outs() << "BOLT-DIFF: Starting ICF pass for binary 1";
BC->logBOLTErrorsAndQuitOnFatal(ICF.runOnFunctions(*BC));
outs() << "BOLT-DIFF: Starting ICF pass for binary 2";
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index efeaf469eedeea..7b46c6297a40ec 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -6,7 +6,7 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFICPTest.s -o %t2.o
# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index 37c5debe8c814b..5efbff9b3f3f76 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -4,8 +4,8 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf --skip-funcs=_Z7helper1PFiiiEii,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=all -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf --skip-funcs=_Z7helper1PFiiiEii,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index 3b5d7400d85115..c80d35a5f576ff 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -1,11 +1,11 @@
-## Checks that BOLT handles correctly with no relocations with --safe-icf option.
+## Checks that BOLT handles correctly with no relocations with --icf=safe option.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
# RUN: %clang %cflags %t1.o %t2.o -o %t.exe
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: not llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: not llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index 2b41633d07bf93..96986dec1e1922 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -5,7 +5,7 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index 904d792e225b9c..9464dc05782ee5 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -5,7 +5,7 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index 288faf252ad745..935a5ddb189ef7 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -5,7 +5,7 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
index 56a329b2f7a598..9fb783539da39f 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -5,7 +5,7 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index d0782e46b17e06..55fa11ada15490 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -5,7 +5,7 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --safe-icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
>From d794fb02ad8312892a4d935a77ac03e4cdf98522 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Fri, 15 Nov 2024 14:29:54 -0800
Subject: [PATCH 03/34] addressed comments
---
bolt/include/bolt/Core/BinaryContext.h | 9 ++++-----
bolt/include/bolt/Core/BinaryFunction.h | 2 +-
.../include/bolt/Passes/IdenticalCodeFolding.h | 5 +++--
bolt/lib/Core/BinaryContext.cpp | 18 +++++++++---------
bolt/lib/Passes/IdenticalCodeFolding.cpp | 8 ++++----
5 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 3e58ec502acd09..318535b2fac239 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -278,9 +278,8 @@ class BinaryContext {
public:
enum class ICFLevel {
None,
- Safe, // Safe ICF for all sections.
- All, // Aggressive ICF for code, but safe ICF for data, similar to MSVC's
- // behavior.
+ Safe,
+ All,
};
static Expected<std::unique_ptr<BinaryContext>>
createBinaryContext(Triple TheTriple, StringRef InputFileName,
@@ -673,7 +672,7 @@ class BinaryContext {
std::unique_ptr<MCAsmBackend> MAB;
/// ICF level to use for this binary.
- ICFLevel ICFLevelVar{ICFLevel::None};
+ ICFLevel CurrICFLevel{ICFLevel::None};
/// Allows BOLT to print to log whenever it is necessary (with or without
/// const references)
@@ -1494,7 +1493,7 @@ class BinaryContext {
return *IOAddressMap;
}
- ICFLevel getICFLevel() const { return ICFLevelVar; }
+ ICFLevel getICFLevel() const { return CurrICFLevel; }
raw_ostream &outs() const { return Logger.Out; }
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index 5e1ddcc6bff9a2..f05ea40cfb1334 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -824,7 +824,7 @@ class BinaryFunction {
bool isSafeToICF() const { return IsSafeToICF; }
/// Sets the function is not safe to fold.
- void setUnsetToICF() { IsSafeToICF = false; }
+ void setUnsafeICF() { IsSafeToICF = false; }
/// Returns the raw binary encoding of this function.
ErrorOr<ArrayRef<uint8_t>> getData() const;
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index 41fb17408d5876..eb803031bf0f0e 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -38,8 +38,9 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
Error runOnFunctions(BinaryContext &BC) override;
private:
- /// Create a skip list of functions that should not be folded.
- Error createFoldSkipList(BinaryContext &BC);
+ /// Analyses .text section and relocations and marks functions that are not
+ /// safe to fold.
+ Error markFunctionsUnsafeToFold(BinaryContext &BC);
/// Processes relocations in the .data section to identify function
/// references.
void processDataRelocations(BinaryContext &BC,
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 6cf1562735eb45..960849371660b2 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -205,7 +205,7 @@ BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
Logger(Logger), InitialDynoStats(isAArch64()) {
RegularPageSize = isAArch64() ? RegularPageSizeAArch64 : RegularPageSizeX86;
PageAlign = opts::NoHugePages ? RegularPageSize : HugePageSize;
- ICFLevelVar = parseICFLevel();
+ CurrICFLevel = parseICFLevel();
}
BinaryContext::~BinaryContext() {
@@ -2024,16 +2024,16 @@ static bool skipInstruction(const MCInst &Inst, const BinaryContext &BC) {
BC.MIB->isCall(Inst) || BC.MIB->isBranch(Inst));
}
void BinaryContext::processInstructionForFuncReferences(const MCInst &Inst) {
- if (ICFLevelVar != ICFLevel::Safe || skipInstruction(Inst, *this))
+ if (CurrICFLevel != ICFLevel::Safe || skipInstruction(Inst, *this))
return;
for (const MCOperand &Op : MCPlus::primeOperands(Inst)) {
- if (Op.isExpr()) {
- const MCExpr &Expr = *Op.getExpr();
- if (Expr.getKind() == MCExpr::SymbolRef) {
- const MCSymbol &Symbol = cast<MCSymbolRefExpr>(Expr).getSymbol();
- if (BinaryFunction *BF = getFunctionForSymbol(&Symbol))
- BF->setUnsetToICF();
- }
+ if (!Op.isExpr())
+ continue;
+ const MCExpr &Expr = *Op.getExpr();
+ if (Expr.getKind() == MCExpr::SymbolRef) {
+ const MCSymbol &Symbol = cast<MCSymbolRefExpr>(Expr).getSymbol();
+ if (BinaryFunction *BF = getFunctionForSymbol(&Symbol))
+ BF->setUnsafeICF();
}
}
}
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 6e00ccda338556..8fb22897a44f62 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -355,16 +355,16 @@ void IdenticalCodeFolding::processDataRelocations(
const uint64_t SymbolAddress = cantFail(Symbol.getAddress());
const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(OwningObj);
if (!ELFObj)
- assert(false && "Only ELFObjectFileBase is supported");
+ llvm_unreachable("Only ELFObjectFileBase is supported");
const int64_t Addend = BinaryContext::getRelocationAddend(ELFObj, Rel);
BinaryFunction *BF = BC.getBinaryFunctionAtAddress(SymbolAddress + Addend);
if (!BF)
continue;
- BF->setUnsetToICF();
+ BF->setUnsafeICF();
}
}
-Error IdenticalCodeFolding::createFoldSkipList(BinaryContext &BC) {
+Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
Error ErrorStatus = Error::success();
ErrorOr<BinarySection &> SecRelData = BC.getUniqueSectionByName(".rela.data");
if (!BC.HasRelocations)
@@ -551,7 +551,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
LLVM_DEBUG(SinglePass.stopTimer());
};
if (BC.getICFLevel() == BinaryContext::ICFLevel::Safe) {
- if (Error Err = createFoldSkipList(BC)) {
+ if (Error Err = markFunctionsUnsafeToFold(BC)) {
return Err;
}
}
>From 6e853ca31324fdc32a172fb9c48d550ceab3547c Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Fri, 15 Nov 2024 16:41:00 -0800
Subject: [PATCH 04/34] Added four tests for pic/no-pic mode. Tests for global
const function pointer
---
.../Inputs/helperSafeICFGlobalConstPtrNoPic.s | 83 ++++
...lperSafeICFGlobalConstPtrNoPicExtFuncRef.s | 84 ++++
.../Inputs/helperSafeICFGlobalConstPtrPic.s | 84 ++++
...helperSafeICFGlobalConstPtrPicExtFuncRef.s | 84 ++++
.../Inputs/mainSafeICFGlobalConstPtrNoPic.s | 339 ++++++++++++++++
...mainSafeICFGlobalConstPtrNoPicExtFuncRef.s | 343 +++++++++++++++++
.../X86/Inputs/mainSafeICFGlobalConstPtrPic.s | 350 +++++++++++++++++
.../mainSafeICFGlobalConstPtrPicExtFuncRef.s | 364 ++++++++++++++++++
.../icf-safe-test2GlobalConstPtrNoPic.test | 24 ++
...fe-test2GlobalConstPtrNoPicExtFuncRef.test | 24 ++
.../X86/icf-safe-test2GlobalConstPtrPic.test | 24 ++
...safe-test2GlobalConstPtrPicExtFuncRef.test | 24 ++
12 files changed, 1827 insertions(+)
create mode 100644 bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
create mode 100644 bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
create mode 100644 bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
create mode 100644 bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
create mode 100644 bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
create mode 100644 bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
create mode 100644 bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
create mode 100644 bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
create mode 100644 bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
new file mode 100644
index 00000000000000..8697f77862e66f
--- /dev/null
+++ b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
@@ -0,0 +1,83 @@
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
+
+ .text
+ .file "helper.cpp"
+ .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .p2align 4, 0x90
+ .type _Z12barAddHdlperii, at function
+_Z12barAddHdlperii: # @_Z12barAddHdlperii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
+ .cfi_endproc
+ # -- End function
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $16, %rsp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %edi
+ movl -8(%rbp), %esi
+ callq _Z12barAddHdlperii
+ addl $5, %eax
+ addq $16, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z12barAddHdlperii
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
new file mode 100644
index 00000000000000..489400c3ccaa63
--- /dev/null
+++ b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
@@ -0,0 +1,84 @@
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
+
+
+ .text
+ .file "helper.cpp"
+ .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .p2align 4, 0x90
+ .type _Z12barAddHdlperii, at function
+_Z12barAddHdlperii: # @_Z12barAddHdlperii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
+ .cfi_endproc
+ # -- End function
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $16, %rsp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %edi
+ movl -8(%rbp), %esi
+ callq _Z12barAddHdlperii
+ addl $5, %eax
+ addq $16, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z12barAddHdlperii
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
new file mode 100644
index 00000000000000..489400c3ccaa63
--- /dev/null
+++ b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
@@ -0,0 +1,84 @@
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
+
+
+ .text
+ .file "helper.cpp"
+ .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .p2align 4, 0x90
+ .type _Z12barAddHdlperii, at function
+_Z12barAddHdlperii: # @_Z12barAddHdlperii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
+ .cfi_endproc
+ # -- End function
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $16, %rsp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %edi
+ movl -8(%rbp), %esi
+ callq _Z12barAddHdlperii
+ addl $5, %eax
+ addq $16, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z12barAddHdlperii
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
new file mode 100644
index 00000000000000..489400c3ccaa63
--- /dev/null
+++ b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
@@ -0,0 +1,84 @@
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
+
+
+ .text
+ .file "helper.cpp"
+ .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .p2align 4, 0x90
+ .type _Z12barAddHdlperii, at function
+_Z12barAddHdlperii: # @_Z12barAddHdlperii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
+ .cfi_endproc
+ # -- End function
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $16, %rsp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %edi
+ movl -8(%rbp), %esi
+ callq _Z12barAddHdlperii
+ addl $5, %eax
+ addq $16, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z12barAddHdlperii
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
new file mode 100644
index 00000000000000..c113f1b45ac1a2
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
@@ -0,0 +1,339 @@
+# clang++ main.cpp -c -o
+# #define MY_CONST const
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# MY_CONST int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
+# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFKiiiEii, at function
+_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $32, %rsp
+ movq %rdi, -16(%rbp)
+ movl %esi, -20(%rbp)
+ movl %edx, -24(%rbp)
+ movabsq $_Z6barAddii, %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+# %bb.1:
+ movl $1, -4(%rbp)
+ jmp .LBB6_3
+.LBB6_2:
+ movq -16(%rbp), %rax
+ movl -20(%rbp), %edi
+ movl -24(%rbp), %esi
+ callq *%rax
+ subl $4, %eax
+ movl %eax, -4(%rbp)
+.LBB6_3:
+ movl -4(%rbp), %eax
+ addq $32, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFKiiiES1_ii, at function
+_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movq %rdi, -16(%rbp)
+ movq %rsi, -24(%rbp)
+ movl %edx, -28(%rbp)
+ movl %ecx, -32(%rbp)
+ movq -16(%rbp), %rax
+ cmpq -24(%rbp), %rax
+ jne .LBB7_2
+# %bb.1:
+ movl $2, -4(%rbp)
+ jmp .LBB7_3
+.LBB7_2:
+ movq -16(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq -24(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -4(%rbp)
+.LBB7_3:
+ movl -4(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+ movl FooVar, %esi
+ movl BarVar, %edx
+ movabsq $_Z6barAddii, %rdi
+ callq _Z7helper1PFKiiiEii
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movl FooVar, %edx
+ movl BarVar, %ecx
+ movabsq $_Z6fooMulii, %rdi
+ movabsq $_Z6barMulii, %rsi
+ callq _Z7helper2PFKiiiES1_ii
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -32(%rbp) # 4-byte Spill
+ movl FooVar, %edi
+ movl BarVar, %esi
+ callq _Z6fooSubii
+ movl %eax, %ecx
+ movl -32(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -28(%rbp) # 4-byte Spill
+ movl FooVar, %edi
+ movl BarVar, %esi
+ callq _Z6barSubii
+ movl %eax, %ecx
+ movl -28(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -24(%rbp) # 4-byte Spill
+ movl FooVar, %edi
+ movl BarVar, %esi
+ callq _Z6fooAddii
+ movl %eax, %ecx
+ movl -24(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -20(%rbp)
+ movl -20(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooSubii
+ .addrsig_sym _Z6barSubii
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6barMulii
+ .addrsig_sym _Z6fooAddii
+ .addrsig_sym _Z6barAddii
+ .addrsig_sym _Z7helper1PFKiiiEii
+ .addrsig_sym _Z7helper2PFKiiiES1_ii
+ .addrsig_sym FooVar
+ .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
new file mode 100644
index 00000000000000..40f30cbbc30550
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
@@ -0,0 +1,343 @@
+# clang++ main.cpp -c -o
+# #define MY_CONST const
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# MY_CONST int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# extern MY_CONST int barAddHdlper(int a, int b);
+# extern MY_CONST int fooGlobalFuncHelper(int a, int b);
+# MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
+# MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFKiiiEii, at function
+_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $32, %rsp
+ movq %rdi, -16(%rbp)
+ movl %esi, -20(%rbp)
+ movl %edx, -24(%rbp)
+ movabsq $_Z6barAddii, %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+# %bb.1:
+ movl $1, -4(%rbp)
+ jmp .LBB6_3
+.LBB6_2:
+ movq -16(%rbp), %rax
+ movl -20(%rbp), %edi
+ movl -24(%rbp), %esi
+ callq *%rax
+ subl $4, %eax
+ movl %eax, -4(%rbp)
+.LBB6_3:
+ movl -4(%rbp), %eax
+ addq $32, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFKiiiES1_ii, at function
+_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movq %rdi, -16(%rbp)
+ movq %rsi, -24(%rbp)
+ movl %edx, -28(%rbp)
+ movl %ecx, -32(%rbp)
+ movq -16(%rbp), %rax
+ cmpq -24(%rbp), %rax
+ jne .LBB7_2
+# %bb.1:
+ movl $2, -4(%rbp)
+ jmp .LBB7_3
+.LBB7_2:
+ movq -16(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq -24(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -4(%rbp)
+.LBB7_3:
+ movl -4(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+ movl FooVar, %esi
+ movl BarVar, %edx
+ movabsq $_Z12barAddHdlperii, %rdi
+ callq _Z7helper1PFKiiiEii
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movl FooVar, %edx
+ movl BarVar, %ecx
+ movabsq $_Z6fooMulii, %rdi
+ movabsq $_Z19fooGlobalFuncHelperii, %rsi
+ callq _Z7helper2PFKiiiES1_ii
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -32(%rbp) # 4-byte Spill
+ movl FooVar, %edi
+ movl BarVar, %esi
+ callq _Z6fooSubii
+ movl %eax, %ecx
+ movl -32(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -28(%rbp) # 4-byte Spill
+ movl FooVar, %edi
+ movl BarVar, %esi
+ callq _Z6barSubii
+ movl %eax, %ecx
+ movl -28(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -24(%rbp) # 4-byte Spill
+ movl FooVar, %edi
+ movl BarVar, %esi
+ callq _Z6fooAddii
+ movl %eax, %ecx
+ movl -24(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -20(%rbp)
+ movl -20(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooSubii
+ .addrsig_sym _Z6barSubii
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6fooAddii
+ .addrsig_sym _Z6barAddii
+ .addrsig_sym _Z7helper1PFKiiiEii
+ .addrsig_sym _Z7helper2PFKiiiES1_ii
+ .addrsig_sym _Z12barAddHdlperii
+ .addrsig_sym _Z19fooGlobalFuncHelperii
+ .addrsig_sym FooVar
+ .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
new file mode 100644
index 00000000000000..16976abc7d081c
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
@@ -0,0 +1,350 @@
+# clang++ main.cpp -c -o
+# #define MY_CONST const
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# MY_CONST int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
+# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFKiiiEii, at function
+_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $32, %rsp
+ movq %rdi, -16(%rbp)
+ movl %esi, -20(%rbp)
+ movl %edx, -24(%rbp)
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+# %bb.1:
+ movl $1, -4(%rbp)
+ jmp .LBB6_3
+.LBB6_2:
+ movq -16(%rbp), %rax
+ movl -20(%rbp), %edi
+ movl -24(%rbp), %esi
+ callq *%rax
+ subl $4, %eax
+ movl %eax, -4(%rbp)
+.LBB6_3:
+ movl -4(%rbp), %eax
+ addq $32, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFKiiiES1_ii, at function
+_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movq %rdi, -16(%rbp)
+ movq %rsi, -24(%rbp)
+ movl %edx, -28(%rbp)
+ movl %ecx, -32(%rbp)
+ movq -16(%rbp), %rax
+ cmpq -24(%rbp), %rax
+ jne .LBB7_2
+# %bb.1:
+ movl $2, -4(%rbp)
+ jmp .LBB7_3
+.LBB7_2:
+ movq -16(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq -24(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -4(%rbp)
+.LBB7_3:
+ movl -4(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFKiiiEii
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %ecx
+ leaq _Z6fooMulii(%rip), %rdi
+ leaq _Z6barMulii(%rip), %rsi
+ callq _Z7helper2PFKiiiES1_ii
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -32(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooSubii
+ movl %eax, %ecx
+ movl -32(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -28(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6barSubii
+ movl %eax, %ecx
+ movl -28(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -24(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooAddii
+ movl %eax, %ecx
+ movl -24(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -20(%rbp)
+ movl -20(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooSubii
+ .addrsig_sym _Z6barSubii
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6barMulii
+ .addrsig_sym _Z6fooAddii
+ .addrsig_sym _Z6barAddii
+ .addrsig_sym _Z7helper1PFKiiiEii
+ .addrsig_sym _Z7helper2PFKiiiES1_ii
+ .addrsig_sym FooVar
+ .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
new file mode 100644
index 00000000000000..a7da985b93bc38
--- /dev/null
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
@@ -0,0 +1,364 @@
+# clang++ main.cpp -c -o
+# #define MY_CONST const
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# MY_CONST int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# extern MY_CONST int barAddHdlper(int a, int b);
+# extern MY_CONST int fooGlobalFuncHelper(int a, int b);
+# MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
+# MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ subl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+ movl %esi, -8(%rbp)
+ movl -4(%rbp), %eax
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFKiiiEii, at function
+_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $32, %rsp
+ movq %rdi, -16(%rbp)
+ movl %esi, -20(%rbp)
+ movl %edx, -24(%rbp)
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+# %bb.1:
+ movl $1, -4(%rbp)
+ jmp .LBB6_3
+.LBB6_2:
+ movq -16(%rbp), %rax
+ movl -20(%rbp), %edi
+ movl -24(%rbp), %esi
+ callq *%rax
+ subl $4, %eax
+ movl %eax, -4(%rbp)
+.LBB6_3:
+ movl -4(%rbp), %eax
+ addq $32, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFKiiiES1_ii, at function
+_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movq %rdi, -16(%rbp)
+ movq %rsi, -24(%rbp)
+ movl %edx, -28(%rbp)
+ movl %ecx, -32(%rbp)
+ movq -16(%rbp), %rax
+ cmpq -24(%rbp), %rax
+ jne .LBB7_2
+# %bb.1:
+ movl $2, -4(%rbp)
+ jmp .LBB7_3
+.LBB7_2:
+ movq -16(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq -24(%rbp), %rax
+ movl -28(%rbp), %edi
+ movl -32(%rbp), %esi
+ callq *%rax
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -4(%rbp)
+.LBB7_3:
+ movl -4(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+# %bb.0:
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ subq $48, %rsp
+ movl $0, -4(%rbp)
+ movl %edi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ movq _Z12barAddHdlperii at GOTPCREL(%rip), %rdi
+ callq _Z7helper1PFKiiiEii
+ movl %eax, -36(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edx
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %ecx
+ leaq _Z6fooMulii(%rip), %rdi
+ movq _Z19fooGlobalFuncHelperii at GOTPCREL(%rip), %rsi
+ callq _Z7helper2PFKiiiES1_ii
+ movl %eax, %ecx
+ movl -36(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -32(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooSubii
+ movl %eax, %ecx
+ movl -32(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -28(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6barSubii
+ movl %eax, %ecx
+ movl -28(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -24(%rbp) # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movl (%rax), %edi
+ movq BarVar at GOTPCREL(%rip), %rax
+ movl (%rax), %esi
+ callq _Z6fooAddii
+ movl %eax, %ecx
+ movl -24(%rbp), %eax # 4-byte Reload
+ addl %ecx, %eax
+ movl %eax, -20(%rbp)
+ movl -20(%rbp), %esi
+ leaq .L.str(%rip), %rdi
+ movb $0, %al
+ callq printf at PLT
+ movl -20(%rbp), %eax
+ addq $48, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .type .L.str, at object # @.str
+ .section .rodata.str1.1,"aMS", at progbits,1
+.L.str:
+ .asciz "val: %d\n"
+ .size .L.str, 9
+
+ .ident "clang version 20.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym _Z6fooSubii
+ .addrsig_sym _Z6barSubii
+ .addrsig_sym _Z6fooMulii
+ .addrsig_sym _Z6fooAddii
+ .addrsig_sym _Z6barAddii
+ .addrsig_sym _Z7helper1PFKiiiEii
+ .addrsig_sym _Z7helper2PFKiiiES1_ii
+ .addrsig_sym _Z12barAddHdlperii
+ .addrsig_sym _Z19fooGlobalFuncHelperii
+ .addrsig_sym printf
+ .addrsig_sym FooVar
+ .addrsig_sym BarVar
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
new file mode 100644
index 00000000000000..332c4296f45e5f
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -0,0 +1,24 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## This checks global const function pointer in -fno-pic mode is handled correctly.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrNoPic.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFGlobalConstPtrNoPic.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q -no-pie
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
new file mode 100644
index 00000000000000..a46fdb86574c0b
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
@@ -0,0 +1,24 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## This checks global const function pointer in -fno-pic mode is handled correctly.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q -no-pie
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z12barAddHdlperii
+# SAFEICFCHECK-NEXT: skipping function _Z19fooGlobalFuncHelperii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
new file mode 100644
index 00000000000000..ab84fdc619ae9b
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -0,0 +1,24 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## This checks global const function pointer in -fpic mode is handled correctly.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrPic.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFGlobalConstPtrPic.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
new file mode 100644
index 00000000000000..f416f8f5f4f9c8
--- /dev/null
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -0,0 +1,24 @@
+## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## This checks global const function pointer with external function reference in -fpic mode is handled correctly.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+## Check that BOLT successfully folded a function with jump table:
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
+# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+
+# SAFEICFCHECK: skipping function _Z12barAddHdlperii
+# SAFEICFCHECK-NEXT: skipping function _Z19fooGlobalFuncHelperii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: ===---------
>From e36ec02bfeb440e56a9b8593f454a9e7f2fe7ed5 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Fri, 15 Nov 2024 18:17:01 -0800
Subject: [PATCH 05/34] switched to enum version of icf compile option
---
bolt/lib/Core/BinaryContext.cpp | 24 +++++++++++-------------
bolt/test/X86/shared_object_entry.s | 2 +-
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 960849371660b2..aaa7a125e94147 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -76,8 +76,16 @@ cl::opt<std::string> CompDirOverride(
"to *.dwo files."),
cl::Hidden, cl::init(""), cl::cat(BoltCategory));
-cl::opt<std::string> ICF("icf", cl::desc("fold functions with identical code"),
- cl::ValueOptional, cl::cat(BoltOptCategory));
+cl::opt<bolt::BinaryContext::ICFLevel> ICF(
+ "icf", cl::desc("fold functions with identical code"),
+ cl::init(bolt::BinaryContext::ICFLevel::None),
+ cl::values(
+ clEnumValN(bolt::BinaryContext::ICFLevel::All, "all", "enable ICF"),
+ clEnumValN(bolt::BinaryContext::ICFLevel::All, "", "enable ICF"),
+ clEnumValN(bolt::BinaryContext::ICFLevel::None, "none", "disable ICF"),
+ clEnumValN(bolt::BinaryContext::ICFLevel::Safe, "safe",
+ "enable safe ICF")),
+ cl::ZeroOrMore, cl::ValueOptional, cl::cat(BoltOptCategory));
} // namespace opts
namespace {
@@ -171,16 +179,6 @@ void BinaryContext::logBOLTErrorsAndQuitOnFatal(Error E) {
});
}
-static BinaryContext::ICFLevel parseICFLevel() {
- if (!opts::ICF.getNumOccurrences())
- return BinaryContext::ICFLevel::None;
- std::string Str = StringRef(opts::ICF).lower();
- return StringSwitch<BinaryContext::ICFLevel>(Str)
- .Case("all", BinaryContext::ICFLevel::All)
- .Case("safe", BinaryContext::ICFLevel::Safe)
- .Default(BinaryContext::ICFLevel::All);
-}
-
BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
std::unique_ptr<DWARFContext> DwCtx,
std::unique_ptr<Triple> TheTriple,
@@ -205,7 +203,7 @@ BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
Logger(Logger), InitialDynoStats(isAArch64()) {
RegularPageSize = isAArch64() ? RegularPageSizeAArch64 : RegularPageSizeX86;
PageAlign = opts::NoHugePages ? RegularPageSize : HugePageSize;
- CurrICFLevel = parseICFLevel();
+ CurrICFLevel = opts::ICF;
}
BinaryContext::~BinaryContext() {
diff --git a/bolt/test/X86/shared_object_entry.s b/bolt/test/X86/shared_object_entry.s
index 87a3c0655533d1..2caab5afdb7805 100644
--- a/bolt/test/X86/shared_object_entry.s
+++ b/bolt/test/X86/shared_object_entry.s
@@ -2,7 +2,7 @@
# RUN: ld.lld %t.o -o %t.so --shared --entry=func1.cold.1 --emit-relocs
# RUN: llvm-bolt -relocs %t.so -o %t -reorder-functions=hfsort+ \
# RUN: -split-functions -reorder-blocks=ext-tsp -split-all-cold \
-# RUN: -dyno-stats -icf=1 -use-gnu-stack
+# RUN: -dyno-stats -icf -use-gnu-stack
## Check that an entry point is a cold symbol
# RUN: llvm-readelf -h %t.so > %t.log
>From b83c3350ec08623350c1639347cb9f8e71850fba Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 19 Nov 2024 16:21:32 -0800
Subject: [PATCH 06/34] simplified debug print, removed shared func
---
.../bolt/Passes/IdenticalCodeFolding.h | 2 ++
bolt/lib/Passes/IdenticalCodeFolding.cpp | 29 +++++--------------
bolt/test/X86/icf-safe-test1-no-cfg.test | 4 +--
bolt/test/X86/icf-safe-test1.test | 4 +--
.../icf-safe-test2GlobalConstPtrNoPic.test | 4 +--
...fe-test2GlobalConstPtrNoPicExtFuncRef.test | 6 ++--
.../X86/icf-safe-test2GlobalConstPtrPic.test | 4 +--
...safe-test2GlobalConstPtrPicExtFuncRef.test | 6 ++--
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 4 +--
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 4 +--
bolt/test/X86/icf-safe-test3LocalVarO0.test | 4 +--
bolt/test/X86/icf-safe-test3LocalVarO3.test | 4 +--
12 files changed, 32 insertions(+), 43 deletions(-)
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index eb803031bf0f0e..9d8d3ece1a2edf 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -27,6 +27,8 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
return false;
if (BF.hasSDTMarker())
return false;
+ if (!BF.isSafeToICF())
+ return false;
return BinaryFunctionPass::shouldOptimize(BF);
}
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 8fb22897a44f62..2114bfe874bd18 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -393,22 +393,12 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
"markUnsafe", /*ForceSequential*/ false, 2);
LLVM_DEBUG({
- std::vector<StringRef> Vect;
- std::mutex PrintMutex;
- ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
- if (BF.isSafeToICF())
- return;
- std::lock_guard<std::mutex> Lock(PrintMutex);
- Vect.push_back(BF.getOneName());
- };
- ParallelUtilities::PredicateTy SkipFunc =
- [&](const BinaryFunction &BF) -> bool { return false; };
- ParallelUtilities::runOnEachFunction(
- BC, ParallelUtilities::SchedulingPolicy::SP_TRIVIAL, WorkFun, SkipFunc,
- "markUnsafe", /*ForceSequential*/ false, 2);
- llvm::sort(Vect);
- for (const auto &FuncName : Vect)
- dbgs() << "BOLT-DEBUG: skipping function " << FuncName << '\n';
+ for (auto &BFIter : BC.getBinaryFunctions()) {
+ if (BFIter.second.isSafeToICF())
+ continue;
+ dbgs() << "BOLT-DEBUG: skipping function " << BFIter.second.getOneName()
+ << '\n';
+ }
});
return ErrorStatus;
}
@@ -422,9 +412,6 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
std::atomic<uint64_t> NumFoldedLastIteration{0};
CongruentBucketsMap CongruentBuckets;
- auto SkipFuncShared = [&](const BinaryFunction &BF) {
- return !shouldOptimize(BF) || !BF.isSafeToICF();
- };
// Hash all the functions
auto hashFunctions = [&]() {
NamedRegionTimer HashFunctionsTimer("hashing", "hashing", "ICF breakdown",
@@ -444,7 +431,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
};
ParallelUtilities::PredicateTy SkipFunc = [&](const BinaryFunction &BF) {
- return SkipFuncShared(BF);
+ return !shouldOptimize(BF);
};
ParallelUtilities::runOnEachFunction(
@@ -460,7 +447,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
"ICF breakdown", opts::TimeICF);
for (auto &BFI : BC.getBinaryFunctions()) {
BinaryFunction &BF = BFI.second;
- if (SkipFuncShared(BF))
+ if (!shouldOptimize(BF))
continue;
CongruentBuckets[&BF].emplace(&BF);
}
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index 5efbff9b3f3f76..8617dfa590d941 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -13,9 +13,9 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index 96986dec1e1922..b60795d7fa3bee 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -13,9 +13,9 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index 332c4296f45e5f..83e7e798afcd8c 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -15,9 +15,9 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
index a46fdb86574c0b..bef5b71a25c4f6 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
@@ -15,10 +15,10 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z12barAddHdlperii
-# SAFEICFCHECK-NEXT: skipping function _Z19fooGlobalFuncHelperii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z12barAddHdlperii
+# SAFEICFCHECK-NEXT: skipping function _Z19fooGlobalFuncHelperii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
index ab84fdc619ae9b..d2c039769e8d23 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -15,9 +15,9 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
index f416f8f5f4f9c8..2a93af6d44220c 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -15,10 +15,10 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z12barAddHdlperii
-# SAFEICFCHECK-NEXT: skipping function _Z19fooGlobalFuncHelperii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z12barAddHdlperii
+# SAFEICFCHECK-NEXT: skipping function _Z19fooGlobalFuncHelperii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index 9464dc05782ee5..de5c1ebca81e17 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -13,9 +13,9 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index 935a5ddb189ef7..06853bfe328904 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -13,9 +13,9 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
index 9fb783539da39f..0a88cca49e1bd4 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -13,9 +13,9 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index 55fa11ada15490..d961980df15be6 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -13,9 +13,9 @@
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
-# SAFEICFCHECK: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6fooMulii
+# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
>From 39c79029a60b07646bcd764b469057a05f3a659e Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 19 Nov 2024 17:59:05 -0800
Subject: [PATCH 07/34] updated tests
---
.../Inputs/helperSafeICFGlobalConstPtrNoPic.s | 59 --------
.../Inputs/helperSafeICFGlobalConstPtrPic.s | 60 --------
.../Inputs/mainSafeICFGlobalConstPtrNoPic.s | 133 +++++-------------
.../X86/Inputs/mainSafeICFGlobalConstPtrPic.s | 127 ++++-------------
bolt/test/X86/icf-safe-icp.test | 1 -
bolt/test/X86/icf-safe-test1-no-cfg.test | 1 -
bolt/test/X86/icf-safe-test1-no-relocs.test | 1 -
bolt/test/X86/icf-safe-test1.test | 1 -
.../icf-safe-test2GlobalConstPtrNoPic.test | 5 -
...fe-test2GlobalConstPtrNoPicExtFuncRef.test | 1 -
.../X86/icf-safe-test2GlobalConstPtrPic.test | 5 -
...safe-test2GlobalConstPtrPicExtFuncRef.test | 1 -
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 1 -
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 1 -
bolt/test/X86/icf-safe-test3LocalVarO0.test | 1 -
bolt/test/X86/icf-safe-test3LocalVarO3.test | 1 -
16 files changed, 65 insertions(+), 334 deletions(-)
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
index 8697f77862e66f..a970897fa0771b 100644
--- a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
+++ b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
@@ -2,66 +2,8 @@
# #define MY_CONST const
# int FooVar = 1;
# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-
.text
.file "helper.cpp"
- .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
- .p2align 4, 0x90
- .type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii: # @_Z12barAddHdlperii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
- addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end0:
- .size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
- .cfi_endproc
- # -- End function
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $16, %rsp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %edi
- movl -8(%rbp), %esi
- callq _Z12barAddHdlperii
- addl $5, %eax
- addq $16, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end1:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
.type FooVar, at object # @FooVar
.data
.globl FooVar
@@ -80,4 +22,3 @@ BarVar:
.ident "clang version 20.0.0git"
.section ".note.GNU-stack","", at progbits
.addrsig
- .addrsig_sym _Z12barAddHdlperii
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
index 489400c3ccaa63..a970897fa0771b 100644
--- a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
+++ b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
@@ -2,67 +2,8 @@
# #define MY_CONST const
# int FooVar = 1;
# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-
-
.text
.file "helper.cpp"
- .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
- .p2align 4, 0x90
- .type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii: # @_Z12barAddHdlperii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
- addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end0:
- .size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
- .cfi_endproc
- # -- End function
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $16, %rsp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %edi
- movl -8(%rbp), %esi
- callq _Z12barAddHdlperii
- addl $5, %eax
- addq $16, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end1:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
.type FooVar, at object # @FooVar
.data
.globl FooVar
@@ -81,4 +22,3 @@ BarVar:
.ident "clang version 20.0.0git"
.section ".note.GNU-stack","", at progbits
.addrsig
- .addrsig_sym _Z12barAddHdlperii
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
index c113f1b45ac1a2..11465a0b1ffd0a 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
@@ -3,14 +3,6 @@
# extern int FooVar;
# extern int BarVar;
# [[clang::noinline]]
-# MY_CONST int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
# MY_CONST int fooMul(int a, int b) {
# return a * b;
# }
@@ -42,57 +34,13 @@
# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
# int main(int argc, char **argv) {
# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar)
+# fooAdd(FooVar, BarVar);
# MY_PRINTF("val: %d", temp);
# return temp;
# }
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
- subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
- subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
.globl _Z6fooMulii # -- Begin function _Z6fooMulii
.p2align 4, 0x90
.type _Z6fooMulii, at function
@@ -111,8 +59,8 @@ _Z6fooMulii: # @_Z6fooMulii
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+.Lfunc_end0:
+ .size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
.cfi_endproc
# -- End function
.globl _Z6barMulii # -- Begin function _Z6barMulii
@@ -133,8 +81,8 @@ _Z6barMulii: # @_Z6barMulii
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+.Lfunc_end1:
+ .size _Z6barMulii, .Lfunc_end1-_Z6barMulii
.cfi_endproc
# -- End function
.globl _Z6fooAddii # -- Begin function _Z6fooAddii
@@ -155,8 +103,8 @@ _Z6fooAddii: # @_Z6fooAddii
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+.Lfunc_end2:
+ .size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
.cfi_endproc
# -- End function
.globl _Z6barAddii # -- Begin function _Z6barAddii
@@ -177,8 +125,8 @@ _Z6barAddii: # @_Z6barAddii
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+.Lfunc_end3:
+ .size _Z6barAddii, .Lfunc_end3-_Z6barAddii
.cfi_endproc
# -- End function
.globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
@@ -198,25 +146,25 @@ _Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
movl %edx, -24(%rbp)
movabsq $_Z6barAddii, %rax
cmpq %rax, -16(%rbp)
- jne .LBB6_2
+ jne .LBB4_2
# %bb.1:
movl $1, -4(%rbp)
- jmp .LBB6_3
-.LBB6_2:
+ jmp .LBB4_3
+.LBB4_2:
movq -16(%rbp), %rax
movl -20(%rbp), %edi
movl -24(%rbp), %esi
callq *%rax
subl $4, %eax
movl %eax, -4(%rbp)
-.LBB6_3:
+.LBB4_3:
movl -4(%rbp), %eax
addq $32, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end6:
- .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+.Lfunc_end4:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
.cfi_endproc
# -- End function
.globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
@@ -237,11 +185,11 @@ _Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
movl %ecx, -32(%rbp)
movq -16(%rbp), %rax
cmpq -24(%rbp), %rax
- jne .LBB7_2
+ jne .LBB5_2
# %bb.1:
movl $2, -4(%rbp)
- jmp .LBB7_3
-.LBB7_2:
+ jmp .LBB5_3
+.LBB5_2:
movq -16(%rbp), %rax
movl -28(%rbp), %edi
movl -32(%rbp), %esi
@@ -255,14 +203,14 @@ _Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
movl -36(%rbp), %eax # 4-byte Reload
addl %ecx, %eax
movl %eax, -4(%rbp)
-.LBB7_3:
+.LBB5_3:
movl -4(%rbp), %eax
addq $48, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end7:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+.Lfunc_end5:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
.cfi_endproc
# -- End function
.globl main # -- Begin function main
@@ -276,7 +224,7 @@ main: # @main
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
- subq $48, %rsp
+ subq $32, %rsp
movl $0, -4(%rbp)
movl %edi, -8(%rbp)
movq %rsi, -16(%rbp)
@@ -284,27 +232,13 @@ main: # @main
movl BarVar, %edx
movabsq $_Z6barAddii, %rdi
callq _Z7helper1PFKiiiEii
- movl %eax, -36(%rbp) # 4-byte Spill
+ movl %eax, -28(%rbp) # 4-byte Spill
movl FooVar, %edx
movl BarVar, %ecx
movabsq $_Z6fooMulii, %rdi
movabsq $_Z6barMulii, %rsi
callq _Z7helper2PFKiiiES1_ii
movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -32(%rbp) # 4-byte Spill
- movl FooVar, %edi
- movl BarVar, %esi
- callq _Z6fooSubii
- movl %eax, %ecx
- movl -32(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -28(%rbp) # 4-byte Spill
- movl FooVar, %edi
- movl BarVar, %esi
- callq _Z6barSubii
- movl %eax, %ecx
movl -28(%rbp), %eax # 4-byte Reload
addl %ecx, %eax
movl %eax, -24(%rbp) # 4-byte Spill
@@ -315,25 +249,34 @@ main: # @main
movl -24(%rbp), %eax # 4-byte Reload
addl %ecx, %eax
movl %eax, -20(%rbp)
+ movl -20(%rbp), %esi
+ movabsq $.L.str, %rdi
+ movb $0, %al
+ callq printf
movl -20(%rbp), %eax
- addq $48, %rsp
+ addq $32, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
+.Lfunc_end6:
+ .size main, .Lfunc_end6-main
.cfi_endproc
# -- End function
+ .type .L.str, at object # @.str
+ .section .rodata.str1.1,"aMS", at progbits,1
+.L.str:
+ .asciz "val: %d\n"
+ .size .L.str, 9
+
.ident "clang version 20.0.0git"
.section ".note.GNU-stack","", at progbits
.addrsig
- .addrsig_sym _Z6fooSubii
- .addrsig_sym _Z6barSubii
.addrsig_sym _Z6fooMulii
.addrsig_sym _Z6barMulii
.addrsig_sym _Z6fooAddii
.addrsig_sym _Z6barAddii
.addrsig_sym _Z7helper1PFKiiiEii
.addrsig_sym _Z7helper2PFKiiiES1_ii
+ .addrsig_sym printf
.addrsig_sym FooVar
.addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
index 16976abc7d081c..3c878a7de8e6b8 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
@@ -3,14 +3,6 @@
# extern int FooVar;
# extern int BarVar;
# [[clang::noinline]]
-# MY_CONST int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
# MY_CONST int fooMul(int a, int b) {
# return a * b;
# }
@@ -42,58 +34,13 @@
# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
# int main(int argc, char **argv) {
# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) +
+# fooAdd(FooVar, BarVar);
# MY_PRINTF("val: %d", temp);
# return temp;
# }
-
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
- subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
- subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
.globl _Z6fooMulii # -- Begin function _Z6fooMulii
.p2align 4, 0x90
.type _Z6fooMulii, at function
@@ -112,8 +59,8 @@ _Z6fooMulii: # @_Z6fooMulii
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+.Lfunc_end0:
+ .size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
.cfi_endproc
# -- End function
.globl _Z6barMulii # -- Begin function _Z6barMulii
@@ -134,8 +81,8 @@ _Z6barMulii: # @_Z6barMulii
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+.Lfunc_end1:
+ .size _Z6barMulii, .Lfunc_end1-_Z6barMulii
.cfi_endproc
# -- End function
.globl _Z6fooAddii # -- Begin function _Z6fooAddii
@@ -156,8 +103,8 @@ _Z6fooAddii: # @_Z6fooAddii
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+.Lfunc_end2:
+ .size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
.cfi_endproc
# -- End function
.globl _Z6barAddii # -- Begin function _Z6barAddii
@@ -178,8 +125,8 @@ _Z6barAddii: # @_Z6barAddii
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+.Lfunc_end3:
+ .size _Z6barAddii, .Lfunc_end3-_Z6barAddii
.cfi_endproc
# -- End function
.globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
@@ -199,25 +146,25 @@ _Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
movl %edx, -24(%rbp)
leaq _Z6barAddii(%rip), %rax
cmpq %rax, -16(%rbp)
- jne .LBB6_2
+ jne .LBB4_2
# %bb.1:
movl $1, -4(%rbp)
- jmp .LBB6_3
-.LBB6_2:
+ jmp .LBB4_3
+.LBB4_2:
movq -16(%rbp), %rax
movl -20(%rbp), %edi
movl -24(%rbp), %esi
callq *%rax
subl $4, %eax
movl %eax, -4(%rbp)
-.LBB6_3:
+.LBB4_3:
movl -4(%rbp), %eax
addq $32, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end6:
- .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+.Lfunc_end4:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
.cfi_endproc
# -- End function
.globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
@@ -238,11 +185,11 @@ _Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
movl %ecx, -32(%rbp)
movq -16(%rbp), %rax
cmpq -24(%rbp), %rax
- jne .LBB7_2
+ jne .LBB5_2
# %bb.1:
movl $2, -4(%rbp)
- jmp .LBB7_3
-.LBB7_2:
+ jmp .LBB5_3
+.LBB5_2:
movq -16(%rbp), %rax
movl -28(%rbp), %edi
movl -32(%rbp), %esi
@@ -256,14 +203,14 @@ _Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
movl -36(%rbp), %eax # 4-byte Reload
addl %ecx, %eax
movl %eax, -4(%rbp)
-.LBB7_3:
+.LBB5_3:
movl -4(%rbp), %eax
addq $48, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end7:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+.Lfunc_end5:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
.cfi_endproc
# -- End function
.globl main # -- Begin function main
@@ -277,7 +224,7 @@ main: # @main
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
- subq $48, %rsp
+ subq $32, %rsp
movl $0, -4(%rbp)
movl %edi, -8(%rbp)
movq %rsi, -16(%rbp)
@@ -287,7 +234,7 @@ main: # @main
movl (%rax), %edx
leaq _Z6barAddii(%rip), %rdi
callq _Z7helper1PFKiiiEii
- movl %eax, -36(%rbp) # 4-byte Spill
+ movl %eax, -28(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
movl (%rax), %edx
movq BarVar at GOTPCREL(%rip), %rax
@@ -296,24 +243,6 @@ main: # @main
leaq _Z6barMulii(%rip), %rsi
callq _Z7helper2PFKiiiES1_ii
movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -32(%rbp) # 4-byte Spill
- movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
- movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
- callq _Z6fooSubii
- movl %eax, %ecx
- movl -32(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -28(%rbp) # 4-byte Spill
- movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
- movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
- callq _Z6barSubii
- movl %eax, %ecx
movl -28(%rbp), %eax # 4-byte Reload
addl %ecx, %eax
movl %eax, -24(%rbp) # 4-byte Spill
@@ -327,19 +256,17 @@ main: # @main
addl %ecx, %eax
movl %eax, -20(%rbp)
movl -20(%rbp), %eax
- addq $48, %rsp
+ addq $32, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
+.Lfunc_end6:
+ .size main, .Lfunc_end6-main
.cfi_endproc
# -- End function
.ident "clang version 20.0.0git"
.section ".note.GNU-stack","", at progbits
.addrsig
- .addrsig_sym _Z6fooSubii
- .addrsig_sym _Z6barSubii
.addrsig_sym _Z6fooMulii
.addrsig_sym _Z6barMulii
.addrsig_sym _Z6fooAddii
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index 7b46c6297a40ec..a88a31c620330c 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -8,7 +8,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# ICFCHECK-NEXT: folding _ZNK8Derived34funcEii into _ZNK8Derived24funcEii
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index 8617dfa590d941..bbcac0a18977f1 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -7,7 +7,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=all -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf --skip-funcs=_Z7helper1PFiiiEii,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index c80d35a5f576ff..43be7f19af4bc8 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -7,7 +7,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: not llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index b60795d7fa3bee..89479102f1fda6 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -7,7 +7,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index 83e7e798afcd8c..fb72e8413ac8cc 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -8,17 +8,12 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
index bef5b71a25c4f6..fe8009d6087cc9 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
@@ -8,7 +8,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
index d2c039769e8d23..22d85b92a0454a 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -8,17 +8,12 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK: skipping function _Z6fooMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
index 2a93af6d44220c..9482ac688d8a72 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -8,7 +8,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index de5c1ebca81e17..cfe2dd0c745321 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -7,7 +7,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index 06853bfe328904..6557bb9107517c 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -7,7 +7,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
index 0a88cca49e1bd4..88d6249f405144 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -7,7 +7,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index d961980df15be6..64419fb568c2b8 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -7,7 +7,6 @@
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-## Check that BOLT successfully folded a function with jump table:
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
>From 39586b3fdf46f1ccda67789e274239081a58677f Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 19 Nov 2024 18:09:52 -0800
Subject: [PATCH 08/34] addressed comments
---
bolt/include/bolt/Core/BinaryContext.h | 6 +++---
bolt/include/bolt/Passes/IdenticalCodeFolding.h | 4 ++--
bolt/lib/Core/BinaryContext.cpp | 1 +
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 318535b2fac239..b7bbf6dcc5808a 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -277,9 +277,9 @@ class BinaryContext {
public:
enum class ICFLevel {
- None,
- Safe,
- All,
+ None, // No ICF. (Default)
+ Safe, // Safe ICF for all sections.
+ All, // Aggressive ICF for code.
};
static Expected<std::unique_ptr<BinaryContext>>
createBinaryContext(Triple TheTriple, StringRef InputFileName,
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index 9d8d3ece1a2edf..a7b49daa3cf6ad 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -40,10 +40,10 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
Error runOnFunctions(BinaryContext &BC) override;
private:
- /// Analyses .text section and relocations and marks functions that are not
+ /// Analyze .text section and relocations and mark functions that are not
/// safe to fold.
Error markFunctionsUnsafeToFold(BinaryContext &BC);
- /// Processes relocations in the .data section to identify function
+ /// Process relocations in the .data section to identify function
/// references.
void processDataRelocations(BinaryContext &BC,
const SectionRef &SecRefRelData);
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index aaa7a125e94147..8e74d3e5d31e1c 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -2015,6 +2015,7 @@ static void printDebugInfo(raw_ostream &OS, const MCInst &Instruction,
OS << " discriminator:" << Row.Discriminator;
}
+/// Skip instructions that are not interesting for safe ICF.
static bool skipInstruction(const MCInst &Inst, const BinaryContext &BC) {
const bool IsX86 = BC.isX86();
return (BC.MIB->isPseudo(Inst) || BC.MIB->isUnconditionalBranch(Inst) ||
>From debeb6f61b04f47120f9ce0f7995ed95251b6563 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 19 Nov 2024 18:19:09 -0800
Subject: [PATCH 09/34] updated icf option descriptions
---
bolt/docs/CommandLineArgumentReference.md | 5 ++++-
bolt/lib/Core/BinaryContext.cpp | 22 ++++++++++++----------
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/bolt/docs/CommandLineArgumentReference.md b/bolt/docs/CommandLineArgumentReference.md
index 6d3b797da3787e..91918d614a90f1 100644
--- a/bolt/docs/CommandLineArgumentReference.md
+++ b/bolt/docs/CommandLineArgumentReference.md
@@ -498,9 +498,12 @@
Automatically put hot code on 2MB page(s) (hugify) at runtime. No manual call
to hugify is needed in the binary (which is what --hot-text relies on).
-- `--icf`
+- `--icf=<value>`
Fold functions with identical code
+ - `all`: Enable identical code folding
+ - `none`: Disable identical code folding (default)
+ - `safe`: Enable safe identical code folding
- `--icp`
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 8e74d3e5d31e1c..4f96c99e2bd5c9 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -76,16 +76,18 @@ cl::opt<std::string> CompDirOverride(
"to *.dwo files."),
cl::Hidden, cl::init(""), cl::cat(BoltCategory));
-cl::opt<bolt::BinaryContext::ICFLevel> ICF(
- "icf", cl::desc("fold functions with identical code"),
- cl::init(bolt::BinaryContext::ICFLevel::None),
- cl::values(
- clEnumValN(bolt::BinaryContext::ICFLevel::All, "all", "enable ICF"),
- clEnumValN(bolt::BinaryContext::ICFLevel::All, "", "enable ICF"),
- clEnumValN(bolt::BinaryContext::ICFLevel::None, "none", "disable ICF"),
- clEnumValN(bolt::BinaryContext::ICFLevel::Safe, "safe",
- "enable safe ICF")),
- cl::ZeroOrMore, cl::ValueOptional, cl::cat(BoltOptCategory));
+cl::opt<bolt::BinaryContext::ICFLevel>
+ ICF("icf", cl::desc("fold functions with identical code"),
+ cl::init(bolt::BinaryContext::ICFLevel::None),
+ cl::values(clEnumValN(bolt::BinaryContext::ICFLevel::All, "all",
+ "Enable identical code folding"),
+ clEnumValN(bolt::BinaryContext::ICFLevel::All, "",
+ "Enable identical code folding"),
+ clEnumValN(bolt::BinaryContext::ICFLevel::None, "none",
+ "Disable identical code folding (default)"),
+ clEnumValN(bolt::BinaryContext::ICFLevel::Safe, "safe",
+ "Enable safe identical code folding")),
+ cl::ZeroOrMore, cl::ValueOptional, cl::cat(BoltOptCategory));
} // namespace opts
namespace {
>From 429075e4e0b0dc33b0c5e0c91bb8fdeca07d3392 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Wed, 20 Nov 2024 14:59:19 -0800
Subject: [PATCH 10/34] moved getRelocation* to Relocs.cpp
---
bolt/include/bolt/Core/BinaryContext.h | 6 ---
bolt/include/bolt/Core/Relocation.h | 7 +++
bolt/lib/Core/BinaryContext.cpp | 58 ----------------------
bolt/lib/Core/Relocation.cpp | 62 ++++++++++++++++++++++++
bolt/lib/Passes/IdenticalCodeFolding.cpp | 3 +-
bolt/lib/Rewrite/RewriteInstance.cpp | 6 +--
6 files changed, 73 insertions(+), 69 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index b7bbf6dcc5808a..0ea8276f4fe886 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -287,12 +287,6 @@ class BinaryContext {
std::unique_ptr<DWARFContext> DwCtx,
JournalingStreams Logger);
- /// Returns addend of a relocation.
- static int64_t getRelocationAddend(const ELFObjectFileBase *Obj,
- const RelocationRef &Rel);
- /// Returns symbol of a relocation.
- static uint32_t getRelocationSymbol(const ELFObjectFileBase *Obj,
- const RelocationRef &Rel);
/// Superset of compiler units that will contain overwritten code that needs
/// new debug info. In a few cases, functions may end up not being
/// overwritten, but it is okay to re-generate debug info for them.
diff --git a/bolt/include/bolt/Core/Relocation.h b/bolt/include/bolt/Core/Relocation.h
index 933f62a31f8fd7..1fe22e09912f75 100644
--- a/bolt/include/bolt/Core/Relocation.h
+++ b/bolt/include/bolt/Core/Relocation.h
@@ -16,6 +16,8 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/TargetParser/Triple.h"
namespace llvm {
@@ -178,6 +180,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Relocation &Rel) {
return OS;
}
+uint32_t getRelocationSymbol(const object::ELFObjectFileBase *Obj,
+ const object::RelocationRef &Rel);
+
+int64_t getRelocationAddend(const object::ELFObjectFileBase *Obj,
+ const object::RelocationRef &Rel);
} // namespace bolt
} // namespace llvm
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 4f96c99e2bd5c9..7489f9dc8c3d16 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -90,54 +90,6 @@ cl::opt<bolt::BinaryContext::ICFLevel>
cl::ZeroOrMore, cl::ValueOptional, cl::cat(BoltOptCategory));
} // namespace opts
-namespace {
-template <typename ELFT>
-int64_t getRelocationAddend(const ELFObjectFile<ELFT> *Obj,
- const RelocationRef &RelRef) {
- using ELFShdrTy = typename ELFT::Shdr;
- using Elf_Rela = typename ELFT::Rela;
- int64_t Addend = 0;
- const ELFFile<ELFT> &EF = Obj->getELFFile();
- DataRefImpl Rel = RelRef.getRawDataRefImpl();
- const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
- switch (RelocationSection->sh_type) {
- default:
- llvm_unreachable("unexpected relocation section type");
- case ELF::SHT_REL:
- break;
- case ELF::SHT_RELA: {
- const Elf_Rela *RelA = Obj->getRela(Rel);
- Addend = RelA->r_addend;
- break;
- }
- }
-
- return Addend;
-}
-
-template <typename ELFT>
-uint32_t getRelocationSymbol(const ELFObjectFile<ELFT> *Obj,
- const RelocationRef &RelRef) {
- using ELFShdrTy = typename ELFT::Shdr;
- uint32_t Symbol = 0;
- const ELFFile<ELFT> &EF = Obj->getELFFile();
- DataRefImpl Rel = RelRef.getRawDataRefImpl();
- const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
- switch (RelocationSection->sh_type) {
- default:
- llvm_unreachable("unexpected relocation section type");
- case ELF::SHT_REL:
- Symbol = Obj->getRel(Rel)->getSymbol(EF.isMips64EL());
- break;
- case ELF::SHT_RELA:
- Symbol = Obj->getRela(Rel)->getSymbol(EF.isMips64EL());
- break;
- }
-
- return Symbol;
-}
-} // anonymous namespace
-
namespace llvm {
namespace bolt {
@@ -218,16 +170,6 @@ BinaryContext::~BinaryContext() {
clearBinaryData();
}
-uint32_t BinaryContext::getRelocationSymbol(const ELFObjectFileBase *Obj,
- const RelocationRef &Rel) {
- return ::getRelocationSymbol(cast<ELF64LEObjectFile>(Obj), Rel);
-}
-
-int64_t BinaryContext::getRelocationAddend(const ELFObjectFileBase *Obj,
- const RelocationRef &Rel) {
- return ::getRelocationAddend(cast<ELF64LEObjectFile>(Obj), Rel);
-}
-
/// Create BinaryContext for a given architecture \p ArchName and
/// triple \p TripleName.
Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
diff --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp
index 4e888a5b147aca..c3c760d9262198 100644
--- a/bolt/lib/Core/Relocation.cpp
+++ b/bolt/lib/Core/Relocation.cpp
@@ -1115,3 +1115,65 @@ void Relocation::print(raw_ostream &OS) const {
OS << ", 0x" << Twine::utohexstr(Addend);
OS << ", 0x" << Twine::utohexstr(Value);
}
+
+namespace {
+template <typename ELFT>
+int64_t getRelocationAddend(const llvm::object::ELFObjectFile<ELFT> *Obj,
+ const llvm::object::RelocationRef &RelRef) {
+ using ELFShdrTy = typename ELFT::Shdr;
+ using Elf_Rela = typename ELFT::Rela;
+ int64_t Addend = 0;
+ const llvm::object::ELFFile<ELFT> &EF = Obj->getELFFile();
+ llvm::object::DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
+ switch (RelocationSection->sh_type) {
+ default:
+ llvm_unreachable("unexpected relocation section type");
+ case ELF::SHT_REL:
+ break;
+ case ELF::SHT_RELA: {
+ const Elf_Rela *RelA = Obj->getRela(Rel);
+ Addend = RelA->r_addend;
+ break;
+ }
+ }
+
+ return Addend;
+}
+
+template <typename ELFT>
+uint32_t getRelocationSymbol(const llvm::object::ELFObjectFile<ELFT> *Obj,
+ const llvm::object::RelocationRef &RelRef) {
+ using ELFShdrTy = typename ELFT::Shdr;
+ uint32_t Symbol = 0;
+ const llvm::object::ELFFile<ELFT> &EF = Obj->getELFFile();
+ llvm::object::DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
+ switch (RelocationSection->sh_type) {
+ default:
+ llvm_unreachable("unexpected relocation section type");
+ case ELF::SHT_REL:
+ Symbol = Obj->getRel(Rel)->getSymbol(EF.isMips64EL());
+ break;
+ case ELF::SHT_RELA:
+ Symbol = Obj->getRela(Rel)->getSymbol(EF.isMips64EL());
+ break;
+ }
+
+ return Symbol;
+}
+} // namespace
+
+namespace llvm {
+namespace bolt {
+uint32_t getRelocationSymbol(const llvm::object::ELFObjectFileBase *Obj,
+ const llvm::object::RelocationRef &Rel) {
+ return ::getRelocationSymbol(cast<llvm::object::ELF64LEObjectFile>(Obj), Rel);
+}
+
+int64_t getRelocationAddend(const llvm::object::ELFObjectFileBase *Obj,
+ const llvm::object::RelocationRef &Rel) {
+ return ::getRelocationAddend(cast<llvm::object::ELF64LEObjectFile>(Obj), Rel);
+}
+} // namespace bolt
+} // namespace llvm
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 2114bfe874bd18..66dbdbbeda43b7 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -11,7 +11,6 @@
//===----------------------------------------------------------------------===//
#include "bolt/Passes/IdenticalCodeFolding.h"
-#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/HashUtilities.h"
#include "bolt/Core/ParallelUtilities.h"
#include "bolt/Rewrite/RewriteInstance.h"
@@ -356,7 +355,7 @@ void IdenticalCodeFolding::processDataRelocations(
const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(OwningObj);
if (!ELFObj)
llvm_unreachable("Only ELFObjectFileBase is supported");
- const int64_t Addend = BinaryContext::getRelocationAddend(ELFObj, Rel);
+ const int64_t Addend = getRelocationAddend(ELFObj, Rel);
BinaryFunction *BF = BC.getBinaryFunctionAtAddress(SymbolAddress + Addend);
if (!BF)
continue;
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 70c9eeef3cdc57..42e1231eeed1ab 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2138,7 +2138,7 @@ bool RewriteInstance::analyzeRelocation(
return true;
ExtractedValue = Relocation::extractValue(RType, *Value, Rel.getOffset());
- Addend = BinaryContext::getRelocationAddend(InputFile, Rel);
+ Addend = getRelocationAddend(InputFile, Rel);
const bool IsPCRelative = Relocation::isPCRelative(RType);
const uint64_t PCRelOffset = IsPCRelative && !IsAArch64 ? Rel.getOffset() : 0;
@@ -2338,7 +2338,7 @@ void RewriteInstance::readDynamicRelocations(const SectionRef &Section,
StringRef SymbolName = "<none>";
MCSymbol *Symbol = nullptr;
uint64_t SymbolAddress = 0;
- const uint64_t Addend = BinaryContext::getRelocationAddend(InputFile, Rel);
+ const uint64_t Addend = getRelocationAddend(InputFile, Rel);
symbol_iterator SymbolIter = Rel.getSymbol();
if (SymbolIter != InputFile->symbol_end()) {
@@ -2363,7 +2363,7 @@ void RewriteInstance::readDynamicRelocations(const SectionRef &Section,
IsJmpRelocation[RType] = true;
if (Symbol)
- SymbolIndex[Symbol] = BinaryContext::getRelocationSymbol(InputFile, Rel);
+ SymbolIndex[Symbol] = getRelocationSymbol(InputFile, Rel);
BC->addDynamicRelocation(Rel.getOffset(), Symbol, RType, Addend);
}
>From 29cc4660efd53677a9fc60eef3ec6b6df5dd5e91 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Wed, 20 Nov 2024 15:38:12 -0800
Subject: [PATCH 11/34] moved code around
---
bolt/lib/Passes/IdenticalCodeFolding.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 66dbdbbeda43b7..7d2560cca2d468 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -365,7 +365,6 @@ void IdenticalCodeFolding::processDataRelocations(
Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
Error ErrorStatus = Error::success();
- ErrorOr<BinarySection &> SecRelData = BC.getUniqueSectionByName(".rela.data");
if (!BC.HasRelocations)
ErrorStatus = joinErrors(
std::move(ErrorStatus),
@@ -373,6 +372,7 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
"relocations. Safe ICF is not supported")));
if (ErrorStatus)
return ErrorStatus;
+ ErrorOr<BinarySection &> SecRelData = BC.getUniqueSectionByName(".rela.data");
if (SecRelData) {
SectionRef SecRefRelData = SecRelData->getSectionRef();
processDataRelocations(BC, SecRefRelData);
>From bf3bf2b413b8df2aa3ed11dab4a4380a6c25f7e4 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Thu, 21 Nov 2024 17:54:07 -0800
Subject: [PATCH 12/34] simplified assembly
---
...lperSafeICFGlobalConstPtrNoPicExtFuncRef.s | 31 +--
...helperSafeICFGlobalConstPtrPicExtFuncRef.s | 29 ---
.../Inputs/mainSafeICFGlobalConstPtrNoPic.s | 142 +------------
...mainSafeICFGlobalConstPtrNoPicExtFuncRef.s | 188 +----------------
.../X86/Inputs/mainSafeICFGlobalConstPtrPic.s | 150 +-------------
.../mainSafeICFGlobalConstPtrPicExtFuncRef.s | 190 +-----------------
bolt/test/X86/Inputs/mainSafeICFICPTest.s | 84 +-------
bolt/test/X86/Inputs/mainSafeICFTest1.s | 177 +---------------
.../X86/Inputs/mainSafeICFTest2GlobalVarO0.s | 185 +----------------
.../X86/Inputs/mainSafeICFTest2GlobalVarO3.s | 119 +----------
.../X86/Inputs/mainSafeICFTest3LocalVarO0.s | 185 +----------------
.../X86/Inputs/mainSafeICFTest3LocalVarO3.s | 119 +----------
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 2 +-
bolt/test/X86/icf-safe-test3LocalVarO3.test | 2 +-
14 files changed, 21 insertions(+), 1582 deletions(-)
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
index 489400c3ccaa63..09259e0c3cd2d7 100644
--- a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
+++ b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
@@ -11,7 +11,7 @@
# MY_CONST int fooGlobalFuncHelper(int a, int b) {
# return 5 + funcGlobalBarMulExt(a, b);
# }
-
+# Manually modified to remove "extra" assembly.
.text
.file "helper.cpp"
@@ -20,18 +20,7 @@
.type _Z12barAddHdlperii, at function
_Z12barAddHdlperii: # @_Z12barAddHdlperii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
@@ -42,22 +31,7 @@ _Z12barAddHdlperii: # @_Z12barAddHdlperii
.type _Z19fooGlobalFuncHelperii, at function
_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $16, %rsp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %edi
- movl -8(%rbp), %esi
callq _Z12barAddHdlperii
- addl $5, %eax
- addq $16, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
@@ -79,6 +53,3 @@ BarVar:
.size BarVar, 4
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z12barAddHdlperii
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
index 489400c3ccaa63..836ff0e247ce79 100644
--- a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
+++ b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
@@ -20,18 +20,7 @@
.type _Z12barAddHdlperii, at function
_Z12barAddHdlperii: # @_Z12barAddHdlperii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
@@ -42,22 +31,7 @@ _Z12barAddHdlperii: # @_Z12barAddHdlperii
.type _Z19fooGlobalFuncHelperii, at function
_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $16, %rsp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %edi
- movl -8(%rbp), %esi
callq _Z12barAddHdlperii
- addl $5, %eax
- addq $16, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
@@ -79,6 +53,3 @@ BarVar:
.size BarVar, 4
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z12barAddHdlperii
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
index 11465a0b1ffd0a..ddc1906d8c5818 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
@@ -39,6 +39,7 @@
# MY_PRINTF("val: %d", temp);
# return temp;
# }
+# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
.globl _Z6fooMulii # -- Begin function _Z6fooMulii
@@ -46,15 +47,6 @@
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
popq %rbp
.cfi_def_cfa %rsp, 8
@@ -68,15 +60,6 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
popq %rbp
.cfi_def_cfa %rsp, 8
@@ -90,15 +73,6 @@ _Z6barMulii: # @_Z6barMulii
.type _Z6fooAddii, at function
_Z6fooAddii: # @_Z6fooAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
popq %rbp
.cfi_def_cfa %rsp, 8
@@ -112,15 +86,6 @@ _Z6fooAddii: # @_Z6fooAddii
.type _Z6barAddii, at function
_Z6barAddii: # @_Z6barAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
popq %rbp
.cfi_def_cfa %rsp, 8
@@ -134,34 +99,8 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFKiiiEii, at function
_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movq %rdi, -16(%rbp)
- movl %esi, -20(%rbp)
- movl %edx, -24(%rbp)
movabsq $_Z6barAddii, %rax
cmpq %rax, -16(%rbp)
- jne .LBB4_2
-# %bb.1:
- movl $1, -4(%rbp)
- jmp .LBB4_3
-.LBB4_2:
- movq -16(%rbp), %rax
- movl -20(%rbp), %edi
- movl -24(%rbp), %esi
- callq *%rax
- subl $4, %eax
- movl %eax, -4(%rbp)
-.LBB4_3:
- movl -4(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end4:
.size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
@@ -171,43 +110,8 @@ _Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
.p2align 4, 0x90
.type _Z7helper2PFKiiiES1_ii, at function
_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movq %rdi, -16(%rbp)
- movq %rsi, -24(%rbp)
- movl %edx, -28(%rbp)
- movl %ecx, -32(%rbp)
- movq -16(%rbp), %rax
- cmpq -24(%rbp), %rax
- jne .LBB5_2
-# %bb.1:
- movl $2, -4(%rbp)
- jmp .LBB5_3
-.LBB5_2:
- movq -16(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, -36(%rbp) # 4-byte Spill
- movq -24(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -4(%rbp)
-.LBB5_3:
- movl -4(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
+ .cfi_startproc
+ # no direct function references.
retq
.Lfunc_end5:
.size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
@@ -218,16 +122,6 @@ _Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movl $0, -4(%rbp)
- movl %edi, -8(%rbp)
- movq %rsi, -16(%rbp)
movl FooVar, %esi
movl BarVar, %edx
movabsq $_Z6barAddii, %rdi
@@ -238,25 +132,6 @@ main: # @main
movabsq $_Z6fooMulii, %rdi
movabsq $_Z6barMulii, %rsi
callq _Z7helper2PFKiiiES1_ii
- movl %eax, %ecx
- movl -28(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -24(%rbp) # 4-byte Spill
- movl FooVar, %edi
- movl BarVar, %esi
- callq _Z6fooAddii
- movl %eax, %ecx
- movl -24(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -20(%rbp)
- movl -20(%rbp), %esi
- movabsq $.L.str, %rdi
- movb $0, %al
- callq printf
- movl -20(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end6:
.size main, .Lfunc_end6-main
@@ -269,14 +144,3 @@ main: # @main
.size .L.str, 9
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6barMulii
- .addrsig_sym _Z6fooAddii
- .addrsig_sym _Z6barAddii
- .addrsig_sym _Z7helper1PFKiiiEii
- .addrsig_sym _Z7helper2PFKiiiES1_ii
- .addrsig_sym printf
- .addrsig_sym FooVar
- .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
index 40f30cbbc30550..44d4a388995028 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
@@ -49,7 +49,7 @@
# MY_PRINTF("val: %d", temp);
# return temp;
# }
-
+# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
.globl _Z6fooSubii # -- Begin function _Z6fooSubii
@@ -57,18 +57,7 @@
.type _Z6fooSubii, at function
_Z6fooSubii: # @_Z6fooSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
@@ -79,18 +68,7 @@ _Z6fooSubii: # @_Z6fooSubii
.type _Z6barSubii, at function
_Z6barSubii: # @_Z6barSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _Z6barSubii, .Lfunc_end1-_Z6barSubii
@@ -101,18 +79,7 @@ _Z6barSubii: # @_Z6barSubii
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end2:
.size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
@@ -123,18 +90,7 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end3:
.size _Z6barMulii, .Lfunc_end3-_Z6barMulii
@@ -145,18 +101,7 @@ _Z6barMulii: # @_Z6barMulii
.type _Z6fooAddii, at function
_Z6fooAddii: # @_Z6fooAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end4:
.size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
@@ -165,20 +110,9 @@ _Z6fooAddii: # @_Z6fooAddii
.globl _Z6barAddii # -- Begin function _Z6barAddii
.p2align 4, 0x90
.type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
+_Z6barAddii:
+ .cfi_startproc # @_Z6barAddii
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end5:
.size _Z6barAddii, .Lfunc_end5-_Z6barAddii
@@ -189,34 +123,8 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFKiiiEii, at function
_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movq %rdi, -16(%rbp)
- movl %esi, -20(%rbp)
- movl %edx, -24(%rbp)
movabsq $_Z6barAddii, %rax
cmpq %rax, -16(%rbp)
- jne .LBB6_2
-# %bb.1:
- movl $1, -4(%rbp)
- jmp .LBB6_3
-.LBB6_2:
- movq -16(%rbp), %rax
- movl -20(%rbp), %edi
- movl -24(%rbp), %esi
- callq *%rax
- subl $4, %eax
- movl %eax, -4(%rbp)
-.LBB6_3:
- movl -4(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end6:
.size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
@@ -227,42 +135,7 @@ _Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
.type _Z7helper2PFKiiiES1_ii, at function
_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movq %rdi, -16(%rbp)
- movq %rsi, -24(%rbp)
- movl %edx, -28(%rbp)
- movl %ecx, -32(%rbp)
- movq -16(%rbp), %rax
- cmpq -24(%rbp), %rax
- jne .LBB7_2
-# %bb.1:
- movl $2, -4(%rbp)
- jmp .LBB7_3
-.LBB7_2:
- movq -16(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, -36(%rbp) # 4-byte Spill
- movq -24(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -4(%rbp)
-.LBB7_3:
- movl -4(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
+ # All operations on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
@@ -273,71 +146,18 @@ _Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movl $0, -4(%rbp)
- movl %edi, -8(%rbp)
- movq %rsi, -16(%rbp)
movl FooVar, %esi
movl BarVar, %edx
movabsq $_Z12barAddHdlperii, %rdi
callq _Z7helper1PFKiiiEii
- movl %eax, -36(%rbp) # 4-byte Spill
movl FooVar, %edx
movl BarVar, %ecx
movabsq $_Z6fooMulii, %rdi
movabsq $_Z19fooGlobalFuncHelperii, %rsi
callq _Z7helper2PFKiiiES1_ii
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -32(%rbp) # 4-byte Spill
- movl FooVar, %edi
- movl BarVar, %esi
- callq _Z6fooSubii
- movl %eax, %ecx
- movl -32(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -28(%rbp) # 4-byte Spill
- movl FooVar, %edi
- movl BarVar, %esi
- callq _Z6barSubii
- movl %eax, %ecx
- movl -28(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -24(%rbp) # 4-byte Spill
- movl FooVar, %edi
- movl BarVar, %esi
- callq _Z6fooAddii
- movl %eax, %ecx
- movl -24(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -20(%rbp)
- movl -20(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
# -- End function
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooSubii
- .addrsig_sym _Z6barSubii
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6fooAddii
- .addrsig_sym _Z6barAddii
- .addrsig_sym _Z7helper1PFKiiiEii
- .addrsig_sym _Z7helper2PFKiiiES1_ii
- .addrsig_sym _Z12barAddHdlperii
- .addrsig_sym _Z19fooGlobalFuncHelperii
- .addrsig_sym FooVar
- .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
index 3c878a7de8e6b8..3366b94f3ac9b5 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
@@ -39,6 +39,7 @@
# MY_PRINTF("val: %d", temp);
# return temp;
# }
+# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
.globl _Z6fooMulii # -- Begin function _Z6fooMulii
@@ -46,18 +47,7 @@
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
@@ -68,18 +58,7 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _Z6barMulii, .Lfunc_end1-_Z6barMulii
@@ -90,18 +69,7 @@ _Z6barMulii: # @_Z6barMulii
.type _Z6fooAddii, at function
_Z6fooAddii: # @_Z6fooAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end2:
.size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
@@ -112,18 +80,7 @@ _Z6fooAddii: # @_Z6fooAddii
.type _Z6barAddii, at function
_Z6barAddii: # @_Z6barAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end3:
.size _Z6barAddii, .Lfunc_end3-_Z6barAddii
@@ -134,34 +91,8 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFKiiiEii, at function
_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movq %rdi, -16(%rbp)
- movl %esi, -20(%rbp)
- movl %edx, -24(%rbp)
leaq _Z6barAddii(%rip), %rax
cmpq %rax, -16(%rbp)
- jne .LBB4_2
-# %bb.1:
- movl $1, -4(%rbp)
- jmp .LBB4_3
-.LBB4_2:
- movq -16(%rbp), %rax
- movl -20(%rbp), %edi
- movl -24(%rbp), %esi
- callq *%rax
- subl $4, %eax
- movl %eax, -4(%rbp)
-.LBB4_3:
- movl -4(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end4:
.size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
@@ -172,42 +103,7 @@ _Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
.type _Z7helper2PFKiiiES1_ii, at function
_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movq %rdi, -16(%rbp)
- movq %rsi, -24(%rbp)
- movl %edx, -28(%rbp)
- movl %ecx, -32(%rbp)
- movq -16(%rbp), %rax
- cmpq -24(%rbp), %rax
- jne .LBB5_2
-# %bb.1:
- movl $2, -4(%rbp)
- jmp .LBB5_3
-.LBB5_2:
- movq -16(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, -36(%rbp) # 4-byte Spill
- movq -24(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -4(%rbp)
-.LBB5_3:
- movl -4(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
+ # Operates on registers.
retq
.Lfunc_end5:
.size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
@@ -218,60 +114,18 @@ _Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movl $0, -4(%rbp)
- movl %edi, -8(%rbp)
- movq %rsi, -16(%rbp)
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
leaq _Z6barAddii(%rip), %rdi
callq _Z7helper1PFKiiiEii
- movl %eax, -28(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %ecx
leaq _Z6fooMulii(%rip), %rdi
leaq _Z6barMulii(%rip), %rsi
callq _Z7helper2PFKiiiES1_ii
- movl %eax, %ecx
- movl -28(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -24(%rbp) # 4-byte Spill
- movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
- movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
- callq _Z6fooAddii
- movl %eax, %ecx
- movl -24(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -20(%rbp)
- movl -20(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end6:
.size main, .Lfunc_end6-main
.cfi_endproc
# -- End function
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6barMulii
- .addrsig_sym _Z6fooAddii
- .addrsig_sym _Z6barAddii
- .addrsig_sym _Z7helper1PFKiiiEii
- .addrsig_sym _Z7helper2PFKiiiES1_ii
- .addrsig_sym FooVar
- .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
index a7da985b93bc38..913a1349312a29 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
@@ -57,18 +57,7 @@
.type _Z6fooSubii, at function
_Z6fooSubii: # @_Z6fooSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
@@ -79,18 +68,7 @@ _Z6fooSubii: # @_Z6fooSubii
.type _Z6barSubii, at function
_Z6barSubii: # @_Z6barSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _Z6barSubii, .Lfunc_end1-_Z6barSubii
@@ -101,18 +79,7 @@ _Z6barSubii: # @_Z6barSubii
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end2:
.size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
@@ -123,18 +90,7 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end3:
.size _Z6barMulii, .Lfunc_end3-_Z6barMulii
@@ -145,18 +101,7 @@ _Z6barMulii: # @_Z6barMulii
.type _Z6fooAddii, at function
_Z6fooAddii: # @_Z6fooAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end4:
.size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
@@ -167,18 +112,7 @@ _Z6fooAddii: # @_Z6fooAddii
.type _Z6barAddii, at function
_Z6barAddii: # @_Z6barAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end5:
.size _Z6barAddii, .Lfunc_end5-_Z6barAddii
@@ -189,34 +123,8 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFKiiiEii, at function
_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movq %rdi, -16(%rbp)
- movl %esi, -20(%rbp)
- movl %edx, -24(%rbp)
leaq _Z6barAddii(%rip), %rax
cmpq %rax, -16(%rbp)
- jne .LBB6_2
-# %bb.1:
- movl $1, -4(%rbp)
- jmp .LBB6_3
-.LBB6_2:
- movq -16(%rbp), %rax
- movl -20(%rbp), %edi
- movl -24(%rbp), %esi
- callq *%rax
- subl $4, %eax
- movl %eax, -4(%rbp)
-.LBB6_3:
- movl -4(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end6:
.size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
@@ -227,42 +135,7 @@ _Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
.type _Z7helper2PFKiiiES1_ii, at function
_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movq %rdi, -16(%rbp)
- movq %rsi, -24(%rbp)
- movl %edx, -28(%rbp)
- movl %ecx, -32(%rbp)
- movq -16(%rbp), %rax
- cmpq -24(%rbp), %rax
- jne .LBB7_2
-# %bb.1:
- movl $2, -4(%rbp)
- jmp .LBB7_3
-.LBB7_2:
- movq -16(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, -36(%rbp) # 4-byte Spill
- movq -24(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -4(%rbp)
-.LBB7_3:
- movl -4(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
+ # Operates on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
@@ -273,69 +146,24 @@ _Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movl $0, -4(%rbp)
- movl %edi, -8(%rbp)
- movq %rsi, -16(%rbp)
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
movq _Z12barAddHdlperii at GOTPCREL(%rip), %rdi
callq _Z7helper1PFKiiiEii
- movl %eax, -36(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %ecx
leaq _Z6fooMulii(%rip), %rdi
movq _Z19fooGlobalFuncHelperii at GOTPCREL(%rip), %rsi
callq _Z7helper2PFKiiiES1_ii
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -32(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6fooSubii
- movl %eax, %ecx
- movl -32(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -28(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
- callq _Z6barSubii
- movl %eax, %ecx
- movl -28(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -24(%rbp) # 4-byte Spill
+ callq _Z6barSubii # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6fooAddii
- movl %eax, %ecx
- movl -24(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -20(%rbp)
- movl -20(%rbp), %esi
- leaq .L.str(%rip), %rdi
- movb $0, %al
- callq printf at PLT
- movl -20(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
@@ -348,17 +176,3 @@ main: # @main
.size .L.str, 9
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooSubii
- .addrsig_sym _Z6barSubii
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6fooAddii
- .addrsig_sym _Z6barAddii
- .addrsig_sym _Z7helper1PFKiiiEii
- .addrsig_sym _Z7helper2PFKiiiES1_ii
- .addrsig_sym _Z12barAddHdlperii
- .addrsig_sym _Z19fooGlobalFuncHelperii
- .addrsig_sym printf
- .addrsig_sym FooVar
- .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFICPTest.s b/bolt/test/X86/Inputs/mainSafeICFICPTest.s
index 4b12acdeae0995..665256da48e777 100644
--- a/bolt/test/X86/Inputs/mainSafeICFICPTest.s
+++ b/bolt/test/X86/Inputs/mainSafeICFICPTest.s
@@ -60,6 +60,7 @@
# sum += ptr->func(b, a) + ptr2->func(b, a);
# return 0;
# }
+# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
.section .text.hot.,"ax", at progbits
@@ -68,26 +69,10 @@
.type _Z10createTypei, at function
_Z10createTypei: # @_Z10createTypei
.cfi_startproc
-# %bb.0: # %entry
- pushq %rbx
- .cfi_def_cfa_offset 16
- .cfi_offset %rbx, -16
- movl %edi, %ebx
- movl $16, %edi
callq _Znwm at PLT
- cmpl $4, %ebx
- xorps %xmm0, %xmm0
leaq _ZTV8Derived2+16(%rip), %rcx
leaq _ZTV8Derived3+16(%rip), %rdx
cmoveq %rcx, %rdx
- movl $5, %ecx
- movl $500, %esi # imm = 0x1F4
- cmovel %ecx, %esi
- movaps %xmm0, (%rax)
- movq %rdx, (%rax)
- movl %esi, 8(%rax)
- popq %rbx
- .cfi_def_cfa_offset 8
retq
.Lfunc_end0:
.size _Z10createTypei, .Lfunc_end0-_Z10createTypei
@@ -98,71 +83,22 @@ _Z10createTypei: # @_Z10createTypei
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0: # %entry
- pushq %rbp
- .cfi_def_cfa_offset 16
- pushq %r15
- .cfi_def_cfa_offset 24
- pushq %r14
- .cfi_def_cfa_offset 32
- pushq %rbx
- .cfi_def_cfa_offset 40
- pushq %rax
- .cfi_def_cfa_offset 48
- .cfi_offset %rbx, -40
- .cfi_offset %r14, -32
- .cfi_offset %r15, -24
- .cfi_offset %rbp, -16
callq _Z16returnFourOrFivei at PLT
- movl %eax, %ebx
callq _Z10returnFivev at PLT
- movl %eax, %ebp
- movl %ebx, %edi
callq _Z10createTypei
- movq %rax, %r15
- movl %ebp, %edi
callq _Z10createTypei
- movq %rax, %r14
- movq (%r15), %rax
- movq (%rax), %rax
leaq _ZNK8Derived24funcEii(%rip), %rcx
- movq %r15, %rdi
- movl %ebp, %esi
- movl %ebx, %edx
- cmpq %rcx, %rax
jne .LBB1_2
-# %bb.1: # %if.true.direct_targ
callq _ZNK8Derived24funcEii
.LBB1_3: # %if.end.icp
- movq (%r14), %rax
- movq (%rax), %rax
leaq _ZNK8Derived34funcEii(%rip), %rcx
- movq %r14, %rdi
- movl %ebp, %esi
- movl %ebx, %edx
- cmpq %rcx, %rax
jne .LBB1_5
-# %bb.4: # %if.true.direct_targ1
callq _ZNK8Derived34funcEii
.LBB1_6: # %if.end.icp3
- xorl %eax, %eax
- addq $8, %rsp
- .cfi_def_cfa_offset 40
- popq %rbx
- .cfi_def_cfa_offset 32
- popq %r14
- .cfi_def_cfa_offset 24
- popq %r15
- .cfi_def_cfa_offset 16
- popq %rbp
- .cfi_def_cfa_offset 8
retq
.LBB1_2: # %if.false.orig_indirect
- .cfi_def_cfa_offset 48
- callq *%rax
jmp .LBB1_3
.LBB1_5: # %if.false.orig_indirect2
- callq *%rax
jmp .LBB1_6
.Lfunc_end1:
.size main, .Lfunc_end1-main
@@ -174,11 +110,7 @@ main: # @main
.type _ZNK8Derived24funcEii, at function
_ZNK8Derived24funcEii: # @_ZNK8Derived24funcEii
.cfi_startproc
-# %bb.0: # %entry
- movl %esi, %eax
- subl %edx, %eax
imull %esi, %eax
- addl 8(%rdi), %eax
retq
.Lfunc_end2:
.size _ZNK8Derived24funcEii, .Lfunc_end2-_ZNK8Derived24funcEii
@@ -203,11 +135,7 @@ _ZN8Derived2D0Ev: # @_ZN8Derived2D0Ev
.type _ZNK8Derived34funcEii, at function
_ZNK8Derived34funcEii: # @_ZNK8Derived34funcEii
.cfi_startproc
-# %bb.0: # %entry
- movl %esi, %eax
- subl %edx, %eax
imull %esi, %eax
- addl 8(%rdi), %eax
retq
.Lfunc_end4:
.size _ZNK8Derived34funcEii, .Lfunc_end4-_ZNK8Derived34funcEii
@@ -319,13 +247,3 @@ _ZTI8Derived3:
.cg_profile main, _ZNK8Derived24funcEii, 1
.cg_profile main, _ZNK8Derived34funcEii, 1
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _ZTVN10__cxxabiv120__si_class_type_infoE
- .addrsig_sym _ZTS8Derived2
- .addrsig_sym _ZTVN10__cxxabiv117__class_type_infoE
- .addrsig_sym _ZTS4Base
- .addrsig_sym _ZTI4Base
- .addrsig_sym _ZTI8Derived2
- .addrsig_sym _ZTS8Derived3
- .addrsig_sym _ZTI8Derived3
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest1.s b/bolt/test/X86/Inputs/mainSafeICFTest1.s
index 7d38f0bd190fd8..b6e0b6cbf97dcc 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest1.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest1.s
@@ -50,18 +50,7 @@
.type _Z6fooSubii, at function
_Z6fooSubii: # @_Z6fooSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
@@ -72,18 +61,7 @@ _Z6fooSubii: # @_Z6fooSubii
.type _Z6barSubii, at function
_Z6barSubii: # @_Z6barSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _Z6barSubii, .Lfunc_end1-_Z6barSubii
@@ -94,18 +72,7 @@ _Z6barSubii: # @_Z6barSubii
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end2:
.size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
@@ -116,18 +83,7 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end3:
.size _Z6barMulii, .Lfunc_end3-_Z6barMulii
@@ -138,18 +94,7 @@ _Z6barMulii: # @_Z6barMulii
.type _Z6fooAddii, at function
_Z6fooAddii: # @_Z6fooAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end4:
.size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
@@ -160,18 +105,7 @@ _Z6fooAddii: # @_Z6fooAddii
.type _Z6barAddii, at function
_Z6barAddii: # @_Z6barAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end5:
.size _Z6barAddii, .Lfunc_end5-_Z6barAddii
@@ -182,34 +116,13 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFiiiEii, at function
_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movq %rdi, -16(%rbp)
- movl %esi, -20(%rbp)
- movl %edx, -24(%rbp)
leaq _Z6barAddii(%rip), %rax
cmpq %rax, -16(%rbp)
jne .LBB6_2
-# %bb.1:
- movl $1, -4(%rbp)
jmp .LBB6_3
.LBB6_2:
- movq -16(%rbp), %rax
- movl -20(%rbp), %edi
- movl -24(%rbp), %esi
callq *%rax
- subl $4, %eax
- movl %eax, -4(%rbp)
.LBB6_3:
- movl -4(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end6:
.size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
@@ -220,42 +133,7 @@ _Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.type _Z7helper2PFiiiES0_ii, at function
_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movq %rdi, -16(%rbp)
- movq %rsi, -24(%rbp)
- movl %edx, -28(%rbp)
- movl %ecx, -32(%rbp)
- movq -16(%rbp), %rax
- cmpq -24(%rbp), %rax
- jne .LBB7_2
-# %bb.1:
- movl $2, -4(%rbp)
- jmp .LBB7_3
-.LBB7_2:
- movq -16(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, -36(%rbp) # 4-byte Spill
- movq -24(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -4(%rbp)
-.LBB7_3:
- movl -4(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
+ # Operates on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
@@ -266,80 +144,27 @@ _Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movl $0, -4(%rbp)
- movl %edi, -8(%rbp)
- movq %rsi, -16(%rbp)
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
leaq _Z6barAddii(%rip), %rdi
callq _Z7helper1PFiiiEii
- movl %eax, -36(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %ecx
leaq _Z6fooMulii(%rip), %rdi
leaq _Z6barMulii(%rip), %rsi
callq _Z7helper2PFiiiES0_ii
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -32(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6fooSubii
- movl %eax, %ecx
- movl -32(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -28(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6barSubii
- movl %eax, %ecx
- movl -28(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -24(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6fooAddii
- movl %eax, %ecx
- movl -24(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -20(%rbp)
- movl -20(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
# -- End function
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooSubii
- .addrsig_sym _Z6barSubii
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6barMulii
- .addrsig_sym _Z6fooAddii
- .addrsig_sym _Z6barAddii
- .addrsig_sym _Z7helper1PFiiiEii
- .addrsig_sym _Z7helper2PFiiiES0_ii
- .addrsig_sym FooVar
- .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
index 5d5d00c12320be..42b5069f0fdd66 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
@@ -45,6 +45,7 @@
# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
# return temp;
# }
+# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
.globl _Z6fooSubii # -- Begin function _Z6fooSubii
@@ -52,18 +53,7 @@
.type _Z6fooSubii, at function
_Z6fooSubii: # @_Z6fooSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
@@ -74,18 +64,7 @@ _Z6fooSubii: # @_Z6fooSubii
.type _Z6barSubii, at function
_Z6barSubii: # @_Z6barSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _Z6barSubii, .Lfunc_end1-_Z6barSubii
@@ -96,18 +75,7 @@ _Z6barSubii: # @_Z6barSubii
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end2:
.size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
@@ -118,18 +86,7 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end3:
.size _Z6barMulii, .Lfunc_end3-_Z6barMulii
@@ -140,18 +97,7 @@ _Z6barMulii: # @_Z6barMulii
.type _Z6fooAddii, at function
_Z6fooAddii: # @_Z6fooAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end4:
.size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
@@ -162,18 +108,7 @@ _Z6fooAddii: # @_Z6fooAddii
.type _Z6barAddii, at function
_Z6barAddii: # @_Z6barAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end5:
.size _Z6barAddii, .Lfunc_end5-_Z6barAddii
@@ -184,34 +119,8 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFiiiEii, at function
_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movq %rdi, -16(%rbp)
- movl %esi, -20(%rbp)
- movl %edx, -24(%rbp)
leaq _Z6barAddii(%rip), %rax
cmpq %rax, -16(%rbp)
- jne .LBB6_2
-# %bb.1:
- movl $1, -4(%rbp)
- jmp .LBB6_3
-.LBB6_2:
- movq -16(%rbp), %rax
- movl -20(%rbp), %edi
- movl -24(%rbp), %esi
- callq *%rax
- subl $4, %eax
- movl %eax, -4(%rbp)
-.LBB6_3:
- movl -4(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end6:
.size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
@@ -222,42 +131,7 @@ _Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.type _Z7helper2PFiiiES0_ii, at function
_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movq %rdi, -16(%rbp)
- movq %rsi, -24(%rbp)
- movl %edx, -28(%rbp)
- movl %ecx, -32(%rbp)
- movq -16(%rbp), %rax
- cmpq -24(%rbp), %rax
- jne .LBB7_2
-# %bb.1:
- movl $2, -4(%rbp)
- jmp .LBB7_3
-.LBB7_2:
- movq -16(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, -36(%rbp) # 4-byte Spill
- movq -24(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -4(%rbp)
-.LBB7_3:
- movl -4(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
+ # Operates on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
@@ -268,65 +142,24 @@ _Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movl $0, -4(%rbp)
- movl %edi, -8(%rbp)
- movq %rsi, -16(%rbp)
movq _ZL16funcGlobalBarAdd(%rip), %rdi
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
callq _Z7helper1PFiiiEii
- movl %eax, -36(%rbp) # 4-byte Spill
movq funcGlobalBarMul(%rip), %rsi
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %ecx
leaq _Z6fooMulii(%rip), %rdi
callq _Z7helper2PFiiiES0_ii
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -32(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6fooSubii
- movl %eax, %ecx
- movl -32(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -28(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6barSubii
- movl %eax, %ecx
- movl -28(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -24(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6fooAddii
- movl %eax, %ecx
- movl -24(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -20(%rbp)
- movl -20(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
@@ -347,17 +180,3 @@ _ZL16funcGlobalBarAdd:
.size _ZL16funcGlobalBarAdd, 8
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooSubii
- .addrsig_sym _Z6barSubii
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6barMulii
- .addrsig_sym _Z6fooAddii
- .addrsig_sym _Z6barAddii
- .addrsig_sym _Z7helper1PFiiiEii
- .addrsig_sym _Z7helper2PFiiiES0_ii
- .addrsig_sym funcGlobalBarMul
- .addrsig_sym _ZL16funcGlobalBarAdd
- .addrsig_sym FooVar
- .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
index 3579fa2eae293b..8a0d76a15aca9e 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
@@ -52,8 +52,6 @@
.type _Z6fooSubii, at function
_Z6fooSubii: # @_Z6fooSubii
.cfi_startproc
-# %bb.0:
- movl %edi, %eax
subl %esi, %eax
retq
.Lfunc_end0:
@@ -65,8 +63,6 @@ _Z6fooSubii: # @_Z6fooSubii
.type _Z6barSubii, at function
_Z6barSubii: # @_Z6barSubii
.cfi_startproc
-# %bb.0:
- movl %edi, %eax
subl %esi, %eax
retq
.Lfunc_end1:
@@ -78,8 +74,6 @@ _Z6barSubii: # @_Z6barSubii
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- movl %edi, %eax
imull %esi, %eax
retq
.Lfunc_end2:
@@ -91,8 +85,6 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- movl %edi, %eax
imull %esi, %eax
retq
.Lfunc_end3:
@@ -132,20 +124,8 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFiiiEii, at function
_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.cfi_startproc
-# %bb.0:
leaq _Z6barAddii(%rip), %rcx
cmpq %rcx, %rdi
- je .LBB6_1
-# %bb.2:
- pushq %rax
- .cfi_def_cfa_offset 16
- movq %rdi, %rax
- movl %esi, %edi
- movl %edx, %esi
- callq *%rax
- addl $-4, %eax
- addq $8, %rsp
- .cfi_def_cfa_offset 8
retq
.LBB6_1:
movl $1, %eax
@@ -159,53 +139,7 @@ _Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.type _Z7helper2PFiiiES0_ii, at function
_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.cfi_startproc
-# %bb.0:
- cmpq %rsi, %rdi
- je .LBB7_1
-# %bb.2:
- pushq %rbp
- .cfi_def_cfa_offset 16
- pushq %r15
- .cfi_def_cfa_offset 24
- pushq %r14
- .cfi_def_cfa_offset 32
- pushq %rbx
- .cfi_def_cfa_offset 40
- pushq %rax
- .cfi_def_cfa_offset 48
- .cfi_offset %rbx, -40
- .cfi_offset %r14, -32
- .cfi_offset %r15, -24
- .cfi_offset %rbp, -16
- movl %ecx, %ebx
- movl %edx, %ebp
- movq %rsi, %r14
- movq %rdi, %rax
- movl %edx, %edi
- movl %ecx, %esi
- callq *%rax
- movl %eax, %r15d
- movl %ebp, %edi
- movl %ebx, %esi
- callq *%r14
- addl %r15d, %eax
- addq $8, %rsp
- .cfi_def_cfa_offset 40
- popq %rbx
- .cfi_def_cfa_offset 32
- popq %r14
- .cfi_def_cfa_offset 24
- popq %r15
- .cfi_def_cfa_offset 16
- popq %rbp
- .cfi_def_cfa_offset 8
- .cfi_restore %rbx
- .cfi_restore %r14
- .cfi_restore %r15
- .cfi_restore %rbp
- retq
-.LBB7_1:
- movl $2, %eax
+ # Operates on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
@@ -216,62 +150,16 @@ _Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- pushq %r15
- .cfi_def_cfa_offset 24
- pushq %r14
- .cfi_def_cfa_offset 32
- pushq %r12
- .cfi_def_cfa_offset 40
- pushq %rbx
- .cfi_def_cfa_offset 48
- .cfi_offset %rbx, -48
- .cfi_offset %r12, -40
- .cfi_offset %r14, -32
- .cfi_offset %r15, -24
- .cfi_offset %rbp, -16
movq FooVar at GOTPCREL(%rip), %r14
- movl (%r14), %esi
movq BarVar at GOTPCREL(%rip), %r15
- movl (%r15), %edx
leaq _Z6barAddii(%rip), %rdi
callq _Z7helper1PFiiiEii
- movl %eax, %ebx
movq funcGlobalBarMul(%rip), %rsi
- movl (%r14), %edx
- movl (%r15), %ecx
leaq _Z6fooMulii(%rip), %rdi
callq _Z7helper2PFiiiES0_ii
- movl %eax, %ebp
- addl %ebx, %ebp
- movl (%r14), %ebx
- movl (%r15), %r14d
- movl %ebx, %edi
- movl %r14d, %esi
callq _Z6fooSubii
- movl %eax, %r15d
- movl %ebx, %edi
- movl %r14d, %esi
callq _Z6barSubii
- movl %eax, %r12d
- addl %r15d, %r12d
- addl %ebp, %r12d
- movl %ebx, %edi
- movl %r14d, %esi
callq _Z6fooAddii
- addl %r12d, %eax
- popq %rbx
- .cfi_def_cfa_offset 40
- popq %r12
- .cfi_def_cfa_offset 32
- popq %r14
- .cfi_def_cfa_offset 24
- popq %r15
- .cfi_def_cfa_offset 16
- popq %rbp
- .cfi_def_cfa_offset 8
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
@@ -286,8 +174,3 @@ funcGlobalBarMul:
.size funcGlobalBarMul, 8
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6barMulii
- .addrsig_sym _Z6barAddii
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
index 56036d1b14e2b9..7a9e3fec52a697 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
@@ -54,18 +54,7 @@
.type _Z6fooSubii, at function
_Z6fooSubii: # @_Z6fooSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
@@ -76,18 +65,7 @@ _Z6fooSubii: # @_Z6fooSubii
.type _Z6barSubii, at function
_Z6barSubii: # @_Z6barSubii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
subl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _Z6barSubii, .Lfunc_end1-_Z6barSubii
@@ -98,18 +76,7 @@ _Z6barSubii: # @_Z6barSubii
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end2:
.size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
@@ -120,18 +87,7 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end3:
.size _Z6barMulii, .Lfunc_end3-_Z6barMulii
@@ -142,18 +98,7 @@ _Z6barMulii: # @_Z6barMulii
.type _Z6fooAddii, at function
_Z6fooAddii: # @_Z6fooAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end4:
.size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
@@ -164,18 +109,7 @@ _Z6fooAddii: # @_Z6fooAddii
.type _Z6barAddii, at function
_Z6barAddii: # @_Z6barAddii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- movl %edi, -4(%rbp)
- movl %esi, -8(%rbp)
- movl -4(%rbp), %eax
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end5:
.size _Z6barAddii, .Lfunc_end5-_Z6barAddii
@@ -186,34 +120,8 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFiiiEii, at function
_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $32, %rsp
- movq %rdi, -16(%rbp)
- movl %esi, -20(%rbp)
- movl %edx, -24(%rbp)
leaq _Z6barAddii(%rip), %rax
cmpq %rax, -16(%rbp)
- jne .LBB6_2
-# %bb.1:
- movl $1, -4(%rbp)
- jmp .LBB6_3
-.LBB6_2:
- movq -16(%rbp), %rax
- movl -20(%rbp), %edi
- movl -24(%rbp), %esi
- callq *%rax
- subl $4, %eax
- movl %eax, -4(%rbp)
-.LBB6_3:
- movl -4(%rbp), %eax
- addq $32, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end6:
.size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
@@ -224,42 +132,7 @@ _Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.type _Z7helper2PFiiiES0_ii, at function
_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movq %rdi, -16(%rbp)
- movq %rsi, -24(%rbp)
- movl %edx, -28(%rbp)
- movl %ecx, -32(%rbp)
- movq -16(%rbp), %rax
- cmpq -24(%rbp), %rax
- jne .LBB7_2
-# %bb.1:
- movl $2, -4(%rbp)
- jmp .LBB7_3
-.LBB7_2:
- movq -16(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, -36(%rbp) # 4-byte Spill
- movq -24(%rbp), %rax
- movl -28(%rbp), %edi
- movl -32(%rbp), %esi
- callq *%rax
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -4(%rbp)
-.LBB7_3:
- movl -4(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
+ # Operates on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
@@ -270,67 +143,24 @@ _Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
- subq $48, %rsp
- movl $0, -4(%rbp)
- movl %edi, -8(%rbp)
- movq %rsi, -16(%rbp)
leaq _Z6barMulii(%rip), %rax
- movq %rax, -24(%rbp)
movq _ZZ4mainE16funcGlobalBarAdd(%rip), %rdi
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
callq _Z7helper1PFiiiEii
- movl %eax, -44(%rbp) # 4-byte Spill
- movq -24(%rbp), %rsi
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edx
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %ecx
leaq _Z6fooMulii(%rip), %rdi
callq _Z7helper2PFiiiES0_ii
- movl %eax, %ecx
- movl -44(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -40(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6fooSubii
- movl %eax, %ecx
- movl -40(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -36(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6barSubii
- movl %eax, %ecx
- movl -36(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -32(%rbp) # 4-byte Spill
movq FooVar at GOTPCREL(%rip), %rax
- movl (%rax), %edi
movq BarVar at GOTPCREL(%rip), %rax
- movl (%rax), %esi
callq _Z6fooAddii
- movl %eax, %ecx
- movl -32(%rbp), %eax # 4-byte Reload
- addl %ecx, %eax
- movl %eax, -28(%rbp)
- movl -28(%rbp), %eax
- addq $48, %rsp
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
@@ -344,16 +174,3 @@ _ZZ4mainE16funcGlobalBarAdd:
.size _ZZ4mainE16funcGlobalBarAdd, 8
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooSubii
- .addrsig_sym _Z6barSubii
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6barMulii
- .addrsig_sym _Z6fooAddii
- .addrsig_sym _Z6barAddii
- .addrsig_sym _Z7helper1PFiiiEii
- .addrsig_sym _Z7helper2PFiiiES0_ii
- .addrsig_sym _ZZ4mainE16funcGlobalBarAdd
- .addrsig_sym FooVar
- .addrsig_sym BarVar
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
index aedad906912654..d7e70a397eb1e8 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
@@ -53,8 +53,6 @@
.type _Z6fooSubii, at function
_Z6fooSubii: # @_Z6fooSubii
.cfi_startproc
-# %bb.0:
- movl %edi, %eax
subl %esi, %eax
retq
.Lfunc_end0:
@@ -66,8 +64,6 @@ _Z6fooSubii: # @_Z6fooSubii
.type _Z6barSubii, at function
_Z6barSubii: # @_Z6barSubii
.cfi_startproc
-# %bb.0:
- movl %edi, %eax
subl %esi, %eax
retq
.Lfunc_end1:
@@ -79,8 +75,6 @@ _Z6barSubii: # @_Z6barSubii
.type _Z6fooMulii, at function
_Z6fooMulii: # @_Z6fooMulii
.cfi_startproc
-# %bb.0:
- movl %edi, %eax
imull %esi, %eax
retq
.Lfunc_end2:
@@ -92,8 +86,6 @@ _Z6fooMulii: # @_Z6fooMulii
.type _Z6barMulii, at function
_Z6barMulii: # @_Z6barMulii
.cfi_startproc
-# %bb.0:
- movl %edi, %eax
imull %esi, %eax
retq
.Lfunc_end3:
@@ -133,20 +125,8 @@ _Z6barAddii: # @_Z6barAddii
.type _Z7helper1PFiiiEii, at function
_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.cfi_startproc
-# %bb.0:
leaq _Z6barAddii(%rip), %rcx
cmpq %rcx, %rdi
- je .LBB6_1
-# %bb.2:
- pushq %rax
- .cfi_def_cfa_offset 16
- movq %rdi, %rax
- movl %esi, %edi
- movl %edx, %esi
- callq *%rax
- addl $-4, %eax
- addq $8, %rsp
- .cfi_def_cfa_offset 8
retq
.LBB6_1:
movl $1, %eax
@@ -160,53 +140,7 @@ _Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.type _Z7helper2PFiiiES0_ii, at function
_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.cfi_startproc
-# %bb.0:
- cmpq %rsi, %rdi
- je .LBB7_1
-# %bb.2:
- pushq %rbp
- .cfi_def_cfa_offset 16
- pushq %r15
- .cfi_def_cfa_offset 24
- pushq %r14
- .cfi_def_cfa_offset 32
- pushq %rbx
- .cfi_def_cfa_offset 40
- pushq %rax
- .cfi_def_cfa_offset 48
- .cfi_offset %rbx, -40
- .cfi_offset %r14, -32
- .cfi_offset %r15, -24
- .cfi_offset %rbp, -16
- movl %ecx, %ebx
- movl %edx, %ebp
- movq %rsi, %r14
- movq %rdi, %rax
- movl %edx, %edi
- movl %ecx, %esi
- callq *%rax
- movl %eax, %r15d
- movl %ebp, %edi
- movl %ebx, %esi
- callq *%r14
- addl %r15d, %eax
- addq $8, %rsp
- .cfi_def_cfa_offset 40
- popq %rbx
- .cfi_def_cfa_offset 32
- popq %r14
- .cfi_def_cfa_offset 24
- popq %r15
- .cfi_def_cfa_offset 16
- popq %rbp
- .cfi_def_cfa_offset 8
- .cfi_restore %rbx
- .cfi_restore %r14
- .cfi_restore %r15
- .cfi_restore %rbp
- retq
-.LBB7_1:
- movl $2, %eax
+ # Operates on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
@@ -217,70 +151,19 @@ _Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
.type main, at function
main: # @main
.cfi_startproc
-# %bb.0:
- pushq %rbp
- .cfi_def_cfa_offset 16
- pushq %r15
- .cfi_def_cfa_offset 24
- pushq %r14
- .cfi_def_cfa_offset 32
- pushq %r12
- .cfi_def_cfa_offset 40
- pushq %rbx
- .cfi_def_cfa_offset 48
- .cfi_offset %rbx, -48
- .cfi_offset %r12, -40
- .cfi_offset %r14, -32
- .cfi_offset %r15, -24
- .cfi_offset %rbp, -16
movq FooVar at GOTPCREL(%rip), %r14
- movl (%r14), %esi
movq BarVar at GOTPCREL(%rip), %r15
- movl (%r15), %edx
leaq _Z6barAddii(%rip), %rdi
callq _Z7helper1PFiiiEii
- movl %eax, %ebx
- movl (%r14), %edx
- movl (%r15), %ecx
leaq _Z6fooMulii(%rip), %rdi
leaq _Z6barMulii(%rip), %rsi
callq _Z7helper2PFiiiES0_ii
- movl %eax, %ebp
- addl %ebx, %ebp
- movl (%r14), %ebx
- movl (%r15), %r14d
- movl %ebx, %edi
- movl %r14d, %esi
callq _Z6fooSubii
- movl %eax, %r15d
- movl %ebx, %edi
- movl %r14d, %esi
callq _Z6barSubii
- movl %eax, %r12d
- addl %r15d, %r12d
- addl %ebp, %r12d
- movl %ebx, %edi
- movl %r14d, %esi
callq _Z6fooAddii
- addl %r12d, %eax
- popq %rbx
- .cfi_def_cfa_offset 40
- popq %r12
- .cfi_def_cfa_offset 32
- popq %r14
- .cfi_def_cfa_offset 24
- popq %r15
- .cfi_def_cfa_offset 16
- popq %rbp
- .cfi_def_cfa_offset 8
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
# -- End function
.ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
- .addrsig_sym _Z6fooMulii
- .addrsig_sym _Z6barMulii
- .addrsig_sym _Z6barAddii
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index 6557bb9107517c..9a1c99becb0363 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -8,8 +8,8 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK: skipping function _Z6fooMulii
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index 64419fb568c2b8..66696c334b1556 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -8,8 +8,8 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK: skipping function _Z6fooMulii
>From e867900db846778bdef86b03bf4cde0b577f1065 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Fri, 22 Nov 2024 13:06:24 -0800
Subject: [PATCH 13/34] changed comment
---
bolt/lib/Core/BinaryContext.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 7489f9dc8c3d16..caf09c0c18ead0 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -1959,7 +1959,8 @@ static void printDebugInfo(raw_ostream &OS, const MCInst &Instruction,
OS << " discriminator:" << Row.Discriminator;
}
-/// Skip instructions that are not interesting for safe ICF.
+/// Skip instructions that do not potentially manipulate or compare function
+/// addresses.
static bool skipInstruction(const MCInst &Inst, const BinaryContext &BC) {
const bool IsX86 = BC.isX86();
return (BC.MIB->isPseudo(Inst) || BC.MIB->isUnconditionalBranch(Inst) ||
>From ab51077d3d226fdd1e7018394645928493abbae0 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Mon, 25 Nov 2024 13:53:39 -0800
Subject: [PATCH 14/34] consolidate main/helper assembly under main. Next step
move to test themselves
---
bolt/test/X86/Inputs/helperSafeICF.s | 39 ------------
.../Inputs/helperSafeICFGlobalConstPtrNoPic.s | 24 -------
...lperSafeICFGlobalConstPtrNoPicExtFuncRef.s | 55 ----------------
.../Inputs/helperSafeICFGlobalConstPtrPic.s | 24 -------
...helperSafeICFGlobalConstPtrPicExtFuncRef.s | 55 ----------------
bolt/test/X86/Inputs/helperSafeICFICPTest.s | 40 ------------
.../Inputs/mainSafeICFGlobalConstPtrNoPic.s | 20 ++++++
...mainSafeICFGlobalConstPtrNoPicExtFuncRef.s | 53 ++++++++++++++++
.../X86/Inputs/mainSafeICFGlobalConstPtrPic.s | 19 ++++++
.../mainSafeICFGlobalConstPtrPicExtFuncRef.s | 63 +++++++++++++++++++
bolt/test/X86/Inputs/mainSafeICFICPTest.s | 36 +++++++++++
.../X86/Inputs/mainSafeICFTest2GlobalVarO0.s | 27 ++++++++
.../X86/Inputs/mainSafeICFTest2GlobalVarO3.s | 34 ++++++++++
.../X86/Inputs/mainSafeICFTest3LocalVarO0.s | 34 ++++++++++
.../X86/Inputs/mainSafeICFTest3LocalVarO3.s | 35 +++++++++++
bolt/test/X86/icf-safe-icp.test | 3 +-
bolt/test/X86/icf-safe-test1-no-cfg.test | 3 +-
bolt/test/X86/icf-safe-test1-no-relocs.test | 3 +-
bolt/test/X86/icf-safe-test1.test | 3 +-
.../icf-safe-test2GlobalConstPtrNoPic.test | 3 +-
...fe-test2GlobalConstPtrNoPicExtFuncRef.test | 3 +-
.../X86/icf-safe-test2GlobalConstPtrPic.test | 3 +-
...safe-test2GlobalConstPtrPicExtFuncRef.test | 3 +-
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 3 +-
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 3 +-
bolt/test/X86/icf-safe-test3LocalVarO0.test | 3 +-
bolt/test/X86/icf-safe-test3LocalVarO3.test | 3 +-
27 files changed, 333 insertions(+), 261 deletions(-)
delete mode 100644 bolt/test/X86/Inputs/helperSafeICF.s
delete mode 100644 bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
delete mode 100644 bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
delete mode 100644 bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
delete mode 100644 bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
delete mode 100644 bolt/test/X86/Inputs/helperSafeICFICPTest.s
diff --git a/bolt/test/X86/Inputs/helperSafeICF.s b/bolt/test/X86/Inputs/helperSafeICF.s
deleted file mode 100644
index 8ab47324454cbc..00000000000000
--- a/bolt/test/X86/Inputs/helperSafeICF.s
+++ /dev/null
@@ -1,39 +0,0 @@
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
- .text
- .file "helper.cpp"
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
-.Lfunc_end0:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end0-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
deleted file mode 100644
index a970897fa0771b..00000000000000
--- a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPic.s
+++ /dev/null
@@ -1,24 +0,0 @@
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
- .text
- .file "helper.cpp"
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
deleted file mode 100644
index 09259e0c3cd2d7..00000000000000
--- a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s
+++ /dev/null
@@ -1,55 +0,0 @@
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-# Manually modified to remove "extra" assembly.
-
- .text
- .file "helper.cpp"
- .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
- .p2align 4, 0x90
- .type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii: # @_Z12barAddHdlperii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
- .cfi_endproc
- # -- End function
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
- callq _Z12barAddHdlperii
- retq
-.Lfunc_end1:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
deleted file mode 100644
index a970897fa0771b..00000000000000
--- a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPic.s
+++ /dev/null
@@ -1,24 +0,0 @@
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
- .text
- .file "helper.cpp"
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
diff --git a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s b/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
deleted file mode 100644
index 836ff0e247ce79..00000000000000
--- a/bolt/test/X86/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s
+++ /dev/null
@@ -1,55 +0,0 @@
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-
-
- .text
- .file "helper.cpp"
- .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
- .p2align 4, 0x90
- .type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii: # @_Z12barAddHdlperii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size _Z12barAddHdlperii, .Lfunc_end0-_Z12barAddHdlperii
- .cfi_endproc
- # -- End function
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
- callq _Z12barAddHdlperii
- retq
-.Lfunc_end1:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end1-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/helperSafeICFICPTest.s b/bolt/test/X86/Inputs/helperSafeICFICPTest.s
deleted file mode 100644
index ae62b4f292656f..00000000000000
--- a/bolt/test/X86/Inputs/helperSafeICFICPTest.s
+++ /dev/null
@@ -1,40 +0,0 @@
-# clang++ -O2 helper.cpp -c -o helperProf.o
-# int returnFive() {
-# return 5;
-# }
-# int returnFourOrFive(int val) {
-# return val == 1 ? 4 : 5;
-# }
-
- .text
- .file "helper.cpp"
- .globl _Z10returnFivev # -- Begin function _Z10returnFivev
- .p2align 4, 0x90
- .type _Z10returnFivev, at function
-_Z10returnFivev: # @_Z10returnFivev
- .cfi_startproc
-# %bb.0: # %entry
- movl $5, %eax
- retq
-.Lfunc_end0:
- .size _Z10returnFivev, .Lfunc_end0-_Z10returnFivev
- .cfi_endproc
- # -- End function
- .globl _Z16returnFourOrFivei # -- Begin function _Z16returnFourOrFivei
- .p2align 4, 0x90
- .type _Z16returnFourOrFivei, at function
-_Z16returnFourOrFivei: # @_Z16returnFourOrFivei
- .cfi_startproc
-# %bb.0: # %entry
- xorl %eax, %eax
- cmpl $1, %edi
- sete %al
- xorl $5, %eax
- retq
-.Lfunc_end1:
- .size _Z16returnFourOrFivei, .Lfunc_end1-_Z16returnFourOrFivei
- .cfi_endproc
- # -- End function
- .ident "clang version 20.0.0git"
- .section ".note.GNU-stack","", at progbits
- .addrsig
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
index ddc1906d8c5818..0a46d1d9243ddb 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
@@ -39,6 +39,10 @@
# MY_PRINTF("val: %d", temp);
# return temp;
# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
@@ -136,6 +140,21 @@ main: # @main
.Lfunc_end6:
.size main, .Lfunc_end6-main
.cfi_endproc
+
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
# -- End function
.type .L.str, at object # @.str
.section .rodata.str1.1,"aMS", at progbits,1
@@ -143,4 +162,5 @@ main: # @main
.asciz "val: %d\n"
.size .L.str, 9
+
.ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
index 44d4a388995028..0556e1b9bea287 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
@@ -49,6 +49,19 @@
# MY_PRINTF("val: %d", temp);
# return temp;
# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
@@ -159,5 +172,45 @@ main: # @main
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
+
+
+ .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .p2align 4, 0x90
+ .type _Z12barAddHdlperii, at function
+_Z12barAddHdlperii: # @_Z12barAddHdlperii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end01:
+ .size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
+ .cfi_endproc
+ # -- End function
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+ callq _Z12barAddHdlperii
+ retq
+.Lfunc_end11:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end11-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+
# -- End function
.ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
index 3366b94f3ac9b5..d9c1197ac18192 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
@@ -39,6 +39,10 @@
# MY_PRINTF("val: %d", temp);
# return temp;
# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
@@ -127,5 +131,20 @@ main: # @main
.Lfunc_end6:
.size main, .Lfunc_end6-main
.cfi_endproc
+
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
# -- End function
.ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
index 913a1349312a29..834342fd095728 100644
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
+++ b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
@@ -48,6 +48,32 @@
# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
# MY_PRINTF("val: %d", temp);
# return temp;
+# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
# }
.text
@@ -168,6 +194,43 @@ main: # @main
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
+
+ .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .p2align 4, 0x90
+ .type _Z12barAddHdlperii, at function
+_Z12barAddHdlperii: # @_Z12barAddHdlperii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end01:
+ .size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
+ .cfi_endproc
+ # -- End function
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+ callq _Z12barAddHdlperii
+ retq
+.Lfunc_end11:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end11-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
# -- End function
.type .L.str, at object # @.str
.section .rodata.str1.1,"aMS", at progbits,1
diff --git a/bolt/test/X86/Inputs/mainSafeICFICPTest.s b/bolt/test/X86/Inputs/mainSafeICFICPTest.s
index 665256da48e777..0479fe56514c55 100644
--- a/bolt/test/X86/Inputs/mainSafeICFICPTest.s
+++ b/bolt/test/X86/Inputs/mainSafeICFICPTest.s
@@ -60,6 +60,13 @@
# sum += ptr->func(b, a) + ptr2->func(b, a);
# return 0;
# }
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
+# }
# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
@@ -78,6 +85,35 @@ _Z10createTypei: # @_Z10createTypei
.size _Z10createTypei, .Lfunc_end0-_Z10createTypei
.cfi_endproc
# -- End function
+
+ .globl _Z10returnFivev # -- Begin function _Z10returnFivev
+ .p2align 4, 0x90
+ .type _Z10returnFivev, at function
+_Z10returnFivev: # @_Z10returnFivev
+ .cfi_startproc
+# %bb.0: # %entry
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z10returnFivev, .Lfunc_end01-_Z10returnFivev
+ .cfi_endproc
+ # -- End function
+ .globl _Z16returnFourOrFivei # -- Begin function _Z16returnFourOrFivei
+ .p2align 4, 0x90
+ .type _Z16returnFourOrFivei, at function
+_Z16returnFourOrFivei: # @_Z16returnFourOrFivei
+ .cfi_startproc
+# %bb.0: # %entry
+ xorl %eax, %eax
+ cmpl $1, %edi
+ sete %al
+ xorl $5, %eax
+ retq
+.Lfunc_end11:
+ .size _Z16returnFourOrFivei, .Lfunc_end11-_Z16returnFourOrFivei
+ .cfi_endproc
+
+
.globl main # -- Begin function main
.p2align 4, 0x90
.type main, at function
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
index 42b5069f0fdd66..072901b2319a4e 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
@@ -163,8 +163,35 @@ main: # @main
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
+ .cfi_endproc
+
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
.cfi_endproc
# -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
.type funcGlobalBarMul, at object # @funcGlobalBarMul
.data
.globl funcGlobalBarMul
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
index 8a0d76a15aca9e..f8c9fe390fea42 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
@@ -44,6 +44,13 @@
# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
# return temp;
+# }
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
# }
.text
.file "main.cpp"
@@ -163,8 +170,35 @@ main: # @main
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
+ .cfi_endproc
+
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
.cfi_endproc
# -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
.type funcGlobalBarMul, at object # @funcGlobalBarMul
.data
.globl funcGlobalBarMul
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
index 7a9e3fec52a697..a47e7348143630 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
@@ -46,6 +46,13 @@
# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
# MY_PRINTF("val: %d", temp);
# return temp;
+# }
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
# }
.text
.file "main.cpp"
@@ -164,8 +171,35 @@ main: # @main
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
+ .cfi_endproc
+
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
.cfi_endproc
# -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
.type _ZZ4mainE16funcGlobalBarAdd, at object # @_ZZ4mainE16funcGlobalBarAdd
.data
.p2align 3, 0x0
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
index d7e70a397eb1e8..d4292fb9b65eee 100644
--- a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
+++ b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
@@ -45,6 +45,13 @@
# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
# MY_PRINTF("val: %d", temp);
# return temp;
+# }
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
# }
.text
.file "main.cpp"
@@ -164,6 +171,34 @@ main: # @main
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
+ .cfi_endproc
+
+
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
.cfi_endproc
# -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
.ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index a88a31c620330c..543d61a1f0734f 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -3,8 +3,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFICPTest.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFICPTest.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index bbcac0a18977f1..5a147c792eae03 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -2,8 +2,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf=all -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf --skip-funcs=_Z7helper1PFiiiEii,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index 43be7f19af4bc8..fbaccebe30a957 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -2,8 +2,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe
+# RUN: %clang %cflags %t1.o -o %t.exe
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: not llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index 89479102f1fda6..e991f2126cf3fb 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -2,8 +2,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index fb72e8413ac8cc..eddc3e64650eef 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -3,8 +3,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrNoPic.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFGlobalConstPtrNoPic.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q -no-pie
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q -no-pie
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
index fe8009d6087cc9..8c33059c1213f3 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
@@ -3,8 +3,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFGlobalConstPtrNoPicExtFuncRef.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q -no-pie
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q -no-pie
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
index 22d85b92a0454a..99e633102f3ce5 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -3,8 +3,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrPic.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFGlobalConstPtrPic.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
index 9482ac688d8a72..23a94d3e11879b 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -3,8 +3,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICFGlobalConstPtrPicExtFuncRef.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index cfe2dd0c745321..6666e488fa7e23 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -2,8 +2,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest2GlobalVarO0.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index 9a1c99becb0363..0c8857960e41e9 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -2,8 +2,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest2GlobalVarO3.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
index 88d6249f405144..4172b32002b36b 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -2,8 +2,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest3LocalVarO0.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index 66696c334b1556..04809ad6dab701 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -2,8 +2,7 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest3LocalVarO3.s -o %t1.o
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/helperSafeICF.s -o %t2.o
-# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
>From 8fe4b3cf37ad39cc056f46ffc8c0bcf86865119e Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Mon, 25 Nov 2024 16:26:51 -0800
Subject: [PATCH 15/34] move assembly into test
---
.../Inputs/mainSafeICFGlobalConstPtrNoPic.s | 166 ----------
...mainSafeICFGlobalConstPtrNoPicExtFuncRef.s | 216 -------------
.../X86/Inputs/mainSafeICFGlobalConstPtrPic.s | 150 ---------
.../mainSafeICFGlobalConstPtrPicExtFuncRef.s | 241 ---------------
bolt/test/X86/Inputs/mainSafeICFICPTest.s | 285 -----------------
bolt/test/X86/Inputs/mainSafeICFTest1.s | 170 -----------
.../X86/Inputs/mainSafeICFTest2GlobalVarO0.s | 209 -------------
.../X86/Inputs/mainSafeICFTest2GlobalVarO3.s | 210 -------------
.../X86/Inputs/mainSafeICFTest3LocalVarO0.s | 210 -------------
.../X86/Inputs/mainSafeICFTest3LocalVarO3.s | 204 -------------
bolt/test/X86/icf-safe-icp.test | 289 +++++++++++++++++-
bolt/test/X86/icf-safe-test1-no-cfg.test | 173 ++++++++++-
bolt/test/X86/icf-safe-test1-no-relocs.test | 173 ++++++++++-
bolt/test/X86/icf-safe-test1.test | 173 ++++++++++-
.../icf-safe-test2GlobalConstPtrNoPic.test | 169 +++++++++-
...fe-test2GlobalConstPtrNoPicExtFuncRef.test | 219 ++++++++++++-
.../X86/icf-safe-test2GlobalConstPtrPic.test | 153 +++++++++-
...safe-test2GlobalConstPtrPicExtFuncRef.test | 245 ++++++++++++++-
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 213 ++++++++++++-
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 213 ++++++++++++-
bolt/test/X86/icf-safe-test3LocalVarO0.test | 213 ++++++++++++-
bolt/test/X86/icf-safe-test3LocalVarO3.test | 207 ++++++++++++-
22 files changed, 2428 insertions(+), 2073 deletions(-)
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFICPTest.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFTest1.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
delete mode 100644 bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
deleted file mode 100644
index 0a46d1d9243ddb..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPic.s
+++ /dev/null
@@ -1,166 +0,0 @@
-# clang++ main.cpp -c -o
-# #define MY_CONST const
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# MY_CONST int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
-# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar)
-# fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end0:
- .size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end1:
- .size _Z6barMulii, .Lfunc_end1-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end2:
- .size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
- retq
-.Lfunc_end3:
- .size _Z6barAddii, .Lfunc_end3-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
- .cfi_startproc
- movabsq $_Z6barAddii, %rax
- cmpq %rax, -16(%rbp)
- retq
-.Lfunc_end4:
- .size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
- .p2align 4, 0x90
- .type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
- .cfi_startproc
- # no direct function references.
- retq
-.Lfunc_end5:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- movl FooVar, %esi
- movl BarVar, %edx
- movabsq $_Z6barAddii, %rdi
- callq _Z7helper1PFKiiiEii
- movl %eax, -28(%rbp) # 4-byte Spill
- movl FooVar, %edx
- movl BarVar, %ecx
- movabsq $_Z6fooMulii, %rdi
- movabsq $_Z6barMulii, %rsi
- callq _Z7helper2PFKiiiES1_ii
- retq
-.Lfunc_end6:
- .size main, .Lfunc_end6-main
- .cfi_endproc
-
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
- # -- End function
- .type .L.str, at object # @.str
- .section .rodata.str1.1,"aMS", at progbits,1
-.L.str:
- .asciz "val: %d\n"
- .size .L.str, 9
-
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
deleted file mode 100644
index 0556e1b9bea287..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s
+++ /dev/null
@@ -1,216 +0,0 @@
-# clang++ main.cpp -c -o
-# #define MY_CONST const
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# MY_CONST int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# extern MY_CONST int barAddHdlper(int a, int b);
-# extern MY_CONST int fooGlobalFuncHelper(int a, int b);
-# MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
-# MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii:
- .cfi_startproc # @_Z6barAddii
- addl -8(%rbp), %eax
- retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
- .cfi_startproc
- movabsq $_Z6barAddii, %rax
- cmpq %rax, -16(%rbp)
- retq
-.Lfunc_end6:
- .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
- .p2align 4, 0x90
- .type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
- .cfi_startproc
- # All operations on registers.
- retq
-.Lfunc_end7:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- movl FooVar, %esi
- movl BarVar, %edx
- movabsq $_Z12barAddHdlperii, %rdi
- callq _Z7helper1PFKiiiEii
- movl FooVar, %edx
- movl BarVar, %ecx
- movabsq $_Z6fooMulii, %rdi
- movabsq $_Z19fooGlobalFuncHelperii, %rsi
- callq _Z7helper2PFKiiiES1_ii
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
-
- .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
- .p2align 4, 0x90
- .type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii: # @_Z12barAddHdlperii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end01:
- .size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
- .cfi_endproc
- # -- End function
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
- callq _Z12barAddHdlperii
- retq
-.Lfunc_end11:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end11-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
-
- # -- End function
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
deleted file mode 100644
index d9c1197ac18192..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPic.s
+++ /dev/null
@@ -1,150 +0,0 @@
-# clang++ main.cpp -c -o
-# #define MY_CONST const
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# MY_CONST int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
-# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) +
-# fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size _Z6barMulii, .Lfunc_end1-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size _Z6barAddii, .Lfunc_end3-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
- .cfi_startproc
- leaq _Z6barAddii(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
-.Lfunc_end4:
- .size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
- .p2align 4, 0x90
- .type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end5:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFKiiiEii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- leaq _Z6barMulii(%rip), %rsi
- callq _Z7helper2PFKiiiES1_ii
- retq
-.Lfunc_end6:
- .size main, .Lfunc_end6-main
- .cfi_endproc
-
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
- # -- End function
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s b/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
deleted file mode 100644
index 834342fd095728..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s
+++ /dev/null
@@ -1,241 +0,0 @@
-# clang++ main.cpp -c -o
-# #define MY_CONST const
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# MY_CONST int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# extern MY_CONST int barAddHdlper(int a, int b);
-# extern MY_CONST int fooGlobalFuncHelper(int a, int b);
-# MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
-# MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-
- .text
- .file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
- .cfi_startproc
- leaq _Z6barAddii(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
-.Lfunc_end6:
- .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
- .p2align 4, 0x90
- .type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- movq _Z12barAddHdlperii at GOTPCREL(%rip), %rdi
- callq _Z7helper1PFKiiiEii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- movq _Z19fooGlobalFuncHelperii at GOTPCREL(%rip), %rsi
- callq _Z7helper2PFKiiiES1_ii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii # 4-byte Spill
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
- .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
- .p2align 4, 0x90
- .type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii: # @_Z12barAddHdlperii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end01:
- .size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
- .cfi_endproc
- # -- End function
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
- callq _Z12barAddHdlperii
- retq
-.Lfunc_end11:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end11-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
- # -- End function
- .type .L.str, at object # @.str
- .section .rodata.str1.1,"aMS", at progbits,1
-.L.str:
- .asciz "val: %d\n"
- .size .L.str, 9
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFICPTest.s b/bolt/test/X86/Inputs/mainSafeICFICPTest.s
deleted file mode 100644
index 0479fe56514c55..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFICPTest.s
+++ /dev/null
@@ -1,285 +0,0 @@
-# generate profile
-# clang++ -O2 -fprofile-generate=. main.cpp -c -o mainProf.o
-# PROF=test.profdata
-# clang++ -m64 -fprofile-use=$PROF \
-# -mllvm -disable-icp=true -mllvm -print-after-all \
-# -g0 -flto=thin -fwhole-program-vtables -fno-split-lto-unit -O2 \
-# -fdebug-types-section \
-# main.cpp -c -o mainProfLTO.bc
-# PASS='pgo-icall-prom'
-# clang++ -m64 -fprofile-use=$PROF \
-# -O3 -Rpass=$PASS \
-# -mllvm -print-before=$PASS \
-# -mllvm -print-after=$PASS \
-# -mllvm -filter-print-funcs=main \
-# -mllvm -debug-only=$PASS \
-# -x ir \
-# mainProfLTO.bc -c -o mainProfFinal.o
-
-# class Base {
-# public:
-# virtual int func(int a, int b) const = 0;
-#
-# virtual ~Base() {};
-# };
-#
-# //namespace {
-# class Derived2 : public Base {
-# int c = 5;
-# public:
-# __attribute__((noinline)) int func(int a, int b)const override { return a * (a - b) + this->c; }
-#
-# ~Derived2() {}
-# };
-#
-# class Derived3 : public Base {
-# int c = 500;
-# public:
-# __attribute__((noinline)) int func(int a, int b) const override { return a * (a - b) + this->c; }
-# ~Derived3() {}
-# };
-# //} // namespace//
-#
-# __attribute__((noinline)) Base *createType(int a) {
-# Base *base = nullptr;
-# if (a == 4)
-# base = new Derived2();
-# else
-# base = new Derived3();
-# return base;
-# }
-#
-# extern int returnFive();
-# extern int returnFourOrFive(int val);
-# int main(int argc, char **argv) {
-# int sum = 0;
-# int a = returnFourOrFive(argc);
-# int b = returnFive();
-# Base *ptr = createType(a);
-# Base *ptr2 = createType(b);
-# sum += ptr->func(b, a) + ptr2->func(b, a);
-# return 0;
-# }
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
-# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
- .section .text.hot.,"ax", at progbits
- .globl _Z10createTypei # -- Begin function _Z10createTypei
- .p2align 4, 0x90
- .type _Z10createTypei, at function
-_Z10createTypei: # @_Z10createTypei
- .cfi_startproc
- callq _Znwm at PLT
- leaq _ZTV8Derived2+16(%rip), %rcx
- leaq _ZTV8Derived3+16(%rip), %rdx
- cmoveq %rcx, %rdx
- retq
-.Lfunc_end0:
- .size _Z10createTypei, .Lfunc_end0-_Z10createTypei
- .cfi_endproc
- # -- End function
-
- .globl _Z10returnFivev # -- Begin function _Z10returnFivev
- .p2align 4, 0x90
- .type _Z10returnFivev, at function
-_Z10returnFivev: # @_Z10returnFivev
- .cfi_startproc
-# %bb.0: # %entry
- movl $5, %eax
- retq
-.Lfunc_end01:
- .size _Z10returnFivev, .Lfunc_end01-_Z10returnFivev
- .cfi_endproc
- # -- End function
- .globl _Z16returnFourOrFivei # -- Begin function _Z16returnFourOrFivei
- .p2align 4, 0x90
- .type _Z16returnFourOrFivei, at function
-_Z16returnFourOrFivei: # @_Z16returnFourOrFivei
- .cfi_startproc
-# %bb.0: # %entry
- xorl %eax, %eax
- cmpl $1, %edi
- sete %al
- xorl $5, %eax
- retq
-.Lfunc_end11:
- .size _Z16returnFourOrFivei, .Lfunc_end11-_Z16returnFourOrFivei
- .cfi_endproc
-
-
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- callq _Z16returnFourOrFivei at PLT
- callq _Z10returnFivev at PLT
- callq _Z10createTypei
- callq _Z10createTypei
- leaq _ZNK8Derived24funcEii(%rip), %rcx
- jne .LBB1_2
- callq _ZNK8Derived24funcEii
-.LBB1_3: # %if.end.icp
- leaq _ZNK8Derived34funcEii(%rip), %rcx
- jne .LBB1_5
- callq _ZNK8Derived34funcEii
-.LBB1_6: # %if.end.icp3
- retq
-.LBB1_2: # %if.false.orig_indirect
- jmp .LBB1_3
-.LBB1_5: # %if.false.orig_indirect2
- jmp .LBB1_6
-.Lfunc_end1:
- .size main, .Lfunc_end1-main
- .cfi_endproc
- # -- End function
- .section .text.hot._ZNK8Derived24funcEii,"axG", at progbits,_ZNK8Derived24funcEii,comdat
- .weak _ZNK8Derived24funcEii # -- Begin function _ZNK8Derived24funcEii
- .p2align 4, 0x90
- .type _ZNK8Derived24funcEii, at function
-_ZNK8Derived24funcEii: # @_ZNK8Derived24funcEii
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end2:
- .size _ZNK8Derived24funcEii, .Lfunc_end2-_ZNK8Derived24funcEii
- .cfi_endproc
- # -- End function
- .section .text.unlikely._ZN8Derived2D0Ev,"axG", at progbits,_ZN8Derived2D0Ev,comdat
- .weak _ZN8Derived2D0Ev # -- Begin function _ZN8Derived2D0Ev
- .p2align 4, 0x90
- .type _ZN8Derived2D0Ev, at function
-_ZN8Derived2D0Ev: # @_ZN8Derived2D0Ev
- .cfi_startproc
-# %bb.0: # %entry
- movl $16, %esi
- jmp _ZdlPvm at PLT # TAILCALL
-.Lfunc_end3:
- .size _ZN8Derived2D0Ev, .Lfunc_end3-_ZN8Derived2D0Ev
- .cfi_endproc
- # -- End function
- .section .text.hot._ZNK8Derived34funcEii,"axG", at progbits,_ZNK8Derived34funcEii,comdat
- .weak _ZNK8Derived34funcEii # -- Begin function _ZNK8Derived34funcEii
- .p2align 4, 0x90
- .type _ZNK8Derived34funcEii, at function
-_ZNK8Derived34funcEii: # @_ZNK8Derived34funcEii
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end4:
- .size _ZNK8Derived34funcEii, .Lfunc_end4-_ZNK8Derived34funcEii
- .cfi_endproc
- # -- End function
- .section .text.unlikely._ZN4BaseD2Ev,"axG", at progbits,_ZN4BaseD2Ev,comdat
- .weak _ZN4BaseD2Ev # -- Begin function _ZN4BaseD2Ev
- .p2align 4, 0x90
- .type _ZN4BaseD2Ev, at function
-_ZN4BaseD2Ev: # @_ZN4BaseD2Ev
- .cfi_startproc
-# %bb.0: # %entry
- retq
-.Lfunc_end5:
- .size _ZN4BaseD2Ev, .Lfunc_end5-_ZN4BaseD2Ev
- .cfi_endproc
- # -- End function
- .section .text.unlikely._ZN8Derived3D0Ev,"axG", at progbits,_ZN8Derived3D0Ev,comdat
- .weak _ZN8Derived3D0Ev # -- Begin function _ZN8Derived3D0Ev
- .p2align 4, 0x90
- .type _ZN8Derived3D0Ev, at function
-_ZN8Derived3D0Ev: # @_ZN8Derived3D0Ev
- .cfi_startproc
-# %bb.0: # %entry
- movl $16, %esi
- jmp _ZdlPvm at PLT # TAILCALL
-.Lfunc_end6:
- .size _ZN8Derived3D0Ev, .Lfunc_end6-_ZN8Derived3D0Ev
- .cfi_endproc
- # -- End function
- .type _ZTV8Derived2, at object # @_ZTV8Derived2
- .section .data.rel.ro._ZTV8Derived2,"awG", at progbits,_ZTV8Derived2,comdat
- .weak _ZTV8Derived2
- .p2align 3, 0x0
-_ZTV8Derived2:
- .quad 0
- .quad _ZTI8Derived2
- .quad _ZNK8Derived24funcEii
- .quad _ZN4BaseD2Ev
- .quad _ZN8Derived2D0Ev
- .size _ZTV8Derived2, 40
-
- .type _ZTS8Derived2, at object # @_ZTS8Derived2
- .section .rodata._ZTS8Derived2,"aG", at progbits,_ZTS8Derived2,comdat
- .weak _ZTS8Derived2
-_ZTS8Derived2:
- .asciz "8Derived2"
- .size _ZTS8Derived2, 10
-
- .type _ZTS4Base, at object # @_ZTS4Base
- .section .rodata._ZTS4Base,"aG", at progbits,_ZTS4Base,comdat
- .weak _ZTS4Base
-_ZTS4Base:
- .asciz "4Base"
- .size _ZTS4Base, 6
-
- .type _ZTI4Base, at object # @_ZTI4Base
- .section .data.rel.ro._ZTI4Base,"awG", at progbits,_ZTI4Base,comdat
- .weak _ZTI4Base
- .p2align 3, 0x0
-_ZTI4Base:
- .quad _ZTVN10__cxxabiv117__class_type_infoE+16
- .quad _ZTS4Base
- .size _ZTI4Base, 16
-
- .type _ZTI8Derived2, at object # @_ZTI8Derived2
- .section .data.rel.ro._ZTI8Derived2,"awG", at progbits,_ZTI8Derived2,comdat
- .weak _ZTI8Derived2
- .p2align 3, 0x0
-_ZTI8Derived2:
- .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
- .quad _ZTS8Derived2
- .quad _ZTI4Base
- .size _ZTI8Derived2, 24
-
- .type _ZTV8Derived3, at object # @_ZTV8Derived3
- .section .data.rel.ro._ZTV8Derived3,"awG", at progbits,_ZTV8Derived3,comdat
- .weak _ZTV8Derived3
- .p2align 3, 0x0
-_ZTV8Derived3:
- .quad 0
- .quad _ZTI8Derived3
- .quad _ZNK8Derived34funcEii
- .quad _ZN4BaseD2Ev
- .quad _ZN8Derived3D0Ev
- .size _ZTV8Derived3, 40
-
- .type _ZTS8Derived3, at object # @_ZTS8Derived3
- .section .rodata._ZTS8Derived3,"aG", at progbits,_ZTS8Derived3,comdat
- .weak _ZTS8Derived3
-_ZTS8Derived3:
- .asciz "8Derived3"
- .size _ZTS8Derived3, 10
-
- .type _ZTI8Derived3, at object # @_ZTI8Derived3
- .section .data.rel.ro._ZTI8Derived3,"awG", at progbits,_ZTI8Derived3,comdat
- .weak _ZTI8Derived3
- .p2align 3, 0x0
-_ZTI8Derived3:
- .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
- .quad _ZTS8Derived3
- .quad _ZTI4Base
- .size _ZTI8Derived3, 24
-
- .cg_profile _Z10createTypei, _Znwm, 2
- .cg_profile main, _Z16returnFourOrFivei, 1
- .cg_profile main, _Z10returnFivev, 1
- .cg_profile main, _Z10createTypei, 2
- .cg_profile main, _ZNK8Derived24funcEii, 1
- .cg_profile main, _ZNK8Derived34funcEii, 1
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest1.s b/bolt/test/X86/Inputs/mainSafeICFTest1.s
deleted file mode 100644
index b6e0b6cbf97dcc..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFTest1.s
+++ /dev/null
@@ -1,170 +0,0 @@
-# clang++ -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# int main(int argc, char **argv) {
-# int temp = helper1(barAdd, FooVar, BarVar) +
-# helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# return temp;
-# }
- .text
- .file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
- .cfi_startproc
- leaq _Z6barAddii(%rip), %rax
- cmpq %rax, -16(%rbp)
- jne .LBB6_2
- jmp .LBB6_3
-.LBB6_2:
- callq *%rax
-.LBB6_3:
- retq
-.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
- .p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFiiiEii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- leaq _Z6barMulii(%rip), %rsi
- callq _Z7helper2PFiiiES0_ii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
- # -- End function
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
deleted file mode 100644
index 072901b2319a4e..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO0.s
+++ /dev/null
@@ -1,209 +0,0 @@
-# clang++ -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# static int (*funcGlobalBarAdd)(int, int) = barAdd;
-# int (*funcGlobalBarMul)(int, int) = barMul;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# return temp;
-# }
-# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
- .cfi_startproc
- leaq _Z6barAddii(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
-.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
- .p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- movq _ZL16funcGlobalBarAdd(%rip), %rdi
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z7helper1PFiiiEii
- movq funcGlobalBarMul(%rip), %rsi
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- callq _Z7helper2PFiiiES0_ii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
-.Lfunc_end01:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .type funcGlobalBarMul, at object # @funcGlobalBarMul
- .data
- .globl funcGlobalBarMul
- .p2align 3, 0x0
-funcGlobalBarMul:
- .quad _Z6barMulii
- .size funcGlobalBarMul, 8
-
- .type _ZL16funcGlobalBarAdd, at object # @_ZL16funcGlobalBarAdd
- .p2align 3, 0x0
-_ZL16funcGlobalBarAdd:
- .quad _Z6barAddii
- .size _ZL16funcGlobalBarAdd, 8
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s b/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
deleted file mode 100644
index f8c9fe390fea42..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFTest2GlobalVarO3.s
+++ /dev/null
@@ -1,210 +0,0 @@
-# clang++ -O3 -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# static int (*funcGlobalBarAdd)(int, int) = barAdd;
-# int (*funcGlobalBarMul)(int, int) = barMul;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# return temp;
-# }
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
- .text
- .file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
- subl %esi, %eax
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
- subl %esi, %eax
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
-# %bb.0:
- # kill: def $esi killed $esi def $rsi
- # kill: def $edi killed $edi def $rdi
- leal (%rdi,%rsi), %eax
- retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
-# %bb.0:
- # kill: def $esi killed $esi def $rsi
- # kill: def $edi killed $edi def $rdi
- leal (%rdi,%rsi), %eax
- retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
- .cfi_startproc
- leaq _Z6barAddii(%rip), %rcx
- cmpq %rcx, %rdi
- retq
-.LBB6_1:
- movl $1, %eax
- retq
-.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
- .p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %r14
- movq BarVar at GOTPCREL(%rip), %r15
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFiiiEii
- movq funcGlobalBarMul(%rip), %rsi
- leaq _Z6fooMulii(%rip), %rdi
- callq _Z7helper2PFiiiES0_ii
- callq _Z6fooSubii
- callq _Z6barSubii
- callq _Z6fooAddii
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
-.Lfunc_end01:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .type funcGlobalBarMul, at object # @funcGlobalBarMul
- .data
- .globl funcGlobalBarMul
- .p2align 3, 0x0
-funcGlobalBarMul:
- .quad _Z6barMulii
- .size funcGlobalBarMul, 8
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
deleted file mode 100644
index a47e7348143630..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO0.s
+++ /dev/null
@@ -1,210 +0,0 @@
-
-# clang++ -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# int main(int argc, char **argv) {
-# static int (*funcGlobalBarAdd)(int, int) = barAdd;
-# int (*funcGlobalBarMul)(int, int) = barMul;
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
- .text
- .file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
- .cfi_startproc
- leaq _Z6barAddii(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
-.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
- .p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- leaq _Z6barMulii(%rip), %rax
- movq _ZZ4mainE16funcGlobalBarAdd(%rip), %rdi
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z7helper1PFiiiEii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- callq _Z7helper2PFiiiES0_ii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
-.Lfunc_end01:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .type _ZZ4mainE16funcGlobalBarAdd, at object # @_ZZ4mainE16funcGlobalBarAdd
- .data
- .p2align 3, 0x0
-_ZZ4mainE16funcGlobalBarAdd:
- .quad _Z6barAddii
- .size _ZZ4mainE16funcGlobalBarAdd, 8
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s b/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
deleted file mode 100644
index d4292fb9b65eee..00000000000000
--- a/bolt/test/X86/Inputs/mainSafeICFTest3LocalVarO3.s
+++ /dev/null
@@ -1,204 +0,0 @@
-# clang++ -O3 -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# int main(int argc, char **argv) {
-# static int (*funcGlobalBarAdd)(int, int) = barAdd;
-# int (*funcGlobalBarMul)(int, int) = barMul;
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
- .text
- .file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
- .p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
- .cfi_startproc
- subl %esi, %eax
- retq
-.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
- .cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
- .p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
- .cfi_startproc
- subl %esi, %eax
- retq
-.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
- .cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
- .p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
- .cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
- .p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
- .cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
- .p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
- .cfi_startproc
-# %bb.0:
- # kill: def $esi killed $esi def $rsi
- # kill: def $edi killed $edi def $rdi
- leal (%rdi,%rsi), %eax
- retq
-.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
- .cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
- .p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
- .cfi_startproc
-# %bb.0:
- # kill: def $esi killed $esi def $rsi
- # kill: def $edi killed $edi def $rdi
- leal (%rdi,%rsi), %eax
- retq
-.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
- .cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
- .cfi_startproc
- leaq _Z6barAddii(%rip), %rcx
- cmpq %rcx, %rdi
- retq
-.LBB6_1:
- movl $1, %eax
- retq
-.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
- .cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
- .p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
- .cfi_endproc
- # -- End function
- .globl main # -- Begin function main
- .p2align 4, 0x90
- .type main, at function
-main: # @main
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %r14
- movq BarVar at GOTPCREL(%rip), %r15
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFiiiEii
- leaq _Z6fooMulii(%rip), %rdi
- leaq _Z6barMulii(%rip), %rsi
- callq _Z7helper2PFiiiES0_ii
- callq _Z6fooSubii
- callq _Z6barSubii
- callq _Z6fooAddii
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
-
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
- .p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
-.Lfunc_end01:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
- .cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1 # 0x1
- .size FooVar, 4
-
- .type BarVar, at object # @BarVar
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2 # 0x2
- .size BarVar, 4
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index 543d61a1f0734f..bd6e486700e933 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -2,7 +2,7 @@
# The compare is generated by the ICP path with instrumentation profiling.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFICPTest.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -16,3 +16,290 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# SAFEICFCHECK-NEXT: ===---------
+
+
+# generate profile
+# clang++ -O2 -fprofile-generate=. main.cpp -c -o mainProf.o
+# PROF=test.profdata
+# clang++ -m64 -fprofile-use=$PROF \
+# -mllvm -disable-icp=true -mllvm -print-after-all \
+# -g0 -flto=thin -fwhole-program-vtables -fno-split-lto-unit -O2 \
+# -fdebug-types-section \
+# main.cpp -c -o mainProfLTO.bc
+# PASS='pgo-icall-prom'
+# clang++ -m64 -fprofile-use=$PROF \
+# -O3 -Rpass=$PASS \
+# -mllvm -print-before=$PASS \
+# -mllvm -print-after=$PASS \
+# -mllvm -filter-print-funcs=main \
+# -mllvm -debug-only=$PASS \
+# -x ir \
+# mainProfLTO.bc -c -o mainProfFinal.o
+
+# class Base {
+# public:
+# virtual int func(int a, int b) const = 0;
+#
+# virtual ~Base() {};
+# };
+#
+# //namespace {
+# class Derived2 : public Base {
+# int c = 5;
+# public:
+# __attribute__((noinline)) int func(int a, int b)const override { return a * (a - b) + this->c; }
+#
+# ~Derived2() {}
+# };
+#
+# class Derived3 : public Base {
+# int c = 500;
+# public:
+# __attribute__((noinline)) int func(int a, int b) const override { return a * (a - b) + this->c; }
+# ~Derived3() {}
+# };
+# //} // namespace//
+#
+# __attribute__((noinline)) Base *createType(int a) {
+# Base *base = nullptr;
+# if (a == 4)
+# base = new Derived2();
+# else
+# base = new Derived3();
+# return base;
+# }
+#
+# extern int returnFive();
+# extern int returnFourOrFive(int val);
+# int main(int argc, char **argv) {
+# int sum = 0;
+# int a = returnFourOrFive(argc);
+# int b = returnFive();
+# Base *ptr = createType(a);
+# Base *ptr2 = createType(b);
+# sum += ptr->func(b, a) + ptr2->func(b, a);
+# return 0;
+# }
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
+# }
+# Manually modified to remove "extra" assembly.
+ .text
+ .file "main.cpp"
+ .section .text.hot.,"ax", at progbits
+ .globl _Z10createTypei # -- Begin function _Z10createTypei
+ .p2align 4, 0x90
+ .type _Z10createTypei, at function
+_Z10createTypei: # @_Z10createTypei
+ .cfi_startproc
+ callq _Znwm at PLT
+ leaq _ZTV8Derived2+16(%rip), %rcx
+ leaq _ZTV8Derived3+16(%rip), %rdx
+ cmoveq %rcx, %rdx
+ retq
+.Lfunc_end0:
+ .size _Z10createTypei, .Lfunc_end0-_Z10createTypei
+ .cfi_endproc
+ # -- End function
+
+ .globl _Z10returnFivev # -- Begin function _Z10returnFivev
+ .p2align 4, 0x90
+ .type _Z10returnFivev, at function
+_Z10returnFivev: # @_Z10returnFivev
+ .cfi_startproc
+# %bb.0: # %entry
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z10returnFivev, .Lfunc_end01-_Z10returnFivev
+ .cfi_endproc
+ # -- End function
+ .globl _Z16returnFourOrFivei # -- Begin function _Z16returnFourOrFivei
+ .p2align 4, 0x90
+ .type _Z16returnFourOrFivei, at function
+_Z16returnFourOrFivei: # @_Z16returnFourOrFivei
+ .cfi_startproc
+# %bb.0: # %entry
+ xorl %eax, %eax
+ cmpl $1, %edi
+ sete %al
+ xorl $5, %eax
+ retq
+.Lfunc_end11:
+ .size _Z16returnFourOrFivei, .Lfunc_end11-_Z16returnFourOrFivei
+ .cfi_endproc
+
+
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ callq _Z16returnFourOrFivei at PLT
+ callq _Z10returnFivev at PLT
+ callq _Z10createTypei
+ callq _Z10createTypei
+ leaq _ZNK8Derived24funcEii(%rip), %rcx
+ jne .LBB1_2
+ callq _ZNK8Derived24funcEii
+.LBB1_3: # %if.end.icp
+ leaq _ZNK8Derived34funcEii(%rip), %rcx
+ jne .LBB1_5
+ callq _ZNK8Derived34funcEii
+.LBB1_6: # %if.end.icp3
+ retq
+.LBB1_2: # %if.false.orig_indirect
+ jmp .LBB1_3
+.LBB1_5: # %if.false.orig_indirect2
+ jmp .LBB1_6
+.Lfunc_end1:
+ .size main, .Lfunc_end1-main
+ .cfi_endproc
+ # -- End function
+ .section .text.hot._ZNK8Derived24funcEii,"axG", at progbits,_ZNK8Derived24funcEii,comdat
+ .weak _ZNK8Derived24funcEii # -- Begin function _ZNK8Derived24funcEii
+ .p2align 4, 0x90
+ .type _ZNK8Derived24funcEii, at function
+_ZNK8Derived24funcEii: # @_ZNK8Derived24funcEii
+ .cfi_startproc
+ imull %esi, %eax
+ retq
+.Lfunc_end2:
+ .size _ZNK8Derived24funcEii, .Lfunc_end2-_ZNK8Derived24funcEii
+ .cfi_endproc
+ # -- End function
+ .section .text.unlikely._ZN8Derived2D0Ev,"axG", at progbits,_ZN8Derived2D0Ev,comdat
+ .weak _ZN8Derived2D0Ev # -- Begin function _ZN8Derived2D0Ev
+ .p2align 4, 0x90
+ .type _ZN8Derived2D0Ev, at function
+_ZN8Derived2D0Ev: # @_ZN8Derived2D0Ev
+ .cfi_startproc
+# %bb.0: # %entry
+ movl $16, %esi
+ jmp _ZdlPvm at PLT # TAILCALL
+.Lfunc_end3:
+ .size _ZN8Derived2D0Ev, .Lfunc_end3-_ZN8Derived2D0Ev
+ .cfi_endproc
+ # -- End function
+ .section .text.hot._ZNK8Derived34funcEii,"axG", at progbits,_ZNK8Derived34funcEii,comdat
+ .weak _ZNK8Derived34funcEii # -- Begin function _ZNK8Derived34funcEii
+ .p2align 4, 0x90
+ .type _ZNK8Derived34funcEii, at function
+_ZNK8Derived34funcEii: # @_ZNK8Derived34funcEii
+ .cfi_startproc
+ imull %esi, %eax
+ retq
+.Lfunc_end4:
+ .size _ZNK8Derived34funcEii, .Lfunc_end4-_ZNK8Derived34funcEii
+ .cfi_endproc
+ # -- End function
+ .section .text.unlikely._ZN4BaseD2Ev,"axG", at progbits,_ZN4BaseD2Ev,comdat
+ .weak _ZN4BaseD2Ev # -- Begin function _ZN4BaseD2Ev
+ .p2align 4, 0x90
+ .type _ZN4BaseD2Ev, at function
+_ZN4BaseD2Ev: # @_ZN4BaseD2Ev
+ .cfi_startproc
+# %bb.0: # %entry
+ retq
+.Lfunc_end5:
+ .size _ZN4BaseD2Ev, .Lfunc_end5-_ZN4BaseD2Ev
+ .cfi_endproc
+ # -- End function
+ .section .text.unlikely._ZN8Derived3D0Ev,"axG", at progbits,_ZN8Derived3D0Ev,comdat
+ .weak _ZN8Derived3D0Ev # -- Begin function _ZN8Derived3D0Ev
+ .p2align 4, 0x90
+ .type _ZN8Derived3D0Ev, at function
+_ZN8Derived3D0Ev: # @_ZN8Derived3D0Ev
+ .cfi_startproc
+# %bb.0: # %entry
+ movl $16, %esi
+ jmp _ZdlPvm at PLT # TAILCALL
+.Lfunc_end6:
+ .size _ZN8Derived3D0Ev, .Lfunc_end6-_ZN8Derived3D0Ev
+ .cfi_endproc
+ # -- End function
+ .type _ZTV8Derived2, at object # @_ZTV8Derived2
+ .section .data.rel.ro._ZTV8Derived2,"awG", at progbits,_ZTV8Derived2,comdat
+ .weak _ZTV8Derived2
+ .p2align 3, 0x0
+_ZTV8Derived2:
+ .quad 0
+ .quad _ZTI8Derived2
+ .quad _ZNK8Derived24funcEii
+ .quad _ZN4BaseD2Ev
+ .quad _ZN8Derived2D0Ev
+ .size _ZTV8Derived2, 40
+
+ .type _ZTS8Derived2, at object # @_ZTS8Derived2
+ .section .rodata._ZTS8Derived2,"aG", at progbits,_ZTS8Derived2,comdat
+ .weak _ZTS8Derived2
+_ZTS8Derived2:
+ .asciz "8Derived2"
+ .size _ZTS8Derived2, 10
+
+ .type _ZTS4Base, at object # @_ZTS4Base
+ .section .rodata._ZTS4Base,"aG", at progbits,_ZTS4Base,comdat
+ .weak _ZTS4Base
+_ZTS4Base:
+ .asciz "4Base"
+ .size _ZTS4Base, 6
+
+ .type _ZTI4Base, at object # @_ZTI4Base
+ .section .data.rel.ro._ZTI4Base,"awG", at progbits,_ZTI4Base,comdat
+ .weak _ZTI4Base
+ .p2align 3, 0x0
+_ZTI4Base:
+ .quad _ZTVN10__cxxabiv117__class_type_infoE+16
+ .quad _ZTS4Base
+ .size _ZTI4Base, 16
+
+ .type _ZTI8Derived2, at object # @_ZTI8Derived2
+ .section .data.rel.ro._ZTI8Derived2,"awG", at progbits,_ZTI8Derived2,comdat
+ .weak _ZTI8Derived2
+ .p2align 3, 0x0
+_ZTI8Derived2:
+ .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
+ .quad _ZTS8Derived2
+ .quad _ZTI4Base
+ .size _ZTI8Derived2, 24
+
+ .type _ZTV8Derived3, at object # @_ZTV8Derived3
+ .section .data.rel.ro._ZTV8Derived3,"awG", at progbits,_ZTV8Derived3,comdat
+ .weak _ZTV8Derived3
+ .p2align 3, 0x0
+_ZTV8Derived3:
+ .quad 0
+ .quad _ZTI8Derived3
+ .quad _ZNK8Derived34funcEii
+ .quad _ZN4BaseD2Ev
+ .quad _ZN8Derived3D0Ev
+ .size _ZTV8Derived3, 40
+
+ .type _ZTS8Derived3, at object # @_ZTS8Derived3
+ .section .rodata._ZTS8Derived3,"aG", at progbits,_ZTS8Derived3,comdat
+ .weak _ZTS8Derived3
+_ZTS8Derived3:
+ .asciz "8Derived3"
+ .size _ZTS8Derived3, 10
+
+ .type _ZTI8Derived3, at object # @_ZTI8Derived3
+ .section .data.rel.ro._ZTI8Derived3,"awG", at progbits,_ZTI8Derived3,comdat
+ .weak _ZTI8Derived3
+ .p2align 3, 0x0
+_ZTI8Derived3:
+ .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
+ .quad _ZTS8Derived3
+ .quad _ZTI4Base
+ .size _ZTI8Derived3, 24
+
+ .cg_profile _Z10createTypei, _Znwm, 2
+ .cg_profile main, _Z16returnFourOrFivei, 1
+ .cg_profile main, _Z10returnFivev, 1
+ .cg_profile main, _Z10createTypei, 2
+ .cg_profile main, _ZNK8Derived24funcEii, 1
+ .cg_profile main, _ZNK8Derived34funcEii, 1
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index 5a147c792eae03..4abfdb2df538ee 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -1,7 +1,7 @@
## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf=all -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf --skip-funcs=_Z7helper1PFiiiEii,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -17,3 +17,174 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
+
+# clang++ -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# int main(int argc, char **argv) {
+# int temp = helper1(barAdd, FooVar, BarVar) +
+# helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+ jmp .LBB6_3
+.LBB6_2:
+ callq *%rax
+.LBB6_3:
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFiiiEii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6fooMulii(%rip), %rdi
+ leaq _Z6barMulii(%rip), %rsi
+ callq _Z7helper2PFiiiES0_ii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6barSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooAddii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index fbaccebe30a957..f773d10b941684 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -1,7 +1,7 @@
## Checks that BOLT handles correctly with no relocations with --icf=safe option.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: not llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -12,3 +12,174 @@
# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK: BOLT-ERROR: Binary built without relocations. Safe ICF is not supported
+
+# clang++ -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# int main(int argc, char **argv) {
+# int temp = helper1(barAdd, FooVar, BarVar) +
+# helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+ jmp .LBB6_3
+.LBB6_2:
+ callq *%rax
+.LBB6_3:
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFiiiEii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6fooMulii(%rip), %rdi
+ leaq _Z6barMulii(%rip), %rsi
+ callq _Z7helper2PFiiiES0_ii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6barSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooAddii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index e991f2126cf3fb..f09117fe1a1783 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -1,7 +1,7 @@
## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest1.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -17,3 +17,174 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
+
+# clang++ -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# int main(int argc, char **argv) {
+# int temp = helper1(barAdd, FooVar, BarVar) +
+# helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# return temp;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ jne .LBB6_2
+ jmp .LBB6_3
+.LBB6_2:
+ callq *%rax
+.LBB6_3:
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFiiiEii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6fooMulii(%rip), %rdi
+ leaq _Z6barMulii(%rip), %rsi
+ callq _Z7helper2PFiiiES0_ii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6barSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooAddii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+ # -- End function
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index eddc3e64650eef..fee72ec53143ec 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -2,7 +2,7 @@
## This checks global const function pointer in -fno-pic mode is handled correctly.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrNoPic.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q -no-pie
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -16,3 +16,170 @@
# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: ===---------
+
+# clang++ main.cpp -c -o
+# #define MY_CONST const
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# MY_CONST int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
+# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar)
+# fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# Manually modified to remove "extra" assembly.
+ .text
+ .file "main.cpp"
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end0:
+ .size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end1:
+ .size _Z6barMulii, .Lfunc_end1-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end2:
+ .size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Lfunc_end3:
+ .size _Z6barAddii, .Lfunc_end3-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFKiiiEii, at function
+_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+ .cfi_startproc
+ movabsq $_Z6barAddii, %rax
+ cmpq %rax, -16(%rbp)
+ retq
+.Lfunc_end4:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFKiiiES1_ii, at function
+_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+ .cfi_startproc
+ # no direct function references.
+ retq
+.Lfunc_end5:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movl FooVar, %esi
+ movl BarVar, %edx
+ movabsq $_Z6barAddii, %rdi
+ callq _Z7helper1PFKiiiEii
+ movl %eax, -28(%rbp) # 4-byte Spill
+ movl FooVar, %edx
+ movl BarVar, %ecx
+ movabsq $_Z6fooMulii, %rdi
+ movabsq $_Z6barMulii, %rsi
+ callq _Z7helper2PFKiiiES1_ii
+ retq
+.Lfunc_end6:
+ .size main, .Lfunc_end6-main
+ .cfi_endproc
+
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+ # -- End function
+ .type .L.str, at object # @.str
+ .section .rodata.str1.1,"aMS", at progbits,1
+.L.str:
+ .asciz "val: %d\n"
+ .size .L.str, 9
+
+
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
index 8c33059c1213f3..4e6a292b530420 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
@@ -2,7 +2,7 @@
## This checks global const function pointer in -fno-pic mode is handled correctly.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrNoPicExtFuncRef.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q -no-pie
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -20,3 +20,220 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
+
+# clang++ main.cpp -c -o
+# #define MY_CONST const
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# MY_CONST int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# extern MY_CONST int barAddHdlper(int a, int b);
+# extern MY_CONST int fooGlobalFuncHelper(int a, int b);
+# MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
+# MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
+# Manually modified to remove "extra" assembly.
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii:
+ .cfi_startproc # @_Z6barAddii
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFKiiiEii, at function
+_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+ .cfi_startproc
+ movabsq $_Z6barAddii, %rax
+ cmpq %rax, -16(%rbp)
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFKiiiES1_ii, at function
+_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+ .cfi_startproc
+ # All operations on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movl FooVar, %esi
+ movl BarVar, %edx
+ movabsq $_Z12barAddHdlperii, %rdi
+ callq _Z7helper1PFKiiiEii
+ movl FooVar, %edx
+ movl BarVar, %ecx
+ movabsq $_Z6fooMulii, %rdi
+ movabsq $_Z19fooGlobalFuncHelperii, %rsi
+ callq _Z7helper2PFKiiiES1_ii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+
+
+ .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .p2align 4, 0x90
+ .type _Z12barAddHdlperii, at function
+_Z12barAddHdlperii: # @_Z12barAddHdlperii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end01:
+ .size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
+ .cfi_endproc
+ # -- End function
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+ callq _Z12barAddHdlperii
+ retq
+.Lfunc_end11:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end11-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+
+ # -- End function
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
index 99e633102f3ce5..fedd7e6a508884 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -2,7 +2,7 @@
## This checks global const function pointer in -fpic mode is handled correctly.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrPic.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -16,3 +16,154 @@
# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: ===---------
+
+# clang++ main.cpp -c -o
+# #define MY_CONST const
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# MY_CONST int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
+# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) +
+# fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# Manually modified to remove "extra" assembly.
+ .text
+ .file "main.cpp"
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barMulii, .Lfunc_end1-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barAddii, .Lfunc_end3-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFKiiiEii, at function
+_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ retq
+.Lfunc_end4:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFKiiiES1_ii, at function
+_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end5:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFKiiiEii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6fooMulii(%rip), %rdi
+ leaq _Z6barMulii(%rip), %rsi
+ callq _Z7helper2PFKiiiES1_ii
+ retq
+.Lfunc_end6:
+ .size main, .Lfunc_end6-main
+ .cfi_endproc
+
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+ # -- End function
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
index 23a94d3e11879b..956b7037fc2e98 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -2,7 +2,7 @@
## This checks global const function pointer with external function reference in -fpic mode is handled correctly.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFGlobalConstPtrPicExtFuncRef.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -20,3 +20,246 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
+
+
+# clang++ main.cpp -c -o
+# #define MY_CONST const
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# MY_CONST int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# MY_CONST int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# extern MY_CONST int barAddHdlper(int a, int b);
+# extern MY_CONST int fooGlobalFuncHelper(int a, int b);
+# MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
+# MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
+# clang++ helper.cpp -c -o
+# #define MY_CONST const
+# int FooVar = 1;
+# int BarVar = 2;
+# [[clang::noinline]]
+# MY_CONST int barAddHdlper(int a, int b) {
+# return a + b;
+# }
+#
+# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+# MY_CONST int fooGlobalFuncHelper(int a, int b) {
+# return 5 + funcGlobalBarMulExt(a, b);
+# }
+
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFKiiiEii, at function
+_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFKiiiES1_ii, at function
+_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ movq _Z12barAddHdlperii at GOTPCREL(%rip), %rdi
+ callq _Z7helper1PFKiiiEii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6fooMulii(%rip), %rdi
+ movq _Z19fooGlobalFuncHelperii at GOTPCREL(%rip), %rsi
+ callq _Z7helper2PFKiiiES1_ii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6barSubii # 4-byte Spill
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooAddii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+
+ .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .p2align 4, 0x90
+ .type _Z12barAddHdlperii, at function
+_Z12barAddHdlperii: # @_Z12barAddHdlperii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end01:
+ .size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
+ .cfi_endproc
+ # -- End function
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+ callq _Z12barAddHdlperii
+ retq
+.Lfunc_end11:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end11-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+ # -- End function
+ .type .L.str, at object # @.str
+ .section .rodata.str1.1,"aMS", at progbits,1
+.L.str:
+ .asciz "val: %d\n"
+ .size .L.str, 9
+
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index 6666e488fa7e23..4ebe647eccf01f 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -1,7 +1,7 @@
## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest2GlobalVarO0.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -17,3 +17,214 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
+
+
+# clang++ -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# static int (*funcGlobalBarAdd)(int, int) = barAdd;
+# int (*funcGlobalBarMul)(int, int) = barMul;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# return temp;
+# }
+# Manually modified to remove "extra" assembly.
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movq _ZL16funcGlobalBarAdd(%rip), %rdi
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z7helper1PFiiiEii
+ movq funcGlobalBarMul(%rip), %rsi
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6fooMulii(%rip), %rdi
+ callq _Z7helper2PFiiiES0_ii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6barSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooAddii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .type funcGlobalBarMul, at object # @funcGlobalBarMul
+ .data
+ .globl funcGlobalBarMul
+ .p2align 3, 0x0
+funcGlobalBarMul:
+ .quad _Z6barMulii
+ .size funcGlobalBarMul, 8
+
+ .type _ZL16funcGlobalBarAdd, at object # @_ZL16funcGlobalBarAdd
+ .p2align 3, 0x0
+_ZL16funcGlobalBarAdd:
+ .quad _Z6barAddii
+ .size _ZL16funcGlobalBarAdd, 8
+
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index 0c8857960e41e9..b25e66c704a3df 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -1,7 +1,7 @@
## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest2GlobalVarO3.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -17,3 +17,214 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
+
+# clang++ -O3 -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# static int (*funcGlobalBarAdd)(int, int) = barAdd;
+# int (*funcGlobalBarMul)(int, int) = barMul;
+# int main(int argc, char **argv) {
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# return temp;
+# }
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl %esi, %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl %esi, %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull %esi, %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull %esi, %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ # kill: def $esi killed $esi def $rsi
+ # kill: def $edi killed $edi def $rdi
+ leal (%rdi,%rsi), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ # kill: def $esi killed $esi def $rsi
+ # kill: def $edi killed $edi def $rdi
+ leal (%rdi,%rsi), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rcx
+ cmpq %rcx, %rdi
+ retq
+.LBB6_1:
+ movl $1, %eax
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movq FooVar at GOTPCREL(%rip), %r14
+ movq BarVar at GOTPCREL(%rip), %r15
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFiiiEii
+ movq funcGlobalBarMul(%rip), %rsi
+ leaq _Z6fooMulii(%rip), %rdi
+ callq _Z7helper2PFiiiES0_ii
+ callq _Z6fooSubii
+ callq _Z6barSubii
+ callq _Z6fooAddii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .type funcGlobalBarMul, at object # @funcGlobalBarMul
+ .data
+ .globl funcGlobalBarMul
+ .p2align 3, 0x0
+funcGlobalBarMul:
+ .quad _Z6barMulii
+ .size funcGlobalBarMul, 8
+
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
index 4172b32002b36b..9e6e52c64a533b 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -1,7 +1,7 @@
## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest3LocalVarO0.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -17,3 +17,214 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
+
+
+# clang++ -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# int main(int argc, char **argv) {
+# static int (*funcGlobalBarAdd)(int, int) = barAdd;
+# int (*funcGlobalBarMul)(int, int) = barMul;
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl -8(%rbp), %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull -8(%rbp), %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+ addl -8(%rbp), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rax
+ cmpq %rax, -16(%rbp)
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ leaq _Z6barMulii(%rip), %rax
+ movq _ZZ4mainE16funcGlobalBarAdd(%rip), %rdi
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z7helper1PFiiiEii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ leaq _Z6fooMulii(%rip), %rdi
+ callq _Z7helper2PFiiiES0_ii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6barSubii
+ movq FooVar at GOTPCREL(%rip), %rax
+ movq BarVar at GOTPCREL(%rip), %rax
+ callq _Z6fooAddii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .type _ZZ4mainE16funcGlobalBarAdd, at object # @_ZZ4mainE16funcGlobalBarAdd
+ .data
+ .p2align 3, 0x0
+_ZZ4mainE16funcGlobalBarAdd:
+ .quad _Z6barAddii
+ .size _ZZ4mainE16funcGlobalBarAdd, 8
+
+ .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index 04809ad6dab701..693888493caf78 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -1,7 +1,7 @@
## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %p/Inputs/mainSafeICFTest3LocalVarO3.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
@@ -17,3 +17,208 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
# SAFEICFCHECK-NEXT: ===---------
+
+# clang++ -O3 -c main.cpp -o main.o
+# extern int FooVar;
+# extern int BarVar;
+# [[clang::noinline]]
+# int fooSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int barSub(int a, int b) {
+# return a - b;
+# }
+# [[clang::noinline]]
+# int fooMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int barMul(int a, int b) {
+# return a * b;
+# }
+# [[clang::noinline]]
+# int fooAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int barAdd(int a, int b) {
+# return a + b;
+# }
+# [[clang::noinline]]
+# int helper1(int (*func)(int, int), int a, int b) {
+# if (func == barAdd)
+# return 1;
+# return func(a, b) - 4;
+# }
+# [[clang::noinline]]
+# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+# if (func == func2)
+# return 2;
+# return func(a, b) + func2(a, b);
+# }
+# int main(int argc, char **argv) {
+# static int (*funcGlobalBarAdd)(int, int) = barAdd;
+# int (*funcGlobalBarMul)(int, int) = barMul;
+# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+# MY_PRINTF("val: %d", temp);
+# return temp;
+# }
+# clang++ -c helper.cpp -o helper.o
+# int FooVar = 1;
+# int BarVar = 2;
+#
+# int fooGlobalFuncHelper(int a, int b) {
+# return 5;
+# }
+ .text
+ .file "main.cpp"
+ .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .p2align 4, 0x90
+ .type _Z6fooSubii, at function
+_Z6fooSubii: # @_Z6fooSubii
+ .cfi_startproc
+ subl %esi, %eax
+ retq
+.Lfunc_end0:
+ .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barSubii # -- Begin function _Z6barSubii
+ .p2align 4, 0x90
+ .type _Z6barSubii, at function
+_Z6barSubii: # @_Z6barSubii
+ .cfi_startproc
+ subl %esi, %eax
+ retq
+.Lfunc_end1:
+ .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .p2align 4, 0x90
+ .type _Z6fooMulii, at function
+_Z6fooMulii: # @_Z6fooMulii
+ .cfi_startproc
+ imull %esi, %eax
+ retq
+.Lfunc_end2:
+ .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barMulii # -- Begin function _Z6barMulii
+ .p2align 4, 0x90
+ .type _Z6barMulii, at function
+_Z6barMulii: # @_Z6barMulii
+ .cfi_startproc
+ imull %esi, %eax
+ retq
+.Lfunc_end3:
+ .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+ .p2align 4, 0x90
+ .type _Z6fooAddii, at function
+_Z6fooAddii: # @_Z6fooAddii
+ .cfi_startproc
+# %bb.0:
+ # kill: def $esi killed $esi def $rsi
+ # kill: def $edi killed $edi def $rdi
+ leal (%rdi,%rsi), %eax
+ retq
+.Lfunc_end4:
+ .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z6barAddii # -- Begin function _Z6barAddii
+ .p2align 4, 0x90
+ .type _Z6barAddii, at function
+_Z6barAddii: # @_Z6barAddii
+ .cfi_startproc
+# %bb.0:
+ # kill: def $esi killed $esi def $rsi
+ # kill: def $edi killed $edi def $rdi
+ leal (%rdi,%rsi), %eax
+ retq
+.Lfunc_end5:
+ .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+ .p2align 4, 0x90
+ .type _Z7helper1PFiiiEii, at function
+_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .cfi_startproc
+ leaq _Z6barAddii(%rip), %rcx
+ cmpq %rcx, %rdi
+ retq
+.LBB6_1:
+ movl $1, %eax
+ retq
+.Lfunc_end6:
+ .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+ .p2align 4, 0x90
+ .type _Z7helper2PFiiiES0_ii, at function
+_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .cfi_startproc
+ # Operates on registers.
+ retq
+.Lfunc_end7:
+ .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+ .cfi_startproc
+ movq FooVar at GOTPCREL(%rip), %r14
+ movq BarVar at GOTPCREL(%rip), %r15
+ leaq _Z6barAddii(%rip), %rdi
+ callq _Z7helper1PFiiiEii
+ leaq _Z6fooMulii(%rip), %rdi
+ leaq _Z6barMulii(%rip), %rsi
+ callq _Z7helper2PFiiiES0_ii
+ callq _Z6fooSubii
+ callq _Z6barSubii
+ callq _Z6fooAddii
+ retq
+.Lfunc_end8:
+ .size main, .Lfunc_end8-main
+ .cfi_endproc
+
+
+ .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .p2align 4, 0x90
+ .type _Z19fooGlobalFuncHelperii, at function
+_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .cfi_startproc
+# %bb.0:
+ movl $5, %eax
+ retq
+.Lfunc_end01:
+ .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
+ .cfi_endproc
+ # -- End function
+ .type FooVar, at object # @FooVar
+ .data
+ .globl FooVar
+ .p2align 2, 0x0
+FooVar:
+ .long 1 # 0x1
+ .size FooVar, 4
+
+ .type BarVar, at object # @BarVar
+ .globl BarVar
+ .p2align 2, 0x0
+BarVar:
+ .long 2 # 0x2
+ .size BarVar, 4
+
+ .ident "clang version 20.0.0git"
>From dc41c580850bccd5ce1284956b5cf26801bd992e Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Mon, 25 Nov 2024 16:36:42 -0800
Subject: [PATCH 16/34] removed some lines from assembly
---
bolt/test/X86/icf-safe-icp.test | 10 +---------
bolt/test/X86/icf-safe-test1-no-cfg.test | 2 --
bolt/test/X86/icf-safe-test1-no-relocs.test | 2 --
bolt/test/X86/icf-safe-test1.test | 2 --
bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test | 3 ---
.../icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test | 4 ----
bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test | 2 --
.../X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test | 2 --
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 2 --
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 2 --
bolt/test/X86/icf-safe-test3LocalVarO0.test | 2 --
bolt/test/X86/icf-safe-test3LocalVarO3.test | 2 --
12 files changed, 1 insertion(+), 34 deletions(-)
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index bd6e486700e933..c810e87f73cab6 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -8,8 +8,8 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# ICFCHECK-NEXT: folding _ZNK8Derived34funcEii into _ZNK8Derived24funcEii
+# ICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# SAFEICFCHECK: skipping function _ZNK8Derived24funcEii
# SAFEICFCHECK-NEXT: skipping function _ZNK8Derived34funcEii
@@ -295,11 +295,3 @@ _ZTI8Derived3:
.quad _ZTS8Derived3
.quad _ZTI4Base
.size _ZTI8Derived3, 24
-
- .cg_profile _Z10createTypei, _Znwm, 2
- .cg_profile main, _Z16returnFourOrFivei, 1
- .cg_profile main, _Z10returnFivev, 1
- .cg_profile main, _Z10createTypei, 2
- .cg_profile main, _ZNK8Derived24funcEii, 1
- .cg_profile main, _ZNK8Derived34funcEii, 1
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index 4abfdb2df538ee..d8fa1ef4a89dba 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -186,5 +186,3 @@ main: # @main
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
- # -- End function
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index f773d10b941684..6f8889f1ffe699 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -181,5 +181,3 @@ main: # @main
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
- # -- End function
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index f09117fe1a1783..203da0fd928510 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -186,5 +186,3 @@ main: # @main
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
- # -- End function
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index fee72ec53143ec..1f58477d36ca6a 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -180,6 +180,3 @@ BarVar:
.L.str:
.asciz "val: %d\n"
.size .L.str, 9
-
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
index 4e6a292b530420..44c9a8f08eb67e 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
@@ -233,7 +233,3 @@ FooVar:
BarVar:
.long 2 # 0x2
.size BarVar, 4
-
-
- # -- End function
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
index fedd7e6a508884..80478833c44d23 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -165,5 +165,3 @@ FooVar:
BarVar:
.long 2 # 0x2
.size BarVar, 4
- # -- End function
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
index 956b7037fc2e98..bddfe258109aaf 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -261,5 +261,3 @@ BarVar:
.L.str:
.asciz "val: %d\n"
.size .L.str, 9
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index 4ebe647eccf01f..84264cf62bfacb 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -226,5 +226,3 @@ funcGlobalBarMul:
_ZL16funcGlobalBarAdd:
.quad _Z6barAddii
.size _ZL16funcGlobalBarAdd, 8
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index b25e66c704a3df..0003d4d5adc68f 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -226,5 +226,3 @@ BarVar:
funcGlobalBarMul:
.quad _Z6barMulii
.size funcGlobalBarMul, 8
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
index 9e6e52c64a533b..f95dbc9c683194 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -226,5 +226,3 @@ BarVar:
_ZZ4mainE16funcGlobalBarAdd:
.quad _Z6barAddii
.size _ZZ4mainE16funcGlobalBarAdd, 8
-
- .ident "clang version 20.0.0git"
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index 693888493caf78..9d51d1e563d49b 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -220,5 +220,3 @@ FooVar:
BarVar:
.long 2 # 0x2
.size BarVar, 4
-
- .ident "clang version 20.0.0git"
>From 6287a7f7b68702aef415502fea1c0ef56b432afe Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Mon, 25 Nov 2024 17:45:30 -0800
Subject: [PATCH 17/34] removed comments, changed demangled names for key
functions
---
bolt/test/X86/icf-safe-icp.test | 96 ++++++------
bolt/test/X86/icf-safe-test1-no-cfg.test | 118 +++++++--------
bolt/test/X86/icf-safe-test1-no-relocs.test | 108 +++++++-------
bolt/test/X86/icf-safe-test1.test | 116 +++++++--------
.../icf-safe-test2GlobalConstPtrNoPic.test | 88 +++++------
...fe-test2GlobalConstPtrNoPicExtFuncRef.test | 124 ++++++++--------
.../X86/icf-safe-test2GlobalConstPtrPic.test | 82 +++++-----
...safe-test2GlobalConstPtrPicExtFuncRef.test | 132 ++++++++---------
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 138 ++++++++---------
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 140 +++++++++---------
bolt/test/X86/icf-safe-test3LocalVarO0.test | 136 ++++++++---------
bolt/test/X86/icf-safe-test3LocalVarO3.test | 138 +++++++++--------
12 files changed, 704 insertions(+), 712 deletions(-)
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index c810e87f73cab6..645266ca287730 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -91,10 +91,10 @@
.text
.file "main.cpp"
.section .text.hot.,"ax", at progbits
- .globl _Z10createTypei # -- Begin function _Z10createTypei
+ .globl _Z10createTypei
.p2align 4, 0x90
.type _Z10createTypei, at function
-_Z10createTypei: # @_Z10createTypei
+_Z10createTypei:
.cfi_startproc
callq _Znwm at PLT
leaq _ZTV8Derived2+16(%rip), %rcx
@@ -104,125 +104,125 @@ _Z10createTypei: # @_Z10createTypei
.Lfunc_end0:
.size _Z10createTypei, .Lfunc_end0-_Z10createTypei
.cfi_endproc
- # -- End function
- .globl _Z10returnFivev # -- Begin function _Z10returnFivev
+
+ .globl _Z10returnFivev
.p2align 4, 0x90
.type _Z10returnFivev, at function
-_Z10returnFivev: # @_Z10returnFivev
+_Z10returnFivev:
.cfi_startproc
-# %bb.0: # %entry
+# %bb.0:
movl $5, %eax
retq
.Lfunc_end01:
.size _Z10returnFivev, .Lfunc_end01-_Z10returnFivev
.cfi_endproc
- # -- End function
- .globl _Z16returnFourOrFivei # -- Begin function _Z16returnFourOrFivei
+
+ .globl returnFourOrFiveFunc
.p2align 4, 0x90
- .type _Z16returnFourOrFivei, at function
-_Z16returnFourOrFivei: # @_Z16returnFourOrFivei
+ .type returnFourOrFiveFunc, at function
+returnFourOrFiveFunc:
.cfi_startproc
-# %bb.0: # %entry
+# %bb.0:
xorl %eax, %eax
cmpl $1, %edi
sete %al
xorl $5, %eax
retq
.Lfunc_end11:
- .size _Z16returnFourOrFivei, .Lfunc_end11-_Z16returnFourOrFivei
+ .size returnFourOrFiveFunc, .Lfunc_end11-returnFourOrFiveFunc
.cfi_endproc
- .globl main # -- Begin function main
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
- callq _Z16returnFourOrFivei at PLT
+ callq returnFourOrFiveFunc at PLT
callq _Z10returnFivev at PLT
callq _Z10createTypei
callq _Z10createTypei
leaq _ZNK8Derived24funcEii(%rip), %rcx
jne .LBB1_2
callq _ZNK8Derived24funcEii
-.LBB1_3: # %if.end.icp
+.LBB1_3:
leaq _ZNK8Derived34funcEii(%rip), %rcx
jne .LBB1_5
callq _ZNK8Derived34funcEii
-.LBB1_6: # %if.end.icp3
+.LBB1_6:
retq
-.LBB1_2: # %if.false.orig_indirect
+.LBB1_2:
jmp .LBB1_3
-.LBB1_5: # %if.false.orig_indirect2
+.LBB1_5:
jmp .LBB1_6
.Lfunc_end1:
.size main, .Lfunc_end1-main
.cfi_endproc
- # -- End function
+
.section .text.hot._ZNK8Derived24funcEii,"axG", at progbits,_ZNK8Derived24funcEii,comdat
- .weak _ZNK8Derived24funcEii # -- Begin function _ZNK8Derived24funcEii
+ .weak _ZNK8Derived24funcEii
.p2align 4, 0x90
.type _ZNK8Derived24funcEii, at function
-_ZNK8Derived24funcEii: # @_ZNK8Derived24funcEii
+_ZNK8Derived24funcEii: #
.cfi_startproc
imull %esi, %eax
retq
.Lfunc_end2:
.size _ZNK8Derived24funcEii, .Lfunc_end2-_ZNK8Derived24funcEii
.cfi_endproc
- # -- End function
+
.section .text.unlikely._ZN8Derived2D0Ev,"axG", at progbits,_ZN8Derived2D0Ev,comdat
- .weak _ZN8Derived2D0Ev # -- Begin function _ZN8Derived2D0Ev
+ .weak _ZN8Derived2D0Ev
.p2align 4, 0x90
.type _ZN8Derived2D0Ev, at function
-_ZN8Derived2D0Ev: # @_ZN8Derived2D0Ev
+_ZN8Derived2D0Ev:
.cfi_startproc
-# %bb.0: # %entry
+# %bb.0:
movl $16, %esi
- jmp _ZdlPvm at PLT # TAILCALL
+ jmp _ZdlPvm at PLT
.Lfunc_end3:
.size _ZN8Derived2D0Ev, .Lfunc_end3-_ZN8Derived2D0Ev
.cfi_endproc
- # -- End function
+
.section .text.hot._ZNK8Derived34funcEii,"axG", at progbits,_ZNK8Derived34funcEii,comdat
- .weak _ZNK8Derived34funcEii # -- Begin function _ZNK8Derived34funcEii
+ .weak _ZNK8Derived34funcEii
.p2align 4, 0x90
.type _ZNK8Derived34funcEii, at function
-_ZNK8Derived34funcEii: # @_ZNK8Derived34funcEii
+_ZNK8Derived34funcEii:
.cfi_startproc
imull %esi, %eax
retq
.Lfunc_end4:
.size _ZNK8Derived34funcEii, .Lfunc_end4-_ZNK8Derived34funcEii
.cfi_endproc
- # -- End function
+
.section .text.unlikely._ZN4BaseD2Ev,"axG", at progbits,_ZN4BaseD2Ev,comdat
- .weak _ZN4BaseD2Ev # -- Begin function _ZN4BaseD2Ev
+ .weak _ZN4BaseD2Ev
.p2align 4, 0x90
.type _ZN4BaseD2Ev, at function
-_ZN4BaseD2Ev: # @_ZN4BaseD2Ev
+_ZN4BaseD2Ev:
.cfi_startproc
-# %bb.0: # %entry
+# %bb.0:
retq
.Lfunc_end5:
.size _ZN4BaseD2Ev, .Lfunc_end5-_ZN4BaseD2Ev
.cfi_endproc
- # -- End function
+
.section .text.unlikely._ZN8Derived3D0Ev,"axG", at progbits,_ZN8Derived3D0Ev,comdat
- .weak _ZN8Derived3D0Ev # -- Begin function _ZN8Derived3D0Ev
+ .weak _ZN8Derived3D0Ev
.p2align 4, 0x90
.type _ZN8Derived3D0Ev, at function
-_ZN8Derived3D0Ev: # @_ZN8Derived3D0Ev
+_ZN8Derived3D0Ev:
.cfi_startproc
-# %bb.0: # %entry
+# %bb.0:
movl $16, %esi
- jmp _ZdlPvm at PLT # TAILCALL
+ jmp _ZdlPvm at PLT
.Lfunc_end6:
.size _ZN8Derived3D0Ev, .Lfunc_end6-_ZN8Derived3D0Ev
.cfi_endproc
- # -- End function
- .type _ZTV8Derived2, at object # @_ZTV8Derived2
+
+ .type _ZTV8Derived2, at object
.section .data.rel.ro._ZTV8Derived2,"awG", at progbits,_ZTV8Derived2,comdat
.weak _ZTV8Derived2
.p2align 3, 0x0
@@ -234,21 +234,21 @@ _ZTV8Derived2:
.quad _ZN8Derived2D0Ev
.size _ZTV8Derived2, 40
- .type _ZTS8Derived2, at object # @_ZTS8Derived2
+ .type _ZTS8Derived2, at object
.section .rodata._ZTS8Derived2,"aG", at progbits,_ZTS8Derived2,comdat
.weak _ZTS8Derived2
_ZTS8Derived2:
.asciz "8Derived2"
.size _ZTS8Derived2, 10
- .type _ZTS4Base, at object # @_ZTS4Base
+ .type _ZTS4Base, at object
.section .rodata._ZTS4Base,"aG", at progbits,_ZTS4Base,comdat
.weak _ZTS4Base
_ZTS4Base:
.asciz "4Base"
.size _ZTS4Base, 6
- .type _ZTI4Base, at object # @_ZTI4Base
+ .type _ZTI4Base, at object
.section .data.rel.ro._ZTI4Base,"awG", at progbits,_ZTI4Base,comdat
.weak _ZTI4Base
.p2align 3, 0x0
@@ -257,7 +257,7 @@ _ZTI4Base:
.quad _ZTS4Base
.size _ZTI4Base, 16
- .type _ZTI8Derived2, at object # @_ZTI8Derived2
+ .type _ZTI8Derived2, at object
.section .data.rel.ro._ZTI8Derived2,"awG", at progbits,_ZTI8Derived2,comdat
.weak _ZTI8Derived2
.p2align 3, 0x0
@@ -267,7 +267,7 @@ _ZTI8Derived2:
.quad _ZTI4Base
.size _ZTI8Derived2, 24
- .type _ZTV8Derived3, at object # @_ZTV8Derived3
+ .type _ZTV8Derived3, at object
.section .data.rel.ro._ZTV8Derived3,"awG", at progbits,_ZTV8Derived3,comdat
.weak _ZTV8Derived3
.p2align 3, 0x0
@@ -279,14 +279,14 @@ _ZTV8Derived3:
.quad _ZN8Derived3D0Ev
.size _ZTV8Derived3, 40
- .type _ZTS8Derived3, at object # @_ZTS8Derived3
+ .type _ZTS8Derived3, at object
.section .rodata._ZTS8Derived3,"aG", at progbits,_ZTS8Derived3,comdat
.weak _ZTS8Derived3
_ZTS8Derived3:
.asciz "8Derived3"
.size _ZTS8Derived3, 10
- .type _ZTI8Derived3, at object # @_ZTI8Derived3
+ .type _ZTI8Derived3, at object
.section .data.rel.ro._ZTI8Derived3,"awG", at progbits,_ZTI8Derived3,comdat
.weak _ZTI8Derived3
.p2align 3, 0x0
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index d8fa1ef4a89dba..65d3868fe14b90 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -4,18 +4,18 @@
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
# RUN: llvm-bolt --no-threads %t.exe --icf=all -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf --skip-funcs=_Z7helper1PFiiiEii,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf --skip-funcs=helper1Func,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
# clang++ -c main.cpp -o main.o
@@ -65,78 +65,78 @@
# }
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+
+ .globl helper1Func
.p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .type helper1Func, at function
+helper1Func:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rax
+ leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
jne .LBB6_2
jmp .LBB6_3
@@ -145,43 +145,43 @@ _Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.LBB6_3:
retq
.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .size helper1Func, .Lfunc_end6-helper1Func
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+
+ .globl helper2Func
.p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .type helper2Func, at function
+helper2Func:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .size helper2Func, .Lfunc_end7-helper2Func
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFiiiEii
+ leaq barAddFunc(%rip), %rdi
+ callq helper1Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- leaq _Z6barMulii(%rip), %rsi
- callq _Z7helper2PFiiiES0_ii
+ leaq fooMulFunc(%rip), %rdi
+ leaq barMulFunc(%rip), %rsi
+ callq helper2Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
+ callq fooSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii
+ callq barSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
+ callq fooAddFunc
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index 6f8889f1ffe699..10ef5e6c5e7ed2 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -7,9 +7,9 @@
# RUN: not llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK: BOLT-ERROR: Binary built without relocations. Safe ICF is not supported
@@ -60,78 +60,78 @@
# }
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+
+ .globl helper1Func
.p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .type helper1Func, at function
+helper1Func:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rax
+ leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
jne .LBB6_2
jmp .LBB6_3
@@ -140,43 +140,43 @@ _Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.LBB6_3:
retq
.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .size helper1Func, .Lfunc_end6-helper1Func
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+
+ .globl helper2Func
.p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .type helper2Func, at function
+helper2Func:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .size helper2Func, .Lfunc_end7-helper2Func
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFiiiEii
+ leaq barAddFunc(%rip), %rdi
+ callq helper1Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- leaq _Z6barMulii(%rip), %rsi
- callq _Z7helper2PFiiiES0_ii
+ leaq fooMulFunc(%rip), %rdi
+ leaq barMulFunc(%rip), %rsi
+ callq helper2Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
+ callq fooSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii
+ callq barSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
+ callq fooAddFunc
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index 203da0fd928510..3807a1d1f10c10 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -7,15 +7,15 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
# clang++ -c main.cpp -o main.o
@@ -65,78 +65,78 @@
# }
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+
+ .globl helper1Func
.p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .type helper1Func, at function
+helper1Func:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rax
+ leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
jne .LBB6_2
jmp .LBB6_3
@@ -145,43 +145,43 @@ _Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
.LBB6_3:
retq
.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .size helper1Func, .Lfunc_end6-helper1Func
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+
+ .globl helper2Func
.p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .type helper2Func, at function
+helper2Func:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .size helper2Func, .Lfunc_end7-helper2Func
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFiiiEii
+ leaq barAddFunc(%rip), %rdi
+ callq helper1Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- leaq _Z6barMulii(%rip), %rsi
- callq _Z7helper2PFiiiES0_ii
+ leaq fooMulFunc(%rip), %rdi
+ leaq barMulFunc(%rip), %rsi
+ callq helper2Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
+ callq fooSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii
+ callq barSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
+ callq fooAddFunc
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index 1f58477d36ca6a..a6f97031a2a320 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -8,12 +8,12 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: ===---------
@@ -65,117 +65,117 @@
# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
- .size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end0-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
- .size _Z6barMulii, .Lfunc_end1-_Z6barMulii
+ .size barMulFunc, .Lfunc_end1-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end2:
- .size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end2-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end3:
- .size _Z6barAddii, .Lfunc_end3-_Z6barAddii
+ .size barAddFunc, .Lfunc_end3-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+
+ .globl _Z7helper1PFKiiiEii
.p2align 4, 0x90
.type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+_Z7helper1PFKiiiEii:
.cfi_startproc
- movabsq $_Z6barAddii, %rax
+ movabsq $barAddFunc, %rax
cmpq %rax, -16(%rbp)
retq
.Lfunc_end4:
.size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+
+ .globl _Z7helper2PFKiiiES1_ii
.p2align 4, 0x90
.type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+_Z7helper2PFKiiiES1_ii:
.cfi_startproc
# no direct function references.
retq
.Lfunc_end5:
.size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movl FooVar, %esi
movl BarVar, %edx
- movabsq $_Z6barAddii, %rdi
+ movabsq $barAddFunc, %rdi
callq _Z7helper1PFKiiiEii
- movl %eax, -28(%rbp) # 4-byte Spill
+ movl %eax, -28(%rbp)
movl FooVar, %edx
movl BarVar, %ecx
- movabsq $_Z6fooMulii, %rdi
- movabsq $_Z6barMulii, %rsi
+ movabsq $fooMulFunc, %rdi
+ movabsq $barMulFunc, %rsi
callq _Z7helper2PFKiiiES1_ii
retq
.Lfunc_end6:
.size main, .Lfunc_end6-main
.cfi_endproc
- .type FooVar, at object # @FooVar
+ .type FooVar, at object
.data
.globl FooVar
.p2align 2, 0x0
FooVar:
- .long 1 # 0x1
+ .long 1
.size FooVar, 4
- .type BarVar, at object # @BarVar
+ .type BarVar, at object
.globl BarVar
.p2align 2, 0x0
BarVar:
- .long 2 # 0x2
+ .long 2
.size BarVar, 4
- # -- End function
- .type .L.str, at object # @.str
+
+ .type .L.str, at object
.section .rodata.str1.1,"aMS", at progbits,1
.L.str:
.asciz "val: %d\n"
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
index 44c9a8f08eb67e..f3c351fc87461f 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
@@ -8,17 +8,17 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding _Z12barAddHdlperii into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: skipping function _Z12barAddHdlperii
-# SAFEICFCHECK-NEXT: skipping function _Z19fooGlobalFuncHelperii
+# SAFEICFCHECK-NEXT: skipping function fooGlobalFuncHelperFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
# clang++ main.cpp -c -o
@@ -88,99 +88,99 @@
# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii:
- .cfi_startproc # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
+ .cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+
+ .globl _Z7helper1PFKiiiEii
.p2align 4, 0x90
.type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+_Z7helper1PFKiiiEii:
.cfi_startproc
- movabsq $_Z6barAddii, %rax
+ movabsq $barAddFunc, %rax
cmpq %rax, -16(%rbp)
retq
.Lfunc_end6:
.size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+
+ .globl _Z7helper2PFKiiiES1_ii
.p2align 4, 0x90
.type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+_Z7helper2PFKiiiES1_ii:
.cfi_startproc
# All operations on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movl FooVar, %esi
movl BarVar, %edx
@@ -188,8 +188,8 @@ main: # @main
callq _Z7helper1PFKiiiEii
movl FooVar, %edx
movl BarVar, %ecx
- movabsq $_Z6fooMulii, %rdi
- movabsq $_Z19fooGlobalFuncHelperii, %rsi
+ movabsq $fooMulFunc, %rdi
+ movabsq $fooGlobalFuncHelperFunc, %rsi
callq _Z7helper2PFKiiiES1_ii
retq
.Lfunc_end8:
@@ -197,39 +197,39 @@ main: # @main
.cfi_endproc
- .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .globl _Z12barAddHdlperii
.p2align 4, 0x90
.type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii: # @_Z12barAddHdlperii
+_Z12barAddHdlperii:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end01:
.size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
.cfi_endproc
- # -- End function
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+
+ .globl fooGlobalFuncHelperFunc
.p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .type fooGlobalFuncHelperFunc, at function
+fooGlobalFuncHelperFunc:
.cfi_startproc
callq _Z12barAddHdlperii
retq
.Lfunc_end11:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end11-_Z19fooGlobalFuncHelperii
+ .size fooGlobalFuncHelperFunc, .Lfunc_end11-fooGlobalFuncHelperFunc
.cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
+
+ .type FooVar, at object
.data
.globl FooVar
.p2align 2, 0x0
FooVar:
- .long 1 # 0x1
+ .long 1
.size FooVar, 4
- .type BarVar, at object # @BarVar
+ .type BarVar, at object
.globl BarVar
.p2align 2, 0x0
BarVar:
- .long 2 # 0x2
+ .long 2
.size BarVar, 4
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
index 80478833c44d23..cee3e0a221a900 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -8,12 +8,12 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: ===---------
@@ -65,103 +65,103 @@
# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end0:
- .size _Z6fooMulii, .Lfunc_end0-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end0-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end1:
- .size _Z6barMulii, .Lfunc_end1-_Z6barMulii
+ .size barMulFunc, .Lfunc_end1-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end2:
- .size _Z6fooAddii, .Lfunc_end2-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end2-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end3:
- .size _Z6barAddii, .Lfunc_end3-_Z6barAddii
+ .size barAddFunc, .Lfunc_end3-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+
+ .globl _Z7helper1PFKiiiEii
.p2align 4, 0x90
.type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+_Z7helper1PFKiiiEii:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rax
+ leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
retq
.Lfunc_end4:
.size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+
+ .globl _Z7helper2PFKiiiES1_ii
.p2align 4, 0x90
.type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+_Z7helper2PFKiiiES1_ii:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end5:
.size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6barAddii(%rip), %rdi
+ leaq barAddFunc(%rip), %rdi
callq _Z7helper1PFKiiiEii
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- leaq _Z6barMulii(%rip), %rsi
+ leaq fooMulFunc(%rip), %rdi
+ leaq barMulFunc(%rip), %rsi
callq _Z7helper2PFKiiiES1_ii
retq
.Lfunc_end6:
.size main, .Lfunc_end6-main
.cfi_endproc
- .type FooVar, at object # @FooVar
+ .type FooVar, at object
.data
.globl FooVar
.p2align 2, 0x0
FooVar:
- .long 1 # 0x1
+ .long 1
.size FooVar, 4
- .type BarVar, at object # @BarVar
+ .type BarVar, at object
.globl BarVar
.p2align 2, 0x0
BarVar:
- .long 2 # 0x2
+ .long 2
.size BarVar, 4
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
index bddfe258109aaf..2b7ac08e066447 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -8,17 +8,17 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z12barAddHdlperii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding _Z12barAddHdlperii into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: skipping function _Z12barAddHdlperii
-# SAFEICFCHECK-NEXT: skipping function _Z19fooGlobalFuncHelperii
+# SAFEICFCHECK-NEXT: skipping function fooGlobalFuncHelperFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
@@ -102,99 +102,99 @@
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFKiiiEii # -- Begin function _Z7helper1PFKiiiEii
+
+ .globl _Z7helper1PFKiiiEii
.p2align 4, 0x90
.type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii: # @_Z7helper1PFKiiiEii
+_Z7helper1PFKiiiEii:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rax
+ leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
retq
.Lfunc_end6:
.size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFKiiiES1_ii # -- Begin function _Z7helper2PFKiiiES1_ii
+
+ .globl _Z7helper2PFKiiiES1_ii
.p2align 4, 0x90
.type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii: # @_Z7helper2PFKiiiES1_ii
+_Z7helper2PFKiiiES1_ii:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end7:
.size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
@@ -202,61 +202,61 @@ main: # @main
callq _Z7helper1PFKiiiEii
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- movq _Z19fooGlobalFuncHelperii at GOTPCREL(%rip), %rsi
+ leaq fooMulFunc(%rip), %rdi
+ movq fooGlobalFuncHelperFunc at GOTPCREL(%rip), %rsi
callq _Z7helper2PFKiiiES1_ii
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
+ callq fooSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii # 4-byte Spill
+ callq barSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
+ callq fooAddFunc
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
- .globl _Z12barAddHdlperii # -- Begin function _Z12barAddHdlperii
+ .globl _Z12barAddHdlperii
.p2align 4, 0x90
.type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii: # @_Z12barAddHdlperii
+_Z12barAddHdlperii:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end01:
.size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
.cfi_endproc
- # -- End function
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+
+ .globl fooGlobalFuncHelperFunc
.p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .type fooGlobalFuncHelperFunc, at function
+fooGlobalFuncHelperFunc:
.cfi_startproc
callq _Z12barAddHdlperii
retq
.Lfunc_end11:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end11-_Z19fooGlobalFuncHelperii
+ .size fooGlobalFuncHelperFunc, .Lfunc_end11-fooGlobalFuncHelperFunc
.cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
+
+ .type FooVar, at object
.data
.globl FooVar
.p2align 2, 0x0
FooVar:
- .long 1 # 0x1
+ .long 1
.size FooVar, 4
- .type BarVar, at object # @BarVar
+ .type BarVar, at object
.globl BarVar
.p2align 2, 0x0
BarVar:
- .long 2 # 0x2
+ .long 2
.size BarVar, 4
- # -- End function
- .type .L.str, at object # @.str
+
+ .type .L.str, at object
.section .rodata.str1.1,"aMS", at progbits,1
.L.str:
.asciz "val: %d\n"
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index 84264cf62bfacb..df74e950754d80 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -7,15 +7,15 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
@@ -69,160 +69,160 @@
# Manually modified to remove "extra" assembly.
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+
+ .globl helper1Func
.p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .type helper1Func, at function
+helper1Func:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rax
+ leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
retq
.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .size helper1Func, .Lfunc_end6-helper1Func
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+
+ .globl helper2Func
.p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .type helper2Func, at function
+helper2Func:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .size helper2Func, .Lfunc_end7-helper2Func
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movq _ZL16funcGlobalBarAdd(%rip), %rdi
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z7helper1PFiiiEii
+ callq helper1Func
movq funcGlobalBarMul(%rip), %rsi
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- callq _Z7helper2PFiiiES0_ii
+ leaq fooMulFunc(%rip), %rdi
+ callq helper2Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
+ callq fooSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii
+ callq barSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
+ callq fooAddFunc
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .globl fooGlobalFuncHelperFunc
.p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .type fooGlobalFuncHelperFunc, at function
+fooGlobalFuncHelperFunc:
.cfi_startproc
# %bb.0:
movl $5, %eax
retq
.Lfunc_end01:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
+ .size fooGlobalFuncHelperFunc, .Lfunc_end01-fooGlobalFuncHelperFunc
.cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
+
+ .type FooVar, at object
.data
.globl FooVar
.p2align 2, 0x0
FooVar:
- .long 1 # 0x1
+ .long 1
.size FooVar, 4
- .type BarVar, at object # @BarVar
+ .type BarVar, at object
.globl BarVar
.p2align 2, 0x0
BarVar:
- .long 2 # 0x2
+ .long 2
.size BarVar, 4
- .type funcGlobalBarMul, at object # @funcGlobalBarMul
+ .type funcGlobalBarMul, at object
.data
.globl funcGlobalBarMul
.p2align 3, 0x0
funcGlobalBarMul:
- .quad _Z6barMulii
+ .quad barMulFunc
.size funcGlobalBarMul, 8
- .type _ZL16funcGlobalBarAdd, at object # @_ZL16funcGlobalBarAdd
+ .type _ZL16funcGlobalBarAdd, at object
.p2align 3, 0x0
_ZL16funcGlobalBarAdd:
- .quad _Z6barAddii
+ .quad barAddFunc
.size _ZL16funcGlobalBarAdd, 8
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index 0003d4d5adc68f..d8de30813809ac 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -7,15 +7,15 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
# clang++ -O3 -c main.cpp -o main.o
@@ -74,155 +74,151 @@
# }
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl %esi, %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl %esi, %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull %esi, %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull %esi, %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
# %bb.0:
- # kill: def $esi killed $esi def $rsi
- # kill: def $edi killed $edi def $rdi
leal (%rdi,%rsi), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
# %bb.0:
- # kill: def $esi killed $esi def $rsi
- # kill: def $edi killed $edi def $rdi
leal (%rdi,%rsi), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+
+ .globl helper1Func
.p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .type helper1Func, at function
+helper1Func:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rcx
+ leaq barAddFunc(%rip), %rcx
cmpq %rcx, %rdi
retq
.LBB6_1:
movl $1, %eax
retq
.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .size helper1Func, .Lfunc_end6-helper1Func
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+
+ .globl helper2Func
.p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .type helper2Func, at function
+helper2Func:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .size helper2Func, .Lfunc_end7-helper2Func
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movq FooVar at GOTPCREL(%rip), %r14
movq BarVar at GOTPCREL(%rip), %r15
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFiiiEii
+ leaq barAddFunc(%rip), %rdi
+ callq helper1Func
movq funcGlobalBarMul(%rip), %rsi
- leaq _Z6fooMulii(%rip), %rdi
- callq _Z7helper2PFiiiES0_ii
- callq _Z6fooSubii
- callq _Z6barSubii
- callq _Z6fooAddii
+ leaq fooMulFunc(%rip), %rdi
+ callq helper2Func
+ callq fooSubFunc
+ callq barSubFunc
+ callq fooAddFunc
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .globl fooGlobalFuncHelperFunc
.p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .type fooGlobalFuncHelperFunc, at function
+fooGlobalFuncHelperFunc:
.cfi_startproc
# %bb.0:
movl $5, %eax
retq
.Lfunc_end01:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
+ .size fooGlobalFuncHelperFunc, .Lfunc_end01-fooGlobalFuncHelperFunc
.cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
+
+ .type FooVar, at object
.data
.globl FooVar
.p2align 2, 0x0
FooVar:
- .long 1 # 0x1
+ .long 1
.size FooVar, 4
- .type BarVar, at object # @BarVar
+ .type BarVar, at object
.globl BarVar
.p2align 2, 0x0
BarVar:
- .long 2 # 0x2
+ .long 2
.size BarVar, 4
- .type funcGlobalBarMul, at object # @funcGlobalBarMul
+ .type funcGlobalBarMul, at object
.data
.globl funcGlobalBarMul
.p2align 3, 0x0
funcGlobalBarMul:
- .quad _Z6barMulii
+ .quad barMulFunc
.size funcGlobalBarMul, 8
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
index f95dbc9c683194..b7eb36fbad8e2c 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -7,15 +7,15 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
@@ -76,153 +76,153 @@
# }
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+
+ .globl helper1Func
.p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .type helper1Func, at function
+helper1Func:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rax
+ leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
retq
.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .size helper1Func, .Lfunc_end6-helper1Func
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+
+ .globl helper2Func
.p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .type helper2Func, at function
+helper2Func:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .size helper2Func, .Lfunc_end7-helper2Func
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
- leaq _Z6barMulii(%rip), %rax
+ leaq barMulFunc(%rip), %rax
movq _ZZ4mainE16funcGlobalBarAdd(%rip), %rdi
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z7helper1PFiiiEii
+ callq helper1Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- leaq _Z6fooMulii(%rip), %rdi
- callq _Z7helper2PFiiiES0_ii
+ leaq fooMulFunc(%rip), %rdi
+ callq helper2Func
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooSubii
+ callq fooSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6barSubii
+ callq barSubFunc
movq FooVar at GOTPCREL(%rip), %rax
movq BarVar at GOTPCREL(%rip), %rax
- callq _Z6fooAddii
+ callq fooAddFunc
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .globl fooGlobalFuncHelperFunc
.p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .type fooGlobalFuncHelperFunc, at function
+fooGlobalFuncHelperFunc:
.cfi_startproc
# %bb.0:
movl $5, %eax
retq
.Lfunc_end01:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
+ .size fooGlobalFuncHelperFunc, .Lfunc_end01-fooGlobalFuncHelperFunc
.cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
+
+ .type FooVar, at object
.data
.globl FooVar
.p2align 2, 0x0
FooVar:
- .long 1 # 0x1
+ .long 1
.size FooVar, 4
- .type BarVar, at object # @BarVar
+ .type BarVar, at object
.globl BarVar
.p2align 2, 0x0
BarVar:
- .long 2 # 0x2
+ .long 2
.size BarVar, 4
- .type _ZZ4mainE16funcGlobalBarAdd, at object # @_ZZ4mainE16funcGlobalBarAdd
+ .type _ZZ4mainE16funcGlobalBarAdd, at object
.data
.p2align 3, 0x0
_ZZ4mainE16funcGlobalBarAdd:
- .quad _Z6barAddii
+ .quad barAddFunc
.size _ZZ4mainE16funcGlobalBarAdd, 8
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index 9d51d1e563d49b..4241766dbdcd1a 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -7,15 +7,15 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _Z6barMulii into _Z6fooMulii
-# ICFCHECK-NEXT: folding _Z6barAddii into _Z6fooAddii
-# ICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function _Z6fooMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barMulii
-# SAFEICFCHECK-NEXT: skipping function _Z6barAddii
+# SAFEICFCHECK: skipping function fooMulFunc
+# SAFEICFCHECK-NEXT: skipping function barMulFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _Z6barSubii into _Z6fooSubii
+# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
# clang++ -O3 -c main.cpp -o main.o
@@ -75,148 +75,144 @@
# }
.text
.file "main.cpp"
- .globl _Z6fooSubii # -- Begin function _Z6fooSubii
+ .globl fooSubFunc
.p2align 4, 0x90
- .type _Z6fooSubii, at function
-_Z6fooSubii: # @_Z6fooSubii
+ .type fooSubFunc, at function
+fooSubFunc:
.cfi_startproc
subl %esi, %eax
retq
.Lfunc_end0:
- .size _Z6fooSubii, .Lfunc_end0-_Z6fooSubii
+ .size fooSubFunc, .Lfunc_end0-fooSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6barSubii # -- Begin function _Z6barSubii
+
+ .globl barSubFunc
.p2align 4, 0x90
- .type _Z6barSubii, at function
-_Z6barSubii: # @_Z6barSubii
+ .type barSubFunc, at function
+barSubFunc:
.cfi_startproc
subl %esi, %eax
retq
.Lfunc_end1:
- .size _Z6barSubii, .Lfunc_end1-_Z6barSubii
+ .size barSubFunc, .Lfunc_end1-barSubFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooMulii # -- Begin function _Z6fooMulii
+
+ .globl fooMulFunc
.p2align 4, 0x90
- .type _Z6fooMulii, at function
-_Z6fooMulii: # @_Z6fooMulii
+ .type fooMulFunc, at function
+fooMulFunc:
.cfi_startproc
imull %esi, %eax
retq
.Lfunc_end2:
- .size _Z6fooMulii, .Lfunc_end2-_Z6fooMulii
+ .size fooMulFunc, .Lfunc_end2-fooMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6barMulii # -- Begin function _Z6barMulii
+
+ .globl barMulFunc
.p2align 4, 0x90
- .type _Z6barMulii, at function
-_Z6barMulii: # @_Z6barMulii
+ .type barMulFunc, at function
+barMulFunc:
.cfi_startproc
imull %esi, %eax
retq
.Lfunc_end3:
- .size _Z6barMulii, .Lfunc_end3-_Z6barMulii
+ .size barMulFunc, .Lfunc_end3-barMulFunc
.cfi_endproc
- # -- End function
- .globl _Z6fooAddii # -- Begin function _Z6fooAddii
+
+ .globl fooAddFunc
.p2align 4, 0x90
- .type _Z6fooAddii, at function
-_Z6fooAddii: # @_Z6fooAddii
+ .type fooAddFunc, at function
+fooAddFunc:
.cfi_startproc
# %bb.0:
- # kill: def $esi killed $esi def $rsi
- # kill: def $edi killed $edi def $rdi
leal (%rdi,%rsi), %eax
retq
.Lfunc_end4:
- .size _Z6fooAddii, .Lfunc_end4-_Z6fooAddii
+ .size fooAddFunc, .Lfunc_end4-fooAddFunc
.cfi_endproc
- # -- End function
- .globl _Z6barAddii # -- Begin function _Z6barAddii
+
+ .globl barAddFunc
.p2align 4, 0x90
- .type _Z6barAddii, at function
-_Z6barAddii: # @_Z6barAddii
+ .type barAddFunc, at function
+barAddFunc:
.cfi_startproc
# %bb.0:
- # kill: def $esi killed $esi def $rsi
- # kill: def $edi killed $edi def $rdi
leal (%rdi,%rsi), %eax
retq
.Lfunc_end5:
- .size _Z6barAddii, .Lfunc_end5-_Z6barAddii
+ .size barAddFunc, .Lfunc_end5-barAddFunc
.cfi_endproc
- # -- End function
- .globl _Z7helper1PFiiiEii # -- Begin function _Z7helper1PFiiiEii
+
+ .globl helper1Func
.p2align 4, 0x90
- .type _Z7helper1PFiiiEii, at function
-_Z7helper1PFiiiEii: # @_Z7helper1PFiiiEii
+ .type helper1Func, at function
+helper1Func:
.cfi_startproc
- leaq _Z6barAddii(%rip), %rcx
+ leaq barAddFunc(%rip), %rcx
cmpq %rcx, %rdi
retq
.LBB6_1:
movl $1, %eax
retq
.Lfunc_end6:
- .size _Z7helper1PFiiiEii, .Lfunc_end6-_Z7helper1PFiiiEii
+ .size helper1Func, .Lfunc_end6-helper1Func
.cfi_endproc
- # -- End function
- .globl _Z7helper2PFiiiES0_ii # -- Begin function _Z7helper2PFiiiES0_ii
+
+ .globl helper2Func
.p2align 4, 0x90
- .type _Z7helper2PFiiiES0_ii, at function
-_Z7helper2PFiiiES0_ii: # @_Z7helper2PFiiiES0_ii
+ .type helper2Func, at function
+helper2Func:
.cfi_startproc
# Operates on registers.
retq
.Lfunc_end7:
- .size _Z7helper2PFiiiES0_ii, .Lfunc_end7-_Z7helper2PFiiiES0_ii
+ .size helper2Func, .Lfunc_end7-helper2Func
.cfi_endproc
- # -- End function
- .globl main # -- Begin function main
+
+ .globl main
.p2align 4, 0x90
.type main, at function
-main: # @main
+main:
.cfi_startproc
movq FooVar at GOTPCREL(%rip), %r14
movq BarVar at GOTPCREL(%rip), %r15
- leaq _Z6barAddii(%rip), %rdi
- callq _Z7helper1PFiiiEii
- leaq _Z6fooMulii(%rip), %rdi
- leaq _Z6barMulii(%rip), %rsi
- callq _Z7helper2PFiiiES0_ii
- callq _Z6fooSubii
- callq _Z6barSubii
- callq _Z6fooAddii
+ leaq barAddFunc(%rip), %rdi
+ callq helper1Func
+ leaq fooMulFunc(%rip), %rdi
+ leaq barMulFunc(%rip), %rsi
+ callq helper2Func
+ callq fooSubFunc
+ callq barSubFunc
+ callq fooAddFunc
retq
.Lfunc_end8:
.size main, .Lfunc_end8-main
.cfi_endproc
- .globl _Z19fooGlobalFuncHelperii # -- Begin function _Z19fooGlobalFuncHelperii
+ .globl fooGlobalFuncHelperFunc
.p2align 4, 0x90
- .type _Z19fooGlobalFuncHelperii, at function
-_Z19fooGlobalFuncHelperii: # @_Z19fooGlobalFuncHelperii
+ .type fooGlobalFuncHelperFunc, at function
+fooGlobalFuncHelperFunc:
.cfi_startproc
# %bb.0:
movl $5, %eax
retq
.Lfunc_end01:
- .size _Z19fooGlobalFuncHelperii, .Lfunc_end01-_Z19fooGlobalFuncHelperii
+ .size fooGlobalFuncHelperFunc, .Lfunc_end01-fooGlobalFuncHelperFunc
.cfi_endproc
- # -- End function
- .type FooVar, at object # @FooVar
+
+ .type FooVar, at object
.data
.globl FooVar
.p2align 2, 0x0
FooVar:
- .long 1 # 0x1
+ .long 1
.size FooVar, 4
- .type BarVar, at object # @BarVar
+ .type BarVar, at object
.globl BarVar
.p2align 2, 0x0
BarVar:
- .long 2 # 0x2
+ .long 2
.size BarVar, 4
>From c6a196594b708b9fb46f4fdff885bd16939452ad Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Mon, 25 Nov 2024 17:51:36 -0800
Subject: [PATCH 18/34] removed .text and .file
---
bolt/test/X86/icf-safe-icp.test | 2 --
bolt/test/X86/icf-safe-test1-no-cfg.test | 2 --
bolt/test/X86/icf-safe-test1-no-relocs.test | 2 --
bolt/test/X86/icf-safe-test1.test | 2 --
bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test | 2 --
bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test | 2 --
bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test | 2 --
bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test | 3 ---
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 2 --
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 2 --
bolt/test/X86/icf-safe-test3LocalVarO0.test | 2 --
bolt/test/X86/icf-safe-test3LocalVarO3.test | 2 --
12 files changed, 25 deletions(-)
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index 645266ca287730..b9427bf7b09944 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -88,8 +88,6 @@
# return 5;
# }
# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
.section .text.hot.,"ax", at progbits
.globl _Z10createTypei
.p2align 4, 0x90
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index 65d3868fe14b90..337e04e0c5407b 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -63,8 +63,6 @@
# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
# return temp;
# }
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index 10ef5e6c5e7ed2..ec47108da24ccb 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -58,8 +58,6 @@
# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
# return temp;
# }
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index 3807a1d1f10c10..68c37c1ce01f2e 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -63,8 +63,6 @@
# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
# return temp;
# }
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index a6f97031a2a320..4ca6eb2665270c 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -63,8 +63,6 @@
# int FooVar = 1;
# int BarVar = 2;
# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
.globl fooMulFunc
.p2align 4, 0x90
.type fooMulFunc, at function
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
index f3c351fc87461f..c55ca49964a938 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
@@ -86,8 +86,6 @@
# return 5 + funcGlobalBarMulExt(a, b);
# }
# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
index cee3e0a221a900..ebcd224542d238 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -63,8 +63,6 @@
# int FooVar = 1;
# int BarVar = 2;
# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
.globl fooMulFunc
.p2align 4, 0x90
.type fooMulFunc, at function
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
index 2b7ac08e066447..8e02c30aa5e2a8 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -99,9 +99,6 @@
# MY_CONST int fooGlobalFuncHelper(int a, int b) {
# return 5 + funcGlobalBarMulExt(a, b);
# }
-
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index df74e950754d80..e73ac27d065134 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -67,8 +67,6 @@
# return temp;
# }
# Manually modified to remove "extra" assembly.
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
index d8de30813809ac..bfc6218d813af8 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
@@ -72,8 +72,6 @@
# int fooGlobalFuncHelper(int a, int b) {
# return 5;
# }
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
index b7eb36fbad8e2c..65e4ed5bfb084e 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO0.test
@@ -74,8 +74,6 @@
# int fooGlobalFuncHelper(int a, int b) {
# return 5;
# }
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
index 4241766dbdcd1a..6e06e03898f40c 100644
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ b/bolt/test/X86/icf-safe-test3LocalVarO3.test
@@ -73,8 +73,6 @@
# int fooGlobalFuncHelper(int a, int b) {
# return 5;
# }
- .text
- .file "main.cpp"
.globl fooSubFunc
.p2align 4, 0x90
.type fooSubFunc, at function
>From d393b5efab0f9471365ffd6848ca4a7b712a7ad0 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Sat, 30 Nov 2024 14:19:52 -0800
Subject: [PATCH 19/34] Changed schedule strategy, cleaned up tests some more,
and removed some redudant tests
---
bolt/lib/Passes/IdenticalCodeFolding.cpp | 13 +-
bolt/test/X86/icf-safe-icp.test | 197 ++++++---------
bolt/test/X86/icf-safe-test1-no-cfg.test | 144 +++++------
bolt/test/X86/icf-safe-test1-no-relocs.test | 169 +------------
bolt/test/X86/icf-safe-test1.test | 143 +++++------
.../icf-safe-test2GlobalConstPtrNoPic.test | 125 ++++------
...fe-test2GlobalConstPtrNoPicExtFuncRef.test | 233 ------------------
.../X86/icf-safe-test2GlobalConstPtrPic.test | 126 ++++------
...safe-test2GlobalConstPtrPicExtFuncRef.test | 209 +++++++---------
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 164 +++++-------
bolt/test/X86/icf-safe-test2GlobalVarO3.test | 222 -----------------
bolt/test/X86/icf-safe-test3LocalVarO0.test | 226 -----------------
bolt/test/X86/icf-safe-test3LocalVarO3.test | 216 ----------------
13 files changed, 457 insertions(+), 1730 deletions(-)
delete mode 100644 bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
delete mode 100644 bolt/test/X86/icf-safe-test2GlobalVarO3.test
delete mode 100644 bolt/test/X86/icf-safe-test3LocalVarO0.test
delete mode 100644 bolt/test/X86/icf-safe-test3LocalVarO3.test
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 7d2560cca2d468..759e6ee4327864 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -38,12 +38,9 @@ static cl::opt<bool>
ICFUseDFS("icf-dfs", cl::desc("use DFS ordering when using -icf option"),
cl::ReallyHidden, cl::cat(BoltOptCategory));
-static cl::opt<bool>
-TimeICF("time-icf",
- cl::desc("time icf steps"),
- cl::ReallyHidden,
- cl::ZeroOrMore,
- cl::cat(BoltOptCategory));
+static cl::opt<bool> TimeICF("time-icf", cl::desc("time icf steps"),
+ cl::ReallyHidden, cl::ZeroOrMore,
+ cl::cat(BoltOptCategory));
} // namespace opts
/// Compare two jump tables in 2 functions. The function relies on consistent
@@ -388,8 +385,8 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
ParallelUtilities::PredicateTy SkipFunc =
[&](const BinaryFunction &BF) -> bool { return (bool)ErrorStatus; };
ParallelUtilities::runOnEachFunction(
- BC, ParallelUtilities::SchedulingPolicy::SP_TRIVIAL, WorkFun, SkipFunc,
- "markUnsafe", /*ForceSequential*/ false, 2);
+ BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun,
+ SkipFunc, "markUnsafe", /*ForceSequential*/ false, 2);
LLVM_DEBUG({
for (auto &BFIter : BC.getBinaryFunctions()) {
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index b9427bf7b09944..d830bb102fa1e2 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -1,5 +1,5 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
-# The compare is generated by the ICP path with instrumentation profiling.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
+## The compare is generated by the ICP path with instrumentation profiling.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
@@ -18,79 +18,78 @@
# SAFEICFCHECK-NEXT: ===---------
-# generate profile
-# clang++ -O2 -fprofile-generate=. main.cpp -c -o mainProf.o
-# PROF=test.profdata
-# clang++ -m64 -fprofile-use=$PROF \
-# -mllvm -disable-icp=true -mllvm -print-after-all \
-# -g0 -flto=thin -fwhole-program-vtables -fno-split-lto-unit -O2 \
-# -fdebug-types-section \
-# main.cpp -c -o mainProfLTO.bc
-# PASS='pgo-icall-prom'
-# clang++ -m64 -fprofile-use=$PROF \
-# -O3 -Rpass=$PASS \
-# -mllvm -print-before=$PASS \
-# -mllvm -print-after=$PASS \
-# -mllvm -filter-print-funcs=main \
-# -mllvm -debug-only=$PASS \
-# -x ir \
-# mainProfLTO.bc -c -o mainProfFinal.o
+## generate profile
+## clang++ -O2 -fprofile-generate=. main.cpp -c -o mainProf.o
+## PROF=test.profdata
+## clang++ -m64 -fprofile-use=$PROF \
+## -mllvm -disable-icp=true -mllvm -print-after-all \
+## -g0 -flto=thin -fwhole-program-vtables -fno-split-lto-unit -O2 \
+## -fdebug-types-section \
+## main.cpp -c -o mainProfLTO.bc
+## PASS='pgo-icall-prom'
+## clang++ -m64 -fprofile-use=$PROF \
+## -O3 -Rpass=$PASS \
+## -mllvm -print-before=$PASS \
+## -mllvm -print-after=$PASS \
+## -mllvm -filter-print-funcs=main \
+## -mllvm -debug-only=$PASS \
+## -x ir \
+## mainProfLTO.bc -c -o mainProfFinal.o
-# class Base {
-# public:
-# virtual int func(int a, int b) const = 0;
-#
-# virtual ~Base() {};
-# };
-#
-# //namespace {
-# class Derived2 : public Base {
-# int c = 5;
-# public:
-# __attribute__((noinline)) int func(int a, int b)const override { return a * (a - b) + this->c; }
-#
-# ~Derived2() {}
-# };
-#
-# class Derived3 : public Base {
-# int c = 500;
-# public:
-# __attribute__((noinline)) int func(int a, int b) const override { return a * (a - b) + this->c; }
-# ~Derived3() {}
-# };
-# //} // namespace//
-#
-# __attribute__((noinline)) Base *createType(int a) {
-# Base *base = nullptr;
-# if (a == 4)
-# base = new Derived2();
-# else
-# base = new Derived3();
-# return base;
-# }
-#
-# extern int returnFive();
-# extern int returnFourOrFive(int val);
-# int main(int argc, char **argv) {
-# int sum = 0;
-# int a = returnFourOrFive(argc);
-# int b = returnFive();
-# Base *ptr = createType(a);
-# Base *ptr2 = createType(b);
-# sum += ptr->func(b, a) + ptr2->func(b, a);
-# return 0;
-# }
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
-# Manually modified to remove "extra" assembly.
+## class Base {
+## public:
+## virtual int func(int a, int b) const = 0;
+##
+## virtual ~Base() {};
+## };
+##
+## //namespace {
+## class Derived2 : public Base {
+## int c = 5;
+## public:
+## __attribute__((noinline)) int func(int a, int b)const override { return a * (a - b) + this->c; }
+##
+## ~Derived2() {}
+## };
+##
+## class Derived3 : public Base {
+## int c = 500;
+## public:
+## __attribute__((noinline)) int func(int a, int b) const override { return a * (a - b) + this->c; }
+## ~Derived3() {}
+## };
+## //} // namespace//
+##
+## __attribute__((noinline)) Base *createType(int a) {
+## Base *base = nullptr;
+## if (a == 4)
+## base = new Derived2();
+## else
+## base = new Derived3();
+## return base;
+## }
+##
+## extern int returnFive();
+## extern int returnFourOrFive(int val);
+## int main(int argc, char **argv) {
+## int sum = 0;
+## int a = returnFourOrFive(argc);
+## int b = returnFive();
+## Base *ptr = createType(a);
+## Base *ptr2 = createType(b);
+## sum += ptr->func(b, a) + ptr2->func(b, a);
+## return 0;
+## }
+## clang++ -c helper.cpp -o helper.o
+## int FooVar = 1;
+## int BarVar = 2;
+##
+## int fooGlobalFuncHelper(int a, int b) {
+## return 5;
+## }
+## Manually modified to remove "extra" assembly.
.section .text.hot.,"ax", at progbits
.globl _Z10createTypei
- .p2align 4, 0x90
.type _Z10createTypei, at function
_Z10createTypei:
.cfi_startproc
@@ -99,41 +98,33 @@ _Z10createTypei:
leaq _ZTV8Derived3+16(%rip), %rdx
cmoveq %rcx, %rdx
retq
-.Lfunc_end0:
- .size _Z10createTypei, .Lfunc_end0-_Z10createTypei
+ .size _Z10createTypei, .-_Z10createTypei
.cfi_endproc
.globl _Z10returnFivev
- .p2align 4, 0x90
.type _Z10returnFivev, at function
_Z10returnFivev:
.cfi_startproc
-# %bb.0:
movl $5, %eax
retq
-.Lfunc_end01:
- .size _Z10returnFivev, .Lfunc_end01-_Z10returnFivev
+ .size _Z10returnFivev, .-_Z10returnFivev
.cfi_endproc
.globl returnFourOrFiveFunc
- .p2align 4, 0x90
.type returnFourOrFiveFunc, at function
returnFourOrFiveFunc:
.cfi_startproc
-# %bb.0:
xorl %eax, %eax
cmpl $1, %edi
sete %al
xorl $5, %eax
retq
-.Lfunc_end11:
- .size returnFourOrFiveFunc, .Lfunc_end11-returnFourOrFiveFunc
+ .size returnFourOrFiveFunc, .-returnFourOrFiveFunc
.cfi_endproc
.globl main
- .p2align 4, 0x90
.type main, at function
main:
.cfi_startproc
@@ -142,88 +133,64 @@ main:
callq _Z10createTypei
callq _Z10createTypei
leaq _ZNK8Derived24funcEii(%rip), %rcx
- jne .LBB1_2
callq _ZNK8Derived24funcEii
-.LBB1_3:
leaq _ZNK8Derived34funcEii(%rip), %rcx
- jne .LBB1_5
callq _ZNK8Derived34funcEii
-.LBB1_6:
- retq
-.LBB1_2:
- jmp .LBB1_3
-.LBB1_5:
- jmp .LBB1_6
-.Lfunc_end1:
- .size main, .Lfunc_end1-main
+ .size main, .-main
.cfi_endproc
.section .text.hot._ZNK8Derived24funcEii,"axG", at progbits,_ZNK8Derived24funcEii,comdat
.weak _ZNK8Derived24funcEii
- .p2align 4, 0x90
.type _ZNK8Derived24funcEii, at function
_ZNK8Derived24funcEii: #
.cfi_startproc
imull %esi, %eax
retq
-.Lfunc_end2:
- .size _ZNK8Derived24funcEii, .Lfunc_end2-_ZNK8Derived24funcEii
+ .size _ZNK8Derived24funcEii, .-_ZNK8Derived24funcEii
.cfi_endproc
.section .text.unlikely._ZN8Derived2D0Ev,"axG", at progbits,_ZN8Derived2D0Ev,comdat
.weak _ZN8Derived2D0Ev
- .p2align 4, 0x90
.type _ZN8Derived2D0Ev, at function
_ZN8Derived2D0Ev:
.cfi_startproc
-# %bb.0:
movl $16, %esi
jmp _ZdlPvm at PLT
-.Lfunc_end3:
- .size _ZN8Derived2D0Ev, .Lfunc_end3-_ZN8Derived2D0Ev
+ .size _ZN8Derived2D0Ev, .-_ZN8Derived2D0Ev
.cfi_endproc
.section .text.hot._ZNK8Derived34funcEii,"axG", at progbits,_ZNK8Derived34funcEii,comdat
.weak _ZNK8Derived34funcEii
- .p2align 4, 0x90
.type _ZNK8Derived34funcEii, at function
_ZNK8Derived34funcEii:
.cfi_startproc
imull %esi, %eax
retq
-.Lfunc_end4:
- .size _ZNK8Derived34funcEii, .Lfunc_end4-_ZNK8Derived34funcEii
+ .size _ZNK8Derived34funcEii, .-_ZNK8Derived34funcEii
.cfi_endproc
.section .text.unlikely._ZN4BaseD2Ev,"axG", at progbits,_ZN4BaseD2Ev,comdat
.weak _ZN4BaseD2Ev
- .p2align 4, 0x90
.type _ZN4BaseD2Ev, at function
_ZN4BaseD2Ev:
.cfi_startproc
-# %bb.0:
retq
-.Lfunc_end5:
- .size _ZN4BaseD2Ev, .Lfunc_end5-_ZN4BaseD2Ev
+ .size _ZN4BaseD2Ev, .-_ZN4BaseD2Ev
.cfi_endproc
.section .text.unlikely._ZN8Derived3D0Ev,"axG", at progbits,_ZN8Derived3D0Ev,comdat
.weak _ZN8Derived3D0Ev
- .p2align 4, 0x90
.type _ZN8Derived3D0Ev, at function
_ZN8Derived3D0Ev:
.cfi_startproc
-# %bb.0:
movl $16, %esi
jmp _ZdlPvm at PLT
-.Lfunc_end6:
- .size _ZN8Derived3D0Ev, .Lfunc_end6-_ZN8Derived3D0Ev
+ .size _ZN8Derived3D0Ev, .-_ZN8Derived3D0Ev
.cfi_endproc
.type _ZTV8Derived2, at object
.section .data.rel.ro._ZTV8Derived2,"awG", at progbits,_ZTV8Derived2,comdat
.weak _ZTV8Derived2
- .p2align 3, 0x0
_ZTV8Derived2:
.quad 0
.quad _ZTI8Derived2
@@ -249,7 +216,6 @@ _ZTS4Base:
.type _ZTI4Base, at object
.section .data.rel.ro._ZTI4Base,"awG", at progbits,_ZTI4Base,comdat
.weak _ZTI4Base
- .p2align 3, 0x0
_ZTI4Base:
.quad _ZTVN10__cxxabiv117__class_type_infoE+16
.quad _ZTS4Base
@@ -258,7 +224,6 @@ _ZTI4Base:
.type _ZTI8Derived2, at object
.section .data.rel.ro._ZTI8Derived2,"awG", at progbits,_ZTI8Derived2,comdat
.weak _ZTI8Derived2
- .p2align 3, 0x0
_ZTI8Derived2:
.quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
.quad _ZTS8Derived2
@@ -268,7 +233,6 @@ _ZTI8Derived2:
.type _ZTV8Derived3, at object
.section .data.rel.ro._ZTV8Derived3,"awG", at progbits,_ZTV8Derived3,comdat
.weak _ZTV8Derived3
- .p2align 3, 0x0
_ZTV8Derived3:
.quad 0
.quad _ZTI8Derived3
@@ -287,7 +251,6 @@ _ZTS8Derived3:
.type _ZTI8Derived3, at object
.section .data.rel.ro._ZTI8Derived3,"awG", at progbits,_ZTI8Derived3,comdat
.weak _ZTI8Derived3
- .p2align 3, 0x0
_ZTI8Derived3:
.quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
.quad _ZTS8Derived3
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
index 337e04e0c5407b..fab405abb81e7c 100644
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ b/bolt/test/X86/icf-safe-test1-no-cfg.test
@@ -1,4 +1,5 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
+## Tests disassemble path for a function.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
@@ -18,169 +19,136 @@
# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
-# clang++ -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# int main(int argc, char **argv) {
-# int temp = helper1(barAdd, FooVar, BarVar) +
-# helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# return temp;
-# }
+## clang++ -c main.cpp -o main.o
+## extern int FooVar;
+## extern int BarVar;
+## [[clang::noinline]]
+## int fooSub(int a, int b) {
+## return a - b;
+## }
+## [[clang::noinline]]
+## int barSub(int a, int b) {
+## return a - b;
+## }
+## [[clang::noinline]]
+## int fooMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## int barMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## int fooAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## int barAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## int helper1(int (*func)(int, int), int a, int b) {
+## if (func == barAdd)
+## return 1;
+## return func(a, b) - 4;
+## }
+## [[clang::noinline]]
+## int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+## if (func == func2)
+## return 2;
+## return func(a, b) + func2(a, b);
+## }
+## int main(int arßgc, char **argv) {
+## int temp = helper1(barAdd, FooVar, BarVar) +
+## helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+## return temp;
+## }
.globl fooSubFunc
- .p2align 4, 0x90
.type fooSubFunc, at function
fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
+ .size fooSubFunc, .-fooSubFunc
.cfi_endproc
.globl barSubFunc
- .p2align 4, 0x90
.type barSubFunc, at function
barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
-.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
+ .size barSubFunc, .-barSubFunc
.cfi_endproc
.globl fooMulFunc
- .p2align 4, 0x90
.type fooMulFunc, at function
fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
+ .size fooMulFunc, .-fooMulFunc
.cfi_endproc
.globl barMulFunc
- .p2align 4, 0x90
.type barMulFunc, at function
barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
+ .size barMulFunc, .-barMulFunc
.cfi_endproc
.globl fooAddFunc
- .p2align 4, 0x90
.type fooAddFunc, at function
fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
+ .size fooAddFunc, .-fooAddFunc
.cfi_endproc
.globl barAddFunc
- .p2align 4, 0x90
.type barAddFunc, at function
barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
+ .size barAddFunc, .-barAddFunc
.cfi_endproc
.globl helper1Func
- .p2align 4, 0x90
.type helper1Func, at function
helper1Func:
.cfi_startproc
leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
- jne .LBB6_2
- jmp .LBB6_3
-.LBB6_2:
- callq *%rax
-.LBB6_3:
retq
-.Lfunc_end6:
- .size helper1Func, .Lfunc_end6-helper1Func
+ .size helper1Func, .-helper1Func
.cfi_endproc
.globl helper2Func
- .p2align 4, 0x90
.type helper2Func, at function
helper2Func:
.cfi_startproc
# Operates on registers.
retq
-.Lfunc_end7:
- .size helper2Func, .Lfunc_end7-helper2Func
+ .size helper2Func, .-helper2Func
.cfi_endproc
.globl main
- .p2align 4, 0x90
.type main, at function
main:
.cfi_startproc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
leaq barAddFunc(%rip), %rdi
callq helper1Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
leaq fooMulFunc(%rip), %rdi
leaq barMulFunc(%rip), %rsi
callq helper2Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq fooSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq barSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq fooAddFunc
retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
+ .size main, .-main
.cfi_endproc
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index ec47108da24ccb..bd3d093defa5df 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -3,179 +3,18 @@
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
# RUN: not llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-
# SAFEICFCHECK: BOLT-ERROR: Binary built without relocations. Safe ICF is not supported
-# clang++ -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# int main(int argc, char **argv) {
-# int temp = helper1(barAdd, FooVar, BarVar) +
-# helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# return temp;
-# }
- .globl fooSubFunc
- .p2align 4, 0x90
- .type fooSubFunc, at function
-fooSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
- .cfi_endproc
-
- .globl barSubFunc
- .p2align 4, 0x90
- .type barSubFunc, at function
-barSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .p2align 4, 0x90
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .p2align 4, 0x90
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .p2align 4, 0x90
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .p2align 4, 0x90
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
- .cfi_endproc
-
- .globl helper1Func
- .p2align 4, 0x90
- .type helper1Func, at function
-helper1Func:
- .cfi_startproc
- leaq barAddFunc(%rip), %rax
- cmpq %rax, -16(%rbp)
- jne .LBB6_2
- jmp .LBB6_3
-.LBB6_2:
- callq *%rax
-.LBB6_3:
- retq
-.Lfunc_end6:
- .size helper1Func, .Lfunc_end6-helper1Func
- .cfi_endproc
-
- .globl helper2Func
- .p2align 4, 0x90
- .type helper2Func, at function
-helper2Func:
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size helper2Func, .Lfunc_end7-helper2Func
- .cfi_endproc
-
+## int main(int argc, char **argv) {
+## return temp;
+## }
.globl main
- .p2align 4, 0x90
.type main, at function
main:
.cfi_startproc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq barAddFunc(%rip), %rdi
- callq helper1Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq fooMulFunc(%rip), %rdi
- leaq barMulFunc(%rip), %rsi
- callq helper2Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq fooSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq barSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq fooAddFunc
retq
.Lfunc_end8:
- .size main, .Lfunc_end8-main
+ .size main, .-main
.cfi_endproc
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index 68c37c1ce01f2e..e0392dc72bd6f8 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -1,4 +1,4 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
@@ -18,169 +18,136 @@
# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
-# clang++ -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# int main(int argc, char **argv) {
-# int temp = helper1(barAdd, FooVar, BarVar) +
-# helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# return temp;
-# }
+## clang++ -c main.cpp -o main.o
+## extern int FooVar;
+## extern int BarVar;
+## [[clang::noinline]]
+## int fooSub(int a, int b) {
+## return a - b;
+## }
+## [[clang::noinline]]
+## int barSub(int a, int b) {
+## return a - b;
+## }
+## [[clang::noinline]]
+## int fooMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## int barMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## int fooAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## int barAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## int helper1(int (*func)(int, int), int a, int b) {
+## if (func == barAdd)
+## return 1;
+## return func(a, b) - 4;
+## }
+## [[clang::noinline]]
+## int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+## if (func == func2)
+## return 2;
+## return func(a, b) + func2(a, b);
+## }
+## int main(int argc, char **argv) {
+## int temp = helper1(barAdd, FooVar, BarVar) +
+## helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+## return temp;
+## }
.globl fooSubFunc
- .p2align 4, 0x90
.type fooSubFunc, at function
fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
+ .size fooSubFunc, .-fooSubFunc
.cfi_endproc
.globl barSubFunc
- .p2align 4, 0x90
.type barSubFunc, at function
barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
-.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
+ .size barSubFunc, .-barSubFunc
.cfi_endproc
.globl fooMulFunc
- .p2align 4, 0x90
.type fooMulFunc, at function
fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
+ .size fooMulFunc, .-fooMulFunc
.cfi_endproc
.globl barMulFunc
- .p2align 4, 0x90
.type barMulFunc, at function
barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
+ .size barMulFunc, .-barMulFunc
.cfi_endproc
.globl fooAddFunc
- .p2align 4, 0x90
.type fooAddFunc, at function
fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
+ .size fooAddFunc, .-fooAddFunc
.cfi_endproc
.globl barAddFunc
- .p2align 4, 0x90
.type barAddFunc, at function
barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
+ .size barAddFunc, .-barAddFunc
.cfi_endproc
.globl helper1Func
- .p2align 4, 0x90
.type helper1Func, at function
helper1Func:
.cfi_startproc
leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
- jne .LBB6_2
- jmp .LBB6_3
-.LBB6_2:
- callq *%rax
-.LBB6_3:
retq
-.Lfunc_end6:
- .size helper1Func, .Lfunc_end6-helper1Func
+ .size helper1Func, .-helper1Func
.cfi_endproc
.globl helper2Func
- .p2align 4, 0x90
.type helper2Func, at function
helper2Func:
.cfi_startproc
# Operates on registers.
retq
-.Lfunc_end7:
- .size helper2Func, .Lfunc_end7-helper2Func
+ .size helper2Func, .-helper2Func
.cfi_endproc
.globl main
- .p2align 4, 0x90
.type main, at function
main:
.cfi_startproc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
leaq barAddFunc(%rip), %rdi
callq helper1Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
leaq fooMulFunc(%rip), %rdi
leaq barMulFunc(%rip), %rsi
callq helper2Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq fooSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq barSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq fooAddFunc
retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
+ .size main, .-main
.cfi_endproc
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index 4ca6eb2665270c..48b90628dfa141 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -1,4 +1,4 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
## This checks global const function pointer in -fno-pic mode is handled correctly.
# REQUIRES: system-linux
@@ -17,54 +17,54 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: ===---------
-# clang++ main.cpp -c -o
-# #define MY_CONST const
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# MY_CONST int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
-# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar)
-# fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# Manually modified to remove "extra" assembly.
+## clang++ main.cpp -c -o
+## Similar code gets generated for external reference function.
+## #define MY_CONST const
+## extern int FooVar;
+## extern int BarVar;
+## [[clang::noinline]]
+## MY_CONST int fooMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## MY_CONST int barMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## MY_CONST int fooAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## MY_CONST int barAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+## if (func == barAdd)
+## return 1;
+## return func(a, b) - 4;
+## }
+## [[clang::noinline]]
+## MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+## if (func == func2)
+## return 2;
+## return func(a, b) + func2(a, b);
+## }
+## MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
+## MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
+## int main(int argc, char **argv) {
+## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+## helper2(fooMul, funcGlobalBarMul, FooVar, BarVar)
+## fooAdd(FooVar, BarVar);
+## MY_PRINTF("val: %d", temp);
+## return temp;
+## }
+## clang++ helper.cpp -c -o
+## #define MY_CONST const
+## int FooVar = 1;
+## int BarVar = 2;
+## Manually modified to remove "extra" assembly.
.globl fooMulFunc
- .p2align 4, 0x90
.type fooMulFunc, at function
fooMulFunc:
.cfi_startproc
@@ -72,12 +72,10 @@ fooMulFunc:
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end0:
- .size fooMulFunc, .Lfunc_end0-fooMulFunc
+ .size fooMulFunc, .-fooMulFunc
.cfi_endproc
.globl barMulFunc
- .p2align 4, 0x90
.type barMulFunc, at function
barMulFunc:
.cfi_startproc
@@ -85,12 +83,10 @@ barMulFunc:
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end1:
- .size barMulFunc, .Lfunc_end1-barMulFunc
+ .size barMulFunc, .-barMulFunc
.cfi_endproc
.globl fooAddFunc
- .p2align 4, 0x90
.type fooAddFunc, at function
fooAddFunc:
.cfi_startproc
@@ -98,12 +94,10 @@ fooAddFunc:
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end2:
- .size fooAddFunc, .Lfunc_end2-fooAddFunc
+ .size fooAddFunc, .-fooAddFunc
.cfi_endproc
.globl barAddFunc
- .p2align 4, 0x90
.type barAddFunc, at function
barAddFunc:
.cfi_startproc
@@ -111,35 +105,29 @@ barAddFunc:
popq %rbp
.cfi_def_cfa %rsp, 8
retq
-.Lfunc_end3:
- .size barAddFunc, .Lfunc_end3-barAddFunc
+ .size barAddFunc, .-barAddFunc
.cfi_endproc
.globl _Z7helper1PFKiiiEii
- .p2align 4, 0x90
.type _Z7helper1PFKiiiEii, at function
_Z7helper1PFKiiiEii:
.cfi_startproc
movabsq $barAddFunc, %rax
cmpq %rax, -16(%rbp)
retq
-.Lfunc_end4:
- .size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
+ .size _Z7helper1PFKiiiEii, .-_Z7helper1PFKiiiEii
.cfi_endproc
.globl _Z7helper2PFKiiiES1_ii
- .p2align 4, 0x90
.type _Z7helper2PFKiiiES1_ii, at function
_Z7helper2PFKiiiES1_ii:
.cfi_startproc
# no direct function references.
retq
-.Lfunc_end5:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
+ .size _Z7helper2PFKiiiES1_ii, .-_Z7helper2PFKiiiES1_ii
.cfi_endproc
.globl main
- .p2align 4, 0x90
.type main, at function
main:
.cfi_startproc
@@ -147,9 +135,6 @@ main:
movl BarVar, %edx
movabsq $barAddFunc, %rdi
callq _Z7helper1PFKiiiEii
- movl %eax, -28(%rbp)
- movl FooVar, %edx
- movl BarVar, %ecx
movabsq $fooMulFunc, %rdi
movabsq $barMulFunc, %rsi
callq _Z7helper2PFKiiiES1_ii
@@ -161,14 +146,12 @@ main:
.type FooVar, at object
.data
.globl FooVar
- .p2align 2, 0x0
FooVar:
.long 1
.size FooVar, 4
.type BarVar, at object
.globl BarVar
- .p2align 2, 0x0
BarVar:
.long 2
.size BarVar, 4
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
deleted file mode 100644
index c55ca49964a938..00000000000000
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPicExtFuncRef.test
+++ /dev/null
@@ -1,233 +0,0 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
-## This checks global const function pointer in -fno-pic mode is handled correctly.
-
-# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
-# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q -no-pie
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding _Z12barAddHdlperii into fooAddFunc
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
-# SAFEICFCHECK-NEXT: skipping function _Z12barAddHdlperii
-# SAFEICFCHECK-NEXT: skipping function fooGlobalFuncHelperFunc
-# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK-NEXT: ===---------
-
-# clang++ main.cpp -c -o
-# #define MY_CONST const
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# MY_CONST int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# extern MY_CONST int barAddHdlper(int a, int b);
-# extern MY_CONST int fooGlobalFuncHelper(int a, int b);
-# MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
-# MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-# Manually modified to remove "extra" assembly.
- .globl fooSubFunc
- .p2align 4, 0x90
- .type fooSubFunc, at function
-fooSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
- .cfi_endproc
-
- .globl barSubFunc
- .p2align 4, 0x90
- .type barSubFunc, at function
-barSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .p2align 4, 0x90
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .p2align 4, 0x90
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .p2align 4, 0x90
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .p2align 4, 0x90
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
- .cfi_endproc
-
- .globl _Z7helper1PFKiiiEii
- .p2align 4, 0x90
- .type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii:
- .cfi_startproc
- movabsq $barAddFunc, %rax
- cmpq %rax, -16(%rbp)
- retq
-.Lfunc_end6:
- .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
- .cfi_endproc
-
- .globl _Z7helper2PFKiiiES1_ii
- .p2align 4, 0x90
- .type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii:
- .cfi_startproc
- # All operations on registers.
- retq
-.Lfunc_end7:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
- .cfi_endproc
-
- .globl main
- .p2align 4, 0x90
- .type main, at function
-main:
- .cfi_startproc
- movl FooVar, %esi
- movl BarVar, %edx
- movabsq $_Z12barAddHdlperii, %rdi
- callq _Z7helper1PFKiiiEii
- movl FooVar, %edx
- movl BarVar, %ecx
- movabsq $fooMulFunc, %rdi
- movabsq $fooGlobalFuncHelperFunc, %rsi
- callq _Z7helper2PFKiiiES1_ii
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
-
- .globl _Z12barAddHdlperii
- .p2align 4, 0x90
- .type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end01:
- .size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
- .cfi_endproc
-
- .globl fooGlobalFuncHelperFunc
- .p2align 4, 0x90
- .type fooGlobalFuncHelperFunc, at function
-fooGlobalFuncHelperFunc:
- .cfi_startproc
- callq _Z12barAddHdlperii
- retq
-.Lfunc_end11:
- .size fooGlobalFuncHelperFunc, .Lfunc_end11-fooGlobalFuncHelperFunc
- .cfi_endproc
-
- .type FooVar, at object
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1
- .size FooVar, 4
-
- .type BarVar, at object
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2
- .size BarVar, 4
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
index ebcd224542d238..6dbc8039ab48d2 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
@@ -1,4 +1,4 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
## This checks global const function pointer in -fpic mode is handled correctly.
# REQUIRES: system-linux
@@ -17,121 +17,108 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: ===---------
-# clang++ main.cpp -c -o
-# #define MY_CONST const
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# MY_CONST int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
-# MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) +
-# fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# Manually modified to remove "extra" assembly.
+## clang++ main.cpp -c -o
+## #define MY_CONST const
+## extern int FooVar;
+## extern int BarVar;
+## [[clang::noinline]]
+## MY_CONST int fooMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## MY_CONST int barMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## MY_CONST int fooAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## MY_CONST int barAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+## if (func == barAdd)
+## return 1;
+## return func(a, b) - 4;
+## }
+## [[clang::noinline]]
+## MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+## if (func == func2)
+## return 2;
+## return func(a, b) + func2(a, b);
+## }
+## MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
+## MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
+## int main(int argc, char **argv) {
+## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+## helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) +
+## fooAdd(FooVar, BarVar);
+## MY_PRINTF("val: %d", temp);
+## return temp;
+## }
+## clang++ helper.cpp -c -o
+## #define MY_CONST const
+## int FooVar = 1;
+## int BarVar = 2;
+## Manually modified to remove "extra" assembly.
.globl fooMulFunc
- .p2align 4, 0x90
.type fooMulFunc, at function
fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end0:
- .size fooMulFunc, .Lfunc_end0-fooMulFunc
+ .size fooMulFunc, .-fooMulFunc
.cfi_endproc
.globl barMulFunc
- .p2align 4, 0x90
.type barMulFunc, at function
barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end1:
- .size barMulFunc, .Lfunc_end1-barMulFunc
+ .size barMulFunc, .-barMulFunc
.cfi_endproc
.globl fooAddFunc
- .p2align 4, 0x90
.type fooAddFunc, at function
fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end2:
- .size fooAddFunc, .Lfunc_end2-fooAddFunc
+ .size fooAddFunc, .-fooAddFunc
.cfi_endproc
.globl barAddFunc
- .p2align 4, 0x90
.type barAddFunc, at function
barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end3:
- .size barAddFunc, .Lfunc_end3-barAddFunc
+ .size barAddFunc, .-barAddFunc
.cfi_endproc
.globl _Z7helper1PFKiiiEii
- .p2align 4, 0x90
.type _Z7helper1PFKiiiEii, at function
_Z7helper1PFKiiiEii:
.cfi_startproc
leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
retq
-.Lfunc_end4:
- .size _Z7helper1PFKiiiEii, .Lfunc_end4-_Z7helper1PFKiiiEii
+ .size _Z7helper1PFKiiiEii, .-_Z7helper1PFKiiiEii
.cfi_endproc
.globl _Z7helper2PFKiiiES1_ii
- .p2align 4, 0x90
.type _Z7helper2PFKiiiES1_ii, at function
_Z7helper2PFKiiiES1_ii:
.cfi_startproc
# Operates on registers.
retq
-.Lfunc_end5:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end5-_Z7helper2PFKiiiES1_ii
+ .size _Z7helper2PFKiiiES1_ii, .-_Z7helper2PFKiiiES1_ii
.cfi_endproc
.globl main
- .p2align 4, 0x90
.type main, at function
main:
.cfi_startproc
@@ -139,27 +126,22 @@ main:
movq BarVar at GOTPCREL(%rip), %rax
leaq barAddFunc(%rip), %rdi
callq _Z7helper1PFKiiiEii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
leaq fooMulFunc(%rip), %rdi
leaq barMulFunc(%rip), %rsi
callq _Z7helper2PFKiiiES1_ii
retq
-.Lfunc_end6:
- .size main, .Lfunc_end6-main
+ .size main, .-main
.cfi_endproc
.type FooVar, at object
.data
.globl FooVar
- .p2align 2, 0x0
FooVar:
.long 1
.size FooVar, 4
.type BarVar, at object
.globl BarVar
- .p2align 2, 0x0
BarVar:
.long 2
.size BarVar, 4
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
index 8e02c30aa5e2a8..ca2f82912450b9 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
@@ -1,4 +1,4 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
## This checks global const function pointer with external function reference in -fpic mode is handled correctly.
# REQUIRES: system-linux
@@ -22,174 +22,158 @@
# SAFEICFCHECK-NEXT: ===---------
-# clang++ main.cpp -c -o
-# #define MY_CONST const
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# MY_CONST int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# MY_CONST int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# extern MY_CONST int barAddHdlper(int a, int b);
-# extern MY_CONST int fooGlobalFuncHelper(int a, int b);
-# MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
-# MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
-# clang++ helper.cpp -c -o
-# #define MY_CONST const
-# int FooVar = 1;
-# int BarVar = 2;
-# [[clang::noinline]]
-# MY_CONST int barAddHdlper(int a, int b) {
-# return a + b;
-# }
-#
-# MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-# MY_CONST int fooGlobalFuncHelper(int a, int b) {
-# return 5 + funcGlobalBarMulExt(a, b);
-# }
+## clang++ main.cpp -c -o
+## #define MY_CONST const
+## extern int FooVar;
+## extern int BarVar;
+## [[clang::noinline]]
+## MY_CONST int fooSub(int a, int b) {
+## return a - b;
+## }
+## [[clang::noinline]]
+## MY_CONST int barSub(int a, int b) {
+## return a - b;
+## }
+## [[clang::noinline]]
+## MY_CONST int fooMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## MY_CONST int barMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## MY_CONST int fooAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## MY_CONST int barAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
+## if (func == barAdd)
+## return 1;
+## return func(a, b) - 4;
+## }
+## [[clang::noinline]]
+## MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
+## if (func == func2)
+## return 2;
+## return func(a, b) + func2(a, b);
+## }
+## extern MY_CONST int barAddHdlper(int a, int b);
+## extern MY_CONST int fooGlobalFuncHelper(int a, int b);
+## MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
+## MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
+## int main(int argc, char **argv) {
+## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+## helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+## MY_PRINTF("val: %d", temp);
+## return temp;
+## }
+## clang++ helper.cpp -c -o
+## #define MY_CONST const
+## int FooVar = 1;
+## int BarVar = 2;
+## [[clang::noinline]]
+## MY_CONST int barAddHdlper(int a, int b) {
+## return a + b;
+## }
+##
+## MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+## MY_CONST int fooGlobalFuncHelper(int a, int b) {
+## return 5 + funcGlobalBarMulExt(a, b);
+## }
+## clang++ helper.cpp -c -o
+## #define MY_CONST const
+## int FooVar = 1;
+## int BarVar = 2;
+## [[clang::noinline]]
+## MY_CONST int barAddHdlper(int a, int b) {
+## return a + b;
+## }
+##
+## MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
+## MY_CONST int fooGlobalFuncHelper(int a, int b) {
+## return 5 + funcGlobalBarMulExt(a, b);
+## }
.globl fooSubFunc
- .p2align 4, 0x90
.type fooSubFunc, at function
fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
+ .size fooSubFunc, .-fooSubFunc
.cfi_endproc
.globl barSubFunc
- .p2align 4, 0x90
.type barSubFunc, at function
barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
+ .size barSubFunc, .-barSubFunc
.cfi_endproc
.globl fooMulFunc
- .p2align 4, 0x90
.type fooMulFunc, at function
fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
+ .size fooMulFunc, .-fooMulFunc
.cfi_endproc
.globl barMulFunc
- .p2align 4, 0x90
.type barMulFunc, at function
barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
+ .size barMulFunc, .-barMulFunc
.cfi_endproc
.globl fooAddFunc
- .p2align 4, 0x90
.type fooAddFunc, at function
fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
+ .size fooAddFunc, .-fooAddFunc
.cfi_endproc
.globl barAddFunc
- .p2align 4, 0x90
.type barAddFunc, at function
barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
+ .size barAddFunc, .-barAddFunc
.cfi_endproc
.globl _Z7helper1PFKiiiEii
- .p2align 4, 0x90
.type _Z7helper1PFKiiiEii, at function
_Z7helper1PFKiiiEii:
.cfi_startproc
leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
retq
-.Lfunc_end6:
- .size _Z7helper1PFKiiiEii, .Lfunc_end6-_Z7helper1PFKiiiEii
+ .size _Z7helper1PFKiiiEii, .-_Z7helper1PFKiiiEii
.cfi_endproc
.globl _Z7helper2PFKiiiES1_ii
- .p2align 4, 0x90
.type _Z7helper2PFKiiiES1_ii, at function
_Z7helper2PFKiiiES1_ii:
.cfi_startproc
# Operates on registers.
retq
-.Lfunc_end7:
- .size _Z7helper2PFKiiiES1_ii, .Lfunc_end7-_Z7helper2PFKiiiES1_ii
+ .size _Z7helper2PFKiiiES1_ii, .-_Z7helper2PFKiiiES1_ii
.cfi_endproc
.globl main
- .p2align 4, 0x90
.type main, at function
main:
.cfi_startproc
@@ -197,58 +181,43 @@ main:
movq BarVar at GOTPCREL(%rip), %rax
movq _Z12barAddHdlperii at GOTPCREL(%rip), %rdi
callq _Z7helper1PFKiiiEii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
leaq fooMulFunc(%rip), %rdi
movq fooGlobalFuncHelperFunc at GOTPCREL(%rip), %rsi
callq _Z7helper2PFKiiiES1_ii
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq fooSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq barSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq fooAddFunc
retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
+ .size main, .-main
.cfi_endproc
.globl _Z12barAddHdlperii
- .p2align 4, 0x90
.type _Z12barAddHdlperii, at function
_Z12barAddHdlperii:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end01:
- .size _Z12barAddHdlperii, .Lfunc_end01-_Z12barAddHdlperii
+ .size _Z12barAddHdlperii, .-_Z12barAddHdlperii
.cfi_endproc
.globl fooGlobalFuncHelperFunc
- .p2align 4, 0x90
.type fooGlobalFuncHelperFunc, at function
fooGlobalFuncHelperFunc:
.cfi_startproc
callq _Z12barAddHdlperii
retq
-.Lfunc_end11:
- .size fooGlobalFuncHelperFunc, .Lfunc_end11-fooGlobalFuncHelperFunc
+ .size fooGlobalFuncHelperFunc, .-fooGlobalFuncHelperFunc
.cfi_endproc
.type FooVar, at object
.data
.globl FooVar
- .p2align 2, 0x0
FooVar:
.long 1
.size FooVar, 4
.type BarVar, at object
.globl BarVar
- .p2align 2, 0x0
BarVar:
.long 2
.size BarVar, 4
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
index e73ac27d065134..7dc10a42f0847b 100644
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
@@ -1,4 +1,4 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
@@ -19,198 +19,154 @@
# SAFEICFCHECK-NEXT: ===---------
-# clang++ -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# static int (*funcGlobalBarAdd)(int, int) = barAdd;
-# int (*funcGlobalBarMul)(int, int) = barMul;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# return temp;
-# }
-# Manually modified to remove "extra" assembly.
+## clang++ -c main.cpp -o main.o
+# Similar assembly gets generated with -O3 and local function pointers.
+## extern int FooVar;
+## extern int BarVar;
+## [[clang::noinline]]
+## int fooSub(int a, int b) {
+## return a - b;
+## }
+## [[clang::noinline]]
+## int barSub(int a, int b) {
+## return a - b;
+## }
+## [[clang::noinline]]
+## int fooMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## int barMul(int a, int b) {
+## return a * b;
+## }
+## [[clang::noinline]]
+## int fooAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## int barAdd(int a, int b) {
+## return a + b;
+## }
+## [[clang::noinline]]
+## int helper1(int (*func)(int, int), int a, int b) {
+## if (func == barAdd)
+## return 1;
+## return func(a, b) - 4;
+## }
+## [[clang::noinline]]
+## int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
+## if (func == func2)
+## return 2;
+## return func(a, b) + func2(a, b);
+## }
+## static int (*funcGlobalBarAdd)(int, int) = barAdd;
+## int (*funcGlobalBarMul)(int, int) = barMul;
+## int main(int argc, char **argv) {
+## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
+## helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
+## return temp;
+## }
+## Manually modified to remove "extra" assembly.
.globl fooSubFunc
- .p2align 4, 0x90
.type fooSubFunc, at function
fooSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
+ .size fooSubFunc, .-fooSubFunc
.cfi_endproc
.globl barSubFunc
- .p2align 4, 0x90
.type barSubFunc, at function
barSubFunc:
.cfi_startproc
subl -8(%rbp), %eax
retq
-.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
+ .size barSubFunc, .-barSubFunc
.cfi_endproc
.globl fooMulFunc
- .p2align 4, 0x90
.type fooMulFunc, at function
fooMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
+ .size fooMulFunc, .-fooMulFunc
.cfi_endproc
.globl barMulFunc
- .p2align 4, 0x90
.type barMulFunc, at function
barMulFunc:
.cfi_startproc
imull -8(%rbp), %eax
retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
+ .size barMulFunc, .-barMulFunc
.cfi_endproc
.globl fooAddFunc
- .p2align 4, 0x90
.type fooAddFunc, at function
fooAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
+ .size fooAddFunc, .-fooAddFunc
.cfi_endproc
.globl barAddFunc
- .p2align 4, 0x90
.type barAddFunc, at function
barAddFunc:
.cfi_startproc
addl -8(%rbp), %eax
retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
+ .size barAddFunc, .-barAddFunc
.cfi_endproc
.globl helper1Func
- .p2align 4, 0x90
.type helper1Func, at function
helper1Func:
.cfi_startproc
leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
retq
-.Lfunc_end6:
- .size helper1Func, .Lfunc_end6-helper1Func
+ .size helper1Func, .-helper1Func
.cfi_endproc
.globl helper2Func
- .p2align 4, 0x90
.type helper2Func, at function
helper2Func:
.cfi_startproc
# Operates on registers.
retq
-.Lfunc_end7:
- .size helper2Func, .Lfunc_end7-helper2Func
+ .size helper2Func, .-helper2Func
.cfi_endproc
.globl main
- .p2align 4, 0x90
.type main, at function
main:
.cfi_startproc
movq _ZL16funcGlobalBarAdd(%rip), %rdi
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq helper1Func
movq funcGlobalBarMul(%rip), %rsi
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
leaq fooMulFunc(%rip), %rdi
callq helper2Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq fooSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq barSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
callq fooAddFunc
retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
+ .size main, .-main
.cfi_endproc
.globl fooGlobalFuncHelperFunc
- .p2align 4, 0x90
.type fooGlobalFuncHelperFunc, at function
fooGlobalFuncHelperFunc:
.cfi_startproc
# %bb.0:
movl $5, %eax
retq
-.Lfunc_end01:
- .size fooGlobalFuncHelperFunc, .Lfunc_end01-fooGlobalFuncHelperFunc
+ .size fooGlobalFuncHelperFunc, .-fooGlobalFuncHelperFunc
.cfi_endproc
- .type FooVar, at object
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1
- .size FooVar, 4
-
- .type BarVar, at object
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2
- .size BarVar, 4
-
.type funcGlobalBarMul, at object
.data
.globl funcGlobalBarMul
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO3.test b/bolt/test/X86/icf-safe-test2GlobalVarO3.test
deleted file mode 100644
index bfc6218d813af8..00000000000000
--- a/bolt/test/X86/icf-safe-test2GlobalVarO3.test
+++ /dev/null
@@ -1,222 +0,0 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
-
-# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
-# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
-# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK-NEXT: ===---------
-
-# clang++ -O3 -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# static int (*funcGlobalBarAdd)(int, int) = barAdd;
-# int (*funcGlobalBarMul)(int, int) = barMul;
-# int main(int argc, char **argv) {
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# return temp;
-# }
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
- .globl fooSubFunc
- .p2align 4, 0x90
- .type fooSubFunc, at function
-fooSubFunc:
- .cfi_startproc
- subl %esi, %eax
- retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
- .cfi_endproc
-
- .globl barSubFunc
- .p2align 4, 0x90
- .type barSubFunc, at function
-barSubFunc:
- .cfi_startproc
- subl %esi, %eax
- retq
-.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .p2align 4, 0x90
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .p2align 4, 0x90
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .p2align 4, 0x90
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
-# %bb.0:
- leal (%rdi,%rsi), %eax
- retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .p2align 4, 0x90
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
-# %bb.0:
- leal (%rdi,%rsi), %eax
- retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
- .cfi_endproc
-
- .globl helper1Func
- .p2align 4, 0x90
- .type helper1Func, at function
-helper1Func:
- .cfi_startproc
- leaq barAddFunc(%rip), %rcx
- cmpq %rcx, %rdi
- retq
-.LBB6_1:
- movl $1, %eax
- retq
-.Lfunc_end6:
- .size helper1Func, .Lfunc_end6-helper1Func
- .cfi_endproc
-
- .globl helper2Func
- .p2align 4, 0x90
- .type helper2Func, at function
-helper2Func:
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size helper2Func, .Lfunc_end7-helper2Func
- .cfi_endproc
-
- .globl main
- .p2align 4, 0x90
- .type main, at function
-main:
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %r14
- movq BarVar at GOTPCREL(%rip), %r15
- leaq barAddFunc(%rip), %rdi
- callq helper1Func
- movq funcGlobalBarMul(%rip), %rsi
- leaq fooMulFunc(%rip), %rdi
- callq helper2Func
- callq fooSubFunc
- callq barSubFunc
- callq fooAddFunc
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
- .globl fooGlobalFuncHelperFunc
- .p2align 4, 0x90
- .type fooGlobalFuncHelperFunc, at function
-fooGlobalFuncHelperFunc:
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
-.Lfunc_end01:
- .size fooGlobalFuncHelperFunc, .Lfunc_end01-fooGlobalFuncHelperFunc
- .cfi_endproc
-
- .type FooVar, at object
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1
- .size FooVar, 4
-
- .type BarVar, at object
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2
- .size BarVar, 4
-
- .type funcGlobalBarMul, at object
- .data
- .globl funcGlobalBarMul
- .p2align 3, 0x0
-funcGlobalBarMul:
- .quad barMulFunc
- .size funcGlobalBarMul, 8
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO0.test b/bolt/test/X86/icf-safe-test3LocalVarO0.test
deleted file mode 100644
index 65e4ed5bfb084e..00000000000000
--- a/bolt/test/X86/icf-safe-test3LocalVarO0.test
+++ /dev/null
@@ -1,226 +0,0 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
-
-# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
-# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
-# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK-NEXT: ===---------
-
-
-# clang++ -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# int main(int argc, char **argv) {
-# static int (*funcGlobalBarAdd)(int, int) = barAdd;
-# int (*funcGlobalBarMul)(int, int) = barMul;
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
- .globl fooSubFunc
- .p2align 4, 0x90
- .type fooSubFunc, at function
-fooSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
- .cfi_endproc
-
- .globl barSubFunc
- .p2align 4, 0x90
- .type barSubFunc, at function
-barSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .p2align 4, 0x90
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .p2align 4, 0x90
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .p2align 4, 0x90
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .p2align 4, 0x90
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
- .cfi_endproc
-
- .globl helper1Func
- .p2align 4, 0x90
- .type helper1Func, at function
-helper1Func:
- .cfi_startproc
- leaq barAddFunc(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
-.Lfunc_end6:
- .size helper1Func, .Lfunc_end6-helper1Func
- .cfi_endproc
-
- .globl helper2Func
- .p2align 4, 0x90
- .type helper2Func, at function
-helper2Func:
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size helper2Func, .Lfunc_end7-helper2Func
- .cfi_endproc
-
- .globl main
- .p2align 4, 0x90
- .type main, at function
-main:
- .cfi_startproc
- leaq barMulFunc(%rip), %rax
- movq _ZZ4mainE16funcGlobalBarAdd(%rip), %rdi
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq helper1Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq fooMulFunc(%rip), %rdi
- callq helper2Func
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq fooSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq barSubFunc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- callq fooAddFunc
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
- .globl fooGlobalFuncHelperFunc
- .p2align 4, 0x90
- .type fooGlobalFuncHelperFunc, at function
-fooGlobalFuncHelperFunc:
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
-.Lfunc_end01:
- .size fooGlobalFuncHelperFunc, .Lfunc_end01-fooGlobalFuncHelperFunc
- .cfi_endproc
-
- .type FooVar, at object
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1
- .size FooVar, 4
-
- .type BarVar, at object
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2
- .size BarVar, 4
-
- .type _ZZ4mainE16funcGlobalBarAdd, at object
- .data
- .p2align 3, 0x0
-_ZZ4mainE16funcGlobalBarAdd:
- .quad barAddFunc
- .size _ZZ4mainE16funcGlobalBarAdd, 8
diff --git a/bolt/test/X86/icf-safe-test3LocalVarO3.test b/bolt/test/X86/icf-safe-test3LocalVarO3.test
deleted file mode 100644
index 6e06e03898f40c..00000000000000
--- a/bolt/test/X86/icf-safe-test3LocalVarO3.test
+++ /dev/null
@@ -1,216 +0,0 @@
-## Check that BOLT handles correctly folding functions with --icf-safe that can be referenced.
-
-# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
-# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
-# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK-NEXT: ===---------
-
-# clang++ -O3 -c main.cpp -o main.o
-# extern int FooVar;
-# extern int BarVar;
-# [[clang::noinline]]
-# int fooSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int barSub(int a, int b) {
-# return a - b;
-# }
-# [[clang::noinline]]
-# int fooMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int barMul(int a, int b) {
-# return a * b;
-# }
-# [[clang::noinline]]
-# int fooAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int barAdd(int a, int b) {
-# return a + b;
-# }
-# [[clang::noinline]]
-# int helper1(int (*func)(int, int), int a, int b) {
-# if (func == barAdd)
-# return 1;
-# return func(a, b) - 4;
-# }
-# [[clang::noinline]]
-# int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-# if (func == func2)
-# return 2;
-# return func(a, b) + func2(a, b);
-# }
-# int main(int argc, char **argv) {
-# static int (*funcGlobalBarAdd)(int, int) = barAdd;
-# int (*funcGlobalBarMul)(int, int) = barMul;
-# int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-# helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-# barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-# MY_PRINTF("val: %d", temp);
-# return temp;
-# }
-# clang++ -c helper.cpp -o helper.o
-# int FooVar = 1;
-# int BarVar = 2;
-#
-# int fooGlobalFuncHelper(int a, int b) {
-# return 5;
-# }
- .globl fooSubFunc
- .p2align 4, 0x90
- .type fooSubFunc, at function
-fooSubFunc:
- .cfi_startproc
- subl %esi, %eax
- retq
-.Lfunc_end0:
- .size fooSubFunc, .Lfunc_end0-fooSubFunc
- .cfi_endproc
-
- .globl barSubFunc
- .p2align 4, 0x90
- .type barSubFunc, at function
-barSubFunc:
- .cfi_startproc
- subl %esi, %eax
- retq
-.Lfunc_end1:
- .size barSubFunc, .Lfunc_end1-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .p2align 4, 0x90
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end2:
- .size fooMulFunc, .Lfunc_end2-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .p2align 4, 0x90
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull %esi, %eax
- retq
-.Lfunc_end3:
- .size barMulFunc, .Lfunc_end3-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .p2align 4, 0x90
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
-# %bb.0:
- leal (%rdi,%rsi), %eax
- retq
-.Lfunc_end4:
- .size fooAddFunc, .Lfunc_end4-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .p2align 4, 0x90
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
-# %bb.0:
- leal (%rdi,%rsi), %eax
- retq
-.Lfunc_end5:
- .size barAddFunc, .Lfunc_end5-barAddFunc
- .cfi_endproc
-
- .globl helper1Func
- .p2align 4, 0x90
- .type helper1Func, at function
-helper1Func:
- .cfi_startproc
- leaq barAddFunc(%rip), %rcx
- cmpq %rcx, %rdi
- retq
-.LBB6_1:
- movl $1, %eax
- retq
-.Lfunc_end6:
- .size helper1Func, .Lfunc_end6-helper1Func
- .cfi_endproc
-
- .globl helper2Func
- .p2align 4, 0x90
- .type helper2Func, at function
-helper2Func:
- .cfi_startproc
- # Operates on registers.
- retq
-.Lfunc_end7:
- .size helper2Func, .Lfunc_end7-helper2Func
- .cfi_endproc
-
- .globl main
- .p2align 4, 0x90
- .type main, at function
-main:
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %r14
- movq BarVar at GOTPCREL(%rip), %r15
- leaq barAddFunc(%rip), %rdi
- callq helper1Func
- leaq fooMulFunc(%rip), %rdi
- leaq barMulFunc(%rip), %rsi
- callq helper2Func
- callq fooSubFunc
- callq barSubFunc
- callq fooAddFunc
- retq
-.Lfunc_end8:
- .size main, .Lfunc_end8-main
- .cfi_endproc
-
-
- .globl fooGlobalFuncHelperFunc
- .p2align 4, 0x90
- .type fooGlobalFuncHelperFunc, at function
-fooGlobalFuncHelperFunc:
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
-.Lfunc_end01:
- .size fooGlobalFuncHelperFunc, .Lfunc_end01-fooGlobalFuncHelperFunc
- .cfi_endproc
-
- .type FooVar, at object
- .data
- .globl FooVar
- .p2align 2, 0x0
-FooVar:
- .long 1
- .size FooVar, 4
-
- .type BarVar, at object
- .globl BarVar
- .p2align 2, 0x0
-BarVar:
- .long 2
- .size BarVar, 4
>From 4ace9bd7190366e94b3b19b7538e381484dbe97c Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Sat, 30 Nov 2024 15:10:03 -0800
Subject: [PATCH 20/34] moved reloc checking code, and changed elf object from
assert to return error
---
.../bolt/Passes/IdenticalCodeFolding.h | 4 +-
bolt/lib/Passes/IdenticalCodeFolding.cpp | 32 ++-
bolt/lib/Rewrite/RewriteInstance.cpp | 183 ++++++++----------
3 files changed, 92 insertions(+), 127 deletions(-)
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index a7b49daa3cf6ad..f40d856bfc7b72 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -45,8 +45,8 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
Error markFunctionsUnsafeToFold(BinaryContext &BC);
/// Process relocations in the .data section to identify function
/// references.
- void processDataRelocations(BinaryContext &BC,
- const SectionRef &SecRefRelData);
+ Error processDataRelocations(BinaryContext &BC,
+ const SectionRef &SecRefRelData);
};
} // namespace bolt
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 759e6ee4327864..a8d87880926552 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -340,7 +340,7 @@ typedef std::unordered_map<BinaryFunction *, std::vector<BinaryFunction *>,
namespace llvm {
namespace bolt {
-void IdenticalCodeFolding::processDataRelocations(
+Error IdenticalCodeFolding::processDataRelocations(
BinaryContext &BC, const SectionRef &SecRefRelData) {
for (const RelocationRef &Rel : SecRefRelData.relocations()) {
symbol_iterator SymbolIter = Rel.getSymbol();
@@ -351,39 +351,35 @@ void IdenticalCodeFolding::processDataRelocations(
const uint64_t SymbolAddress = cantFail(Symbol.getAddress());
const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(OwningObj);
if (!ELFObj)
- llvm_unreachable("Only ELFObjectFileBase is supported");
+ return createFatalBOLTError(
+ Twine("BOLT-ERROR: Only ELFObjectFileBase is supported"));
const int64_t Addend = getRelocationAddend(ELFObj, Rel);
BinaryFunction *BF = BC.getBinaryFunctionAtAddress(SymbolAddress + Addend);
if (!BF)
continue;
BF->setUnsafeICF();
}
+ return Error::success();
}
Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
- Error ErrorStatus = Error::success();
- if (!BC.HasRelocations)
- ErrorStatus = joinErrors(
- std::move(ErrorStatus),
- createFatalBOLTError(Twine("BOLT-ERROR: Binary built without "
- "relocations. Safe ICF is not supported")));
- if (ErrorStatus)
- return ErrorStatus;
ErrorOr<BinarySection &> SecRelData = BC.getUniqueSectionByName(".rela.data");
if (SecRelData) {
SectionRef SecRefRelData = SecRelData->getSectionRef();
- processDataRelocations(BC, SecRefRelData);
+ Error ErrorStatus = processDataRelocations(BC, SecRefRelData);
+ if (ErrorStatus)
+ return ErrorStatus;
}
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
- if (BF.getState() == BinaryFunction::State::CFG) {
- for (const BinaryBasicBlock *BB : BF.getLayout().blocks())
- for (const MCInst &Inst : *BB)
- BC.processInstructionForFuncReferences(Inst);
- }
+ for (const BinaryBasicBlock *BB : BF.getLayout().blocks())
+ for (const MCInst &Inst : *BB)
+ BC.processInstructionForFuncReferences(Inst);
};
ParallelUtilities::PredicateTy SkipFunc =
- [&](const BinaryFunction &BF) -> bool { return (bool)ErrorStatus; };
+ [&](const BinaryFunction &BF) -> bool {
+ return BF.getState() != BinaryFunction::State::CFG;
+ };
ParallelUtilities::runOnEachFunction(
BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun,
SkipFunc, "markUnsafe", /*ForceSequential*/ false, 2);
@@ -396,7 +392,7 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
<< '\n';
}
});
- return ErrorStatus;
+ return Error::success();
}
Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 42e1231eeed1ab..473d99c280a56e 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -63,7 +63,7 @@
#include <optional>
#include <system_error>
-#undef DEBUG_TYPE
+#undef DEBUG_TYPE
#define DEBUG_TYPE "bolt"
using namespace llvm;
@@ -109,19 +109,15 @@ cl::opt<bool> DumpDotAll(
"enable '-print-loops' for color-coded blocks"),
cl::Hidden, cl::cat(BoltCategory));
-static cl::list<std::string>
-ForceFunctionNames("funcs",
- cl::CommaSeparated,
- cl::desc("limit optimizations to functions from the list"),
- cl::value_desc("func1,func2,func3,..."),
- cl::Hidden,
- cl::cat(BoltCategory));
+static cl::list<std::string> ForceFunctionNames(
+ "funcs", cl::CommaSeparated,
+ cl::desc("limit optimizations to functions from the list"),
+ cl::value_desc("func1,func2,func3,..."), cl::Hidden, cl::cat(BoltCategory));
static cl::opt<std::string>
-FunctionNamesFile("funcs-file",
- cl::desc("file with list of functions to optimize"),
- cl::Hidden,
- cl::cat(BoltCategory));
+ FunctionNamesFile("funcs-file",
+ cl::desc("file with list of functions to optimize"),
+ cl::Hidden, cl::cat(BoltCategory));
static cl::list<std::string> ForceFunctionNamesNR(
"funcs-no-regex", cl::CommaSeparated,
@@ -133,22 +129,17 @@ static cl::opt<std::string> FunctionNamesFileNR(
cl::desc("file with list of functions to optimize (non-regex)"), cl::Hidden,
cl::cat(BoltCategory));
-cl::opt<bool>
-KeepTmp("keep-tmp",
- cl::desc("preserve intermediate .o file"),
- cl::Hidden,
- cl::cat(BoltCategory));
+cl::opt<bool> KeepTmp("keep-tmp", cl::desc("preserve intermediate .o file"),
+ cl::Hidden, cl::cat(BoltCategory));
-static cl::opt<unsigned>
-LiteThresholdPct("lite-threshold-pct",
- cl::desc("threshold (in percent) for selecting functions to process in lite "
- "mode. Higher threshold means fewer functions to process. E.g "
- "threshold of 90 means only top 10 percent of functions with "
- "profile will be processed."),
- cl::init(0),
- cl::ZeroOrMore,
- cl::Hidden,
- cl::cat(BoltOptCategory));
+static cl::opt<unsigned> LiteThresholdPct(
+ "lite-threshold-pct",
+ cl::desc(
+ "threshold (in percent) for selecting functions to process in lite "
+ "mode. Higher threshold means fewer functions to process. E.g "
+ "threshold of 90 means only top 10 percent of functions with "
+ "profile will be processed."),
+ cl::init(0), cl::ZeroOrMore, cl::Hidden, cl::cat(BoltOptCategory));
static cl::opt<unsigned> LiteThresholdCount(
"lite-threshold-count",
@@ -200,43 +191,35 @@ static cl::opt<cl::boolOrDefault> RelocationMode(
extern cl::opt<std::string> SaveProfile;
-static cl::list<std::string>
-SkipFunctionNames("skip-funcs",
- cl::CommaSeparated,
- cl::desc("list of functions to skip"),
- cl::value_desc("func1,func2,func3,..."),
- cl::Hidden,
- cl::cat(BoltCategory));
+static cl::list<std::string> SkipFunctionNames(
+ "skip-funcs", cl::CommaSeparated, cl::desc("list of functions to skip"),
+ cl::value_desc("func1,func2,func3,..."), cl::Hidden, cl::cat(BoltCategory));
static cl::opt<std::string>
-SkipFunctionNamesFile("skip-funcs-file",
- cl::desc("file with list of functions to skip"),
- cl::Hidden,
- cl::cat(BoltCategory));
+ SkipFunctionNamesFile("skip-funcs-file",
+ cl::desc("file with list of functions to skip"),
+ cl::Hidden, cl::cat(BoltCategory));
-cl::opt<bool>
-TrapOldCode("trap-old-code",
- cl::desc("insert traps in old function bodies (relocation mode)"),
- cl::Hidden,
- cl::cat(BoltCategory));
+cl::opt<bool> TrapOldCode(
+ "trap-old-code",
+ cl::desc("insert traps in old function bodies (relocation mode)"),
+ cl::Hidden, cl::cat(BoltCategory));
static cl::opt<std::string> DWPPathName("dwp",
cl::desc("Path and name to DWP file."),
cl::Hidden, cl::init(""),
cl::cat(BoltCategory));
-static cl::opt<bool>
-UseGnuStack("use-gnu-stack",
- cl::desc("use GNU_STACK program header for new segment (workaround for "
- "issues with strip/objcopy)"),
- cl::ZeroOrMore,
- cl::cat(BoltCategory));
+static cl::opt<bool> UseGnuStack(
+ "use-gnu-stack",
+ cl::desc("use GNU_STACK program header for new segment (workaround for "
+ "issues with strip/objcopy)"),
+ cl::ZeroOrMore, cl::cat(BoltCategory));
static cl::opt<bool>
-SequentialDisassembly("sequential-disassembly",
- cl::desc("performs disassembly sequentially"),
- cl::init(false),
- cl::cat(BoltOptCategory));
+ SequentialDisassembly("sequential-disassembly",
+ cl::desc("performs disassembly sequentially"),
+ cl::init(false), cl::cat(BoltOptCategory));
static cl::opt<bool> WriteBoltInfoSection(
"bolt-info", cl::desc("write bolt info section in the output binary"),
@@ -519,12 +502,12 @@ Error RewriteInstance::discoverStorage() {
for (const ELF64LE::Phdr &Phdr : PHs) {
switch (Phdr.p_type) {
case ELF::PT_LOAD:
- BC->FirstAllocAddress = std::min(BC->FirstAllocAddress,
- static_cast<uint64_t>(Phdr.p_vaddr));
- NextAvailableAddress = std::max(NextAvailableAddress,
- Phdr.p_vaddr + Phdr.p_memsz);
- NextAvailableOffset = std::max(NextAvailableOffset,
- Phdr.p_offset + Phdr.p_filesz);
+ BC->FirstAllocAddress =
+ std::min(BC->FirstAllocAddress, static_cast<uint64_t>(Phdr.p_vaddr));
+ NextAvailableAddress =
+ std::max(NextAvailableAddress, Phdr.p_vaddr + Phdr.p_memsz);
+ NextAvailableOffset =
+ std::max(NextAvailableOffset, Phdr.p_offset + Phdr.p_filesz);
BC->SegmentMapInfo[Phdr.p_vaddr] = SegmentInfo{
Phdr.p_vaddr, Phdr.p_memsz, Phdr.p_offset,
@@ -1524,7 +1507,7 @@ void RewriteInstance::registerFragments() {
}
}
-registerParent:
+ registerParent:
// No local parent is found, use global parent function.
if (!ParentAddress)
if (BinaryData *ParentBD = BC->getBinaryDataByName(ParentName))
@@ -2050,6 +2033,13 @@ void RewriteInstance::adjustCommandLineOptions() {
exit(1);
}
+ if (!BC->HasRelocations &&
+ BC->getICFLevel() == BinaryContext::ICFLevel::Safe) {
+ BC->errs() << "BOLT-ERROR: Binary built without relocations. Safe ICF is "
+ "not supported\n";
+ exit(1);
+ }
+
if (opts::Instrument ||
(opts::ReorderFunctions != ReorderFunctions::RT_NONE &&
!opts::HotText.getNumOccurrences())) {
@@ -2350,14 +2340,12 @@ void RewriteInstance::readDynamicRelocations(const SectionRef &Section,
(void)SymbolAddress;
}
- LLVM_DEBUG(
- SmallString<16> TypeName;
- Rel.getTypeName(TypeName);
- dbgs() << "BOLT-DEBUG: dynamic relocation at 0x"
- << Twine::utohexstr(Rel.getOffset()) << " : " << TypeName
- << " : " << SymbolName << " : " << Twine::utohexstr(SymbolAddress)
- << " : + 0x" << Twine::utohexstr(Addend) << '\n'
- );
+ LLVM_DEBUG(SmallString<16> TypeName; Rel.getTypeName(TypeName);
+ dbgs() << "BOLT-DEBUG: dynamic relocation at 0x"
+ << Twine::utohexstr(Rel.getOffset()) << " : " << TypeName
+ << " : " << SymbolName << " : "
+ << Twine::utohexstr(SymbolAddress) << " : + 0x"
+ << Twine::utohexstr(Addend) << '\n');
if (IsJmpRel)
IsJmpRelocation[RType] = true;
@@ -3660,9 +3648,8 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) {
return Section->getOutputAddress();
});
LLVM_DEBUG(dbgs() << "Code sections in the order of output:\n";
- for (const BinarySection *Section : CodeSections)
- dbgs() << Section->getName() << '\n';
- );
+ for (const BinarySection *Section : CodeSections) dbgs()
+ << Section->getName() << '\n';);
uint64_t PaddingSize = 0; // size of padding required at the end
@@ -3829,13 +3816,9 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) {
const unsigned Flags = BinarySection::getFlags(/*IsReadOnly=*/true,
/*IsText=*/true,
/*IsAllocatable=*/true);
- BinarySection &Section =
- BC->registerOrUpdateSection(getBOLTTextSectionName(),
- ELF::SHT_PROGBITS,
- Flags,
- /*Data=*/nullptr,
- NewTextSectionSize,
- 16);
+ BinarySection &Section = BC->registerOrUpdateSection(
+ getBOLTTextSectionName(), ELF::SHT_PROGBITS, Flags,
+ /*Data=*/nullptr, NewTextSectionSize, 16);
Section.setOutputAddress(NewTextSectionStartAddress);
Section.setOutputFileOffset(
getFileOffsetForAddress(NewTextSectionStartAddress));
@@ -4086,7 +4069,7 @@ uint64_t appendPadding(raw_pwrite_stream &OS, uint64_t Offset,
return Offset + PaddingSize;
}
-}
+} // namespace
void RewriteInstance::rewriteNoteSections() {
auto ELF64LEFile = cast<ELF64LEObjectFile>(InputFile);
@@ -4206,12 +4189,9 @@ void RewriteInstance::finalizeSectionStringTable(ELFObjectFile<ELFT> *File) {
uint8_t *DataCopy = new uint8_t[SHStrTabSize];
memset(DataCopy, 0, SHStrTabSize);
SHStrTab.write(DataCopy);
- BC->registerOrUpdateNoteSection(".shstrtab",
- DataCopy,
- SHStrTabSize,
+ BC->registerOrUpdateNoteSection(".shstrtab", DataCopy, SHStrTabSize,
/*Alignment=*/1,
- /*IsReadOnly=*/true,
- ELF::SHT_STRTAB);
+ /*IsReadOnly=*/true, ELF::SHT_STRTAB);
}
void RewriteInstance::addBoltInfoSection() {
@@ -4467,11 +4447,9 @@ void RewriteInstance::patchELFSectionHeaderTable(ELFObjectFile<ELFT> *File) {
std::vector<uint32_t> NewSectionIndex;
std::vector<ELFShdrTy> OutputSections =
getOutputSections(File, NewSectionIndex);
- LLVM_DEBUG(
- dbgs() << "BOLT-DEBUG: old to new section index mapping:\n";
- for (uint64_t I = 0; I < NewSectionIndex.size(); ++I)
- dbgs() << " " << I << " -> " << NewSectionIndex[I] << '\n';
- );
+ LLVM_DEBUG(dbgs() << "BOLT-DEBUG: old to new section index mapping:\n";
+ for (uint64_t I = 0; I < NewSectionIndex.size(); ++I) dbgs()
+ << " " << I << " -> " << NewSectionIndex[I] << '\n';);
// Align starting address for section header table. There's no architecutal
// need to align this, it is just for pleasant human readability.
@@ -4966,13 +4944,10 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
if (DynSymSection) {
updateELFSymbolTable(
File,
- /*IsDynSym=*/true,
- *DynSymSection,
- NewSectionIndex,
+ /*IsDynSym=*/true, *DynSymSection, NewSectionIndex,
[&](size_t Offset, const ELFSymTy &Sym) {
Out->os().pwrite(reinterpret_cast<const char *>(&Sym),
- sizeof(ELFSymTy),
- DynSymSection->sh_offset + Offset);
+ sizeof(ELFSymTy), DynSymSection->sh_offset + Offset);
},
[](StringRef) -> size_t { return 0; });
}
@@ -5004,9 +4979,7 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
NumLocalSymbols = 0;
updateELFSymbolTable(
File,
- /*IsDynSym=*/false,
- *SymTabSection,
- NewSectionIndex,
+ /*IsDynSym=*/false, *SymTabSection, NewSectionIndex,
[&](size_t Offset, const ELFSymTy &Sym) {
if (Sym.getBinding() == ELF::STB_LOCAL)
++NumLocalSymbols;
@@ -5020,19 +4993,15 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
return Idx;
});
- BC->registerOrUpdateNoteSection(SecName,
- copyByteArray(NewContents),
+ BC->registerOrUpdateNoteSection(SecName, copyByteArray(NewContents),
NewContents.size(),
/*Alignment=*/1,
- /*IsReadOnly=*/true,
- ELF::SHT_SYMTAB);
+ /*IsReadOnly=*/true, ELF::SHT_SYMTAB);
- BC->registerOrUpdateNoteSection(StrSecName,
- copyByteArray(NewStrTab),
+ BC->registerOrUpdateNoteSection(StrSecName, copyByteArray(NewStrTab),
NewStrTab.size(),
/*Alignment=*/1,
- /*IsReadOnly=*/true,
- ELF::SHT_STRTAB);
+ /*IsReadOnly=*/true, ELF::SHT_STRTAB);
}
template <typename ELFT>
@@ -5128,8 +5097,8 @@ void RewriteInstance::patchELFAllocatableRelrSection(
}
template <typename ELFT>
-void
-RewriteInstance::patchELFAllocatableRelaSections(ELFObjectFile<ELFT> *File) {
+void RewriteInstance::patchELFAllocatableRelaSections(
+ ELFObjectFile<ELFT> *File) {
using Elf_Rela = typename ELFT::Rela;
raw_fd_ostream &OS = Out->os();
const ELFFile<ELFT> &EF = File->getELFFile();
>From 09bc3fa2436d33fa99a92c1ee4c5f8596f0dc7ee Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Sat, 30 Nov 2024 15:44:15 -0800
Subject: [PATCH 21/34] fixing formatting that was messed up due to VSC format
on save getting turned on somehow
---
bolt/lib/Passes/IdenticalCodeFolding.cpp | 9 +-
bolt/lib/Rewrite/RewriteInstance.cpp | 178 ++++++++++++++---------
2 files changed, 114 insertions(+), 73 deletions(-)
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index a8d87880926552..2a3b9f218a1322 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -38,9 +38,12 @@ static cl::opt<bool>
ICFUseDFS("icf-dfs", cl::desc("use DFS ordering when using -icf option"),
cl::ReallyHidden, cl::cat(BoltOptCategory));
-static cl::opt<bool> TimeICF("time-icf", cl::desc("time icf steps"),
- cl::ReallyHidden, cl::ZeroOrMore,
- cl::cat(BoltOptCategory));
+static cl::opt<bool>
+TimeICF("time-icf",
+ cl::desc("time icf steps"),
+ cl::ReallyHidden,
+ cl::ZeroOrMore,
+ cl::cat(BoltOptCategory));
} // namespace opts
/// Compare two jump tables in 2 functions. The function relies on consistent
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 473d99c280a56e..128dcf9e6f1ecd 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -63,7 +63,7 @@
#include <optional>
#include <system_error>
-#undef DEBUG_TYPE
+#undef DEBUG_TYPE
#define DEBUG_TYPE "bolt"
using namespace llvm;
@@ -109,15 +109,19 @@ cl::opt<bool> DumpDotAll(
"enable '-print-loops' for color-coded blocks"),
cl::Hidden, cl::cat(BoltCategory));
-static cl::list<std::string> ForceFunctionNames(
- "funcs", cl::CommaSeparated,
- cl::desc("limit optimizations to functions from the list"),
- cl::value_desc("func1,func2,func3,..."), cl::Hidden, cl::cat(BoltCategory));
+static cl::list<std::string>
+ForceFunctionNames("funcs",
+ cl::CommaSeparated,
+ cl::desc("limit optimizations to functions from the list"),
+ cl::value_desc("func1,func2,func3,..."),
+ cl::Hidden,
+ cl::cat(BoltCategory));
static cl::opt<std::string>
- FunctionNamesFile("funcs-file",
- cl::desc("file with list of functions to optimize"),
- cl::Hidden, cl::cat(BoltCategory));
+FunctionNamesFile("funcs-file",
+ cl::desc("file with list of functions to optimize"),
+ cl::Hidden,
+ cl::cat(BoltCategory));
static cl::list<std::string> ForceFunctionNamesNR(
"funcs-no-regex", cl::CommaSeparated,
@@ -129,17 +133,22 @@ static cl::opt<std::string> FunctionNamesFileNR(
cl::desc("file with list of functions to optimize (non-regex)"), cl::Hidden,
cl::cat(BoltCategory));
-cl::opt<bool> KeepTmp("keep-tmp", cl::desc("preserve intermediate .o file"),
- cl::Hidden, cl::cat(BoltCategory));
+cl::opt<bool>
+KeepTmp("keep-tmp",
+ cl::desc("preserve intermediate .o file"),
+ cl::Hidden,
+ cl::cat(BoltCategory));
-static cl::opt<unsigned> LiteThresholdPct(
- "lite-threshold-pct",
- cl::desc(
- "threshold (in percent) for selecting functions to process in lite "
- "mode. Higher threshold means fewer functions to process. E.g "
- "threshold of 90 means only top 10 percent of functions with "
- "profile will be processed."),
- cl::init(0), cl::ZeroOrMore, cl::Hidden, cl::cat(BoltOptCategory));
+static cl::opt<unsigned>
+LiteThresholdPct("lite-threshold-pct",
+ cl::desc("threshold (in percent) for selecting functions to process in lite "
+ "mode. Higher threshold means fewer functions to process. E.g "
+ "threshold of 90 means only top 10 percent of functions with "
+ "profile will be processed."),
+ cl::init(0),
+ cl::ZeroOrMore,
+ cl::Hidden,
+ cl::cat(BoltOptCategory));
static cl::opt<unsigned> LiteThresholdCount(
"lite-threshold-count",
@@ -191,35 +200,43 @@ static cl::opt<cl::boolOrDefault> RelocationMode(
extern cl::opt<std::string> SaveProfile;
-static cl::list<std::string> SkipFunctionNames(
- "skip-funcs", cl::CommaSeparated, cl::desc("list of functions to skip"),
- cl::value_desc("func1,func2,func3,..."), cl::Hidden, cl::cat(BoltCategory));
+static cl::list<std::string>
+SkipFunctionNames("skip-funcs",
+ cl::CommaSeparated,
+ cl::desc("list of functions to skip"),
+ cl::value_desc("func1,func2,func3,..."),
+ cl::Hidden,
+ cl::cat(BoltCategory));
static cl::opt<std::string>
- SkipFunctionNamesFile("skip-funcs-file",
- cl::desc("file with list of functions to skip"),
- cl::Hidden, cl::cat(BoltCategory));
+SkipFunctionNamesFile("skip-funcs-file",
+ cl::desc("file with list of functions to skip"),
+ cl::Hidden,
+ cl::cat(BoltCategory));
-cl::opt<bool> TrapOldCode(
- "trap-old-code",
- cl::desc("insert traps in old function bodies (relocation mode)"),
- cl::Hidden, cl::cat(BoltCategory));
+cl::opt<bool>
+TrapOldCode("trap-old-code",
+ cl::desc("insert traps in old function bodies (relocation mode)"),
+ cl::Hidden,
+ cl::cat(BoltCategory));
static cl::opt<std::string> DWPPathName("dwp",
cl::desc("Path and name to DWP file."),
cl::Hidden, cl::init(""),
cl::cat(BoltCategory));
-static cl::opt<bool> UseGnuStack(
- "use-gnu-stack",
- cl::desc("use GNU_STACK program header for new segment (workaround for "
- "issues with strip/objcopy)"),
- cl::ZeroOrMore, cl::cat(BoltCategory));
+static cl::opt<bool>
+UseGnuStack("use-gnu-stack",
+ cl::desc("use GNU_STACK program header for new segment (workaround for "
+ "issues with strip/objcopy)"),
+ cl::ZeroOrMore,
+ cl::cat(BoltCategory));
static cl::opt<bool>
- SequentialDisassembly("sequential-disassembly",
- cl::desc("performs disassembly sequentially"),
- cl::init(false), cl::cat(BoltOptCategory));
+SequentialDisassembly("sequential-disassembly",
+ cl::desc("performs disassembly sequentially"),
+ cl::init(false),
+ cl::cat(BoltOptCategory));
static cl::opt<bool> WriteBoltInfoSection(
"bolt-info", cl::desc("write bolt info section in the output binary"),
@@ -502,12 +519,12 @@ Error RewriteInstance::discoverStorage() {
for (const ELF64LE::Phdr &Phdr : PHs) {
switch (Phdr.p_type) {
case ELF::PT_LOAD:
- BC->FirstAllocAddress =
- std::min(BC->FirstAllocAddress, static_cast<uint64_t>(Phdr.p_vaddr));
- NextAvailableAddress =
- std::max(NextAvailableAddress, Phdr.p_vaddr + Phdr.p_memsz);
- NextAvailableOffset =
- std::max(NextAvailableOffset, Phdr.p_offset + Phdr.p_filesz);
+ BC->FirstAllocAddress = std::min(BC->FirstAllocAddress,
+ static_cast<uint64_t>(Phdr.p_vaddr));
+ NextAvailableAddress = std::max(NextAvailableAddress,
+ Phdr.p_vaddr + Phdr.p_memsz);
+ NextAvailableOffset = std::max(NextAvailableOffset,
+ Phdr.p_offset + Phdr.p_filesz);
BC->SegmentMapInfo[Phdr.p_vaddr] = SegmentInfo{
Phdr.p_vaddr, Phdr.p_memsz, Phdr.p_offset,
@@ -1507,7 +1524,7 @@ void RewriteInstance::registerFragments() {
}
}
- registerParent:
+registerParent:
// No local parent is found, use global parent function.
if (!ParentAddress)
if (BinaryData *ParentBD = BC->getBinaryDataByName(ParentName))
@@ -2340,12 +2357,14 @@ void RewriteInstance::readDynamicRelocations(const SectionRef &Section,
(void)SymbolAddress;
}
- LLVM_DEBUG(SmallString<16> TypeName; Rel.getTypeName(TypeName);
- dbgs() << "BOLT-DEBUG: dynamic relocation at 0x"
- << Twine::utohexstr(Rel.getOffset()) << " : " << TypeName
- << " : " << SymbolName << " : "
- << Twine::utohexstr(SymbolAddress) << " : + 0x"
- << Twine::utohexstr(Addend) << '\n');
+ LLVM_DEBUG(
+ SmallString<16> TypeName;
+ Rel.getTypeName(TypeName);
+ dbgs() << "BOLT-DEBUG: dynamic relocation at 0x"
+ << Twine::utohexstr(Rel.getOffset()) << " : " << TypeName
+ << " : " << SymbolName << " : " << Twine::utohexstr(SymbolAddress)
+ << " : + 0x" << Twine::utohexstr(Addend) << '\n'
+ );
if (IsJmpRel)
IsJmpRelocation[RType] = true;
@@ -3648,8 +3667,9 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) {
return Section->getOutputAddress();
});
LLVM_DEBUG(dbgs() << "Code sections in the order of output:\n";
- for (const BinarySection *Section : CodeSections) dbgs()
- << Section->getName() << '\n';);
+ for (const BinarySection *Section : CodeSections)
+ dbgs() << Section->getName() << '\n';
+ );
uint64_t PaddingSize = 0; // size of padding required at the end
@@ -3816,9 +3836,13 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) {
const unsigned Flags = BinarySection::getFlags(/*IsReadOnly=*/true,
/*IsText=*/true,
/*IsAllocatable=*/true);
- BinarySection &Section = BC->registerOrUpdateSection(
- getBOLTTextSectionName(), ELF::SHT_PROGBITS, Flags,
- /*Data=*/nullptr, NewTextSectionSize, 16);
+ BinarySection &Section =
+ BC->registerOrUpdateSection(getBOLTTextSectionName(),
+ ELF::SHT_PROGBITS,
+ Flags,
+ /*Data=*/nullptr,
+ NewTextSectionSize,
+ 16);
Section.setOutputAddress(NewTextSectionStartAddress);
Section.setOutputFileOffset(
getFileOffsetForAddress(NewTextSectionStartAddress));
@@ -4069,7 +4093,7 @@ uint64_t appendPadding(raw_pwrite_stream &OS, uint64_t Offset,
return Offset + PaddingSize;
}
-} // namespace
+}
void RewriteInstance::rewriteNoteSections() {
auto ELF64LEFile = cast<ELF64LEObjectFile>(InputFile);
@@ -4189,9 +4213,12 @@ void RewriteInstance::finalizeSectionStringTable(ELFObjectFile<ELFT> *File) {
uint8_t *DataCopy = new uint8_t[SHStrTabSize];
memset(DataCopy, 0, SHStrTabSize);
SHStrTab.write(DataCopy);
- BC->registerOrUpdateNoteSection(".shstrtab", DataCopy, SHStrTabSize,
+ BC->registerOrUpdateNoteSection(".shstrtab",
+ DataCopy,
+ SHStrTabSize,
/*Alignment=*/1,
- /*IsReadOnly=*/true, ELF::SHT_STRTAB);
+ /*IsReadOnly=*/true,
+ ELF::SHT_STRTAB);
}
void RewriteInstance::addBoltInfoSection() {
@@ -4447,9 +4474,11 @@ void RewriteInstance::patchELFSectionHeaderTable(ELFObjectFile<ELFT> *File) {
std::vector<uint32_t> NewSectionIndex;
std::vector<ELFShdrTy> OutputSections =
getOutputSections(File, NewSectionIndex);
- LLVM_DEBUG(dbgs() << "BOLT-DEBUG: old to new section index mapping:\n";
- for (uint64_t I = 0; I < NewSectionIndex.size(); ++I) dbgs()
- << " " << I << " -> " << NewSectionIndex[I] << '\n';);
+ LLVM_DEBUG(
+ dbgs() << "BOLT-DEBUG: old to new section index mapping:\n";
+ for (uint64_t I = 0; I < NewSectionIndex.size(); ++I)
+ dbgs() << " " << I << " -> " << NewSectionIndex[I] << '\n';
+ );
// Align starting address for section header table. There's no architecutal
// need to align this, it is just for pleasant human readability.
@@ -4944,12 +4973,15 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
if (DynSymSection) {
updateELFSymbolTable(
File,
- /*IsDynSym=*/true, *DynSymSection, NewSectionIndex,
+ /*IsDynSym=*/true,
+ *DynSymSection,
+ NewSectionIndex,
[&](size_t Offset, const ELFSymTy &Sym) {
Out->os().pwrite(reinterpret_cast<const char *>(&Sym),
- sizeof(ELFSymTy), DynSymSection->sh_offset + Offset);
+ sizeof(ELFSymTy),
+ DynSymSection->sh_offset + Offset);
},
- [](StringRef) -> size_t { return 0; });
+ [](StringRef) -> size_t { return 0; });;
}
if (opts::RemoveSymtab)
@@ -4979,7 +5011,9 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
NumLocalSymbols = 0;
updateELFSymbolTable(
File,
- /*IsDynSym=*/false, *SymTabSection, NewSectionIndex,
+ /*IsDynSym=*/false,
+ *SymTabSection,
+ NewSectionIndex,
[&](size_t Offset, const ELFSymTy &Sym) {
if (Sym.getBinding() == ELF::STB_LOCAL)
++NumLocalSymbols;
@@ -4993,15 +5027,19 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
return Idx;
});
- BC->registerOrUpdateNoteSection(SecName, copyByteArray(NewContents),
+ BC->registerOrUpdateNoteSection(SecName,
+ copyByteArray(NewContents),
NewContents.size(),
/*Alignment=*/1,
- /*IsReadOnly=*/true, ELF::SHT_SYMTAB);
+ /*IsReadOnly=*/true,
+ ELF::SHT_SYMTAB);
- BC->registerOrUpdateNoteSection(StrSecName, copyByteArray(NewStrTab),
+ BC->registerOrUpdateNoteSection(StrSecName,
+ copyByteArray(NewStrTab),
NewStrTab.size(),
/*Alignment=*/1,
- /*IsReadOnly=*/true, ELF::SHT_STRTAB);
+ /*IsReadOnly=*/true,
+ ELF::SHT_STRTAB);
}
template <typename ELFT>
@@ -5097,8 +5135,8 @@ void RewriteInstance::patchELFAllocatableRelrSection(
}
template <typename ELFT>
-void RewriteInstance::patchELFAllocatableRelaSections(
- ELFObjectFile<ELFT> *File) {
+void
+RewriteInstance::patchELFAllocatableRelaSections(ELFObjectFile<ELFT> *File) {
using Elf_Rela = typename ELFT::Rela;
raw_fd_ostream &OS = Out->os();
const ELFFile<ELFT> &EF = File->getELFFile();
>From 3912b85e0afec1fd4c09a7a1e15e5bcf4f5b7e4f Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Sat, 30 Nov 2024 17:27:22 -0800
Subject: [PATCH 22/34] some cleanup after code changes to address comments
---
bolt/lib/Passes/IdenticalCodeFolding.cpp | 10 +++-------
bolt/lib/Rewrite/BoltDiff.cpp | 2 --
bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test | 3 +--
3 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 2a3b9f218a1322..647b84342a82ca 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -13,7 +13,6 @@
#include "bolt/Passes/IdenticalCodeFolding.h"
#include "bolt/Core/HashUtilities.h"
#include "bolt/Core/ParallelUtilities.h"
-#include "bolt/Rewrite/RewriteInstance.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ThreadPool.h"
@@ -32,7 +31,6 @@ using namespace bolt;
namespace opts {
extern cl::OptionCategory BoltOptCategory;
-extern cl::opt<unsigned> Verbosity;
static cl::opt<bool>
ICFUseDFS("icf-dfs", cl::desc("use DFS ordering when using -icf option"),
@@ -531,12 +529,10 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
ThPool->wait();
LLVM_DEBUG(SinglePass.stopTimer());
- };
- if (BC.getICFLevel() == BinaryContext::ICFLevel::Safe) {
- if (Error Err = markFunctionsUnsafeToFold(BC)) {
+ };
+ if (BC.getICFLevel() == BinaryContext::ICFLevel::Safe)
+ if (Error Err = markFunctionsUnsafeToFold(BC))
return Err;
- }
- }
hashFunctions();
createCongruentBuckets();
diff --git a/bolt/lib/Rewrite/BoltDiff.cpp b/bolt/lib/Rewrite/BoltDiff.cpp
index 5d3021ea845e7e..20fc5aae874d14 100644
--- a/bolt/lib/Rewrite/BoltDiff.cpp
+++ b/bolt/lib/Rewrite/BoltDiff.cpp
@@ -28,8 +28,6 @@ using namespace bolt;
namespace opts {
extern cl::OptionCategory BoltDiffCategory;
extern cl::opt<bool> NeverPrint;
-extern cl::opt<bool> ICF;
-extern cl::opt<bool> SafeICF;
static cl::opt<bool> IgnoreLTOSuffix(
"ignore-lto-suffix",
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index 48b90628dfa141..ba7b9dafdb1a27 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -139,8 +139,7 @@ main:
movabsq $barMulFunc, %rsi
callq _Z7helper2PFKiiiES1_ii
retq
-.Lfunc_end6:
- .size main, .Lfunc_end6-main
+ .size main, .-main
.cfi_endproc
.type FooVar, at object
>From 769cf24b27bdd0ba4d2b54853095ba35778d84a3 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Sat, 30 Nov 2024 17:28:10 -0800
Subject: [PATCH 23/34] clang-format
---
bolt/lib/Passes/IdenticalCodeFolding.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 647b84342a82ca..42ee95f43e5137 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -529,7 +529,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
ThPool->wait();
LLVM_DEBUG(SinglePass.stopTimer());
- };
+ };
if (BC.getICFLevel() == BinaryContext::ICFLevel::Safe)
if (Error Err = markFunctionsUnsafeToFold(BC))
return Err;
>From d4f81c9d491ba7cef3391209929a3fa4cebb93c5 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 3 Dec 2024 18:51:15 -0800
Subject: [PATCH 24/34] removed some redundant tests, re-added on more
targetted one that just checks .rela.data
---
bolt/lib/Rewrite/RewriteInstance.cpp | 2 +-
bolt/test/X86/icf-safe-icp.test | 20 --
bolt/test/X86/icf-safe-process-rela-data.test | 67 +++++
bolt/test/X86/icf-safe-test1-no-cfg.test | 154 ------------
bolt/test/X86/icf-safe-test1.test | 83 ++-----
.../icf-safe-test2GlobalConstPtrNoPic.test | 87 +------
.../X86/icf-safe-test2GlobalConstPtrPic.test | 147 -----------
...safe-test2GlobalConstPtrPicExtFuncRef.test | 229 ------------------
8 files changed, 92 insertions(+), 697 deletions(-)
create mode 100644 bolt/test/X86/icf-safe-process-rela-data.test
delete mode 100644 bolt/test/X86/icf-safe-test1-no-cfg.test
delete mode 100644 bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
delete mode 100644 bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 128dcf9e6f1ecd..6eeb243c591b8a 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -4981,7 +4981,7 @@ void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) {
sizeof(ELFSymTy),
DynSymSection->sh_offset + Offset);
},
- [](StringRef) -> size_t { return 0; });;
+ [](StringRef) -> size_t { return 0; });
}
if (opts::RemoveSymtab)
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index d830bb102fa1e2..19aa0f48383668 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -92,42 +92,33 @@
.globl _Z10createTypei
.type _Z10createTypei, at function
_Z10createTypei:
- .cfi_startproc
callq _Znwm at PLT
leaq _ZTV8Derived2+16(%rip), %rcx
leaq _ZTV8Derived3+16(%rip), %rdx
cmoveq %rcx, %rdx
retq
.size _Z10createTypei, .-_Z10createTypei
- .cfi_endproc
-
.globl _Z10returnFivev
.type _Z10returnFivev, at function
_Z10returnFivev:
- .cfi_startproc
movl $5, %eax
retq
.size _Z10returnFivev, .-_Z10returnFivev
- .cfi_endproc
.globl returnFourOrFiveFunc
.type returnFourOrFiveFunc, at function
returnFourOrFiveFunc:
- .cfi_startproc
xorl %eax, %eax
cmpl $1, %edi
sete %al
xorl $5, %eax
retq
.size returnFourOrFiveFunc, .-returnFourOrFiveFunc
- .cfi_endproc
-
.globl main
.type main, at function
main:
- .cfi_startproc
callq returnFourOrFiveFunc at PLT
callq _Z10returnFivev at PLT
callq _Z10createTypei
@@ -137,56 +128,45 @@ main:
leaq _ZNK8Derived34funcEii(%rip), %rcx
callq _ZNK8Derived34funcEii
.size main, .-main
- .cfi_endproc
.section .text.hot._ZNK8Derived24funcEii,"axG", at progbits,_ZNK8Derived24funcEii,comdat
.weak _ZNK8Derived24funcEii
.type _ZNK8Derived24funcEii, at function
_ZNK8Derived24funcEii: #
- .cfi_startproc
imull %esi, %eax
retq
.size _ZNK8Derived24funcEii, .-_ZNK8Derived24funcEii
- .cfi_endproc
.section .text.unlikely._ZN8Derived2D0Ev,"axG", at progbits,_ZN8Derived2D0Ev,comdat
.weak _ZN8Derived2D0Ev
.type _ZN8Derived2D0Ev, at function
_ZN8Derived2D0Ev:
- .cfi_startproc
movl $16, %esi
jmp _ZdlPvm at PLT
.size _ZN8Derived2D0Ev, .-_ZN8Derived2D0Ev
- .cfi_endproc
.section .text.hot._ZNK8Derived34funcEii,"axG", at progbits,_ZNK8Derived34funcEii,comdat
.weak _ZNK8Derived34funcEii
.type _ZNK8Derived34funcEii, at function
_ZNK8Derived34funcEii:
- .cfi_startproc
imull %esi, %eax
retq
.size _ZNK8Derived34funcEii, .-_ZNK8Derived34funcEii
- .cfi_endproc
.section .text.unlikely._ZN4BaseD2Ev,"axG", at progbits,_ZN4BaseD2Ev,comdat
.weak _ZN4BaseD2Ev
.type _ZN4BaseD2Ev, at function
_ZN4BaseD2Ev:
- .cfi_startproc
retq
.size _ZN4BaseD2Ev, .-_ZN4BaseD2Ev
- .cfi_endproc
.section .text.unlikely._ZN8Derived3D0Ev,"axG", at progbits,_ZN8Derived3D0Ev,comdat
.weak _ZN8Derived3D0Ev
.type _ZN8Derived3D0Ev, at function
_ZN8Derived3D0Ev:
- .cfi_startproc
movl $16, %esi
jmp _ZdlPvm at PLT
.size _ZN8Derived3D0Ev, .-_ZN8Derived3D0Ev
- .cfi_endproc
.type _ZTV8Derived2, at object
.section .data.rel.ro._ZTV8Derived2,"awG", at progbits,_ZTV8Derived2,comdat
diff --git a/bolt/test/X86/icf-safe-process-rela-data.test b/bolt/test/X86/icf-safe-process-rela-data.test
new file mode 100644
index 00000000000000..9d6d82a93833a5
--- /dev/null
+++ b/bolt/test/X86/icf-safe-process-rela-data.test
@@ -0,0 +1,67 @@
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
+## This checks when only reference to a function is in .rela.data section.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q -no-pie
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+# ICFCHECK: ICF iteration 1
+# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
+
+# SAFEICFCHECK: skipping function fooAddFunc
+# SAFEICFCHECK-NEXT: skipping function barAddFunc
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: ===---------
+
+## clang++ main.cpp
+## Other functions removed for brevity.
+## int main(int argc, char **argv) {
+## const static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
+## const int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
+## helper2(funcGlobalBarAdd, funcGlobalFooAdd, 3, 4)
+## }
+## Extra assembly removed.
+
+ .text
+ .file "main.cpp"
+ .globl fooAddFunc
+ .type fooAddFunc, at function
+fooAddFunc:
+ addl -8(%rbp), %eax
+ retq
+ .size fooAddFunc, .-fooAddFunc
+
+ .globl barAddFunc
+ .type barAddFunc, at function
+barAddFunc:
+ addl -8(%rbp), %eax
+ retq
+ .size barAddFunc, .-barAddFunc
+
+ .globl helperFunc
+ .type helperFunc, at function
+helperFunc:
+ retq
+ .size helperFunc, .-helperFunc
+
+ .globl main
+ .type main, at function
+main:
+ movq localStaticVarBarAdd, %rdi
+ movq localStaticVarFooAdd, %rsi
+ callq helperFunc
+ retq
+ .size main, .-main
+
+ .type localStaticVarBarAdd, at object # @localStaticVarBarAdd
+ .data
+localStaticVarBarAdd:
+ .quad barAddFunc
+ .size localStaticVarBarAdd, 8
+
+ .type localStaticVarFooAdd, at object # @localStaticVarFooAdd
+localStaticVarFooAdd:
+ .quad fooAddFunc
+ .size localStaticVarFooAdd, 8
diff --git a/bolt/test/X86/icf-safe-test1-no-cfg.test b/bolt/test/X86/icf-safe-test1-no-cfg.test
deleted file mode 100644
index fab405abb81e7c..00000000000000
--- a/bolt/test/X86/icf-safe-test1-no-cfg.test
+++ /dev/null
@@ -1,154 +0,0 @@
-## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
-## Tests disassemble path for a function.
-
-# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
-# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf=all -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf --skip-funcs=helper1Func,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
-# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK-NEXT: ===---------
-
-## clang++ -c main.cpp -o main.o
-## extern int FooVar;
-## extern int BarVar;
-## [[clang::noinline]]
-## int fooSub(int a, int b) {
-## return a - b;
-## }
-## [[clang::noinline]]
-## int barSub(int a, int b) {
-## return a - b;
-## }
-## [[clang::noinline]]
-## int fooMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## int barMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## int fooAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## int barAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## int helper1(int (*func)(int, int), int a, int b) {
-## if (func == barAdd)
-## return 1;
-## return func(a, b) - 4;
-## }
-## [[clang::noinline]]
-## int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-## if (func == func2)
-## return 2;
-## return func(a, b) + func2(a, b);
-## }
-## int main(int arßgc, char **argv) {
-## int temp = helper1(barAdd, FooVar, BarVar) +
-## helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-## return temp;
-## }
- .globl fooSubFunc
- .type fooSubFunc, at function
-fooSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
- .size fooSubFunc, .-fooSubFunc
- .cfi_endproc
-
- .globl barSubFunc
- .type barSubFunc, at function
-barSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
- .size barSubFunc, .-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size fooMulFunc, .-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size barMulFunc, .-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size fooAddFunc, .-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size barAddFunc, .-barAddFunc
- .cfi_endproc
-
- .globl helper1Func
- .type helper1Func, at function
-helper1Func:
- .cfi_startproc
- leaq barAddFunc(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
- .size helper1Func, .-helper1Func
- .cfi_endproc
-
- .globl helper2Func
- .type helper2Func, at function
-helper2Func:
- .cfi_startproc
- # Operates on registers.
- retq
- .size helper2Func, .-helper2Func
- .cfi_endproc
-
- .globl main
- .type main, at function
-main:
- .cfi_startproc
- leaq barAddFunc(%rip), %rdi
- callq helper1Func
- leaq fooMulFunc(%rip), %rdi
- leaq barMulFunc(%rip), %rsi
- callq helper2Func
- callq fooSubFunc
- callq barSubFunc
- callq fooAddFunc
- retq
- .size main, .-main
- .cfi_endproc
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index e0392dc72bd6f8..2f199dcb5261e1 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -1,23 +1,30 @@
## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
+## It invokes BOLT twice first testing CFG path, and second when function has to be disassembled.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf \
+# RUN: -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf \
+# RUN: -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf \
+# RUN: --skip-funcs=helper1Func,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECKNOCFG %s
# ICFCHECK: ICF iteration 1
# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
+# SAFEICFCHECK: skipping function barAddFunc
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
# SAFEICFCHECK-NEXT: ===---------
+# SAFEICFCHECKNOCFG: skipping function barAddFunc
+# SAFEICFCHECKNOCFG-NEXT: ICF iteration 1
+# SAFEICFCHECKNOCFG-NEXT: folding barSubFunc into fooSubFunc
+# SAFEICFCHECKNOCFG-NEXT: ===---------
+
## clang++ -c main.cpp -o main.o
## extern int FooVar;
## extern int BarVar;
@@ -30,14 +37,6 @@
## return a - b;
## }
## [[clang::noinline]]
-## int fooMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## int barMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
## int fooAdd(int a, int b) {
## return a + b;
## }
@@ -45,109 +44,55 @@
## int barAdd(int a, int b) {
## return a + b;
## }
-## [[clang::noinline]]
-## int helper1(int (*func)(int, int), int a, int b) {
-## if (func == barAdd)
-## return 1;
-## return func(a, b) - 4;
-## }
-## [[clang::noinline]]
-## int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-## if (func == func2)
-## return 2;
-## return func(a, b) + func2(a, b);
-## }
## int main(int argc, char **argv) {
## int temp = helper1(barAdd, FooVar, BarVar) +
-## helper2(fooMul, barMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
+## fooSub(FooVar, BarVar) +
## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
## return temp;
## }
.globl fooSubFunc
.type fooSubFunc, at function
fooSubFunc:
- .cfi_startproc
subl -8(%rbp), %eax
retq
.size fooSubFunc, .-fooSubFunc
- .cfi_endproc
.globl barSubFunc
.type barSubFunc, at function
barSubFunc:
- .cfi_startproc
subl -8(%rbp), %eax
retq
.size barSubFunc, .-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size fooMulFunc, .-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size barMulFunc, .-barMulFunc
- .cfi_endproc
.globl fooAddFunc
.type fooAddFunc, at function
fooAddFunc:
- .cfi_startproc
addl -8(%rbp), %eax
retq
.size fooAddFunc, .-fooAddFunc
- .cfi_endproc
.globl barAddFunc
.type barAddFunc, at function
barAddFunc:
- .cfi_startproc
addl -8(%rbp), %eax
retq
.size barAddFunc, .-barAddFunc
- .cfi_endproc
.globl helper1Func
.type helper1Func, at function
helper1Func:
- .cfi_startproc
leaq barAddFunc(%rip), %rax
cmpq %rax, -16(%rbp)
retq
.size helper1Func, .-helper1Func
- .cfi_endproc
-
- .globl helper2Func
- .type helper2Func, at function
-helper2Func:
- .cfi_startproc
- # Operates on registers.
- retq
- .size helper2Func, .-helper2Func
- .cfi_endproc
.globl main
.type main, at function
main:
- .cfi_startproc
leaq barAddFunc(%rip), %rdi
callq helper1Func
- leaq fooMulFunc(%rip), %rdi
- leaq barMulFunc(%rip), %rsi
- callq helper2Func
callq fooSubFunc
callq barSubFunc
callq fooAddFunc
retq
.size main, .-main
- .cfi_endproc
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index ba7b9dafdb1a27..b00ad8b7067e3d 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -17,130 +17,63 @@
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: ===---------
-## clang++ main.cpp -c -o
+## clang++ main.cpp -c -o -fno-PIC
## Similar code gets generated for external reference function.
-## #define MY_CONST const
-## extern int FooVar;
-## extern int BarVar;
-## [[clang::noinline]]
-## MY_CONST int fooMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## MY_CONST int barMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## MY_CONST int fooAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## MY_CONST int barAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-## if (func == barAdd)
-## return 1;
-## return func(a, b) - 4;
-## }
-## [[clang::noinline]]
-## MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-## if (func == func2)
-## return 2;
-## return func(a, b) + func2(a, b);
-## }
-## MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
-## MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
+## Other functions removed for brevity.
+## const static int (*const funcGlobalBarAdd)(int, int) = barAdd;
+## const int (*const funcGlobalBarMul)(int, int) = barMul;
## int main(int argc, char **argv) {
-## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-## helper2(fooMul, funcGlobalBarMul, FooVar, BarVar)
-## fooAdd(FooVar, BarVar);
-## MY_PRINTF("val: %d", temp);
+## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar)
## return temp;
## }
-## clang++ helper.cpp -c -o
-## #define MY_CONST const
-## int FooVar = 1;
-## int BarVar = 2;
## Manually modified to remove "extra" assembly.
.globl fooMulFunc
.type fooMulFunc, at function
fooMulFunc:
- .cfi_startproc
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.size fooMulFunc, .-fooMulFunc
- .cfi_endproc
.globl barMulFunc
.type barMulFunc, at function
barMulFunc:
- .cfi_startproc
imull -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.size barMulFunc, .-barMulFunc
- .cfi_endproc
.globl fooAddFunc
.type fooAddFunc, at function
fooAddFunc:
- .cfi_startproc
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.size fooAddFunc, .-fooAddFunc
- .cfi_endproc
.globl barAddFunc
.type barAddFunc, at function
barAddFunc:
- .cfi_startproc
addl -8(%rbp), %eax
- popq %rbp
- .cfi_def_cfa %rsp, 8
retq
.size barAddFunc, .-barAddFunc
- .cfi_endproc
- .globl _Z7helper1PFKiiiEii
- .type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii:
- .cfi_startproc
+ .globl helperFunc
+ .type helperFunc, at function
+helperFunc:
movabsq $barAddFunc, %rax
cmpq %rax, -16(%rbp)
retq
- .size _Z7helper1PFKiiiEii, .-_Z7helper1PFKiiiEii
- .cfi_endproc
-
- .globl _Z7helper2PFKiiiES1_ii
- .type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii:
- .cfi_startproc
- # no direct function references.
- retq
- .size _Z7helper2PFKiiiES1_ii, .-_Z7helper2PFKiiiES1_ii
- .cfi_endproc
+ .size helperFunc, .-helperFunc
.globl main
.type main, at function
main:
- .cfi_startproc
movl FooVar, %esi
movl BarVar, %edx
movabsq $barAddFunc, %rdi
- callq _Z7helper1PFKiiiEii
+ callq helperFunc
movabsq $fooMulFunc, %rdi
movabsq $barMulFunc, %rsi
- callq _Z7helper2PFKiiiES1_ii
retq
.size main, .-main
- .cfi_endproc
.type FooVar, at object
.data
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
deleted file mode 100644
index 6dbc8039ab48d2..00000000000000
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPic.test
+++ /dev/null
@@ -1,147 +0,0 @@
-## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
-## This checks global const function pointer in -fpic mode is handled correctly.
-
-# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
-# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
-# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: ===---------
-
-## clang++ main.cpp -c -o
-## #define MY_CONST const
-## extern int FooVar;
-## extern int BarVar;
-## [[clang::noinline]]
-## MY_CONST int fooMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## MY_CONST int barMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## MY_CONST int fooAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## MY_CONST int barAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-## if (func == barAdd)
-## return 1;
-## return func(a, b) - 4;
-## }
-## [[clang::noinline]]
-## MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-## if (func == func2)
-## return 2;
-## return func(a, b) + func2(a, b);
-## }
-## MY_CONST static int (*MY_CONST funcGlobalBarAdd)(int, int) = barAdd;
-## MY_CONST int (*MY_CONST funcGlobalBarMul)(int, int) = barMul;
-## int main(int argc, char **argv) {
-## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-## helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) +
-## fooAdd(FooVar, BarVar);
-## MY_PRINTF("val: %d", temp);
-## return temp;
-## }
-## clang++ helper.cpp -c -o
-## #define MY_CONST const
-## int FooVar = 1;
-## int BarVar = 2;
-## Manually modified to remove "extra" assembly.
- .globl fooMulFunc
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size fooMulFunc, .-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size barMulFunc, .-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size fooAddFunc, .-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size barAddFunc, .-barAddFunc
- .cfi_endproc
-
- .globl _Z7helper1PFKiiiEii
- .type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii:
- .cfi_startproc
- leaq barAddFunc(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
- .size _Z7helper1PFKiiiEii, .-_Z7helper1PFKiiiEii
- .cfi_endproc
-
- .globl _Z7helper2PFKiiiES1_ii
- .type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii:
- .cfi_startproc
- # Operates on registers.
- retq
- .size _Z7helper2PFKiiiES1_ii, .-_Z7helper2PFKiiiES1_ii
- .cfi_endproc
-
- .globl main
- .type main, at function
-main:
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- leaq barAddFunc(%rip), %rdi
- callq _Z7helper1PFKiiiEii
- leaq fooMulFunc(%rip), %rdi
- leaq barMulFunc(%rip), %rsi
- callq _Z7helper2PFKiiiES1_ii
- retq
- .size main, .-main
- .cfi_endproc
-
- .type FooVar, at object
- .data
- .globl FooVar
-FooVar:
- .long 1
- .size FooVar, 4
-
- .type BarVar, at object
- .globl BarVar
-BarVar:
- .long 2
- .size BarVar, 4
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
deleted file mode 100644
index ca2f82912450b9..00000000000000
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrPicExtFuncRef.test
+++ /dev/null
@@ -1,229 +0,0 @@
-## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
-## This checks global const function pointer with external function reference in -fpic mode is handled correctly.
-
-# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
-# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding _Z12barAddHdlperii into fooAddFunc
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
-# SAFEICFCHECK-NEXT: skipping function _Z12barAddHdlperii
-# SAFEICFCHECK-NEXT: skipping function fooGlobalFuncHelperFunc
-# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK-NEXT: ===---------
-
-
-## clang++ main.cpp -c -o
-## #define MY_CONST const
-## extern int FooVar;
-## extern int BarVar;
-## [[clang::noinline]]
-## MY_CONST int fooSub(int a, int b) {
-## return a - b;
-## }
-## [[clang::noinline]]
-## MY_CONST int barSub(int a, int b) {
-## return a - b;
-## }
-## [[clang::noinline]]
-## MY_CONST int fooMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## MY_CONST int barMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## MY_CONST int fooAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## MY_CONST int barAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## MY_CONST int helper1(MY_CONST int (*func)(int, int), int a, int b) {
-## if (func == barAdd)
-## return 1;
-## return func(a, b) - 4;
-## }
-## [[clang::noinline]]
-## MY_CONST int helper2(MY_CONST int (*func)(int, int), MY_CONST int (*func2)(int, int), int a, int b) {
-## if (func == func2)
-## return 2;
-## return func(a, b) + func2(a, b);
-## }
-## extern MY_CONST int barAddHdlper(int a, int b);
-## extern MY_CONST int fooGlobalFuncHelper(int a, int b);
-## MY_CONST static int (*const funcGlobalBarAdd)(int, int) = barAddHdlper;
-## MY_CONST int (* const funcGlobalBarMul)(int, int) = fooGlobalFuncHelper;
-## int main(int argc, char **argv) {
-## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-## helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-## MY_PRINTF("val: %d", temp);
-## return temp;
-## }
-## clang++ helper.cpp -c -o
-## #define MY_CONST const
-## int FooVar = 1;
-## int BarVar = 2;
-## [[clang::noinline]]
-## MY_CONST int barAddHdlper(int a, int b) {
-## return a + b;
-## }
-##
-## MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-## MY_CONST int fooGlobalFuncHelper(int a, int b) {
-## return 5 + funcGlobalBarMulExt(a, b);
-## }
-## clang++ helper.cpp -c -o
-## #define MY_CONST const
-## int FooVar = 1;
-## int BarVar = 2;
-## [[clang::noinline]]
-## MY_CONST int barAddHdlper(int a, int b) {
-## return a + b;
-## }
-##
-## MY_CONST int (*const funcGlobalBarMulExt)(int, int) = barAddHdlper;
-## MY_CONST int fooGlobalFuncHelper(int a, int b) {
-## return 5 + funcGlobalBarMulExt(a, b);
-## }
- .globl fooSubFunc
- .type fooSubFunc, at function
-fooSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
- .size fooSubFunc, .-fooSubFunc
- .cfi_endproc
-
- .globl barSubFunc
- .type barSubFunc, at function
-barSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
-.Lfunc_end1:
- .size barSubFunc, .-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size fooMulFunc, .-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size barMulFunc, .-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size fooAddFunc, .-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size barAddFunc, .-barAddFunc
- .cfi_endproc
-
- .globl _Z7helper1PFKiiiEii
- .type _Z7helper1PFKiiiEii, at function
-_Z7helper1PFKiiiEii:
- .cfi_startproc
- leaq barAddFunc(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
- .size _Z7helper1PFKiiiEii, .-_Z7helper1PFKiiiEii
- .cfi_endproc
-
- .globl _Z7helper2PFKiiiES1_ii
- .type _Z7helper2PFKiiiES1_ii, at function
-_Z7helper2PFKiiiES1_ii:
- .cfi_startproc
- # Operates on registers.
- retq
- .size _Z7helper2PFKiiiES1_ii, .-_Z7helper2PFKiiiES1_ii
- .cfi_endproc
-
- .globl main
- .type main, at function
-main:
- .cfi_startproc
- movq FooVar at GOTPCREL(%rip), %rax
- movq BarVar at GOTPCREL(%rip), %rax
- movq _Z12barAddHdlperii at GOTPCREL(%rip), %rdi
- callq _Z7helper1PFKiiiEii
- leaq fooMulFunc(%rip), %rdi
- movq fooGlobalFuncHelperFunc at GOTPCREL(%rip), %rsi
- callq _Z7helper2PFKiiiES1_ii
- callq fooSubFunc
- callq barSubFunc
- callq fooAddFunc
- retq
- .size main, .-main
- .cfi_endproc
-
- .globl _Z12barAddHdlperii
- .type _Z12barAddHdlperii, at function
-_Z12barAddHdlperii:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size _Z12barAddHdlperii, .-_Z12barAddHdlperii
- .cfi_endproc
-
- .globl fooGlobalFuncHelperFunc
- .type fooGlobalFuncHelperFunc, at function
-fooGlobalFuncHelperFunc:
- .cfi_startproc
- callq _Z12barAddHdlperii
- retq
- .size fooGlobalFuncHelperFunc, .-fooGlobalFuncHelperFunc
- .cfi_endproc
-
- .type FooVar, at object
- .data
- .globl FooVar
-FooVar:
- .long 1
- .size FooVar, 4
-
- .type BarVar, at object
- .globl BarVar
-BarVar:
- .long 2
- .size BarVar, 4
-
- .type .L.str, at object
- .section .rodata.str1.1,"aMS", at progbits,1
-.L.str:
- .asciz "val: %d\n"
- .size .L.str, 9
>From ec54f246a59df2f5083bae08cfa0ad0b68cacafc Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 3 Dec 2024 18:52:52 -0800
Subject: [PATCH 25/34] removed one more test I missed
---
bolt/test/X86/icf-safe-test2GlobalVarO0.test | 182 -------------------
1 file changed, 182 deletions(-)
delete mode 100644 bolt/test/X86/icf-safe-test2GlobalVarO0.test
diff --git a/bolt/test/X86/icf-safe-test2GlobalVarO0.test b/bolt/test/X86/icf-safe-test2GlobalVarO0.test
deleted file mode 100644
index 7dc10a42f0847b..00000000000000
--- a/bolt/test/X86/icf-safe-test2GlobalVarO0.test
+++ /dev/null
@@ -1,182 +0,0 @@
-## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
-
-# REQUIRES: system-linux
-# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
-# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
-# RUN: llvm-bolt --no-threads %t.exe --icf -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
-# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-
-# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc
-# ICFCHECK-NEXT: folding barMulFunc into fooMulFunc
-# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-
-# SAFEICFCHECK: skipping function fooMulFunc
-# SAFEICFCHECK-NEXT: skipping function barMulFunc
-# SAFEICFCHECK-NEXT: skipping function barAddFunc
-# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc
-# SAFEICFCHECK-NEXT: ===---------
-
-
-## clang++ -c main.cpp -o main.o
-# Similar assembly gets generated with -O3 and local function pointers.
-## extern int FooVar;
-## extern int BarVar;
-## [[clang::noinline]]
-## int fooSub(int a, int b) {
-## return a - b;
-## }
-## [[clang::noinline]]
-## int barSub(int a, int b) {
-## return a - b;
-## }
-## [[clang::noinline]]
-## int fooMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## int barMul(int a, int b) {
-## return a * b;
-## }
-## [[clang::noinline]]
-## int fooAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## int barAdd(int a, int b) {
-## return a + b;
-## }
-## [[clang::noinline]]
-## int helper1(int (*func)(int, int), int a, int b) {
-## if (func == barAdd)
-## return 1;
-## return func(a, b) - 4;
-## }
-## [[clang::noinline]]
-## int helper2(int (*func)(int, int), int (*func2)(int, int), int a, int b) {
-## if (func == func2)
-## return 2;
-## return func(a, b) + func2(a, b);
-## }
-## static int (*funcGlobalBarAdd)(int, int) = barAdd;
-## int (*funcGlobalBarMul)(int, int) = barMul;
-## int main(int argc, char **argv) {
-## int temp = helper1(funcGlobalBarAdd, FooVar, BarVar) +
-## helper2(fooMul, funcGlobalBarMul, FooVar, BarVar) + fooSub(FooVar, BarVar) +
-## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar);
-## return temp;
-## }
-## Manually modified to remove "extra" assembly.
- .globl fooSubFunc
- .type fooSubFunc, at function
-fooSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
- .size fooSubFunc, .-fooSubFunc
- .cfi_endproc
-
- .globl barSubFunc
- .type barSubFunc, at function
-barSubFunc:
- .cfi_startproc
- subl -8(%rbp), %eax
- retq
- .size barSubFunc, .-barSubFunc
- .cfi_endproc
-
- .globl fooMulFunc
- .type fooMulFunc, at function
-fooMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size fooMulFunc, .-fooMulFunc
- .cfi_endproc
-
- .globl barMulFunc
- .type barMulFunc, at function
-barMulFunc:
- .cfi_startproc
- imull -8(%rbp), %eax
- retq
- .size barMulFunc, .-barMulFunc
- .cfi_endproc
-
- .globl fooAddFunc
- .type fooAddFunc, at function
-fooAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size fooAddFunc, .-fooAddFunc
- .cfi_endproc
-
- .globl barAddFunc
- .type barAddFunc, at function
-barAddFunc:
- .cfi_startproc
- addl -8(%rbp), %eax
- retq
- .size barAddFunc, .-barAddFunc
- .cfi_endproc
-
- .globl helper1Func
- .type helper1Func, at function
-helper1Func:
- .cfi_startproc
- leaq barAddFunc(%rip), %rax
- cmpq %rax, -16(%rbp)
- retq
- .size helper1Func, .-helper1Func
- .cfi_endproc
-
- .globl helper2Func
- .type helper2Func, at function
-helper2Func:
- .cfi_startproc
- # Operates on registers.
- retq
- .size helper2Func, .-helper2Func
- .cfi_endproc
-
- .globl main
- .type main, at function
-main:
- .cfi_startproc
- movq _ZL16funcGlobalBarAdd(%rip), %rdi
- callq helper1Func
- movq funcGlobalBarMul(%rip), %rsi
- leaq fooMulFunc(%rip), %rdi
- callq helper2Func
- callq fooSubFunc
- callq barSubFunc
- callq fooAddFunc
- retq
- .size main, .-main
- .cfi_endproc
-
- .globl fooGlobalFuncHelperFunc
- .type fooGlobalFuncHelperFunc, at function
-fooGlobalFuncHelperFunc:
- .cfi_startproc
-# %bb.0:
- movl $5, %eax
- retq
- .size fooGlobalFuncHelperFunc, .-fooGlobalFuncHelperFunc
- .cfi_endproc
-
- .type funcGlobalBarMul, at object
- .data
- .globl funcGlobalBarMul
- .p2align 3, 0x0
-funcGlobalBarMul:
- .quad barMulFunc
- .size funcGlobalBarMul, 8
-
- .type _ZL16funcGlobalBarAdd, at object
- .p2align 3, 0x0
-_ZL16funcGlobalBarAdd:
- .quad barAddFunc
- .size _ZL16funcGlobalBarAdd, 8
>From 13bcc2242c109f3d50bcbd565e28186fd336ca46 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Thu, 5 Dec 2024 14:15:53 -0800
Subject: [PATCH 26/34] Changed so that general data sections are processed.
Moved ICF option to ICF Pass. Renambed flag in BC
---
bolt/include/bolt/Core/BinaryContext.h | 10 ---
bolt/include/bolt/Core/BinaryFunction.h | 6 +-
.../bolt/Passes/IdenticalCodeFolding.h | 10 ++-
bolt/lib/Core/BinaryContext.cpp | 23 ++-----
bolt/lib/Passes/IdenticalCodeFolding.cpp | 63 ++++++++++++++++---
bolt/lib/Rewrite/BinaryPassManager.cpp | 5 +-
bolt/lib/Rewrite/BoltDiff.cpp | 3 +-
bolt/lib/Rewrite/RewriteInstance.cpp | 4 +-
bolt/test/X86/icf-safe-icp.test | 4 +-
9 files changed, 81 insertions(+), 47 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 0ea8276f4fe886..9b43d30c7f18bd 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -276,11 +276,6 @@ class BinaryContext {
void deregisterSectionName(const BinarySection &Section);
public:
- enum class ICFLevel {
- None, // No ICF. (Default)
- Safe, // Safe ICF for all sections.
- All, // Aggressive ICF for code.
- };
static Expected<std::unique_ptr<BinaryContext>>
createBinaryContext(Triple TheTriple, StringRef InputFileName,
SubtargetFeatures *Features, bool IsPIC,
@@ -665,9 +660,6 @@ class BinaryContext {
std::unique_ptr<MCAsmBackend> MAB;
- /// ICF level to use for this binary.
- ICFLevel CurrICFLevel{ICFLevel::None};
-
/// Allows BOLT to print to log whenever it is necessary (with or without
/// const references)
mutable JournalingStreams Logger;
@@ -1487,8 +1479,6 @@ class BinaryContext {
return *IOAddressMap;
}
- ICFLevel getICFLevel() const { return CurrICFLevel; }
-
raw_ostream &outs() const { return Logger.Out; }
raw_ostream &errs() const { return Logger.Err; }
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index f05ea40cfb1334..aa07a206ee6920 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -429,7 +429,7 @@ class BinaryFunction {
uint32_t Index{-1U};
/// Indicates if the function is safe to fold.
- bool IsSafeToICF{true};
+ bool HasAddressTaken{false};
/// Get basic block index assuming it belongs to this function.
unsigned getIndex(const BinaryBasicBlock *BB) const {
@@ -821,10 +821,10 @@ class BinaryFunction {
}
/// Indicates if the function is safe to fold.
- bool isSafeToICF() const { return IsSafeToICF; }
+ bool hasAddressTaken() const { return HasAddressTaken; }
/// Sets the function is not safe to fold.
- void setUnsafeICF() { IsSafeToICF = false; }
+ void setHasAddressTaken(bool Hat) { HasAddressTaken = Hat; }
/// Returns the raw binary encoding of this function.
ErrorOr<ArrayRef<uint8_t>> getData() const;
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index f40d856bfc7b72..aaea4a6a0469c0 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -27,12 +27,17 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
return false;
if (BF.hasSDTMarker())
return false;
- if (!BF.isSafeToICF())
+ if (BF.hasAddressTaken())
return false;
return BinaryFunctionPass::shouldOptimize(BF);
}
public:
+ enum class ICFLevel {
+ None, // No ICF. (Default)
+ Safe, // Safe ICF for all sections.
+ All, // Aggressive ICF for code.
+ };
explicit IdenticalCodeFolding(const cl::opt<bool> &PrintPass)
: BinaryFunctionPass(PrintPass) {}
@@ -46,7 +51,8 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
/// Process relocations in the .data section to identify function
/// references.
Error processDataRelocations(BinaryContext &BC,
- const SectionRef &SecRefRelData);
+ const SectionRef &SecRefRelData,
+ const bool HasAddressTaken);
};
} // namespace bolt
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index caf09c0c18ead0..7e3f032bea00e5 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -75,19 +75,6 @@ cl::opt<std::string> CompDirOverride(
"location, which is used with DW_AT_dwo_name to construct a path "
"to *.dwo files."),
cl::Hidden, cl::init(""), cl::cat(BoltCategory));
-
-cl::opt<bolt::BinaryContext::ICFLevel>
- ICF("icf", cl::desc("fold functions with identical code"),
- cl::init(bolt::BinaryContext::ICFLevel::None),
- cl::values(clEnumValN(bolt::BinaryContext::ICFLevel::All, "all",
- "Enable identical code folding"),
- clEnumValN(bolt::BinaryContext::ICFLevel::All, "",
- "Enable identical code folding"),
- clEnumValN(bolt::BinaryContext::ICFLevel::None, "none",
- "Disable identical code folding (default)"),
- clEnumValN(bolt::BinaryContext::ICFLevel::Safe, "safe",
- "Enable safe identical code folding")),
- cl::ZeroOrMore, cl::ValueOptional, cl::cat(BoltOptCategory));
} // namespace opts
namespace llvm {
@@ -157,7 +144,6 @@ BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
Logger(Logger), InitialDynoStats(isAArch64()) {
RegularPageSize = isAArch64() ? RegularPageSizeAArch64 : RegularPageSizeX86;
PageAlign = opts::NoHugePages ? RegularPageSize : HugePageSize;
- CurrICFLevel = opts::ICF;
}
BinaryContext::~BinaryContext() {
@@ -1962,13 +1948,12 @@ static void printDebugInfo(raw_ostream &OS, const MCInst &Instruction,
/// Skip instructions that do not potentially manipulate or compare function
/// addresses.
static bool skipInstruction(const MCInst &Inst, const BinaryContext &BC) {
- const bool IsX86 = BC.isX86();
return (BC.MIB->isPseudo(Inst) || BC.MIB->isUnconditionalBranch(Inst) ||
- (IsX86 && BC.MIB->isConditionalBranch(Inst)) ||
- BC.MIB->isCall(Inst) || BC.MIB->isBranch(Inst));
+ BC.MIB->isConditionalBranch(Inst) || BC.MIB->isCall(Inst) ||
+ BC.MIB->isBranch(Inst));
}
void BinaryContext::processInstructionForFuncReferences(const MCInst &Inst) {
- if (CurrICFLevel != ICFLevel::Safe || skipInstruction(Inst, *this))
+ if (skipInstruction(Inst, *this))
return;
for (const MCOperand &Op : MCPlus::primeOperands(Inst)) {
if (!Op.isExpr())
@@ -1977,7 +1962,7 @@ void BinaryContext::processInstructionForFuncReferences(const MCInst &Inst) {
if (Expr.getKind() == MCExpr::SymbolRef) {
const MCSymbol &Symbol = cast<MCSymbolRefExpr>(Expr).getSymbol();
if (BinaryFunction *BF = getFunctionForSymbol(&Symbol))
- BF->setUnsafeICF();
+ BF->setHasAddressTaken(true);
}
}
}
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 42ee95f43e5137..3938fdc853d9ed 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -42,6 +42,19 @@ TimeICF("time-icf",
cl::ReallyHidden,
cl::ZeroOrMore,
cl::cat(BoltOptCategory));
+
+cl::opt<bolt::IdenticalCodeFolding::ICFLevel> ICF(
+ "icf", cl::desc("fold functions with identical code"),
+ cl::init(bolt::IdenticalCodeFolding::ICFLevel::None),
+ cl::values(clEnumValN(bolt::IdenticalCodeFolding::ICFLevel::All, "all",
+ "Enable identical code folding"),
+ clEnumValN(bolt::IdenticalCodeFolding::ICFLevel::All, "",
+ "Enable identical code folding"),
+ clEnumValN(bolt::IdenticalCodeFolding::ICFLevel::None, "none",
+ "Disable identical code folding (default)"),
+ clEnumValN(bolt::IdenticalCodeFolding::ICFLevel::Safe, "safe",
+ "Enable safe identical code folding")),
+ cl::ZeroOrMore, cl::ValueOptional, cl::cat(BoltOptCategory));
} // namespace opts
/// Compare two jump tables in 2 functions. The function relies on consistent
@@ -342,7 +355,8 @@ namespace llvm {
namespace bolt {
Error IdenticalCodeFolding::processDataRelocations(
- BinaryContext &BC, const SectionRef &SecRefRelData) {
+ BinaryContext &BC, const SectionRef &SecRefRelData,
+ const bool HasAddressTaken) {
for (const RelocationRef &Rel : SecRefRelData.relocations()) {
symbol_iterator SymbolIter = Rel.getSymbol();
const ObjectFile *OwningObj = Rel.getObject();
@@ -358,16 +372,49 @@ Error IdenticalCodeFolding::processDataRelocations(
BinaryFunction *BF = BC.getBinaryFunctionAtAddress(SymbolAddress + Addend);
if (!BF)
continue;
- BF->setUnsafeICF();
+ BF->setHasAddressTaken(HasAddressTaken);
}
return Error::success();
}
Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
- ErrorOr<BinarySection &> SecRelData = BC.getUniqueSectionByName(".rela.data");
- if (SecRelData) {
- SectionRef SecRefRelData = SecRelData->getSectionRef();
- Error ErrorStatus = processDataRelocations(BC, SecRefRelData);
+ for (const auto &Sec : BC.sections()) {
+ if (!Sec.hasSectionRef() || !Sec.isRela())
+ continue;
+ const SectionRef &SecRef = Sec.getSectionRef();
+ section_iterator RelocatedSecIter = cantFail(SecRef.getRelocatedSection());
+ assert(RelocatedSecIter != SecRef.getObject()->section_end() &&
+ "Relocation section exists without corresponding relocated section");
+ const SectionRef &RelocatedSecRef = *RelocatedSecIter;
+ const StringRef RelocatedSectionName = cantFail(RelocatedSecRef.getName());
+ const bool SkipRelocs =
+ StringSwitch<bool>(RelocatedSectionName)
+ .Cases(".plt", ".got.plt", ".eh_frame", ".gcc_except_table",
+ ".fini_array", ".init_array", true)
+ .Default(false);
+ if (!RelocatedSecRef.isData() || SkipRelocs)
+ continue;
+
+ Error ErrorStatus =
+ processDataRelocations(BC, SecRef, true /* HasAddressTaken */);
+ if (ErrorStatus)
+ return ErrorStatus;
+ }
+ ErrorOr<BinarySection &> SecRelDataIA =
+ BC.getUniqueSectionByName(".rela.init_array");
+ if (SecRelDataIA) {
+ const SectionRef SecRefRelData = SecRelDataIA->getSectionRef();
+ Error ErrorStatus =
+ processDataRelocations(BC, SecRefRelData, true /* HasAddressTaken */);
+ if (ErrorStatus)
+ return ErrorStatus;
+ }
+ ErrorOr<BinarySection &> SecRelDataFIA =
+ BC.getUniqueSectionByName(".rela.fini_array");
+ if (SecRelDataFIA) {
+ const SectionRef SecRefRelData = SecRelDataFIA->getSectionRef();
+ Error ErrorStatus =
+ processDataRelocations(BC, SecRefRelData, false /* !HasAddressTaken */);
if (ErrorStatus)
return ErrorStatus;
}
@@ -387,7 +434,7 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
LLVM_DEBUG({
for (auto &BFIter : BC.getBinaryFunctions()) {
- if (BFIter.second.isSafeToICF())
+ if (!BFIter.second.hasAddressTaken())
continue;
dbgs() << "BOLT-DEBUG: skipping function " << BFIter.second.getOneName()
<< '\n';
@@ -530,7 +577,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
LLVM_DEBUG(SinglePass.stopTimer());
};
- if (BC.getICFLevel() == BinaryContext::ICFLevel::Safe)
+ if (opts::ICF == ICFLevel::Safe)
if (Error Err = markFunctionsUnsafeToFold(BC))
return Err;
hashFunctions();
diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp
index e5fb1f5b257850..bafc5c722c1a51 100644
--- a/bolt/lib/Rewrite/BinaryPassManager.cpp
+++ b/bolt/lib/Rewrite/BinaryPassManager.cpp
@@ -54,6 +54,7 @@ extern cl::opt<bool> PrintDynoStats;
extern cl::opt<bool> DumpDotAll;
extern cl::opt<std::string> AsmDump;
extern cl::opt<bolt::PLTCall::OptType> PLT;
+extern cl::opt<bolt::IdenticalCodeFolding::ICFLevel> ICF;
static cl::opt<bool>
DynoStatsAll("dyno-stats-all",
@@ -395,7 +396,7 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
opts::StripRepRet);
Manager.registerPass(std::make_unique<IdenticalCodeFolding>(PrintICF),
- BC.getICFLevel() != BinaryContext::ICFLevel::None);
+ opts::ICF != IdenticalCodeFolding::ICFLevel::None);
Manager.registerPass(
std::make_unique<SpecializeMemcpy1>(NeverPrint, opts::SpecializeMemcpy1),
@@ -420,7 +421,7 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
Manager.registerPass(std::make_unique<Inliner>(PrintInline));
Manager.registerPass(std::make_unique<IdenticalCodeFolding>(PrintICF),
- BC.getICFLevel() != BinaryContext::ICFLevel::None);
+ opts::ICF != IdenticalCodeFolding::ICFLevel::None);
Manager.registerPass(std::make_unique<PLTCall>(PrintPLT));
diff --git a/bolt/lib/Rewrite/BoltDiff.cpp b/bolt/lib/Rewrite/BoltDiff.cpp
index 20fc5aae874d14..55399bc0c1cd3e 100644
--- a/bolt/lib/Rewrite/BoltDiff.cpp
+++ b/bolt/lib/Rewrite/BoltDiff.cpp
@@ -28,6 +28,7 @@ using namespace bolt;
namespace opts {
extern cl::OptionCategory BoltDiffCategory;
extern cl::opt<bool> NeverPrint;
+extern cl::opt<bolt::IdenticalCodeFolding::ICFLevel> ICF;
static cl::opt<bool> IgnoreLTOSuffix(
"ignore-lto-suffix",
@@ -696,7 +697,7 @@ void RewriteInstance::compare(RewriteInstance &RI2) {
}
// Pre-pass ICF
- if (BC->getICFLevel() != BinaryContext::ICFLevel::None) {
+ if (opts::ICF != IdenticalCodeFolding::ICFLevel::None) {
IdenticalCodeFolding ICF(opts::NeverPrint);
outs() << "BOLT-DIFF: Starting ICF pass for binary 1";
BC->logBOLTErrorsAndQuitOnFatal(ICF.runOnFunctions(*BC));
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 6eeb243c591b8a..6399bcef54487b 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -19,6 +19,7 @@
#include "bolt/Core/Relocation.h"
#include "bolt/Passes/BinaryPasses.h"
#include "bolt/Passes/CacheMetrics.h"
+#include "bolt/Passes/IdenticalCodeFolding.h"
#include "bolt/Passes/ReorderFunctions.h"
#include "bolt/Profile/BoltAddressTranslation.h"
#include "bolt/Profile/DataAggregator.h"
@@ -86,6 +87,7 @@ extern cl::opt<bolt::ReorderFunctions::ReorderType> ReorderFunctions;
extern cl::opt<bool> TerminalTrap;
extern cl::opt<bool> TimeBuild;
extern cl::opt<bool> TimeRewrite;
+extern cl::opt<bolt::IdenticalCodeFolding::ICFLevel> ICF;
cl::opt<bool> AllowStripped("allow-stripped",
cl::desc("allow processing of stripped binaries"),
@@ -2051,7 +2053,7 @@ void RewriteInstance::adjustCommandLineOptions() {
}
if (!BC->HasRelocations &&
- BC->getICFLevel() == BinaryContext::ICFLevel::Safe) {
+ opts::ICF == IdenticalCodeFolding::ICFLevel::Safe) {
BC->errs() << "BOLT-ERROR: Binary built without relocations. Safe ICF is "
"not supported\n";
exit(1);
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index 19aa0f48383668..0180a89998b0b7 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -12,9 +12,11 @@
# ICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# SAFEICFCHECK: skipping function _ZNK8Derived24funcEii
+# SAFEICFCHECK-NEXT: skipping function _ZN8Derived2D0Ev
# SAFEICFCHECK-NEXT: skipping function _ZNK8Derived34funcEii
+# SAFEICFCHECK-NEXT: skipping function _ZN4BaseD2Ev
+# SAFEICFCHECK-NEXT: skipping function _ZN8Derived3D0Ev
# SAFEICFCHECK-NEXT: ICF iteration 1
-# SAFEICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# SAFEICFCHECK-NEXT: ===---------
>From 5110f742c6be7f609021c5120216ed69eb798466 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Thu, 5 Dec 2024 20:10:29 -0800
Subject: [PATCH 27/34] Added vtable filtering, and check fo X86 architecture
---
.../bolt/Passes/IdenticalCodeFolding.h | 1 +
bolt/lib/Passes/IdenticalCodeFolding.cpp | 35 ++++++++++++++-----
bolt/test/X86/icf-safe-icp.test | 4 +--
3 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index aaea4a6a0469c0..c309e68a84110d 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -52,6 +52,7 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
/// references.
Error processDataRelocations(BinaryContext &BC,
const SectionRef &SecRefRelData,
+ const llvm::BitVector &BitVector,
const bool HasAddressTaken);
};
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 3938fdc853d9ed..2ae82d3181b4e8 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -13,6 +13,7 @@
#include "bolt/Passes/IdenticalCodeFolding.h"
#include "bolt/Core/HashUtilities.h"
#include "bolt/Core/ParallelUtilities.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ThreadPool.h"
@@ -353,16 +354,29 @@ typedef std::unordered_map<BinaryFunction *, std::vector<BinaryFunction *>,
namespace llvm {
namespace bolt {
-
+/// Scans symbol table and creates a bit vector of memory addresses of vtables.
+static void processSymbolTable(const BinaryContext &BC,
+ llvm::BitVector &BitVector) {
+ for (auto [Address, Data] : BC.getBinaryData()) {
+ // Filter out all symbols that are not vtables.
+ if (!Data->getName().starts_with("_ZTV"))
+ continue;
+ for (uint64_t I = Address / 8, End = I + (Data->getSize() / 8); I < End;
+ ++I)
+ BitVector.set(I);
+ }
+}
Error IdenticalCodeFolding::processDataRelocations(
BinaryContext &BC, const SectionRef &SecRefRelData,
- const bool HasAddressTaken) {
+ const llvm::BitVector &BitVector, const bool HasAddressTaken) {
for (const RelocationRef &Rel : SecRefRelData.relocations()) {
symbol_iterator SymbolIter = Rel.getSymbol();
const ObjectFile *OwningObj = Rel.getObject();
assert(SymbolIter != OwningObj->symbol_end() &&
"relocation Symbol expected");
const SymbolRef &Symbol = *SymbolIter;
+ if (BitVector.test(Rel.getOffset() / 8))
+ continue;
const uint64_t SymbolAddress = cantFail(Symbol.getAddress());
const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(OwningObj);
if (!ELFObj)
@@ -378,6 +392,11 @@ Error IdenticalCodeFolding::processDataRelocations(
}
Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
+ if (!BC.isX86())
+ BC.outs() << "BOLT-WARNING: Safe ICF is only supported for x86\n";
+ constexpr uint64_t NumBits = (((uint64_t)1) << 32) / 8;
+ llvm::BitVector BitVector(NumBits);
+ processSymbolTable(BC, BitVector);
for (const auto &Sec : BC.sections()) {
if (!Sec.hasSectionRef() || !Sec.isRela())
continue;
@@ -395,8 +414,8 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
if (!RelocatedSecRef.isData() || SkipRelocs)
continue;
- Error ErrorStatus =
- processDataRelocations(BC, SecRef, true /* HasAddressTaken */);
+ Error ErrorStatus = processDataRelocations(BC, SecRef, BitVector,
+ /* HasAddressTaken */ true);
if (ErrorStatus)
return ErrorStatus;
}
@@ -404,8 +423,8 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
BC.getUniqueSectionByName(".rela.init_array");
if (SecRelDataIA) {
const SectionRef SecRefRelData = SecRelDataIA->getSectionRef();
- Error ErrorStatus =
- processDataRelocations(BC, SecRefRelData, true /* HasAddressTaken */);
+ Error ErrorStatus = processDataRelocations(BC, SecRefRelData, BitVector,
+ /* !HasAddressTaken */ false);
if (ErrorStatus)
return ErrorStatus;
}
@@ -413,8 +432,8 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
BC.getUniqueSectionByName(".rela.fini_array");
if (SecRelDataFIA) {
const SectionRef SecRefRelData = SecRelDataFIA->getSectionRef();
- Error ErrorStatus =
- processDataRelocations(BC, SecRefRelData, false /* !HasAddressTaken */);
+ Error ErrorStatus = processDataRelocations(BC, SecRefRelData, BitVector,
+ /* !HasAddressTaken */ false);
if (ErrorStatus)
return ErrorStatus;
}
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index 0180a89998b0b7..19aa0f48383668 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -12,11 +12,9 @@
# ICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# SAFEICFCHECK: skipping function _ZNK8Derived24funcEii
-# SAFEICFCHECK-NEXT: skipping function _ZN8Derived2D0Ev
# SAFEICFCHECK-NEXT: skipping function _ZNK8Derived34funcEii
-# SAFEICFCHECK-NEXT: skipping function _ZN4BaseD2Ev
-# SAFEICFCHECK-NEXT: skipping function _ZN8Derived3D0Ev
# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# SAFEICFCHECK-NEXT: ===---------
>From d524ed58f2412fa2b99e5af5414376460b3bb7ae Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Fri, 6 Dec 2024 11:20:30 -0800
Subject: [PATCH 28/34] moved check as first one
---
bolt/lib/Passes/IdenticalCodeFolding.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 2ae82d3181b4e8..2588599b763752 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -370,13 +370,13 @@ Error IdenticalCodeFolding::processDataRelocations(
BinaryContext &BC, const SectionRef &SecRefRelData,
const llvm::BitVector &BitVector, const bool HasAddressTaken) {
for (const RelocationRef &Rel : SecRefRelData.relocations()) {
+ if (BitVector.test(Rel.getOffset() / 8))
+ continue;
symbol_iterator SymbolIter = Rel.getSymbol();
const ObjectFile *OwningObj = Rel.getObject();
assert(SymbolIter != OwningObj->symbol_end() &&
"relocation Symbol expected");
- const SymbolRef &Symbol = *SymbolIter;
- if (BitVector.test(Rel.getOffset() / 8))
- continue;
+ const SymbolRef &Symbol = *SymbolIter;
const uint64_t SymbolAddress = cantFail(Symbol.getAddress());
const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(OwningObj);
if (!ELFObj)
>From 77ae0a2a2af0969e89cb9dbc48ffdef3a50f2d2b Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Fri, 6 Dec 2024 12:33:07 -0800
Subject: [PATCH 29/34] fix formatter
---
bolt/lib/Passes/IdenticalCodeFolding.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 2588599b763752..fb0eb7b7697962 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -376,7 +376,7 @@ Error IdenticalCodeFolding::processDataRelocations(
const ObjectFile *OwningObj = Rel.getObject();
assert(SymbolIter != OwningObj->symbol_end() &&
"relocation Symbol expected");
- const SymbolRef &Symbol = *SymbolIter;
+ const SymbolRef &Symbol = *SymbolIter;
const uint64_t SymbolAddress = cantFail(Symbol.getAddress());
const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(OwningObj);
if (!ELFObj)
>From d03ff1d4ee51690edf7df46380572e68697e27ca Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 10 Dec 2024 13:31:39 -0800
Subject: [PATCH 30/34] minor nits
---
bolt/include/bolt/Core/BinaryFunction.h | 6 +++---
bolt/lib/Passes/IdenticalCodeFolding.cpp | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index aa07a206ee6920..c5085be36be63e 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -428,7 +428,7 @@ class BinaryFunction {
/// Function order for streaming into the destination binary.
uint32_t Index{-1U};
- /// Indicates if the function is safe to fold.
+ /// Indicates function is referenced by none-control flow instruction.
bool HasAddressTaken{false};
/// Get basic block index assuming it belongs to this function.
@@ -820,10 +820,10 @@ class BinaryFunction {
return nullptr;
}
- /// Indicates if the function is safe to fold.
+ /// Returns true if function is referenced in none-control flow instructions..
bool hasAddressTaken() const { return HasAddressTaken; }
- /// Sets the function is not safe to fold.
+ /// Sets whether function is referenced in none-control flow instructions.
void setHasAddressTaken(bool Hat) { HasAddressTaken = Hat; }
/// Returns the raw binary encoding of this function.
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index fb0eb7b7697962..fe06383e0cbb60 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -357,7 +357,7 @@ namespace bolt {
/// Scans symbol table and creates a bit vector of memory addresses of vtables.
static void processSymbolTable(const BinaryContext &BC,
llvm::BitVector &BitVector) {
- for (auto [Address, Data] : BC.getBinaryData()) {
+ for (auto &[Address, Data] : BC.getBinaryData()) {
// Filter out all symbols that are not vtables.
if (!Data->getName().starts_with("_ZTV"))
continue;
>From 38758ee3074a38a9448a6cf01d2441cf0e581a8b Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 10 Dec 2024 15:51:07 -0800
Subject: [PATCH 31/34] Removed skip and moved
processInstructionForFuncReferences, nits
---
bolt/include/bolt/Core/BinaryContext.h | 3 -
bolt/include/bolt/Core/BinaryFunction.h | 10 ++-
bolt/lib/Core/BinaryContext.cpp | 22 ------
bolt/lib/Core/BinaryFunction.cpp | 18 ++++-
bolt/lib/Passes/IdenticalCodeFolding.cpp | 9 ++-
bolt/test/X86/icf-safe-icp.test | 95 ++----------------------
6 files changed, 35 insertions(+), 122 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 9b43d30c7f18bd..08ce892054874c 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -1350,9 +1350,6 @@ class BinaryContext {
return Code.size();
}
- /// Processes .text section to identify function references.
- void processInstructionForFuncReferences(const MCInst &Inst);
-
/// Compute the native code size for a range of instructions.
/// Note: this can be imprecise wrt the final binary since happening prior to
/// relaxation, as well as wrt the original binary because of opcode
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index c5085be36be63e..e34ee55704c6af 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -428,7 +428,7 @@ class BinaryFunction {
/// Function order for streaming into the destination binary.
uint32_t Index{-1U};
- /// Indicates function is referenced by none-control flow instruction.
+ /// Indicates function is referenced by non-control flow instruction.
bool HasAddressTaken{false};
/// Get basic block index assuming it belongs to this function.
@@ -820,10 +820,10 @@ class BinaryFunction {
return nullptr;
}
- /// Returns true if function is referenced in none-control flow instructions..
+ /// Return true if function is referenced in non-control flow instructions..
bool hasAddressTaken() const { return HasAddressTaken; }
- /// Sets whether function is referenced in none-control flow instructions.
+ /// Set whether function is referenced in non-control flow instructions.
void setHasAddressTaken(bool Hat) { HasAddressTaken = Hat; }
/// Returns the raw binary encoding of this function.
@@ -2103,6 +2103,10 @@ class BinaryFunction {
// adjustments.
void handleAArch64IndirectCall(MCInst &Instruction, const uint64_t Offset);
+ /// Processes code section to identify function references.
+ void processInstructionForFuncReferences(BinaryContext &BC,
+ const MCInst &Inst);
+
/// Scan function for references to other functions. In relocation mode,
/// add relocations for external references. In non-relocation mode, detect
/// and mark new entry points.
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 7e3f032bea00e5..f246750209d6c4 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -1945,28 +1945,6 @@ static void printDebugInfo(raw_ostream &OS, const MCInst &Instruction,
OS << " discriminator:" << Row.Discriminator;
}
-/// Skip instructions that do not potentially manipulate or compare function
-/// addresses.
-static bool skipInstruction(const MCInst &Inst, const BinaryContext &BC) {
- return (BC.MIB->isPseudo(Inst) || BC.MIB->isUnconditionalBranch(Inst) ||
- BC.MIB->isConditionalBranch(Inst) || BC.MIB->isCall(Inst) ||
- BC.MIB->isBranch(Inst));
-}
-void BinaryContext::processInstructionForFuncReferences(const MCInst &Inst) {
- if (skipInstruction(Inst, *this))
- return;
- for (const MCOperand &Op : MCPlus::primeOperands(Inst)) {
- if (!Op.isExpr())
- continue;
- const MCExpr &Expr = *Op.getExpr();
- if (Expr.getKind() == MCExpr::SymbolRef) {
- const MCSymbol &Symbol = cast<MCSymbolRefExpr>(Expr).getSymbol();
- if (BinaryFunction *BF = getFunctionForSymbol(&Symbol))
- BF->setHasAddressTaken(true);
- }
- }
-}
-
void BinaryContext::printInstruction(raw_ostream &OS, const MCInst &Instruction,
uint64_t Offset,
const BinaryFunction *Function,
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 07d386efb26ec5..c72d366a5f1acb 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1513,6 +1513,20 @@ MCSymbol *BinaryFunction::registerBranch(uint64_t Src, uint64_t Dst) {
return Target;
}
+void BinaryFunction::processInstructionForFuncReferences(BinaryContext &BC,
+ const MCInst &Inst) {
+ for (const MCOperand &Op : MCPlus::primeOperands(Inst)) {
+ if (!Op.isExpr())
+ continue;
+ const MCExpr &Expr = *Op.getExpr();
+ if (Expr.getKind() == MCExpr::SymbolRef) {
+ const MCSymbol &Symbol = cast<MCSymbolRefExpr>(Expr).getSymbol();
+ if (BinaryFunction *BF = BC.getFunctionForSymbol(&Symbol))
+ BF->setHasAddressTaken(true);
+ }
+ }
+}
+
bool BinaryFunction::scanExternalRefs() {
bool Success = true;
bool DisassemblyFailed = false;
@@ -1626,8 +1640,6 @@ bool BinaryFunction::scanExternalRefs() {
if (!BC.HasRelocations)
continue;
- BC.processInstructionForFuncReferences(Instruction);
-
if (BranchTargetSymbol) {
BC.MIB->replaceBranchTarget(Instruction, BranchTargetSymbol,
Emitter.LocalCtx.get());
@@ -1635,6 +1647,8 @@ bool BinaryFunction::scanExternalRefs() {
[](const MCOperand &Op) { return Op.isExpr(); })) {
// Skip assembly if the instruction may not have any symbolic operands.
continue;
+ } else {
+ processInstructionForFuncReferences(BC, Instruction);
}
// Emit the instruction using temp emitter and generate relocations.
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index fe06383e0cbb60..0150f5ec2cd193 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -439,9 +439,12 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
}
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
- for (const BinaryBasicBlock *BB : BF.getLayout().blocks())
- for (const MCInst &Inst : *BB)
- BC.processInstructionForFuncReferences(Inst);
+ for (const BinaryBasicBlock *BB : BF.getLayout().blocks()) {
+ for (const MCInst &Inst : *BB) {
+ if (!(BC.MIB->isCall(Inst) || BC.MIB->isBranch(Inst)))
+ BF.processInstructionForFuncReferences(BC, Inst);
+ }
+ }
};
ParallelUtilities::PredicateTy SkipFunc =
[&](const BinaryFunction &BF) -> bool {
diff --git a/bolt/test/X86/icf-safe-icp.test b/bolt/test/X86/icf-safe-icp.test
index 19aa0f48383668..b7013eb4b932fa 100644
--- a/bolt/test/X86/icf-safe-icp.test
+++ b/bolt/test/X86/icf-safe-icp.test
@@ -1,5 +1,6 @@
-## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
-## The compare is generated by the ICP path with instrumentation profiling.
+## Check that BOLT handles correctly folding functions with --icf=safe
+## that can be referenced through a non control flow instruction when ICP optimization is enabled.
+## This tests also checks that destructors are not folded.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
@@ -8,11 +9,10 @@
# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
# ICFCHECK: ICF iteration 1
-# ICFCHECK-NEXT: folding _ZNK8Derived34funcEii into _ZNK8Derived24funcEii
# ICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
+# ICFCHECK-NEXT: folding _ZNK8Derived34funcEii into _ZNK8Derived24funcEii
-# SAFEICFCHECK: skipping function _ZNK8Derived24funcEii
-# SAFEICFCHECK-NEXT: skipping function _ZNK8Derived34funcEii
+# SAFEICFCHECK: skipping function _ZNK8Derived34funcEii
# SAFEICFCHECK-NEXT: ICF iteration 1
# SAFEICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
# SAFEICFCHECK-NEXT: ===---------
@@ -88,43 +88,9 @@
## return 5;
## }
## Manually modified to remove "extra" assembly.
- .section .text.hot.,"ax", at progbits
- .globl _Z10createTypei
- .type _Z10createTypei, at function
-_Z10createTypei:
- callq _Znwm at PLT
- leaq _ZTV8Derived2+16(%rip), %rcx
- leaq _ZTV8Derived3+16(%rip), %rdx
- cmoveq %rcx, %rdx
- retq
- .size _Z10createTypei, .-_Z10createTypei
-
- .globl _Z10returnFivev
- .type _Z10returnFivev, at function
-_Z10returnFivev:
- movl $5, %eax
- retq
- .size _Z10returnFivev, .-_Z10returnFivev
-
- .globl returnFourOrFiveFunc
- .type returnFourOrFiveFunc, at function
-returnFourOrFiveFunc:
- xorl %eax, %eax
- cmpl $1, %edi
- sete %al
- xorl $5, %eax
- retq
- .size returnFourOrFiveFunc, .-returnFourOrFiveFunc
-
.globl main
.type main, at function
main:
- callq returnFourOrFiveFunc at PLT
- callq _Z10returnFivev at PLT
- callq _Z10createTypei
- callq _Z10createTypei
- leaq _ZNK8Derived24funcEii(%rip), %rcx
- callq _ZNK8Derived24funcEii
leaq _ZNK8Derived34funcEii(%rip), %rcx
callq _ZNK8Derived34funcEii
.size main, .-main
@@ -132,7 +98,7 @@ main:
.section .text.hot._ZNK8Derived24funcEii,"axG", at progbits,_ZNK8Derived24funcEii,comdat
.weak _ZNK8Derived24funcEii
.type _ZNK8Derived24funcEii, at function
-_ZNK8Derived24funcEii: #
+_ZNK8Derived24funcEii:
imull %esi, %eax
retq
.size _ZNK8Derived24funcEii, .-_ZNK8Derived24funcEii
@@ -141,7 +107,6 @@ _ZNK8Derived24funcEii: #
.weak _ZN8Derived2D0Ev
.type _ZN8Derived2D0Ev, at function
_ZN8Derived2D0Ev:
- movl $16, %esi
jmp _ZdlPvm at PLT
.size _ZN8Derived2D0Ev, .-_ZN8Derived2D0Ev
@@ -164,7 +129,6 @@ _ZN4BaseD2Ev:
.weak _ZN8Derived3D0Ev
.type _ZN8Derived3D0Ev, at function
_ZN8Derived3D0Ev:
- movl $16, %esi
jmp _ZdlPvm at PLT
.size _ZN8Derived3D0Ev, .-_ZN8Derived3D0Ev
@@ -179,37 +143,6 @@ _ZTV8Derived2:
.quad _ZN8Derived2D0Ev
.size _ZTV8Derived2, 40
- .type _ZTS8Derived2, at object
- .section .rodata._ZTS8Derived2,"aG", at progbits,_ZTS8Derived2,comdat
- .weak _ZTS8Derived2
-_ZTS8Derived2:
- .asciz "8Derived2"
- .size _ZTS8Derived2, 10
-
- .type _ZTS4Base, at object
- .section .rodata._ZTS4Base,"aG", at progbits,_ZTS4Base,comdat
- .weak _ZTS4Base
-_ZTS4Base:
- .asciz "4Base"
- .size _ZTS4Base, 6
-
- .type _ZTI4Base, at object
- .section .data.rel.ro._ZTI4Base,"awG", at progbits,_ZTI4Base,comdat
- .weak _ZTI4Base
-_ZTI4Base:
- .quad _ZTVN10__cxxabiv117__class_type_infoE+16
- .quad _ZTS4Base
- .size _ZTI4Base, 16
-
- .type _ZTI8Derived2, at object
- .section .data.rel.ro._ZTI8Derived2,"awG", at progbits,_ZTI8Derived2,comdat
- .weak _ZTI8Derived2
-_ZTI8Derived2:
- .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
- .quad _ZTS8Derived2
- .quad _ZTI4Base
- .size _ZTI8Derived2, 24
-
.type _ZTV8Derived3, at object
.section .data.rel.ro._ZTV8Derived3,"awG", at progbits,_ZTV8Derived3,comdat
.weak _ZTV8Derived3
@@ -220,19 +153,3 @@ _ZTV8Derived3:
.quad _ZN4BaseD2Ev
.quad _ZN8Derived3D0Ev
.size _ZTV8Derived3, 40
-
- .type _ZTS8Derived3, at object
- .section .rodata._ZTS8Derived3,"aG", at progbits,_ZTS8Derived3,comdat
- .weak _ZTS8Derived3
-_ZTS8Derived3:
- .asciz "8Derived3"
- .size _ZTS8Derived3, 10
-
- .type _ZTI8Derived3, at object
- .section .data.rel.ro._ZTI8Derived3,"awG", at progbits,_ZTI8Derived3,comdat
- .weak _ZTI8Derived3
-_ZTI8Derived3:
- .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
- .quad _ZTS8Derived3
- .quad _ZTI4Base
- .size _ZTI8Derived3, 24
>From bfb1dc6e55fdd517d53c7c75afdfb0d9bf65057c Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 10 Dec 2024 16:17:18 -0800
Subject: [PATCH 32/34] refactor bit vector
---
.../bolt/Passes/IdenticalCodeFolding.h | 13 +++++++--
bolt/lib/Passes/IdenticalCodeFolding.cpp | 27 +++++++++----------
2 files changed, 23 insertions(+), 17 deletions(-)
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index c309e68a84110d..8b2ed8cbf8efb3 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -39,12 +39,22 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
All, // Aggressive ICF for code.
};
explicit IdenticalCodeFolding(const cl::opt<bool> &PrintPass)
- : BinaryFunctionPass(PrintPass) {}
+ : BinaryFunctionPass(PrintPass) {
+ VtableBitVector.resize((((uint64_t)1) << 32) / 8);
+ }
const char *getName() const override { return "identical-code-folding"; }
Error runOnFunctions(BinaryContext &BC) override;
private:
+ /// Bit vector of memory addresses of vtables.
+ llvm::BitVector VtableBitVector;
+ bool isInVTable(uint64_t Address) const {
+ return VtableBitVector.test(Address / 8);
+ }
+ /// Scans symbol table and creates a bit vector of memory addresses of
+ /// vtables.
+ void processSymbolTable(const BinaryContext &BC);
/// Analyze .text section and relocations and mark functions that are not
/// safe to fold.
Error markFunctionsUnsafeToFold(BinaryContext &BC);
@@ -52,7 +62,6 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
/// references.
Error processDataRelocations(BinaryContext &BC,
const SectionRef &SecRefRelData,
- const llvm::BitVector &BitVector,
const bool HasAddressTaken);
};
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 0150f5ec2cd193..8012afabedbafc 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -355,22 +355,21 @@ typedef std::unordered_map<BinaryFunction *, std::vector<BinaryFunction *>,
namespace llvm {
namespace bolt {
/// Scans symbol table and creates a bit vector of memory addresses of vtables.
-static void processSymbolTable(const BinaryContext &BC,
- llvm::BitVector &BitVector) {
+void IdenticalCodeFolding::processSymbolTable(const BinaryContext &BC) {
for (auto &[Address, Data] : BC.getBinaryData()) {
// Filter out all symbols that are not vtables.
if (!Data->getName().starts_with("_ZTV"))
continue;
for (uint64_t I = Address / 8, End = I + (Data->getSize() / 8); I < End;
++I)
- BitVector.set(I);
+ VtableBitVector.set(I);
}
}
Error IdenticalCodeFolding::processDataRelocations(
BinaryContext &BC, const SectionRef &SecRefRelData,
- const llvm::BitVector &BitVector, const bool HasAddressTaken) {
+ const bool HasAddressTaken) {
for (const RelocationRef &Rel : SecRefRelData.relocations()) {
- if (BitVector.test(Rel.getOffset() / 8))
+ if (isInVTable(Rel.getOffset()))
continue;
symbol_iterator SymbolIter = Rel.getSymbol();
const ObjectFile *OwningObj = Rel.getObject();
@@ -393,10 +392,8 @@ Error IdenticalCodeFolding::processDataRelocations(
Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
if (!BC.isX86())
- BC.outs() << "BOLT-WARNING: Safe ICF is only supported for x86\n";
- constexpr uint64_t NumBits = (((uint64_t)1) << 32) / 8;
- llvm::BitVector BitVector(NumBits);
- processSymbolTable(BC, BitVector);
+ BC.outs() << "BOLT-WARNING: safe ICF is only supported for x86\n";
+ processSymbolTable(BC);
for (const auto &Sec : BC.sections()) {
if (!Sec.hasSectionRef() || !Sec.isRela())
continue;
@@ -414,8 +411,8 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
if (!RelocatedSecRef.isData() || SkipRelocs)
continue;
- Error ErrorStatus = processDataRelocations(BC, SecRef, BitVector,
- /* HasAddressTaken */ true);
+ Error ErrorStatus =
+ processDataRelocations(BC, SecRef, /* HasAddressTaken */ true);
if (ErrorStatus)
return ErrorStatus;
}
@@ -423,8 +420,8 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
BC.getUniqueSectionByName(".rela.init_array");
if (SecRelDataIA) {
const SectionRef SecRefRelData = SecRelDataIA->getSectionRef();
- Error ErrorStatus = processDataRelocations(BC, SecRefRelData, BitVector,
- /* !HasAddressTaken */ false);
+ Error ErrorStatus =
+ processDataRelocations(BC, SecRefRelData, /* !HasAddressTaken */ false);
if (ErrorStatus)
return ErrorStatus;
}
@@ -432,8 +429,8 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
BC.getUniqueSectionByName(".rela.fini_array");
if (SecRelDataFIA) {
const SectionRef SecRefRelData = SecRelDataFIA->getSectionRef();
- Error ErrorStatus = processDataRelocations(BC, SecRefRelData, BitVector,
- /* !HasAddressTaken */ false);
+ Error ErrorStatus =
+ processDataRelocations(BC, SecRefRelData, /* !HasAddressTaken */ false);
if (ErrorStatus)
return ErrorStatus;
}
>From 417196cffdceb47477837bf5b17ae1878713dbc9 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Tue, 10 Dec 2024 16:36:39 -0800
Subject: [PATCH 33/34] nit
---
bolt/lib/Rewrite/RewriteInstance.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 6399bcef54487b..2783bdeb2f3abc 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2054,7 +2054,7 @@ void RewriteInstance::adjustCommandLineOptions() {
if (!BC->HasRelocations &&
opts::ICF == IdenticalCodeFolding::ICFLevel::Safe) {
- BC->errs() << "BOLT-ERROR: Binary built without relocations. Safe ICF is "
+ BC->errs() << "BOLT-ERROR: binary built without relocations. Safe ICF is "
"not supported\n";
exit(1);
}
>From bbf015f2ffd13c0f61d3784abddfd91742ff9a94 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Fri, 13 Dec 2024 11:46:58 -0800
Subject: [PATCH 34/34] changed to using BinarySections, cleaned up code that
is no longer necessary, etc
---
bolt/include/bolt/Core/BinarySection.h | 2 +
bolt/include/bolt/Core/Relocation.h | 5 -
.../bolt/Passes/IdenticalCodeFolding.h | 27 ++--
bolt/lib/Core/Relocation.cpp | 62 ---------
bolt/lib/Passes/IdenticalCodeFolding.cpp | 126 +++++++-----------
bolt/lib/Rewrite/RewriteInstance.cpp | 58 ++++++++
bolt/test/X86/icf-safe-process-rela-data.test | 3 +-
bolt/test/X86/icf-safe-test1-no-relocs.test | 4 +-
bolt/test/X86/icf-safe-test1.test | 4 +-
.../icf-safe-test2GlobalConstPtrNoPic.test | 4 +-
10 files changed, 129 insertions(+), 166 deletions(-)
diff --git a/bolt/include/bolt/Core/BinarySection.h b/bolt/include/bolt/Core/BinarySection.h
index d362961176b326..5ff719623bba5b 100644
--- a/bolt/include/bolt/Core/BinarySection.h
+++ b/bolt/include/bolt/Core/BinarySection.h
@@ -340,6 +340,8 @@ class BinarySection {
/// Does this section have any non-pending relocations?
bool hasRelocations() const { return !Relocations.empty(); }
+ bool hasDynamicRelocations() const { return !DynamicRelocations.empty(); }
+
/// Does this section have any pending relocations?
bool hasPendingRelocations() const { return !PendingRelocations.empty(); }
diff --git a/bolt/include/bolt/Core/Relocation.h b/bolt/include/bolt/Core/Relocation.h
index 1fe22e09912f75..b353ba77a29445 100644
--- a/bolt/include/bolt/Core/Relocation.h
+++ b/bolt/include/bolt/Core/Relocation.h
@@ -180,11 +180,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Relocation &Rel) {
return OS;
}
-uint32_t getRelocationSymbol(const object::ELFObjectFileBase *Obj,
- const object::RelocationRef &Rel);
-
-int64_t getRelocationAddend(const object::ELFObjectFileBase *Obj,
- const object::RelocationRef &Rel);
} // namespace bolt
} // namespace llvm
diff --git a/bolt/include/bolt/Passes/IdenticalCodeFolding.h b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
index 8b2ed8cbf8efb3..0ceadb5bc96799 100644
--- a/bolt/include/bolt/Passes/IdenticalCodeFolding.h
+++ b/bolt/include/bolt/Passes/IdenticalCodeFolding.h
@@ -39,9 +39,7 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
All, // Aggressive ICF for code.
};
explicit IdenticalCodeFolding(const cl::opt<bool> &PrintPass)
- : BinaryFunctionPass(PrintPass) {
- VtableBitVector.resize((((uint64_t)1) << 32) / 8);
- }
+ : BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "identical-code-folding"; }
Error runOnFunctions(BinaryContext &BC) override;
@@ -49,20 +47,27 @@ class IdenticalCodeFolding : public BinaryFunctionPass {
private:
/// Bit vector of memory addresses of vtables.
llvm::BitVector VtableBitVector;
- bool isInVTable(uint64_t Address) const {
+ /// Returns true if the memory address is in the bit vector of vtables.
+ bool isAddressInVTable(uint64_t Address) const {
return VtableBitVector.test(Address / 8);
}
+ /// Initialize bit vector of memory addresses of vtables.
+ void initVtable() {VtableBitVector.resize((((uint64_t)1) << 32) / 8);}
+ /// Mark memory address of vtable as used.
+ void setAddressUsedInVTable(uint64_t Address) { VtableBitVector.set(Address / 8); }
/// Scans symbol table and creates a bit vector of memory addresses of
/// vtables.
- void processSymbolTable(const BinaryContext &BC);
+ void initVTableReferences(const BinaryContext &BC);
/// Analyze .text section and relocations and mark functions that are not
/// safe to fold.
- Error markFunctionsUnsafeToFold(BinaryContext &BC);
- /// Process relocations in the .data section to identify function
- /// references.
- Error processDataRelocations(BinaryContext &BC,
- const SectionRef &SecRefRelData,
- const bool HasAddressTaken);
+ void markFunctionsUnsafeToFold(BinaryContext &BC);
+ /// Process static and dynamic relocations in the data sections to identify
+ /// function references, and marks them as unsafe to fold. It filters out
+ /// symbol references that are in vtables.
+ void analyzeDataRelocations(BinaryContext &BC);
+ /// Process functions that have CFG created and mark functions unsafe to fold
+ /// that are used in non-control flow instructions.
+ void analyzeFunctions(BinaryContext &BC);
};
} // namespace bolt
diff --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp
index c3c760d9262198..4e888a5b147aca 100644
--- a/bolt/lib/Core/Relocation.cpp
+++ b/bolt/lib/Core/Relocation.cpp
@@ -1115,65 +1115,3 @@ void Relocation::print(raw_ostream &OS) const {
OS << ", 0x" << Twine::utohexstr(Addend);
OS << ", 0x" << Twine::utohexstr(Value);
}
-
-namespace {
-template <typename ELFT>
-int64_t getRelocationAddend(const llvm::object::ELFObjectFile<ELFT> *Obj,
- const llvm::object::RelocationRef &RelRef) {
- using ELFShdrTy = typename ELFT::Shdr;
- using Elf_Rela = typename ELFT::Rela;
- int64_t Addend = 0;
- const llvm::object::ELFFile<ELFT> &EF = Obj->getELFFile();
- llvm::object::DataRefImpl Rel = RelRef.getRawDataRefImpl();
- const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
- switch (RelocationSection->sh_type) {
- default:
- llvm_unreachable("unexpected relocation section type");
- case ELF::SHT_REL:
- break;
- case ELF::SHT_RELA: {
- const Elf_Rela *RelA = Obj->getRela(Rel);
- Addend = RelA->r_addend;
- break;
- }
- }
-
- return Addend;
-}
-
-template <typename ELFT>
-uint32_t getRelocationSymbol(const llvm::object::ELFObjectFile<ELFT> *Obj,
- const llvm::object::RelocationRef &RelRef) {
- using ELFShdrTy = typename ELFT::Shdr;
- uint32_t Symbol = 0;
- const llvm::object::ELFFile<ELFT> &EF = Obj->getELFFile();
- llvm::object::DataRefImpl Rel = RelRef.getRawDataRefImpl();
- const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
- switch (RelocationSection->sh_type) {
- default:
- llvm_unreachable("unexpected relocation section type");
- case ELF::SHT_REL:
- Symbol = Obj->getRel(Rel)->getSymbol(EF.isMips64EL());
- break;
- case ELF::SHT_RELA:
- Symbol = Obj->getRela(Rel)->getSymbol(EF.isMips64EL());
- break;
- }
-
- return Symbol;
-}
-} // namespace
-
-namespace llvm {
-namespace bolt {
-uint32_t getRelocationSymbol(const llvm::object::ELFObjectFileBase *Obj,
- const llvm::object::RelocationRef &Rel) {
- return ::getRelocationSymbol(cast<llvm::object::ELF64LEObjectFile>(Obj), Rel);
-}
-
-int64_t getRelocationAddend(const llvm::object::ELFObjectFileBase *Obj,
- const llvm::object::RelocationRef &Rel) {
- return ::getRelocationAddend(cast<llvm::object::ELF64LEObjectFile>(Obj), Rel);
-}
-} // namespace bolt
-} // namespace llvm
diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp
index 8012afabedbafc..ed347009fa7bcb 100644
--- a/bolt/lib/Passes/IdenticalCodeFolding.cpp
+++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp
@@ -14,6 +14,8 @@
#include "bolt/Core/HashUtilities.h"
#include "bolt/Core/ParallelUtilities.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ThreadPool.h"
@@ -354,94 +356,51 @@ typedef std::unordered_map<BinaryFunction *, std::vector<BinaryFunction *>,
namespace llvm {
namespace bolt {
-/// Scans symbol table and creates a bit vector of memory addresses of vtables.
-void IdenticalCodeFolding::processSymbolTable(const BinaryContext &BC) {
- for (auto &[Address, Data] : BC.getBinaryData()) {
+/// Scans symbol table and creates a bit vector of memory addresses of vtable symbols.
+void IdenticalCodeFolding::initVTableReferences(const BinaryContext &BC) {
+ initVtable();
+ for (const auto &[Address, Data] : BC.getBinaryData()) {
// Filter out all symbols that are not vtables.
if (!Data->getName().starts_with("_ZTV"))
continue;
- for (uint64_t I = Address / 8, End = I + (Data->getSize() / 8); I < End;
- ++I)
- VtableBitVector.set(I);
+ for (uint64_t I = Address, End = I + Data->getSize(); I < End; I += 8)
+ setAddressUsedInVTable(I);
}
}
-Error IdenticalCodeFolding::processDataRelocations(
- BinaryContext &BC, const SectionRef &SecRefRelData,
- const bool HasAddressTaken) {
- for (const RelocationRef &Rel : SecRefRelData.relocations()) {
- if (isInVTable(Rel.getOffset()))
+void IdenticalCodeFolding::analyzeDataRelocations(BinaryContext &BC) {
+ initVTableReferences(BC);
+ for (const BinarySection &Sec : BC.sections()) {
+ if (!Sec.hasSectionRef() || !Sec.isData())
continue;
- symbol_iterator SymbolIter = Rel.getSymbol();
- const ObjectFile *OwningObj = Rel.getObject();
- assert(SymbolIter != OwningObj->symbol_end() &&
- "relocation Symbol expected");
- const SymbolRef &Symbol = *SymbolIter;
- const uint64_t SymbolAddress = cantFail(Symbol.getAddress());
- const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(OwningObj);
- if (!ELFObj)
- return createFatalBOLTError(
- Twine("BOLT-ERROR: Only ELFObjectFileBase is supported"));
- const int64_t Addend = getRelocationAddend(ELFObj, Rel);
- BinaryFunction *BF = BC.getBinaryFunctionAtAddress(SymbolAddress + Addend);
- if (!BF)
- continue;
- BF->setHasAddressTaken(HasAddressTaken);
+ for (const auto &Rel : Sec.relocations()) {
+ const uint64_t RelAddr = Rel.Offset + Sec.getAddress();
+ if (isAddressInVTable(RelAddr))
+ continue;
+ BinaryFunction *BF = BC.getFunctionForSymbol(Rel.Symbol);
+ if (!BF)
+ continue;
+ BF->setHasAddressTaken(true);
+ }
+ for (const auto &Rel : Sec.dynamicRelocations()) {
+ const uint64_t RelAddr = Rel.Offset + Sec.getAddress();
+ if (isAddressInVTable(RelAddr))
+ continue;
+ BinaryFunction *BF =
+ BC.getBinaryFunctionContainingAddress(Rel.Addend,
+ /*CheckPastEnd*/ false,
+ /*UseMaxSize*/ true);
+ if (!BF)
+ continue;
+ BF->setHasAddressTaken(true);
+ }
}
- return Error::success();
}
-
-Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
- if (!BC.isX86())
- BC.outs() << "BOLT-WARNING: safe ICF is only supported for x86\n";
- processSymbolTable(BC);
- for (const auto &Sec : BC.sections()) {
- if (!Sec.hasSectionRef() || !Sec.isRela())
- continue;
- const SectionRef &SecRef = Sec.getSectionRef();
- section_iterator RelocatedSecIter = cantFail(SecRef.getRelocatedSection());
- assert(RelocatedSecIter != SecRef.getObject()->section_end() &&
- "Relocation section exists without corresponding relocated section");
- const SectionRef &RelocatedSecRef = *RelocatedSecIter;
- const StringRef RelocatedSectionName = cantFail(RelocatedSecRef.getName());
- const bool SkipRelocs =
- StringSwitch<bool>(RelocatedSectionName)
- .Cases(".plt", ".got.plt", ".eh_frame", ".gcc_except_table",
- ".fini_array", ".init_array", true)
- .Default(false);
- if (!RelocatedSecRef.isData() || SkipRelocs)
- continue;
-
- Error ErrorStatus =
- processDataRelocations(BC, SecRef, /* HasAddressTaken */ true);
- if (ErrorStatus)
- return ErrorStatus;
- }
- ErrorOr<BinarySection &> SecRelDataIA =
- BC.getUniqueSectionByName(".rela.init_array");
- if (SecRelDataIA) {
- const SectionRef SecRefRelData = SecRelDataIA->getSectionRef();
- Error ErrorStatus =
- processDataRelocations(BC, SecRefRelData, /* !HasAddressTaken */ false);
- if (ErrorStatus)
- return ErrorStatus;
- }
- ErrorOr<BinarySection &> SecRelDataFIA =
- BC.getUniqueSectionByName(".rela.fini_array");
- if (SecRelDataFIA) {
- const SectionRef SecRefRelData = SecRelDataFIA->getSectionRef();
- Error ErrorStatus =
- processDataRelocations(BC, SecRefRelData, /* !HasAddressTaken */ false);
- if (ErrorStatus)
- return ErrorStatus;
- }
-
+void IdenticalCodeFolding::analyzeFunctions(BinaryContext &BC) {
ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
- for (const BinaryBasicBlock *BB : BF.getLayout().blocks()) {
- for (const MCInst &Inst : *BB) {
+ for (const BinaryBasicBlock *BB : BF.getLayout().blocks())
+ for (const MCInst &Inst : *BB)
if (!(BC.MIB->isCall(Inst) || BC.MIB->isBranch(Inst)))
BF.processInstructionForFuncReferences(BC, Inst);
- }
- }
};
ParallelUtilities::PredicateTy SkipFunc =
[&](const BinaryFunction &BF) -> bool {
@@ -459,7 +418,15 @@ Error IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
<< '\n';
}
});
- return Error::success();
+}
+void IdenticalCodeFolding::markFunctionsUnsafeToFold(BinaryContext &BC) {
+ NamedRegionTimer MarkFunctionsUnsafeToFoldTimer(
+ "markFunctionsUnsafeToFold", "markFunctionsUnsafeToFold", "ICF breakdown",
+ "ICF breakdown", opts::TimeICF);
+ if (!BC.isX86())
+ BC.outs() << "BOLT-WARNING: safe ICF is only supported for x86\n";
+ analyzeDataRelocations(BC);
+ analyzeFunctions(BC);
}
Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
@@ -597,8 +564,7 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) {
LLVM_DEBUG(SinglePass.stopTimer());
};
if (opts::ICF == ICFLevel::Safe)
- if (Error Err = markFunctionsUnsafeToFold(BC))
- return Err;
+ markFunctionsUnsafeToFold(BC);
hashFunctions();
createCongruentBuckets();
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 2783bdeb2f3abc..54b1fd00296487 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2120,6 +2120,64 @@ void RewriteInstance::adjustCommandLineOptions() {
}
}
+namespace {
+template <typename ELFT>
+int64_t getRelocationAddend(const ELFObjectFile<ELFT> *Obj,
+ const RelocationRef &RelRef) {
+ using ELFShdrTy = typename ELFT::Shdr;
+ using Elf_Rela = typename ELFT::Rela;
+ int64_t Addend = 0;
+ const ELFFile<ELFT> &EF = Obj->getELFFile();
+ DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
+ switch (RelocationSection->sh_type) {
+ default:
+ llvm_unreachable("unexpected relocation section type");
+ case ELF::SHT_REL:
+ break;
+ case ELF::SHT_RELA: {
+ const Elf_Rela *RelA = Obj->getRela(Rel);
+ Addend = RelA->r_addend;
+ break;
+ }
+ }
+
+ return Addend;
+}
+
+int64_t getRelocationAddend(const ELFObjectFileBase *Obj,
+ const RelocationRef &Rel) {
+ return getRelocationAddend(cast<ELF64LEObjectFile>(Obj), Rel);
+}
+
+template <typename ELFT>
+uint32_t getRelocationSymbol(const ELFObjectFile<ELFT> *Obj,
+ const RelocationRef &RelRef) {
+ using ELFShdrTy = typename ELFT::Shdr;
+ uint32_t Symbol = 0;
+ const ELFFile<ELFT> &EF = Obj->getELFFile();
+ DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a));
+ switch (RelocationSection->sh_type) {
+ default:
+ llvm_unreachable("unexpected relocation section type");
+ case ELF::SHT_REL:
+ Symbol = Obj->getRel(Rel)->getSymbol(EF.isMips64EL());
+ break;
+ case ELF::SHT_RELA:
+ Symbol = Obj->getRela(Rel)->getSymbol(EF.isMips64EL());
+ break;
+ }
+
+ return Symbol;
+}
+
+uint32_t getRelocationSymbol(const ELFObjectFileBase *Obj,
+ const RelocationRef &Rel) {
+ return getRelocationSymbol(cast<ELF64LEObjectFile>(Obj), Rel);
+}
+} // anonymous namespace
+
bool RewriteInstance::analyzeRelocation(
const RelocationRef &Rel, uint64_t &RType, std::string &SymbolName,
bool &IsSectionRelocation, uint64_t &SymbolAddress, int64_t &Addend,
diff --git a/bolt/test/X86/icf-safe-process-rela-data.test b/bolt/test/X86/icf-safe-process-rela-data.test
index 9d6d82a93833a5..e8c533ca4abdf1 100644
--- a/bolt/test/X86/icf-safe-process-rela-data.test
+++ b/bolt/test/X86/icf-safe-process-rela-data.test
@@ -1,5 +1,4 @@
-## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
-## This checks when only reference to a function is in .rela.data section.
+## Check that BOLT handles correctly folding functions with --icf=safe that are only reference in a .rela.data section.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
diff --git a/bolt/test/X86/icf-safe-test1-no-relocs.test b/bolt/test/X86/icf-safe-test1-no-relocs.test
index bd3d093defa5df..5101462ef7b221 100644
--- a/bolt/test/X86/icf-safe-test1-no-relocs.test
+++ b/bolt/test/X86/icf-safe-test1-no-relocs.test
@@ -1,11 +1,11 @@
-## Checks that BOLT handles correctly with no relocations with --icf=safe option.
+## Check that BOLT handles correctly a binary with no relocations with the --icf=safe option.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
# RUN: %clang %cflags %t1.o -o %t.exe
# RUN: not llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
-# SAFEICFCHECK: BOLT-ERROR: Binary built without relocations. Safe ICF is not supported
+# SAFEICFCHECK: BOLT-ERROR: binary built without relocations. Safe ICF is not supported
## int main(int argc, char **argv) {
## return temp;
diff --git a/bolt/test/X86/icf-safe-test1.test b/bolt/test/X86/icf-safe-test1.test
index 2f199dcb5261e1..364b4fb6f807bf 100644
--- a/bolt/test/X86/icf-safe-test1.test
+++ b/bolt/test/X86/icf-safe-test1.test
@@ -1,5 +1,5 @@
-## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
-## It invokes BOLT twice first testing CFG path, and second when function has to be disassembled.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced by non-control flow instructions.
+## It invokes BOLT twice first testing CFG path, and second when functions have to be disassembled.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
diff --git a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
index b00ad8b7067e3d..b25b63d4794524 100644
--- a/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
+++ b/bolt/test/X86/icf-safe-test2GlobalConstPtrNoPic.test
@@ -1,5 +1,5 @@
-## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced.
-## This checks global const function pointer in -fno-pic mode is handled correctly.
+## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced by non-control flow instructions,
+## when binary is built with -fno-PIC/-fno-PIE mode.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
More information about the llvm-commits
mailing list