Merge pull request #20952 from xwu/stdlib-style-fixes

diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def
index 432f60e..f88c975 100644
--- a/include/swift/AST/Builtins.def
+++ b/include/swift/AST/Builtins.def
@@ -478,14 +478,6 @@
 BUILTIN_MISC_OPERATION(SToUCheckedTrunc, "s_to_u_checked_trunc", "n", Special)
 BUILTIN_MISC_OPERATION(UToUCheckedTrunc, "u_to_u_checked_trunc", "n", Special)
 
-/// Checked conversions for signed <-> unsigned integers of the same size.
-/// Returns a tuple containing the conversion result as well as
-/// the sign error / overflow bit.
-BUILTIN_MISC_OPERATION(SUCheckedConversion,
-                       "s_to_u_checked_conversion", "n", Special)
-BUILTIN_MISC_OPERATION(USCheckedConversion,
-                       "u_to_s_checked_conversion", "n", Special)
-
 /// IntToFPWithOverflow has type (Integer) -> Float
 BUILTIN_MISC_OPERATION(IntToFPWithOverflow, "itofp_with_overflow", "n", Special)
 
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index dd1d1e9..658fef3 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -5631,10 +5631,6 @@
     return getSelfAccessKind() == SelfAccessKind::__Consuming;
   }
 
-  TypeLoc getReturnTypeLoc() const {
-    return FnRetType;
-  }
-  
   SelfAccessKind getSelfAccessKind() const {
     return static_cast<SelfAccessKind>(Bits.FuncDecl.SelfAccess);
   }
diff --git a/include/swift/SIL/PatternMatch.h b/include/swift/SIL/PatternMatch.h
index b5c1313..ae3fc3e 100644
--- a/include/swift/SIL/PatternMatch.h
+++ b/include/swift/SIL/PatternMatch.h
@@ -715,13 +715,6 @@
 // if any of the sub-matchers succeed.
 //
 
-/// Matcher for any of the builtin checked conversions.
-template <typename T0>
-inline typename OneOf_match<BuiltinApplyTy<T0>, BuiltinApplyTy<T0>>::Ty
-m_CheckedConversion(const T0 &Op0) {
-  return m_USCheckedConversion(Op0) || m_SUCheckedConversion(Op0);
-}
-
 /// Matcher for any of the builtin ExtOrBitCast instructions.
 template <typename T0>
 inline typename OneOf_match<BuiltinApplyTy<T0>, BuiltinApplyTy<T0>>::Ty
diff --git a/include/swift/SILOptimizer/Utils/Existential.h b/include/swift/SILOptimizer/Utils/Existential.h
index 4ac1807..fa0f3c6 100644
--- a/include/swift/SILOptimizer/Utils/Existential.h
+++ b/include/swift/SILOptimizer/Utils/Existential.h
@@ -35,7 +35,7 @@
 /// alloc_stack user \p ASIUser.
 /// If the value is copied from another stack location, \p isCopied is set to
 /// true.
-SILValue getAddressOfStackInit(AllocStackInst *ASI, SILInstruction *ASIUser,
+SILValue getAddressOfStackInit(SILValue allocStackAddr, SILInstruction *ASIUser,
                                bool &isCopied);
 
 /// Find the init_existential, which could be used to determine a concrete
diff --git a/include/swift/SILOptimizer/Utils/Local.h b/include/swift/SILOptimizer/Utils/Local.h
index f5cb3dc..f0348a0 100644
--- a/include/swift/SILOptimizer/Utils/Local.h
+++ b/include/swift/SILOptimizer/Utils/Local.h
@@ -127,6 +127,13 @@
                                       SILValue Value,
                                       SILType SrcTy,
                                       SILType DestTy);
+/// Peek through trivial Enum initialization, typically for pointless
+/// Optionals.
+///
+/// The returned InitEnumDataAddr dominates the given
+/// UncheckedTakeEnumDataAddrInst.
+InitEnumDataAddrInst *
+findInitAddressForTrivialEnum(UncheckedTakeEnumDataAddrInst *UTEDAI);
 
 /// Returns a project_box if it is the next instruction after \p ABI and
 /// and has \p ABI as operand. Otherwise it creates a new project_box right
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index 931af61..64abf0d 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -1106,19 +1106,6 @@
   return getBuiltinFunction(Id, { InTy }, ResultTy);
 }
 
-static ValueDecl *getCheckedConversionOperation(ASTContext &Context,
-                                                Identifier Id,
-                                                Type Ty) {
-  Type BuiltinTy = Ty->getAs<BuiltinIntegerType>();
-  if (!BuiltinTy)
-    return nullptr;
-
-  Type SignErrorBitTy = BuiltinIntegerType::get(1, Context);
-  TupleTypeElt ResultElts[] = { BuiltinTy, SignErrorBitTy };
-  Type ResultTy = TupleType::get(ResultElts, Context);
-  return getBuiltinFunction(Id, { BuiltinTy }, ResultTy);
-}
-
 static ValueDecl *getIntToFPWithOverflowOperation(ASTContext &Context,
                                                   Identifier Id, Type InputTy,
                                                   Type OutputTy) {
@@ -1853,11 +1840,6 @@
     if (Types.size() != 2) return nullptr;
     return getCheckedTruncOperation(Context, Id, Types[0], Types[1], false);
 
-  case BuiltinValueKind::SUCheckedConversion:
-  case BuiltinValueKind::USCheckedConversion:
-    if (Types.size() != 1) return nullptr;
-    return getCheckedConversionOperation(Context, Id, Types[0]);
-
   case BuiltinValueKind::ClassifyBridgeObject:
     if (!Types.empty()) return nullptr;
     return getClassifyBridgeObject(Context, Id);
diff --git a/lib/IDE/SyntaxModel.cpp b/lib/IDE/SyntaxModel.cpp
index c88a2e9..adee7cf 100644
--- a/lib/IDE/SyntaxModel.cpp
+++ b/lib/IDE/SyntaxModel.cpp
@@ -749,7 +749,7 @@
                         AFD->getSignatureSourceRange());
     if (FD) {
       SN.TypeRange = charSourceRangeFromSourceRange(SM,
-                                    FD->getReturnTypeLoc().getSourceRange());
+                                    FD->getBodyResultTypeLoc().getSourceRange());
     }
     pushStructureNode(SN, AFD);
   } else if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
diff --git a/lib/IRGen/GenBuiltin.cpp b/lib/IRGen/GenBuiltin.cpp
index 8607de9..3dbbf68 100644
--- a/lib/IRGen/GenBuiltin.cpp
+++ b/lib/IRGen/GenBuiltin.cpp
@@ -758,22 +758,6 @@
     return out.add(OverflowFlag);
   }
 
-  if (Builtin.ID == BuiltinValueKind::SUCheckedConversion ||
-      Builtin.ID == BuiltinValueKind::USCheckedConversion) {
-    auto Ty =
-      IGF.IGM.getStorageTypeForLowered(Builtin.Types[0]->getCanonicalType());
-
-    // Report a sign error if the input parameter is a negative number, when
-    // interpreted as signed.
-    llvm::Value *Arg = args.claimNext();
-    llvm::Value *Zero = llvm::ConstantInt::get(Ty, 0);
-    llvm::Value *OverflowFlag = IGF.Builder.CreateICmpSLT(Arg, Zero);
-
-    // Return the tuple: (the result (same as input), the overflow flag).
-    out.add(Arg);
-    return out.add(OverflowFlag);
-  }
-
   // We are currently emitting code for '_convertFromBuiltinIntegerLiteral',
   // which will call the builtin and pass it a non-compile-time-const parameter.
   if (Builtin.ID == BuiltinValueKind::IntToFPWithOverflow) {
diff --git a/lib/SIL/OperandOwnership.cpp b/lib/SIL/OperandOwnership.cpp
index 155d6fe..2e4ddda 100644
--- a/lib/SIL/OperandOwnership.cpp
+++ b/lib/SIL/OperandOwnership.cpp
@@ -1122,7 +1122,6 @@
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, SSubOver)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, SToSCheckedTrunc)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, SToUCheckedTrunc)
-CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, SUCheckedConversion)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, Shl)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, Sizeof)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, StaticReport)
@@ -1140,7 +1139,6 @@
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, UIToFP)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, UMulOver)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, URem)
-CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, USCheckedConversion)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, USubOver)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, UToSCheckedTrunc)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, UToUCheckedTrunc)
diff --git a/lib/SIL/ValueOwnership.cpp b/lib/SIL/ValueOwnership.cpp
index 7159493..5c3e131 100644
--- a/lib/SIL/ValueOwnership.cpp
+++ b/lib/SIL/ValueOwnership.cpp
@@ -479,8 +479,6 @@
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, SToSCheckedTrunc)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, SToUCheckedTrunc)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, UToUCheckedTrunc)
-CONSTANT_OWNERSHIP_BUILTIN(Trivial, SUCheckedConversion)
-CONSTANT_OWNERSHIP_BUILTIN(Trivial, USCheckedConversion)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, IntToFPWithOverflow)
 
 // This is surprising, Builtin.unreachable returns a "Never" value which is
diff --git a/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp b/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp
index 09e203f..21a7c05 100644
--- a/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp
+++ b/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp
@@ -492,18 +492,6 @@
         return Result;
     }
 
-    // trunc(tuple_extract(conversion(extOrBitCast(x))))) -> x
-    if (match(Op, m_TupleExtractInst(
-                   m_CheckedConversion(
-                     m_ExtOrBitCast(m_SILValue(Result))), 0))) {
-      // If the top bit of Result is known to be 0, then
-      // it is safe to replace the whole pattern by original bits of x
-      if (Result->getType() == BI->getType()) {
-        if (auto signBit = computeSignBit(Result))
-          if (!signBit.getValue())
-            return Result;
-      }
-    }
     return SILValue();
   }
 
@@ -639,23 +627,6 @@
   switch (Builtin.ID) {
   default: break;
 
-  case BuiltinValueKind::SUCheckedConversion:
-  case BuiltinValueKind::USCheckedConversion: {
-    OperandValueArrayRef Args = BI->getArguments();
-    const SILValue &Op = Args[0];
-    if (auto signBit = computeSignBit(Op))
-      if (!signBit.getValue())
-        return Op;
-    SILValue Result;
-    // CheckedConversion(ExtOrBitCast(x)) -> x
-    if (match(BI, m_CheckedConversion(m_ExtOrBitCast(m_SILValue(Result)))))
-      if (Result->getType() == BI->getType().getTupleElementType(0)) {
-        assert (!computeSignBit(Result).getValue() && "Sign bit should be 0");
-        return Result;
-      }
-    }
-    break;
-
   case BuiltinValueKind::UToSCheckedTrunc:
   case BuiltinValueKind::UToUCheckedTrunc:
   case BuiltinValueKind::SToUCheckedTrunc:
diff --git a/lib/SILOptimizer/Analysis/ValueTracking.cpp b/lib/SILOptimizer/Analysis/ValueTracking.cpp
index 02b71d4..58d0e3a 100644
--- a/lib/SILOptimizer/Analysis/ValueTracking.cpp
+++ b/lib/SILOptimizer/Analysis/ValueTracking.cpp
@@ -296,25 +296,6 @@
         continue;
       }
 
-      // Source and target type sizes are the same.
-      // S->U conversion can only succeed if
-      // the sign bit of its operand is 0, i.e. it is >= 0.
-      // The sign bit of a result is 0 only if the sign
-      // bit of a source operand is 0.
-      case BuiltinValueKind::SUCheckedConversion:
-        Value = BI->getArguments()[0];
-        continue;
-
-      // Source and target type sizes are the same.
-      // U->S conversion can only succeed if
-      // the top bit of its operand is 0, i.e.
-      // it is representable as a signed integer >=0.
-      // The sign bit of a result is 0 only if the sign
-      // bit of a source operand is 0.
-      case BuiltinValueKind::USCheckedConversion:
-        Value = BI->getArguments()[0];
-        continue;
-
       // Sign bit of the operand is promoted.
       case BuiltinValueKind::SExt:
         Value = BI->getArguments()[0];
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 51dc183..c6fbe6b 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -722,6 +722,13 @@
   SILValue existentialAddr =
       cast<InitExistentialAddrInst>(InitExistential)->getOperand();
 
+  // If we peeked through an InitEnumDataAddr or some such, then don't assume we
+  // can reuse the copied value. It's likely destroyed by
+  // UncheckedTakeEnumDataInst before the copy.
+  auto *ASI = dyn_cast<AllocStackInst>(existentialAddr);
+  if (!ASI)
+    return false;
+
   // Return true only if the given value is guaranteed to be initialized across
   // the given call site.
   //
diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp
index d73f09b..2ca1417 100644
--- a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp
+++ b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp
@@ -122,8 +122,6 @@
     case BuiltinValueKind::SToUCheckedTrunc:
     case BuiltinValueKind::SToSCheckedTrunc:
     case BuiltinValueKind::UToUCheckedTrunc:
-    case BuiltinValueKind::SUCheckedConversion:
-    case BuiltinValueKind::USCheckedConversion:
     case BuiltinValueKind::IntToFPWithOverflow:
     case BuiltinValueKind::ZeroInitializer:
     case BuiltinValueKind::Once:
diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp
index 0afc9a6..0b4de9a 100644
--- a/lib/SILOptimizer/Utils/ConstExpr.cpp
+++ b/lib/SILOptimizer/Utils/ConstExpr.cpp
@@ -210,8 +210,6 @@
     if (!operand.isConstant())
       return operand;
 
-    // TODO: SUCheckedConversion/USCheckedConversion
-
     // Implement support for s_to_s_checked_trunc_Int2048_Int64 and other
     // checking integer truncates.  These produce a tuple of the result value
     // and an overflow bit.
diff --git a/lib/SILOptimizer/Utils/ConstantFolding.cpp b/lib/SILOptimizer/Utils/ConstantFolding.cpp
index 259c08e..0bc6a21 100644
--- a/lib/SILOptimizer/Utils/ConstantFolding.cpp
+++ b/lib/SILOptimizer/Utils/ConstantFolding.cpp
@@ -674,9 +674,7 @@
   assert(Builtin.ID == BuiltinValueKind::SToSCheckedTrunc ||
          Builtin.ID == BuiltinValueKind::UToUCheckedTrunc ||
          Builtin.ID == BuiltinValueKind::SToUCheckedTrunc ||
-         Builtin.ID == BuiltinValueKind::UToSCheckedTrunc ||
-         Builtin.ID == BuiltinValueKind::SUCheckedConversion ||
-         Builtin.ID == BuiltinValueKind::USCheckedConversion);
+         Builtin.ID == BuiltinValueKind::UToSCheckedTrunc);
 
   // Check if we are converting a constant integer.
   OperandValueArrayRef Args = BI->getArguments();
@@ -688,11 +686,9 @@
   auto SrcBitWidth = SrcVal.getBitWidth();
 
   bool DstTySigned = (Builtin.ID == BuiltinValueKind::SToSCheckedTrunc ||
-                      Builtin.ID == BuiltinValueKind::UToSCheckedTrunc ||
-                      Builtin.ID == BuiltinValueKind::USCheckedConversion);
+                      Builtin.ID == BuiltinValueKind::UToSCheckedTrunc);
   bool SrcTySigned = (Builtin.ID == BuiltinValueKind::SToSCheckedTrunc ||
-                      Builtin.ID == BuiltinValueKind::SToUCheckedTrunc ||
-                      Builtin.ID == BuiltinValueKind::SUCheckedConversion);
+                      Builtin.ID == BuiltinValueKind::SToUCheckedTrunc);
 
   // Get source type and bit width.
   auto SrcTy = Builtin.Types[0]->castTo<AnyBuiltinIntegerType>();
@@ -705,44 +701,33 @@
   bool OverflowError;
   Type DstTy;
 
-  // Process conversions signed <-> unsigned for same size integers.
-  if (Builtin.ID == BuiltinValueKind::SUCheckedConversion ||
-      Builtin.ID == BuiltinValueKind::USCheckedConversion) {
-    DstTy = SrcTy;
+  assert(Builtin.Types.size() == 2);
+  DstTy = Builtin.Types[1];
+  uint32_t DstBitWidth =
+    DstTy->castTo<BuiltinIntegerType>()->getGreatestWidth();
+
+  assert((DstBitWidth < SrcBitWidth || !SrcTy->getWidth().isFixedWidth()) &&
+         "preconditions on builtin trunc operations should prevent"
+         "fixed-width truncations that actually extend");
+
+  // The only way a true extension can overflow is if the value is
+  // negative and the result is unsigned.
+  if (DstBitWidth > SrcBitWidth) {
+    OverflowError = (SrcTySigned && !DstTySigned && SrcVal.isNegative());
+    Result = (SrcTySigned ? SrcVal.sext(DstBitWidth)
+                          : SrcVal.zext(DstBitWidth));
+
+  // A same-width change can overflow if the top bit disagrees.
+  } else if (DstBitWidth == SrcBitWidth) {
+    OverflowError = (SrcTySigned != DstTySigned && SrcVal.isNegative());
     Result = SrcVal;
-    // Report an error if the sign bit is set.
-    OverflowError = SrcVal.isNegative();
 
-  // Process the checked truncations.
+  // A truncation can overflow if the value changes.
   } else {
-    assert(Builtin.Types.size() == 2);
-    DstTy = Builtin.Types[1];
-    uint32_t DstBitWidth =
-      DstTy->castTo<BuiltinIntegerType>()->getGreatestWidth();
-
-    assert((DstBitWidth < SrcBitWidth || !SrcTy->getWidth().isFixedWidth()) &&
-           "preconditions on builtin trunc operations should prevent"
-           "fixed-width truncations that actually extend");
-
-    // The only way a true extension can overflow is if the value is
-    // negative and the result is unsigned.
-    if (DstBitWidth > SrcBitWidth) {
-      OverflowError = (SrcTySigned && !DstTySigned && SrcVal.isNegative());
-      Result = (SrcTySigned ? SrcVal.sext(DstBitWidth)
-                            : SrcVal.zext(DstBitWidth));
-
-    // A same-width change can overflow if the top bit disagrees.
-    } else if (DstBitWidth == SrcBitWidth) {
-      OverflowError = (SrcTySigned != DstTySigned && SrcVal.isNegative());
-      Result = SrcVal;
-
-    // A truncation can overflow if the value changes.
-    } else {
-      Result = SrcVal.trunc(DstBitWidth);
-      APInt Ext = (DstTySigned ? Result.sext(SrcBitWidth)
-                               : Result.zext(SrcBitWidth));
-      OverflowError = (SrcVal != Ext);
-    }
+    Result = SrcVal.trunc(DstBitWidth);
+    APInt Ext = (DstTySigned ? Result.sext(SrcBitWidth)
+                             : Result.zext(SrcBitWidth));
+    OverflowError = (SrcVal != Ext);
   }
 
   // Check for overflow.
@@ -819,25 +804,19 @@
                  DstTySigned, DstTy, SrcAsString);
       }
     } else {
-      if (Builtin.ID == BuiltinValueKind::SUCheckedConversion) {
+      // Try to print user-visible types if they are available.
+      if (!UserSrcTy.isNull()) {
         diagnose(M.getASTContext(), Loc.getSourceLoc(),
-                 diag::integer_conversion_sign_error,
-                 UserDstTy.isNull() ? DstTy : UserDstTy);
-      } else {
-        // Try to print user-visible types if they are available.
-        if (!UserSrcTy.isNull()) {
-          diagnose(M.getASTContext(), Loc.getSourceLoc(),
-                   diag::integer_conversion_overflow,
-                   UserSrcTy, UserDstTy);
+                 diag::integer_conversion_overflow,
+                 UserSrcTy, UserDstTy);
 
-        // Otherwise, print the Builtin Types.
-        } else {
-          // Since builtin types are sign-agnostic, print the signedness
-          // separately.
-          diagnose(M.getASTContext(), Loc.getSourceLoc(),
-                   diag::integer_conversion_overflow_builtin_types,
-                   SrcTySigned, SrcTy, DstTySigned, DstTy);
-        }
+      // Otherwise, print the Builtin Types.
+      } else {
+        // Since builtin types are sign-agnostic, print the signedness
+        // separately.
+        diagnose(M.getASTContext(), Loc.getSourceLoc(),
+                 diag::integer_conversion_overflow_builtin_types,
+                 SrcTySigned, SrcTy, DstTySigned, DstTy);
       }
     }
 
@@ -1220,9 +1199,7 @@
   case BuiltinValueKind::SToSCheckedTrunc:
   case BuiltinValueKind::UToUCheckedTrunc:
   case BuiltinValueKind::SToUCheckedTrunc:
-  case BuiltinValueKind::UToSCheckedTrunc:
-  case BuiltinValueKind::SUCheckedConversion:
-  case BuiltinValueKind::USCheckedConversion: {
+  case BuiltinValueKind::UToSCheckedTrunc: {
     return constantFoldAndCheckIntegerConversions(BI, Builtin, ResultsInError);
   }
 
diff --git a/lib/SILOptimizer/Utils/Existential.cpp b/lib/SILOptimizer/Utils/Existential.cpp
index 4192183..6e32257 100644
--- a/lib/SILOptimizer/Utils/Existential.cpp
+++ b/lib/SILOptimizer/Utils/Existential.cpp
@@ -10,12 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "swift/SILOptimizer/Utils/Existential.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/ProtocolConformance.h"
-#include "swift/SILOptimizer/Utils/Existential.h"
-#include "swift/SILOptimizer/Utils/CFG.h"
-#include "swift/SIL/InstructionUtils.h"
 #include "swift/SIL/BasicBlockUtils.h"
+#include "swift/SIL/InstructionUtils.h"
+#include "swift/SILOptimizer/Utils/CFG.h"
+#include "swift/SILOptimizer/Utils/Local.h"
 #include "llvm/ADT/SmallPtrSet.h"
 
 using namespace swift;
@@ -122,11 +123,14 @@
 /// alloc_stack user \p ASIUser.
 /// If the value is copied from another stack location, \p isCopied is set to
 /// true.
-SILValue swift::getAddressOfStackInit(AllocStackInst *ASI,
+///
+/// allocStackAddr may either itself be an AllocStackInst or an
+/// InitEnumDataAddrInst that projects the value of an AllocStackInst.
+SILValue swift::getAddressOfStackInit(SILValue allocStackAddr,
                                       SILInstruction *ASIUser, bool &isCopied) {
   SILInstruction *SingleWrite = nullptr;
   // Check that this alloc_stack is initialized only once.
-  for (auto Use : ASI->getUses()) {
+  for (auto Use : allocStackAddr->getUses()) {
     auto *User = Use->getUser();
 
     // Ignore instructions which don't write to the stack location.
@@ -138,7 +142,7 @@
       continue;
     }
     if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
-      if (CAI->getDest() == ASI) {
+      if (CAI->getDest() == allocStackAddr) {
         if (SingleWrite)
           return SILValue();
         SingleWrite = CAI;
@@ -168,8 +172,13 @@
 
   // A very simple dominance check. As ASI is an operand of ASIUser,
   // SingleWrite dominates ASIUser if it is in the same block as ASI or ASIUser.
+  //
+  // If allocStack holds an Optional, then ASI is an InitEnumDataAddrInst
+  // projection and not strictly an operand of ASIUser. We rely on the guarantee
+  // that this InitEnumDataAddrInst must occur before the InjectEnumAddrInst
+  // that was the source of the existential address.
   SILBasicBlock *BB = SingleWrite->getParent();
-  if (BB != ASI->getParent() && BB != ASIUser->getParent())
+  if (BB != allocStackAddr->getParentBlock() && BB != ASIUser->getParent())
     return SILValue();
 
   if (auto *CAI = dyn_cast<CopyAddrInst>(SingleWrite)) {
@@ -179,6 +188,21 @@
     SILValue CAISrc = CAI->getSrc();
     if (auto *ASI = dyn_cast<AllocStackInst>(CAISrc))
       return getAddressOfStackInit(ASI, CAI, isCopied);
+
+    // Recognize a stack location holding an Optional.
+    //   %stack_adr = alloc_stack
+    //   %data_adr  = init_enum_data_addr %stk_adr
+    //   %enum_adr  = inject_enum_addr %stack_adr
+    //   %copy_src  = unchecked_take_enum_data_addr %enum_adr
+    // Replace %copy_src with %data_adr and recurse.
+    //
+    // TODO: a general Optional elimination sil-combine could
+    // supersede this check.
+    if (auto *UTEDAI = dyn_cast<UncheckedTakeEnumDataAddrInst>(CAISrc)) {
+      if (InitEnumDataAddrInst *IEDAI = findInitAddressForTrivialEnum(UTEDAI))
+        return getAddressOfStackInit(IEDAI, CAI, isCopied);
+    }
+
     // Check if the CAISrc is a global_addr.
     if (auto *GAI = dyn_cast<GlobalAddrInst>(CAISrc)) {
       return findInitExistentialFromGlobalAddrAndCopyAddr(GAI, CAI);
diff --git a/lib/SILOptimizer/Utils/Local.cpp b/lib/SILOptimizer/Utils/Local.cpp
index 4f71557..3971d64 100644
--- a/lib/SILOptimizer/Utils/Local.cpp
+++ b/lib/SILOptimizer/Utils/Local.cpp
@@ -653,6 +653,51 @@
   return B.createProjectBox(ABI->getLoc(), ABI, Index);
 }
 
+// Peek through trivial Enum initialization, typically for pointless
+// Optionals.
+//
+// Given an UncheckedTakeEnumDataAddrInst, check that there are no
+// other uses of the Enum value and return the address used to initialized the
+// enum's payload:
+//
+//   %stack_adr = alloc_stack
+//   %data_adr  = init_enum_data_addr %stk_adr
+//   %enum_adr  = inject_enum_addr %stack_adr
+//   %copy_src  = unchecked_take_enum_data_addr %enum_adr
+//   dealloc_stack %stack_adr
+//   (No other uses of %stack_adr.)
+InitEnumDataAddrInst *
+swift::findInitAddressForTrivialEnum(UncheckedTakeEnumDataAddrInst *UTEDAI) {
+  auto *ASI = dyn_cast<AllocStackInst>(UTEDAI->getOperand());
+  if (!ASI)
+    return nullptr;
+
+  SILInstruction *singleUser = nullptr;
+  for (auto use : ASI->getUses()) {
+    auto *user = use->getUser();
+    if (user == UTEDAI)
+      continue;
+
+    // As long as there's only one UncheckedTakeEnumDataAddrInst and one
+    // InitEnumDataAddrInst, we don't care how many InjectEnumAddr and
+    // DeallocStack users there are.
+    if (isa<InjectEnumAddrInst>(user) || isa<DeallocStackInst>(user))
+      continue;
+
+    if (singleUser)
+      return nullptr;
+
+    singleUser = user;
+  }
+  if (!singleUser)
+    return nullptr;
+
+  // Assume, without checking, that the returned InitEnumDataAddr dominates the
+  // given UncheckedTakeEnumDataAddrInst, because that's how SIL is defined. I
+  // don't know where this is actually verified.
+  return dyn_cast<InitEnumDataAddrInst>(singleUser);
+}
+
 //===----------------------------------------------------------------------===//
 //                       String Concatenation Optimizer
 //===----------------------------------------------------------------------===//
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 3a34ed6..78b9c2b 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -4940,7 +4940,7 @@
         break;
         
       case InvalidMethod::Reason::ReturnType:
-        tc.diagnose(invalidMethod.method->getReturnTypeLoc().getLoc(),
+        tc.diagnose(invalidMethod.method->getBodyResultTypeLoc().getLoc(),
                     diag::append_interpolation_void_or_discardable)
             .fixItInsert(invalidMethod.method->getStartLoc(),
                          "@discardableResult ");
diff --git a/stdlib/private/SwiftPrivateThreadExtras/SwiftPrivateThreadExtras.swift b/stdlib/private/SwiftPrivateThreadExtras/SwiftPrivateThreadExtras.swift
index 6cca91d..e568607 100644
--- a/stdlib/private/SwiftPrivateThreadExtras/SwiftPrivateThreadExtras.swift
+++ b/stdlib/private/SwiftPrivateThreadExtras/SwiftPrivateThreadExtras.swift
@@ -1,8 +1,8 @@
-//===--- SwiftPrivateThreadExtras.swift ----------------------------------===//
+//===--- SwiftPrivateThreadExtras.swift -----------------------------------===//
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
 // See https://swift.org/LICENSE.txt for license information
diff --git a/stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift b/stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift
index d0be2eb..ae6932b 100644
--- a/stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift
+++ b/stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift
@@ -1,8 +1,8 @@
-//===--- ThreadBarriers.swift --------------------------------------------===//
+//===--- ThreadBarriers.swift ---------------------------------------------===//
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
 // See https://swift.org/LICENSE.txt for license information
diff --git a/stdlib/public/Platform/winsdk.modulemap b/stdlib/public/Platform/winsdk.modulemap
index 1d69b29..e398a81 100644
--- a/stdlib/public/Platform/winsdk.modulemap
+++ b/stdlib/public/Platform/winsdk.modulemap
@@ -2,7 +2,7 @@
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
 // See https://swift.org/LICENSE.txt for license information
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
index 43c932c..401497b 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
@@ -30,11 +30,11 @@
 
 #endif // __OBJC__
 
-#import <APINotesFrameworkTest/Classes.h>
-#import <APINotesFrameworkTest/Enums.h>
-#import <APINotesFrameworkTest/Globals.h>
-#import <APINotesFrameworkTest/ImportAsMember.h>
-#import <APINotesFrameworkTest/Properties.h>
-#import <APINotesFrameworkTest/Protocols.h>
-#import <APINotesFrameworkTest/Types.h>
-#import <APINotesFrameworkTest/SwiftWrapper.h>
+#include <APINotesFrameworkTest/Classes.h>
+#include <APINotesFrameworkTest/Enums.h>
+#include <APINotesFrameworkTest/Globals.h>
+#include <APINotesFrameworkTest/ImportAsMember.h>
+#include <APINotesFrameworkTest/Properties.h>
+#include <APINotesFrameworkTest/Protocols.h>
+#include <APINotesFrameworkTest/Types.h>
+#include <APINotesFrameworkTest/SwiftWrapper.h>
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d4350d0..fde14c2 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -250,7 +250,7 @@
       set(LIT_ARGS "${SWIFT_TEST_EXTRA_ARGS} ${LLVM_LIT_ARGS}")
       separate_arguments(LIT_ARGS)
 
-      if(NOT SWIFT_BUILD_STDLIB)
+      if(NOT SWIFT_BUILD_STDLIB AND NOT SWIFT_PATH_TO_EXTERNAL_STDLIB_BUILD)
         list(APPEND LIT_ARGS
             "--param" "test_sdk_overlay_dir=${SWIFTLIB_DIR}/${SWIFT_SDK_${SDK}_LIB_SUBDIR}")
       endif()
diff --git a/test/ClangImporter/Inputs/chained-unit-test-bridging-header-to-pch.h b/test/ClangImporter/Inputs/chained-unit-test-bridging-header-to-pch.h
index c91801c..c027342 100644
--- a/test/ClangImporter/Inputs/chained-unit-test-bridging-header-to-pch.h
+++ b/test/ClangImporter/Inputs/chained-unit-test-bridging-header-to-pch.h
@@ -1,4 +1,4 @@
-#import "app-bridging-header-to-pch.h"
+#include "app-bridging-header-to-pch.h"
 
 static inline int unit_test_function(int x) {
   return x + 28;
diff --git a/test/SILOptimizer/devirt_specialized_conformance.swift b/test/SILOptimizer/devirt_specialized_conformance.swift
index 62cb05d..9f636c0 100644
--- a/test/SILOptimizer/devirt_specialized_conformance.swift
+++ b/test/SILOptimizer/devirt_specialized_conformance.swift
@@ -42,3 +42,32 @@
 }
 
 driver()
+
+// <rdar://problem/46322928> Failure to devirtualize a protocol method
+// applied to an opened existential blocks implemention of
+// DataProtocol.
+public protocol ContiguousBytes {
+    func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
+}
+
+extension Array : ContiguousBytes {}
+extension ContiguousArray : ContiguousBytes {}
+
+@inline(never)
+func takesPointer(_ p: UnsafeRawBufferPointer) {}
+
+// In specialized testWithUnsafeBytes<A>(_:), the conditional case and call to withUnsafeBytes must be eliminated.
+// CHECK-LABEL: sil shared [noinline] @$s30devirt_specialized_conformance19testWithUnsafeBytesyyxlFSayypG_Tg5 : $@convention(thin) (@guaranteed Array<Any>) -> () {
+// CHECK: bb0
+// CHECK-NOT: witness_method
+// CHECK: [[TAKES_PTR:%.*]] = function_ref @$s30devirt_specialized_conformance12takesPointeryySWF : $@convention(thin) (UnsafeRawBufferPointer) -> ()
+// CHECK: apply [[TAKES_PTR]](%{{.*}}) : $@convention(thin) (UnsafeRawBufferPointer) -> ()
+// CHECK-LABEL: } // end sil function '$s30devirt_specialized_conformance19testWithUnsafeBytesyyxlFSayypG_Tg5'
+@inline(never)
+func testWithUnsafeBytes<T>(_ t: T) {
+  if let cb = t as? ContiguousBytes {
+    cb.withUnsafeBytes { takesPointer($0) }
+  }
+}
+
+testWithUnsafeBytes([])
diff --git a/test/SILOptimizer/peephole_trunc_and_ext.sil b/test/SILOptimizer/peephole_trunc_and_ext.sil
index 171f00e..eab8a64 100644
--- a/test/SILOptimizer/peephole_trunc_and_ext.sil
+++ b/test/SILOptimizer/peephole_trunc_and_ext.sil
@@ -21,143 +21,6 @@
   var value: Builtin.Word
 }
 
-// peephole: Word(Int64(x >> 1)) -> (x >> 1)
-// CHECK-LABEL: sil @_TF4test29test_trunc_u_to_s_zext_lshr_1FSuSi : $@convention(thin) (BuiltinUWord) -> BuiltinWord
-// CHECK: builtin "lshr_Word"
-// CHECK-NOT: builtin "zextOrBitCast_Word_Int64"
-// CHECK-NOT: builtin "u_to_s_checked_conversion_Int64"
-// CHECK-NOT: builtin "truncOrBitCast_Int64_Word"
-// CHECK: return
-// test.test_trunc_u_to_s_zext_lshr_1 (BuiltinUWord) -> Swift.BuiltinWord
-sil @_TF4test29test_trunc_u_to_s_zext_lshr_1FSuSi : $@convention(thin) (BuiltinUWord) -> BuiltinWord {
-bb0(%0 : $BuiltinUWord):
-  debug_value %0 : $BuiltinUWord, let, name "x" // id: %1
-  %2 = integer_literal $Builtin.Word, 1           // user: %7
-  br bb1                                          // id: %3
-
-bb1:                                              // Preds: bb0
-  br bb2                                          // id: %4
-
-bb2:                                              // Preds: bb1
-  %6 = struct_extract %0 : $BuiltinUWord, #BuiltinUWord.value     // user: %7
-  %7 = builtin "lshr_Word"(%6 : $Builtin.Word, %2 : $Builtin.Word) : $Builtin.Word // user: %8
-  %8 = struct $BuiltinUWord (%7 : $Builtin.Word)  // user: %11
-  br bb3                                          // id: %9
-
-bb3:                                              // Preds: bb2
-  %11 = struct_extract %8 : $BuiltinUWord, #BuiltinUWord.value    // user: %12
-  %12 = builtin "zextOrBitCast_Word_Int64"(%11 : $Builtin.Word) : $Builtin.Int64 // user: %14
-  %14 = builtin "u_to_s_checked_conversion_Int64"(%12 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1) // users: %15, %16
-  %15 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 0 // user: %18
-  %16 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 1 // user: %17
-  cond_fail %16 : $Builtin.Int1                   // id: %17
-  %18 = struct $Int64 (%15 : $Builtin.Int64)      // user: %19
-  %19 = struct_extract %18 : $Int64, #Int64._value // user: %21
-  %21 = builtin "truncOrBitCast_Int64_Word"(%19 : $Builtin.Int64) : $Builtin.Word // user: %22
-  %22 = struct $BuiltinWord (%21 : $Builtin.Word) // users: %23, %24
-  debug_value %22 : $BuiltinWord, let, name "v1" // id: %23
-  return %22 : $BuiltinWord                       // id: %24
-}
-
-
-// peephole: Word(Int64(x >> 10)) -> (x >> 1)
-// CHECK-LABEL: sil @_TF4test30test_trunc_u_to_s_zext_lshr_10FSuSi : $@convention(thin) (BuiltinUWord) -> BuiltinWord
-// CHECK: builtin "lshr_Word"
-// CHECK-NOT: builtin "zextOrBitCast_Word_Int64"
-// CHECK-NOT: builtin "u_to_s_checked_conversion_Int64"
-// CHECK-NOT: builtin "truncOrBitCast_Int64_Word"
-// CHECK: return
-// test.test_trunc_u_to_s_zext_lshr_10 (Swift.BuiltinUWord) -> Swift.BuiltinWord
-sil @_TF4test30test_trunc_u_to_s_zext_lshr_10FSuSi : $@convention(thin) (BuiltinUWord) -> BuiltinWord {
-bb0(%0 : $BuiltinUWord):
-  debug_value %0 : $BuiltinUWord, let, name "x" // id: %1
-  %2 = integer_literal $Builtin.Word, 10          // user: %7
-  br bb1                                          // id: %3
-
-bb1:                                              // Preds: bb0
-  br bb2                                          // id: %4
-
-bb2:                                              // Preds: bb1
-  %6 = struct_extract %0 : $BuiltinUWord, #BuiltinUWord.value     // user: %7
-  %7 = builtin "lshr_Word"(%6 : $Builtin.Word, %2 : $Builtin.Word) : $Builtin.Word // user: %8
-  %8 = struct $BuiltinUWord (%7 : $Builtin.Word)          // user: %11
-  br bb3                                          // id: %9
-
-bb3:                                              // Preds: bb2
-  %11 = struct_extract %8 : $BuiltinUWord, #BuiltinUWord.value    // user: %12
-  %12 = builtin "zextOrBitCast_Word_Int64"(%11 : $Builtin.Word) : $Builtin.Int64 // user: %14
-  %14 = builtin "u_to_s_checked_conversion_Int64"(%12 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1) // users: %15, %16
-  %15 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 0 // user: %18
-  %16 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 1 // user: %17
-  cond_fail %16 : $Builtin.Int1                   // id: %17
-  %18 = struct $Int64 (%15 : $Builtin.Int64)      // user: %19
-  %19 = struct_extract %18 : $Int64, #Int64._value // user: %21
-  %21 = builtin "truncOrBitCast_Int64_Word"(%19 : $Builtin.Int64) : $Builtin.Word // user: %22
-  %22 = struct $BuiltinWord (%21 : $Builtin.Word)         // users: %23, %24
-  debug_value %22 : $BuiltinWord, let, name "v1" // id: %23
-  return %22 : $BuiltinWord                               // id: %24
-}
-
-// no peephole: Word(Int64(x >> c)), where c is a variable
-// This should not trigger the optimization as it is not known if c > 0
-// CHECK-LABEL: sil @_TF4test31test_trunc_u_to_s_zext_lshr_varFTSuSu_Si : $@convention(thin) (BuiltinUWord, BuiltinUWord) -> BuiltinWord
-// CHECK: builtin "u_to_s_checked_conversion_Int64"
-// CHECK: builtin "truncOrBitCast_Int64_Word"
-// CHECK: return
-// test.test_trunc_u_to_s_zext_lshr_var (Swift.BuiltinUWord, Swift.BuiltinUWord) -> Swift.BuiltinWord
-sil @_TF4test31test_trunc_u_to_s_zext_lshr_varFTSuSu_Si : $@convention(thin) (BuiltinUWord, BuiltinUWord) -> BuiltinWord {
-bb0(%0 : $BuiltinUWord, %1 : $BuiltinUWord):
-  debug_value %0 : $BuiltinUWord, let, name "x" // id: %2
-  debug_value %1 : $BuiltinUWord, let, name "c" // id: %3
-  %4 = tuple ()
-  %5 = tuple ()
-  %6 = tuple ()
-  %7 = tuple ()
-  %8 = tuple ()
-  %9 = tuple ()
-  %10 = tuple ()
-  %11 = tuple ()
-  %12 = tuple ()
-  br bb1                                          // id: %13
-
-bb1:                                              // Preds: bb0
-  %14 = integer_literal $Builtin.Word, 64         // user: %17
-  %16 = struct_extract %1 : $BuiltinUWord, #BuiltinUWord.value    // user: %17
-  %17 = builtin "cmp_ult_Word"(%16 : $Builtin.Word, %14 : $Builtin.Word) : $Builtin.Int1 // user: %20
-  %18 = integer_literal $Builtin.Int1, -1         // user: %20
-  %20 = builtin "int_expect_Int1"(%17 : $Builtin.Int1, %18 : $Builtin.Int1) : $Builtin.Int1 // user: %21
-  cond_br %20, bb2, bb3                           // id: %21
-
-bb2:                                              // Preds: bb1
-  %23 = struct_extract %0 : $BuiltinUWord, #BuiltinUWord.value    // user: %25
-  %24 = struct_extract %1 : $BuiltinUWord, #BuiltinUWord.value    // user: %25
-  %25 = builtin "lshr_Word"(%23 : $Builtin.Word, %24 : $Builtin.Word) : $Builtin.Word // user: %26
-  %26 = struct $BuiltinUWord (%25 : $Builtin.Word)        // user: %35
-  br bb4                                          // id: %27
-
-bb3:                                              // Preds: bb1
-  %28 = function_ref @fatalError : $@convention(thin) () -> Never // user: %32
-  %29 = tuple ()
-  %30 = tuple ()
-  %31 = tuple ()
-  %32 = apply %28() : $@convention(thin) () -> Never
-  unreachable                                     // id: %33
-
-bb4:                                              // Preds: bb2
-  %35 = struct_extract %26 : $BuiltinUWord, #BuiltinUWord.value   // user: %36
-  %36 = builtin "zextOrBitCast_Word_Int64"(%35 : $Builtin.Word) : $Builtin.Int64 // user: %38
-  %38 = builtin "u_to_s_checked_conversion_Int64"(%36 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1) // users: %39, %40
-  %39 = tuple_extract %38 : $(Builtin.Int64, Builtin.Int1), 0 // user: %42
-  %40 = tuple_extract %38 : $(Builtin.Int64, Builtin.Int1), 1 // user: %41
-  cond_fail %40 : $Builtin.Int1                   // id: %41
-  %42 = struct $Int64 (%39 : $Builtin.Int64)      // user: %43
-  %43 = struct_extract %42 : $Int64, #Int64._value // user: %45
-  %45 = builtin "truncOrBitCast_Int64_Word"(%43 : $Builtin.Int64) : $Builtin.Word // user: %46
-  %46 = struct $BuiltinWord (%45 : $Builtin.Word)         // users: %47, %48
-  debug_value %46 : $BuiltinWord, let, name "v1" // id: %47
-  return %46 : $BuiltinWord                               // id: %48
-}
-
 // peephole: UInt16(Int32(x >> 1)) -> (x >> 1)
 // CHECK-LABEL: sil @_TF4test36test_uint16_trunc_u_to_s_zext_lshr_1FVs6UInt16S0_ : $@convention(thin) (UInt16) -> UInt16
 // CHECK: builtin "lshr_Int16"
@@ -233,60 +96,6 @@
   return %20 : $Int16                             // id: %22
 }
 
-// No peephole for UWord(UInt64(x)), because it is not known if top bit of x is set
-// CHECK-LABEL: sil @_TF4test26test_trunc_s_to_u_zext_varFSiSu : $@convention(thin) (BuiltinWord) -> BuiltinUWord
-// This should not trigger the optimization as it is not known if top bit of x is set
-// CHECK: builtin "zextOrBitCast_Word_Int64"
-// CHECK: builtin "s_to_u_checked_conversion_Int64"
-// CHECK: builtin "truncOrBitCast_Int64_Word"
-// CHECK: return
-// test.test_trunc_s_to_u_zext_var (Swift.BuiltinWord) -> Swift.BuiltinUWord
-sil @_TF4test26test_trunc_s_to_u_zext_varFSiSu : $@convention(thin) (BuiltinWord) -> BuiltinUWord {
-bb0(%0 : $BuiltinWord):
-  debug_value %0 : $BuiltinWord, let, name "x" // id: %1
-  %3 = struct_extract %0 : $BuiltinWord, #BuiltinWord.value // user: %4
-  %4 = builtin "zextOrBitCast_Word_Int64"(%3 : $Builtin.Word) : $Builtin.Int64 // user: %6
-  %6 = builtin "s_to_u_checked_conversion_Int64"(%4 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1) // users: %7, %8
-  %7 = tuple_extract %6 : $(Builtin.Int64, Builtin.Int1), 0 // user: %10
-  %8 = tuple_extract %6 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
-  cond_fail %8 : $Builtin.Int1                              // id: %9
-  %10 = struct $UInt64 (%7 : $Builtin.Int64)                // user: %11
-  %11 = struct_extract %10 : $UInt64, #UInt64._value         // user: %13
-  %13 = builtin "truncOrBitCast_Int64_Word"(%11 : $Builtin.Int64) : $Builtin.Word // user: %14
-  %14 = struct $BuiltinUWord (%13 : $Builtin.Word)          // user: %15
-  return %14 : $BuiltinUWord                                // id: %15
-}
-
-
-// sizeof is known to return strictly positive values
-// peephole: UWord(UInt64(sizeof(Int.self))) -> sizeof(Int.self)
-// CHECK-LABEL: sil @_TF4test29test_trunc_s_to_u_zext_sizeofFT_Su : $@convention(thin) () -> BuiltinUWord
-// CHECK: builtin "sizeof"
-// CHECK-NOT: builtin "zextOrBitCast_Word_Int64"
-// CHECK-NOT: builtin "s_to_u_checked_conversion_Int64"
-// CHECK-NOT: builtin "truncOrBitCast_Int64_Word"
-// CHECK: return
-// test.test_trunc_s_to_u_zext_sizeof () -> Swift.BuiltinUWord
-sil @_TF4test29test_trunc_s_to_u_zext_sizeofFT_Su : $@convention(thin) () -> BuiltinUWord {
-bb0:
-  %0 = metatype $@thin BuiltinWord.Type
-  %2 = metatype $@thick BuiltinWord.Type                      // user: %3
-  %3 = builtin "sizeof"<(BuiltinWord)>(%2 : $@thick (BuiltinWord).Type) : $Builtin.Word // user: %4
-  %4 = struct $BuiltinWord (%3 : $Builtin.Word)              // user: %6
-  %6 = struct_extract %4 : $BuiltinWord, #BuiltinWord.value  // user: %7
-  %7 = builtin "zextOrBitCast_Word_Int64"(%6 : $Builtin.Word) : $Builtin.Int64 // user: %9
-  %9 = builtin "s_to_u_checked_conversion_Int64"(%7 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1) // users: %10, %11
-  %10 = tuple_extract %9 : $(Builtin.Int64, Builtin.Int1), 0 // user: %13
-  %11 = tuple_extract %9 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
-  cond_fail %11 : $Builtin.Int1                              // id: %12
-  %13 = struct $UInt64 (%10 : $Builtin.Int64)                // user: %14
-  %14 = struct_extract %13 : $UInt64, #UInt64._value          // user: %16
-  %16 = builtin "truncOrBitCast_Int64_Word"(%14 : $Builtin.Int64) : $Builtin.Word // user: %17
-  %17 = struct $BuiltinUWord (%16 : $Builtin.Word)           // user: %18
-  return %17 : $BuiltinUWord                                 // id: %18
-}
-
-
 // sizeof is known to return strictly positive values
 // But Word ->Int64 is not a safe conversion
 // No peephole for UInt16(UInt32(sizeof(Int.self)))
@@ -318,55 +127,6 @@
   return %20 : $UInt16                            // id: %21
 }
 
-
-// peephole: UInt16(UInt32(Int16(x>>1))) -> x>>1
-// CHECK-LABEL: sil @_TF4test34test_int16_trunc_s_to_u_zext_int16FVs6UInt16S0_ : $@convention(thin) (UInt16) -> UInt16
-// CHECK: builtin "lshr_Int16"
-// CHECK-NOT: builtin "u_to_s_checked_conversion_Int16"
-// CHECK-NOT: builtin "s_to_u_checked_conversion_Int16"
-// CHECK-NOT: builtin "sext_Int16_Int32"
-// CHECK-NOT: builtin "u_to_u_checked_trunc_Int32_Int16"
-// CHECK-NOT: tuple_extract
-// CHECK: return
-// test.test_int16_trunc_s_to_u_zext_int16 (Swift.UInt16) -> Swift.UInt16
-sil @_TF4test34test_int16_trunc_s_to_u_zext_int16FVs6UInt16S0_ : $@convention(thin) (UInt16) -> UInt16 {
-bb0(%0 : $UInt16):
-  debug_value %0 : $UInt16, let, name "x" // id: %1
-  %2 = integer_literal $Builtin.Int16, 1          // user: %7
-  br bb1                                          // id: %3
-
-bb1:                                              // Preds: bb0
-  br bb2                                          // id: %4
-
-bb2:                                              // Preds: bb1
-  %6 = struct_extract %0 : $UInt16, #UInt16._value // user: %7
-  %7 = builtin "lshr_Int16"(%6 : $Builtin.Int16, %2 : $Builtin.Int16) : $Builtin.Int16 // user: %8
-  %8 = struct $UInt16 (%7 : $Builtin.Int16)       // user: %10
-  br bb3                                          // id: %9
-
-bb3:                                              // Preds: bb2
-  %10 = struct_extract %8 : $UInt16, #UInt16._value // user: %12
-  %12 = builtin "u_to_s_checked_conversion_Int16"(%10 : $Builtin.Int16) : $(Builtin.Int16, Builtin.Int1) // users: %13, %14
-  %13 = tuple_extract %12 : $(Builtin.Int16, Builtin.Int1), 0 // user: %16
-  %14 = tuple_extract %12 : $(Builtin.Int16, Builtin.Int1), 1 // user: %15
-  cond_fail %14 : $Builtin.Int1                   // id: %15
-  %16 = struct $Int16 (%13 : $Builtin.Int16)      // user: %17
-  %17 = struct_extract %16 : $Int16, #Int16._value // user: %19
-  %19 = builtin "s_to_u_checked_conversion_Int16"(%17 : $Builtin.Int16) : $(Builtin.Int16, Builtin.Int1) // users: %20, %21
-  %20 = tuple_extract %19 : $(Builtin.Int16, Builtin.Int1), 0 // user: %24
-  %21 = tuple_extract %19 : $(Builtin.Int16, Builtin.Int1), 1 // user: %22
-  cond_fail %21 : $Builtin.Int1                   // id: %22
-  %24 = builtin "sext_Int16_Int32"(%20 : $Builtin.Int16) : $Builtin.Int32 // user: %25
-  %25 = struct $UInt32 (%24 : $Builtin.Int32)     // user: %26
-  %26 = struct_extract %25 : $UInt32, #UInt32._value // user: %28
-  %28 = builtin "u_to_u_checked_trunc_Int32_Int16"(%26 : $Builtin.Int32) : $(Builtin.Int16, Builtin.Int1) // users: %29, %30
-  %29 = tuple_extract %28 : $(Builtin.Int16, Builtin.Int1), 0 // user: %32
-  %30 = tuple_extract %28 : $(Builtin.Int16, Builtin.Int1), 1 // user: %31
-  cond_fail %30 : $Builtin.Int1                   // id: %31
-  %32 = struct $UInt16 (%29 : $Builtin.Int16)     // user: %33
-  return %32 : $UInt16                            // id: %33
-}
-
 // peephole: Int8(x & 127) -> remove overflow check
 // CHECK-LABEL: sil @_TF22peephole_trunc_and_ext32test_s_to_s_checked_trunc_of_andFVs5Int32Vs4Int8 : $@convention(thin) (Int32) -> Int8
 // CHECK: builtin "and_Int32"
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 08fda37..becb301 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -2198,134 +2198,6 @@
   return %2 : $Builtin.RawPointer
 }
 
-// CHECK-LABEL: sil @remove_trunc_utos_zext_of_and
-// CHECK:       bb0([[Ref:%.*]]: $Builtin.Word):
-// CHECK:         integer_literal $Builtin.Word, 4611686018427387903
-// CHECK:         builtin "and_Word"
-// CHECK-NOT:     builtin "zextOrBitCast_Word_Int64"
-// CHECK-NOT:     builtin "u_to_s_checked_conversion_Int64"
-// CHECK-NOT:     builtin "truncOrBitCast_Int64_Word"
-// CHECK:         return
-sil @remove_trunc_utos_zext_of_and : $@convention(thin) (Builtin.Word) -> (Builtin.Word) {
-bb0(%0 : $Builtin.Word):
-  %1 = integer_literal $Builtin.Word, 4611686018427387903
-  %2 = builtin "and_Word"(%0 : $Builtin.Word, %1 : $Builtin.Word) : $Builtin.Word
-  %3 = builtin "zextOrBitCast_Word_Int64"(%2 : $Builtin.Word) : $Builtin.Int64
-  %4 = builtin "u_to_s_checked_conversion_Int64"(%3 : $Builtin.Int64): $(Builtin.Int64, Builtin.Int1)
-  %5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 0
-  %6 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1
-  cond_fail %6 : $Builtin.Int1
-  %8 = builtin "truncOrBitCast_Int64_Word"(%5 : $Builtin.Int64) : $Builtin.Word
-  return %8 : $Builtin.Word
-}
-
-// CHECK-LABEL: sil @dont_remove_trunc_utos_zext_of_and
-// CHECK:       bb0([[Ref:%.*]]: $Builtin.Word, [[Ref:%.*]]: $Builtin.Word):
-// CHECK:         builtin "and_Word"
-// CHECK:         builtin "zextOrBitCast_Word_Int64"
-// CHECK:         builtin "u_to_s_checked_conversion_Int64"
-// CHECK:         builtin "truncOrBitCast_Int64_Word"
-// CHECK:         return
-sil @dont_remove_trunc_utos_zext_of_and : $@convention(thin) (Builtin.Word, Builtin.Word) -> (Builtin.Word) {
-bb0(%0 : $Builtin.Word, %1 : $Builtin.Word):
-  %2 = builtin "and_Word"(%0 : $Builtin.Word, %1 : $Builtin.Word) : $Builtin.Word
-  %3 = builtin "zextOrBitCast_Word_Int64"(%2 : $Builtin.Word) : $Builtin.Int64
-  %4 = builtin "u_to_s_checked_conversion_Int64"(%3 : $Builtin.Int64): $(Builtin.Int64, Builtin.Int1)
-  %5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 0
-  %6 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1
-  cond_fail %6 : $Builtin.Int1
-  %8 = builtin "truncOrBitCast_Int64_Word"(%5 : $Builtin.Int64) : $Builtin.Word
-  return %8 : $Builtin.Word
-}
-
-// CHECK-LABEL: sil @remove_trunc_utos_zext_of_or
-// CHECK:       bb0([[Ref:%.*]]: $Builtin.Word):
-// CHECK:         integer_literal $Builtin.Word, 1
-// CHECK:         builtin "lshr_Word"
-// CHECK:         builtin "or_Word"
-// CHECK-NOT:     builtin "zextOrBitCast_Word_Int64"
-// CHECK-NOT:     builtin "u_to_s_checked_conversion_Int64"
-// CHECK-NOT:     builtin "truncOrBitCast_Int64_Word"
-// CHECK:         return
-sil @remove_trunc_utos_zext_of_or : $@convention(thin) (Builtin.Word) -> (Builtin.Word) {
-bb0(%0 : $Builtin.Word):
-  %1 = integer_literal $Builtin.Word, 1
-  %l1 = builtin "lshr_Word"(%0 : $Builtin.Word, %1 : $Builtin.Word) : $Builtin.Word
-  %2 = builtin "or_Word"(%l1 : $Builtin.Word, %1 : $Builtin.Word) : $Builtin.Word
-  %3 = builtin "zextOrBitCast_Word_Int64"(%2 : $Builtin.Word) : $Builtin.Int64
-  %4 = builtin "u_to_s_checked_conversion_Int64"(%3 : $Builtin.Int64): $(Builtin.Int64, Builtin.Int1)
-  %5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 0
-  %6 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1
-  cond_fail %6 : $Builtin.Int1
-  %8 = builtin "truncOrBitCast_Int64_Word"(%5 : $Builtin.Int64) : $Builtin.Word
-  return %8 : $Builtin.Word
-}
-
-// CHECK-LABEL: sil @dont_remove_trunc_utos_zext_of_or
-// CHECK:       bb0([[Ref:%.*]]: $Builtin.Word):
-// CHECK:         integer_literal $Builtin.Word, -2
-// CHECK:         builtin "or_Word"
-// CHECK:         builtin "zextOrBitCast_Word_Int64"
-// CHECK:         builtin "u_to_s_checked_conversion_Int64"
-// CHECK:         builtin "truncOrBitCast_Int64_Word"
-// CHECK:         return
-sil @dont_remove_trunc_utos_zext_of_or : $@convention(thin) (Builtin.Word) -> (Builtin.Word) {
-bb0(%0 : $Builtin.Word):
-  %1 = integer_literal $Builtin.Word, -2
-  %2 = builtin "or_Word"(%0 : $Builtin.Word, %1 : $Builtin.Word) : $Builtin.Word
-  %3 = builtin "zextOrBitCast_Word_Int64"(%2 : $Builtin.Word) : $Builtin.Int64
-  %4 = builtin "u_to_s_checked_conversion_Int64"(%3 : $Builtin.Int64): $(Builtin.Int64, Builtin.Int1)
-  %5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 0
-  %6 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1
-  cond_fail %6 : $Builtin.Int1
-  %8 = builtin "truncOrBitCast_Int64_Word"(%5 : $Builtin.Int64) : $Builtin.Word
-  return %8 : $Builtin.Word
-}
-
-// CHECK-LABEL: sil @remove_trunc_utos_zext_of_xor
-// CHECK:       bb0:
-// CHECK:         integer_literal $Builtin.Word, -1
-// CHECK:         integer_literal $Builtin.Word, -1
-// CHECK:         builtin "xor_Word"
-// CHECK-NOT:     builtin "zextOrBitCast_Word_Int64"
-// CHECK-NOT:     builtin "u_to_s_checked_conversion_Int64"
-// CHECK-NOT:     builtin "truncOrBitCast_Int64_Word"
-// CHECK:         return
-sil @remove_trunc_utos_zext_of_xor : $@convention(thin) () -> (Builtin.Word) {
-bb0:
-  %0 = integer_literal $Builtin.Word, -1
-  %1 = integer_literal $Builtin.Word, -1
-  %2 = builtin "xor_Word"(%0 : $Builtin.Word, %1 : $Builtin.Word) : $Builtin.Word
-  %3 = builtin "zextOrBitCast_Word_Int64"(%2 : $Builtin.Word) : $Builtin.Int64
-  %4 = builtin "u_to_s_checked_conversion_Int64"(%3 : $Builtin.Int64): $(Builtin.Int64, Builtin.Int1)
-  %5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 0
-  %6 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1
-  cond_fail %6 : $Builtin.Int1
-  %8 = builtin "truncOrBitCast_Int64_Word"(%5 : $Builtin.Int64) : $Builtin.Word
-  return %8 : $Builtin.Word
-}
-
-// CHECK-LABEL: sil @dont_remove_trunc_utos_zext_of_xor
-// CHECK:       bb0([[Ref:%.*]]: $Builtin.Word):
-// CHECK:         integer_literal $Builtin.Word, 1
-// CHECK:         builtin "xor_Word"
-// CHECK:         builtin "zextOrBitCast_Word_Int64"
-// CHECK:         builtin "u_to_s_checked_conversion_Int64"
-// CHECK:         builtin "truncOrBitCast_Int64_Word"
-// CHECK:         return
-sil @dont_remove_trunc_utos_zext_of_xor : $@convention(thin) (Builtin.Word) -> (Builtin.Word) {
-bb0(%0 : $Builtin.Word):
-  %1 = integer_literal $Builtin.Word, 1
-  %2 = builtin "xor_Word"(%0 : $Builtin.Word, %1 : $Builtin.Word) : $Builtin.Word
-  %3 = builtin "zextOrBitCast_Word_Int64"(%2 : $Builtin.Word) : $Builtin.Int64
-  %4 = builtin "u_to_s_checked_conversion_Int64"(%3 : $Builtin.Int64): $(Builtin.Int64, Builtin.Int1)
-  %5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 0
-  %6 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1
-  cond_fail %6 : $Builtin.Int1
-  %8 = builtin "truncOrBitCast_Int64_Word"(%5 : $Builtin.Int64) : $Builtin.Word
-  return %8 : $Builtin.Word
-}
-
 struct GenContainer<T> {
 }
 
diff --git a/test/SILOptimizer/sil_combine_concrete_existential.sil b/test/SILOptimizer/sil_combine_concrete_existential.sil
index 9e93646..f8a96c8 100644
--- a/test/SILOptimizer/sil_combine_concrete_existential.sil
+++ b/test/SILOptimizer/sil_combine_concrete_existential.sil
@@ -437,3 +437,65 @@
   %v = tuple ()
   return %v : $()
 }
+
+// <rdar://problem/46322928> Failure to devirtualize a protocol method
+// applied to an opened existential blocks implemention of
+// DataProtocol.
+public protocol ContiguousBytes {
+  func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
+}
+
+extension Array : ContiguousBytes {
+}
+
+// specialized thunk for @callee_guaranteed (@unowned UnsafeRawBufferPointer) -> (@error @owned Error)
+sil [transparent] [reabstraction_thunk] @testDevirtExistentialEnumThunk : $@convention(thin) (UnsafeRawBufferPointer) -> (@out (), @error Error)
+
+// Test that the witness method's opened archetype is replaced by a
+// concrete conformance.
+//
+// Note that the enum is destroyed by unchecked_take_enum_data_addr
+// before the apply (and the extracted data is destroy by the copy
+// itself), so SILCombine cannot replace the call's self
+// argument. Instead, we expect a later devirtualizer pass to just
+// insert a cast of the opened existential.
+//
+// CHECK-LABEL: sil shared [noinline] @testDevirtExistentialEnum : $@convention(thin) (@guaranteed Array<Int>) -> () {
+// CHECK: [[ALLOC_EXISTENTIAL:%.*]] = alloc_stack $ContiguousBytes
+// CHECK: [[ALLOC_ENUM:%.*]] = alloc_stack $Optional<ContiguousBytes>
+// CHECK: [[ENUM:%.*]] = init_enum_data_addr [[ALLOC_ENUM]] : $*Optional<ContiguousBytes>, #Optional.some!enumelt.1
+// CHECK: [[INIT_DATA:%.*]] = init_existential_addr [[ENUM]] : $*ContiguousBytes, $Array<Int>
+// CHECK: store %0 to [[INIT_DATA]] : $*Array<Int>
+// CHECK: inject_enum_addr [[ALLOC_ENUM]] : $*Optional<ContiguousBytes>, #Optional.some!enumelt.1
+// CHECK: [[TAKE_DATA:%.*]] = unchecked_take_enum_data_addr [[ALLOC_ENUM]] : $*Optional<ContiguousBytes>, #Optional.some!enumelt.1
+// CHECK: copy_addr [take] [[TAKE_DATA]] to [initialization] [[ALLOC_EXISTENTIAL]] : $*ContiguousBytes
+// CHECK: [[OPENED:%.*]] = open_existential_addr immutable_access [[ALLOC_EXISTENTIAL]] : $*ContiguousBytes to $*@opened("8402EC1A-F35D-11E8-950A-D0817AD9F6DD") ContiguousBytes
+// CHECK: [[THUNK:%.*]] = function_ref @testDevirtExistentialEnumThunk : $@convention(thin) (UnsafeRawBufferPointer) -> (@out (), @error Error)
+// CHECK: [[TTF:%.*]] = thin_to_thick_function [[THUNK:%.*]] : $@convention(thin) (UnsafeRawBufferPointer) -> (@out (), @error Error) to $@noescape @callee_guaranteed (UnsafeRawBufferPointer) -> (@out (), @error Error)
+// CHECK: [[WM:%.*]] = witness_method $Array<Int>, #ContiguousBytes.withUnsafeBytes!1 : <Self where Self : ContiguousBytes><R> (Self) -> ((UnsafeRawBufferPointer) throws -> R) throws -> R : $@convention(witness_method: ContiguousBytes) <τ_0_0 where τ_0_0 : ContiguousBytes><τ_1_0> (@noescape @callee_guaranteed (UnsafeRawBufferPointer) -> (@out τ_1_0, @error Error), @in_guaranteed τ_0_0) -> (@out τ_1_0, @error Error)
+// CHECK: apply [nothrow] [[WM]]<@opened("8402EC1A-F35D-11E8-950A-D0817AD9F6DD") ContiguousBytes, ()>(%{{.*}}, [[TTF]], [[OPENED]]) : $@convention(witness_method: ContiguousBytes) <τ_0_0 where τ_0_0 : ContiguousBytes><τ_1_0> (@noescape @callee_guaranteed (UnsafeRawBufferPointer) -> (@out τ_1_0, @error Error), @in_guaranteed τ_0_0) -> (@out τ_1_0, @error Error)
+// CHECK: destroy_addr [[ALLOC_EXISTENTIAL]] : $*ContiguousBytes
+// CHECK-LABEL: } // end sil function 'testDevirtExistentialEnum'
+sil shared [noinline] @testDevirtExistentialEnum : $@convention(thin) (@guaranteed Array<Int>) -> () {
+bb0(%0 : $Array<Int>):
+  %3 = alloc_stack $ContiguousBytes
+  %4 = alloc_stack $Optional<ContiguousBytes>
+  %5 = init_enum_data_addr %4 : $*Optional<ContiguousBytes>, #Optional.some!enumelt.1
+  %6 = init_existential_addr %5 : $*ContiguousBytes, $Array<Int>
+  store %0 to %6 : $*Array<Int>
+  inject_enum_addr %4 : $*Optional<ContiguousBytes>, #Optional.some!enumelt.1
+  %9 = unchecked_take_enum_data_addr %4 : $*Optional<ContiguousBytes>, #Optional.some!enumelt.1
+  copy_addr [take] %9 to [initialization] %3 : $*ContiguousBytes
+  dealloc_stack %4 : $*Optional<ContiguousBytes>
+  %12 = open_existential_addr immutable_access %3 : $*ContiguousBytes to $*@opened("8402EC1A-F35D-11E8-950A-D0817AD9F6DD") ContiguousBytes
+  %13 = alloc_stack $()
+  %14 = function_ref @testDevirtExistentialEnumThunk : $@convention(thin) (UnsafeRawBufferPointer) -> (@out (), @error Error)
+  %15 = thin_to_thick_function %14 : $@convention(thin) (UnsafeRawBufferPointer) -> (@out (), @error Error) to $@noescape @callee_guaranteed (UnsafeRawBufferPointer) -> (@out (), @error Error)
+  %16 = witness_method $@opened("8402EC1A-F35D-11E8-950A-D0817AD9F6DD") ContiguousBytes, #ContiguousBytes.withUnsafeBytes!1 : <Self where Self : ContiguousBytes><R> (Self) -> ((UnsafeRawBufferPointer) throws -> R) throws -> R, %12 : $*@opened("8402EC1A-F35D-11E8-950A-D0817AD9F6DD") ContiguousBytes : $@convention(witness_method: ContiguousBytes) <τ_0_0 where τ_0_0 : ContiguousBytes><τ_1_0> (@noescape @callee_guaranteed (UnsafeRawBufferPointer) -> (@out τ_1_0, @error Error), @in_guaranteed τ_0_0) -> (@out τ_1_0, @error Error)
+  %21 = apply [nothrow] %16<@opened("8402EC1A-F35D-11E8-950A-D0817AD9F6DD") ContiguousBytes, ()>(%13, %15, %12) : $@convention(witness_method: ContiguousBytes) <τ_0_0 where τ_0_0 : ContiguousBytes><τ_1_0> (@noescape @callee_guaranteed (UnsafeRawBufferPointer) -> (@out τ_1_0, @error Error), @in_guaranteed τ_0_0) -> (@out τ_1_0, @error Error)
+  dealloc_stack %13 : $*()
+  destroy_addr %3 : $*ContiguousBytes
+  dealloc_stack %3 : $*ContiguousBytes
+  %25 = tuple ()
+  return %25 : $()
+}