Index: lib/MC/MCSectionXCOFF.cpp
===================================================================
--- lib/MC/MCSectionXCOFF.cpp
+++ lib/MC/MCSectionXCOFF.cpp
@@ -72,6 +72,11 @@
   }
 
   if (isCsect() && getMappingClass() == XCOFF::XMC_TD) {
+    // Common csect type (uninitialized storage) does not have to print csect
+    // directive for section switching unless it is local.
+    if (getKind().isCommon() && !getKind().isBSSLocal())
+      return;
+
     assert((getKind().isBSSExtern() || getKind().isBSSLocal() ||
             getKind().isReadOnlyWithRel()) &&
            "Unexepected section kind for toc-data");
@@ -126,5 +131,7 @@
     return false;
   assert(isCsect() &&
          "Handling for isVirtualSection not implemented for this section!");
-  return XCOFF::XTY_CM == CsectProp->Type;
+  // XTY_CM sections are virtual except for toc-data symbols.
+  return (XCOFF::XTY_CM == CsectProp->Type) &&
+         (getMappingClass() != XCOFF::XMC_TD);
 }
Index: lib/MC/XCOFFObjectWriter.cpp
===================================================================
--- lib/MC/XCOFFObjectWriter.cpp
+++ lib/MC/XCOFFObjectWriter.cpp
@@ -467,9 +467,15 @@
     return TOCCsects;
   case XCOFF::XMC_TC:
   case XCOFF::XMC_TE:
-  case XCOFF::XMC_TD:
     assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
-           "Only an initialized csect can contain TC entry.");
+           "A TOC symbol must be an initialized csect.");
+    assert(!TOCCsects.empty() &&
+           "We should at least have a TOC-base in this CsectGroup.");
+    return TOCCsects;
+  case XCOFF::XMC_TD:
+    assert((XCOFF::XTY_SD == MCSec->getCSectType() ||
+            XCOFF::XTY_CM == MCSec->getCSectType()) &&
+           "Symbol type incompatible with toc-data.");
     assert(!TOCCsects.empty() &&
            "We should at least have a TOC-base in this CsectGroup.");
     return TOCCsects;
Index: lib/Target/PowerPC/PPCAsmPrinter.cpp
===================================================================
--- lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -2554,12 +2554,18 @@
     GVSym->setStorageClass(
         TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
 
-    if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal())
-      OutStreamer->emitXCOFFLocalCommonSymbol(
-          OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size,
-          GVSym, Alignment);
-    else
+    if (GVKind.isBSSLocal() && Csect->getMappingClass() == XCOFF::XMC_TD) {
+        OutStreamer->emitZeros(Size);
+    } else if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal()) {
+        assert(Csect->getMappingClass() != XCOFF::XMC_TD &&
+               "BSS local toc-data already handled and TLS variables "
+               "incompatible with XMC_TD");
+        OutStreamer->emitXCOFFLocalCommonSymbol(
+            OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size,
+            GVSym, Alignment);
+    } else {
       OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);
+    }
     return;
   }
 
@@ -2702,8 +2708,17 @@
     TS->emitTCEntry(*I.first.first, I.first.second);
   }
 
-  for (const auto *GV : TOCDataGlobalVars)
-    emitGlobalVariableHelper(GV);
+  // Traverse the list of global variables twice, emitting all of the
+  // non-common global variables before the common ones, as emitting a
+  // .comm directive changes the scope from .toc to the common symbol.
+  for (const auto *GV : TOCDataGlobalVars) {
+    if (!GV->hasCommonLinkage())
+      emitGlobalVariableHelper(GV);
+  }
+  for (const auto *GV : TOCDataGlobalVars) {
+    if (GV->hasCommonLinkage())
+      emitGlobalVariableHelper(GV);
+  }
 }
 
 bool PPCAIXAsmPrinter::doInitialization(Module &M) {
Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -549,12 +549,9 @@
          "A GlobalVariable with size larger than a TOC entry is not currently "
          "supported by the toc data transformation.");
 
-  if (GV->hasLocalLinkage() || GV->hasPrivateLinkage())
-    report_fatal_error("A GlobalVariable with private or local linkage is not "
-                       "currently supported by the toc data transformation.");
-
-  assert(!GV->hasCommonLinkage() &&
-         "Tentative definitions cannot have the mapping class XMC_TD.");
+  if (GV->hasPrivateLinkage())
+     report_fatal_error("A GlobalVariable with private linkage is not "
+                        "currently supported by the toc data transformation.");
 
   return true;
 }
Index: test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll
===================================================================
--- test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll
+++ test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll
@@ -1,6 +1,6 @@
-; RUN: not --crash llc  -mtriple powerpc-ibm-aix-xcoff  -verify-machineinstrs \
+; RUN: llc  -mtriple powerpc-ibm-aix-xcoff  -verify-machineinstrs \
 ; RUN:     < %s 2>&1 | FileCheck %s
-; RUN: not --crash llc  -mtriple powerpc64-ibm-aix-xcoff  -verify-machineinstrs \
+; RUN: llc  -mtriple powerpc64-ibm-aix-xcoff  -verify-machineinstrs \
 ; RUN:     < %s 2>&1 | FileCheck %s
 
 @ilocal = internal global i32 0, align 4 #0
@@ -11,6 +11,8 @@
     ret i32 %0
 }
 
-; CHECK: LLVM ERROR: A GlobalVariable with private or local linkage is not currently supported by the toc data transformation.
-
 attributes #0 = { "toc-data" }
+
+; CHECK:      .toc
+; CHECK-NEXT: .csect ilocal[TD],2
+; CHECK-NEXT: .space  4