From eddd94c27df609113af1d1b795d8483aa6dd662c Mon Sep 17 00:00:00 2001 From: Yuanfang Chen Date: Mon, 7 Mar 2022 12:42:09 -0800 Subject: [PATCH] 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. --- clang/include/clang/Basic/DiagnosticDriverKinds.td | 7 +- clang/include/clang/Driver/Options.td | 7 +- clang/lib/Driver/ToolChains/Clang.cpp | 16 ++- clang/test/Driver/cl-options.c | 2 +- clang/test/Driver/clang_f_opts.c | 9 ++ llvm/lib/CodeGen/JMCInstrumenter.cpp | 95 ++++++++++------- .../JustMyCode/jmc-instrument-elf.ll | 115 +++++++++++++++++++++ .../JustMyCode/jmc-instrument-x86.ll | 4 +- .../Instrumentation/JustMyCode/jmc-instrument.ll | 6 +- 9 files changed, 210 insertions(+), 51 deletions(-) create mode 100644 llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 1ac5bf8..afedb37 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; + +def warn_drv_fjmc_for_elf_only : Warning< + "-fjmc works only for ELF; option ignored">, InGroup; def err_drv_target_variant_invalid : Error< diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 06802ae..3b70117 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, HelpText<"Do not elide types when printing diagnostics">, MarshallingInfoNegativeFlag>; def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group; -def fjmc : Flag<["-"], "fjmc">, Group,Flags<[CC1Option]>, - HelpText<"Enable just-my-code debugging">, - MarshallingInfoFlag>; 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, Flags<[CC1Option]>, @@ -1923,6 +1920,10 @@ def finline_functions : Flag<["-"], "finline-functions">, Group, def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group, Flags<[CC1Option]>, HelpText<"Inline functions which are (explicitly or implicitly) marked inline">; def finline : Flag<["-"], "finline">, Group; +defm jmc : BoolFOption<"jmc", + CodeGenOpts<"JMCInstrument">, DefaultFalse, + PosFlag, + NegFlag>; def fglobal_isel : Flag<["-"], "fglobal-isel">, Group, HelpText<"Enables the global instruction selector">; def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 7cb8df6..89d8b0c 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 4a8a1b3c..f332cd83 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 4b0159b..da50152 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 b9f686f..69967d0 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 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( - 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( + 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 0000000..7ee2df75 --- /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@c" = internal unnamed_addr global i8 1, section ".just.my.code", align 1, !dbg !0 +; CHECK: @"__A85D9D03_x@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@c") +; CHECK: ret void +; CHECK: } + +; CHECK: define void @l2() !dbg !16 { +; CHECK: call void @__CheckForDebuggerJustMyCode(i8* noundef @"__7DF23CF5_x@c") +; CHECK: ret void +; CHECK: } + +; CHECK: define void @w1() !dbg !18 { +; CHECK: call void @__CheckForDebuggerJustMyCode(i8* noundef @"__A85D9D03_x@c") +; CHECK: ret void +; CHECK: } + +; CHECK: define void @w2() !dbg !19 { +; CHECK: call void @__CheckForDebuggerJustMyCode(i8* noundef @"__A85D9D03_x@c") +; CHECK: ret void +; CHECK: } + +; CHECK: define void @w3() !dbg !21 { +; CHECK: call void @__CheckForDebuggerJustMyCode(i8* noundef @"__A85D9D03_x@c") +; CHECK: ret void +; CHECK: } + +; CHECK: define void @w4() !dbg !23 { +; CHECK: call void @__CheckForDebuggerJustMyCode(i8* noundef @"__A85D9D03_x@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@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@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 b864c4b..3a6fa52 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@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 61c03fa..a944480 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@c" = internal unnamed_addr global i8 1, section ".msvcjmc", align 1, !dbg !0 -; CHECK: @"__A8764FDD_x@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@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@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()) -- 2.7.4