Switch all of the indirect-call code in IRGen to FunctionPointer.

To make this stick, I've disallowed direct use of that overload of
CreateCall.  I've left the Constant overloads available, but eventually
we might want to consider fixing those, too, just to get all of this
code out of the business of manually remembering to pass around
attributes and calling conventions.

The test changes reflect the fact that we weren't really setting
attributes consistently at all, in this case on value witnesses.
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