Merge pull request #18893 from slavapestov/resilient-class-pattern

Use a true-const pattern to initialize non-generic resilient class metadata
diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h
index bd2fc60..51ed926 100644
--- a/include/swift/ABI/Metadata.h
+++ b/include/swift/ABI/Metadata.h
@@ -3085,7 +3085,7 @@
   }
 };
 
-/// An instantiation pattern for class metadata.
+/// An instantiation pattern for generic class metadata.
 template <typename Runtime>
 struct TargetGenericClassMetadataPattern final :
        TargetGenericMetadataPattern<Runtime>,
@@ -3138,7 +3138,7 @@
 using GenericClassMetadataPattern =
   TargetGenericClassMetadataPattern<InProcess>;
 
-/// An instantiation pattern for value metadata.
+/// An instantiation pattern for generic value metadata.
 template <typename Runtime>
 struct TargetGenericValueMetadataPattern final :
        TargetGenericMetadataPattern<Runtime>,
@@ -3316,10 +3316,43 @@
 using InPlaceValueMetadataCache =
   TargetInPlaceValueMetadataCache<InProcess>;
 
+template <typename Runtime>
+struct TargetResilientClassMetadataPattern;
+
 /// An instantiation pattern for non-generic resilient class metadata.
 /// Used in conjunction with InPlaceValueMetadataInitialization.
 using MetadataRelocator =
-  Metadata *(const TargetTypeContextDescriptor<InProcess> *description);
+  Metadata *(const TargetTypeContextDescriptor<InProcess> *type,
+             const TargetResilientClassMetadataPattern<InProcess> *pattern);
+
+/// An instantiation pattern for non-generic resilient class metadata.
+template <typename Runtime>
+struct TargetResilientClassMetadataPattern {
+  /// If the class descriptor's hasResilientSuperclass() flag is set,
+  /// this field instead points at a function that allocates metadata
+  /// with the correct size at runtime.
+  TargetRelativeDirectPointer<Runtime, MetadataRelocator> RelocationFunction;
+
+  /// The heap-destructor function.
+  TargetRelativeDirectPointer<Runtime, HeapObjectDestroyer> Destroy;
+
+  /// The ivar-destructor function.
+  TargetRelativeDirectPointer<Runtime, ClassIVarDestroyer> IVarDestroyer;
+
+  /// The class flags.
+  ClassFlags Flags;
+
+  // The following fields are only present in ObjC interop.
+
+  /// Our ClassROData.
+  TargetRelativeDirectPointer<Runtime, void> Data;
+
+  /// Our metaclass.
+  TargetRelativeDirectPointer<Runtime, TargetAnyClassMetadata<Runtime>> Metaclass;
+};
+
+using ResilientClassMetadataPattern =
+  TargetResilientClassMetadataPattern<InProcess>;
 
 /// The control structure for performing non-trivial initialization of
 /// singleton value metadata, which is required when e.g. a non-generic
@@ -3340,8 +3373,8 @@
     /// If the class descriptor's hasResilientSuperclass() flag is set,
     /// this field instead points at a function that allocates metadata
     /// with the correct size at runtime.
-    TargetRelativeDirectPointer<Runtime, MetadataRelocator>
-      RelocationFunction;
+    TargetRelativeDirectPointer<Runtime, TargetResilientClassMetadataPattern<Runtime>>
+      ResilientPattern;
   };
 
   /// The completion function.  The pattern will always be null.
@@ -3358,8 +3391,10 @@
 
   TargetMetadata<Runtime> *allocate(
       const TargetTypeContextDescriptor<Runtime> *description) const {
-    if (hasRelocationFunction(description))
-      return RelocationFunction(description);
+    if (hasRelocationFunction(description)) {
+      return ResilientPattern->RelocationFunction(description,
+                                                  ResilientPattern.get());
+    }
     return IncompleteMetadata.get();
   }
 };
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index 177ef2f..13580c3 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -574,15 +574,13 @@
                               const TypeLayout * const *fieldTypes,
                               uint32_t *fieldOffsets);
 
-/// Relocate the metadata for a class and copy fields from the given template.
-/// The final size of the metadata is calculated at runtime from the size of
-/// the superclass metadata together with the given number of immediate
-/// members.
+/// Allocate the metadata for a class and copy fields from the given pattern.
+/// The final size of the metadata is calculated at runtime from the metadata
+/// bounds in the class descriptor.
 SWIFT_RUNTIME_EXPORT
 ClassMetadata *
 swift_relocateClassMetadata(ClassDescriptor *descriptor,
-                            ClassMetadata *pattern,
-                            size_t patternSize);
+                            ResilientClassMetadataPattern *pattern);
 
 /// Initialize the field offset vector for a dependent-layout class, using the
 /// "Universal" layout strategy.
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index 70dcc95..b9db24ba 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -670,19 +670,19 @@
 
 // Metadata *swift_allocateGenericClassMetadata(ClassDescriptor *type,
 //                                              const void * const *arguments,
-//                                              const void * const *template);
+//                                              const void *template);
 FUNCTION(AllocateGenericClassMetadata, swift_allocateGenericClassMetadata,
          C_CC, RETURNS(TypeMetadataPtrTy),
-         ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrPtrTy),
+         ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrTy),
          ATTRS(NoUnwind))
 
 // Metadata *swift_allocateGenericValueMetadata(ValueTypeDescriptor *type,
 //                                              const void * const *arguments,
-//                                              const void * const *template,
+//                                              const void *template,
 //                                              size_t extraSize);
 FUNCTION(AllocateGenericValueMetadata, swift_allocateGenericValueMetadata,
          C_CC, RETURNS(TypeMetadataPtrTy),
-         ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrPtrTy, SizeTy),
+         ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrTy, SizeTy),
          ATTRS(NoUnwind))
 
 // MetadataResponse swift_checkMetadataState(MetadataRequest request,
@@ -809,12 +809,11 @@
          ATTRS(NoUnwind, ReadOnly))
 
 // Metadata *swift_relocateClassMetadata(TypeContextDescriptor *descriptor,
-//                                       Metadata *pattern,
-//                                       size_t patternSize);
+//                                       const void *pattern);
 FUNCTION(RelocateClassMetadata,
          swift_relocateClassMetadata, C_CC,
          RETURNS(TypeMetadataPtrTy),
-         ARGS(TypeContextDescriptorPtrTy, TypeMetadataPtrTy, SizeTy),
+         ARGS(TypeContextDescriptorPtrTy, Int8PtrTy),
          ATTRS(NoUnwind))
 
 // struct FieldInfo { size_t Size; size_t AlignMask; };
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 8d620e9..efcff0d 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -3282,8 +3282,9 @@
   assert(init);
 
   if (isPattern) {
+    assert(isConstant && "Type metadata patterns must be constant");
     auto addr = getAddrOfTypeMetadataPattern(concreteType->getAnyNominal(),
-                                             isConstant, init, section);
+                                             init, section);
 
     return cast<llvm::GlobalValue>(addr);
   }
@@ -3488,12 +3489,11 @@
 
 llvm::Constant *
 IRGenModule::getAddrOfTypeMetadataPattern(NominalTypeDecl *D) {
-  return getAddrOfTypeMetadataPattern(D, false, ConstantInit(), "");
+  return getAddrOfTypeMetadataPattern(D, ConstantInit(), "");
 }
 
 llvm::Constant *
 IRGenModule::getAddrOfTypeMetadataPattern(NominalTypeDecl *D,
-                                          bool isConstant,
                                           ConstantInit init,
                                           StringRef section) {
   if (!init)
@@ -3502,7 +3502,7 @@
   auto alignment = getPointerAlignment();
   LinkEntity entity = LinkEntity::forTypeMetadataPattern(D);
   auto addr = getAddrOfLLVMVariable(entity, alignment, init,
-                                   Int8PtrTy, DebugTypeInfo());
+                                   Int8Ty, DebugTypeInfo());
 
   if (init) {
     auto var = cast<llvm::GlobalVariable>(addr);
@@ -3565,7 +3565,7 @@
       /// Generic arguments.
       Int8PtrPtrTy,
       /// Generic metadata pattern.
-      Int8PtrPtrTy
+      Int8PtrTy
     };
 
     fnType = llvm::FunctionType::get(TypeMetadataPtrTy, argTys,
@@ -3577,6 +3577,8 @@
     llvm::Type *argTys[] = {
       /// Type descriptor.
       TypeContextDescriptorPtrTy,
+      /// Resilient metadata pattern.
+      Int8PtrTy
     };
 
     fnType = llvm::FunctionType::get(TypeMetadataPtrTy, argTys,
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index c290299..8c21133 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -1245,10 +1245,8 @@
         return;
       }
 
-      llvm::Function *relocationFunction =
-        IGM.getAddrOfTypeMetadataInstantiationFunction(getType(),
-                                                       NotForDefinition);
-      B.addRelativeAddress(relocationFunction);
+      auto *pattern = IGM.getAddrOfTypeMetadataPattern(Type);
+      B.addRelativeAddress(pattern);
     }
 
     ContextDescriptorKind getContextKind() {
@@ -1617,11 +1615,11 @@
                   IGF.IGM.getPointerSize() * storedProperties.size());
 }
 
-static void emitInitializeMetadata(IRGenFunction &IGF,
-                                   NominalTypeDecl *nominalDecl,
-                                   llvm::Value *metadata,
-                                   bool isVWTMutable,
-                                   MetadataDependencyCollector *collector) {
+static void emitInitializeValueMetadata(IRGenFunction &IGF,
+                                        NominalTypeDecl *nominalDecl,
+                                        llvm::Value *metadata,
+                                        bool isVWTMutable,
+                                        MetadataDependencyCollector *collector) {
   auto loweredTy =
     IGF.IGM.getLoweredType(nominalDecl->getDeclaredTypeInContext());
 
@@ -1992,7 +1990,8 @@
                                 llvm::Value *metadata,
                                 bool isVWTMutable,
                                 MetadataDependencyCollector *collector) {
-      ::emitInitializeMetadata(IGF, Target, metadata, isVWTMutable, collector);
+      emitInitializeValueMetadata(IGF, Target, metadata,
+                                  isVWTMutable, collector);
     }
   };
 } // end anonymous namespace
@@ -2019,6 +2018,23 @@
   });
 }
 
+/// Create an access function for the given non-generic type.
+static void createNonGenericMetadataAccessFunction(IRGenModule &IGM,
+                                                   NominalTypeDecl *typeDecl) {
+  assert(!typeDecl->isGenericContext());
+  auto type = typeDecl->getDeclaredType()->getCanonicalType();
+
+  // If the type requires the in-place initialization pattern, use it.
+  if (needsInPlaceMetadataInitialization(IGM, typeDecl)) {
+    createInPlaceInitializationMetadataAccessFunction(IGM, typeDecl, type);
+    return;
+  }
+
+  // Otherwise, use the lazy pattern, which should be emitted using a
+  // direct reference to the metadata.
+  createDirectTypeMetadataAccessFunction(IGM, type, /*allow existing*/ false);
+}
+
 // Classes
 
 /// Emit the base-offset variable for the class.
@@ -2169,13 +2185,7 @@
     }
 
     void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {
-      for (unsigned i = 0,
-                    e = placeholder->getNumberOfFieldOffsetVectorEntries();
-           i < e; ++i) {
-        // Emit placeholder values for some number of stored properties we
-        // know exist but aren't able to reference directly.
-        B.addInt(IGM.SizeTy, 0);
-      }
+      llvm_unreachable("Fixed class metadata cannot have missing members");
     }
 
     void addMethod(SILDeclRef fn) {
@@ -2261,26 +2271,6 @@
     }
   };
 
-  /// Utility class for building member metadata for classes with resilient
-  /// ancestry. The total size of the class metadata is not known at compile
-  /// time, and requires relocation.
-  class ResilientClassMemberBuilder {
-  public:
-    ResilientClassMemberBuilder(IRGenModule &IGM,
-                                ConstantStructBuilder &builder,
-                                SILVTable *vtable) {}
-
-    void addFieldOffset(VarDecl *var) {}
-
-    void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {}
-
-    void addMethod(SILDeclRef fn) {}
-
-    void addGenericArgument(ClassDecl *forClass) {}
-
-    void addGenericWitnessTable(ClassDecl *forClass) {}
-  };
-
   /// Base class for layout of non-generic class metadata.
   template<class Impl, class MemberBuilder>
   class ClassMetadataBuilderBase : public ClassMetadataVisitor<Impl> {
@@ -2319,11 +2309,7 @@
 
     void noteResilientSuperclass() {}
 
-    void noteStartOfImmediateMembers(ClassDecl *theClass) {
-      if (theClass == Target) {
-        emitClassMetadataBaseOffset(IGM, theClass);
-      }
-    }
+    void noteStartOfImmediateMembers(ClassDecl *theClass) {}
 
     /// The 'metadata flags' field in a class is actually a pointer to
     /// the metaclass object for the class.
@@ -2529,17 +2515,11 @@
 
     void createMetadataAccessFunction() {
       assert(!Target->isGenericContext());
-      auto type =cast<ClassType>(Target->getDeclaredType()->getCanonicalType());
+      emitClassMetadataBaseOffset(IGM, Target);
+      createNonGenericMetadataAccessFunction(IGM, Target);
 
-      // Fixed case.
-      if (!doesClassMetadataRequireInitialization(IGM, Target)) {
-        (void) createDirectTypeMetadataAccessFunction(IGM, type,
-                                                      /*allowExisting*/ false);
+      if (!doesClassMetadataRequireInitialization(IGM, Target))
         return;
-      }
-
-      // Otherwise, we have to initialize metadata at runtime.
-      createInPlaceInitializationMetadataAccessFunction(IGM, Target, type);
 
       emitMetadataCompletionFunction(
           IGM, Target,
@@ -2548,45 +2528,6 @@
         emitInitializeClassMetadata(IGF, Target, FieldLayout, metadata,
                                     collector);
       });
-
-      // If the class has resilient ancestry we also need a relocation
-      // function.
-      if (doesClassMetadataRequireRelocation(IGM, Target))
-        emitRelocationFunction();
-    }
-
-  private:
-    /// Emit the create function for a class with resilient ancestry.
-    void emitRelocationFunction() {
-      // using MetadataRelocator =
-      //   Metadata *(TypeContextDescriptor *type,
-      //              Metadata *metadata);
-      llvm::Function *f =
-        IGM.getAddrOfTypeMetadataInstantiationFunction(Target, ForDefinition);
-      f->setAttributes(IGM.constructInitialAttributes());
-
-      IRGenFunction IGF(IGM, f);
-
-      // Skip instrumentation when building for TSan to avoid false positives.
-      // The synchronization for this happens in the Runtime and we do not see it.
-      if (IGM.IRGen.Opts.Sanitizers & SanitizerKind::Thread)
-        f->removeFnAttr(llvm::Attribute::SanitizeThread);
-
-      if (IGM.DebugInfo)
-        IGM.DebugInfo->emitArtificialFunction(IGF, f);
-
-      Explosion params = IGF.collectParameters();
-      llvm::Value *descriptor = params.claimNext();
-
-      llvm::Value *metadata = IGF.IGM.getAddrOfTypeMetadata(
-        Target->getDeclaredType()->getCanonicalType());
-
-      // Relocate the metadata.
-      auto patternSize = IGM.getSize(Size(B.getNextOffsetFromGlobal()));
-      metadata = IGF.Builder.CreateCall(IGF.IGM.getRelocateClassMetadataFn(),
-                                        {descriptor, metadata, patternSize});
-
-      IGF.Builder.CreateRet(metadata);
     }
   };
 
@@ -2620,18 +2561,120 @@
       : super(IGM, theClass, builder, fieldLayout) {}
   };
 
-  /// A builder for non-generic class metadata with resilient ancestry.
-  class ResilientClassMetadataBuilder :
-      public ClassMetadataBuilderBase<ResilientClassMetadataBuilder,
-                                      ResilientClassMemberBuilder> {
-    using super = ClassMetadataBuilderBase<ResilientClassMetadataBuilder,
-                                           ResilientClassMemberBuilder>;
+  /// A builder for metadata patterns for non-generic class with
+  /// resilient ancestry.
+  class ResilientClassMetadataBuilder {
+    IRGenModule &IGM;
+    ClassDecl *Target;
+    ConstantStructBuilder &B;
+    const ClassLayout &FieldLayout;
 
   public:
     ResilientClassMetadataBuilder(IRGenModule &IGM, ClassDecl *theClass,
                                   ConstantStructBuilder &builder,
                                   const ClassLayout &fieldLayout)
-      : super(IGM, theClass, builder, fieldLayout) {}
+      : IGM(IGM), Target(theClass), B(builder), FieldLayout(fieldLayout) {}
+
+    llvm::Constant *emitNominalTypeDescriptor() {
+      return ClassContextDescriptorBuilder(IGM, Target, RequireMetadata).emit();
+    }
+
+    void layout() {
+      emitNominalTypeDescriptor();
+
+      addRelocationFunction();
+      addDestructorFunction();
+      addIVarDestroyer();
+      addClassFlags();
+      addClassDataPointer();
+      addMetaclass();
+    }
+
+    void addRelocationFunction() {
+      auto function = IGM.getAddrOfTypeMetadataInstantiationFunction(
+        Target, NotForDefinition);
+      B.addRelativeAddress(function);
+    }
+
+    void addDestructorFunction() {
+      auto function = getAddrOfDestructorFunction(IGM, Target);
+      B.addRelativeAddressOrNull(function ? *function : nullptr);
+    }
+
+    void addIVarDestroyer() {
+      auto function = IGM.getAddrOfIVarInitDestroy(Target,
+                                                   /*isDestroyer=*/ true,
+                                                   /*isForeign=*/ false,
+                                                   NotForDefinition);
+      B.addRelativeAddressOrNull(function ? *function : nullptr);
+    }
+
+    void addClassFlags() {
+      B.addInt32((uint32_t) getClassFlags(Target));
+    }
+
+    void addClassDataPointer() {
+      auto data = (IGM.ObjCInterop
+                   ? emitClassPrivateData(IGM, Target)
+                   : nullptr);
+      B.addRelativeAddressOrNull(data);
+    }
+
+    void addMetaclass() {
+      auto metaclass = (IGM.ObjCInterop
+                        ? IGM.getAddrOfMetaclassObject(Target, NotForDefinition)
+                        : nullptr);
+      B.addRelativeAddressOrNull(metaclass);
+    }
+
+    void createMetadataAccessFunction() {
+      assert(doesClassMetadataRequireRelocation(IGM, Target));
+
+      assert(!Target->isGenericContext());
+      emitClassMetadataBaseOffset(IGM, Target);
+      createNonGenericMetadataAccessFunction(IGM, Target);
+
+      emitMetadataCompletionFunction(
+          IGM, Target,
+          [&](IRGenFunction &IGF, llvm::Value *metadata,
+              MetadataDependencyCollector *collector) {
+        emitInitializeClassMetadata(IGF, Target, FieldLayout, metadata,
+                                    collector);
+      });
+
+      emitRelocationFunction();
+    }
+
+  private:
+    /// Emit the create function for a class with resilient ancestry.
+    void emitRelocationFunction() {
+      // using MetadataRelocator =
+      //   Metadata *(TypeContextDescriptor *type, void *pattern);
+      llvm::Function *f =
+        IGM.getAddrOfTypeMetadataInstantiationFunction(Target, ForDefinition);
+      f->setAttributes(IGM.constructInitialAttributes());
+
+      IRGenFunction IGF(IGM, f);
+
+      // Skip instrumentation when building for TSan to avoid false positives.
+      // The synchronization for this happens in the Runtime and we do not see it.
+      if (IGM.IRGen.Opts.Sanitizers & SanitizerKind::Thread)
+        f->removeFnAttr(llvm::Attribute::SanitizeThread);
+
+      if (IGM.DebugInfo)
+        IGM.DebugInfo->emitArtificialFunction(IGF, f);
+
+      Explosion params = IGF.collectParameters();
+      llvm::Value *descriptor = params.claimNext();
+      llvm::Value *pattern = params.claimNext();
+
+      // Allocate class metadata using the pattern we emitted.
+      llvm::Value *metadata =
+        IGF.Builder.CreateCall(IGF.IGM.getRelocateClassMetadataFn(),
+                               {descriptor, pattern});
+
+      IGF.Builder.CreateRet(metadata);
+    }
   };
 
   /// A builder for GenericClassMetadataPattern objects.
@@ -2803,7 +2846,8 @@
                                 bool isVWTMutable,
                                 MetadataDependencyCollector *collector) {
       assert(!HasDependentVWT && "class should never have dependent VWT");
-      emitInitializeClassMetadata(IGF, Target, FieldLayout, metadata, collector);
+      emitInitializeClassMetadata(IGF, Target, FieldLayout,
+                                  metadata, collector);
     }
   };
 } // end anonymous namespace
@@ -2846,20 +2890,23 @@
   auto init = builder.beginStruct();
   init.setPacked(true);
 
-  bool isGeneric = classDecl->isGenericContext();
+  // If the class is generic or has resilient ancestry, we emit a pattern,
+  // not type metadata.
+  bool isPattern = doesClassMetadataRequireRelocation(IGM, classDecl);
+
   bool canBeConstant;
   if (classDecl->isGenericContext()) {
     GenericClassMetadataBuilder builder(IGM, classDecl, init,
                                         fieldLayout);
     builder.layout();
-    canBeConstant = false;
+    canBeConstant = true;
 
     builder.createMetadataAccessFunction();
   } else if (doesClassMetadataRequireRelocation(IGM, classDecl)) {
     ResilientClassMetadataBuilder builder(IGM, classDecl, init,
                                           fieldLayout);
     builder.layout();
-    canBeConstant = builder.canBeConstant();
+    canBeConstant = true;
 
     builder.createMetadataAccessFunction();
   } else if (doesClassMetadataRequireInitialization(IGM, classDecl)) {
@@ -2885,14 +2932,14 @@
       IGM.TargetInfo.OutputObjectFormat == llvm::Triple::MachO)
     section = "__DATA,__objc_data, regular";
 
-  auto var = IGM.defineTypeMetadata(declaredType, isGeneric, canBeConstant,
+  auto var = IGM.defineTypeMetadata(declaredType, isPattern, canBeConstant,
                                     init.finishAndCreateFuture(), section);
 
   // Add classes that don't require dynamic initialization to the
   // ObjC class list.
   //
   // FIXME: This is where we check the completely fragile layout.
-  if (IGM.ObjCInterop && !isGeneric &&
+  if (IGM.ObjCInterop && !isPattern &&
       !doesClassMetadataRequireInitialization(IGM, classDecl)) {
     // Emit the ObjC class symbol to make the class visible to ObjC.
     if (classDecl->isObjC()) {
@@ -3021,30 +3068,13 @@
       emitMetadataCompletionFunction(IGM, Target,
         [&](IRGenFunction &IGF, llvm::Value *metadata,
             MetadataDependencyCollector *collector) {
-        emitInitializeMetadata(IGF, Target, metadata, /*vwt mutable*/true,
-                               collector);
+        emitInitializeValueMetadata(IGF, Target, metadata,
+                                    /*vwt mutable*/true, collector);
       });
     }
   };
 }
 
-/// Create an access function for the given non-generic type.
-static void createNonGenericMetadataAccessFunction(IRGenModule &IGM,
-                                                   NominalTypeDecl *typeDecl) {
-  assert(!typeDecl->isGenericContext());
-  auto type = typeDecl->getDeclaredType()->getCanonicalType();
-
-  // If the type requires the in-place initialization pattern, use it.
-  if (needsInPlaceMetadataInitialization(IGM, typeDecl)) {
-    createInPlaceInitializationMetadataAccessFunction(IGM, typeDecl, type);
-    return;
-  }
-
-  // Otherwise, use the lazy pattern, which should be emitted using a
-  // direct reference to the metadata.
-  createDirectTypeMetadataAccessFunction(IGM, type, /*allow existing*/ false);
-}
-
 
 //===----------------------------------------------------------------------===//
 // Structs
@@ -3270,7 +3300,7 @@
     GenericStructMetadataBuilder builder(IGM, structDecl, init);
     builder.layout();
     isPattern = true;
-    canBeConstant = false;
+    canBeConstant = true;
 
     builder.createMetadataAccessFunction();
   } else {
@@ -3465,7 +3495,7 @@
     GenericEnumMetadataBuilder builder(IGM, theEnum, init);
     builder.layout();
     isPattern = true;
-    canBeConstant = false;
+    canBeConstant = true;
 
     builder.createMetadataAccessFunction();
   } else {
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 336a432..e813024 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -1168,7 +1168,6 @@
                                           SymbolReferenceKind kind);
   llvm::Constant *getAddrOfTypeMetadataPattern(NominalTypeDecl *D);
   llvm::Constant *getAddrOfTypeMetadataPattern(NominalTypeDecl *D,
-                                               bool isConstant,
                                                ConstantInit init,
                                                StringRef section);
   llvm::Function *getAddrOfTypeMetadataCompletionFunction(NominalTypeDecl *D,
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index b2f0d1a..e90b75a 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -350,7 +350,7 @@
   // Initialize the header:
 
   // Heap destructor.
-  fullMetadata->destroy = pattern->Destroy;
+  fullMetadata->destroy = pattern->Destroy.get();
 
   // Value witness table.
 #if SWIFT_OBJC_INTEROP
@@ -2121,29 +2121,83 @@
 
 ClassMetadata *
 swift::swift_relocateClassMetadata(ClassDescriptor *description,
-                                   ClassMetadata *pattern,
-                                   size_t patternSize) {
+                                   ResilientClassMetadataPattern *pattern) {
   auto bounds = description->getMetadataBounds();
-  auto metadataSize = bounds.getTotalSizeInBytes();
 
-  if (patternSize < metadataSize) {
-    auto bytes = (char*) malloc(metadataSize);
+  auto metadata = reinterpret_cast<ClassMetadata *>(
+      (char*) malloc(bounds.getTotalSizeInBytes()) +
+      bounds.getAddressPointInBytes());
+  auto fullMetadata = asFullMetadata(metadata);
+  char *rawMetadata = reinterpret_cast<char*>(metadata);
 
-    auto fullPattern = (const char*) pattern;
-    fullPattern -= pattern->getClassAddressPoint();
-    memcpy(bytes, fullPattern, patternSize);
-    memset(bytes + patternSize, 0,
-           metadataSize - patternSize);
+  // Zero out the entire immediate-members section.
+  void **immediateMembers =
+    reinterpret_cast<void**>(rawMetadata + bounds.ImmediateMembersOffset);
+  memset(immediateMembers, 0, description->getImmediateMembersSize());
 
-    auto addressPoint = bytes + bounds.getAddressPointInBytes();
-    auto metadata = reinterpret_cast<ClassMetadata *>(addressPoint);
+  // Initialize the header:
 
-    metadata->setClassSize(metadataSize);
-    assert(metadata->isTypeMetadata());
-    return metadata;
-  }
+  // Heap destructor.
+  fullMetadata->destroy = pattern->Destroy.get();
 
-  return pattern;
+  // Value witness table.
+#if SWIFT_OBJC_INTEROP
+  fullMetadata->ValueWitnesses =
+    (pattern->Flags & ClassFlags::UsesSwiftRefcounting)
+       ? &VALUE_WITNESS_SYM(Bo)
+       : &VALUE_WITNESS_SYM(BO);
+#else
+  fullMetadata->ValueWitnesses = &VALUE_WITNESS_SYM(Bo);
+#endif
+
+  // MetadataKind / isa.
+#if SWIFT_OBJC_INTEROP
+  metadata->setClassISA(pattern->Metaclass.get());
+#else
+  metadata->setKind(MetadataKind::Class);
+#endif
+
+  // Superclass.
+  metadata->Superclass = nullptr;
+
+#if SWIFT_OBJC_INTEROP
+  // Cache data.  Install the same initializer that the compiler is
+  // required to use.  We don't need to do this in non-ObjC-interop modes.
+  metadata->CacheData[0] = &_objc_empty_cache;
+  metadata->CacheData[1] = nullptr;
+#endif
+
+  // RO-data pointer.
+#if SWIFT_OBJC_INTEROP
+  auto classRO = pattern->Data.get();
+  metadata->Data =
+    reinterpret_cast<uintptr_t>(classRO) | SWIFT_CLASS_IS_SWIFT_MASK;
+#else
+  metadata->Data = SWIFT_CLASS_IS_SWIFT_MASK;
+#endif
+
+  // Class flags.
+  metadata->Flags = pattern->Flags;
+
+  // Instance layout.
+  metadata->InstanceAddressPoint = 0;
+  metadata->InstanceSize = 0;
+  metadata->InstanceAlignMask = 0;
+
+  // Reserved.
+  metadata->Reserved = 0;
+
+  // Class metadata layout.
+  metadata->ClassSize = bounds.getTotalSizeInBytes();
+  metadata->ClassAddressPoint = bounds.getAddressPointInBytes();
+
+  // Class descriptor.
+  metadata->setDescription(description);
+
+  // I-var destroyer.
+  metadata->IVarDestroyer = pattern->IVarDestroyer;
+
+  return metadata;
 }
 
 /// Initialize the field offset vector for a dependent-layout class, using the
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index dcc0a26f..04d693a 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -3,7 +3,7 @@
 // RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
 // RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
 // RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift
-// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience %t/class_resilience.swift | %FileCheck %t/class_resilience.swift --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience %t/class_resilience.swift | %FileCheck %t/class_resilience.swift --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-runtime -DINT=i%target-ptrsize
 // RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience -O %t/class_resilience.swift
 
 // CHECK: @"$S16class_resilience26ClassWithResilientPropertyC1s16resilient_struct4SizeVvpWvd" = hidden global [[INT]] 0
@@ -33,14 +33,50 @@
 // CHECK: @"$S16class_resilience14ResilientChildCMn" = {{(protected )?}}{{(dllexport )?}}constant <{{.*}}> <{
 // --       flags: class, unique, has vtable, in-place initialization, has resilient superclass
 // CHECK-SAME:   <i32 0xC401_0050>
+// --       parent:
+// CHECK-SAME:   @"$S16class_resilienceMXM"
 // --       name:
 // CHECK-SAME:   [15 x i8]* [[RESILIENTCHILD_NAME]]
-// --       num fields
+// --       metadata accessor function:
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCMa"
+// --       field descriptor:
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCMF"
+// -- superclass:
+// CHECK-SAME:   @"got.$S15resilient_class22ResilientOutsideParentCMn"
+// -- metadata bounds:
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCMo"
+// --       metadata positive size in words (not used):
+// CHECK-SAME:   i32 0,
+// --       num immediate members:
+// CHECK-SAME:   i32 4,
+// --       num fields:
 // CHECK-SAME:   i32 1,
-// --       field offset vector offset
+// --       field offset vector offset:
 // CHECK-SAME:   i32 3,
+// --       singleton metadata initialization cache:
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCMl"
+// --       resilient pattern:
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCMP"
+// --       completion function:
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCMr"
 // CHECK-SAME: }>
 
+// CHECK: @"$S16class_resilience14ResilientChildCMP" = internal constant <{{.*}}> <{
+// --       instantiation function:
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCMi"
+// --       destructor:
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCfD"
+// --       ivar destroyer:
+// CHECK-SAME:   i32 0,
+// --       flags:
+// CHECK-SAME:   i32 3,
+// --       RO data:
+// CHECK-objc-SAME: @_DATA__TtC16class_resilience14ResilientChild
+// CHECK-native-SAME: i32 0,
+// --       metaclass:
+// CHECK-objc-SAME: @"$S16class_resilience14ResilientChildCMm"
+// CHECK-native-SAME: i32 0
+
 // CHECK: @"$S16class_resilience16FixedLayoutChildCMo" = {{(protected )?}}{{(dllexport )?}}global [[BOUNDS]] zeroinitializer
 
 // CHECK: @"$S16class_resilience17MyResilientParentCMo" = {{(protected )?}}{{(dllexport )?}}constant [[BOUNDS]]
@@ -361,10 +397,10 @@
 // CHECK:      void @swift_initClassMetadata(%swift.type* %0, %swift.type* null, [[INT]] 256, [[INT]] 3, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]])
 
 // CHECK-native:      [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}}
-// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience26ClassWithResilientPropertyC1s16resilient_struct4SizeVvWvd"
+// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience26ClassWithResilientPropertyC1s16resilient_struct4SizeVvpWvd"
 
 // CHECK-native:      [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}}
-// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience26ClassWithResilientPropertyC5colors5Int32VvWvd"
+// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience26ClassWithResilientPropertyC5colors5Int32VvpWvd"
 
 // CHECK: br label %metadata-dependencies.cont
 
@@ -400,10 +436,10 @@
 // CHECK:      call void @swift_initClassMetadata(%swift.type* %0, %swift.type* null, [[INT]] 256, [[INT]] 2, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]])
 
 // CHECK-native:      [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}}
-// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience33ClassWithResilientlySizedPropertyC1r16resilient_struct9RectangleVvWvd"
+// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience33ClassWithResilientlySizedPropertyC1r16resilient_struct9RectangleVvpWvd"
 
 // CHECK-native:      [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}}
-// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience33ClassWithResilientlySizedPropertyC5colors5Int32VvWvd"
+// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$S16class_resilience33ClassWithResilientlySizedPropertyC5colors5Int32VvpWvd"
 
 // CHECK: br label %metadata-dependencies.cont
 
@@ -416,14 +452,6 @@
 // CHECK-NEXT: ret %swift.metadata_response [[T1]]
 
 
-// ResilientChild metadata relocation function
-
-// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience14ResilientChildCMi"(%swift.type_descriptor*)
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, %swift.type* bitcast ({{.*}} @"$S16class_resilience14ResilientChildCMf", {{.*}}), [[INT]] {{60|96}})
-// CHECK-NEXT: ret %swift.type* [[METADATA]]
-
-
 // ResilientChild metadata initialization function
 
 // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$S16class_resilience14ResilientChildCMr"(%swift.type*, i8*, i8**)
@@ -467,6 +495,14 @@
 // CHECK-NEXT: ret %swift.metadata_response [[T1]]
 
 
+// ResilientChild metadata relocation function
+
+// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience14ResilientChildCMi"(%swift.type_descriptor*, i8*)
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, i8* %1)
+// CHECK-NEXT: ret %swift.type* [[METADATA]]
+
+
 // ResilientChild.field setter dispatch thunk
 
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$S16class_resilience14ResilientChildC5fields5Int32VvsTj"(i32, %T16class_resilience14ResilientChildC* swiftself)
@@ -482,14 +518,6 @@
 // CHECK-NEXT: ret void
 
 
-// FixedLayoutChild metadata relocation function
-
-// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience16FixedLayoutChildCMi"(%swift.type_descriptor*)
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, %swift.type* bitcast ({{.*}} @"$S16class_resilience16FixedLayoutChildCMf", {{.*}}), [[INT]] {{60|96}})
-// CHECK-NEXT: ret %swift.type* [[METADATA]]
-
-
 // FixedLayoutChild metadata initialization function
 
 // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$S16class_resilience16FixedLayoutChildCMr"(%swift.type*, i8*, i8**)
@@ -516,10 +544,18 @@
 // CHECK-NEXT: ret %swift.metadata_response [[T1]]
 
 
+// FixedLayoutChild metadata relocation function
+
+// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience16FixedLayoutChildCMi"(%swift.type_descriptor*, i8*)
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, i8* %1)
+// CHECK-NEXT: ret %swift.type* [[METADATA]]
+
+
 // ResilientGenericChild metadata initialization function
 
-// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience21ResilientGenericChildCMi"(%swift.type_descriptor*, i8**, i8**)
-// CHECK:              [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK-LABEL: define internal %swift.type* @"$S16class_resilience21ResilientGenericChildCMi"(%swift.type_descriptor*, i8**, i8*)
+// CHECK:              [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
 // CHECK:              ret %swift.type* [[METADATA]]
 
 // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$S16class_resilience21ResilientGenericChildCMr"
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index 5076f51..18b4e89 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -2633,10 +2633,10 @@
 }
 
 // -- Fill function for dynamic singleton.
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S4enum16DynamicSingletonOMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S4enum16DynamicSingletonOMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
 // CHECK:   [[T0:%.*]] = bitcast i8** %1 to %swift.type**
 // CHECK:   [[T:%T]] = load %swift.type*, %swift.type** [[T0]],
-// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2, [[WORD]] {{4|8}})
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2, [[WORD]] {{4|8}})
 // CHECK-NEXT: ret %swift.type* [[METADATA]]
 
 // CHECK-LABEL: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$S4enum16DynamicSingletonOMr"
diff --git a/test/IRGen/enum_dynamic_multi_payload.sil b/test/IRGen/enum_dynamic_multi_payload.sil
index 331f184..2a2080d 100644
--- a/test/IRGen/enum_dynamic_multi_payload.sil
+++ b/test/IRGen/enum_dynamic_multi_payload.sil
@@ -417,7 +417,7 @@
   return undef : $()
 }
 
-// CHECK: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S26enum_dynamic_multi_payload8EitherOrOMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S26enum_dynamic_multi_payload8EitherOrOMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
 // CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata
 
 // CHECK: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$S26enum_dynamic_multi_payload8EitherOrOMr"
diff --git a/test/IRGen/enum_value_semantics.sil b/test/IRGen/enum_value_semantics.sil
index 4ce6124..8cba4d2 100644
--- a/test/IRGen/enum_value_semantics.sil
+++ b/test/IRGen/enum_value_semantics.sil
@@ -167,7 +167,7 @@
 
 // CHECK-LABEL: @"$S20enum_value_semantics18GenericFixedLayoutOMP" = internal constant <{ {{.*}} }> <{
 //   Instantiation function.
-// CHECK-SAME:    i32 trunc (i64 sub (i64 ptrtoint (%swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S20enum_value_semantics18GenericFixedLayoutOMi" to i64), i64 ptrtoint (<{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP" to i64)) to i32),
+// CHECK-SAME:    i32 trunc (i64 sub (i64 ptrtoint (%swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S20enum_value_semantics18GenericFixedLayoutOMi" to i64), i64 ptrtoint (<{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP" to i64)) to i32),
 //   Completion function.
 // CHECK-SAME:    i32 0,
 //   Pattern flags.  0x4020_0000 == (MetadataKind::Enum << 21).
diff --git a/test/IRGen/generic_classes.sil b/test/IRGen/generic_classes.sil
index 407da21..e1eb794 100644
--- a/test/IRGen/generic_classes.sil
+++ b/test/IRGen/generic_classes.sil
@@ -44,7 +44,7 @@
 // CHECK-LABEL: @"$S15generic_classes11RootGenericCMP" = internal constant
 // CHECK-SAME: <{
 // --       template instantiation function
-// CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_classes11RootGenericCMi"
+// CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S15generic_classes11RootGenericCMi"
 // --       heap destructor
 // CHECK-SAME:   @"$S15generic_classes11RootGenericCfD"
 // --       ivar destroyer
@@ -113,7 +113,7 @@
 
 // CHECK: @"$S15generic_classes015GenericInheritsC0CMP" = internal constant
 // --       template instantiation function
-// CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_classes015GenericInheritsC0CMi"
+// CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S15generic_classes015GenericInheritsC0CMi"
 // --       pattern flags (1 == has extra data pattern)
 // CHECK-SAME-native: i32 0,
 // CHECK-SAME-objc:   i32 1,
@@ -339,8 +339,8 @@
 }
  */
 
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
-// CHECK:   [[METADATA:%.*]] = call{{( tail)?}} %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
+// CHECK:   [[METADATA:%.*]] = call{{( tail)?}} %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
 
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal swiftcc %swift.metadata_response @"$S15generic_classes11RootGenericCMr"
 // CHECK-SAME:    (%swift.type* [[METADATA:%.*]], i8*, i8**) {{.*}} {
@@ -348,22 +348,22 @@
 // CHECK:   call void @swift_initClassMetadata(%swift.type* [[METADATA]], %swift.type* null, i64 0, i64 3, i8*** {{%.*}}, i64* {{%.*}})
 // CHECK: }
 
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
-// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
+// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
 
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal swiftcc %swift.metadata_response @"$S15generic_classes22RootGenericFixedLayoutCMr"
 // CHECK-SAME:    (%swift.type* [[METADATA:%.*]], i8*, i8**) {{.*}} {
 // CHECK:   call void @swift_initClassMetadata(%swift.type* [[METADATA]], %swift.type* null, i64 0, i64 3, i8*** {{%.*}}, i64* {{%.*}})
 // CHECK: }
 
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes015GenericInheritsC0CMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S15generic_classes015GenericInheritsC0CMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
 //   Bind the generic parameters.
 // CHECK:   [[T0:%.*]] = bitcast i8** %1 to %swift.type**
 // CHECK:   %A  = load %swift.type*, %swift.type** [[T0]]
 // CHECK:   [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
 // CHECK:   %B  = load %swift.type*, %swift.type** [[T1]]
 //   Construct the class.
-// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
 // CHECK-NEXT:   ret %swift.type* [[METADATA]]
 
 // CHECK-LABEL: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$S15generic_classes015GenericInheritsC0CMr"
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 00e30a0..eba7d27 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -11,7 +11,7 @@
 // CHECK:       [[PATTERN:@.*]] = internal constant [4 x i32] [i32 0, i32 1, i32 8, i32 0]
 // CHECK-LABEL: @"$S15generic_structs18FixedLayoutGenericVMP" = internal constant <{ {{.*}} }> <{
 // -- instantiation function
-// CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_structs18FixedLayoutGenericVMi"
+// CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S15generic_structs18FixedLayoutGenericVMi"
 // -- completion function
 // CHECK-SAME:   i32 0,
 // -- pattern flags
@@ -56,7 +56,7 @@
 // CHECK-SAME: }>
 // CHECK: @"$S15generic_structs13SingleDynamicVMP" = internal constant <{ {{.*}} }> <{
 // -- instantiation function
-// CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_structs13SingleDynamicVMi"
+// CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$S15generic_structs13SingleDynamicVMi"
 // -- vwtable pointer
 // CHECK-SAME:   @"$S15generic_structs13SingleDynamicVWV"
 
@@ -195,10 +195,10 @@
   return %v : $()
 }
 
-// CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_structs13SingleDynamicVMi"(%swift.type_descriptor*, i8**, i8**)
+// CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_structs13SingleDynamicVMi"(%swift.type_descriptor*, i8**, i8*)
 // CHECK:   [[T0:%.*]] = bitcast i8** %1 to %swift.type**
 // CHECK:   %T = load %swift.type*, %swift.type** [[T0]], align 8
-// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2, i64 16)
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2, i64 16)
 // CHECK-NEXT:   ret %swift.type* [[METADATA]]
 // CHECK: }
 
diff --git a/test/IRGen/generic_types.swift b/test/IRGen/generic_types.swift
index d8b5df0..d93d05e 100644
--- a/test/IRGen/generic_types.swift
+++ b/test/IRGen/generic_types.swift
@@ -93,17 +93,17 @@
 // CHECK-SAME:   i32 {{3|2}},
 // CHECK-SAME: }
 
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S13generic_types1ACMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S13generic_types1ACMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
 // CHECK:   [[T0:%.*]] = bitcast i8** %1 to %swift.type**
 // CHECK:   %T = load %swift.type*, %swift.type** [[T0]],
-// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
 // CHECK-NEXT:   ret %swift.type* [[METADATA]]
 // CHECK: }
 
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S13generic_types1BCMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} {
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$S13generic_types1BCMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
 // CHECK:   [[T0:%.*]] = bitcast i8** %1 to %swift.type**
 // CHECK:   %T = load %swift.type*, %swift.type** [[T0]],
-// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
 // CHECK-NEXT: ret %swift.type* [[METADATA]]
 // CHECK: }
 
diff --git a/test/IRGen/generic_vtable.swift b/test/IRGen/generic_vtable.swift
index 3a49a06..e8c15f8 100644
--- a/test/IRGen/generic_vtable.swift
+++ b/test/IRGen/generic_vtable.swift
@@ -110,12 +110,12 @@
 //// Metadata initialization function for 'Derived' copies superclass vtable
 //// and installs overrides for 'm2()' and 'init()'.
 
-// CHECK-LABEL: define internal %swift.type* @"$S14generic_vtable7DerivedCMi"(%swift.type_descriptor*, i8**, i8**)
+// CHECK-LABEL: define internal %swift.type* @"$S14generic_vtable7DerivedCMi"(%swift.type_descriptor*, i8**, i8*)
 
 // - 2 immediate members:
 //   - type metadata for generic parameter T,
 //   - and vtable entry for 'm3()'
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2)
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2)
 // CHECK: ret %swift.type* [[METADATA]]
 
 // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$S14generic_vtable7DerivedCMr"
diff --git a/test/multifile/require-layout-generic-arg-closure.swift b/test/multifile/require-layout-generic-arg-closure.swift
index 49b7bf2..6d7b299 100644
--- a/test/multifile/require-layout-generic-arg-closure.swift
+++ b/test/multifile/require-layout-generic-arg-closure.swift
@@ -17,7 +17,7 @@
 public func requestType2<T>(x: T) {
   requestTypeThrough(closure: { x in print(x) }, arg: x)
 }
-// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8**)
+// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8*)
 // FILE2:   [[T_ADDR:%.*]] = bitcast i8** %1 to %swift.type**
 // FILE2:   [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
 // FILE2:   [[CLASSMETADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata
diff --git a/test/multifile/require-layout-generic-arg-subscript.swift b/test/multifile/require-layout-generic-arg-subscript.swift
index fe8e1e2..7eb7f65 100644
--- a/test/multifile/require-layout-generic-arg-subscript.swift
+++ b/test/multifile/require-layout-generic-arg-subscript.swift
@@ -21,7 +21,7 @@
   }
 }
 
-// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8**)
+// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8*)
 // FILE2:   [[T_ADDR:%.*]] = bitcast i8** %1 to %swift.type**
 // FILE2:   [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
 // FILE2:   [[CLASSMETADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata
diff --git a/test/multifile/require-layout-generic-arg.swift b/test/multifile/require-layout-generic-arg.swift
index 0f2ebc0..9c7af0c 100644
--- a/test/multifile/require-layout-generic-arg.swift
+++ b/test/multifile/require-layout-generic-arg.swift
@@ -15,7 +15,7 @@
   print(T.self)
 }
 
-// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8**)
+// FILE2-LABEL: define internal %swift.type* @"$S4test3SubCMi"(%swift.type_descriptor*, i8**, i8*)
 // FILE2:   [[T_ADDR:%.*]] = bitcast i8** %1 to %swift.type**
 // FILE2:   [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
 // FILE2:   [[CLASSMETADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata