Merge pull request #11255 from rjmccall/signatures-and-function-pointers

diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp
index 29f7e32..edd085b 100644
--- a/lib/IRGen/GenCall.cpp
+++ b/lib/IRGen/GenCall.cpp
@@ -1335,7 +1335,7 @@
 
 llvm::CallInst *IRBuilder::CreateCall(const FunctionPointer &fn,
                                       ArrayRef<llvm::Value*> args) {
-  llvm::CallInst *call = CreateCall(fn.getPointer(), args);
+  llvm::CallInst *call = IRBuilderBase::CreateCall(fn.getPointer(), args);
   call->setAttributes(fn.getAttributes());
   call->setCallingConv(fn.getCallingConv());
   return call;
diff --git a/lib/IRGen/GenCast.cpp b/lib/IRGen/GenCast.cpp
index 21cb26f..53b4b00 100644
--- a/lib/IRGen/GenCast.cpp
+++ b/lib/IRGen/GenCast.cpp
@@ -224,7 +224,7 @@
                                  Explosion &ex) {
   // Pick a runtime entry point and target metadata based on what kind of
   // representation we're casting.
-  llvm::Value *castFn;
+  llvm::Constant *castFn;
   llvm::Value *toMetadata;
 
   switch (toMetatype->getRepresentation()) {
@@ -630,7 +630,7 @@
     
     // Pick the cast function based on the cast mode and on whether we're
     // casting a Swift metatype or ObjC object.
-    llvm::Value *castFn;
+    llvm::Constant *castFn;
     switch (mode) {
     case CheckedCastMode::Unconditional:
       castFn = objcObject
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 119e8c4..c0fa6af 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -969,7 +969,7 @@
                               false /* = isVarArg */);
     llvm::InlineAsm *inlineAsm =
       llvm::InlineAsm::get(asmFnTy, "", "r", true /* = SideEffects */);
-    RegisterIGF.Builder.CreateCall(inlineAsm, MetaData);
+    RegisterIGF.Builder.CreateAsmCall(inlineAsm, MetaData);
   }
   RegisterIGF.Builder.CreateRetVoid();
 
@@ -1535,17 +1535,15 @@
 }
 
 /// Get or create an LLVM function with these linkage rules.
-llvm::Function *swift::irgen::createFunction(IRGenModule &IGM,
-                                             LinkInfo &linkInfo,
-                                             llvm::FunctionType *fnType,
-                                             llvm::CallingConv::ID cc,
-                                             const llvm::AttributeSet &attrs,
-                                             llvm::Function *insertBefore) {
+llvm::Function *irgen::createFunction(IRGenModule &IGM,
+                                      LinkInfo &linkInfo,
+                                      const Signature &signature,
+                                      llvm::Function *insertBefore) {
   auto name = linkInfo.getName();
 
   llvm::Function *existing = IGM.Module.getFunction(name);
   if (existing) {
-    if (isPointerTo(existing->getType(), fnType))
+    if (isPointerTo(existing->getType(), signature.getType()))
       return cast<llvm::Function>(existing);
 
     IGM.error(SourceLoc(),
@@ -1557,10 +1555,10 @@
   }
 
   llvm::Function *fn =
-      llvm::Function::Create(fnType, linkInfo.getLinkage(), name);
+    llvm::Function::Create(signature.getType(), linkInfo.getLinkage(), name);
   fn->setVisibility(linkInfo.getVisibility());
   fn->setDLLStorageClass(linkInfo.getDLLStorage());
-  fn->setCallingConv(cc);
+  fn->setCallingConv(signature.getCallingConv());
 
   if (insertBefore) {
     IGM.Module.getFunctionList().insert(insertBefore->getIterator(), fn);
@@ -1570,8 +1568,10 @@
 
   auto initialAttrs = IGM.constructInitialAttributes();
   // Merge initialAttrs with attrs.
-  auto updatedAttrs = attrs.addAttributes(IGM.getLLVMContext(),
-                        llvm::AttributeSet::FunctionIndex, initialAttrs);
+  auto updatedAttrs =
+    signature.getAttributes().addAttributes(IGM.getLLVMContext(),
+                                      llvm::AttributeSet::FunctionIndex,
+                                            initialAttrs);
   if (!updatedAttrs.isEmpty())
     fn->setAttributes(updatedAttrs);
 
@@ -1897,21 +1897,19 @@
   }
 
   Signature signature = getSignature(f->getLoweredFunctionType());
-  llvm::FunctionType *fnType = signature.getType();
-  auto cc = signature.getCallingConv();
-  auto attrs = signature.getAttributes();
+  auto &attrs = signature.getMutableAttributes();
 
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
 
   if (f->getInlineStrategy() == NoInline) {
-    attrs = attrs.addAttribute(fnType->getContext(),
+    attrs = attrs.addAttribute(getLLVMContext(),
                 llvm::AttributeSet::FunctionIndex, llvm::Attribute::NoInline);
   }
   if (isReadOnlyFunction(f)) {
-    attrs = attrs.addAttribute(fnType->getContext(),
+    attrs = attrs.addAttribute(getLLVMContext(),
                 llvm::AttributeSet::FunctionIndex, llvm::Attribute::ReadOnly);
   }
-  fn = createFunction(*this, link, fnType, cc, attrs, insertBefore);
+  fn = createFunction(*this, link, signature, insertBefore);
 
   // If we have an order number for this function, set it up as appropriate.
   if (hasOrderNumber) {
@@ -2511,8 +2509,9 @@
   }
 
   auto fnType = llvm::FunctionType::get(TypeMetadataPtrTy, false);
+  Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
-  entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
+  entry = createFunction(*this, link, signature);
   return entry;
 }
 
@@ -2536,8 +2535,9 @@
   }
 
   auto fnType = llvm::FunctionType::get(TypeMetadataPtrTy, genericArgs, false);
+  Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
-  entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
+  entry = createFunction(*this, link, signature);
   return entry;
 }
 
@@ -2846,13 +2846,9 @@
     return entry;
   }
 
-  // Find the appropriate function type.
-  llvm::FunctionType *fnType =
-    cast<llvm::FunctionType>(
-      cast<llvm::PointerType>(getValueWitnessTy(index))
-        ->getElementType());
+  auto signature = getValueWitnessSignature(index);
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
-  entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
+  entry = createFunction(*this, link, signature);
   return entry;
 }
 
@@ -3326,8 +3322,9 @@
                                           TypeMetadataPtrTy,
                                           Int8PtrPtrTy },
                                         /*varargs*/ false);
+  Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
-  entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
+  entry = createFunction(*this, link, signature);
   return entry;
 }
 
@@ -3374,8 +3371,9 @@
     fnType = llvm::FunctionType::get(WitnessTablePtrTy, false);
   }
 
+  Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
-  entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
+  entry = createFunction(*this, link, signature);
   return entry;
 }
 
@@ -3396,8 +3394,9 @@
   llvm::FunctionType *fnType
     = llvm::FunctionType::get(WitnessTablePtrTy, false);
 
+  Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
-  entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
+  entry = createFunction(*this, link, signature);
   return entry;
 }
 
@@ -3446,9 +3445,9 @@
     return entry;
   }
 
-  auto fnType = getAssociatedTypeMetadataAccessFunctionTy();
+  auto signature = getAssociatedTypeMetadataAccessFunctionSignature();
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
-  entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
+  entry = createFunction(*this, link, signature);
   return entry;
 }
 
@@ -3469,9 +3468,9 @@
     return entry;
   }
 
-  auto fnType = getAssociatedTypeWitnessTableAccessFunctionTy();
+  auto signature = getAssociatedTypeWitnessTableAccessFunctionSignature();
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
-  entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
+  entry = createFunction(*this, link, signature);
   return entry;
 }
 
diff --git a/lib/IRGen/GenDecl.h b/lib/IRGen/GenDecl.h
index b9c2dba..0d66cc04 100644
--- a/lib/IRGen/GenDecl.h
+++ b/lib/IRGen/GenDecl.h
@@ -30,12 +30,11 @@
 namespace irgen {
   class IRGenModule;
   class LinkInfo;
+  class Signature;
 
   llvm::Function *createFunction(IRGenModule &IGM,
                                  LinkInfo &linkInfo,
-                                 llvm::FunctionType *fnType,
-                                 llvm::CallingConv::ID cc,
-                                 const llvm::AttributeSet &attrs,
+                                 const Signature &signature,
                                  llvm::Function *insertBefore = nullptr);
 
 
diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp
index f8c545a..4fc9bd0 100644
--- a/lib/IRGen/GenFunc.cpp
+++ b/lib/IRGen/GenFunc.cpp
@@ -1174,23 +1174,30 @@
     }
   }
 
-  // Derive the callee function pointer.  If we found a function
-  // pointer statically, great.
+  // Derive the callee function pointer.
   auto fnTy = origSig.getType()->getPointerTo();
-  llvm::Value *fnPtr;
-  if (staticFnPtr) {
-    assert(staticFnPtr->getType() == fnTy && "static function type mismatch?!");
-    fnPtr = staticFnPtr;
+  FunctionPointer fnPtr = [&] {
+    // If we found a function pointer statically, great.
+    if (staticFnPtr) {
+      assert(staticFnPtr->getType() == fnTy &&
+             "static function type mismatch?!");
+      Signature sig(cast<llvm::FunctionType>(fnTy->getElementType()),
+                    staticFnPtr->getAttributes(),
+                    staticFnPtr->getCallingConv());
+      return FunctionPointer::forDirect(staticFnPtr, sig);
+    }
 
-  // Otherwise, it was the last thing we added to the layout.
-  } else {
+    // Otherwise, it was the last thing we added to the layout.
+
     // The dynamic function pointer is packed "last" into the context,
     // and we pulled it out as an argument.  Just pop it off.
-    fnPtr = args.takeLast();
+    auto fnPtr = args.takeLast();
 
     // It comes out of the context as an i8*. Cast to the function type.
     fnPtr = subIGF.Builder.CreateBitCast(fnPtr, fnTy);
-  }
+
+    return FunctionPointer(fnPtr, origSig);
+  }();
 
   // Derive the context argument if needed.  This is either:
   //   - the saved context argument, in which case it was the last
@@ -1246,17 +1253,6 @@
 
   llvm::CallInst *call = subIGF.Builder.CreateCall(fnPtr, args.claimAll());
   
-  if (staticFnPtr) {
-    // Use the attributes and calling convention from the static definition if
-    // we have it.
-    call->setAttributes(staticFnPtr->getAttributes());
-    call->setCallingConv(staticFnPtr->getCallingConv());
-  } else {
-    // Otherwise, use the default attributes for the dynamic type.
-    call->setAttributes(origSig.getAttributes());
-    // Use the calling convention of the partially applied function type.
-    call->setCallingConv(origSig.getCallingConv());
-  }
   if (addressesToDeallocate.empty() && !needsAllocas &&
       (!consumesContext || !dependsOnContextLifetime))
     call->setTailCall();
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index b162052..e82303a 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -15,6 +15,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Callee.h"
 #include "ConstantBuilder.h"
 #include "Explosion.h"
 #include "GenClass.h"
@@ -72,7 +73,7 @@
   if (requirements.empty()) {
     return accessorFn;
   }
-  
+
   auto accessorFnTy = accessorFn->getType()->getPointerElementType();
   
   // Otherwise, we need a thunk to unmarshal the generic environment from the
@@ -142,9 +143,9 @@
                              forwardingSubs,
                              &witnessMetadata,
                              forwardedArgs);
-    auto call = IGF.Builder.CreateCall(accessorFn, forwardedArgs.claimAll());
-    if (whichAccessor == Getter)
-      call->addAttribute(1, llvm::Attribute::StructRet);
+    auto fnPtr = FunctionPointer::forDirect(IGM, accessorFn,
+                                          accessor->getLoweredFunctionType());
+    IGF.Builder.CreateCall(fnPtr, forwardedArgs.claimAll());
     
     IGF.Builder.CreateRetVoid();
   }
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 67695f0..5917fba 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -33,7 +33,6 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Module.h"
 
 #include "Address.h"
@@ -1790,8 +1789,7 @@
 
     /// Emit the type layout by projecting it from dynamic type metadata.
     llvm::Value *emitFromTypeMetadata(CanType t) {
-      auto *vwtable = IGF.emitValueWitnessTableRefForLayout(
-                                                    IGF.IGM.getLoweredType(t));
+      auto *vwtable = IGF.emitValueWitnessTableRef(IGF.IGM.getLoweredType(t));
       return emitFromValueWitnessTablePointer(vwtable);
     }
 
@@ -4129,14 +4127,18 @@
 /// Given a lowered SIL type, load a value witness table that represents its
 /// layout.
 llvm::Value *
-IRGenFunction::emitValueWitnessTableRefForLayout(SILType type) {
+IRGenFunction::emitValueWitnessTableRef(SILType type,
+                                        llvm::Value **metadataSlot) {
   // See if we have a cached projection we can use.
   if (auto cached = tryGetLocalTypeDataForLayout(type,
                                   LocalTypeDataKind::forValueWitnessTable())) {
+    if (metadataSlot)
+      *metadataSlot = emitTypeMetadataRefForLayout(type);
     return cached;
   }
   
   auto metadata = emitTypeMetadataRefForLayout(type);
+  if (metadataSlot) *metadataSlot = metadata;
   auto vwtable = emitValueWitnessTableRefForMetadata(metadata);
   setScopedLocalTypeDataForLayout(type,
                                   LocalTypeDataKind::forValueWitnessTable(),
diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp
index a44bd5a..ffd5c6e 100644
--- a/lib/IRGen/GenObjC.cpp
+++ b/lib/IRGen/GenObjC.cpp
@@ -124,7 +124,7 @@
   return call;
 }
 
-llvm::Value *IRGenModule::getObjCRetainAutoreleasedReturnValueMarker() {
+llvm::InlineAsm *IRGenModule::getObjCRetainAutoreleasedReturnValueMarker() {
   // Check to see if we've already computed the market.  Note that we
   // might have cached a null marker, and that's fine.
   auto &cache = ObjCRetainAutoreleasedReturnValueMarker;
@@ -170,7 +170,7 @@
                                                           llvm::Value *value) {
   // Call the inline-assembly marker if we need one.
   if (auto marker = IGF.IGM.getObjCRetainAutoreleasedReturnValueMarker()) {
-    IGF.Builder.CreateCall(marker, {});
+    IGF.Builder.CreateAsmCall(marker, {});
   }
 
   auto fn = IGF.IGM.getObjCRetainAutoreleasedReturnValueFn();
diff --git a/lib/IRGen/GenOpaque.cpp b/lib/IRGen/GenOpaque.cpp
index 39db7e0..7fab62f 100644
--- a/lib/IRGen/GenOpaque.cpp
+++ b/lib/IRGen/GenOpaque.cpp
@@ -25,6 +25,7 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "swift/IRGen/ValueWitness.h"
 
+#include "Callee.h"
 #include "FixedTypeInfo.h"
 #include "IRGenFunction.h"
 #include "IRGenModule.h"
@@ -59,15 +60,13 @@
   // void (*destroy)(T *object, witness_t *self);
   case ValueWitness::Destroy: {
     llvm::Type *args[] = { IGM.OpaquePtrTy, IGM.TypeMetadataPtrTy };
-    return llvm::FunctionType::get(IGM.VoidTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(IGM.VoidTy, args, /*isVarArg*/ false);
   }
 
   // void (*destroyArray)(T *object, size_t n, witness_t *self);
   case ValueWitness::DestroyArray: {
     llvm::Type *args[] = { IGM.OpaquePtrTy, IGM.SizeTy, IGM.TypeMetadataPtrTy };
-    return llvm::FunctionType::get(IGM.VoidTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(IGM.VoidTy, args, /*isVarArg*/ false);
   }
 
   // T *(*initializeBufferWithCopyOfBuffer)(B *dest, B *src, M *self);
@@ -76,8 +75,7 @@
   case ValueWitness::InitializeBufferWithTakeOfBuffer: {
     llvm::Type *bufPtrTy = IGM.getFixedBufferTy()->getPointerTo(0);
     llvm::Type *args[] = { bufPtrTy, bufPtrTy, IGM.TypeMetadataPtrTy };
-    return llvm::FunctionType::get(IGM.OpaquePtrTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(IGM.OpaquePtrTy, args, /*isVarArg*/ false);
   }
 
   // T *(*assignWithCopy)(T *dest, T *src, M *self);
@@ -90,8 +88,7 @@
   case ValueWitness::InitializeWithTake: {
     llvm::Type *ptrTy = IGM.OpaquePtrTy;
     llvm::Type *args[] = { ptrTy, ptrTy, IGM.TypeMetadataPtrTy };
-    return llvm::FunctionType::get(ptrTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(ptrTy, args, /*isVarArg*/ false);
   }
       
   // T *(*initializeArrayWithCopy)(T *dest, T *src, size_t n, M *self);
@@ -102,8 +99,7 @@
   case ValueWitness::InitializeArrayWithTakeBackToFront: {
     llvm::Type *ptrTy = IGM.OpaquePtrTy;
     llvm::Type *args[] = { ptrTy, ptrTy, IGM.SizeTy, IGM.TypeMetadataPtrTy };
-    return llvm::FunctionType::get(ptrTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(ptrTy, args, /*isVarArg*/ false);
   }
       
   /// void (*storeExtraInhabitant)(T *obj, unsigned index, M *self);
@@ -114,8 +110,7 @@
     llvm::Type *voidTy = IGM.VoidTy;
     llvm::Type *args[] = {ptrTy, indexTy, metaTy};
     
-    return llvm::FunctionType::get(voidTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(voidTy, args, /*isVarArg*/ false);
   }
       
   /// int (*getExtraInhabitantIndex)(T *obj, M *self);
@@ -126,8 +121,7 @@
     
     llvm::Type *args[] = {ptrTy, metaTy};
     
-    return llvm::FunctionType::get(indexTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(indexTy, args, /*isVarArg*/ false);
   }
   
   /// int (*getEnumTag)(T *obj, M *self);
@@ -138,8 +132,7 @@
 
     llvm::Type *args[] = {ptrTy, metaTy};
 
-    return llvm::FunctionType::get(indexTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(indexTy, args, /*isVarArg*/ false);
   }
 
   /// void (*destructiveProjectEnumData)(T *obj, M *self);
@@ -150,8 +143,7 @@
 
     llvm::Type *args[] = {ptrTy, metaTy};
 
-    return llvm::FunctionType::get(voidTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(voidTy, args, /*isVarArg*/ false);
   }
 
   /// void (*destructiveInjectEnumTag)(T *obj, int tag, M *self);
@@ -163,8 +155,7 @@
 
     llvm::Type *args[] = {ptrTy, indexTy, metaTy};
 
-    return llvm::FunctionType::get(voidTy, args, /*isVarArg*/ false)
-      ->getPointerTo();
+    return llvm::FunctionType::get(voidTy, args, /*isVarArg*/ false);
   }
 
   case ValueWitness::Size:
@@ -177,6 +168,53 @@
   llvm_unreachable("bad value witness!");
 }
 
+static llvm::AttributeSet getValueWitnessAttrs(IRGenModule &IGM,
+                                               ValueWitness index) {
+  assert(isValueWitnessFunction(index));
+
+  auto &ctx = IGM.getLLVMContext();
+
+  // All value witnesses are nounwind.
+  auto attrs = llvm::AttributeSet::get(ctx,
+                                       llvm::AttributeSet::FunctionIndex,
+                                       llvm::Attribute::NoUnwind);
+
+  switch (index) {
+  // These have two arguments, but they can alias.
+  case ValueWitness::AssignWithCopy:
+  case ValueWitness::InitializeArrayWithTakeFrontToBack:
+  case ValueWitness::InitializeArrayWithTakeBackToFront:
+    return attrs;
+
+  // These have one argument.
+  case ValueWitness::Destroy:
+  case ValueWitness::DestroyArray:
+  case ValueWitness::DestructiveInjectEnumTag:
+  case ValueWitness::DestructiveProjectEnumData:
+  case ValueWitness::GetEnumTag:
+  case ValueWitness::GetExtraInhabitantIndex:
+  case ValueWitness::StoreExtraInhabitant:
+    return attrs.addAttribute(ctx, 1, llvm::Attribute::NoAlias);
+
+  // These have two arguments and they don't alias each other.
+  case ValueWitness::AssignWithTake:
+  case ValueWitness::InitializeArrayWithCopy:
+  case ValueWitness::InitializeBufferWithCopyOfBuffer:
+  case ValueWitness::InitializeBufferWithTakeOfBuffer:
+  case ValueWitness::InitializeWithCopy:
+  case ValueWitness::InitializeWithTake:
+    return attrs.addAttribute(ctx, 1, llvm::Attribute::NoAlias)
+                .addAttribute(ctx, 2, llvm::Attribute::NoAlias);
+
+  case ValueWitness::Size:
+  case ValueWitness::Flags:
+  case ValueWitness::Stride:
+  case ValueWitness::ExtraInhabitantFlags:
+    llvm_unreachable("not a function value witness");
+  }
+  llvm_unreachable("bad witness");
+}
+
 /// Return the cached pointer-to-function type for the given value
 /// witness index.
 llvm::Type *IRGenModule::getValueWitnessTy(ValueWitness index) {
@@ -188,6 +226,13 @@
   return ty;
 }
 
+Signature IRGenModule::getValueWitnessSignature(ValueWitness index) {
+  assert(isValueWitnessFunction(index));
+  auto fnTy = cast<llvm::FunctionType>(getValueWitnessTy(index));
+  auto attrs = getValueWitnessAttrs(*this, index);
+  return Signature(fnTy, attrs, DefaultCC);
+}
+
 static StringRef getValueWitnessLabel(ValueWitness index) {
   switch (index) {
   case ValueWitness::Destroy:
@@ -255,145 +300,139 @@
 
 /// Given a value witness table, load one of the value witnesses.
 /// The result has the appropriate type for the witness.
-static llvm::Value *emitLoadOfValueWitness(IRGenFunction &IGF,
-                                           llvm::Value *table,
-                                           ValueWitness index) {
+static llvm::Value *emitLoadOfValueWitnessValue(IRGenFunction &IGF,
+                                                llvm::Value *table,
+                                                ValueWitness index) {
+  assert(!isValueWitnessFunction(index));
   llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, table, index);
   auto label = getValueWitnessLabel(index);
   auto type = IGF.IGM.getValueWitnessTy(index);
-  if (isValueWitnessFunction(index)) {
-    return IGF.Builder.CreateBitCast(witness, type, label);
-  } else {
-    return IGF.Builder.CreatePtrToInt(witness, type, label);
-  }
+  return IGF.Builder.CreatePtrToInt(witness, type, label);
 }
 
 /// Given a type metadata pointer, load one of the value witnesses from its
 /// value witness table.
-static llvm::Value *emitLoadOfValueWitnessFromMetadata(IRGenFunction &IGF,
-                                                       llvm::Value *metadata,
-                                                       ValueWitness index) {
+static llvm::Value *
+emitLoadOfValueWitnessValueFromMetadata(IRGenFunction &IGF,
+                                        llvm::Value *metadata,
+                                        ValueWitness index) {
   llvm::Value *vwtable = IGF.emitValueWitnessTableRefForMetadata(metadata);
-  return emitLoadOfValueWitness(IGF, vwtable, index);
+  return emitLoadOfValueWitnessValue(IGF, vwtable, index);
 }
 
-llvm::Value *IRGenFunction::emitValueWitness(CanType type, ValueWitness index) {
-  if (auto witness =
-        tryGetLocalTypeData(type, LocalTypeDataKind::forValueWitness(index)))
+/// Given a value witness table, load one of the value witnesses.
+/// The result has the appropriate type for the witness.
+static FunctionPointer emitLoadOfValueWitnessFunction(IRGenFunction &IGF,
+                                                      llvm::Value *table,
+                                                      ValueWitness index) {
+  assert(isValueWitnessFunction(index));
+  llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, table, index);
+  auto label = getValueWitnessLabel(index);
+  auto signature = IGF.IGM.getValueWitnessSignature(index);
+
+  auto type = signature.getType()->getPointerTo();
+  witness = IGF.Builder.CreateBitCast(witness, type, label);
+
+  return FunctionPointer(witness, signature);
+}
+
+/// Given a type metadata pointer, load one of the function
+/// value witnesses from its value witness table.
+static FunctionPointer
+emitLoadOfValueWitnessFunctionFromMetadata(IRGenFunction &IGF,
+                                           llvm::Value *metadata,
+                                           ValueWitness index) {
+  llvm::Value *vwtable = IGF.emitValueWitnessTableRefForMetadata(metadata);
+  return emitLoadOfValueWitnessFunction(IGF, vwtable, index);
+}
+
+llvm::Value * IRGenFunction::emitValueWitnessValue(SILType type,
+                                                   ValueWitness index) {
+  assert(!isValueWitnessFunction(index));
+
+  if (auto witness = tryGetLocalTypeDataForLayout(type,
+                                LocalTypeDataKind::forValueWitness(index))) {
     return witness;
+  }
   
   auto vwtable = emitValueWitnessTableRef(type);
-  auto witness = emitLoadOfValueWitness(*this, vwtable, index);
-  setScopedLocalTypeData(type, LocalTypeDataKind::forValueWitness(index),
-                         witness);
-  return witness;
-}
-
-llvm::Value *IRGenFunction::emitValueWitnessForLayout(SILType type,
-                                                      ValueWitness index) {
-  if (auto witness = tryGetLocalTypeDataForLayout(type,
-                                    LocalTypeDataKind::forValueWitness(index)))
-    return witness;
-  
-  auto vwtable = emitValueWitnessTableRefForLayout(type);
-  auto witness = emitLoadOfValueWitness(*this, vwtable, index);
+  auto witness = emitLoadOfValueWitnessValue(*this, vwtable, index);
   setScopedLocalTypeDataForLayout(type,
-                           LocalTypeDataKind::forValueWitness(index), witness);
+                                  LocalTypeDataKind::forValueWitness(index),
+                                  witness);
   return witness;
 }
 
-/// Given a call to a helper function that produces a result
-/// into its first argument, set attributes appropriately.
-static void setHelperAttributesForAggResult(llvm::CallInst *call,
-                                            bool isFormalResult = true) {
-  // Set as nounwind.
-  auto attrs = llvm::AttributeSet::get(call->getContext(),
-                                       llvm::AttributeSet::FunctionIndex,
-                                       llvm::Attribute::NoUnwind);
+FunctionPointer
+IRGenFunction::emitValueWitnessFunctionRef(SILType type,
+                                           llvm::Value *&metadataSlot,
+                                           ValueWitness index) {
+  assert(isValueWitnessFunction(index));
 
-  attrs = attrs.addAttribute(call->getContext(), 1, llvm::Attribute::NoAlias);
-
-  // Only set 'sret' if this is also the formal result.
-  if (isFormalResult) {
-    attrs = attrs.addAttribute(call->getContext(), 1,
-                               llvm::Attribute::StructRet);
+  if (auto witness = tryGetLocalTypeDataForLayout(type,
+                                LocalTypeDataKind::forValueWitness(index))) {
+    metadataSlot = emitTypeMetadataRefForLayout(type);
+    auto signature = IGM.getValueWitnessSignature(index);
+    return FunctionPointer(witness, signature);
   }
-
-  call->setAttributes(attrs);
+  
+  auto vwtable = emitValueWitnessTableRef(type, &metadataSlot);
+  auto witness = emitLoadOfValueWitnessFunction(*this, vwtable, index);
+  setScopedLocalTypeDataForLayout(type,
+                                  LocalTypeDataKind::forValueWitness(index),
+                                  witness.getPointer());
+  return witness;
 }
 
-/// Given a call to a helper function, set attributes appropriately.
-static void setHelperAttributes(llvm::CallInst *call) {
-  // Set as nounwind.
-  auto attrs = llvm::AttributeSet::get(call->getContext(),
-                                       llvm::AttributeSet::FunctionIndex,
-                                       llvm::Attribute::NoUnwind);
-
-  call->setAttributes(attrs);
+llvm::Value *irgen::emitInitializeBufferWithCopyOfBufferCall(IRGenFunction &IGF,
+                                                     SILType T,
+                                                     Address destBuffer,
+                                                     Address srcBuffer) {
+  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
+  return emitInitializeBufferWithCopyOfBufferCall(IGF, metadata,
+                                                  destBuffer, srcBuffer);
 }
 
 /// Emit a call to do an 'initializeBufferWithCopyOfBuffer' operation.
-llvm::Value *irgen::emitInitializeBufferWithCopyOfBufferCall(IRGenFunction &IGF,
-                                                     llvm::Value *metadata,
-                                                     Address destBuffer,
-                                                     Address srcBuffer) {
-  llvm::Value *copyFn = emitLoadOfValueWitnessFromMetadata(IGF, metadata,
+llvm::Value *
+irgen::emitInitializeBufferWithCopyOfBufferCall(IRGenFunction &IGF,
+                                                llvm::Value *metadata,
+                                                Address destBuffer,
+                                                Address srcBuffer) {
+  auto copyFn = emitLoadOfValueWitnessFunctionFromMetadata(IGF, metadata,
                              ValueWitness::InitializeBufferWithCopyOfBuffer);
   llvm::CallInst *call =
     IGF.Builder.CreateCall(copyFn,
       {destBuffer.getAddress(), srcBuffer.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributesForAggResult(call, false);
 
   return call;
 }
 
-llvm::Value *irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
-                                                     SILType T,
-                                                     Address destBuffer,
-                                                     Address srcBuffer) {
+llvm::Value *
+irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
+                                                SILType T,
+                                                Address destBuffer,
+                                                Address srcBuffer) {
   auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
-                                ValueWitness::InitializeBufferWithTakeOfBuffer);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
-      {destBuffer.getAddress(), srcBuffer.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
-  return call;
+  return emitInitializeBufferWithTakeOfBufferCall(IGF, metadata,
+                                                  destBuffer, srcBuffer);
 }
 
 /// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
-llvm::Value *irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
-                                                     llvm::Value *metadata,
-                                                     Address destBuffer,
-                                                     Address srcBuffer) {
-  llvm::Value *copyFn = emitLoadOfValueWitnessFromMetadata(IGF, metadata,
+llvm::Value *
+irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
+                                                llvm::Value *metadata,
+                                                Address destBuffer,
+                                                Address srcBuffer) {
+  auto copyFn = emitLoadOfValueWitnessFunctionFromMetadata(IGF, metadata,
                              ValueWitness::InitializeBufferWithTakeOfBuffer);
   llvm::CallInst *call =
     IGF.Builder.CreateCall(copyFn,
       {destBuffer.getAddress(), srcBuffer.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributesForAggResult(call, false);
 
   return call;
 }
 
-llvm::Value *irgen::emitInitializeBufferWithCopyOfBufferCall(IRGenFunction &IGF,
-                                                     SILType T,
-                                                     Address destBuffer,
-                                                     Address srcBuffer) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
-                                ValueWitness::InitializeBufferWithCopyOfBuffer);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
-      {destBuffer.getAddress(), srcBuffer.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
-  return call;
-}
-
 /// Emit a dynamic alloca call to allocate enough memory to hold an object of
 /// type 'T' and an optional llvm.stackrestore point if 'isInEntryBlock' is
 /// false.
@@ -432,51 +471,18 @@
   IGF.Builder.CreateCall(stackRestoreFn, address.getSavedSP());
 }
 
-/// Emit a call to do an 'initializeWithCopy' operation.
-void irgen::emitInitializeWithCopyCall(IRGenFunction &IGF,
-                                       SILType T,
-                                       Address destObject,
-                                       Address srcObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
-                                         ValueWitness::InitializeWithCopy);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
-      {destObject.getAddress(), srcObject.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
-}
-
 /// Emit a call to do an 'initializeArrayWithCopy' operation.
 void irgen::emitInitializeArrayWithCopyCall(IRGenFunction &IGF,
                                             SILType T,
                                             Address destObject,
                                             Address srcObject,
                                             llvm::Value *count) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
-                                         ValueWitness::InitializeArrayWithCopy);
+  llvm::Value *metadata;
+  auto copyFn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                       ValueWitness::InitializeArrayWithCopy);
 
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
+  IGF.Builder.CreateCall(copyFn,
       {destObject.getAddress(), srcObject.getAddress(), count, metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
-}
-
-/// Emit a call to do an 'initializeWithTake' operation.
-void irgen::emitInitializeWithTakeCall(IRGenFunction &IGF,
-                                       SILType T,
-                                       Address destObject,
-                                       Address srcObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
-                                            ValueWitness::InitializeWithTake);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
-      {destObject.getAddress(), srcObject.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
 }
 
 /// Emit a call to do an 'initializeArrayWithTakeFrontToBack' operation.
@@ -485,14 +491,11 @@
                                             Address destObject,
                                             Address srcObject,
                                             llvm::Value *count) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
-                             ValueWitness::InitializeArrayWithTakeFrontToBack);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
+  llvm::Value *metadata;
+  auto copyFn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                            ValueWitness::InitializeArrayWithTakeFrontToBack);
+  IGF.Builder.CreateCall(copyFn,
       {destObject.getAddress(), srcObject.getAddress(), count, metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
 }
 
 /// Emit a call to do an 'initializeArrayWithTakeBackToFront' operation.
@@ -501,14 +504,23 @@
                                             Address destObject,
                                             Address srcObject,
                                             llvm::Value *count) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
+  llvm::Value *metadata;
+  auto copyFn = IGF.emitValueWitnessFunctionRef(T, metadata,
                              ValueWitness::InitializeArrayWithTakeBackToFront);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
+  IGF.Builder.CreateCall(copyFn,
       {destObject.getAddress(), srcObject.getAddress(), count, metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
+}
+
+/// Emit a call to do an 'assignWithCopy' operation.
+void irgen::emitAssignWithCopyCall(IRGenFunction &IGF,
+                                   SILType T,
+                                   Address destObject,
+                                   Address srcObject) {
+  llvm::Value *metadata;
+  auto copyFn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                                ValueWitness::AssignWithCopy);
+  IGF.Builder.CreateCall(copyFn,
+      {destObject.getAddress(), srcObject.getAddress(), metadata});
 }
 
 /// Emit a call to do an 'assignWithCopy' operation.
@@ -516,26 +528,10 @@
                                    llvm::Value *metadata,
                                    Address destObject,
                                    Address srcObject) {
-  llvm::Value *copyFn = emitLoadOfValueWitnessFromMetadata(IGF, metadata,
+  auto copyFn = emitLoadOfValueWitnessFunctionFromMetadata(IGF, metadata,
                                          ValueWitness::AssignWithCopy);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
+  IGF.Builder.CreateCall(copyFn,
       {destObject.getAddress(), srcObject.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
-}
-void irgen::emitAssignWithCopyCall(IRGenFunction &IGF,
-                                   SILType T,
-                                   Address destObject,
-                                   Address srcObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
-                                         ValueWitness::AssignWithCopy);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
-      {destObject.getAddress(), srcObject.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
 }
 
 /// Emit a call to do an 'assignWithTake' operation.
@@ -543,30 +539,11 @@
                                    SILType T,
                                    Address destObject,
                                    Address srcObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
-                                         ValueWitness::AssignWithTake);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
+  llvm::Value *metadata;
+  auto copyFn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                                ValueWitness::AssignWithTake);
+  IGF.Builder.CreateCall(copyFn,
       {destObject.getAddress(), srcObject.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
-}
-
-/// Emit a call to do a 'destroy' operation.
-void irgen::emitDestroyCall(IRGenFunction &IGF,
-                            SILType T,
-                            Address object) {
-  // If T is a trivial/POD type, nothing needs to be done.
-  if (T.getObjectType().isTrivial(IGF.getSILModule()))
-    return;
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
-                                   ValueWitness::Destroy);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(fn, {object.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributes(call);
 }
 
 /// Emit a call to do a 'destroyArray' operation.
@@ -577,13 +554,11 @@
   // If T is a trivial/POD type, nothing needs to be done.
   if (T.getObjectType().isTrivial(IGF.getSILModule()))
     return;
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
-                                   ValueWitness::DestroyArray);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(fn, {object.getAddress(), count, metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributes(call);
+
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                            ValueWitness::DestroyArray);
+  IGF.Builder.CreateCall(fn, {object.getAddress(), count, metadata});
 }
 
 /// Emit a call to the 'getExtraInhabitantIndex' operation.
@@ -591,14 +566,12 @@
 llvm::Value *irgen::emitGetExtraInhabitantIndexCall(IRGenFunction &IGF,
                                                     SILType T,
                                                     Address srcObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
-                                         ValueWitness::GetExtraInhabitantIndex);
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                       ValueWitness::GetExtraInhabitantIndex);
   
   llvm::CallInst *call =
     IGF.Builder.CreateCall(fn, {srcObject.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributes(call);
   return call;
 }
 
@@ -608,13 +581,11 @@
                                                  SILType T,
                                                  llvm::Value *index,
                                                  Address destObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
-                                       ValueWitness::StoreExtraInhabitant);
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                          ValueWitness::StoreExtraInhabitant);
   llvm::CallInst *call =
     IGF.Builder.CreateCall(fn, {destObject.getAddress(), index, metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributes(call);
   return call;
 }
 
@@ -622,13 +593,12 @@
 llvm::Value *irgen::emitGetEnumTagCall(IRGenFunction &IGF,
                                        SILType T,
                                        Address srcObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
-                                       ValueWitness::GetEnumTag);
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                            ValueWitness::GetEnumTag);
+
   llvm::CallInst *call =
     IGF.Builder.CreateCall(fn, {srcObject.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributes(call);
   return call;
 }
 
@@ -637,13 +607,10 @@
 void irgen::emitDestructiveProjectEnumDataCall(IRGenFunction &IGF,
                                                SILType T,
                                                Address srcObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
-                                      ValueWitness::DestructiveProjectEnumData);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(fn, {srcObject.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributes(call);
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                    ValueWitness::DestructiveProjectEnumData);
+  IGF.Builder.CreateCall(fn, {srcObject.getAddress(), metadata});
 }
 
 /// Emit a call to the 'destructiveInjectEnumTag' operation.
@@ -652,25 +619,22 @@
                                              SILType T,
                                              unsigned tag,
                                              Address srcObject) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
                                       ValueWitness::DestructiveInjectEnumTag);
   llvm::Value *tagValue =
     llvm::ConstantInt::get(IGF.IGM.Int32Ty, tag);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(fn, {srcObject.getAddress(), tagValue, metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributes(call);
+  IGF.Builder.CreateCall(fn, {srcObject.getAddress(), tagValue, metadata});
 }
 
 /// Load the 'size' value witness from the given table as a size_t.
 llvm::Value *irgen::emitLoadOfSize(IRGenFunction &IGF, SILType T) {
-  return IGF.emitValueWitnessForLayout(T, ValueWitness::Size);
+  return IGF.emitValueWitnessValue(T, ValueWitness::Size);
 }
 
 /// Load the 'alignmentMask' value witness from the given table as a size_t.
 llvm::Value *irgen::emitLoadOfAlignmentMask(IRGenFunction &IGF, SILType T) {
-  auto flags = IGF.emitValueWitnessForLayout(T, ValueWitness::Flags);
+  auto flags = IGF.emitValueWitnessValue(T, ValueWitness::Flags);
   auto mask = IGF.IGM.getSize(Size(ValueWitnessFlags::AlignmentMask));
   return IGF.Builder.CreateAnd(flags, mask,
                                flags->getName() + ".alignmentMask");
@@ -678,7 +642,7 @@
 
 /// Load the 'isPOD' valueWitness from the given table as an i1.
 llvm::Value *irgen::emitLoadOfIsPOD(IRGenFunction &IGF, SILType T) {
-  auto flags = IGF.emitValueWitnessForLayout(T, ValueWitness::Flags);
+  auto flags = IGF.emitValueWitnessValue(T, ValueWitness::Flags);
   auto mask = IGF.IGM.getSize(Size(ValueWitnessFlags::IsNonPOD));
   auto masked = IGF.Builder.CreateAnd(flags, mask);
   return IGF.Builder.CreateICmpEQ(masked, IGF.IGM.getSize(Size(0)),
@@ -687,7 +651,7 @@
 
 /// Load the 'isBitwiseTakable' valueWitness from the given table as an i1.
 llvm::Value *irgen::emitLoadOfIsBitwiseTakable(IRGenFunction &IGF, SILType T) {
-  auto flags = IGF.emitValueWitnessForLayout(T, ValueWitness::Flags);
+  auto flags = IGF.emitValueWitnessValue(T, ValueWitness::Flags);
   auto mask = IGF.IGM.getSize(Size(ValueWitnessFlags::IsNonBitwiseTakable));
   auto masked = IGF.Builder.CreateAnd(flags, mask);
   return IGF.Builder.CreateICmpEQ(masked, IGF.IGM.getSize(Size(0)),
@@ -696,7 +660,7 @@
 
 /// Load the 'isInline' valueWitness from the given table as an i1.
 llvm::Value *irgen::emitLoadOfIsInline(IRGenFunction &IGF, SILType T) {
-  auto flags = IGF.emitValueWitnessForLayout(T, ValueWitness::Flags);
+  auto flags = IGF.emitValueWitnessValue(T, ValueWitness::Flags);
   auto mask = IGF.IGM.getSize(Size(ValueWitnessFlags::IsNonInline));
   auto masked = IGF.Builder.CreateAnd(flags, mask);
   return IGF.Builder.CreateICmpEQ(masked, IGF.IGM.getSize(Size(0)),
@@ -705,7 +669,7 @@
 
 /// Load the 'hasExtraInhabitants' valueWitness from the given table as an i1.
 llvm::Value *irgen::emitLoadOfHasExtraInhabitants(IRGenFunction &IGF, SILType T) {
-  auto flags = IGF.emitValueWitnessForLayout(T, ValueWitness::Flags);
+  auto flags = IGF.emitValueWitnessValue(T, ValueWitness::Flags);
   auto mask = IGF.IGM.getSize(Size(ValueWitnessFlags::Enum_HasExtraInhabitants));
   auto masked = IGF.Builder.CreateAnd(flags, mask);
   return IGF.Builder.CreateICmpNE(masked, IGF.IGM.getSize(Size(0)),
@@ -714,13 +678,13 @@
 
 /// Load the 'stride' value witness from the given table as a size_t.
 llvm::Value *irgen::emitLoadOfStride(IRGenFunction &IGF, SILType T) {
-  return IGF.emitValueWitnessForLayout(T, ValueWitness::Stride);
+  return IGF.emitValueWitnessValue(T, ValueWitness::Stride);
 }
 
 llvm::Value *irgen::emitLoadOfExtraInhabitantCount(IRGenFunction &IGF,
                                                    SILType T) {
-  auto xiFlags = IGF.emitValueWitnessForLayout(T,
-                                           ValueWitness::ExtraInhabitantFlags);
+  auto xiFlags =
+    IGF.emitValueWitnessValue(T, ValueWitness::ExtraInhabitantFlags);
   auto mask = IGF.IGM.getSize(
                           Size(ExtraInhabitantFlags::NumExtraInhabitantsMask));
   return IGF.Builder.CreateAnd(xiFlags, mask,
@@ -729,8 +693,8 @@
 
 std::pair<llvm::Value *, llvm::Value *>
 irgen::emitLoadOfIsInline(IRGenFunction &IGF, llvm::Value *metadata) {
-  auto *flags =
-      emitLoadOfValueWitnessFromMetadata(IGF, metadata, ValueWitness::Flags);
+  auto *flags = emitLoadOfValueWitnessValueFromMetadata(IGF, metadata,
+                                                        ValueWitness::Flags);
   auto mask = IGF.IGM.getSize(Size(ValueWitnessFlags::IsNonInline));
   auto masked = IGF.Builder.CreateAnd(flags, mask);
   return std::make_pair(
@@ -740,8 +704,8 @@
 }
 
 llvm::Value *irgen::emitLoadOfSize(IRGenFunction &IGF, llvm::Value *metadata) {
-  auto *size =
-      emitLoadOfValueWitnessFromMetadata(IGF, metadata, ValueWitness::Size);
+  auto *size = emitLoadOfValueWitnessValueFromMetadata(IGF, metadata,
+                                                       ValueWitness::Size);
   return size;
 }
 
@@ -752,40 +716,68 @@
                                flags->getName() + ".alignmentMask");
 }
 
+/// Emit a call to do an 'initializeWithCopy' operation.
+void irgen::emitInitializeWithCopyCall(IRGenFunction &IGF,
+                                       SILType T,
+                                       Address dest,
+                                       Address src) {
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                            ValueWitness::InitializeWithCopy);
+  IGF.Builder.CreateCall(fn, {dest.getAddress(), src.getAddress(), metadata});
+}
+
 llvm::Value *irgen::emitInitializeWithCopyCall(IRGenFunction &IGF,
                                                llvm::Value *metadata,
                                                Address dest, Address src) {
-  llvm::Value *copyFn = emitLoadOfValueWitnessFromMetadata(
+  auto copyFn = emitLoadOfValueWitnessFunctionFromMetadata(
       IGF, metadata, ValueWitness::InitializeWithCopy);
   llvm::CallInst *call = IGF.Builder.CreateCall(
       copyFn, {dest.getAddress(), src.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
 
   return call;
 }
 
+/// Emit a call to do an 'initializeWithTake' operation.
+void irgen::emitInitializeWithTakeCall(IRGenFunction &IGF,
+                                       SILType T,
+                                       Address dest,
+                                       Address src) {
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                            ValueWitness::InitializeWithTake);
+  IGF.Builder.CreateCall(fn, {dest.getAddress(), src.getAddress(), metadata});
+}
+
 llvm::Value *irgen::emitInitializeWithTakeCall(IRGenFunction &IGF,
                                                llvm::Value *metadata,
                                                Address dest, Address src) {
-  llvm::Value *copyFn = emitLoadOfValueWitnessFromMetadata(
+  auto copyFn = emitLoadOfValueWitnessFunctionFromMetadata(
       IGF, metadata, ValueWitness::InitializeWithTake);
   llvm::CallInst *call = IGF.Builder.CreateCall(
       copyFn, {dest.getAddress(), src.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  call->setDoesNotThrow();
 
   return call;
 }
 
+/// Emit a call to do a 'destroy' operation.
+void irgen::emitDestroyCall(IRGenFunction &IGF,
+                            SILType T,
+                            Address object) {
+  // If T is a trivial/POD type, nothing needs to be done.
+  if (T.getObjectType().isTrivial(IGF.getSILModule()))
+    return;
+  llvm::Value *metadata;
+  auto fn = IGF.emitValueWitnessFunctionRef(T, metadata,
+                                            ValueWitness::Destroy);
+  IGF.Builder.CreateCall(fn, {object.getAddress(), metadata});
+}
+
 void irgen::emitDestroyCall(IRGenFunction &IGF, llvm::Value *metadata,
                             Address object) {
-  llvm::Value *fn =
-      emitLoadOfValueWitnessFromMetadata(IGF, metadata, ValueWitness::Destroy);
-  llvm::CallInst *call =
-      IGF.Builder.CreateCall(fn, {object.getAddress(), metadata});
-  call->setCallingConv(IGF.IGM.DefaultCC);
-  setHelperAttributes(call);
+  auto fn = emitLoadOfValueWitnessFunctionFromMetadata(IGF, metadata,
+                                                       ValueWitness::Destroy);
+  IGF.Builder.CreateCall(fn, {object.getAddress(), metadata});
 }
 
 static llvm::Constant *getAllocateValueBufferFunction(IRGenModule &IGM) {
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 3940767..03283f1 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -1985,14 +1985,15 @@
   llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, wtable, index);
 
   // Cast the witness to the appropriate function type.
-  auto witnessTy = IGF.IGM.getAssociatedTypeWitnessTableAccessFunctionTy();
+  auto sig = IGF.IGM.getAssociatedTypeWitnessTableAccessFunctionSignature();
+  auto witnessTy = sig.getType();
   witness = IGF.Builder.CreateBitCast(witness, witnessTy->getPointerTo());
 
+  FunctionPointer witnessFnPtr(witness, sig);
+
   // Call the accessor.
-  auto call = IGF.Builder.CreateCall(witness,
+  auto call = IGF.Builder.CreateCall(witnessFnPtr,
                             { associatedTypeMetadata, parentMetadata, wtable });
-  call->setDoesNotThrow();
-  call->setCallingConv(IGF.IGM.DefaultCC);
 
   return call;
 }
@@ -2831,16 +2832,20 @@
   return FunctionPointer(witnessFnPtr, signature);
 }
 
-llvm::FunctionType *IRGenModule::getAssociatedTypeMetadataAccessFunctionTy() {
-  if (AssociatedTypeMetadataAccessFunctionTy)
-    return AssociatedTypeMetadataAccessFunctionTy;
+Signature IRGenModule::getAssociatedTypeMetadataAccessFunctionSignature() {
+  auto &fnType = AssociatedTypeMetadataAccessFunctionTy;
+  if (!fnType) {
+    fnType = llvm::FunctionType::get(TypeMetadataPtrTy,
+                                     { TypeMetadataPtrTy,
+                                       WitnessTablePtrTy },
+                                     /*varargs*/ false);
+  }
 
-  auto accessorTy = llvm::FunctionType::get(TypeMetadataPtrTy,
-                                            { TypeMetadataPtrTy,
-                                              WitnessTablePtrTy },
-                                            /*varargs*/ false);
-  AssociatedTypeMetadataAccessFunctionTy = accessorTy;
-  return accessorTy;
+  auto attrs = llvm::AttributeSet::get(getLLVMContext(),
+                                       llvm::AttributeSet::FunctionIndex,
+                                       llvm::Attribute::NoUnwind);
+
+  return Signature(fnType, attrs, DefaultCC);
 }
 
 llvm::Value *irgen::emitAssociatedTypeMetadataRef(IRGenFunction &IGF,
@@ -2852,31 +2857,37 @@
   llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, wtable, index);
 
   // Cast the witness to the appropriate function type.
-  auto witnessTy = IGF.IGM.getAssociatedTypeMetadataAccessFunctionTy();
+  auto sig = IGF.IGM.getAssociatedTypeMetadataAccessFunctionSignature();
+  auto witnessTy = sig.getType();
   witness = IGF.Builder.CreateBitCast(witness, witnessTy->getPointerTo());
 
+  FunctionPointer witnessFnPtr(witness, sig);
+
   // Call the accessor.
   assert((!IGF.IGM.DebugInfo || IGF.Builder.getCurrentDebugLocation()) &&
          "creating a function call without a debug location");
-  auto call = IGF.Builder.CreateCall(witness, { parentMetadata, wtable });
-  call->setDoesNotThrow();
-  call->setCallingConv(IGF.IGM.DefaultCC);
+  auto call = IGF.Builder.CreateCall(witnessFnPtr,
+                                     { parentMetadata, wtable });
 
   return call;
 }
 
-llvm::FunctionType *
-IRGenModule::getAssociatedTypeWitnessTableAccessFunctionTy() {
-  if (AssociatedTypeWitnessTableAccessFunctionTy)
-    return AssociatedTypeWitnessTableAccessFunctionTy;
+Signature
+IRGenModule::getAssociatedTypeWitnessTableAccessFunctionSignature() {
+  auto &fnType = AssociatedTypeWitnessTableAccessFunctionTy;
+  if (!fnType) {
+    // The associated type metadata is passed first so that this function is
+    // CC-compatible with a conformance's witness table access function.
+    fnType = llvm::FunctionType::get(WitnessTablePtrTy,
+                                     { TypeMetadataPtrTy,
+                                       TypeMetadataPtrTy,
+                                       WitnessTablePtrTy },
+                                     /*varargs*/ false);
+  }
 
-  // The associated type metadata is passed first so that this function is
-  // CC-compatible with a conformance's witness table access function.
-  auto accessorTy = llvm::FunctionType::get(WitnessTablePtrTy,
-                                            { TypeMetadataPtrTy,
-                                              TypeMetadataPtrTy,
-                                              WitnessTablePtrTy },
-                                            /*varargs*/ false);
-  AssociatedTypeWitnessTableAccessFunctionTy = accessorTy;
-  return accessorTy;
+  auto attrs = llvm::AttributeSet::get(getLLVMContext(),
+                                       llvm::AttributeSet::FunctionIndex,
+                                       llvm::Attribute::NoUnwind);
+
+  return Signature(fnType, attrs, DefaultCC);
 }
diff --git a/lib/IRGen/IRBuilder.h b/lib/IRGen/IRBuilder.h
index 45d4612..8b17048 100644
--- a/lib/IRGen/IRBuilder.h
+++ b/lib/IRGen/IRBuilder.h
@@ -19,6 +19,7 @@
 
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InlineAsm.h"
 #include "swift/Basic/LLVM.h"
 #include "Address.h"
 #include "IRGen.h"
@@ -264,19 +265,15 @@
                    llvm::ConstantInt::get(Context, APInt(64, size.getValue())));
   }
 
-  //using IRBuilderBase::CreateCall;
+  // We're intentionally not allowing direct use of
+  // llvm::IRBuilder::CreateCall in order to push code towards using
+  // FunctionPointer.
 
   llvm::CallInst *CreateCall(llvm::Value *Callee, ArrayRef<llvm::Value *> Args,
                              const Twine &Name = "",
-                             llvm::MDNode *FPMathTag = nullptr) {
-    // assert((!DebugInfo || getCurrentDebugLocation()) && "no debugloc on
-    // call");
-    auto Call = IRBuilderBase::CreateCall(Callee, Args, Name, FPMathTag);
-    setCallingConvUsingCallee(Call);
-    return Call;
-  }
+                             llvm::MDNode *FPMathTag = nullptr) = delete;
 
-  llvm::CallInst *CreateCall(llvm::FunctionType *FTy, llvm::Value *Callee,
+  llvm::CallInst *CreateCall(llvm::FunctionType *FTy, llvm::Constant *Callee,
                              ArrayRef<llvm::Value *> Args,
                              const Twine &Name = "",
                              llvm::MDNode *FPMathTag = nullptr) {
@@ -286,7 +283,7 @@
     return Call;
   }
 
-  llvm::CallInst *CreateCall(llvm::Function *Callee,
+  llvm::CallInst *CreateCall(llvm::Constant *Callee,
                              ArrayRef<llvm::Value *> Args,
                              const Twine &Name = "",
                              llvm::MDNode *FPMathTag = nullptr) {
@@ -299,6 +296,11 @@
 
   llvm::CallInst *CreateCall(const FunctionPointer &fn,
                              ArrayRef<llvm::Value *> args);
+
+  llvm::CallInst *CreateAsmCall(llvm::InlineAsm *asmBlock,
+                                ArrayRef<llvm::Value *> args) {
+    return IRBuilderBase::CreateCall(asmBlock, args);
+  }
 };
 
 } // end namespace irgen
diff --git a/lib/IRGen/IRGenFunction.cpp b/lib/IRGen/IRGenFunction.cpp
index 1d726bf..2ca323d 100644
--- a/lib/IRGen/IRGenFunction.cpp
+++ b/lib/IRGen/IRGenFunction.cpp
@@ -100,8 +100,8 @@
 }
 
 static llvm::Value *emitAllocatingCall(IRGenFunction &IGF,
-                                       llvm::Value *fn,
-                                       std::initializer_list<llvm::Value*> args,
+                                       llvm::Constant *fn,
+                                       ArrayRef<llvm::Value*> args,
                                        const llvm::Twine &name) {
   auto allocAttrs = IGF.IGM.getAllocAttrs();
   llvm::CallInst *call =
diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h
index ab552dc..270d86d 100644
--- a/lib/IRGen/IRGenFunction.h
+++ b/lib/IRGen/IRGenFunction.h
@@ -215,11 +215,14 @@
   llvm::Value *emitTypeMetadataRefForLayout(SILType type);
   
   llvm::Value *emitValueWitnessTableRef(CanType type);
-  llvm::Value *emitValueWitnessTableRefForLayout(SILType type);
+  llvm::Value *emitValueWitnessTableRef(SILType type,
+                                        llvm::Value **metadataSlot = nullptr);
   llvm::Value *emitValueWitnessTableRefForMetadata(llvm::Value *metadata);
   
-  llvm::Value *emitValueWitness(CanType type, ValueWitness index);
-  llvm::Value *emitValueWitnessForLayout(SILType type, ValueWitness index);
+  llvm::Value *emitValueWitnessValue(SILType type, ValueWitness index);
+  FunctionPointer emitValueWitnessFunctionRef(SILType type,
+                                              llvm::Value *&metadataSlot,
+                                              ValueWitness index);
 
   /// Emit a load of a reference to the given Objective-C selector.
   llvm::Value *emitObjCSelectorRefLoad(StringRef selector);
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 4286f8e..27d5d11 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -48,6 +48,7 @@
   class Function;
   class FunctionType;
   class GlobalVariable;
+  class InlineAsm;
   class IntegerType;
   class LLVMContext;
   class MDNode;
@@ -507,8 +508,8 @@
   llvm::CallingConv::ID SwiftCC;     /// swift calling convention
   bool UseSwiftCC;
 
-  llvm::FunctionType *getAssociatedTypeMetadataAccessFunctionTy();
-  llvm::FunctionType *getAssociatedTypeWitnessTableAccessFunctionTy();
+  Signature getAssociatedTypeMetadataAccessFunctionSignature();
+  Signature getAssociatedTypeWitnessTableAccessFunctionSignature();
   llvm::StructType *getGenericWitnessTableCacheTy();
 
   /// Get the bit width of an integer type for the target platform.
@@ -571,6 +572,7 @@
 
   llvm::Type *getFixedBufferTy();
   llvm::Type *getValueWitnessTy(ValueWitness index);
+  Signature getValueWitnessSignature(ValueWitness index);
 
   void unimplemented(SourceLoc, StringRef Message);
   LLVM_ATTRIBUTE_NORETURN
@@ -867,7 +869,7 @@
   llvm::Constant *getEmptyTupleMetadata();
   llvm::Constant *getObjCEmptyCachePtr();
   llvm::Constant *getObjCEmptyVTablePtr();
-  llvm::Value *getObjCRetainAutoreleasedReturnValueMarker();
+  llvm::InlineAsm *getObjCRetainAutoreleasedReturnValueMarker();
   ClassDecl *getObjCRuntimeBaseForSwiftRootClass(ClassDecl *theClass);
   ClassDecl *getObjCRuntimeBaseClass(Identifier name, Identifier objcName);
   llvm::Module *getModule() const;
@@ -879,7 +881,7 @@
   llvm::Constant *ObjCEmptyCachePtr = nullptr;
   llvm::Constant *ObjCEmptyVTablePtr = nullptr;
   llvm::Constant *ObjCISAMaskPtr = nullptr;
-  Optional<llvm::Value*> ObjCRetainAutoreleasedReturnValueMarker;
+  Optional<llvm::InlineAsm*> ObjCRetainAutoreleasedReturnValueMarker;
   llvm::DenseMap<Identifier, ClassDecl*> SwiftRootClasses;
   llvm::AttributeSet AllocAttrs;
 
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index e522f37..c866aa8 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -623,7 +623,7 @@
         // Emit an empty inline assembler expression depending on the register.
         auto *AsmFnTy = llvm::FunctionType::get(IGM.VoidTy, ArgTys, false);
         auto *InlineAsm = llvm::InlineAsm::get(AsmFnTy, "", "r", true);
-        Builder.CreateCall(InlineAsm, Storage);
+        Builder.CreateAsmCall(InlineAsm, Storage);
         // Propagate the dbg.value intrinsics into the later basic blocks.  Note
         // that this shouldn't be necessary. LiveDebugValues should be doing
         // this but can't in general because it currently only tracks register
@@ -5011,8 +5011,8 @@
       llvm::FunctionType::get(IGM.VoidTy, argTys, false /* = isVarArg */);
     llvm::InlineAsm *inlineAsm =
       llvm::InlineAsm::get(asmFnTy, "", "n", true /* = SideEffects */);
-    Builder.CreateCall(inlineAsm,
-                       llvm::ConstantInt::get(asmArgTy, NumCondFails++));
+    Builder.CreateAsmCall(inlineAsm,
+                          llvm::ConstantInt::get(asmArgTy, NumCondFails++));
   }
 
   // Emit the trap instruction.
diff --git a/lib/IRGen/NonFixedTypeInfo.h b/lib/IRGen/NonFixedTypeInfo.h
index a9499a7..f011fc3 100644
--- a/lib/IRGen/NonFixedTypeInfo.h
+++ b/lib/IRGen/NonFixedTypeInfo.h
@@ -85,7 +85,7 @@
   }
 
   llvm::Value *getValueWitnessTable(IRGenFunction &IGF, SILType T) const {
-    return IGF.emitValueWitnessTableRefForLayout(T);
+    return IGF.emitValueWitnessTableRef(T);
   }
 
   std::pair<llvm::Value*,llvm::Value*>
diff --git a/lib/IRGen/Signature.h b/lib/IRGen/Signature.h
index 3e9408c..5ff5dab 100644
--- a/lib/IRGen/Signature.h
+++ b/lib/IRGen/Signature.h
@@ -54,6 +54,11 @@
   llvm::CallingConv::ID CallingConv;
 
 public:
+  Signature() {}
+  Signature(llvm::FunctionType *fnType, llvm::AttributeSet attrs,
+            llvm::CallingConv::ID callingConv)
+    : Type(fnType), Attributes(attrs), CallingConv(callingConv) {}
+
   bool isValid() const {
     return Type != nullptr;
   }
@@ -97,8 +102,6 @@
     assert(isValid());
     return Attributes;
   }
-
-
 };
 
 } // end namespace irgen
diff --git a/test/IRGen/array_value_witnesses.sil b/test/IRGen/array_value_witnesses.sil
index 456ce12..530078f 100644
--- a/test/IRGen/array_value_witnesses.sil
+++ b/test/IRGen/array_value_witnesses.sil
@@ -50,7 +50,7 @@
 // CHECK:         @_T021array_value_witnesses8SomeWeakVwtT
 
 // CHECK-LABEL: define linkonce_odr hidden void @_T021array_value_witnesses8SomeWeakVwXx
-// CHECK:         (%swift.opaque* [[ARRAY_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %SomeWeak) {{.*}} {
+// CHECK:         (%swift.opaque* noalias [[ARRAY_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %SomeWeak) {{.*}} {
 // CHECK:         [[BEGIN:%.*]] = bitcast %swift.opaque* [[ARRAY_PTR]] to [[SOMEWEAK:%T21array_value_witnesses8SomeWeakV]]*
 // CHECK:         br label %iter
 // CHECK:       iter:
@@ -68,7 +68,7 @@
 // CHECK:         ret
 
 // CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T021array_value_witnesses8SomeWeakVwCc
-// CHECK:         (%swift.opaque* [[DEST_PTR:%.*]], %swift.opaque* [[SRC_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %SomeWeak) {{.*}} {
+// CHECK:         (%swift.opaque* noalias [[DEST_PTR:%.*]], %swift.opaque* noalias [[SRC_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %SomeWeak) {{.*}} {
 // CHECK:         [[DEST_BEGIN:%.*]] = bitcast %swift.opaque* [[DEST_PTR]] to [[SOMEWEAK]]*
 // CHECK:         [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
 // CHECK:         br label %iter
diff --git a/test/IRGen/boxed_existential.sil b/test/IRGen/boxed_existential.sil
index 809e961..f6e7a0d 100644
--- a/test/IRGen/boxed_existential.sil
+++ b/test/IRGen/boxed_existential.sil
@@ -26,7 +26,7 @@
   // CHECK: [[ADDR:%.*]] = extractvalue { %swift.error*, %swift.opaque* } [[BOX_PAIR]], 1
   %b = alloc_existential_box $Error, $T
   %p = project_existential_box $T in %b : $Error
-  // CHECK: call %swift.opaque* %initializeWithTake(%swift.opaque* [[ADDR]], %swift.opaque* %0, %swift.type* %T)
+  // CHECK: call %swift.opaque* %initializeWithTake(%swift.opaque* noalias [[ADDR]], %swift.opaque* noalias %0, %swift.type* %T)
   copy_addr [take] %x to [initialization] %p : $*T
   // CHECK: ret %swift.error* [[BOX]]
   return %b : $Error
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index f6dcf60..5f0f4a5 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -2728,7 +2728,7 @@
 // CHECK-LABEL: define{{( protected)?}} private %swift.type* @create_generic_metadata_DynamicSinglePayload(%swift.type_pattern*, i8**) {{.*}} {
 // CHECK:   call void @swift_initEnumValueWitnessTableSinglePayload
 
-// CHECK-64-LABEL: define linkonce_odr hidden void @_T04enum17StructWithWeakVarVwxs(%swift.opaque* %dest, i32 %index, %swift.type* %StructWithWeakVar)
+// CHECK-64-LABEL: define linkonce_odr hidden void @_T04enum17StructWithWeakVarVwxs(%swift.opaque* noalias %dest, i32 %index, %swift.type* %StructWithWeakVar)
 // -- TODO: some pointless masking here.
 // -- TODO: should use EnumPayload word-chunking.
 // CHECK-64:         %1 = zext i32 %index to i128
@@ -2741,7 +2741,7 @@
 // --                             0x1__0000_0000_0000_0000
 // CHECK-64:         %6 = or i128 %5, 18446744073709551616
 
-// CHECK-LABEL: define linkonce_odr hidden i32 @_T04enum40MultiPayloadLessThan32BitsWithEmptyCasesOwug(%swift.opaque* %value
+// CHECK-LABEL: define linkonce_odr hidden i32 @_T04enum40MultiPayloadLessThan32BitsWithEmptyCasesOwug(%swift.opaque* noalias %value
 // CHECK:  [[VAL00:%.*]] = bitcast %swift.opaque* %value to %T4enum40MultiPayloadLessThan32BitsWithEmptyCasesO*
 // CHECK:  [[VAL01:%.*]] = bitcast %T4enum40MultiPayloadLessThan32BitsWithEmptyCasesO* [[VAL00]] to i8*
 // CHECK:  [[VAL02:%.*]] = load {{.*}} [[VAL01]]
@@ -2756,7 +2756,7 @@
 // CHECK:  [[VAL11:%.*]] = select i1 [[VAL10]], i32 [[VAL09]], i32 [[VAL07]]
 // CHECK:  ret i32 [[VAL11]]
 
-// CHECK-LABEL: define linkonce_odr hidden void @_T04enum40MultiPayloadLessThan32BitsWithEmptyCasesOwui(%swift.opaque* %value, i32 %tag
+// CHECK-LABEL: define linkonce_odr hidden void @_T04enum40MultiPayloadLessThan32BitsWithEmptyCasesOwui(%swift.opaque* noalias %value, i32 %tag
 // CHECK: entry:
 // CHECK:  [[VAL00:%.*]] = bitcast %swift.opaque* %value
 // CHECK:  [[VAL01:%.*]] = icmp sge i32 %tag, 0
diff --git a/test/IRGen/enum_dynamic_multi_payload.sil b/test/IRGen/enum_dynamic_multi_payload.sil
index 0d45571..9a60eef 100644
--- a/test/IRGen/enum_dynamic_multi_payload.sil
+++ b/test/IRGen/enum_dynamic_multi_payload.sil
@@ -343,7 +343,7 @@
   // CHECK:        [[COND:%.*]] = icmp ne i32 [[TAG]], 0
   // CHECK-NEXT:   br i1 [[COND]], label %[[NOOP:[0-9]+]], label %[[LEFT:[0-9]+]]
   // CHECK:      <label>:[[LEFT]]
-  // CHECK:        call void %destroy(%swift.opaque* {{%.*}}, %swift.type* %T)
+  // CHECK:        call void %destroy(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
   // CHECK:        br label %[[NOOP]]
   // CHECK:      <label>:[[NOOP]]
   destroy_addr %a : $*EitherOr<T, Builtin.Int64>
@@ -353,7 +353,7 @@
   // CHECK:        [[COND:%.*]] = icmp ne i32 [[TAG]], 0
   // CHECK-NEXT:   br i1 [[COND]], label %[[TRIVIAL:[0-9]+]], label %[[LEFT:[0-9]+]]
   // CHECK:      <label>:[[LEFT]]
-  // CHECK:        call %swift.opaque* %initializeWithTake(%swift.opaque* {{%.*}}, %swift.type* %T)
+  // CHECK:        call %swift.opaque* %initializeWithTake(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
   // CHECK:        br label %[[DONE:[0-9]+]]
   // CHECK:      <label>:[[TRIVIAL]]
   // CHECK:        call void @llvm.memcpy
@@ -378,7 +378,7 @@
   // CHECK-NEXT:     i32 1, label %[[RIGHT:[0-9]+]]
   // CHECK-NEXT:   ]
   // CHECK:      <label>:[[LEFT]]
-  // CHECK:        call void %destroy(%swift.opaque* {{%.*}}, %swift.type* %T)
+  // CHECK:        call void %destroy(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
   // CHECK:        br label %[[NOOP]]
   // CHECK:      <label>:[[RIGHT]]
   // CHECK:        call void {{.*}} @swift_rt_swift_release
@@ -390,7 +390,7 @@
   // CHECK:        [[COND:%.*]] = icmp ne i32 [[TAG]], 0
   // CHECK-NEXT:   br i1 [[COND]], label %[[TRIVIAL:[0-9]+]], label %[[LEFT:[0-9]+]]
   // CHECK:      <label>:[[LEFT]]
-  // CHECK:        call %swift.opaque* %initializeWithTake(%swift.opaque* {{%.*}}, %swift.type* %T)
+  // CHECK:        call %swift.opaque* %initializeWithTake(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
   // CHECK:        br label %[[DONE:[0-9]+]]
   // CHECK:      <label>:[[TRIVIAL]]
   // CHECK:        call void @llvm.memcpy
@@ -405,7 +405,7 @@
   // CHECK-NEXT:     i32 1, label %[[RIGHT:[0-9]+]]
   // CHECK-NEXT:   ]
   // CHECK:      <label>:[[LEFT]]
-  // CHECK:        call %swift.opaque* %initializeWithCopy(%swift.opaque* {{%.*}}, %swift.type* %T)
+  // CHECK:        call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias {{%.*}}, %swift.type* %T)
   // CHECK:        br label %[[DONE:[0-9]+]]
   // CHECK:      <label>:[[RIGHT]]
   // CHECK:        call void @swift_rt_swift_retain
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index d5051c9..eea396a 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -72,7 +72,7 @@
 // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 4
 // CHECK-NEXT: [[WITNESS:%.*]]  = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK-NEXT: call %swift.opaque* [[WITNESS_FN]](%swift.opaque* %0, %swift.opaque* %1, %swift.type* [[METADATA]])
+// CHECK-NEXT: call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* [[METADATA]])
 // CHECK-NEXT: ret void
 
   return m
@@ -88,7 +88,7 @@
 // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 4
 // CHECK-NEXT: [[WITNESS:%.*]]  = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK-NEXT: call %swift.opaque* [[WITNESS_FN]](%swift.opaque* %0, %swift.opaque* %1, %swift.type* [[METADATA]])
+// CHECK-NEXT: call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* [[METADATA]])
 // CHECK-NEXT: ret void
 
   return ia
@@ -104,7 +104,7 @@
 // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 19
 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* %0, i32 0, %swift.type* [[METADATA]])
+// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 0, %swift.type* [[METADATA]])
 
 // CHECK-NEXT: ret void
   return Medium.Paper
@@ -120,7 +120,7 @@
 // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
 // CHECK-NEXT: [[WITNESS:%.*]]  = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK-NEXT: [[COPY:%.*]] = call %swift.opaque* %initializeWithCopy(%swift.opaque* %0, %swift.opaque* %1, %swift.type* [[METADATA]])
+// CHECK-NEXT: [[COPY:%.*]] = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* [[METADATA]])
 
 // CHECK-NEXT: [[METADATA2:%.*]] = call %swift.type* @_T014resilient_enum6MediumOMa()
 // CHECK-NEXT: [[METADATA_ADDR2:%.*]] = bitcast %swift.type* [[METADATA2]] to i8***
@@ -130,12 +130,12 @@
 // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 19
 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* %0, i32 -2, %swift.type* [[METADATA2]])
+// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 -2, %swift.type* [[METADATA2]])
 
 // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 1
 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* %1, %swift.type* [[METADATA]])
+// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %1, %swift.type* [[METADATA]])
 
 // CHECK-NEXT: ret void
   return Medium.Postcard(s)
@@ -158,12 +158,12 @@
 // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK: [[ENUM_COPY:%.*]] = call %swift.opaque* [[WITNESS_FN]](%swift.opaque* [[ENUM_STORAGE]], %swift.opaque* %0, %swift.type* [[METADATA]])
+// CHECK: [[ENUM_COPY:%.*]] = call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.opaque* noalias %0, %swift.type* [[METADATA]])
 
 // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 17
 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK: [[TAG:%.*]] = call i32 %getEnumTag(%swift.opaque* [[ENUM_STORAGE]], %swift.type* [[METADATA]])
+// CHECK: [[TAG:%.*]] = call i32 %getEnumTag(%swift.opaque* noalias [[ENUM_STORAGE]], %swift.type* [[METADATA]])
 
 // CHECK: switch i32 [[TAG]], label %[[DEFAULT_CASE:.*]] [
 // CHECK:   i32 -1, label %[[PAMPHLET_CASE:.*]]
diff --git a/test/IRGen/enum_value_semantics.sil b/test/IRGen/enum_value_semantics.sil
index 71f8862..3e1d3e7 100644
--- a/test/IRGen/enum_value_semantics.sil
+++ b/test/IRGen/enum_value_semantics.sil
@@ -277,7 +277,7 @@
 
 
 // -- SinglePayloadNontrivial destroyBuffer
-// CHECK: define linkonce_odr hidden void @_T020enum_value_semantics23SinglePayloadNontrivialOwxx(%swift.opaque* [[OBJ:%.*]], %swift.type* %SinglePayloadNontrivial) {{.*}} {
+// CHECK: define linkonce_odr hidden void @_T020enum_value_semantics23SinglePayloadNontrivialOwxx(%swift.opaque* noalias [[OBJ:%.*]], %swift.type* %SinglePayloadNontrivial) {{.*}} {
 // CHECK:      [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %T20enum_value_semantics23SinglePayloadNontrivialO*
 // CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %T20enum_value_semantics23SinglePayloadNontrivialO* [[ADDR]] to i64*
 // CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
@@ -446,7 +446,7 @@
 
 
 // -- MultiPayloadNontrivial destroyBuffer
-// CHECK: define linkonce_odr hidden void @_T020enum_value_semantics22MultiPayloadNontrivialOwxx(%swift.opaque* [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivial)
+// CHECK: define linkonce_odr hidden void @_T020enum_value_semantics22MultiPayloadNontrivialOwxx(%swift.opaque* noalias [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivial)
 // CHECK:      [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %T20enum_value_semantics22MultiPayloadNontrivialO*
 // CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %T20enum_value_semantics22MultiPayloadNontrivialO* [[ADDR]] to { i64, i64 }*
 // CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
@@ -492,7 +492,7 @@
 
 // -- MultiPayloadNontrivialSpareBits destroyBuffer
 // CHECK-LABEL: define linkonce_odr hidden void @_T020enum_value_semantics31MultiPayloadNontrivialSpareBitsOwxx
-// CHECK-SAME: (%swift.opaque* [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivialSpareBits) {{.*}} {
+// CHECK-SAME: (%swift.opaque* noalias [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivialSpareBits) {{.*}} {
 // CHECK:      [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %T20enum_value_semantics31MultiPayloadNontrivialSpareBitsO*
 // CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %T20enum_value_semantics31MultiPayloadNontrivialSpareBitsO* [[ADDR]] to { i64, i64 }*
 // CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
diff --git a/test/IRGen/enum_value_semantics_special_cases.sil b/test/IRGen/enum_value_semantics_special_cases.sil
index e8bca44..c8c6e36 100644
--- a/test/IRGen/enum_value_semantics_special_cases.sil
+++ b/test/IRGen/enum_value_semantics_special_cases.sil
@@ -11,7 +11,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @_T034enum_value_semantics_special_cases18NullableRefcountedOwxx(%swift.opaque* %object, %swift.type* %NullableRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden void @_T034enum_value_semantics_special_cases18NullableRefcountedOwxx(%swift.opaque* noalias %object, %swift.type* %NullableRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T34enum_value_semantics_special_cases18NullableRefcountedO*
 // CHECK:   %1 = bitcast %T34enum_value_semantics_special_cases18NullableRefcountedO* %0 to %swift.refcounted**
@@ -20,7 +20,7 @@
 // CHECK:   ret void
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases18NullableRefcountedOwcp(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases18NullableRefcountedOwcp(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases18NullableRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases18NullableRefcountedO*
@@ -48,7 +48,7 @@
 // CHECK:   ret %swift.opaque* %6
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases18NullableRefcountedOwta(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases18NullableRefcountedOwta(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases18NullableRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases18NullableRefcountedO*
@@ -69,7 +69,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @_T034enum_value_semantics_special_cases23NullableBlockRefcountedOwxx(%swift.opaque* %object, %swift.type* %NullableBlockRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden void @_T034enum_value_semantics_special_cases23NullableBlockRefcountedOwxx(%swift.opaque* noalias %object, %swift.type* %NullableBlockRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
 // CHECK:   %1 = bitcast %T34enum_value_semantics_special_cases23NullableBlockRefcountedO* %0 to %objc_block**
@@ -78,7 +78,7 @@
 // CHECK:   ret void
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases23NullableBlockRefcountedOwcp(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases23NullableBlockRefcountedOwcp(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
@@ -106,7 +106,7 @@
 // CHECK:   ret %swift.opaque* %7
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases23NullableBlockRefcountedOwta(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases23NullableBlockRefcountedOwta(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
@@ -127,7 +127,7 @@
   case B
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @_T034enum_value_semantics_special_cases23MultipleEmptyRefcountedOwxx(%swift.opaque* %object, %swift.type* %MultipleEmptyRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden void @_T034enum_value_semantics_special_cases23MultipleEmptyRefcountedOwxx(%swift.opaque* noalias %object, %swift.type* %MultipleEmptyRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T34enum_value_semantics_special_cases23MultipleEmptyRefcountedO*
 // CHECK:   %1 = bitcast %T34enum_value_semantics_special_cases23MultipleEmptyRefcountedO* %0 to i64*
@@ -164,7 +164,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @_T034enum_value_semantics_special_cases13AllRefcountedOwxx(%swift.opaque* %object, %swift.type* %AllRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden void @_T034enum_value_semantics_special_cases13AllRefcountedOwxx(%swift.opaque* noalias %object, %swift.type* %AllRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T34enum_value_semantics_special_cases13AllRefcountedO*
 // CHECK:   %1 = bitcast %T34enum_value_semantics_special_cases13AllRefcountedO* %0 to i64*
@@ -176,7 +176,7 @@
 // CHECK:   ret void
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases13AllRefcountedOwcp(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %AllRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T034enum_value_semantics_special_cases13AllRefcountedOwcp(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %AllRefcounted) {{.*}} {
 // CHECK:         %3 = load i64, i64* %2, align 8
 // --                              0x3fffffffffffffff
 // CHECK:         %4 = and i64 %3, 4611686018427387903
diff --git a/test/IRGen/enum_value_semantics_special_cases_objc.sil b/test/IRGen/enum_value_semantics_special_cases_objc.sil
index f0d4362..b9e0569 100644
--- a/test/IRGen/enum_value_semantics_special_cases_objc.sil
+++ b/test/IRGen/enum_value_semantics_special_cases_objc.sil
@@ -10,7 +10,7 @@
   case Ref(Builtin.UnknownObject)
   case None
 }
-// CHECK-LABEL: define linkonce_odr hidden void @_T039enum_value_semantics_special_cases_objc22NullableObjCRefcountedOwxx(%swift.opaque* %object, %swift.type* %NullableObjCRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden void @_T039enum_value_semantics_special_cases_objc22NullableObjCRefcountedOwxx(%swift.opaque* noalias %object, %swift.type* %NullableObjCRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T39enum_value_semantics_special_cases_objc22NullableObjCRefcountedO*
 // CHECK:   %1 = bitcast %T39enum_value_semantics_special_cases_objc22NullableObjCRefcountedO* %0 to %objc_object**
@@ -31,7 +31,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @_T039enum_value_semantics_special_cases_objc18AllMixedRefcountedOwxx(%swift.opaque* %object, %swift.type* %AllMixedRefcounted) {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden void @_T039enum_value_semantics_special_cases_objc18AllMixedRefcountedOwxx(%swift.opaque* noalias %object, %swift.type* %AllMixedRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T39enum_value_semantics_special_cases_objc18AllMixedRefcountedO*
 // CHECK:   %1 = bitcast %T39enum_value_semantics_special_cases_objc18AllMixedRefcountedO* %0 to i64*
diff --git a/test/IRGen/existentials_opaque_boxed.sil b/test/IRGen/existentials_opaque_boxed.sil
index 71645c9..e505ec3 100644
--- a/test/IRGen/existentials_opaque_boxed.sil
+++ b/test/IRGen/existentials_opaque_boxed.sil
@@ -259,7 +259,7 @@
 // CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 1
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[DESTROY:%.*]] = bitcast i8* [[VW]] to void (%swift.opaque*, %swift.type*)*
-// CHECK:   call void [[DESTROY]](%swift.opaque* [[OPAQUE]], %swift.type* [[METADATA]])
+// CHECK:   call void [[DESTROY]](%swift.opaque* noalias [[OPAQUE]], %swift.type* [[METADATA]])
 // CHECK:   ret void
 //
 // CHECK: outline:
@@ -363,7 +363,7 @@
 // CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 4
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[INITWITHTAKE:%.*]] = bitcast i8* [[VW]] to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)*
-// CHECK:   call %swift.opaque* [[INITWITHTAKE]](%swift.opaque* [[TMPBUFFER_OPAQUE]], %swift.opaque* [[DESTBUFFER_OPAQUE]], %swift.type* [[DEST_TYPE]])
+// CHECK:   call %swift.opaque* [[INITWITHTAKE]](%swift.opaque* noalias [[TMPBUFFER_OPAQUE]], %swift.opaque* noalias [[DESTBUFFER_OPAQUE]], %swift.type* [[DEST_TYPE]])
 // CHECK:   br i1 [[SRC_ISINLINE]], label %dest-inline-src-inline, label %dest-inline-src-outline
 //
 // CHECK: dest-inline-src-inline:
@@ -375,7 +375,7 @@
 // CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[INITWITHCOPY:%.*]] = bitcast i8* [[VW]] to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)*
-// CHECK:   call %swift.opaque* [[INITWITHCOPY]](%swift.opaque* [[DESTBUFFER_OPAQUE]], %swift.opaque* [[SRCBUFFER_OPAQUE]], %swift.type* [[SRC_TYPE]])
+// CHECK:   call %swift.opaque* [[INITWITHCOPY]](%swift.opaque* noalias [[DESTBUFFER_OPAQUE]], %swift.opaque* noalias [[SRCBUFFER_OPAQUE]], %swift.type* [[SRC_TYPE]])
 // CHECK:   br label %dest-inline-cont
 //
 // CHECK: dest-inline-src-outline:
@@ -394,7 +394,7 @@
 // CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 1
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[DESTROY:%.*]] = bitcast i8* [[VW]] to void (%swift.opaque*, %swift.type*)*
-// CHECK:   call void [[DESTROY]](%swift.opaque* [[TMPBUFFER_OPAQUE]], %swift.type* [[DEST_TYPE]])
+// CHECK:   call void [[DESTROY]](%swift.opaque* noalias [[TMPBUFFER_OPAQUE]], %swift.type* [[DEST_TYPE]])
 // CHECK:   br label %done
 //
 // CHECK: dest-outline:
@@ -411,7 +411,7 @@
 // CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[INITWITHCOPY:%.*]] = bitcast i8* [[VW]] to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)*
-// CHECK:   call %swift.opaque* [[INITWITHCOPY]](%swift.opaque* [[DESTBUFFER_OPAQUE]], %swift.opaque* [[SRCBUFFER_OPAQUE]], %swift.type* [[SRC_TYPE]])
+// CHECK:   call %swift.opaque* [[INITWITHCOPY]](%swift.opaque* noalias [[DESTBUFFER_OPAQUE]], %swift.opaque* noalias [[SRCBUFFER_OPAQUE]], %swift.type* [[SRC_TYPE]])
 // CHECK:   br label %dest-outline-cont
 //
 // CHECK: dest-outline-src-outline:
@@ -505,7 +505,7 @@
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VWT]]
 // CHECK:   [[INITWITHCOPYBUFFER:%.*]] = bitcast i8* [[VW]]
-// CHECK:     call %swift.opaque* [[INITWITHCOPYBUFFER]]({{.*}} [[BUFFER_LOCAL_ADDR]], {{.*}} [[BUFFER_ARG_ADDR]], %swift.type* [[ARG_TYPE]])
+// CHECK:     call %swift.opaque* [[INITWITHCOPYBUFFER]]({{.*}} noalias [[BUFFER_LOCAL_ADDR]], {{.*}} noalias [[BUFFER_ARG_ADDR]], %swift.type* [[ARG_TYPE]])
 // CHECK:   ret void
 sil @test_initWithCopy_existential_addr : $@convention(thin) (@in Existential) -> () {
 bb0(%0 : $*Existential):
diff --git a/test/IRGen/generic_casts.swift b/test/IRGen/generic_casts.swift
index 8e32996..a9551dc 100644
--- a/test/IRGen/generic_casts.swift
+++ b/test/IRGen/generic_casts.swift
@@ -43,7 +43,7 @@
   // CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
   // CHECK: [[T_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
   // CHECK: [[T_TMP:%.*]] = bitcast i8* [[T_ALLOCA]] to %swift.opaque*
-  // CHECK: [[TEMP:%.*]] = call %swift.opaque* {{.*}}(%swift.opaque* [[T_TMP]], %swift.opaque* %0, %swift.type* %T)
+  // CHECK: [[TEMP:%.*]] = call %swift.opaque* {{.*}}(%swift.opaque* noalias [[T_TMP]], %swift.opaque* noalias %0, %swift.type* %T)
   // CHECK: [[T0:%.*]] = bitcast %TSi* [[INT_TEMP]] to %swift.opaque*
   // CHECK: call i1 @swift_rt_swift_dynamicCast(%swift.opaque* [[T0]], %swift.opaque* [[T_TMP]], %swift.type* %T, %swift.type* @_T0SiN, i64 7)
   // CHECK: [[T0:%.*]] = getelementptr inbounds %TSi, %TSi* [[INT_TEMP]], i32 0, i32 0
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 757207f..aa0b603 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -171,21 +171,21 @@
 // Check that we directly delegate buffer witnesses to a single dynamic field:
 
 //   initializeBufferWithCopyOfBuffer
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T015generic_structs13SingleDynamicVwCP([24 x i8]* %dest, [24 x i8]* %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T015generic_structs13SingleDynamicVwCP([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
 // CHECK:      %T = load %swift.type*,
 // CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
 // CHECK-NEXT: %T.valueWitnesses = load i8**, i8*** [[T1]]
 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** %T.valueWitnesses,
 // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[T1]] to %swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)*
-// CHECK-NEXT: [[T0:%.*]] = call %swift.opaque* [[FN]]([24 x i8]* %dest, [24 x i8]* %src, %swift.type* %T)
+// CHECK-NEXT: [[T0:%.*]] = call %swift.opaque* [[FN]]([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %T)
 // CHECK-NEXT: [[T1:%.*]] = bitcast %swift.opaque* [[T0]] to {{.*}}
 // CHECK-NEXT: [[T2:%.*]] = bitcast {{.*}} [[T1]] to %swift.opaque*
 // CHECK-NEXT: ret %swift.opaque* [[T2]]
 
 
 //   initializeBufferWithTakeOfBuffer
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T015generic_structs13SingleDynamicVwTK([24 x i8]* %dest, [24 x i8]* %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T015generic_structs13SingleDynamicVwTK([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
 // CHECK:      %T = load %swift.type*,
 // CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
@@ -193,7 +193,7 @@
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 6
 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]],
 // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[T1]] to %swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)*
-// CHECK-NEXT: [[T0:%.*]] = call %swift.opaque* [[FN]]([24 x i8]* %dest, [24 x i8]* %src, %swift.type* %T)
+// CHECK-NEXT: [[T0:%.*]] = call %swift.opaque* [[FN]]([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %T)
 // CHECK-NEXT: [[T1:%.*]] = bitcast %swift.opaque* [[T0]] to {{.*}}
 // CHECK-NEXT: [[T2:%.*]] = bitcast {{.*}} [[T1]] to %swift.opaque*
 // CHECK-NEXT: ret %swift.opaque* [[T2]]
diff --git a/test/IRGen/generic_tuples.swift b/test/IRGen/generic_tuples.swift
index 39a146d..df9016f 100644
--- a/test/IRGen/generic_tuples.swift
+++ b/test/IRGen/generic_tuples.swift
@@ -25,14 +25,14 @@
 // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]], align 8
 // CHECK-NEXT: [[INITIALIZE_WITH_COPY:%.*]] = bitcast i8* [[WITNESS]] to [[OPAQUE]]* ([[OPAQUE]]*, [[OPAQUE]]*, [[TYPE]]*)*
-// CHECK-NEXT: [[X:%.*]] = call [[OPAQUE]]* [[INITIALIZE_WITH_COPY]]([[OPAQUE]]* [[X_TMP]], [[OPAQUE]]* {{.*}}, [[TYPE]]* %T)
+// CHECK-NEXT: [[X:%.*]] = call [[OPAQUE]]* [[INITIALIZE_WITH_COPY]]([[OPAQUE]]* noalias [[X_TMP]], [[OPAQUE]]* noalias {{.*}}, [[TYPE]]* %T)
 //   Copy 'x' into the first result.
-// CHECK-NEXT: call [[OPAQUE]]* [[INITIALIZE_WITH_COPY]]([[OPAQUE]]* %0, [[OPAQUE]]* [[X_TMP]], [[TYPE]]* %T)
+// CHECK-NEXT: call [[OPAQUE]]* [[INITIALIZE_WITH_COPY]]([[OPAQUE]]* noalias %0, [[OPAQUE]]* noalias [[X_TMP]], [[TYPE]]* %T)
 //   Copy 'x' into the second element.
 // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 4
 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]], align 8
 // CHECK-NEXT: [[TAKE_FN:%.*]] = bitcast i8* [[WITNESS]] to [[OPAQUE]]* ([[OPAQUE]]*, [[OPAQUE]]*, [[TYPE]]*)*
-// CHECK-NEXT: call [[OPAQUE]]* [[TAKE_FN]]([[OPAQUE]]* %1, [[OPAQUE]]* [[X_TMP]], [[TYPE]]* %T)
+// CHECK-NEXT: call [[OPAQUE]]* [[TAKE_FN]]([[OPAQUE]]* noalias %1, [[OPAQUE]]* noalias [[X_TMP]], [[TYPE]]* %T)
 
 struct S {}
 
diff --git a/test/IRGen/indirect_return.swift b/test/IRGen/indirect_return.swift
index 089ac10..222b80a 100644
--- a/test/IRGen/indirect_return.swift
+++ b/test/IRGen/indirect_return.swift
@@ -6,6 +6,6 @@
 func generic_get<T>(p: UnsafeMutablePointer<T>) -> T {
   // CHECK-NOT: [[T0:%.*]] = call i8* @_TFVs20UnsafeMutablePointerl6memoryQ_(i8* %1, %swift.type* %T)
   // CHECK: [[T1:%.*]] = bitcast i8* {{%.*}} to %swift.opaque*
-  // CHECK: call %swift.opaque* {{%.*}}(%swift.opaque* %0, %swift.opaque* [[T1]], %swift.type* %T)
+  // CHECK: call %swift.opaque* {{%.*}}(%swift.opaque* noalias %0, %swift.opaque* noalias [[T1]], %swift.type* %T)
   return p.pointee
 }
diff --git a/test/IRGen/lifetime.sil b/test/IRGen/lifetime.sil
index bb5a1c4..6d9cb56 100644
--- a/test/IRGen/lifetime.sil
+++ b/test/IRGen/lifetime.sil
@@ -32,14 +32,14 @@
 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align
 // CHECK-NEXT: [[INIT_WITH_COPY_FN:%.*]] = bitcast i8* [[T4]] to [[OPAQUE]]* ([[OPAQUE]]*, [[OPAQUE]]*, [[TYPE]]*)*
-// CHECK-NEXT: [[Y:%.*]] = call [[OPAQUE]]* [[INIT_WITH_COPY_FN]]([[OPAQUE]]* [[Y_TMP]], [[OPAQUE]]* [[X:%.*]], [[TYPE]]* %T)
+// CHECK-NEXT: [[Y:%.*]] = call [[OPAQUE]]* [[INIT_WITH_COPY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[OPAQUE]]* noalias [[X:%.*]], [[TYPE]]* %T)
 //   Destroy 'y'.
 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 1
 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align
 // CHECK-NEXT: [[DESTROY_FN:%.*]] = bitcast i8* [[T4]] to void ([[OPAQUE]]*, [[TYPE]]*)*
-// CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* [[Y_TMP]], [[TYPE]]* %T)
+// CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[TYPE]]* %T)
 //   Destroy 'x'.
-// CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* [[X]], [[TYPE]]* %T)
+// CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* noalias [[X]], [[TYPE]]* %T)
 // CHECK-NEXT: [[YBUFLIFE:%.*]] = bitcast [[OPAQUE]]* [[Y_TMP]] to i8*
 // CHECK-NEXT: call void @llvm.lifetime.end({{(i32|i64)}} -1, i8* [[YBUFLIFE]])
 //   Return.
@@ -71,19 +71,19 @@
 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align
 // CHECK-NEXT: [[INIT_WITH_COPY_FN:%.*]] = bitcast i8* [[T4]] to [[OPAQUE]]* ([[OPAQUE]]*, [[OPAQUE]]*, [[TYPE]]*)*
-// CHECK-NEXT: [[Y:%.*]] = call [[OPAQUE]]* [[INIT_WITH_COPY_FN]]([[OPAQUE]]* [[Y_TMP]], [[OPAQUE]]* [[X:%.*]], [[TYPE]]* %T)
+// CHECK-NEXT: [[Y:%.*]] = call [[OPAQUE]]* [[INIT_WITH_COPY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[OPAQUE]]* noalias [[X:%.*]], [[TYPE]]* %T)
 //   Destroy 'y'.
 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 1
 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align
 // CHECK-NEXT: [[DESTROY_FN:%.*]] = bitcast i8* [[T4]] to void ([[OPAQUE]]*, [[TYPE]]*)*
-// CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* [[Y_TMP]], [[TYPE]]* %T)
+// CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[TYPE]]* %T)
 //   Copy 'x' into 'y' again, this time as a take.
 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 4
 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align
 // CHECK-NEXT: [[TAKE_FN:%.*]] = bitcast i8* [[T4]] to [[OPAQUE]]* ([[OPAQUE]]*, [[OPAQUE]]*, [[TYPE]]*)*
-// CHECK-NEXT: call [[OPAQUE]]* [[TAKE_FN]]([[OPAQUE]]* [[Y_TMP]], [[OPAQUE]]* [[X]], [[TYPE]]* %T)
+// CHECK-NEXT: call [[OPAQUE]]* [[TAKE_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[OPAQUE]]* noalias [[X]], [[TYPE]]* %T)
 //   Destroy 'y'.
-// CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* [[Y_TMP]], [[TYPE]]* %T)
+// CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[TYPE]]* %T)
 // CHECK-NEXT: [[YBUFLIFE:%.*]] = bitcast [[OPAQUE]]* [[Y_TMP]] to i8*
 // CHECK-NEXT: call void @llvm.lifetime.end({{(i32|i64)}} -1, i8* [[YBUFLIFE]])
 //   Return.
diff --git a/test/IRGen/opaque_values_irgen.sil b/test/IRGen/opaque_values_irgen.sil
index d03c1a8..c1635a6 100644
--- a/test/IRGen/opaque_values_irgen.sil
+++ b/test/IRGen/opaque_values_irgen.sil
@@ -7,7 +7,7 @@
 // CHECK: define hidden swiftcc void @f010_irgen_identity(%swift.opaque* noalias nocapture sret, %swift.opaque* noalias nocapture, %swift.type* %T)
 // CHECK: entry:
 // CHECK-NOT: call
-// CHECK: %{{.*}} = call %swift.opaque* %initializeWithTake(%swift.opaque* %0, %swift.opaque* %1, %swift.type* %T)
+// CHECK: %{{.*}} = call %swift.opaque* %initializeWithTake(%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* %T)
 // CHECK-NOT: call
 // CHECK: ret void
 sil hidden @f010_irgen_identity : $@convention(thin) <T> (@in T) -> @out T {
diff --git a/test/IRGen/struct_resilience.swift b/test/IRGen/struct_resilience.swift
index dfb167d..e46b196 100644
--- a/test/IRGen/struct_resilience.swift
+++ b/test/IRGen/struct_resilience.swift
@@ -32,7 +32,7 @@
 // CHECK: [[WITNESS_PTR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_PTR]]
 // CHECK: [[initializeWithCopy:%.*]] = bitcast i8* [[WITNESS]]
-// CHECK: [[STRUCT_LOC:%.*]] = call %swift.opaque* [[initializeWithCopy]](%swift.opaque* [[STRUCT_ADDR]], %swift.opaque* %1, %swift.type* [[METADATA]])
+// CHECK: [[STRUCT_LOC:%.*]] = call %swift.opaque* [[initializeWithCopy]](%swift.opaque* noalias [[STRUCT_ADDR]], %swift.opaque* noalias %1, %swift.type* [[METADATA]])
 
 // CHECK: [[FN:%.*]] = bitcast i8* %2 to void (%swift.opaque*, %swift.opaque*, %swift.refcounted*)*
 // CHECK: call swiftcc void [[FN]](%swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture [[STRUCT_ADDR]], %swift.refcounted* swiftself %3)
@@ -40,7 +40,7 @@
 // CHECK: [[WITNESS_PTR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 1
 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_PTR]]
 // CHECK: [[destroy:%.*]] = bitcast i8* [[WITNESS]] to void (%swift.opaque*, %swift.type*)*
-// CHECK: call void [[destroy]](%swift.opaque* %1, %swift.type* [[METADATA]])
+// CHECK: call void [[destroy]](%swift.opaque* noalias %1, %swift.type* [[METADATA]])
 // CHECK: ret void
 
   return f(s)
diff --git a/test/IRGen/unowned.sil b/test/IRGen/unowned.sil
index 274b744..f3545b0 100644
--- a/test/IRGen/unowned.sil
+++ b/test/IRGen/unowned.sil
@@ -46,7 +46,7 @@
 // Value witnesses for A:
 
 //   initializeBufferWithCopyOfBuffer
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T07unowned1AVwCP([[BUFFER:\[24 x i8\]]]* [[DESTBUF:%.*]], [[BUFFER]]* [[SRCBUF:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T07unowned1AVwCP([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -60,7 +60,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   destroy
-// CHECK:    define linkonce_odr hidden void @_T07unowned1AVwxx([[OPAQUE]]* [[ARG:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden void @_T07unowned1AVwxx([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
 // CHECK:      [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]*
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0
 // CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]*
@@ -69,7 +69,7 @@
 // CHECK-NEXT: ret void
 
 //   initializeWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T07unowned1AVwcp([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T07unowned1AVwcp([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -99,7 +99,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   assignWithTake
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T07unowned1AVwta([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T07unowned1AVwta([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
diff --git a/test/IRGen/unowned_objc.sil b/test/IRGen/unowned_objc.sil
index f521a94..7c6674e 100644
--- a/test/IRGen/unowned_objc.sil
+++ b/test/IRGen/unowned_objc.sil
@@ -149,7 +149,7 @@
 // Value witnesses for A:
 
 //   initializeBufferWithCopyOfBuffer
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T012unowned_objc1AVwCP([[BUFFER:\[24 x i8\]]]* [[DESTBUF:%.*]], [[BUFFER]]* [[SRCBUF:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T012unowned_objc1AVwCP([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -163,7 +163,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   destroy
-// CHECK:    define linkonce_odr hidden void @_T012unowned_objc1AVwxx([[OPAQUE]]* [[ARG:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden void @_T012unowned_objc1AVwxx([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
 // CHECK:      [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]*
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0
 // CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]*
@@ -172,7 +172,7 @@
 // CHECK-NEXT: ret void
 
 //   initializeWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T012unowned_objc1AVwcp([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T012unowned_objc1AVwcp([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -202,7 +202,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   assignWithTake
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T012unowned_objc1AVwta([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T012unowned_objc1AVwta([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
diff --git a/test/IRGen/weak.sil b/test/IRGen/weak.sil
index 8eae972..1870514 100644
--- a/test/IRGen/weak.sil
+++ b/test/IRGen/weak.sil
@@ -104,7 +104,7 @@
 // Value witnesses for A:
 
 //   initializeBufferWithCopyOfBuffer
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T04weak1AVwCP([[BUFFER:\[24 x i8\]]]* [[DESTBUF:%.*]], [[BUFFER]]* [[SRCBUF:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T04weak1AVwCP([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -114,14 +114,14 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   destroy
-// CHECK:    define linkonce_odr hidden void @_T04weak1AVwxx([[OPAQUE]]* [[ARG:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden void @_T04weak1AVwxx([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
 // CHECK:      [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]*
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0
 // CHECK-NEXT: call void @swift_weakDestroy([[WEAK]]* [[T1]])
 // CHECK-NEXT: ret void
 
 //   initializeWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T04weak1AVwcp([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T04weak1AVwcp([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -141,7 +141,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   assignWithTake
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T04weak1AVwta([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @_T04weak1AVwta([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
diff --git a/test/IRGen/weak_value_witnesses.sil b/test/IRGen/weak_value_witnesses.sil
index 9385f96..dcfa0d2 100644
--- a/test/IRGen/weak_value_witnesses.sil
+++ b/test/IRGen/weak_value_witnesses.sil
@@ -40,7 +40,7 @@
 // CHECK-NOT: @_T020weak_value_witnesses6NoWeakVwTK
 
 // Weak references must be taken by swift_weakTakeInit.
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T020weak_value_witnesses8SomeWeakVwtk(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %SomeWeak)
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T020weak_value_witnesses8SomeWeakVwtk(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %SomeWeak)
 // CHECK:         call void @swift_weakTakeInit
 
 // CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T020weak_value_witnesses8SomeWeakVwTK(
@@ -57,5 +57,5 @@
 // CHECK-NEXT: ret %swift.opaque* [[T0]]
 
 // Generic types must be taken using their value witness.
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T020weak_value_witnesses3GenVwtk(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %"Gen<T>")
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_T020weak_value_witnesses3GenVwtk(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %"Gen<T>")
 // CHECK:         call %swift.opaque* %initializeWithTake