Merge pull request #4932 from slavapestov/fix-resilient-build

Fix resilient build
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index 26d0537..0a5261c 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -170,7 +170,7 @@
   constexpr TypeMetadataRecordFlags(int_type Data) : Data(Data) {}
   
   constexpr TypeMetadataRecordKind getTypeKind() const {
-    return TypeMetadataRecordKind((Data >> TypeKindShift) & TypeKindMask);
+    return TypeMetadataRecordKind((Data & TypeKindMask) >> TypeKindShift);
   }
   constexpr TypeMetadataRecordFlags withTypeKind(
                                         TypeMetadataRecordKind ptk) const {
@@ -199,8 +199,8 @@
                      (Data & ~TypeKindMask) | (int_type(ptk) << TypeKindShift));
   }
   constexpr ProtocolConformanceReferenceKind getConformanceKind() const {
-    return ProtocolConformanceReferenceKind((Data >> ConformanceKindShift)
-                                     & ConformanceKindMask);
+    return ProtocolConformanceReferenceKind((Data & ConformanceKindMask)
+                                     >> ConformanceKindShift);
   }
   constexpr ProtocolConformanceFlags withConformanceKind(
                                   ProtocolConformanceReferenceKind pck) const {
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index 627ea42..b92807b 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -141,6 +141,11 @@
     /// \brief Enable experimental nested generic types feature.
     bool EnableExperimentalNestedGenericTypes = false;
 
+    /// \brief Staging flag for class resilience, which we do not want to enable
+    /// fully until more code is in place, to allow the standard library to be
+    /// tested with value type resilience only.
+    bool EnableClassResilience = false;
+
     /// Should we check the target OSs of serialized modules to see that they're
     /// new enough?
     bool EnableTargetOSChecking = true;
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index 7c1cee3..052bcb6 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -331,6 +331,10 @@
    HelpText<"Compile the module to export resilient interfaces for all "
             "public declarations by default">;
 
+def enable_class_resilience : Flag<["-"], "enable-class-resilience">,
+   HelpText<"Compile the module to export resilient interfaces for all "
+            "public classes by default (doesn't work yet)">;
+
 def group_info_path : Separate<["-"], "group-info-path">,
   HelpText<"The path to collect the group information of the compiled module">;
 
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 6ecf61d..ef70d3e 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -787,6 +787,9 @@
   Opts.EnableExperimentalNestedGenericTypes |=
     Args.hasArg(OPT_enable_experimental_nested_generic_types);
 
+  Opts.EnableClassResilience |=
+    Args.hasArg(OPT_enable_class_resilience);
+
   Opts.DisableAvailabilityChecking |=
       Args.hasArg(OPT_disable_availability_checking);
   if (FrontendOpts.InputKind == InputFileKind::IFK_SIL)
diff --git a/lib/IRGen/ClassMetadataLayout.h b/lib/IRGen/ClassMetadataLayout.h
index f87f5d8..4f9d239 100644
--- a/lib/IRGen/ClassMetadataLayout.h
+++ b/lib/IRGen/ClassMetadataLayout.h
@@ -88,7 +88,8 @@
       // Skip superclass fields if superclass is resilient.
       // FIXME: Needs runtime support to ensure the field offset vector is
       // populated correctly.
-      if (!IGM.isResilient(superclassDecl, ResilienceExpansion::Maximal)) {
+      if (!IGM.Context.LangOpts.EnableClassResilience ||
+          !IGM.isResilient(superclassDecl, ResilienceExpansion::Maximal)) {
         addClassMembers(superclassDecl, superclass);
       }
     }
diff --git a/lib/IRGen/EnumMetadataLayout.h b/lib/IRGen/EnumMetadataLayout.h
index 06d0fff..7dba6ea 100644
--- a/lib/IRGen/EnumMetadataLayout.h
+++ b/lib/IRGen/EnumMetadataLayout.h
@@ -52,15 +52,15 @@
     // emitParentMetadataRef.
 
     // Instantiation-specific.
-    
+
+    // Add fields for generic cases.
+    asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
+
     // Reserve a word to cache the payload size if the type has dynamic layout.
     auto &strategy = getEnumImplStrategy(IGM,
            Target->DeclContext::getDeclaredTypeInContext()->getCanonicalType());
     if (strategy.needsPayloadSizeInMetadata())
       asImpl().addPayloadSize();
-    
-    // Add fields for generic cases.
-    asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
   }
 };
 
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index 5687d4c..d989366 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -242,7 +242,16 @@
 
           // If the superclass is resilient to us, we cannot statically
           // know the layout of either its instances or its class objects.
-          ClassHasFixedFieldCount = false;
+          //
+          // FIXME: We need to implement indirect field/vtable entry access
+          // before we can enable this
+          if (IGM.Context.LangOpts.EnableClassResilience) {
+            ClassHasFixedFieldCount = false;
+          } else {
+            addFieldsForClass(superclass, superclassType);
+            NumInherited = Elements.size();
+          }
+
           ClassHasFixedSize = false;
 
           // Furthermore, if the superclass is a generic context, we have to
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 21f2fb0..6151547 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2174,17 +2174,27 @@
                   getPointerAlignment(), ProtocolDescriptorStructTy);
     auto typeEntity = getTypeEntityInfo(*this,
                                     conformance->getType()->getCanonicalType());
-    auto flags = typeEntity.flags
-        .withConformanceKind(ProtocolConformanceReferenceKind::WitnessTable);
+    auto flags = typeEntity.flags;
 
-    // If the conformance is in this object's table, then the witness table
-    // should also be in this object file, so we can always directly reference
-    // it.
-    // TODO: Should use accessor kind for lazy conformances
-    // TODO: Produce a relative reference to a private generator function
-    // if the witness table requires lazy initialization, instantiation, or
-    // conditional conformance checking.
-    auto witnessTableVar = getAddrOfWitnessTable(conformance);
+    llvm::Constant *witnessTableVar;
+
+    if (!isResilient(conformance->getProtocol(),
+                     ResilienceExpansion::Maximal)) {
+      flags = flags.withConformanceKind(
+          ProtocolConformanceReferenceKind::WitnessTable);
+
+      // If the conformance is in this object's table, then the witness table
+      // should also be in this object file, so we can always directly reference
+      // it.
+      witnessTableVar = getAddrOfWitnessTable(conformance);
+    } else {
+      flags = flags.withConformanceKind(
+          ProtocolConformanceReferenceKind::WitnessTableAccessor);
+
+      witnessTableVar = getAddrOfWitnessTableAccessFunction(
+          conformance, ForDefinition);
+    }
+
     auto witnessTableRef =
       ConstantReference(witnessTableVar, ConstantReference::Direct);
 
diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp
index 077d2eb..085cc76 100644
--- a/lib/IRGen/GenEnum.cpp
+++ b/lib/IRGen/GenEnum.cpp
@@ -4656,7 +4656,7 @@
     }
     
     bool needsPayloadSizeInMetadata() const override {
-      llvm_unreachable("resilient enums cannot be defined");
+      return false;
     }
 
     void initializeMetadata(IRGenFunction &IGF,
diff --git a/stdlib/public/core/ArrayBuffer.swift b/stdlib/public/core/ArrayBuffer.swift
index 0dd308e..e0d8931 100644
--- a/stdlib/public/core/ArrayBuffer.swift
+++ b/stdlib/public/core/ArrayBuffer.swift
@@ -21,6 +21,7 @@
 internal typealias _ArrayBridgeStorage
   = _BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCore>
 
+@_versioned
 @_fixed_layout
 internal struct _ArrayBuffer<Element> : _ArrayBufferProtocol {
 
@@ -29,6 +30,7 @@
     _storage = _ArrayBridgeStorage(native: _emptyArrayStorage)
   }
 
+  @_versioned  // FIXME(abi): Used from tests
   internal init(nsArray: _NSArrayCore) {
     _sanityCheck(_isClassOrObjCExistential(Element.self))
     _storage = _ArrayBridgeStorage(objC: nsArray)
@@ -113,6 +115,7 @@
   /// Convert to an NSArray.
   ///
   /// O(1) if the element type is bridged verbatim, O(*n*) otherwise.
+  @_versioned  // FIXME(abi): Used from tests
   internal func _asCocoaArray() -> _NSArrayCore {
     return _fastPath(_isNative) ? _native._asCocoaArray() : _nonNative
   }
@@ -273,6 +276,7 @@
   /// A pointer to the first element.
   ///
   /// - Precondition: The elements are known to be stored contiguously.
+  @_versioned
   internal var firstElementAddress: UnsafeMutablePointer<Element> {
     _sanityCheck(_isNative, "must be a native buffer")
     return _native.firstElementAddress
diff --git a/stdlib/public/core/ArrayBufferProtocol.swift b/stdlib/public/core/ArrayBufferProtocol.swift
index 6bfef6f..b70f483 100644
--- a/stdlib/public/core/ArrayBufferProtocol.swift
+++ b/stdlib/public/core/ArrayBufferProtocol.swift
@@ -12,6 +12,7 @@
 
 /// The underlying buffer for an ArrayType conforms to
 /// `_ArrayBufferProtocol`.  This buffer does not provide value semantics.
+@_versioned
 internal protocol _ArrayBufferProtocol
   : MutableCollection, RandomAccessCollection {
 
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index c689094..35b8923 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -283,6 +283,7 @@
 // Declare it here instead of RuntimeShims.h, because we need to specify
 // the type of argument to be AnyClass. This is currently not possible
 // when using RuntimeShims.h
+@_versioned
 @_silgen_name("swift_objc_class_usesNativeSwiftReferenceCounting")
 func _usesNativeSwiftReferenceCounting(_ theClass: AnyClass) -> Bool
 #else
@@ -480,6 +481,7 @@
   )
 }
 
+@_versioned
 @_silgen_name("_swift_class_getSuperclass")
 internal func _swift_class_getSuperclass(_ t: AnyClass) -> AnyClass?
 
diff --git a/stdlib/public/core/ContiguousArrayBuffer.swift b/stdlib/public/core/ContiguousArrayBuffer.swift
index f27d91ba..8d2b0ed 100644
--- a/stdlib/public/core/ContiguousArrayBuffer.swift
+++ b/stdlib/public/core/ContiguousArrayBuffer.swift
@@ -176,6 +176,7 @@
   }
 }
 
+@_versioned
 @_fixed_layout
 internal struct _ContiguousArrayBuffer<Element> : _ArrayBufferProtocol {
 
@@ -247,6 +248,7 @@
   }
 
   /// A pointer to the first element.
+  @_versioned
   internal var firstElementAddress: UnsafeMutablePointer<Element> {
     return UnsafeMutablePointer(Builtin.projectTailElems(_storage,
                                                          Element.self))
@@ -318,6 +320,7 @@
   }
 
   /// Get or set the value of the ith element.
+  @_versioned
   internal subscript(i: Int) -> Element {
     get {
       return getElement(i)
@@ -434,6 +437,7 @@
 #endif
 
   /// An object that keeps the elements stored in this buffer alive.
+  @_versioned
   internal var owner: AnyObject {
     return _storage
   }
diff --git a/stdlib/public/core/HashedCollections.swift.gyb b/stdlib/public/core/HashedCollections.swift.gyb
index 15b0c2d..b58f711 100644
--- a/stdlib/public/core/HashedCollections.swift.gyb
+++ b/stdlib/public/core/HashedCollections.swift.gyb
@@ -2508,6 +2508,7 @@
 /// Enough bytes are allocated to hold the bitmap for marking valid entries,
 /// keys, and values. The data layout starts with the bitmap, followed by the
 /// keys, followed by the values.
+@_versioned
 final internal class _Native${Self}StorageImpl<${TypeParameters}> {
   // Note: It is intended that ${TypeParameters}
   // (without : Hashable) is used here - this storage must work
@@ -3229,6 +3230,7 @@
 /// is also a proper `NS${Self}` subclass, which is returned to Objective-C
 /// during bridging.  `${Self}Index` points directly to
 /// `_Native${Self}Storage`.
+@_versioned
 final internal class _Native${Self}StorageOwner<${TypeParametersDecl}>
   : _SwiftNativeNS${Self}, _NS${Self}Core {
 
@@ -3564,7 +3566,10 @@
 }
 
 #if _runtime(_ObjC)
+@_versioned
+@_fixed_layout
 internal struct _Cocoa${Self}Storage : _HashStorage {
+  @_versioned
   internal var cocoa${Self}: _NS${Self}
 
   internal typealias Index = _Cocoa${Self}Index
@@ -3695,6 +3700,8 @@
 internal struct _Cocoa${Self}Storage {}
 #endif
 
+@_versioned
+@_fixed_layout
 internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorage {
 
   internal typealias NativeStorage = _Native${Self}Storage<${TypeParameters}>
@@ -4408,6 +4415,7 @@
   }
 }
 
+@_versioned
 internal struct _Native${Self}Index<${TypeParametersDecl}> :
   Comparable {
 
@@ -4418,6 +4426,8 @@
   // the new model.
   @_versioned
   internal var nativeStorage: NativeStorage
+
+  @_versioned
   internal var offset: Int
 
   @_versioned
@@ -4799,6 +4809,7 @@
 final internal class _Cocoa${Self}Iterator {}
 #endif
 
+@_versioned
 internal enum ${Self}IteratorRepresentation<${TypeParametersDecl}> {
   internal typealias _Iterator = ${Self}Iterator<${TypeParameters}>
   internal typealias _NativeStorageOwner =
diff --git a/stdlib/public/core/SipHash.swift.gyb b/stdlib/public/core/SipHash.swift.gyb
index 4f92b5a..00cab1e 100644
--- a/stdlib/public/core/SipHash.swift.gyb
+++ b/stdlib/public/core/SipHash.swift.gyb
@@ -19,12 +19,15 @@
 /// * Daniel J. Bernstein <djb@cr.yp.to>
 //===----------------------------------------------------------------------===//
 
+@_versioned
 internal enum _SipHashDetail {
+  @_versioned
   @inline(__always)
   internal static func _rotate(_ x: UInt64, leftBy amount: Int) -> UInt64 {
     return (x << UInt64(amount)) | (x >> (64 - UInt64(amount)))
   }
 
+  @_versioned
   @inline(__always)
   internal static func _loadUnalignedUInt64LE(
     from p: UnsafeRawPointer
@@ -40,6 +43,7 @@
       (UInt64(p.load(fromByteOffset: 7, as: UInt8.self)) << 56)
   }
 
+  @_versioned
   @inline(__always)
   internal static func _loadPartialUnalignedUInt64LE(
     from p: UnsafeRawPointer,
@@ -57,6 +61,7 @@
     return result
   }
 
+  @_versioned
   @inline(__always)
   internal static func _sipRound(
     v0: inout UInt64,
@@ -87,16 +92,28 @@
 public // @testable
 struct ${Self} {
   // "somepseudorandomlygeneratedbytes"
+  @_versioned
   internal var v0: UInt64 = 0x736f6d6570736575
+
+  @_versioned
   internal var v1: UInt64 = 0x646f72616e646f6d
+
+  @_versioned
   internal var v2: UInt64 = 0x6c7967656e657261
+
+  @_versioned
   internal var v3: UInt64 = 0x7465646279746573
 
+  @_versioned
   internal var hashedByteCount: UInt64 = 0
 
+  @_versioned
   internal var dataTail: UInt64 = 0
+
+  @_versioned
   internal var dataTailByteCount: Int = 0
 
+  @_versioned
   internal var finalizedHash: UInt64?
 
   public init(key: (UInt64, UInt64)) {
@@ -113,6 +130,7 @@
   }
 
   // FIXME(ABI)#63 (UnsafeRawBufferPointer): Use UnsafeRawBufferPointer.
+  @_versioned
   @inline(__always)
   internal mutating func _append_alwaysInline(
     _ data: UnsafeRawPointer,
@@ -165,6 +183,7 @@
 
   /// This function mixes in the given word directly into the state,
   /// ignoring `dataTail`.
+  @_versioned
   @inline(__always)
   internal mutating func _appendDirectly(_ m: UInt64) {
     v3 ^= m
@@ -188,6 +207,7 @@
     return _finalizeAndReturnHash_alwaysInline()
   }
 
+  @_versioned
   @inline(__always)
   internal mutating func _finalizeAndReturnHash_alwaysInline() -> UInt64 {
     if let finalizedHash = finalizedHash {
@@ -238,6 +258,7 @@
   }
 
   // FIXME(ABI)#65 (UnsafeRawBufferPointer): Use UnsafeRawBufferPointer.
+  @_versioned
   @inline(__always)
   public // @testable
   static func _hash_alwaysInline(
diff --git a/stdlib/public/core/SliceBuffer.swift b/stdlib/public/core/SliceBuffer.swift
index 1c15abc..c369cb5c 100644
--- a/stdlib/public/core/SliceBuffer.swift
+++ b/stdlib/public/core/SliceBuffer.swift
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 /// Buffer type for `ArraySlice<Element>`.
+@_versioned
 internal struct _SliceBuffer<Element>
   : _ArrayBufferProtocol,
     RandomAccessCollection
@@ -121,6 +122,7 @@
   internal var owner: AnyObject
   internal let subscriptBaseAddress: UnsafeMutablePointer<Element>
 
+  @_versioned
   internal var firstElementAddress: UnsafeMutablePointer<Element> {
     return subscriptBaseAddress + startIndex
   }
diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp
index 4ac9ad9..4219a03 100644
--- a/stdlib/public/runtime/ProtocolConformance.cpp
+++ b/stdlib/public/runtime/ProtocolConformance.cpp
@@ -637,15 +637,11 @@
           C.cacheFailure(metadata, P);
         }
 
-      // If the record provides a nondependent witness table for all instances
-      // of a generic type, cache it for the generic pattern.
       // TODO: "Nondependent witness table" probably deserves its own flag.
       // An accessor function might still be necessary even if the witness table
       // can be shared.
       } else if (record.getTypeKind()
-                   == TypeMetadataRecordKind::UniqueNominalTypeDescriptor
-                 && record.getConformanceKind()
-                   == ProtocolConformanceReferenceKind::WitnessTable) {
+                   == TypeMetadataRecordKind::UniqueNominalTypeDescriptor) {
 
         auto R = record.getNominalTypeDescriptor();
         auto P = record.getProtocol();
@@ -658,7 +654,20 @@
           continue;
 
         // Store the type-protocol pair in the cache.
-        C.cacheSuccess(R, P, record.getStaticWitnessTable());
+        switch (record.getConformanceKind()) {
+        case ProtocolConformanceReferenceKind::WitnessTable:
+          // If the record provides a nondependent witness table for all
+          // instances of a generic type, cache it for the generic pattern.
+          C.cacheSuccess(R, P, record.getStaticWitnessTable());
+          break;
+
+        case ProtocolConformanceReferenceKind::WitnessTableAccessor:
+          // If the record provides a dependent witness table accessor,
+          // cache the result for the instantiated type metadata.
+          C.cacheSuccess(type, P, record.getWitnessTable(type));
+          break;
+
+        }
       }
     }
   }
diff --git a/test/DebugInfo/linetable-cleanups.swift b/test/DebugInfo/linetable-cleanups.swift
index a8c60cd..27399b4 100644
--- a/test/DebugInfo/linetable-cleanups.swift
+++ b/test/DebugInfo/linetable-cleanups.swift
@@ -1,5 +1,8 @@
 // RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 func markUsed<T>(_ t: T) {}
 
 class Person {
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index c917193..8cebaf4 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
-// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -O %s
+// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -enable-class-resilience %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
+// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -enable-class-resilience -O %s
 
 // CHECK: %swift.type = type { [[INT:i32|i64]] }
 
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index ce70ef3..7650913 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -239,4 +239,17 @@
 // CHECK-NEXT: [[RESULT:%.*]] = phi %swift.type* [ [[METADATA]], %entry ], [ [[METADATA2]], %cacheIsNull ]
 // CHECK-NEXT: ret %swift.type* [[RESULT]]
 
+// Methods inside extensions of resilient enums fish out type parameters
+// from metadata -- make sure we can do that
+extension ResilientMultiPayloadGenericEnum {
+
+// CHECK-LABEL: define{{( protected)?}} %swift.type* @_TFE15enum_resilienceO14resilient_enum32ResilientMultiPayloadGenericEnum16getTypeParameterfT_Mx(%swift.type* %"ResilientMultiPayloadGenericEnum<T>", %swift.opaque* noalias nocapture)
+// CHECK: [[METADATA:%.*]] = bitcast %swift.type* %"ResilientMultiPayloadGenericEnum<T>" to %swift.type**
+// CHECK-NEXT: [[T_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[METADATA]], [[INT]] 3
+// CHECK-NEXT: [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
+  public func getTypeParameter() -> T.Type {
+    return T.self
+  }
+}
+
 // CHECK-LABEL: define{{( protected)?}} private void @initialize_metadata_EnumWithResilientPayload(i8*)
diff --git a/test/IRGen/vector_reduction.swift b/test/IRGen/vector_reduction.swift
index 0da5b4e..ea4b71b 100644
--- a/test/IRGen/vector_reduction.swift
+++ b/test/IRGen/vector_reduction.swift
@@ -2,6 +2,9 @@
 
 // REQUIRES: CPU=x86_64
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 // We were missing target transform info and not vectorizing the loop below.
 
 // CHECK: xor <2 x i64>
diff --git a/test/Inputs/resilient_enum.swift b/test/Inputs/resilient_enum.swift
index 5127b7e..cc39e88 100644
--- a/test/Inputs/resilient_enum.swift
+++ b/test/Inputs/resilient_enum.swift
@@ -185,6 +185,14 @@
   case Y(T)                       // -2
 }
 
+public enum ResilientMultiPayloadGenericEnumFixedSize<T> {
+  case A                          // 0
+  case B                          // 1
+  case C                          // 2
+  case X(Int)                     // -1
+  case Y(Int)                     // -2
+}
+
 public enum ResilientIndirectEnum {
   // 0
   case Base
diff --git a/test/Inputs/resilient_protocol.swift b/test/Inputs/resilient_protocol.swift
index 306dfa3..0df25a5 100644
--- a/test/Inputs/resilient_protocol.swift
+++ b/test/Inputs/resilient_protocol.swift
@@ -15,3 +15,9 @@
     set { x = newValue }
   }
 }
+
+public protocol ResilientBaseProtocol {
+  func requirement() -> Int
+}
+
+public protocol ResilientDerivedProtocol : ResilientBaseProtocol {}
diff --git a/test/Interpreter/enum_resilience.swift b/test/Interpreter/enum_resilience.swift
index 9bbc42f..10b823c 100644
--- a/test/Interpreter/enum_resilience.swift
+++ b/test/Interpreter/enum_resilience.swift
@@ -404,4 +404,25 @@
   expectEqual(b, [0, 1, 2])
 }
 
+// Methods inside extensions of resilient enums fish out type parameters
+// from metadata -- make sure we can do that
+extension ResilientMultiPayloadGenericEnum {
+  public func getTypeParameter() -> T.Type {
+    return T.self
+  }
+}
+
+extension ResilientMultiPayloadGenericEnumFixedSize {
+  public func getTypeParameter() -> T.Type {
+    return T.self
+  }
+}
+
+class Base {}
+
+ResilientEnumTestSuite.test("ResilientEnumExtension") {
+  expectEqual(Base.self, ResilientMultiPayloadGenericEnum<Base>.A.getTypeParameter())
+  expectEqual(Base.self, ResilientMultiPayloadGenericEnumFixedSize<Base>.A.getTypeParameter())
+}
+
 runAllTests()
diff --git a/test/Interpreter/protocol_resilience.swift b/test/Interpreter/protocol_resilience.swift
index 11a470d..909d206 100644
--- a/test/Interpreter/protocol_resilience.swift
+++ b/test/Interpreter/protocol_resilience.swift
@@ -10,9 +10,6 @@
 // requirements with default implementations is actually tested in
 // validation-test/Evolution/test_protocol_*.
 //
-// This test just ensures we can call materializeForSet defined in a
-// protocol extension from a different resilience domain.
-//
 
 import StdlibUnittest
 
@@ -27,6 +24,8 @@
 
 struct OtherConformingType : OtherResilientProtocol { }
 
+// Ensure we can call materializeForSet defined in a protocol extension
+// from a different resilience domain.
 ResilientProtocolTestSuite.test("PropertyInProtocolExtension") {
   var o = OtherConformingType()
 
@@ -36,4 +35,22 @@
   expectEqual(OtherConformingType.staticPropertyInExtension, 12)
 }
 
+struct DerivedConformingType : ResilientDerivedProtocol {
+  func requirement() -> Int { return 42 }
+}
+
+// Ensure dynamic casts to resilient types work.
+func callBaseRequirement(t: ResilientBaseProtocol) -> Int {
+  return t.requirement()
+}
+
+@_semantics("optimize.sil.never")
+func castToDerivedProtocol<T>(t: T) -> Int {
+  return callBaseRequirement(t: t as! ResilientDerivedProtocol)
+}
+
+ResilientProtocolTestSuite.test("DynamicCastToResilientProtocol") {
+  expectEqual(castToDerivedProtocol(t: DerivedConformingType()), 42)
+}
+
 runAllTests()
diff --git a/test/SILGen/unsafe_pointer_gen.swift b/test/SILGen/unsafe_pointer_gen.swift
index 471ac99..7596ae4 100644
--- a/test/SILGen/unsafe_pointer_gen.swift
+++ b/test/SILGen/unsafe_pointer_gen.swift
@@ -1,5 +1,8 @@
 // RUN: %target-swift-frontend -O -emit-sil -parse-as-library %s | %FileCheck %s
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 // Test the absence of a 'strict' flag.
 // CHECK-LABEL: _TF18unsafe_pointer_gen13test_raw_loadFT2rpSV_Si
 // CHECK: pointer_to_address {{%.*}} : $Builtin.RawPointer to $*Int
diff --git a/test/SILOptimizer/DestructorAnalysis.swift b/test/SILOptimizer/DestructorAnalysis.swift
index 60ba39c..a42e0ec 100644
--- a/test/SILOptimizer/DestructorAnalysis.swift
+++ b/test/SILOptimizer/DestructorAnalysis.swift
@@ -3,6 +3,9 @@
 // This test depends on asserts because we look at debug output.
 // REQUIRES: asserts
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 class Foo {}
 
 var a: [Int] = []
diff --git a/test/SILOptimizer/bridged_casts_folding.swift b/test/SILOptimizer/bridged_casts_folding.swift
index 3579915..73abf86 100644
--- a/test/SILOptimizer/bridged_casts_folding.swift
+++ b/test/SILOptimizer/bridged_casts_folding.swift
@@ -2,6 +2,9 @@
 
 // REQUIRES: objc_interop
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 // Check that casts between bridged types are replaced by more 
 // efficient code sequences.
 // 
diff --git a/test/SILOptimizer/cast_folding_no_bridging.sil b/test/SILOptimizer/cast_folding_no_bridging.sil
index effde0f..6326895 100644
--- a/test/SILOptimizer/cast_folding_no_bridging.sil
+++ b/test/SILOptimizer/cast_folding_no_bridging.sil
@@ -1,6 +1,9 @@
 // RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s
 // REQUIRES: objc_interop
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 // We want to check that casts between two types which are both Swift types or
 // both are ObjC types are not optimized by the cast optimizer into casts
 // to/from ObjC.
diff --git a/test/SILOptimizer/prespecialize.swift b/test/SILOptimizer/prespecialize.swift
index b5f416b..60b67fa 100644
--- a/test/SILOptimizer/prespecialize.swift
+++ b/test/SILOptimizer/prespecialize.swift
@@ -2,6 +2,9 @@
 
 // REQUIRES: optimized_stdlib
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 // Check that pre-specialization works at -Onone.
 // This test requires the standard library to be compiled with pre-specializations!
 
diff --git a/test/SILOptimizer/sil_combine_objc.sil b/test/SILOptimizer/sil_combine_objc.sil
index d92af47..4c6d512 100644
--- a/test/SILOptimizer/sil_combine_objc.sil
+++ b/test/SILOptimizer/sil_combine_objc.sil
@@ -1,6 +1,9 @@
 // RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -verify-skip-unreachable-must-be-last | %FileCheck %s
 // REQUIRES: objc_interop
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 sil_stage canonical
 
 import Builtin
diff --git a/test/SILOptimizer/stack_promotion_escaping.swift b/test/SILOptimizer/stack_promotion_escaping.swift
index de9a9e9..2229370 100644
--- a/test/SILOptimizer/stack_promotion_escaping.swift
+++ b/test/SILOptimizer/stack_promotion_escaping.swift
@@ -1,5 +1,8 @@
 // RUN: %target-swift-frontend -parse-as-library -O -module-name=test %s -emit-sil | %FileCheck %s
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 final class Item {}
 
 final public class Escaper {
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index f3f1fa8..8519b0c 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -64,6 +64,9 @@
 if "@SWIFT_OPTIMIZED@" == "TRUE":
     config.available_features.add("optimized_stdlib")
 
+if "@SWIFT_STDLIB_ENABLE_RESILIENCE@" == "TRUE":
+    config.available_features.add("resilient_stdlib")
+
 if "@SWIFT_HAVE_WORKING_STD_REGEX@" == "FALSE":
     config.available_features.add('broken_std_regex')
 
diff --git a/test/stdlib/FloatingPoint.swift.gyb b/test/stdlib/FloatingPoint.swift.gyb
index ebf623a..c3c2172 100644
--- a/test/stdlib/FloatingPoint.swift.gyb
+++ b/test/stdlib/FloatingPoint.swift.gyb
@@ -3,6 +3,9 @@
 // RUN: %line-directive %t/FloatingPoint.swift -- %target-run %t/a.out
 // REQUIRES: executable_test
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 %{
 from gyb_stdlib_unittest_support import TRACE, stackTrace, trace
 }%
diff --git a/validation-test/Reflection/reflect_Character.swift b/validation-test/Reflection/reflect_Character.swift
index 3d16f73..98cb2d4 100644
--- a/validation-test/Reflection/reflect_Character.swift
+++ b/validation-test/Reflection/reflect_Character.swift
@@ -4,6 +4,9 @@
 // REQUIRES: objc_interop
 // REQUIRES: executable_test
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 import SwiftReflectionTest
 
 class TestClass {
diff --git a/validation-test/Reflection/reflect_multiple_types.swift b/validation-test/Reflection/reflect_multiple_types.swift
index 51a51bd..84ae68c 100644
--- a/validation-test/Reflection/reflect_multiple_types.swift
+++ b/validation-test/Reflection/reflect_multiple_types.swift
@@ -4,6 +4,9 @@
 // REQUIRES: objc_interop
 // REQUIRES: executable_test
 
+// FIXME: https://bugs.swift.org/browse/SR-2808
+// XFAIL: resilient_stdlib
+
 import SwiftReflectionTest
 import Foundation
 
diff --git a/validation-test/lit.site.cfg.in b/validation-test/lit.site.cfg.in
index dd6cf9a..904583d 100644
--- a/validation-test/lit.site.cfg.in
+++ b/validation-test/lit.site.cfg.in
@@ -60,6 +60,9 @@
 if "@SWIFT_OPTIMIZED@" == "TRUE":
     config.available_features.add("optimized_stdlib")
 
+if "@SWIFT_STDLIB_ENABLE_RESILIENCE@" == "TRUE":
+    config.available_features.add("resilient_stdlib")
+
 if "@CMAKE_GENERATOR@" == "Xcode":
     xcode_bin_dir = os.path.join(config.llvm_obj_root, "@LLVM_BUILD_TYPE@",
                                  'bin')