diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -1405,6 +1405,25 @@ return InlineAsm; } +static void fixupCGProfileUser(Module &DstM) { + MDNode *CFGProfile = cast_or_null(DstM.getModuleFlag("CG Profile")); + if (!CFGProfile) + return; + + auto StripCast = [](MDNode *E, unsigned Idx) { + const MDOperand &MDO = E->getOperand(Idx); + auto V = cast(MDO); + if (Value *StrippedV = V->getValue()->stripPointerCasts()) + E->replaceOperandWith(Idx, ValueAsMetadata::get(StrippedV)); + }; + + for (const auto &Edge : CFGProfile->operands()) { + MDNode *E = cast(Edge); + StripCast(E, 0); + StripCast(E, 1); + } +} + Error IRLinker::run() { // Ensure metadata materialized before value mapping. if (SrcM->getMaterializer()) @@ -1471,6 +1490,8 @@ flushRAUWWorklist(); } + fixupCGProfileUser(DstM); + // Note that we are done linking global value bodies. This prevents // metadata linking from creating new references. DoneLinkingBodies = true; diff --git a/llvm/test/Transforms/FunctionImport/Inputs/cg_profile.ll b/llvm/test/Transforms/FunctionImport/Inputs/cg_profile.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/FunctionImport/Inputs/cg_profile.ll @@ -0,0 +1,12 @@ +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%class.A = type { [16 x i8] } + +define void @bar(%class.A*) { + ret void +} + +!llvm.module.flags = !{!1} + +!1 = !{i32 1, !"EnableSplitLTOUnit", i32 0} diff --git a/llvm/test/Transforms/FunctionImport/cg_profile.ll b/llvm/test/Transforms/FunctionImport/cg_profile.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/FunctionImport/cg_profile.ll @@ -0,0 +1,25 @@ +; Check that RAUW performed by IRMover during function importing does not +; generate bitcast in "CG Profile" related metadat nodes. +; RUN: opt -cg-profile -module-summary %s -o %t.bc +; RUN: opt -module-summary %p/Inputs/cg_profile.ll -o %t2.bc +; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc +; RUN: opt -function-import -print-imports -summary-file %t3.thinlto.bc %t.bc -o %t.o + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; %class.A is defined differently in %p/Inputs/cg_profile.ll. This is to trigger +; bitcast. +%class.A = type { i8 } + +define void @foo() !prof !2 { + call void @bar(%class.A* null) + ret void +} + +declare void @bar(%class.A*) + +!llvm.module.flags = !{!1} + +!1 = !{i32 1, !"EnableSplitLTOUnit", i32 0} +!2 = !{!"function_entry_count", i64 2753}