https://github.com/OCHyams created 
https://github.com/llvm/llvm-project/pull/144107

Patch 1/4 adding bitcode support.

Store whether or not a function is using Key Instructions in its DISubprogram 
so that we don't need to rely on the -mllvm flag -dwarf-use-key-instructions to 
determine whether or not to interpret Key Instructions metadata to decide 
is_stmt placement at DWARF emission time. This makes bitcode support simple and 
enables well defined mixing of non-key-instructions and key-instructions 
functions in an LTO context.

This patch adds the bit (using DISubprogram::SubclassData1).

#144104 and #144103 use it during DWARF emission.
#144102 adds bitcode support.

---

I explored an alternative - tracking a function-local nextAtomRank number in 
DISubprogram, allowing us the benefit of this patch and in addition letting us 
move away from the global LLVMContextImpl::NextAtomGroup. I discarded that 
approach as there were no substantial compile time or max-rss savings (despite 
allowing us to shrink atomGroup to 32-bits) and it added some weird 
complexities:
* The DISubprogram had to be updated frequently, which would mean be expensive 
in the normal "metadata is constant once created" model. There's precedent with 
edit-able fields for distinct-only DISubprograms with scopeLine, and this 
approach worked fine for nextAtomGroup, but it seems like a bit of a hack.
* The DILocation's subprogram isn't the one that tracks its nextAtomGroup, it's 
the subprogram the intsruction it's attached to is in (i.e., it's inlined-at 
scope if inlined). This meant to avoid inlined-at chain lookups DISubprogram 
has to get passed into functions like CloneBasicBlock, which is a bit weird.

>From 035414edf0fc80f5d69249f94f0dc39d9e1dda8f Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hy...@sony.com>
Date: Tue, 13 May 2025 17:01:34 +0100
Subject: [PATCH] [KeyInstr] Add DISubprogram::keyInstructions bit

Store whether or not a function is using Key Instructions in its DISubprogram so
that we don't need to rely on the -mllvm flag -dwarf-use-key-instructions to
determine whether or not to interpret Key Instructions metadata to decide
is_stmt placement at DWARF emission time. This makes bitcode support simple and
enables well defined mixing of non-key-instructions and key-instructions
functions in an LTO context.

This patch adds the bit (using DISubprogram::SubclassData1).
<link> uses it at DWARF emission.
<link> adds bitcode support.

---

I explored an alternative - tracking a function-local nextAtomRank number in
DISubprogram, allowing us the benefit of this patch and in addition letting us
move away from the global LLVMContextImpl::Context. I discarded that approach as
there were no substantial compile time or max-rss savings and it added some
weird complexities:
* The DISubprogram had to be updated frequently, which would mean no uniqing,
  i.e., only edit-able for distinct DISubprograms (though that does have
  precedent with scopeLine).
* The DILocation's subprogram isn't the one that tracks its nextAtomGroup, it's
  the subprogram the intsruction it's attached to is in (i.e., it's inlined-at
  scope if inlined). This meant to avoid inlined-at chain lookups DISubprogram
  has to get passed into functions like CloneBasicBlock, which is a bit weird.
---
 clang/lib/CodeGen/CGDebugInfo.cpp             | 18 +++--
 llvm/include/llvm/IR/DIBuilder.h              | 23 +++---
 llvm/include/llvm/IR/DebugInfoMetadata.h      | 30 +++++---
 llvm/lib/AsmParser/LLParser.cpp               |  5 +-
 llvm/lib/IR/AsmWriter.cpp                     |  1 +
 llvm/lib/IR/DIBuilder.cpp                     | 10 +--
 llvm/lib/IR/DebugInfoMetadata.cpp             | 15 ++--
 llvm/lib/IR/LLVMContextImpl.h                 | 18 +++--
 llvm/lib/IR/Verifier.cpp                      |  6 ++
 llvm/lib/Transforms/Utils/Debugify.cpp        |  4 +-
 .../KeyInstructions/Generic/inline-nodbg.ll   |  4 +-
 .../KeyInstructions/Generic/inline.ll         |  6 +-
 .../Generic/jump-threading-2-bbs.ll           |  3 +-
 .../Generic/jump-threading-basic.ll           |  3 +-
 ...-threading-dup-cond-br-on-phi-into-pred.ll |  3 +-
 .../KeyInstructions/Generic/loop-rotate.ll    |  3 +-
 .../Generic/loop-unroll-runtime.ll            |  3 +-
 .../KeyInstructions/Generic/loop-unroll.ll    |  2 +-
 .../KeyInstructions/Generic/loop-unswitch.ll  |  3 +-
 .../KeyInstructions/Generic/parse.ll          |  3 +-
 .../Generic/simplifycfg-branch-fold.ll        |  4 +-
 .../Generic/simplifycfg-thread-phi.ll         |  4 +-
 .../KeyInstructions/Generic/verify.ll         | 22 ++++++
 .../X86/cgp-break-critical-edge.ll            |  2 +-
 .../KeyInstructions/X86/dwarf-basic-ranks.ll  |  2 +-
 .../KeyInstructions/X86/dwarf-basic.ll        |  4 +-
 .../X86/dwarf-buoy-multi-key.mir              |  2 +-
 .../KeyInstructions/X86/dwarf-buoy.mir        |  2 +-
 .../KeyInstructions/X86/dwarf-calls.ll        |  2 +-
 .../KeyInstructions/X86/dwarf-ranks-blocks.ll |  2 +-
 .../DebugInfo/KeyInstructions/debugify.ll     |  3 +
 llvm/unittests/IR/BasicBlockDbgInfoTest.cpp   |  2 +-
 llvm/unittests/IR/MetadataTest.cpp            | 76 +++++++++++--------
 .../Transforms/Utils/CloningTest.cpp          |  4 +-
 34 files changed, 189 insertions(+), 105 deletions(-)
 create mode 100644 llvm/test/DebugInfo/KeyInstructions/Generic/verify.ll

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index ee5e3d68a5ffa..7b8b001d4921e 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1904,7 +1904,8 @@ CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
         /*ScopeLine=*/0,
         /*Flags=*/llvm::DINode::FlagArtificial,
         /*SPFlags=*/llvm::DISubprogram::SPFlagDefinition,
-        /*TParams=*/nullptr, /*ThrownTypes=*/nullptr, /*Annotations=*/nullptr);
+        /*TParams=*/nullptr, /*ThrownTypes=*/nullptr, /*Annotations=*/nullptr,
+        nullptr, StringRef(), CGM.getCodeGenOpts().DebugKeyInstructions);
   }
 
   return SP;
@@ -2284,7 +2285,8 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
   llvm::DISubprogram *SP = DBuilder.createMethod(
       RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
       MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
-      TParamsArray.get());
+      TParamsArray.get(), /*ThrownTypes*/ nullptr,
+      CGM.getCodeGenOpts().DebugKeyInstructions);
 
   SPCache[Method->getCanonicalDecl()].reset(SP);
 
@@ -4350,7 +4352,9 @@ llvm::DISubprogram 
*CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
     return DBuilder.createFunction(
         DContext, Name, LinkageName, Unit, Line,
         getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags,
-        TParamsArray.get(), getFunctionDeclaration(FD));
+        TParamsArray.get(), getFunctionDeclaration(FD), /*ThrownTypes*/ 
nullptr,
+        /*Annotations*/ nullptr, /*TargetFuncName*/ "",
+        CGM.getCodeGenOpts().DebugKeyInstructions);
   }
 
   llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
@@ -4686,8 +4690,9 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, 
SourceLocation Loc,
   llvm::DISubprogram *SP = DBuilder.createFunction(
       FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
       FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl, nullptr,
-      Annotations);
+      Annotations, "", CGM.getCodeGenOpts().DebugKeyInstructions);
   Fn->setSubprogram(SP);
+
   // We might get here with a VarDecl in the case we're generating
   // code for the initialization of globals. Do not record these decls
   // as they will overwrite the actual VarDecl Decl in the cache.
@@ -4746,9 +4751,12 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, 
SourceLocation Loc,
 
   llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
   llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
+  // Key Instructions: Don't set flag on declarations.
+  assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
   llvm::DISubprogram *SP = DBuilder.createFunction(
       FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
-      SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations);
+      SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations,
+      /*TargetFunctionName*/ "", /*UseKeyInstructions*/ false);
 
   // Preserve btf_decl_tag attributes for parameters of extern functions
   // for BPF target. The parameters created in this loop are attached as
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index 43fca571ee6d5..7d3e331a40184 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -894,6 +894,8 @@ namespace llvm {
     /// \param Annotations   Attribute Annotations.
     /// \param TargetFuncName The name of the target function if this is
     ///                       a trampoline.
+    /// \param UseKeyInstructions Instruct DWARF emission to interpret Key
+    /// Instructions metadata on instructions to determine is_stmt placement.
     LLVM_ABI DISubprogram *createFunction(
         DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
         unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,
@@ -901,7 +903,8 @@ namespace llvm {
         DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero,
         DITemplateParameterArray TParams = nullptr,
         DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr,
-        DINodeArray Annotations = nullptr, StringRef TargetFuncName = "");
+        DINodeArray Annotations = nullptr, StringRef TargetFuncName = "",
+        bool UseKeyInstructions = false);
 
     /// Identical to createFunction,
     /// except that the resulting DbgNode is meant to be RAUWed.
@@ -932,15 +935,15 @@ namespace llvm {
     /// \param SPFlags       Additional flags specific to subprograms.
     /// \param TParams       Function template parameters.
     /// \param ThrownTypes   Exception types this function may throw.
-    LLVM_ABI DISubprogram *
-    createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName,
-                 DIFile *File, unsigned LineNo, DISubroutineType *Ty,
-                 unsigned VTableIndex = 0, int ThisAdjustment = 0,
-                 DIType *VTableHolder = nullptr,
-                 DINode::DIFlags Flags = DINode::FlagZero,
-                 DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero,
-                 DITemplateParameterArray TParams = nullptr,
-                 DITypeArray ThrownTypes = nullptr);
+    /// \param UseKeyInstructions Enable Key Instructions debug info.
+    LLVM_ABI DISubprogram *createMethod(
+        DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
+        unsigned LineNo, DISubroutineType *Ty, unsigned VTableIndex = 0,
+        int ThisAdjustment = 0, DIType *VTableHolder = nullptr,
+        DINode::DIFlags Flags = DINode::FlagZero,
+        DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero,
+        DITemplateParameterArray TParams = nullptr,
+        DITypeArray ThrownTypes = nullptr, bool UseKeyInstructions = false);
 
     /// Create common block entry for a Fortran common block.
     /// \param Scope       Scope of this common block.
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h 
b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 18228b7757897..42bbb0b1d1ee2 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -1962,7 +1962,7 @@ class DILocalScope : public DIScope {
   }
 };
 
-/// Subprogram description.
+/// Subprogram description. Uses SubclassData1.
 class DISubprogram : public DILocalScope {
   friend class LLVMContextImpl;
   friend class MDNode;
@@ -2009,7 +2009,8 @@ class DISubprogram : public DILocalScope {
 
   DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
                unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
-               DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops);
+               DIFlags Flags, DISPFlags SPFlags, bool UsesKeyInstructions,
+               ArrayRef<Metadata *> Ops);
   ~DISubprogram() = default;
 
   static DISubprogram *
@@ -2021,15 +2022,17 @@ class DISubprogram : public DILocalScope {
           DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
           DINodeArray RetainedNodes, DITypeArray ThrownTypes,
           DINodeArray Annotations, StringRef TargetFuncName,
-          StorageType Storage, bool ShouldCreate = true) {
+          bool UsesKeyInstructions, StorageType Storage,
+          bool ShouldCreate = true) {
     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
                    getCanonicalMDString(Context, LinkageName), File, Line, 
Type,
                    ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
                    Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
                    RetainedNodes.get(), ThrownTypes.get(), Annotations.get(),
                    getCanonicalMDString(Context, TargetFuncName),
-                   Storage, ShouldCreate);
+                   UsesKeyInstructions, Storage, ShouldCreate);
   }
+
   LLVM_ABI static DISubprogram *
   getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
           MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
@@ -2037,8 +2040,8 @@ class DISubprogram : public DILocalScope {
           int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
           Metadata *TemplateParams, Metadata *Declaration,
           Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata 
*Annotations,
-          MDString *TargetFuncName, StorageType Storage,
-          bool ShouldCreate = true);
+          MDString *TargetFuncName, bool UsesKeyInstructions,
+          StorageType Storage, bool ShouldCreate = true);
 
   TempDISubprogram cloneImpl() const {
     return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
@@ -2047,7 +2050,7 @@ class DISubprogram : public DILocalScope {
                         getThisAdjustment(), getFlags(), getSPFlags(),
                         getUnit(), getTemplateParams(), getDeclaration(),
                         getRetainedNodes(), getThrownTypes(), getAnnotations(),
-                        getTargetFuncName());
+                        getTargetFuncName(), getKeyInstructionsEnabled());
   }
 
 public:
@@ -2060,10 +2063,11 @@ class DISubprogram : public DILocalScope {
        DITemplateParameterArray TemplateParams = nullptr,
        DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = 
nullptr,
        DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr,
-       StringRef TargetFuncName = ""),
+       StringRef TargetFuncName = "", bool UsesKeyInstructions = false),
       (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
        VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
-       Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName))
+       Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName,
+       UsesKeyInstructions))
 
   DEFINE_MDNODE_GET(
       DISubprogram,
@@ -2073,10 +2077,12 @@ class DISubprogram : public DILocalScope {
        DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
        Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
        Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr,
-       Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr),
+       Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr,
+       bool UsesKeyInstructions = false),
       (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
        VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
-       Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName))
+       Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName,
+       UsesKeyInstructions))
 
   TempDISubprogram clone() const { return cloneImpl(); }
 
@@ -2087,6 +2093,8 @@ class DISubprogram : public DILocalScope {
     return NewSP;
   }
 
+  bool getKeyInstructionsEnabled() const { return SubclassData1; }
+
 public:
   unsigned getLine() const { return Line; }
   unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 926dc6211eb8d..6f19711669743 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -5821,7 +5821,8 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool 
IsDistinct) {
   OPTIONAL(retainedNodes, MDField, );                                          
\
   OPTIONAL(thrownTypes, MDField, );                                            
\
   OPTIONAL(annotations, MDField, );                                            
\
-  OPTIONAL(targetFuncName, MDStringField, );
+  OPTIONAL(targetFuncName, MDStringField, );                                   
\
+  OPTIONAL(keyInstructions, MDBoolField, );
   PARSE_MD_FIELDS();
 #undef VISIT_MD_FIELDS
 
@@ -5841,7 +5842,7 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool 
IsDistinct) {
        type.Val, scopeLine.Val, containingType.Val, virtualIndex.Val,
        thisAdjustment.Val, flags.Val, SPFlags, unit.Val, templateParams.Val,
        declaration.Val, retainedNodes.Val, thrownTypes.Val, annotations.Val,
-       targetFuncName.Val));
+       targetFuncName.Val, keyInstructions.Val));
   return false;
 }
 
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 7828ba45ec27f..ff45afe399c82 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2459,6 +2459,7 @@ static void writeDISubprogram(raw_ostream &Out, const 
DISubprogram *N,
   Printer.printMetadata("thrownTypes", N->getRawThrownTypes());
   Printer.printMetadata("annotations", N->getRawAnnotations());
   Printer.printString("targetFuncName", N->getTargetFuncName());
+  Printer.printBool("keyInstructions", N->getKeyInstructionsEnabled(), false);
   Out << ")";
 }
 
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index fd8c2d7bb5cc3..367c52271c5a1 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -933,14 +933,14 @@ DISubprogram *DIBuilder::createFunction(
     unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,
     DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags,
     DITemplateParameterArray TParams, DISubprogram *Decl,
-    DITypeArray ThrownTypes, DINodeArray Annotations,
-    StringRef TargetFuncName) {
+    DITypeArray ThrownTypes, DINodeArray Annotations, StringRef TargetFuncName,
+    bool UseKeyInstructions) {
   bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;
   auto *Node = getSubprogram(
       /*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context),
       Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags,
       SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, nullptr,
-      ThrownTypes, Annotations, TargetFuncName);
+      ThrownTypes, Annotations, TargetFuncName, UseKeyInstructions);
 
   AllSubprograms.push_back(Node);
   trackIfUnresolved(Node);
@@ -967,7 +967,7 @@ DISubprogram *DIBuilder::createMethod(
     unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment,
     DIType *VTableHolder, DINode::DIFlags Flags,
     DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams,
-    DITypeArray ThrownTypes) {
+    DITypeArray ThrownTypes, bool UseKeyInstructions) {
   assert(getNonCompileUnitScope(Context) &&
          "Methods should have both a Context and a context that isn't "
          "the compile unit.");
@@ -977,7 +977,7 @@ DISubprogram *DIBuilder::createMethod(
       /*IsDistinct=*/IsDefinition, VMContext, cast<DIScope>(Context), Name,
       LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment,
       Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr,
-      nullptr, ThrownTypes);
+      nullptr, ThrownTypes, nullptr, "", IsDefinition && UseKeyInstructions);
 
   AllSubprograms.push_back(SP);
   trackIfUnresolved(SP);
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp 
b/llvm/lib/IR/DebugInfoMetadata.cpp
index 473114b99225b..ec62756bc0366 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1293,11 +1293,12 @@ const char 
*DICompileUnit::nameTableKindString(DebugNameTableKind NTK) {
 DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
                            unsigned ScopeLine, unsigned VirtualIndex,
                            int ThisAdjustment, DIFlags Flags, DISPFlags 
SPFlags,
-                           ArrayRef<Metadata *> Ops)
+                           bool UsesKeyInstructions, ArrayRef<Metadata *> Ops)
     : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, 
Ops),
       Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
       ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
   static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
+  SubclassData1 = UsesKeyInstructions;
 }
 DISubprogram::DISPFlags
 DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool 
IsOptimized,
@@ -1396,7 +1397,7 @@ DISubprogram *DISubprogram::getImpl(
     int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
     Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
     Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName,
-    StorageType Storage, bool ShouldCreate) {
+    bool UsesKeyInstructions, StorageType Storage, bool ShouldCreate) {
   assert(isCanonical(Name) && "Expected canonical MDString");
   assert(isCanonical(LinkageName) && "Expected canonical MDString");
   assert(isCanonical(TargetFuncName) && "Expected canonical MDString");
@@ -1405,7 +1406,7 @@ DISubprogram *DISubprogram::getImpl(
                          ContainingType, VirtualIndex, ThisAdjustment, Flags,
                          SPFlags, Unit, TemplateParams, Declaration,
                          RetainedNodes, ThrownTypes, Annotations,
-                         TargetFuncName));
+                         TargetFuncName, UsesKeyInstructions));
   SmallVector<Metadata *, 13> Ops = {
       File,           Scope,          Name,        LinkageName,
       Type,           Unit,           Declaration, RetainedNodes,
@@ -1425,10 +1426,10 @@ DISubprogram *DISubprogram::getImpl(
       }
     }
   }
-  DEFINE_GETIMPL_STORE_N(
-      DISubprogram,
-      (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops,
-      Ops.size());
+  DEFINE_GETIMPL_STORE_N(DISubprogram,
+                         (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags,
+                          SPFlags, UsesKeyInstructions),
+                         Ops, Ops.size());
 }
 
 bool DISubprogram::describes(const Function *F) const {
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index ef279721b9643..ac90363b9e4b1 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -922,8 +922,8 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
   MDString *LinkageName;
   Metadata *File;
   unsigned Line;
-  Metadata *Type;
   unsigned ScopeLine;
+  Metadata *Type;
   Metadata *ContainingType;
   unsigned VirtualIndex;
   int ThisAdjustment;
@@ -936,6 +936,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
   Metadata *ThrownTypes;
   Metadata *Annotations;
   MDString *TargetFuncName;
+  bool UsesKeyInstructions;
 
   MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
                 Metadata *File, unsigned Line, Metadata *Type,
@@ -944,18 +945,19 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
                 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
                 Metadata *Declaration, Metadata *RetainedNodes,
                 Metadata *ThrownTypes, Metadata *Annotations,
-                MDString *TargetFuncName)
+                MDString *TargetFuncName, bool UsesKeyInstructions)
       : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
-        Line(Line), Type(Type), ScopeLine(ScopeLine),
+        Line(Line), ScopeLine(ScopeLine), Type(Type),
         ContainingType(ContainingType), VirtualIndex(VirtualIndex),
         ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
         Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
         RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
-        Annotations(Annotations), TargetFuncName(TargetFuncName) {}
+        Annotations(Annotations), TargetFuncName(TargetFuncName),
+        UsesKeyInstructions(UsesKeyInstructions) {}
   MDNodeKeyImpl(const DISubprogram *N)
       : Scope(N->getRawScope()), Name(N->getRawName()),
         LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
-        Line(N->getLine()), Type(N->getRawType()), 
ScopeLine(N->getScopeLine()),
+        Line(N->getLine()), ScopeLine(N->getScopeLine()), 
Type(N->getRawType()),
         ContainingType(N->getRawContainingType()),
         VirtualIndex(N->getVirtualIndex()),
         ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
@@ -965,7 +967,8 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
         RetainedNodes(N->getRawRetainedNodes()),
         ThrownTypes(N->getRawThrownTypes()),
         Annotations(N->getRawAnnotations()),
-        TargetFuncName(N->getRawTargetFuncName()) {}
+        TargetFuncName(N->getRawTargetFuncName()),
+        UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
 
   bool isKeyOf(const DISubprogram *RHS) const {
     return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
@@ -982,7 +985,8 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
            RetainedNodes == RHS->getRawRetainedNodes() &&
            ThrownTypes == RHS->getRawThrownTypes() &&
            Annotations == RHS->getRawAnnotations() &&
-           TargetFuncName == RHS->getRawTargetFuncName();
+           TargetFuncName == RHS->getRawTargetFuncName() &&
+           UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
   }
 
   bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; 
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 1f1041b259736..b044316f18233 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3160,6 +3160,12 @@ void Verifier::visitFunction(const Function &F) {
     CheckDI(SP->describes(&F),
             "!dbg attachment points at wrong subprogram for function", N, &F,
             &I, DL, Scope, SP);
+
+    if (DL->getAtomGroup())
+      CheckDI(DL->getScope()->getSubprogram()->getKeyInstructionsEnabled(),
+              "DbgLoc uses atomGroup but DISubprogram doesn't have Key "
+              "Instructions enabled",
+              DL, DL->getScope()->getSubprogram());
   };
   for (auto &BB : F)
     for (auto &I : BB) {
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp 
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..67aa41de82d59 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -123,7 +123,9 @@ bool llvm::applyDebugifyMetadata(
     if (F.hasPrivateLinkage() || F.hasInternalLinkage())
       SPFlags |= DISubprogram::SPFlagLocalToUnit;
     auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine,
-                                 SPType, NextLine, DINode::FlagZero, SPFlags);
+                                 SPType, NextLine, DINode::FlagZero, SPFlags,
+                                 nullptr, nullptr, nullptr, nullptr, "",
+                                 /*UseKeyInstructions*/ ApplyAtomGroups);
     F.setSubprogram(SP);
 
     // Helper that inserts a dbg.value before \p InsertBefore, copying the
diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/inline-nodbg.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/inline-nodbg.ll
index 33f7f673d91c3..125ce16927582 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/inline-nodbg.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/inline-nodbg.ll
@@ -11,6 +11,8 @@
 
 ; CHECK: _Z1bv()
 ; CHECK: store i32 1, ptr @g, align 4, !dbg [[DBG:!.*]]
+
+; CHECK: distinct !DISubprogram(name: "b", {{.*}}keyInstructions: true)
 ; CHECK: [[DBG]] = !DILocation(line: 3, scope: ![[#]])
 
 @g = hidden global i32 0, align 4
@@ -36,7 +38,7 @@ entry:
 !2 = !{i32 7, !"Dwarf Version", i32 5}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !10 = !{!"clang version 19.0.0"}
-!15 = distinct !DISubprogram(name: "b", scope: !1, file: !1, line: 3, type: 
!16, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!15 = distinct !DISubprogram(name: "b", scope: !1, file: !1, line: 3, type: 
!16, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
 !16 = !DISubroutineType(types: !17)
 !17 = !{}
 !18 = !DILocation(line: 3, scope: !15, atomGroup: 1, atomRank: 1)
diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll
index b9b6abdd1e9c0..0d5cc6d4a44de 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/inline.ll
@@ -8,6 +8,7 @@
 ; CHECK: %add.i = add nsw i32 %mul.i, 1, !dbg [[G1R2:!.*]]
 ; CHECK-NEXT: store i32 %add.i, ptr %x.i, align 4, !dbg [[G1R1:!.*]]
 
+; CHECK: distinct !DISubprogram(name: "g", {{.*}}keyInstructions: true)
 ; CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
 ; CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
 
@@ -41,11 +42,10 @@ entry:
 !2 = !{i32 7, !"Dwarf Version", i32 5}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !10 = !{!"clang version 19.0.0"}
-!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
 !12 = !DISubroutineType(types: !13)
 !13 = !{}
 !19 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 2)
 !20 = !DILocation(line: 2, scope: !11, atomGroup: 1, atomRank: 1)
-!23 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 4, type: 
!12, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!23 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 4, type: 
!12, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
 !24 = !DILocation(line: 5, scope: !23)
-
diff --git 
a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-2-bbs.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-2-bbs.ll
index 612e74792fac2..175272e4e8bb6 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-2-bbs.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-2-bbs.ll
@@ -27,6 +27,7 @@
 ; CHECK: bb.f2:
 ; CHECK-NEXT: store ptr @a, ptr %p, align 4, !dbg [[G4R1:!.*]]
 
+; CHECK: distinct !DISubprogram(name: "foo", {{.*}}keyInstructions: true)
 ; CHECK: [[G1R2]] = !DILocation(line: 1, column: 1, scope: ![[#]], atomGroup: 
1, atomRank: 2)
 ; CHECK: [[G1R1]] = !DILocation(line: 1, column: 1, scope: ![[#]], atomGroup: 
1, atomRank: 1)
 ; CHECK: [[G3R2]] = !DILocation(line: 1, column: 1, scope: ![[#]], atomGroup: 
3, atomRank: 2)
@@ -76,7 +77,7 @@ declare void @f2()
 !2 = !{i32 16}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0)
+!5 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
 !9 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 2)
diff --git 
a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-basic.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-basic.ll
index 1541df3469087..f285ebbdfda31 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-basic.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-basic.ll
@@ -26,6 +26,7 @@
 ; CHECK-NEXT: %C = add i32 %v2, 1, !dbg [[G1R2:!.*]]
 ; CHECK-NEXT: store i32 %C, ptr %p, align 4, !dbg [[G1R1:!.*]]
 
+; CHECK: distinct !DISubprogram(name: "test1", {{.*}}keyInstructions: true)
 ; CHECK: [[G2R2]] = !DILocation(line: 8, column: 1, scope: ![[#]], atomGroup: 
2, atomRank: 2)
 ; CHECK: [[G2R1]] = !DILocation(line: 8, column: 1, scope: ![[#]], atomGroup: 
2, atomRank: 1)
 ; CHECK: [[G1R2]] = !DILocation(line: 8, column: 1, scope: ![[#]], atomGroup: 
1, atomRank: 2)
@@ -70,7 +71,7 @@ declare void @f3()
 !2 = !{i32 12}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: "test1", linkageName: "test1", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0)
+!5 = distinct !DISubprogram(name: "test1", linkageName: "test1", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
 !8 = !DILocation(line: 8, column: 1, scope: !5, atomGroup: 1, atomRank: 2)
diff --git 
a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-dup-cond-br-on-phi-into-pred.ll
 
b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-dup-cond-br-on-phi-into-pred.ll
index 1ab1c1ac2e9f6..a8a34d0698944 100644
--- 
a/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-dup-cond-br-on-phi-into-pred.ll
+++ 
b/llvm/test/DebugInfo/KeyInstructions/Generic/jump-threading-dup-cond-br-on-phi-into-pred.ll
@@ -30,6 +30,7 @@
 ; CHECK-NEXT: %C = add i32 %v2, 1, !dbg [[G2R2:!.*]]
 ; CHECK-NEXT: store i32 %C, ptr %p, align 4, !dbg [[G2R1:!.*]]
 
+; CHECK: distinct !DISubprogram(name: "test5", {{.*}}keyInstructions: true)
 ; CHECK: [[G3R2]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 2)
 ; CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
 ; CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
@@ -79,7 +80,7 @@ declare void @f3()
 !2 = !{i32 12}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: "test5", linkageName: "test5", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0)
+!5 = distinct !DISubprogram(name: "test5", linkageName: "test5", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
 !8 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1)
diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-rotate.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-rotate.ll
index 6da7146b5b07a..0ea0453c4a6c4 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-rotate.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-rotate.ll
@@ -25,6 +25,7 @@
 ; CHECK:    [[CMP:%.*]] = icmp slt i32 {{.*}}, 100, !dbg [[G2R2:![0-9]+]]
 ; CHECK:    br i1 [[CMP]], label %for.body, label %for.end, !dbg 
[[G2R1:![0-9]+]]
 ;
+; CHECK: distinct !DISubprogram(name: "test1", {{.*}}keyInstructions: true)
 ; CHECK: [[G3R1]] = !DILocation(line: 4{{.*}}, atomGroup: 3, atomRank: 1)
 ; CHECK: [[G4R1]] = !DILocation(line: 6{{.*}}, atomGroup: 4, atomRank: 1)
 ; CHECK: [[G1R1]] = !DILocation(line: 4{{.*}}, atomGroup: 1, atomRank: 1)
@@ -69,6 +70,6 @@ attributes #1 = { noduplicate }
 !2 = !{i32 12}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: "test1", linkageName: "test1", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0)
+!5 = distinct !DISubprogram(name: "test1", linkageName: "test1", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll-runtime.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll-runtime.ll
index 6deb04cc00f8d..d23afaed9a047 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll-runtime.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll-runtime.ll
@@ -25,6 +25,7 @@
 ; CHECK-NEXT: store i64 %indvars.iv.next.2, ptr %p, align 4, !dbg [[G7R1:!.*]]
 ; CHECK-NEXT: %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
 
+; CHECK: distinct !DISubprogram(name: "unroll", {{.*}}keyInstructions: true)
 ; CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
 ; CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
 ; CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
@@ -63,7 +64,7 @@ for.body:                                         ; preds = 
%for.body, %for.body
 !2 = !{i32 17}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: "unroll", linkageName: "unroll", scope: 
null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0)
+!5 = distinct !DISubprogram(name: "unroll", linkageName: "unroll", scope: 
null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
 !8 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1)
diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll.ll
index 557e8387e5bc5..3b13bde8bfb3f 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unroll.ll
@@ -41,7 +41,7 @@ attributes #0 = { nounwind ssp uwtable }
 !2 = !{i32 8}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: 
!1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0)
+!5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: 
!1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
 !11 = !DILocation(line: 4, column: 1, scope: !5, atomGroup: 1, atomRank: 2)
diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unswitch.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unswitch.ll
index 557950439ef3b..fee7e845d4df9 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unswitch.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/loop-unswitch.ll
@@ -125,7 +125,7 @@ declare void @clobber()
 !2 = !{i32 13}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: 
"partial_unswitch_true_successor_hoist_invariant", linkageName: 
"partial_unswitch_true_successor_hoist_invariant", scope: null, file: !1, line: 
1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, 
unit: !0)
+!5 = distinct !DISubprogram(name: 
"partial_unswitch_true_successor_hoist_invariant", linkageName: 
"partial_unswitch_true_successor_hoist_invariant", scope: null, file: !1, line: 
1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, 
unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
 !8 = !DILocation(line: 1, scope: !5, atomGroup: 1, atomRank: 1)
@@ -142,6 +142,7 @@ declare void @clobber()
 !19 = !DILocation(line: 12, scope: !5, atomGroup: 12, atomRank: 1)
 !20 = !DILocation(line: 13, scope: !5, atomGroup: 13, atomRank: 1)
 ;.
+; CHECK: distinct !DISubprogram(name: 
"partial_unswitch_true_successor_hoist_invariant", {{.*}}keyInstructions: true)
 ; CHECK: [[DBG8]] = !DILocation(line: 3{{.*}}, atomGroup: 24, atomRank: 1)
 ; CHECK: [[DBG9]] = !DILocation(line: 4{{.*}}, atomGroup: 25, atomRank: 1)
 ; CHECK: [[DBG10]] = !DILocation(line: 5{{.*}}, atomGroup: 26, atomRank: 1)
diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/parse.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/parse.ll
index 33219a582fee8..79f7a7d79610c 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/parse.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/parse.ll
@@ -1,5 +1,6 @@
 ; RUN: opt %s -o - -S| FileCheck %s
 
+; CHECK: distinct !DISubprogram(name: "f", {{.*}}keyInstructions: true)
 ; CHECK: !DILocation(line: 1, column: 11, scope: ![[#]], atomGroup: 1, 
atomRank: 1)
 
 define dso_local void @f() !dbg !10 {
@@ -13,7 +14,7 @@ entry:
 !1 = !DIFile(filename: "test.cpp", directory: "/")
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !9 = !{!"clang version 21.0.0git"}
-!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: 
!0)
+!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: 
!0, keyInstructions: true)
 !11 = !DISubroutineType(types: !12)
 !12 = !{null}
 !13 = !DILocation(line: 1, column: 11, scope: !10, atomGroup: 1, atomRank: 1)
diff --git 
a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll
index 75a05ad931707..3ad956cabdb2d 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-branch-fold.ll
@@ -70,7 +70,7 @@ f:
 !4 = !{i32 0}
 !5 = !{i32 2, !"Debug Info Version", i32 3}
 !7 = !DISubroutineType(types: !2)
-!17 = distinct !DISubprogram(name: "f", scope: null, file: !1, line: 1, type: 
!7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, 
retainedNodes: !2)
+!17 = distinct !DISubprogram(name: "f", scope: null, file: !1, line: 1, type: 
!7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, 
retainedNodes: !2, keyInstructions: true)
 !18 = !DILocation(line: 10, column: 10, scope: !17)
 !19 = !DILocation(line: 10, column: 10, scope: !17, atomGroup: 1, atomRank: 2)
 !20 = !DILocation(line: 10, column: 10, scope: !17, atomGroup: 2, atomRank: 2)
@@ -79,7 +79,7 @@ f:
 ; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, 
file: [[META1:![0-9]+]], producer: "debugify", isOptimized: true, 
runtimeVersion: 0, emissionKind: FullDebug, enums: [[META2:![0-9]+]])
 ; CHECK: [[META1]] = !DIFile(filename: "a.ll", directory: {{.*}})
 ; CHECK: [[META2]] = !{}
-; CHECK: [[DBG6]] = distinct !DISubprogram(name: "f", scope: null, file: 
[[META1]], line: 1, type: [[META7:![0-9]+]], scopeLine: 1, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: 
[[META2]])
+; CHECK: [[DBG6]] = distinct !DISubprogram(name: "f", scope: null, file: 
[[META1]], line: 1, type: [[META7:![0-9]+]], scopeLine: 1, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: 
[[META2]], keyInstructions: true)
 ; CHECK: [[META7]] = !DISubroutineType(types: [[META2]])
 ; CHECK: [[DBG8]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], 
atomGroup: 5, atomRank: 2)
 ; CHECK: [[DBG9]] = !DILocation(line: 10, column: 10, scope: [[DBG6]], 
atomGroup: 6, atomRank: 2)
diff --git 
a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-thread-phi.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-thread-phi.ll
index f8477600c6418..774c637e3b831 100644
--- a/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-thread-phi.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/simplifycfg-thread-phi.ll
@@ -13,6 +13,8 @@
 ; CHECK:   store i32 1{{.*}}, !dbg [[DBG1:!.*]]
 ; CHECK: if.end.1.critedge:
 ; CHECK:   store i32 1{{.*}}, !dbg [[DBG2:!.*]]
+;
+; CHECK: distinct !DISubprogram(name: "bar", {{.*}}keyInstructions: true)
 ; CHECK: [[DBG1]] = !DILocation(line: 1{{.*}}, atomGroup: 1
 ; CHECK: [[DBG2]] = !DILocation(line: 1{{.*}}, atomGroup: 2
 
@@ -56,7 +58,7 @@ declare void @foo()
 !2 = !{i32 15}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: "bar", linkageName: "bar", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0)
+!5 = distinct !DISubprogram(name: "bar", linkageName: "bar", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
 !8 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1)
diff --git a/llvm/test/DebugInfo/KeyInstructions/Generic/verify.ll 
b/llvm/test/DebugInfo/KeyInstructions/Generic/verify.ll
new file mode 100644
index 0000000000000..0f8f505c51a58
--- /dev/null
+++ b/llvm/test/DebugInfo/KeyInstructions/Generic/verify.ll
@@ -0,0 +1,22 @@
+; RUN: opt %s -o - -S --passes=verify 2>&1 | FileCheck %s
+
+; CHECK: DbgLoc uses atomGroup but DISubprogram doesn't have Key Instructions 
enabled
+; CHECK-NEXT: ![[#]] = !DILocation(line: 1, column: 11, scope: ![[f:.*]], 
atomGroup: 1, atomRank: 1)
+; CHECK-NEXT: ![[f]] = distinct !DISubprogram(name: "f"
+; CHECK-NEXT: warning: ignoring invalid debug info
+
+define dso_local void @f() !dbg !10 {
+entry:
+  ret void, !dbg !13
+}
+
+!llvm.module.flags = !{!3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, 
producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, 
emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.cpp", directory: "/")
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{!"clang version 21.0.0git"}
+!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: 
!0)
+!11 = !DISubroutineType(types: !12)
+!12 = !{null}
+!13 = !DILocation(line: 1, column: 11, scope: !10, atomGroup: 1, atomRank: 1)
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/cgp-break-critical-edge.ll 
b/llvm/test/DebugInfo/KeyInstructions/X86/cgp-break-critical-edge.ll
index a21b1da15a45d..dcacd96e69a17 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/cgp-break-critical-edge.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/cgp-break-critical-edge.ll
@@ -46,7 +46,7 @@ if.else1:                                         ; preds = 
%if.else1, %preheade
 !2 = !{i32 11}
 !3 = !{i32 0}
 !4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = distinct !DISubprogram(name: "test", linkageName: "test", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0)
+!5 = distinct !DISubprogram(name: "test", linkageName: "test", scope: null, 
file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | 
DISPFlagOptimized, unit: !0, keyInstructions: true)
 !6 = !DISubroutineType(types: !7)
 !7 = !{}
 !12 = !DILocation(line: 1, column: 1, scope: !5, atomGroup: 1, atomRank: 1)
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic-ranks.ll 
b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic-ranks.ll
index 6988a6fb2ec3f..154bb872684f0 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic-ranks.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic-ranks.ll
@@ -64,6 +64,6 @@ declare void @_Z12prologue_endv() local_unnamed_addr #1
 !2 = !{i32 7, !"Dwarf Version", i32 5}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !10 = !{!"clang version 19.0.0"}
-!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: 
!12, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: 
!12, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
 !12 = !DISubroutineType(types: !13)
 !13 = !{}
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll 
b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll
index ba38bb2ffe903..b97b436ffc573 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll
@@ -55,8 +55,8 @@ entry:
 !2 = !{i32 7, !"Dwarf Version", i32 5}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !10 = !{!"clang version 19.0.0"}
-!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
 !12 = !DISubroutineType(types: !13)
 !13 = !{}
-!16 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 5, type: 
!12, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!16 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 5, type: 
!12, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
 !18 = distinct !DILocation(line: 6, scope: !16)
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy-multi-key.mir 
b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy-multi-key.mir
index 3b7d5850e7e83..abe27e9870cda 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy-multi-key.mir
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy-multi-key.mir
@@ -48,7 +48,7 @@
   !2 = !{i32 7, !"Dwarf Version", i32 5}
   !3 = !{i32 2, !"Debug Info Version", i32 3}
   !4 = !{!"clang version 19.0.0"}
-  !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+  !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
   !6 = !DISubroutineType(types: !7)
   !7 = !{}
   !8 = !DILocalVariable(name: "x", scope: !5, file: !1, line: 1, type: !7)
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy.mir 
b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy.mir
index 3aff5e22326ec..222604493cc8f 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy.mir
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-buoy.mir
@@ -44,7 +44,7 @@
   !2 = !{i32 7, !"Dwarf Version", i32 5}
   !3 = !{i32 2, !"Debug Info Version", i32 3}
   !4 = !{!"clang version 19.0.0"}
-  !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+  !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
   !6 = !DISubroutineType(types: !7)
   !7 = !{}
   !8 = !DILocalVariable(name: "x", scope: !5, file: !1, line: 1, type: !7)
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-calls.ll 
b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-calls.ll
index 14dfa8a6a9ccb..72fc4db6402a0 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-calls.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-calls.ll
@@ -109,6 +109,6 @@ declare i32  @g() local_unnamed_addr
 !2 = !{i32 7, !"Dwarf Version", i32 5}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !10 = !{!"clang version 19.0.0"}
-!11 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: 
!12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!11 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: 
!12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
 !12 = !DISubroutineType(types: !13)
 !13 = !{}
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-ranks-blocks.ll 
b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-ranks-blocks.ll
index cd840ecce07f5..e9067e4489426 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-ranks-blocks.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-ranks-blocks.ll
@@ -60,6 +60,6 @@ declare void @_Z12prologue_endv() local_unnamed_addr #1
 !2 = !{i32 7, !"Dwarf Version", i32 5}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !10 = !{!"clang version 19.0.0"}
-!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!11 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: 
!12, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: 
DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
 !12 = !DISubroutineType(types: !13)
 !13 = !{}
diff --git a/llvm/test/DebugInfo/KeyInstructions/debugify.ll 
b/llvm/test/DebugInfo/KeyInstructions/debugify.ll
index 881375873f324..551ae2794c2f3 100644
--- a/llvm/test/DebugInfo/KeyInstructions/debugify.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/debugify.ll
@@ -38,9 +38,12 @@ define i32 @boom() {
   ret i32 %retval
 }
 
+; CHECK: distinct !DISubprogram(name: "foo", {{.*}}keyInstructions: true)
 ; CHECK-DAG: ![[RET1]] = !DILocation(line: 1, {{.*}}, atomGroup: 1, atomRank: 1
+; CHECK: distinct !DISubprogram(name: "bar", {{.*}}keyInstructions: true)
 ; CHECK-DAG: ![[CALL1]] = !DILocation(line: 2, {{.*}}, atomGroup: 2, atomRank: 
1
 ; CHECK-DAG: ![[ADD1]] = !DILocation(line: 3, {{.*}}, atomGroup: 3, atomRank: 1
 ; CHECK-DAG: ![[RET2]] = !DILocation(line: 4, {{.*}}, atomGroup: 4, atomRank: 1
+; CHECK: distinct !DISubprogram(name: "boom", {{.*}}keyInstructions: true)
 ; CHECK-DAG: ![[musttail]] = !DILocation(line: 5, {{.*}}, atomGroup: 5, 
atomRank: 1
 ; CHECK-DAG: ![[musttailRes]] = !DILocation(line: 6, {{.*}}, atomGroup: 6, 
atomRank: 1
diff --git a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp 
b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
index cb1a56a26f063..aac0f96845f2f 100644
--- a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
+++ b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
@@ -164,7 +164,7 @@ TEST(BasicBlockDbgInfoTest, DropSourceAtomOnSplit) {
     !1 = !DIFile(filename: "dummy", directory: "dummy")
     !2 = !{i32 7, !"Dwarf Version", i32 5}
     !3 = !{i32 2, !"Debug Info Version", i32 3}
-    !10 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, 
type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: 
!13)
+    !10 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, 
type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: 
!13, keyInstructions: true)
     !11 = !DISubroutineType(types: !12)
     !12 = !{null}
     !13 = !{}
diff --git a/llvm/unittests/IR/MetadataTest.cpp 
b/llvm/unittests/IR/MetadataTest.cpp
index df415602cef59..ba8367f4a396e 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -3023,12 +3023,13 @@ TEST_F(DISubprogramTest, get) {
   assert(!IsLocalToUnit && IsDefinition && !IsOptimized &&
          "bools and SPFlags have to match");
   SPFlags |= DISubprogram::SPFlagDefinition;
+  bool KeyInstructions = false;
 
   auto *N = DISubprogram::get(
       Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine,
       ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit,
       TemplateParams, Declaration, RetainedNodes, ThrownTypes, Annotations,
-      TargetFuncName);
+      TargetFuncName, KeyInstructions);
 
   EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag());
   EXPECT_EQ(Scope, N->getScope());
@@ -3053,125 +3054,138 @@ TEST_F(DISubprogramTest, get) {
   EXPECT_EQ(ThrownTypes, N->getThrownTypes().get());
   EXPECT_EQ(Annotations, N->getAnnotations().get());
   EXPECT_EQ(TargetFuncName, N->getTargetFuncName());
+  EXPECT_EQ(KeyInstructions, N->getKeyInstructionsEnabled());
   EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, ContainingType, VirtualIndex,
                                  ThisAdjustment, Flags, SPFlags, Unit,
                                  TemplateParams, Declaration, RetainedNodes,
-                                 ThrownTypes, Annotations, TargetFuncName));
+                                 ThrownTypes, Annotations, TargetFuncName,
+                                 KeyInstructions));
 
   EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, 
LinkageName,
                                  File, Line, Type, ScopeLine, ContainingType,
                                  VirtualIndex, ThisAdjustment, Flags, SPFlags,
                                  Unit, TemplateParams, Declaration,
                                  RetainedNodes, ThrownTypes, Annotations,
-                                 TargetFuncName));
+                                 TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File,
                                  Line, Type, ScopeLine, ContainingType,
                                  VirtualIndex, ThisAdjustment, Flags, SPFlags,
                                  Unit, TemplateParams, Declaration,
                                  RetainedNodes, ThrownTypes, Annotations,
-                                 TargetFuncName));
-  EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line,
-                                 Type, ScopeLine, ContainingType, VirtualIndex,
-                                 ThisAdjustment, Flags, SPFlags, Unit,
-                                 TemplateParams, Declaration, RetainedNodes,
-                                 ThrownTypes, Annotations, TargetFuncName));
+                                 TargetFuncName, KeyInstructions));
+  EXPECT_NE(N, DISubprogram::get(
+                   Context, Scope, Name, "other", File, Line, Type, ScopeLine,
+                   ContainingType, VirtualIndex, ThisAdjustment, Flags, 
SPFlags,
+                   Unit, TemplateParams, Declaration, RetainedNodes,
+                   ThrownTypes, Annotations, TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(),
                                  Line, Type, ScopeLine, ContainingType,
                                  VirtualIndex, ThisAdjustment, Flags, SPFlags,
                                  Unit, TemplateParams, Declaration,
                                  RetainedNodes, ThrownTypes, Annotations,
-                                 TargetFuncName));
+                                 TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File,
                                  Line + 1, Type, ScopeLine, ContainingType,
                                  VirtualIndex, ThisAdjustment, Flags, SPFlags,
                                  Unit, TemplateParams, Declaration,
                                  RetainedNodes, ThrownTypes, Annotations,
-                                 TargetFuncName));
+                                 TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  getSubroutineType(), ScopeLine, 
ContainingType,
                                  VirtualIndex, ThisAdjustment, Flags, SPFlags,
                                  Unit, TemplateParams, Declaration,
                                  RetainedNodes, ThrownTypes, Annotations,
-                                 TargetFuncName));
+                                 TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(
                    Context, Scope, Name, LinkageName, File, Line, Type,
                    ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
                    Flags, SPFlags ^ DISubprogram::SPFlagLocalToUnit, Unit,
                    TemplateParams, Declaration, RetainedNodes, ThrownTypes,
-                   Annotations, TargetFuncName));
+                   Annotations, TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(
                    Context, Scope, Name, LinkageName, File, Line, Type,
                    ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
                    Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit,
                    TemplateParams, Declaration, RetainedNodes, ThrownTypes,
-                   Annotations, TargetFuncName));
+                   Annotations, TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine + 1, ContainingType,
                                  VirtualIndex, ThisAdjustment, Flags, SPFlags,
                                  Unit, TemplateParams, Declaration,
                                  RetainedNodes, ThrownTypes, Annotations,
-                                 TargetFuncName));
+                                 TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, getCompositeType(),
                                  VirtualIndex, ThisAdjustment, Flags, SPFlags,
                                  Unit, TemplateParams, Declaration,
                                  RetainedNodes, ThrownTypes, Annotations,
-                                 TargetFuncName));
+                                 TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(
                    Context, Scope, Name, LinkageName, File, Line, Type,
                    ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
                    Flags, SPFlags ^ DISubprogram::SPFlagVirtual, Unit,
                    TemplateParams, Declaration, RetainedNodes, ThrownTypes,
-                   Annotations, TargetFuncName));
+                   Annotations, TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, ContainingType,
                                  VirtualIndex + 1, ThisAdjustment, Flags,
                                  SPFlags, Unit, TemplateParams, Declaration,
                                  RetainedNodes, ThrownTypes, Annotations,
-                                 TargetFuncName));
+                                 TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(
                    Context, Scope, Name, LinkageName, File, Line, Type,
                    ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
                    Flags, SPFlags ^ DISubprogram::SPFlagOptimized, Unit,
                    TemplateParams, Declaration, RetainedNodes, ThrownTypes,
-                   Annotations, TargetFuncName));
+                   Annotations, TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, ContainingType, VirtualIndex,
                                  ThisAdjustment, Flags, SPFlags, nullptr,
                                  TemplateParams, Declaration, RetainedNodes,
-                                 ThrownTypes, Annotations, TargetFuncName));
-  EXPECT_NE(N,
-            DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
-                              Type, ScopeLine, ContainingType, VirtualIndex,
-                              ThisAdjustment, Flags, SPFlags, Unit, getTuple(),
-                              Declaration, RetainedNodes, ThrownTypes,
-                              Annotations, TargetFuncName));
+                                 ThrownTypes, Annotations, TargetFuncName,
+                                 KeyInstructions));
+  EXPECT_NE(N, DISubprogram::get(
+                   Context, Scope, Name, LinkageName, File, Line, Type,
+                   ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
+                   Flags, SPFlags, Unit, getTuple(), Declaration, 
RetainedNodes,
+                   ThrownTypes, Annotations, TargetFuncName, KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, ContainingType, VirtualIndex,
                                  ThisAdjustment, Flags, SPFlags, Unit,
                                  TemplateParams, getSubprogram(), 
RetainedNodes,
-                                 ThrownTypes, Annotations, TargetFuncName));
+                                 ThrownTypes, Annotations, TargetFuncName,
+                                 KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, ContainingType, VirtualIndex,
                                  ThisAdjustment, Flags, SPFlags, Unit,
                                  TemplateParams, Declaration, getTuple(),
-                                 ThrownTypes, Annotations, TargetFuncName));
+                                 ThrownTypes, Annotations, TargetFuncName,
+                                 KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, ContainingType, VirtualIndex,
                                  ThisAdjustment, Flags, SPFlags, Unit,
                                  TemplateParams, Declaration, RetainedNodes,
-                                 getTuple(), Annotations, TargetFuncName));
+                                 getTuple(), Annotations, TargetFuncName,
+                                 KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, ContainingType, VirtualIndex,
                                  ThisAdjustment, Flags, SPFlags, Unit,
                                  TemplateParams, Declaration, RetainedNodes,
-                                 ThrownTypes, getTuple(), TargetFuncName));
+                                 ThrownTypes, getTuple(), TargetFuncName,
+                                 KeyInstructions));
   EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
                                  Type, ScopeLine, ContainingType, VirtualIndex,
                                  ThisAdjustment, Flags, SPFlags, Unit,
                                  TemplateParams, Declaration, RetainedNodes,
-                                 ThrownTypes, Annotations, "other"));
+                                 ThrownTypes, Annotations, "other",
+                                 KeyInstructions));
+  EXPECT_NE(N,
+            DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+                              Type, ScopeLine, ContainingType, VirtualIndex,
+                              ThisAdjustment, Flags, SPFlags, Unit,
+                              TemplateParams, Declaration, RetainedNodes,
+                              ThrownTypes, Annotations, TargetFuncName, true));
 
   TempDISubprogram Temp = N->clone();
   EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp 
b/llvm/unittests/Transforms/Utils/CloningTest.cpp
index 09b32bf09df0e..b8b035751637a 100644
--- a/llvm/unittests/Transforms/Utils/CloningTest.cpp
+++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp
@@ -1192,8 +1192,8 @@ TEST_F(CloneInstruction, cloneKeyInstructions) {
     !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1)
     !1 = !DIFile(filename: "test.cpp",  directory: "")
     !2 = !{i32 1, !"Debug Info Version", i32 3}
-    !3 = distinct !DISubprogram(name: "test", scope: !0, unit: !0)
-    !4 = distinct !DISubprogram(name: "inlined", scope: !0, unit: !0, 
retainedNodes: !{!5})
+    !3 = distinct !DISubprogram(name: "test", scope: !0, unit: !0, 
keyInstructions: true)
+    !4 = distinct !DISubprogram(name: "inlined", scope: !0, unit: !0, 
retainedNodes: !{!5}, keyInstructions: true)
     !5 = !DILocalVariable(name: "awaitables", scope: !4)
     !6 = !DILocation(line: 1, scope: !4, inlinedAt: !8, atomGroup: 1, 
atomRank: 1)
     !7 = !DILocation(line: 2, scope: !3, atomGroup: 1, atomRank: 1)

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to