[llvm-branch-commits] [clang] [llvm] [llvm] Introduce callee_type metadata (PR #87573)

Prabhu Rajasekaran via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Apr 18 19:16:06 PDT 2025


https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/87573

>From a8a5848885e12c771f12cfa33b4dbc6a0272e925 Mon Sep 17 00:00:00 2001
From: Prabhuk <prabhukr at google.com>
Date: Mon, 22 Apr 2024 11:34:04 -0700
Subject: [PATCH 1/8] Update clang/lib/CodeGen/CodeGenModule.cpp

Cleaner if checks.

Co-authored-by: Matt Arsenault <Matthew.Arsenault at amd.com>
---
 clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index e19bbee996f58..ff1586d2fa8ab 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2711,7 +2711,7 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
 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()))
+  if (!CodeGenOpts.CallGraphSection || !CB || !CB->isIndirectCall())
     return;
 
   auto *MD = CreateMetadataIdentifierGeneralized(QT);

>From 019b2ca5e1c263183ed114e0b967b4e77b4a17a8 Mon Sep 17 00:00:00 2001
From: Prabhuk <prabhukr at google.com>
Date: Mon, 22 Apr 2024 11:34:31 -0700
Subject: [PATCH 2/8] Update clang/lib/CodeGen/CodeGenModule.cpp

Update the comments as suggested.

Co-authored-by: Matt Arsenault <Matthew.Arsenault at amd.com>
---
 clang/lib/CodeGen/CodeGenModule.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index ff1586d2fa8ab..5635a87d2358a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2680,9 +2680,9 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
   bool EmittedMDIdGeneralized = false;
   if (CodeGenOpts.CallGraphSection &&
       (!F->hasLocalLinkage() ||
-       F->getFunction().hasAddressTaken(nullptr, /* IgnoreCallbackUses */ true,
-                                        /* IgnoreAssumeLikeCalls */ true,
-                                        /* IgnoreLLVMUsed */ false))) {
+       F->getFunction().hasAddressTaken(nullptr, /*IgnoreCallbackUses=*/ true,
+                                        /*IgnoreAssumeLikeCalls=*/ true,
+                                        /*IgnoreLLVMUsed=*/ false))) {
     F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType()));
     EmittedMDIdGeneralized = true;
   }

>From 99242900c51778abd4b7e7f4361b09202b7abcda Mon Sep 17 00:00:00 2001
From: Prabhuk <prabhukr at google.com>
Date: Mon, 29 Apr 2024 11:53:40 -0700
Subject: [PATCH 3/8] dyn_cast to isa

Created using spr 1.3.6-beta.1
---
 clang/lib/CodeGen/CGCall.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 526a63b24ff83..45033ced1d834 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5713,8 +5713,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
     if (callOrInvoke && *callOrInvoke && (*callOrInvoke)->isIndirectCall()) {
       if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
         // Type id metadata is set only for C/C++ contexts.
-        if (dyn_cast<CXXConstructorDecl>(FD) || dyn_cast<CXXMethodDecl>(FD) ||
-            dyn_cast<CXXDestructorDecl>(FD)) {
+        if (isa<CXXConstructorDecl>(FD) || isa<CXXMethodDecl>(FD) ||
+            isa<CXXDestructorDecl>(FD)) {
           CGM.CreateFunctionTypeMetadataForIcall(FD->getType(), *callOrInvoke);
         }
       }

>From 24882b15939b781bcf28d87fdf4f6e8834b6cfde Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Tue, 10 Dec 2024 14:54:27 -0800
Subject: [PATCH 4/8] Address review comments. Break llvm and clang patches.

Created using spr 1.3.6-beta.1
---
 llvm/lib/IR/Verifier.cpp              | 7 +++----
 llvm/test/Verifier/operand-bundles.ll | 4 ++--
 2 files changed, 5 insertions(+), 6 deletions(-)

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 4041391f30b43f836f36294489c1b1630d46fba2 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Sun, 2 Feb 2025 00:30:28 +0000
Subject: [PATCH 5/8] Address maybe unused comment

Created using spr 1.3.6-beta.1
---
 llvm/lib/IR/LLVMContext.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index 20b3008e4f071..23c5c9d79e3d4 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -97,10 +97,9 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
          "convergencectrl operand bundle id drifted!");
   (void)ConvergenceCtrlEntry;
 
-  auto *TypeEntry = pImpl->getOrInsertBundleTag("type");
+  [[maybe_unused]] auto *TypeEntry = pImpl->getOrInsertBundleTag("type");
   assert(TypeEntry->second == LLVMContext::OB_type &&
          "type operand bundle id drifted!");
-  (void)TypeEntry;
 
   SyncScope::ID SingleThreadSSID =
       pImpl->getOrInsertSyncScopeID("singlethread");

>From 995729bbbc19afa7da7121e9a37d2bfee300cf96 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 5 Feb 2025 23:07:01 +0000
Subject: [PATCH 6/8] Rename OB_type to OB_callee_type.

Created using spr 1.3.6-beta.1
---
 llvm/include/llvm/IR/LLVMContext.h                  |  2 +-
 .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp    |  7 ++++---
 llvm/lib/IR/LLVMContext.cpp                         |  6 +++---
 llvm/lib/IR/Verifier.cpp                            | 13 +++++++------
 llvm/test/Verifier/operand-bundles.ll               | 10 +++++-----
 5 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h
index a84d470e76d5d..97ff6b73f4473 100644
--- a/llvm/include/llvm/IR/LLVMContext.h
+++ b/llvm/include/llvm/IR/LLVMContext.h
@@ -96,7 +96,7 @@ class LLVMContext {
     OB_ptrauth = 7,                // "ptrauth"
     OB_kcfi = 8,                   // "kcfi"
     OB_convergencectrl = 9,        // "convergencectrl"
-    OB_type = 10,                  // "type"
+    OB_callee_type = 10,           // "callee_type"
   };
 
   /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 8d224bd55e1d2..a8b94afb7e002 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3333,7 +3333,8 @@ 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_type}) &&
+              LLVMContext::OB_clang_arc_attachedcall,
+              LLVMContext::OB_callee_type}) &&
          "Cannot lower invokes with arbitrary operand bundles yet!");
 
   const Value *Callee(I.getCalledOperand());
@@ -3424,7 +3425,7 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
   // have to do anything here to lower funclet bundles.
   assert(!I.hasOperandBundlesOtherThan({LLVMContext::OB_deopt,
                                         LLVMContext::OB_funclet,
-                                        LLVMContext::OB_type}) &&
+                                        LLVMContext::OB_callee_type}) &&
          "Cannot lower callbrs with arbitrary operand bundles yet!");
 
   assert(I.isInlineAsm() && "Only know how to handle inlineasm callbr");
@@ -9588,7 +9589,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_type}) &&
+              LLVMContext::OB_convergencectrl, LLVMContext::OB_callee_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 8ab7c37583361..18e95978bd9f6 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -82,9 +82,9 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
     assert(Entry->second == BundleTagID && "operand bundle id drifted!");
   }
 
-  [[maybe_unused]] auto *TypeEntry = pImpl->getOrInsertBundleTag("type");
-  assert(TypeEntry->second == LLVMContext::OB_type &&
-         "type 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");
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 19f7c3388bac6..34c751e6357c6 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3722,13 +3722,13 @@ void Verifier::visitCallBase(CallBase &Call) {
       visitIntrinsicCall(ID, Call);
 
   // Verify that a callsite has at most one operand bundle for each of the
-  // following: "deopt", "funclet", "gc-transition", "cfguardtarget", "type",
-  // "preallocated", and "ptrauth".
+  // following: "deopt", "funclet", "gc-transition", "cfguardtarget",
+  // "callee_type", "preallocated", and "ptrauth".
   bool FoundDeoptBundle = false, FoundFuncletBundle = false,
        FoundGCTransitionBundle = false, FoundCFGuardTargetBundle = false,
        FoundPreallocatedBundle = false, FoundGCLiveBundle = false,
        FoundPtrauthBundle = false, FoundKCFIBundle = false,
-       FoundAttachedCallBundle = false, FoundTypeBundle = false;
+       FoundAttachedCallBundle = false, FoundCalleeTypeBundle = false;
   for (unsigned i = 0, e = Call.getNumOperandBundles(); i < e; ++i) {
     OperandBundleUse BU = Call.getOperandBundleAt(i);
     uint32_t Tag = BU.getTagID();
@@ -3791,9 +3791,10 @@ 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;
+    } else if (Tag == LLVMContext::OB_callee_type) {
+      Check(!FoundCalleeTypeBundle, "Multiple \"callee_type\" operand bundles",
+            Call);
+      FoundCalleeTypeBundle = true;
     }
   }
 
diff --git a/llvm/test/Verifier/operand-bundles.ll b/llvm/test/Verifier/operand-bundles.ll
index 575cafad66279..79b5af35b353e 100644
--- a/llvm/test/Verifier/operand-bundles.ll
+++ b/llvm/test/Verifier/operand-bundles.ll
@@ -106,14 +106,14 @@ declare ptr @objc_unsafeClaimAutoreleasedReturnValue(ptr)
 declare void @llvm.assume(i1)
 
 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") ]
+; 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
-  call void @g() [ "type"(metadata !"_ZTSFvE.generalized"), "type"(metadata !"_ZTSFvE.generalized") ]
-  call void @g() [ "type"(metadata !"_ZTSFvE.generalized") ]
+  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
 }

>From 10c0327f91d35d57e9d2d609e326a3ca232b77d2 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 19 Mar 2025 02:53:43 +0000
Subject: [PATCH 7/8] Address review comments on the test file.

Created using spr 1.3.6-beta.1
---
 llvm/test/Verifier/operand-bundles.ll | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

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 27c970a092c3f18f6587cb63e66a0558f9437fed Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Sat, 19 Apr 2025 02:15:52 +0000
Subject: [PATCH 8/8] Remove callee_type operand bundle.

Created using spr 1.3.6-beta.1
---
 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 +++++++++++++++++++
 .../SelectionDAG/SelectionDAGBuilder.cpp      | 10 ++++-----
 llvm/lib/IR/LLVMContext.cpp                   |  4 ----
 llvm/lib/IR/Verifier.cpp                      | 12 ++++-------
 llvm/lib/Transforms/Utils/Local.cpp           |  5 +++++
 .../Bitcode/operand-bundles-bc-analyzer.ll    |  5 ++---
 llvm/test/Verifier/operand-bundles.ll         | 13 ------------
 10 files changed, 39 insertions(+), 35 deletions(-)

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/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 34c751e6357c6..8432779c107de 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3721,14 +3721,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,10 +3791,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);
-      FoundCalleeTypeBundle = true;
     }
   }
 
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/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!



More information about the llvm-branch-commits mailing list