https://github.com/sivadeilra updated 
https://github.com/llvm/llvm-project/pull/138972

>From 18bcf7a9da1b0698b6e7b9808edf4f12d0db16aa Mon Sep 17 00:00:00 2001
From: Arlie Davis <arda...@microsoft.com>
Date: Thu, 3 Apr 2025 16:10:50 -0700
Subject: [PATCH 1/4] Windows hotpatching support

Address PR feedback

* Simply use F.getName() for function name.
* Fix llvm/test/CodeGen/Generic/ms-hotpatch-direct-global-access.ll
* Add negative testing for functions that are not supposed to be hotpatched
---
 clang/include/clang/Basic/CodeGenOptions.h    |   7 +
 clang/include/clang/Driver/Options.td         |  14 +
 clang/lib/CodeGen/CGCall.cpp                  |   9 +
 clang/lib/CodeGen/CodeGenModule.cpp           |  31 +++
 clang/lib/CodeGen/CodeGenModule.h             |   5 +
 clang/lib/Driver/ToolChains/Clang.cpp         |  10 +
 clang/test/CodeGen/ms-hotpatch-bad-file.c     |  16 ++
 clang/test/CodeGen/ms-hotpatch-cpp.cpp        |  22 ++
 clang/test/CodeGen/ms-hotpatch-functions.txt  |   1 +
 clang/test/CodeGen/ms-hotpatch-lto.c          |  18 ++
 clang/test/CodeGen/ms-hotpatch.c              |  20 ++
 llvm/include/llvm/Bitcode/LLVMBitCodes.h      |   2 +
 llvm/include/llvm/CodeGen/Passes.h            |   3 +
 .../DebugInfo/CodeView/CodeViewSymbols.def    |   2 +
 .../llvm/DebugInfo/CodeView/SymbolRecord.h    |  15 ++
 llvm/include/llvm/IR/Attributes.td            |  11 +
 llvm/include/llvm/InitializePasses.h          |   1 +
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp     |   4 +
 llvm/lib/Bitcode/Writer/BitcodeWriter.cpp     |   4 +
 llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp |  32 ++-
 llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h   |   2 +
 llvm/lib/CodeGen/CMakeLists.txt               |   1 +
 llvm/lib/CodeGen/TargetPassConfig.cpp         |   3 +
 llvm/lib/CodeGen/WindowsHotPatch.cpp          | 242 ++++++++++++++++++
 llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp  |   7 +
 .../CodeView/SymbolRecordMapping.cpp          |   7 +
 llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp   |   5 +
 llvm/lib/Transforms/Utils/CodeExtractor.cpp   |   2 +
 llvm/test/CodeGen/Generic/ms-hotpatch-attr.ll |  38 +++
 .../CodeGen/Generic/ms-hotpatch-bad-file.ll   |  16 ++
 .../ms-hotpatch-direct-global-access.ll       |  39 +++
 .../Generic/ms-hotpatch-functions-file.ll     |  38 +++
 .../Generic/ms-hotpatch-functions-file.txt    |   1 +
 .../Generic/ms-hotpatch-functions-list.ll     |  38 +++
 .../llvm-pdbutil/MinimalSymbolDumper.cpp      |   8 +
 35 files changed, 672 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGen/ms-hotpatch-bad-file.c
 create mode 100644 clang/test/CodeGen/ms-hotpatch-cpp.cpp
 create mode 100644 clang/test/CodeGen/ms-hotpatch-functions.txt
 create mode 100644 clang/test/CodeGen/ms-hotpatch-lto.c
 create mode 100644 clang/test/CodeGen/ms-hotpatch.c
 create mode 100644 llvm/lib/CodeGen/WindowsHotPatch.cpp
 create mode 100644 llvm/test/CodeGen/Generic/ms-hotpatch-attr.ll
 create mode 100644 llvm/test/CodeGen/Generic/ms-hotpatch-bad-file.ll
 create mode 100644 
llvm/test/CodeGen/Generic/ms-hotpatch-direct-global-access.ll
 create mode 100644 llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.ll
 create mode 100644 llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.txt
 create mode 100644 llvm/test/CodeGen/Generic/ms-hotpatch-functions-list.ll

diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 278803f7bb960..b0efc445b8450 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -501,6 +501,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
 
   /// A list of functions that are replacable by the loader.
   std::vector<std::string> LoaderReplaceableFunctionNames;
+  /// The name of a file that contains functions which will be compiled for
+  /// hotpatching. See -fms-hot-patch-functions-file.
+  std::string MSHotPatchFunctionsFile;
+
+  /// A list of functions which will be compiled for hotpatching.
+  /// See -fms-hot-patch-functions-list.
+  std::vector<std::string> MSHotPatchFunctionsList;
 
 public:
   // Define accessors/mutators for code generation options of enumeration type.
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index bd8df8f6a749a..9d1931381dee7 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3830,6 +3830,20 @@ def fms_hotpatch : Flag<["-"], "fms-hotpatch">, 
Group<f_Group>,
   Visibility<[ClangOption, CC1Option, CLOption]>,
   HelpText<"Ensure that all functions can be hotpatched at runtime">,
   MarshallingInfoFlag<CodeGenOpts<"HotPatch">>;
+def fms_hotpatch_functions_file
+    : Joined<["-"], "fms-hotpatch-functions-file=">,
+      Group<f_Group>,
+      Visibility<[ClangOption, CC1Option, CLOption]>,
+      MarshallingInfoString<CodeGenOpts<"MSHotPatchFunctionsFile">>,
+      HelpText<"Path to a file that contains a list of mangled symbol names of 
"
+               "functions that should be hot-patched">;
+def fms_hotpatch_functions_list
+    : CommaJoined<["-"], "fms-hotpatch-functions-list=">,
+      Group<f_Group>,
+      Visibility<[ClangOption, CC1Option, CLOption]>,
+      MarshallingInfoStringVector<CodeGenOpts<"MSHotPatchFunctionsList">>,
+      HelpText<"List of mangled symbol names of functions that should be "
+               "hot-patched">;
 def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Override the default ABI to return all structs on the stack">;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index aa1909443e8cd..666b00809c37e 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2639,6 +2639,15 @@ void CodeGenModule::ConstructAttributeList(StringRef 
Name,
     // CPU/feature overrides.  addDefaultFunctionDefinitionAttributes
     // handles these separately to set them based on the global defaults.
     GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs);
+
+    // Windows hotpatching support
+    if (!MSHotPatchFunctions.empty()) {
+      bool IsHotPatched = std::binary_search(MSHotPatchFunctions.begin(),
+                                             MSHotPatchFunctions.end(), Name);
+      if (IsHotPatched) {
+        FuncAttrs.addAttribute(llvm::Attribute::MarkedForWindowsHotPatching);
+      }
+    }
   }
 
   // Mark functions that are replaceable by the loader.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 428a4b8335524..aa11487c4dce1 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -453,6 +453,37 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   if (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
     getModule().addModuleFlag(llvm::Module::Error, "NumRegisterParameters",
                               CodeGenOpts.NumRegisterParameters);
+
+  // If there are any functions that are marked for Windows hot-patching,
+  // then build the list of functions now.
+  if (!CGO.MSHotPatchFunctionsFile.empty() ||
+      !CGO.MSHotPatchFunctionsList.empty()) {
+    if (!CGO.MSHotPatchFunctionsFile.empty()) {
+      auto BufOrErr = llvm::MemoryBuffer::getFile(CGO.MSHotPatchFunctionsFile);
+      if (BufOrErr) {
+        const llvm::MemoryBuffer &FileBuffer = **BufOrErr;
+        for (llvm::line_iterator I(FileBuffer.getMemBufferRef(), true), E;
+             I != E; ++I) {
+          this->MSHotPatchFunctions.push_back(std::string{*I});
+        }
+      } else {
+        auto &DE = Context.getDiagnostics();
+        unsigned DiagID =
+            DE.getCustomDiagID(DiagnosticsEngine::Error,
+                               "failed to open hotpatch functions file "
+                               "(-fms-hotpatch-functions-file): %0 : %1");
+        DE.Report(DiagID) << CGO.MSHotPatchFunctionsFile
+                          << BufOrErr.getError().message();
+      }
+    }
+
+    for (const auto &FuncName : CGO.MSHotPatchFunctionsList) {
+      this->MSHotPatchFunctions.push_back(FuncName);
+    }
+
+    std::sort(this->MSHotPatchFunctions.begin(),
+              this->MSHotPatchFunctions.end());
+  }
 }
 
 CodeGenModule::~CodeGenModule() {}
diff --git a/clang/lib/CodeGen/CodeGenModule.h 
b/clang/lib/CodeGen/CodeGenModule.h
index 1db5c3bc4e4ef..45411cb95b7d2 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -678,6 +678,11 @@ class CodeGenModule : public CodeGenTypeCache {
 
   AtomicOptions AtomicOpts;
 
+  // A set of functions which should be hot-patched; see
+  // -fms-hotpatch-functions-file (and -list). This will nearly always be 
empty.
+  // The list is sorted for binary-searching.
+  std::vector<std::string> MSHotPatchFunctions;
+
 public:
   CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
                 const HeaderSearchOptions &headersearchopts,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index a08bdba99bfe0..6a38a9ada42ec 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6946,6 +6946,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
 
   Args.AddLastArg(CmdArgs, options::OPT_fms_hotpatch);
 
+  if (Arg *A = Args.getLastArg(options::OPT_fms_hotpatch_functions_file)) {
+    Args.AddLastArg(CmdArgs, options::OPT_fms_hotpatch_functions_file);
+  }
+
+  for (const auto &A :
+       Args.getAllArgValues(options::OPT_fms_hotpatch_functions_list)) {
+    CmdArgs.push_back(
+        Args.MakeArgString("-fms-hotpatch-functions-list=" + Twine(A)));
+  }
+
   if (TC.SupportsProfiling()) {
     Args.AddLastArg(CmdArgs, options::OPT_pg);
 
diff --git a/clang/test/CodeGen/ms-hotpatch-bad-file.c 
b/clang/test/CodeGen/ms-hotpatch-bad-file.c
new file mode 100644
index 0000000000000..55304488175df
--- /dev/null
+++ b/clang/test/CodeGen/ms-hotpatch-bad-file.c
@@ -0,0 +1,16 @@
+// This verifies that we correctly handle a -fms-hotpatch-functions-file 
argument that points
+// to a missing file.
+//
+// RUN: not %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt
 /Fo%t.obj %s 2>&1 | FileCheck %s
+// CHECK: failed to open hotpatch functions file
+
+void this_might_have_side_effects();
+
+int __declspec(noinline) this_gets_hotpatched() {
+    this_might_have_side_effects();
+    return 42;
+}
+
+int __declspec(noinline) this_does_not_get_hotpatched() {
+    return this_gets_hotpatched() + 100;
+}
diff --git a/clang/test/CodeGen/ms-hotpatch-cpp.cpp 
b/clang/test/CodeGen/ms-hotpatch-cpp.cpp
new file mode 100644
index 0000000000000..26e11f429c962
--- /dev/null
+++ b/clang/test/CodeGen/ms-hotpatch-cpp.cpp
@@ -0,0 +1,22 @@
+// This verifies that hotpatch function attributes are correctly propagated 
when compiling directly to OBJ,
+// and that name mangling works as expected.
+//
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-list=?this_gets_hotpatched@@YAHXZ /Fo%t.obj %s
+// RUN: llvm-readobj --codeview %t.obj | FileCheck %s
+
+void this_might_have_side_effects();
+
+int __declspec(noinline) this_gets_hotpatched() {
+    this_might_have_side_effects();
+    return 42;
+}
+
+// CHECK: Kind: S_HOTPATCHFUNC (0x1169)
+// CHECK-NEXT: Function: this_gets_hotpatched
+// CHECK-NEXT: Name: ?this_gets_hotpatched@@YAHXZ
+
+extern "C" int __declspec(noinline) this_does_not_get_hotpatched() {
+    return this_gets_hotpatched() + 100;
+}
+
+// CHECK-NOT: S_HOTPATCHFUNC
diff --git a/clang/test/CodeGen/ms-hotpatch-functions.txt 
b/clang/test/CodeGen/ms-hotpatch-functions.txt
new file mode 100644
index 0000000000000..2512ba3881c66
--- /dev/null
+++ b/clang/test/CodeGen/ms-hotpatch-functions.txt
@@ -0,0 +1 @@
+this_gets_hotpatched
diff --git a/clang/test/CodeGen/ms-hotpatch-lto.c 
b/clang/test/CodeGen/ms-hotpatch-lto.c
new file mode 100644
index 0000000000000..290f7695b02f6
--- /dev/null
+++ b/clang/test/CodeGen/ms-hotpatch-lto.c
@@ -0,0 +1,18 @@
+// This verifies that hotpatch function attributes are correctly propagated 
through LLVM IR when compiling with LTO.
+//
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-file=%S/ms-hotpatch-functions.txt -flto /Fo%t.bc %s
+// RUN: llvm-dis %t.bc -o - | FileCheck %s
+//
+// CHECK: ; Function Attrs: marked_for_windows_hot_patching mustprogress 
nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) 
uwtable
+// CHECK-NEXT: define dso_local noundef i32 @this_gets_hotpatched() 
local_unnamed_addr #0 !dbg !13 {
+//
+// CHECK: ; Function Attrs: mustprogress nofree noinline norecurse nosync 
nounwind sspstrong willreturn memory(none) uwtable
+// CHECK-NEXT: define dso_local noundef i32 @this_does_not_get_hotpatched() 
local_unnamed_addr #1 !dbg !19 {
+
+int __declspec(noinline) this_gets_hotpatched() {
+    return 42;
+}
+
+int __declspec(noinline) this_does_not_get_hotpatched() {
+    return this_gets_hotpatched() + 100;
+}
diff --git a/clang/test/CodeGen/ms-hotpatch.c b/clang/test/CodeGen/ms-hotpatch.c
new file mode 100644
index 0000000000000..79da105f4cec3
--- /dev/null
+++ b/clang/test/CodeGen/ms-hotpatch.c
@@ -0,0 +1,20 @@
+// This verifies that hotpatch function attributes are correctly propagated 
when compiling directly to OBJ.
+//
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-file=%S/ms-hotpatch-functions.txt /Fo%t.obj %s
+// RUN: llvm-readobj --codeview %t.obj | FileCheck %s
+
+void this_might_have_side_effects();
+
+int __declspec(noinline) this_gets_hotpatched() {
+    this_might_have_side_effects();
+    return 42;
+}
+
+// CHECK: Kind: S_HOTPATCHFUNC (0x1169)
+// CHECK-NEXT: Function: this_gets_hotpatched
+
+int __declspec(noinline) this_does_not_get_hotpatched() {
+    return this_gets_hotpatched() + 100;
+}
+
+// CHECK-NOT: S_HOTPATCHFUNC
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h 
b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index b362a88963f6c..707e51031f7dd 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -798,6 +798,8 @@ enum AttributeKindCodes {
   ATTR_KIND_NO_DIVERGENCE_SOURCE = 100,
   ATTR_KIND_SANITIZE_TYPE = 101,
   ATTR_KIND_CAPTURES = 102,
+  ATTR_KIND_ALLOW_DIRECT_ACCESS_IN_HOT_PATCH_FUNCTION = 103,
+  ATTR_KIND_MARKED_FOR_WINDOWS_HOT_PATCHING = 104,
 };
 
 enum ComdatSelectionKindCodes {
diff --git a/llvm/include/llvm/CodeGen/Passes.h 
b/llvm/include/llvm/CodeGen/Passes.h
index d214ab9306c2f..c4163617da5ae 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -617,6 +617,9 @@ namespace llvm {
 
   /// Lowers KCFI operand bundles for indirect calls.
   FunctionPass *createKCFIPass();
+
+  /// Creates Windows Hot Patch pass. \see WindowsHotPatch.cpp
+  ModulePass *createWindowsHotPatch();
 } // End llvm namespace
 
 #endif
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def 
b/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
index 9d85acc49fa02..b38bdb482df43 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
@@ -256,6 +256,8 @@ SYMBOL_RECORD_ALIAS(S_GTHREAD32     , 0x1113, GlobalTLS, 
ThreadLocalDataSym)
 SYMBOL_RECORD(S_UNAMESPACE    , 0x1124, UsingNamespaceSym)
 SYMBOL_RECORD(S_ANNOTATION    , 0x1019, AnnotationSym)
 
+SYMBOL_RECORD(S_HOTPATCHFUNC  , 0x1169, HotPatchFuncSym)
+
 #undef CV_SYMBOL
 #undef SYMBOL_RECORD
 #undef SYMBOL_RECORD_ALIAS
diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h 
b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index 3cce40dcf735a..de80d37999890 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -176,6 +176,21 @@ class CallerSym : public SymbolRecord {
   uint32_t RecordOffset = 0;
 };
 
+class HotPatchFuncSym : public SymbolRecord {
+public:
+  explicit HotPatchFuncSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+  HotPatchFuncSym(uint32_t RecordOffset)
+      : SymbolRecord(SymbolRecordKind::HotPatchFuncSym),
+        RecordOffset(RecordOffset) {}
+
+  // This is an ItemID in the IPI stream, which points to an LF_FUNC_ID or
+  // LF_MFUNC_ID record.
+  TypeIndex Function;
+  StringRef Name;
+
+  uint32_t RecordOffset = 0;
+};
+
 struct DecodedAnnotation {
   StringRef Name;
   ArrayRef<uint8_t> Bytes;
diff --git a/llvm/include/llvm/IR/Attributes.td 
b/llvm/include/llvm/IR/Attributes.td
index d488c5f419b82..9baf9a53d2f4d 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -389,6 +389,17 @@ def CoroDestroyOnlyWhenComplete : 
EnumAttr<"coro_only_destroy_when_complete", In
 /// pipeline to perform elide on the call or invoke instruction.
 def CoroElideSafe : EnumAttr<"coro_elide_safe", IntersectPreserve, [FnAttr]>;
 
+/// Function is marked for Windows Hot Patching
+def MarkedForWindowsHotPatching
+    : EnumAttr<"marked_for_windows_hot_patching", IntersectPreserve, [FnAttr]>;
+
+/// Global variable should not be accessed through a "__ref_" global variable 
in
+/// a hot patching function This attribute is applied to the global variable
+/// decl, not the hotpatched function.
+def AllowDirectAccessInHotPatchFunction
+    : EnumAttr<"allow_direct_access_in_hot_patch_function",
+               IntersectPreserve, [FnAttr]>;
+
 /// Target-independent string attributes.
 def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
 def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
diff --git a/llvm/include/llvm/InitializePasses.h 
b/llvm/include/llvm/InitializePasses.h
index 5a282d17b72c8..53722dd10fac7 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -323,6 +323,7 @@ void initializeVirtRegMapWrapperLegacyPass(PassRegistry &);
 void initializeVirtRegRewriterLegacyPass(PassRegistry &);
 void initializeWasmEHPreparePass(PassRegistry &);
 void initializeWinEHPreparePass(PassRegistry &);
+void initializeWindowsHotPatchPass(PassRegistry &);
 void initializeWriteBitcodePassPass(PassRegistry &);
 void initializeXRayInstrumentationLegacyPass(PassRegistry &);
 
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp 
b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 1e07f060d72cb..eb72655a75560 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2247,6 +2247,10 @@ static Attribute::AttrKind getAttrFromCode(uint64_t 
Code) {
     return Attribute::NoExt;
   case bitc::ATTR_KIND_CAPTURES:
     return Attribute::Captures;
+  case bitc::ATTR_KIND_ALLOW_DIRECT_ACCESS_IN_HOT_PATCH_FUNCTION:
+    return Attribute::AllowDirectAccessInHotPatchFunction;
+  case bitc::ATTR_KIND_MARKED_FOR_WINDOWS_HOT_PATCHING:
+    return Attribute::MarkedForWindowsHotPatching;
   }
 }
 
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp 
b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 1a15c5120d3fd..b3c2d974c3db1 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -937,6 +937,10 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind 
Kind) {
     return bitc::ATTR_KIND_NO_EXT;
   case Attribute::Captures:
     return bitc::ATTR_KIND_CAPTURES;
+  case Attribute::AllowDirectAccessInHotPatchFunction:
+    return bitc::ATTR_KIND_ALLOW_DIRECT_ACCESS_IN_HOT_PATCH_FUNCTION;
+  case Attribute::MarkedForWindowsHotPatching:
+    return bitc::ATTR_KIND_MARKED_FOR_WINDOWS_HOT_PATCHING;
   case Attribute::EndAttrKinds:
     llvm_unreachable("Can not encode end-attribute kinds marker.");
   case Attribute::None:
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp 
b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index df4e48571692c..c643bd269f3b1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -627,8 +627,6 @@ void CodeViewDebug::beginModule(Module *M) {
 
   CurrentSourceLanguage = MapDWLangToCVLang(CU->getSourceLanguage());
 
-  collectGlobalVariableInfo();
-
   // Check if we should emit type record hashes.
   ConstantInt *GH =
       mdconst::extract_or_null<ConstantInt>(M->getModuleFlag("CodeViewGHash"));
@@ -639,6 +637,8 @@ void CodeViewDebug::endModule() {
   if (!Asm || !Asm->hasDebugInfo())
     return;
 
+  collectGlobalVariableInfo();
+
   // The COFF .debug$S section consists of several subsections, each starting
   // with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length
   // of the payload followed by the payload itself.  The subsections are 4-byte
@@ -653,6 +653,8 @@ void CodeViewDebug::endModule() {
   emitCompilerInformation();
   endCVSubsection(CompilerInfo);
 
+  emitHotPatchInformation();
+
   emitInlineeLinesSubsection();
 
   // Emit per-function debug information.
@@ -807,6 +809,32 @@ void CodeViewDebug::emitObjName() {
   endSymbolRecord(CompilerEnd);
 }
 
+void CodeViewDebug::emitHotPatchInformation() {
+  MCSymbol *hotPatchInfo = nullptr;
+  for (const auto &F : MMI->getModule()->functions()) {
+    if (!F.isDeclarationForLinker() &&
+        F.hasFnAttribute(Attribute::MarkedForWindowsHotPatching)) {
+      if (hotPatchInfo == nullptr) {
+        hotPatchInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
+      }
+      MCSymbol *HotPatchEnd = beginSymbolRecord(SymbolKind::S_HOTPATCHFUNC);
+      auto *SP = F.getSubprogram();
+      OS.AddComment("Function");
+      OS.emitInt32(getFuncIdForSubprogram(SP).getIndex());
+      OS.AddComment("Name");
+      llvm::StringRef Name = SP->getLinkageName();
+      if (Name.empty()) {
+        Name = F.getName();
+      }
+      emitNullTerminatedSymbolName(OS, Name);
+      endSymbolRecord(HotPatchEnd);
+    }
+  }
+  if (hotPatchInfo != nullptr) {
+    endCVSubsection(hotPatchInfo);
+  }
+}
+
 namespace {
 struct Version {
   int Part[4];
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h 
b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 7a138a0332b6d..3cc47b79b5b32 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -333,6 +333,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public 
DebugHandlerBase {
 
   void emitCompilerInformation();
 
+  void emitHotPatchInformation();
+
   void emitBuildInfo();
 
   void emitInlineeLinesSubsection();
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 5dd6413431255..f18f085b0450b 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -250,6 +250,7 @@ add_llvm_component_library(LLVMCodeGen
   VirtRegMap.cpp
   WasmEHPrepare.cpp
   WindowScheduler.cpp
+  WindowsHotPatch.cpp
   WinEHPrepare.cpp
   XRayInstrumentation.cpp
   ${GeneratedMLSources}
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp 
b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 0095ce3d96277..1d93efc21fbab 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -893,6 +893,9 @@ void TargetPassConfig::addIRPasses() {
 
   if (EnableGlobalMergeFunc)
     addPass(createGlobalMergeFuncPass());
+
+  if (TM->getTargetTriple().isOSBinFormatCOFF())
+    addPass(createWindowsHotPatch());
 }
 
 /// Turn exception handling constructs into something the code generators can
diff --git a/llvm/lib/CodeGen/WindowsHotPatch.cpp 
b/llvm/lib/CodeGen/WindowsHotPatch.cpp
new file mode 100644
index 0000000000000..08995439e51e9
--- /dev/null
+++ b/llvm/lib/CodeGen/WindowsHotPatch.cpp
@@ -0,0 +1,242 @@
+//===------ WindowsHotPatch.cpp - Support for Windows hotpatching 
---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Marks functions with the `marked_for_windows_hot_patching` attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "windows-hot-patch"
+
+// A file containing list of mangled function names to mark for hot patching.
+static cl::opt<std::string> LLVMMSHotPatchFunctionsFile(
+    "ms-hotpatch-functions-file", cl::value_desc("filename"),
+    cl::desc("A file containing list of mangled function names to mark for hot 
"
+             "patching"));
+
+// A list of mangled function names to mark for hot patching.
+static cl::list<std::string> LLVMMSHotPatchFunctionsList(
+    "ms-hotpatch-functions-list", cl::value_desc("list"),
+    cl::desc("A list of mangled function names to mark for hot patching"),
+    cl::CommaSeparated);
+
+namespace {
+
+class WindowsHotPatch : public ModulePass {
+  struct GlobalVariableUse {
+    GlobalVariable *GV;
+    Instruction *User;
+    unsigned Op;
+  };
+
+public:
+  static char ID;
+
+  WindowsHotPatch() : ModulePass(ID) {
+    initializeWindowsHotPatchPass(*PassRegistry::getPassRegistry());
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesCFG();
+  }
+
+  bool runOnModule(Module &M) override;
+
+private:
+  bool
+  runOnFunction(Function &F,
+                SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping);
+  void replaceGlobalVariableUses(
+      Function &F, SmallVectorImpl<GlobalVariableUse> &GVUses,
+      SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping,
+      DIBuilder &DebugInfo);
+};
+
+} // end anonymous namespace
+
+char WindowsHotPatch::ID = 0;
+
+INITIALIZE_PASS(WindowsHotPatch, "windows-hot-patch",
+                "Mark functions for Windows hot patch support", false, false)
+ModulePass *llvm::createWindowsHotPatch() { return new WindowsHotPatch(); }
+
+// Find functions marked with Attribute::MarkedForWindowsHotPatching and modify
+// their code (if necessary) to account for accesses to global variables.
+bool WindowsHotPatch::runOnModule(Module &M) {
+  // The front end may have already marked functions for hot-patching. However,
+  // we also allow marking functions by passing -ms-hotpatch-functions-file or
+  // -ms-hotpatch-functions-list directly to LLVM. This allows hot-patching to
+  // work with languages that have not yet updated their front-ends.
+  if (!LLVMMSHotPatchFunctionsFile.empty() ||
+      !LLVMMSHotPatchFunctionsList.empty()) {
+    std::vector<std::string> HotPatchFunctionsList;
+
+    if (!LLVMMSHotPatchFunctionsFile.empty()) {
+      auto BufOrErr = llvm::MemoryBuffer::getFile(LLVMMSHotPatchFunctionsFile);
+      if (BufOrErr) {
+        const llvm::MemoryBuffer &FileBuffer = **BufOrErr;
+        for (llvm::line_iterator I(FileBuffer.getMemBufferRef(), true), E;
+             I != E; ++I) {
+          HotPatchFunctionsList.push_back(std::string{*I});
+        }
+      } else {
+        M.getContext().diagnose(llvm::DiagnosticInfoGeneric{
+            llvm::Twine("failed to open hotpatch functions file "
+                        "(--ms-hotpatch-functions-file): ") +
+            LLVMMSHotPatchFunctionsFile + llvm::Twine(" : ") +
+            BufOrErr.getError().message()});
+      }
+    }
+
+    if (!LLVMMSHotPatchFunctionsList.empty()) {
+      for (const auto &FuncName : LLVMMSHotPatchFunctionsList) {
+        HotPatchFunctionsList.push_back(FuncName);
+      }
+    }
+
+    // Build a set for quick lookups. This points into HotPatchFunctionsList, 
so
+    // HotPatchFunctionsList must live longer than HotPatchFunctionsSet.
+    llvm::SmallSet<llvm::StringRef, 16> HotPatchFunctionsSet;
+    for (const auto &FuncName : HotPatchFunctionsList) {
+      HotPatchFunctionsSet.insert(llvm::StringRef{FuncName});
+    }
+
+    // Iterate through all of the functions and check whether they need to be
+    // marked for hotpatching using the list provided directly to LLVM.
+    for (auto &F : M.functions()) {
+      // Ignore declarations that are not definitions.
+      if (F.isDeclarationForLinker()) {
+        continue;
+      }
+
+      if (HotPatchFunctionsSet.contains(F.getName())) {
+        F.addFnAttr(Attribute::MarkedForWindowsHotPatching);
+      }
+    }
+  }
+
+  SmallDenseMap<GlobalVariable *, GlobalVariable *> RefMapping;
+  bool MadeChanges = false;
+  for (auto &F : M.functions()) {
+    if (F.hasFnAttribute(Attribute::MarkedForWindowsHotPatching)) {
+      if (runOnFunction(F, RefMapping)) {
+        MadeChanges = true;
+      }
+    }
+  }
+  return MadeChanges;
+}
+
+// Processes a function that is marked for hot-patching.
+//
+// If a function is marked for hot-patching, we generate an S_HOTPATCHFUNC
+// CodeView debug symbol. Tools that generate hot-patches look for
+// S_HOTPATCHFUNC in final PDBs so that they can find functions that have been
+// hot-patched and so that they can distinguish hot-patched functions from
+// non-hot-patched functions.
+//
+// Also, in functions that are hot-patched, we must indirect all access to
+// (mutable) global variables through a pointer. This pointer may point into 
the
+// unpatched ("base") binary or may point into the patched image, depending on
+// whether a hot-patch was loaded as a patch or as a base image.  These
+// indirections go through a new global variable, `named __ref_<Foo>` where
+// `<Foo>` is the original symbol name of the global variable.
+//
+// This function handles rewriting accesses to global variables, but the
+// generation of S_HOTPATCHFUNC occurs in
+// CodeViewDebug::emitHotPatchInformation().
+//
+// Returns true if any changes were made to the function.
+bool WindowsHotPatch::runOnFunction(
+    Function &F,
+    SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping) {
+  SmallVector<GlobalVariableUse, 32> GVUses;
+  for (auto &I : instructions(F)) {
+    for (auto &U : I.operands()) {
+      // Discover all uses of GlobalVariable, these will need to be replaced.
+      GlobalVariable *GV = dyn_cast<GlobalVariable>(&U);
+      if ((GV != nullptr) &&
+          !GV->hasAttribute(Attribute::AllowDirectAccessInHotPatchFunction)) {
+        unsigned OpNo = &U - I.op_begin();
+        GVUses.push_back({GV, &I, OpNo});
+      }
+    }
+  }
+
+  if (!GVUses.empty()) {
+    const llvm::DISubprogram *Subprogram = F.getSubprogram();
+    DIBuilder DebugInfo{*F.getParent(), true,
+                        Subprogram != nullptr ? Subprogram->getUnit()
+                                              : nullptr};
+    replaceGlobalVariableUses(F, GVUses, RefMapping, DebugInfo);
+    if (Subprogram != nullptr) {
+      DebugInfo.finalize();
+    }
+    return true;
+  } else {
+    return false;
+  }
+}
+
+void WindowsHotPatch::replaceGlobalVariableUses(
+    Function &F, SmallVectorImpl<GlobalVariableUse> &GVUses,
+    SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping,
+    DIBuilder &DebugInfo) {
+  for (auto &GVUse : GVUses) {
+    IRBuilder<> Builder(GVUse.User);
+
+    // Get or create a new global variable that points to the old one and who's
+    // name begins with `__ref_`.
+    GlobalVariable *&ReplaceWithRefGV =
+        RefMapping.try_emplace(GVUse.GV).first->second;
+    if (ReplaceWithRefGV == nullptr) {
+      Constant *AddrOfOldGV = ConstantExpr::getGetElementPtr(
+          Builder.getPtrTy(), GVUse.GV, ArrayRef<Value *>{});
+      ReplaceWithRefGV =
+          new GlobalVariable(*F.getParent(), Builder.getPtrTy(), true,
+                             GlobalValue::InternalLinkage, AddrOfOldGV,
+                             Twine("__ref_").concat(GVUse.GV->getName()),
+                             nullptr, GlobalVariable::NotThreadLocal);
+
+      // Create debug info for the replacement global variable.
+      DISubprogram *SP = F.getSubprogram();
+      DataLayout Layout = F.getParent()->getDataLayout();
+      DIType *DebugType = DebugInfo.createPointerType(
+          nullptr, Layout.getTypeSizeInBits(GVUse.GV->getValueType()));
+      DIGlobalVariableExpression *GVE =
+          DebugInfo.createGlobalVariableExpression(
+              SP != nullptr ? SP->getUnit() : nullptr,
+              ReplaceWithRefGV->getName(), StringRef{},
+              SP != nullptr ? SP->getFile() : nullptr, /*LineNo*/ 0, DebugType,
+              /*IsLocalToUnit*/ false);
+      ReplaceWithRefGV->addDebugInfo(GVE);
+    }
+
+    // Now replace the use of that global variable with the new one (via a load
+    // since it is a pointer to the old global variable).
+    LoadInst *LoadedRefGV =
+        Builder.CreateLoad(ReplaceWithRefGV->getValueType(), ReplaceWithRefGV);
+    GVUse.User->setOperand(GVUse.Op, LoadedRefGV);
+  }
+}
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp 
b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index f56739db7c75f..9cb3bca8d6e5e 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -672,6 +672,13 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
   return Error::success();
 }
 
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+                                           HotPatchFuncSym &HotPatchFunc) {
+  printTypeIndex("Function", HotPatchFunc.Function);
+  W.printString("Name", HotPatchFunc.Name);
+  return Error::success();
+}
+
 Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
   W.printNumber("Length", CVR.length());
   return Error::success();
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp 
b/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
index b5e366b965a95..525343b90a3ae 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
@@ -496,6 +496,13 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
   return Error::success();
 }
 
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+                                            HotPatchFuncSym &HotPatchFunc) {
+  error(IO.mapInteger(HotPatchFunc.Function));
+  error(IO.mapStringZ(HotPatchFunc.Name));
+  return Error::success();
+}
+
 RegisterId codeview::decodeFramePtrReg(EncodedFramePtrReg EncodedReg,
                                        CPUType CPU) {
   assert(unsigned(EncodedReg) < 4);
diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp 
b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
index b15919f68725f..3056251809308 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -605,6 +605,11 @@ template <> void SymbolRecordImpl<JumpTableSym>::map(IO 
&IO) {
   IO.mapRequired("EntriesCount", Symbol.EntriesCount);
 }
 
+template <> void SymbolRecordImpl<HotPatchFuncSym>::map(IO &IO) {
+  IO.mapRequired("Function", Symbol.Function);
+  IO.mapRequired("Name", Symbol.Name);
+}
+
 } // end namespace detail
 } // end namespace CodeViewYAML
 } // end namespace llvm
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp 
b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index c4894c90c127f..37888210377f2 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -938,6 +938,8 @@ Function *CodeExtractor::constructFunctionDeclaration(
       case Attribute::CoroDestroyOnlyWhenComplete:
       case Attribute::CoroElideSafe:
       case Attribute::NoDivergenceSource:
+      case Attribute::MarkedForWindowsHotPatching:
+      case Attribute::AllowDirectAccessInHotPatchFunction:
         continue;
       // Those attributes should be safe to propagate to the extracted 
function.
       case Attribute::AlwaysInline:
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-attr.ll 
b/llvm/test/CodeGen/Generic/ms-hotpatch-attr.ll
new file mode 100644
index 0000000000000..08fbc073e0716
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/ms-hotpatch-attr.ll
@@ -0,0 +1,38 @@
+; This tests directly annotating a function with 
marked_for_windows_hot_patching.
+;
+; RUN: llc -mtriple=x86_64-windows < %s | FileCheck %s
+
+source_filename = ".\\ms-hotpatch-attr.ll"
+target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.36.32537"
+
+@some_global_var = external global i32
+
+define noundef i32 @this_gets_hotpatched() #0 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #0 = { marked_for_windows_hot_patching mustprogress noinline 
nounwind optnone uwtable }
+
+; CHECK: this_gets_hotpatched: # @this_gets_hotpatched
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: movq __ref_some_global_var(%rip), %rax
+; CHECK-NEXT: movl (%rax), %eax
+; CHECK-NEXT: addl $1, %eax
+; CHECK-NEXT: retq
+
+define noundef i32 @this_does_not_get_hotpatched() #1 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #1 = { mustprogress noinline nounwind optnone uwtable }
+
+; CHECK: this_does_not_get_hotpatched: # @this_does_not_get_hotpatched
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: movl some_global_var(%rip), %eax
+; CHECK-NEXT: addl $1, %eax
+; CHECK-NEXT: retq
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-bad-file.ll 
b/llvm/test/CodeGen/Generic/ms-hotpatch-bad-file.ll
new file mode 100644
index 0000000000000..59a83c9040a41
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/ms-hotpatch-bad-file.ll
@@ -0,0 +1,16 @@
+; RUN: not llc -mtriple=x86_64-windows 
--ms-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt
 < %s 2>&1 | FileCheck %s
+; CHECK: failed to open hotpatch functions file
+
+source_filename = ".\\ms-hotpatch.ll"
+target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.36.32537"
+
+@some_global_var = external global i32
+
+define noundef i32 @this_gets_hotpatched() #0 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #0 = { marked_for_windows_hot_patching mustprogress noinline 
nounwind optnone uwtable }
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-direct-global-access.ll 
b/llvm/test/CodeGen/Generic/ms-hotpatch-direct-global-access.ll
new file mode 100644
index 0000000000000..eb8754ee6c3f7
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/ms-hotpatch-direct-global-access.ll
@@ -0,0 +1,39 @@
+; This tests hotpatching functions that bypass double-indirection for global 
variables.
+;
+; RUN: llc -mtriple=x86_64-windows < %s | FileCheck %s
+
+source_filename = ".\\ms-hotpatch-direct-global-access.ll"
+target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.36.32537"
+
+@some_global_var = external global i32 #2
+
+define noundef i32 @this_gets_hotpatched() #0 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #0 = { marked_for_windows_hot_patching mustprogress noinline 
nounwind optnone uwtable }
+
+; CHECK: this_gets_hotpatched: # @this_gets_hotpatched
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: movl some_global_var(%rip), %eax
+; CHECK-NEXT: addl $1, %eax
+; CHECK-NEXT: retq
+
+define noundef i32 @this_does_not_get_hotpatched() #1 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #1 = { mustprogress noinline nounwind optnone uwtable }
+
+attributes #2 = { allow_direct_access_in_hot_patch_function }
+
+; CHECK: this_does_not_get_hotpatched: # @this_does_not_get_hotpatched
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: movl some_global_var(%rip), %eax
+; CHECK-NEXT: addl $1, %eax
+; CHECK-NEXT: retq
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.ll 
b/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.ll
new file mode 100644
index 0000000000000..d02d1ae1bfed5
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.ll
@@ -0,0 +1,38 @@
+; This tests annotating a function with marked_for_windows_hot_patching by 
using --ms-hotpatch-functions-file.
+;
+; RUN: llc -mtriple=x86_64-windows 
--ms-hotpatch-functions-file=%S/ms-hotpatch-functions-file.txt < %s | FileCheck 
%s
+
+source_filename = ".\\ms-hotpatch-functions-file.ll"
+target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.36.32537"
+
+@some_global_var = external global i32
+
+define noundef i32 @this_gets_hotpatched() #0 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #0 = { mustprogress noinline nounwind optnone uwtable }
+
+; CHECK: this_gets_hotpatched: # @this_gets_hotpatched
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: movq __ref_some_global_var(%rip), %rax
+; CHECK-NEXT: movl (%rax), %eax
+; CHECK-NEXT: addl $1, %eax
+; CHECK-NEXT: retq
+
+define noundef i32 @this_does_not_get_hotpatched() #1 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #1 = { mustprogress noinline nounwind optnone uwtable }
+
+; CHECK: this_does_not_get_hotpatched: # @this_does_not_get_hotpatched
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: movl some_global_var(%rip), %eax
+; CHECK-NEXT: addl $1, %eax
+; CHECK-NEXT: retq
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.txt 
b/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.txt
new file mode 100644
index 0000000000000..2512ba3881c66
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.txt
@@ -0,0 +1 @@
+this_gets_hotpatched
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-list.ll 
b/llvm/test/CodeGen/Generic/ms-hotpatch-functions-list.ll
new file mode 100644
index 0000000000000..c5565824cbe6c
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/ms-hotpatch-functions-list.ll
@@ -0,0 +1,38 @@
+; This tests annotating a function with marked_for_windows_hot_patching by 
using --ms-hotpatch-functions-list.
+;
+; RUN: llc -mtriple=x86_64-windows 
--ms-hotpatch-functions-list=this_gets_hotpatched < %s | FileCheck %s
+
+source_filename = ".\\ms-hotpatch-functions-list.ll"
+target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.36.32537"
+
+@some_global_var = external global i32
+
+define noundef i32 @this_gets_hotpatched() #0 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #0 = { mustprogress noinline nounwind optnone uwtable }
+
+; CHECK: this_gets_hotpatched: # @this_gets_hotpatched
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: movq __ref_some_global_var(%rip), %rax
+; CHECK-NEXT: movl (%rax), %eax
+; CHECK-NEXT: addl $1, %eax
+; CHECK-NEXT: retq
+
+define noundef i32 @this_does_not_get_hotpatched() #1 {
+    %1 = load i32, ptr @some_global_var
+    %2 = add i32 %1, 1
+    ret i32 %2
+}
+
+attributes #1 = { mustprogress noinline nounwind optnone uwtable }
+
+; CHECK: this_does_not_get_hotpatched: # @this_does_not_get_hotpatched
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: movl some_global_var(%rip), %eax
+; CHECK-NEXT: addl $1, %eax
+; CHECK-NEXT: retq
diff --git a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp 
b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
index 479d025835188..66a091f50d6b2 100644
--- a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
@@ -955,3 +955,11 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
       JumpTable.EntriesCount);
   return Error::success();
 }
+
+Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
+                                            HotPatchFuncSym &JumpTable) {
+  AutoIndent Indent(P, 7);
+  P.formatLine("function = {0}, name = {1}", typeIndex(JumpTable.Function),
+               JumpTable.Name);
+  return Error::success();
+}

>From 6e727ebfe44b9dfa4221a7fafa4749283c42953e Mon Sep 17 00:00:00 2001
From: sivadeilra <arlie.da...@microsoft.com>
Date: Tue, 13 May 2025 10:37:14 -0700
Subject: [PATCH 2/4] Rename to Secure, in LLVM

---
 llvm/include/llvm/CodeGen/Passes.h            |   2 +-
 llvm/include/llvm/InitializePasses.h          |   2 +-
 llvm/lib/CodeGen/CMakeLists.txt               |   2 +-
 llvm/lib/CodeGen/TargetPassConfig.cpp         |   2 +-
 ...Patch.cpp => WindowsSecureHotPatching.cpp} | 110 ++++++++++++------
 .../Generic/ms-hotpatch-functions-file.txt    |   1 -
 ...tch-attr.ll => ms-secure-hotpatch-attr.ll} |   0
 ...file.ll => ms-secure-hotpatch-bad-file.ll} |   2 +-
 ...s-secure-hotpatch-direct-global-access.ll} |   0
 ...l => ms-secure-hotpatch-functions-file.ll} |   3 +-
 ...l => ms-secure-hotpatch-functions-list.ll} |   2 +-
 11 files changed, 80 insertions(+), 46 deletions(-)
 rename llvm/lib/CodeGen/{WindowsHotPatch.cpp => WindowsSecureHotPatching.cpp} 
(62%)
 delete mode 100644 llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.txt
 rename llvm/test/CodeGen/Generic/{ms-hotpatch-attr.ll => 
ms-secure-hotpatch-attr.ll} (100%)
 rename llvm/test/CodeGen/Generic/{ms-hotpatch-bad-file.ll => 
ms-secure-hotpatch-bad-file.ll} (75%)
 rename llvm/test/CodeGen/Generic/{ms-hotpatch-direct-global-access.ll => 
ms-secure-hotpatch-direct-global-access.ll} (100%)
 rename llvm/test/CodeGen/Generic/{ms-hotpatch-functions-file.ll => 
ms-secure-hotpatch-functions-file.ll} (86%)
 rename llvm/test/CodeGen/Generic/{ms-hotpatch-functions-list.ll => 
ms-secure-hotpatch-functions-list.ll} (91%)

diff --git a/llvm/include/llvm/CodeGen/Passes.h 
b/llvm/include/llvm/CodeGen/Passes.h
index c4163617da5ae..d0cee3ddf268d 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -619,7 +619,7 @@ namespace llvm {
   FunctionPass *createKCFIPass();
 
   /// Creates Windows Hot Patch pass. \see WindowsHotPatch.cpp
-  ModulePass *createWindowsHotPatch();
+  ModulePass *createWindowsSecureHotPatching();
 } // End llvm namespace
 
 #endif
diff --git a/llvm/include/llvm/InitializePasses.h 
b/llvm/include/llvm/InitializePasses.h
index 53722dd10fac7..3b204d79a21d6 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -323,7 +323,7 @@ void initializeVirtRegMapWrapperLegacyPass(PassRegistry &);
 void initializeVirtRegRewriterLegacyPass(PassRegistry &);
 void initializeWasmEHPreparePass(PassRegistry &);
 void initializeWinEHPreparePass(PassRegistry &);
-void initializeWindowsHotPatchPass(PassRegistry &);
+void initializeWindowsSecureHotPatchingPass(PassRegistry &);
 void initializeWriteBitcodePassPass(PassRegistry &);
 void initializeXRayInstrumentationLegacyPass(PassRegistry &);
 
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index f18f085b0450b..f8f9bbba53e43 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -250,7 +250,7 @@ add_llvm_component_library(LLVMCodeGen
   VirtRegMap.cpp
   WasmEHPrepare.cpp
   WindowScheduler.cpp
-  WindowsHotPatch.cpp
+  WindowsSecureHotPatching.cpp
   WinEHPrepare.cpp
   XRayInstrumentation.cpp
   ${GeneratedMLSources}
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp 
b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 1d93efc21fbab..0f6ac3ee12316 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -895,7 +895,7 @@ void TargetPassConfig::addIRPasses() {
     addPass(createGlobalMergeFuncPass());
 
   if (TM->getTargetTriple().isOSBinFormatCOFF())
-    addPass(createWindowsHotPatch());
+    addPass(createWindowsSecureHotPatching());
 }
 
 /// Turn exception handling constructs into something the code generators can
diff --git a/llvm/lib/CodeGen/WindowsHotPatch.cpp 
b/llvm/lib/CodeGen/WindowsSecureHotPatching.cpp
similarity index 62%
rename from llvm/lib/CodeGen/WindowsHotPatch.cpp
rename to llvm/lib/CodeGen/WindowsSecureHotPatching.cpp
index 08995439e51e9..977f950ee6ea6 100644
--- a/llvm/lib/CodeGen/WindowsHotPatch.cpp
+++ b/llvm/lib/CodeGen/WindowsSecureHotPatching.cpp
@@ -6,7 +6,50 @@
 //
 
//===----------------------------------------------------------------------===//
 //
-// Marks functions with the `marked_for_windows_hot_patching` attribute.
+// Provides support for the Windows "Secure Hot-Patching" feature.
+//
+// Windows contains technology, called "Secure Hot-Patching" (SHP), for 
securely applying
+// hot-patches to a running system. Hot-patches may be applied to the kernel, 
kernel-mode
+// components, device drivers, user-mode system services, etc.
+//
+// SHP relies on integration between many tools, including compiler, linker, 
hot-patch
+// generation tools, and the Windows kernel. This file implements that part of 
the workflow
+// needed in compilers / code generators.
+//
+// SHP is not intended for productivity scenarios, such as Edit-and-Continue 
or interactive
+// development. SHP is intended to minimize downtime during installation of 
Windows OS patches.
+//
+// In order to work with SHP, LLVM must do all of the following:
+//
+// * On some architectures (X86, AMD64), the function prolog must begin with 
hot-patchable
+//   instructions. This is handled by the MSVC `/hotpatch` option and the 
equivalent `-fms-hotpatch`
+//   function. This is necessary because we generally cannot anticipate which 
functions will need
+//   to be patched in the future. This option ensures that a function can be 
hot-patched in the
+//   future, but does not actually generate any hot-patch for it.
+//
+// * For a selected set of functions that are being hot-patched (which are 
identified using
+//   command-line options), LLVM must generate the `S_HOTPATCHFUNC` CodeView 
record (symbol).
+//   This record indicates that a function was compiled with hot-patching 
enabled.
+//
+//   This implementation uses the `MarkedForWindowsHotPatching` attribute to 
annotate those
+//   functions that were marked for hot-patching by command-line parameters. 
The attribute
+//   may be specified by a language front-end by setting an attribute when a 
function is created
+//   in LLVM IR, or it may be set by passing LLVM arguments.
+//
+// * For those functions that are hot-patched, LLVM must rewrite references to 
global variables
+//   so that they are indirected through a `__ref_*` pointer variable.  For 
each global variable,
+//   that is accessed by a hot-patched function, e.g. `FOO`, a `__ref_FOO` 
global pointer variable
+//   is created and all references to the original `FOO` are rewritten as 
dereferences of the
+//   `__ref_FOO` pointer.
+//
+//   Some globals do not need `__ref_*` indirection. The pointer indirection 
behavior can be
+//   disabled for these globals by marking them with the 
`AllowDirectAccessInHotPatchFunction`.
+//
+// References
+//
+// * "Hotpatching on Windows": 
https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541
+// * "Hotpatch for Windows client now available": 
https://techcommunity.microsoft.com/blog/windows-itpro-blog/hotpatch-for-windows-client-now-available/4399808
+// * "Get hotpatching for Windows Server": 
https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/?msockid=19a6f8f09bd160ac0b18ed449afc614b
 //
 
//===----------------------------------------------------------------------===//
 
@@ -30,20 +73,19 @@ using namespace llvm;
 #define DEBUG_TYPE "windows-hot-patch"
 
 // A file containing list of mangled function names to mark for hot patching.
-static cl::opt<std::string> LLVMMSHotPatchFunctionsFile(
-    "ms-hotpatch-functions-file", cl::value_desc("filename"),
-    cl::desc("A file containing list of mangled function names to mark for hot 
"
-             "patching"));
+static cl::opt<std::string> LLVMMSSecureHotPatchFunctionsFile(
+    "ms-secure-hotpatch-functions-file", cl::value_desc("filename"),
+    cl::desc("A file containing list of mangled function names to mark for 
Windows Secure Hot-Patching"));
 
 // A list of mangled function names to mark for hot patching.
-static cl::list<std::string> LLVMMSHotPatchFunctionsList(
-    "ms-hotpatch-functions-list", cl::value_desc("list"),
-    cl::desc("A list of mangled function names to mark for hot patching"),
+static cl::list<std::string> LLVMMSSecureHotPatchFunctionsList(
+    "ms-secure-hotpatch-functions-list", cl::value_desc("list"),
+    cl::desc("A list of mangled function names to mark for Windows Secure 
Hot-Patching"),
     cl::CommaSeparated);
 
 namespace {
 
-class WindowsHotPatch : public ModulePass {
+class WindowsSecureHotPatching : public ModulePass {
   struct GlobalVariableUse {
     GlobalVariable *GV;
     Instruction *User;
@@ -53,8 +95,8 @@ class WindowsHotPatch : public ModulePass {
 public:
   static char ID;
 
-  WindowsHotPatch() : ModulePass(ID) {
-    initializeWindowsHotPatchPass(*PassRegistry::getPassRegistry());
+  WindowsSecureHotPatching() : ModulePass(ID) {
+    initializeWindowsSecureHotPatchingPass(*PassRegistry::getPassRegistry());
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -75,64 +117,58 @@ class WindowsHotPatch : public ModulePass {
 
 } // end anonymous namespace
 
-char WindowsHotPatch::ID = 0;
+char WindowsSecureHotPatching::ID = 0;
 
-INITIALIZE_PASS(WindowsHotPatch, "windows-hot-patch",
+INITIALIZE_PASS(WindowsSecureHotPatching, "windows-secure-hot-patch",
                 "Mark functions for Windows hot patch support", false, false)
-ModulePass *llvm::createWindowsHotPatch() { return new WindowsHotPatch(); }
+ModulePass *llvm::createWindowsSecureHotPatching() { return new 
WindowsSecureHotPatching(); }
 
 // Find functions marked with Attribute::MarkedForWindowsHotPatching and modify
 // their code (if necessary) to account for accesses to global variables.
-bool WindowsHotPatch::runOnModule(Module &M) {
+bool WindowsSecureHotPatching::runOnModule(Module &M) {
   // The front end may have already marked functions for hot-patching. However,
   // we also allow marking functions by passing -ms-hotpatch-functions-file or
   // -ms-hotpatch-functions-list directly to LLVM. This allows hot-patching to
   // work with languages that have not yet updated their front-ends.
-  if (!LLVMMSHotPatchFunctionsFile.empty() ||
-      !LLVMMSHotPatchFunctionsList.empty()) {
+  if (!LLVMMSSecureHotPatchFunctionsFile.empty() ||
+      !LLVMMSSecureHotPatchFunctionsList.empty()) {
     std::vector<std::string> HotPatchFunctionsList;
 
-    if (!LLVMMSHotPatchFunctionsFile.empty()) {
-      auto BufOrErr = llvm::MemoryBuffer::getFile(LLVMMSHotPatchFunctionsFile);
+    if (!LLVMMSSecureHotPatchFunctionsFile.empty()) {
+      auto BufOrErr = 
llvm::MemoryBuffer::getFile(LLVMMSSecureHotPatchFunctionsFile);
       if (BufOrErr) {
         const llvm::MemoryBuffer &FileBuffer = **BufOrErr;
         for (llvm::line_iterator I(FileBuffer.getMemBufferRef(), true), E;
-             I != E; ++I) {
+             I != E; ++I)
           HotPatchFunctionsList.push_back(std::string{*I});
-        }
       } else {
         M.getContext().diagnose(llvm::DiagnosticInfoGeneric{
             llvm::Twine("failed to open hotpatch functions file "
                         "(--ms-hotpatch-functions-file): ") +
-            LLVMMSHotPatchFunctionsFile + llvm::Twine(" : ") +
+            LLVMMSSecureHotPatchFunctionsFile + llvm::Twine(" : ") +
             BufOrErr.getError().message()});
       }
     }
 
-    if (!LLVMMSHotPatchFunctionsList.empty()) {
-      for (const auto &FuncName : LLVMMSHotPatchFunctionsList) {
+    if (!LLVMMSSecureHotPatchFunctionsList.empty())
+      for (const auto &FuncName : LLVMMSSecureHotPatchFunctionsList)
         HotPatchFunctionsList.push_back(FuncName);
-      }
-    }
 
     // Build a set for quick lookups. This points into HotPatchFunctionsList, 
so
     // HotPatchFunctionsList must live longer than HotPatchFunctionsSet.
     llvm::SmallSet<llvm::StringRef, 16> HotPatchFunctionsSet;
-    for (const auto &FuncName : HotPatchFunctionsList) {
+    for (const auto &FuncName : HotPatchFunctionsList)
       HotPatchFunctionsSet.insert(llvm::StringRef{FuncName});
-    }
 
     // Iterate through all of the functions and check whether they need to be
     // marked for hotpatching using the list provided directly to LLVM.
     for (auto &F : M.functions()) {
       // Ignore declarations that are not definitions.
-      if (F.isDeclarationForLinker()) {
+      if (F.isDeclarationForLinker())
         continue;
-      }
 
-      if (HotPatchFunctionsSet.contains(F.getName())) {
+      if (HotPatchFunctionsSet.contains(F.getName()))
         F.addFnAttr(Attribute::MarkedForWindowsHotPatching);
-      }
     }
   }
 
@@ -140,9 +176,8 @@ bool WindowsHotPatch::runOnModule(Module &M) {
   bool MadeChanges = false;
   for (auto &F : M.functions()) {
     if (F.hasFnAttribute(Attribute::MarkedForWindowsHotPatching)) {
-      if (runOnFunction(F, RefMapping)) {
+      if (runOnFunction(F, RefMapping))
         MadeChanges = true;
-      }
     }
   }
   return MadeChanges;
@@ -168,7 +203,7 @@ bool WindowsHotPatch::runOnModule(Module &M) {
 // CodeViewDebug::emitHotPatchInformation().
 //
 // Returns true if any changes were made to the function.
-bool WindowsHotPatch::runOnFunction(
+bool WindowsSecureHotPatching::runOnFunction(
     Function &F,
     SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping) {
   SmallVector<GlobalVariableUse, 32> GVUses;
@@ -190,16 +225,15 @@ bool WindowsHotPatch::runOnFunction(
                         Subprogram != nullptr ? Subprogram->getUnit()
                                               : nullptr};
     replaceGlobalVariableUses(F, GVUses, RefMapping, DebugInfo);
-    if (Subprogram != nullptr) {
+    if (Subprogram != nullptr)
       DebugInfo.finalize();
-    }
     return true;
   } else {
     return false;
   }
 }
 
-void WindowsHotPatch::replaceGlobalVariableUses(
+void WindowsSecureHotPatching::replaceGlobalVariableUses(
     Function &F, SmallVectorImpl<GlobalVariableUse> &GVUses,
     SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping,
     DIBuilder &DebugInfo) {
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.txt 
b/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.txt
deleted file mode 100644
index 2512ba3881c66..0000000000000
--- a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.txt
+++ /dev/null
@@ -1 +0,0 @@
-this_gets_hotpatched
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-attr.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-attr.ll
similarity index 100%
rename from llvm/test/CodeGen/Generic/ms-hotpatch-attr.ll
rename to llvm/test/CodeGen/Generic/ms-secure-hotpatch-attr.ll
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-bad-file.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-bad-file.ll
similarity index 75%
rename from llvm/test/CodeGen/Generic/ms-hotpatch-bad-file.ll
rename to llvm/test/CodeGen/Generic/ms-secure-hotpatch-bad-file.ll
index 59a83c9040a41..4501863dd0bd2 100644
--- a/llvm/test/CodeGen/Generic/ms-hotpatch-bad-file.ll
+++ b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-bad-file.ll
@@ -1,4 +1,4 @@
-; RUN: not llc -mtriple=x86_64-windows 
--ms-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt
 < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple=x86_64-windows 
--ms-secure-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt
 < %s 2>&1 | FileCheck %s
 ; CHECK: failed to open hotpatch functions file
 
 source_filename = ".\\ms-hotpatch.ll"
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-direct-global-access.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-direct-global-access.ll
similarity index 100%
rename from llvm/test/CodeGen/Generic/ms-hotpatch-direct-global-access.ll
rename to llvm/test/CodeGen/Generic/ms-secure-hotpatch-direct-global-access.ll
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-file.ll
similarity index 86%
rename from llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.ll
rename to llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-file.ll
index d02d1ae1bfed5..eef572832c726 100644
--- a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-file.ll
+++ b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-file.ll
@@ -1,6 +1,7 @@
 ; This tests annotating a function with marked_for_windows_hot_patching by 
using --ms-hotpatch-functions-file.
 ;
-; RUN: llc -mtriple=x86_64-windows 
--ms-hotpatch-functions-file=%S/ms-hotpatch-functions-file.txt < %s | FileCheck 
%s
+; RUN: echo this_gets_hotpatched > %t.patch-functions.txt
+; RUN: llc -mtriple=x86_64-windows 
--ms-secure-hotpatch-functions-file=%t.patch-functions.txt < %s | FileCheck %s
 
 source_filename = ".\\ms-hotpatch-functions-file.ll"
 target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-list.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-list.ll
similarity index 91%
rename from llvm/test/CodeGen/Generic/ms-hotpatch-functions-list.ll
rename to llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-list.ll
index c5565824cbe6c..f841db41d3821 100644
--- a/llvm/test/CodeGen/Generic/ms-hotpatch-functions-list.ll
+++ b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-list.ll
@@ -1,6 +1,6 @@
 ; This tests annotating a function with marked_for_windows_hot_patching by 
using --ms-hotpatch-functions-list.
 ;
-; RUN: llc -mtriple=x86_64-windows 
--ms-hotpatch-functions-list=this_gets_hotpatched < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-windows 
--ms-secure-hotpatch-functions-list=this_gets_hotpatched < %s | FileCheck %s
 
 source_filename = ".\\ms-hotpatch-functions-list.ll"
 target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"

>From 25dcedc3c1dcb7548b309d6a5bd898b8cd0c0d62 Mon Sep 17 00:00:00 2001
From: sivadeilra <arlie.da...@microsoft.com>
Date: Tue, 13 May 2025 10:43:57 -0700
Subject: [PATCH 3/4] rename more integration tests

---
 clang/test/CodeGen/ms-hotpatch-functions.txt                   | 1 -
 .../{ms-hotpatch-bad-file.c => ms-secure-hotpatch-bad-file.c}  | 0
 .../{ms-hotpatch-cpp.cpp => ms-secure-hotpatch-cpp.cpp}        | 0
 .../CodeGen/{ms-hotpatch-lto.c => ms-secure-hotpatch-lto.c}    | 2 +-
 clang/test/CodeGen/{ms-hotpatch.c => ms-secure-hotpatch.c}     | 3 ++-
 llvm/test/CodeGen/Generic/ms-secure-hotpatch-attr.ll           | 2 +-
 llvm/test/CodeGen/Generic/ms-secure-hotpatch-bad-file.ll       | 2 +-
 .../CodeGen/Generic/ms-secure-hotpatch-direct-global-access.ll | 2 +-
 llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-file.ll | 2 +-
 llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-list.ll | 2 +-
 10 files changed, 8 insertions(+), 8 deletions(-)
 delete mode 100644 clang/test/CodeGen/ms-hotpatch-functions.txt
 rename clang/test/CodeGen/{ms-hotpatch-bad-file.c => 
ms-secure-hotpatch-bad-file.c} (100%)
 rename clang/test/CodeGen/{ms-hotpatch-cpp.cpp => ms-secure-hotpatch-cpp.cpp} 
(100%)
 rename clang/test/CodeGen/{ms-hotpatch-lto.c => ms-secure-hotpatch-lto.c} (92%)
 rename clang/test/CodeGen/{ms-hotpatch.c => ms-secure-hotpatch.c} (83%)

diff --git a/clang/test/CodeGen/ms-hotpatch-functions.txt 
b/clang/test/CodeGen/ms-hotpatch-functions.txt
deleted file mode 100644
index 2512ba3881c66..0000000000000
--- a/clang/test/CodeGen/ms-hotpatch-functions.txt
+++ /dev/null
@@ -1 +0,0 @@
-this_gets_hotpatched
diff --git a/clang/test/CodeGen/ms-hotpatch-bad-file.c 
b/clang/test/CodeGen/ms-secure-hotpatch-bad-file.c
similarity index 100%
rename from clang/test/CodeGen/ms-hotpatch-bad-file.c
rename to clang/test/CodeGen/ms-secure-hotpatch-bad-file.c
diff --git a/clang/test/CodeGen/ms-hotpatch-cpp.cpp 
b/clang/test/CodeGen/ms-secure-hotpatch-cpp.cpp
similarity index 100%
rename from clang/test/CodeGen/ms-hotpatch-cpp.cpp
rename to clang/test/CodeGen/ms-secure-hotpatch-cpp.cpp
diff --git a/clang/test/CodeGen/ms-hotpatch-lto.c 
b/clang/test/CodeGen/ms-secure-hotpatch-lto.c
similarity index 92%
rename from clang/test/CodeGen/ms-hotpatch-lto.c
rename to clang/test/CodeGen/ms-secure-hotpatch-lto.c
index 290f7695b02f6..e8791f1f0935e 100644
--- a/clang/test/CodeGen/ms-hotpatch-lto.c
+++ b/clang/test/CodeGen/ms-secure-hotpatch-lto.c
@@ -1,6 +1,6 @@
 // This verifies that hotpatch function attributes are correctly propagated 
through LLVM IR when compiling with LTO.
 //
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-file=%S/ms-hotpatch-functions.txt -flto /Fo%t.bc %s
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-list=this_gets_hotpatched -flto /Fo%t.bc %s
 // RUN: llvm-dis %t.bc -o - | FileCheck %s
 //
 // CHECK: ; Function Attrs: marked_for_windows_hot_patching mustprogress 
nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) 
uwtable
diff --git a/clang/test/CodeGen/ms-hotpatch.c 
b/clang/test/CodeGen/ms-secure-hotpatch.c
similarity index 83%
rename from clang/test/CodeGen/ms-hotpatch.c
rename to clang/test/CodeGen/ms-secure-hotpatch.c
index 79da105f4cec3..71ae2be34a500 100644
--- a/clang/test/CodeGen/ms-hotpatch.c
+++ b/clang/test/CodeGen/ms-secure-hotpatch.c
@@ -1,6 +1,7 @@
 // This verifies that hotpatch function attributes are correctly propagated 
when compiling directly to OBJ.
 //
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-file=%S/ms-hotpatch-functions.txt /Fo%t.obj %s
+// RUN: echo this_gets_hotpatched > %t.patch-functions.txt
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-file=%t.patch-functions.txt /Fo%t.obj %s
 // RUN: llvm-readobj --codeview %t.obj | FileCheck %s
 
 void this_might_have_side_effects();
diff --git a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-attr.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-attr.ll
index 08fbc073e0716..11d99bae1ca8c 100644
--- a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-attr.ll
+++ b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-attr.ll
@@ -2,7 +2,7 @@
 ;
 ; RUN: llc -mtriple=x86_64-windows < %s | FileCheck %s
 
-source_filename = ".\\ms-hotpatch-attr.ll"
+source_filename = ".\\ms-secure-hotpatch-attr.ll"
 target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc19.36.32537"
 
diff --git a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-bad-file.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-bad-file.ll
index 4501863dd0bd2..8f8624ea0de49 100644
--- a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-bad-file.ll
+++ b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-bad-file.ll
@@ -1,7 +1,7 @@
 ; RUN: not llc -mtriple=x86_64-windows 
--ms-secure-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt
 < %s 2>&1 | FileCheck %s
 ; CHECK: failed to open hotpatch functions file
 
-source_filename = ".\\ms-hotpatch.ll"
+source_filename = ".\\ms-secure-hotpatch.ll"
 target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc19.36.32537"
 
diff --git 
a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-direct-global-access.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-direct-global-access.ll
index eb8754ee6c3f7..960a76fe43f12 100644
--- a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-direct-global-access.ll
+++ b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-direct-global-access.ll
@@ -2,7 +2,7 @@
 ;
 ; RUN: llc -mtriple=x86_64-windows < %s | FileCheck %s
 
-source_filename = ".\\ms-hotpatch-direct-global-access.ll"
+source_filename = ".\\ms-secure-hotpatch-direct-global-access.ll"
 target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc19.36.32537"
 
diff --git a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-file.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-file.ll
index eef572832c726..bb79e08683aa7 100644
--- a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-file.ll
+++ b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-file.ll
@@ -3,7 +3,7 @@
 ; RUN: echo this_gets_hotpatched > %t.patch-functions.txt
 ; RUN: llc -mtriple=x86_64-windows 
--ms-secure-hotpatch-functions-file=%t.patch-functions.txt < %s | FileCheck %s
 
-source_filename = ".\\ms-hotpatch-functions-file.ll"
+source_filename = ".\\ms-secure-hotpatch-functions-file.ll"
 target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc19.36.32537"
 
diff --git a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-list.ll 
b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-list.ll
index f841db41d3821..b1da1a2db66dc 100644
--- a/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-list.ll
+++ b/llvm/test/CodeGen/Generic/ms-secure-hotpatch-functions-list.ll
@@ -2,7 +2,7 @@
 ;
 ; RUN: llc -mtriple=x86_64-windows 
--ms-secure-hotpatch-functions-list=this_gets_hotpatched < %s | FileCheck %s
 
-source_filename = ".\\ms-hotpatch-functions-list.ll"
+source_filename = ".\\ms-secure-hotpatch-functions-list.ll"
 target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc19.36.32537"
 

>From d015c8b1871bba466aed8e22dd7e1c63578b7cb6 Mon Sep 17 00:00:00 2001
From: sivadeilra <arlie.da...@microsoft.com>
Date: Tue, 13 May 2025 11:08:02 -0700
Subject: [PATCH 4/4] finish renaming to SHP

---
 clang/include/clang/Basic/CodeGenOptions.h    |  8 +++----
 clang/include/clang/Driver/Options.td         | 22 +++++++++++--------
 clang/lib/CodeGen/CodeGenModule.cpp           | 22 +++++++++----------
 clang/lib/Driver/ToolChains/Clang.cpp         | 10 ++++-----
 .../CodeGen/ms-secure-hotpatch-bad-file.c     |  4 ++--
 clang/test/CodeGen/ms-secure-hotpatch-cpp.cpp |  2 +-
 clang/test/CodeGen/ms-secure-hotpatch-lto.c   |  2 +-
 clang/test/CodeGen/ms-secure-hotpatch.c       |  2 +-
 8 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index b0efc445b8450..5a5deb03847f1 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -502,12 +502,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// A list of functions that are replacable by the loader.
   std::vector<std::string> LoaderReplaceableFunctionNames;
   /// The name of a file that contains functions which will be compiled for
-  /// hotpatching. See -fms-hot-patch-functions-file.
-  std::string MSHotPatchFunctionsFile;
+  /// hotpatching. See -fms-secure-hotpatch-functions-file.
+  std::string MSSecureHotPatchFunctionsFile;
 
   /// A list of functions which will be compiled for hotpatching.
-  /// See -fms-hot-patch-functions-list.
-  std::vector<std::string> MSHotPatchFunctionsList;
+  /// See -fms-secure-hotpatch-functions-list.
+  std::vector<std::string> MSSecureHotPatchFunctionsList;
 
 public:
   // Define accessors/mutators for code generation options of enumeration type.
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 9d1931381dee7..d47f88bf4eb8f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3830,20 +3830,24 @@ def fms_hotpatch : Flag<["-"], "fms-hotpatch">, 
Group<f_Group>,
   Visibility<[ClangOption, CC1Option, CLOption]>,
   HelpText<"Ensure that all functions can be hotpatched at runtime">,
   MarshallingInfoFlag<CodeGenOpts<"HotPatch">>;
-def fms_hotpatch_functions_file
-    : Joined<["-"], "fms-hotpatch-functions-file=">,
+
+// See llvm/lib/CodeGen/WindowsSecureHotPatching.cpp
+def fms_secure_hotpatch_functions_file
+    : Joined<["-"], "fms-secure-hotpatch-functions-file=">,
       Group<f_Group>,
       Visibility<[ClangOption, CC1Option, CLOption]>,
-      MarshallingInfoString<CodeGenOpts<"MSHotPatchFunctionsFile">>,
-      HelpText<"Path to a file that contains a list of mangled symbol names of 
"
-               "functions that should be hot-patched">;
-def fms_hotpatch_functions_list
-    : CommaJoined<["-"], "fms-hotpatch-functions-list=">,
+      MarshallingInfoString<CodeGenOpts<"MSSecureHotPatchFunctionsFile">>,
+      HelpText<"Path to a file that contains a list of mangled names of "
+               "functions that should be hot-patched for Windows Secure "
+               "Hot-Patching">;
+def fms_secure_hotpatch_functions_list
+    : CommaJoined<["-"], "fms-secure-hotpatch-functions-list=">,
       Group<f_Group>,
       Visibility<[ClangOption, CC1Option, CLOption]>,
-      MarshallingInfoStringVector<CodeGenOpts<"MSHotPatchFunctionsList">>,
+      
MarshallingInfoStringVector<CodeGenOpts<"MSSecureHotPatchFunctionsList">>,
       HelpText<"List of mangled symbol names of functions that should be "
-               "hot-patched">;
+               "hot-patched for Windows Secure Hot-Patching">;
+
 def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Override the default ABI to return all structs on the stack">;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index aa11487c4dce1..81eced29305fd 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -454,35 +454,33 @@ CodeGenModule::CodeGenModule(ASTContext &C,
     getModule().addModuleFlag(llvm::Module::Error, "NumRegisterParameters",
                               CodeGenOpts.NumRegisterParameters);
 
-  // If there are any functions that are marked for Windows hot-patching,
+  // If there are any functions that are marked for Windows secure 
hot-patching,
   // then build the list of functions now.
-  if (!CGO.MSHotPatchFunctionsFile.empty() ||
-      !CGO.MSHotPatchFunctionsList.empty()) {
-    if (!CGO.MSHotPatchFunctionsFile.empty()) {
-      auto BufOrErr = llvm::MemoryBuffer::getFile(CGO.MSHotPatchFunctionsFile);
+  if (!CGO.MSSecureHotPatchFunctionsFile.empty() ||
+      !CGO.MSSecureHotPatchFunctionsList.empty()) {
+    if (!CGO.MSSecureHotPatchFunctionsFile.empty()) {
+      auto BufOrErr =
+          llvm::MemoryBuffer::getFile(CGO.MSSecureHotPatchFunctionsFile);
       if (BufOrErr) {
         const llvm::MemoryBuffer &FileBuffer = **BufOrErr;
         for (llvm::line_iterator I(FileBuffer.getMemBufferRef(), true), E;
-             I != E; ++I) {
+             I != E; ++I)
           this->MSHotPatchFunctions.push_back(std::string{*I});
-        }
       } else {
         auto &DE = Context.getDiagnostics();
         unsigned DiagID =
             DE.getCustomDiagID(DiagnosticsEngine::Error,
                                "failed to open hotpatch functions file "
                                "(-fms-hotpatch-functions-file): %0 : %1");
-        DE.Report(DiagID) << CGO.MSHotPatchFunctionsFile
+        DE.Report(DiagID) << CGO.MSSecureHotPatchFunctionsFile
                           << BufOrErr.getError().message();
       }
     }
 
-    for (const auto &FuncName : CGO.MSHotPatchFunctionsList) {
+    for (const auto &FuncName : CGO.MSSecureHotPatchFunctionsList)
       this->MSHotPatchFunctions.push_back(FuncName);
-    }
 
-    std::sort(this->MSHotPatchFunctions.begin(),
-              this->MSHotPatchFunctions.end());
+    llvm::sort(this->MSHotPatchFunctions);
   }
 }
 
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 6a38a9ada42ec..574ebc26bc56f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6946,15 +6946,13 @@ void Clang::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   Args.AddLastArg(CmdArgs, options::OPT_fms_hotpatch);
 
-  if (Arg *A = Args.getLastArg(options::OPT_fms_hotpatch_functions_file)) {
-    Args.AddLastArg(CmdArgs, options::OPT_fms_hotpatch_functions_file);
-  }
+  if (Arg *A = 
Args.getLastArg(options::OPT_fms_secure_hotpatch_functions_file))
+    Args.AddLastArg(CmdArgs, options::OPT_fms_secure_hotpatch_functions_file);
 
   for (const auto &A :
-       Args.getAllArgValues(options::OPT_fms_hotpatch_functions_list)) {
+       Args.getAllArgValues(options::OPT_fms_secure_hotpatch_functions_list))
     CmdArgs.push_back(
-        Args.MakeArgString("-fms-hotpatch-functions-list=" + Twine(A)));
-  }
+        Args.MakeArgString("-fms-secure-hotpatch-functions-list=" + Twine(A)));
 
   if (TC.SupportsProfiling()) {
     Args.AddLastArg(CmdArgs, options::OPT_pg);
diff --git a/clang/test/CodeGen/ms-secure-hotpatch-bad-file.c 
b/clang/test/CodeGen/ms-secure-hotpatch-bad-file.c
index 55304488175df..22f10b34d82fb 100644
--- a/clang/test/CodeGen/ms-secure-hotpatch-bad-file.c
+++ b/clang/test/CodeGen/ms-secure-hotpatch-bad-file.c
@@ -1,7 +1,7 @@
-// This verifies that we correctly handle a -fms-hotpatch-functions-file 
argument that points
+// This verifies that we correctly handle a 
-fms-secure-hotpatch-functions-file argument that points
 // to a missing file.
 //
-// RUN: not %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt
 /Fo%t.obj %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-secure-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt
 /Fo%t.obj %s 2>&1 | FileCheck %s
 // CHECK: failed to open hotpatch functions file
 
 void this_might_have_side_effects();
diff --git a/clang/test/CodeGen/ms-secure-hotpatch-cpp.cpp 
b/clang/test/CodeGen/ms-secure-hotpatch-cpp.cpp
index 26e11f429c962..c8112ad54baab 100644
--- a/clang/test/CodeGen/ms-secure-hotpatch-cpp.cpp
+++ b/clang/test/CodeGen/ms-secure-hotpatch-cpp.cpp
@@ -1,7 +1,7 @@
 // This verifies that hotpatch function attributes are correctly propagated 
when compiling directly to OBJ,
 // and that name mangling works as expected.
 //
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-list=?this_gets_hotpatched@@YAHXZ /Fo%t.obj %s
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-secure-hotpatch-functions-list=?this_gets_hotpatched@@YAHXZ /Fo%t.obj %s
 // RUN: llvm-readobj --codeview %t.obj | FileCheck %s
 
 void this_might_have_side_effects();
diff --git a/clang/test/CodeGen/ms-secure-hotpatch-lto.c 
b/clang/test/CodeGen/ms-secure-hotpatch-lto.c
index e8791f1f0935e..6771d3e9f49cf 100644
--- a/clang/test/CodeGen/ms-secure-hotpatch-lto.c
+++ b/clang/test/CodeGen/ms-secure-hotpatch-lto.c
@@ -1,6 +1,6 @@
 // This verifies that hotpatch function attributes are correctly propagated 
through LLVM IR when compiling with LTO.
 //
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-list=this_gets_hotpatched -flto /Fo%t.bc %s
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-secure-hotpatch-functions-list=this_gets_hotpatched -flto /Fo%t.bc %s
 // RUN: llvm-dis %t.bc -o - | FileCheck %s
 //
 // CHECK: ; Function Attrs: marked_for_windows_hot_patching mustprogress 
nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) 
uwtable
diff --git a/clang/test/CodeGen/ms-secure-hotpatch.c 
b/clang/test/CodeGen/ms-secure-hotpatch.c
index 71ae2be34a500..f170de851ae51 100644
--- a/clang/test/CodeGen/ms-secure-hotpatch.c
+++ b/clang/test/CodeGen/ms-secure-hotpatch.c
@@ -1,7 +1,7 @@
 // This verifies that hotpatch function attributes are correctly propagated 
when compiling directly to OBJ.
 //
 // RUN: echo this_gets_hotpatched > %t.patch-functions.txt
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-hotpatch-functions-file=%t.patch-functions.txt /Fo%t.obj %s
+// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 
-fms-secure-hotpatch-functions-file=%t.patch-functions.txt /Fo%t.obj %s
 // RUN: llvm-readobj --codeview %t.obj | FileCheck %s
 
 void this_might_have_side_effects();

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

Reply via email to