https://github.com/abidh updated 
https://github.com/llvm/llvm-project/pull/160540

>From e2876ad56fa614c2b6cf9bbfb8a151ac1911d6c3 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqad...@amd.com>
Date: Tue, 23 Sep 2025 19:28:15 +0100
Subject: [PATCH 1/3] [flang][Driver] Support -gsplit-dwarf.

I have tried to follow the logic of the clang implementation where
possible. Some functions were moved where they could be used by
both clang and flang. The `addOtherOptions` was renamed to
`addDebugOptions` to better reflect its purpose.

The clang also set the splitDebugFilename field of the
DICompileUnit in the IR when this option is present. That part is
currently missing from this patch and it will come in a follow-up PR.
---
 clang/include/clang/Driver/CommonArgs.h       | 10 ++++
 clang/include/clang/Driver/Options.td         | 15 +++---
 clang/lib/Driver/ToolChains/Clang.cpp         | 31 -----------
 clang/lib/Driver/ToolChains/Clang.h           |  6 ---
 clang/lib/Driver/ToolChains/CommonArgs.cpp    | 31 +++++++++++
 clang/lib/Driver/ToolChains/Flang.cpp         | 51 +++++++++++++++++--
 clang/lib/Driver/ToolChains/Flang.h           |  8 ++-
 flang/include/flang/Frontend/CodeGenOptions.h |  7 +++
 flang/lib/Frontend/CompilerInvocation.cpp     |  6 +++
 flang/lib/Frontend/FrontendActions.cpp        | 18 ++++++-
 flang/test/Driver/split-debug.f90             | 43 ++++++++++++++++
 flang/test/Integration/debug-split-dwarf.f90  | 21 ++++++++
 12 files changed, 195 insertions(+), 52 deletions(-)
 create mode 100644 flang/test/Driver/split-debug.f90
 create mode 100644 flang/test/Integration/debug-split-dwarf.f90

diff --git a/clang/include/clang/Driver/CommonArgs.h 
b/clang/include/clang/Driver/CommonArgs.h
index 1464ce4e1b31b..40ae40665b040 100644
--- a/clang/include/clang/Driver/CommonArgs.h
+++ b/clang/include/clang/Driver/CommonArgs.h
@@ -105,6 +105,16 @@ unsigned DwarfVersionNum(StringRef ArgValue);
 const llvm::opt::Arg *getDwarfNArg(const llvm::opt::ArgList &Args);
 unsigned getDwarfVersion(const ToolChain &TC, const llvm::opt::ArgList &Args);
 
+enum class DwarfFissionKind { None, Split, Single };
+
+DwarfFissionKind getDebugFissionKind(const Driver &D,
+                                     const llvm::opt::ArgList &Args,
+                                     llvm::opt::Arg *&Arg);
+
+bool checkDebugInfoOption(const llvm::opt::Arg *A,
+                          const llvm::opt::ArgList &Args, const Driver &D,
+                          const ToolChain &TC);
+
 void AddAssemblerKPIC(const ToolChain &ToolChain,
                       const llvm::opt::ArgList &Args,
                       llvm::opt::ArgStringList &CmdArgs);
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 16e1c396fedbe..61fd0fa3794ee 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4754,13 +4754,13 @@ defm column_info : BoolOption<"g", "column-info",
   PosFlag<SetTrue>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>,
   Group<g_flags_Group>;
 def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>,
-  Visibility<[ClangOption, CLOption, DXCOption]>;
+  Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
 def gsplit_dwarf_EQ : Joined<["-"], "gsplit-dwarf=">, Group<g_flags_Group>,
-  Visibility<[ClangOption, CLOption, DXCOption]>,
+  Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
   HelpText<"Set DWARF fission mode">,
   Values<"split,single">;
 def gno_split_dwarf : Flag<["-"], "gno-split-dwarf">, Group<g_flags_Group>,
-  Visibility<[ClangOption, CLOption, DXCOption]>;
+  Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
 def gtemplate_alias : Flag<["-"], "gtemplate-alias">, Group<g_flags_Group>, 
Visibility<[ClangOption, CC1Option]>;
 def gno_template_alias : Flag<["-"], "gno-template-alias">, 
Group<g_flags_Group>, Visibility<[ClangOption]>;
 def gsimple_template_names : Flag<["-"], "gsimple-template-names">, 
Group<g_flags_Group>;
@@ -8405,7 +8405,7 @@ def main_file_name : Separate<["-"], "main-file-name">,
   MarshallingInfoString<CodeGenOpts<"MainFileName">>;
 def split_dwarf_output : Separate<["-"], "split-dwarf-output">,
   HelpText<"File name to use for split dwarf debug info output">,
-  Visibility<[CC1Option, CC1AsOption]>,
+  Visibility<[CC1Option, CC1AsOption, FC1Option]>,
   MarshallingInfoString<CodeGenOpts<"SplitDwarfOutput">>;
 
 let Visibility = [CC1Option, FC1Option] in {
@@ -8437,6 +8437,10 @@ def dependent_lib : Joined<["--"], "dependent-lib=">,
   HelpText<"Add dependent library">,
   MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>;
 
+def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
+  HelpText<"Name of the split dwarf debug info file to encode in the object 
file">,
+  MarshallingInfoString<CodeGenOpts<"SplitDwarfFile">>;
+
 } // let Visibility = [CC1Option, FC1Option]
 
 let Visibility = [CC1Option] in {
@@ -8447,9 +8451,6 @@ def fblocks_runtime_optional : Flag<["-"], 
"fblocks-runtime-optional">,
 def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">,
   HelpText<"Assume all functions with C linkage do not unwind">,
   MarshallingInfoFlag<LangOpts<"ExternCNoUnwind">>;
-def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
-  HelpText<"Name of the split dwarf debug info file to encode in the object 
file">,
-  MarshallingInfoString<CodeGenOpts<"SplitDwarfFile">>;
 def fno_wchar : Flag<["-"], "fno-wchar">,
   HelpText<"Disable C++ builtin type wchar_t">,
   MarshallingInfoNegativeFlag<LangOpts<"WChar">, cplusplus.KeyPath>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index e7aabee273a34..43cf8f54e272e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -695,16 +695,6 @@ RenderDebugEnablingArgs(const ArgList &Args, ArgStringList 
&CmdArgs,
   }
 }
 
-static bool checkDebugInfoOption(const Arg *A, const ArgList &Args,
-                                 const Driver &D, const ToolChain &TC) {
-  assert(A && "Expected non-nullptr argument.");
-  if (TC.supportsDebugInfoOption(A))
-    return true;
-  D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target)
-      << A->getAsString(Args) << TC.getTripleString();
-  return false;
-}
-
 static void RenderDebugInfoCompressionArgs(const ArgList &Args,
                                            ArgStringList &CmdArgs,
                                            const Driver &D,
@@ -4327,27 +4317,6 @@ static void RenderDiagnosticsOptions(const Driver &D, 
const ArgList &Args,
   Args.addLastArg(CmdArgs, options::OPT_warning_suppression_mappings_EQ);
 }
 
-DwarfFissionKind tools::getDebugFissionKind(const Driver &D,
-                                            const ArgList &Args, Arg *&Arg) {
-  Arg = Args.getLastArg(options::OPT_gsplit_dwarf, 
options::OPT_gsplit_dwarf_EQ,
-                        options::OPT_gno_split_dwarf);
-  if (!Arg || Arg->getOption().matches(options::OPT_gno_split_dwarf))
-    return DwarfFissionKind::None;
-
-  if (Arg->getOption().matches(options::OPT_gsplit_dwarf))
-    return DwarfFissionKind::Split;
-
-  StringRef Value = Arg->getValue();
-  if (Value == "split")
-    return DwarfFissionKind::Split;
-  if (Value == "single")
-    return DwarfFissionKind::Single;
-
-  D.Diag(diag::err_drv_unsupported_option_argument)
-      << Arg->getSpelling() << Arg->getValue();
-  return DwarfFissionKind::None;
-}
-
 static void renderDwarfFormat(const Driver &D, const llvm::Triple &T,
                               const ArgList &Args, ArgStringList &CmdArgs,
                               unsigned DwarfVersion) {
diff --git a/clang/lib/Driver/ToolChains/Clang.h 
b/clang/lib/Driver/ToolChains/Clang.h
index 18f6c5ed06a59..c22789591e00a 100644
--- a/clang/lib/Driver/ToolChains/Clang.h
+++ b/clang/lib/Driver/ToolChains/Clang.h
@@ -187,12 +187,6 @@ class LLVM_LIBRARY_VISIBILITY LinkerWrapper final : public 
Tool {
                     const char *LinkingOutput) const override;
 };
 
-enum class DwarfFissionKind { None, Split, Single };
-
-DwarfFissionKind getDebugFissionKind(const Driver &D,
-                                     const llvm::opt::ArgList &Args,
-                                     llvm::opt::Arg *&Arg);
-
 // Calculate the output path of the module file when compiling a module unit
 // with the `-fmodule-output` option or `-fmodule-output=` option specified.
 // The behavior is:
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 08cd98fd04df0..4902c2f3c0cbe 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2270,6 +2270,37 @@ unsigned tools::getDwarfVersion(const ToolChain &TC,
   return DwarfVersion;
 }
 
+DwarfFissionKind tools::getDebugFissionKind(const Driver &D,
+                                            const ArgList &Args, Arg *&Arg) {
+  Arg = Args.getLastArg(options::OPT_gsplit_dwarf, 
options::OPT_gsplit_dwarf_EQ,
+                        options::OPT_gno_split_dwarf);
+  if (!Arg || Arg->getOption().matches(options::OPT_gno_split_dwarf))
+    return DwarfFissionKind::None;
+
+  if (Arg->getOption().matches(options::OPT_gsplit_dwarf))
+    return DwarfFissionKind::Split;
+
+  StringRef Value = Arg->getValue();
+  if (Value == "split")
+    return DwarfFissionKind::Split;
+  if (Value == "single")
+    return DwarfFissionKind::Single;
+
+  D.Diag(diag::err_drv_unsupported_option_argument)
+      << Arg->getSpelling() << Arg->getValue();
+  return DwarfFissionKind::None;
+}
+
+bool tools::checkDebugInfoOption(const Arg *A, const ArgList &Args,
+                                 const Driver &D, const ToolChain &TC) {
+  assert(A && "Expected non-nullptr argument.");
+  if (TC.supportsDebugInfoOption(A))
+    return true;
+  D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target)
+      << A->getAsString(Args) << TC.getTripleString();
+  return false;
+}
+
 void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
                              ArgStringList &CmdArgs) {
   llvm::Reloc::Model RelocationModel;
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index 6fc372eb75eb7..3e8444c151f36 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -120,7 +120,11 @@ static bool shouldLoopVersion(const ArgList &Args) {
   return false;
 }
 
-void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const 
{
+void Flang::addDebugOptions(const llvm::opt::ArgList &Args, const JobAction 
&JA,
+                            const InputInfo &Output, const InputInfo &Input,
+                            llvm::opt::ArgStringList &CmdArgs) const {
+  const auto &TC = getToolChain();
+  const Driver &D = TC.getDriver();
   Args.addAllArgs(CmdArgs,
                   {options::OPT_module_dir, options::OPT_fdebug_module_writer,
                    options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
@@ -131,20 +135,57 @@ void Flang::addOtherOptions(const ArgList &Args, 
ArgStringList &CmdArgs) const {
                    options::OPT_finstrument_functions});
 
   llvm::codegenoptions::DebugInfoKind DebugInfoKind;
+  bool hasDwarfNArg = getDwarfNArg(Args) != nullptr;
   if (Args.hasArg(options::OPT_gN_Group)) {
     Arg *gNArg = Args.getLastArg(options::OPT_gN_Group);
     DebugInfoKind = debugLevelToInfoKind(*gNArg);
-  } else if (Args.hasArg(options::OPT_g_Group)) {
+  } else if (Args.hasArg(options::OPT_g_Flag) || hasDwarfNArg) {
     DebugInfoKind = llvm::codegenoptions::FullDebugInfo;
   } else {
     DebugInfoKind = llvm::codegenoptions::NoDebugInfo;
   }
   addDebugInfoKind(CmdArgs, DebugInfoKind);
-  if (getDwarfNArg(Args)) {
+  if (hasDwarfNArg) {
     const unsigned DwarfVersion = getDwarfVersion(getToolChain(), Args);
     CmdArgs.push_back(
         Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion)));
   }
+  if (Args.hasArg(options::OPT_gsplit_dwarf) ||
+      Args.hasArg(options::OPT_gsplit_dwarf_EQ)) {
+    // FIXME: -gsplit-dwarf on AIX is currently unimplemented.
+    if (TC.getTriple().isOSAIX()) {
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << Args.getLastArg(options::OPT_gsplit_dwarf)->getSpelling()
+          << TC.getTriple().str();
+      return;
+    }
+    if (DebugInfoKind == llvm::codegenoptions::NoDebugInfo)
+      return;
+
+    Arg *SplitDWARFArg;
+    DwarfFissionKind DwarfFission = getDebugFissionKind(D, Args, 
SplitDWARFArg);
+
+    if (DwarfFission == DwarfFissionKind::None ||
+        !checkDebugInfoOption(SplitDWARFArg, Args, D, TC))
+      return;
+
+    if (!TC.getTriple().isOSBinFormatELF() &&
+        !TC.getTriple().isOSBinFormatWasm() &&
+        !TC.getTriple().isOSBinFormatCOFF())
+      return;
+
+    if (!isa<AssembleJobAction>(JA) && !isa<CompileJobAction>(JA) &&
+        isa<BackendJobAction>(JA))
+      return;
+
+    const char *SplitDWARFOut = SplitDebugName(JA, Args, Input, Output);
+    CmdArgs.push_back("-split-dwarf-file");
+    CmdArgs.push_back(SplitDWARFOut);
+    if (DwarfFission == DwarfFissionKind::Split) {
+      CmdArgs.push_back("-split-dwarf-output");
+      CmdArgs.push_back(SplitDWARFOut);
+    }
+  }
 }
 
 void Flang::addCodegenOptions(const ArgList &Args,
@@ -936,8 +977,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction 
&JA,
   if (willEmitRemarks(Args))
     renderRemarksOptions(Args, CmdArgs, Input);
 
-  // Add other compile options
-  addOtherOptions(Args, CmdArgs);
+  // Add debug compile options
+  addDebugOptions(Args, JA, Output, Input, CmdArgs);
 
   // Disable all warnings
   // TODO: Handle interactions between -w, -pedantic, -Wall, -WOption
diff --git a/clang/lib/Driver/ToolChains/Flang.h 
b/clang/lib/Driver/ToolChains/Flang.h
index 98167e1b75e15..c0837b80c032e 100644
--- a/clang/lib/Driver/ToolChains/Flang.h
+++ b/clang/lib/Driver/ToolChains/Flang.h
@@ -125,12 +125,16 @@ class LLVM_LIBRARY_VISIBILITY Flang : public Tool {
   void addCodegenOptions(const llvm::opt::ArgList &Args,
                          llvm::opt::ArgStringList &CmdArgs) const;
 
-  /// Extract other compilation options from the driver arguments and add them
+  /// Extract debug compilation options from the driver arguments and add them
   /// to the command arguments.
   ///
   /// \param [in] Args The list of input driver arguments
+  /// \param [in] JA The job action
+  /// \param [in] Output The output information on the current file output
+  /// \param [in] Input The input information on the current file input
   /// \param [out] CmdArgs The list of output command arguments
-  void addOtherOptions(const llvm::opt::ArgList &Args,
+  void addDebugOptions(const llvm::opt::ArgList &Args, const JobAction &JA,
+                       const InputInfo &Output, const InputInfo &Input,
                        llvm::opt::ArgStringList &CmdArgs) const;
 
 public:
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h 
b/flang/include/flang/Frontend/CodeGenOptions.h
index df6063cc90340..3dca169d43b39 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -168,6 +168,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// by -fprofile-sample-use or -fprofile-instr-use.
   std::string ProfileRemappingFile;
 
+  /// The name for the split debug info file used for the DW_AT_[GNU_]dwo_name
+  /// attribute in the skeleton CU.
+  std::string SplitDwarfFile;
+
+  /// Output filename for the split debug info, not used in the skeleton CU.
+  std::string SplitDwarfOutput;
+
   /// Check if Clang profile instrumenation is on.
   bool hasProfileClangInstr() const {
     return getProfileInstr() == llvm::driver::ProfileClangInstr;
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp 
b/flang/lib/Frontend/CompilerInvocation.cpp
index 09b51730d6216..81610edee36fb 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -160,6 +160,12 @@ static bool 
parseDebugArgs(Fortran::frontend::CodeGenOptions &opts,
     opts.DwarfVersion =
         getLastArgIntValue(args, clang::driver::options::OPT_dwarf_version_EQ,
                            /*Default=*/0, diags);
+    if (const llvm::opt::Arg *a =
+            args.getLastArg(clang::driver::options::OPT_split_dwarf_file))
+      opts.SplitDwarfFile = a->getValue();
+    if (const llvm::opt::Arg *a =
+            args.getLastArg(clang::driver::options::OPT_split_dwarf_output))
+      opts.SplitDwarfOutput = a->getValue();
   }
   return true;
 }
diff --git a/flang/lib/Frontend/FrontendActions.cpp 
b/flang/lib/Frontend/FrontendActions.cpp
index c3c53d51015a2..867797ff1efdb 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -898,7 +898,19 @@ static void 
generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
   llvm::CodeGenFileType cgft = (act == BackendActionTy::Backend_EmitAssembly)
                                    ? llvm::CodeGenFileType::AssemblyFile
                                    : llvm::CodeGenFileType::ObjectFile;
-  if (tm.addPassesToEmitFile(codeGenPasses, os, nullptr, cgft)) {
+  std::unique_ptr<llvm::ToolOutputFile> DwoOS;
+  if (!codeGenOpts.SplitDwarfOutput.empty()) {
+    std::error_code EC;
+    DwoOS = 
std::make_unique<llvm::ToolOutputFile>(codeGenOpts.SplitDwarfOutput,
+                                                   EC, llvm::sys::fs::OF_None);
+    if (EC) {
+      diags.Report(clang::diag::err_fe_unable_to_open_output)
+          << codeGenOpts.SplitDwarfOutput << EC.message();
+      return;
+    }
+  }
+  if (tm.addPassesToEmitFile(codeGenPasses, os, DwoOS ? &DwoOS->os() : nullptr,
+                             cgft)) {
     unsigned diagID =
         diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
                               "emission of this file type is not supported");
@@ -909,6 +921,9 @@ static void 
generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
   // Run the passes
   codeGenPasses.run(llvmModule);
 
+  if (DwoOS)
+    DwoOS->keep();
+
   // Cleanup
   delete tlii;
 }
@@ -1324,6 +1339,7 @@ void CodeGenAction::executeAction() {
   llvm::TargetMachine &targetMachine = ci.getTargetMachine();
 
   targetMachine.Options.MCOptions.AsmVerbose = targetOpts.asmVerbose;
+  targetMachine.Options.MCOptions.SplitDwarfFile = codeGenOpts.SplitDwarfFile;
 
   const llvm::Triple &theTriple = targetMachine.getTargetTriple();
 
diff --git a/flang/test/Driver/split-debug.f90 
b/flang/test/Driver/split-debug.f90
new file mode 100644
index 0000000000000..a63024328d807
--- /dev/null
+++ b/flang/test/Driver/split-debug.f90
@@ -0,0 +1,43 @@
+! Test -gsplit-dwarf and -gsplit-dwarf={split,single}.
+
+! RUN: %flang -### -c -target x86_64 -g -gsplit-dwarf %s 2>&1 | FileCheck %s 
--check-prefixes=SPLIT
+! RUN: %flang -### -c -target x86_64 -gsplit-dwarf -g %s 2>&1 | FileCheck %s 
--check-prefixes=SPLIT
+! RUN: %flang -### -c -target x86_64 -gsplit-dwarf=split -g %s 2>&1 | 
FileCheck %s --check-prefixes=SPLIT
+
+! SPLIT: "-split-dwarf-file" "split-debug.dwo" "-split-dwarf-output" 
"split-debug.dwo"
+
+! -gsplit-dwarf is a no-op on a non-ELF platform.
+! RUN: %flang -### -c -target x86_64-apple-darwin  -gsplit-dwarf -g %s 2>&1 | 
FileCheck %s --check-prefix=DARWIN
+! DARWIN-NOT: "-split-dwarf
+
+
+! -gno-split-dwarf disables debug fission.
+! RUN: %flang -### -c -target x86_64 -gsplit-dwarf -g -gno-split-dwarf %s 2>&1 
| FileCheck %s --check-prefix=NOSPLIT
+! RUN: %flang -### -c -target x86_64 -gsplit-dwarf=single -g -gno-split-dwarf 
%s 2>&1 | FileCheck %s --check-prefix=NOSPLIT
+! RUN: %flang -### -c -target x86_64 -gno-split-dwarf -g -gsplit-dwarf %s 2>&1 
| FileCheck %s --check-prefixes=SPLIT
+
+! NOSPLIT-NOT: "-split-dwarf
+
+! Test -gsplit-dwarf=single.
+! RUN: %flang -### -c -target x86_64 -gsplit-dwarf=single -g %s 2>&1 | 
FileCheck %s --check-prefix=SINGLE
+
+! SINGLE: "-split-dwarf-file" "split-debug.o"
+! SINGLE-NOT: "-split-dwarf-output"
+
+! RUN: %flang -### -c -target x86_64 -gsplit-dwarf=single -g -o %tfoo.o %s 
2>&1 | FileCheck %s --check-prefix=SINGLE_WITH_FILENAME
+! SINGLE_WITH_FILENAME: "-split-dwarf-file" "{{.*}}foo.o"
+! SINGLE_WITH_FILENAME-NOT: "-split-dwarf-output"
+
+
+! Invoke objcopy if not using the integrated assembler.
+! RUN: %flang -### -c -target x86_64-unknown-linux-gnu -fno-integrated-as 
-gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefix=OBJCOPY
+! OBJCOPY:      objcopy{{(.exe)?}}" "--extract-dwo"
+! OBJCOPY-NEXT: objcopy{{(.exe)?}}" "--strip-dwo"
+
+! RUN: not %flang -target powerpc-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \
+! RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX
+! RUN: not %flang -target powerpc64-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \
+! RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX64
+
+// UNSUP_OPT_AIX: error: unsupported option '-gsplit-dwarf' for target 
'powerpc-ibm-aix'
+// UNSUP_OPT_AIX64: error: unsupported option '-gsplit-dwarf' for target 
'powerpc64-ibm-aix'
diff --git a/flang/test/Integration/debug-split-dwarf.f90 
b/flang/test/Integration/debug-split-dwarf.f90
new file mode 100644
index 0000000000000..60373efddc358
--- /dev/null
+++ b/flang/test/Integration/debug-split-dwarf.f90
@@ -0,0 +1,21 @@
+! REQUIRES: x86-registered-target
+
+! Testing to ensure that setting only -split-dwarf-file allows to place
+! .dwo sections into regular output object.
+!  RUN: %flang_fc1 -debug-info-kind=standalone -triple x86_64-unknown-linux \
+!  RUN:   -split-dwarf-file %t.o -emit-obj -o %t.o %s
+!  RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=DWO %s
+
+! Testing to ensure that setting both -split-dwarf-file and -split-dwarf-output
+! does not place .dwo sections into regular output object but in a separate
+! file.
+!  RUN: %flang_fc1 -debug-info-kind=standalone -triple x86_64-unknown-linux \
+!  RUN:   -split-dwarf-file %t.dwo -split-dwarf-output %t.dwo -emit-obj -o 
%t.o %s
+!  RUN: llvm-readobj -S %t.dwo | FileCheck --check-prefix=DWO %s
+!  RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=SPLIT %s
+
+!  DWO: .dwo
+!  SPLIT-NOT: .dwo
+
+program test
+end program test

>From d100412cd111999371d275f7bac46f30d9b1b269 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqad...@amd.com>
Date: Thu, 25 Sep 2025 10:57:23 +0100
Subject: [PATCH 2/3] Handle review comments.

---
 flang/lib/Frontend/FrontendActions.cpp | 18 +++++++++---------
 flang/test/Driver/split-debug.f90      | 10 ++++++----
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/flang/lib/Frontend/FrontendActions.cpp 
b/flang/lib/Frontend/FrontendActions.cpp
index 867797ff1efdb..9e0bef035a643 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -898,18 +898,18 @@ static void 
generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
   llvm::CodeGenFileType cgft = (act == BackendActionTy::Backend_EmitAssembly)
                                    ? llvm::CodeGenFileType::AssemblyFile
                                    : llvm::CodeGenFileType::ObjectFile;
-  std::unique_ptr<llvm::ToolOutputFile> DwoOS;
+  std::unique_ptr<llvm::ToolOutputFile> dwoOS;
   if (!codeGenOpts.SplitDwarfOutput.empty()) {
-    std::error_code EC;
-    DwoOS = 
std::make_unique<llvm::ToolOutputFile>(codeGenOpts.SplitDwarfOutput,
-                                                   EC, llvm::sys::fs::OF_None);
-    if (EC) {
+    std::error_code ec;
+    dwoOS = 
std::make_unique<llvm::ToolOutputFile>(codeGenOpts.SplitDwarfOutput,
+                                                   ec, llvm::sys::fs::OF_None);
+    if (ec) {
       diags.Report(clang::diag::err_fe_unable_to_open_output)
-          << codeGenOpts.SplitDwarfOutput << EC.message();
+          << codeGenOpts.SplitDwarfOutput << ec.message();
       return;
     }
   }
-  if (tm.addPassesToEmitFile(codeGenPasses, os, DwoOS ? &DwoOS->os() : nullptr,
+  if (tm.addPassesToEmitFile(codeGenPasses, os, dwoOS ? &dwoOS->os() : nullptr,
                              cgft)) {
     unsigned diagID =
         diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
@@ -921,8 +921,8 @@ static void 
generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
   // Run the passes
   codeGenPasses.run(llvmModule);
 
-  if (DwoOS)
-    DwoOS->keep();
+  if (dwoOS)
+    dwoOS->keep();
 
   // Cleanup
   delete tlii;
diff --git a/flang/test/Driver/split-debug.f90 
b/flang/test/Driver/split-debug.f90
index a63024328d807..de8863eae0934 100644
--- a/flang/test/Driver/split-debug.f90
+++ b/flang/test/Driver/split-debug.f90
@@ -31,13 +31,15 @@
 
 ! Invoke objcopy if not using the integrated assembler.
 ! RUN: %flang -### -c -target x86_64-unknown-linux-gnu -fno-integrated-as 
-gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefix=OBJCOPY
-! OBJCOPY:      objcopy{{(.exe)?}}" "--extract-dwo"
-! OBJCOPY-NEXT: objcopy{{(.exe)?}}" "--strip-dwo"
+! OBJCOPY:      objcopy{{(.exe)?}}
+! OBJCOPY-SAME: --extract-dwo
+! OBJCOPY-NEXT: objcopy{{(.exe)?}}
+! OBJCOPY-SAME: --strip-dwo
 
 ! RUN: not %flang -target powerpc-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \
 ! RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX
 ! RUN: not %flang -target powerpc64-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \
 ! RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX64
 
-// UNSUP_OPT_AIX: error: unsupported option '-gsplit-dwarf' for target 
'powerpc-ibm-aix'
-// UNSUP_OPT_AIX64: error: unsupported option '-gsplit-dwarf' for target 
'powerpc64-ibm-aix'
+! UNSUP_OPT_AIX: error: unsupported option '-gsplit-dwarf' for target 
'powerpc-ibm-aix'
+! UNSUP_OPT_AIX64: error: unsupported option '-gsplit-dwarf' for target 
'powerpc64-ibm-aix'

>From 9d0589fa5526628065b0a4f5dee5e1897e76994c Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqad...@amd.com>
Date: Thu, 25 Sep 2025 12:50:50 +0100
Subject: [PATCH 3/3] Add warning on non-supported platforms.

---
 clang/lib/Driver/ToolChains/Flang.cpp | 5 ++++-
 flang/test/Driver/split-debug.f90     | 7 +++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index 3e8444c151f36..a5394813eeb97 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -171,8 +171,11 @@ void Flang::addDebugOptions(const llvm::opt::ArgList 
&Args, const JobAction &JA,
 
     if (!TC.getTriple().isOSBinFormatELF() &&
         !TC.getTriple().isOSBinFormatWasm() &&
-        !TC.getTriple().isOSBinFormatCOFF())
+        !TC.getTriple().isOSBinFormatCOFF()) {
+      D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target)
+          << SplitDWARFArg->getSpelling() << TC.getTriple().str();
       return;
+    }
 
     if (!isa<AssembleJobAction>(JA) && !isa<CompileJobAction>(JA) &&
         isa<BackendJobAction>(JA))
diff --git a/flang/test/Driver/split-debug.f90 
b/flang/test/Driver/split-debug.f90
index de8863eae0934..1cb9f84d7a5d2 100644
--- a/flang/test/Driver/split-debug.f90
+++ b/flang/test/Driver/split-debug.f90
@@ -6,10 +6,9 @@
 
 ! SPLIT: "-split-dwarf-file" "split-debug.dwo" "-split-dwarf-output" 
"split-debug.dwo"
 
-! -gsplit-dwarf is a no-op on a non-ELF platform.
-! RUN: %flang -### -c -target x86_64-apple-darwin  -gsplit-dwarf -g %s 2>&1 | 
FileCheck %s --check-prefix=DARWIN
-! DARWIN-NOT: "-split-dwarf
-
+! Check warning on non-supported platforms.
+! RUN: %flang -### -c -target x86_64-apple-darwin  -gsplit-dwarf -g %s 2>&1 | 
FileCheck %s --check-prefix=WARN
+! WARN: warning: debug information option '-gsplit-dwarf' is not supported for 
target 'x86_64-apple-darwin'
 
 ! -gno-split-dwarf disables debug fission.
 ! RUN: %flang -### -c -target x86_64 -gsplit-dwarf -g -gno-split-dwarf %s 2>&1 
| FileCheck %s --check-prefix=NOSPLIT

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

Reply via email to