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/13] 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/13] 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/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 <prabh...@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 <prabh...@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 <prabh...@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 <prabh...@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 <prabh...@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 <prabh...@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 <prabh...@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 <prabh...@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 <prabh...@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 <prabh...@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"} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits