Index: include/llvm/Support/FileSystem.h
===================================================================
--- include/llvm/Support/FileSystem.h
+++ include/llvm/Support/FileSystem.h
@@ -1064,6 +1064,7 @@
   void *FileHandle;
 #endif
   mapmode Mode;
+  bool Executable; ///< The file is an executable
 
   std::error_code init(int FD, uint64_t Offset, mapmode Mode);
 
@@ -1076,7 +1077,7 @@
   ///   ownership if closefd is true. It must have been opended in the correct
   ///   mode.
   mapped_file_region(int fd, mapmode mode, size_t length, uint64_t offset,
-                     std::error_code &ec);
+                     bool Exe, std::error_code &ec);
 
   ~mapped_file_region();
 
Index: lib/Support/FileOutputBuffer.cpp
===================================================================
--- lib/Support/FileOutputBuffer.cpp
+++ lib/Support/FileOutputBuffer.cpp
@@ -144,7 +144,8 @@
   // Mmap it.
   std::error_code EC;
   auto MappedFile = llvm::make_unique<fs::mapped_file_region>(
-      File.FD, fs::mapped_file_region::readwrite, Size, 0, EC);
+      File.FD, fs::mapped_file_region::readwrite, Size, 0,
+      !!(Mode & fs::all_exe), EC);
   if (EC) {
     consumeError(File.discard());
     return errorCodeToError(EC);
Index: lib/Support/MemoryBuffer.cpp
===================================================================
--- lib/Support/MemoryBuffer.cpp
+++ lib/Support/MemoryBuffer.cpp
@@ -184,9 +184,11 @@
 
 public:
   MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len,
-                       uint64_t Offset, std::error_code &EC)
+                       uint64_t Offset, llvm::sys::fs::perms Perm,
+                       std::error_code &EC)
       : MFR(FD, MB::Mapmode, getLegalMapSize(Len, Offset),
-            getLegalMapOffset(Offset), EC) {
+            getLegalMapOffset(Offset), !!(Perm & llvm::sys::fs::perms::all_exe),
+            EC) {
     if (!EC) {
       const char *Start = getStart(Len, Offset);
       MemoryBuffer::init(Start, Start + Len, RequiresNullTerminator);
@@ -370,16 +372,14 @@
   if (EC)
     return EC;
 
+  sys::fs::file_status Status;
+  EC = sys::fs::status(FD, Status);
+  if (EC)
+    return EC;
+
   // Default is to map the full file.
   if (MapSize == uint64_t(-1)) {
-    // If we don't know the file size, use fstat to find out.  fstat on an open
-    // file descriptor is cheaper than stat on a random path.
     if (FileSize == uint64_t(-1)) {
-      sys::fs::file_status Status;
-      std::error_code EC = sys::fs::status(FD, Status);
-      if (EC)
-        return EC;
-
       // If this not a file or a block device (e.g. it's a named pipe
       // or character device), we can't mmap it, so error out.
       sys::fs::file_type Type = Status.type();
@@ -395,7 +395,7 @@
   std::unique_ptr<WriteThroughMemoryBuffer> Result(
       new (NamedBufferAlloc(Filename))
           MemoryBufferMMapFile<WriteThroughMemoryBuffer>(false, FD, MapSize,
-                                                         Offset, EC));
+                                                         Offset, Status.permissions(), EC));
   if (EC)
     return EC;
   return std::move(Result);
@@ -420,16 +420,14 @@
                 bool IsVolatile) {
   static int PageSize = sys::Process::getPageSize();
 
+  sys::fs::file_status Status;
+  std::error_code EC = sys::fs::status(FD, Status);
+  if (EC)
+    return EC;
+
   // Default is to map the full file.
   if (MapSize == uint64_t(-1)) {
-    // If we don't know the file size, use fstat to find out.  fstat on an open
-    // file descriptor is cheaper than stat on a random path.
     if (FileSize == uint64_t(-1)) {
-      sys::fs::file_status Status;
-      std::error_code EC = sys::fs::status(FD, Status);
-      if (EC)
-        return EC;
-
       // If this not a file or a block device (e.g. it's a named pipe
       // or character device), we can't trust the size. Create the memory
       // buffer by copying off the stream.
@@ -446,9 +444,9 @@
   if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator,
                     PageSize, IsVolatile)) {
     std::error_code EC;
-    std::unique_ptr<MB> Result(
-        new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile<MB>(
-            RequiresNullTerminator, FD, MapSize, Offset, EC));
+    std::unique_ptr<MB> Result(new (NamedBufferAlloc(
+        Filename)) MemoryBufferMMapFile<MB>(RequiresNullTerminator, FD, MapSize,
+                                            Offset, Status.permissions(), EC));
     if (!EC)
       return std::move(Result);
   }
Index: lib/Support/Windows/Path.inc
===================================================================
--- lib/Support/Windows/Path.inc
+++ lib/Support/Windows/Path.inc
@@ -847,8 +847,9 @@
 }
 
 mapped_file_region::mapped_file_region(int fd, mapmode mode, size_t length,
-                                       uint64_t offset, std::error_code &ec)
-    : Size(length), Mapping() {
+                                       uint64_t offset, bool Exe,
+                                       std::error_code &ec)
+    : Size(length), Mapping(), Executable(Exe) {
   ec = init(fd, offset, mode);
   if (ec)
     Mapping = 0;
@@ -858,12 +859,14 @@
   if (Mapping) {
     ::UnmapViewOfFile(Mapping);
 
-    if (Mode == mapmode::readwrite) {
+    if (Mode == mapmode::readwrite && Executable) {
       // There is a Windows kernel bug, the exact trigger conditions of which
       // are not well understood.  When triggered, dirty pages are not properly
       // flushed and subsequent process's attempts to read a file can return
       // invalid data.  Calling FlushFileBuffers on the write handle is
       // sufficient to ensure that this bug is not triggered.
+      // The bug only occurs when writing an executable and executing it right
+      // after, under high I/O pressure.
       ::FlushFileBuffers(FileHandle);
     }
 
Index: lib/XRay/InstrumentationMap.cpp
===================================================================
--- lib/XRay/InstrumentationMap.cpp
+++ lib/XRay/InstrumentationMap.cpp
@@ -137,7 +137,8 @@
          InstrumentationMap::FunctionAddressReverseMap &FunctionIds) {
   std::error_code EC;
   sys::fs::mapped_file_region MappedFile(
-      Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
+      Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0,
+      false /*Exe*/, EC);
   if (EC)
     return make_error<StringError>(
         Twine("Failed memory-mapping file '") + Filename + "'.", EC);
Index: lib/XRay/Profile.cpp
===================================================================
--- lib/XRay/Profile.cpp
+++ lib/XRay/Profile.cpp
@@ -273,7 +273,8 @@
 
   std::error_code EC;
   sys::fs::mapped_file_region MappedFile(
-      Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
+      Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0,
+      false /*Exe*/, EC);
   if (EC)
     return make_error<StringError>(
         Twine("Cannot mmap profile '") + Filename + "'", EC);
Index: lib/XRay/Trace.cpp
===================================================================
--- lib/XRay/Trace.cpp
+++ lib/XRay/Trace.cpp
@@ -381,7 +381,8 @@
   // Map the opened file into memory and use a StringRef to access it later.
   std::error_code EC;
   sys::fs::mapped_file_region MappedFile(
-      Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
+      Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0,
+      false /*Exe*/, EC);
   if (EC) {
     return make_error<StringError>(
         Twine("Cannot read log from '") + Filename + "'", EC);
Index: tools/llvm-xray/xray-fdr-dump.cpp
===================================================================
--- tools/llvm-xray/xray-fdr-dump.cpp
+++ tools/llvm-xray/xray-fdr-dump.cpp
@@ -48,7 +48,8 @@
 
   std::error_code EC;
   sys::fs::mapped_file_region MappedFile(
-      Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0, EC);
+      Fd, sys::fs::mapped_file_region::mapmode::readonly, FileSize, 0,
+      false /*Exe*/, EC);
 
   DataExtractor DE(StringRef(MappedFile.data(), MappedFile.size()), true, 8);
   uint32_t OffsetPtr = 0;
Index: unittests/Support/Path.cpp
===================================================================
--- unittests/Support/Path.cpp
+++ unittests/Support/Path.cpp
@@ -1049,7 +1049,8 @@
   StringRef Val("hello there");
   {
     fs::mapped_file_region mfr(FileDescriptor,
-                               fs::mapped_file_region::readwrite, Size, 0, EC);
+                               fs::mapped_file_region::readwrite, Size, 0,
+                               false /*Executable*/, EC);
     ASSERT_NO_ERROR(EC);
     std::copy(Val.begin(), Val.end(), mfr.data());
     // Explicitly add a 0.
@@ -1063,14 +1064,16 @@
     int FD;
     EC = fs::openFileForRead(Twine(TempPath), FD);
     ASSERT_NO_ERROR(EC);
-    fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC);
+    fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0,
+                               false /*Executable*/, EC);
     ASSERT_NO_ERROR(EC);
 
     // Verify content
     EXPECT_EQ(StringRef(mfr.const_data()), Val);
 
     // Unmap temp file
-    fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC);
+    fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0,
+                             false /*Executable*/, EC);
     ASSERT_NO_ERROR(EC);
     ASSERT_EQ(close(FD), 0);
   }
Index: unittests/Support/ReplaceFileTest.cpp
===================================================================
--- unittests/Support/ReplaceFileTest.cpp
+++ unittests/Support/ReplaceFileTest.cpp
@@ -147,8 +147,9 @@
     std::error_code EC;
     ASSERT_NO_ERROR(fs::openFileForRead(TargetFileName, TargetFD));
     ScopedFD X(TargetFD);
-    sys::fs::mapped_file_region MFR(
-        TargetFD, sys::fs::mapped_file_region::readonly, 10, 0, EC);
+    sys::fs::mapped_file_region MFR(TargetFD,
+                                    sys::fs::mapped_file_region::readonly, 10,
+                                    0, false /*Executable*/, EC);
     ASSERT_FALSE(EC);
 
     ASSERT_NO_ERROR(fs::rename(SourceFileName, TargetFileName));