[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