[clang] eddd94c - Reland "[clang][debug] port clang-cl /JMC flag to ELF"

Yuanfang Chen via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 7 21:55:55 PST 2022


Author: Yuanfang Chen
Date: 2022-03-07T21:55:41-08:00
New Revision: eddd94c27df609113af1d1b795d8483aa6dd662c

URL: https://github.com/llvm/llvm-project/commit/eddd94c27df609113af1d1b795d8483aa6dd662c
DIFF: https://github.com/llvm/llvm-project/commit/eddd94c27df609113af1d1b795d8483aa6dd662c.diff

LOG: Reland "[clang][debug] port clang-cl /JMC flag to ELF"

This relands commit 731347431976509823e38329a96fcbc69fe98cd2.

It failed on Windows/Mac because `-fjmc` is only checked for ELF targets.
Check the flag unconditionally instead and issue a warning for non-ELF targets.

Added: 
    llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll

Modified: 
    clang/include/clang/Basic/DiagnosticDriverKinds.td
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/test/Driver/cl-options.c
    clang/test/Driver/clang_f_opts.c
    llvm/lib/CodeGen/JMCInstrumenter.cpp
    llvm/test/Instrumentation/JustMyCode/jmc-instrument-x86.ll
    llvm/test/Instrumentation/JustMyCode/jmc-instrument.ll

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 1ac5bf844efe6..afedb37797e32 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -634,7 +634,12 @@ def err_drv_cuda_offload_only_emit_bc : Error<
   "CUDA offload target is supported only along with --emit-llvm">;
 
 def warn_drv_jmc_requires_debuginfo : Warning<
-  "/JMC requires debug info. Use '/Zi', '/Z7' or other debug options; option ignored">,
+  "%0 requires debug info. Use %1 or debug options that enable debugger's "
+  "stepping function; option ignored">,
+  InGroup<OptionIgnored>;
+
+def warn_drv_fjmc_for_elf_only : Warning<
+  "-fjmc works only for ELF; option ignored">,
   InGroup<OptionIgnored>;
 
 def err_drv_target_variant_invalid : Error<

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 06802ae424f7a..3b7011760a5b5 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1459,9 +1459,6 @@ def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>,
     HelpText<"Do not elide types when printing diagnostics">,
     MarshallingInfoNegativeFlag<DiagnosticOpts<"ElideType">>;
 def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>;
-def fjmc : Flag<["-"], "fjmc">, Group<f_Group>,Flags<[CC1Option]>,
-    HelpText<"Enable just-my-code debugging">,
-    MarshallingInfoFlag<CodeGenOpts<"JMCInstrument">>;
 defm eliminate_unused_debug_types : OptOutCC1FFlag<"eliminate-unused-debug-types",
   "Do not emit ", "Emit ", " debug info for defined but unused types">;
 def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>,
@@ -1923,6 +1920,10 @@ def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>,
 def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
   HelpText<"Inline functions which are (explicitly or implicitly) marked inline">;
 def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
+defm jmc : BoolFOption<"jmc",
+  CodeGenOpts<"JMCInstrument">, DefaultFalse,
+  PosFlag<SetTrue, [CC1Option], "Enable just-my-code debugging">,
+  NegFlag<SetFalse>>;
 def fglobal_isel : Flag<["-"], "fglobal-isel">, Group<f_clang_Group>,
   HelpText<"Enables the global instruction selector">;
 def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group<f_clang_Group>,

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 7cb8df6e44c04..89d8b0c4dc413 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5392,6 +5392,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                      types::isLLVMIR(InputType), CmdArgs, DebugInfoKind,
                      DwarfFission);
 
+  // This controls whether or not we perform JustMyCode instrumentation.
+  if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) {
+    if (TC.getTriple().isOSBinFormatELF()) {
+      if (DebugInfoKind >= codegenoptions::DebugInfoConstructor)
+        CmdArgs.push_back("-fjmc");
+      else
+        D.Diag(clang::diag::warn_drv_jmc_requires_debuginfo) << "-fjmc"
+                                                             << "-g";
+    } else {
+      D.Diag(clang::diag::warn_drv_fjmc_for_elf_only);
+    }
+  }
+
   // Add the split debug info name to the command lines here so we
   // can propagate it to the backend.
   bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) &&
@@ -7533,7 +7546,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
     if (*EmitCodeView && *DebugInfoKind >= codegenoptions::DebugInfoConstructor)
       CmdArgs.push_back("-fjmc");
     else
-      D.Diag(clang::diag::warn_drv_jmc_requires_debuginfo);
+      D.Diag(clang::diag::warn_drv_jmc_requires_debuginfo) << "/JMC"
+                                                           << "'/Zi', '/Z7'";
   }
 
   EHFlags EH = parseClangCLEHFlags(D, Args);

diff  --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c
index 4a8a1b3c5ac4e..f332cd83b26e4 100644
--- a/clang/test/Driver/cl-options.c
+++ b/clang/test/Driver/cl-options.c
@@ -779,7 +779,7 @@
 // TARGET: "-triple" "i686-pc-windows-msvc19.14.0"
 
 // RUN: %clang_cl /JMC /c -### -- %s 2>&1 | FileCheck %s --check-prefix JMCWARN
-// JMCWARN: /JMC requires debug info. Use '/Zi', '/Z7' or other debug options; option ignored
+// JMCWARN: /JMC requires debug info. Use '/Zi', '/Z7' or debug options that enable debugger's stepping function; option ignored
 
 // RUN: %clang_cl /JMC /c -### -- %s 2>&1 | FileCheck %s --check-prefix NOJMC
 // RUN: %clang_cl /JMC /Z7 /JMC- /c -### -- %s 2>&1 | FileCheck %s --check-prefix NOJMC

diff  --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index 4b0159b80f739..da501520148e9 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -597,3 +597,12 @@
 // RUN: %clang -### -xobjective-c %s 2>&1 | FileCheck -check-prefix=CHECK_NO_DISABLE_DIRECT %s
 // CHECK_DISABLE_DIRECT: -fobjc-disable-direct-methods-for-testing
 // CHECK_NO_DISABLE_DIRECT-NOT: -fobjc-disable-direct-methods-for-testing
+
+// RUN: %clang -### -S -fjmc -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s
+// RUN: %clang -### -S -fjmc -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN_NOT_ELF,CHECK_NOJMC %s
+// RUN: %clang -### -S -fjmc -g -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_JMC %s
+// RUN: %clang -### -S -fjmc -g -fno-jmc -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC %s
+// CHECK_JMC_WARN: -fjmc requires debug info. Use -g or debug options that enable debugger's stepping function; option ignored
+// CHECK_JMC_WARN_NOT_ELF: -fjmc works only for ELF; option ignored
+// CHECK_NOJMC-NOT: -fjmc
+// CHECK_JMC: -fjmc

diff  --git a/llvm/lib/CodeGen/JMCInstrumenter.cpp b/llvm/lib/CodeGen/JMCInstrumenter.cpp
index b9f686f0782eb..69967d02550ab 100644
--- a/llvm/lib/CodeGen/JMCInstrumenter.cpp
+++ b/llvm/lib/CodeGen/JMCInstrumenter.cpp
@@ -7,14 +7,17 @@
 //===----------------------------------------------------------------------===//
 //
 // JMCInstrumenter pass:
-// - add "/alternatename:__CheckForDebuggerJustMyCode=__JustMyCode_Default" to
-//   "llvm.linker.options"
-// - create the dummy COMDAT function __JustMyCode_Default
 // - instrument each function with a call to __CheckForDebuggerJustMyCode. The
 //   sole argument should be defined in .msvcjmc. Each flag is 1 byte initilized
 //   to 1.
-// - (TODO) currently targeting MSVC, adds ELF debuggers support
-//
+// - create the dummy COMDAT function __JustMyCode_Default to prevent linking
+//   error if __CheckForDebuggerJustMyCode is not available.
+// - For MSVC:
+//   add "/alternatename:__CheckForDebuggerJustMyCode=__JustMyCode_Default" to
+//   "llvm.linker.options"
+//   For ELF:
+//   Rename __JustMyCode_Default to __CheckForDebuggerJustMyCode and mark it as
+//   weak symbol.
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/SmallString.h"
@@ -110,7 +113,7 @@ FunctionType *getCheckFunctionType(LLVMContext &Ctx) {
   return FunctionType::get(VoidTy, VoidPtrTy, false);
 }
 
-void createDefaultCheckFunction(Module &M, bool UseX86FastCall) {
+Function *createDefaultCheckFunction(Module &M, bool UseX86FastCall) {
   LLVMContext &Ctx = M.getContext();
   const char *DefaultCheckFunctionName =
       UseX86FastCall ? "_JustMyCode_Default" : "__JustMyCode_Default";
@@ -122,21 +125,10 @@ void createDefaultCheckFunction(Module &M, bool UseX86FastCall) {
   DefaultCheckFunc->addParamAttr(0, Attribute::NoUndef);
   if (UseX86FastCall)
     DefaultCheckFunc->addParamAttr(0, Attribute::InReg);
-  appendToUsed(M, {DefaultCheckFunc});
-  Comdat *C = M.getOrInsertComdat(DefaultCheckFunctionName);
-  C->setSelectionKind(Comdat::Any);
-  DefaultCheckFunc->setComdat(C);
+
   BasicBlock *EntryBB = BasicBlock::Create(Ctx, "", DefaultCheckFunc);
   ReturnInst::Create(Ctx, EntryBB);
-
-  // Add a linker option /alternatename to set the default implementation for
-  // the check function.
-  // https://devblogs.microsoft.com/oldnewthing/20200731-00/?p=104024
-  std::string AltOption = std::string("/alternatename:") + CheckFunctionName +
-                          "=" + DefaultCheckFunctionName;
-  llvm::Metadata *Ops[] = {llvm::MDString::get(Ctx, AltOption)};
-  MDTuple *N = MDNode::get(Ctx, Ops);
-  M.getOrInsertNamedMetadata("llvm.linker.options")->addOperand(N);
+  return DefaultCheckFunc;
 }
 } // namespace
 
@@ -144,10 +136,13 @@ bool JMCInstrumenter::runOnModule(Module &M) {
   bool Changed = false;
   LLVMContext &Ctx = M.getContext();
   Triple ModuleTriple(M.getTargetTriple());
-  bool UseX86FastCall =
-      ModuleTriple.isOSWindows() && ModuleTriple.getArch() == Triple::x86;
+  bool IsMSVC = ModuleTriple.isKnownWindowsMSVCEnvironment();
+  bool IsELF = ModuleTriple.isOSBinFormatELF();
+  assert((IsELF || IsMSVC) && "Unsupported triple for JMC");
+  bool UseX86FastCall = IsMSVC && ModuleTriple.getArch() == Triple::x86;
+  const char *const FlagSymbolSection = IsELF ? ".just.my.code" : ".msvcjmc";
 
-  Function *CheckFunction = nullptr;
+  GlobalValue *CheckFunction = nullptr;
   DenseMap<DISubprogram *, Constant *> SavedFlags(8);
   for (auto &F : M) {
     if (F.isDeclaration())
@@ -166,7 +161,7 @@ bool JMCInstrumenter::runOnModule(Module &M) {
         GlobalVariable *GV = new GlobalVariable(
             M, FlagTy, /*isConstant=*/false, GlobalValue::InternalLinkage,
             ConstantInt::get(FlagTy, 1), FlagName);
-        GV->setSection(".msvcjmc");
+        GV->setSection(FlagSymbolSection);
         GV->setAlignment(Align(1));
         GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
         attachDebugInfo(*GV, *SP);
@@ -175,22 +170,46 @@ bool JMCInstrumenter::runOnModule(Module &M) {
     }
 
     if (!CheckFunction) {
-      assert(!M.getFunction(CheckFunctionName) &&
-             "JMC instrument more than once?");
-      CheckFunction = cast<Function>(
-          M.getOrInsertFunction(CheckFunctionName, getCheckFunctionType(Ctx))
-              .getCallee());
-      CheckFunction->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
-      CheckFunction->addParamAttr(0, Attribute::NoUndef);
-      if (UseX86FastCall) {
-        CheckFunction->setCallingConv(CallingConv::X86_FastCall);
-        CheckFunction->addParamAttr(0, Attribute::InReg);
+      Function *DefaultCheckFunc =
+          createDefaultCheckFunction(M, UseX86FastCall);
+      if (IsELF) {
+        DefaultCheckFunc->setName(CheckFunctionName);
+        DefaultCheckFunc->setLinkage(GlobalValue::WeakAnyLinkage);
+        CheckFunction = DefaultCheckFunc;
+      } else {
+        assert(!M.getFunction(CheckFunctionName) &&
+               "JMC instrument more than once?");
+        auto *CheckFunc = cast<Function>(
+            M.getOrInsertFunction(CheckFunctionName, getCheckFunctionType(Ctx))
+                .getCallee());
+        CheckFunc->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
+        CheckFunc->addParamAttr(0, Attribute::NoUndef);
+        if (UseX86FastCall) {
+          CheckFunc->setCallingConv(CallingConv::X86_FastCall);
+          CheckFunc->addParamAttr(0, Attribute::InReg);
+        }
+        CheckFunction = CheckFunc;
+
+        StringRef DefaultCheckFunctionName = DefaultCheckFunc->getName();
+        appendToUsed(M, {DefaultCheckFunc});
+        Comdat *C = M.getOrInsertComdat(DefaultCheckFunctionName);
+        C->setSelectionKind(Comdat::Any);
+        DefaultCheckFunc->setComdat(C);
+        // Add a linker option /alternatename to set the default implementation
+        // for the check function.
+        // https://devblogs.microsoft.com/oldnewthing/20200731-00/?p=104024
+        std::string AltOption = std::string("/alternatename:") +
+                                CheckFunctionName + "=" +
+                                DefaultCheckFunctionName.str();
+        llvm::Metadata *Ops[] = {llvm::MDString::get(Ctx, AltOption)};
+        MDTuple *N = MDNode::get(Ctx, Ops);
+        M.getOrInsertNamedMetadata("llvm.linker.options")->addOperand(N);
       }
     }
     // FIXME: it would be nice to make CI scheduling boundary, although in
     //        practice it does not matter much.
-    auto *CI = CallInst::Create(CheckFunction, {Flag}, "",
-                                &*F.begin()->getFirstInsertionPt());
+    auto *CI = CallInst::Create(getCheckFunctionType(Ctx), CheckFunction,
+                                {Flag}, "", &*F.begin()->getFirstInsertionPt());
     CI->addParamAttr(0, Attribute::NoUndef);
     if (UseX86FastCall) {
       CI->setCallingConv(CallingConv::X86_FastCall);
@@ -199,9 +218,5 @@ bool JMCInstrumenter::runOnModule(Module &M) {
 
     Changed = true;
   }
-  if (!Changed)
-    return false;
-
-  createDefaultCheckFunction(M, UseX86FastCall);
-  return true;
+  return Changed;
 }

diff  --git a/llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll b/llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
new file mode 100644
index 0000000000000..7ee2df759c6bd
--- /dev/null
+++ b/llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
@@ -0,0 +1,115 @@
+; REQUIRES: system-linux
+; RUN: opt -jmc-instrument -mtriple=x86_64-unknown-linux-gnu  -S < %s | FileCheck %s
+
+; CHECK: @"__7DF23CF5_x at c" = internal unnamed_addr global i8 1, section ".just.my.code", align 1, !dbg !0
+; CHECK: @"__A85D9D03_x at c" = internal unnamed_addr global i8 1, section ".just.my.code", align 1, !dbg !5
+
+; CHECK: define void @l1() !dbg !12 {
+; CHECK:   call void @__CheckForDebuggerJustMyCode(i8* noundef @"__7DF23CF5_x at c")
+; CHECK:   ret void
+; CHECK: }
+
+; CHECK: define void @l2() !dbg !16 {
+; CHECK:   call void @__CheckForDebuggerJustMyCode(i8* noundef @"__7DF23CF5_x at c")
+; CHECK:   ret void
+; CHECK: }
+
+; CHECK: define void @w1() !dbg !18 {
+; CHECK:   call void @__CheckForDebuggerJustMyCode(i8* noundef @"__A85D9D03_x at c")
+; CHECK:   ret void
+; CHECK: }
+
+; CHECK: define void @w2() !dbg !19 {
+; CHECK:   call void @__CheckForDebuggerJustMyCode(i8* noundef @"__A85D9D03_x at c")
+; CHECK:   ret void
+; CHECK: }
+
+; CHECK: define void @w3() !dbg !21 {
+; CHECK:   call void @__CheckForDebuggerJustMyCode(i8* noundef @"__A85D9D03_x at c")
+; CHECK:   ret void
+; CHECK: }
+
+; CHECK: define void @w4() !dbg !23 {
+; CHECK:   call void @__CheckForDebuggerJustMyCode(i8* noundef @"__A85D9D03_x at c")
+; CHECK:   ret void
+; CHECK: }
+
+; CHECK: define weak void @__CheckForDebuggerJustMyCode(i8* noundef %0) unnamed_addr {
+; CHECK:   ret void
+; CHECK: }
+
+; CHECK: !llvm.dbg.cu = !{!2}
+; CHECK: !llvm.module.flags = !{!9, !10}
+; CHECK: !llvm.ident = !{!11}
+
+; CHECK: !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+; CHECK: !1 = distinct !DIGlobalVariable(name: "__7DF23CF5_x at c", scope: !2, file: !3, type: !8, isLocal: true, isDefinition: true)
+; CHECK: !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+; CHECK: !3 = !DIFile(filename: "a/x.c", directory: "/tmp")
+; CHECK: !4 = !{!0, !5}
+; CHECK: !5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
+; CHECK: !6 = distinct !DIGlobalVariable(name: "__A85D9D03_x at c", scope: !2, file: !7, type: !8, isLocal: true, isDefinition: true)
+; CHECK: !7 = !DIFile(filename: "./x.c", directory: "C:\\\\a\\\\b\\\\")
+; CHECK: !8 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char, flags: DIFlagArtificial)
+; CHECK: !9 = !{i32 2, !"CodeView", i32 1}
+; CHECK: !10 = !{i32 2, !"Debug Info Version", i32 3}
+; CHECK: !11 = !{!"clang"}
+; CHECK: !12 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 1, type: !13, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15)
+; CHECK: !13 = !DISubroutineType(types: !14)
+; CHECK: !14 = !{null}
+; CHECK: !15 = !{}
+; CHECK: !16 = distinct !DISubprogram(name: "f", scope: !17, file: !17, line: 1, type: !13, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15)
+; CHECK: !17 = !DIFile(filename: "x.c", directory: "/tmp/a")
+; CHECK: !18 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 1, type: !13, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15)
+; CHECK: !19 = distinct !DISubprogram(name: "f", scope: !20, file: !20, line: 1, type: !13, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15)
+; CHECK: !20 = !DIFile(filename: "./b\\x.c", directory: "C:\\\\a\\\\")
+; CHECK: !21 = distinct !DISubprogram(name: "f", scope: !22, file: !22, line: 1, type: !13, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15)
+; CHECK: !22 = !DIFile(filename: "./b/x.c", directory: "C:\\\\a\\\\")
+; CHECK: !23 = distinct !DISubprogram(name: "f", scope: !24, file: !24, line: 1, type: !13, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15)
+; CHECK: !24 = !DIFile(filename: "./b/./../b/x.c", directory: "C:\\\\a")
+
+; All use the same flag
+define void @l1() !dbg !10 {
+  ret void
+}
+define void @l2() !dbg !11 {
+  ret void
+}
+
+; All use the same flag
+define void @w1() !dbg !12 {
+  ret void
+}
+define void @w2() !dbg !13 {
+  ret void
+}
+define void @w3() !dbg !14 {
+  ret void
+}
+define void @w4() !dbg !15 {
+  ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!7, !8}
+!llvm.ident = !{!9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "a/x.c", directory: "/tmp")
+!2 = !DIFile(filename: "x.c", directory: "/tmp/a")
+!3 = !DIFile(filename: "./x.c", directory: "C:\\\\a\\\\b\\\\")
+!4 = !DIFile(filename: "./b\\x.c", directory: "C:\\\\a\\\\")
+!5 = !DIFile(filename: "./b/x.c", directory: "C:\\\\a\\\\")
+!6 = !DIFile(filename: "./b/./../b/x.c", directory: "C:\\\\a")
+!7 = !{i32 2, !"CodeView", i32 1}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{!"clang"}
+!10 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !31, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !33)
+!11 = distinct !DISubprogram(name: "f", scope: !2, file: !2, line: 1, type: !31, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !33)
+!12 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 1, type: !31, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !33)
+!13 = distinct !DISubprogram(name: "f", scope: !4, file: !4, line: 1, type: !31, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !33)
+!14 = distinct !DISubprogram(name: "f", scope: !5, file: !5, line: 1, type: !31, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !33)
+!15 = distinct !DISubprogram(name: "f", scope: !6, file: !6, line: 1, type: !31, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !33)
+!31 = !DISubroutineType(types: !32)
+!32 = !{null}
+!33 = !{}

diff  --git a/llvm/test/Instrumentation/JustMyCode/jmc-instrument-x86.ll b/llvm/test/Instrumentation/JustMyCode/jmc-instrument-x86.ll
index b864c4b7df63c..3a6fa528a6bac 100644
--- a/llvm/test/Instrumentation/JustMyCode/jmc-instrument-x86.ll
+++ b/llvm/test/Instrumentation/JustMyCode/jmc-instrument-x86.ll
@@ -11,12 +11,12 @@
 ; CHECK:   ret void
 ; CHECK: }
 
-; CHECK: declare x86_fastcallcc void @__CheckForDebuggerJustMyCode(i8* inreg noundef) unnamed_addr
-
 ; CHECK: define void @_JustMyCode_Default(i8* inreg noundef %0) unnamed_addr comdat {
 ; CHECK:   ret void
 ; CHECK: }
 
+; CHECK: declare x86_fastcallcc void @__CheckForDebuggerJustMyCode(i8* inreg noundef) unnamed_addr
+
 ; CHECK: !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
 ; CHECK: !1 = distinct !DIGlobalVariable(name: "_A8764FDD_x at c", scope: !2, file: !3, type: !5, isLocal: true, isDefinition: true)
 ; CHECK: !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)

diff  --git a/llvm/test/Instrumentation/JustMyCode/jmc-instrument.ll b/llvm/test/Instrumentation/JustMyCode/jmc-instrument.ll
index 61c03fa40a37e..a9444808f199b 100644
--- a/llvm/test/Instrumentation/JustMyCode/jmc-instrument.ll
+++ b/llvm/test/Instrumentation/JustMyCode/jmc-instrument.ll
@@ -6,8 +6,8 @@
 ; CHECK: $__JustMyCode_Default = comdat any
 
 ; CHECK: @"__E6EA670F_x at c" = internal unnamed_addr global i8 1, section ".msvcjmc", align 1, !dbg !0
-; CHECK: @"__A8764FDD_x at c" = internal unnamed_addr global i8 1, section ".msvcjmc", align 1, !dbg !5
 ; CHECK: @llvm.used = appending global [1 x i8*] [i8* bitcast (void (i8*)* @__JustMyCode_Default to i8*)], section "llvm.metadata"
+; CHECK: @"__A8764FDD_x at c" = internal unnamed_addr global i8 1, section ".msvcjmc", align 1, !dbg !5
 
 ; CHECK: define void @l1() !dbg !13 {
 ; CHECK:   call void @__CheckForDebuggerJustMyCode(i8* noundef @"__E6EA670F_x at c")
@@ -39,12 +39,12 @@
 ; CHECK:   ret void
 ; CHECK: }
 
-; CHECK: declare void @__CheckForDebuggerJustMyCode(i8* noundef) unnamed_addr
-
 ; CHECK: define void @__JustMyCode_Default(i8* noundef %0) unnamed_addr comdat {
 ; CHECK:   ret void
 ; CHECK: }
 
+; CHECK: declare void @__CheckForDebuggerJustMyCode(i8* noundef) unnamed_addr
+
 ; CHECK: !llvm.linker.options = !{!12}
 
 ; CHECK: !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())


        


More information about the cfe-commits mailing list