diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index bba0c38cec777420ca21f31f00d96c0bc12ef30b..b2f58ead0e7560d785e6236667a024f33730045d 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -786,6 +786,22 @@ public:
            (!getLangOpts().Modules || (bool)getMacroDefinition(II));
   }
 
+  /// \brief Determine whether II is defined as a macro within the module M,
+  /// if that is a module that we've already preprocessed. Does not check for
+  /// macros imported into M.
+  bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M) {
+    if (!II->hasMacroDefinition())
+      return false;
+    auto I = Submodules.find(M);
+    if (I == Submodules.end())
+      return false;
+    auto J = I->second.Macros.find(II);
+    if (J == I->second.Macros.end())
+      return false;
+    auto *MD = J->second.getLatest();
+    return MD && MD->isDefined();
+  }
+
   MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
     if (!II->hasMacroDefinition())
       return MacroDefinition();
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 6c5c64bd266b0a5865bd91bcc00d6aced91fbaed..b805990eecbf2c4703d52f5241376c7656c09fbe 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -995,7 +995,8 @@ HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
   return HFI;
 }
 
-bool HeaderSearch::tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const {
+bool HeaderSearch::tryGetFileInfo(const FileEntry *FE,
+                                  HeaderFileInfo &Result) const {
   if (FE->getUID() >= FileInfo.size())
     return false;
   const HeaderFileInfo &HFI = FileInfo[FE->getUID()];
@@ -1028,7 +1029,7 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
 
   HeaderFileInfo &HFI = FileInfo[FE->getUID()];
   HFI.isModuleHeader = true;
-  HFI.isCompilingModuleHeader = isCompilingModuleHeader;
+  HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
   HFI.setHeaderRole(Role);
 }
 
@@ -1058,15 +1059,16 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
   // Next, check to see if the file is wrapped with #ifndef guards.  If so, and
   // if the macro that guards it is defined, we know the #include has no effect.
   if (const IdentifierInfo *ControllingMacro
-      = FileInfo.getControllingMacro(ExternalLookup))
-    // If the include file is part of a module, and we already know what its
-    // controlling macro is, then we've already parsed it and can safely just
-    // make it visible. This saves us needing to switch into the visibility
-    // state of the module just to check whether the macro is defined within it.
-    if (M || PP.isMacroDefined(ControllingMacro)) {
+      = FileInfo.getControllingMacro(ExternalLookup)) {
+    // If the header corresponds to a module, check whether the macro is already
+    // defined in that module rather than checking in the current set of visible
+    // modules.
+    if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M)
+          : PP.isMacroDefined(ControllingMacro)) {
       ++NumMultiIncludeFileOptzn;
       return false;
     }
+  }
 
   // Increment the number of times this file has been included.
   ++FileInfo.NumIncludes;
diff --git a/test/Modules/Inputs/multiple-include/a.h b/test/Modules/Inputs/multiple-include/a.h
new file mode 100644
index 0000000000000000000000000000000000000000..8266190858888adfe621c73a9f7722dab8737ece
--- /dev/null
+++ b/test/Modules/Inputs/multiple-include/a.h
@@ -0,0 +1 @@
+#include "x.h"
diff --git a/test/Modules/Inputs/multiple-include/b.h b/test/Modules/Inputs/multiple-include/b.h
new file mode 100644
index 0000000000000000000000000000000000000000..f56ab64da6b1c0883345bd52f8fbd8899f35f3c9
--- /dev/null
+++ b/test/Modules/Inputs/multiple-include/b.h
@@ -0,0 +1,3 @@
+#pragma clang __debug macro C_H
+#include "c.h"
+inline int get() { return c; }
diff --git a/test/Modules/Inputs/multiple-include/c.h b/test/Modules/Inputs/multiple-include/c.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e7d4b742dc3ab667eb06d23fc519d5b744ead4a
--- /dev/null
+++ b/test/Modules/Inputs/multiple-include/c.h
@@ -0,0 +1,4 @@
+#ifndef C_H
+#define C_H
+extern int c;
+#endif
diff --git a/test/Modules/Inputs/multiple-include/module.modulemap b/test/Modules/Inputs/multiple-include/module.modulemap
new file mode 100644
index 0000000000000000000000000000000000000000..1228ae6cbb732119318c8843e474f7dc0cf50063
--- /dev/null
+++ b/test/Modules/Inputs/multiple-include/module.modulemap
@@ -0,0 +1,2 @@
+module A { module a { header "a.h" } module b { header "b.h" } module c { header "c.h" } }
+module X { module x { header "x.h" } module c { header "c.h" } }
diff --git a/test/Modules/Inputs/multiple-include/x.h b/test/Modules/Inputs/multiple-include/x.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/test/Modules/multiple-include.cpp b/test/Modules/multiple-include.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7cbeefc81782efa1493984294fd9651426144f61
--- /dev/null
+++ b/test/Modules/multiple-include.cpp
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -I%S/Inputs/multiple-include -fmodules-cache-path=%t -fimplicit-module-maps -verify %s -fmodules-local-submodule-visibility
+// expected-no-diagnostics
+#include "b.h"
+int c = get();