Merge pull request #20825 from DougGregor/runtime-override-conforms-to-swift-protocol

diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 93b6b65..a0c7dfd 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -378,7 +378,7 @@
 function(_add_variant_link_flags)
   set(oneValueArgs SDK ARCH BUILD_TYPE ENABLE_ASSERTIONS ANALYZE_CODE_COVERAGE
   DEPLOYMENT_VERSION_OSX DEPLOYMENT_VERSION_IOS DEPLOYMENT_VERSION_TVOS DEPLOYMENT_VERSION_WATCHOS
-  RESULT_VAR_NAME ENABLE_LTO LTO_OBJECT_NAME LIBRARY_SEARCH_DIRECTORIES_VAR_NAME)
+  RESULT_VAR_NAME ENABLE_LTO LTO_OBJECT_NAME LINK_LIBRARIES_VAR_NAME LIBRARY_SEARCH_DIRECTORIES_VAR_NAME)
   cmake_parse_arguments(LFLAGS
     ""
     "${oneValueArgs}"
@@ -389,6 +389,7 @@
   precondition(LFLAGS_ARCH MESSAGE "Should specify an architecture")
 
   set(result ${${LFLAGS_RESULT_VAR_NAME}})
+  set(link_libraries ${${LFLAGS_LINK_LIBRARIES_VAR_NAME}})
   set(library_search_directories ${${LFLAGS_LIBRARY_SEARCH_DIRECTORIES_VAR_NAME}})
 
   _add_variant_c_compile_link_flags(
@@ -405,9 +406,9 @@
     RESULT_VAR_NAME result)
 
   if("${LFLAGS_SDK}" STREQUAL "LINUX")
-    list(APPEND result "-lpthread" "-latomic" "-ldl")
+    list(APPEND link_libraries "pthread" "atomic" "dl")
   elseif("${LFLAGS_SDK}" STREQUAL "FREEBSD")
-    list(APPEND result "-lpthread")
+    list(APPEND link_libraries "pthread")
   elseif("${LFLAGS_SDK}" STREQUAL "CYGWIN")
     # No extra libraries required.
   elseif("${LFLAGS_SDK}" STREQUAL "WINDOWS")
@@ -425,9 +426,10 @@
     list(APPEND library_search_directories
          ${CMAKE_BINARY_DIR}/winsdk_lib_${LFLAGS_ARCH}_symlinks)
   elseif("${LFLAGS_SDK}" STREQUAL "HAIKU")
-    list(APPEND result "-lbsd" "-latomic" "-Wl,-Bsymbolic")
+    list(APPEND link_libraries "bsd" "atomic")
+    list(APPEND result "-Wl,-Bsymbolic")
   elseif("${LFLAGS_SDK}" STREQUAL "ANDROID")
-    list(APPEND result "-ldl" "-llog" "-latomic" "-licudataswift" "-licui18nswift" "-licuucswift")
+    list(APPEND link_libraries "dl" "log" "atomic" "icudataswift" "icui18nswift" "icuucswift")
     if("${LFLAGS_ARCH}" MATCHES armv7)
       list(APPEND result "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so")
     elseif("${LFLAGS_ARCH}" MATCHES aarch64)
@@ -437,7 +439,7 @@
     endif()
     swift_android_lib_for_arch(${LFLAGS_ARCH} ${LFLAGS_ARCH}_LIB)
     foreach(path IN LISTS ${LFLAGS_ARCH}_LIB)
-      list(APPEND library_search_directories ${path}) 
+      list(APPEND library_search_directories ${path})
     endforeach()
   else()
     # If lto is enabled, we need to add the object path flag so that the LTO code
@@ -477,6 +479,7 @@
   endif()
 
   set("${LFLAGS_RESULT_VAR_NAME}" "${result}" PARENT_SCOPE)
+  set("${LFLAGS_LINK_LIBRARIES_VAR_NAME}" "${link_libraries}" PARENT_SCOPE)
   set("${LFLAGS_LIBRARY_SEARCH_DIRECTORIES_VAR_NAME}" "${library_search_directories}" PARENT_SCOPE)
 endfunction()
 
@@ -1209,6 +1212,7 @@
     DEPLOYMENT_VERSION_TVOS "${SWIFTLIB_DEPLOYMENT_VERSION_TVOS}"
     DEPLOYMENT_VERSION_WATCHOS "${SWIFTLIB_DEPLOYMENT_VERSION_WATCHOS}"
     RESULT_VAR_NAME link_flags
+    LINK_LIBRARIES_VAR_NAME link_libraries
     LIBRARY_SEARCH_DIRECTORIES_VAR_NAME library_search_directories
       )
 
@@ -1253,6 +1257,7 @@
       COMPILE_FLAGS " ${c_compile_flags}")
   set_property(TARGET "${target}" APPEND_STRING PROPERTY
       LINK_FLAGS " ${link_flags}")
+  set_property(TARGET "${target}" APPEND PROPERTY LINK_LIBRARIES ${link_libraries})
   swift_target_link_search_directories("${target}" "${library_search_directories}")
 
   # Adjust the linked libraries for windows targets.  On Windows, the link is
@@ -2127,6 +2132,7 @@
     LTO_OBJECT_NAME "${name}-${SWIFTEXE_SINGLE_SDK}-${SWIFTEXE_SINGLE_ARCHITECTURE}"
     ANALYZE_CODE_COVERAGE "${SWIFT_ANALYZE_CODE_COVERAGE}"
     RESULT_VAR_NAME link_flags
+    LINK_LIBRARIES_VAR_NAME link_libraries
     LIBRARY_SEARCH_DIRECTORIES_VAR_NAME library_search_directories)
 
   if(${SWIFTEXE_SINGLE_SDK} IN_LIST SWIFT_APPLE_PLATFORMS)
@@ -2192,6 +2198,7 @@
   swift_target_link_search_directories("${name}" "${library_search_directories}")
   set_property(TARGET ${name} APPEND_STRING PROPERTY
       LINK_FLAGS " ${link_flags}")
+  set_property(TARGET ${name} APPEND PROPERTY LINK_LIBRARIES ${link_libraries})
   if (SWIFT_PARALLEL_LINK_JOBS)
     set_property(TARGET ${name} PROPERTY JOB_POOL_LINK swift_link_job_pool)
   endif()
diff --git a/include/swift/Basic/Statistic.h b/include/swift/Basic/Statistic.h
index e2ea4a2..bc623bc 100644
--- a/include/swift/Basic/Statistic.h
+++ b/include/swift/Basic/Statistic.h
@@ -21,7 +21,9 @@
 #include <thread>
 #include <tuple>
 
-#define SWIFT_FUNC_STAT                                                 \
+#define SWIFT_FUNC_STAT SWIFT_FUNC_STAT_NAMED(DEBUG_TYPE)
+
+#define SWIFT_FUNC_STAT_NAMED(DEBUG_TYPE)                               \
   do {                                                                  \
     static llvm::Statistic FStat =                                      \
       {DEBUG_TYPE, __func__, __func__, {0}, {false}};                   \
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 78cc044..adfef30 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -67,6 +67,10 @@
   /// Set of basic blocks where unreachable was inserted.
   SmallPtrSet<SILBasicBlock *, 32> BlocksWithUnreachables;
 
+  // Keep track of the last cloned block in function order. For single block
+  // regions, this will be the start block.
+  SILBasicBlock *lastClonedBB = nullptr;
+
 public:
   using SILInstructionVisitor<ImplClass>::asImpl;
 
@@ -102,6 +106,10 @@
 
   SILBuilder &getBuilder() { return Builder; }
 
+  // After cloning, returns a non-null pointer to the last cloned block in
+  // function order. For single block regions, this will be the start block.
+  SILBasicBlock *getLastClonedBB() { return lastClonedBB; }
+
   /// Visit all blocks reachable from the given `StartBB` and all instructions
   /// in those blocks.
   ///
@@ -655,7 +663,7 @@
   // order they are created, which differs from the order they are
   // cloned. Blocks are created in BFS order but cloned in DFS preorder (when no
   // critical edges are present).
-  SILBasicBlock *lastClonedBB = BBMap[startBB];
+  lastClonedBB = BBMap[startBB];
   while (!dfsWorklist.empty()) {
     auto *BB = dfsWorklist.pop_back_val();
     preorderBlocks.push_back(BB);
diff --git a/include/swift/SILOptimizer/Utils/CFG.h b/include/swift/SILOptimizer/Utils/CFG.h
index 2913240..fe3581a 100644
--- a/include/swift/SILOptimizer/Utils/CFG.h
+++ b/include/swift/SILOptimizer/Utils/CFG.h
@@ -127,6 +127,16 @@
 bool mergeBasicBlockWithSuccessor(SILBasicBlock *BB, DominanceInfo *DT,
                                   SILLoopInfo *LI);
 
+/// Merge basic blocks in the given function by eliminating all unconditional
+/// branches to single-predecessor branch targets.
+///
+/// During optimization, SimplifyCFG also handles this, but this is a basic
+/// canonicalization after any pass that splits blocks, such as inlining. This
+/// is not done on-the-fly after splitting blocks because merging is linear in
+/// the number of instructions, so interleaved merging and splitting is
+/// quadratic.
+bool mergeBasicBlocks(SILFunction *F);
+
 /// Given a list of \p UserBlocks and a list of \p DefBlocks, find a set of
 /// blocks that together with \p UserBlocks joint-postdominate \p
 /// DefBlocks. This is in a sense finding a set of blocks that "complete" \p
diff --git a/include/swift/SILOptimizer/Utils/SILInliner.h b/include/swift/SILOptimizer/Utils/SILInliner.h
index 8a7fcb6..12fe700 100644
--- a/include/swift/SILOptimizer/Utils/SILInliner.h
+++ b/include/swift/SILOptimizer/Utils/SILInliner.h
@@ -80,18 +80,32 @@
   /// iterator to the first inlined instruction (or first instruction after the
   /// call for an empty function).
   ///
-  /// This may split basic blocks and delete instructions.
-  ///
   /// This only performs one step of inlining: it does not recursively
   /// inline functions called by the callee.
   ///
+  /// This may split basic blocks and delete instructions anywhere.
+  ///
+  /// All inlined instructions must be either inside the original call block or
+  /// inside new basic blocks laid out after the original call block.
+  ///
+  /// Any instructions in the original call block after the inlined call must be
+  /// in a new basic block laid out after all inlined blocks.
+  ///
+  /// The above guarantees ensure that inlining is liner in the number of
+  /// instructions and that inlined instructions are revisited exactly once.
+  ///
   /// *NOTE*: This attempts to perform inlining unconditionally and thus asserts
   /// if inlining will fail. All users /must/ check that a function is allowed
   /// to be inlined using SILInliner::canInlineApplySite before calling this
   /// function.
-  SILBasicBlock::iterator inlineFunction(SILFunction *calleeFunction,
-                                         FullApplySite apply,
-                                         ArrayRef<SILValue> appliedArgs);
+  ///
+  /// Returns an iterator to the first inlined instruction (or the end of the
+  /// caller block for empty functions) and the last block in function order
+  /// containing inlined instructions (the original caller block for
+  /// single-block functions).
+  std::pair<SILBasicBlock::iterator, SILBasicBlock *>
+  inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
+                 ArrayRef<SILValue> appliedArgs);
 };
 
 } // end namespace swift
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index c1722dc..4cbb719 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -52,7 +52,7 @@
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
 /// Don't worry about adhering to the 80-column limit for this line.
-const uint16_t SWIFTMODULE_VERSION_MINOR = 468; // Last change: SelfProtocolConformance
+const uint16_t SWIFTMODULE_VERSION_MINOR = 469; // @_hasStorage
 
 using DeclIDField = BCFixed<31>;
 
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index f0d6f5c..e621748 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -2111,7 +2111,9 @@
   }
 
 
-  CanType type = decl->getInterfaceType()->getCanonicalType();
+  CanType type = decl->getInterfaceType()
+                      ->getReferenceStorageReferent()
+                      ->getCanonicalType();
   if (auto gft = dyn_cast<GenericFunctionType>(type)) {
     genericSig = gft.getGenericSignature();
     CurGenericSignature = gft.getGenericSignature();
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index ec97c83..1c6f0b7 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -591,11 +591,13 @@
       return;
 
     printAccess(D->getFormalAccess());
+    bool shouldSkipSetterAccess =
+      llvm::is_contained(Options.ExcludeAttrList, DAK_SetterAccess);
 
     if (auto storageDecl = dyn_cast<AbstractStorageDecl>(D)) {
       if (auto setter = storageDecl->getSetter()) {
         AccessLevel setterAccess = setter->getFormalAccess();
-        if (setterAccess != D->getFormalAccess())
+        if (setterAccess != D->getFormalAccess() && !shouldSkipSetterAccess)
           printAccess(setterAccess, "(set)");
       }
     }
@@ -865,6 +867,10 @@
   return setter && setter->isExplicitNonMutating();
 }
 
+static bool hasLessAccessibleSetter(const AbstractStorageDecl *ASD) {
+  return ASD->getSetterFormalAccess() < ASD->getFormalAccess();
+}
+
 void PrintAST::printAttributes(const Decl *D) {
   if (Options.SkipAttributes)
     return;
@@ -880,11 +886,20 @@
       Options.ExcludeAttrList.push_back(DAK_Final);
     }
 
-    // Don't print @_hasInitialValue if we're printing an initializer
-    // expression.
     if (auto vd = dyn_cast<VarDecl>(D)) {
+      // Don't print @_hasInitialValue if we're printing an initializer
+      // expression.
       if (vd->isInitExposedToClients())
         Options.ExcludeAttrList.push_back(DAK_HasInitialValue);
+
+      if (!Options.PrintForSIL) {
+        // Don't print @_hasStorage if the value is simply stored, or the
+        // decl is resilient.
+        if (vd->isResilient() ||
+            (vd->getImplInfo().isSimpleStored() &&
+             !hasLessAccessibleSetter(vd)))
+          Options.ExcludeAttrList.push_back(DAK_HasStorage);
+      }
     }
 
     // Don't print any contextual decl modifiers.
@@ -1613,19 +1628,28 @@
   if (isa<VarDecl>(ASD) && !Options.PrintPropertyAccessors)
     return;
 
-  // Never print anything for stored properties.
-  if (ASD->getAllAccessors().empty())
-    return;
-
   auto impl = ASD->getImplInfo();
 
-  // Treat StoredWithTrivialAccessors the same as Stored unless
-  // we're printing for SIL, in which case we want to distinguish it
-  // from a pure stored property.
+  // Don't print accessors for trivially stored properties...
   if (impl.isSimpleStored()) {
+    // ...unless we're printing for SIL, which expects a { get set? } on
+    //    trivial properties
     if (Options.PrintForSIL) {
       Printer << " { get " << (impl.supportsMutation() ? "set }" : "}");
     }
+    // ...or you're private/internal(set), at which point we'll print
+    //    @_hasStorage var x: T { get }
+    else if (ASD->isSettable(nullptr) && hasLessAccessibleSetter(ASD)) {
+      Printer << " {";
+      {
+        IndentRAII indentMore(*this);
+        indent();
+        Printer.printNewline();
+        Printer << "get";
+        Printer.printNewline();
+      }
+      Printer << "}";
+    }
     return;
   }
 
@@ -1762,12 +1786,8 @@
       llvm_unreachable("simply-stored variable should have been filtered out");
     case WriteImplKind::StoredWithObservers:
     case WriteImplKind::InheritedWithObservers: {
-      bool skippedWillSet = PrintAccessor(ASD->getWillSetFunc());
-      bool skippedDidSet = PrintAccessor(ASD->getDidSetFunc());
-      if (skippedDidSet && skippedWillSet) {
-        PrintAccessor(ASD->getGetter());
-        PrintAccessor(ASD->getSetter());
-      }
+      PrintAccessor(ASD->getGetter());
+      PrintAccessor(ASD->getSetter());
       break;
     }
     case WriteImplKind::Set:
@@ -2091,6 +2111,12 @@
       SmallString<128> scratch;
       Printer << " = " << entry.getInitStringRepresentation(scratch);
     }
+
+    // HACK: If we're just printing a single pattern and it has accessors,
+    //       print the accessors here.
+    if (decl->getNumPatternEntries() == 1) {
+      printAccessors(vd);
+    }
   }
 }
 
@@ -2322,7 +2348,6 @@
                        Options.BracketOptions.shouldCloseNominal(decl));
   }
 }
-
 static bool isStructOrClassContext(DeclContext *dc) {
   auto *nominal = dc->getSelfNominalTypeDecl();
   if (nominal == nullptr)
diff --git a/lib/ClangImporter/MappedTypes.def b/lib/ClangImporter/MappedTypes.def
index 0fd435a..9afc664 100644
--- a/lib/ClangImporter/MappedTypes.def
+++ b/lib/ClangImporter/MappedTypes.def
@@ -161,6 +161,9 @@
 
 // CoreFoundation types.
 // Note that we're preserving the typealias for CFIndex.
+MAP_STDLIB_TYPE("CFTypeID", UnsignedWord, 0, "UInt", false, DefineAndUse)
+MAP_STDLIB_TYPE("CFOptionFlags", UnsignedWord, 0, "UInt", false, DefineAndUse)
+MAP_STDLIB_TYPE("CFHashCode", UnsignedWord, 0, "UInt", false, DefineAndUse)
 MAP_STDLIB_TYPE("CFIndex", SignedWord, 0, "Int", false, DefineAndUse)
 
 // Foundation types.
diff --git a/lib/Frontend/ParseableInterfaceSupport.cpp b/lib/Frontend/ParseableInterfaceSupport.cpp
index 5ff58c8..344baf9 100644
--- a/lib/Frontend/ParseableInterfaceSupport.cpp
+++ b/lib/Frontend/ParseableInterfaceSupport.cpp
@@ -344,10 +344,12 @@
     }
 
     LLVM_DEBUG(llvm::dbgs() << "Serializing " << OutPath << "\n");
+    FrontendOptions &FEOpts = SubInvocation.getFrontendOptions();
     SerializationOptions SerializationOpts;
     std::string OutPathStr = OutPath;
     SerializationOpts.OutputPath = OutPathStr.c_str();
     SerializationOpts.SerializeAllSIL = true;
+    SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName;
     SmallVector<FileDependency, 16> Deps;
     if (collectDepsForSerialization(FS, SubInstance, InPath, ModuleCachePath,
                                     Deps, Diags, OuterTracker)) {
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index d46cfb4..71d485f 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -4777,6 +4777,72 @@
   }
 }
 
+/// Gets the storage info of the provided storage decl if it has the
+/// @_hasStorage attribute and it's not in SIL mode.
+///
+/// In this case, we say the decl is:
+///
+/// Read:
+///   - Stored, always
+/// Write:
+///   - Stored, if the decl is a 'var'.
+///   - StoredWithObservers, if the decl has a setter
+///     - This indicates that the original decl had a 'didSet' and/or 'willSet'
+///   - InheritedWithObservers, if the decl has a setter and is an overridde.
+///   - Immutable, if the decl is a 'let' or it does not have a setter.
+/// ReadWrite:
+///   - Stored, if the decl has no accessors listed.
+///   - Immutable, if the decl is a 'let' or it does not have a setter.
+///   - MaterializeToTemporary, if the decl has a setter.
+static StorageImplInfo classifyWithHasStorageAttr(
+  Parser::ParsedAccessors &accessors, ASTContext &ctx,
+  AbstractStorageDecl *storage, const DeclAttributes &attrs) {
+
+  // Determines if the storage is immutable, either by declaring itself as a
+  // `let` or by omitting a setter.
+  auto isImmutable = [&]() {
+    if (auto varDecl = dyn_cast<VarDecl>(storage))
+      return varDecl->isImmutable();
+    if (accessors.Set == nullptr) return true;
+    return false;
+  };
+
+  // Determines if the storage had a private setter, i.e. it's not a 'let' and
+  // it had a setter.
+  auto isPrivateSet = [&]() {
+    if (auto varDecl = dyn_cast<VarDecl>(storage))
+      return !varDecl->isImmutable() && accessors.Set == nullptr;
+    return false;
+  };
+
+  // Default to stored writes.
+  WriteImplKind writeImpl = WriteImplKind::Stored;
+  ReadWriteImplKind readWriteImpl = ReadWriteImplKind::Stored;
+
+  if (accessors.Get && accessors.Set) {
+    // If we see `@_hasStorage var x: T { get set }`, then our property has
+    // willSet/didSet observers.
+    writeImpl = attrs.hasAttribute<OverrideAttr>() ?
+      WriteImplKind::InheritedWithObservers :
+      WriteImplKind::StoredWithObservers;
+    readWriteImpl = ReadWriteImplKind::MaterializeToTemporary;
+  } else if (isImmutable()) {
+    writeImpl = WriteImplKind::Immutable;
+    readWriteImpl = ReadWriteImplKind::Immutable;
+  }
+
+  if (isPrivateSet()) {
+    // If we saw a 'var' with no setter, that means it was
+    // private/internal(set). Honor that with a synthesized attribute.
+    storage->getAttrs().add(
+      new (ctx) SetterAccessAttr(
+        SourceLoc(), SourceLoc(), AccessLevel::Private, /*implicit: */true));
+  }
+
+  // Always force Stored reads if @_hasStorage is present.
+  return StorageImplInfo(ReadImplKind::Stored, writeImpl, readWriteImpl);
+}
+
 StorageImplInfo
 Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
                                   bool invalid, ParseDeclOptions flags,
@@ -4935,10 +5001,26 @@
     readWriteImpl = ReadWriteImplKind::Immutable;
   }
 
-  // Allow the _hasStorage attribute to override all the accessors we parsed
+  // Allow the @_hasStorage attribute to override all the accessors we parsed
   // when making the final classification.
   if (attrs.hasAttribute<HasStorageAttr>()) {
-    return StorageImplInfo::getSimpleStored(StorageIsMutable_t(Set != nullptr));
+    // The SIL rules for @_hasStorage are slightly different from the non-SIL
+    // rules. In SIL mode, @_hasStorage marks that the type is simply stored,
+    // and the only thing that determines mutability is the existence of the
+    // setter.
+    //
+    // FIXME: SIL should not be special cased here. The behavior should be
+    //        consistent between SIL and non-SIL.
+    //        The strategy here should be to keep track of all opaque accessors
+    //        along with enough information to access the storage trivially
+    //        if allowed. This could be a representational change to
+    //        StorageImplInfo such that it keeps a bitset of listed accessors
+    //        and dynamically determines the access strategy from that.
+    if (P.isInSILMode())
+      return StorageImplInfo::getSimpleStored(
+        StorageIsMutable_t(Set != nullptr));
+
+    return classifyWithHasStorageAttr(*this, P.Context, storage, attrs);
   }
 
   return StorageImplInfo(readImpl, writeImpl, readWriteImpl);
diff --git a/lib/SIL/SILInstruction.cpp b/lib/SIL/SILInstruction.cpp
index 159c252..ea4d808 100644
--- a/lib/SIL/SILInstruction.cpp
+++ b/lib/SIL/SILInstruction.cpp
@@ -86,8 +86,10 @@
   if (ThisParent == L2.getContainingBlock()) return;
 
   // Update the parent fields in the instructions.
-  for (; first != last; ++first)
+  for (; first != last; ++first) {
+    SWIFT_FUNC_STAT_NAMED("sil");
     first->ParentBB = ThisParent;
+  }
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
index 9924339..8a98443 100644
--- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
+++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
@@ -49,7 +49,7 @@
 /// and that the function implementing the closure consumes its capture
 /// arguments.
 static void fixupReferenceCounts(
-    SILBasicBlock::iterator I, SILValue CalleeValue,
+    SILInstruction *I, SILValue CalleeValue,
     SmallVectorImpl<std::pair<SILValue, ParameterConvention>> &CaptureArgs,
     bool isCalleeGuaranteed) {
   // Add a copy of each non-address type capture argument to lifetime extend the
@@ -60,7 +60,7 @@
     if (!CaptureArg.first->getType().isAddress() &&
         CaptureArg.second != ParameterConvention::Direct_Guaranteed &&
         CaptureArg.second != ParameterConvention::Direct_Unowned) {
-      createIncrementBefore(CaptureArg.first, &*I);
+      createIncrementBefore(CaptureArg.first, I);
     } else {
       // FIXME: What about indirectly owned parameters? The invocation of the
       // closure would perform an indirect copy which we should mimick here.
@@ -190,35 +190,31 @@
 class ClosureCleanup {
   using DeadInstSet = SmallBlotSetVector<SILInstruction *, 4>;
 
-  /// A helper class to update an instruction iterator if
-  /// removal of instructions would invalidate it.
+  /// A helper class to update the set of dead instructions.
   ///
   /// Since this is called by the SILModule callback, the instruction may longer
   /// be well-formed. Do not visit its operands. However, it's position in the
   /// basic block is still valid.
   ///
-  /// FIXME: Using the Module's callback mechanism is undesirable. Instead,
-  /// cleanupCalleeValue could be easily rewritten to use its own instruction
-  /// deletion helper and pass a callback to tryDeleteDeadClosure and
-  /// recursivelyDeleteTriviallyDeadInstructions.
-  class IteratorUpdateHandler : public DeleteNotificationHandler {
+  /// FIXME: Using the Module's callback mechanism for this is terrible.
+  /// Instead, cleanupCalleeValue could be easily rewritten to use its own
+  /// instruction deletion helper and pass a callback to tryDeleteDeadClosure
+  /// and recursivelyDeleteTriviallyDeadInstructions.
+  class DeleteUpdateHandler : public DeleteNotificationHandler {
     SILModule &Module;
-    SILBasicBlock::iterator CurrentI;
     DeadInstSet &DeadInsts;
 
   public:
-    IteratorUpdateHandler(SILBasicBlock::iterator I, DeadInstSet &DeadInsts)
-        : Module(I->getModule()), CurrentI(I), DeadInsts(DeadInsts) {
+    DeleteUpdateHandler(SILModule &M, DeadInstSet &DeadInsts)
+        : Module(M), DeadInsts(DeadInsts) {
       Module.registerDeleteNotificationHandler(this);
     }
 
-    ~IteratorUpdateHandler() override {
+    ~DeleteUpdateHandler() override {
       // Unregister the handler.
       Module.removeDeleteNotificationHandler(this);
     }
 
-    SILBasicBlock::iterator getIterator() const { return CurrentI; }
-
     // Handling of instruction removal notifications.
     bool needsNotifications() override { return true; }
 
@@ -229,9 +225,6 @@
         return;
 
       DeadInsts.erase(deletedI);
-
-      if (CurrentI == SILBasicBlock::iterator(deletedI))
-        ++CurrentI;
     }
   };
 
@@ -260,8 +253,8 @@
   // Note: instructions in the `deadFunctionVals` set may use each other, so the
   // set needs to continue to be updated (by this handler) when deleting
   // instructions. This assumes that DeadFunctionValSet::erase() is stable.
-  SILBasicBlock::iterator cleanupDeadClosures(SILBasicBlock::iterator II) {
-    IteratorUpdateHandler iteratorUpdate(II, deadFunctionVals);
+  void cleanupDeadClosures(SILFunction *F) {
+    DeleteUpdateHandler deleteUpdate(F->getModule(), deadFunctionVals);
     for (Optional<SILInstruction *> I : deadFunctionVals) {
       if (!I.hasValue())
         continue;
@@ -269,7 +262,6 @@
       if (auto *SVI = dyn_cast<SingleValueInstruction>(I.getValue()))
         cleanupCalleeValue(SVI);
     }
-    return iteratorUpdate.getIterator();
   }
 };
 } // end of namespace
@@ -472,21 +464,21 @@
   return CalleeFunction;
 }
 
-static std::tuple<FullApplySite, SILBasicBlock::iterator>
-tryDevirtualizeApplyHelper(FullApplySite InnerAI, SILBasicBlock::iterator I,
-                           ClassHierarchyAnalysis *CHA) {
+static SILInstruction *tryDevirtualizeApplyHelper(FullApplySite InnerAI,
+                                                  ClassHierarchyAnalysis *CHA) {
   auto NewInst = tryDevirtualizeApply(InnerAI, CHA);
-  if (!NewInst) {
-    return std::make_tuple(InnerAI, I);
-  }
+  if (!NewInst)
+    return InnerAI.getInstruction();
 
   deleteDevirtualizedApply(InnerAI);
 
+  // FIXME: Comments at the use of this helper indicate that devirtualization
+  // may return SILArgument. Yet here we assert that it must return an
+  // instruction.
   auto newApplyAI = NewInst.getInstruction();
   assert(newApplyAI && "devirtualized but removed apply site?");
 
-  return std::make_tuple(FullApplySite::isa(newApplyAI),
-                         newApplyAI->getIterator());
+  return newApplyAI;
 }
 
 /// \brief Inlines all mandatory inlined functions into the body of a function,
@@ -532,23 +524,34 @@
   SmallVector<std::pair<SILValue, ParameterConvention>, 16> CaptureArgs;
   SmallVector<SILValue, 32> FullArgs;
 
-  for (auto BI = F->begin(), BE = F->end(); BI != BE; ++BI) {
+  // Visiting blocks in reverse order avoids revisiting instructions after block
+  // splitting, which would be quadratic.
+  for (auto BI = F->rbegin(), BE = F->rend(), nextBB = BI; BI != BE;
+       BI = nextBB) {
+    // After inlining, the block iterator will be adjusted to point to the last
+    // block containing inlined instructions. This way, the inlined function
+    // body will be reprocessed within the caller's context without revisiting
+    // any original instructions.
+    nextBB = std::next(BI);
+
     // While iterating over this block, instructions are inserted and deleted.
-    for (auto II = BI->begin(), nextI = II; II != BI->end(); II = nextI) {
-      nextI = std::next(II);
-
+    // To avoid quadratic block splitting, instructions must be processed in
+    // reverse order (block splitting reassigned the parent pointer of all
+    // instructions below the split point).
+    for (auto II = BI->rbegin(); II != BI->rend(); ++II) {
       FullApplySite InnerAI = FullApplySite::isa(&*II);
-
       if (!InnerAI)
         continue;
 
-      auto *ApplyBlock = InnerAI.getParent();
-
-      // *NOTE* If devirtualization succeeds, sometimes II will not be InnerAI,
+      // *NOTE* If devirtualization succeeds, devirtInst may not be InnerAI,
       // but a casted result of InnerAI or even a block argument due to
-      // abstraction changes when calling the witness or class method. We still
-      // know that InnerAI dominates II though.
-      std::tie(InnerAI, II) = tryDevirtualizeApplyHelper(InnerAI, II, CHA);
+      // abstraction changes when calling the witness or class method.
+      auto *devirtInst = tryDevirtualizeApplyHelper(InnerAI, CHA);
+      // Restore II to the current apply site.
+      II = devirtInst->getReverseIterator();
+      // If the devirtualized call result is no longer a invalid FullApplySite,
+      // then it has succeeded, but the result is not immediately inlinable.
+      InnerAI = FullApplySite::isa(devirtInst);
       if (!InnerAI)
         continue;
 
@@ -597,13 +600,8 @@
 
       SILInliner Inliner(FuncBuilder, SILInliner::InlineKind::MandatoryInline,
                          Subs, OpenedArchetypesTracker);
-      if (!Inliner.canInlineApplySite(InnerAI)) {
-        // See comment above about casting when devirtualizing and how this
-        // sometimes causes II and InnerAI to be different and even in different
-        // blocks.
-        II = InnerAI.getInstruction()->getIterator();
+      if (!Inliner.canInlineApplySite(InnerAI))
         continue;
-      }
 
       // Inline function at I, which also changes I to refer to the first
       // instruction inlined in the case that it succeeds. We purposely
@@ -620,7 +618,8 @@
         bool IsCalleeGuaranteed =
             PAI &&
             PAI->getType().castTo<SILFunctionType>()->isCalleeGuaranteed();
-        fixupReferenceCounts(II, CalleeValue, CaptureArgs, IsCalleeGuaranteed);
+        fixupReferenceCounts(InnerAI.getInstruction(), CalleeValue, CaptureArgs,
+                             IsCalleeGuaranteed);
       }
 
       // Register a callback to record potentially unused function values after
@@ -632,20 +631,23 @@
 
       // Inlining deletes the apply, and can introduce multiple new basic
       // blocks. After this, CalleeValue and other instructions may be invalid.
-      nextI = Inliner.inlineFunction(CalleeFunction, InnerAI, FullArgs);
+      // nextBB will point to the last inlined block
+      auto firstInlinedInstAndLastBB =
+          Inliner.inlineFunction(CalleeFunction, InnerAI, FullArgs);
+      nextBB = firstInlinedInstAndLastBB.second->getReverseIterator();
       ++NumMandatoryInlines;
 
       // The IR is now valid, and trivial dead arguments are removed. However,
       // we may be able to remove dead callee computations (e.g. dead
       // partial_apply closures).
-      nextI = closureCleanup.cleanupDeadClosures(nextI);
+      closureCleanup.cleanupDeadClosures(F);
 
-      assert(nextI == ApplyBlock->end()
-             || nextI->getParent() == ApplyBlock
-                    && "Mismatch between the instruction and basic block");
+      // Resume inlining within nextBB, which contains only the inlined
+      // instructions and possibly instructions in the original call block that
+      // have not yet been visited.
+      break;
     }
   }
-
   // Keep track of full inlined functions so we don't waste time recursively
   // reprocessing them.
   FullyInlinedSet.insert(F);
@@ -680,6 +682,9 @@
       runOnFunctionRecursively(FuncBuilder, &F,
                                FullApplySite(), FullyInlinedSet, SetFactory,
                                SetFactory.getEmptySet(), CHA);
+      // The inliner splits blocks at call sites. Re-merge trivial branches
+      // to reestablish a canonical CFG.
+      mergeBasicBlocks(&F);
     }
 
     if (!ShouldCleanup)
diff --git a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
index 33eb20b..8e99a66 100644
--- a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
+++ b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
@@ -17,6 +17,7 @@
 #include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
+#include "swift/SILOptimizer/Utils/CFG.h"
 #include "swift/SILOptimizer/Utils/Devirtualize.h"
 #include "swift/SILOptimizer/Utils/Generics.h"
 #include "swift/SILOptimizer/Utils/PerformanceInlinerUtils.h"
@@ -903,6 +904,9 @@
     Inliner.inlineFunction(Callee, AI, Args);
     NumFunctionsInlined++;
   }
+  // The inliner splits blocks at call sites. Re-merge trivial branches to
+  // reestablish a canonical CFG.
+  mergeBasicBlocks(Caller);
   return true;
 }
 
diff --git a/lib/SILOptimizer/Utils/CFG.cpp b/lib/SILOptimizer/Utils/CFG.cpp
index 14f215b..de2ce17 100644
--- a/lib/SILOptimizer/Utils/CFG.cpp
+++ b/lib/SILOptimizer/Utils/CFG.cpp
@@ -493,6 +493,19 @@
   return true;
 }
 
+bool swift::mergeBasicBlocks(SILFunction *F) {
+  bool merged = false;
+  for (auto BBIter = F->begin(); BBIter != F->end();) {
+    if (mergeBasicBlockWithSuccessor(&*BBIter, /*DT*/ nullptr, /*LI*/ nullptr)) {
+      merged = true;
+      // Continue to merge the current block without advancing.
+      continue;
+    }
+    ++BBIter;
+  }
+  return merged;
+}
+
 /// Splits the critical edges between from and to. This code assumes there is
 /// only one edge between the two basic blocks.
 SILBasicBlock *swift::splitIfCriticalEdge(SILBasicBlock *From,
diff --git a/lib/SILOptimizer/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp
index 418188a..d995992 100644
--- a/lib/SILOptimizer/Utils/SILInliner.cpp
+++ b/lib/SILOptimizer/Utils/SILInliner.cpp
@@ -388,7 +388,7 @@
 };
 } // namespace swift
 
-SILBasicBlock::iterator
+std::pair<SILBasicBlock::iterator, SILBasicBlock *>
 SILInliner::inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
                            ArrayRef<SILValue> appliedArgs) {
   assert(canInlineApplySite(apply)
@@ -396,7 +396,8 @@
 
   SILInlineCloner cloner(calleeFunction, apply, FuncBuilder, IKind, ApplySubs,
                          OpenedArchetypesTracker, DeletionCallback);
-  return cloner.cloneInline(appliedArgs);
+  auto nextI = cloner.cloneInline(appliedArgs);
+  return std::make_pair(nextI, cloner.getLastClonedBB());
 }
 
 SILInlineCloner::SILInlineCloner(
@@ -512,23 +513,16 @@
   // NextIter is initialized during `fixUp`.
   cloneFunctionBody(getCalleeFunction(), callerBB, entryArgs);
 
-  // As a trivial optimization, if the apply block falls through, merge it. The
-  // fall through is likely the ReturnToBB, but that is not guaranteed.
-  if (auto *BI = dyn_cast<BranchInst>(callerBB->getTerminator())) {
-    // FIXME: should be an assert once critical edges are fixed.
-    // assert(BI->getDestBB()->getSinglePredecessorBlock() &&
-    //       "the return block cannot have other predecessors.");
-    if (BI->getDestBB()->getSinglePredecessorBlock()) {
-      SILInstruction *firstInlinedInst = &*NextIter;
-      if (firstInlinedInst == BI)
-        firstInlinedInst = &BI->getDestBB()->front();
-
-      mergeBasicBlockWithSuccessor(BI->getParent(), /*DT*/ nullptr,
-                                   /*LI*/ nullptr);
-      NextIter = firstInlinedInst->getIterator();
-      ReturnToBB = nullptr;
-    }
-  }
+  // For non-throwing applies, the inlined body now unconditionally branches to
+  // the returned-to-code, which was previously part of the call site's basic
+  // block. We could trivially merge these blocks now, however, this would be
+  // quadratic: O(num-calls-in-block * num-instructions-in-block). Also,
+  // guaranteeing that caller instructions following the inlined call are in a
+  // separate block gives the inliner control over revisiting only the inlined
+  // instructions.
+  //
+  // Once all calls in a function are inlined, unconditional branches are
+  // eliminated by mergeBlocks.
   return NextIter;
 }
 
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 69902e2..5577763 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -85,6 +85,7 @@
   IGNORED_ATTR(FixedLayout)
   IGNORED_ATTR(ForbidSerializingReference)
   IGNORED_ATTR(Frozen)
+  IGNORED_ATTR(HasStorage)
   IGNORED_ATTR(Implements)
   IGNORED_ATTR(ImplicitlyUnwrappedOptional)
   IGNORED_ATTR(Infix)
@@ -285,7 +286,6 @@
   void visitAccessControlAttr(AccessControlAttr *attr);
   void visitSetterAccessAttr(SetterAccessAttr *attr);
   bool visitAbstractAccessControlAttr(AbstractAccessControlAttr *attr);
-  void visitHasStorageAttr(HasStorageAttr *attr);
   void visitObjCMembersAttr(ObjCMembersAttr *attr);
 };
 } // end anonymous namespace
@@ -428,16 +428,6 @@
                                  attr->getAttrName());
 }
 
-void AttributeEarlyChecker::visitHasStorageAttr(HasStorageAttr *attr) {
-  auto *VD = cast<VarDecl>(D);
-  if (VD->getDeclContext()->getSelfClassDecl())
-    return;
-  auto nominalDecl = VD->getDeclContext()->getSelfNominalTypeDecl();
-  if (nominalDecl && isa<StructDecl>(nominalDecl))
-    return;
-  diagnoseAndRemoveAttr(attr, diag::invalid_decl_attribute_simple);
-}
-
 static Optional<Diag<bool,Type>>
 isAcceptableOutletType(Type type, bool &isArray, TypeChecker &TC) {
   if (type->isObjCExistentialType() || type->isAny())
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index ab09d49..9f8ac22 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4057,6 +4057,10 @@
     auto *VD = cast<VarDecl>(D);
     auto *PBD = VD->getParentPatternBinding();
 
+    // Add the '@_hasStorage' attribute if this property is stored.
+    if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasStorageAttr>())
+      VD->getAttrs().add(new (Context) HasStorageAttr(/*isImplicit=*/true));
+
     // Note that we need to handle the fact that some VarDecls don't
     // have a PatternBindingDecl, for example the iterator in a
     // 'for ... in ...' loop.
diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp
index 5878682..727e2c7 100644
--- a/lib/Sema/TypeCheckDeclOverride.cpp
+++ b/lib/Sema/TypeCheckDeclOverride.cpp
@@ -1205,6 +1205,7 @@
     UNINTERESTING_ATTR(Convenience)
     UNINTERESTING_ATTR(Semantics)
     UNINTERESTING_ATTR(SetterAccess)
+    UNINTERESTING_ATTR(HasStorage)
     UNINTERESTING_ATTR(UIApplicationMain)
     UNINTERESTING_ATTR(UsableFromInline)
     UNINTERESTING_ATTR(ObjCNonLazyRealization)
@@ -1224,7 +1225,6 @@
     UNINTERESTING_ATTR(SynthesizedProtocol)
     UNINTERESTING_ATTR(RequiresStoredPropertyInits)
     UNINTERESTING_ATTR(Transparent)
-    UNINTERESTING_ATTR(HasStorage)
     UNINTERESTING_ATTR(Testable)
 
     UNINTERESTING_ATTR(WarnUnqualifiedAccess)
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 8b4cfa3..26dff8f 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -3018,21 +3018,29 @@
 
     configureStorage(var, opaqueReadOwnership,
                      readImpl, writeImpl, readWriteImpl, accessors);
-
-    if (auto accessLevel = getActualAccessLevel(rawAccessLevel)) {
-      var->setAccess(*accessLevel);
-    } else {
+    auto accessLevel = getActualAccessLevel(rawAccessLevel);
+    if (!accessLevel) {
       error();
       return nullptr;
     }
 
+    var->setAccess(*accessLevel);
+
     if (var->isSettable(nullptr)) {
-      if (auto setterAccess = getActualAccessLevel(rawSetterAccessLevel)) {
-        var->setSetterAccess(*setterAccess);
-      } else {
+      auto setterAccess = getActualAccessLevel(rawSetterAccessLevel);
+      if (!setterAccess) {
         error();
         return nullptr;
       }
+      var->setSetterAccess(*setterAccess);
+
+      // If we have a less-accessible setter, honor that by adding the
+      // setter access attribute.
+      if (*setterAccess < *accessLevel) {
+        AddAttribute(
+          new (ctx) SetterAccessAttr(SourceLoc(), SourceLoc(),
+                                     *setterAccess, /*implicit*/true));
+      }
     }
 
     if (isImplicit)
@@ -3043,6 +3051,10 @@
     if (var->getOverriddenDecl())
       AddAttribute(new (ctx) OverrideAttr(SourceLoc()));
 
+    // Add the @_hasStorage attribute if this var has storage.
+    if (var->hasStorage())
+      AddAttribute(new (ctx) HasStorageAttr(/*isImplicit:*/true));
+
     break;
   }
 
diff --git a/stdlib/public/core/StringGutsSlice.swift b/stdlib/public/core/StringGutsSlice.swift
index 820dbb9..3c6d25d4 100644
--- a/stdlib/public/core/StringGutsSlice.swift
+++ b/stdlib/public/core/StringGutsSlice.swift
@@ -16,22 +16,18 @@
 
 // A sliced _StringGuts, convenient for unifying String/Substring comparison,
 // hashing, and RRC.
-@_fixed_layout
-@usableFromInline
 internal struct _StringGutsSlice {
-  @usableFromInline
   internal var _guts: _StringGuts
 
-  @usableFromInline
   internal var _offsetRange: Range<Int>
 
-  @inlinable @inline(__always)
+  @inline(__always)
   internal init(_ guts: _StringGuts) {
     self._guts = guts
     self._offsetRange = 0..<self._guts.count
   }
 
-  @inlinable @inline(__always)
+  @inline(__always)
   internal init(_ guts: _StringGuts, _ offsetRange: Range<Int>) {
     self._guts = guts
     self._offsetRange = offsetRange
@@ -83,7 +79,7 @@
     }
   }
 
-  @inlinable @inline(__always)
+  @inline(__always)
   internal func withFastUTF8<R>(
     _ f: (UnsafeBufferPointer<UInt8>) throws -> R
   ) rethrows -> R {
diff --git a/stdlib/public/core/StringHashable.swift b/stdlib/public/core/StringHashable.swift
index 3e335a3..9512337 100644
--- a/stdlib/public/core/StringHashable.swift
+++ b/stdlib/public/core/StringHashable.swift
@@ -45,7 +45,6 @@
 }
 
 extension _StringGutsSlice {
-  @usableFromInline // @opaque
   @inline(never) // slow-path
   internal func _normalizedHash(into hasher: inout Hasher) {
     if self.isNFCFastUTF8 {
diff --git a/stdlib/public/core/StringProtocol.swift b/stdlib/public/core/StringProtocol.swift
index 2927db9..433f104 100644
--- a/stdlib/public/core/StringProtocol.swift
+++ b/stdlib/public/core/StringProtocol.swift
@@ -132,7 +132,6 @@
     get { return String(self) }
   }
 
-  @inlinable // Eliminate for String, Substring
   internal var _gutsSlice: _StringGutsSlice {
     @_specialize(where Self == String)
     @_specialize(where Self == Substring)
@@ -152,7 +151,8 @@
     @inline(__always) get {
       let start = startIndex
       let end = endIndex
-      _internalInvariant(start.transcodedOffset == 0 && end.transcodedOffset == 0)
+      _internalInvariant(
+        start.transcodedOffset == 0 && end.transcodedOffset == 0)
       return Range(uncheckedBounds: (start.encodedOffset, end.encodedOffset))
     }
   }
diff --git a/test/ClangImporter/ctypes_parse_objc.swift b/test/ClangImporter/ctypes_parse_objc.swift
index 415eb49..9a5e396 100644
--- a/test/ClangImporter/ctypes_parse_objc.swift
+++ b/test/ClangImporter/ctypes_parse_objc.swift
@@ -70,8 +70,17 @@
 }
 
 func testImportCFTypes() {
-  let t1_unqual: Int = CFIndex_test
-  _ = t1_unqual as CoreFoundation.CFIndex
+  let t1_unqual: UInt = CFTypeID_test
+  _ = t1_unqual as CoreFoundation.CFTypeID
+
+  let t2_unqual: UInt = CFOptionFlags_test
+  _ = t2_unqual as CoreFoundation.CFOptionFlags
+
+  let t3_unqual: UInt = CFHashCode_test
+  _ = t3_unqual as CoreFoundation.CFHashCode
+
+  let t4_unqual: Int = CFIndex_test
+  _ = t4_unqual as CoreFoundation.CFIndex
 }
 
 func testImportSEL() {
diff --git a/test/DebugInfo/returnlocation.swift b/test/DebugInfo/returnlocation.swift
index 9d964cd..0b4eda2 100644
--- a/test/DebugInfo/returnlocation.swift
+++ b/test/DebugInfo/returnlocation.swift
@@ -184,10 +184,10 @@
   public required init?() {
     print("hello")
     // CHECK_INIT: call {{.*}}@"$ss5print_9separator10terminatoryypd_S2StF"{{.*}}, !dbg [[printLoc:![0-9]+]]
-    // CHECK_INIT: br label {{.*}}, !dbg [[retnLoc:![0-9]+]]
+    // CHECK_INIT: ret i{{32|64}} 0, !dbg [[retnLoc:![0-9]+]]
 
-    // CHECK_INIT: [[printLoc]] = !DILocation(line: [[@LINE-4]]
-    // CHECK_INIT: [[retnLoc]] = !DILocation(line: [[@LINE+1]]
+    // CHECK_INIT: [[retnLoc]] = !DILocation(line: 0
+    // CHECK_INIT: [[printLoc]] = !DILocation(line: [[@LINE-5]]
     return nil
   }
 }
diff --git a/test/IRGen/nondominant.sil b/test/IRGen/nondominant.sil
index 0f408f3..038628f 100644
--- a/test/IRGen/nondominant.sil
+++ b/test/IRGen/nondominant.sil
@@ -16,11 +16,9 @@
   br bb2
 }
 // CHECK:   define{{( dllexport)?}}{{( protected)?}} swiftcc i8 @test0()
-// CHECK:     br
 // CHECK-NOT: }
 // CHECK:     ret i8 7
 // CHECK-NOT: }
-// CHECK:     br
 // CHECK:   }
 
 // Just don't crash on this one.
diff --git a/test/IRGen/objc_properties.swift b/test/IRGen/objc_properties.swift
index d66b6e8..8e87328 100644
--- a/test/IRGen/objc_properties.swift
+++ b/test/IRGen/objc_properties.swift
@@ -235,10 +235,10 @@
 // CHECK: @_INSTANCE_METHODS__TtC15objc_properties4Tree =
 // CHECK:    i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(parent)", i64 0, i64 0),
 // CHECK:    i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0),
-// CHECK:    i8* bitcast (%2* (%2*, i8*)* @"$s15objc_properties4TreeC6parentACSgXwvgTo" to i8*)
+// CHECK:    i8* bitcast (%2* (%2*, i8*)* @"$s15objc_properties4TreeC6parentACSgvgTo" to i8*)
 // CHECK:    i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"\01L_selector_data(setParent:)", i64 0, i64 0),
 // CHECK:    i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_SIGNATURE]], i64 0, i64 0),
-// CHECK:    i8* bitcast (void (%2*, i8*, %2*)* @"$s15objc_properties4TreeC6parentACSgXwvsTo" to i8*)
+// CHECK:    i8* bitcast (void (%2*, i8*, %2*)* @"$s15objc_properties4TreeC6parentACSgvsTo" to i8*)
 
 // CHECK: @_PROTOCOL__TtP15objc_properties5Proto_ = private constant { {{.+}} } {
 // CHECK:   i8* null,
diff --git a/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h b/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
index 508e499..51cd769 100644
--- a/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
+++ b/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
@@ -18,8 +18,21 @@
 
 typedef CFTypeRef CFAliasForTypeRef;
 
-
+#if __LLP64__
+typedef unsigned long long CFTypeID;
+typedef unsigned long long CFOptionFlags;
+typedef unsigned long long CFHashCode;
+typedef signed long long CFIndex;
+#else
+typedef unsigned long CFTypeID;
+typedef unsigned long CFOptionFlags;
+typedef unsigned long CFHashCode;
 typedef signed long CFIndex;
+#endif
+
+extern CFTypeID CFTypeID_test;
+extern CFOptionFlags CFOptionFlags_test;
+extern CFHashCode CFHashCode_test;
 extern CFIndex CFIndex_test;
 
 #define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
diff --git a/test/ParseableInterface/Inputs/TestModule.swift b/test/ParseableInterface/Inputs/TestModule.swift
new file mode 100644
index 0000000..4d60117
--- /dev/null
+++ b/test/ParseableInterface/Inputs/TestModule.swift
@@ -0,0 +1,3 @@
+public struct TestStruct {
+  public init() {}
+}
diff --git a/test/ParseableInterface/access-filter.swift b/test/ParseableInterface/access-filter.swift
index 64e2a75..b499dda 100644
--- a/test/ParseableInterface/access-filter.swift
+++ b/test/ParseableInterface/access-filter.swift
@@ -109,7 +109,9 @@
 
 // CHECK: extension PublicStruct {{[{]$}}
 extension PublicStruct {
-  // CHECK: public private(set) static var secretlySettable: Int{{$}}
+  // CHECK: @_hasInitialValue public static var secretlySettable: Int {
+  // CHECK-NEXT: get
+  // CHECK-NEXT: }
   public private(set) static var secretlySettable: Int = 0
 } // CHECK: {{^[}]$}}
 
diff --git a/test/ParseableInterface/linking-to-module.swift b/test/ParseableInterface/linking-to-module.swift
new file mode 100644
index 0000000..ee9dd64
--- /dev/null
+++ b/test/ParseableInterface/linking-to-module.swift
@@ -0,0 +1,10 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-build-swift -emit-library -module-name TestModule -module-link-name coreTestModuleKitUtilsTool %S/Inputs/TestModule.swift -emit-parseable-module-interface -o %t/libcoreTestModuleKitUtilsTool.%target-dylib-extension
+// RUN: %target-swift-frontend -emit-ir -I %t -L %t -enable-parseable-module-interface %s | %FileCheck %s
+
+import TestModule
+
+_ = TestStruct()
+
+// CHECK: -lcoreTestModuleKitUtilsTool
diff --git a/test/ParseableInterface/stored-properties-client.swift b/test/ParseableInterface/stored-properties-client.swift
new file mode 100644
index 0000000..a7e04fd
--- /dev/null
+++ b/test/ParseableInterface/stored-properties-client.swift
@@ -0,0 +1,143 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-swift-frontend -typecheck %S/stored-properties.swift -module-name StoredProperties -emit-parseable-module-interface-path %t/StoredProperties.swiftinterface
+// RUN: %target-swift-frontend -emit-ir %s -I %t -enable-parseable-module-interface | %FileCheck %s -check-prefix CHECK -check-prefix COMMON
+
+// RUN: %target-swift-frontend -typecheck %S/stored-properties.swift -enable-resilience -module-name StoredProperties -emit-parseable-module-interface-path %t/StoredProperties.swiftinterface
+// RUN: %target-swift-frontend -emit-ir %s -I %t -enable-parseable-module-interface | %FileCheck %s -check-prefix RESILIENT -check-prefix COMMON
+
+import StoredProperties
+
+/// This test makes sure clients of a parseable interface see correct type
+/// layout and use the right access patterns in the presence of a
+/// .swiftinterface file, in both resilient and non-resilient cases.
+
+// COMMON: %[[BAGOFVARIABLES:T16StoredProperties14BagOfVariablesV]] = type <{ %TSi, %TSb, [{{(3|7)}} x i8], %TSi }>
+
+// This type is non-@_fixed_layout, so it becomes opaque in a resilient module
+// CHECK: %[[HASSTOREDPROPERTIES:T16StoredProperties03HasaB0V]] = type <{ %TSi, %TSi, %TSb, [{{(3|7)}} x i8], %TSi, %TSb }>
+// RESILIENT: %[[HASSTOREDPROPERTIES:swift.opaque]] = type opaque
+
+// COMMON: %[[HASSTOREDPROPERTIESFIXEDLAYOUT:T16StoredProperties03HasaB11FixedLayoutV]] = type <{ %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]] }>
+
+// These are here just to make sure the compiler doesn't optimize away accesses.
+// They're overloaded instead of generic so we avoid generic dispatch.
+
+@inline(never)
+func _blackHole(_ value: Int) {}
+
+@inline(never)
+func _blackHole(_ value: Bool) {}
+
+@inline(never)
+func _blackHole(_ value: BagOfVariables) {}
+
+/// In the following code, getting and setting is split because otherwise
+/// the resulting IR is ordered differently.
+
+/// Test that we call the correct accessors in a resilient module, and that
+/// we use trivial storage accesses in a non-resilient module.
+
+func testGetting() {
+  // CHECK: %[[VALUE:.*]] = alloca %[[HASSTOREDPROPERTIES]]
+  // CHECK: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* {{.*}} %[[VALUE]])
+  // RESILIENT: %[[VALUE:.*]] = alloca i8, [[WORD:i[0-9]+]] %size
+  // RESILIENT: %[[VALUECAST:.*]] = bitcast i8* %value to %[[HASSTOREDPROPERTIES]]*
+  // RESILIENT: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* noalias nocapture sret %[[VALUECAST]])
+  var value = HasStoredProperties()
+
+  // CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 1
+  // CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 2
+
+  // These are accessed in declaration order so the IR is emitted in the same
+  // order.
+
+  // COMMON: call swiftcc [[WORD:i[0-9]+]] @"$s16StoredProperties03HasaB0V14computedGetterSivg"
+  _blackHole(value.computedGetter)
+
+  // COMMON: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V14computedGetSetSivg"
+  _blackHole(value.computedGetSet)
+
+  // CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 0
+  // CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 4
+
+  // RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V06simpleA9ImmutableSivg"
+  _blackHole(value.simpleStoredImmutable)
+
+  // RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V06simpleA7MutableSivg"
+  _blackHole(value.simpleStoredMutable)
+
+  // RESILIENT: call swiftcc i1 @"$s16StoredProperties03HasaB0V19storedWithObserversSbvg"
+  _blackHole(value.storedWithObservers)
+
+  // RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V16storedPrivateSetSivg"
+  _blackHole(value.storedPrivateSet)
+}
+
+func testSetting() {
+  // CHECK: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* {{.*}})
+  // RESILIENT: call swiftcc %swift.metadata_response @"$s16StoredProperties03HasaB0VMa"([[WORD]] 0)
+  // RESILIENT: %[[VALUEALLOC:.*]] = alloca i8, [[WORD]] %size
+  // RESILIENT: bitcast i8* %[[VALUEALLOC]] to %[[HASSTOREDPROPERTIES]]*
+  var value = HasStoredProperties()
+
+  // COMMON: call swiftcc void @"$s16StoredProperties03HasaB0V19storedWithObserversSbvs"(i1 false, %[[HASSTOREDPROPERTIES]]* {{.*}})
+  value.storedWithObservers = false
+
+  // COMMON-NEXT: call swiftcc void @"$s16StoredProperties03HasaB0V14computedGetSetSivs"([[WORD]] 4, %[[HASSTOREDPROPERTIES]]* {{.*}})
+  value.computedGetSet = 4
+
+  // CHECK: %[[MUTABLE_PTR:.*]] = getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* {{.*}}, i32 0, i32 1
+  // CHECK: %[[MUTABLE_INT_PTR:.*]] = getelementptr inbounds %TSi, %TSi* %[[MUTABLE_PTR]], i32 0, i32 0
+  // CHECK: store [[WORD]] 4, [[WORD]]* %[[MUTABLE_INT_PTR]]
+  // RESILIENT: call swiftcc void @"$s16StoredProperties03HasaB0V06simpleA7MutableSivs"([[WORD]] 4, %[[HASSTOREDPROPERTIES]]* {{.*}})
+  value.simpleStoredMutable = 4
+}
+
+testGetting()
+testSetting()
+
+/// Test that we always use trivial access patterns for @_fixed_layout types
+/// in resilient or non-resilient modules.
+
+func testFixedLayoutGetting() {
+  // COMMON: %[[VALUEALLOCA:.*]] = alloca %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]
+  // COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutVACycfC"(%[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* {{.*}} %[[VALUEALLOCA]])
+  var value = HasStoredPropertiesFixedLayout()
+
+  // These next two tests just make sure we don't use resilient access patterns
+  // for these fixed_layout structs.
+
+  // COMMON: getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %[[VALUEALLOCA]], i32 0, i32 0
+  // COMMON: getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %[[VALUEALLOCA]], i32 0, i32 1
+
+  // COMMON: call swiftcc void @"$s4main10_blackHoleyy16StoredProperties14BagOfVariablesVF"([[WORD]] %{{.*}}, i1 %{{.*}}, [[WORD]] %{{.*}})
+  _blackHole(value.simpleStoredMutable)
+
+  // COMMON: call swiftcc void @"$s4main10_blackHoleyy16StoredProperties14BagOfVariablesVF"([[WORD]] %{{.*}}, i1 %{{.*}}, [[WORD]] %{{.*}})
+  _blackHole(value.storedWithObservers)
+}
+
+func testFixedLayoutSetting() {
+  // COMMON: %[[VALUEALLOCA:.*]] = alloca %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]
+  // COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutVACycfC"(%[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* {{.*}} %[[VALUEALLOCA]])
+  var value = HasStoredPropertiesFixedLayout()
+
+  // COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutV19storedWithObserversAA14BagOfVariablesVvs"
+  value.storedWithObservers = BagOfVariables()
+
+  // COMMON: %[[PROP:.*]] = getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %value, i32 0, i32 0
+  // COMMON: %[[PROPA:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 0
+  // COMMON: %[[PROPAVAL:.*]] = getelementptr inbounds %TSi, %TSi* %[[PROPA]], i32 0, i32 0
+  // COMMON: store [[WORD]] {{.*}} %[[PROPAVAL]]
+  // COMMON: %[[PROPB:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 1
+  // COMMON: %[[PROPBVAL:.*]] = getelementptr inbounds %TSb, %TSb* %[[PROPB]], i32 0, i32 0
+  // COMMON: store i1 {{.*}} %[[PROPBVAL]]
+  // COMMON: %[[PROPC:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 3
+  // COMMON: %[[PROPCVAL:.*]] = getelementptr inbounds %TSi, %TSi* %[[PROPC]], i32 0, i32 0
+  // COMMON: store [[WORD]] {{.*}} %[[PROPCVAL]]
+  value.simpleStoredMutable = BagOfVariables()
+}
+
+testFixedLayoutGetting()
+testFixedLayoutSetting()
diff --git a/test/ParseableInterface/stored-properties.swift b/test/ParseableInterface/stored-properties.swift
new file mode 100644
index 0000000..35e7682
--- /dev/null
+++ b/test/ParseableInterface/stored-properties.swift
@@ -0,0 +1,104 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.swiftinterface %s
+// RUN: %FileCheck %s < %t.swiftinterface --check-prefix CHECK --check-prefix COMMON
+
+// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t-resilient.swiftinterface -enable-resilience %s
+// RUN: %FileCheck %s < %t-resilient.swiftinterface --check-prefix RESILIENT --check-prefix COMMON
+
+// RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule %t.swiftinterface -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -module-name Test -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix CHECK --check-prefix COMMON
+
+// RUN: %target-swift-frontend -emit-module -o %t/TestResilient.swiftmodule -enable-resilience %t-resilient.swiftinterface -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/TestResilient.swiftmodule -module-name TestResilient -enable-resilience -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix RESILIENT --check-prefix COMMON
+
+// COMMON: public struct HasStoredProperties {
+public struct HasStoredProperties {
+  // COMMON: public var computedGetter: [[INT:.*Int]] {
+  // COMMON-NEXT: get
+  // COMMON-NEXT: }
+  public var computedGetter: Int { return 3 }
+
+  // COMMON: public var computedGetSet: [[INT]] {
+  // COMMON-NEXT: get
+  // COMMON-NEXT: set
+  // COMMON-NEXT: }
+  public var computedGetSet: Int {
+    get { return 3 }
+    set {}
+  }
+
+  // COMMON: public let simpleStoredImmutable: [[INT]]{{$}}
+  public let simpleStoredImmutable: Int
+
+  // COMMON: public var simpleStoredMutable: [[INT]]{{$}}
+  public var simpleStoredMutable: Int
+
+  // CHECK: @_hasStorage public var storedWithObservers: [[BOOL:.*Bool]] {
+  // RESILIENT: {{^}}  public var storedWithObservers: [[BOOL:.*Bool]] {
+  // COMMON-NEXT: get
+  // COMMON-NEXT: set
+  // COMMON-NEXT: }
+  public var storedWithObservers: Bool {
+    willSet {}
+  }
+
+  // CHECK: @_hasStorage public var storedPrivateSet: [[INT]] {
+  // RESILIENT: {{^}}  public var storedPrivateSet: [[INT]] {
+  // COMMON-NEXT: get
+  // COMMON-NEXT: }
+  public private(set) var storedPrivateSet: Int
+
+  // CHECK: private var _: [[BOOL]]
+  private var privateVar: Bool
+
+  // COMMON: public init(){{$}}
+  public init() {
+    self.simpleStoredImmutable = 0
+    self.simpleStoredMutable = 0
+    self.storedPrivateSet = 0
+    self.storedWithObservers = false
+    self.privateVar = false
+  }
+
+// COMMON: }
+}
+
+// COMMON: @_fixed_layout public struct BagOfVariables {
+@_fixed_layout
+public struct BagOfVariables {
+  // COMMON: public let a: [[INT]] = 0
+  public let a: Int = 0
+
+  // COMMON: public var b: [[BOOL]] = false
+  public var b: Bool = false
+
+  // COMMON: public var c: [[INT]] = 0
+  public var c: Int = 0
+
+  // COMMON: public init()
+  public init() {}
+
+// COMMON: }
+}
+
+// COMMON: @_fixed_layout public struct HasStoredPropertiesFixedLayout {
+@_fixed_layout
+public struct HasStoredPropertiesFixedLayout {
+  // COMMON: public var simpleStoredMutable: [[BAGOFVARIABLES:.*BagOfVariables]]
+  public var simpleStoredMutable: BagOfVariables
+
+  // COMMON: @_hasStorage public var storedWithObservers: [[BAGOFVARIABLES]] {
+  // COMMON-NEXT: get
+  // COMMON-NEXT: set
+  // COMMON-NEXT: }
+  public var storedWithObservers: BagOfVariables {
+    didSet {}
+  }
+
+  // COMMON: public init(){{$}}
+  public init() {
+    self.simpleStoredMutable = BagOfVariables()
+    self.storedWithObservers = BagOfVariables()
+  }
+}
diff --git a/test/SIL/Parser/final.swift b/test/SIL/Parser/final.swift
index 6be8eef..7f0e30f 100644
--- a/test/SIL/Parser/final.swift
+++ b/test/SIL/Parser/final.swift
@@ -1,7 +1,7 @@
 // RUN: %target-swift-frontend %s -emit-silgen | %FileCheck %s
 
 // CHECK: final class Rect
-// CHECK: @_hasStorage @_hasInitialValue final var orgx: Double
+// CHECK: @_hasInitialValue @_hasStorage final var orgx: Double
 final class Rect {
   var orgx = 0.0
 }
diff --git a/test/SILGen/modify.swift b/test/SILGen/modify.swift
index 212979a..1b975ae 100644
--- a/test/SILGen/modify.swift
+++ b/test/SILGen/modify.swift
@@ -224,7 +224,7 @@
 class HasWeak {
   weak var weakvar: HasWeak?
 }
-// CHECK-LABEL: sil hidden [transparent] @$s6modify7HasWeakC7weakvarACSgXwvM : $@yield_once @convention(method) (@guaranteed HasWeak) -> @yields @inout Optional<HasWeak> {
+// CHECK-LABEL: sil hidden [transparent] @$s6modify7HasWeakC7weakvarACSgvM : $@yield_once @convention(method) (@guaranteed HasWeak) -> @yields @inout Optional<HasWeak> {
 // CHECK: bb0([[SELF:%.*]] : @guaranteed $HasWeak):
 // CHECK:   [[PROP:%.*]] = ref_element_addr [[SELF]] : $HasWeak, #HasWeak.weakvar
 // CHECK:   [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[PROP]] : $*@sil_weak Optional<HasWeak>
diff --git a/test/SILGen/struct_resilience.swift b/test/SILGen/struct_resilience.swift
index cbb2404..dc85336 100644
--- a/test/SILGen/struct_resilience.swift
+++ b/test/SILGen/struct_resilience.swift
@@ -120,6 +120,11 @@
 // CHECK-LABEL: sil @$s17struct_resilience6MySizeV1hSivg : $@convention(method) (@in_guaranteed MySize) -> Int
   public let h: Int
 
+  // Weak property
+
+// CHECK-LABEL: sil @$s17struct_resilience6MySizeV1iyXlSgvg : $@convention(method) (@in_guaranteed MySize) -> @owned Optional<AnyObject>
+  public weak var i: AnyObject?
+
   // Static stored property
 
 // CHECK-LABEL: sil @$s17struct_resilience6MySizeV9copyrightSivgZ : $@convention(method) (@thin MySize.Type) -> Int
diff --git a/test/SILOptimizer/accessed_storage_analysis.sil b/test/SILOptimizer/accessed_storage_analysis.sil
index e12d8ff..124749d 100644
--- a/test/SILOptimizer/accessed_storage_analysis.sil
+++ b/test/SILOptimizer/accessed_storage_analysis.sil
@@ -340,7 +340,7 @@
 
 // CHECK-LABEL: @readIdentifiedClass
 // CHECK: [read] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
 sil @readIdentifiedClass : $@convention(thin) (@guaranteed C) -> Int {
 bb0(%0 : $C):
   %1 = ref_element_addr %0 : $C, #C.property
@@ -352,7 +352,7 @@
 
 // CHECK-LABEL: @writeIdentifiedClass
 // CHECK: [modify] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
 sil @writeIdentifiedClass : $@convention(thin) (@guaranteed C, Int) -> () {
 bb0(%0 : $C, %1 : $Int):
   %2 = ref_element_addr %0 : $C, #C.property
@@ -365,7 +365,7 @@
 
 // CHECK-LABEL: @readWriteIdentifiedClass
 // CHECK: [modify] Class   %1 = alloc_ref $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
 sil @readWriteIdentifiedClass : $@convention(thin) (Int) -> (Int) {
 bb0(%0 : $Int):
   %1 = alloc_ref $C
@@ -380,7 +380,7 @@
 
 // CHECK-LABEL: @readIdentifiedNestedClass
 // CHECK: [read] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
 sil @readIdentifiedNestedClass : $@convention(thin) (@guaranteed C) -> Int {
 bb0(%0 : $C):
   %1 = ref_element_addr %0 : $C, #C.property
@@ -394,7 +394,7 @@
 
 // CHECK-LABEL: @writeIdentifiedNestedClass
 // CHECK: [modify] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
 sil @writeIdentifiedNestedClass : $@convention(thin) (@guaranteed C, Int) -> () {
 bb0(%0 : $C, %1 : $Int):
   %2 = ref_element_addr %0 : $C, #C.property
@@ -409,7 +409,7 @@
 
 // CHECK-LABEL: @readWriteIdentifiedNestedClass
 // CHECK: [modify] Class   %1 = alloc_ref $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
 sil @readWriteIdentifiedNestedClass : $@convention(thin) (Int) -> (Int) {
 bb0(%0 : $Int):
   %1 = alloc_ref $C
@@ -541,7 +541,7 @@
 // Test directly recursive argument access.
 // CHECK-LABEL: @readRecursiveArgument
 // CHECK:   [read] Class %0 = argument of bb0 : $C
-// CHECK:   Field: @_hasStorage var property: Int
+// CHECK:   Field: var property: Int
 sil @readRecursiveArgument : $@convention(thin) (@guaranteed C, Int) -> Int {
 bb0(%0 : $C, %1 : $Int):
   %propaddr = ref_element_addr %0 : $C, #C.property
@@ -556,7 +556,7 @@
 // Test a class argument access from an optional caller value.
 // CHECK-LABEL: @readOptionalArgumentInCallee
 // CHECK:   [read] Class   %1 = unchecked_enum_data %0 : $Optional<C>, #Optional.some!enumelt.1
-// CHECK:   Field: @_hasStorage var property: Int
+// CHECK:   Field: var property: Int
 sil @readOptionalArgumentInCallee : $@convention(thin) (@guaranteed Optional<C>) -> Int {
 bb0(%0 : $Optional<C>):
   %c = unchecked_enum_data %0 : $Optional<C>, #Optional.some!enumelt.1
@@ -567,7 +567,7 @@
 
 // CHECK-LABEL: @readOptionalArgumentInCalleeHelper
 // CHECK:   [read] Class %0 = argument of bb0 : $C
-// CHECK:   Field: @_hasStorage var property: Int
+// CHECK:   Field: var property: Int
 sil private @readOptionalArgumentInCalleeHelper : $@convention(thin) (@guaranteed C) -> Int {
 bb0(%0 : $C):
   %propaddr = ref_element_addr %0 : $C, #C.property
diff --git a/test/SILOptimizer/definite_init_failable_initializers.swift b/test/SILOptimizer/definite_init_failable_initializers.swift
index 4e07dbd..fca7369 100644
--- a/test/SILOptimizer/definite_init_failable_initializers.swift
+++ b/test/SILOptimizer/definite_init_failable_initializers.swift
@@ -38,12 +38,8 @@
 // CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers14FailableStructV24failBeforeInitializationACSgyt_tcfC
 // CHECK:       bb0(%0 : $@thin FailableStruct.Type):
 // CHECK:         [[SELF_BOX:%.*]] = alloc_stack $FailableStruct
-// CHECK:         br bb1
-// CHECK:       bb1:
-// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
+// CHECK:         dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[SELF]]
   init?(failBeforeInitialization: ()) {
     return nil
@@ -57,14 +53,10 @@
 // CHECK-NEXT:    [[X_ADDR:%.*]] = struct_element_addr [[WRITE]]
 // CHECK-NEXT:    store [[CANARY]] to [[X_ADDR]]
 // CHECK-NEXT:    end_access [[WRITE]] : $*FailableStruct
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]
 // CHECK-NEXT:    destroy_addr [[X_ADDR]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[SELF]]
   init?(failAfterPartialInitialization: ()) {
     x = Canary()
@@ -84,13 +76,9 @@
 // CHECK-NEXT:    [[Y_ADDR:%.*]] = struct_element_addr [[WRITE]]
 // CHECK-NEXT:    store [[CANARY2]] to [[Y_ADDR]]
 // CHECK-NEXT:    end_access [[WRITE]] : $*FailableStruct
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[NEW_SELF]]
   init?(failAfterFullInitialization: ()) {
     x = Canary()
@@ -105,13 +93,9 @@
 // CHECK-NEXT:    [[WRITE:%.*]] = begin_access [modify] [static] [[SELF_BOX]] : $*FailableStruct
 // CHECK-NEXT:    store [[CANARY]] to [[WRITE]]
 // CHECK-NEXT:    end_access [[WRITE]] : $*FailableStruct
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[SELF_VALUE:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[SELF_VALUE]]
   init?(failAfterWholeObjectInitializationByAssignment: ()) {
     self = FailableStruct(noFail: ())
@@ -124,13 +108,9 @@
 // CHECK:         [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers14FailableStructV6noFailACyt_tcfC
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = apply [[INIT_FN]](%0)
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[NEW_SELF]]
   init?(failAfterWholeObjectInitializationByDelegation: ()) {
     self.init(noFail: ())
@@ -147,7 +127,9 @@
 //
 // CHECK:       [[FAIL_BB]]:
 // CHECK-NEXT:    release_value [[SELF_OPTIONAL]]
-// CHECK-NEXT:    br [[FAIL_EPILOG_BB:bb[0-9]+]]
+// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
+// CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
+// CHECK-NEXT:    br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<FailableStruct>)
 //
 // CHECK:       [[SUCC_BB]]:
 // CHECK-NEXT:    [[SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]]
@@ -158,11 +140,6 @@
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<FailableStruct>)
 //
-// CHECK:       [[FAIL_EPILOG_BB]]:
-// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT:    br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<FailableStruct>)
-//
 // CHECK:       [[EPILOG_BB]]([[NEW_SELF:%.*]] : $Optional<FailableStruct>)
 // CHECK-NEXT:    return [[NEW_SELF]]
   // Optional to optional
@@ -212,12 +189,8 @@
 // CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers22FailableAddrOnlyStructV{{[_0-9a-zA-Z]*}}failBeforeInitialization{{.*}}tcfC
 // CHECK:       bb0(%0 : $*Optional<FailableAddrOnlyStruct<T>>, %1 : $@thin FailableAddrOnlyStruct<T>.Type):
 // CHECK:         [[SELF_BOX:%.*]] = alloc_stack $FailableAddrOnlyStruct<T>
-// CHECK:         br bb1
-// CHECK:       bb1:
-// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
+// CHECK:         dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    inject_enum_addr %0
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK:         return
   init?(failBeforeInitialization: ()) {
     return nil
@@ -235,14 +208,10 @@
 // CHECK-NEXT:    copy_addr [take] [[X_BOX]] to [initialization] [[X_ADDR]]
 // CHECK-NEXT:    end_access [[WRITE]] : $*FailableAddrOnlyStruct<T>
 // CHECK-NEXT:    dealloc_stack [[X_BOX]]
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]
 // CHECK-NEXT:    destroy_addr [[X_ADDR]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    inject_enum_addr %0
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK:         return
   init?(failAfterPartialInitialization: ()) {
     x = T()
@@ -270,13 +239,9 @@
 // CHECK-NEXT:    copy_addr [take] [[Y_BOX]] to [initialization] [[Y_ADDR]]
 // CHECK-NEXT:    end_access [[WRITE]] : $*FailableAddrOnlyStruct<T>
 // CHECK-NEXT:    dealloc_stack [[Y_BOX]]
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    inject_enum_addr %0
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK:         return
   init?(failAfterFullInitialization: ()) {
     x = T()
@@ -548,8 +513,10 @@
 // CHECK-NEXT:    cond_br [[COND]], [[SUCC_BB:bb[0-9]+]], [[FAIL_BB:bb[0-9]+]]
 //
 // CHECK:       [[FAIL_BB]]:
-// CHECK-NEXT:    release_value [[SELF_OPTIONAL]]
-// CHECK-NEXT:    br [[FAIL_EPILOG_BB:bb[0-9]+]]
+// CHECK:         release_value [[SELF_OPTIONAL]]
+// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
+// CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<ThrowStruct>, #Optional.none!enumelt
+// CHECK-NEXT:    br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<ThrowStruct>)
 //
 // CHECK:       [[SUCC_BB]]:
 // CHECK-NEXT:    [[SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]]
@@ -560,21 +527,13 @@
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<ThrowStruct>)
 //
-// CHECK:       [[FAIL_EPILOG_BB]]:
-// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<ThrowStruct>, #Optional.none!enumelt
-// CHECK-NEXT:    br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<ThrowStruct>)
-//
 // CHECK:       [[EPILOG_BB]]([[NEW_SELF:%.*]] : $Optional<ThrowStruct>):
 // CHECK-NEXT:    return [[NEW_SELF]] : $Optional<ThrowStruct>
 //
-// CHECK:       [[TRY_APPLY_FAIL_TRAMPOLINE_BB:bb[0-9]+]]:
+// CHECK:       [[TRY_APPLY_FAIL_BB]]([[ERROR]] : $Error):
 // CHECK-NEXT:    strong_release [[ERROR:%.*]] : $Error
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<ThrowStruct>, #Optional.none!enumelt
 // CHECK-NEXT:    br [[TRY_APPLY_CONT]]([[NEW_SELF]] : $Optional<ThrowStruct>)
-//
-// CHECK:       [[TRY_APPLY_FAIL_BB]]([[ERROR]] : $Error):
-// CHECK-NEXT:    br [[TRY_APPLY_FAIL_TRAMPOLINE_BB]]
   init?(throwsToOptional: Int) {
     try? self.init(failDuringDelegation: throwsToOptional)
   }
@@ -767,12 +726,8 @@
 // CHECK-NEXT:    [[WRITE:%.*]] = begin_access [modify] [dynamic] [[MEMBER_ADDR]] : $*Canary
 // CHECK-NEXT:    store [[CANARY]] to [[WRITE]]
 // CHECK-NEXT:    end_access [[WRITE]] : $*Canary
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    strong_release %0
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[NEW_SELF]]
   init?(failAfterFullInitialization: ()) {
     member = Canary()
@@ -782,12 +737,8 @@
 // CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers17FailableBaseClassC20failBeforeDelegationACSgyt_tcfC
 // CHECK:       bb0(%0 : $@thick FailableBaseClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass
-// CHECK:         br bb1
-// CHECK:       bb1:
-// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
+// CHECK:         dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[RESULT]]
   convenience init?(failBeforeDelegation: ()) {
     return nil
@@ -799,13 +750,9 @@
 // CHECK:         [[INIT_FN:%.*]] = class_method %0
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = apply [[INIT_FN]](%0)
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[RESULT]]
   convenience init?(failAfterDelegation: ()) {
     self.init(noFail: ())
@@ -834,8 +781,8 @@
 // CHECK-NEXT:    br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<FailableBaseClass>)
 //
 // CHECK:       [[FAIL_TRAMPOLINE_BB]]:
-// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
+// CHECK:         dealloc_stack [[SELF_BOX]]
+// CHECK:         [[NEW_SELF:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
 // CHECK-NEXT:    br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<FailableBaseClass>)
 //
 // CHECK:       [[EPILOG_BB]]([[NEW_SELF:%.*]] : $Optional<FailableBaseClass>):
@@ -875,14 +822,10 @@
 // CHECK:       bb0(%0 : $FailableDerivedClass):
 // CHECK:         [[SELF_BOX:%.*]] = alloc_stack $FailableDerivedClass
 // CHECK:         store %0 to [[SELF_BOX]]
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    [[METATYPE:%.*]] = metatype $@thick FailableDerivedClass.Type
 // CHECK-NEXT:    dealloc_partial_ref %0 : $FailableDerivedClass, [[METATYPE]] : $@thick FailableDerivedClass.Type
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[RESULT:%.*]] = enum $Optional<FailableDerivedClass>, #Optional.none!enumelt
-// CHECK-NEXT:    br bb2
-// CHECK:       bb2:
 // CHECK-NEXT:    return [[RESULT]]
   init?(derivedFailBeforeDelegation: ()) {
     return nil
@@ -905,7 +848,9 @@
 //
 // CHECK:       [[FAIL_BB]]:
 // CHECK-NEXT:    release_value [[SELF_OPTIONAL]]
-// CHECK-NEXT:    br [[FAIL_TRAMPOLINE_BB:bb[0-9]+]]
+// CHECK:         dealloc_stack [[SELF_BOX]]
+// CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<FailableDerivedClass>, #Optional.none!enumelt
+// CHECK-NEXT:    br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<FailableDerivedClass>)
 //
 // CHECK:       [[SUCC_BB]]:
 // CHECK-NEXT:    [[BASE_SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]]
@@ -917,11 +862,6 @@
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<FailableDerivedClass>)
 //
-// CHECK:       [[FAIL_TRAMPOLINE_BB]]:
-// CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT:    [[NEW_SELF:%.*]] = enum $Optional<FailableDerivedClass>, #Optional.none!enumelt
-// CHECK-NEXT:    br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<FailableDerivedClass>)
-//
 // CHECK:       [[EPILOG_BB]]([[NEW_SELF:%.*]] : $Optional<FailableDerivedClass>):
 // CHECK-NEXT:    return [[NEW_SELF]] : $Optional<FailableDerivedClass>
   init?(derivedFailDuringDelegation: ()) {
diff --git a/test/SILOptimizer/definite_init_failable_initializers_objc.swift b/test/SILOptimizer/definite_init_failable_initializers_objc.swift
index 04abe6b..c19d1bb 100644
--- a/test/SILOptimizer/definite_init_failable_initializers_objc.swift
+++ b/test/SILOptimizer/definite_init_failable_initializers_objc.swift
@@ -39,12 +39,15 @@
     // CHECK-NEXT: cond_br [[COND]], bb1, bb2
 
   // CHECK: bb1:
-    // CHECK-NEXT: br bb4
+    // CHECK-NEXT: [[FIELD_ADDR:%.*]] = ref_element_addr %2 : $Cat, #Cat.x
+    // CHECK-NEXT: destroy_addr [[FIELD_ADDR]] : $*LifetimeTracked
+    // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick Cat.Type
+    // CHECK-NEXT: dealloc_partial_ref %2 : $Cat, [[METATYPE]] : $@thick Cat.Type
+    // CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
+    // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<Cat>, #Optional.none!enumelt
+    // CHECK-NEXT: br bb3([[RESULT]] : $Optional<Cat>)
 
   // CHECK: bb2:
-    // ChECK-NEXT br bb3
-
-  // CHECK: bb3:
     // CHECK-NEXT: [[SUPER:%.*]] = upcast %2 : $Cat to $FakeNSObject
     // CHECK-NEXT: [[SUB:%.*]] = unchecked_ref_cast [[SUPER]] : $FakeNSObject to $Cat
     // CHECK-NEXT: [[SUPER_FN:%.*]] = objc_super_method [[SUB]] : $Cat, #FakeNSObject.init!initializer.1.foreign : (FakeNSObject.Type) -> () -> FakeNSObject, $@convention(objc_method) (@owned FakeNSObject) -> @owned FakeNSObject
@@ -56,18 +59,9 @@
     // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<Cat>, #Optional.some!enumelt.1, [[NEW_SELF]] : $Cat
     // CHECK-NEXT: destroy_addr [[SELF_BOX]]
     // CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
-    // CHECK-NEXT: br bb5([[RESULT]] : $Optional<Cat>)
+    // CHECK-NEXT: br bb3([[RESULT]] : $Optional<Cat>)
 
-  // CHECK: bb4:
-    // CHECK-NEXT: [[FIELD_ADDR:%.*]] = ref_element_addr %2 : $Cat, #Cat.x
-    // CHECK-NEXT: destroy_addr [[FIELD_ADDR]] : $*LifetimeTracked
-    // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick Cat.Type
-    // CHECK-NEXT: dealloc_partial_ref %2 : $Cat, [[METATYPE]] : $@thick Cat.Type
-    // CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
-    // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<Cat>, #Optional.none!enumelt
-    // CHECK-NEXT: br bb5([[RESULT]] : $Optional<Cat>)
-
-  // CHECK: bb5([[RESULT:%.*]] : $Optional<Cat>):
+  // CHECK: bb3([[RESULT:%.*]] : $Optional<Cat>):
     // CHECK-NEXT: return [[RESULT]] : $Optional<Cat>
 
   init?(n: Int, after: Bool) {
diff --git a/test/SILOptimizer/inline_begin_apply.sil b/test/SILOptimizer/inline_begin_apply.sil
index 0bf0a83..2be4c42 100644
--- a/test/SILOptimizer/inline_begin_apply.sil
+++ b/test/SILOptimizer/inline_begin_apply.sil
@@ -54,41 +54,29 @@
 // CHECK:  [[MK_IND:%.*]] = function_ref @make_indirect
 // CHECK:  apply [[MK_IND]]<SomeSubclass>([[TEMP]])
 // CHECK:  destroy_addr [[TEMP]] : $*Indirect<SomeSubclass>
-// CHECK:  cond_br %0, bb3, bb5
+// CHECK:  cond_br %0, bb1, bb2
 
-// CHECK:bb1:
+// CHECK: bb1:
+// CHECK:   [[I4:%.*]] = integer_literal $Builtin.Int32, 10
+// CHECK:   apply [[MARKER]]([[I4]])
 // CHECK:  [[I2:%.*]] = integer_literal $Builtin.Int32, 2000
 // CHECK:  apply [[MARKER2]]([[I2]])
 // CHECK:  dealloc_stack [[TEMP]] : $*Indirect<SomeSubclass>
-// CHECK:  br bb4
+// CHECK:   [[I5:%.*]] = integer_literal $Builtin.Int32, 20
+// CHECK:   apply [[MARKER]]([[I5]])
+// CHECK:  br bb3
 
 // CHECK: bb2:
+// CHECK:   [[I6:%.*]] = integer_literal $Builtin.Int32, 11
+// CHECK:   apply [[MARKER]]([[I6]])
 // CHECK:  [[I3:%.*]] = integer_literal $Builtin.Int32, 3000
 // CHECK:  apply [[MARKER2]]([[I3]])
 // CHECK:  dealloc_stack [[TEMP]] : $*Indirect<SomeSubclass>
-// CHECK:  br bb6
-
-// CHECK: bb3:
-// CHECK:   [[I4:%.*]] = integer_literal $Builtin.Int32, 10
-// CHECK:   apply [[MARKER]]([[I4]])
-// CHECK:   br bb1
-
-// CHECK: bb4:
-// CHECK:   [[I5:%.*]] = integer_literal $Builtin.Int32, 20
-// CHECK:   apply [[MARKER]]([[I5]])
-// CHECK:  br bb7
-
-// CHECK: bb5:
-// CHECK:   [[I6:%.*]] = integer_literal $Builtin.Int32, 11
-// CHECK:   apply [[MARKER]]([[I6]])
-// CHECK:   br bb2
-
-// CHECK: bb6:
 // CHECK:   [[I7:%.*]] = integer_literal $Builtin.Int32, 21
 // CHECK:   [[MARKER]]([[I7]])
-// CHECK:  br bb7
+// CHECK:  br bb3
 
-// CHECK:bb7:
+// CHECK:bb3:
 // CHECK:  return
 // CHECK:}
 
@@ -197,34 +185,19 @@
 // CHECK-NEXT:   %2 = function_ref @marker
 // CHECK-NEXT:   %3 = integer_literal $Builtin.Int32, 1000
 // CHECK-NEXT:   %4 = apply %2(%3)
-// CHECK-NEXT:   cond_br %0, bb3, bb5
-
+// CHECK-NEXT:   cond_br %0, bb1, bb2
 // CHECK:      bb1:
 // CHECK-NEXT:   [[T0:%.*]] = integer_literal $Builtin.Int32, 2000
 // CHECK-NEXT:   apply %2([[T0]])
 // CHECK-NEXT:   destroy_value %1 : $SomeClass
 // CHECK-NEXT:   tuple ()
-// CHECK-NEXT:   br bb4
-
+// CHECK-NEXT:   br bb3
 // CHECK:      bb2:
 // CHECK-NEXT:   [[T1:%.*]] = integer_literal $Builtin.Int32, 3000
 // CHECK-NEXT:   apply %2([[T1]])
 // CHECK-NEXT:   destroy_value %1 : $SomeClass
-// CHECK-NEXT:   br bb6
-
+// CHECK-NEXT:   br bb3
 // CHECK:      bb3:
-// CHECK-NEXT:   br bb1
-
-// CHECK:      bb4:
-// CHECK-NEXT:   br bb7
-
-// CHECK:      bb5:
-// CHECK-NEXT:   br bb2
-
-// CHECK:      bb6:
-// CHECK-NEXT:   br bb7
-
-// CHECK:      bb7:
 // CHECK-NEXT:   [[T0:%.*]] = tuple ()
 // CHECK-NEXT:   return [[T0]] : $()
 
@@ -298,15 +271,17 @@
 // CHECK-NEXT:   %1 = alloc_stack $Builtin.Int8
 // CHECK-NEXT:   %2 = integer_literal $Builtin.Int8, 8
 // CHECK-NEXT:   store %2 to [trivial] %1 : $*Builtin.Int8
-// CHECK-NEXT:   cond_br %0, bb3, bb5
+// CHECK-NEXT:   cond_br %0, bb1, bb2
 
 // CHECK:      bb1:
+// CHECK-NEXT:   [[T0:%.*]] = integer_literal $Builtin.Int8, 8
+// CHECK-NEXT:   store [[T0]] to [trivial] %1 : $*Builtin.Int8
 // CHECK-NEXT:   // function_ref
 // CHECK-NEXT:   [[USE:%.*]] = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> ()
 // CHECK-NEXT:   apply [[USE]](%1) : $@convention(thin) (@in Builtin.Int8) -> ()
 // CHECK-NEXT:   dealloc_stack %1 : $*Builtin.Int8
 // CHECK-NEXT:   tuple ()
-// CHECK-NEXT:   br bb4
+// CHECK-NEXT:   br bb3
 
 // CHECK:      bb2:
 // CHECK-NEXT:   [[T0:%.*]] = integer_literal $Builtin.Int32, 3000
@@ -314,23 +289,9 @@
 // CHECK-NEXT:   [[MARKER:%.*]] = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
 // CHECK-NEXT:   apply [[MARKER]]([[T0]]) : $@convention(thin) (Builtin.Int32) -> ()
 // CHECK-NEXT:   dealloc_stack %1 : $*Builtin.Int8
-// CHECK-NEXT:   br bb6
+// CHECK-NEXT:   br bb3
 
 // CHECK:      bb3:
-// CHECK-NEXT:   [[T0:%.*]] = integer_literal $Builtin.Int8, 8
-// CHECK-NEXT:   store [[T0]] to [trivial] %1 : $*Builtin.Int8
-// CHECK-NEXT:   br bb1
-
-// CHECK:      bb4:
-// CHECK-NEXT:   br bb7
-
-// CHECK:      bb5:
-// CHECK-NEXT:   br bb2
-
-// CHECK:      bb6:
-// CHECK-NEXT:   br bb7
-
-// CHECK:      bb7:
 // CHECK-NEXT:   [[T0:%.*]] = tuple ()
 // CHECK-NEXT:   return [[T0]] : $()
 // CHECK:      }
@@ -471,8 +432,6 @@
 // CHECK-NEXT:    store [[I1000]] to [trivial] [[A32]]
 // CHECK-NEXT:    [[I2000:%.*]] = integer_literal $Builtin.Int32, 2000
 // CHECK-NEXT:    apply [[MARKER]]([[I2000]])
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    [[I3000:%.*]] = integer_literal $Builtin.Int32, 3000
 // CHECK-NEXT:    apply [[MARKER]]([[I3000]])
 // CHECK-NEXT:    dealloc_stack [[A32]] : $*Builtin.Int32
@@ -481,8 +440,6 @@
 // CHECK-NEXT:    [[I4000:%.*]] = integer_literal $Builtin.Int32, 4000
 // CHECK-NEXT:    apply [[MARKER]]([[I4000]])
 // CHECK-NEXT:    tuple ()
-// CHECK-NEXT:    br [[END:bb[0-9]+]]
-// CHECK:       [[END]]:
 // CHECK-NEXT:    [[RET:%.*]] = tuple ()
 // CHECK-NEXT:    return [[RET]] : $()
 // CHECK-LABEL: // end sil function 'test_stack_overlap_dealloc'
@@ -507,15 +464,11 @@
 // CHECK-NEXT:    [[I2000:%.*]] = integer_literal $Builtin.Int32, 2000
 // CHECK-NEXT:    apply [[MARKER]]([[I2000]])
 // CHECK-NEXT:    [[A16:%.*]] = alloc_stack $Builtin.Int16
-// CHECK-NEXT:    br bb1
-// CHECK:       bb1:
 // CHECK-NEXT:    [[I3000:%.*]] = integer_literal $Builtin.Int32, 3000
 // CHECK-NEXT:    apply [[MARKER]]([[I3000]])
 // CHECK-NEXT:    [[I4000:%.*]] = integer_literal $Builtin.Int32, 4000
 // CHECK-NEXT:    apply [[MARKER]]([[I4000]])
 // CHECK-NEXT:    tuple ()
-// CHECK-NEXT:    br [[END:bb[0-9]+]]
-// CHECK:       [[END]]:
 // CHECK-NEXT:    dealloc_stack [[A16]] : $*Builtin.Int16
 //   Note that this has been delayed to follow stack discipline.
 // CHECK-NEXT:    dealloc_stack [[A32]] : $*Builtin.Int32
diff --git a/test/SILOptimizer/mandatory_inlining.sil b/test/SILOptimizer/mandatory_inlining.sil
index a269fca..d5a7ba3 100644
--- a/test/SILOptimizer/mandatory_inlining.sil
+++ b/test/SILOptimizer/mandatory_inlining.sil
@@ -353,19 +353,13 @@
 
 // CHECK: [[BB5]]:
   // CHECK: [[VAL50:%.*]] = load [[PB16]]
-  // CHECK: br [[BB6:.*]]([[VAL50]]
-
-// CHECK: [[BB6]]([[VAL52:%.*]] : $Float):
   // CHECK: strong_release [[VAL16]]
   // CHECK: strong_release [[VAL15]]
-  // CHECK: br [[BB7:.*]]([[VAL52]]
-
-// CHECK: [[BB7]]([[VAL56:%.*]] : $Float):
   // CHECK: [[VAL57:%.*]] = function_ref @convertFromBuiltinFloatLiteral
   // CHECK: [[VAL58:%.*]] = metatype $@thin Float.Type
   // CHECK: [[VAL59:%.*]] = float_literal $Builtin.FPIEEE64, 0x4008000000000000
   // CHECK: [[VAL60:%.*]] = apply [[VAL57]]([[VAL59]], [[VAL58]])
-  // CHECK: [[VAL61:%.*]] = apply [[VAL3]]([[VAL56]], [[VAL60]])
+  // CHECK: [[VAL61:%.*]] = apply [[VAL3]]([[VAL50]], [[VAL60]])
   // CHECK: strong_release [[VAL1]]
   // CHECK: return [[VAL61]]
 
@@ -512,22 +506,14 @@
 // CHECK-LABEL: sil [transparent] @test_partial_nativeobject_foo : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
 // CHECK: bb0([[ARG:%.*]] : $Builtin.NativeObject):
 // CHECK:   [[FN:%.*]] = function_ref @test_partial_nativeobject_baz :
-// CHECK:   br bb1
-//
-// CHECK: bb1:
 // CHECK:   strong_retain [[ARG]]
 // CHECK:   [[PAI:%.*]] = partial_apply [[FN]]([[ARG]])
-// CHECK:   br bb2
-//
-// CHECK: bb2:
 // CHECK:   strong_retain [[ARG]]
 // CHECK:   strong_retain [[PAI]]
 // CHECK:   strong_retain [[ARG]]
 // CHECK:   strong_release [[PAI]]
 // CHECK:   [[FN2:%.*]] = function_ref @nativeobject_plus :
 // CHECK:   [[RESULT:%.*]] = apply [[FN2]]([[ARG]], [[ARG]])
-//
-// CHECK: bb3:
 // CHECK:   strong_retain [[PAI]]
 // CHECK:   [[OPAQUE_FN:%.*]] = function_ref @partial_apply_user
 // CHECK:   apply [[OPAQUE_FN]]([[PAI]])
@@ -631,9 +617,6 @@
   // CHECK: br [[BB3]](
 
 // CHECK: [[BB3]](
-  // CHECK: br [[BB4:.*]](
-
-// CHECK: [[BB4]](
   // CHECK: strong_release [[VAL4]]
   // CHECK: return {{.*}}
 
@@ -681,9 +664,6 @@
   // CHECK: br [[BB3]](
 
 // CHECK: [[BB3]](
-  // CHECK: br [[BB4:.*]](
-
-// CHECK: [[BB4]](
   // CHECK: strong_release [[VAL3]]
   // CHECK: return {{.*}}
 
diff --git a/test/SILOptimizer/mandatory_inlining_ownership.sil b/test/SILOptimizer/mandatory_inlining_ownership.sil
index 4712c3b..2ba9b37 100644
--- a/test/SILOptimizer/mandatory_inlining_ownership.sil
+++ b/test/SILOptimizer/mandatory_inlining_ownership.sil
@@ -57,14 +57,15 @@
 // CHECK:   [[BORROW:%.*]] = begin_borrow %0 : $C
 // CHECK:   [[ADDR:%.*]] = ref_element_addr [[BORROW]] : $C, #C.i
 // CHECK:   [[VAL:%.*]] = load [trivial] [[ADDR]] : $*Builtin.Int64
-// CHECK: bb{{.*}}([[RET:%.*]] : @trivial $Builtin.Int64):
-// CHECK:   end_borrow [[BORROW]] : $C
-// CHECK:   destroy_value %0 : $C
-// CHECK:   return [[RET]] : $Builtin.Int64
-// CHECK: bb{{.*}}([[ERR:%.*]] : @owned $Error):
+// CHECK: bb{{.*}}:
+// CHECK:   [[ERR:%.*]] = alloc_existential_box $Error, $MyError
 // CHECK:   end_borrow [[BORROW]] : $C
 // CHECK:   destroy_value %0 : $C
 // CHECK:   throw [[ERR]] : $Error
+// CHECK: bb{{.*}}:
+// CHECK:   end_borrow [[BORROW]] : $C
+// CHECK:   destroy_value %0 : $C
+// CHECK:   return [[VAL]] : $Builtin.Int64
 // CHECK-LABEL: } // end sil function 'callerWithThrow'
 sil @callerWithThrow : $@convention(thin) (@owned C) -> (Builtin.Int64, @error Error) {
 bb(%0 : @owned $C):
diff --git a/test/api-digester/Outputs/cake-abi.json b/test/api-digester/Outputs/cake-abi.json
index dc86703..1eab10e 100644
--- a/test/api-digester/Outputs/cake-abi.json
+++ b/test/api-digester/Outputs/cake-abi.json
@@ -246,7 +246,7 @@
                 }
               ],
               "declKind": "Accessor",
-              "usr": "s:4cake2C1C3InsACSgXwvg",
+              "usr": "s:4cake2C1C3InsACSgvg",
               "moduleName": "cake",
               "implicit": true,
               "declAttributes": [
@@ -279,7 +279,7 @@
                 }
               ],
               "declKind": "Accessor",
-              "usr": "s:4cake2C1C3InsACSgXwvs",
+              "usr": "s:4cake2C1C3InsACSgvs",
               "moduleName": "cake",
               "implicit": true,
               "declAttributes": [
@@ -288,11 +288,12 @@
             }
           ],
           "declKind": "Var",
-          "usr": "s:4cake2C1C3InsACSgXwvp",
+          "usr": "s:4cake2C1C3InsACSgvp",
           "moduleName": "cake",
           "declAttributes": [
             "HasInitialValue",
-            "ReferenceOwnership"
+            "ReferenceOwnership",
+            "HasStorage"
           ],
           "fixedbinaryorder": 0,
           "ownership": 1,
@@ -321,7 +322,7 @@
                 }
               ],
               "declKind": "Accessor",
-              "usr": "s:4cake2C1C4Ins2ACXovg",
+              "usr": "s:4cake2C1C4Ins2ACvg",
               "moduleName": "cake",
               "implicit": true,
               "declAttributes": [
@@ -346,7 +347,7 @@
                 }
               ],
               "declKind": "Accessor",
-              "usr": "s:4cake2C1C4Ins2ACXovs",
+              "usr": "s:4cake2C1C4Ins2ACvs",
               "moduleName": "cake",
               "implicit": true,
               "declAttributes": [
@@ -355,11 +356,12 @@
             }
           ],
           "declKind": "Var",
-          "usr": "s:4cake2C1C4Ins2ACXovp",
+          "usr": "s:4cake2C1C4Ins2ACvp",
           "moduleName": "cake",
           "declAttributes": [
             "HasInitialValue",
-            "ReferenceOwnership"
+            "ReferenceOwnership",
+            "HasStorage"
           ],
           "fixedbinaryorder": 1,
           "ownership": 2,
@@ -743,7 +745,8 @@
           "usr": "s:4cake17fixedLayoutStructV1aSivp",
           "moduleName": "cake",
           "declAttributes": [
-            "HasInitialValue"
+            "HasInitialValue",
+            "HasStorage"
           ],
           "fixedbinaryorder": 0,
           "hasStorage": true
@@ -786,7 +789,8 @@
           "moduleName": "cake",
           "isInternal": true,
           "declAttributes": [
-            "HasInitialValue"
+            "HasInitialValue",
+            "HasStorage"
           ],
           "fixedbinaryorder": 1,
           "hasStorage": true,
@@ -831,7 +835,8 @@
           "moduleName": "cake",
           "isInternal": true,
           "declAttributes": [
-            "HasInitialValue"
+            "HasInitialValue",
+            "HasStorage"
           ],
           "fixedbinaryorder": 2,
           "hasStorage": true
@@ -873,7 +878,8 @@
           "moduleName": "cake",
           "declAttributes": [
             "HasInitialValue",
-            "Available"
+            "Available",
+            "HasStorage"
           ],
           "fixedbinaryorder": 3,
           "isLet": true,
@@ -1135,7 +1141,8 @@
       "usr": "s:4cake9GlobalVarSivp",
       "moduleName": "cake",
       "declAttributes": [
-        "HasInitialValue"
+        "HasInitialValue",
+        "HasStorage"
       ],
       "isLet": true,
       "hasStorage": true
@@ -1193,7 +1200,8 @@
           "moduleName": "cake",
           "isInternal": true,
           "declAttributes": [
-            "HasInitialValue"
+            "HasInitialValue",
+            "HasStorage"
           ],
           "fixedbinaryorder": 0,
           "hasStorage": true
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index 10e7ad1..346e4ef 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -289,7 +289,7 @@
                 }
               ],
               "declKind": "Accessor",
-              "usr": "s:4cake2C1C3InsACSgXwvg",
+              "usr": "s:4cake2C1C3InsACSgvg",
               "moduleName": "cake",
               "implicit": true,
               "declAttributes": [
@@ -322,7 +322,7 @@
                 }
               ],
               "declKind": "Accessor",
-              "usr": "s:4cake2C1C3InsACSgXwvs",
+              "usr": "s:4cake2C1C3InsACSgvs",
               "moduleName": "cake",
               "implicit": true,
               "declAttributes": [
@@ -331,11 +331,12 @@
             }
           ],
           "declKind": "Var",
-          "usr": "s:4cake2C1C3InsACSgXwvp",
+          "usr": "s:4cake2C1C3InsACSgvp",
           "moduleName": "cake",
           "declAttributes": [
             "HasInitialValue",
-            "ReferenceOwnership"
+            "ReferenceOwnership",
+            "HasStorage"
           ],
           "ownership": 1,
           "hasStorage": true
@@ -363,7 +364,7 @@
                 }
               ],
               "declKind": "Accessor",
-              "usr": "s:4cake2C1C4Ins2ACXovg",
+              "usr": "s:4cake2C1C4Ins2ACvg",
               "moduleName": "cake",
               "implicit": true,
               "declAttributes": [
@@ -388,7 +389,7 @@
                 }
               ],
               "declKind": "Accessor",
-              "usr": "s:4cake2C1C4Ins2ACXovs",
+              "usr": "s:4cake2C1C4Ins2ACvs",
               "moduleName": "cake",
               "implicit": true,
               "declAttributes": [
@@ -397,11 +398,12 @@
             }
           ],
           "declKind": "Var",
-          "usr": "s:4cake2C1C4Ins2ACXovp",
+          "usr": "s:4cake2C1C4Ins2ACvp",
           "moduleName": "cake",
           "declAttributes": [
             "HasInitialValue",
-            "ReferenceOwnership"
+            "ReferenceOwnership",
+            "HasStorage"
           ],
           "ownership": 2,
           "hasStorage": true
@@ -807,7 +809,8 @@
           "usr": "s:4cake17fixedLayoutStructV1aSivp",
           "moduleName": "cake",
           "declAttributes": [
-            "HasInitialValue"
+            "HasInitialValue",
+            "HasStorage"
           ],
           "hasStorage": true
         }
@@ -1084,7 +1087,8 @@
       "usr": "s:4cake9GlobalVarSivp",
       "moduleName": "cake",
       "declAttributes": [
-        "HasInitialValue"
+        "HasInitialValue",
+        "HasStorage"
       ],
       "isLet": true,
       "hasStorage": true
diff --git a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
index ba9d048..e2348bb 100644
--- a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
+++ b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
@@ -483,6 +483,23 @@
 Protocol _NSFastEnumeration has been removed
 Protocol _ShadowProtocol has been removed
 
+Constructor _StringGutsSlice.init(_:) has been removed
+Constructor _StringGutsSlice.init(_:_:) has been removed
+Func _StringGutsSlice._normalizedHash(into:) has been removed
+Func _StringGutsSlice.compare(with:expecting:) has been removed
+Func _StringGutsSlice.withFastUTF8(_:) has been removed
+Struct _StringGutsSlice is now without @_fixed_layout
+Var StringProtocol._gutsSlice has been removed
+Var _StringGutsSlice._guts has been removed
+Var _StringGutsSlice._offsetRange has been removed
+Var _StringGutsSlice.count has been removed
+Var _StringGutsSlice.end has been removed
+Var _StringGutsSlice.isASCII has been removed
+Var _StringGutsSlice.isFastUTF8 has been removed
+Var _StringGutsSlice.isNFCFastUTF8 has been removed
+Var _StringGutsSlice.range has been removed
+Var _StringGutsSlice.start has been removed
+
 Func ManagedBufferPointer._sanityCheckValidBufferClass(_:creating:) has been removed
 Func _sanityCheck(_:_:file:line:) has been removed
 Func _sanityCheckFailure(_:file:line:) has been removed
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index 1db82b3..8e13c28 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -839,19 +839,19 @@
   }
 
   var observingAccessorsVar1: Int {
-  // CHECK: @objc var observingAccessorsVar1: Int {
+  // CHECK: @_hasStorage @objc var observingAccessorsVar1: Int {
     willSet {}
-    // CHECK-NEXT: {{^}} willSet {}
+    // CHECK-NEXT: {{^}} @objc get
     didSet {}
-    // CHECK-NEXT: {{^}} didSet {}
+    // CHECK-NEXT: {{^}} @objc set
   }
 
   @objc var observingAccessorsVar1_: Int {
-  // CHECK: {{^}} @objc var observingAccessorsVar1_: Int {
+  // CHECK: {{^}} @objc @_hasStorage var observingAccessorsVar1_: Int {
     willSet {}
-    // CHECK-NEXT: {{^}} willSet {}
+    // CHECK-NEXT: {{^}} @objc get
     didSet {}
-    // CHECK-NEXT: {{^}} didSet {}
+    // CHECK-NEXT: {{^}} @objc set
   }
 
 
@@ -1709,14 +1709,20 @@
 
   @NSManaged
   var goodManaged: Class_ObjC1
-  // CHECK-LABEL: {{^}}  @objc @NSManaged dynamic var goodManaged: Class_ObjC1
+  // CHECK-LABEL: {{^}}  @objc @NSManaged @_hasStorage dynamic var goodManaged: Class_ObjC1 {
+  // CHECK-NEXT: {{^}} @objc get
+  // CHECK-NEXT: {{^}} @objc set
+  // CHECK-NEXT: {{^}} }
 
   @NSManaged
   var badManaged: PlainStruct
   // expected-error@-1 {{property cannot be marked @NSManaged because its type cannot be represented in Objective-C}}
   // expected-note@-2 {{Swift structs cannot be represented in Objective-C}}
   // expected-error@-3{{'dynamic' property 'badManaged' must also be '@objc'}}
-  // CHECK-LABEL: {{^}}  @NSManaged var badManaged: PlainStruct
+  // CHECK-LABEL: {{^}}  @NSManaged @_hasStorage var badManaged: PlainStruct {
+  // CHECK-NEXT: {{^}} get
+  // CHECK-NEXT: {{^}} set
+  // CHECK-NEXT: {{^}} }
 }
 
 //===---
diff --git a/test/attr/hasInitialValue.swift b/test/attr/hasInitialValue.swift
index e259b24..42594ab 100644
--- a/test/attr/hasInitialValue.swift
+++ b/test/attr/hasInitialValue.swift
@@ -12,7 +12,7 @@
     // CHECK: {{^}}  @_implicitly_unwrapped_optional @_hasInitialValue var iuo: Int!
     var iuo: Int!
 
-    // CHECK: {{^}}  lazy var lazyIsntARealInit: Int
+    // CHECK: {{^}}  @_hasStorage lazy var lazyIsntARealInit: Int
     lazy var lazyIsntARealInit: Int = 0
 
     init() {
diff --git a/test/lit.cfg b/test/lit.cfg
index 8dc375e..60957ae 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -846,7 +846,7 @@
     config.target_swift_ide_test =                                               \
             ('%r -target %s %s %s %s' % (config.swift_ide_test,                  \
                                          config.variant_triple,                  \
-                                         resource_dir_opt, pcp_opt, ccp_opt))
+                                         resource_dir_opt, mcp_opt, ccp_opt))
 
     subst_target_swift_ide_test_mock_sdk = config.target_swift_ide_test
     subst_target_swift_ide_test_mock_sdk_after = ''
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
index aac8587..66e59a8 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
@@ -688,6 +688,7 @@
     case DAK_ShowInInterface:
     case DAK_RawDocComment:
     case DAK_HasInitialValue:
+    case DAK_HasStorage:
       return None;
     default:
       break;
diff --git a/utils/build-presets.ini b/utils/build-presets.ini
index a00f122..512664e 100644
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -804,6 +804,7 @@
 android-icu-uc-include=%(arm_dir)s/icu/source/common
 android-icu-i18n=%(arm_dir)s/libicui18nswift.so
 android-icu-i18n-include=%(arm_dir)s/icu/source/i18n
+android-icu-data=%(arm_dir)s/libicudataswift.so
 
 # Ubuntu 18.04 preset for backwards compat and future customizations.
 [preset: buildbot_linux_1804]
diff --git a/utils/build-script b/utils/build-script
index 8afec0f..1c6f250 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -254,7 +254,7 @@
                     args.android_icu_data is None:
                 diagnostics.fatal(
                     "when building for Android, --android-ndk, "
-                    "--android-ndk-version, --android-icu-uc, "
+                    "--android-api-level, --android-icu-uc, "
                     "--android-icu-uc-include, --android-icu-i18n, "
                     "--android-icu-i18n-include, and --android-icu-data "
                     "must be specified")
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 72f0f66..e85b97a 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -1181,6 +1181,7 @@
 XCTEST_SOURCE_DIR="${WORKSPACE}/swift-corelibs-xctest"
 FOUNDATION_SOURCE_DIR="${WORKSPACE}/swift-corelibs-foundation"
 LIBDISPATCH_SOURCE_DIR="${WORKSPACE}/swift-corelibs-libdispatch"
+LIBDISPATCH_STATIC_SOURCE_DIR="${WORKSPACE}/swift-corelibs-libdispatch"
 LIBICU_SOURCE_DIR="${WORKSPACE}/icu"
 PLAYGROUNDSUPPORT_SOURCE_DIR="${WORKSPACE}/swift-xcode-playground-support"
 
@@ -1223,6 +1224,9 @@
 # products first.
 if [[ ! "${SKIP_BUILD_LIBDISPATCH}" ]] ; then
      PRODUCTS=("${PRODUCTS[@]}" libdispatch)
+     if [[ -z "${SKIP_BUILD_SWIFT_STATIC_LIBDISPATCH}" ]] ; then
+       PRODUCTS=("${PRODUCTS[@]}" libdispatch_static)
+     fi
 fi
 if [[ ! "${SKIP_BUILD_FOUNDATION}" ]] ; then
      PRODUCTS=("${PRODUCTS[@]}" foundation)
@@ -1570,7 +1574,7 @@
             foundation)
                 echo "${root}/${FOUNDATION_BUILD_TYPE}/bin"
                 ;;
-            libdispatch)
+            libdispatch|libdispatch_static)
                 echo "${root}/${LIBDISPATCH_BUILD_TYPE}/bin"
                 ;;
             libicu)
@@ -1715,7 +1719,7 @@
             foundation)
                 echo "--config ${FOUNDATION_BUILD_TYPE}"
                 ;;
-            libdispatch)
+            libdispatch|libdispatch_static)
                 echo "--config ${LIBDISPATCH_BUILD_TYPE}"
                 ;;
             libicu)
@@ -2286,7 +2290,6 @@
                     -DSWIFT_PATH_TO_CMARK_SOURCE:PATH="${CMARK_SOURCE_DIR}"
                     -DSWIFT_PATH_TO_CMARK_BUILD:PATH="$(build_directory ${host} cmark)"
                     -DSWIFT_PATH_TO_LIBDISPATCH_SOURCE:PATH="${LIBDISPATCH_SOURCE_DIR}"
-                    -DSWIFT_PATH_TO_LIBDISPATCH_BUILD:PATH="$(build_directory ${host} libdispatch)"
                 )
 
                 if [[ ! "${SKIP_BUILD_LIBICU}" ]] ; then
@@ -2662,7 +2665,7 @@
                 )
 
                 ;;
-            libdispatch)
+            libdispatch|libdispatch_static)
                 LIBDISPATCH_BUILD_DIR=$(build_directory ${host} ${product})
                 SWIFT_BUILD_PATH="$(build_directory ${host} swift)"
                 SWIFTC_BIN="$(build_directory_bin ${LOCAL_HOST} swift)/swiftc"
@@ -2726,6 +2729,7 @@
                     -DSwift_DIR="${SWIFT_BUILD_PATH}/lib/cmake/swift"
 
                     -DENABLE_TESTING=YES
+                    -DBUILD_SHARED_LIBS=$([[ ${product} == libdispatch_static ]] && echo "NO" || echo "YES")
                   )
                 ;;
                 esac
@@ -3282,6 +3286,11 @@
                 ;;
                 esac
                 ;;
+            libdispatch_static)
+              # FIXME: merge with libdispatch once the unit tests work with
+              # libdispatch_static
+              continue
+            ;;
             libicu)
                 if [[ "${SKIP_TEST_LIBICU}" ]]; then
                     continue
@@ -3526,7 +3535,7 @@
                 fi
 
                 ;;
-            libdispatch)
+            libdispatch|libdispatch_static)
                 if [[ -z "${INSTALL_LIBDISPATCH}" ]] ; then
                     continue
                 fi
diff --git a/validation-test/compiler_scale/array_init.swift.gyb b/validation-test/compiler_scale/array_init.swift.gyb
new file mode 100644
index 0000000..18d2096
--- /dev/null
+++ b/validation-test/compiler_scale/array_init.swift.gyb
@@ -0,0 +1,13 @@
+// RUN: %scale-test -Onone --begin 0 --end 10 --step 1 --select transferNodesFromList %s
+// REQUIRES: OS=macosx
+// REQUIRES: asserts
+
+// Test that mandatory inlining is linear on a long series of integer
+// initialization calls.
+
+ let _: [Int] = [
+ %for i in range(0, N):
+   1,
+ %end
+   1
+ ]