[clang] [llvm] [clang] Introduce CallGraphSection option (PR #117037)
Prabhu Rajasekaran via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 31 13:55:11 PDT 2025
https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/117037
>From 29d4db25c24703747add84eb528fcfdc7fe14acb Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 20 Nov 2024 11:53:38 -0800
Subject: [PATCH 01/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
clang/lib/CodeGen/CGCall.cpp | 38 ++++++
clang/lib/CodeGen/CGExpr.cpp | 6 +
clang/lib/CodeGen/CGObjCMac.cpp | 5 +-
clang/lib/CodeGen/CodeGenModule.cpp | 35 ++++-
clang/lib/CodeGen/CodeGenModule.h | 4 +
clang/test/CodeGen/call-graph-section-1.cpp | 110 +++++++++++++++
clang/test/CodeGen/call-graph-section-2.cpp | 95 +++++++++++++
clang/test/CodeGen/call-graph-section-3.cpp | 52 ++++++++
clang/test/CodeGen/call-graph-section.c | 85 ++++++++++++
llvm/include/llvm/CodeGen/AsmPrinter.h | 28 ++++
llvm/include/llvm/CodeGen/CommandFlags.h | 2 +
llvm/include/llvm/CodeGen/MIRYamlMapping.h | 5 +
llvm/include/llvm/CodeGen/MachineFunction.h | 41 +++++-
llvm/include/llvm/IR/LLVMContext.h | 1 +
llvm/include/llvm/MC/MCObjectFileInfo.h | 5 +
llvm/include/llvm/Target/TargetOptions.h | 12 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 125 ++++++++++++++++++
llvm/lib/CodeGen/CommandFlags.cpp | 7 +
llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 10 +-
llvm/lib/CodeGen/MIRPrinter.cpp | 3 +
llvm/lib/CodeGen/MachineFunction.cpp | 2 +-
.../SelectionDAG/ScheduleDAGSDNodes.cpp | 3 +-
.../SelectionDAG/SelectionDAGBuilder.cpp | 9 +-
llvm/lib/IR/LLVMContext.cpp | 5 +
llvm/lib/IR/Verifier.cpp | 10 +-
llvm/lib/MC/MCObjectFileInfo.cpp | 20 +++
.../Target/AArch64/AArch64ISelLowering.cpp | 5 +
llvm/lib/Target/ARM/ARMISelLowering.cpp | 5 +
llvm/lib/Target/Mips/MipsISelLowering.cpp | 6 +-
llvm/lib/Target/X86/X86FastISel.cpp | 8 ++
llvm/lib/Target/X86/X86ISelLoweringCall.cpp | 4 +
.../Bitcode/operand-bundles-bc-analyzer.ll | 5 +-
.../CodeGen/AArch64/call-site-info-typeid.ll | 29 ++++
.../test/CodeGen/ARM/call-site-info-typeid.ll | 29 ++++
.../CodeGen/MIR/X86/call-site-info-typeid.ll | 102 ++++++++++++++
.../CodeGen/MIR/X86/call-site-info-typeid.mir | 63 +++++++++
.../CodeGen/Mips/call-site-info-typeid.ll | 29 ++++
.../test/CodeGen/X86/call-site-info-typeid.ll | 29 ++++
llvm/test/CodeGen/call-graph-section.ll | 73 ++++++++++
llvm/test/Verifier/operand-bundles.ll | 13 ++
40 files changed, 1090 insertions(+), 28 deletions(-)
create mode 100644 clang/test/CodeGen/call-graph-section-1.cpp
create mode 100644 clang/test/CodeGen/call-graph-section-2.cpp
create mode 100644 clang/test/CodeGen/call-graph-section-3.cpp
create mode 100644 clang/test/CodeGen/call-graph-section.c
create mode 100644 llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
create mode 100644 llvm/test/CodeGen/ARM/call-site-info-typeid.ll
create mode 100644 llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
create mode 100644 llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
create mode 100644 llvm/test/CodeGen/Mips/call-site-info-typeid.ll
create mode 100644 llvm/test/CodeGen/X86/call-site-info-typeid.ll
create mode 100644 llvm/test/CodeGen/call-graph-section.ll
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 35d495d4dfab8..d5240db0fceb8 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -25,6 +25,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
@@ -5077,6 +5078,11 @@ static unsigned getMaxVectorWidth(const llvm::Type *Ty) {
return MaxVectorWidth;
}
+static bool isCXXDeclType(const FunctionDecl *FD) {
+ return isa<CXXConstructorDecl>(FD) || isa<CXXMethodDecl>(FD) ||
+ isa<CXXDestructorDecl>(FD);
+}
+
RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
const CGCallee &Callee,
ReturnValueSlot ReturnValue,
@@ -5765,6 +5771,38 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
AllocAlignAttrEmitter AllocAlignAttrEmitter(*this, TargetDecl, CallArgs);
Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
+ if (CGM.getCodeGenOpts().CallGraphSection) {
+ // Create operand bundle only for indirect calls, not for all
+ if (callOrInvoke && *callOrInvoke && (*callOrInvoke)->isIndirectCall()) {
+
+ assert((TargetDecl && TargetDecl->getFunctionType() ||
+ Callee.getAbstractInfo().getCalleeFunctionProtoType()) &&
+ "cannot find callsite type");
+
+ QualType CST;
+ if (TargetDecl && TargetDecl->getFunctionType())
+ CST = QualType(TargetDecl->getFunctionType(), 0);
+ else if (const auto *FPT =
+ Callee.getAbstractInfo().getCalleeFunctionProtoType())
+ CST = QualType(FPT, 0);
+
+ if (!CST.isNull()) {
+ auto *TypeIdMD = CGM.CreateMetadataIdentifierGeneralized(CST);
+ auto *TypeIdMDVal =
+ llvm::MetadataAsValue::get(getLLVMContext(), TypeIdMD);
+ BundleList.emplace_back("type", TypeIdMDVal);
+ }
+
+ // Set type identifier metadata of indirect calls for call graph section.
+ if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
+ // Type id metadata is set only for C/C++ contexts.
+ if (isCXXDeclType(FD)) {
+ CGM.CreateFunctionTypeMetadataForIcall(FD->getType(), *callOrInvoke);
+ }
+ }
+ }
+ }
+
// Emit the actual call/invoke instruction.
llvm::CallBase *CI;
if (!InvokeDest) {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 232cac22d1bfc..97f2cfe35ec59 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -6173,6 +6173,12 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
if (CallOrInvoke)
*CallOrInvoke = LocalCallOrInvoke;
+ // Set type identifier metadata of indirect calls for call graph section.
+ if (CGM.getCodeGenOpts().CallGraphSection && LocalCallOrInvoke &&
+ LocalCallOrInvoke->isIndirectCall())
+ CGM.CreateFunctionTypeMetadataForIcall(QualType(FnType, 0),
+ LocalCallOrInvoke);
+
return Call;
}
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 7b85dcc2c7984..248fb2ef68c43 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -2214,9 +2214,8 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
llvm::CallBase *CallSite;
CGCallee Callee = CGCallee::forDirect(BitcastFn);
- RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
- &CallSite);
-
+ RValue rvalue =
+ CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
// Mark the call as noreturn if the method is marked noreturn and the
// receiver cannot be null.
if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b854eeb62a80c..56a831b13bd08 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2622,8 +2622,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// In the cross-dso CFI mode with canonical jump tables, we want !type
// attributes on definitions only.
- if (CodeGenOpts.SanitizeCfiCrossDso &&
- CodeGenOpts.SanitizeCfiCanonicalJumpTables) {
+ if ((CodeGenOpts.SanitizeCfiCrossDso &&
+ CodeGenOpts.SanitizeCfiCanonicalJumpTables) ||
+ CodeGenOpts.CallGraphSection) {
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
// Skip available_externally functions. They won't be codegen'ed in the
// current module anyway.
@@ -2813,7 +2814,17 @@ static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND) {
void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F) {
- // Only if we are checking indirect calls.
+ bool EmittedMDIdGeneralized = false;
+ if (CodeGenOpts.CallGraphSection &&
+ (!F->hasLocalLinkage() ||
+ F->getFunction().hasAddressTaken(nullptr, /*IgnoreCallbackUses=*/true,
+ /*IgnoreAssumeLikeCalls=*/true,
+ /*IgnoreLLVMUsed=*/false))) {
+ F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType()));
+ EmittedMDIdGeneralized = true;
+ }
+
+ // Add additional metadata only if we are checking indirect calls with CFI.
if (!LangOpts.Sanitize.has(SanitizerKind::CFIICall))
return;
@@ -2824,7 +2835,9 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Metadata *MD = CreateMetadataIdentifierForType(FD->getType());
F->addTypeMetadata(0, MD);
- F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType()));
+ // Add the generalized identifier if not added already.
+ if (!EmittedMDIdGeneralized)
+ F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType()));
// Emit a hash-based bit set entry for cross-DSO calls.
if (CodeGenOpts.SanitizeCfiCrossDso)
@@ -2832,6 +2845,17 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId));
}
+void CodeGenModule::CreateFunctionTypeMetadataForIcall(const QualType &QT,
+ llvm::CallBase *CB) {
+ // Only if needed for call graph section and only for indirect calls.
+ if (!CodeGenOpts.CallGraphSection || !CB || !CB->isIndirectCall())
+ return;
+
+ auto *MD = CreateMetadataIdentifierGeneralized(QT);
+ auto *MDN = llvm::MDNode::get(getLLVMContext(), MD);
+ CB->setMetadata(llvm::LLVMContext::MD_type, MDN);
+}
+
void CodeGenModule::setKCFIType(const FunctionDecl *FD, llvm::Function *F) {
llvm::LLVMContext &Ctx = F->getContext();
llvm::MDBuilder MDB(Ctx);
@@ -2959,7 +2983,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
// are non-canonical then we need type metadata in order to produce the local
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
- !CodeGenOpts.SanitizeCfiCanonicalJumpTables)
+ !CodeGenOpts.SanitizeCfiCanonicalJumpTables ||
+ CodeGenOpts.CallGraphSection)
CreateFunctionTypeMetadataForIcall(FD, F);
if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 741b0f17da658..bbaf5b150f176 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1572,6 +1572,10 @@ class CodeGenModule : public CodeGenTypeCache {
void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F);
+ /// Create and attach type metadata to the given call.
+ void CreateFunctionTypeMetadataForIcall(const QualType &QT,
+ llvm::CallBase *CB);
+
/// Set type metadata to the given function.
void setKCFIType(const FunctionDecl *FD, llvm::Function *F);
diff --git a/clang/test/CodeGen/call-graph-section-1.cpp b/clang/test/CodeGen/call-graph-section-1.cpp
new file mode 100644
index 0000000000000..25397e94422b7
--- /dev/null
+++ b/clang/test/CodeGen/call-graph-section-1.cpp
@@ -0,0 +1,110 @@
+// Tests that we assign appropriate identifiers to indirect calls and targets
+// specifically for C++ class and instance methods.
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fcall-graph-section -S \
+// RUN: -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix=FT %s < %t
+// RUN: FileCheck --check-prefix=CST %s < %t
+
+////////////////////////////////////////////////////////////////////////////////
+// Class definitions (check for indirect target metadata)
+
+class Cls1 {
+public:
+ // FT-DAG: define {{.*}} ptr @_ZN4Cls18receiverEPcPf({{.*}} !type [[F_TCLS1RECEIVER:![0-9]+]]
+ static int *receiver(char *a, float *b) { return 0; }
+};
+
+class Cls2 {
+public:
+ int *(*fp)(char *, float *);
+
+ // FT-DAG: define {{.*}} i32 @_ZN4Cls22f1Ecfd({{.*}} !type [[F_TCLS2F1:![0-9]+]]
+ int f1(char a, float b, double c) { return 0; }
+
+ // FT-DAG: define {{.*}} ptr @_ZN4Cls22f2EPcPfPd({{.*}} !type [[F_TCLS2F2:![0-9]+]]
+ int *f2(char *a, float *b, double *c) { return 0; }
+
+ // FT-DAG: define {{.*}} void @_ZN4Cls22f3E4Cls1({{.*}} !type [[F_TCLS2F3F4:![0-9]+]]
+ void f3(Cls1 a) {}
+
+ // FT-DAG: define {{.*}} void @_ZN4Cls22f4E4Cls1({{.*}} !type [[F_TCLS2F3F4]]
+ void f4(const Cls1 a) {}
+
+ // FT-DAG: define {{.*}} void @_ZN4Cls22f5EP4Cls1({{.*}} !type [[F_TCLS2F5:![0-9]+]]
+ void f5(Cls1 *a) {}
+
+ // FT-DAG: define {{.*}} void @_ZN4Cls22f6EPK4Cls1({{.*}} !type [[F_TCLS2F6:![0-9]+]]
+ void f6(const Cls1 *a) {}
+
+ // FT-DAG: define {{.*}} void @_ZN4Cls22f7ER4Cls1({{.*}} !type [[F_TCLS2F7:![0-9]+]]
+ void f7(Cls1 &a) {}
+
+ // FT-DAG: define {{.*}} void @_ZN4Cls22f8ERK4Cls1({{.*}} !type [[F_TCLS2F8:![0-9]+]]
+ void f8(const Cls1 &a) {}
+
+ // FT-DAG: define {{.*}} void @_ZNK4Cls22f9Ev({{.*}} !type [[F_TCLS2F9:![0-9]+]]
+ void f9() const {}
+};
+
+// FT-DAG: [[F_TCLS1RECEIVER]] = !{i64 0, !"_ZTSFPvS_S_E.generalized"}
+// FT-DAG: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFPvS_S_S_E.generalized"}
+// FT-DAG: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFicfdE.generalized"}
+// FT-DAG: [[F_TCLS2F3F4]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"}
+// FT-DAG: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvPvE.generalized"}
+// FT-DAG: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvPKvE.generalized"}
+// FT-DAG: [[F_TCLS2F7]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"}
+// FT-DAG: [[F_TCLS2F8]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"}
+// FT-DAG: [[F_TCLS2F9]] = !{i64 0, !"_ZTSKFvvE.generalized"}
+
+////////////////////////////////////////////////////////////////////////////////
+// Callsites (check for indirect callsite operand bundles)
+
+// CST-LABEL: define {{.*}} @_Z3foov
+void foo() {
+ Cls2 ObjCls2;
+ ObjCls2.fp = &Cls1::receiver;
+
+ // CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPvS_S_E.generalized") ]
+ ObjCls2.fp(0, 0);
+
+ auto fp_f1 = &Cls2::f1;
+ auto fp_f2 = &Cls2::f2;
+ auto fp_f3 = &Cls2::f3;
+ auto fp_f4 = &Cls2::f4;
+ auto fp_f5 = &Cls2::f5;
+ auto fp_f6 = &Cls2::f6;
+ auto fp_f7 = &Cls2::f7;
+ auto fp_f8 = &Cls2::f8;
+ auto fp_f9 = &Cls2::f9;
+
+ Cls2 *ObjCls2Ptr = &ObjCls2;
+ Cls1 Cls1Param;
+
+ // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFicfdE.generalized") ]
+ (ObjCls2Ptr->*fp_f1)(0, 0, 0);
+
+ // CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
+ (ObjCls2Ptr->*fp_f2)(0, 0, 0);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
+ (ObjCls2Ptr->*fp_f3)(Cls1Param);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
+ (ObjCls2Ptr->*fp_f4)(Cls1Param);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPvE.generalized") ]
+ (ObjCls2Ptr->*fp_f5)(&Cls1Param);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPKvE.generalized") ]
+ (ObjCls2Ptr->*fp_f6)(&Cls1Param);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvR4Cls1E.generalized") ]
+ (ObjCls2Ptr->*fp_f7)(Cls1Param);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvRK4Cls1E.generalized") ]
+ (ObjCls2Ptr->*fp_f8)(Cls1Param);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSKFvvE.generalized") ]
+ (ObjCls2Ptr->*fp_f9)();
+}
diff --git a/clang/test/CodeGen/call-graph-section-2.cpp b/clang/test/CodeGen/call-graph-section-2.cpp
new file mode 100644
index 0000000000000..4187faea495be
--- /dev/null
+++ b/clang/test/CodeGen/call-graph-section-2.cpp
@@ -0,0 +1,95 @@
+// Tests that we assign appropriate identifiers to indirect calls and targets
+// specifically for C++ templates.
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fcall-graph-section -S \
+// RUN: -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix=FT %s < %t
+// RUN: FileCheck --check-prefix=CST %s < %t
+// RUN: FileCheck --check-prefix=CHECK %s < %t
+
+////////////////////////////////////////////////////////////////////////////////
+// Class definitions and template classes (check for indirect target metadata)
+
+class Cls1 {};
+
+// Cls2 is instantiated with T=Cls1 in foo(). Following checks are for this
+// instantiation.
+template <class T>
+class Cls2 {
+public:
+ // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f1Ev({{.*}} !type [[F_TCLS2F1:![0-9]+]]
+ void f1() {}
+
+ // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f2ES0_({{.*}} !type [[F_TCLS2F2:![0-9]+]]
+ void f2(T a) {}
+
+ // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f3EPS0_({{.*}} !type [[F_TCLS2F3:![0-9]+]]
+ void f3(T *a) {}
+
+ // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f4EPKS0_({{.*}} !type [[F_TCLS2F4:![0-9]+]]
+ void f4(const T *a) {}
+
+ // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f5ERS0_({{.*}} !type [[F_TCLS2F5:![0-9]+]]
+ void f5(T &a) {}
+
+ // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f6ERKS0_({{.*}} !type [[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-DAG: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFvvE.generalized"}
+// FT-DAG: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"}
+// FT-DAG: [[F_TCLS2F3]] = !{i64 0, !"_ZTSFvPvE.generalized"}
+// FT-DAG: [[F_TCLS2F4]] = !{i64 0, !"_ZTSFvPKvE.generalized"}
+// FT-DAG: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"}
+// FT-DAG: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"}
+
+////////////////////////////////////////////////////////////////////////////////
+// Callsites (check for indirect callsite operand bundles)
+
+template <class T>
+T *T_func(T a, T *b, const T *c, T &d, const T &e) { return b; }
+
+// CST-LABEL: define {{.*}} @_Z3foov
+void foo() {
+ // Methods for Cls2<Cls1> is checked above within the template description.
+ Cls2<Cls1> Obj;
+
+ // CHECK-DAG: define {{.*}} @_Z6T_funcI4Cls1EPT_S1_S2_PKS1_RS1_RS3_({{.*}} !type [[F_TFUNC_CLS1:![0-9]+]]
+ // CHECK-DAG: [[F_TFUNC_CLS1]] = !{i64 0, !"_ZTSFPv4Cls1S_PKvRS0_RKS0_E.generalized"}
+ Obj.fp = T_func<Cls1>;
+ Cls1 Cls1Obj;
+
+ // CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPv4Cls1S_PKvRS0_RKS0_E.generalized") ]
+ Obj.fp(Cls1Obj, &Cls1Obj, &Cls1Obj, Cls1Obj, Cls1Obj);
+
+ // Make indirect calls to Cls2's member methods
+ auto fp_f1 = &Cls2<Cls1>::f1;
+ auto fp_f2 = &Cls2<Cls1>::f2;
+ auto fp_f3 = &Cls2<Cls1>::f3;
+ auto fp_f4 = &Cls2<Cls1>::f4;
+ auto fp_f5 = &Cls2<Cls1>::f5;
+ auto fp_f6 = &Cls2<Cls1>::f6;
+
+ auto *Obj2Ptr = &Obj;
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvvE.generalized") ]
+ (Obj2Ptr->*fp_f1)();
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
+ (Obj2Ptr->*fp_f2)(Cls1Obj);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPvE.generalized") ]
+ (Obj2Ptr->*fp_f3)(&Cls1Obj);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPKvE.generalized") ]
+ (Obj2Ptr->*fp_f4)(&Cls1Obj);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvR4Cls1E.generalized") ]
+ (Obj2Ptr->*fp_f5)(Cls1Obj);
+
+ // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvRK4Cls1E.generalized") ]
+ (Obj2Ptr->*fp_f6)(Cls1Obj);
+}
diff --git a/clang/test/CodeGen/call-graph-section-3.cpp b/clang/test/CodeGen/call-graph-section-3.cpp
new file mode 100644
index 0000000000000..77bb110c664ef
--- /dev/null
+++ b/clang/test/CodeGen/call-graph-section-3.cpp
@@ -0,0 +1,52 @@
+// Tests that we assign appropriate identifiers to indirect calls and targets
+// specifically for virtual methods.
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fcall-graph-section -S \
+// RUN: -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix=FT %s < %t
+// RUN: FileCheck --check-prefix=CST %s < %t
+
+////////////////////////////////////////////////////////////////////////////////
+// Class definitions (check for indirect target metadata)
+
+class Base {
+public:
+ // FT-DAG: define {{.*}} @_ZN4Base2vfEPc({{.*}} !type [[F_TVF:![0-9]+]]
+ virtual int vf(char *a) { return 0; };
+};
+
+class Derived : public Base {
+public:
+ // FT-DAG: define {{.*}} @_ZN7Derived2vfEPc({{.*}} !type [[F_TVF]]
+ int vf(char *a) override { return 1; };
+};
+
+// FT-DAG: [[F_TVF]] = !{i64 0, !"_ZTSFiPvE.generalized"}
+
+////////////////////////////////////////////////////////////////////////////////
+// Callsites (check for indirect callsite operand bundles)
+
+// CST-LABEL: define {{.*}} @_Z3foov
+void foo() {
+ auto B = Base();
+ auto D = Derived();
+
+ Base *Bptr = &B;
+ Base *BptrToD = &D;
+ Derived *Dptr = &D;
+
+ auto FpBaseVf = &Base::vf;
+ auto FpDerivedVf = &Derived::vf;
+
+ // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
+ (Bptr->*FpBaseVf)(0);
+
+ // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
+ (BptrToD->*FpBaseVf)(0);
+
+ // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
+ (Dptr->*FpBaseVf)(0);
+
+ // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
+ (Dptr->*FpDerivedVf)(0);
+}
diff --git a/clang/test/CodeGen/call-graph-section.c b/clang/test/CodeGen/call-graph-section.c
new file mode 100644
index 0000000000000..ed1bdb876152a
--- /dev/null
+++ b/clang/test/CodeGen/call-graph-section.c
@@ -0,0 +1,85 @@
+// Tests that we assign appropriate identifiers to indirect calls and targets.
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fcall-graph-section -S \
+// RUN: -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,ITANIUM %s
+
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fcall-graph-section -S \
+// RUN: -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,MS %s
+
+// CHECK-DAG: define {{(dso_local)?}} void @foo({{.*}} !type [[F_TVOID:![0-9]+]]
+void foo() {
+}
+
+// CHECK-DAG: define {{(dso_local)?}} void @bar({{.*}} !type [[F_TVOID]]
+void bar() {
+ void (*fp)() = foo;
+ // ITANIUM: call {{.*}} [ "type"(metadata !"_ZTSFvE.generalized") ]
+ // MS: call {{.*}} [ "type"(metadata !"?6AX at Z.generalized") ]
+ fp();
+}
+
+// CHECK-DAG: define {{(dso_local)?}} i32 @baz({{.*}} !type [[F_TPRIMITIVE:![0-9]+]]
+int baz(char a, float b, double c) {
+ return 1;
+}
+
+// CHECK-DAG: define {{(dso_local)?}} ptr @qux({{.*}} !type [[F_TPTR:![0-9]+]]
+int *qux(char *a, float *b, double *c) {
+ return 0;
+}
+
+// CHECK-DAG: define {{(dso_local)?}} void @corge({{.*}} !type [[F_TVOID]]
+void corge() {
+ int (*fp_baz)(char, float, double) = baz;
+ // ITANIUM: call i32 {{.*}} [ "type"(metadata !"_ZTSFicfdE.generalized") ]
+ // MS: call i32 {{.*}} [ "type"(metadata !"?6AHDMN at Z.generalized") ]
+ fp_baz('a', .0f, .0);
+
+ int *(*fp_qux)(char *, float *, double *) = qux;
+ // ITANIUM: call ptr {{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
+ // MS: call ptr {{.*}} [ "type"(metadata !"?6APEAXPEAX00 at Z.generalized") ]
+ fp_qux(0, 0, 0);
+}
+
+struct st1 {
+ int *(*fp)(char *, float *, double *);
+};
+
+struct st2 {
+ struct st1 m;
+};
+
+// CHECK-DAG: define {{(dso_local)?}} void @stparam({{.*}} !type [[F_TSTRUCT:![0-9]+]]
+void stparam(struct st2 a, struct st2 *b) {}
+
+// CHECK-DAG: define {{(dso_local)?}} void @stf({{.*}} !type [[F_TVOID]]
+void stf() {
+ struct st1 St1;
+ St1.fp = qux;
+ // ITANIUM: call ptr {{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
+ // MS: call ptr {{.*}} [ "type"(metadata !"?6APEAXPEAX00 at Z.generalized") ]
+ St1.fp(0, 0, 0);
+
+ struct st2 St2;
+ St2.m.fp = qux;
+ // ITANIUM: call ptr {{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
+ // MS: call ptr {{.*}} [ "type"(metadata !"?6APEAXPEAX00 at Z.generalized") ]
+ St2.m.fp(0, 0, 0);
+
+ // ITANIUM: call void {{.*}} [ "type"(metadata !"_ZTSFv3st2PvE.generalized") ]
+ // MS: call void {{.*}} [ "type"(metadata !"?6AXUst2@@PEAX at Z.generalized") ]
+ void (*fp_stparam)(struct st2, struct st2 *) = stparam;
+ fp_stparam(St2, &St2);
+}
+
+// ITANIUM-DAG: [[F_TVOID]] = !{i64 0, !"_ZTSFvE.generalized"}
+// MS-DAG: [[F_TVOID]] = !{i64 0, !"?6AX at Z.generalized"}
+
+// ITANIUM-DAG: [[F_TPRIMITIVE]] = !{i64 0, !"_ZTSFicfdE.generalized"}
+// MS-DAG: [[F_TPRIMITIVE]] = !{i64 0, !"?6AHDMN at Z.generalized"}
+
+// ITANIUM-DAG: [[F_TPTR]] = !{i64 0, !"_ZTSFPvS_S_S_E.generalized"}
+// MS-DAG: [[F_TPTR]] = !{i64 0, !"?6APEAXPEAX00 at Z.generalized"}
+
+// ITANIUM-DAG: [[F_TSTRUCT]] = !{i64 0, !"_ZTSFv3st2PvE.generalized"}
+// MS-DAG: [[F_TSTRUCT]] = !{i64 0, !"?6AXUst2@@PEAX at Z.generalized"}
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index c9a88d7b1c015..76bbcaa250bfa 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -173,6 +173,32 @@ class AsmPrinter : public MachineFunctionPass {
/// Emit comments in assembly output if this is true.
bool VerboseAsm;
+ /// Store symbols and type identifiers used to create call graph section
+ /// entries related to a function.
+ struct FunctionInfo {
+ /// Numeric type identifier used in call graph section for indirect calls
+ /// and targets.
+ using CGTypeId = uint64_t;
+
+ /// Enumeration of function kinds, and their mapping to function kind values
+ /// stored in call graph section entries.
+ /// Must match the enum in llvm/tools/llvm-objdump/llvm-objdump.cpp.
+ enum FunctionKind {
+ /// Function cannot be target to indirect calls.
+ NOT_INDIRECT_TARGET = 0,
+
+ /// Function may be target to indirect calls but its type id is unknown.
+ INDIRECT_TARGET_UNKNOWN_TID = 1,
+
+ /// Function may be target to indirect calls and its type id is known.
+ INDIRECT_TARGET_KNOWN_TID = 2,
+ };
+
+ /// Map type identifiers to callsite labels. Labels are only for indirect
+ /// calls and inclusive of all indirect calls of the function.
+ SmallVector<std::pair<CGTypeId, MCSymbol *>> CallSiteLabels;
+ };
+
/// Output stream for the stack usage file (i.e., .su file).
std::unique_ptr<raw_fd_ostream> StackUsageStream;
@@ -414,6 +440,8 @@ class AsmPrinter : public MachineFunctionPass {
void emitKCFITrapEntry(const MachineFunction &MF, const MCSymbol *Symbol);
virtual void emitKCFITypeId(const MachineFunction &MF);
+ void emitCallGraphSection(const MachineFunction &MF, FunctionInfo &FuncInfo);
+
void emitPseudoProbe(const MachineInstr &MI);
void emitRemarksSection(remarks::RemarkStreamer &RS);
diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index d5448d781363d..eb93192700a83 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -132,6 +132,8 @@ bool getEnableStackSizeSection();
bool getEnableAddrsig();
+bool getEnableCallGraphSection();
+
bool getEmitCallSiteInfo();
bool getEnableMachineFunctionSplitter();
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index 09a6ca936fe1f..fe35c8253f6a5 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -483,6 +483,10 @@ struct CallSiteInfo {
MachineInstrLoc CallLocation;
std::vector<ArgRegPair> ArgForwardingRegs;
+ /// Numeric callee type identifier used for call graph section.
+ using TypeIdTy = std::optional<uint64_t>;
+ TypeIdTy TypeId;
+
bool operator==(const CallSiteInfo &Other) const {
return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
CallLocation.Offset == Other.CallLocation.Offset;
@@ -511,6 +515,7 @@ template <> struct MappingTraits<CallSiteInfo> {
YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
std::vector<CallSiteInfo::ArgRegPair>());
+ YamlIO.mapOptional("typeId", CSInfo.TypeId);
}
static const bool flow = true;
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index bb75d5aa8cfa6..31c24e3bc8409 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -26,11 +26,14 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/EHPersonalities.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ArrayRecycler.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MD5.h"
#include "llvm/Support/Recycler.h"
#include "llvm/Target/TargetOptions.h"
#include <bitset>
@@ -486,6 +489,40 @@ class LLVM_ABI MachineFunction {
struct CallSiteInfo {
/// Vector of call argument and its forwarding register.
SmallVector<ArgRegPair, 1> ArgRegPairs;
+
+ /// Callee type id.
+ ConstantInt *TypeId = nullptr;
+
+ CallSiteInfo() = default;
+
+ /// Extracts the numeric type id from the CallBase's type operand bundle,
+ /// and sets TypeId. This is used as type id for the indirect call in the
+ /// call graph section.
+ CallSiteInfo(const CallBase &CB) {
+ // Call graph section needs numeric type id only for indirect calls.
+ if (!CB.isIndirectCall())
+ return;
+
+ std::optional<OperandBundleUse> Opt =
+ CB.getOperandBundle(LLVMContext::OB_type);
+ // Return if the operand bundle for call graph section cannot be found.
+ if (!Opt)
+ return;
+
+ // Get generalized type id string
+ auto OB = *Opt;
+ assert(OB.Inputs.size() == 1 && "invalid input size");
+ auto *OBVal = OB.Inputs.front().get();
+ auto *TypeIdMD = cast<MetadataAsValue>(OBVal)->getMetadata();
+ auto *TypeIdStr = cast<MDString>(TypeIdMD);
+ assert(TypeIdStr->getString().endswith(".generalized") &&
+ "invalid type identifier");
+
+ // Compute numeric type id from generalized type id string
+ uint64_t TypeIdVal = MD5Hash(TypeIdStr->getString());
+ IntegerType *Int64Ty = Type::getInt64Ty(CB.getContext());
+ TypeId = ConstantInt::get(Int64Ty, TypeIdVal, /*IsSigned=*/false);
+ }
};
private:
@@ -493,7 +530,7 @@ class LLVM_ABI MachineFunction {
GISelChangeObserver *Observer = nullptr;
using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>;
- /// Map a call instruction to call site arguments forwarding info.
+ /// Map a call instruction to call site arguments forwarding and type id.
CallSiteInfoMap CallSitesInfo;
/// A helper function that returns call site info for a give call
@@ -1355,7 +1392,7 @@ class LLVM_ABI MachineFunction {
});
}
- /// Start tracking the arguments passed to the call \p CallI.
+ /// Start tracking the arguments passed to the call \p CallI and call type.
void addCallSiteInfo(const MachineInstr *CallI, CallSiteInfo &&CallInfo) {
assert(CallI->isCandidateForCallSiteEntry());
bool Inserted =
diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h
index 6d4a59ba6b1f6..0190f5677c437 100644
--- a/llvm/include/llvm/IR/LLVMContext.h
+++ b/llvm/include/llvm/IR/LLVMContext.h
@@ -96,6 +96,7 @@ class LLVMContext {
OB_ptrauth = 7, // "ptrauth"
OB_kcfi = 8, // "kcfi"
OB_convergencectrl = 9, // "convergencectrl"
+ OB_type = 10, // "type"
};
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index e2a2c84e47910..cdf7550a7d2a1 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -68,6 +68,9 @@ class MCObjectFileInfo {
/// Language Specific Data Area information is emitted to.
MCSection *LSDASection = nullptr;
+ /// Section containing metadata on call graph.
+ MCSection *CallGraphSection = nullptr;
+
/// If exception handling is supported by the target and the target can
/// support a compact representation of the CIE and FDE, this is the section
/// to emit them into.
@@ -355,6 +358,8 @@ class MCObjectFileInfo {
MCSection *getFaultMapSection() const { return FaultMapSection; }
MCSection *getRemarksSection() const { return RemarksSection; }
+ MCSection *getCallGraphSection(const MCSection &TextSec) const;
+
MCSection *getStackSizesSection(const MCSection &TextSec) const;
MCSection *getBBAddrMapSection(const MCSection &TextSec) const;
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index 88f253805ca99..68270d5fcfa85 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -146,10 +146,11 @@ namespace llvm {
EmulatedTLS(false), EnableTLSDESC(false), EnableIPRA(false),
EmitStackSizeSection(false), EnableMachineOutliner(false),
EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false),
- EmitAddrsig(false), BBAddrMap(false), EmitCallSiteInfo(false),
- SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
- ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
- XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
+ EmitAddrsig(false), BBAddrMap(false), EmitCallGraphSection(false),
+ EmitCallSiteInfo(false), SupportsDebugEntryValues(false),
+ EnableDebugEntryValues(false), ValueTrackingVariableLocations(false),
+ ForceDwarfFrameSection(false), XRayFunctionIndex(true),
+ DebugStrictDwarf(false), Hotpatch(false),
PPCGenScalarMASSEntries(false), JMCInstrument(false),
EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
VerifyArgABICompliance(true),
@@ -329,6 +330,9 @@ namespace llvm {
/// to selectively generate basic block sections.
std::shared_ptr<MemoryBuffer> BBSectionsFuncListBuf;
+ /// Emit section containing call graph metadata.
+ unsigned EmitCallGraphSection : 1;
+
/// The flag enables call site info production. It is used only for debug
/// info, and it is restricted only to optimized code. This can be used for
/// something else, so that should be controlled in the frontend.
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 030d0e1c82ab7..9b48bf3386251 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1629,6 +1629,105 @@ void AsmPrinter::emitStackUsage(const MachineFunction &MF) {
*StackUsageStream << "static\n";
}
+/// Extracts a generalized numeric type identifier of a Function's type from
+/// type metadata. Returns null if metadata cannot be found.
+static ConstantInt *extractNumericCGTypeId(const Function &F) {
+ SmallVector<MDNode *, 2> Types;
+ F.getMetadata(LLVMContext::MD_type, Types);
+ MDString *MDGeneralizedTypeId = nullptr;
+ for (const auto &Type : Types) {
+ if (Type->getNumOperands() == 2 && isa<MDString>(Type->getOperand(1))) {
+ auto *TMDS = cast<MDString>(Type->getOperand(1));
+ if (TMDS->getString().ends_with("generalized")) {
+ MDGeneralizedTypeId = TMDS;
+ break;
+ }
+ }
+ }
+
+ if (!MDGeneralizedTypeId) {
+ errs() << "warning: can't find indirect target type id metadata "
+ << "for " << F.getName() << "\n";
+ return nullptr;
+ }
+
+ uint64_t TypeIdVal = llvm::MD5Hash(MDGeneralizedTypeId->getString());
+ Type *Int64Ty = Type::getInt64Ty(F.getContext());
+ return cast<ConstantInt>(ConstantInt::get(Int64Ty, TypeIdVal));
+}
+
+/// Emits call graph section.
+void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
+ FunctionInfo &FuncInfo) {
+ if (!MF.getTarget().Options.EmitCallGraphSection)
+ return;
+
+ // Switch to the call graph section for the function
+ MCSection *FuncCGSection =
+ getObjFileLowering().getCallGraphSection(*getCurrentSection());
+ assert(FuncCGSection && "null call graph section");
+ OutStreamer->pushSection();
+ OutStreamer->switchSection(FuncCGSection);
+
+ // Emit format version number.
+ OutStreamer->emitInt64(0);
+
+ // Emit function's self information, which is composed of:
+ // 1) FunctionEntryPc
+ // 2) FunctionKind: Whether the function is indirect target, and if so,
+ // whether its type id is known.
+ // 3) FunctionTypeId: Emit only when the function is an indirect target
+ // and its type id is known.
+
+ // Emit function entry pc.
+ const MCSymbol *FunctionSymbol = getFunctionBegin();
+ OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize());
+
+ // If this function has external linkage or has its address taken and
+ // it is not a callback, then anything could call it.
+ const Function &F = MF.getFunction();
+ bool IsIndirectTarget =
+ !F.hasLocalLinkage() || F.hasAddressTaken(nullptr,
+ /*IgnoreCallbackUses=*/true,
+ /*IgnoreAssumeLikeCalls=*/true,
+ /*IgnoreLLVMUsed=*/false);
+
+ // FIXME: FunctionKind takes a few values but emitted as a 64-bit value.
+ // Can be optimized to occupy 2 bits instead.
+ // Emit function kind, and type id if available.
+ if (!IsIndirectTarget) {
+ OutStreamer->emitInt64(FunctionInfo::FunctionKind::NOT_INDIRECT_TARGET);
+ } else {
+ const auto *TypeId = extractNumericCGTypeId(F);
+ if (TypeId) {
+ OutStreamer->emitInt64(
+ FunctionInfo::FunctionKind::INDIRECT_TARGET_KNOWN_TID);
+ OutStreamer->emitInt64(TypeId->getZExtValue());
+ } else {
+ OutStreamer->emitInt64(
+ FunctionInfo::FunctionKind::INDIRECT_TARGET_UNKNOWN_TID);
+ }
+ }
+
+ // Emit callsite labels, where each element is a pair of type id and
+ // indirect callsite pc.
+ const auto &CallSiteLabels = FuncInfo.CallSiteLabels;
+
+ // Emit the count of pairs.
+ OutStreamer->emitInt64(CallSiteLabels.size());
+
+ // Emit the type id and call site label pairs.
+ for (const std::pair<uint64_t, MCSymbol *> &El : CallSiteLabels) {
+ auto TypeId = El.first;
+ const auto &Label = El.second;
+ OutStreamer->emitInt64(TypeId);
+ OutStreamer->emitSymbolValue(Label, TM.getProgramPointerSize());
+ }
+ FuncInfo.CallSiteLabels.clear();
+
+ OutStreamer->popSection();
+}
+
void AsmPrinter::emitPCSectionsLabel(const MachineFunction &MF,
const MDNode &MD) {
MCSymbol *S = MF.getContext().createTempSymbol("pcsection");
@@ -1805,6 +1904,8 @@ void AsmPrinter::emitFunctionBody() {
MBBSectionRanges[MF->front().getSectionID()] =
MBBSectionRange{CurrentFnBegin, nullptr};
+ FunctionInfo FuncInfo;
+ const auto &CallSitesInfoMap = MF->getCallSitesInfo();
for (auto &MBB : *MF) {
// Print a label for the basic block.
emitBasicBlockStart(MBB);
@@ -1935,6 +2036,26 @@ void AsmPrinter::emitFunctionBody() {
break;
}
+ // FIXME: Some indirect calls can get lowered to jump instructions,
+ // resulting in emitting labels for them. The extra information can
+ // be neglected while disassembling but still takes space in the binary.
+ if (TM.Options.EmitCallGraphSection && MI.isCall()) {
+ // Only indirect calls have type identifiers set.
+ const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
+ if (CallSiteInfo != CallSitesInfoMap.end()) {
+ if (auto *TypeId = CallSiteInfo->second.TypeId) {
+ // Emit label.
+ MCSymbol *S = MF->getContext().createTempSymbol();
+ OutStreamer->emitLabel(S);
+
+ // Get type id value.
+ uint64_t TypeIdVal = TypeId->getZExtValue();
+
+ // Add to function's callsite labels.
+ FuncInfo.CallSiteLabels.emplace_back(TypeIdVal, S);
+ }
+ }
+ }
// If there is a post-instruction symbol, emit a label for it here.
if (MCSymbol *S = MI.getPostInstrSymbol())
OutStreamer->emitLabel(S);
@@ -2112,6 +2233,9 @@ void AsmPrinter::emitFunctionBody() {
// Emit section containing stack size metadata.
emitStackSizeSection(*MF);
+ // Emit section containing call graph metadata.
+ emitCallGraphSection(*MF, FuncInfo);
+
// Emit .su file containing function stack size information.
emitStackUsage(*MF);
@@ -2697,6 +2821,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
F.hasFnAttribute("xray-instruction-threshold") ||
needFuncLabels(MF, *this) || NeedsLocalForSize ||
MF.getTarget().Options.EmitStackSizeSection ||
+ MF.getTarget().Options.EmitCallGraphSection ||
MF.getTarget().Options.BBAddrMap) {
CurrentFnBegin = createTempSymbol("func_begin");
if (NeedsLocalForSize)
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index d180cfcea658c..c2a7a0d7ea663 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -101,6 +101,7 @@ CGOPT(EABI, EABIVersion)
CGOPT(DebuggerKind, DebuggerTuningOpt)
CGOPT(bool, EnableStackSizeSection)
CGOPT(bool, EnableAddrsig)
+CGOPT(bool, EnableCallGraphSection)
CGOPT(bool, EmitCallSiteInfo)
CGOPT(bool, EnableMachineFunctionSplitter)
CGOPT(bool, EnableDebugEntryValues)
@@ -460,6 +461,11 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
cl::init(false));
CGBINDOPT(EnableAddrsig);
+ static cl::opt<bool> EnableCallGraphSection(
+ "call-graph-section", cl::desc("Emit a call graph section"),
+ cl::init(false));
+ CGBINDOPT(EnableCallGraphSection);
+
static cl::opt<bool> EmitCallSiteInfo(
"emit-call-site-info",
cl::desc(
@@ -587,6 +593,7 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
Options.EmitStackSizeSection = getEnableStackSizeSection();
Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
Options.EmitAddrsig = getEnableAddrsig();
+ Options.EmitCallGraphSection = getEnableCallGraphSection();
Options.EmitCallSiteInfo = getEmitCallSiteInfo();
Options.EnableDebugEntryValues = getEnableDebugEntryValues();
Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index e2543f883f91c..091315462a3f4 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -488,12 +488,18 @@ bool MIRParserImpl::initializeCallSiteInfo(
return error(Error, ArgRegPair.Reg.SourceRange);
CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);
}
+ if (YamlCSInfo.TypeId.has_value()) {
+ IntegerType *Int64Ty = Type::getInt64Ty(Context);
+ CSInfo.TypeId = ConstantInt::get(Int64Ty, YamlCSInfo.TypeId.value(),
+ /*isSigned=*/false);
+ }
- if (TM.Options.EmitCallSiteInfo)
+ if (TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection)
MF.addCallSiteInfo(&*CallI, std::move(CSInfo));
}
- if (YamlMF.CallSitesInfo.size() && !TM.Options.EmitCallSiteInfo)
+ if (YamlMF.CallSitesInfo.size() &&
+ !(TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection))
return error(Twine("Call site info provided but not used"));
return false;
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 658bbe0e577e5..f5f48b8b4aa46 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -571,6 +571,9 @@ void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
}
+ // Get type id.
+ if (CSInfo.second.TypeId)
+ YmlCS.TypeId = CSInfo.second.TypeId->getZExtValue();
YMF.CallSitesInfo.push_back(YmlCS);
}
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index a293a77d3fae9..c5e76994d9f62 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -913,7 +913,7 @@ MachineFunction::getCallSiteInfo(const MachineInstr *MI) {
assert(MI->isCandidateForCallSiteEntry() &&
"Call site info refers only to call (MI) candidates");
- if (!Target.Options.EmitCallSiteInfo)
+ if (!Target.Options.EmitCallSiteInfo && !Target.Options.EmitCallGraphSection)
return CallSitesInfo.end();
return CallSitesInfo.find(MI);
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index 31939ae5922ec..250f98c1bd5d2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -889,7 +889,8 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
}
if (MI->isCandidateForCallSiteEntry() &&
- DAG->getTarget().Options.EmitCallSiteInfo) {
+ (DAG->getTarget().Options.EmitCallSiteInfo ||
+ DAG->getTarget().Options.EmitCallGraphSection)) {
MF.addCallSiteInfo(MI, DAG->getCallSiteInfo(Node));
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 9d729d448502d..dd6b77cdd3df5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3326,7 +3326,7 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
{LLVMContext::OB_deopt, LLVMContext::OB_gc_transition,
LLVMContext::OB_gc_live, LLVMContext::OB_funclet,
LLVMContext::OB_cfguardtarget, LLVMContext::OB_ptrauth,
- LLVMContext::OB_clang_arc_attachedcall}) &&
+ LLVMContext::OB_clang_arc_attachedcall, LLVMContext::OB_type}) &&
"Cannot lower invokes with arbitrary operand bundles yet!");
const Value *Callee(I.getCalledOperand());
@@ -3415,8 +3415,9 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
// Deopt bundles are lowered in LowerCallSiteWithDeoptBundle, and we don't
// have to do anything here to lower funclet bundles.
- assert(!I.hasOperandBundlesOtherThan(
- {LLVMContext::OB_deopt, LLVMContext::OB_funclet}) &&
+ assert(!I.hasOperandBundlesOtherThan({LLVMContext::OB_deopt,
+ LLVMContext::OB_funclet,
+ LLVMContext::OB_type}) &&
"Cannot lower callbrs with arbitrary operand bundles yet!");
assert(I.isInlineAsm() && "Only know how to handle inlineasm callbr");
@@ -9599,7 +9600,7 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
{LLVMContext::OB_deopt, LLVMContext::OB_funclet,
LLVMContext::OB_cfguardtarget, LLVMContext::OB_preallocated,
LLVMContext::OB_clang_arc_attachedcall, LLVMContext::OB_kcfi,
- LLVMContext::OB_convergencectrl}) &&
+ LLVMContext::OB_convergencectrl, LLVMContext::OB_type}) &&
"Cannot lower calls with arbitrary operand bundles!");
SDValue Callee = getValue(I.getCalledOperand());
diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index e078527b597b4..20b3008e4f071 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -97,6 +97,11 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
"convergencectrl operand bundle id drifted!");
(void)ConvergenceCtrlEntry;
+ auto *TypeEntry = pImpl->getOrInsertBundleTag("type");
+ assert(TypeEntry->second == LLVMContext::OB_type &&
+ "type operand bundle id drifted!");
+ (void)TypeEntry;
+
SyncScope::ID SingleThreadSSID =
pImpl->getOrInsertSyncScopeID("singlethread");
assert(SingleThreadSSID == SyncScope::SingleThread &&
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 5c0ccf734cccb..0ad7ba555bfad 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3708,13 +3708,14 @@ void Verifier::visitCallBase(CallBase &Call) {
visitIntrinsicCall(ID, Call);
// Verify that a callsite has at most one "deopt", at most one "funclet", at
- // most one "gc-transition", at most one "cfguardtarget", at most one
- // "preallocated" operand bundle, and at most one "ptrauth" operand bundle.
+ // most one "gc-transition", at most one "cfguardtarget", at most one "type",
+ // at most one "preallocated" operand bundle, and at most one "ptrauth"
+ // operand bundle.
bool FoundDeoptBundle = false, FoundFuncletBundle = false,
FoundGCTransitionBundle = false, FoundCFGuardTargetBundle = false,
FoundPreallocatedBundle = false, FoundGCLiveBundle = false,
FoundPtrauthBundle = false, FoundKCFIBundle = false,
- FoundAttachedCallBundle = false;
+ FoundAttachedCallBundle = false, FoundTypeBundle = false;
for (unsigned i = 0, e = Call.getNumOperandBundles(); i < e; ++i) {
OperandBundleUse BU = Call.getOperandBundleAt(i);
uint32_t Tag = BU.getTagID();
@@ -3777,6 +3778,9 @@ void Verifier::visitCallBase(CallBase &Call) {
"Multiple \"clang.arc.attachedcall\" operand bundles", Call);
FoundAttachedCallBundle = true;
verifyAttachedCallBundle(Call, BU);
+ } else if (Tag == LLVMContext::OB_type) {
+ Check(!FoundTypeBundle, "Multiple \"type\" operand bundles", Call);
+ FoundTypeBundle = true;
}
}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index f37e138edc36b..eb019f233b402 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -536,6 +536,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
EHFrameSection =
Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);
+ CallGraphSection = Ctx->getELFSection(".callgraph", ELF::SHT_PROGBITS, 0);
+
StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0);
PseudoProbeSection = Ctx->getELFSection(".pseudo_probe", DebugSecType, 0);
@@ -1076,6 +1078,24 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
llvm_unreachable("Unknown ObjectFormatType");
}
+MCSection *
+MCObjectFileInfo::getCallGraphSection(const MCSection &TextSec) const {
+ if (Ctx->getObjectFileType() != MCContext::IsELF)
+ return CallGraphSection;
+
+ const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
+ unsigned Flags = ELF::SHF_LINK_ORDER;
+ StringRef GroupName;
+ if (const MCSymbol *Group = ElfSec.getGroup()) {
+ GroupName = Group->getName();
+ Flags |= ELF::SHF_GROUP;
+ }
+
+ return Ctx->getELFSection(".callgraph", ELF::SHT_PROGBITS, Flags, 0,
+ GroupName, true, ElfSec.getUniqueID(),
+ cast<MCSymbolELF>(TextSec.getBeginSymbol()));
+}
+
MCSection *
MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const {
if ((Ctx->getObjectFileType() != MCContext::IsELF) ||
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ad1d1237aa25a..0c5a83863835f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -8739,6 +8739,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID &CallConv = CLI.CallConv;
bool IsVarArg = CLI.IsVarArg;
+ const auto *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
MachineFunction::CallSiteInfo CSInfo;
@@ -8778,6 +8779,10 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
*DAG.getContext());
RetCCInfo.AnalyzeCallResult(Ins, RetCC);
+ // Set type id for call site info.
+ if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
+ CSInfo = MachineFunction::CallSiteInfo(*CB);
+
// Check callee args/returns for SVE registers and set calling convention
// accordingly.
if (CallConv == CallingConv::C || CallConv == CallingConv::Fast) {
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 84b37ae6833ae..ec8e6005c1663 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2431,6 +2431,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
CallingConv::ID CallConv = CLI.CallConv;
bool doesNotRet = CLI.DoesNotReturn;
bool isVarArg = CLI.IsVarArg;
+ const auto *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
@@ -2454,6 +2455,10 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
!Subtarget->noBTIAtReturnTwice())
GuardWithBTI = AFI->branchTargetEnforcement();
+ // Set type id for call site info.
+ if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
+ CSInfo = MachineFunction::CallSiteInfo(*CB);
+
// Determine whether this is a non-secure function call.
if (CLI.CB && CLI.CB->getAttributes().hasFnAttr("cmse_nonsecure_call"))
isCmseNSCall = true;
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index d90348153fd3e..922441cdceffb 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3250,6 +3250,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
bool IsVarArg = CLI.IsVarArg;
+ const auto *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -3306,8 +3307,11 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Get a count of how many bytes are to be pushed on the stack.
unsigned StackSize = CCInfo.getStackSize();
- // Call site info for function parameters tracking.
+ // Call site info for function parameters tracking and call base type info.
MachineFunction::CallSiteInfo CSInfo;
+ // Set type id for call site info.
+ if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
+ CSInfo = MachineFunction::CallSiteInfo(*CB);
// Check if it's really possible to do a tail call. Restrict it to functions
// that are part of this compilation unit.
diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp
index 039b8929c93a8..da2e1f6c02f32 100644
--- a/llvm/lib/Target/X86/X86FastISel.cpp
+++ b/llvm/lib/Target/X86/X86FastISel.cpp
@@ -3631,6 +3631,12 @@ bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
CLI.NumResultRegs = RVLocs.size();
CLI.Call = MIB;
+ // Add call site info for call graph section.
+ if (TM.Options.EmitCallGraphSection && CB && CB->isIndirectCall()) {
+ MachineFunction::CallSiteInfo CSInfo(*CB);
+ MF->addCallSiteInfo(CLI.Call, std::move(CSInfo));
+ }
+
return true;
}
@@ -4026,6 +4032,8 @@ bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
MO.setReg(IndexReg);
}
+ if (MI->isCall())
+ FuncInfo.MF->moveCallSiteInfo(MI, Result);
Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
Result->cloneInstrSymbols(*FuncInfo.MF, *MI);
MachineBasicBlock::iterator I(MI);
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 8a764de561413..4dbea3b58e0ad 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -2027,6 +2027,10 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (CallConv == CallingConv::X86_INTR)
report_fatal_error("X86 interrupts may not be called directly");
+ // Set type id for call site info.
+ if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
+ CSInfo = MachineFunction::CallSiteInfo(*CB);
+
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.getContext());
diff --git a/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll b/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
index d860104b9cb3d..ca3f3a929194a 100644
--- a/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
+++ b/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
@@ -13,6 +13,7 @@
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
+; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: </OPERAND_BUNDLE_TAGS_BLOCK
; CHECK: <FUNCTION_BLOCK
@@ -25,9 +26,9 @@
declare void @callee0()
-define void @f0(i32* %ptr) {
+define void @f0(ptr %ptr) {
entry:
- %l = load i32, i32* %ptr
+ %l = load i32, ptr %ptr
%x = add i32 42, 1
call void @callee0() [ "foo"(i32 42, i64 100, i32 %x), "bar"(float 0.000000e+00, i64 100, i32 %l) ]
ret void
diff --git a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
new file mode 100644
index 0000000000000..f3b98c2c7a395
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
@@ -0,0 +1,29 @@
+;; Tests that call site type ids can be extracted and set from type operand
+;; bundles.
+
+;; Verify the exact typeId value to ensure it is not garbage but the value
+;; computed as the type id from the type operand bundle.
+; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
+
+define dso_local void @foo(i8 signext %a) !type !3 {
+entry:
+ ret void
+}
+
+; CHECK: name: main
+define dso_local i32 @main() !type !4 {
+entry:
+ %retval = alloca i32, align 4
+ %fp = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp, align 8
+ %0 = load ptr, ptr %fp, align 8
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: 7854600665770582568 }
+ call void %0(i8 signext 97) [ "type"(metadata !"_ZTSFvcE.generalized") ]
+ ret i32 0
+}
+
+!3 = !{i64 0, !"_ZTSFvcE.generalized"}
+!4 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
new file mode 100644
index 0000000000000..9feeef9a564cc
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
@@ -0,0 +1,29 @@
+;; Tests that call site type ids can be extracted and set from type operand
+;; bundles.
+
+;; Verify the exact typeId value to ensure it is not garbage but the value
+;; computed as the type id from the type operand bundle.
+; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
+
+define dso_local void @foo(i8 signext %a) !type !3 {
+entry:
+ ret void
+}
+
+; CHECK: name: main
+define dso_local i32 @main() !type !4 {
+entry:
+ %retval = alloca i32, align 4
+ %fp = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp, align 8
+ %0 = load ptr, ptr %fp, align 8
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: 7854600665770582568 }
+ call void %0(i8 signext 97) [ "type"(metadata !"_ZTSFvcE.generalized") ]
+ ret i32 0
+}
+
+!3 = !{i64 0, !"_ZTSFvcE.generalized"}
+!4 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
new file mode 100644
index 0000000000000..a8b2de8d8f8cf
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
@@ -0,0 +1,102 @@
+;; Test MIR printer and parser for type id field in call site info. Test that
+;; it works well with/without --emit-call-site-info.
+
+;; Multiplex --call-graph-section and -emit-call-site-info as both utilize
+;; CallSiteInfo and callSites.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Test printer and parser with --call-graph-section only.
+
+;; Test printer.
+;; Verify that fwdArgRegs is not set, typeId is set.
+;; Verify the exact typeId value to ensure it is not garbage but the value
+;; computed as the type id from the type operand bundle.
+; RUN: llc --call-graph-section %s -stop-before=finalize-isel -o %t1.mir
+; RUN: cat %t1.mir | FileCheck %s --check-prefix=PRINTER_CGS
+; PRINTER_CGS: name: main
+; PRINTER_CGS: callSites:
+; PRINTER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+; PRINTER_CGS-NEXT: 7854600665770582568 }
+
+
+;; Test parser.
+;; Verify that we get the same result.
+; RUN: llc --call-graph-section %t1.mir -run-pass=finalize-isel -o - \
+; RUN: | FileCheck %s --check-prefix=PARSER_CGS
+; PARSER_CGS: name: main
+; PARSER_CGS: callSites:
+; PARSER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+; PARSER_CGS-NEXT: 7854600665770582568 }
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Test printer and parser with -emit-call-site-info only.
+
+;; Test printer.
+;; Verify that fwdArgRegs is set, typeId is not set.
+; RUN: llc -emit-call-site-info %s -stop-before=finalize-isel -o %t2.mir
+; RUN: cat %t2.mir | FileCheck %s --check-prefix=PRINTER_CSI
+; PRINTER_CSI: name: main
+; PRINTER_CSI: callSites:
+; PRINTER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; PRINTER_CSI-NEXT: { arg: 0, reg: '$edi' }
+; PRINTER_CSI-NOT: typeId:
+
+
+;; Test parser.
+;; Verify that we get the same result.
+; RUN: llc -emit-call-site-info %t2.mir -run-pass=finalize-isel -o - \
+; RUN: | FileCheck %s --check-prefix=PARSER_CSI
+; PARSER_CSI: name: main
+; PARSER_CSI: callSites:
+; PARSER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; PARSER_CSI-NEXT: { arg: 0, reg: '$edi' }
+; PARSER_CSI-NOT: typeId:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Test printer and parser with both -emit-call-site-info and --call-graph-section.
+
+;; Test printer.
+;; Verify both fwdArgRegs and typeId are set.
+;; Verify the exact typeId value to ensure it is not garbage but the value
+;; computed as the type id from the type operand bundle.
+; RUN: llc --call-graph-section -emit-call-site-info %s -stop-before=finalize-isel -o %t2.mir
+; RUN: cat %t2.mir | FileCheck %s --check-prefix=PRINTER_CGS_CSI
+; PRINTER_CGS_CSI: name: main
+; PRINTER_CGS_CSI: callSites:
+; PRINTER_CGS_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; PRINTER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, typeId:
+; PRINTER_CGS_CSI-NEXT: 7854600665770582568 }
+
+
+;; Test parser.
+;; Verify that we get the same result.
+; RUN: llc --call-graph-section -emit-call-site-info %t2.mir -run-pass=finalize-isel -o - \
+; RUN: | FileCheck %s --check-prefix=PARSER_CGS_CSI
+; PARSER_CGS_CSI: name: main
+; PARSER_CGS_CSI: callSites:
+; PARSER_CGS_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; PARSER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, typeId:
+; PARSER_CGS_CSI-NEXT: 7854600665770582568 }
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local void @foo(i8 signext %a) !type !3 {
+entry:
+ ret void
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local i32 @main() !type !4 {
+entry:
+ %retval = alloca i32, align 4
+ %fp = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp, align 8
+ %0 = load ptr, ptr %fp, align 8
+ call void %0(i8 signext 97) [ "type"(metadata !"_ZTSFvcE.generalized") ]
+ ret i32 0
+}
+
+!3 = !{i64 0, !"_ZTSFvcE.generalized"}
+!4 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
new file mode 100644
index 0000000000000..dd21246e5dedc
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
@@ -0,0 +1,63 @@
+# Test MIR printer and parser for type id field in callSites. It is used
+# for propogating call site type identifiers to emit in the call graph section.
+
+# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
+# CHECK: name: main
+# CHECK: callSites:
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+# CHECK-NEXT: 123456789 }
+
+--- |
+ define dso_local void @foo(i8 signext %a) {
+ entry:
+ ret void
+ }
+
+ define dso_local i32 @main() {
+ entry:
+ %retval = alloca i32, align 4
+ %fp = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp, align 8
+ %0 = load ptr, ptr %fp, align 8
+ call void %0(i8 signext 97)
+ ret i32 0
+ }
+
+...
+---
+name: foo
+tracksRegLiveness: true
+body: |
+ bb.0.entry:
+ RET 0
+
+...
+---
+name: main
+tracksRegLiveness: true
+stack:
+ - { id: 0, name: retval, type: default, offset: 0, size: 4, alignment: 4,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+ - { id: 1, name: fp, type: default, offset: 0, size: 8, alignment: 8,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+callSites:
+ - { bb: 0, offset: 6, fwdArgRegs: [], typeId:
+ 123456789 }
+body: |
+ bb.0.entry:
+ MOV32mi %stack.0.retval, 1, $noreg, 0, $noreg, 0 :: (store (s32) into %ir.retval)
+ MOV64mi32 %stack.1.fp, 1, $noreg, 0, $noreg, @foo :: (store (s64) into %ir.fp)
+ %0:gr64 = MOV32ri64 @foo
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ %1:gr32 = MOV32ri 97
+ $edi = COPY %1
+ CALL64r killed %0, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ %2:gr32 = MOV32r0 implicit-def dead $eflags
+ $eax = COPY %2
+ RET 0, $eax
+
+...
diff --git a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
new file mode 100644
index 0000000000000..91de6a83524e5
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
@@ -0,0 +1,29 @@
+;; Tests that call site type ids can be extracted and set from type operand
+;; bundles.
+
+;; Verify the exact typeId value to ensure it is not garbage but the value
+;; computed as the type id from the type operand bundle.
+; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
+
+define dso_local void @foo(i8 signext %a) !type !3 {
+entry:
+ ret void
+}
+
+; CHECK: name: main
+define dso_local i32 @main() !type !4 {
+entry:
+ %retval = alloca i32, align 4
+ %fp = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp, align 8
+ %0 = load ptr, ptr %fp, align 8
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: 7854600665770582568 }
+ call void %0(i8 signext 97) [ "type"(metadata !"_ZTSFvcE.generalized") ]
+ ret i32 0
+}
+
+!3 = !{i64 0, !"_ZTSFvcE.generalized"}
+!4 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
new file mode 100644
index 0000000000000..6fbdce4f3c206
--- /dev/null
+++ b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
@@ -0,0 +1,29 @@
+;; Tests that call site type ids can be extracted and set from type operand
+;; bundles.
+
+;; Verify the exact typeId value to ensure it is not garbage but the value
+;; computed as the type id from the type operand bundle.
+; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-before=finalize-isel -o - | FileCheck %s
+
+define dso_local void @foo(i8 signext %a) !type !3 {
+entry:
+ ret void
+}
+
+; CHECK: name: main
+define dso_local i32 @main() !type !4 {
+entry:
+ %retval = alloca i32, align 4
+ %fp = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp, align 8
+ %0 = load ptr, ptr %fp, align 8
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: 7854600665770582568 }
+ call void %0(i8 signext 97) [ "type"(metadata !"_ZTSFvcE.generalized") ]
+ ret i32 0
+}
+
+!3 = !{i64 0, !"_ZTSFvcE.generalized"}
+!4 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/call-graph-section.ll b/llvm/test/CodeGen/call-graph-section.ll
new file mode 100644
index 0000000000000..eb10161a62e96
--- /dev/null
+++ b/llvm/test/CodeGen/call-graph-section.ll
@@ -0,0 +1,73 @@
+; Tests that we store the type identifiers in .callgraph section of the binary.
+
+; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
+; RUN: llvm-readelf -x .callgraph - | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define dso_local void @foo() #0 !type !4 {
+entry:
+ ret void
+}
+
+define dso_local i32 @bar(i8 signext %a) #0 !type !5 {
+entry:
+ %a.addr = alloca i8, align 1
+ store i8 %a, i8* %a.addr, align 1
+ ret i32 0
+}
+
+define dso_local i32* @baz(i8* %a) #0 !type !6 {
+entry:
+ %a.addr = alloca i8*, align 8
+ store i8* %a, i8** %a.addr, align 8
+ ret i32* null
+}
+
+define dso_local i32 @main() #0 !type !7 {
+entry:
+ %retval = alloca i32, align 4
+ %fp_foo = alloca void (...)*, align 8
+ %a = alloca i8, align 1
+ %fp_bar = alloca i32 (i8)*, align 8
+ %fp_baz = alloca i32* (i8*)*, align 8
+ store i32 0, i32* %retval, align 4
+ store void (...)* bitcast (void ()* @foo to void (...)*), void (...)** %fp_foo, align 8
+ %0 = load void (...)*, void (...)** %fp_foo, align 8
+ call void (...) %0() [ "type"(metadata !"_ZTSFvE.generalized") ]
+ store i32 (i8)* @bar, i32 (i8)** %fp_bar, align 8
+ %1 = load i32 (i8)*, i32 (i8)** %fp_bar, align 8
+ %2 = load i8, i8* %a, align 1
+ %call = call i32 %1(i8 signext %2) [ "type"(metadata !"_ZTSFicE.generalized") ]
+ store i32* (i8*)* @baz, i32* (i8*)** %fp_baz, align 8
+ %3 = load i32* (i8*)*, i32* (i8*)** %fp_baz, align 8
+ %call1 = call i32* %3(i8* %a) [ "type"(metadata !"_ZTSFPvS_E.generalized") ]
+ call void @foo() [ "type"(metadata !"_ZTSFvE.generalized") ]
+ %4 = load i8, i8* %a, align 1
+ %call2 = call i32 @bar(i8 signext %4) [ "type"(metadata !"_ZTSFicE.generalized") ]
+ %call3 = call i32* @baz(i8* %a) [ "type"(metadata !"_ZTSFPvS_E.generalized") ]
+ ret i32 0
+}
+
+attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+; Check that the numeric type id (md5 hash) for the below type ids are emitted
+; to the callgraph section.
+
+; CHECK: Hex dump of section '.callgraph':
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 7, !"uwtable", i32 1}
+!2 = !{i32 7, !"frame-pointer", i32 2}
+!3 = !{!"clang version 13.0.0 (git at github.com:llvm/llvm-project.git 6d35f403b91c2f2c604e23763f699d580370ca96)"}
+; CHECK-DAG: 2444f731 f5eecb3e
+!4 = !{i64 0, !"_ZTSFvE.generalized"}
+; CHECK-DAG: 5486bc59 814b8e30
+!5 = !{i64 0, !"_ZTSFicE.generalized"}
+; CHECK-DAG: 7ade6814 f897fd77
+!6 = !{i64 0, !"_ZTSFPvS_E.generalized"}
+; CHECK-DAG: caaf769a 600968fa
+!7 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/Verifier/operand-bundles.ll b/llvm/test/Verifier/operand-bundles.ll
index db85b6ae6ef5f..788006494edce 100644
--- a/llvm/test/Verifier/operand-bundles.ll
+++ b/llvm/test/Verifier/operand-bundles.ll
@@ -105,4 +105,17 @@ declare ptr @objc_retainAutoreleasedReturnValue(ptr)
declare ptr @objc_unsafeClaimAutoreleasedReturnValue(ptr)
declare void @llvm.assume(i1)
+define void @f_type(i32* %ptr) {
+; CHECK: Multiple "type" operand bundles
+; CHECK-NEXT: call void @g() [ "type"(metadata !"_ZTSFvE.generalized"), "type"(metadata !"_ZTSFvE.generalized") ]
+; CHECK-NOT: call void @g() [ "type"(metadata !"_ZTSFvE.generalized") ]
+
+ entry:
+ %l = load i32, i32* %ptr
+ call void @g() [ "type"(metadata !"_ZTSFvE.generalized"), "type"(metadata !"_ZTSFvE.generalized") ]
+ call void @g() [ "type"(metadata !"_ZTSFvE.generalized") ]
+ %x = add i32 42, 1
+ ret void
+}
+
attributes #0 = { noreturn }
>From a794047a270a16a53c4e0e8f4114ac099f0f88b6 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Tue, 10 Dec 2024 14:55:27 -0800
Subject: [PATCH 02/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
clang/lib/CodeGen/CGCall.cpp | 38 -------
clang/lib/CodeGen/CGExpr.cpp | 6 --
clang/lib/CodeGen/CGObjCMac.cpp | 5 +-
clang/lib/CodeGen/CodeGenModule.cpp | 35 +------
clang/lib/CodeGen/CodeGenModule.h | 4 -
clang/test/CodeGen/call-graph-section-1.cpp | 110 --------------------
clang/test/CodeGen/call-graph-section-2.cpp | 95 -----------------
clang/test/CodeGen/call-graph-section-3.cpp | 52 ---------
clang/test/CodeGen/call-graph-section.c | 85 ---------------
llvm/include/llvm/CodeGen/MachineFunction.h | 6 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 5 +-
llvm/lib/IR/Verifier.cpp | 7 +-
llvm/test/Verifier/operand-bundles.ll | 4 +-
13 files changed, 17 insertions(+), 435 deletions(-)
delete mode 100644 clang/test/CodeGen/call-graph-section-1.cpp
delete mode 100644 clang/test/CodeGen/call-graph-section-2.cpp
delete mode 100644 clang/test/CodeGen/call-graph-section-3.cpp
delete mode 100644 clang/test/CodeGen/call-graph-section.c
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d5240db0fceb8..35d495d4dfab8 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -25,7 +25,6 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Type.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
@@ -5078,11 +5077,6 @@ static unsigned getMaxVectorWidth(const llvm::Type *Ty) {
return MaxVectorWidth;
}
-static bool isCXXDeclType(const FunctionDecl *FD) {
- return isa<CXXConstructorDecl>(FD) || isa<CXXMethodDecl>(FD) ||
- isa<CXXDestructorDecl>(FD);
-}
-
RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
const CGCallee &Callee,
ReturnValueSlot ReturnValue,
@@ -5771,38 +5765,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
AllocAlignAttrEmitter AllocAlignAttrEmitter(*this, TargetDecl, CallArgs);
Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
- if (CGM.getCodeGenOpts().CallGraphSection) {
- // Create operand bundle only for indirect calls, not for all
- if (callOrInvoke && *callOrInvoke && (*callOrInvoke)->isIndirectCall()) {
-
- assert((TargetDecl && TargetDecl->getFunctionType() ||
- Callee.getAbstractInfo().getCalleeFunctionProtoType()) &&
- "cannot find callsite type");
-
- QualType CST;
- if (TargetDecl && TargetDecl->getFunctionType())
- CST = QualType(TargetDecl->getFunctionType(), 0);
- else if (const auto *FPT =
- Callee.getAbstractInfo().getCalleeFunctionProtoType())
- CST = QualType(FPT, 0);
-
- if (!CST.isNull()) {
- auto *TypeIdMD = CGM.CreateMetadataIdentifierGeneralized(CST);
- auto *TypeIdMDVal =
- llvm::MetadataAsValue::get(getLLVMContext(), TypeIdMD);
- BundleList.emplace_back("type", TypeIdMDVal);
- }
-
- // Set type identifier metadata of indirect calls for call graph section.
- if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
- // Type id metadata is set only for C/C++ contexts.
- if (isCXXDeclType(FD)) {
- CGM.CreateFunctionTypeMetadataForIcall(FD->getType(), *callOrInvoke);
- }
- }
- }
- }
-
// Emit the actual call/invoke instruction.
llvm::CallBase *CI;
if (!InvokeDest) {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 97f2cfe35ec59..232cac22d1bfc 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -6173,12 +6173,6 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
if (CallOrInvoke)
*CallOrInvoke = LocalCallOrInvoke;
- // Set type identifier metadata of indirect calls for call graph section.
- if (CGM.getCodeGenOpts().CallGraphSection && LocalCallOrInvoke &&
- LocalCallOrInvoke->isIndirectCall())
- CGM.CreateFunctionTypeMetadataForIcall(QualType(FnType, 0),
- LocalCallOrInvoke);
-
return Call;
}
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 248fb2ef68c43..7b85dcc2c7984 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -2214,8 +2214,9 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
llvm::CallBase *CallSite;
CGCallee Callee = CGCallee::forDirect(BitcastFn);
- RValue rvalue =
- CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
+ RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
+ &CallSite);
+
// Mark the call as noreturn if the method is marked noreturn and the
// receiver cannot be null.
if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 56a831b13bd08..b854eeb62a80c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2622,9 +2622,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// In the cross-dso CFI mode with canonical jump tables, we want !type
// attributes on definitions only.
- if ((CodeGenOpts.SanitizeCfiCrossDso &&
- CodeGenOpts.SanitizeCfiCanonicalJumpTables) ||
- CodeGenOpts.CallGraphSection) {
+ if (CodeGenOpts.SanitizeCfiCrossDso &&
+ CodeGenOpts.SanitizeCfiCanonicalJumpTables) {
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
// Skip available_externally functions. They won't be codegen'ed in the
// current module anyway.
@@ -2814,17 +2813,7 @@ static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND) {
void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F) {
- bool EmittedMDIdGeneralized = false;
- if (CodeGenOpts.CallGraphSection &&
- (!F->hasLocalLinkage() ||
- F->getFunction().hasAddressTaken(nullptr, /*IgnoreCallbackUses=*/true,
- /*IgnoreAssumeLikeCalls=*/true,
- /*IgnoreLLVMUsed=*/false))) {
- F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType()));
- EmittedMDIdGeneralized = true;
- }
-
- // Add additional metadata only if we are checking indirect calls with CFI.
+ // Only if we are checking indirect calls.
if (!LangOpts.Sanitize.has(SanitizerKind::CFIICall))
return;
@@ -2835,9 +2824,7 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Metadata *MD = CreateMetadataIdentifierForType(FD->getType());
F->addTypeMetadata(0, MD);
- // Add the generalized identifier if not added already.
- if (!EmittedMDIdGeneralized)
- F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType()));
+ F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType()));
// Emit a hash-based bit set entry for cross-DSO calls.
if (CodeGenOpts.SanitizeCfiCrossDso)
@@ -2845,17 +2832,6 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId));
}
-void CodeGenModule::CreateFunctionTypeMetadataForIcall(const QualType &QT,
- llvm::CallBase *CB) {
- // Only if needed for call graph section and only for indirect calls.
- if (!CodeGenOpts.CallGraphSection || !CB || !CB->isIndirectCall())
- return;
-
- auto *MD = CreateMetadataIdentifierGeneralized(QT);
- auto *MDN = llvm::MDNode::get(getLLVMContext(), MD);
- CB->setMetadata(llvm::LLVMContext::MD_type, MDN);
-}
-
void CodeGenModule::setKCFIType(const FunctionDecl *FD, llvm::Function *F) {
llvm::LLVMContext &Ctx = F->getContext();
llvm::MDBuilder MDB(Ctx);
@@ -2983,8 +2959,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
// are non-canonical then we need type metadata in order to produce the local
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
- !CodeGenOpts.SanitizeCfiCanonicalJumpTables ||
- CodeGenOpts.CallGraphSection)
+ !CodeGenOpts.SanitizeCfiCanonicalJumpTables)
CreateFunctionTypeMetadataForIcall(FD, F);
if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index bbaf5b150f176..741b0f17da658 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1572,10 +1572,6 @@ class CodeGenModule : public CodeGenTypeCache {
void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
llvm::Function *F);
- /// Create and attach type metadata to the given call.
- void CreateFunctionTypeMetadataForIcall(const QualType &QT,
- llvm::CallBase *CB);
-
/// Set type metadata to the given function.
void setKCFIType(const FunctionDecl *FD, llvm::Function *F);
diff --git a/clang/test/CodeGen/call-graph-section-1.cpp b/clang/test/CodeGen/call-graph-section-1.cpp
deleted file mode 100644
index 25397e94422b7..0000000000000
--- a/clang/test/CodeGen/call-graph-section-1.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-// Tests that we assign appropriate identifiers to indirect calls and targets
-// specifically for C++ class and instance methods.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fcall-graph-section -S \
-// RUN: -emit-llvm -o %t %s
-// RUN: FileCheck --check-prefix=FT %s < %t
-// RUN: FileCheck --check-prefix=CST %s < %t
-
-////////////////////////////////////////////////////////////////////////////////
-// Class definitions (check for indirect target metadata)
-
-class Cls1 {
-public:
- // FT-DAG: define {{.*}} ptr @_ZN4Cls18receiverEPcPf({{.*}} !type [[F_TCLS1RECEIVER:![0-9]+]]
- static int *receiver(char *a, float *b) { return 0; }
-};
-
-class Cls2 {
-public:
- int *(*fp)(char *, float *);
-
- // FT-DAG: define {{.*}} i32 @_ZN4Cls22f1Ecfd({{.*}} !type [[F_TCLS2F1:![0-9]+]]
- int f1(char a, float b, double c) { return 0; }
-
- // FT-DAG: define {{.*}} ptr @_ZN4Cls22f2EPcPfPd({{.*}} !type [[F_TCLS2F2:![0-9]+]]
- int *f2(char *a, float *b, double *c) { return 0; }
-
- // FT-DAG: define {{.*}} void @_ZN4Cls22f3E4Cls1({{.*}} !type [[F_TCLS2F3F4:![0-9]+]]
- void f3(Cls1 a) {}
-
- // FT-DAG: define {{.*}} void @_ZN4Cls22f4E4Cls1({{.*}} !type [[F_TCLS2F3F4]]
- void f4(const Cls1 a) {}
-
- // FT-DAG: define {{.*}} void @_ZN4Cls22f5EP4Cls1({{.*}} !type [[F_TCLS2F5:![0-9]+]]
- void f5(Cls1 *a) {}
-
- // FT-DAG: define {{.*}} void @_ZN4Cls22f6EPK4Cls1({{.*}} !type [[F_TCLS2F6:![0-9]+]]
- void f6(const Cls1 *a) {}
-
- // FT-DAG: define {{.*}} void @_ZN4Cls22f7ER4Cls1({{.*}} !type [[F_TCLS2F7:![0-9]+]]
- void f7(Cls1 &a) {}
-
- // FT-DAG: define {{.*}} void @_ZN4Cls22f8ERK4Cls1({{.*}} !type [[F_TCLS2F8:![0-9]+]]
- void f8(const Cls1 &a) {}
-
- // FT-DAG: define {{.*}} void @_ZNK4Cls22f9Ev({{.*}} !type [[F_TCLS2F9:![0-9]+]]
- void f9() const {}
-};
-
-// FT-DAG: [[F_TCLS1RECEIVER]] = !{i64 0, !"_ZTSFPvS_S_E.generalized"}
-// FT-DAG: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFPvS_S_S_E.generalized"}
-// FT-DAG: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFicfdE.generalized"}
-// FT-DAG: [[F_TCLS2F3F4]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"}
-// FT-DAG: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvPvE.generalized"}
-// FT-DAG: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvPKvE.generalized"}
-// FT-DAG: [[F_TCLS2F7]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"}
-// FT-DAG: [[F_TCLS2F8]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"}
-// FT-DAG: [[F_TCLS2F9]] = !{i64 0, !"_ZTSKFvvE.generalized"}
-
-////////////////////////////////////////////////////////////////////////////////
-// Callsites (check for indirect callsite operand bundles)
-
-// CST-LABEL: define {{.*}} @_Z3foov
-void foo() {
- Cls2 ObjCls2;
- ObjCls2.fp = &Cls1::receiver;
-
- // CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPvS_S_E.generalized") ]
- ObjCls2.fp(0, 0);
-
- auto fp_f1 = &Cls2::f1;
- auto fp_f2 = &Cls2::f2;
- auto fp_f3 = &Cls2::f3;
- auto fp_f4 = &Cls2::f4;
- auto fp_f5 = &Cls2::f5;
- auto fp_f6 = &Cls2::f6;
- auto fp_f7 = &Cls2::f7;
- auto fp_f8 = &Cls2::f8;
- auto fp_f9 = &Cls2::f9;
-
- Cls2 *ObjCls2Ptr = &ObjCls2;
- Cls1 Cls1Param;
-
- // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFicfdE.generalized") ]
- (ObjCls2Ptr->*fp_f1)(0, 0, 0);
-
- // CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
- (ObjCls2Ptr->*fp_f2)(0, 0, 0);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
- (ObjCls2Ptr->*fp_f3)(Cls1Param);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
- (ObjCls2Ptr->*fp_f4)(Cls1Param);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPvE.generalized") ]
- (ObjCls2Ptr->*fp_f5)(&Cls1Param);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPKvE.generalized") ]
- (ObjCls2Ptr->*fp_f6)(&Cls1Param);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvR4Cls1E.generalized") ]
- (ObjCls2Ptr->*fp_f7)(Cls1Param);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvRK4Cls1E.generalized") ]
- (ObjCls2Ptr->*fp_f8)(Cls1Param);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSKFvvE.generalized") ]
- (ObjCls2Ptr->*fp_f9)();
-}
diff --git a/clang/test/CodeGen/call-graph-section-2.cpp b/clang/test/CodeGen/call-graph-section-2.cpp
deleted file mode 100644
index 4187faea495be..0000000000000
--- a/clang/test/CodeGen/call-graph-section-2.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-// Tests that we assign appropriate identifiers to indirect calls and targets
-// specifically for C++ templates.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fcall-graph-section -S \
-// RUN: -emit-llvm -o %t %s
-// RUN: FileCheck --check-prefix=FT %s < %t
-// RUN: FileCheck --check-prefix=CST %s < %t
-// RUN: FileCheck --check-prefix=CHECK %s < %t
-
-////////////////////////////////////////////////////////////////////////////////
-// Class definitions and template classes (check for indirect target metadata)
-
-class Cls1 {};
-
-// Cls2 is instantiated with T=Cls1 in foo(). Following checks are for this
-// instantiation.
-template <class T>
-class Cls2 {
-public:
- // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f1Ev({{.*}} !type [[F_TCLS2F1:![0-9]+]]
- void f1() {}
-
- // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f2ES0_({{.*}} !type [[F_TCLS2F2:![0-9]+]]
- void f2(T a) {}
-
- // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f3EPS0_({{.*}} !type [[F_TCLS2F3:![0-9]+]]
- void f3(T *a) {}
-
- // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f4EPKS0_({{.*}} !type [[F_TCLS2F4:![0-9]+]]
- void f4(const T *a) {}
-
- // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f5ERS0_({{.*}} !type [[F_TCLS2F5:![0-9]+]]
- void f5(T &a) {}
-
- // FT: define {{.*}} void @_ZN4Cls2I4Cls1E2f6ERKS0_({{.*}} !type [[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-DAG: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFvvE.generalized"}
-// FT-DAG: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"}
-// FT-DAG: [[F_TCLS2F3]] = !{i64 0, !"_ZTSFvPvE.generalized"}
-// FT-DAG: [[F_TCLS2F4]] = !{i64 0, !"_ZTSFvPKvE.generalized"}
-// FT-DAG: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"}
-// FT-DAG: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"}
-
-////////////////////////////////////////////////////////////////////////////////
-// Callsites (check for indirect callsite operand bundles)
-
-template <class T>
-T *T_func(T a, T *b, const T *c, T &d, const T &e) { return b; }
-
-// CST-LABEL: define {{.*}} @_Z3foov
-void foo() {
- // Methods for Cls2<Cls1> is checked above within the template description.
- Cls2<Cls1> Obj;
-
- // CHECK-DAG: define {{.*}} @_Z6T_funcI4Cls1EPT_S1_S2_PKS1_RS1_RS3_({{.*}} !type [[F_TFUNC_CLS1:![0-9]+]]
- // CHECK-DAG: [[F_TFUNC_CLS1]] = !{i64 0, !"_ZTSFPv4Cls1S_PKvRS0_RKS0_E.generalized"}
- Obj.fp = T_func<Cls1>;
- Cls1 Cls1Obj;
-
- // CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPv4Cls1S_PKvRS0_RKS0_E.generalized") ]
- Obj.fp(Cls1Obj, &Cls1Obj, &Cls1Obj, Cls1Obj, Cls1Obj);
-
- // Make indirect calls to Cls2's member methods
- auto fp_f1 = &Cls2<Cls1>::f1;
- auto fp_f2 = &Cls2<Cls1>::f2;
- auto fp_f3 = &Cls2<Cls1>::f3;
- auto fp_f4 = &Cls2<Cls1>::f4;
- auto fp_f5 = &Cls2<Cls1>::f5;
- auto fp_f6 = &Cls2<Cls1>::f6;
-
- auto *Obj2Ptr = &Obj;
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvvE.generalized") ]
- (Obj2Ptr->*fp_f1)();
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
- (Obj2Ptr->*fp_f2)(Cls1Obj);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPvE.generalized") ]
- (Obj2Ptr->*fp_f3)(&Cls1Obj);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPKvE.generalized") ]
- (Obj2Ptr->*fp_f4)(&Cls1Obj);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvR4Cls1E.generalized") ]
- (Obj2Ptr->*fp_f5)(Cls1Obj);
-
- // CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvRK4Cls1E.generalized") ]
- (Obj2Ptr->*fp_f6)(Cls1Obj);
-}
diff --git a/clang/test/CodeGen/call-graph-section-3.cpp b/clang/test/CodeGen/call-graph-section-3.cpp
deleted file mode 100644
index 77bb110c664ef..0000000000000
--- a/clang/test/CodeGen/call-graph-section-3.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Tests that we assign appropriate identifiers to indirect calls and targets
-// specifically for virtual methods.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fcall-graph-section -S \
-// RUN: -emit-llvm -o %t %s
-// RUN: FileCheck --check-prefix=FT %s < %t
-// RUN: FileCheck --check-prefix=CST %s < %t
-
-////////////////////////////////////////////////////////////////////////////////
-// Class definitions (check for indirect target metadata)
-
-class Base {
-public:
- // FT-DAG: define {{.*}} @_ZN4Base2vfEPc({{.*}} !type [[F_TVF:![0-9]+]]
- virtual int vf(char *a) { return 0; };
-};
-
-class Derived : public Base {
-public:
- // FT-DAG: define {{.*}} @_ZN7Derived2vfEPc({{.*}} !type [[F_TVF]]
- int vf(char *a) override { return 1; };
-};
-
-// FT-DAG: [[F_TVF]] = !{i64 0, !"_ZTSFiPvE.generalized"}
-
-////////////////////////////////////////////////////////////////////////////////
-// Callsites (check for indirect callsite operand bundles)
-
-// CST-LABEL: define {{.*}} @_Z3foov
-void foo() {
- auto B = Base();
- auto D = Derived();
-
- Base *Bptr = &B;
- Base *BptrToD = &D;
- Derived *Dptr = &D;
-
- auto FpBaseVf = &Base::vf;
- auto FpDerivedVf = &Derived::vf;
-
- // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
- (Bptr->*FpBaseVf)(0);
-
- // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
- (BptrToD->*FpBaseVf)(0);
-
- // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
- (Dptr->*FpBaseVf)(0);
-
- // CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
- (Dptr->*FpDerivedVf)(0);
-}
diff --git a/clang/test/CodeGen/call-graph-section.c b/clang/test/CodeGen/call-graph-section.c
deleted file mode 100644
index ed1bdb876152a..0000000000000
--- a/clang/test/CodeGen/call-graph-section.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// Tests that we assign appropriate identifiers to indirect calls and targets.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fcall-graph-section -S \
-// RUN: -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,ITANIUM %s
-
-// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fcall-graph-section -S \
-// RUN: -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,MS %s
-
-// CHECK-DAG: define {{(dso_local)?}} void @foo({{.*}} !type [[F_TVOID:![0-9]+]]
-void foo() {
-}
-
-// CHECK-DAG: define {{(dso_local)?}} void @bar({{.*}} !type [[F_TVOID]]
-void bar() {
- void (*fp)() = foo;
- // ITANIUM: call {{.*}} [ "type"(metadata !"_ZTSFvE.generalized") ]
- // MS: call {{.*}} [ "type"(metadata !"?6AX at Z.generalized") ]
- fp();
-}
-
-// CHECK-DAG: define {{(dso_local)?}} i32 @baz({{.*}} !type [[F_TPRIMITIVE:![0-9]+]]
-int baz(char a, float b, double c) {
- return 1;
-}
-
-// CHECK-DAG: define {{(dso_local)?}} ptr @qux({{.*}} !type [[F_TPTR:![0-9]+]]
-int *qux(char *a, float *b, double *c) {
- return 0;
-}
-
-// CHECK-DAG: define {{(dso_local)?}} void @corge({{.*}} !type [[F_TVOID]]
-void corge() {
- int (*fp_baz)(char, float, double) = baz;
- // ITANIUM: call i32 {{.*}} [ "type"(metadata !"_ZTSFicfdE.generalized") ]
- // MS: call i32 {{.*}} [ "type"(metadata !"?6AHDMN at Z.generalized") ]
- fp_baz('a', .0f, .0);
-
- int *(*fp_qux)(char *, float *, double *) = qux;
- // ITANIUM: call ptr {{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
- // MS: call ptr {{.*}} [ "type"(metadata !"?6APEAXPEAX00 at Z.generalized") ]
- fp_qux(0, 0, 0);
-}
-
-struct st1 {
- int *(*fp)(char *, float *, double *);
-};
-
-struct st2 {
- struct st1 m;
-};
-
-// CHECK-DAG: define {{(dso_local)?}} void @stparam({{.*}} !type [[F_TSTRUCT:![0-9]+]]
-void stparam(struct st2 a, struct st2 *b) {}
-
-// CHECK-DAG: define {{(dso_local)?}} void @stf({{.*}} !type [[F_TVOID]]
-void stf() {
- struct st1 St1;
- St1.fp = qux;
- // ITANIUM: call ptr {{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
- // MS: call ptr {{.*}} [ "type"(metadata !"?6APEAXPEAX00 at Z.generalized") ]
- St1.fp(0, 0, 0);
-
- struct st2 St2;
- St2.m.fp = qux;
- // ITANIUM: call ptr {{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
- // MS: call ptr {{.*}} [ "type"(metadata !"?6APEAXPEAX00 at Z.generalized") ]
- St2.m.fp(0, 0, 0);
-
- // ITANIUM: call void {{.*}} [ "type"(metadata !"_ZTSFv3st2PvE.generalized") ]
- // MS: call void {{.*}} [ "type"(metadata !"?6AXUst2@@PEAX at Z.generalized") ]
- void (*fp_stparam)(struct st2, struct st2 *) = stparam;
- fp_stparam(St2, &St2);
-}
-
-// ITANIUM-DAG: [[F_TVOID]] = !{i64 0, !"_ZTSFvE.generalized"}
-// MS-DAG: [[F_TVOID]] = !{i64 0, !"?6AX at Z.generalized"}
-
-// ITANIUM-DAG: [[F_TPRIMITIVE]] = !{i64 0, !"_ZTSFicfdE.generalized"}
-// MS-DAG: [[F_TPRIMITIVE]] = !{i64 0, !"?6AHDMN at Z.generalized"}
-
-// ITANIUM-DAG: [[F_TPTR]] = !{i64 0, !"_ZTSFPvS_S_S_E.generalized"}
-// MS-DAG: [[F_TPTR]] = !{i64 0, !"?6APEAXPEAX00 at Z.generalized"}
-
-// ITANIUM-DAG: [[F_TSTRUCT]] = !{i64 0, !"_ZTSFv3st2PvE.generalized"}
-// MS-DAG: [[F_TSTRUCT]] = !{i64 0, !"?6AXUst2@@PEAX at Z.generalized"}
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index 31c24e3bc8409..28b73c5b37b2e 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -515,7 +515,7 @@ class LLVM_ABI MachineFunction {
auto *OBVal = OB.Inputs.front().get();
auto *TypeIdMD = cast<MetadataAsValue>(OBVal)->getMetadata();
auto *TypeIdStr = cast<MDString>(TypeIdMD);
- assert(TypeIdStr->getString().endswith(".generalized") &&
+ assert(TypeIdStr->getString().ends_with(".generalized") &&
"invalid type identifier");
// Compute numeric type id from generalized type id string
@@ -530,7 +530,7 @@ class LLVM_ABI MachineFunction {
GISelChangeObserver *Observer = nullptr;
using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>;
- /// Map a call instruction to call site arguments forwarding and type id.
+ /// Map a call instruction to call site arguments forwarding info.
CallSiteInfoMap CallSitesInfo;
/// A helper function that returns call site info for a give call
@@ -1392,7 +1392,7 @@ class LLVM_ABI MachineFunction {
});
}
- /// Start tracking the arguments passed to the call \p CallI and call type.
+ /// Start tracking the arguments passed to the call \p CallI.
void addCallSiteInfo(const MachineInstr *CallI, CallSiteInfo &&CallInfo) {
assert(CallI->isCandidateForCallSiteEntry());
bool Inserted =
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 9b48bf3386251..f439783e4946b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1645,11 +1645,8 @@ static ConstantInt *extractNumericCGTypeId(const Function &F) {
}
}
- if (!MDGeneralizedTypeId) {
- errs() << "warning: can't find indirect target type id metadata "
- << "for " << F.getName() << "\n";
+ if (!MDGeneralizedTypeId)
return nullptr;
- }
uint64_t TypeIdVal = llvm::MD5Hash(MDGeneralizedTypeId->getString());
Type *Int64Ty = Type::getInt64Ty(F.getContext());
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 0ad7ba555bfad..b72672e7b8e56 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3707,10 +3707,9 @@ void Verifier::visitCallBase(CallBase &Call) {
if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
visitIntrinsicCall(ID, Call);
- // Verify that a callsite has at most one "deopt", at most one "funclet", at
- // most one "gc-transition", at most one "cfguardtarget", at most one "type",
- // at most one "preallocated" operand bundle, and at most one "ptrauth"
- // operand bundle.
+ // Verify that a callsite has at most one operand bundle for each of the
+ // following: "deopt", "funclet", "gc-transition", "cfguardtarget", "type",
+ // "preallocated", and "ptrauth".
bool FoundDeoptBundle = false, FoundFuncletBundle = false,
FoundGCTransitionBundle = false, FoundCFGuardTargetBundle = false,
FoundPreallocatedBundle = false, FoundGCLiveBundle = false,
diff --git a/llvm/test/Verifier/operand-bundles.ll b/llvm/test/Verifier/operand-bundles.ll
index 788006494edce..575cafad66279 100644
--- a/llvm/test/Verifier/operand-bundles.ll
+++ b/llvm/test/Verifier/operand-bundles.ll
@@ -105,13 +105,13 @@ declare ptr @objc_retainAutoreleasedReturnValue(ptr)
declare ptr @objc_unsafeClaimAutoreleasedReturnValue(ptr)
declare void @llvm.assume(i1)
-define void @f_type(i32* %ptr) {
+define void @f_type(ptr %ptr) {
; CHECK: Multiple "type" operand bundles
; CHECK-NEXT: call void @g() [ "type"(metadata !"_ZTSFvE.generalized"), "type"(metadata !"_ZTSFvE.generalized") ]
; CHECK-NOT: call void @g() [ "type"(metadata !"_ZTSFvE.generalized") ]
entry:
- %l = load i32, i32* %ptr
+ %l = load i32, ptr %ptr, align 4
call void @g() [ "type"(metadata !"_ZTSFvE.generalized"), "type"(metadata !"_ZTSFvE.generalized") ]
call void @g() [ "type"(metadata !"_ZTSFvE.generalized") ]
%x = add i32 42, 1
>From 6a12be2c5b60a95a06875b0b2c4f14228d1fa882 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 12 Mar 2025 23:30:01 +0000
Subject: [PATCH 03/43] Fix EOF newlines.
Created using spr 1.3.6-beta.1
---
clang/test/Driver/call-graph-section.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c
index 108446729d857..5832aa6754137 100644
--- a/clang/test/Driver/call-graph-section.c
+++ b/clang/test/Driver/call-graph-section.c
@@ -2,4 +2,4 @@
// RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s
// CALL-GRAPH-SECTION: "-fcall-graph-section"
-// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section"
\ No newline at end of file
+// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section"
>From a068971d7c237785b3b265882bdf39184de84497 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 13 Mar 2025 01:03:54 +0000
Subject: [PATCH 04/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
...te-info-ambiguous-indirect-call-typeid.mir | 145 ++++++++++++++++++
.../call-site-info-direct-calls-typeid.mir | 145 ++++++++++++++++++
2 files changed, 290 insertions(+)
create mode 100644 llvm/test/CodeGen/MIR/X86/call-site-info-ambiguous-indirect-call-typeid.mir
create mode 100644 llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
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
new file mode 100644
index 0000000000000..9d1b099cc9093
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-ambiguous-indirect-call-typeid.mir
@@ -0,0 +1,145 @@
+# Test MIR printer and parser for type id field in callSites. It is used
+# for propogating call site type identifiers to emit in the call graph section.
+
+# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
+# CHECK: name: main
+# CHECK: callSites:
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+# CHECK-NEXT: 1234567890 }
+
+--- |
+ ; Function Attrs: mustprogress noinline nounwind optnone uwtable
+ define dso_local noundef i32 @_Z3addii(i32 noundef %a, i32 noundef %b) #0 !type !6 !type !6 {
+ entry:
+ %a.addr = alloca i32, align 4
+ %b.addr = alloca i32, align 4
+ store i32 %a, ptr %a.addr, align 4
+ store i32 %b, ptr %b.addr, align 4
+ %0 = load i32, ptr %a.addr, align 4
+ %1 = load i32, ptr %b.addr, align 4
+ %add = add nsw i32 %0, %1
+ ret i32 %add
+ }
+
+ ; Function Attrs: mustprogress noinline nounwind optnone uwtable
+ define dso_local noundef i32 @_Z8multiplyii(i32 noundef %a, i32 noundef %b) #0 !type !6 !type !6 {
+ entry:
+ %a.addr = alloca i32, align 4
+ %b.addr = alloca i32, align 4
+ store i32 %a, ptr %a.addr, align 4
+ store i32 %b, ptr %b.addr, align 4
+ %0 = load i32, ptr %a.addr, align 4
+ %1 = load i32, ptr %b.addr, align 4
+ %mul = mul nsw i32 %0, %1
+ ret i32 %mul
+ }
+
+ ; Function Attrs: mustprogress noinline nounwind optnone uwtable
+ define dso_local noundef ptr @_Z13get_operationb(i1 noundef zeroext %is_addition) #0 !type !7 !type !7 {
+ entry:
+ %is_addition.addr = alloca i8, align 1
+ %storedv = zext i1 %is_addition to i8
+ store i8 %storedv, ptr %is_addition.addr, align 1
+ %0 = load i8, ptr %is_addition.addr, align 1
+ %loadedv = trunc i8 %0 to i1
+ br i1 %loadedv, label %cond.true, label %cond.false
+
+ cond.true: ; preds = %entry
+ br label %cond.end
+
+ cond.false: ; preds = %entry
+ br label %cond.end
+
+ cond.end: ; preds = %cond.false, %cond.true
+ %cond = phi ptr [ @_Z3addii, %cond.true ], [ @_Z8multiplyii, %cond.false ]
+ ret ptr %cond
+ }
+
+ ; Function Attrs: mustprogress noinline norecurse optnone uwtable
+ define dso_local noundef i32 @main(i32 noundef %argc) #1 !type !8 !type !8 {
+ entry:
+ %retval = alloca i32, align 4
+ %argc.addr = alloca i32, align 4
+ %x = alloca i32, align 4
+ %y = alloca i32, align 4
+ %op = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store i32 %argc, ptr %argc.addr, align 4
+ store i32 5, ptr %x, align 4
+ store i32 10, ptr %y, align 4
+ %0 = load i32, ptr %argc.addr, align 4
+ %rem = srem i32 %0, 2
+ %cmp = icmp eq i32 %rem, 0
+ %call = call noundef ptr @_Z13get_operationb(i1 noundef zeroext %cmp) [ "callee_type"(metadata !"_ZTSFPvbE.generalized") ]
+ store ptr %call, ptr %op, align 8
+ %1 = load ptr, ptr %op, align 8
+ %2 = load i32, ptr %x, align 4
+ %3 = load i32, ptr %y, align 4
+ %call1 = call noundef i32 %1(i32 noundef %2, i32 noundef %3) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ ret i32 %call1
+ }
+
+ attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+ attributes #1 = { mustprogress noinline norecurse optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+
+ !6 = !{i64 0, !"_ZTSFiiiE.generalized"}
+ !7 = !{i64 0, !"_ZTSFPvbE.generalized"}
+ !8 = !{i64 0, !"_ZTSFiiE.generalized"}
+
+...
+---
+name: main
+liveins:
+ - { reg: '$edi', virtual-reg: '%0' }
+stack:
+ - { id: 0, name: retval, size: 4 }
+ - { id: 1, name: argc.addr, size: 4 }
+ - { id: 2, name: x, size: 4 }
+ - { id: 3, name: y, size: 4 }
+ - { id: 4, name: op, size: 8 }
+callSites:
+ - { bb: 0, offset: 18, fwdArgRegs: [] }
+ - { bb: 0, offset: 29, fwdArgRegs: [], typeId:
+ 1234567890 }
+body: |
+ bb.0.entry:
+ liveins: $edi
+
+ %0:gr32 = COPY $edi
+ %1:gr32 = COPY killed %0
+ MOV32mi %stack.0.retval, 1, $noreg, 0, $noreg, 0 :: (store (s32) into %ir.retval)
+ MOV32mr %stack.1.argc.addr, 1, $noreg, 0, $noreg, %1 :: (store (s32) into %ir.argc.addr)
+ MOV32mi %stack.2.x, 1, $noreg, 0, $noreg, 5 :: (store (s32) into %ir.x)
+ MOV32mi %stack.3.y, 1, $noreg, 0, $noreg, 10 :: (store (s32) into %ir.y)
+ %21:gr32 = MOV32rm %stack.1.argc.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.argc.addr)
+ %19:gr32 = MOV32ri 2
+ $eax = COPY %21
+ CDQ implicit-def $eax, implicit-def $edx, implicit $eax
+ IDIV32r %19, implicit-def $eax, implicit-def $edx, implicit-def $eflags, implicit $eax, implicit $edx
+ %20:gr32 = COPY $edx
+ CMP32ri %20, 0, implicit-def $eflags
+ %15:gr8 = SETCCr 4, implicit $eflags
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ %12:gr32 = MOVZX32rr8 %15
+ %13:gr32 = AND32ri %12, 1, implicit-def dead $eflags
+ $edi = COPY %13
+ CALL64pcrel32 @_Z13get_operationb, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ %14:gr64 = COPY $rax
+ %10:gr64 = COPY %14
+ MOV64mr %stack.4.op, 1, $noreg, 0, $noreg, %10 :: (store (s64) into %ir.op)
+ %9:gr64 = MOV64rm %stack.4.op, 1, $noreg, 0, $noreg :: (load (s64) from %ir.op)
+ %8:gr32 = MOV32rm %stack.2.x, 1, $noreg, 0, $noreg :: (load (s32) from %ir.x)
+ %7:gr32 = MOV32rm %stack.3.y, 1, $noreg, 0, $noreg :: (load (s32) from %ir.y)
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ $edi = COPY %8
+ $esi = COPY %7
+ CALL64r %9, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ %6:gr32 = COPY $eax
+ %2:gr32 = COPY %6
+ $eax = COPY %2
+ RET64 implicit $eax
+
+...
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
new file mode 100644
index 0000000000000..564cc8268e5cd
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
@@ -0,0 +1,145 @@
+# Test MIR printer and parser to NOT have `typeId` field in callSites. `typeId` is used
+# for propogating call site type identifiers to emit in the call graph section for
+# indirect targets only. This test do not contain any indirect targets.
+
+# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
+# CHECK-NOT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+# CHECK: name: _Z3barii
+# CHECK: callSites:
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
+# CHECK: name: _Z3fooii
+# CHECK: callSites:
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
+
+--- |
+ ; Function Attrs: mustprogress noinline nounwind optnone uwtable
+ define dso_local noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y) #0 !type !6 !type !6 {
+ entry:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ %0 = load i32, ptr %x.addr, align 4
+ %1 = load i32, ptr %y.addr, align 4
+ %add = add nsw i32 %0, %1
+ ret i32 %add
+ }
+
+ ; Function Attrs: mustprogress noinline nounwind optnone uwtable
+ define dso_local noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y) #0 !type !6 !type !6 {
+ entry:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ %0 = load i32, ptr %x.addr, align 4
+ %1 = load i32, ptr %y.addr, align 4
+ %mul = mul nsw i32 %0, %1
+ ret i32 %mul
+ }
+
+ ; Function Attrs: mustprogress noinline nounwind optnone uwtable
+ define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) #0 !type !6 !type !6 {
+ entry:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ %0 = load i32, ptr %x.addr, align 4
+ %1 = load i32, ptr %y.addr, align 4
+ %call = call noundef i32 @_Z4buzzii(i32 noundef %0, i32 noundef %1) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %2 = load i32, ptr %x.addr, align 4
+ %3 = load i32, ptr %y.addr, align 4
+ %call1 = call noundef i32 @_Z4fizzii(i32 noundef %2, i32 noundef %3) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %sub = sub nsw i32 %call, %call1
+ ret i32 %sub
+ }
+
+ ; Function Attrs: mustprogress noinline nounwind optnone uwtable
+ define dso_local noundef i32 @_Z3fooii(i32 noundef %x, i32 noundef %y) #0 !type !6 !type !6 {
+ entry:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ %0 = load i32, ptr %x.addr, align 4
+ %1 = load i32, ptr %y.addr, align 4
+ %call = call noundef i32 @_Z3barii(i32 noundef %0, i32 noundef %1) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ ret i32 %call
+ }
+
+ !6 = !{i64 0, !"_ZTSFiiiE.generalized"}
+
+...
+---
+name: _Z3barii
+stack:
+ - { id: 0, name: x.addr, size: 4 }
+ - { id: 1, name: y.addr, size: 4 }
+callSites:
+ - { bb: 0, offset: 11, fwdArgRegs: [] }
+ - { bb: 0, offset: 20, fwdArgRegs: [] }
+body: |
+ bb.0.entry:
+ liveins: $edi, $esi
+
+ %2:gr32 = COPY $esi
+ %0:gr32 = COPY $edi
+ %1:gr32 = COPY killed %0
+ %3:gr32 = COPY killed %2
+ MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %1 :: (store (s32) into %ir.x.addr)
+ MOV32mr %stack.1.y.addr, 1, $noreg, 0, $noreg, %3 :: (store (s32) into %ir.y.addr)
+ %17:gr32 = MOV32rm %stack.0.x.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.x.addr)
+ %16:gr32 = MOV32rm %stack.1.y.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.y.addr)
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ $edi = COPY %17
+ $esi = COPY %16
+ CALL64pcrel32 @_Z4buzzii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ %15:gr32 = COPY $eax
+ %5:gr32 = COPY %15
+ %12:gr32 = MOV32rm %stack.0.x.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.x.addr)
+ %11:gr32 = MOV32rm %stack.1.y.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.y.addr)
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ $edi = COPY %12
+ $esi = COPY %11
+ CALL64pcrel32 @_Z4fizzii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ %10:gr32 = COPY $eax
+ %6:gr32 = COPY %10
+ %7:gr32 = SUB32rr %5, %6, implicit-def $eflags
+ $eax = COPY %7
+ RET64 implicit $eax
+
+...
+---
+name: _Z3fooii
+stack:
+ - { id: 0, name: x.addr, size: 4 }
+ - { id: 1, name: y.addr, size: 4 }
+callSites:
+ - { bb: 0, offset: 11, fwdArgRegs: [] }
+body: |
+ bb.0.entry:
+ liveins: $edi, $esi
+
+ %2:gr32 = COPY $esi
+ %0:gr32 = COPY $edi
+ %1:gr32 = COPY killed %0
+ %3:gr32 = COPY killed %2
+ MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %1 :: (store (s32) into %ir.x.addr)
+ MOV32mr %stack.1.y.addr, 1, $noreg, 0, $noreg, %3 :: (store (s32) into %ir.y.addr)
+ %9:gr32 = MOV32rm %stack.0.x.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.x.addr)
+ %8:gr32 = MOV32rm %stack.1.y.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.y.addr)
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ $edi = COPY %9
+ $esi = COPY %8
+ CALL64pcrel32 @_Z3barii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ %7:gr32 = COPY $eax
+ %4:gr32 = COPY %7
+ $eax = COPY %4
+ RET64 implicit $eax
+
+...
>From 74044aae4c0b36603f98d1738030fbdc783a0230 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 13 Mar 2025 01:21:41 +0000
Subject: [PATCH 05/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
.../X86/call-site-info-ambiguous-indirect-call-typeid.mir | 3 ---
.../CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir | 6 +++---
2 files changed, 3 insertions(+), 6 deletions(-)
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 9d1b099cc9093..40fb1ddbbc004 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
@@ -80,9 +80,6 @@
ret i32 %call1
}
- attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
- attributes #1 = { mustprogress noinline norecurse optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
-
!6 = !{i64 0, !"_ZTSFiiiE.generalized"}
!7 = !{i64 0, !"_ZTSFPvbE.generalized"}
!8 = !{i64 0, !"_ZTSFiiE.generalized"}
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
index 564cc8268e5cd..528ddb5908d0d 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
@@ -1,6 +1,6 @@
-# Test MIR printer and parser to NOT have `typeId` field in callSites. `typeId` is used
-# for propogating call site type identifiers to emit in the call graph section for
-# indirect targets only. This test do not contain any indirect targets.
+# Test MIR printer and parser to NOT have `typeId` field in callSites.
+# `typeId` is used for propogating call site type identifiers for
+# indirect targets only. This test does not contain any indirect targets.
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
# CHECK-NOT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
>From 1826b033c1e5b9565c64172077940a242f882c16 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 13 Mar 2025 01:41:06 +0000
Subject: [PATCH 06/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/test/CodeGen/X86/call-graph-section.ll | 66 +++++++++++++++++++
llvm/test/CodeGen/call-graph-section.ll | 73 ---------------------
2 files changed, 66 insertions(+), 73 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/call-graph-section.ll
delete mode 100644 llvm/test/CodeGen/call-graph-section.ll
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
new file mode 100644
index 0000000000000..a77a2b8051ed3
--- /dev/null
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -0,0 +1,66 @@
+;; Tests that we store the type identifiers in .callgraph section of the binary.
+
+; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
+; RUN: llvm-readelf -x .callgraph - | FileCheck %s
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local void @foo() #0 !type !4 {
+entry:
+ ret void
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local i32 @bar(i8 signext %a) #0 !type !5 {
+entry:
+ %a.addr = alloca i8, align 1
+ store i8 %a, ptr %a.addr, align 1
+ ret i32 0
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local ptr @baz(ptr %a) #0 !type !6 {
+entry:
+ %a.addr = alloca ptr, align 8
+ store ptr %a, ptr %a.addr, align 8
+ ret ptr null
+}
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local void @main() #0 !type !7 {
+entry:
+ %retval = alloca i32, align 4
+ %fp_foo = alloca ptr, align 8
+ %a = alloca i8, align 1
+ %fp_bar = alloca ptr, align 8
+ %fp_baz = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp_foo, align 8
+ %0 = load ptr, ptr %fp_foo, align 8
+ call void (...) %0() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
+ store ptr @bar, ptr %fp_bar, align 8
+ %1 = load ptr, ptr %fp_bar, align 8
+ %2 = load i8, ptr %a, align 1
+ %call = call i32 %1(i8 signext %2) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
+ store ptr @baz, ptr %fp_baz, align 8
+ %3 = load ptr, ptr %fp_baz, align 8
+ %call1 = call ptr %3(ptr %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
+ call void @foo() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
+ %4 = load i8, ptr %a, align 1
+ %call2 = call i32 @bar(i8 signext %4) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
+ %call3 = call ptr @baz(ptr %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
+ ret void
+}
+
+;; Check that the numeric type id (md5 hash) for the below type ids are emitted
+;; to the callgraph section.
+
+; CHECK: Hex dump of section '.callgraph':
+
+; CHECK-DAG: 2444f731 f5eecb3e
+!4 = !{i64 0, !"_ZTSFvE.generalized"}
+; CHECK-DAG: 5486bc59 814b8e30
+!5 = !{i64 0, !"_ZTSFicE.generalized"}
+; CHECK-DAG: 7ade6814 f897fd77
+!6 = !{i64 0, !"_ZTSFPvS_E.generalized"}
+; CHECK-DAG: caaf769a 600968fa
+!7 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/call-graph-section.ll b/llvm/test/CodeGen/call-graph-section.ll
deleted file mode 100644
index bb158d11e82c9..0000000000000
--- a/llvm/test/CodeGen/call-graph-section.ll
+++ /dev/null
@@ -1,73 +0,0 @@
-; Tests that we store the type identifiers in .callgraph section of the binary.
-
-; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
-; RUN: llvm-readelf -x .callgraph - | FileCheck %s
-
-target triple = "x86_64-unknown-linux-gnu"
-
-define dso_local void @foo() #0 !type !4 {
-entry:
- ret void
-}
-
-define dso_local i32 @bar(i8 signext %a) #0 !type !5 {
-entry:
- %a.addr = alloca i8, align 1
- store i8 %a, i8* %a.addr, align 1
- ret i32 0
-}
-
-define dso_local i32* @baz(i8* %a) #0 !type !6 {
-entry:
- %a.addr = alloca i8*, align 8
- store i8* %a, i8** %a.addr, align 8
- ret i32* null
-}
-
-define dso_local i32 @main() #0 !type !7 {
-entry:
- %retval = alloca i32, align 4
- %fp_foo = alloca void (...)*, align 8
- %a = alloca i8, align 1
- %fp_bar = alloca i32 (i8)*, align 8
- %fp_baz = alloca i32* (i8*)*, align 8
- store i32 0, i32* %retval, align 4
- store void (...)* bitcast (void ()* @foo to void (...)*), void (...)** %fp_foo, align 8
- %0 = load void (...)*, void (...)** %fp_foo, align 8
- call void (...) %0() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
- store i32 (i8)* @bar, i32 (i8)** %fp_bar, align 8
- %1 = load i32 (i8)*, i32 (i8)** %fp_bar, align 8
- %2 = load i8, i8* %a, align 1
- %call = call i32 %1(i8 signext %2) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
- store i32* (i8*)* @baz, i32* (i8*)** %fp_baz, align 8
- %3 = load i32* (i8*)*, i32* (i8*)** %fp_baz, align 8
- %call1 = call i32* %3(i8* %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
- call void @foo() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
- %4 = load i8, i8* %a, align 1
- %call2 = call i32 @bar(i8 signext %4) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
- %call3 = call i32* @baz(i8* %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
- ret i32 0
-}
-
-attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
-
-!llvm.module.flags = !{!0, !1, !2}
-!llvm.ident = !{!3}
-
-; Check that the numeric type id (md5 hash) for the below type ids are emitted
-; to the callgraph section.
-
-; CHECK: Hex dump of section '.callgraph':
-
-!0 = !{i32 1, !"wchar_size", i32 4}
-!1 = !{i32 7, !"uwtable", i32 1}
-!2 = !{i32 7, !"frame-pointer", i32 2}
-!3 = !{!"clang version 13.0.0 (git at github.com:llvm/llvm-project.git 6d35f403b91c2f2c604e23763f699d580370ca96)"}
-; CHECK-DAG: 2444f731 f5eecb3e
-!4 = !{i64 0, !"_ZTSFvE.generalized"}
-; CHECK-DAG: 5486bc59 814b8e30
-!5 = !{i64 0, !"_ZTSFicE.generalized"}
-; CHECK-DAG: 7ade6814 f897fd77
-!6 = !{i64 0, !"_ZTSFPvS_E.generalized"}
-; CHECK-DAG: caaf769a 600968fa
-!7 = !{i64 0, !"_ZTSFiE.generalized"}
>From 2f7dbf2dbcaa45b60ee4bac3637b9dfeaf6a8b7f Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 13 Mar 2025 02:08:35 +0000
Subject: [PATCH 07/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/CodeGen/AsmPrinter.h | 2 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 11 ++++++-----
llvm/test/CodeGen/X86/call-graph-section.ll | 22 +++------------------
3 files changed, 10 insertions(+), 25 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 1ad6d6cd18f9a..f9bf50adef5a7 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -184,7 +184,7 @@ class AsmPrinter : public MachineFunctionPass {
/// Enumeration of function kinds, and their mapping to function kind values
/// stored in call graph section entries.
/// Must match the enum in llvm/tools/llvm-objdump/llvm-objdump.cpp.
- enum FunctionKind {
+ enum class FunctionKind : uint64_t {
/// Function cannot be target to indirect calls.
NOT_INDIRECT_TARGET = 0,
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index a1b86ee368927..d86962668a056 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1706,16 +1706,17 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
// Can be optimized to occupy 2 bits instead.
// Emit function kind, and type id if available.
if (!IsIndirectTarget) {
- OutStreamer->emitInt64(FunctionInfo::FunctionKind::NOT_INDIRECT_TARGET);
+ OutStreamer->emitInt64(
+ static_cast<uint64_t>(FunctionInfo::FunctionKind::NOT_INDIRECT_TARGET));
} else {
const auto *TypeId = extractNumericCGTypeId(F);
if (TypeId) {
- OutStreamer->emitInt64(
- FunctionInfo::FunctionKind::INDIRECT_TARGET_KNOWN_TID);
+ OutStreamer->emitInt64(static_cast<uint64_t>(
+ FunctionInfo::FunctionKind::INDIRECT_TARGET_KNOWN_TID));
OutStreamer->emitInt64(TypeId->getZExtValue());
} else {
- OutStreamer->emitInt64(
- FunctionInfo::FunctionKind::INDIRECT_TARGET_UNKNOWN_TID);
+ OutStreamer->emitInt64(static_cast<uint64_t>(
+ FunctionInfo::FunctionKind::INDIRECT_TARGET_UNKNOWN_TID));
}
}
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index a77a2b8051ed3..d0e6e1acb0c06 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -3,27 +3,11 @@
; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
-; Function Attrs: noinline nounwind optnone uwtable
-define dso_local void @foo() #0 !type !4 {
-entry:
- ret void
-}
+declare !type !4 void @foo() #0
-; Function Attrs: noinline nounwind optnone uwtable
-define dso_local i32 @bar(i8 signext %a) #0 !type !5 {
-entry:
- %a.addr = alloca i8, align 1
- store i8 %a, ptr %a.addr, align 1
- ret i32 0
-}
+declare !type !5 noundef i32 @bar(i8 signext %a) #0
-; Function Attrs: noinline nounwind optnone uwtable
-define dso_local ptr @baz(ptr %a) #0 !type !6 {
-entry:
- %a.addr = alloca ptr, align 8
- store ptr %a, ptr %a.addr, align 8
- ret ptr null
-}
+declare !type !6 noundef ptr @baz(ptr %a) #0
; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @main() #0 !type !7 {
>From 7014fef455703f416e8f86351dcca5974b7b3373 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 13 Mar 2025 02:20:29 +0000
Subject: [PATCH 08/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d86962668a056..8da914385b0d7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1662,8 +1662,8 @@ static ConstantInt *extractNumericCGTypeId(const Function &F) {
return nullptr;
uint64_t TypeIdVal = llvm::MD5Hash(MDGeneralizedTypeId->getString());
- Type *Int64Ty = Type::getInt64Ty(F.getContext());
- return cast<ConstantInt>(ConstantInt::get(Int64Ty, TypeIdVal));
+ IntegerType *Int64Ty = Type::getInt64Ty(F.getContext());
+ return ConstantInt::get(Int64Ty, TypeIdVal);
}
/// Emits call graph section.
>From eb582bd008b291ea346dc18ee6a9e95fc8cc6112 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 13 Mar 2025 17:34:36 +0000
Subject: [PATCH 09/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/CodeGen/MachineFunction.h | 15 ++++++---------
llvm/lib/IR/Verifier.cpp | 7 ++++---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 2 +-
llvm/lib/Target/ARM/ARMISelLowering.cpp | 2 +-
llvm/lib/Target/Mips/MipsISelLowering.cpp | 2 +-
5 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index cdbdd12ef54fc..ef8586dda1040 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -513,20 +513,17 @@ class LLVM_ABI MachineFunction {
if (!CB.isIndirectCall())
return;
- std::optional<OperandBundleUse> Opt =
+ std::optional<OperandBundleUse> CalleeTypeOB =
CB.getOperandBundle(LLVMContext::OB_callee_type);
// Return if the operand bundle for call graph section cannot be found.
- if (!Opt)
+ if (!CalleeTypeOB)
return;
// Get generalized type id string
- auto OB = *Opt;
- assert(OB.Inputs.size() == 1 && "invalid input size");
- auto *OBVal = OB.Inputs.front().get();
- auto *TypeIdMD = cast<MetadataAsValue>(OBVal)->getMetadata();
- auto *TypeIdStr = cast<MDString>(TypeIdMD);
- assert(TypeIdStr->getString().ends_with(".generalized") &&
- "invalid type identifier");
+ Value *CalleeTypeOBVal = CalleeTypeOB->Inputs.front().get();
+ Metadata *TypeIdMD =
+ cast<MetadataAsValue>(CalleeTypeOBVal)->getMetadata();
+ MDString *TypeIdStr = cast<MDString>(TypeIdMD);
// Compute numeric type id from generalized type id string
uint64_t TypeIdVal = MD5Hash(TypeIdStr->getString());
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e01a59908ad80..b0a34488909f8 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3794,9 +3794,10 @@ void Verifier::visitCallBase(CallBase &Call) {
} else if (Tag == LLVMContext::OB_callee_type) {
Check(!FoundCalleeTypeBundle, "Multiple \"callee_type\" operand bundles",
Call);
- auto *OBVal = BU.Inputs.front().get();
- auto *TypeIdMD = cast<MetadataAsValue>(OBVal)->getMetadata();
- auto *TypeIdStr = cast<MDString>(TypeIdMD);
+ Value *CalleeTypeOBVal = BU.Inputs.front().get();
+ Metadata *TypeIdMD =
+ cast<MetadataAsValue>(CalleeTypeOBVal)->getMetadata();
+ MDString *TypeIdStr = cast<MDString>(TypeIdMD);
Check(TypeIdStr->getString().ends_with(".generalized"),
"Invalid \"callee_type\" type identifier", Call);
FoundCalleeTypeBundle = true;
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 82b3543583f9b..6d6b279f41948 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -8915,7 +8915,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID &CallConv = CLI.CallConv;
bool IsVarArg = CLI.IsVarArg;
- const auto *CB = CLI.CB;
+ const CallBase *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
MachineFunction::CallSiteInfo CSInfo;
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index d00d4443dfbfc..95853d9503b8b 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2439,7 +2439,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
CallingConv::ID CallConv = CLI.CallConv;
bool doesNotRet = CLI.DoesNotReturn;
bool isVarArg = CLI.IsVarArg;
- const auto *CB = CLI.CB;
+ const CallBase *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index ef9e4040d5717..2279870ebf955 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3264,7 +3264,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
bool IsVarArg = CLI.IsVarArg;
- const auto *CB = CLI.CB;
+ const CallBase *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
>From 63883644679037cc7ca14b11f982ae788dd6f095 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 13 Mar 2025 18:24:57 +0000
Subject: [PATCH 10/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/test/CodeGen/X86/call-graph-section.ll | 37 ++++++++++-----------
1 file changed, 18 insertions(+), 19 deletions(-)
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index d0e6e1acb0c06..3c295a6d262ff 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -3,14 +3,13 @@
; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
-declare !type !4 void @foo() #0
+declare !type !0 void @foo()
-declare !type !5 noundef i32 @bar(i8 signext %a) #0
+declare !type !1 noundef i32 @bar(i8 signext)
-declare !type !6 noundef ptr @baz(ptr %a) #0
+declare !type !2 noundef ptr @baz(ptr)
-; Function Attrs: noinline nounwind optnone uwtable
-define dso_local void @main() #0 !type !7 {
+define dso_local void @main() !type !3 {
entry:
%retval = alloca i32, align 4
%fp_foo = alloca ptr, align 8
@@ -19,19 +18,19 @@ entry:
%fp_baz = alloca ptr, align 8
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp_foo, align 8
- %0 = load ptr, ptr %fp_foo, align 8
- call void (...) %0() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
+ %fp_foo_val = load ptr, ptr %fp_foo, align 8
+ call void (...) %fp_foo_val() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
store ptr @bar, ptr %fp_bar, align 8
- %1 = load ptr, ptr %fp_bar, align 8
- %2 = load i8, ptr %a, align 1
- %call = call i32 %1(i8 signext %2) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
+ %fp_bar_val = load ptr, ptr %fp_bar, align 8
+ %a_val = load i8, ptr %a, align 1
+ %call_fp_bar = call i32 %fp_bar_val(i8 signext %a_val) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
store ptr @baz, ptr %fp_baz, align 8
- %3 = load ptr, ptr %fp_baz, align 8
- %call1 = call ptr %3(ptr %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
+ %fp_baz_val = load ptr, ptr %fp_baz, align 8
+ %call_fp_baz = call ptr %fp_baz_val(ptr %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
call void @foo() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
- %4 = load i8, ptr %a, align 1
- %call2 = call i32 @bar(i8 signext %4) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
- %call3 = call ptr @baz(ptr %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
+ %a_val_2 = load i8, ptr %a, align 1
+ %call_bar = call i32 @bar(i8 signext %a_val_2) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
+ %call_baz = call ptr @baz(ptr %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
ret void
}
@@ -41,10 +40,10 @@ entry:
; CHECK: Hex dump of section '.callgraph':
; CHECK-DAG: 2444f731 f5eecb3e
-!4 = !{i64 0, !"_ZTSFvE.generalized"}
+!0 = !{i64 0, !"_ZTSFvE.generalized"}
; CHECK-DAG: 5486bc59 814b8e30
-!5 = !{i64 0, !"_ZTSFicE.generalized"}
+!1 = !{i64 0, !"_ZTSFicE.generalized"}
; CHECK-DAG: 7ade6814 f897fd77
-!6 = !{i64 0, !"_ZTSFPvS_E.generalized"}
+!2 = !{i64 0, !"_ZTSFPvS_E.generalized"}
; CHECK-DAG: caaf769a 600968fa
-!7 = !{i64 0, !"_ZTSFiE.generalized"}
+!3 = !{i64 0, !"_ZTSFiE.generalized"}
>From f90b397de952a3c5558d9df497cd7ea4ff83edb6 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Fri, 14 Mar 2025 04:10:28 +0000
Subject: [PATCH 11/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 13 ++++++++
.../CodeGen/AArch64/call-site-info-typeid.ll | 12 ++++----
.../test/CodeGen/ARM/call-site-info-typeid.ll | 12 ++++----
.../CodeGen/Mips/call-site-info-typeid.ll | 12 ++++----
.../CodeGen/RISCV/call-site-info-typeid.ll | 30 +++++++++++++++++++
.../test/CodeGen/X86/call-site-info-typeid.ll | 12 ++++----
6 files changed, 67 insertions(+), 24 deletions(-)
create mode 100644 llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index ff44ff5249973..e21b2e615b223 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20845,8 +20845,14 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
bool IsVarArg = CLI.IsVarArg;
EVT PtrVT = getPointerTy(DAG.getDataLayout());
MVT XLenVT = Subtarget.getXLenVT();
+ const CallBase *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
+ MachineFunction::CallSiteInfo CSInfo;
+
+ // Set type id for call site info.
+ if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
+ CSInfo = MachineFunction::CallSiteInfo(*CB);
// Analyze the operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -21104,6 +21110,9 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
if (CLI.CFIType)
Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
+ if (MF.getTarget().Options.EmitCallGraphSection && CB &&
+ CB->isIndirectCall())
+ DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
return Ret;
}
@@ -21111,6 +21120,10 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
Chain = DAG.getNode(CallOpc, DL, NodeTys, Ops);
if (CLI.CFIType)
Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
+
+ if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
+ DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
+
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
Glue = Chain.getValue(1);
diff --git a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
index b0d4855c72997..1bad6c25dc39a 100644
--- a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
@@ -5,25 +5,25 @@
;; computed as the type id from the type operand bundle.
; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !3 {
+define dso_local void @foo(i8 signext %a) !type !0 {
entry:
ret void
}
; CHECK: name: main
-define dso_local i32 @main() !type !4 {
+define dso_local i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp, align 8
- %0 = load ptr, ptr %fp, align 8
+ %fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
; CHECK-NEXT: 7854600665770582568 }
- call void %0(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
}
-!3 = !{i64 0, !"_ZTSFvcE.generalized"}
-!4 = !{i64 0, !"_ZTSFiE.generalized"}
+!0 = !{i64 0, !"_ZTSFvcE.generalized"}
+!1 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
index 7eb5c3e434fd5..4af6f25c7622a 100644
--- a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
@@ -5,25 +5,25 @@
;; computed as the type id from the type operand bundle.
; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !3 {
+define dso_local void @foo(i8 signext %a) !type !0 {
entry:
ret void
}
; CHECK: name: main
-define dso_local i32 @main() !type !4 {
+define dso_local i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp, align 8
- %0 = load ptr, ptr %fp, align 8
+ %fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
; CHECK-NEXT: 7854600665770582568 }
- call void %0(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
}
-!3 = !{i64 0, !"_ZTSFvcE.generalized"}
-!4 = !{i64 0, !"_ZTSFiE.generalized"}
+!0 = !{i64 0, !"_ZTSFvcE.generalized"}
+!1 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
index 74faa774d78de..05b7fb022eb34 100644
--- a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
@@ -5,25 +5,25 @@
;; computed as the type id from the type operand bundle.
; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !3 {
+define dso_local void @foo(i8 signext %a) !type !0 {
entry:
ret void
}
; CHECK: name: main
-define dso_local i32 @main() !type !4 {
+define dso_local i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp, align 8
- %0 = load ptr, ptr %fp, align 8
+ %fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
; CHECK-NEXT: 7854600665770582568 }
- call void %0(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
}
-!3 = !{i64 0, !"_ZTSFvcE.generalized"}
-!4 = !{i64 0, !"_ZTSFiE.generalized"}
+!0 = !{i64 0, !"_ZTSFvcE.generalized"}
+!1 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll b/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
new file mode 100644
index 0000000000000..e0dac6b40a41f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
@@ -0,0 +1,30 @@
+;; Tests that call site type ids can be extracted and set from type operand
+;; bundles.
+
+;; Verify the exact typeId value to ensure it is not garbage but the value
+;; computed as the type id from the type operand bundle.
+; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-before=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-before=finalize-isel -o - | FileCheck %s
+
+define dso_local void @foo(i8 signext %a) !type !0 {
+entry:
+ ret void
+}
+
+; CHECK: name: main
+define dso_local i32 @main() !type !1 {
+entry:
+ %retval = alloca i32, align 4
+ %fp = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp, align 8
+ %fp_val = load ptr, ptr %fp, align 8
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: 7854600665770582568 }
+ call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ ret i32 0
+}
+
+!0 = !{i64 0, !"_ZTSFvcE.generalized"}
+!1 = !{i64 0, !"_ZTSFiE.generalized"}
diff --git a/llvm/test/CodeGen/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
index 0463bf8627853..57d4bc78275d3 100644
--- a/llvm/test/CodeGen/X86/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
@@ -5,25 +5,25 @@
;; computed as the type id from the type operand bundle.
; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !3 {
+define dso_local void @foo(i8 signext %a) !type !0 {
entry:
ret void
}
; CHECK: name: main
-define dso_local i32 @main() !type !4 {
+define dso_local i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp, align 8
- %0 = load ptr, ptr %fp, align 8
+ %fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
; CHECK-NEXT: 7854600665770582568 }
- call void %0(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
}
-!3 = !{i64 0, !"_ZTSFvcE.generalized"}
-!4 = !{i64 0, !"_ZTSFiE.generalized"}
+!0 = !{i64 0, !"_ZTSFvcE.generalized"}
+!1 = !{i64 0, !"_ZTSFiE.generalized"}
>From da8ae04516a03ddbed3746ab763c4cafb0431609 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Sat, 15 Mar 2025 01:09:53 +0000
Subject: [PATCH 12/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
...te-info-ambiguous-indirect-call-typeid.mir | 107 +++++-------------
.../call-site-info-direct-calls-typeid.mir | 107 +++++-------------
.../CodeGen/MIR/X86/call-site-info-typeid.mir | 31 +----
3 files changed, 60 insertions(+), 185 deletions(-)
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 40fb1ddbbc004..18aad1813339a 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
@@ -9,55 +9,48 @@
# CHECK-NEXT: 1234567890 }
--- |
- ; Function Attrs: mustprogress noinline nounwind optnone uwtable
- define dso_local noundef i32 @_Z3addii(i32 noundef %a, i32 noundef %b) #0 !type !6 !type !6 {
+ define dso_local noundef i32 @_Z3addii(i32 noundef %a, i32 noundef %b) !type !0 !type !0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
store i32 %a, ptr %a.addr, align 4
store i32 %b, ptr %b.addr, align 4
- %0 = load i32, ptr %a.addr, align 4
- %1 = load i32, ptr %b.addr, align 4
- %add = add nsw i32 %0, %1
+ %a_val = load i32, ptr %a.addr, align 4
+ %b_val = load i32, ptr %b.addr, align 4
+ %add = add nsw i32 %a_val, %b_val
ret i32 %add
}
- ; Function Attrs: mustprogress noinline nounwind optnone uwtable
- define dso_local noundef i32 @_Z8multiplyii(i32 noundef %a, i32 noundef %b) #0 !type !6 !type !6 {
+ define dso_local noundef i32 @_Z8multiplyii(i32 noundef %a, i32 noundef %b) !type !0 !type !0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
store i32 %a, ptr %a.addr, align 4
store i32 %b, ptr %b.addr, align 4
- %0 = load i32, ptr %a.addr, align 4
- %1 = load i32, ptr %b.addr, align 4
- %mul = mul nsw i32 %0, %1
+ %a_val = load i32, ptr %a.addr, align 4
+ %b_val = load i32, ptr %b.addr, align 4
+ %mul = mul nsw i32 %a_val, %b_val
ret i32 %mul
}
- ; Function Attrs: mustprogress noinline nounwind optnone uwtable
- define dso_local noundef ptr @_Z13get_operationb(i1 noundef zeroext %is_addition) #0 !type !7 !type !7 {
+ define dso_local noundef ptr @_Z13get_operationb(i1 noundef zeroext %is_addition) !type !1 !type !1 {
entry:
%is_addition.addr = alloca i8, align 1
%storedv = zext i1 %is_addition to i8
store i8 %storedv, ptr %is_addition.addr, align 1
- %0 = load i8, ptr %is_addition.addr, align 1
- %loadedv = trunc i8 %0 to i1
- br i1 %loadedv, label %cond.true, label %cond.false
-
- cond.true: ; preds = %entry
- br label %cond.end
+ %is_addition_val = load i8, ptr %is_addition.addr, align 1
+ %loadedv = trunc i8 %is_addition_val to i1
+ br i1 %loadedv, label %cond.end, label %cond.false
cond.false: ; preds = %entry
br label %cond.end
- cond.end: ; preds = %cond.false, %cond.true
- %cond = phi ptr [ @_Z3addii, %cond.true ], [ @_Z8multiplyii, %cond.false ]
+ cond.end: ; preds = %cond.false, %entry
+ %cond = phi ptr [ @_Z8multiplyii, %cond.false ], [ @_Z3addii, %entry ]
ret ptr %cond
}
- ; Function Attrs: mustprogress noinline norecurse optnone uwtable
- define dso_local noundef i32 @main(i32 noundef %argc) #1 !type !8 !type !8 {
+ define dso_local noundef i32 @main(i32 noundef %argc) !type !2 !type !2 {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
@@ -68,75 +61,33 @@
store i32 %argc, ptr %argc.addr, align 4
store i32 5, ptr %x, align 4
store i32 10, ptr %y, align 4
- %0 = load i32, ptr %argc.addr, align 4
- %rem = srem i32 %0, 2
+ %argc_val = load i32, ptr %argc.addr, align 4
+ %rem = srem i32 %argc_val, 2
%cmp = icmp eq i32 %rem, 0
%call = call noundef ptr @_Z13get_operationb(i1 noundef zeroext %cmp) [ "callee_type"(metadata !"_ZTSFPvbE.generalized") ]
store ptr %call, ptr %op, align 8
- %1 = load ptr, ptr %op, align 8
- %2 = load i32, ptr %x, align 4
- %3 = load i32, ptr %y, align 4
- %call1 = call noundef i32 %1(i32 noundef %2, i32 noundef %3) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %op_val = load ptr, ptr %op, align 8
+ %x_val = load i32, ptr %x, align 4
+ %y_val = load i32, ptr %y, align 4
+ %call1 = call noundef i32 %op_val(i32 noundef %x_val, i32 noundef %y_val) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
ret i32 %call1
}
- !6 = !{i64 0, !"_ZTSFiiiE.generalized"}
- !7 = !{i64 0, !"_ZTSFPvbE.generalized"}
- !8 = !{i64 0, !"_ZTSFiiE.generalized"}
+ !0 = !{i64 0, !"_ZTSFiiiE.generalized"}
+ !1 = !{i64 0, !"_ZTSFPvbE.generalized"}
+ !2 = !{i64 0, !"_ZTSFiiE.generalized"}
...
---
name: main
-liveins:
- - { reg: '$edi', virtual-reg: '%0' }
-stack:
- - { id: 0, name: retval, size: 4 }
- - { id: 1, name: argc.addr, size: 4 }
- - { id: 2, name: x, size: 4 }
- - { id: 3, name: y, size: 4 }
- - { id: 4, name: op, size: 8 }
callSites:
- - { bb: 0, offset: 18, fwdArgRegs: [] }
- - { bb: 0, offset: 29, fwdArgRegs: [], typeId:
+ - { bb: 0, offset: 0, fwdArgRegs: [] }
+ - { bb: 0, offset: 2, fwdArgRegs: [], typeId:
1234567890 }
body: |
bb.0.entry:
- liveins: $edi
-
- %0:gr32 = COPY $edi
- %1:gr32 = COPY killed %0
- MOV32mi %stack.0.retval, 1, $noreg, 0, $noreg, 0 :: (store (s32) into %ir.retval)
- MOV32mr %stack.1.argc.addr, 1, $noreg, 0, $noreg, %1 :: (store (s32) into %ir.argc.addr)
- MOV32mi %stack.2.x, 1, $noreg, 0, $noreg, 5 :: (store (s32) into %ir.x)
- MOV32mi %stack.3.y, 1, $noreg, 0, $noreg, 10 :: (store (s32) into %ir.y)
- %21:gr32 = MOV32rm %stack.1.argc.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.argc.addr)
- %19:gr32 = MOV32ri 2
- $eax = COPY %21
- CDQ implicit-def $eax, implicit-def $edx, implicit $eax
- IDIV32r %19, implicit-def $eax, implicit-def $edx, implicit-def $eflags, implicit $eax, implicit $edx
- %20:gr32 = COPY $edx
- CMP32ri %20, 0, implicit-def $eflags
- %15:gr8 = SETCCr 4, implicit $eflags
- ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- %12:gr32 = MOVZX32rr8 %15
- %13:gr32 = AND32ri %12, 1, implicit-def dead $eflags
- $edi = COPY %13
- CALL64pcrel32 @_Z13get_operationb, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
- ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- %14:gr64 = COPY $rax
- %10:gr64 = COPY %14
- MOV64mr %stack.4.op, 1, $noreg, 0, $noreg, %10 :: (store (s64) into %ir.op)
- %9:gr64 = MOV64rm %stack.4.op, 1, $noreg, 0, $noreg :: (load (s64) from %ir.op)
- %8:gr32 = MOV32rm %stack.2.x, 1, $noreg, 0, $noreg :: (load (s32) from %ir.x)
- %7:gr32 = MOV32rm %stack.3.y, 1, $noreg, 0, $noreg :: (load (s32) from %ir.y)
- ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- $edi = COPY %8
- $esi = COPY %7
- CALL64r %9, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
- ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- %6:gr32 = COPY $eax
- %2:gr32 = COPY %6
- $eax = COPY %2
- RET64 implicit $eax
+ CALL64pcrel32 @_Z13get_operationb, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
+ %7:gr64 = COPY $rax
+ CALL64r %7, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
...
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
index 528ddb5908d0d..c94b20138da55 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
@@ -13,133 +13,78 @@
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
--- |
- ; Function Attrs: mustprogress noinline nounwind optnone uwtable
- define dso_local noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y) #0 !type !6 !type !6 {
+ define dso_local noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
store i32 %x, ptr %x.addr, align 4
store i32 %y, ptr %y.addr, align 4
- %0 = load i32, ptr %x.addr, align 4
- %1 = load i32, ptr %y.addr, align 4
- %add = add nsw i32 %0, %1
+ %x_val = load i32, ptr %x.addr, align 4
+ %y_val = load i32, ptr %y.addr, align 4
+ %add = add nsw i32 %x_val, %y_val
ret i32 %add
}
- ; Function Attrs: mustprogress noinline nounwind optnone uwtable
- define dso_local noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y) #0 !type !6 !type !6 {
+ define dso_local noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
store i32 %x, ptr %x.addr, align 4
store i32 %y, ptr %y.addr, align 4
- %0 = load i32, ptr %x.addr, align 4
- %1 = load i32, ptr %y.addr, align 4
- %mul = mul nsw i32 %0, %1
+ %x_val = load i32, ptr %x.addr, align 4
+ %y_val = load i32, ptr %y.addr, align 4
+ %mul = mul nsw i32 %x_val, %y_val
ret i32 %mul
}
- ; Function Attrs: mustprogress noinline nounwind optnone uwtable
- define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) #0 !type !6 !type !6 {
+ define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
store i32 %x, ptr %x.addr, align 4
store i32 %y, ptr %y.addr, align 4
- %0 = load i32, ptr %x.addr, align 4
- %1 = load i32, ptr %y.addr, align 4
- %call = call noundef i32 @_Z4buzzii(i32 noundef %0, i32 noundef %1) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
- %2 = load i32, ptr %x.addr, align 4
- %3 = load i32, ptr %y.addr, align 4
- %call1 = call noundef i32 @_Z4fizzii(i32 noundef %2, i32 noundef %3) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %x_val = load i32, ptr %x.addr, align 4
+ %y_val = load i32, ptr %y.addr, align 4
+ %call = call noundef i32 @_Z4buzzii(i32 noundef %x_val, i32 noundef %y_val) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %x_val_2 = load i32, ptr %x.addr, align 4
+ %y_val_2 = load i32, ptr %y.addr, align 4
+ %call1 = call noundef i32 @_Z4fizzii(i32 noundef %x_val_2, i32 noundef %y_val_2) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
%sub = sub nsw i32 %call, %call1
ret i32 %sub
}
- ; Function Attrs: mustprogress noinline nounwind optnone uwtable
- define dso_local noundef i32 @_Z3fooii(i32 noundef %x, i32 noundef %y) #0 !type !6 !type !6 {
+ define dso_local noundef i32 @_Z3fooii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
store i32 %x, ptr %x.addr, align 4
store i32 %y, ptr %y.addr, align 4
- %0 = load i32, ptr %x.addr, align 4
- %1 = load i32, ptr %y.addr, align 4
- %call = call noundef i32 @_Z3barii(i32 noundef %0, i32 noundef %1) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %x_val = load i32, ptr %x.addr, align 4
+ %y_val = load i32, ptr %y.addr, align 4
+ %call = call noundef i32 @_Z3barii(i32 noundef %x_val, i32 noundef %y_val) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
ret i32 %call
- }
+ }
- !6 = !{i64 0, !"_ZTSFiiiE.generalized"}
+ !0 = !{i64 0, !"_ZTSFiiiE.generalized"}
...
---
name: _Z3barii
-stack:
- - { id: 0, name: x.addr, size: 4 }
- - { id: 1, name: y.addr, size: 4 }
callSites:
- - { bb: 0, offset: 11, fwdArgRegs: [] }
- - { bb: 0, offset: 20, fwdArgRegs: [] }
+ - { bb: 0, offset: 0, fwdArgRegs: [] }
+ - { bb: 0, offset: 1, fwdArgRegs: [] }
body: |
bb.0.entry:
- liveins: $edi, $esi
-
- %2:gr32 = COPY $esi
- %0:gr32 = COPY $edi
- %1:gr32 = COPY killed %0
- %3:gr32 = COPY killed %2
- MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %1 :: (store (s32) into %ir.x.addr)
- MOV32mr %stack.1.y.addr, 1, $noreg, 0, $noreg, %3 :: (store (s32) into %ir.y.addr)
- %17:gr32 = MOV32rm %stack.0.x.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.x.addr)
- %16:gr32 = MOV32rm %stack.1.y.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.y.addr)
- ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- $edi = COPY %17
- $esi = COPY %16
- CALL64pcrel32 @_Z4buzzii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
- ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- %15:gr32 = COPY $eax
- %5:gr32 = COPY %15
- %12:gr32 = MOV32rm %stack.0.x.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.x.addr)
- %11:gr32 = MOV32rm %stack.1.y.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.y.addr)
- ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- $edi = COPY %12
- $esi = COPY %11
- CALL64pcrel32 @_Z4fizzii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
- ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- %10:gr32 = COPY $eax
- %6:gr32 = COPY %10
- %7:gr32 = SUB32rr %5, %6, implicit-def $eflags
- $eax = COPY %7
- RET64 implicit $eax
+ CALL64pcrel32 @_Z4buzzii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ CALL64pcrel32 @_Z4fizzii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
...
---
name: _Z3fooii
-stack:
- - { id: 0, name: x.addr, size: 4 }
- - { id: 1, name: y.addr, size: 4 }
callSites:
- - { bb: 0, offset: 11, fwdArgRegs: [] }
+ - { bb: 0, offset: 0, fwdArgRegs: [] }
body: |
bb.0.entry:
- liveins: $edi, $esi
-
- %2:gr32 = COPY $esi
- %0:gr32 = COPY $edi
- %1:gr32 = COPY killed %0
- %3:gr32 = COPY killed %2
- MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %1 :: (store (s32) into %ir.x.addr)
- MOV32mr %stack.1.y.addr, 1, $noreg, 0, $noreg, %3 :: (store (s32) into %ir.y.addr)
- %9:gr32 = MOV32rm %stack.0.x.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.x.addr)
- %8:gr32 = MOV32rm %stack.1.y.addr, 1, $noreg, 0, $noreg :: (load (s32) from %ir.y.addr)
- ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- $edi = COPY %9
- $esi = COPY %8
CALL64pcrel32 @_Z3barii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
- ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- %7:gr32 = COPY $eax
- %4:gr32 = COPY %7
- $eax = COPY %4
- RET64 implicit $eax
...
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 a99ee50a608fb..9342c3a70ed40 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
@@ -19,41 +19,20 @@
%fp = alloca ptr, align 8
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp, align 8
- %0 = load ptr, ptr %fp, align 8
- call void %0(i8 signext 97)
+ %fp_val = load ptr, ptr %fp, align 8
+ call void %fp_val(i8 signext 97)
ret i32 0
}
-...
----
-name: foo
-tracksRegLiveness: true
-body: |
- bb.0.entry:
- RET 0
-
...
---
name: main
-tracksRegLiveness: true
-stack:
- - { id: 0, name: retval, size: 4, alignment: 4 }
- - { id: 1, name: fp, size: 8, alignment: 8 }
callSites:
- - { bb: 0, offset: 6, fwdArgRegs: [], typeId:
+ - { bb: 0, offset: 1, fwdArgRegs: [], typeId:
123456789 }
body: |
- bb.0.entry:
- MOV32mi %stack.0.retval, 1, $noreg, 0, $noreg, 0 :: (store (s32) into %ir.retval)
- MOV64mi32 %stack.1.fp, 1, $noreg, 0, $noreg, @foo :: (store (s64) into %ir.fp)
- %0:gr64 = MOV32ri64 @foo
- ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- %1:gr32 = MOV32ri 97
- $edi = COPY %1
+ bb.0.entry:
+ %0:gr64 = MOV32ri64 @foo
CALL64r killed %0, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp
- ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
- %2:gr32 = MOV32r0 implicit-def dead $eflags
- $eax = COPY %2
- RET 0, $eax
...
>From 573eebe303f3acafdca1cf70e9a1cfbc34707e8e Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Wed, 19 Mar 2025 02:54:32 +0000
Subject: [PATCH 13/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/CodeGen/MIRYamlMapping.h | 4 +-
llvm/include/llvm/CodeGen/MachineFunction.h | 4 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +-
llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 10 ++--
llvm/lib/CodeGen/MIRPrinter.cpp | 4 +-
.../CodeGen/AArch64/call-site-info-typeid.ll | 13 ++---
.../test/CodeGen/ARM/call-site-info-typeid.ll | 13 ++---
...te-info-ambiguous-indirect-call-typeid.mir | 48 +++----------------
.../call-site-info-direct-calls-typeid.mir | 28 ++---------
.../CodeGen/MIR/X86/call-site-info-typeid.ll | 26 +++++-----
.../CodeGen/MIR/X86/call-site-info-typeid.mir | 11 ++---
.../CodeGen/Mips/call-site-info-typeid.ll | 11 ++---
.../CodeGen/RISCV/call-site-info-typeid.ll | 11 ++---
.../test/CodeGen/X86/call-site-info-typeid.ll | 11 ++---
llvm/test/Verifier/operand-bundles.ll | 6 +--
15 files changed, 65 insertions(+), 137 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index 93dcc4e09918d..0bc31e6ba084e 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -485,7 +485,7 @@ struct CallSiteInfo {
/// Numeric callee type identifier used for call graph section.
using TypeIdTy = std::optional<uint64_t>;
- TypeIdTy TypeId;
+ TypeIdTy CalleeTypeId;
bool operator==(const CallSiteInfo &Other) const {
return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
@@ -515,7 +515,7 @@ template <> struct MappingTraits<CallSiteInfo> {
YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
std::vector<CallSiteInfo::ArgRegPair>());
- YamlIO.mapOptional("typeId", CSInfo.TypeId);
+ YamlIO.mapOptional("calleeTypeId", CSInfo.CalleeTypeId);
}
static const bool flow = true;
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index ef8586dda1040..bff1a2e28b0de 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -501,7 +501,7 @@ class LLVM_ABI MachineFunction {
SmallVector<ArgRegPair, 1> ArgRegPairs;
/// Callee type id.
- ConstantInt *TypeId = nullptr;
+ ConstantInt *CalleeTypeId = nullptr;
CallSiteInfo() = default;
@@ -528,7 +528,7 @@ class LLVM_ABI MachineFunction {
// Compute numeric type id from generalized type id string
uint64_t TypeIdVal = MD5Hash(TypeIdStr->getString());
IntegerType *Int64Ty = Type::getInt64Ty(CB.getContext());
- TypeId = ConstantInt::get(Int64Ty, TypeIdVal, /*IsSigned=*/false);
+ CalleeTypeId = ConstantInt::get(Int64Ty, TypeIdVal, /*IsSigned=*/false);
}
};
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 8da914385b0d7..264b884ccf37d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2054,7 +2054,7 @@ void AsmPrinter::emitFunctionBody() {
// Only indirect calls have type identifiers set.
const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
if (CallSiteInfo != CallSitesInfoMap.end()) {
- if (auto *TypeId = CallSiteInfo->second.TypeId) {
+ if (auto *TypeId = CallSiteInfo->second.CalleeTypeId) {
// Emit label.
MCSymbol *S = MF->getContext().createTempSymbol();
OutStreamer->emitLabel(S);
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index dbd75a8b9e7c4..e7a0444daa519 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -504,19 +504,19 @@ bool MIRParserImpl::initializeCallSiteInfo(
return error(Error, ArgRegPair.Reg.SourceRange);
CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);
}
- if (YamlCSInfo.TypeId.has_value()) {
+ if (YamlCSInfo.CalleeTypeId) {
IntegerType *Int64Ty = Type::getInt64Ty(Context);
- CSInfo.TypeId = ConstantInt::get(Int64Ty, YamlCSInfo.TypeId.value(),
- /*isSigned=*/false);
+ CSInfo.CalleeTypeId = ConstantInt::get(Int64Ty, *YamlCSInfo.CalleeTypeId,
+ /*isSigned=*/false);
}
if (TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection)
MF.addCallSiteInfo(&*CallI, std::move(CSInfo));
}
- if (YamlMF.CallSitesInfo.size() &&
+ if (!YamlMF.CallSitesInfo.empty() &&
!(TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection))
- return error(Twine("Call site info provided but not used"));
+ return error(Twine("call site info provided but not used"));
return false;
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 9bc6c7fd1e21b..90d130c150d7d 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -577,8 +577,8 @@ void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
}
// Get type id.
- if (CSInfo.second.TypeId)
- YmlCS.TypeId = CSInfo.second.TypeId->getZExtValue();
+ if (CSInfo.second.CalleeTypeId)
+ YmlCS.CalleeTypeId = CSInfo.second.CalleeTypeId->getZExtValue();
YMF.CallSitesInfo.push_back(std::move(YmlCS));
}
diff --git a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
index 1bad6c25dc39a..92d8db473cc11 100644
--- a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
@@ -1,14 +1,11 @@
-;; Tests that call site type ids can be extracted and set from type operand
+;; Tests that call site type ids can be extracted and set from callee_type operand
;; bundles.
-;; Verify the exact typeId value to ensure it is not garbage but the value
-;; computed as the type id from the type operand bundle.
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type operand bundle.
; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !0 {
-entry:
- ret void
-}
+declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
define dso_local i32 @main() !type !1 {
@@ -19,7 +16,7 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
; CHECK-NEXT: 7854600665770582568 }
call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
diff --git a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
index 4af6f25c7622a..e1c338924436d 100644
--- a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
@@ -1,14 +1,11 @@
-;; Tests that call site type ids can be extracted and set from type operand
+;; Tests that call site type ids can be extracted and set from callee_type operand
;; bundles.
-;; Verify the exact typeId value to ensure it is not garbage but the value
-;; computed as the type id from the type operand bundle.
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type operand bundle.
; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !0 {
-entry:
- ret void
-}
+declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
define dso_local i32 @main() !type !1 {
@@ -19,7 +16,7 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
; CHECK-NEXT: 7854600665770582568 }
call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
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 18aad1813339a..afc4701a09803 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
@@ -1,54 +1,20 @@
# Test MIR printer and parser for type id field in callSites. It is used
-# for propogating call site type identifiers to emit in the call graph section.
+# for propagating call site type identifiers to emit in the call graph section.
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
# CHECK: name: main
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
-# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
# CHECK-NEXT: 1234567890 }
--- |
- define dso_local noundef i32 @_Z3addii(i32 noundef %a, i32 noundef %b) !type !0 !type !0 {
- entry:
- %a.addr = alloca i32, align 4
- %b.addr = alloca i32, align 4
- store i32 %a, ptr %a.addr, align 4
- store i32 %b, ptr %b.addr, align 4
- %a_val = load i32, ptr %a.addr, align 4
- %b_val = load i32, ptr %b.addr, align 4
- %add = add nsw i32 %a_val, %b_val
- ret i32 %add
- }
-
- define dso_local noundef i32 @_Z8multiplyii(i32 noundef %a, i32 noundef %b) !type !0 !type !0 {
- entry:
- %a.addr = alloca i32, align 4
- %b.addr = alloca i32, align 4
- store i32 %a, ptr %a.addr, align 4
- store i32 %b, ptr %b.addr, align 4
- %a_val = load i32, ptr %a.addr, align 4
- %b_val = load i32, ptr %b.addr, align 4
- %mul = mul nsw i32 %a_val, %b_val
- ret i32 %mul
- }
- define dso_local noundef ptr @_Z13get_operationb(i1 noundef zeroext %is_addition) !type !1 !type !1 {
- entry:
- %is_addition.addr = alloca i8, align 1
- %storedv = zext i1 %is_addition to i8
- store i8 %storedv, ptr %is_addition.addr, align 1
- %is_addition_val = load i8, ptr %is_addition.addr, align 1
- %loadedv = trunc i8 %is_addition_val to i1
- br i1 %loadedv, label %cond.end, label %cond.false
-
- cond.false: ; preds = %entry
- br label %cond.end
+ declare !type !0 noundef i32 @_Z3addii(i32 noundef, i32 noundef)
+
+ declare !type !0 noundef i32 @_Z8multiplyii(i32 noundef, i32 noundef)
- cond.end: ; preds = %cond.false, %entry
- %cond = phi ptr [ @_Z8multiplyii, %cond.false ], [ @_Z3addii, %entry ]
- ret ptr %cond
- }
+ declare !type !1 noundef ptr @_Z13get_operationb(i1 noundef zeroext %is_addition)
define dso_local noundef i32 @main(i32 noundef %argc) !type !2 !type !2 {
entry:
@@ -82,7 +48,7 @@
name: main
callSites:
- { bb: 0, offset: 0, fwdArgRegs: [] }
- - { bb: 0, offset: 2, fwdArgRegs: [], typeId:
+ - { bb: 0, offset: 2, fwdArgRegs: [], calleeTypeId:
1234567890 }
body: |
bb.0.entry:
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
index c94b20138da55..c02dfd5233eac 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
@@ -1,9 +1,9 @@
# Test MIR printer and parser to NOT have `typeId` field in callSites.
-# `typeId` is used for propogating call site type identifiers for
+# `typeId` is used for propagating call site type identifiers for
# indirect targets only. This test does not contain any indirect targets.
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
-# CHECK-NOT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+# CHECK-NOT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
# CHECK: name: _Z3barii
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
@@ -13,29 +13,9 @@
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
--- |
- define dso_local noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
- entry:
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- %x_val = load i32, ptr %x.addr, align 4
- %y_val = load i32, ptr %y.addr, align 4
- %add = add nsw i32 %x_val, %y_val
- ret i32 %add
- }
+ declare !type !0 noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y)
- define dso_local noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
- entry:
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- %x_val = load i32, ptr %x.addr, align 4
- %y_val = load i32, ptr %y.addr, align 4
- %mul = mul nsw i32 %x_val, %y_val
- ret i32 %mul
- }
+ declare !type !0 noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y)
define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
entry:
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
index 01e4618d9f39d..fe0f9bf443dc0 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
@@ -8,14 +8,14 @@
;; Test printer and parser with --call-graph-section only.
;; Test printer.
-;; Verify that fwdArgRegs is not set, typeId is set.
-;; Verify the exact typeId value to ensure it is not garbage but the value
-;; computed as the type id from the type operand bundle.
+;; Verify that fwdArgRegs is not set, calleeTypeId is set.
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type operand bundle.
; RUN: llc --call-graph-section %s -stop-before=finalize-isel -o %t1.mir
; RUN: cat %t1.mir | FileCheck %s --check-prefix=PRINTER_CGS
; PRINTER_CGS: name: main
; PRINTER_CGS: callSites:
-; PRINTER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+; PRINTER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
; PRINTER_CGS-NEXT: 7854600665770582568 }
@@ -25,21 +25,21 @@
; RUN: | FileCheck %s --check-prefix=PARSER_CGS
; PARSER_CGS: name: main
; PARSER_CGS: callSites:
-; PARSER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+; PARSER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
; PARSER_CGS-NEXT: 7854600665770582568 }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test printer and parser with -emit-call-site-info only.
;; Test printer.
-;; Verify that fwdArgRegs is set, typeId is not set.
+;; Verify that fwdArgRegs is set, calleeTypeId is not set.
; RUN: llc -emit-call-site-info %s -stop-before=finalize-isel -o %t2.mir
; RUN: cat %t2.mir | FileCheck %s --check-prefix=PRINTER_CSI
; PRINTER_CSI: name: main
; PRINTER_CSI: callSites:
; PRINTER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
; PRINTER_CSI-NEXT: { arg: 0, reg: '$edi' }
-; PRINTER_CSI-NOT: typeId:
+; PRINTER_CSI-NOT: calleeTypeId:
;; Test parser.
@@ -50,21 +50,21 @@
; PARSER_CSI: callSites:
; PARSER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
; PARSER_CSI-NEXT: { arg: 0, reg: '$edi' }
-; PARSER_CSI-NOT: typeId:
+; PARSER_CSI-NOT: calleeTypeId:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test printer and parser with both -emit-call-site-info and --call-graph-section.
;; Test printer.
-;; Verify both fwdArgRegs and typeId are set.
-;; Verify the exact typeId value to ensure it is not garbage but the value
-;; computed as the type id from the type operand bundle.
+;; Verify both fwdArgRegs and calleeTypeId are set.
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type operand bundle.
; RUN: llc --call-graph-section -emit-call-site-info %s -stop-before=finalize-isel -o %t2.mir
; RUN: cat %t2.mir | FileCheck %s --check-prefix=PRINTER_CGS_CSI
; PRINTER_CGS_CSI: name: main
; PRINTER_CGS_CSI: callSites:
; PRINTER_CGS_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PRINTER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, typeId:
+; PRINTER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, calleeTypeId:
; PRINTER_CGS_CSI-NEXT: 7854600665770582568 }
@@ -75,7 +75,7 @@
; PARSER_CGS_CSI: name: main
; PARSER_CGS_CSI: callSites:
; PARSER_CGS_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PARSER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, typeId:
+; PARSER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, calleeTypeId:
; PARSER_CGS_CSI-NEXT: 7854600665770582568 }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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 9342c3a70ed40..608849570e836 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
@@ -1,17 +1,14 @@
# Test MIR printer and parser for type id field in callSites. It is used
-# for propogating call site type identifiers to emit in the call graph section.
+# for propagating call site type identifiers to emit in the call graph section.
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
# CHECK: name: main
# CHECK: callSites:
-# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
# CHECK-NEXT: 123456789 }
--- |
- define dso_local void @foo(i8 signext %a) {
- entry:
- ret void
- }
+ declare void @foo(i8 signext %a)
define dso_local i32 @main() {
entry:
@@ -28,7 +25,7 @@
---
name: main
callSites:
- - { bb: 0, offset: 1, fwdArgRegs: [], typeId:
+ - { bb: 0, offset: 1, fwdArgRegs: [], calleeTypeId:
123456789 }
body: |
bb.0.entry:
diff --git a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
index 05b7fb022eb34..e7670dccbf93a 100644
--- a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
@@ -1,14 +1,11 @@
;; Tests that call site type ids can be extracted and set from type operand
;; bundles.
-;; Verify the exact typeId value to ensure it is not garbage but the value
-;; computed as the type id from the type operand bundle.
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type operand bundle.
; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !0 {
-entry:
- ret void
-}
+declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
define dso_local i32 @main() !type !1 {
@@ -19,7 +16,7 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
; CHECK-NEXT: 7854600665770582568 }
call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
diff --git a/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll b/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
index e0dac6b40a41f..3a905e05d0cd2 100644
--- a/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
@@ -1,15 +1,12 @@
;; Tests that call site type ids can be extracted and set from type operand
;; bundles.
-;; Verify the exact typeId value to ensure it is not garbage but the value
-;; computed as the type id from the type operand bundle.
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type operand bundle.
; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-before=finalize-isel -o - | FileCheck %s
; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !0 {
-entry:
- ret void
-}
+declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
define dso_local i32 @main() !type !1 {
@@ -20,7 +17,7 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
; CHECK-NEXT: 7854600665770582568 }
call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
diff --git a/llvm/test/CodeGen/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
index 57d4bc78275d3..4d580c8634ad4 100644
--- a/llvm/test/CodeGen/X86/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
@@ -1,14 +1,11 @@
;; Tests that call site type ids can be extracted and set from type operand
;; bundles.
-;; Verify the exact typeId value to ensure it is not garbage but the value
-;; computed as the type id from the type operand bundle.
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type operand bundle.
; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-before=finalize-isel -o - | FileCheck %s
-define dso_local void @foo(i8 signext %a) !type !0 {
-entry:
- ret void
-}
+declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
define dso_local i32 @main() !type !1 {
@@ -19,7 +16,7 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
; CHECK-NEXT: 7854600665770582568 }
call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
ret i32 0
diff --git a/llvm/test/Verifier/operand-bundles.ll b/llvm/test/Verifier/operand-bundles.ll
index 79b5af35b353e..ed6e10f210c75 100644
--- a/llvm/test/Verifier/operand-bundles.ll
+++ b/llvm/test/Verifier/operand-bundles.ll
@@ -108,14 +108,14 @@ declare void @llvm.assume(i1)
define void @f_type(ptr %ptr) {
; CHECK: Multiple "callee_type" operand bundles
; CHECK-NEXT: call void @g() [ "callee_type"(metadata !"_ZTSFvE.generalized"), "callee_type"(metadata !"_ZTSFvE.generalized") ]
-; CHECK-NOT: call void @g() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
entry:
- %l = load i32, ptr %ptr, align 4
+ %ptr_val = load i32, ptr %ptr, align 4
call void @g() [ "callee_type"(metadata !"_ZTSFvE.generalized"), "callee_type"(metadata !"_ZTSFvE.generalized") ]
- call void @g() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
%x = add i32 42, 1
ret void
}
attributes #0 = { noreturn }
+
+; CHECK-NEXT: error: input module is broken!
>From 823a5130987047b36555238e7030320ed9a19b40 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Sat, 19 Apr 2025 02:18:29 +0000
Subject: [PATCH 14/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/CodeGen/MIRYamlMapping.h | 8 ++--
llvm/include/llvm/CodeGen/MachineFunction.h | 39 +++++++++----------
llvm/include/llvm/IR/FixedMetadataKinds.def | 1 +
llvm/include/llvm/IR/LLVMContext.h | 1 -
llvm/include/llvm/IR/Metadata.h | 2 +
llvm/lib/Analysis/MemoryProfileInfo.cpp | 21 ++++++++++
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 24 ++++++------
llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 10 +++--
llvm/lib/CodeGen/MIRPrinter.cpp | 7 ++--
.../SelectionDAG/SelectionDAGBuilder.cpp | 10 ++---
llvm/lib/IR/LLVMContext.cpp | 4 --
llvm/lib/IR/Verifier.cpp | 37 +++++++++++-------
llvm/lib/Transforms/Utils/Local.cpp | 5 +++
.../Bitcode/operand-bundles-bc-analyzer.ll | 5 +--
.../CodeGen/AArch64/call-site-info-typeid.ll | 13 ++++---
.../test/CodeGen/ARM/call-site-info-typeid.ll | 13 ++++---
...te-info-ambiguous-indirect-call-typeid.mir | 15 +++----
.../call-site-info-direct-calls-typeid.mir | 20 +++++-----
.../CodeGen/MIR/X86/call-site-info-typeid.ll | 31 ++++++++-------
.../CodeGen/MIR/X86/call-site-info-typeid.mir | 8 ++--
.../CodeGen/Mips/call-site-info-typeid.ll | 13 ++++---
.../CodeGen/RISCV/call-site-info-typeid.ll | 11 +++---
llvm/test/CodeGen/X86/call-graph-section.ll | 29 +++++++-------
.../test/CodeGen/X86/call-site-info-typeid.ll | 13 ++++---
llvm/test/Verifier/operand-bundles.ll | 13 -------
25 files changed, 189 insertions(+), 164 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index 0bc31e6ba084e..c920505f0fc05 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -482,10 +482,8 @@ struct CallSiteInfo {
MachineInstrLoc CallLocation;
std::vector<ArgRegPair> ArgForwardingRegs;
-
- /// Numeric callee type identifier used for call graph section.
- using TypeIdTy = std::optional<uint64_t>;
- TypeIdTy CalleeTypeId;
+ /// Numeric callee type identifiers for the callgraph section.
+ std::vector<uint64_t> CalleeTypeIds;
bool operator==(const CallSiteInfo &Other) const {
return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
@@ -515,7 +513,7 @@ template <> struct MappingTraits<CallSiteInfo> {
YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
std::vector<CallSiteInfo::ArgRegPair>());
- YamlIO.mapOptional("calleeTypeId", CSInfo.CalleeTypeId);
+ YamlIO.mapOptional("calleeTypeIds", CSInfo.CalleeTypeIds);
}
static const bool flow = true;
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index bff1a2e28b0de..8d4de273f8a84 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -499,36 +499,33 @@ class LLVM_ABI MachineFunction {
struct CallSiteInfo {
/// Vector of call argument and its forwarding register.
SmallVector<ArgRegPair, 1> ArgRegPairs;
-
- /// Callee type id.
- ConstantInt *CalleeTypeId = nullptr;
+ /// Callee type ids.
+ SmallVector<ConstantInt *, 4> CalleeTypeIds;
CallSiteInfo() = default;
- /// Extracts the numeric type id from the CallBase's type operand bundle,
- /// and sets TypeId. This is used as type id for the indirect call in the
- /// call graph section.
+ /// Extracts the numeric type id from the CallBase's callee_type Metadata,
+ /// and sets CalleeTypeIds. This is used as type id for the indirect call in
+ /// the call graph section.
CallSiteInfo(const CallBase &CB) {
- // Call graph section needs numeric type id only for indirect calls.
+ // Call graph section needs numeric callee_type id only for indirect
+ // calls.
if (!CB.isIndirectCall())
return;
- std::optional<OperandBundleUse> CalleeTypeOB =
- CB.getOperandBundle(LLVMContext::OB_callee_type);
- // Return if the operand bundle for call graph section cannot be found.
- if (!CalleeTypeOB)
+ MDNode *CalleeTypeList = CB.getMetadata(LLVMContext::MD_callee_type);
+ if (!CalleeTypeList)
return;
- // Get generalized type id string
- Value *CalleeTypeOBVal = CalleeTypeOB->Inputs.front().get();
- Metadata *TypeIdMD =
- cast<MetadataAsValue>(CalleeTypeOBVal)->getMetadata();
- MDString *TypeIdStr = cast<MDString>(TypeIdMD);
-
- // Compute numeric type id from generalized type id string
- uint64_t TypeIdVal = MD5Hash(TypeIdStr->getString());
- IntegerType *Int64Ty = Type::getInt64Ty(CB.getContext());
- CalleeTypeId = ConstantInt::get(Int64Ty, TypeIdVal, /*IsSigned=*/false);
+ for (const MDOperand &Op : CalleeTypeList->operands()) {
+ MDNode *TypeMD = cast<MDNode>(Op);
+ MDString *TypeIdStr = cast<MDString>(TypeMD->getOperand(1));
+ // Compute numeric type id from generalized type id string
+ uint64_t TypeIdVal = MD5Hash(TypeIdStr->getString());
+ IntegerType *Int64Ty = Type::getInt64Ty(CB.getContext());
+ CalleeTypeIds.push_back(
+ ConstantInt::get(Int64Ty, TypeIdVal, /*IsSigned=*/false));
+ }
}
};
diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def
index df572e8791e13..90276eae13e4b 100644
--- a/llvm/include/llvm/IR/FixedMetadataKinds.def
+++ b/llvm/include/llvm/IR/FixedMetadataKinds.def
@@ -53,3 +53,4 @@ LLVM_FIXED_MD_KIND(MD_DIAssignID, "DIAssignID", 38)
LLVM_FIXED_MD_KIND(MD_coro_outside_frame, "coro.outside.frame", 39)
LLVM_FIXED_MD_KIND(MD_mmra, "mmra", 40)
LLVM_FIXED_MD_KIND(MD_noalias_addrspace, "noalias.addrspace", 41)
+LLVM_FIXED_MD_KIND(MD_callee_type, "callee_type", 42)
diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h
index 97ff6b73f4473..bbd125fd38cf1 100644
--- a/llvm/include/llvm/IR/LLVMContext.h
+++ b/llvm/include/llvm/IR/LLVMContext.h
@@ -96,7 +96,6 @@ class LLVMContext {
OB_ptrauth = 7, // "ptrauth"
OB_kcfi = 8, // "kcfi"
OB_convergencectrl = 9, // "convergencectrl"
- OB_callee_type = 10, // "callee_type"
};
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index ec7d030a20de8..43a3ba20589dd 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1470,6 +1470,8 @@ class MDNode : public Metadata {
const Instruction *BInstr);
static MDNode *getMergedMemProfMetadata(MDNode *A, MDNode *B);
static MDNode *getMergedCallsiteMetadata(MDNode *A, MDNode *B);
+ static MDNode *getMergedCalleeTypeMetadata(LLVMContext &Ctx, MDNode *A,
+ MDNode *B);
};
/// Tuple of metadata.
diff --git a/llvm/lib/Analysis/MemoryProfileInfo.cpp b/llvm/lib/Analysis/MemoryProfileInfo.cpp
index a22344e19d045..94ddd96226fc5 100644
--- a/llvm/lib/Analysis/MemoryProfileInfo.cpp
+++ b/llvm/lib/Analysis/MemoryProfileInfo.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/MemoryProfileInfo.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/IR/Constants.h"
#include "llvm/Support/CommandLine.h"
@@ -435,3 +436,23 @@ MDNode *MDNode::getMergedCallsiteMetadata(MDNode *A, MDNode *B) {
return A;
return B;
}
+
+MDNode *MDNode::getMergedCalleeTypeMetadata([[maybe_unused]] LLVMContext &Ctx,
+ MDNode *A, MDNode *B) {
+ SmallVector<Metadata *, 8> AB;
+ SmallSet<Metadata *, 8> MergedCallees;
+ auto AddUniqueCallees = [&](llvm::MDNode *N) {
+ if (!N)
+ return;
+ for (const MDOperand &Op : N->operands()) {
+ Metadata *MD = Op.get();
+ if (!MergedCallees.contains(MD)) {
+ MergedCallees.insert(MD);
+ AB.push_back(MD);
+ }
+ }
+ };
+ AddUniqueCallees(A);
+ AddUniqueCallees(B);
+ return llvm::MDNode::get(Ctx, AB);
+}
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 264b884ccf37d..77e8c45faecd5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1651,7 +1651,7 @@ static ConstantInt *extractNumericCGTypeId(const Function &F) {
for (const auto &Type : Types) {
if (Type->getNumOperands() == 2 && isa<MDString>(Type->getOperand(1))) {
auto *TMDS = cast<MDString>(Type->getOperand(1));
- if (TMDS->getString().ends_with("generalized")) {
+ if (TMDS->getString().ends_with(".generalized")) {
MDGeneralizedTypeId = TMDS;
break;
}
@@ -2054,16 +2054,18 @@ void AsmPrinter::emitFunctionBody() {
// Only indirect calls have type identifiers set.
const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
if (CallSiteInfo != CallSitesInfoMap.end()) {
- if (auto *TypeId = CallSiteInfo->second.CalleeTypeId) {
- // Emit label.
- MCSymbol *S = MF->getContext().createTempSymbol();
- OutStreamer->emitLabel(S);
-
- // Get type id value.
- uint64_t TypeIdVal = TypeId->getZExtValue();
-
- // Add to function's callsite labels.
- FuncInfo.CallSiteLabels.emplace_back(TypeIdVal, S);
+ if (!CallSiteInfo->second.CalleeTypeIds.empty()) {
+ for (auto *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
+ // Emit label.
+ MCSymbol *S = MF->getContext().createTempSymbol();
+ OutStreamer->emitLabel(S);
+
+ // Get numeric callee_type id value.
+ uint64_t CalleeTypeIdVal = CalleeTypeId->getZExtValue();
+
+ // Add to function's callsite labels.
+ FuncInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S);
+ }
}
}
}
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index e7a0444daa519..0bee797f53331 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -504,10 +504,12 @@ bool MIRParserImpl::initializeCallSiteInfo(
return error(Error, ArgRegPair.Reg.SourceRange);
CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);
}
- if (YamlCSInfo.CalleeTypeId) {
- IntegerType *Int64Ty = Type::getInt64Ty(Context);
- CSInfo.CalleeTypeId = ConstantInt::get(Int64Ty, *YamlCSInfo.CalleeTypeId,
- /*isSigned=*/false);
+ if (!YamlCSInfo.CalleeTypeIds.empty()) {
+ for (auto CalleeTypeId : YamlCSInfo.CalleeTypeIds) {
+ IntegerType *Int64Ty = Type::getInt64Ty(Context);
+ CSInfo.CalleeTypeIds.push_back(ConstantInt::get(Int64Ty, CalleeTypeId,
+ /*isSigned=*/false));
+ }
}
if (TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection)
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 90d130c150d7d..ef0a4ccccd4cd 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -576,9 +576,10 @@ void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
}
- // Get type id.
- if (CSInfo.second.CalleeTypeId)
- YmlCS.CalleeTypeId = CSInfo.second.CalleeTypeId->getZExtValue();
+ // Get type ids.
+ for (auto *CalleeTypeId : CSInfo.second.CalleeTypeIds) {
+ YmlCS.CalleeTypeIds.push_back(CalleeTypeId->getZExtValue());
+ }
YMF.CallSitesInfo.push_back(std::move(YmlCS));
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 52b088e7ec12b..5a5596a542f72 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3332,8 +3332,7 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
{LLVMContext::OB_deopt, LLVMContext::OB_gc_transition,
LLVMContext::OB_gc_live, LLVMContext::OB_funclet,
LLVMContext::OB_cfguardtarget, LLVMContext::OB_ptrauth,
- LLVMContext::OB_clang_arc_attachedcall,
- LLVMContext::OB_callee_type}) &&
+ LLVMContext::OB_clang_arc_attachedcall}) &&
"Cannot lower invokes with arbitrary operand bundles yet!");
const Value *Callee(I.getCalledOperand());
@@ -3422,9 +3421,8 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
// Deopt bundles are lowered in LowerCallSiteWithDeoptBundle, and we don't
// have to do anything here to lower funclet bundles.
- assert(!I.hasOperandBundlesOtherThan({LLVMContext::OB_deopt,
- LLVMContext::OB_funclet,
- LLVMContext::OB_callee_type}) &&
+ assert(!I.hasOperandBundlesOtherThan(
+ {LLVMContext::OB_deopt, LLVMContext::OB_funclet}) &&
"Cannot lower callbrs with arbitrary operand bundles yet!");
assert(I.isInlineAsm() && "Only know how to handle inlineasm callbr");
@@ -9609,7 +9607,7 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
{LLVMContext::OB_deopt, LLVMContext::OB_funclet,
LLVMContext::OB_cfguardtarget, LLVMContext::OB_preallocated,
LLVMContext::OB_clang_arc_attachedcall, LLVMContext::OB_kcfi,
- LLVMContext::OB_convergencectrl, LLVMContext::OB_callee_type}) &&
+ LLVMContext::OB_convergencectrl}) &&
"Cannot lower calls with arbitrary operand bundles!");
SDValue Callee = getValue(I.getCalledOperand());
diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index 18e95978bd9f6..447e5d92e0b99 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -82,10 +82,6 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
assert(Entry->second == BundleTagID && "operand bundle id drifted!");
}
- [[maybe_unused]] auto *TypeEntry = pImpl->getOrInsertBundleTag("callee_type");
- assert(TypeEntry->second == LLVMContext::OB_callee_type &&
- "callee_type operand bundle id drifted!");
-
SyncScope::ID SingleThreadSSID =
pImpl->getOrInsertSyncScopeID("singlethread");
assert(SingleThreadSSID == SyncScope::SingleThread &&
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index b0a34488909f8..a3be4f32efadb 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -530,6 +530,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
void visitCallStackMetadata(MDNode *MD);
void visitMemProfMetadata(Instruction &I, MDNode *MD);
void visitCallsiteMetadata(Instruction &I, MDNode *MD);
+ void visitCalleeTypeMetadata(Instruction &I, MDNode *MD);
void visitDIAssignIDMetadata(Instruction &I, MDNode *MD);
void visitMMRAMetadata(Instruction &I, MDNode *MD);
void visitAnnotationMetadata(MDNode *Annotation);
@@ -3721,14 +3722,14 @@ void Verifier::visitCallBase(CallBase &Call) {
if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
visitIntrinsicCall(ID, Call);
- // Verify that a callsite has at most one operand bundle for each of the
- // following: "deopt", "funclet", "gc-transition", "cfguardtarget",
- // "callee_type", "preallocated", and "ptrauth".
+ // Verify that a callsite has at most one "deopt", at most one "funclet", at
+ // most one "gc-transition", at most one "cfguardtarget", at most one
+ // "preallocated" operand bundle, and at most one "ptrauth" operand bundle.
bool FoundDeoptBundle = false, FoundFuncletBundle = false,
FoundGCTransitionBundle = false, FoundCFGuardTargetBundle = false,
FoundPreallocatedBundle = false, FoundGCLiveBundle = false,
FoundPtrauthBundle = false, FoundKCFIBundle = false,
- FoundAttachedCallBundle = false, FoundCalleeTypeBundle = false;
+ FoundAttachedCallBundle = false;
for (unsigned i = 0, e = Call.getNumOperandBundles(); i < e; ++i) {
OperandBundleUse BU = Call.getOperandBundleAt(i);
uint32_t Tag = BU.getTagID();
@@ -3791,16 +3792,6 @@ void Verifier::visitCallBase(CallBase &Call) {
"Multiple \"clang.arc.attachedcall\" operand bundles", Call);
FoundAttachedCallBundle = true;
verifyAttachedCallBundle(Call, BU);
- } else if (Tag == LLVMContext::OB_callee_type) {
- Check(!FoundCalleeTypeBundle, "Multiple \"callee_type\" operand bundles",
- Call);
- Value *CalleeTypeOBVal = BU.Inputs.front().get();
- Metadata *TypeIdMD =
- cast<MetadataAsValue>(CalleeTypeOBVal)->getMetadata();
- MDString *TypeIdStr = cast<MDString>(TypeIdMD);
- Check(TypeIdStr->getString().ends_with(".generalized"),
- "Invalid \"callee_type\" type identifier", Call);
- FoundCalleeTypeBundle = true;
}
}
@@ -5060,6 +5051,21 @@ void Verifier::visitCallsiteMetadata(Instruction &I, MDNode *MD) {
visitCallStackMetadata(MD);
}
+void Verifier::visitCalleeTypeMetadata(Instruction &I, MDNode *MD) {
+ Check(isa<CallBase>(I), "!callee_type metadata should only exist on calls",
+ &I);
+ CallBase *CB = cast<CallBase>(&I);
+ Check(CB->isIndirectCall(),
+ "!callee_type metadata should only exist on indirect function calls",
+ &I);
+ for (const auto &Op : MD->operands()) {
+ auto *TypeMD = cast<MDNode>(Op.get());
+ MDString *TypeIdStr = cast<MDString>(TypeMD->getOperand(1));
+ Check(TypeIdStr->getString().ends_with(".generalized"),
+ "Invalid \"callee_type\" type identifier", &I);
+ }
+}
+
void Verifier::visitAnnotationMetadata(MDNode *Annotation) {
Check(isa<MDTuple>(Annotation), "annotation must be a tuple");
Check(Annotation->getNumOperands() >= 1,
@@ -5335,6 +5341,9 @@ void Verifier::visitInstruction(Instruction &I) {
if (MDNode *MD = I.getMetadata(LLVMContext::MD_callsite))
visitCallsiteMetadata(I, MD);
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_callee_type))
+ visitCalleeTypeMetadata(I, MD);
+
if (MDNode *MD = I.getMetadata(LLVMContext::MD_DIAssignID))
visitDIAssignIDMetadata(I, MD);
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 2c6328300738f..4f08c4b703574 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3388,6 +3388,11 @@ static void combineMetadata(Instruction *K, const Instruction *J,
if (!AAOnly)
K->setMetadata(Kind, MDNode::getMergedCallsiteMetadata(KMD, JMD));
break;
+ case LLVMContext::MD_callee_type:
+ if (!AAOnly)
+ K->setMetadata(Kind, MDNode::getMergedCalleeTypeMetadata(
+ K->getContext(), KMD, JMD));
+ break;
case LLVMContext::MD_preserve_access_index:
// Preserve !preserve.access.index in K.
break;
diff --git a/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll b/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
index ca3f3a929194a..d860104b9cb3d 100644
--- a/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
+++ b/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
@@ -13,7 +13,6 @@
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
-; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: </OPERAND_BUNDLE_TAGS_BLOCK
; CHECK: <FUNCTION_BLOCK
@@ -26,9 +25,9 @@
declare void @callee0()
-define void @f0(ptr %ptr) {
+define void @f0(i32* %ptr) {
entry:
- %l = load i32, ptr %ptr
+ %l = load i32, i32* %ptr
%x = add i32 42, 1
call void @callee0() [ "foo"(i32 42, i64 100, i32 %x), "bar"(float 0.000000e+00, i64 100, i32 %l) ]
ret void
diff --git a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
index 92d8db473cc11..e72ba58328f51 100644
--- a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
@@ -1,8 +1,8 @@
-;; Tests that call site type ids can be extracted and set from callee_type operand
-;; bundles.
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata.
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
-;; computed as the type id from the callee_type operand bundle.
+;; computed as the type id from the callee_type metadata.
; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
@@ -16,11 +16,12 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
- ; CHECK-NEXT: 7854600665770582568 }
- call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 7854600665770582568 ] }
+ call void %fp_val(i8 signext 97), !callee_type !2
ret i32 0
}
!0 = !{i64 0, !"_ZTSFvcE.generalized"}
!1 = !{i64 0, !"_ZTSFiE.generalized"}
+!2 = !{!0}
diff --git a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
index e1c338924436d..aebcf918eb1bc 100644
--- a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
@@ -1,8 +1,8 @@
-;; Tests that call site type ids can be extracted and set from callee_type operand
-;; bundles.
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata.
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
-;; computed as the type id from the callee_type operand bundle.
+;; computed as the type id from the callee_type metadata.
; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
@@ -16,11 +16,12 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
- ; CHECK-NEXT: 7854600665770582568 }
- call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 7854600665770582568 ] }
+ call void %fp_val(i8 signext 97), !callee_type !2
ret i32 0
}
!0 = !{i64 0, !"_ZTSFvcE.generalized"}
!1 = !{i64 0, !"_ZTSFiE.generalized"}
+!2 = !{!0}
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 afc4701a09803..a7073cb1ca5f0 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
@@ -5,8 +5,8 @@
# CHECK: name: main
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
-# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
-# CHECK-NEXT: 1234567890 }
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+# CHECK-NEXT: [ 1234567890 ] }
--- |
@@ -16,7 +16,7 @@
declare !type !1 noundef ptr @_Z13get_operationb(i1 noundef zeroext %is_addition)
- define dso_local noundef i32 @main(i32 noundef %argc) !type !2 !type !2 {
+ define dso_local noundef i32 @main(i32 noundef %argc) !type !2 {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
@@ -30,26 +30,27 @@
%argc_val = load i32, ptr %argc.addr, align 4
%rem = srem i32 %argc_val, 2
%cmp = icmp eq i32 %rem, 0
- %call = call noundef ptr @_Z13get_operationb(i1 noundef zeroext %cmp) [ "callee_type"(metadata !"_ZTSFPvbE.generalized") ]
+ %call = call noundef ptr @_Z13get_operationb(i1 noundef zeroext %cmp)
store ptr %call, ptr %op, align 8
%op_val = load ptr, ptr %op, align 8
%x_val = load i32, ptr %x, align 4
%y_val = load i32, ptr %y, align 4
- %call1 = call noundef i32 %op_val(i32 noundef %x_val, i32 noundef %y_val) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %call1 = call noundef i32 %op_val(i32 noundef %x_val, i32 noundef %y_val), !callee_type !3
ret i32 %call1
}
!0 = !{i64 0, !"_ZTSFiiiE.generalized"}
!1 = !{i64 0, !"_ZTSFPvbE.generalized"}
!2 = !{i64 0, !"_ZTSFiiE.generalized"}
+ !3 = !{!0}
...
---
name: main
callSites:
- { bb: 0, offset: 0, fwdArgRegs: [] }
- - { bb: 0, offset: 2, fwdArgRegs: [], calleeTypeId:
- 1234567890 }
+ - { bb: 0, offset: 2, fwdArgRegs: [], calleeTypeIds:
+ [ 1234567890 ] }
body: |
bb.0.entry:
CALL64pcrel32 @_Z13get_operationb, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
index c02dfd5233eac..147d265eaac52 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
@@ -1,9 +1,9 @@
-# Test MIR printer and parser to NOT have `typeId` field in callSites.
-# `typeId` is used for propagating call site type identifiers for
+# Test MIR printer and parser to NOT have `CalleeTypeIds` field in callSites.
+# `CalleeTypeId` is used for propagating call site type identifiers for
# indirect targets only. This test does not contain any indirect targets.
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
-# CHECK-NOT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
+# CHECK-NOT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
# CHECK: name: _Z3barii
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
@@ -13,11 +13,11 @@
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
--- |
- declare !type !0 noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y)
+ declare noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y)
- declare !type !0 noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y)
+ declare noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y)
- define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
+ define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
@@ -25,15 +25,15 @@
store i32 %y, ptr %y.addr, align 4
%x_val = load i32, ptr %x.addr, align 4
%y_val = load i32, ptr %y.addr, align 4
- %call = call noundef i32 @_Z4buzzii(i32 noundef %x_val, i32 noundef %y_val) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %call = call noundef i32 @_Z4buzzii(i32 noundef %x_val, i32 noundef %y_val)
%x_val_2 = load i32, ptr %x.addr, align 4
%y_val_2 = load i32, ptr %y.addr, align 4
- %call1 = call noundef i32 @_Z4fizzii(i32 noundef %x_val_2, i32 noundef %y_val_2) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %call1 = call noundef i32 @_Z4fizzii(i32 noundef %x_val_2, i32 noundef %y_val_2)
%sub = sub nsw i32 %call, %call1
ret i32 %sub
}
- define dso_local noundef i32 @_Z3fooii(i32 noundef %x, i32 noundef %y) !type !0 !type !0 {
+ define dso_local noundef i32 @_Z3fooii(i32 noundef %x, i32 noundef %y) {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
@@ -41,7 +41,7 @@
store i32 %y, ptr %y.addr, align 4
%x_val = load i32, ptr %x.addr, align 4
%y_val = load i32, ptr %y.addr, align 4
- %call = call noundef i32 @_Z3barii(i32 noundef %x_val, i32 noundef %y_val) [ "callee_type"(metadata !"_ZTSFiiiE.generalized") ]
+ %call = call noundef i32 @_Z3barii(i32 noundef %x_val, i32 noundef %y_val)
ret i32 %call
}
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
index fe0f9bf443dc0..fed4fc81c88b0 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
@@ -8,15 +8,15 @@
;; Test printer and parser with --call-graph-section only.
;; Test printer.
-;; Verify that fwdArgRegs is not set, calleeTypeId is set.
-;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
-;; computed as the type id from the callee_type operand bundle.
+;; Verify that fwdArgRegs is not set, calleeTypeIds is set.
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type metadata.
; RUN: llc --call-graph-section %s -stop-before=finalize-isel -o %t1.mir
; RUN: cat %t1.mir | FileCheck %s --check-prefix=PRINTER_CGS
; PRINTER_CGS: name: main
; PRINTER_CGS: callSites:
-; PRINTER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
-; PRINTER_CGS-NEXT: 7854600665770582568 }
+; PRINTER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+; PRINTER_CGS-NEXT: [ 7854600665770582568 ] }
;; Test parser.
@@ -25,8 +25,8 @@
; RUN: | FileCheck %s --check-prefix=PARSER_CGS
; PARSER_CGS: name: main
; PARSER_CGS: callSites:
-; PARSER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
-; PARSER_CGS-NEXT: 7854600665770582568 }
+; PARSER_CGS-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+; PARSER_CGS-NEXT: [ 7854600665770582568 ] }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test printer and parser with -emit-call-site-info only.
@@ -39,7 +39,7 @@
; PRINTER_CSI: callSites:
; PRINTER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
; PRINTER_CSI-NEXT: { arg: 0, reg: '$edi' }
-; PRINTER_CSI-NOT: calleeTypeId:
+; PRINTER_CSI-NOT: calleeTypeIds:
;; Test parser.
@@ -50,7 +50,7 @@
; PARSER_CSI: callSites:
; PARSER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
; PARSER_CSI-NEXT: { arg: 0, reg: '$edi' }
-; PARSER_CSI-NOT: calleeTypeId:
+; PARSER_CSI-NOT: calleeTypeIds:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test printer and parser with both -emit-call-site-info and --call-graph-section.
@@ -58,14 +58,14 @@
;; Test printer.
;; Verify both fwdArgRegs and calleeTypeId are set.
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
-;; computed as the type id from the callee_type operand bundle.
+;; computed as the type id from the callee_type metadata.
; RUN: llc --call-graph-section -emit-call-site-info %s -stop-before=finalize-isel -o %t2.mir
; RUN: cat %t2.mir | FileCheck %s --check-prefix=PRINTER_CGS_CSI
; PRINTER_CGS_CSI: name: main
; PRINTER_CGS_CSI: callSites:
; PRINTER_CGS_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PRINTER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, calleeTypeId:
-; PRINTER_CGS_CSI-NEXT: 7854600665770582568 }
+; PRINTER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, calleeTypeIds:
+; PRINTER_CGS_CSI-NEXT: [ 7854600665770582568 ] }
;; Test parser.
@@ -75,8 +75,8 @@
; PARSER_CGS_CSI: name: main
; PARSER_CGS_CSI: callSites:
; PARSER_CGS_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PARSER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, calleeTypeId:
-; PARSER_CGS_CSI-NEXT: 7854600665770582568 }
+; PARSER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, calleeTypeIds:
+; PARSER_CGS_CSI-NEXT: [ 7854600665770582568 ] }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -94,9 +94,10 @@ entry:
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp, align 8
%0 = load ptr, ptr %fp, align 8
- call void %0(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ call void %0(i8 signext 97), !callee_type !5
ret i32 0
}
!3 = !{i64 0, !"_ZTSFvcE.generalized"}
!4 = !{i64 0, !"_ZTSFiE.generalized"}
+!5 = !{!3}
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 608849570e836..e2f212e52d176 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
@@ -4,8 +4,8 @@
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s
# CHECK: name: main
# CHECK: callSites:
-# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
-# CHECK-NEXT: 123456789 }
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+# CHECK-NEXT: [ 123456789 ] }
--- |
declare void @foo(i8 signext %a)
@@ -25,8 +25,8 @@
---
name: main
callSites:
- - { bb: 0, offset: 1, fwdArgRegs: [], calleeTypeId:
- 123456789 }
+ - { bb: 0, offset: 1, fwdArgRegs: [], calleeTypeIds:
+ [ 123456789 ] }
body: |
bb.0.entry:
%0:gr64 = MOV32ri64 @foo
diff --git a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
index e7670dccbf93a..826be8121d183 100644
--- a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
@@ -1,8 +1,8 @@
-;; Tests that call site type ids can be extracted and set from type operand
-;; bundles.
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata.
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
-;; computed as the type id from the callee_type operand bundle.
+;; computed as the type id from the callee_type metadata.
; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
@@ -16,11 +16,12 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
- ; CHECK-NEXT: 7854600665770582568 }
- call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 7854600665770582568 ] }
+ call void %fp_val(i8 signext 97), !callee_type !2
ret i32 0
}
!0 = !{i64 0, !"_ZTSFvcE.generalized"}
!1 = !{i64 0, !"_ZTSFiE.generalized"}
+!2 = !{!0}
diff --git a/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll b/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
index 3a905e05d0cd2..10fdd15547ec0 100644
--- a/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
@@ -1,5 +1,5 @@
-;; Tests that call site type ids can be extracted and set from type operand
-;; bundles.
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata.
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
;; computed as the type id from the callee_type operand bundle.
@@ -17,11 +17,12 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
- ; CHECK-NEXT: 7854600665770582568 }
- call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 7854600665770582568 ] }
+ call void %fp_val(i8 signext 97), !callee_type !2
ret i32 0
}
!0 = !{i64 0, !"_ZTSFvcE.generalized"}
!1 = !{i64 0, !"_ZTSFiE.generalized"}
+!2 = !{!0}
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index 3c295a6d262ff..db44b5e5ca3a6 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -3,13 +3,13 @@
; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
-declare !type !0 void @foo()
+declare void @foo()
-declare !type !1 noundef i32 @bar(i8 signext)
+declare noundef i32 @bar(i8 signext)
-declare !type !2 noundef ptr @baz(ptr)
+declare noundef ptr @baz(ptr)
-define dso_local void @main() !type !3 {
+define dso_local void @main() {
entry:
%retval = alloca i32, align 4
%fp_foo = alloca ptr, align 8
@@ -19,18 +19,18 @@ entry:
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp_foo, align 8
%fp_foo_val = load ptr, ptr %fp_foo, align 8
- call void (...) %fp_foo_val() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
+ call void (...) %fp_foo_val(), !callee_type !1
store ptr @bar, ptr %fp_bar, align 8
%fp_bar_val = load ptr, ptr %fp_bar, align 8
%a_val = load i8, ptr %a, align 1
- %call_fp_bar = call i32 %fp_bar_val(i8 signext %a_val) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
+ %call_fp_bar = call i32 %fp_bar_val(i8 signext %a_val), !callee_type !3
store ptr @baz, ptr %fp_baz, align 8
%fp_baz_val = load ptr, ptr %fp_baz, align 8
- %call_fp_baz = call ptr %fp_baz_val(ptr %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
- call void @foo() [ "callee_type"(metadata !"_ZTSFvE.generalized") ]
+ %call_fp_baz = call ptr %fp_baz_val(ptr %a), !callee_type !5
+ call void @foo()
%a_val_2 = load i8, ptr %a, align 1
- %call_bar = call i32 @bar(i8 signext %a_val_2) [ "callee_type"(metadata !"_ZTSFicE.generalized") ]
- %call_baz = call ptr @baz(ptr %a) [ "callee_type"(metadata !"_ZTSFPvS_E.generalized") ]
+ %call_bar = call i32 @bar(i8 signext %a_val_2)
+ %call_baz = call ptr @baz(ptr %a)
ret void
}
@@ -41,9 +41,10 @@ entry:
; CHECK-DAG: 2444f731 f5eecb3e
!0 = !{i64 0, !"_ZTSFvE.generalized"}
+!1 = !{!0}
; CHECK-DAG: 5486bc59 814b8e30
-!1 = !{i64 0, !"_ZTSFicE.generalized"}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{!2}
; CHECK-DAG: 7ade6814 f897fd77
-!2 = !{i64 0, !"_ZTSFPvS_E.generalized"}
-; CHECK-DAG: caaf769a 600968fa
-!3 = !{i64 0, !"_ZTSFiE.generalized"}
+!4 = !{i64 0, !"_ZTSFPvS_E.generalized"}
+!5 = !{!4}
diff --git a/llvm/test/CodeGen/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
index 4d580c8634ad4..c785cd636732a 100644
--- a/llvm/test/CodeGen/X86/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
@@ -1,8 +1,8 @@
-;; Tests that call site type ids can be extracted and set from type operand
-;; bundles.
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata.
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
-;; computed as the type id from the callee_type operand bundle.
+;; computed as the type id from the callee_type metadata.
; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-before=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
@@ -16,11 +16,12 @@ entry:
store ptr @foo, ptr %fp, align 8
%fp_val = load ptr, ptr %fp, align 8
; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeId:
- ; CHECK-NEXT: 7854600665770582568 }
- call void %fp_val(i8 signext 97) [ "callee_type"(metadata !"_ZTSFvcE.generalized") ]
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 7854600665770582568 ] }
+ call void %fp_val(i8 signext 97), !callee_type !2
ret i32 0
}
!0 = !{i64 0, !"_ZTSFvcE.generalized"}
!1 = !{i64 0, !"_ZTSFiE.generalized"}
+!2 = !{!0}
diff --git a/llvm/test/Verifier/operand-bundles.ll b/llvm/test/Verifier/operand-bundles.ll
index ed6e10f210c75..db85b6ae6ef5f 100644
--- a/llvm/test/Verifier/operand-bundles.ll
+++ b/llvm/test/Verifier/operand-bundles.ll
@@ -105,17 +105,4 @@ declare ptr @objc_retainAutoreleasedReturnValue(ptr)
declare ptr @objc_unsafeClaimAutoreleasedReturnValue(ptr)
declare void @llvm.assume(i1)
-define void @f_type(ptr %ptr) {
-; CHECK: Multiple "callee_type" operand bundles
-; CHECK-NEXT: call void @g() [ "callee_type"(metadata !"_ZTSFvE.generalized"), "callee_type"(metadata !"_ZTSFvE.generalized") ]
-
- entry:
- %ptr_val = load i32, ptr %ptr, align 4
- call void @g() [ "callee_type"(metadata !"_ZTSFvE.generalized"), "callee_type"(metadata !"_ZTSFvE.generalized") ]
- %x = add i32 42, 1
- ret void
-}
-
attributes #0 = { noreturn }
-
-; CHECK-NEXT: error: input module is broken!
>From 2cac836f3f41fade1bcde3a9f2bed2f3fbf8243f Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Sat, 19 Apr 2025 03:07:25 +0000
Subject: [PATCH 15/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 4 +---
.../CodeGen/AArch64/call-site-info-typeid.ll | 2 +-
llvm/test/CodeGen/ARM/call-site-info-typeid.ll | 2 +-
.../CodeGen/MIR/X86/call-site-info-typeid.ll | 16 ++++++++--------
llvm/test/CodeGen/Mips/call-site-info-typeid.ll | 2 +-
llvm/test/CodeGen/RISCV/call-site-info-typeid.ll | 6 +++---
llvm/test/CodeGen/X86/call-site-info-typeid.ll | 4 ++--
7 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 77e8c45faecd5..f81c443faf719 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1728,9 +1728,7 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
OutStreamer->emitInt64(CallSiteLabels.size());
// Emit the type id and call site label pairs.
- for (const std::pair<uint64_t, MCSymbol *> &El : CallSiteLabels) {
- auto TypeId = El.first;
- const auto &Label = El.second;
+ for (const auto& [TypeId, Label] : CallSiteLabels) {
OutStreamer->emitInt64(TypeId);
OutStreamer->emitSymbolValue(Label, TM.getProgramPointerSize());
}
diff --git a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
index e72ba58328f51..48cf7268d5215 100644
--- a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
@@ -3,7 +3,7 @@
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
;; computed as the type id from the callee_type metadata.
-; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
diff --git a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
index aebcf918eb1bc..0aadcdb46a4a4 100644
--- a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/ARM/call-site-info-typeid.ll
@@ -3,7 +3,7 @@
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
;; computed as the type id from the callee_type metadata.
-; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
index fed4fc81c88b0..4823d2212df1a 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
@@ -11,7 +11,7 @@
;; Verify that fwdArgRegs is not set, calleeTypeIds is set.
;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; computed as the type id from the callee_type metadata.
-; RUN: llc --call-graph-section %s -stop-before=finalize-isel -o %t1.mir
+; RUN: llc --call-graph-section %s -stop-after=finalize-isel -o %t1.mir
; RUN: cat %t1.mir | FileCheck %s --check-prefix=PRINTER_CGS
; PRINTER_CGS: name: main
; PRINTER_CGS: callSites:
@@ -32,8 +32,8 @@
;; Test printer and parser with -emit-call-site-info only.
;; Test printer.
-;; Verify that fwdArgRegs is set, calleeTypeId is not set.
-; RUN: llc -emit-call-site-info %s -stop-before=finalize-isel -o %t2.mir
+;; Verify that fwdArgRegs is set, calleeTypeIds is not set.
+; RUN: llc -emit-call-site-info %s -stop-after=finalize-isel -o %t2.mir
; RUN: cat %t2.mir | FileCheck %s --check-prefix=PRINTER_CSI
; PRINTER_CSI: name: main
; PRINTER_CSI: callSites:
@@ -56,10 +56,10 @@
;; Test printer and parser with both -emit-call-site-info and --call-graph-section.
;; Test printer.
-;; Verify both fwdArgRegs and calleeTypeId are set.
-;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; Verify both fwdArgRegs and calleeTypeIds are set.
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; computed as the type id from the callee_type metadata.
-; RUN: llc --call-graph-section -emit-call-site-info %s -stop-before=finalize-isel -o %t2.mir
+; RUN: llc --call-graph-section -emit-call-site-info %s -stop-after=finalize-isel -o %t2.mir
; RUN: cat %t2.mir | FileCheck %s --check-prefix=PRINTER_CGS_CSI
; PRINTER_CGS_CSI: name: main
; PRINTER_CGS_CSI: callSites:
@@ -93,8 +93,8 @@ entry:
%fp = alloca ptr, align 8
store i32 0, ptr %retval, align 4
store ptr @foo, ptr %fp, align 8
- %0 = load ptr, ptr %fp, align 8
- call void %0(i8 signext 97), !callee_type !5
+ %fp_val = load ptr, ptr %fp, align 8
+ call void %fp_val(i8 signext 97), !callee_type !5
ret i32 0
}
diff --git a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
index 826be8121d183..a6d1969136a85 100644
--- a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/Mips/call-site-info-typeid.ll
@@ -3,7 +3,7 @@
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
;; computed as the type id from the callee_type metadata.
-; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-before=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
diff --git a/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll b/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
index 10fdd15547ec0..46cc0eaebbcee 100644
--- a/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
@@ -1,10 +1,10 @@
;; Tests that call site callee type ids can be extracted and set from
;; callee_type metadata.
-;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; computed as the type id from the callee_type operand bundle.
-; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-before=finalize-isel -o - | FileCheck %s
-; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-before=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-after=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
diff --git a/llvm/test/CodeGen/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
index c785cd636732a..6f0890de3ed37 100644
--- a/llvm/test/CodeGen/X86/call-site-info-typeid.ll
+++ b/llvm/test/CodeGen/X86/call-site-info-typeid.ll
@@ -1,9 +1,9 @@
;; Tests that call site callee type ids can be extracted and set from
;; callee_type metadata.
-;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; computed as the type id from the callee_type metadata.
-; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-before=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-after=finalize-isel -o - | FileCheck %s
declare !type !0 void @foo(i8 signext %a)
>From 0c78d0abc96a765f8c7760957de8ee40b06ef598 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Wed, 23 Apr 2025 01:03:07 +0000
Subject: [PATCH 16/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/CodeGen/AsmPrinter.h | 7 +++
llvm/include/llvm/CodeGen/MachineFunction.h | 3 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 55 ++++++++++---------
.../InstCombine/InstCombineCalls.cpp | 5 ++
.../callsite-emit-calleetypeid-tailcall.ll | 19 +++++++
...ypeid.ll => callsite-emit-calleetypeid.ll} | 0
.../callsite-emit-calleetypeid-tailcall.ll | 19 +++++++
...ypeid.ll => callsite-emit-calleetypeid.ll} | 0
.../call-site-info-direct-calls-typeid.mir | 12 ++--
...ypeid.ll => callsite-emit-calleetypeid.ll} | 0
.../callsite-emit-calleetypeid-tailcall.ll | 19 +++++++
...ypeid.ll => callsite-emit-calleetypeid.ll} | 0
.../callsite-emit-calleetypeid-tailcall.ll | 20 +++++++
...ypeid.ll => callsite-emit-calleetypeid.ll} | 0
llvm/test/CodeGen/X86/call-graph-section.ll | 6 +-
.../callsite-emit-calleetypeid-tailcall.ll | 19 +++++++
...ypeid.ll => callsite-emit-calleetypeid.ll} | 0
.../InstCombine/callee-type-metadata.ll | 25 +++++++++
18 files changed, 174 insertions(+), 35 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
rename llvm/test/CodeGen/AArch64/{call-site-info-typeid.ll => callsite-emit-calleetypeid.ll} (100%)
create mode 100644 llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
rename llvm/test/CodeGen/ARM/{call-site-info-typeid.ll => callsite-emit-calleetypeid.ll} (100%)
rename llvm/test/CodeGen/MIR/X86/{call-site-info-typeid.ll => callsite-emit-calleetypeid.ll} (100%)
create mode 100644 llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
rename llvm/test/CodeGen/Mips/{call-site-info-typeid.ll => callsite-emit-calleetypeid.ll} (100%)
create mode 100644 llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
rename llvm/test/CodeGen/RISCV/{call-site-info-typeid.ll => callsite-emit-calleetypeid.ll} (100%)
create mode 100644 llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
rename llvm/test/CodeGen/X86/{call-site-info-typeid.ll => callsite-emit-calleetypeid.ll} (100%)
create mode 100644 llvm/test/Transforms/InstCombine/callee-type-metadata.ll
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index f9bf50adef5a7..d2c52650b6ce1 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -356,6 +356,13 @@ class AsmPrinter : public MachineFunctionPass {
DwarfUsesRelocationsAcrossSections = Enable;
}
+ /// Generate and emit labels for callees of the indirect callsites which will
+ /// be used to populate the .callgraph section.
+ void emitIndirectCalleeLabels(
+ FunctionInfo &FuncInfo,
+ const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,
+ MachineInstr &MI);
+
//===------------------------------------------------------------------===//
// XRay instrumentation implementation.
//===------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index 8d4de273f8a84..b9013eb611139 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -534,11 +534,12 @@ class LLVM_ABI MachineFunction {
unsigned TargetFlags;
};
+ using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>;
+
private:
Delegate *TheDelegate = nullptr;
GISelChangeObserver *Observer = nullptr;
- using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>;
/// Map a call instruction to call site arguments forwarding info.
CallSiteInfoMap CallSitesInfo;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index f81c443faf719..49c4b29c53dd6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1666,7 +1666,7 @@ static ConstantInt *extractNumericCGTypeId(const Function &F) {
return ConstantInt::get(Int64Ty, TypeIdVal);
}
-/// Emits call graph section.
+/// Emits .callgraph section.
void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
FunctionInfo &FuncInfo) {
if (!MF.getTarget().Options.EmitCallGraphSection)
@@ -1675,7 +1675,7 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
// Switch to the call graph section for the function
MCSection *FuncCGSection =
getObjFileLowering().getCallGraphSection(*getCurrentSection());
- assert(FuncCGSection && "null call graph section");
+ assert(FuncCGSection && "null callgraph section");
OutStreamer->pushSection();
OutStreamer->switchSection(FuncCGSection);
@@ -1728,7 +1728,7 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
OutStreamer->emitInt64(CallSiteLabels.size());
// Emit the type id and call site label pairs.
- for (const auto& [TypeId, Label] : CallSiteLabels) {
+ for (const auto &[TypeId, Label] : CallSiteLabels) {
OutStreamer->emitInt64(TypeId);
OutStreamer->emitSymbolValue(Label, TM.getProgramPointerSize());
}
@@ -1867,6 +1867,30 @@ static StringRef getMIMnemonic(const MachineInstr &MI, MCStreamer &Streamer) {
return Name;
}
+void AsmPrinter::emitIndirectCalleeLabels(
+ FunctionInfo &FuncInfo,
+ const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,
+ MachineInstr &MI) {
+ // Only indirect calls have type identifiers set.
+ const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
+ if (CallSiteInfo == CallSitesInfoMap.end())
+ return;
+ if (CallSiteInfo->second.CalleeTypeIds.empty())
+ return;
+
+ for (auto *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
+ // Emit label.
+ MCSymbol *S = MF->getContext().createTempSymbol();
+ OutStreamer->emitLabel(S);
+
+ // Get numeric callee_type id value.
+ uint64_t CalleeTypeIdVal = CalleeTypeId->getZExtValue();
+
+ // Add to function's callsite labels.
+ FuncInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S);
+ }
+}
+
/// EmitFunctionBody - This method emits the body and trailer for a
/// function.
void AsmPrinter::emitFunctionBody() {
@@ -2045,28 +2069,9 @@ void AsmPrinter::emitFunctionBody() {
break;
}
- // FIXME: Some indirect calls can get lowered to jump instructions,
- // resulting in emitting labels for them. The extra information can
- // be neglected while disassembling but still takes space in the binary.
- if (TM.Options.EmitCallGraphSection && MI.isCall()) {
- // Only indirect calls have type identifiers set.
- const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
- if (CallSiteInfo != CallSitesInfoMap.end()) {
- if (!CallSiteInfo->second.CalleeTypeIds.empty()) {
- for (auto *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
- // Emit label.
- MCSymbol *S = MF->getContext().createTempSymbol();
- OutStreamer->emitLabel(S);
-
- // Get numeric callee_type id value.
- uint64_t CalleeTypeIdVal = CalleeTypeId->getZExtValue();
-
- // Add to function's callsite labels.
- FuncInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S);
- }
- }
- }
- }
+ if (TM.Options.EmitCallGraphSection && MI.isCall())
+ emitIndirectCalleeLabels(FuncInfo, CallSitesInfoMap, MI);
+
// If there is a post-instruction symbol, emit a label for it here.
if (MCSymbol *S = MI.getPostInstrSymbol())
OutStreamer->emitLabel(S);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 400ebcf493713..66e9dc1684969 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -4111,6 +4111,11 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
Call, Builder.CreateBitOrPointerCast(ReturnedArg, CallTy));
}
+ // Drop unnecessary callee_type metadata from calls that were converted
+ // into direct calls.
+ if (Call.getMetadata(LLVMContext::MD_callee_type) && !Call.isIndirectCall())
+ Call.setMetadata(LLVMContext::MD_callee_type, nullptr);
+
// Drop unnecessary kcfi operand bundles from calls that were converted
// into direct calls.
auto Bundle = Call.getOperandBundle(LLVMContext::OB_kcfi);
diff --git a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
new file mode 100644
index 0000000000000..2dbea750c5587
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
@@ -0,0 +1,19 @@
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata for indirect tail calls.
+
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; 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 %s
+
+define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 3498816979441845844 ] }
+ %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ ret i32 %call
+}
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
diff --git a/llvm/test/CodeGen/AArch64/call-site-info-typeid.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
similarity index 100%
rename from llvm/test/CodeGen/AArch64/call-site-info-typeid.ll
rename to llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
new file mode 100644
index 0000000000000..68ea6030e2323
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
@@ -0,0 +1,19 @@
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata for indirect tail calls.
+
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; 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 %s
+
+define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 3498816979441845844 ] }
+ %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ ret i32 %call
+}
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
diff --git a/llvm/test/CodeGen/ARM/call-site-info-typeid.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
similarity index 100%
rename from llvm/test/CodeGen/ARM/call-site-info-typeid.ll
rename to llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
index 147d265eaac52..4c1007da3095d 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
@@ -13,11 +13,11 @@
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
--- |
- declare noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y)
-
- declare noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y)
-
- define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) {
+ declare !type !0 noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y)
+
+ declare !type !0 noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y)
+
+ define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) !type !0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
@@ -33,7 +33,7 @@
ret i32 %sub
}
- define dso_local noundef i32 @_Z3fooii(i32 noundef %x, i32 noundef %y) {
+ define dso_local noundef i32 @_Z3fooii(i32 noundef %x, i32 noundef %y) !type !0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
similarity index 100%
rename from llvm/test/CodeGen/MIR/X86/call-site-info-typeid.ll
rename to llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
new file mode 100644
index 0000000000000..0db930fbaf191
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
@@ -0,0 +1,19 @@
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata for indirect tail calls.
+
+;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; 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 %s
+
+define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 3498816979441845844 ] }
+ %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ ret i32 %call
+}
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
diff --git a/llvm/test/CodeGen/Mips/call-site-info-typeid.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
similarity index 100%
rename from llvm/test/CodeGen/Mips/call-site-info-typeid.ll
rename to llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
new file mode 100644
index 0000000000000..42b9b83c5454b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
@@ -0,0 +1,20 @@
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata for indirect tail calls.
+
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
+;; computed as the type id from the callee_type operand bundle.
+; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-after=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck %s
+
+define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 3498816979441845844 ] }
+ %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ ret i32 %call
+}
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
diff --git a/llvm/test/CodeGen/RISCV/call-site-info-typeid.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
similarity index 100%
rename from llvm/test/CodeGen/RISCV/call-site-info-typeid.ll
rename to llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index db44b5e5ca3a6..0407a00a6906c 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -3,11 +3,11 @@
; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
-declare void @foo()
+declare !type !0 void @foo()
-declare noundef i32 @bar(i8 signext)
+declare !type !1 noundef i32 @bar(i8 signext)
-declare noundef ptr @baz(ptr)
+declare !type !2 noundef ptr @baz(ptr)
define dso_local void @main() {
entry:
diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
new file mode 100644
index 0000000000000..303d6cb1336af
--- /dev/null
+++ b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
@@ -0,0 +1,19 @@
+;; Tests that call site callee type ids can be extracted and set from
+;; callee_type metadata for indirect tail calls.
+
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
+;; 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 %s
+
+define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+ ; CHECK-NEXT: [ 3498816979441845844 ] }
+ %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ ret i32 %call
+}
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
diff --git a/llvm/test/CodeGen/X86/call-site-info-typeid.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
similarity index 100%
rename from llvm/test/CodeGen/X86/call-site-info-typeid.ll
rename to llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
diff --git a/llvm/test/Transforms/InstCombine/callee-type-metadata.ll b/llvm/test/Transforms/InstCombine/callee-type-metadata.ll
new file mode 100644
index 0000000000000..5c86e95ae3f4c
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/callee-type-metadata.ll
@@ -0,0 +1,25 @@
+;; Test if the callee_type metadata is dropped when an indirect function call through a function ptr is promoted
+;; to a direct function call during instcombine.
+
+; RUN: opt < %s -O2 | llvm-dis | FileCheck %s
+
+define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+entry:
+ %call = call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ ret i32 %call
+}
+
+define dso_local noundef i32 @_Z3barv() local_unnamed_addr !type !3 {
+entry:
+ ; CHECK: %call.i = tail call noundef i32 @_Z3fooc(i8 noundef signext 97)
+ ; CHECK-NOT: %call.i = tail call noundef i32 @_Z3fooc(i8 noundef signext 97), !callee_type !1
+ %call = call noundef i32 @_Z13call_indirectPFicEc(ptr noundef nonnull @_Z3fooc, i8 noundef signext 97)
+ ret i32 %call
+}
+
+declare !type !2 noundef i32 @_Z3fooc(i8 noundef signext)
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFivE.generalized"}
>From 7a1c8fbba2b12eef00f859de534131dd26ea4488 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Wed, 23 Apr 2025 03:53:06 +0000
Subject: [PATCH 17/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/IR/Metadata.h | 6 ++++
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 19 ++++-------
llvm/lib/IR/Verifier.cpp | 3 +-
.../X86/call-graph-section-tailcall.ll | 34 +++++++++++++++++++
llvm/test/CodeGen/X86/call-graph-section.ll | 2 +-
5 files changed, 48 insertions(+), 16 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 43a3ba20589dd..02403dd5c752b 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1259,6 +1259,12 @@ class MDNode : public Metadata {
bool isReplaceable() const { return isTemporary() || isAlwaysReplaceable(); }
bool isAlwaysReplaceable() const { return getMetadataID() == DIAssignIDKind; }
+ bool hasGeneralizedMDString() const {
+ 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 49c4b29c53dd6..c427af8508c91 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1647,23 +1647,16 @@ void AsmPrinter::emitStackUsage(const MachineFunction &MF) {
static ConstantInt *extractNumericCGTypeId(const Function &F) {
SmallVector<MDNode *, 2> Types;
F.getMetadata(LLVMContext::MD_type, Types);
- MDString *MDGeneralizedTypeId = nullptr;
for (const auto &Type : Types) {
- if (Type->getNumOperands() == 2 && isa<MDString>(Type->getOperand(1))) {
- auto *TMDS = cast<MDString>(Type->getOperand(1));
- if (TMDS->getString().ends_with(".generalized")) {
- MDGeneralizedTypeId = TMDS;
- break;
- }
+ 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 (!MDGeneralizedTypeId)
- return nullptr;
-
- uint64_t TypeIdVal = llvm::MD5Hash(MDGeneralizedTypeId->getString());
- IntegerType *Int64Ty = Type::getInt64Ty(F.getContext());
- return ConstantInt::get(Int64Ty, TypeIdVal);
+ return nullptr;
}
/// Emits .callgraph section.
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index a3be4f32efadb..07de968b5dbfe 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -5060,8 +5060,7 @@ void Verifier::visitCalleeTypeMetadata(Instruction &I, MDNode *MD) {
&I);
for (const auto &Op : MD->operands()) {
auto *TypeMD = cast<MDNode>(Op.get());
- MDString *TypeIdStr = cast<MDString>(TypeMD->getOperand(1));
- Check(TypeIdStr->getString().ends_with(".generalized"),
+ Check(TypeMD->hasGeneralizedMDString(),
"Invalid \"callee_type\" type identifier", &I);
}
}
diff --git a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
new file mode 100644
index 0000000000000..8cfd6c6fba7a5
--- /dev/null
+++ b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
@@ -0,0 +1,34 @@
+;; Tests that we store the type identifiers in .callgraph section of the object file for tailcalls.
+
+; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
+; RUN: llvm-readelf -x .callgraph - | FileCheck %s
+
+define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+entry:
+ %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ ret i32 %call
+}
+
+define dso_local noundef i32 @main(i32 noundef %argc) local_unnamed_addr !type !3 {
+entry:
+ %0 = and i32 %argc, 1
+ %cmp = icmp eq i32 %0, 0
+ %_Z3fooc._Z3barc = select i1 %cmp, ptr @_Z3fooc, ptr @_Z3barc
+ %call.i = tail call noundef i32 %_Z3fooc._Z3barc(i8 noundef signext 97), !callee_type !1
+ ret i32 %call.i
+}
+
+declare !type !2 noundef i32 @_Z3fooc(i8 noundef signext) local_unnamed_addr
+
+declare !type !2 noundef i32 @_Z3barc(i8 noundef signext) local_unnamed_addr
+
+;; Check that the numeric type id (md5 hash) for the below type ids are emitted
+;; to the callgraph section.
+
+; CHECK: Hex dump of section '.callgraph':
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+; CHECK-DAG: 5486bc59 814b8e30
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFiiE.generalized"}
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index 0407a00a6906c..357f16da6bcb8 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -1,4 +1,4 @@
-;; Tests that we store the type identifiers in .callgraph section of the binary.
+;; Tests that we store the type identifiers in .callgraph section of the object file.
; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
>From a56ccb8ab4f3e8c0ae29702774717509d2273297 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Wed, 23 Apr 2025 23:39:35 +0000
Subject: [PATCH 18/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/CodeGen/AsmPrinter.h | 2 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 4 +---
.../callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../ARM/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../MIR/X86/callsite-emit-calleetypeid.ll | 8 ++++----
.../Mips/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../RISCV/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../CodeGen/X86/call-graph-section-tailcall.ll | 4 ++--
llvm/test/CodeGen/X86/call-graph-section.ll | 2 +-
.../X86/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../InstCombine/callee-type-metadata.ll | 16 ++++++++--------
11 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index d2c52650b6ce1..ae3c726f3eca1 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -361,7 +361,7 @@ class AsmPrinter : public MachineFunctionPass {
void emitIndirectCalleeLabels(
FunctionInfo &FuncInfo,
const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,
- MachineInstr &MI);
+ const MachineInstr &MI);
//===------------------------------------------------------------------===//
// XRay instrumentation implementation.
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index c427af8508c91..de219356266bf 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1863,13 +1863,11 @@ static StringRef getMIMnemonic(const MachineInstr &MI, MCStreamer &Streamer) {
void AsmPrinter::emitIndirectCalleeLabels(
FunctionInfo &FuncInfo,
const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,
- MachineInstr &MI) {
+ const MachineInstr &MI) {
// Only indirect calls have type identifiers set.
const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
if (CallSiteInfo == CallSitesInfoMap.end())
return;
- if (CallSiteInfo->second.CalleeTypeIds.empty())
- return;
for (auto *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
// Emit label.
diff --git a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
index 2dbea750c5587..4c6fcb3223aa2 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 %s
-define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
index 68ea6030e2323..ed0b346a6e171 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 %s
-define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
index 4823d2212df1a..6d6f506540bbc 100644
--- a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
@@ -38,7 +38,7 @@
; PRINTER_CSI: name: main
; PRINTER_CSI: callSites:
; PRINTER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PRINTER_CSI-NEXT: { arg: 0, reg: '$edi' }
+; PRINTER_CSI-NEXT: { arg: 0, reg: {{.*}} }
; PRINTER_CSI-NOT: calleeTypeIds:
@@ -49,7 +49,7 @@
; PARSER_CSI: name: main
; PARSER_CSI: callSites:
; PARSER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PARSER_CSI-NEXT: { arg: 0, reg: '$edi' }
+; PARSER_CSI-NEXT: { arg: 0, reg: {{.*}} }
; PARSER_CSI-NOT: calleeTypeIds:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -64,7 +64,7 @@
; PRINTER_CGS_CSI: name: main
; PRINTER_CGS_CSI: callSites:
; PRINTER_CGS_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PRINTER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, calleeTypeIds:
+; PRINTER_CGS_CSI-NEXT: { arg: 0, reg: {{.*}} }, calleeTypeIds:
; PRINTER_CGS_CSI-NEXT: [ 7854600665770582568 ] }
@@ -75,7 +75,7 @@
; PARSER_CGS_CSI: name: main
; PARSER_CGS_CSI: callSites:
; PARSER_CGS_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PARSER_CGS_CSI-NEXT: { arg: 0, reg: '$edi' }, calleeTypeIds:
+; PARSER_CGS_CSI-NEXT: { arg: 0, reg: {{.*}} }, calleeTypeIds:
; PARSER_CGS_CSI-NEXT: [ 7854600665770582568 ] }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
index 0db930fbaf191..27cb02d8bcf1a 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 %s
-define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
index 42b9b83c5454b..264eb041d136c 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 %s
; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck %s
-define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
index 8cfd6c6fba7a5..0888bc73c9c11 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
@@ -1,9 +1,9 @@
;; Tests that we store the type identifiers in .callgraph section of the object file for tailcalls.
-; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
+; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
-define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
%call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
ret i32 %call
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index 357f16da6bcb8..8fcd177444b03 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -1,6 +1,6 @@
;; Tests that we store the type identifiers in .callgraph section of the object file.
-; RUN: llc --call-graph-section -filetype=obj -o - < %s | \
+; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
declare !type !0 void @foo()
diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
index 303d6cb1336af..31cdc137c52ad 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 %s
-define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef readonly captures(none) %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/Transforms/InstCombine/callee-type-metadata.ll b/llvm/test/Transforms/InstCombine/callee-type-metadata.ll
index 5c86e95ae3f4c..8cf99432c00b7 100644
--- a/llvm/test/Transforms/InstCombine/callee-type-metadata.ll
+++ b/llvm/test/Transforms/InstCombine/callee-type-metadata.ll
@@ -1,23 +1,23 @@
;; Test if the callee_type metadata is dropped when an indirect function call through a function ptr is promoted
;; to a direct function call during instcombine.
-; RUN: opt < %s -O2 | llvm-dis | FileCheck %s
+; RUN: opt < %s -passes="cgscc(inline),instcombine" -S | FileCheck %s
-define dso_local noundef i32 @_Z13call_indirectPFicEc(ptr noundef %func, i8 noundef signext %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
- %call = call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ %call = call i32 %func(i8 %x), !callee_type !1
ret i32 %call
}
-define dso_local noundef i32 @_Z3barv() local_unnamed_addr !type !3 {
+define i32 @_Z3barv() local_unnamed_addr !type !3 {
entry:
- ; CHECK: %call.i = tail call noundef i32 @_Z3fooc(i8 noundef signext 97)
- ; CHECK-NOT: %call.i = tail call noundef i32 @_Z3fooc(i8 noundef signext 97), !callee_type !1
- %call = call noundef i32 @_Z13call_indirectPFicEc(ptr noundef nonnull @_Z3fooc, i8 noundef signext 97)
+ ; CHECK: %call.i = call i32 @_Z3fooc(i8 97)
+ ; CHECK-NOT: %call.i = call i32 @_Z3fooc(i8 97), !callee_type !1
+ %call = call i32 @_Z13call_indirectPFicEc(ptr nonnull @_Z3fooc, i8 97)
ret i32 %call
}
-declare !type !2 noundef i32 @_Z3fooc(i8 noundef signext)
+declare !type !2 i32 @_Z3fooc(i8 signext)
!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
!1 = !{!2}
>From ab461916194b942c0f1a55401ab54ae4d027657d Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 24 Apr 2025 02:28:02 +0000
Subject: [PATCH 19/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +-
llvm/lib/CodeGen/MIRPrinter.cpp | 11 +++++++----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index de219356266bf..86fc8a40262a7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1869,7 +1869,7 @@ void AsmPrinter::emitIndirectCalleeLabels(
if (CallSiteInfo == CallSitesInfoMap.end())
return;
- for (auto *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
+ for (ConstantInt *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
// Emit label.
MCSymbol *S = MF->getContext().createTempSymbol();
OutStreamer->emitLabel(S);
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index ef0a4ccccd4cd..e9fe4ab09c9bd 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -558,26 +558,29 @@ void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
const MachineFunction &MF,
ModuleSlotTracker &MST) {
const auto *TRI = MF.getSubtarget().getRegisterInfo();
- for (auto CSInfo : MF.getCallSitesInfo()) {
+ for (auto CSInfoMap : MF.getCallSitesInfo()) {
yaml::CallSiteInfo YmlCS;
yaml::MachineInstrLoc CallLocation;
// Prepare instruction position.
- MachineBasicBlock::const_instr_iterator CallI = CSInfo.first->getIterator();
+ MachineBasicBlock::const_instr_iterator CallI =
+ CSInfoMap.first->getIterator();
CallLocation.BlockNum = CallI->getParent()->getNumber();
// Get call instruction offset from the beginning of block.
CallLocation.Offset =
std::distance(CallI->getParent()->instr_begin(), CallI);
YmlCS.CallLocation = CallLocation;
+
+ auto [ArgRegPairs, CalleeTypeIds] = CSInfoMap.second;
// Construct call arguments and theirs forwarding register info.
- for (auto ArgReg : CSInfo.second.ArgRegPairs) {
+ for (auto ArgReg : ArgRegPairs) {
yaml::CallSiteInfo::ArgRegPair YmlArgReg;
YmlArgReg.ArgNo = ArgReg.ArgNo;
printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
}
// Get type ids.
- for (auto *CalleeTypeId : CSInfo.second.CalleeTypeIds) {
+ for (auto *CalleeTypeId : CalleeTypeIds) {
YmlCS.CalleeTypeIds.push_back(CalleeTypeId->getZExtValue());
}
YMF.CallSitesInfo.push_back(std::move(YmlCS));
>From 5b3679675c3994763e65187595c4490de9ae8fe1 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 24 Apr 2025 20:40:18 +0000
Subject: [PATCH 20/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
...te-info-ambiguous-indirect-call-typeid.mir | 3 +-
.../CodeGen/MIR/X86/call-site-info-typeid.mir | 3 +-
.../X86/call-graph-section-assembly.ll | 61 +++++++++++++++++++
.../X86/call-graph-section-tailcall.ll | 10 +--
llvm/test/CodeGen/X86/call-graph-section.ll | 4 +-
5 files changed, 70 insertions(+), 11 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/call-graph-section-assembly.ll
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 a7073cb1ca5f0..1a9477640f8f3 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
@@ -49,8 +49,7 @@
name: main
callSites:
- { bb: 0, offset: 0, fwdArgRegs: [] }
- - { bb: 0, offset: 2, fwdArgRegs: [], calleeTypeIds:
- [ 1234567890 ] }
+ - { bb: 0, offset: 2, fwdArgRegs: [], calleeTypeIds: [ 1234567890 ] }
body: |
bb.0.entry:
CALL64pcrel32 @_Z13get_operationb, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
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 e2f212e52d176..c44a4df439609 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
@@ -25,8 +25,7 @@
---
name: main
callSites:
- - { bb: 0, offset: 1, fwdArgRegs: [], calleeTypeIds:
- [ 123456789 ] }
+ - { bb: 0, offset: 1, fwdArgRegs: [], calleeTypeIds: [ 123456789 ] }
body: |
bb.0.entry:
%0:gr64 = MOV32ri64 @foo
diff --git a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
new file mode 100644
index 0000000000000..31c983d8ee852
--- /dev/null
+++ b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
@@ -0,0 +1,61 @@
+;; Test .callgraph section in assembly.
+;; Test if temporary labels are generated for each indirect callsite with a callee_type metadata.
+;; Test if the .callgraph section contains the numerical callee type id for each of the temporary
+;; labels generated.
+
+; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -o - < %s | FileCheck %s
+
+declare !type !0 void @foo()
+
+declare !type !1 i32 @bar(i8 signext)
+
+declare !type !2 ptr @baz(ptr)
+
+; CHECK: ball:
+; CHECK-NEXT: .Lfunc_begin0:
+define void @ball() {
+entry:
+ %retval = alloca i32, align 4
+ %fp_foo = alloca ptr, align 8
+ %a = alloca i8, align 1
+ %fp_bar = alloca ptr, align 8
+ %fp_baz = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ store ptr @foo, ptr %fp_foo, align 8
+ %fp_foo_val = load ptr, ptr %fp_foo, align 8
+ ; CHECK: .Ltmp0:
+ call void (...) %fp_foo_val(), !callee_type !1
+ store ptr @bar, ptr %fp_bar, align 8
+ %fp_bar_val = load ptr, ptr %fp_bar, align 8
+ %a_val = load i8, ptr %a, align 1
+ ; CHECK: .Ltmp1:
+ %call_fp_bar = call i32 %fp_bar_val(i8 signext %a_val), !callee_type !3
+ store ptr @baz, ptr %fp_baz, align 8
+ %fp_baz_val = load ptr, ptr %fp_baz, align 8
+ ; CHECK: .Ltmp2:
+ %call_fp_baz = call ptr %fp_baz_val(ptr %a), !callee_type !5
+ call void @foo()
+ %a_val_2 = load i8, ptr %a, align 1
+ %call_bar = call i32 @bar(i8 signext %a_val_2)
+ %call_baz = call ptr @baz(ptr %a)
+ ret void
+}
+
+; CHECK: .section .callgraph,"o", at progbits,.text
+
+; CHECK-NEXT: .quad 0
+; CHECK-NEXT: .quad .Lfunc_begin0
+; CHECK-NEXT: .quad 1
+; CHECK-NEXT: .quad 3
+; CHECK-NEXT: .quad 4524972987496481828
+; CHECK-NEXT: .quad .Ltmp0
+!0 = !{i64 0, !"_ZTSFvE.generalized"}
+!1 = !{!0}
+; CHECK-NEXT: .quad 3498816979441845844
+; CHECK-NEXT: .quad .Ltmp1
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{!2}
+; CHECK-NEXT: .quad 8646233951371320954
+; CHECK-NEXT: .quad .Ltmp2
+!4 = !{i64 0, !"_ZTSFPvS_E.generalized"}
+!5 = !{!4}
diff --git a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
index 0888bc73c9c11..5841037229e7b 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
@@ -5,22 +5,22 @@
define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
- %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ %call = tail call i32 %func(i8 signext %x), !callee_type !1
ret i32 %call
}
-define dso_local noundef i32 @main(i32 noundef %argc) local_unnamed_addr !type !3 {
+define dso_local i32 @main(i32 %argc) local_unnamed_addr !type !3 {
entry:
%0 = and i32 %argc, 1
%cmp = icmp eq i32 %0, 0
%_Z3fooc._Z3barc = select i1 %cmp, ptr @_Z3fooc, ptr @_Z3barc
- %call.i = tail call noundef i32 %_Z3fooc._Z3barc(i8 noundef signext 97), !callee_type !1
+ %call.i = tail call i32 %_Z3fooc._Z3barc(i8 signext 97), !callee_type !1
ret i32 %call.i
}
-declare !type !2 noundef i32 @_Z3fooc(i8 noundef signext) local_unnamed_addr
+declare !type !2 i32 @_Z3fooc(i8 signext) local_unnamed_addr
-declare !type !2 noundef i32 @_Z3barc(i8 noundef signext) local_unnamed_addr
+declare !type !2 i32 @_Z3barc(i8 signext) local_unnamed_addr
;; Check that the numeric type id (md5 hash) for the below type ids are emitted
;; to the callgraph section.
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index 8fcd177444b03..827d3d6386d04 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -5,9 +5,9 @@
declare !type !0 void @foo()
-declare !type !1 noundef i32 @bar(i8 signext)
+declare !type !1 i32 @bar(i8 signext)
-declare !type !2 noundef ptr @baz(ptr)
+declare !type !2 ptr @baz(ptr)
define dso_local void @main() {
entry:
>From 05057b8af910bf3363b6b7b6d0cecffeeafe74d7 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Thu, 24 Apr 2025 23:50:39 +0000
Subject: [PATCH 21/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/CodeGen/MIRPrinter.cpp | 7 +++---
llvm/lib/IR/Verifier.cpp | 5 +++-
llvm/test/Verifier/callee-type-metadata.ll | 28 ++++++++++++++++++++++
3 files changed, 35 insertions(+), 5 deletions(-)
create mode 100644 llvm/test/Verifier/callee-type-metadata.ll
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index e9fe4ab09c9bd..93c77cfefaec0 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -558,20 +558,19 @@ void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
const MachineFunction &MF,
ModuleSlotTracker &MST) {
const auto *TRI = MF.getSubtarget().getRegisterInfo();
- for (auto CSInfoMap : MF.getCallSitesInfo()) {
+ for (auto [MI, CallSiteInfo] : MF.getCallSitesInfo()) {
yaml::CallSiteInfo YmlCS;
yaml::MachineInstrLoc CallLocation;
// Prepare instruction position.
- MachineBasicBlock::const_instr_iterator CallI =
- CSInfoMap.first->getIterator();
+ MachineBasicBlock::const_instr_iterator CallI = MI->getIterator();
CallLocation.BlockNum = CallI->getParent()->getNumber();
// Get call instruction offset from the beginning of block.
CallLocation.Offset =
std::distance(CallI->getParent()->instr_begin(), CallI);
YmlCS.CallLocation = CallLocation;
- auto [ArgRegPairs, CalleeTypeIds] = CSInfoMap.second;
+ auto [ArgRegPairs, CalleeTypeIds] = CallSiteInfo;
// Construct call arguments and theirs forwarding register info.
for (auto ArgReg : ArgRegPairs) {
yaml::CallSiteInfo::ArgRegPair YmlArgReg;
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 07de968b5dbfe..51da2d62ba160 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -5059,9 +5059,12 @@ void Verifier::visitCalleeTypeMetadata(Instruction &I, MDNode *MD) {
"!callee_type metadata should only exist on indirect function calls",
&I);
for (const auto &Op : MD->operands()) {
+ Check(isa<MDNode>(Op.get()),
+ "The callee_type metadata must be a list of type metadata nodes");
auto *TypeMD = cast<MDNode>(Op.get());
Check(TypeMD->hasGeneralizedMDString(),
- "Invalid \"callee_type\" type identifier", &I);
+ "Only generalized type metadata can be part of the callee_type "
+ "metadata list");
}
}
diff --git a/llvm/test/Verifier/callee-type-metadata.ll b/llvm/test/Verifier/callee-type-metadata.ll
new file mode 100644
index 0000000000000..6382a87758fe1
--- /dev/null
+++ b/llvm/test/Verifier/callee-type-metadata.ll
@@ -0,0 +1,28 @@
+;; Test if the callee_type metadata attached to indirect call sites adhere to the expected format.
+
+; RUN: not opt -passes=verify < %s 2>&1 | FileCheck %s
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 signext %x) !type !0 {
+entry:
+ %func.addr = alloca ptr, align 8
+ %x.addr = alloca i8, align 1
+ store ptr %func, ptr %func.addr, align 8
+ store i8 %x, ptr %x.addr, align 1
+ %fptr = load ptr, ptr %func.addr, align 8
+ %fptr_val = load i8, ptr %x.addr, align 1
+ ;; No failures expected for this callee_type metdata.
+ %call = call i32 %fptr(i8 signext %fptr_val), !callee_type !1
+ ;; callee_type metdata is a type metadata instead of a list of type metadata nodes.
+ ; CHECK: The callee_type metadata must be a list of type metadata nodes
+ %call2 = call i32 %fptr(i8 signext %fptr_val), !callee_type !0
+ ;; callee_type metdata is a list of non "gneralized" type metadata.
+ ; CHECK: Only generalized type metadata can be part of the callee_type metadata list
+ %call3 = call i32 %fptr(i8 signext %fptr_val), !callee_type !4
+ ret i32 %call
+}
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFicE"}
+!4 = !{!3}
+; CHECK-NEXT: error: input module is broken!
>From 2131b83a84a6b717f39ed1521772a5c66df9b93d Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Mon, 28 Apr 2025 22:49:06 +0000
Subject: [PATCH 22/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/CodeGen/AsmPrinter.h | 4 ++
llvm/include/llvm/MC/MCObjectFileInfo.h | 2 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +-
llvm/lib/Transforms/Utils/ValueMapper.cpp | 7 +++
llvm/test/MC/X86/verify-callgraph-section.s | 53 +++++++++++++++++++
.../drop-callee-type-metadata.ll} | 7 ++-
.../InstCombine/drop-callee-type-metadata.ll | 19 +++++++
7 files changed, 88 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/MC/X86/verify-callgraph-section.s
rename llvm/test/Transforms/{InstCombine/callee-type-metadata.ll => Inline/drop-callee-type-metadata.ll} (71%)
create mode 100644 llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index ae3c726f3eca1..5093a2c826ea5 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -200,6 +200,10 @@ class AsmPrinter : public MachineFunctionPass {
SmallVector<std::pair<CGTypeId, MCSymbol *>> CallSiteLabels;
};
+ enum CallGraphSectionFormatVersion : uint64_t {
+ V_0 = 0,
+ };
+
/// Output stream for the stack usage file (i.e., .su file).
std::unique_ptr<raw_fd_ostream> StackUsageStream;
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index 80dc842f43db5..b2b5dfde92131 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -68,7 +68,7 @@ class MCObjectFileInfo {
/// Language Specific Data Area information is emitted to.
MCSection *LSDASection = nullptr;
- /// Section containing metadata on call graph.
+ /// Section containing call graph metadata.
MCSection *CallGraphSection = nullptr;
/// If exception handling is supported by the target and the target can
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 86fc8a40262a7..70f6a2c531333 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1673,7 +1673,7 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
OutStreamer->switchSection(FuncCGSection);
// Emit format version number.
- OutStreamer->emitInt64(0);
+ OutStreamer->emitInt64(CallGraphSectionFormatVersion::V_0);
// Emit function's self information, which is composed of:
// 1) FunctionEntryPc
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index b8569454379bf..7906e0d2ae3fc 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -985,6 +985,13 @@ void Mapper::remapInstruction(Instruction *I) {
"Referenced value not in value map!");
}
+ // Drop callee_type metadata from calls that were remapped
+ // into a direct call from an indirect one.
+ if (auto *CB = dyn_cast<CallBase>(I)) {
+ if (CB->getMetadata(LLVMContext::MD_callee_type) && !CB->isIndirectCall())
+ CB->setMetadata(LLVMContext::MD_callee_type, nullptr);
+ }
+
// Remap phi nodes' incoming blocks.
if (PHINode *PN = dyn_cast<PHINode>(I)) {
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
diff --git a/llvm/test/MC/X86/verify-callgraph-section.s b/llvm/test/MC/X86/verify-callgraph-section.s
new file mode 100644
index 0000000000000..6bc16f5001848
--- /dev/null
+++ b/llvm/test/MC/X86/verify-callgraph-section.s
@@ -0,0 +1,53 @@
+// Test that the assembler produced callgraph section is correct.
+
+// RUN: llvm-mc -triple=x86_64 -filetype=obj -o - < %s | llvm-readelf -x .callgraph - | FileCheck %s
+
+ .text
+ .globl ball # -- Begin function ball
+ .p2align 4
+ .type ball, at function
+ball: # @ball
+.Lfunc_begin0:
+# %bb.0: # %entry
+ pushq %rbx
+ subq $32, %rsp
+ movl $0, 4(%rsp)
+ movq foo at GOTPCREL(%rip), %rcx
+ movq %rcx, 24(%rsp)
+ xorl %eax, %eax
+ callq *%rcx
+.Ltmp0:
+ movq bar at GOTPCREL(%rip), %rax
+ movq %rax, 16(%rsp)
+ movsbl 3(%rsp), %edi
+ callq *%rax
+.Ltmp1:
+ movq baz at GOTPCREL(%rip), %rax
+ movq %rax, 8(%rsp)
+ leaq 3(%rsp), %rbx
+ movq %rbx, %rdi
+ callq *%rax
+.Ltmp2:
+ callq foo at PLT
+ movsbl 3(%rsp), %edi
+ callq bar at PLT
+ movq %rbx, %rdi
+ callq baz at PLT
+ addq $32, %rsp
+ popq %rbx
+ retq
+ .section .callgraph,"o", at progbits,.text
+ .quad 0
+ .quad .Lfunc_begin0
+ .quad 1
+ .quad 3
+ // CHECK: 2444f731 f5eecb3e
+ .quad 0x3ecbeef531f74424
+ .quad .Ltmp0
+ // CHECK: 5486bc59 814b8e30
+ .quad 0x308e4b8159bc8654
+ .quad .Ltmp1
+ // CHECK: 7ade6814 f897fd77
+ .quad 0x77fd97f81468de7a
+ .quad .Ltmp2
+ .text
diff --git a/llvm/test/Transforms/InstCombine/callee-type-metadata.ll b/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
similarity index 71%
rename from llvm/test/Transforms/InstCombine/callee-type-metadata.ll
rename to llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
index 8cf99432c00b7..84463bd3948b3 100644
--- a/llvm/test/Transforms/InstCombine/callee-type-metadata.ll
+++ b/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
@@ -1,7 +1,7 @@
-;; Test if the callee_type metadata is dropped when an indirect function call through a function ptr is promoted
-;; to a direct function call during instcombine.
+;; Test if the callee_type metadata is dropped when it is
+;; is mapped to a direct function call from an indirect call during inlining.
-; RUN: opt < %s -passes="cgscc(inline),instcombine" -S | FileCheck %s
+; RUN: opt < %s -passes="inline" -S | FileCheck %s
define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
@@ -16,7 +16,6 @@ entry:
%call = call i32 @_Z13call_indirectPFicEc(ptr nonnull @_Z3fooc, i8 97)
ret i32 %call
}
-
declare !type !2 i32 @_Z3fooc(i8 signext)
!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
diff --git a/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
new file mode 100644
index 0000000000000..0231343fb56b2
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
@@ -0,0 +1,19 @@
+;; Test if the callee_type metadata is dropped when it is attached
+;; to a direct function call during instcombine.
+
+; RUN: opt < %s -passes="instcombine" -disable-verify -S | FileCheck %s
+
+define i32 @_Z3barv() local_unnamed_addr !type !3 {
+entry:
+ ; CHECK: %call = call i32 @_Z3fooc(i8 97)
+ ; CHECK-NOT: %call = call i32 @_Z3fooc(i8 97), !callee_type !1
+ %call = call i32 @_Z3fooc(i8 97), !callee_type !1
+ ret i32 %call
+}
+
+declare !type !2 i32 @_Z3fooc(i8 signext)
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFivE.generalized"}
>From 759a709c646959357ada67af592b6212c591696f Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Tue, 29 Apr 2025 17:46:19 +0000
Subject: [PATCH 23/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/test/CodeGen/X86/call-graph-section-assembly.ll | 1 -
llvm/test/MC/X86/verify-callgraph-section.s | 7 ++++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
index 31c983d8ee852..b1aa2828581be 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
@@ -1,4 +1,3 @@
-;; Test .callgraph section in assembly.
;; Test if temporary labels are generated for each indirect callsite with a callee_type metadata.
;; Test if the .callgraph section contains the numerical callee type id for each of the temporary
;; labels generated.
diff --git a/llvm/test/MC/X86/verify-callgraph-section.s b/llvm/test/MC/X86/verify-callgraph-section.s
index 6bc16f5001848..fad351b9d52a3 100644
--- a/llvm/test/MC/X86/verify-callgraph-section.s
+++ b/llvm/test/MC/X86/verify-callgraph-section.s
@@ -1,4 +1,6 @@
-// Test that the assembler produced callgraph section is correct.
+/// Test the callgraph section to make sure the indirect callsites
+/// (annotated by generated temporary labels .Ltmp*) are associated
+/// with the corresponding callee type identifiers.
// RUN: llvm-mc -triple=x86_64 -filetype=obj -o - < %s | llvm-readelf -x .callgraph - | FileCheck %s
@@ -41,12 +43,15 @@ ball: # @ball
.quad .Lfunc_begin0
.quad 1
.quad 3
+ /// Numerical hash of the callee type ID for foo.
// CHECK: 2444f731 f5eecb3e
.quad 0x3ecbeef531f74424
.quad .Ltmp0
+ /// Numerical hash of the callee type ID for bar.
// CHECK: 5486bc59 814b8e30
.quad 0x308e4b8159bc8654
.quad .Ltmp1
+ /// Numerical hash of the callee type ID for baz.
// CHECK: 7ade6814 f897fd77
.quad 0x77fd97f81468de7a
.quad .Ltmp2
>From 8a289b123caed2919d656aaee4d97d2b51375abf Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Mon, 5 May 2025 23:13:13 +0000
Subject: [PATCH 24/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/IR/Metadata.cpp | 6 ++----
llvm/lib/IR/Verifier.cpp | 6 +-----
llvm/test/Transforms/Inline/drop-callee-type-metadata.ll | 2 +-
.../Transforms/InstCombine/drop-callee-type-metadata.ll | 2 +-
llvm/test/Verifier/callee-type-metadata.ll | 8 +-------
5 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 2ab6fcd2d0759..82c1b96f5fb7e 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1306,15 +1306,13 @@ MDNode *MDNode::getMergedCalleeTypeMetadata(LLVMContext &Ctx, MDNode *A,
MDNode *B) {
SmallVector<Metadata *, 8> AB;
SmallSet<Metadata *, 8> MergedCallees;
- auto AddUniqueCallees = [&](llvm::MDNode *N) {
+ auto AddUniqueCallees = [&AB, &MergedCallees](llvm::MDNode *N) {
if (!N)
return;
for (const MDOperand &Op : N->operands()) {
Metadata *MD = Op.get();
- if (!MergedCallees.contains(MD)) {
- MergedCallees.insert(MD);
+ if (MergedCallees.insert(MD).second)
AB.push_back(MD);
- }
}
};
AddUniqueCallees(A);
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 914ecc00aa862..9d8ab4742e1b6 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -5100,11 +5100,7 @@ void Verifier::visitCallsiteMetadata(Instruction &I, MDNode *MD) {
void Verifier::visitCalleeTypeMetadata(Instruction &I, MDNode *MD) {
Check(isa<CallBase>(I), "!callee_type metadata should only exist on calls",
&I);
- CallBase *CB = cast<CallBase>(&I);
- Check(CB->isIndirectCall(),
- "!callee_type metadata should only exist on indirect function calls",
- &I);
- for (const auto &Op : MD->operands()) {
+ for (const MDOperand &Op : MD->operands()) {
Check(isa<MDNode>(Op.get()),
"The callee_type metadata must be a list of type metadata nodes");
auto *TypeMD = cast<MDNode>(Op.get());
diff --git a/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll b/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
index c8457aa81970d..ce7830536c200 100644
--- a/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
+++ b/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
@@ -1,7 +1,7 @@
;; Test if the callee_type metadata is dropped when it is
;; is mapped to a direct function call from an indirect call during inlining.
-; RUN: opt < %s -passes="inline" -disable-verify -S | FileCheck %s
+; RUN: opt -passes="inline" -S < %s | FileCheck %s
define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
entry:
diff --git a/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
index b2bd9350d0749..13c60f675d66d 100644
--- a/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
+++ b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
@@ -1,7 +1,7 @@
;; Test if the callee_type metadata is dropped when it is attached
;; to a direct function call during instcombine.
-; RUN: opt < %s -passes="instcombine" -disable-verify -S | FileCheck %s
+; RUN: opt -passes="instcombine" -S < %s | FileCheck %s
define i32 @_Z3barv() local_unnamed_addr !type !3 {
entry:
diff --git a/llvm/test/Verifier/callee-type-metadata.ll b/llvm/test/Verifier/callee-type-metadata.ll
index 0345da9a64145..0107dec27de34 100644
--- a/llvm/test/Verifier/callee-type-metadata.ll
+++ b/llvm/test/Verifier/callee-type-metadata.ll
@@ -14,15 +14,9 @@ entry:
;; callee_type metdata is a type metadata instead of a list of type metadata nodes.
; CHECK: The callee_type metadata must be a list of type metadata nodes
%call2 = call i32 %fptr(i8 signext %x_val), !callee_type !0
- ;; callee_type metdata is a list of non "gneralized" type metadata.
+ ;; callee_type metdata must be a list of "generalized" type metadata.
; CHECK: Only generalized type metadata can be part of the callee_type metadata list
%call3 = call i32 %fptr(i8 signext %x_val), !callee_type !4
- ;; callee_type metadata should not be part of a direct call.
- ; CHECK: !callee_type metadata should only exist on indirect function calls
- %call_direct = call i32 @_Z3barc(i8 signext %x_val), !callee_type !1
- ;; callee_type metadata should not be part of a direct call.
- ; CHECK: !callee_type metadata should only exist on indirect function calls
- %call_direct_wrong_signature = call i32 @_Z3barc(i8 signext %x_val), !callee_type !4
ret i32 %call
}
>From 9c21da82b262b811322140af585d5d57cf3beaf5 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Sat, 10 May 2025 00:33:22 +0000
Subject: [PATCH 25/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/docs/CalleeTypeMetadata.rst | 32 ++++++++++++++++++++++++++++++++
llvm/docs/LangRef.rst | 5 +++++
llvm/docs/Reference.rst | 1 +
3 files changed, 38 insertions(+)
create mode 100644 llvm/docs/CalleeTypeMetadata.rst
diff --git a/llvm/docs/CalleeTypeMetadata.rst b/llvm/docs/CalleeTypeMetadata.rst
new file mode 100644
index 0000000000000..8c35dec125f0c
--- /dev/null
+++ b/llvm/docs/CalleeTypeMetadata.rst
@@ -0,0 +1,32 @@
+====================
+Callee Type Metadata
+====================
+
+Introduction
+============
+This ``!callee_type`` metadata is introduced as part of an ongoing effort to generate a call graph
+section in the object file. The broader design for the call graph section and the compiler flags which
+will enable the feature will be documented as those changes land. The ``!callee_type`` metadata is used
+to identify types of intended callees of indirect call instructions. The ``!callee_type`` metadata is a
+list of one or more ``!type`` metadata objects (See :doc:`TypeMetadata`) with each ``!type`` metadata
+pointing to a callee's :ref:`type identifier
+<calleetype-type-identifier>`.
+
+.. _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 c8cc38c23cff3..9feca0e84d671 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -8091,6 +8091,11 @@ change in the future.
See :doc:`TypeMetadata`.
+'``callee_type``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+See :doc:`CalleeTypeMetadata`.
+
'``associated``' Metadata
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/llvm/docs/Reference.rst b/llvm/docs/Reference.rst
index e1f46b00f2b30..b67ec2332edb0 100644
--- a/llvm/docs/Reference.rst
+++ b/llvm/docs/Reference.rst
@@ -14,6 +14,7 @@ LLVM and API reference documentation.
BlockFrequencyTerminology
BranchWeightMetadata
Bugpoint
+ CalleeTypeMetadata
CIBestPractices
CommandGuide/index
ConvergenceAndUniformity
>From f83a155ad349d5fd6ab7e7d1b98428f018d1a9cc Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Tue, 13 May 2025 17:25:03 +0000
Subject: [PATCH 26/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 2 +-
.../AArch64/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../CodeGen/AArch64/callsite-emit-calleetypeid.ll | 2 +-
.../ARM/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../test/CodeGen/ARM/callsite-emit-calleetypeid.ll | 2 +-
...ll-site-info-ambiguous-indirect-call-typeid.mir | 12 ++++++------
.../MIR/X86/call-site-info-direct-calls-typeid.mir | 14 +++++++-------
.../test/CodeGen/MIR/X86/call-site-info-typeid.mir | 2 +-
.../CodeGen/MIR/X86/callsite-emit-calleetypeid.ll | 4 ++--
.../Mips/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../CodeGen/Mips/callsite-emit-calleetypeid.ll | 2 +-
.../RISCV/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../CodeGen/RISCV/callsite-emit-calleetypeid.ll | 2 +-
.../CodeGen/X86/call-graph-section-tailcall.ll | 2 +-
llvm/test/CodeGen/X86/call-graph-section.ll | 2 +-
.../X86/callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../test/CodeGen/X86/callsite-emit-calleetypeid.ll | 2 +-
17 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index b3d298d9a2894..83be215b98dc2 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -518,7 +518,7 @@ bool MIRParserImpl::initializeCallSiteInfo(
if (!YamlMF.CallSitesInfo.empty() &&
!(TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection))
- return error(Twine("call site info provided but not used"));
+ return error("call site info provided but not used");
return false;
}
diff --git a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
index 4c6fcb3223aa2..d0458a6613479 100644
--- a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
@@ -10,7 +10,7 @@ entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
; CHECK-NEXT: [ 3498816979441845844 ] }
- %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ %call = tail call i32 %func(i8 signext %x), !callee_type !1
ret i32 %call
}
diff --git a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
index 48cf7268d5215..cbdb5f4bec35f 100644
--- a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
@@ -8,7 +8,7 @@
declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
-define dso_local i32 @main() !type !1 {
+define i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
index ed0b346a6e171..bf89e1b76cceb 100644
--- a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
@@ -10,7 +10,7 @@ entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
; CHECK-NEXT: [ 3498816979441845844 ] }
- %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ %call = tail call i32 %func(i8 signext %x), !callee_type !1
ret i32 %call
}
diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
index 0aadcdb46a4a4..87fdbb5635e85 100644
--- a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
@@ -8,7 +8,7 @@
declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
-define dso_local i32 @main() !type !1 {
+define i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
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 1a9477640f8f3..0ce3f27b2a4a8 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
@@ -10,13 +10,13 @@
--- |
- declare !type !0 noundef i32 @_Z3addii(i32 noundef, i32 noundef)
+ declare !type !0 i32 @_Z3addii(i32, i32)
- declare !type !0 noundef i32 @_Z8multiplyii(i32 noundef, i32 noundef)
+ declare !type !0 i32 @_Z8multiplyii(i32, i32)
- declare !type !1 noundef ptr @_Z13get_operationb(i1 noundef zeroext %is_addition)
+ declare !type !1 ptr @_Z13get_operationb(i1 zeroext %is_addition)
- define dso_local noundef i32 @main(i32 noundef %argc) !type !2 {
+ define i32 @main(i32 %argc) !type !2 {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
@@ -30,12 +30,12 @@
%argc_val = load i32, ptr %argc.addr, align 4
%rem = srem i32 %argc_val, 2
%cmp = icmp eq i32 %rem, 0
- %call = call noundef ptr @_Z13get_operationb(i1 noundef zeroext %cmp)
+ %call = call ptr @_Z13get_operationb(i1 zeroext %cmp)
store ptr %call, ptr %op, align 8
%op_val = load ptr, ptr %op, align 8
%x_val = load i32, ptr %x, align 4
%y_val = load i32, ptr %y, align 4
- %call1 = call noundef i32 %op_val(i32 noundef %x_val, i32 noundef %y_val), !callee_type !3
+ %call1 = call i32 %op_val(i32 %x_val, i32 %y_val), !callee_type !3
ret i32 %call1
}
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
index 4c1007da3095d..17c459d868a8f 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
@@ -13,11 +13,11 @@
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: []
--- |
- declare !type !0 noundef i32 @_Z4fizzii(i32 noundef %x, i32 noundef %y)
+ declare !type !0 i32 @_Z4fizzii(i32 %x, i32 %y)
- declare !type !0 noundef i32 @_Z4buzzii(i32 noundef %x, i32 noundef %y)
+ declare !type !0 i32 @_Z4buzzii(i32 %x, i32 %y)
- define dso_local noundef i32 @_Z3barii(i32 noundef %x, i32 noundef %y) !type !0 {
+ define i32 @_Z3barii(i32 %x, i32 %y) !type !0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
@@ -25,15 +25,15 @@
store i32 %y, ptr %y.addr, align 4
%x_val = load i32, ptr %x.addr, align 4
%y_val = load i32, ptr %y.addr, align 4
- %call = call noundef i32 @_Z4buzzii(i32 noundef %x_val, i32 noundef %y_val)
+ %call = call i32 @_Z4buzzii(i32 %x_val, i32 %y_val)
%x_val_2 = load i32, ptr %x.addr, align 4
%y_val_2 = load i32, ptr %y.addr, align 4
- %call1 = call noundef i32 @_Z4fizzii(i32 noundef %x_val_2, i32 noundef %y_val_2)
+ %call1 = call i32 @_Z4fizzii(i32 %x_val_2, i32 %y_val_2)
%sub = sub nsw i32 %call, %call1
ret i32 %sub
}
- define dso_local noundef i32 @_Z3fooii(i32 noundef %x, i32 noundef %y) !type !0 {
+ define i32 @_Z3fooii(i32 %x, i32 %y) !type !0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
@@ -41,7 +41,7 @@
store i32 %y, ptr %y.addr, align 4
%x_val = load i32, ptr %x.addr, align 4
%y_val = load i32, ptr %y.addr, align 4
- %call = call noundef i32 @_Z3barii(i32 noundef %x_val, i32 noundef %y_val)
+ %call = call i32 @_Z3barii(i32 %x_val, i32 %y_val)
ret i32 %call
}
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 c44a4df439609..d60484a75ac72 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
@@ -10,7 +10,7 @@
--- |
declare void @foo(i8 signext %a)
- define dso_local i32 @main() {
+ define i32 @main() {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
diff --git a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
index 6d6f506540bbc..0285ee6a6f9bd 100644
--- a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
@@ -81,13 +81,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function Attrs: noinline nounwind optnone uwtable
-define dso_local void @foo(i8 signext %a) !type !3 {
+define void @foo(i8 signext %a) !type !3 {
entry:
ret void
}
; Function Attrs: noinline nounwind optnone uwtable
-define dso_local i32 @main() !type !4 {
+define i32 @main() !type !4 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
index 27cb02d8bcf1a..0e3aaecc2647f 100644
--- a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
@@ -10,7 +10,7 @@ entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
; CHECK-NEXT: [ 3498816979441845844 ] }
- %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ %call = tail call i32 %func(i8 signext %x), !callee_type !1
ret i32 %call
}
diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
index a6d1969136a85..15306c64e6845 100644
--- a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
@@ -8,7 +8,7 @@
declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
-define dso_local i32 @main() !type !1 {
+define i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
index 264eb041d136c..922af72db2c67 100644
--- a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
@@ -11,7 +11,7 @@ entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
; CHECK-NEXT: [ 3498816979441845844 ] }
- %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ %call = tail call i32 %func(i8 signext %x), !callee_type !1
ret i32 %call
}
diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
index 46cc0eaebbcee..6d4dd4c31060a 100644
--- a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
@@ -9,7 +9,7 @@
declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
-define dso_local i32 @main() !type !1 {
+define i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
diff --git a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
index 5841037229e7b..7265266ce5851 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
@@ -9,7 +9,7 @@ entry:
ret i32 %call
}
-define dso_local i32 @main(i32 %argc) local_unnamed_addr !type !3 {
+define i32 @main(i32 %argc) local_unnamed_addr !type !3 {
entry:
%0 = and i32 %argc, 1
%cmp = icmp eq i32 %0, 0
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index 827d3d6386d04..96642993d3962 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -9,7 +9,7 @@ declare !type !1 i32 @bar(i8 signext)
declare !type !2 ptr @baz(ptr)
-define dso_local void @main() {
+define void @main() {
entry:
%retval = alloca i32, align 4
%fp_foo = alloca ptr, align 8
diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
index 31cdc137c52ad..8daac3c010d7b 100644
--- a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
@@ -10,7 +10,7 @@ entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
; CHECK-NEXT: [ 3498816979441845844 ] }
- %call = tail call noundef i32 %func(i8 noundef signext %x), !callee_type !1
+ %call = tail call i32 %func(i8 signext %x), !callee_type !1
ret i32 %call
}
diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
index 6f0890de3ed37..dbe40cfff6c7d 100644
--- a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
@@ -8,7 +8,7 @@
declare !type !0 void @foo(i8 signext %a)
; CHECK: name: main
-define dso_local i32 @main() !type !1 {
+define i32 @main() !type !1 {
entry:
%retval = alloca i32, align 4
%fp = alloca ptr, align 8
>From 03ad07f3b8a1aa9b9dcc5e72c05ab68f84b1a169 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Tue, 13 May 2025 20:50:04 +0000
Subject: [PATCH 27/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
.../calleetypeid-directcall-mismatched.ll | 42 ++++++++++++++++++
.../ARM/calleetypeid-directcall-mismatched.ll | 42 ++++++++++++++++++
.../calleetypeid-directcall-mismatched.ll | 42 ++++++++++++++++++
.../calleetypeid-directcall-mismatched.ll | 43 +++++++++++++++++++
.../X86/calleetypeid-directcall-mismatched.ll | 42 ++++++++++++++++++
5 files changed, 211 insertions(+)
create mode 100644 llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
create mode 100644 llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
create mode 100644 llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
create mode 100644 llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
create mode 100644 llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
diff --git a/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
new file mode 100644
index 0000000000000..8f882362d30f9
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
@@ -0,0 +1,42 @@
+;; Tests that callee_type metadata attached to direct call sites are safely ignored.
+
+; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
+
+; Function Attrs: mustprogress noinline optnone uwtable
+define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NOT: calleeTypeIds:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ %z.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ store i32 %z, ptr %z.addr, align 4
+ %zval = load i32, ptr %z.addr, align 4
+ %yval = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which matches the
+ ;; callee type accurately.
+ %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
+ %xval = load i32, ptr %x.addr, align 4
+ %yval2 = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ %add = add nsw i32 %call, %call1
+ %xval2 = load i32, ptr %x.addr, align 4
+ %zval2 = load i32, ptr %z.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ %sub = sub nsw i32 %add, %call2
+ ret i32 %sub
+}
+
+declare !type !4 i32 @_Z4fizzii(i32, i32)
+
+!0 = !{!4}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
+!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
diff --git a/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
new file mode 100644
index 0000000000000..c3100ebcb1e3a
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
@@ -0,0 +1,42 @@
+;; Tests that callee_type metadata attached to direct call sites are safely ignored.
+
+; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
+
+; Function Attrs: mustprogress noinline optnone uwtable
+define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NOT: calleeTypeIds:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ %z.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ store i32 %z, ptr %z.addr, align 4
+ %zval = load i32, ptr %z.addr, align 4
+ %yval = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which matches the
+ ;; callee type accurately.
+ %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
+ %xval = load i32, ptr %x.addr, align 4
+ %yval2 = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ %add = add nsw i32 %call, %call1
+ %xval2 = load i32, ptr %x.addr, align 4
+ %zval2 = load i32, ptr %z.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ %sub = sub nsw i32 %add, %call2
+ ret i32 %sub
+}
+
+declare !type !4 i32 @_Z4fizzii(i32, i32)
+
+!0 = !{!4}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
+!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
diff --git a/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
new file mode 100644
index 0000000000000..4fa0b15058b5f
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
@@ -0,0 +1,42 @@
+;; Tests that callee_type metadata attached to direct call sites are safely ignored.
+
+; RUN: llc --call-graph-section -mtriple mips-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
+
+; Function Attrs: mustprogress noinline optnone uwtable
+define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NOT: calleeTypeIds:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ %z.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ store i32 %z, ptr %z.addr, align 4
+ %zval = load i32, ptr %z.addr, align 4
+ %yval = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which matches the
+ ;; callee type accurately.
+ %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
+ %xval = load i32, ptr %x.addr, align 4
+ %yval2 = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ %add = add nsw i32 %call, %call1
+ %xval2 = load i32, ptr %x.addr, align 4
+ %zval2 = load i32, ptr %z.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ %sub = sub nsw i32 %add, %call2
+ ret i32 %sub
+}
+
+declare !type !4 i32 @_Z4fizzii(i32, i32)
+
+!0 = !{!4}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
+!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
diff --git a/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
new file mode 100644
index 0000000000000..102a7adb8270d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
@@ -0,0 +1,43 @@
+;; Tests that callee_type metadata attached to direct call sites are safely ignored.
+
+; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-after=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck %s
+
+; Function Attrs: mustprogress noinline optnone uwtable
+define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NOT: calleeTypeIds:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ %z.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ store i32 %z, ptr %z.addr, align 4
+ %zval = load i32, ptr %z.addr, align 4
+ %yval = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which matches the
+ ;; callee type accurately.
+ %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
+ %xval = load i32, ptr %x.addr, align 4
+ %yval2 = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ %add = add nsw i32 %call, %call1
+ %xval2 = load i32, ptr %x.addr, align 4
+ %zval2 = load i32, ptr %z.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ %sub = sub nsw i32 %add, %call2
+ ret i32 %sub
+}
+
+declare !type !4 i32 @_Z4fizzii(i32, i32)
+
+!0 = !{!4}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
+!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
diff --git a/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
new file mode 100644
index 0000000000000..02ddac672acc8
--- /dev/null
+++ b/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
@@ -0,0 +1,42 @@
+;; Tests that callee_type metadata attached to direct call sites are safely ignored.
+
+; RUN: llc --call-graph-section -mtriple x86_64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
+
+; Function Attrs: mustprogress noinline optnone uwtable
+define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+entry:
+ ; CHECK: callSites:
+ ; CHECK-NOT: calleeTypeIds:
+ %x.addr = alloca i32, align 4
+ %y.addr = alloca i32, align 4
+ %z.addr = alloca i32, align 4
+ store i32 %x, ptr %x.addr, align 4
+ store i32 %y, ptr %y.addr, align 4
+ store i32 %z, ptr %z.addr, align 4
+ %zval = load i32, ptr %z.addr, align 4
+ %yval = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which matches the
+ ;; callee type accurately.
+ %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
+ %xval = load i32, ptr %x.addr, align 4
+ %yval2 = load i32, ptr %y.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ %add = add nsw i32 %call, %call1
+ %xval2 = load i32, ptr %x.addr, align 4
+ %zval2 = load i32, ptr %z.addr, align 4
+ ;; This direct call has a callee_type metadata node which points to a
+ ;; mismatched callee type id.
+ %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ %sub = sub nsw i32 %add, %call2
+ ret i32 %sub
+}
+
+declare !type !4 i32 @_Z4fizzii(i32, i32)
+
+!0 = !{!4}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
+!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
>From edf799da08ea1dfcdf02622d0aaf2ef1b8913cd8 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Wed, 14 May 2025 02:07:59 +0000
Subject: [PATCH 28/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/docs/CalleeTypeMetadata.rst | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/llvm/docs/CalleeTypeMetadata.rst b/llvm/docs/CalleeTypeMetadata.rst
index 8c35dec125f0c..9e0038229d78d 100644
--- a/llvm/docs/CalleeTypeMetadata.rst
+++ b/llvm/docs/CalleeTypeMetadata.rst
@@ -4,13 +4,14 @@ Callee Type Metadata
Introduction
============
-This ``!callee_type`` metadata is introduced as part of an ongoing effort to generate a call graph
-section in the object file. The broader design for the call graph section and the compiler flags which
-will enable the feature will be documented as those changes land. The ``!callee_type`` metadata is used
-to identify types of intended callees of indirect call instructions. The ``!callee_type`` metadata is a
+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 ``!type`` metadata objects (See :doc:`TypeMetadata`) with each ``!type`` metadata
-pointing to a callee's :ref:`type identifier
-<calleetype-type-identifier>`.
+pointing to a callee's :ref:`type identifier <calleetype-type-identifier>`.
+LLVM's `control flow integrity`_ also uses the ``!type`` metadata in its implementation.
+
+.. _Control Flow Integrity(CFI): https://clang.llvm.org/docs/ControlFlowIntegrity.html
.. _calleetype-type-identifier:
>From d04642b82e12c640f7c9ef5a8960a8808bbae4fc Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Wed, 14 May 2025 02:11:30 +0000
Subject: [PATCH 29/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/docs/CalleeTypeMetadata.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/docs/CalleeTypeMetadata.rst b/llvm/docs/CalleeTypeMetadata.rst
index 9e0038229d78d..0190c4dc1cbff 100644
--- a/llvm/docs/CalleeTypeMetadata.rst
+++ b/llvm/docs/CalleeTypeMetadata.rst
@@ -9,9 +9,9 @@ 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 ``!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`_ also uses the ``!type`` metadata in its implementation.
+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
+.. _Control Flow Integrity (CFI): https://clang.llvm.org/docs/ControlFlowIntegrity.html
.. _calleetype-type-identifier:
>From 8bbbe129a34868c1bddfc9698f0c52b794f8858f Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Tue, 27 May 2025 18:29:55 +0000
Subject: [PATCH 30/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/test/Assembler/callee-type-metadata.ll | 24 +++++++++++++++
.../callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../X86/call-graph-section-tailcall.ll | 8 ++---
.../callsite-emit-calleetypeid-tailcall.ll | 2 +-
.../Inline/drop-callee-type-metadata.ll | 29 ++++++++++++++-----
.../InstCombine/drop-callee-type-metadata.ll | 18 ++++++++----
llvm/test/Verifier/callee-type-metadata.ll | 19 ++++--------
10 files changed, 73 insertions(+), 35 deletions(-)
create mode 100644 llvm/test/Assembler/callee-type-metadata.ll
diff --git a/llvm/test/Assembler/callee-type-metadata.ll b/llvm/test/Assembler/callee-type-metadata.ll
new file mode 100644
index 0000000000000..371473b9313cc
--- /dev/null
+++ b/llvm/test/Assembler/callee-type-metadata.ll
@@ -0,0 +1,24 @@
+;; Test if the callee_type metadata attached to indirect call sites adhere to the expected format.
+
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 signext %x) !type !0 {
+entry:
+ %func.addr = alloca ptr, align 8
+ %x.addr = alloca i8, align 1
+ store ptr %func, ptr %func.addr, align 8
+ 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: %call = call i32 %fptr(i8 signext %x_val), !callee_type !1
+ %call = call i32 %fptr(i8 signext %x_val), !callee_type !1
+ ret i32 %call
+}
+
+declare !type !2 i32 @_Z3barc(i8 signext)
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFicE"}
+!4 = !{!3}
+!8 = !{i64 0, !"_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 d0458a6613479..bc46aea43eb62 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 %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
index bf89e1b76cceb..26c63244a571a 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 %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
index 0e3aaecc2647f..b388f90b205d3 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 %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
index 922af72db2c67..682e8d2e3b72e 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 %s
; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
index 7265266ce5851..50d7e4de34fa4 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
@@ -3,13 +3,13 @@
; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
entry:
%call = tail call i32 %func(i8 signext %x), !callee_type !1
ret i32 %call
}
-define i32 @main(i32 %argc) local_unnamed_addr !type !3 {
+define i32 @main(i32 %argc) !type !3 {
entry:
%0 = and i32 %argc, 1
%cmp = icmp eq i32 %0, 0
@@ -18,9 +18,9 @@ entry:
ret i32 %call.i
}
-declare !type !2 i32 @_Z3fooc(i8 signext) local_unnamed_addr
+declare !type !2 i32 @_Z3fooc(i8 signext)
-declare !type !2 i32 @_Z3barc(i8 signext) local_unnamed_addr
+declare !type !2 i32 @_Z3barc(i8 signext)
;; Check that the numeric type id (md5 hash) for the below type ids are emitted
;; to the callgraph section.
diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
index 8daac3c010d7b..a4b4777ab4c87 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 %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll b/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
index ce7830536c200..547588089c5b0 100644
--- a/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
+++ b/llvm/test/Transforms/Inline/drop-callee-type-metadata.ll
@@ -1,20 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
;; Test if the callee_type metadata is dropped when it is
;; is mapped to a direct function call from an indirect call during inlining.
-; RUN: opt -passes="inline" -S < %s | FileCheck %s
+; RUN: opt -passes=inline -S < %s | FileCheck %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) local_unnamed_addr !type !0 {
+define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
+; CHECK-LABEL: define i32 @_Z13call_indirectPFicEc(
+; CHECK-SAME: ptr [[FUNC:%.*]], i8 [[X:%.*]]) !type [[META0:![0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = call i32 [[FUNC]](i8 [[X]]), !callee_type [[META1:![0-9]+]]
+; CHECK-NEXT: ret i32 [[CALL]]
+;
entry:
%call = call i32 %func(i8 %x), !callee_type !1
ret i32 %call
}
-define i32 @_Z3barv() local_unnamed_addr !type !3 {
+define i32 @_Z3barv() !type !3 {
+; CHECK-LABEL: define i32 @_Z3barv(
+; CHECK-SAME: ) !type [[META3:![0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL_I:%.*]] = call i32 @_Z3fooc(i8 97)
+; CHECK-NEXT: ret i32 [[CALL_I]]
+;
entry:
- ; CHECK-LABEL: define i32 @_Z3barv()
- ; CHECK-NEXT: entry:
- ; CHECK-NOT: !callee_type
- ; CHECK-NEXT: %call.i = call i32 @_Z3fooc(i8 97)
%call = call i32 @_Z13call_indirectPFicEc(ptr nonnull @_Z3fooc, i8 97)
ret i32 %call
}
@@ -24,3 +33,9 @@ declare !type !2 i32 @_Z3fooc(i8 signext)
!1 = !{!2}
!2 = !{i64 0, !"_ZTSFicE.generalized"}
!3 = !{i64 0, !"_ZTSFivE.generalized"}
+;.
+; CHECK: [[META0]] = !{i64 0, !"_ZTSFiPvcE.generalized"}
+; CHECK: [[META1]] = !{[[META2:![0-9]+]]}
+; CHECK: [[META2]] = !{i64 0, !"_ZTSFicE.generalized"}
+; CHECK: [[META3]] = !{i64 0, !"_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 13c60f675d66d..debb5eddb9208 100644
--- a/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
+++ b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
@@ -1,14 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
;; Test if the callee_type metadata is dropped when it is attached
;; to a direct function call during instcombine.
-; RUN: opt -passes="instcombine" -S < %s | FileCheck %s
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
-define i32 @_Z3barv() local_unnamed_addr !type !3 {
+define i32 @_Z3barv() !type !3 {
+; CHECK-LABEL: define i32 @_Z3barv(
+; CHECK-SAME: ) !type [[META0:![0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @_Z3fooc(i8 97)
+; CHECK-NEXT: ret i32 [[CALL]]
+;
entry:
- ; CHECK-LABEL: define i32 @_Z3barv()
- ; CHECK-NEXT: entry:
- ; CHECK-NOT: !callee_type
- ; CHECK-NEXT: %call = call i32 @_Z3fooc(i8 97)
%call = call i32 @_Z3fooc(i8 97), !callee_type !1
ret i32 %call
}
@@ -19,3 +22,6 @@ declare !type !2 i32 @_Z3fooc(i8 signext)
!1 = !{!2}
!2 = !{i64 0, !"_ZTSFicE.generalized"}
!3 = !{i64 0, !"_ZTSFivE.generalized"}
+;.
+; CHECK: [[META0]] = !{i64 0, !"_ZTSFivE.generalized"}
+;.
diff --git a/llvm/test/Verifier/callee-type-metadata.ll b/llvm/test/Verifier/callee-type-metadata.ll
index 0107dec27de34..694daab14c784 100644
--- a/llvm/test/Verifier/callee-type-metadata.ll
+++ b/llvm/test/Verifier/callee-type-metadata.ll
@@ -1,6 +1,6 @@
;; Test if the callee_type metadata attached to indirect call sites adhere to the expected format.
-; RUN: not opt -passes=verify < %s 2>&1 | FileCheck %s
+; RUN: not llvm-as -disable-output < %s 2>&1 | FileCheck %s
define i32 @_Z13call_indirectPFicEc(ptr %func, i8 signext %x) !type !0 {
entry:
%func.addr = alloca ptr, align 8
@@ -8,23 +8,16 @@ entry:
store ptr %func, ptr %func.addr, align 8
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
- ;; No failures expected for this callee_type metdata.
- %call = call i32 %fptr(i8 signext %x_val), !callee_type !1
+ %x_val = load i8, ptr %x.addr, align 1
;; callee_type metdata is a type metadata instead of a list of type metadata nodes.
; CHECK: The callee_type metadata must be a list of type metadata nodes
- %call2 = call i32 %fptr(i8 signext %x_val), !callee_type !0
+ %call = call i32 %fptr(i8 signext %x_val), !callee_type !0
;; callee_type metdata must be a list of "generalized" type metadata.
; CHECK: Only generalized type metadata can be part of the callee_type metadata list
- %call3 = call i32 %fptr(i8 signext %x_val), !callee_type !4
+ %call2 = call i32 %fptr(i8 signext %x_val), !callee_type !2
ret i32 %call
}
-declare !type !2 i32 @_Z3barc(i8 signext)
-
!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
-!1 = !{!2}
-!2 = !{i64 0, !"_ZTSFicE.generalized"}
-!3 = !{i64 0, !"_ZTSFicE"}
-!4 = !{!3}
-!8 = !{i64 0, !"_ZTSFicE.generalized"}
+!1 = !{i64 0, !"_ZTSFicE"}
+!2 = !{!1}
>From ca6d2ccbdc8fc1a8a2147286dc526e083272c300 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Tue, 27 May 2025 20:58:17 +0000
Subject: [PATCH 31/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
.../CodeGen/AArch64/calleetypeid-directcall-mismatched.ll | 7 +++++--
.../test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll | 7 +++++--
.../CodeGen/Mips/calleetypeid-directcall-mismatched.ll | 7 +++++--
.../CodeGen/RISCV/calleetypeid-directcall-mismatched.ll | 7 +++++--
.../test/CodeGen/X86/calleetypeid-directcall-mismatched.ll | 7 +++++--
5 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
index 8f882362d30f9..e98dfd8a3b4b7 100644
--- a/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
@@ -5,8 +5,11 @@
; Function Attrs: mustprogress noinline optnone uwtable
define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
entry:
- ; CHECK: callSites:
- ; CHECK-NOT: calleeTypeIds:
+ ;; Test that `calleeTypeIds` field is not present in `callSites`
+ ; CHECK-LABEL: callSites:
+ ; 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: [] }
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
%z.addr = alloca i32, align 4
diff --git a/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
index c3100ebcb1e3a..8e79cc22e87bc 100644
--- a/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
@@ -5,8 +5,11 @@
; Function Attrs: mustprogress noinline optnone uwtable
define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
entry:
- ; CHECK: callSites:
- ; CHECK-NOT: calleeTypeIds:
+ ;; Test that `calleeTypeIds` field is not present in `callSites`
+ ; CHECK-LABEL: callSites:
+ ; 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: [] }
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
%z.addr = alloca i32, align 4
diff --git a/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
index 4fa0b15058b5f..cdf733151b1eb 100644
--- a/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
@@ -5,8 +5,11 @@
; Function Attrs: mustprogress noinline optnone uwtable
define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
entry:
- ; CHECK: callSites:
- ; CHECK-NOT: calleeTypeIds:
+ ;; Test that `calleeTypeIds` field is not present in `callSites`
+ ; CHECK-LABEL: callSites:
+ ; 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: [] }
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
%z.addr = alloca i32, align 4
diff --git a/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
index 102a7adb8270d..b22111384a9e1 100644
--- a/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
@@ -6,8 +6,11 @@
; Function Attrs: mustprogress noinline optnone uwtable
define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
entry:
- ; CHECK: callSites:
- ; CHECK-NOT: calleeTypeIds:
+ ;; Test that `calleeTypeIds` field is not present in `callSites`
+ ; CHECK-LABEL: callSites:
+ ; 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: [] }
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
%z.addr = alloca i32, align 4
diff --git a/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
index 02ddac672acc8..9537e12401f25 100644
--- a/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
@@ -5,8 +5,11 @@
; Function Attrs: mustprogress noinline optnone uwtable
define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
entry:
- ; CHECK: callSites:
- ; CHECK-NOT: calleeTypeIds:
+ ;; Test that `calleeTypeIds` field is not present in `callSites`
+ ; CHECK-LABEL: callSites:
+ ; 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: [] }
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
%z.addr = alloca i32, align 4
>From 8f07a4c1ad5b7df41ef06b9a7093f085ebc7bf65 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Wed, 11 Jun 2025 00:16:43 +0000
Subject: [PATCH 32/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/docs/CalleeTypeMetadata.rst | 4 +-
llvm/lib/IR/Metadata.cpp | 4 +-
.../InstCombine/InstCombineCalls.cpp | 4 +-
llvm/lib/Transforms/Utils/Local.cpp | 17 +-
llvm/test/Assembler/callee-type-metadata.ll | 3 -
.../InstCombine/drop-callee-type-metadata.ll | 8 +-
.../SimplifyCFG/merge-callee-type-metadata.ll | 148 ++++++++++++++++++
7 files changed, 170 insertions(+), 18 deletions(-)
create mode 100644 llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
diff --git a/llvm/docs/CalleeTypeMetadata.rst b/llvm/docs/CalleeTypeMetadata.rst
index 0190c4dc1cbff..45d0657966a8c 100644
--- a/llvm/docs/CalleeTypeMetadata.rst
+++ b/llvm/docs/CalleeTypeMetadata.rst
@@ -7,8 +7,8 @@ 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 ``!type`` metadata objects (See :doc:`TypeMetadata`) with each ``!type`` metadata
-pointing to a callee's :ref:`type identifier <calleetype-type-identifier>`.
+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
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 82c1b96f5fb7e..4894cf41ae7e1 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1306,7 +1306,7 @@ MDNode *MDNode::getMergedCalleeTypeMetadata(LLVMContext &Ctx, MDNode *A,
MDNode *B) {
SmallVector<Metadata *, 8> AB;
SmallSet<Metadata *, 8> MergedCallees;
- auto AddUniqueCallees = [&AB, &MergedCallees](llvm::MDNode *N) {
+ auto AddUniqueCallees = [&AB, &MergedCallees](MDNode *N) {
if (!N)
return;
for (const MDOperand &Op : N->operands()) {
@@ -1317,7 +1317,7 @@ MDNode *MDNode::getMergedCalleeTypeMetadata(LLVMContext &Ctx, MDNode *A,
};
AddUniqueCallees(A);
AddUniqueCallees(B);
- return llvm::MDNode::get(Ctx, AB);
+ return MDNode::get(Ctx, AB);
}
MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 04790af1dbd2b..308d7bc7c91b5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -4163,8 +4163,10 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
// Drop unnecessary callee_type metadata from calls that were converted
// into direct calls.
- if (Call.getMetadata(LLVMContext::MD_callee_type) && !Call.isIndirectCall())
+ if (Call.getMetadata(LLVMContext::MD_callee_type) && !Call.isIndirectCall()) {
Call.setMetadata(LLVMContext::MD_callee_type, nullptr);
+ Changed = true;
+ }
// Drop unnecessary kcfi operand bundles from calls that were converted
// into direct calls.
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index d37fccfaaa301..d8f68089b1074 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3365,6 +3365,7 @@ static void combineMetadata(Instruction *K, const Instruction *J,
case LLVMContext::MD_mmra:
case LLVMContext::MD_memprof:
case LLVMContext::MD_callsite:
+ case LLVMContext::MD_callee_type:
break;
case LLVMContext::MD_align:
if (!AAOnly && (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef)))
@@ -3377,11 +3378,6 @@ static void combineMetadata(Instruction *K, const Instruction *J,
K->setMetadata(Kind,
MDNode::getMostGenericAlignmentOrDereferenceable(JMD, KMD));
break;
- case LLVMContext::MD_callee_type:
- if (!AAOnly)
- K->setMetadata(Kind, MDNode::getMergedCalleeTypeMetadata(
- K->getContext(), KMD, JMD));
- break;
case LLVMContext::MD_preserve_access_index:
// Preserve !preserve.access.index in K.
break;
@@ -3442,6 +3438,17 @@ static void combineMetadata(Instruction *K, const Instruction *J,
MDNode::getMergedCallsiteMetadata(KCallSite, JCallSite));
}
+ // Merge callee_type metadata.
+ // Handle separately to support cases where only one instruction has the
+ // metadata.
+ auto *JCalleeType = J->getMetadata(LLVMContext::MD_callee_type);
+ auto *KCalleeType = K->getMetadata(LLVMContext::MD_callee_type);
+ if (!AAOnly && (JCalleeType || KCalleeType)) {
+ K->setMetadata(LLVMContext::MD_callee_type,
+ MDNode::getMergedCalleeTypeMetadata(
+ K->getContext(), KCalleeType, JCalleeType));
+ }
+
// Merge prof metadata.
// Handle separately to support cases where only one instruction has the
// metadata.
diff --git a/llvm/test/Assembler/callee-type-metadata.ll b/llvm/test/Assembler/callee-type-metadata.ll
index 371473b9313cc..9c3cfbe82fc13 100644
--- a/llvm/test/Assembler/callee-type-metadata.ll
+++ b/llvm/test/Assembler/callee-type-metadata.ll
@@ -19,6 +19,3 @@ declare !type !2 i32 @_Z3barc(i8 signext)
!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
!1 = !{!2}
!2 = !{i64 0, !"_ZTSFicE.generalized"}
-!3 = !{i64 0, !"_ZTSFicE"}
-!4 = !{!3}
-!8 = !{i64 0, !"_ZTSFicE.generalized"}
diff --git a/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
index debb5eddb9208..83215f78be1b0 100644
--- a/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
+++ b/llvm/test/Transforms/InstCombine/drop-callee-type-metadata.ll
@@ -1,14 +1,13 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
;; Test if the callee_type metadata is dropped when it is attached
;; to a direct function call during instcombine.
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
-define i32 @_Z3barv() !type !3 {
+define i32 @_Z3barv() !type !0 {
; CHECK-LABEL: define i32 @_Z3barv(
; CHECK-SAME: ) !type [[META0:![0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @_Z3fooc(i8 97)
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @_Z3fooc(i8 97){{$}}
; CHECK-NEXT: ret i32 [[CALL]]
;
entry:
@@ -18,10 +17,9 @@ entry:
declare !type !2 i32 @_Z3fooc(i8 signext)
-!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!0 = !{i64 0, !"_ZTSFivE.generalized"}
!1 = !{!2}
!2 = !{i64 0, !"_ZTSFicE.generalized"}
-!3 = !{i64 0, !"_ZTSFivE.generalized"}
;.
; CHECK: [[META0]] = !{i64 0, !"_ZTSFivE.generalized"}
;.
diff --git a/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll b/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
new file mode 100644
index 0000000000000..8d230425520c2
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
@@ -0,0 +1,148 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
+;; Test if the callee_type metadata is merged correctly.
+
+; RUN: opt -passes=simplifycfg -S < %s | FileCheck %s
+
+;; Test if the callee_type metadata is merged correctly when
+;; the instructions carry differring callee_type metadata.
+define ptr @_Z10test_diffb(i1 zeroext %b) {
+; CHECK-LABEL: define ptr @_Z10test_diffb(
+; CHECK-SAME: i1 zeroext [[B:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @_Znwm(i64 4), !callee_type [[META0:![0-9]+]]
+; CHECK-NEXT: ret ptr [[CALL]]
+;
+entry:
+ br i1 %b, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call ptr @_Znwm(i64 4), !callee_type !4
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call1 = call ptr @_Znwm(i64 4), !callee_type !3
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %x.0 = phi ptr [ %call, %if.then ], [ %call1, %if.else ]
+ ret ptr %x.0
+}
+
+;; Test if the callee_type metadata is merged correctly when
+;; the instructions carry same callee_type metadata.
+define ptr @_Z10test_sameb(i1 zeroext %b) {
+; CHECK-LABEL: define ptr @_Z10test_sameb(
+; CHECK-SAME: i1 zeroext [[B:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @_Znwm(i64 4), !callee_type [[META3:![0-9]+]]
+; CHECK-NEXT: ret ptr [[CALL]]
+;
+entry:
+ br i1 %b, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call ptr @_Znwm(i64 4), !callee_type !3
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call1 = call ptr @_Znwm(i64 4), !callee_type !3
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %x.0 = phi ptr [ %call, %if.then ], [ %call1, %if.else ]
+ ret ptr %x.0
+}
+
+;; Test if the callee_type metadata is merged correctly when
+;; only the right instruction has callee_type metadata.
+define ptr @_Z10test_leftb(i1 zeroext %b) {
+; CHECK-LABEL: define ptr @_Z10test_leftb(
+; CHECK-SAME: i1 zeroext [[B:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @_Znwm(i64 4), !callee_type [[META4:![0-9]+]]
+; CHECK-NEXT: ret ptr [[CALL]]
+;
+entry:
+ br i1 %b, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call ptr @_Znwm(i64 4), !callee_type !4
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call1 = call ptr @_Znwm(i64 4)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %x.0 = phi ptr [ %call, %if.then ], [ %call1, %if.else ]
+ ret ptr %x.0
+}
+
+;; Test if the callee_type metadata is merged correctly when
+;; each of the callee_type metadata are lists.
+define ptr @_Z10test_rightb(i1 zeroext %b) {
+; CHECK-LABEL: define ptr @_Z10test_rightb(
+; CHECK-SAME: i1 zeroext [[B:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @_Znwm(i64 4), !callee_type [[META3]]
+; CHECK-NEXT: ret ptr [[CALL]]
+;
+entry:
+ br i1 %b, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call ptr @_Znwm(i64 4)
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call1 = call ptr @_Znwm(i64 4), !callee_type !3
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %x.0 = phi ptr [ %call, %if.then ], [ %call1, %if.else ]
+ ret ptr %x.0
+}
+
+;; Test if the callee_type metadata is merged correctly when
+;; only the left instruction has callee_type metadata.
+define ptr @_Z10test_listb(i1 zeroext %b) {
+; CHECK-LABEL: define ptr @_Z10test_listb(
+; CHECK-SAME: i1 zeroext [[B:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @_Znwm(i64 4), !callee_type [[META5:![0-9]+]]
+; CHECK-NEXT: ret ptr [[CALL]]
+;
+entry:
+ br i1 %b, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call ptr @_Znwm(i64 4), !callee_type !6
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call1 = call ptr @_Znwm(i64 4), !callee_type !5
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %x.0 = phi ptr [ %call, %if.then ], [ %call1, %if.else ]
+ ret ptr %x.0
+}
+
+declare ptr @_Znwm(i64)
+
+!0 = !{i64 0, !"callee_type0.generalized"}
+!1 = !{i64 0, !"callee_type1.generalized"}
+!2 = !{i64 0, !"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: [[META3]] = !{[[META2]]}
+; CHECK: [[META4]] = !{[[META1]]}
+; CHECK: [[META5]] = !{[[META2]], [[META1]], [[META6:![0-9]+]]}
+; CHECK: [[META6]] = !{i64 0, !"callee_type1.generalized"}
+;.
>From 0e29abc80e6d21595ecc28839ea1b03b94dcee4c Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Wed, 11 Jun 2025 00:32:51 +0000
Subject: [PATCH 33/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/IR/Metadata.cpp | 2 +-
.../Transforms/SimplifyCFG/merge-callee-type-metadata.ll | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 4894cf41ae7e1..7ba3f5ec6391d 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1305,7 +1305,7 @@ static void addRange(SmallVectorImpl<ConstantInt *> &EndPoints,
MDNode *MDNode::getMergedCalleeTypeMetadata(LLVMContext &Ctx, MDNode *A,
MDNode *B) {
SmallVector<Metadata *, 8> AB;
- SmallSet<Metadata *, 8> MergedCallees;
+ SmallPtrSet<Metadata *, 8> MergedCallees;
auto AddUniqueCallees = [&AB, &MergedCallees](MDNode *N) {
if (!N)
return;
diff --git a/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll b/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
index 8d230425520c2..42bc9b6732176 100644
--- a/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
+++ b/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
@@ -54,7 +54,7 @@ if.end: ; preds = %if.else, %if.then
}
;; Test if the callee_type metadata is merged correctly when
-;; only the right instruction has callee_type metadata.
+;; only the left instruction has callee_type metadata.
define ptr @_Z10test_leftb(i1 zeroext %b) {
; CHECK-LABEL: define ptr @_Z10test_leftb(
; CHECK-SAME: i1 zeroext [[B:%.*]]) {
@@ -79,7 +79,7 @@ if.end: ; preds = %if.else, %if.then
}
;; Test if the callee_type metadata is merged correctly when
-;; each of the callee_type metadata are lists.
+;; only the right instruction has callee_type metadata.
define ptr @_Z10test_rightb(i1 zeroext %b) {
; CHECK-LABEL: define ptr @_Z10test_rightb(
; CHECK-SAME: i1 zeroext [[B:%.*]]) {
@@ -104,7 +104,7 @@ if.end: ; preds = %if.else, %if.then
}
;; Test if the callee_type metadata is merged correctly when
-;; only the left instruction has callee_type metadata.
+;; each of the callee_type metadata are lists.
define ptr @_Z10test_listb(i1 zeroext %b) {
; CHECK-LABEL: define ptr @_Z10test_listb(
; CHECK-SAME: i1 zeroext [[B:%.*]]) {
>From c262b6980d3021511a11801b43126aa860123a59 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Fri, 18 Jul 2025 15:34:08 +0000
Subject: [PATCH 34/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/IR/Verifier.cpp | 3 +--
llvm/test/Verifier/callee-type-metadata.ll | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index cc7f28cf81cca..9bd573e773610 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -5195,9 +5195,8 @@ void Verifier::visitCallsiteMetadata(Instruction &I, MDNode *MD) {
}
static inline bool isConstantIntMetadataOperand(const Metadata *MD) {
- if (auto *VAL = dyn_cast<ValueAsMetadata>(MD)) {
+ if (auto *VAL = dyn_cast<ValueAsMetadata>(MD))
return isa<ConstantInt>(VAL->getValue());
- }
return false;
}
diff --git a/llvm/test/Verifier/callee-type-metadata.ll b/llvm/test/Verifier/callee-type-metadata.ll
index 471e831167038..50cf37b941fe9 100644
--- a/llvm/test/Verifier/callee-type-metadata.ll
+++ b/llvm/test/Verifier/callee-type-metadata.ll
@@ -30,4 +30,4 @@ entry:
!5 = !{!"expected_int", !"_ZTSFicE"}
!6 = !{!5}
!7 = !{i64 0, !"_ZTSFicE"}
-!8 = !{!7}
\ No newline at end of file
+!8 = !{!7}
>From 125ddcd922c8cae26a7246654c9af23b97a01640 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Fri, 18 Jul 2025 17:35:56 +0000
Subject: [PATCH 35/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/Transforms/Utils/Local.cpp | 19 +++++++++++--------
.../SimplifyCFG/merge-callee-type-metadata.ll | 15 +++++++--------
2 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index fc8c4ea002b68..7d0dd447c91ac 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3158,14 +3158,17 @@ static void combineMetadata(Instruction *K, const Instruction *J,
}
// Merge callee_type metadata.
- // Given the called operands are identical, presence of at least one
- // callee_type metadata guarantees the intended callee.
- auto *JCalleeType = J->getMetadata(LLVMContext::MD_callee_type);
- auto *KCalleeType = K->getMetadata(LLVMContext::MD_callee_type);
- if (!AAOnly && (JCalleeType || KCalleeType)) {
- K->setMetadata(LLVMContext::MD_callee_type,
- MDNode::getMergedCalleeTypeMetadata(
- K->getContext(), KCalleeType, JCalleeType));
+ if (!AAOnly) {
+ auto *JCalleeType = J->getMetadata(LLVMContext::MD_callee_type);
+ auto *KCalleeType = K->getMetadata(LLVMContext::MD_callee_type);
+ // Drop the callee_type metadata if either of the call instructions do not
+ // have it.
+ if (JCalleeType && KCalleeType) {
+ K->setMetadata(LLVMContext::MD_callee_type,
+ MDNode::getMergedCalleeTypeMetadata(
+ K->getContext(), KCalleeType, JCalleeType));
+ } else
+ K->setMetadata(LLVMContext::MD_callee_type, nullptr);
}
// Merge prof metadata.
diff --git a/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll b/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
index a01baaba19280..3e56939b1642f 100644
--- a/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
+++ b/llvm/test/Transforms/SimplifyCFG/merge-callee-type-metadata.ll
@@ -61,7 +61,7 @@ if.end: ; preds = %if.else, %if.then
ret ptr %x.0
}
-;; Test if the callee_type metadata is merged correctly when
+;; Test if the callee_type metadata is dropped correctly when
;; only the left instruction has callee_type metadata.
define ptr @_Z10test_leftb(i1 zeroext %b) {
; CHECK-LABEL: define ptr @_Z10test_leftb(
@@ -69,7 +69,7 @@ define ptr @_Z10test_leftb(i1 zeroext %b) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[FN:%.*]] = alloca ptr, align 8
; CHECK-NEXT: store ptr @_Znwm, ptr [[FN]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call ptr [[FN]](i64 4), !callee_type [[META4:![0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr [[FN]](i64 4)
; CHECK-NEXT: ret ptr [[CALL]]
;
entry:
@@ -90,7 +90,7 @@ if.end: ; preds = %if.else, %if.then
ret ptr %x.0
}
-;; Test if the callee_type metadata is merged correctly when
+;; Test if the callee_type metadata is dropped correctly when
;; only the right instruction has callee_type metadata.
define ptr @_Z10test_rightb(i1 zeroext %b) {
; CHECK-LABEL: define ptr @_Z10test_rightb(
@@ -98,7 +98,7 @@ define ptr @_Z10test_rightb(i1 zeroext %b) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[FN:%.*]] = alloca ptr, align 8
; CHECK-NEXT: store ptr @_Znwm, ptr [[FN]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call ptr [[FN]](i64 4), !callee_type [[META3]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr [[FN]](i64 4)
; CHECK-NEXT: ret ptr [[CALL]]
;
entry:
@@ -127,7 +127,7 @@ define ptr @_Z10test_listb(i1 zeroext %b) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[FN:%.*]] = alloca ptr, align 8
; CHECK-NEXT: store ptr @_Znwm, ptr [[FN]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call ptr [[FN]](i64 4), !callee_type [[META5:![0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr [[FN]](i64 4), !callee_type [[META4:![0-9]+]]
; CHECK-NEXT: ret ptr [[CALL]]
;
entry:
@@ -162,7 +162,6 @@ declare ptr @_Znwm(i64)
; CHECK: [[META1]] = !{i64 0, !"callee_type2.generalized"}
; CHECK: [[META2]] = !{i64 0, !"callee_type0.generalized"}
; CHECK: [[META3]] = !{[[META2]]}
-; CHECK: [[META4]] = !{[[META1]]}
-; CHECK: [[META5]] = !{[[META2]], [[META1]], [[META6:![0-9]+]]}
-; CHECK: [[META6]] = !{i64 0, !"callee_type1.generalized"}
+; CHECK: [[META4]] = !{[[META2]], [[META1]], [[META5:![0-9]+]]}
+; CHECK: [[META5]] = !{i64 0, !"callee_type1.generalized"}
;.
>From 9eff07da39bdea61d0fa0ae535fae7619b262390 Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Fri, 18 Jul 2025 21:01:22 +0000
Subject: [PATCH 36/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/lib/IR/Metadata.cpp | 6 ++++--
llvm/lib/Transforms/Utils/Local.cpp | 20 ++++++--------------
2 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 8f3f9df3afafd..929c1d8d6d36e 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1305,11 +1305,13 @@ static void addRange(SmallVectorImpl<ConstantInt *> &EndPoints,
MDNode *MDNode::getMergedCalleeTypeMetadata(LLVMContext &Ctx, MDNode *A,
MDNode *B) {
+ // Drop the callee_type metadata if either of the call instructions do not
+ // have it.
+ if (!A || !B)
+ return nullptr;
SmallVector<Metadata *, 8> AB;
SmallPtrSet<Metadata *, 8> MergedCallees;
auto AddUniqueCallees = [&AB, &MergedCallees](MDNode *N) {
- if (!N)
- return;
for (Metadata *MD : N->operands()) {
if (MergedCallees.insert(MD).second)
AB.push_back(MD);
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 7d0dd447c91ac..f21e00f53eb12 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3080,7 +3080,13 @@ static void combineMetadata(Instruction *K, const Instruction *J,
case LLVMContext::MD_mmra:
case LLVMContext::MD_memprof:
case LLVMContext::MD_callsite:
+ break;
case LLVMContext::MD_callee_type:
+ if (!AAOnly) {
+ K->setMetadata(
+ LLVMContext::MD_callee_type,
+ MDNode::getMergedCalleeTypeMetadata(K->getContext(), KMD, JMD));
+ }
break;
case LLVMContext::MD_align:
if (!AAOnly && (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef)))
@@ -3157,20 +3163,6 @@ static void combineMetadata(Instruction *K, const Instruction *J,
MDNode::getMergedCallsiteMetadata(KCallSite, JCallSite));
}
- // Merge callee_type metadata.
- if (!AAOnly) {
- auto *JCalleeType = J->getMetadata(LLVMContext::MD_callee_type);
- auto *KCalleeType = K->getMetadata(LLVMContext::MD_callee_type);
- // Drop the callee_type metadata if either of the call instructions do not
- // have it.
- if (JCalleeType && KCalleeType) {
- K->setMetadata(LLVMContext::MD_callee_type,
- MDNode::getMergedCalleeTypeMetadata(
- K->getContext(), KCalleeType, JCalleeType));
- } else
- K->setMetadata(LLVMContext::MD_callee_type, nullptr);
- }
-
// Merge prof metadata.
// Handle separately to support cases where only one instruction has the
// metadata.
>From 1ba8c047a0413950f65e076ef2c2d8a35bf9394f Mon Sep 17 00:00:00 2001
From: Necip Fazil Yildiran <necip at google.com>
Date: Fri, 18 Jul 2025 21:35:18 +0000
Subject: [PATCH 37/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/include/llvm/IR/Metadata.h | 4 ++--
llvm/lib/IR/Metadata.cpp | 7 +++----
llvm/lib/Transforms/Utils/Local.cpp | 5 ++---
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 7ed562286bc3c..af252aa24567a 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1474,8 +1474,8 @@ class MDNode : public Metadata {
const Instruction *BInstr);
LLVM_ABI static MDNode *getMergedMemProfMetadata(MDNode *A, MDNode *B);
LLVM_ABI static MDNode *getMergedCallsiteMetadata(MDNode *A, MDNode *B);
- LLVM_ABI static MDNode *getMergedCalleeTypeMetadata(LLVMContext &Ctx,
- MDNode *A, MDNode *B);
+ LLVM_ABI static MDNode *getMergedCalleeTypeMetadata(const MDNode *A,
+ const MDNode *B);
};
/// Tuple of metadata.
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 929c1d8d6d36e..0dbd07f4865dc 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1303,15 +1303,14 @@ static void addRange(SmallVectorImpl<ConstantInt *> &EndPoints,
EndPoints.push_back(High);
}
-MDNode *MDNode::getMergedCalleeTypeMetadata(LLVMContext &Ctx, MDNode *A,
- MDNode *B) {
+MDNode *MDNode::getMergedCalleeTypeMetadata(const MDNode *A, const MDNode *B) {
// Drop the callee_type metadata if either of the call instructions do not
// have it.
if (!A || !B)
return nullptr;
SmallVector<Metadata *, 8> AB;
SmallPtrSet<Metadata *, 8> MergedCallees;
- auto AddUniqueCallees = [&AB, &MergedCallees](MDNode *N) {
+ auto AddUniqueCallees = [&AB, &MergedCallees](const MDNode *N) {
for (Metadata *MD : N->operands()) {
if (MergedCallees.insert(MD).second)
AB.push_back(MD);
@@ -1319,7 +1318,7 @@ MDNode *MDNode::getMergedCalleeTypeMetadata(LLVMContext &Ctx, MDNode *A,
};
AddUniqueCallees(A);
AddUniqueCallees(B);
- return MDNode::get(Ctx, AB);
+ return MDNode::get(A->getContext(), AB);
}
MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index f21e00f53eb12..548070eb1578d 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3083,9 +3083,8 @@ static void combineMetadata(Instruction *K, const Instruction *J,
break;
case LLVMContext::MD_callee_type:
if (!AAOnly) {
- K->setMetadata(
- LLVMContext::MD_callee_type,
- MDNode::getMergedCalleeTypeMetadata(K->getContext(), KMD, JMD));
+ K->setMetadata(LLVMContext::MD_callee_type,
+ MDNode::getMergedCalleeTypeMetadata(KMD, JMD));
}
break;
case LLVMContext::MD_align:
>From c67f714eaab9a7f1e4d2d76da28641b05710231d Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Mon, 21 Jul 2025 23:53:52 +0000
Subject: [PATCH 38/43] Fix review comment on test file.
Created using spr 1.3.6-beta.1
---
clang/test/Driver/call-graph-section.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c
index 5832aa6754137..563f36de4119e 100644
--- a/clang/test/Driver/call-graph-section.c
+++ b/clang/test/Driver/call-graph-section.c
@@ -1,5 +1,5 @@
-// RUN: %clang -### -S -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s
-// RUN: %clang -### -S -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s
+// RUN: %clang -### -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s
+// RUN: %clang -### -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s
// CALL-GRAPH-SECTION: "-fcall-graph-section"
// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section"
>From 7321a3ed8d514e928c5431e0cd24181ea4296503 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 23 Jul 2025 02:51:58 +0000
Subject: [PATCH 39/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
.../calleetypeid-directcall-mismatched.ll | 55 ++++++----------
.../callsite-emit-calleetypeid-tailcall.ll | 4 +-
.../AArch64/callsite-emit-calleetypeid.ll | 27 +++-----
.../ARM/calleetypeid-directcall-mismatched.ll | 55 ++++++----------
.../callsite-emit-calleetypeid-tailcall.ll | 4 +-
.../CodeGen/ARM/callsite-emit-calleetypeid.ll | 27 +++-----
...te-info-ambiguous-indirect-call-typeid.mir | 64 ++++++-------------
.../call-site-info-direct-calls-typeid.mir | 54 ++++++----------
.../CodeGen/MIR/X86/call-site-info-typeid.mir | 24 +++----
.../MIR/X86/callsite-emit-calleetypeid.ll | 22 ++-----
.../calleetypeid-directcall-mismatched.ll | 55 ++++++----------
.../callsite-emit-calleetypeid-tailcall.ll | 4 +-
.../Mips/callsite-emit-calleetypeid.ll | 27 +++-----
.../calleetypeid-directcall-mismatched.ll | 57 +++++++----------
.../callsite-emit-calleetypeid-tailcall.ll | 6 +-
.../RISCV/callsite-emit-calleetypeid.ll | 27 +++-----
.../X86/call-graph-section-assembly.ll | 29 +++++----
.../X86/call-graph-section-tailcall.ll | 14 ++--
llvm/test/CodeGen/X86/call-graph-section.ll | 30 +++------
.../X86/calleetypeid-directcall-mismatched.ll | 55 ++++++----------
.../callsite-emit-calleetypeid-tailcall.ll | 4 +-
.../CodeGen/X86/callsite-emit-calleetypeid.ll | 25 +++-----
22 files changed, 249 insertions(+), 420 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
index e98dfd8a3b4b7..c4c54175ecd9f 100644
--- a/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/AArch64/calleetypeid-directcall-mismatched.ll
@@ -1,45 +1,32 @@
;; Tests that callee_type metadata attached to direct call sites are safely ignored.
-; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
-; Function Attrs: mustprogress noinline optnone uwtable
-define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+;; Test that `calleeTypeIds` field is not present in `callSites`
+; CHECK-LABEL: callSites:
+; 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 {
entry:
- ;; Test that `calleeTypeIds` field is not present in `callSites`
- ; CHECK-LABEL: callSites:
- ; 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: [] }
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- %z.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- store i32 %z, ptr %z.addr, align 4
- %zval = load i32, ptr %z.addr, align 4
- %yval = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which matches the
- ;; callee type accurately.
- %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
- %xval = load i32, ptr %x.addr, align 4
- %yval2 = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ ;; Call instruction with accurate callee_type.
+ ;; callee_type should be dropped seemlessly.
+ %call = call i32 @fizz(i32 %x, i32 %y), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call1 = call i32 @fizz(i32 %x, i32 %y), !callee_type !3
%add = add nsw i32 %call, %call1
- %xval2 = load i32, ptr %x.addr, align 4
- %zval2 = load i32, ptr %z.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call2 = call i32 @fizz(i32 %add, i32 %y), !callee_type !3
%sub = sub nsw i32 %add, %call2
ret i32 %sub
}
-declare !type !4 i32 @_Z4fizzii(i32, i32)
+declare !type !2 i32 @fizz(i32, i32)
-!0 = !{!4}
+!0 = !{i64 0, !"_ZTSFiiiiE.generalized"}
!1 = !{!2}
-!2 = !{i64 0, !"_ZTSFicE.generalized"}
-!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
-!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!2 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!3 = !{!4}
+!4 = !{i64 0, !"_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 bc46aea43eb62..b47607ec135ae 100644
--- a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid-tailcall.ll
@@ -3,9 +3,9 @@
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
;; 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 %s
+; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
+define i32 @check_tailcall(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
index cbdb5f4bec35f..108946685529c 100644
--- a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
@@ -1,27 +1,20 @@
;; Tests that call site callee type ids can be extracted and set from
;; callee_type metadata.
-;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; 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 %s
-
-declare !type !0 void @foo(i8 signext %a)
+; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
; CHECK: name: main
-define i32 @main() !type !1 {
+; CHECK: callSites:
+; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+; CHECK-NEXT: [ 7854600665770582568 ] }
+define i32 @main() {
entry:
- %retval = alloca i32, align 4
- %fp = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store ptr @foo, ptr %fp, align 8
- %fp_val = load ptr, ptr %fp, align 8
- ; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
- ; CHECK-NEXT: [ 7854600665770582568 ] }
- call void %fp_val(i8 signext 97), !callee_type !2
+ %0 = load ptr, ptr null, align 8
+ call void %0(i8 0), !callee_type !0
ret i32 0
}
-!0 = !{i64 0, !"_ZTSFvcE.generalized"}
-!1 = !{i64 0, !"_ZTSFiE.generalized"}
-!2 = !{!0}
+!0 = !{!1}
+!1 = !{i64 0, !"_ZTSFvcE.generalized"}
diff --git a/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
index 8e79cc22e87bc..8f7b0506a5e39 100644
--- a/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/ARM/calleetypeid-directcall-mismatched.ll
@@ -1,45 +1,32 @@
;; Tests that callee_type metadata attached to direct call sites are safely ignored.
-; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
-; Function Attrs: mustprogress noinline optnone uwtable
-define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+;; Test that `calleeTypeIds` field is not present in `callSites`
+; CHECK-LABEL: callSites:
+; 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 {
entry:
- ;; Test that `calleeTypeIds` field is not present in `callSites`
- ; CHECK-LABEL: callSites:
- ; 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: [] }
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- %z.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- store i32 %z, ptr %z.addr, align 4
- %zval = load i32, ptr %z.addr, align 4
- %yval = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which matches the
- ;; callee type accurately.
- %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
- %xval = load i32, ptr %x.addr, align 4
- %yval2 = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ ;; Call instruction with accurate callee_type.
+ ;; callee_type should be dropped seemlessly.
+ %call = call i32 @fizz(i32 %x, i32 %y), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call1 = call i32 @fizz(i32 %x, i32 %y), !callee_type !3
%add = add nsw i32 %call, %call1
- %xval2 = load i32, ptr %x.addr, align 4
- %zval2 = load i32, ptr %z.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call2 = call i32 @fizz(i32 %add, i32 %y), !callee_type !3
%sub = sub nsw i32 %add, %call2
ret i32 %sub
}
-declare !type !4 i32 @_Z4fizzii(i32, i32)
+declare !type !2 i32 @fizz(i32, i32)
-!0 = !{!4}
+!0 = !{i64 0, !"_ZTSFiiiiE.generalized"}
!1 = !{!2}
-!2 = !{i64 0, !"_ZTSFicE.generalized"}
-!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
-!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!2 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!3 = !{!4}
+!4 = !{i64 0, !"_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 26c63244a571a..05e1e8bf0502b 100644
--- a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid-tailcall.ll
@@ -3,9 +3,9 @@
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
;; 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 %s
+; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
+define i32 @check_tailcall(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
index 87fdbb5635e85..68f476ce8a730 100644
--- a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
@@ -1,27 +1,20 @@
;; Tests that call site callee type ids can be extracted and set from
;; callee_type metadata.
-;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; 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 %s
-
-declare !type !0 void @foo(i8 signext %a)
+; RUN: llc --call-graph-section -mtriple arm-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
; CHECK: name: main
-define i32 @main() !type !1 {
+; CHECK: callSites:
+; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+; CHECK-NEXT: [ 7854600665770582568 ] }
+define i32 @main() {
entry:
- %retval = alloca i32, align 4
- %fp = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store ptr @foo, ptr %fp, align 8
- %fp_val = load ptr, ptr %fp, align 8
- ; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
- ; CHECK-NEXT: [ 7854600665770582568 ] }
- call void %fp_val(i8 signext 97), !callee_type !2
+ %0 = load ptr, ptr null, align 8
+ call void %0(i8 0), !callee_type !0
ret i32 0
}
-!0 = !{i64 0, !"_ZTSFvcE.generalized"}
-!1 = !{i64 0, !"_ZTSFiE.generalized"}
-!2 = !{!0}
+!0 = !{!1}
+!1 = !{i64 0, !"_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 c6198df2c1d3a..75585da8cbf22 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
@@ -1,59 +1,31 @@
-# Test MIR printer and parser for type id field in callSites. It is used
-# for propagating call site type identifiers to emit in the call graph section.
+# Test MIR printer and parser to check if a call instruction with multiple
+# callee types are handled correctly.
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck --match-full-lines %s
-# CHECK: name: main
+# CHECK: name: ambiguous_caller
# CHECK: callSites:
-# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [] }
-# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
-# CHECK-NEXT: [ 1234567890 ] }
+# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: {{.*}}, calleeTypeIds:
+# CHECK-NEXT: [ 1234, 5678 ] }
---- |
-
- declare !type !0 i32 @_Z3addii(i32, i32)
-
- declare !type !0 i32 @_Z8multiplyii(i32, i32)
-
- declare !type !1 ptr @_Z13get_operationb(i1 zeroext %is_addition)
-
- define i32 @main(i32 %argc) !type !2 {
+--- |
+ define ptr @ambiguous_caller() {
entry:
- %retval = alloca i32, align 4
- %argc.addr = alloca i32, align 4
- %x = alloca i32, align 4
- %y = alloca i32, align 4
- %op = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store i32 %argc, ptr %argc.addr, align 4
- store i32 5, ptr %x, align 4
- store i32 10, ptr %y, align 4
- %argc_val = load i32, ptr %argc.addr, align 4
- %rem = srem i32 %argc_val, 2
- %cmp = icmp eq i32 %rem, 0
- %call = call ptr @_Z13get_operationb(i1 zeroext %cmp)
- store ptr %call, ptr %op, align 8
- %op_val = load ptr, ptr %op, align 8
- %x_val = load i32, ptr %x, align 4
- %y_val = load i32, ptr %y, align 4
- %call1 = call i32 %op_val(i32 %x_val, i32 %y_val), !callee_type !3
- ret i32 %call1
+ %fn = alloca ptr, align 8
+ %call1 = call ptr %fn(i64 4), !callee_type !0
+ ret ptr %call1
}
- !0 = !{i64 0, !"_ZTSFiiiE.generalized"}
- !1 = !{i64 0, !"_ZTSFPvbE.generalized"}
- !2 = !{i64 0, !"_ZTSFiiE.generalized"}
- !3 = !{!0}
-
+ !0 = !{!1, !2}
+ !1 = !{i64 0, !"callee_type0.generalized"}
+ !2 = !{i64 0, !"callee_type2.generalized"}
...
---
-name: main
+name: ambiguous_caller
callSites:
- - { bb: 0, offset: 0, fwdArgRegs: [] }
- - { bb: 0, offset: 2, fwdArgRegs: [], calleeTypeIds: [ 1234567890 ] }
+ - { bb: 0, offset: 1, fwdArgRegs: [], calleeTypeIds: [ 1234, 5678 ] }
body: |
bb.0.entry:
- CALL64pcrel32 @_Z13get_operationb, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
- %7:gr64 = COPY $rax
- CALL64r %7, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
-
+ %0:gr64 = MOV32ri64 4
+ CALL64r killed %0, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
+ RET 0, $rax
...
diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
index 853e2ce85e188..f4decf2f70f2a 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
@@ -4,67 +4,51 @@
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck --match-full-lines %s
# CHECK-NOT: calleeTypeIds
-# CHECK: name: _Z3barii
+# CHECK: name: bar
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [] }
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [] }
-# CHECK: name: _Z3fooii
+# CHECK: name: foo
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [] }
---- |
- declare !type !0 i32 @_Z4fizzii(i32 %x, i32 %y)
-
- declare !type !0 i32 @_Z4buzzii(i32 %x, i32 %y)
-
- define i32 @_Z3barii(i32 %x, i32 %y) !type !0 {
+--- |
+ declare i32 @fizz(i32, i32)
+
+ declare i32 @buzz(i32, i32)
+
+ define i32 @bar(i32 %x, i32 %y) !type !0 {
entry:
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- %x_val = load i32, ptr %x.addr, align 4
- %y_val = load i32, ptr %y.addr, align 4
- %call = call i32 @_Z4buzzii(i32 %x_val, i32 %y_val)
- %x_val_2 = load i32, ptr %x.addr, align 4
- %y_val_2 = load i32, ptr %y.addr, align 4
- %call1 = call i32 @_Z4fizzii(i32 %x_val_2, i32 %y_val_2)
- %sub = sub nsw i32 %call, %call1
- ret i32 %sub
+ %call = call i32 @buzz(i32 %x, i32 %x)
+ %call1 = call i32 @fizz(i32 %x, i32 %x)
+ ret i32 0
}
- define i32 @_Z3fooii(i32 %x, i32 %y) !type !0 {
+ define i32 @foo(i32 %x, i32 %y) !type !0 {
entry:
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- %x_val = load i32, ptr %x.addr, align 4
- %y_val = load i32, ptr %y.addr, align 4
- %call = call i32 @_Z3barii(i32 %x_val, i32 %y_val)
- ret i32 %call
+ %call1 = call i32 @bar(i32 %x, i32 %x)
+ ret i32 0
}
!0 = !{i64 0, !"_ZTSFiiiE.generalized"}
-
...
---
-name: _Z3barii
+name: bar
callSites:
- { bb: 0, offset: 0, fwdArgRegs: [] }
- { bb: 0, offset: 1, fwdArgRegs: [] }
body: |
bb.0.entry:
- CALL64pcrel32 @_Z4buzzii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
- CALL64pcrel32 @_Z4fizzii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ CALL64pcrel32 target-flags(x86-plt) @buzz, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ CALL64pcrel32 target-flags(x86-plt) @fizz, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
...
---
-name: _Z3fooii
+name: foo
callSites:
- { bb: 0, offset: 0, fwdArgRegs: [] }
body: |
bb.0.entry:
- CALL64pcrel32 @_Z3barii, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ CALL64pcrel32 target-flags(x86-plt) @bar, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
...
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 09cf69c1f1ffa..c646699bd8718 100644
--- a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
+++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
@@ -2,33 +2,27 @@
# for propagating call site type identifiers to emit in the call graph section.
# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck --match-full-lines %s
-# CHECK: name: main
+# CHECK: name: call_foo
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
# CHECK-NEXT: [ 123456789 ] }
--- |
- declare void @foo(i8 signext %a)
-
- define i32 @main() {
+ define i32 @call_foo() {
entry:
- %retval = alloca i32, align 4
- %fp = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store ptr @foo, ptr %fp, align 8
- %fp_val = load ptr, ptr %fp, align 8
- call void %fp_val(i8 signext 97)
+ %0 = load ptr, ptr null, align 8
+ call void %0(i8 0), !callee_type !0
ret i32 0
}
+ !0 = !{!1}
+ !1 = !{i64 0, !"_ZTSFvcE.generalized"}
...
---
-name: main
+name: call_foo
callSites:
- - { bb: 0, offset: 1, fwdArgRegs: [], calleeTypeIds: [ 123456789 ] }
+ - { bb: 0, offset: 0, fwdArgRegs: [], calleeTypeIds: [ 123456789 ] }
body: |
bb.0.entry:
- %0:gr64 = MOV32ri64 @foo
- CALL64r killed %0, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp
-
+ CALL64m $noreg, 1, $noreg, 0, $noreg, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp :: (load (s64) from `ptr null`)
...
diff --git a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
index 0285ee6a6f9bd..367632ee6857c 100644
--- a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
@@ -80,24 +80,12 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Function Attrs: noinline nounwind optnone uwtable
-define void @foo(i8 signext %a) !type !3 {
+define i32 @main() {
entry:
- ret void
-}
-
-; Function Attrs: noinline nounwind optnone uwtable
-define i32 @main() !type !4 {
-entry:
- %retval = alloca i32, align 4
- %fp = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store ptr @foo, ptr %fp, align 8
- %fp_val = load ptr, ptr %fp, align 8
- call void %fp_val(i8 signext 97), !callee_type !5
+ %0 = load ptr, ptr null, align 8
+ call void %0(i8 0), !callee_type !0
ret i32 0
}
-!3 = !{i64 0, !"_ZTSFvcE.generalized"}
-!4 = !{i64 0, !"_ZTSFiE.generalized"}
-!5 = !{!3}
+!0 = !{!1}
+!1 = !{i64 0, !"_ZTSFvcE.generalized"}
diff --git a/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
index cdf733151b1eb..a66a884dc844e 100644
--- a/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/Mips/calleetypeid-directcall-mismatched.ll
@@ -1,45 +1,32 @@
;; Tests that callee_type metadata attached to direct call sites are safely ignored.
-; RUN: llc --call-graph-section -mtriple mips-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple mips-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
-; Function Attrs: mustprogress noinline optnone uwtable
-define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+;; Test that `calleeTypeIds` field is not present in `callSites`
+; CHECK-LABEL: callSites:
+; 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 {
entry:
- ;; Test that `calleeTypeIds` field is not present in `callSites`
- ; CHECK-LABEL: callSites:
- ; 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: [] }
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- %z.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- store i32 %z, ptr %z.addr, align 4
- %zval = load i32, ptr %z.addr, align 4
- %yval = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which matches the
- ;; callee type accurately.
- %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
- %xval = load i32, ptr %x.addr, align 4
- %yval2 = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ ;; Call instruction with accurate callee_type.
+ ;; callee_type should be dropped seemlessly.
+ %call = call i32 @fizz(i32 %x, i32 %y), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call1 = call i32 @fizz(i32 %x, i32 %y), !callee_type !3
%add = add nsw i32 %call, %call1
- %xval2 = load i32, ptr %x.addr, align 4
- %zval2 = load i32, ptr %z.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call2 = call i32 @fizz(i32 %add, i32 %y), !callee_type !3
%sub = sub nsw i32 %add, %call2
ret i32 %sub
}
-declare !type !4 i32 @_Z4fizzii(i32, i32)
+declare !type !2 i32 @fizz(i32, i32)
-!0 = !{!4}
+!0 = !{i64 0, !"_ZTSFiiiiE.generalized"}
!1 = !{!2}
-!2 = !{i64 0, !"_ZTSFicE.generalized"}
-!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
-!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!2 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!3 = !{!4}
+!4 = !{i64 0, !"_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 b388f90b205d3..e7f162c6daa77 100644
--- a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid-tailcall.ll
@@ -3,9 +3,9 @@
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
;; 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 %s
+; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
+define i32 @check_tailcall(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
index 15306c64e6845..65c8d6b906233 100644
--- a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
@@ -1,27 +1,20 @@
;; Tests that call site callee type ids can be extracted and set from
;; callee_type metadata.
-;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
+;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; 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 %s
-
-declare !type !0 void @foo(i8 signext %a)
+; RUN: llc --call-graph-section -mtriple=mips-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
; CHECK: name: main
-define i32 @main() !type !1 {
+; CHECK: callSites:
+; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+; CHECK-NEXT: [ 7854600665770582568 ] }
+define i32 @main() {
entry:
- %retval = alloca i32, align 4
- %fp = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store ptr @foo, ptr %fp, align 8
- %fp_val = load ptr, ptr %fp, align 8
- ; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
- ; CHECK-NEXT: [ 7854600665770582568 ] }
- call void %fp_val(i8 signext 97), !callee_type !2
+ %0 = load ptr, ptr null, align 8
+ call void %0(i8 0), !callee_type !0
ret i32 0
}
-!0 = !{i64 0, !"_ZTSFvcE.generalized"}
-!1 = !{i64 0, !"_ZTSFiE.generalized"}
-!2 = !{!0}
+!0 = !{!1}
+!1 = !{i64 0, !"_ZTSFvcE.generalized"}
diff --git a/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
index b22111384a9e1..34493cec0eab0 100644
--- a/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/RISCV/calleetypeid-directcall-mismatched.ll
@@ -1,46 +1,33 @@
;; Tests that callee_type metadata attached to direct call sites are safely ignored.
-; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-after=finalize-isel -o - | FileCheck %s
-; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck %s
+; 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
-; Function Attrs: mustprogress noinline optnone uwtable
-define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+;; Test that `calleeTypeIds` field is not present in `callSites`
+; CHECK-LABEL: callSites:
+; 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 {
entry:
- ;; Test that `calleeTypeIds` field is not present in `callSites`
- ; CHECK-LABEL: callSites:
- ; 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: [] }
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- %z.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- store i32 %z, ptr %z.addr, align 4
- %zval = load i32, ptr %z.addr, align 4
- %yval = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which matches the
- ;; callee type accurately.
- %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
- %xval = load i32, ptr %x.addr, align 4
- %yval2 = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ ;; Call instruction with accurate callee_type.
+ ;; callee_type should be dropped seemlessly.
+ %call = call i32 @fizz(i32 %x, i32 %y), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call1 = call i32 @fizz(i32 %x, i32 %y), !callee_type !3
%add = add nsw i32 %call, %call1
- %xval2 = load i32, ptr %x.addr, align 4
- %zval2 = load i32, ptr %z.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call2 = call i32 @fizz(i32 %add, i32 %y), !callee_type !3
%sub = sub nsw i32 %add, %call2
ret i32 %sub
}
-declare !type !4 i32 @_Z4fizzii(i32, i32)
+declare !type !2 i32 @fizz(i32, i32)
-!0 = !{!4}
+!0 = !{i64 0, !"_ZTSFiiiiE.generalized"}
!1 = !{!2}
-!2 = !{i64 0, !"_ZTSFicE.generalized"}
-!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
-!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!2 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!3 = !{!4}
+!4 = !{i64 0, !"_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 682e8d2e3b72e..6e1fe92dac8f7 100644
--- a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid-tailcall.ll
@@ -3,10 +3,10 @@
;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; computed as the type id from the callee_type operand bundle.
-; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-after=finalize-isel -o - | FileCheck %s
-; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck %s
+; 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 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
+define i32 @check_tailcall(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
index 6d4dd4c31060a..8189cf74e47df 100644
--- a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
@@ -3,26 +3,19 @@
;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; computed as the type id from the callee_type operand bundle.
-; RUN: llc --call-graph-section -mtriple riscv64 < %s -stop-after=finalize-isel -o - | FileCheck %s
-; RUN: llc --call-graph-section -mtriple riscv32 < %s -stop-after=finalize-isel -o - | FileCheck %s
-
-declare !type !0 void @foo(i8 signext %a)
+; 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
; CHECK: name: main
-define i32 @main() !type !1 {
+; CHECK: callSites:
+; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+; CHECK-NEXT: [ 7854600665770582568 ] }
+define i32 @main() {
entry:
- %retval = alloca i32, align 4
- %fp = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store ptr @foo, ptr %fp, align 8
- %fp_val = load ptr, ptr %fp, align 8
- ; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
- ; CHECK-NEXT: [ 7854600665770582568 ] }
- call void %fp_val(i8 signext 97), !callee_type !2
+ %0 = load ptr, ptr null, align 8
+ call void %0(i8 0), !callee_type !0
ret i32 0
}
-!0 = !{i64 0, !"_ZTSFvcE.generalized"}
-!1 = !{i64 0, !"_ZTSFiE.generalized"}
-!2 = !{!0}
+!0 = !{!1}
+!1 = !{i64 0, !"_ZTSFvcE.generalized"}
diff --git a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
index 5d9f9585763ad..6b6c9f5acac2a 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
@@ -1,21 +1,21 @@
;; Test if temporary labels are generated for each indirect callsite with a callee_type metadata.
-;; Test if the .callgraph section contains the numerical callee type id for each of the temporary
-;; labels generated.
+;; Test if the .callgraph section contains the MD5 hash of callee type ids generated from
+;; generalized type id strings.
; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -o - < %s | FileCheck %s
; CHECK: ball:
-; CHECK-NEXT: .Lfunc_begin0:
+; CHECK-NEXT: [[LABEL_FUNC:\.Lfunc_begin[0-9]+]]:
define ptr @ball() {
entry:
%fp_foo_val = load ptr, ptr null, align 8
- ; CHECK: .Ltmp0:
+ ; CHECK: [[LABEL_TMP0:\.Ltmp[0-9]+]]:
call void (...) %fp_foo_val(), !callee_type !0
%fp_bar_val = load ptr, ptr null, align 8
- ; CHECK: .Ltmp1:
+ ; CHECK: [[LABEL_TMP1:\.Ltmp[0-9]+]]:
%call_fp_bar = call i32 %fp_bar_val(i8 0), !callee_type !2
%fp_baz_val = load ptr, ptr null, align 8
- ; CHECK: .Ltmp2:
+ ; CHECK: [[LABEL_TMP2:\.Ltmp[0-9]+]]:
%call_fp_baz = call ptr %fp_baz_val(ptr null), !callee_type !4
ret ptr %call_fp_baz
}
@@ -23,18 +23,21 @@ entry:
; CHECK: .section .callgraph,"o", at progbits,.text
; CHECK-NEXT: .quad 0
-; CHECK-NEXT: .quad .Lfunc_begin0
+; CHECK-NEXT: .quad [[LABEL_FUNC]]
; CHECK-NEXT: .quad 1
; CHECK-NEXT: .quad 3
-; CHECK-NEXT: .quad 4524972987496481828
-; CHECK-NEXT: .quad .Ltmp0
!0 = !{!1}
!1 = !{i64 0, !"_ZTSFvE.generalized"}
-; CHECK-NEXT: .quad 3498816979441845844
-; CHECK-NEXT: .quad .Ltmp1
+;; Test for MD5 hash of _ZTSFvE.generalized and the generated temporary callsite label.
+; CHECK-NEXT: .quad 4524972987496481828
+; CHECK-NEXT: .quad [[LABEL_TMP0]]
!2 = !{!3}
!3 = !{i64 0, !"_ZTSFicE.generalized"}
-; CHECK-NEXT: .quad 8646233951371320954
-; CHECK-NEXT: .quad .Ltmp2
+;; Test for MD5 hash of _ZTSFicE.generalized and the generated temporary callsite label.
+; CHECK-NEXT: .quad 3498816979441845844
+; CHECK-NEXT: .quad [[LABEL_TMP1]]
!4 = !{!5}
!5 = !{i64 0, !"_ZTSFPvS_E.generalized"}
+;; Test for MD5 hash of _ZTSFPvS_E.generalized and the generated temporary callsite label.
+; CHECK-NEXT: .quad 8646233951371320954
+; CHECK-NEXT: .quad [[LABEL_TMP2]]
diff --git a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
index 50d7e4de34fa4..fa14a98008b45 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-tailcall.ll
@@ -3,7 +3,7 @@
; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -filetype=obj -o - < %s | \
; RUN: llvm-readelf -x .callgraph - | FileCheck %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
+define i32 @check_tailcall(ptr %func, i8 %x) !type !0 {
entry:
%call = tail call i32 %func(i8 signext %x), !callee_type !1
ret i32 %call
@@ -11,16 +11,16 @@ entry:
define i32 @main(i32 %argc) !type !3 {
entry:
- %0 = and i32 %argc, 1
- %cmp = icmp eq i32 %0, 0
- %_Z3fooc._Z3barc = select i1 %cmp, ptr @_Z3fooc, ptr @_Z3barc
- %call.i = tail call i32 %_Z3fooc._Z3barc(i8 signext 97), !callee_type !1
+ %andop = and i32 %argc, 1
+ %cmp = icmp eq i32 %andop, 0
+ %foo.bar = select i1 %cmp, ptr @foo, ptr @bar
+ %call.i = tail call i32 %foo.bar(i8 signext 97), !callee_type !1
ret i32 %call.i
}
-declare !type !2 i32 @_Z3fooc(i8 signext)
+declare !type !2 i32 @foo(i8 signext)
-declare !type !2 i32 @_Z3barc(i8 signext)
+declare !type !2 i32 @bar(i8 signext)
;; Check that the numeric type id (md5 hash) for the below type ids are emitted
;; to the callgraph section.
diff --git a/llvm/test/CodeGen/X86/call-graph-section.ll b/llvm/test/CodeGen/X86/call-graph-section.ll
index 96642993d3962..4a9840eac4898 100644
--- a/llvm/test/CodeGen/X86/call-graph-section.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section.ll
@@ -5,32 +5,20 @@
declare !type !0 void @foo()
-declare !type !1 i32 @bar(i8 signext)
+declare !type !1 i32 @bar(i8)
declare !type !2 ptr @baz(ptr)
define void @main() {
entry:
- %retval = alloca i32, align 4
- %fp_foo = alloca ptr, align 8
%a = alloca i8, align 1
- %fp_bar = alloca ptr, align 8
- %fp_baz = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store ptr @foo, ptr %fp_foo, align 8
- %fp_foo_val = load ptr, ptr %fp_foo, align 8
+ %fp_foo_val = load ptr, ptr null, align 8
call void (...) %fp_foo_val(), !callee_type !1
- store ptr @bar, ptr %fp_bar, align 8
- %fp_bar_val = load ptr, ptr %fp_bar, align 8
- %a_val = load i8, ptr %a, align 1
- %call_fp_bar = call i32 %fp_bar_val(i8 signext %a_val), !callee_type !3
- store ptr @baz, ptr %fp_baz, align 8
- %fp_baz_val = load ptr, ptr %fp_baz, align 8
- %call_fp_baz = call ptr %fp_baz_val(ptr %a), !callee_type !5
- call void @foo()
- %a_val_2 = load i8, ptr %a, align 1
- %call_bar = call i32 @bar(i8 signext %a_val_2)
- %call_baz = call ptr @baz(ptr %a)
+ %fp_bar_val = load ptr, ptr null, align 8
+ %param = trunc i64 0 to i8
+ %call_fp_bar = call i32 %fp_bar_val(i8 signext %param), !callee_type !3
+ %fp_baz_val = load ptr, ptr null, align 8
+ %call_fp_baz = call ptr %fp_baz_val(ptr %a), !callee_type !4
ret void
}
@@ -46,5 +34,5 @@ entry:
!2 = !{i64 0, !"_ZTSFicE.generalized"}
!3 = !{!2}
; CHECK-DAG: 7ade6814 f897fd77
-!4 = !{i64 0, !"_ZTSFPvS_E.generalized"}
-!5 = !{!4}
+!4 = !{!5}
+!5 = !{i64 0, !"_ZTSFPvS_E.generalized"}
diff --git a/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll b/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
index 9537e12401f25..7881ea7d59314 100644
--- a/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
+++ b/llvm/test/CodeGen/X86/calleetypeid-directcall-mismatched.ll
@@ -1,45 +1,32 @@
;; Tests that callee_type metadata attached to direct call sites are safely ignored.
-; RUN: llc --call-graph-section -mtriple x86_64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck %s
+; RUN: llc --call-graph-section -mtriple x86_64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
-; Function Attrs: mustprogress noinline optnone uwtable
-define i32 @_Z3fooiii(i32 %x, i32 %y, i32 %z) !type !3 {
+;; Test that `calleeTypeIds` field is not present in `callSites`
+; CHECK-LABEL: callSites:
+; 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 {
entry:
- ;; Test that `calleeTypeIds` field is not present in `callSites`
- ; CHECK-LABEL: callSites:
- ; 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: [] }
- %x.addr = alloca i32, align 4
- %y.addr = alloca i32, align 4
- %z.addr = alloca i32, align 4
- store i32 %x, ptr %x.addr, align 4
- store i32 %y, ptr %y.addr, align 4
- store i32 %z, ptr %z.addr, align 4
- %zval = load i32, ptr %z.addr, align 4
- %yval = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which matches the
- ;; callee type accurately.
- %call = call i32 @_Z4fizzii(i32 %zval, i32 %yval), !callee_type !0
- %xval = load i32, ptr %x.addr, align 4
- %yval2 = load i32, ptr %y.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call1 = call i32 @_Z4fizzii(i32 %xval, i32 %yval2), !callee_type !1
+ ;; Call instruction with accurate callee_type.
+ ;; callee_type should be dropped seemlessly.
+ %call = call i32 @fizz(i32 %x, i32 %y), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call1 = call i32 @fizz(i32 %x, i32 %y), !callee_type !3
%add = add nsw i32 %call, %call1
- %xval2 = load i32, ptr %x.addr, align 4
- %zval2 = load i32, ptr %z.addr, align 4
- ;; This direct call has a callee_type metadata node which points to a
- ;; mismatched callee type id.
- %call2 = call i32 @_Z4fizzii(i32 %xval2, i32 %zval2), !callee_type !1
+ ;; Call instruction with mismatched callee_type.
+ ;; callee_type should be dropped seemlessly without errors.
+ %call2 = call i32 @fizz(i32 %add, i32 %y), !callee_type !3
%sub = sub nsw i32 %add, %call2
ret i32 %sub
}
-declare !type !4 i32 @_Z4fizzii(i32, i32)
+declare !type !2 i32 @fizz(i32, i32)
-!0 = !{!4}
+!0 = !{i64 0, !"_ZTSFiiiiE.generalized"}
!1 = !{!2}
-!2 = !{i64 0, !"_ZTSFicE.generalized"}
-!3 = !{i64 0, !"_ZTSFiiiiE.generalized"}
-!4 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!2 = !{i64 0, !"_ZTSFiiiE.generalized"}
+!3 = !{!4}
+!4 = !{i64 0, !"_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 a4b4777ab4c87..8f6b7a6d7f240 100644
--- a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
+++ b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid-tailcall.ll
@@ -3,9 +3,9 @@
;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; 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 %s
+; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
-define i32 @_Z13call_indirectPFicEc(ptr %func, i8 %x) !type !0 {
+define i32 @check_tailcall(ptr %func, i8 %x) !type !0 {
entry:
; CHECK: callSites:
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
index dbe40cfff6c7d..d8fab32ec0b99 100644
--- a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
@@ -3,25 +3,18 @@
;; Verify the exact calleeTypeIds value to ensure it is not garbage but the value
;; 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 %s
-
-declare !type !0 void @foo(i8 signext %a)
+; RUN: llc --call-graph-section -mtriple=x86_64-unknown-linux < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
; CHECK: name: main
-define i32 @main() !type !1 {
+; CHECK: callSites:
+; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
+; CHECK-NEXT: [ 7854600665770582568 ] }
+define i32 @main() {
entry:
- %retval = alloca i32, align 4
- %fp = alloca ptr, align 8
- store i32 0, ptr %retval, align 4
- store ptr @foo, ptr %fp, align 8
- %fp_val = load ptr, ptr %fp, align 8
- ; CHECK: callSites:
- ; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
- ; CHECK-NEXT: [ 7854600665770582568 ] }
- call void %fp_val(i8 signext 97), !callee_type !2
+ %0 = load ptr, ptr null, align 8
+ call void %0(i8 0), !callee_type !0
ret i32 0
}
-!0 = !{i64 0, !"_ZTSFvcE.generalized"}
-!1 = !{i64 0, !"_ZTSFiE.generalized"}
-!2 = !{!0}
+!0 = !{!1}
+!1 = !{i64 0, !"_ZTSFvcE.generalized"}
>From 571a431c7c58a52d4c562df1ef338f3a531a3c5e Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 23 Jul 2025 17:47:12 +0000
Subject: [PATCH 40/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll | 4 ++--
llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll | 4 ++--
llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll | 4 ++--
llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll | 4 ++--
llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll | 4 ++--
llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll | 4 ++--
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
index 108946685529c..94b657c6ea908 100644
--- a/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/AArch64/callsite-emit-calleetypeid.ll
@@ -11,8 +11,8 @@
; CHECK-NEXT: [ 7854600665770582568 ] }
define i32 @main() {
entry:
- %0 = load ptr, ptr null, align 8
- call void %0(i8 0), !callee_type !0
+ %fn = load ptr, ptr null, align 8
+ call void %fn(i8 0), !callee_type !0
ret i32 0
}
diff --git a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
index 68f476ce8a730..a65e5c5f8c015 100644
--- a/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/ARM/callsite-emit-calleetypeid.ll
@@ -11,8 +11,8 @@
; CHECK-NEXT: [ 7854600665770582568 ] }
define i32 @main() {
entry:
- %0 = load ptr, ptr null, align 8
- call void %0(i8 0), !callee_type !0
+ %fn = load ptr, ptr null, align 8
+ call void %fn(i8 0), !callee_type !0
ret i32 0
}
diff --git a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
index 367632ee6857c..b2a386bc8abe3 100644
--- a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
@@ -82,8 +82,8 @@
define i32 @main() {
entry:
- %0 = load ptr, ptr null, align 8
- call void %0(i8 0), !callee_type !0
+ %fn = load ptr, ptr null, align 8
+ call void %fn(i8 0), !callee_type !0
ret i32 0
}
diff --git a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
index 65c8d6b906233..9f5e858412ed6 100644
--- a/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/Mips/callsite-emit-calleetypeid.ll
@@ -11,8 +11,8 @@
; CHECK-NEXT: [ 7854600665770582568 ] }
define i32 @main() {
entry:
- %0 = load ptr, ptr null, align 8
- call void %0(i8 0), !callee_type !0
+ %fn = load ptr, ptr null, align 8
+ call void %fn(i8 0), !callee_type !0
ret i32 0
}
diff --git a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
index 8189cf74e47df..1f91f4103abbb 100644
--- a/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/RISCV/callsite-emit-calleetypeid.ll
@@ -12,8 +12,8 @@
; CHECK-NEXT: [ 7854600665770582568 ] }
define i32 @main() {
entry:
- %0 = load ptr, ptr null, align 8
- call void %0(i8 0), !callee_type !0
+ %fn = load ptr, ptr null, align 8
+ call void %fn(i8 0), !callee_type !0
ret i32 0
}
diff --git a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
index d8fab32ec0b99..e97a6ac75e111 100644
--- a/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/X86/callsite-emit-calleetypeid.ll
@@ -11,8 +11,8 @@
; CHECK-NEXT: [ 7854600665770582568 ] }
define i32 @main() {
entry:
- %0 = load ptr, ptr null, align 8
- call void %0(i8 0), !callee_type !0
+ %fn = load ptr, ptr null, align 8
+ call void %fn(i8 0), !callee_type !0
ret i32 0
}
>From 4ec81ea8957c31abe7ebb7741bd04e939133675f Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Mon, 28 Jul 2025 21:25:00 +0000
Subject: [PATCH 41/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/test/CodeGen/X86/call-graph-section-assembly.ll | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
index 6b6c9f5acac2a..11362873fb151 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
@@ -9,13 +9,13 @@
define ptr @ball() {
entry:
%fp_foo_val = load ptr, ptr null, align 8
- ; CHECK: [[LABEL_TMP0:\.Ltmp[0-9]+]]:
+ ; CHECK: [[LABEL_TMP0:\.L.*]]:
call void (...) %fp_foo_val(), !callee_type !0
%fp_bar_val = load ptr, ptr null, align 8
- ; CHECK: [[LABEL_TMP1:\.Ltmp[0-9]+]]:
+ ; CHECK: [[LABEL_TMP1:\.L.*]]:
%call_fp_bar = call i32 %fp_bar_val(i8 0), !callee_type !2
%fp_baz_val = load ptr, ptr null, align 8
- ; CHECK: [[LABEL_TMP2:\.Ltmp[0-9]+]]:
+ ; CHECK: [[LABEL_TMP2:\.L.*]]:
%call_fp_baz = call ptr %fp_baz_val(ptr null), !callee_type !4
ret ptr %call_fp_baz
}
>From 50a57865ebf6a5847a21d3cc1a34a4273cd9c6eb Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Thu, 31 Jul 2025 16:26:25 +0000
Subject: [PATCH 42/43] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20?=
=?UTF-8?q?changes=20introduced=20through=20rebase?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
[skip ci]
---
llvm/test/MC/X86/verify-callgraph-section.s | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/test/MC/X86/verify-callgraph-section.s b/llvm/test/MC/X86/verify-callgraph-section.s
index 036eaa6709c2b..ce07228facb15 100644
--- a/llvm/test/MC/X86/verify-callgraph-section.s
+++ b/llvm/test/MC/X86/verify-callgraph-section.s
@@ -44,15 +44,15 @@ ball: # @ball
.quad 1
.quad 3
/// MD5 hash of the callee type ID for foo.
- // CHECK: 2444f731 f5eecb3e
+ // CHECK: 2444f731 f5eecb3e
.quad 0x3ecbeef531f74424
.quad .Ltmp0
/// MD5 hash of the callee type ID for bar.
- // CHECK: 5486bc59 814b8e30
+ // CHECK: 5486bc59 814b8e30
.quad 0x308e4b8159bc8654
.quad .Ltmp1
/// MD5 hash of the callee type ID for baz.
- // CHECK: 7ade6814 f897fd77
+ // CHECK: 7ade6814 f897fd77
.quad 0x77fd97f81468de7a
.quad .Ltmp2
.text
>From d349feb0e155674a9e172e8db75c4b2349ecfd09 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Thu, 31 Jul 2025 20:54:36 +0000
Subject: [PATCH 43/43] Make Driver flag experimental.
Created using spr 1.3.6-beta.1
---
clang/include/clang/Driver/Options.td | 6 +++---
clang/lib/Driver/ToolChains/Clang.cpp | 6 +++---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 4 ++--
clang/test/Driver/call-graph-section.c | 8 ++++----
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3882019b34aa4..6aed20667c8d7 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4440,9 +4440,9 @@ defm data_sections : BoolFOption<"data-sections",
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Place each data in its own section">,
NegFlag<SetFalse>>;
-defm call_graph_section
- : BoolFOption<"call-graph-section", CodeGenOpts<"CallGraphSection">,
- DefaultFalse,
+defm experimental_call_graph_section
+ : BoolFOption<"experimental-call-graph-section",
+ CodeGenOpts<"CallGraphSection">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Emit a call graph section">,
NegFlag<SetFalse>>;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index d0e254f07ad42..6a13e0c2fefc3 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6478,9 +6478,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue());
}
- if (Args.hasFlag(options::OPT_fcall_graph_section,
- options::OPT_fno_call_graph_section, false))
- CmdArgs.push_back("-fcall-graph-section");
+ if (Args.hasFlag(options::OPT_fexperimental_call_graph_section,
+ options::OPT_fno_experimental_call_graph_section, false))
+ CmdArgs.push_back("-fexperimental-call-graph-section");
Args.addOptInFlag(CmdArgs, options::OPT_fstack_size_section,
options::OPT_fno_stack_size_section);
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index cf67e0903c345..bfd88434d8363 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1269,8 +1269,8 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
CmdArgs.push_back(
Args.MakeArgString(Twine(PluginOptPrefix) + "-stack-size-section"));
- if (Args.hasFlag(options::OPT_fcall_graph_section,
- options::OPT_fno_call_graph_section, false))
+ if (Args.hasFlag(options::OPT_fexperimental_call_graph_section,
+ options::OPT_fno_experimental_call_graph_section, false))
CmdArgs.push_back(
Args.MakeArgString(Twine(PluginOptPrefix) + "-call-graph-section"));
diff --git a/clang/test/Driver/call-graph-section.c b/clang/test/Driver/call-graph-section.c
index 563f36de4119e..00fa896dffb87 100644
--- a/clang/test/Driver/call-graph-section.c
+++ b/clang/test/Driver/call-graph-section.c
@@ -1,5 +1,5 @@
-// RUN: %clang -### -fcall-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s
-// RUN: %clang -### -fcall-graph-section -fno-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s
+// RUN: %clang -### -fexperimental-call-graph-section %s 2>&1 | FileCheck --check-prefix=CALL-GRAPH-SECTION %s
+// RUN: %clang -### -fexperimental-call-graph-section -fno-experimental-call-graph-section %s 2>&1 | FileCheck --check-prefix=NO-CALL-GRAPH-SECTION %s
-// CALL-GRAPH-SECTION: "-fcall-graph-section"
-// NO-CALL-GRAPH-SECTION-NOT: "-fcall-graph-section"
+// CALL-GRAPH-SECTION: "-fexperimental-call-graph-section"
+// NO-CALL-GRAPH-SECTION-NOT: "-fexperimental-call-graph-section"
More information about the llvm-commits
mailing list