Skip to content

Conversation

@cjacek
Copy link
Contributor

@cjacek cjacek commented Jun 5, 2025

No description provided.

@cjacek
Copy link
Contributor Author

cjacek commented Jun 5, 2025

The main motivation is to enable writing llc-based tests for the emitted CodeView data

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. llvm:codegen debuginfo labels Jun 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2025

@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-clang

Author: Jacek Caban (cjacek)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/142969.diff

6 Files Affected:

  • (modified) clang/lib/CodeGen/BackendUtil.cpp (-1)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+4)
  • (modified) clang/test/CodeGen/patchable-function-entry.c (+1)
  • (modified) llvm/include/llvm/Target/TargetOptions.h (+1-4)
  • (modified) llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (+2-2)
  • (added) llvm/test/DebugInfo/PDB/hotpatch.test (+57)
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index cd5fc48c4a22b..2365f675b2dc3 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -473,7 +473,6 @@ static bool initTargetOptions(const CompilerInstance &CI,
   Options.LoopAlignment = CodeGenOpts.LoopAlignment;
   Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;
   Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug;
-  Options.Hotpatch = CodeGenOpts.HotPatch;
   Options.JMCInstrument = CodeGenOpts.JMCInstrument;
   Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers;
 
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 468fc6e0e5c56..3529a5a70bd45 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1031,6 +1031,10 @@ void CodeGenModule::Release() {
     // Function ID tables for EH Continuation Guard.
     getModule().addModuleFlag(llvm::Module::Warning, "ehcontguard", 1);
   }
+  if (CodeGenOpts.HotPatch) {
+    // Note if we are compiling with /hotpatch.
+    getModule().addModuleFlag(llvm::Module::Warning, "ms-hotpatch", 1);
+  }
   if (Context.getLangOpts().Kernel) {
     // Note if we are compiling with /kernel.
     getModule().addModuleFlag(llvm::Module::Warning, "ms-kernel", 1);
diff --git a/clang/test/CodeGen/patchable-function-entry.c b/clang/test/CodeGen/patchable-function-entry.c
index 2acd748758490..b49f297abf7de 100644
--- a/clang/test/CodeGen/patchable-function-entry.c
+++ b/clang/test/CodeGen/patchable-function-entry.c
@@ -39,3 +39,4 @@ void f(void) {}
 // HOTPATCH: attributes #1 = { {{.*}} "patchable-function"="prologue-short-redirect"
 // HOTPATCH: attributes #2 = { {{.*}} "patchable-function"="prologue-short-redirect"
 // HOTPATCH: attributes #3 = { {{.*}} "patchable-function"="prologue-short-redirect"
+// HOTPATCH: !{{.}} = !{i32 2, !"ms-hotpatch", i32 1}
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index fd8dad4f6f791..25bbb73e9dedc 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -150,7 +150,7 @@ namespace llvm {
           EmitAddrsig(false), BBAddrMap(false), EmitCallSiteInfo(false),
           SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
           ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
-          XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
+          XRayFunctionIndex(true), DebugStrictDwarf(false),
           PPCGenScalarMASSEntries(false), JMCInstrument(false),
           EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
           VerifyArgABICompliance(true),
@@ -363,9 +363,6 @@ namespace llvm {
     /// By default, it is set to false.
     unsigned DebugStrictDwarf : 1;
 
-    /// Emit the hotpatch flag in CodeView debug.
-    unsigned Hotpatch : 1;
-
     /// Enables scalar MASS conversions
     unsigned PPCGenScalarMASSEntries : 1;
 
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index fc43bc6f7776d..49e26fcec48d6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -846,8 +846,8 @@ void CodeViewDebug::emitCompilerInformation() {
   }
   using ArchType = llvm::Triple::ArchType;
   ArchType Arch = MMI->getModule()->getTargetTriple().getArch();
-  if (Asm->TM.Options.Hotpatch || Arch == ArchType::thumb ||
-      Arch == ArchType::aarch64) {
+  if (Arch == ArchType::thumb || Arch == ArchType::aarch64 ||
+      MMI->getModule()->getModuleFlag("ms-hotpatch")) {
     Flags |= static_cast<uint32_t>(CompileSym3Flags::HotPatch);
   }
 
diff --git a/llvm/test/DebugInfo/PDB/hotpatch.test b/llvm/test/DebugInfo/PDB/hotpatch.test
new file mode 100644
index 0000000000000..7ff15fa3c69a4
--- /dev/null
+++ b/llvm/test/DebugInfo/PDB/hotpatch.test
@@ -0,0 +1,57 @@
+; RUN: llc -filetype=obj -o - %s | llvm-readobj --codeview - | FileCheck %s
+
+; ModuleID = 'a.c'
+source_filename = "a.c"
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-windows-msvc19.33.0"
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local void @test() #0 !dbg !10 {
+entry:
+  ret void, !dbg !13
+}
+
+attributes #0 = { noinline nounwind optnone uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "patchable-function"="prologue-short-redirect" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
+!llvm.ident = !{!9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "a.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "c59e1f6192de3124537b024248301dd1")
+!2 = !{i32 2, !"CodeView", i32 1}
+!3 = !{i32 2, !"ms-hotpatch", i32 1}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 2}
+!6 = !{i32 8, !"PIC Level", i32 2}
+!7 = !{i32 7, !"uwtable", i32 2}
+!8 = !{i32 1, !"MaxTLSAlign", i32 65536}
+!9 = !{!"clang version 21.0.0git"}
+!10 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0)
+!11 = !DISubroutineType(types: !12)
+!12 = !{null}
+!13 = !DILocation(line: 1, scope: !10)
+
+; CHECK:      CodeViewDebugInfo [
+; CHECK-NEXT:   Section: .debug$S (4)
+; CHECK-NEXT:   Magic: 0x4
+; CHECK-NEXT:   Subsection [
+; CHECK-NEXT:     SubSectionType: Symbols (0xF1)
+; CHECK-NEXT:     SubSectionSize: 0x40
+; CHECK-NEXT:     ObjNameSym {
+; CHECK-NEXT:       Kind: S_OBJNAME (0x1101)
+; CHECK-NEXT:       Signature: 0x0
+; CHECK-NEXT:       ObjectName:
+; CHECK-NEXT:     }
+; CHECK-NEXT:     Compile3Sym {
+; CHECK-NEXT:       Kind: S_COMPILE3 (0x113C)
+; CHECK-NEXT:       Language: C (0x0)
+; CHECK-NEXT:       Flags [ (0x4000)
+; CHECK-NEXT:         HotPatch (0x4000)
+; CHECK-NEXT:       ]
+; CHECK-NEXT:       Machine: X64 (0xD0)
+; CHECK-NEXT:       FrontendVersion: 21.0.0.0
+; CHECK-NEXT:       BackendVersion: 21000.0.0.0
+; CHECK-NEXT:       VersionName: clang version 21.0.0git
+; CHECK-NEXT:     }
+; CHECK-NEXT:   ]

@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2025

@llvm/pr-subscribers-clang-codegen

Author: Jacek Caban (cjacek)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/142969.diff

6 Files Affected:

  • (modified) clang/lib/CodeGen/BackendUtil.cpp (-1)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+4)
  • (modified) clang/test/CodeGen/patchable-function-entry.c (+1)
  • (modified) llvm/include/llvm/Target/TargetOptions.h (+1-4)
  • (modified) llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (+2-2)
  • (added) llvm/test/DebugInfo/PDB/hotpatch.test (+57)
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index cd5fc48c4a22b..2365f675b2dc3 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -473,7 +473,6 @@ static bool initTargetOptions(const CompilerInstance &CI,
   Options.LoopAlignment = CodeGenOpts.LoopAlignment;
   Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;
   Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug;
-  Options.Hotpatch = CodeGenOpts.HotPatch;
   Options.JMCInstrument = CodeGenOpts.JMCInstrument;
   Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers;
 
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 468fc6e0e5c56..3529a5a70bd45 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1031,6 +1031,10 @@ void CodeGenModule::Release() {
     // Function ID tables for EH Continuation Guard.
     getModule().addModuleFlag(llvm::Module::Warning, "ehcontguard", 1);
   }
+  if (CodeGenOpts.HotPatch) {
+    // Note if we are compiling with /hotpatch.
+    getModule().addModuleFlag(llvm::Module::Warning, "ms-hotpatch", 1);
+  }
   if (Context.getLangOpts().Kernel) {
     // Note if we are compiling with /kernel.
     getModule().addModuleFlag(llvm::Module::Warning, "ms-kernel", 1);
diff --git a/clang/test/CodeGen/patchable-function-entry.c b/clang/test/CodeGen/patchable-function-entry.c
index 2acd748758490..b49f297abf7de 100644
--- a/clang/test/CodeGen/patchable-function-entry.c
+++ b/clang/test/CodeGen/patchable-function-entry.c
@@ -39,3 +39,4 @@ void f(void) {}
 // HOTPATCH: attributes #1 = { {{.*}} "patchable-function"="prologue-short-redirect"
 // HOTPATCH: attributes #2 = { {{.*}} "patchable-function"="prologue-short-redirect"
 // HOTPATCH: attributes #3 = { {{.*}} "patchable-function"="prologue-short-redirect"
+// HOTPATCH: !{{.}} = !{i32 2, !"ms-hotpatch", i32 1}
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index fd8dad4f6f791..25bbb73e9dedc 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -150,7 +150,7 @@ namespace llvm {
           EmitAddrsig(false), BBAddrMap(false), EmitCallSiteInfo(false),
           SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
           ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
-          XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
+          XRayFunctionIndex(true), DebugStrictDwarf(false),
           PPCGenScalarMASSEntries(false), JMCInstrument(false),
           EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
           VerifyArgABICompliance(true),
@@ -363,9 +363,6 @@ namespace llvm {
     /// By default, it is set to false.
     unsigned DebugStrictDwarf : 1;
 
-    /// Emit the hotpatch flag in CodeView debug.
-    unsigned Hotpatch : 1;
-
     /// Enables scalar MASS conversions
     unsigned PPCGenScalarMASSEntries : 1;
 
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index fc43bc6f7776d..49e26fcec48d6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -846,8 +846,8 @@ void CodeViewDebug::emitCompilerInformation() {
   }
   using ArchType = llvm::Triple::ArchType;
   ArchType Arch = MMI->getModule()->getTargetTriple().getArch();
-  if (Asm->TM.Options.Hotpatch || Arch == ArchType::thumb ||
-      Arch == ArchType::aarch64) {
+  if (Arch == ArchType::thumb || Arch == ArchType::aarch64 ||
+      MMI->getModule()->getModuleFlag("ms-hotpatch")) {
     Flags |= static_cast<uint32_t>(CompileSym3Flags::HotPatch);
   }
 
diff --git a/llvm/test/DebugInfo/PDB/hotpatch.test b/llvm/test/DebugInfo/PDB/hotpatch.test
new file mode 100644
index 0000000000000..7ff15fa3c69a4
--- /dev/null
+++ b/llvm/test/DebugInfo/PDB/hotpatch.test
@@ -0,0 +1,57 @@
+; RUN: llc -filetype=obj -o - %s | llvm-readobj --codeview - | FileCheck %s
+
+; ModuleID = 'a.c'
+source_filename = "a.c"
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-windows-msvc19.33.0"
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local void @test() #0 !dbg !10 {
+entry:
+  ret void, !dbg !13
+}
+
+attributes #0 = { noinline nounwind optnone uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "patchable-function"="prologue-short-redirect" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
+!llvm.ident = !{!9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "a.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "c59e1f6192de3124537b024248301dd1")
+!2 = !{i32 2, !"CodeView", i32 1}
+!3 = !{i32 2, !"ms-hotpatch", i32 1}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 2}
+!6 = !{i32 8, !"PIC Level", i32 2}
+!7 = !{i32 7, !"uwtable", i32 2}
+!8 = !{i32 1, !"MaxTLSAlign", i32 65536}
+!9 = !{!"clang version 21.0.0git"}
+!10 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0)
+!11 = !DISubroutineType(types: !12)
+!12 = !{null}
+!13 = !DILocation(line: 1, scope: !10)
+
+; CHECK:      CodeViewDebugInfo [
+; CHECK-NEXT:   Section: .debug$S (4)
+; CHECK-NEXT:   Magic: 0x4
+; CHECK-NEXT:   Subsection [
+; CHECK-NEXT:     SubSectionType: Symbols (0xF1)
+; CHECK-NEXT:     SubSectionSize: 0x40
+; CHECK-NEXT:     ObjNameSym {
+; CHECK-NEXT:       Kind: S_OBJNAME (0x1101)
+; CHECK-NEXT:       Signature: 0x0
+; CHECK-NEXT:       ObjectName:
+; CHECK-NEXT:     }
+; CHECK-NEXT:     Compile3Sym {
+; CHECK-NEXT:       Kind: S_COMPILE3 (0x113C)
+; CHECK-NEXT:       Language: C (0x0)
+; CHECK-NEXT:       Flags [ (0x4000)
+; CHECK-NEXT:         HotPatch (0x4000)
+; CHECK-NEXT:       ]
+; CHECK-NEXT:       Machine: X64 (0xD0)
+; CHECK-NEXT:       FrontendVersion: 21.0.0.0
+; CHECK-NEXT:       BackendVersion: 21000.0.0.0
+; CHECK-NEXT:       VersionName: clang version 21.0.0git
+; CHECK-NEXT:     }
+; CHECK-NEXT:   ]

Copy link
Member

@aganea aganea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR will all depend on the course taken on #142970

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part of the test seems to be generated by the other PR, not this one specifically.

@aganea
Copy link
Member

aganea commented Sep 10, 2025

@cjacek Is this still relevant or has it been committed under a different form?

@cjacek
Copy link
Contributor Author

cjacek commented Sep 11, 2025

I originally needed this commit to write a test case for #142970, when I was emitting the compiler info conditionally. Once we decided to enable it unconditionally, I could use a non-hotpatchable input in the test case, so this PR was no longer necessary.

That said, being able to specify hotpatch in tests may still be useful at some point. I’ll rebase the PR, but I don’t mind dropping it if you think it’s not worth changing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category debuginfo llvm:codegen

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants