[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
Thu May 1 13:47:55 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 01/13] 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 02/13] 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 03/13] 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 04/13] 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 05/13] 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 06/13] 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 07/13] 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 08/13] 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!
>From 83c95a1f1e4a3448974e03f12b124e50981f3f9e Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 23 Apr 2025 01:01:47 +0000
Subject: [PATCH 09/13] Handle instcombine usecase for callee_type metadata.
Created using spr 1.3.6-beta.1
---
.../InstCombine/InstCombineCalls.cpp | 5 ++++
.../InstCombine/callee-type-metadata.ll | 25 +++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/callee-type-metadata.ll
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/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 fdf6a1c8b44b11bc3928b59cddbf88ac792fba1d Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 23 Apr 2025 03:52:07 +0000
Subject: [PATCH 10/13] Verifier changes.
Created using spr 1.3.6-beta.1
---
llvm/include/llvm/IR/Metadata.h | 6 ++++++
llvm/lib/IR/Verifier.cpp | 18 ++++++++++++++++++
2 files changed, 24 insertions(+)
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/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 8432779c107de..07de968b5dbfe 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);
@@ -5050,6 +5051,20 @@ 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());
+ Check(TypeMD->hasGeneralizedMDString(),
+ "Invalid \"callee_type\" type identifier", &I);
+ }
+}
+
void Verifier::visitAnnotationMetadata(MDNode *Annotation) {
Check(isa<MDTuple>(Annotation), "annotation must be a tuple");
Check(Annotation->getNumOperands() >= 1,
@@ -5325,6 +5340,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);
>From 4b32ce13a5d1ec10e8bcd77dae8ec90a1f05f494 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 23 Apr 2025 23:38:37 +0000
Subject: [PATCH 11/13] Update the test.
Created using spr 1.3.6-beta.1
---
.../InstCombine/callee-type-metadata.ll | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
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 11404d726fb5e64aed895e3a1ac23d8780c88d5f Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Thu, 24 Apr 2025 23:50:14 +0000
Subject: [PATCH 12/13] Add verifier test.
Created using spr 1.3.6-beta.1
---
llvm/lib/IR/Verifier.cpp | 5 +++-
llvm/test/Verifier/callee-type-metadata.ll | 28 ++++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Verifier/callee-type-metadata.ll
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 193551bb4e8f18d6bcb0469d9c7ce9fd1030e608 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Mon, 28 Apr 2025 22:48:33 +0000
Subject: [PATCH 13/13] Add inliner test. Fix instcombine test.
Created using spr 1.3.6-beta.1
---
llvm/lib/Transforms/Utils/ValueMapper.cpp | 7 +++++++
.../drop-callee-type-metadata.ll} | 7 +++----
.../InstCombine/drop-callee-type-metadata.ll | 19 +++++++++++++++++++
3 files changed, 29 insertions(+), 4 deletions(-)
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/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/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"}
More information about the llvm-branch-commits
mailing list