Index: clang/include/clang/Basic/SourceManager.h
===================================================================
--- clang/include/clang/Basic/SourceManager.h
+++ clang/include/clang/Basic/SourceManager.h
@@ -177,10 +177,8 @@
 
   mutable unsigned IsBufferInvalid : 1;
 
-  ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {}
-
-  ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
-      : OrigEntry(Ent), ContentsEntry(contentEnt), BufferOverridden(false),
+  ContentCache(const FileEntry *Ent = nullptr)
+      : OrigEntry(Ent), ContentsEntry(Ent), BufferOverridden(false),
         IsFileVolatile(false), IsTransient(false), IsBufferInvalid(false) {}
 
   /// The copy ctor does not allow copies where source object has either
@@ -655,10 +653,6 @@
   bool FilesAreTransient = false;
 
   struct OverriddenFilesInfoTy {
-    /// Files that have been overridden with the contents from another
-    /// file.
-    llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
-
     /// Files that were overridden with a memory buffer.
     llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer;
   };
@@ -960,23 +954,11 @@
   void overrideFileContents(const FileEntry *SourceFile,
                             std::unique_ptr<llvm::MemoryBuffer> Buffer);
 
-  /// Override the given source file with another one.
-  ///
-  /// \param SourceFile the source file which will be overridden.
-  ///
-  /// \param NewFile the file whose contents will be used as the
-  /// data instead of the contents of the given source file.
-  void overrideFileContents(const FileEntry *SourceFile,
-                            const FileEntry *NewFile);
-
   /// Returns true if the file contents have been overridden.
   bool isFileOverridden(const FileEntry *File) const {
     if (OverriddenFilesInfo) {
       if (OverriddenFilesInfo->OverriddenFilesWithBuffer.count(File))
         return true;
-      if (OverriddenFilesInfo->OverriddenFiles.find(File) !=
-          OverriddenFilesInfo->OverriddenFiles.end())
-        return true;
     }
     return false;
   }
Index: clang/lib/Basic/SourceManager.cpp
===================================================================
--- clang/lib/Basic/SourceManager.cpp
+++ clang/lib/Basic/SourceManager.cpp
@@ -392,20 +392,7 @@
   // Nope, create a new Cache entry.
   Entry = ContentCacheAlloc.Allocate<ContentCache>();
 
-  if (OverriddenFilesInfo) {
-    // If the file contents are overridden with contents from another file,
-    // pass that file to ContentCache.
-    llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
-        overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
-    if (overI == OverriddenFilesInfo->OverriddenFiles.end())
-      new (Entry) ContentCache(FileEnt);
-    else
-      new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt
-                                                              : overI->second,
-                               overI->second);
-  } else {
-    new (Entry) ContentCache(FileEnt);
-  }
+  new (Entry) ContentCache(FileEnt);
 
   Entry->IsFileVolatile = UserFilesAreVolatile && !isSystemFile;
   Entry->IsTransient = FilesAreTransient;
@@ -687,17 +674,6 @@
   getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
 }
 
-void SourceManager::overrideFileContents(const FileEntry *SourceFile,
-                                         const FileEntry *NewFile) {
-  assert(SourceFile->getSize() == NewFile->getSize() &&
-         "Different sizes, use the FileManager to create a virtual file with "
-         "the correct size");
-  assert(FileInfos.count(SourceFile) == 0 &&
-         "This function should be called at the initialization stage, before "
-         "any parsing occurs.");
-  getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
-}
-
 const FileEntry *
 SourceManager::bypassFileContentsOverride(const FileEntry &File) {
   assert(isFileOverridden(&File));
@@ -2183,9 +2159,6 @@
     + llvm::capacity_in_bytes(SLocEntryLoaded)
     + llvm::capacity_in_bytes(FileInfos);
 
-  if (OverriddenFilesInfo)
-    size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
-
   return size;
 }
 
Index: clang/lib/Frontend/ASTUnit.cpp
===================================================================
--- clang/lib/Frontend/ASTUnit.cpp
+++ clang/lib/Frontend/ASTUnit.cpp
@@ -170,21 +170,6 @@
   if (FileStatus) {
     llvm::sys::fs::UniqueID MainFileID = FileStatus->getUniqueID();
 
-    // Check whether there is a file-file remapping of the main file
-    for (const auto &RF : PreprocessorOpts.RemappedFiles) {
-      std::string MPath(RF.first);
-      auto MPathStatus = VFS->status(MPath);
-      if (MPathStatus) {
-        llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
-        if (MainFileID == MID) {
-          // We found a remapping. Try to load the resulting, remapped source.
-          BufferOwner = valueOrNull(VFS->getBufferForFile(RF.second, -1, true, isVolatile));
-          if (!BufferOwner)
-            return nullptr;
-        }
-      }
-    }
-
     // Check whether there is a file-buffer remapping. It supercedes the
     // file-file remapping.
     for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
@@ -1747,7 +1732,6 @@
   }
 
   PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
-  PPOpts.RemappedFilesKeepOriginalName = true;
   PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
   PPOpts.SingleFileParseMode = SingleFileParse;
   PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -357,31 +357,6 @@
           FromFile, std::unique_ptr<llvm::MemoryBuffer>(
                         const_cast<llvm::MemoryBuffer *>(RB.second)));
   }
-
-  // Remap files in the source manager (with other files).
-  for (const auto &RF : InitOpts.RemappedFiles) {
-    // Find the file that we're mapping to.
-    auto ToFile = FileMgr.getFile(RF.second);
-    if (!ToFile) {
-      Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
-      continue;
-    }
-
-    // Create the file entry for the file that we're mapping from.
-    const FileEntry *FromFile =
-        FileMgr.getVirtualFile(RF.first, (*ToFile)->getSize(), 0);
-    if (!FromFile) {
-      Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
-      continue;
-    }
-
-    // Override the contents of the "from" file with the contents of
-    // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, *ToFile);
-  }
-
-  SourceMgr.setOverridenFilesKeepOriginalName(
-      InitOpts.RemappedFilesKeepOriginalName);
 }
 
 // Preprocessor
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -4057,11 +4057,27 @@
   return Result;
 }
 
+static IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+addRemappedFiles(const CompilerInvocation &CI,
+                 IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) {
+  auto &PPOpts = CI.getPreprocessorOpts();
+  if (PPOpts.RemappedFiles.empty())
+    return BaseFS;
+
+  IntrusiveRefCntPtr<llvm::vfs::FileSystem> Result =
+      llvm::vfs::RedirectingFileSystem::create(
+          PPOpts.RemappedFiles,
+          /*UseExternalNames=*/!PPOpts.RemappedFilesKeepOriginalName, *BaseFS)
+          .release();
+  return Result;
+}
+
 IntrusiveRefCntPtr<llvm::vfs::FileSystem>
 clang::createVFSFromCompilerInvocation(
     const CompilerInvocation &CI, DiagnosticsEngine &Diags,
     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) {
   IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = std::move(BaseFS);
   FS = addVFSOverlays(CI, Diags, std::move(FS));
+  FS = addRemappedFiles(CI, std::move(FS));
   return FS;
 }
Index: clang/lib/Frontend/PrecompiledPreamble.cpp
===================================================================
--- clang/lib/Frontend/PrecompiledPreamble.cpp
+++ clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -534,21 +534,6 @@
   // remapping or unsaved_files.
   std::map<llvm::sys::fs::UniqueID, PreambleFileHash> OverriddenFiles;
   llvm::StringSet<> OverriddenAbsPaths; // Either by buffers or files.
-  for (const auto &R : PreprocessorOpts.RemappedFiles) {
-    llvm::vfs::Status Status;
-    if (!moveOnNoError(VFS.status(R.second), Status)) {
-      // If we can't stat the file we're remapping to, assume that something
-      // horrible happened.
-      return false;
-    }
-    // If a mapped file was previously missing, then it has changed.
-    llvm::SmallString<128> MappedPath(R.first);
-    if (!VFS.makeAbsolute(MappedPath))
-      OverriddenAbsPaths.insert(MappedPath);
-
-    OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile(
-        Status.getSize(), llvm::sys::toTimeT(Status.getLastModificationTime()));
-  }
 
   // OverridenFileBuffers tracks only the files not found in VFS.
   llvm::StringMap<PreambleFileHash> OverridenFileBuffers;
Index: clang/test/PCH/remap-file-from-pch.cpp
===================================================================
--- clang/test/PCH/remap-file-from-pch.cpp
+++ clang/test/PCH/remap-file-from-pch.cpp
@@ -1,10 +1,18 @@
-//  %clang_cc1 -remap-file "%s;%S/Inputs/remapped-file" -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-EXIST %s
-
 // RUN: %clang_cc1 -x c++-header %s.h -emit-pch -o %t.pch
-// RUN: not %clang_cc1 %s -include-pch %t.pch -remap-file "%s.h;%s.remap.h" -fsyntax-only 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 %s -include-pch %t.pch -fsyntax-only 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=NO-REMAP
+// RUN: not %clang_cc1 %s -include-pch %t.pch -remap-file "%s.h;%s.remap.h" -fsyntax-only 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=MISMATCH
+//
+// RUN: %clang_cc1 -x c++-header -remap-file "%s.h;%s.remap.h" %s.h -emit-pch -o %t-remapped.pch
+// RUN: %clang_cc1 %s -include-pch %t-remapped.pch -remap-file "%s.h;%s.remap.h" -fsyntax-only 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=REMAP -allow-empty
+// RUN: not %clang_cc1 %s -include-pch %t-remapped.pch -fsyntax-only 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=MISMATCH
 
 const char *str = STR;
 int ge = zool;
 
-// CHECK: file '{{.*[/\\]}}remap-file-from-pch.cpp.h' from the precompiled header has been overridden
-// CHECK: use of undeclared identifier 'zool'
+// MISMATCH: file '{{.*[/\\]}}remap-file-from-pch.cpp.h' has been modified since the precompiled header
+// NO-REMAP: use of undeclared identifier 'zool'
+// REMAP-NOT: use of undeclared identifier