https://github.com/Prabhuk updated https://github.com/llvm/llvm-project/pull/87573
>From a8a5848885e12c771f12cfa33b4dbc6a0272e925 Mon Sep 17 00:00:00 2001 From: Prabhuk <prabh...@google.com> Date: Mon, 22 Apr 2024 11:34:04 -0700 Subject: [PATCH 01/10] Update clang/lib/CodeGen/CodeGenModule.cpp Cleaner if checks. Co-authored-by: Matt Arsenault <matthew.arsena...@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 <prabh...@google.com> Date: Mon, 22 Apr 2024 11:34:31 -0700 Subject: [PATCH 02/10] Update clang/lib/CodeGen/CodeGenModule.cpp Update the comments as suggested. Co-authored-by: Matt Arsenault <matthew.arsena...@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 <prabh...@google.com> Date: Mon, 29 Apr 2024 11:53:40 -0700 Subject: [PATCH 03/10] 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 <prabh...@google.com> Date: Tue, 10 Dec 2024 14:54:27 -0800 Subject: [PATCH 04/10] 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 <prabh...@google.com> Date: Sun, 2 Feb 2025 00:30:28 +0000 Subject: [PATCH 05/10] 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 <prabh...@google.com> Date: Wed, 5 Feb 2025 23:07:01 +0000 Subject: [PATCH 06/10] 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 <prabh...@google.com> Date: Wed, 19 Mar 2025 02:53:43 +0000 Subject: [PATCH 07/10] 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 <prabh...@google.com> Date: Sat, 19 Apr 2025 02:15:52 +0000 Subject: [PATCH 08/10] 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 <prabh...@google.com> Date: Wed, 23 Apr 2025 01:01:47 +0000 Subject: [PATCH 09/10] 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 <prabh...@google.com> Date: Wed, 23 Apr 2025 03:52:07 +0000 Subject: [PATCH 10/10] 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); _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits