diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1057,26 +1057,6 @@
                       RelaxDefault);
 }
 
-// Extract the integer N from a string spelled "-dwarf-N", returning 0
-// on mismatch. The StringRef input (rather than an Arg) allows
-// for use by the "-Xassembler" option parser.
-static unsigned DwarfVersionNum(StringRef ArgValue) {
-  return llvm::StringSwitch<unsigned>(ArgValue)
-      .Case("-gdwarf-2", 2)
-      .Case("-gdwarf-3", 3)
-      .Case("-gdwarf-4", 4)
-      .Case("-gdwarf-5", 5)
-      .Default(0);
-}
-
-// Find a DWARF format version option.
-// This function is a complementary for DwarfVersionNum().
-static const Arg *getDwarfNArg(const ArgList &Args) {
-  return Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
-                         options::OPT_gdwarf_4, options::OPT_gdwarf_5,
-                         options::OPT_gdwarf);
-}
-
 static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
                                     codegenoptions::DebugInfoKind DebugInfoKind,
                                     unsigned DwarfVersion,
@@ -4235,22 +4215,8 @@
   unsigned RequestedDWARFVersion = 0; // DWARF version requested by the user
   unsigned EffectiveDWARFVersion = 0; // DWARF version TC can generate. It may
                                       // be lower than what the user wanted.
-  unsigned DefaultDWARFVersion = ParseDebugDefaultVersion(TC, Args);
   if (EmitDwarf) {
-    // Start with the platform default DWARF version
-    RequestedDWARFVersion = TC.GetDefaultDwarfVersion();
-    assert(RequestedDWARFVersion &&
-           "toolchain default DWARF version must be nonzero");
-
-    // If the user specified a default DWARF version, that takes precedence
-    // over the platform default.
-    if (DefaultDWARFVersion)
-      RequestedDWARFVersion = DefaultDWARFVersion;
-
-    // Override with a user-specified DWARF version
-    if (GDwarfN)
-      if (auto ExplicitVersion = DwarfVersionNum(GDwarfN->getSpelling()))
-        RequestedDWARFVersion = ExplicitVersion;
+    RequestedDWARFVersion = GetDwarfVersion(TC, Args);
     // Clamp effective DWARF version to the max supported by the toolchain.
     EffectiveDWARFVersion =
         std::min(RequestedDWARFVersion, TC.getMaxDwarfVersion());
@@ -7978,13 +7944,6 @@
     WantDebug = !A->getOption().matches(options::OPT_g0) &&
                 !A->getOption().matches(options::OPT_ggdb0);
 
-  unsigned DwarfVersion = ParseDebugDefaultVersion(getToolChain(), Args);
-  if (const Arg *GDwarfN = getDwarfNArg(Args))
-    DwarfVersion = DwarfVersionNum(GDwarfN->getSpelling());
-
-  if (DwarfVersion == 0)
-    DwarfVersion = getToolChain().GetDefaultDwarfVersion();
-
   codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
 
   // Add the -fdebug-compilation-dir flag if needed.
@@ -8011,6 +7970,7 @@
     // And pass along -I options
     Args.AddAllArgs(CmdArgs, options::OPT_I);
   }
+  unsigned DwarfVersion = GetDwarfVersion(getToolChain(), Args);
   RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
                           llvm::DebuggerKind::Default);
   renderDwarfFormat(D, Triple, Args, CmdArgs, DwarfVersion);
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -14,6 +14,9 @@
 #include "clang/Driver/Multilib.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
 
 namespace clang {
@@ -103,6 +106,14 @@
 
 unsigned ParseDebugDefaultVersion(const ToolChain &TC,
                                   const llvm::opt::ArgList &Args);
+// Extract the integer N from a string spelled "-dwarf-N", returning 0
+// on mismatch. The StringRef input (rather than an Arg) allows
+// for use by the "-Xassembler" option parser.
+unsigned DwarfVersionNum(StringRef ArgValue);
+// Find a DWARF format version option.
+// This function is a complementary for DwarfVersionNum().
+const llvm::opt::Arg *getDwarfNArg(const llvm::opt::ArgList &Args);
+unsigned GetDwarfVersion(const ToolChain &TC, const llvm::opt::ArgList &Args);
 
 void AddAssemblerKPIC(const ToolChain &ToolChain,
                       const llvm::opt::ArgList &Args,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1535,6 +1535,36 @@
   return Value;
 }
 
+unsigned tools::DwarfVersionNum(StringRef ArgValue) {
+  return llvm::StringSwitch<unsigned>(ArgValue)
+    .Case("-gdwarf-2", 2)
+    .Case("-gdwarf-3", 3)
+    .Case("-gdwarf-4", 4)
+    .Case("-gdwarf-5", 5)
+    .Default(0);
+}
+
+const Arg *tools::getDwarfNArg(const ArgList &Args) {
+  return Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
+      options::OPT_gdwarf_4, options::OPT_gdwarf_5,
+      options::OPT_gdwarf);
+}
+
+unsigned tools::GetDwarfVersion(const ToolChain &TC,
+    const llvm::opt::ArgList &Args) {
+  unsigned DwarfVersion = ParseDebugDefaultVersion(TC, Args);
+  if (const Arg* GDwarfN = getDwarfNArg(Args))
+    if (int N = DwarfVersionNum(GDwarfN->getSpelling()))
+      DwarfVersion = N;
+  if (DwarfVersion == 0) {
+    DwarfVersion = TC.GetDefaultDwarfVersion();
+    assert(DwarfVersion &&
+        "toolchain default DWARF version must be nonzero");
+  }
+  return DwarfVersion;
+}
+
+
 void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args,
                              ArgStringList &CmdArgs) {
   llvm::Reloc::Model RelocationModel;
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -969,10 +969,17 @@
   for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
 
-  if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group))
-    if (!A->getOption().matches(options::OPT_g0))
+  if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group,
+        options::OPT_gdwarf_2, options::OPT_gdwarf_3, options::OPT_gdwarf_4,
+        options::OPT_gdwarf_5, options::OPT_gdwarf))
+    if (!A->getOption().matches(options::OPT_g0)) {
       Args.AddLastArg(CmdArgs, options::OPT_g_Flag);
 
+      unsigned DwarfVersion = GetDwarfVersion(getToolChain(), Args);
+      std::string DV = "-gdwarf-" + std::to_string(DwarfVersion);
+      CmdArgs.push_back(Args.MakeArgString(DV));
+    }
+
   const char *Exec =
       Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler));
   C.addCommand(std::make_unique<Command>(JA, *this,
diff --git a/clang/test/Driver/as-options.s b/clang/test/Driver/as-options.s
--- a/clang/test/Driver/as-options.s
+++ b/clang/test/Driver/as-options.s
@@ -122,7 +122,33 @@
 // RUN:   FileCheck --check-prefix=DEBUG %s
 // RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -g0 -g %s -### 2>&1 | \
 // RUN:   FileCheck --check-prefix=DEBUG %s
-// DEBUG: "-g"
+// DEBUG: "-g" "-gdwarf-5"
 // RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -g -g0 %s -### 2>&1 | \
 // RUN:   FileCheck --check-prefix=NODEBUG %s
+// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-5 -g0 %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=NODEBUG %s
 // NODEBUG-NOT: "-g"
+// NODEBUG-NOT: "-gdwarf-
+
+// Test that -gdwarf-* is passed through to GAS.
+// TODO: test without -g
+// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-5 %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=GDWARF5 %s
+// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-4 %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=GDWARF4 %s
+// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-3 %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=GDWARF3 %s
+// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-2 %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=GDWARF2 %s
+// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=GDWARF5 %s
+
+// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-5 %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=GDWARF5 %s
+// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -g \
+// RUN:   -fdebug-default-version=2 %s -### 2>&1 | FileCheck --check-prefix=GDWARF2 %s
+
+// GDWARF5: "-gdwarf-5"
+// GDWARF4: "-gdwarf-4"
+// GDWARF3: "-gdwarf-3"
+// GDWARF2: "-gdwarf-2"