Author: Prabhu Rajasekaran Date: 2026-06-30T18:47:04-07:00 New Revision: c311656883510568fc1ce027916a9534b825f91d
URL: https://github.com/llvm/llvm-project/commit/c311656883510568fc1ce027916a9534b825f91d DIFF: https://github.com/llvm/llvm-project/commit/c311656883510568fc1ce027916a9534b825f91d.diff LOG: [clang][llvm]Uncorrelate CFI and Callgraph related type metadata annotations (#204266) When -fexperimental-call-graph-section flag is set, it adds type metadata to all the functions whose addresses are taken and does not have local linkage. When this flag is set along with CFI, the type metadata is added to all the vtable functions including destructors. This changes which functions are to be treated as CFI functions and includes such vtable entries to become part of the CFI check jumptables. To disambiguate intentions of CFI and callgraph mechanisms, this patch renames metadata set by callgraph mechanism to !callgraph (MD_callgraph). This prevents inflating the list of CFI functions when callgraph section is enabled along with CFI. Added: llvm/test/Transforms/MergeFunc/callgraph-function-merging.ll Modified: clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/test/CodeGen/call-graph-section-callback.cpp clang/test/CodeGen/call-graph-section-internal.cpp clang/test/CodeGen/call-graph-section-templates.cpp clang/test/CodeGen/call-graph-section-virtual-methods.cpp clang/test/CodeGen/call-graph-section.c clang/test/CodeGen/call-graph-section.cpp llvm/docs/LangRef.rst llvm/docs/Reference.md llvm/docs/ReleaseNotes.md llvm/include/llvm/IR/FixedMetadataKinds.def llvm/include/llvm/IR/Metadata.h llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/MachineFunction.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Transforms/IPO/MergeFunctions.cpp llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp llvm/test/Assembler/callee-type-metadata.ll llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll llvm/test/CodeGen/ARM/call-graph-section-assembly.ll llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll llvm/test/CodeGen/ARM/call-graph-section.ll llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll llvm/test/CodeGen/MIR/X86/call-site-info-ambiguous-indirect-call-typeid.mir llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll llvm/test/CodeGen/X86/call-graph-section-addrtaken.ll llvm/test/CodeGen/X86/call-graph-section-assembly.ll llvm/test/CodeGen/X86/call-graph-section-tailcall.ll llvm/test/CodeGen/X86/call-graph-section.ll llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll llvm/test/Transforms/Inline/drop-callee-type-metadata.ll llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll llvm/test/Verifier/callee-type-metadata.ll Removed: llvm/docs/CalleeTypeMetadata.rst ################################################################################ diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 292706d3c5088..813cd67e4dd51 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3402,24 +3402,19 @@ static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND) { GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); } -static bool hasExistingGeneralizedTypeMD(llvm::Function *F) { - llvm::MDNode *MD = F->getMetadata(llvm::LLVMContext::MD_type); - return MD && MD->hasGeneralizedMDString(); -} - void CodeGenModule::createIndirectFunctionTypeMD(const FunctionDecl *FD, llvm::Function *F) { - // Return if generalized type metadata is already attached. - if (hasExistingGeneralizedTypeMD(F)) - return; - // All functions which are not internal linkage could be indirect targets. // Address taken functions with internal linkage could be indirect targets. if (!F->hasLocalLinkage() || F->getFunction().hasAddressTaken(nullptr, /*IgnoreCallbackUses=*/true, /*IgnoreAssumeLikeCalls=*/true, - /*IgnoreLLVMUsed=*/false)) - F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType())); + /*IgnoreLLVMUsed=*/false)) { + F->addMetadata(llvm::LLVMContext::MD_callgraph, + *llvm::MDTuple::get( + getLLVMContext(), + {CreateMetadataIdentifierGeneralized(FD->getType())})); + } } void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD, @@ -3437,12 +3432,10 @@ void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD, /*GeneralizePointers=*/false); llvm::Metadata *MD = CreateMetadataIdentifierForType(FnType); F->addTypeMetadata(0, MD); - // Add the generalized identifier if not added already. - if (!hasExistingGeneralizedTypeMD(F)) { - QualType GenPtrFnType = GeneralizeFunctionType(getContext(), FD->getType(), - /*GeneralizePointers=*/true); - F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(GenPtrFnType)); - } + + QualType GenPtrFnType = GeneralizeFunctionType(getContext(), FD->getType(), + /*GeneralizePointers=*/true); + F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(GenPtrFnType)); // Emit a hash-based bit set entry for cross-DSO calls. if (CodeGenOpts.SanitizeCfiCrossDso) @@ -3461,10 +3454,7 @@ void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT, return; llvm::Metadata *TypeIdMD = CreateMetadataIdentifierGeneralized(QT); - llvm::MDTuple *TypeTuple = llvm::MDTuple::get( - getLLVMContext(), {llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( - llvm::Type::getInt64Ty(getLLVMContext()), 0)), - TypeIdMD}); + llvm::MDTuple *TypeTuple = llvm::MDTuple::get(getLLVMContext(), {TypeIdMD}); llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), {TypeTuple}); CB->setMetadata(llvm::LLVMContext::MD_callee_type, MDN); } diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 4283b6a3dc869..b1e70a7c347db 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1739,11 +1739,11 @@ class CodeGenModule : public CodeGenTypeCache { void createFunctionTypeMetadataForIcall(const FunctionDecl *FD, llvm::Function *F); - /// Create and attach type metadata if the function is a potential indirect - /// call target to support call graph section. + /// Create and attach callgraph metadata if the function is a potential + /// indirect call target to support call graph section. void createIndirectFunctionTypeMD(const FunctionDecl *FD, llvm::Function *F); - /// Create and attach type metadata to the given call. + /// Create and attach callee_type metadata to the given call. void createCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase *CB); /// Set type metadata to the given function. diff --git a/clang/test/CodeGen/call-graph-section-callback.cpp b/clang/test/CodeGen/call-graph-section-callback.cpp index e9b0a1818e3a4..c943050d6d59f 100644 --- a/clang/test/CodeGen/call-graph-section-callback.cpp +++ b/clang/test/CodeGen/call-graph-section-callback.cpp @@ -10,7 +10,7 @@ typedef void (*CallbackFn)(int); // Callback function with "internal" linkage. // CHECK-LABEL: define internal void @_ZL10myCallbacki( -// CHECK-SAME: {{.*}} !type [[F_CALLBACK:![0-9]+]] +// CHECK-SAME: {{.*}} !callgraph [[F_CALLBACK:![0-9]+]] static void myCallback(int value) { volatile int sink = value; @@ -27,4 +27,4 @@ int takeCallbackAddress() { return 0; } -// CHECK: [[F_CALLBACK]] = !{i64 0, !"_ZTSFviE.generalized"} +// CHECK: [[F_CALLBACK]] = !{!"_ZTSFviE.generalized"} diff --git a/clang/test/CodeGen/call-graph-section-internal.cpp b/clang/test/CodeGen/call-graph-section-internal.cpp index aea48675dfa27..923cb4ed053b0 100644 --- a/clang/test/CodeGen/call-graph-section-internal.cpp +++ b/clang/test/CodeGen/call-graph-section-internal.cpp @@ -2,7 +2,7 @@ // Check that we do not generate callee_type metadata for indirect calls // to functions with internal linkage (e.g., types in anonymous namespaces), -// as their type metadata identifiers are distinct MDNodes instead of +// as their callgraph metadata identifiers are distinct MDNodes instead of // generalized strings, which would fail the LLVM Verifier. namespace { diff --git a/clang/test/CodeGen/call-graph-section-templates.cpp b/clang/test/CodeGen/call-graph-section-templates.cpp index 39030d27a4ea9..c26170585e8fd 100644 --- a/clang/test/CodeGen/call-graph-section-templates.cpp +++ b/clang/test/CodeGen/call-graph-section-templates.cpp @@ -17,39 +17,39 @@ template <class T> class Cls2 { public: // FT-LABEL: define {{.*}} void @_ZN4Cls2I4Cls1E2f1Ev( - // FT-SAME: {{.*}} !type [[F_TCLS2F1:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F1:![0-9]+]] void f1() {} // FT-LABEL: define {{.*}} void @_ZN4Cls2I4Cls1E2f2ES0_( - // FT-SAME: {{.*}} !type [[F_TCLS2F2:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F2:![0-9]+]] void f2(T a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls2I4Cls1E2f3EPS0_( - // FT-SAME: {{.*}} !type [[F_TCLS2F3:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F3:![0-9]+]] void f3(T *a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls2I4Cls1E2f4EPKS0_( - // FT-SAME: {{.*}} !type [[F_TCLS2F4:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F4:![0-9]+]] void f4(const T *a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls2I4Cls1E2f5ERS0_( - // FT-SAME: {{.*}} !type [[F_TCLS2F5:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F5:![0-9]+]] void f5(T &a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls2I4Cls1E2f6ERKS0_( - // FT-SAME: {{.*}} !type [[F_TCLS2F6:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F6:![0-9]+]] void f6(const T &a) {} // Mixed type function pointer member T *(*fp)(T a, T *b, const T *c, T &d, const T &e); }; -// FT: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFvvE.generalized"} -// FT: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"} -// FT: [[F_TCLS2F3]] = !{i64 0, !"_ZTSFvP4Cls1E.generalized"} -// FT: [[F_TCLS2F4]] = !{i64 0, !"_ZTSFvPK4Cls1E.generalized"} -// FT: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"} -// FT: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"} +// FT: [[F_TCLS2F1]] = !{!"_ZTSFvvE.generalized"} +// FT: [[F_TCLS2F2]] = !{!"_ZTSFv4Cls1E.generalized"} +// FT: [[F_TCLS2F3]] = !{!"_ZTSFvP4Cls1E.generalized"} +// FT: [[F_TCLS2F4]] = !{!"_ZTSFvPK4Cls1E.generalized"} +// FT: [[F_TCLS2F5]] = !{!"_ZTSFvR4Cls1E.generalized"} +// FT: [[F_TCLS2F6]] = !{!"_ZTSFvRK4Cls1E.generalized"} //////////////////////////////////////////////////////////////////////////////// // Callsites (check for indirect callsite operand bundles) @@ -58,7 +58,7 @@ template <class T> T *T_func(T a, T *b, const T *c, T &d, const T &e) { return b; } // CST-LABEL: define {{.*}} @_Z3foov -// CST-SAME: {{.*}} !type [[F_TCLS2F1:![0-9]+]] +// CST-SAME: {{.*}} !callgraph [[F_TCLS2F1:![0-9]+]] void foo() { // Methods for Cls2<Cls1> is checked above within the template description. Cls2<Cls1> Obj; @@ -99,19 +99,19 @@ void foo() { } // CST-LABEL: define {{.*}} @_Z6T_funcI4Cls1EPT_S1_S2_PKS1_RS1_RS3_( -// CST-SAME: {{.*}} !type [[F_TFUNC_CLS1:![0-9]+]] +// CST-SAME: {{.*}} !callgraph [[F_TFUNC_CLS1:![0-9]+]] -// CST: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFvvE.generalized"} +// CST: [[F_TCLS2F1]] = !{!"_ZTSFvvE.generalized"} // CST: [[F_TFUNC_CLS1_CT]] = !{[[F_TFUNC_CLS1:![0-9]+]]} -// CST: [[F_TFUNC_CLS1]] = !{i64 0, !"_ZTSFP4Cls1S_S0_PKS_RS_RS1_E.generalized"} +// CST: [[F_TFUNC_CLS1]] = !{!"_ZTSFP4Cls1S_S0_PKS_RS_RS1_E.generalized"} // CST: [[F_TCLS2F1_CT]] = !{[[F_TCLS2F1:![0-9]+]]} // CST: [[F_TCLS2F2_CT]] = !{[[F_TCLS2F2:![0-9]+]]} -// CST: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"} +// CST: [[F_TCLS2F2]] = !{!"_ZTSFv4Cls1E.generalized"} // CST: [[F_TCLS2F3_CT]] = !{[[F_TCLS2F3:![0-9]+]]} -// CST: [[F_TCLS2F3]] = !{i64 0, !"_ZTSFvP4Cls1E.generalized"} +// CST: [[F_TCLS2F3]] = !{!"_ZTSFvP4Cls1E.generalized"} // CST: [[F_TCLS2F4_CT]] = !{[[F_TCLS2F4:![0-9]+]]} -// CST: [[F_TCLS2F4]] = !{i64 0, !"_ZTSFvPK4Cls1E.generalized"} +// CST: [[F_TCLS2F4]] = !{!"_ZTSFvPK4Cls1E.generalized"} // CST: [[F_TCLS2F5_CT]] = !{[[F_TCLS2F5:![0-9]+]]} -// CST: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"} +// CST: [[F_TCLS2F5]] = !{!"_ZTSFvR4Cls1E.generalized"} // CST: [[F_TCLS2F6_CT]] = !{[[F_TCLS2F6:![0-9]+]]} -// CST: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"} +// CST: [[F_TCLS2F6]] = !{!"_ZTSFvRK4Cls1E.generalized"} diff --git a/clang/test/CodeGen/call-graph-section-virtual-methods.cpp b/clang/test/CodeGen/call-graph-section-virtual-methods.cpp index afeeae146ec41..34c22c467080b 100644 --- a/clang/test/CodeGen/call-graph-section-virtual-methods.cpp +++ b/clang/test/CodeGen/call-graph-section-virtual-methods.cpp @@ -12,17 +12,17 @@ class Base { public: // FT-LABEL: define {{.*}} @_ZN4Base2vfEPc( - // FT-SAME: {{.*}} !type [[F_TVF:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TVF:![0-9]+]] virtual int vf(char *a) { return 0; }; }; class Derived : public Base { public: - // FT: define {{.*}} @_ZN7Derived2vfEPc({{.*}} !type [[F_TVF]] + // FT: define {{.*}} @_ZN7Derived2vfEPc({{.*}} !callgraph [[F_TVF]] int vf(char *a) override { return 1; }; }; - // FT: [[F_TVF]] = !{i64 0, !"_ZTSFiPcE.generalized"} + // FT: [[F_TVF]] = !{!"_ZTSFiPcE.generalized"} //////////////////////////////////////////////////////////////////////////////// // Callsites (check for indirect callsite operand bundles) @@ -53,4 +53,4 @@ class Base { } // CST: [[F_TVF_CT]] = !{[[F_TVF:![0-9]+]]} - // CST: [[F_TVF]] = !{i64 0, !"_ZTSFiPcE.generalized"} + // CST: [[F_TVF]] = !{!"_ZTSFiPcE.generalized"} diff --git a/clang/test/CodeGen/call-graph-section.c b/clang/test/CodeGen/call-graph-section.c index 69cdd59549190..94581674dc5e3 100644 --- a/clang/test/CodeGen/call-graph-section.c +++ b/clang/test/CodeGen/call-graph-section.c @@ -7,12 +7,12 @@ // RUN: -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,MS %s // CHECK-LABEL: define {{(dso_local)?}} void @foo( -// CHECK-SAME: {{.*}} !type [[F_TVOID:![0-9]+]] +// CHECK-SAME: {{.*}} !callgraph [[F_TVOID:![0-9]+]] void foo() { } // CHECK-LABEL: define {{(dso_local)?}} void @bar( -// CHECK-SAME: {{.*}} !type [[F_TVOID]] +// CHECK-SAME: {{.*}} !callgraph [[F_TVOID]] void bar() { void (*fp)() = foo; // ITANIUM: call {{.*}}, !callee_type [[F_TVOID_CT:![0-9]+]] @@ -21,19 +21,19 @@ void bar() { } // CHECK-LABEL: define {{(dso_local)?}} i32 @baz( -// CHECK-SAME: {{.*}} !type [[F_TPRIMITIVE:![0-9]+]] +// CHECK-SAME: {{.*}} !callgraph [[F_TPRIMITIVE:![0-9]+]] int baz(char a, float b, double c) { return 1; } // CHECK-LABEL: define {{(dso_local)?}} ptr @qux( -// CHECK-SAME: {{.*}} !type [[F_TPTR:![0-9]+]] +// CHECK-SAME: {{.*}} !callgraph [[F_TPTR:![0-9]+]] int *qux(char *a, float *b, double *c) { return 0; } // CHECK-LABEL: define {{(dso_local)?}} void @corge( -// CHECK-SAME: {{.*}} !type [[F_TVOID]] +// CHECK-SAME: {{.*}} !callgraph [[F_TVOID]] void corge() { int (*fp_baz)(char, float, double) = baz; // CHECK: call i32 {{.*}}, !callee_type [[F_TPRIMITIVE_CT:![0-9]+]] @@ -53,11 +53,11 @@ struct st2 { }; // CHECK-LABEL: define {{(dso_local)?}} void @stparam( -// CHECK-SAME: {{.*}} !type [[F_TSTRUCT:![0-9]+]] +// CHECK-SAME: {{.*}} !callgraph [[F_TSTRUCT:![0-9]+]] void stparam(struct st2 a, struct st2 *b) {} // CHECK-LABEL: define {{(dso_local)?}} void @stf( -// CHECK-SAME: {{.*}} !type [[F_TVOID]] +// CHECK-SAME: {{.*}} !callgraph [[F_TVOID]] void stf() { struct st1 St1; St1.fp = qux; @@ -74,20 +74,20 @@ void stf() { fp_stparam(St2, &St2); } -// ITANIUM: [[F_TVOID]] = !{i64 0, !"_ZTSFvE.generalized"} +// ITANIUM: [[F_TVOID]] = !{!"_ZTSFvE.generalized"} // ITANIUM: [[F_TVOID_CT]] = !{[[F_TVOID:![0-9]+]]} -// ITANIUM: [[F_TPRIMITIVE]] = !{i64 0, !"_ZTSFicfdE.generalized"} -// ITANIUM: [[F_TPTR]] = !{i64 0, !"_ZTSFPiPcPfPdE.generalized"} +// ITANIUM: [[F_TPRIMITIVE]] = !{!"_ZTSFicfdE.generalized"} +// ITANIUM: [[F_TPTR]] = !{!"_ZTSFPiPcPfPdE.generalized"} // ITANIUM: [[F_TPRIMITIVE_CT]] = !{[[F_TPRIMITIVE:![0-9]+]]} // ITANIUM: [[F_TPTR_CT]] = !{[[F_TPTR:![0-9]+]]} -// ITANIUM: [[F_TSTRUCT]] = !{i64 0, !"_ZTSFv3st2PS_E.generalized"} +// ITANIUM: [[F_TSTRUCT]] = !{!"_ZTSFv3st2PS_E.generalized"} // ITANIUM: [[F_TSTRUCT_CT]] = !{[[F_TSTRUCT:![0-9]+]]} -// MS: [[F_TVOID]] = !{i64 0, !"[email protected]"} +// MS: [[F_TVOID]] = !{!"[email protected]"} // MS: [[F_TVOID_CT]] = !{[[F_TVOID:![0-9]+]]} -// MS: [[F_TPRIMITIVE]] = !{i64 0, !"[email protected]"} -// MS: [[F_TPTR]] = !{i64 0, !"[email protected]"} +// MS: [[F_TPRIMITIVE]] = !{!"[email protected]"} +// MS: [[F_TPTR]] = !{!"[email protected]"} // MS: [[F_TPRIMITIVE_CT]] = !{[[F_TPRIMITIVE:![0-9]+]]} // MS: [[F_TPTR_CT]] = !{[[F_TPTR:![0-9]+]]} -// MS: [[F_TSTRUCT]] = !{i64 0, !"?6AXUst2@@PEAU0@@Z.generalized"} +// MS: [[F_TSTRUCT]] = !{!"?6AXUst2@@PEAU0@@Z.generalized"} // MS: [[F_TSTRUCT_CT]] = !{[[F_TSTRUCT:![0-9]+]]} diff --git a/clang/test/CodeGen/call-graph-section.cpp b/clang/test/CodeGen/call-graph-section.cpp index 86ed3ee2337a7..a358ff9d2d551 100644 --- a/clang/test/CodeGen/call-graph-section.cpp +++ b/clang/test/CodeGen/call-graph-section.cpp @@ -12,7 +12,7 @@ class Cls1 { public: // FT-LABEL: define {{.*}} ptr @_ZN4Cls18receiverEPcPf( - // FT-SAME: {{.*}} !type [[F_TCLS1RECEIVER:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS1RECEIVER:![0-9]+]] static int *receiver(char *a, float *b) { return 0; } }; @@ -21,51 +21,51 @@ class Cls2 { int *(*fp)(char *, float *); // FT-LABEL: define {{.*}} i32 @_ZN4Cls22f1Ecfd( - // FT-SAME: {{.*}} !type [[F_TCLS2F1:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F1:![0-9]+]] int f1(char a, float b, double c) { return 0; } // FT-LABEL: define {{.*}} ptr @_ZN4Cls22f2EPcPfPd( - // FT-SAME: {{.*}} !type [[F_TCLS2F2:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F2:![0-9]+]] int *f2(char *a, float *b, double *c) { return 0; } // FT-LABEL: define {{.*}} void @_ZN4Cls22f3E4Cls1( - // FT-SAME: {{.*}} !type [[F_TCLS2F3F4:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F3F4:![0-9]+]] void f3(Cls1 a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls22f4E4Cls1( - // FT-SAME: {{.*}} !type [[F_TCLS2F3F4]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F3F4]] void f4(const Cls1 a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls22f5EP4Cls1( - // FT-SAME: {{.*}} !type [[F_TCLS2F5:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F5:![0-9]+]] void f5(Cls1 *a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls22f6EPK4Cls1( - // FT-SAME: {{.*}} !type [[F_TCLS2F6:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F6:![0-9]+]] void f6(const Cls1 *a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls22f7ER4Cls1( - // FT-SAME: {{.*}} !type [[F_TCLS2F7:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F7:![0-9]+]] void f7(Cls1 &a) {} // FT-LABEL: define {{.*}} void @_ZN4Cls22f8ERK4Cls1( - // FT-SAME: {{.*}} !type [[F_TCLS2F8:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F8:![0-9]+]] void f8(const Cls1 &a) {} // FT-LABEL: define {{.*}} void @_ZNK4Cls22f9Ev( - // FT-SAME: {{.*}} !type [[F_TCLS2F9:![0-9]+]] + // FT-SAME: {{.*}} !callgraph [[F_TCLS2F9:![0-9]+]] void f9() const {} }; -// FT: [[F_TCLS1RECEIVER]] = !{i64 0, !"_ZTSFPiPcPfE.generalized"} -// FT: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFicfdE.generalized"} -// FT: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFPiPcPfPdE.generalized"} -// FT: [[F_TCLS2F3F4]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"} -// FT: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvP4Cls1E.generalized"} -// FT: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvPK4Cls1E.generalized"} -// FT: [[F_TCLS2F7]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"} -// FT: [[F_TCLS2F8]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"} -// FT: [[F_TCLS2F9]] = !{i64 0, !"_ZTSKFvvE.generalized"} +// FT: [[F_TCLS1RECEIVER]] = !{!"_ZTSFPiPcPfE.generalized"} +// FT: [[F_TCLS2F1]] = !{!"_ZTSFicfdE.generalized"} +// FT: [[F_TCLS2F2]] = !{!"_ZTSFPiPcPfPdE.generalized"} +// FT: [[F_TCLS2F3F4]] = !{!"_ZTSFv4Cls1E.generalized"} +// FT: [[F_TCLS2F5]] = !{!"_ZTSFvP4Cls1E.generalized"} +// FT: [[F_TCLS2F6]] = !{!"_ZTSFvPK4Cls1E.generalized"} +// FT: [[F_TCLS2F7]] = !{!"_ZTSFvR4Cls1E.generalized"} +// FT: [[F_TCLS2F8]] = !{!"_ZTSFvRK4Cls1E.generalized"} +// FT: [[F_TCLS2F9]] = !{!"_ZTSKFvvE.generalized"} //////////////////////////////////////////////////////////////////////////////// // Callsites (check for indirect callsites' callee_type metadata ) @@ -120,28 +120,28 @@ void foo() { } // CST: [[F_TCLS1RECEIVER_CT]] = !{[[F_TCLS1RECEIVER:![0-9]+]]} -// CST: [[F_TCLS1RECEIVER]] = !{i64 0, !"_ZTSFPiPcPfE.generalized"} +// CST: [[F_TCLS1RECEIVER]] = !{!"_ZTSFPiPcPfE.generalized"} // CST: [[F_TCLS2F1_CT]] = !{[[F_TCLS2F1:![0-9]+]]} -// CST: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFicfdE.generalized"} +// CST: [[F_TCLS2F1]] = !{!"_ZTSFicfdE.generalized"} // CST: [[F_TCLS2F2_CT]] = !{[[F_TCLS2F2:![0-9]+]]} -// CST: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFPiPcPfPdE.generalized"} +// CST: [[F_TCLS2F2]] = !{!"_ZTSFPiPcPfPdE.generalized"} // CST: [[F_TCLS2F3F4_CT]] = !{[[F_TCLS2F3F4:![0-9]+]]} -// CST: [[F_TCLS2F3F4]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"} +// CST: [[F_TCLS2F3F4]] = !{!"_ZTSFv4Cls1E.generalized"} // CST: [[F_TCLS2F5_CT]] = !{[[F_TCLS2F5:![0-9]+]]} -// CST: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvP4Cls1E.generalized"} +// CST: [[F_TCLS2F5]] = !{!"_ZTSFvP4Cls1E.generalized"} // CST: [[F_TCLS2F6_CT]] = !{[[F_TCLS2F6:![0-9]+]]} -// CST: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvPK4Cls1E.generalized"} +// CST: [[F_TCLS2F6]] = !{!"_ZTSFvPK4Cls1E.generalized"} // CST: [[F_TCLS2F7_CT]] = !{[[F_TCLS2F7:![0-9]+]]} -// CST: [[F_TCLS2F7]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"} +// CST: [[F_TCLS2F7]] = !{!"_ZTSFvR4Cls1E.generalized"} // CST: [[F_TCLS2F8_CT]] = !{[[F_TCLS2F8:![0-9]+]]} -// CST: [[F_TCLS2F8]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"} +// CST: [[F_TCLS2F8]] = !{!"_ZTSFvRK4Cls1E.generalized"} // CST: [[F_TCLS2F9_CT]] = !{[[F_TCLS2F9:![0-9]+]]} -// CST: [[F_TCLS2F9]] = !{i64 0, !"_ZTSKFvvE.generalized"} +// CST: [[F_TCLS2F9]] = !{!"_ZTSKFvvE.generalized"} diff --git a/llvm/docs/CalleeTypeMetadata.rst b/llvm/docs/CalleeTypeMetadata.rst deleted file mode 100644 index 45d0657966a8c..0000000000000 --- a/llvm/docs/CalleeTypeMetadata.rst +++ /dev/null @@ -1,33 +0,0 @@ -==================== -Callee Type Metadata -==================== - -Introduction -============ -This ``!callee_type`` metadata is introduced to support the generation of a call graph -section in the object file. The ``!callee_type`` metadata is used -to identify the types of the intended callees of indirect call instructions. The ``!callee_type`` metadata is a -list of one or more generalized ``!type`` metadata objects (See :doc:`TypeMetadata`) with each ``!type`` -metadata pointing to a callee's :ref:`type identifier <calleetype-type-identifier>`. -LLVM's `Control Flow Integrity (CFI)`_ also uses the ``!type`` metadata in its implementation. - -.. _Control Flow Integrity (CFI): https://clang.llvm.org/docs/ControlFlowIntegrity.html - -.. _calleetype-type-identifier: - -Type identifier -================ - -The type for an indirect call target is the callee's function signature. -Mapping from a type to an identifier is an ABI detail. -In the current implementation, an identifier of type T is -computed as follows: - - - Obtain the generalized mangled name for “typeinfo name for T”. - - Compute MD5 hash of the name as a string. - - Reinterpret the first 8 bytes of the hash as a little-endian 64-bit integer. - -To avoid mismatched pointer types, generalizations are applied. -Pointers in return and argument types are treated as equivalent as long as the qualifiers for the -type they point to match. For example, ``char*``, ``char**``, and ``int*`` are considered equivalent -types. However, ``char*`` and ``const char*`` are considered distinct types. diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 5640eec987133..4d880494eb449 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -8700,10 +8700,81 @@ change in the future. See :doc:`TypeMetadata`. +.. _metadata_callee_type: + '``callee_type``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^^^^ -See :doc:`CalleeTypeMetadata`. +The ``!callee_type`` metadata is introduced to support the generation of a call graph +section in the object file. The ``!callee_type`` metadata is used +to identify the types of the intended callees of indirect call instructions. The ``!callee_type`` metadata is a +list of one or more generalized ``!callgraph`` metadata objects (See the :ref:`metadata_callgraph` section) with each ``!callgraph`` +metadata pointing to a callee's :ref:`type identifier <calleetype-type-identifier>`. + +While ``!callee_type`` and ``!callgraph`` are private to the Call Graph Section pipeline and contain no offsets, +LLVM's `Control Flow Integrity (CFI) +<https://clang.org/docs/ControlFlowIntegrity.html>`_ uses a structurally similar ``!type`` metadata in its implementation (See :doc:`TypeMetadata`), +which shares the same type identifier format but includes a leading offset for vtable compatibility. + +.. _calleetype-type-identifier: + +Type identifier +""""""""""""""" + +The type for an indirect call target is the callee's function signature. +Mapping from a type to an identifier is an ABI detail. +In the current implementation, an identifier of type T is +computed as follows: + + - Obtain the generalized mangled name for “typeinfo name for T”. + - Compute MD5 hash of the name as a string. + - Reinterpret the first 8 bytes of the hash as a little-endian 64-bit integer. + +To avoid mismatched pointer types, generalizations are applied. +Pointers in return and argument types are treated as equivalent as long as the qualifiers for the +type they point to match. For example, ``char*``, ``char**``, and ``int*`` are considered equivalent +types. However, ``char*`` and ``const char*`` are considered distinct types. + +.. _metadata_callgraph: + +'``callgraph``' Metadata +^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``!callgraph`` metadata associates a function definition with its type +identifier. It uses the same generalized type encoding as the ``!type`` metadata +used for CFI and WPD, and allows us to emit a call graph section in the object +file that can be used to compute a conservative and precise static call graph +in a linked binary. + +Syntax: +""""""" + +A ``!callgraph`` metadata node is attached to a function definition as follows: + +.. code-block:: llvm + + define void @foo() !callgraph !0 + !0 = !{!"_ZTSFvvE.generalized"} + +The metadata node is a 1-element tuple containing only the generalized type +identifier as ``MDString``. + +Relation to Control Flow Integrity (CFI) +"""""""""""""""""""""""""""""""""""""""" + +While ``!callgraph`` metadata is structurally similar to LLVM's ``!type`` +metadata (which is used by `Control Flow Integrity (CFI) +<https://clang.org/docs/ControlFlowIntegrity.html>`_ and Whole Program +Devirtualization), they serve diff erent purposes: + +* ``!type`` (CFI): Contains an offset (e.g., ``!{i64 0, !"_ZTSFvvE.generalized"}``) + to support virtual table offset calculations and devirtualization. +* ``!callgraph`` (Call Graph Section): Does not contain an offset. This is + private to the Call Graph Section pipeline. + +The generalized type identifier format used by both is identical. For more +details on the generalized type identifier format and CFI's metadata, see +:doc:`TypeMetadata` and :ref:`metadata_callee_type`. '``associated``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/llvm/docs/Reference.md b/llvm/docs/Reference.md index 1bbdc8f4582dd..24a3fe88106d4 100644 --- a/llvm/docs/Reference.md +++ b/llvm/docs/Reference.md @@ -53,7 +53,6 @@ MLGO ContentAddressableStorage CIBestPractices AIToolPolicy -CalleeTypeMetadata CallGraphSection InterfaceExportAnnotations PCSectionsMetadata diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index fdf3fddd1fef9..fd4156032bfc1 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -102,6 +102,11 @@ Makes programs 10x faster by doing Special New Thing. outlining. Add the `noinline` and `nooutline` attributes as well in cases where inlining and outlining should additionally be disabled. +* Added support for ``callgraph`` metadata. The `!callgraph` metadata + associates a function definition with its type identifier and is used for call + graph section generation. See the [callgraph Metadata](https://llvm.org/docs/LangRef.html#callgraph-metadata) + section of the LangRef for details. + ### Changes to LLVM infrastructure * Removed ``Constant::isZeroValue``. It was functionally identical to diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def index 6271633ca6d66..cb6ebfb5c0fb5 100644 --- a/llvm/include/llvm/IR/FixedMetadataKinds.def +++ b/llvm/include/llvm/IR/FixedMetadataKinds.def @@ -65,3 +65,5 @@ LLVM_FIXED_MD_KIND(MD_elf_section_properties, "elf_section_properties", 50) LLVM_FIXED_MD_KIND(MD_unique_id, "guid", 51) LLVM_FIXED_MD_KIND(MD_mem_cache_hint, "mem.cache_hint", 52) LLVM_FIXED_MD_KIND(MD_block_uniformity_profile, "block.uniformity.profile", 53) +LLVM_FIXED_MD_KIND(MD_callgraph, "callgraph", 54) + diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index b9288740a7145..73adeb3416ab1 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -1255,13 +1255,6 @@ class MDNode : public Metadata { bool isReplaceable() const { return isTemporary() || isAlwaysReplaceable(); } bool isAlwaysReplaceable() const { return getMetadataID() == DIAssignIDKind; } - /// Check if this is a valid generalized type metadata node. - bool hasGeneralizedMDString() { - if (getNumOperands() < 2 || !isa<MDString>(getOperand(1))) - return false; - return cast<MDString>(getOperand(1))->getString().ends_with(".generalized"); - } - unsigned getNumTemporaryUses() const { assert(isTemporary() && "Only for temporaries"); return Context.getReplaceableUses()->getNumUses(); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index aedc4956f1bd8..abb20a7919fa1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1752,16 +1752,18 @@ void AsmPrinter::emitStackUsage(const MachineFunction &MF) { } /// Extracts a generalized numeric type identifier of a Function's type from -/// type metadata. Returns null if metadata cannot be found. +/// callgraph metadata. Returns null if metadata cannot be found. static ConstantInt *extractNumericCGTypeId(const Function &F) { SmallVector<MDNode *, 2> Types; - F.getMetadata(LLVMContext::MD_type, Types); + F.getMetadata(LLVMContext::MD_callgraph, Types); for (const auto &Type : Types) { - if (Type->hasGeneralizedMDString()) { - MDString *MDGeneralizedTypeId = cast<MDString>(Type->getOperand(1)); - uint64_t TypeIdVal = llvm::MD5Hash(MDGeneralizedTypeId->getString()); - IntegerType *Int64Ty = Type::getInt64Ty(F.getContext()); - return ConstantInt::get(Int64Ty, TypeIdVal); + if (Type->getNumOperands() == 1 && isa<MDString>(Type->getOperand(0))) { + MDString *MDGeneralizedTypeId = cast<MDString>(Type->getOperand(0)); + if (MDGeneralizedTypeId->getString().ends_with(".generalized")) { + uint64_t TypeIdVal = llvm::MD5Hash(MDGeneralizedTypeId->getString()); + IntegerType *Int64Ty = Type::getInt64Ty(F.getContext()); + return ConstantInt::get(Int64Ty, TypeIdVal); + } } } return nullptr; diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index b0ffdb36f21be..bbc5041a9166d 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -758,7 +758,7 @@ MachineFunction::CallSiteInfo::CallSiteInfo(const CallBase &CB) { for (const MDOperand &Op : CalleeTypeList->operands()) { MDNode *TypeMD = cast<MDNode>(Op); - MDString *TypeIdStr = cast<MDString>(TypeMD->getOperand(1)); + MDString *TypeIdStr = cast<MDString>(TypeMD->getOperand(0)); // Compute numeric type id from generalized type id string uint64_t TypeIdVal = MD5Hash(TypeIdStr->getString()); IntegerType *Int64Ty = Type::getInt64Ty(CB.getContext()); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index a4e0f531ab1ef..88d99750048d5 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -5428,28 +5428,25 @@ void Verifier::visitCallsiteMetadata(Instruction &I, MDNode *MD) { visitCallStackMetadata(MD); } -static inline bool isConstantIntMetadataOperand(const Metadata *MD) { - if (auto *VAL = dyn_cast<ValueAsMetadata>(MD)) - return isa<ConstantInt>(VAL->getValue()); - return false; -} - void Verifier::visitCalleeTypeMetadata(Instruction &I, MDNode *MD) { Check(isa<CallBase>(I), "!callee_type metadata should only exist on calls", &I); for (Metadata *Op : MD->operands()) { Check(isa<MDNode>(Op), - "The callee_type metadata must be a list of type metadata nodes", Op); - auto *TypeMD = cast<MDNode>(Op); - Check(TypeMD->getNumOperands() == 2, - "Well-formed generalized type metadata must contain exactly two " - "operands", + "The callee_type metadata must be a list of callgraph metadata nodes", + Op); + auto *CallgraphMD = cast<MDNode>(Op); + Check(CallgraphMD->getNumOperands() == 1, + "Well-formed generalized callgraph metadata must contain exactly one " + "operand", + Op); + Check(isa<MDString>(CallgraphMD->getOperand(0)), + "The operand of callgraph metadata for functions must be an MDString", Op); - Check(isConstantIntMetadataOperand(TypeMD->getOperand(0)) && - mdconst::extract<ConstantInt>(TypeMD->getOperand(0))->isZero(), - "The first operand of type metadata for functions must be zero", Op); - Check(TypeMD->hasGeneralizedMDString(), - "Only generalized type metadata can be part of the callee_type " + Check(cast<MDString>(CallgraphMD->getOperand(0)) + ->getString() + .ends_with(".generalized"), + "Only generalized callgraph metadata can be part of the callee_type " "metadata list", Op); } diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index 5c8624ba56a27..0b2315faaeb94 100644 --- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -805,6 +805,7 @@ void MergeFunctions::writeThunk(Function *F, Function *G) { // Ensure CFI type metadata is propagated to the new function. copyMetadataIfPresent(G, NewG, "type"); copyMetadataIfPresent(G, NewG, "kcfi_type"); + copyMetadataIfPresent(G, NewG, "callgraph"); removeUsers(G); G->replaceAllUsesWith(NewG); G->eraseFromParent(); @@ -902,6 +903,7 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) { // Ensure CFI type metadata is propagated to the new function. copyMetadataIfPresent(F, NewF, "type"); copyMetadataIfPresent(F, NewF, "kcfi_type"); + copyMetadataIfPresent(F, NewF, "callgraph"); removeUsers(F); F->replaceAllUsesWith(NewF); diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp index c14c9b869525d..a486979a58c2d 100644 --- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp +++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp @@ -169,6 +169,22 @@ void promoteTypeIds(Module &M, StringRef ModuleId) { LLVMContext::MD_type, *MDNode::get(M.getContext(), {MD->getOperand(0), I->second})); } + + SmallVector<MDNode *, 1> CGMDs; + GO.getMetadata(LLVMContext::MD_callgraph, CGMDs); + + GO.eraseMetadata(LLVMContext::MD_callgraph); + for (auto *MD : CGMDs) { + if (MD->getNumOperands() == 1) { + auto I = LocalToGlobal.find(MD->getOperand(0)); + if (I == LocalToGlobal.end()) { + GO.addMetadata(LLVMContext::MD_callgraph, *MD); + continue; + } + GO.addMetadata(LLVMContext::MD_callgraph, + *MDNode::get(M.getContext(), {I->second})); + } + } } } diff --git a/llvm/test/Assembler/callee-type-metadata.ll b/llvm/test/Assembler/callee-type-metadata.ll index 9c3cfbe82fc13..305aedd0b2895 100644 --- a/llvm/test/Assembler/callee-type-metadata.ll +++ b/llvm/test/Assembler/callee-type-metadata.ll @@ -16,6 +16,6 @@ entry: declare !type !2 i32 @_Z3barc(i8 signext) -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll index c4c54175ecd9f..7aae1783de2cb 100644 --- a/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll +++ b/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll @@ -7,7 +7,7 @@ ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } -define i32 @foo(i32 %x, i32 %y) !type !0 { +define i32 @foo(i32 %x, i32 %y) !callgraph !0 { entry: ;; Call instruction with accurate callee_type. ;; callee_type should be dropped seemlessly. @@ -23,10 +23,10 @@ entry: ret i32 %sub } -declare !type !2 i32 @fizz(i32, i32) +declare !callgraph !2 i32 @fizz(i32, i32) -!0 = !{i64 0, !"_ZTSFiiiiE.generalized"} +!0 = !{!"_ZTSFiiiiE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFiiiE.generalized"} +!2 = !{!"_ZTSFiiiE.generalized"} !3 = !{!4} -!4 = !{i64 0, !"_ZTSFicE.generalized"} +!4 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll index b47607ec135ae..780a67695a170 100644 --- a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll +++ b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll @@ -5,7 +5,7 @@ ;; computed as the type id from the callee_type metadata. ; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s -define i32 @check_tailcall(ptr %func, i8 %x) !type !0 { +define i32 @check_tailcall(ptr %func, i8 %x) !callgraph !0 { entry: ; CHECK: callSites: ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds: @@ -14,6 +14,6 @@ entry: ret i32 %call } -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll index 94b657c6ea908..c918558d8bd82 100644 --- a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll +++ b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll @@ -17,4 +17,4 @@ entry: } !0 = !{!1} -!1 = !{i64 0, !"_ZTSFvcE.generalized"} +!1 = !{!"_ZTSFvcE.generalized"} diff --git a/llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll b/llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll index 9e243aec1128d..3ffdb65aed8dc 100644 --- a/llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll +++ b/llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll @@ -5,16 +5,16 @@ ; RUN: llc -mtriple=arm-unknown-linux --call-graph-section -o - < %s | FileCheck %s -declare !type !0 void @_Z6doWorkPFviE(ptr) +declare !callgraph !0 void @_Z6doWorkPFviE(ptr) -define i32 @_Z4testv() !type !1 { +define i32 @_Z4testv() !callgraph !1 { entry: call void @_Z6doWorkPFviE(ptr nonnull @_ZL10myCallbacki) ret i32 0 } ; CHECK: _ZL10myCallbacki: -define internal void @_ZL10myCallbacki(i32 %value) !type !2 { +define internal void @_ZL10myCallbacki(i32 %value) !callgraph !2 { entry: %sink = alloca i32, align 4 store volatile i32 %value, ptr %sink, align 4 @@ -22,9 +22,9 @@ entry: ret void } -!0 = !{i64 0, !"_ZTSFvPFviEE.generalized"} -!1 = !{i64 0, !"_ZTSFivE.generalized"} -!2 = !{i64 0, !"_ZTSFviE.generalized"} +!0 = !{!"_ZTSFvPFviEE.generalized"} +!1 = !{!"_ZTSFivE.generalized"} +!2 = !{!"_ZTSFviE.generalized"} ; CHECK: .section .llvm.callgraph,"o",%llvm_call_graph,.text ;; Version diff --git a/llvm/test/CodeGen/ARM/call-graph-section-assembly.ll b/llvm/test/CodeGen/ARM/call-graph-section-assembly.ll index 8e8881ee722fb..74000dc4337bc 100644 --- a/llvm/test/CodeGen/ARM/call-graph-section-assembly.ll +++ b/llvm/test/CodeGen/ARM/call-graph-section-assembly.ll @@ -6,9 +6,9 @@ ; RUN: llc -mtriple=arm-unknown-linux --call-graph-section -o - < %s | FileCheck %s -declare !type !0 void @direct_foo() -declare !type !1 i32 @direct_bar(i8) -declare !type !2 ptr @direct_baz(ptr) +declare !callgraph !0 void @direct_foo() +declare !callgraph !1 i32 @direct_bar(i8) +declare !callgraph !2 ptr @direct_baz(ptr) ; CHECK: ball: define ptr @ball() { @@ -29,11 +29,11 @@ entry: } !0 = !{!1} -!1 = !{i64 0, !"_ZTSFvE.generalized"} +!1 = !{!"_ZTSFvE.generalized"} !2 = !{!3} -!3 = !{i64 0, !"_ZTSFicE.generalized"} +!3 = !{!"_ZTSFicE.generalized"} !4 = !{!5} -!5 = !{i64 0, !"_ZTSFPvS_E.generalized"} +!5 = !{!"_ZTSFPvS_E.generalized"} ; CHECK: .section .llvm.callgraph,"o",%llvm_call_graph,.text ;; Version diff --git a/llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll b/llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll index 35e570bdde405..eeceea7bc73ab 100644 --- a/llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll +++ b/llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll @@ -3,13 +3,13 @@ ; RUN: llc -mtriple=arm-unknown-linux --call-graph-section -filetype=obj -o - < %s | \ ; RUN: llvm-readelf -x .llvm.callgraph - | FileCheck %s -define i32 @check_tailcall(ptr %func, i8 %x) !type !0 { +define i32 @check_tailcall(ptr %func, i8 %x) !callgraph !0 { entry: %call = tail call i32 %func(i8 signext %x), !callee_type !1 ret i32 %call } -define i32 @main(i32 %argc) !type !3 { +define i32 @main(i32 %argc) !callgraph !3 { entry: %andop = and i32 %argc, 1 %cmp = icmp eq i32 %andop, 0 @@ -18,14 +18,14 @@ entry: ret i32 %call.i } -declare !type !2 i32 @foo(i8 signext) +declare !callgraph !2 i32 @foo(i8 signext) -declare !type !2 i32 @bar(i8 signext) +declare !callgraph !2 i32 @bar(i8 signext) -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} -!3 = !{i64 0, !"_ZTSFiiE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} +!3 = !{!"_ZTSFiiE.generalized"} ; CHECK: Hex dump of section '.llvm.callgraph': ; CHECK-NEXT: 0x00000000 00050000 00008e19 0b7f3326 e3000154 diff --git a/llvm/test/CodeGen/ARM/call-graph-section.ll b/llvm/test/CodeGen/ARM/call-graph-section.ll index 167cc6f3c73bd..4d7b3f44b9353 100644 --- a/llvm/test/CodeGen/ARM/call-graph-section.ll +++ b/llvm/test/CodeGen/ARM/call-graph-section.ll @@ -3,11 +3,11 @@ ; RUN: llc -mtriple=arm-unknown-linux --call-graph-section -filetype=obj -o - < %s | \ ; RUN: llvm-readelf -x .llvm.callgraph - | FileCheck %s -declare !type !0 void @foo() +declare !callgraph !0 void @foo() -declare !type !1 i32 @bar(i8) +declare !callgraph !1 i32 @bar(i8) -declare !type !2 ptr @baz(ptr) +declare !callgraph !2 ptr @baz(ptr) define void @main() { entry: @@ -22,12 +22,12 @@ entry: ;; Check that the numeric type id (md5 hash) for the below type ids are emitted ;; to the callgraph section. -!0 = !{i64 0, !"_ZTSFvE.generalized"} +!0 = !{!"_ZTSFvE.generalized"} !1 = !{!0} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} !3 = !{!2} !4 = !{!5} -!5 = !{i64 0, !"_ZTSFPvS_E.generalized"} +!5 = !{!"_ZTSFPvS_E.generalized"} ;; Make sure following type IDs are in call graph section ;; 0x5eecb3e2444f731f, 0x814b8e305486bc59, 0xf897fd777ade6814 diff --git a/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll index 8f7b0506a5e39..6a474227e2b42 100644 --- a/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll +++ b/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll @@ -7,7 +7,7 @@ ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } -define i32 @foo(i32 %x, i32 %y) !type !0 { +define i32 @foo(i32 %x, i32 %y) !callgraph !0 { entry: ;; Call instruction with accurate callee_type. ;; callee_type should be dropped seemlessly. @@ -23,10 +23,10 @@ entry: ret i32 %sub } -declare !type !2 i32 @fizz(i32, i32) +declare !callgraph !2 i32 @fizz(i32, i32) -!0 = !{i64 0, !"_ZTSFiiiiE.generalized"} +!0 = !{!"_ZTSFiiiiE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFiiiE.generalized"} +!2 = !{!"_ZTSFiiiE.generalized"} !3 = !{!4} -!4 = !{i64 0, !"_ZTSFicE.generalized"} +!4 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll index 05e1e8bf0502b..5233da75435ab 100644 --- a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll +++ b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll @@ -5,7 +5,7 @@ ;; computed as the type id from the callee_type metadata. ; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s -define i32 @check_tailcall(ptr %func, i8 %x) !type !0 { +define i32 @check_tailcall(ptr %func, i8 %x) !callgraph !0 { entry: ; CHECK: callSites: ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds: @@ -14,6 +14,6 @@ entry: ret i32 %call } -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll index a65e5c5f8c015..7e1ab0068ff07 100644 --- a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll +++ b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll @@ -17,4 +17,4 @@ entry: } !0 = !{!1} -!1 = !{i64 0, !"_ZTSFvcE.generalized"} +!1 = !{!"_ZTSFvcE.generalized"} diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-ambiguous-indirect-call-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-ambiguous-indirect-call-typeid.mir index cb78898f3a0d4..5573be87fbb2d 100644 --- a/llvm/test/CodeGen/MIR/X86/call-site-info-ambiguous-indirect-call-typeid.mir +++ b/llvm/test/CodeGen/MIR/X86/call-site-info-ambiguous-indirect-call-typeid.mir @@ -16,8 +16,8 @@ } !0 = !{!1, !2} - !1 = !{i64 0, !"callee_type0.generalized"} - !2 = !{i64 0, !"callee_type2.generalized"} + !1 = !{!"callee_type0.generalized"} + !2 = !{!"callee_type2.generalized"} ... --- name: ambiguous_caller diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir index 303b8fac22a9c..dd835abab5256 100644 --- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir +++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir @@ -16,7 +16,7 @@ } !0 = !{!1} - !1 = !{i64 0, !"_ZTSFvcE.generalized"} + !1 = !{!"_ZTSFvcE.generalized"} ... --- name: call_foo diff --git a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll index fe1980e3f5605..c49d8152a7751 100644 --- a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll +++ b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll @@ -86,4 +86,4 @@ entry: } !0 = !{!1} -!1 = !{i64 0, !"_ZTSFvcE.generalized"} +!1 = !{!"_ZTSFvcE.generalized"} diff --git a/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll index a66a884dc844e..1a1bc63b24a97 100644 --- a/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll +++ b/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll @@ -7,7 +7,7 @@ ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } -define i32 @foo(i32 %x, i32 %y) !type !0 { +define i32 @foo(i32 %x, i32 %y) !callgraph !0 { entry: ;; Call instruction with accurate callee_type. ;; callee_type should be dropped seemlessly. @@ -23,10 +23,10 @@ entry: ret i32 %sub } -declare !type !2 i32 @fizz(i32, i32) +declare !callgraph !2 i32 @fizz(i32, i32) -!0 = !{i64 0, !"_ZTSFiiiiE.generalized"} +!0 = !{!"_ZTSFiiiiE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFiiiE.generalized"} +!2 = !{!"_ZTSFiiiE.generalized"} !3 = !{!4} -!4 = !{i64 0, !"_ZTSFicE.generalized"} +!4 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll index e7f162c6daa77..efe2fb91a85fa 100644 --- a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll +++ b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll @@ -5,7 +5,7 @@ ;; computed as the type id from the callee_type metadata. ; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s -define i32 @check_tailcall(ptr %func, i8 %x) !type !0 { +define i32 @check_tailcall(ptr %func, i8 %x) !callgraph !0 { entry: ; CHECK: callSites: ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds: @@ -14,6 +14,6 @@ entry: ret i32 %call } -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll index 9f5e858412ed6..1b0c885bb8e44 100644 --- a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll +++ b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll @@ -17,4 +17,4 @@ entry: } !0 = !{!1} -!1 = !{i64 0, !"_ZTSFvcE.generalized"} +!1 = !{!"_ZTSFvcE.generalized"} diff --git a/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll index 34493cec0eab0..9bdb6cef6714f 100644 --- a/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll +++ b/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll @@ -8,7 +8,7 @@ ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } -define i32 @foo(i32 %x, i32 %y) !type !0 { +define i32 @foo(i32 %x, i32 %y) !callgraph !0 { entry: ;; Call instruction with accurate callee_type. ;; callee_type should be dropped seemlessly. @@ -24,10 +24,10 @@ entry: ret i32 %sub } -declare !type !2 i32 @fizz(i32, i32) +declare !callgraph !2 i32 @fizz(i32, i32) -!0 = !{i64 0, !"_ZTSFiiiiE.generalized"} +!0 = !{!"_ZTSFiiiiE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFiiiE.generalized"} +!2 = !{!"_ZTSFiiiE.generalized"} !3 = !{!4} -!4 = !{i64 0, !"_ZTSFicE.generalized"} +!4 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll index 6e1fe92dac8f7..5b17a8a56664c 100644 --- a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll +++ b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll @@ -6,7 +6,7 @@ ; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s ; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s -define i32 @check_tailcall(ptr %func, i8 %x) !type !0 { +define i32 @check_tailcall(ptr %func, i8 %x) !callgraph !0 { entry: ; CHECK: callSites: ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds: @@ -15,6 +15,6 @@ entry: ret i32 %call } -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll index 1f91f4103abbb..ec7f4abc0bc2d 100644 --- a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll +++ b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll @@ -18,4 +18,4 @@ entry: } !0 = !{!1} -!1 = !{i64 0, !"_ZTSFvcE.generalized"} +!1 = !{!"_ZTSFvcE.generalized"} diff --git a/llvm/test/CodeGen/X86/call-graph-section-addrtaken.ll b/llvm/test/CodeGen/X86/call-graph-section-addrtaken.ll index ab8498d8d3451..06daa8fa38810 100644 --- a/llvm/test/CodeGen/X86/call-graph-section-addrtaken.ll +++ b/llvm/test/CodeGen/X86/call-graph-section-addrtaken.ll @@ -5,16 +5,16 @@ ; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -o - < %s | FileCheck %s -declare !type !0 void @_Z6doWorkPFviE(ptr) +declare !callgraph !0 void @_Z6doWorkPFviE(ptr) -define i32 @_Z4testv() !type !1 { +define i32 @_Z4testv() !callgraph !1 { entry: call void @_Z6doWorkPFviE(ptr nonnull @_ZL10myCallbacki) ret i32 0 } ; CHECK: _ZL10myCallbacki: -define internal void @_ZL10myCallbacki(i32 %value) !type !2 { +define internal void @_ZL10myCallbacki(i32 %value) !callgraph !2 { entry: %sink = alloca i32, align 4 store volatile i32 %value, ptr %sink, align 4 @@ -22,9 +22,9 @@ entry: ret void } -!0 = !{i64 0, !"_ZTSFvPFviEE.generalized"} -!1 = !{i64 0, !"_ZTSFivE.generalized"} -!2 = !{i64 0, !"_ZTSFviE.generalized"} +!0 = !{!"_ZTSFvPFviEE.generalized"} +!1 = !{!"_ZTSFivE.generalized"} +!2 = !{!"_ZTSFviE.generalized"} ; CHECK: .section .llvm.callgraph,"o",@llvm_call_graph,.text ;; Version diff --git a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll index 02d71073b65c5..38e2c9cbc3b47 100644 --- a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll +++ b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll @@ -6,9 +6,9 @@ ; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -o - < %s | FileCheck %s -declare !type !0 void @direct_foo() -declare !type !1 i32 @direct_bar(i8) -declare !type !2 ptr @direct_baz(ptr) +declare !callgraph !0 void @direct_foo() +declare !callgraph !1 i32 @direct_bar(i8) +declare !callgraph !2 ptr @direct_baz(ptr) ; CHECK: ball: define ptr @ball() { @@ -29,11 +29,11 @@ entry: } !0 = !{!1} -!1 = !{i64 0, !"_ZTSFvE.generalized"} +!1 = !{!"_ZTSFvE.generalized"} !2 = !{!3} -!3 = !{i64 0, !"_ZTSFicE.generalized"} +!3 = !{!"_ZTSFicE.generalized"} !4 = !{!5} -!5 = !{i64 0, !"_ZTSFPvS_E.generalized"} +!5 = !{!"_ZTSFPvS_E.generalized"} ; CHECK: .section .llvm.callgraph,"o",@llvm_call_graph,.text ;; Version diff --git a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll index 49cc335bf7379..753995a9733bf 100644 --- a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll +++ b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll @@ -6,13 +6,13 @@ ; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -filetype=obj -o - < %s | \ ; RUN: llvm-readelf -x .llvm.callgraph - | FileCheck %s -define i32 @check_tailcall(ptr %func, i8 %x) !type !0 { +define i32 @check_tailcall(ptr %func, i8 %x) !callgraph !0 { entry: %call = tail call i32 %func(i8 signext %x), !callee_type !1 ret i32 %call } -define i32 @main(i32 %argc) !type !3 { +define i32 @main(i32 %argc) !callgraph !3 { entry: %andop = and i32 %argc, 1 %cmp = icmp eq i32 %andop, 0 @@ -21,14 +21,14 @@ entry: ret i32 %call.i } -declare !type !2 i32 @foo(i8 signext) +declare !callgraph !2 i32 @foo(i8 signext) -declare !type !2 i32 @bar(i8 signext) +declare !callgraph !2 i32 @bar(i8 signext) -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} -!3 = !{i64 0, !"_ZTSFiiE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} +!3 = !{!"_ZTSFiiE.generalized"} ; CHECK: Hex dump of section '.llvm.callgraph': ; CHECK-NEXT: 0x00000000 00050000 00000000 00008e19 0b7f3326 diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll index 8a1c6ca627cb5..2f08b0edc9ebf 100644 --- a/llvm/test/CodeGen/X86/call-graph-section.ll +++ b/llvm/test/CodeGen/X86/call-graph-section.ll @@ -6,11 +6,11 @@ ; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -filetype=obj -o - < %s | \ ; RUN: llvm-readelf -x .llvm.callgraph - | FileCheck %s -declare !type !0 void @foo() +declare !callgraph !0 void @foo() -declare !type !1 i32 @bar(i8) +declare !callgraph !1 i32 @bar(i8) -declare !type !2 ptr @baz(ptr) +declare !callgraph !2 ptr @baz(ptr) define void @main() { entry: @@ -25,12 +25,12 @@ entry: ;; Check that the numeric type id (md5 hash) for the below type ids are emitted ;; to the callgraph section. -!0 = !{i64 0, !"_ZTSFvE.generalized"} +!0 = !{!"_ZTSFvE.generalized"} !1 = !{!0} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} !3 = !{!2} !4 = !{!5} -!5 = !{i64 0, !"_ZTSFPvS_E.generalized"} +!5 = !{!"_ZTSFPvS_E.generalized"} ;; Make sure following type IDs are in call graph section ;; 0x5eecb3e2444f731f, 0x814b8e305486bc59, 0xf897fd777ade6814 diff --git a/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll index 7881ea7d59314..92d783055d3ba 100644 --- a/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll +++ b/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll @@ -7,7 +7,7 @@ ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } ; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] } -define i32 @foo(i32 %x, i32 %y) !type !0 { +define i32 @foo(i32 %x, i32 %y) !callgraph !0 { entry: ;; Call instruction with accurate callee_type. ;; callee_type should be dropped seemlessly. @@ -23,10 +23,10 @@ entry: ret i32 %sub } -declare !type !2 i32 @fizz(i32, i32) +declare !callgraph !2 i32 @fizz(i32, i32) -!0 = !{i64 0, !"_ZTSFiiiiE.generalized"} +!0 = !{!"_ZTSFiiiiE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFiiiE.generalized"} +!2 = !{!"_ZTSFiiiE.generalized"} !3 = !{!4} -!4 = !{i64 0, !"_ZTSFicE.generalized"} +!4 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll index 8f6b7a6d7f240..91fc652c8b05e 100644 --- a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll +++ b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll @@ -5,7 +5,7 @@ ;; computed as the type id from the callee_type metadata. ; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s -define i32 @check_tailcall(ptr %func, i8 %x) !type !0 { +define i32 @check_tailcall(ptr %func, i8 %x) !callgraph !0 { entry: ; CHECK: callSites: ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds: @@ -14,6 +14,6 @@ entry: ret i32 %call } -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll index e97a6ac75e111..5981b58bdf7e9 100644 --- a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll +++ b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll @@ -17,4 +17,4 @@ entry: } !0 = !{!1} -!1 = !{i64 0, !"_ZTSFvcE.generalized"} +!1 = !{!"_ZTSFvcE.generalized"} diff --git a/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll b/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll index 547588089c5b0..5495441a45738 100644 --- a/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll +++ b/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll @@ -29,13 +29,13 @@ entry: } declare !type !2 i32 @_Z3fooc(i8 signext) -!0 = !{i64 0, !"_ZTSFiPvcE.generalized"} +!0 = !{!"_ZTSFiPvcE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} -!3 = !{i64 0, !"_ZTSFivE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} +!3 = !{!"_ZTSFivE.generalized"} ;. -; CHECK: [[META0]] = !{i64 0, !"_ZTSFiPvcE.generalized"} +; CHECK: [[META0]] = !{!"_ZTSFiPvcE.generalized"} ; CHECK: [[META1]] = !{[[META2:![0-9]+]]} -; CHECK: [[META2]] = !{i64 0, !"_ZTSFicE.generalized"} -; CHECK: [[META3]] = !{i64 0, !"_ZTSFivE.generalized"} +; CHECK: [[META2]] = !{!"_ZTSFicE.generalized"} +; CHECK: [[META3]] = !{!"_ZTSFivE.generalized"} ;. diff --git a/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll index 83215f78be1b0..e5296f96690f5 100644 --- a/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll +++ b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll @@ -17,9 +17,9 @@ entry: declare !type !2 i32 @_Z3fooc(i8 signext) -!0 = !{i64 0, !"_ZTSFivE.generalized"} +!0 = !{!"_ZTSFivE.generalized"} !1 = !{!2} -!2 = !{i64 0, !"_ZTSFicE.generalized"} +!2 = !{!"_ZTSFicE.generalized"} ;. -; CHECK: [[META0]] = !{i64 0, !"_ZTSFivE.generalized"} +; CHECK: [[META0]] = !{!"_ZTSFivE.generalized"} ;. diff --git a/llvm/test/Transforms/MergeFunc/callgraph-function-merging.ll b/llvm/test/Transforms/MergeFunc/callgraph-function-merging.ll new file mode 100644 index 0000000000000..0202412f62fa3 --- /dev/null +++ b/llvm/test/Transforms/MergeFunc/callgraph-function-merging.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -passes=mergefunc < %s | FileCheck %s + +; Verify that !callgraph metadata is correctly preserved and copied to the new +; thunk/backing functions when two identical functions are merged, and that +; the metadata nodes are correctly uniqued. + +declare void @dummy() + +; CHECK: define void @func1(ptr {{.*}}) {{.*}} !callgraph [[MD:![0-9]+]] { +; CHECK: define void @func2(ptr {{.*}}) {{.*}} !callgraph [[MD]] { + +define void @func1(ptr %a) unnamed_addr !callgraph !0 { + call void @dummy() + ret void +} + +define void @func2(ptr %a) unnamed_addr !callgraph !1 { + call void @dummy() + ret void +} + +!0 = !{!"_ZTSFvPvE.generalized"} +!1 = !{!"_ZTSFvPvE.generalized"} + +; CHECK: [[MD]] = !{!"_ZTSFvPvE.generalized"} diff --git a/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll b/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll index 3e56939b1642f..03bfb8e31d0b9 100644 --- a/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll +++ b/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll @@ -150,18 +150,18 @@ if.end: ; preds = %if.else, %if.then declare ptr @_Znwm(i64) -!0 = !{i64 0, !"callee_type0.generalized"} -!1 = !{i64 0, !"callee_type1.generalized"} -!2 = !{i64 0, !"callee_type2.generalized"} +!0 = !{!"callee_type0.generalized"} +!1 = !{!"callee_type1.generalized"} +!2 = !{!"callee_type2.generalized"} !3 = !{!0} !4 = !{!2} !5 = !{!1, !2} !6 = !{!0, !2} ;. ; CHECK: [[META0]] = !{[[META1:![0-9]+]], [[META2:![0-9]+]]} -; CHECK: [[META1]] = !{i64 0, !"callee_type2.generalized"} -; CHECK: [[META2]] = !{i64 0, !"callee_type0.generalized"} +; CHECK: [[META1]] = !{!"callee_type2.generalized"} +; CHECK: [[META2]] = !{!"callee_type0.generalized"} ; CHECK: [[META3]] = !{[[META2]]} ; CHECK: [[META4]] = !{[[META2]], [[META1]], [[META5:![0-9]+]]} -; CHECK: [[META5]] = !{i64 0, !"callee_type1.generalized"} +; CHECK: [[META5]] = !{!"callee_type1.generalized"} ;. diff --git a/llvm/test/Verifier/callee-type-metadata.ll b/llvm/test/Verifier/callee-type-metadata.ll index 50cf37b941fe9..e40d36ae0f234 100644 --- a/llvm/test/Verifier/callee-type-metadata.ll +++ b/llvm/test/Verifier/callee-type-metadata.ll @@ -9,16 +9,14 @@ entry: store i8 %x, ptr %x.addr, align 1 %fptr = load ptr, ptr %func.addr, align 8 %x_val = load i8, ptr %x.addr, align 1 - ; CHECK: The callee_type metadata must be a list of type metadata nodes + ; CHECK: The callee_type metadata must be a list of callgraph metadata nodes %call = call i32 %fptr(i8 signext %x_val), !callee_type !0 - ; CHECK: Well-formed generalized type metadata must contain exactly two operands + ; CHECK: The operand of callgraph metadata for functions must be an MDString %call1 = call i32 %fptr(i8 signext %x_val), !callee_type !2 - ; CHECK: The first operand of type metadata for functions must be zero + ; CHECK: Well-formed generalized callgraph metadata must contain exactly one operand %call2 = call i32 %fptr(i8 signext %x_val), !callee_type !4 - ; CHECK: The first operand of type metadata for functions must be zero + ; CHECK: Only generalized callgraph metadata can be part of the callee_type metadata list %call3 = call i32 %fptr(i8 signext %x_val), !callee_type !6 - ; CHECK: Only generalized type metadata can be part of the callee_type metadata list - %call4 = call i32 %fptr(i8 signext %x_val), !callee_type !8 ret i32 %call } @@ -27,7 +25,5 @@ entry: !2 = !{!2} !3 = !{i64 1, !"_ZTSFicE"} !4 = !{!3} -!5 = !{!"expected_int", !"_ZTSFicE"} +!5 = !{!"_ZTSFicE"} !6 = !{!5} -!7 = !{i64 0, !"_ZTSFicE"} -!8 = !{!7} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
