diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5530bd8..e18dd05 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -772,406 +772,409 @@
   }
 
   // Since return type of reserve_read/write_pipe built-in function is
-  // reserve_id_t, which is not defined in the builtin def file , we used int
-  // as return type and need to override the return type of these functions.
-  Call->setType(S.Context.OCLReserveIDTy);
-
-  return false;
-}
-
-// Performs a semantic analysis on {work_group_/sub_group_
-//        /_}commit_{read/write}_pipe
-// \param S Reference to the semantic analyzer.
-// \param Call The call to the builtin function to be analyzed.
-// \return True if a semantic error was found, false otherwise.
-static bool SemaBuiltinCommitRWPipe(Sema &S, CallExpr *Call) {
-  if (checkArgCount(S, Call, 2))
-    return true;
-
-  if (checkOpenCLPipeArg(S, Call))
-    return true;
-
-  // Check reserve_id_t.
-  if (!Call->getArg(1)->getType()->isReserveIDT()) {
-    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_invalid_arg)
-        << Call->getDirectCallee() << S.Context.OCLReserveIDTy
-        << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
-    return true;
-  }
-
-  return false;
-}
-
-// Performs a semantic analysis on the call to built-in Pipe
-//        Query Functions.
-// \param S Reference to the semantic analyzer.
-// \param Call The call to the builtin function to be analyzed.
-// \return True if a semantic error was found, false otherwise.
-static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) {
-  if (checkArgCount(S, Call, 1))
-    return true;
-
-  if (!Call->getArg(0)->getType()->isPipeType()) {
-    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_first_arg)
-        << Call->getDirectCallee() << Call->getArg(0)->getSourceRange();
-    return true;
-  }
-
-  return false;
-}
-
-// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
-// Performs semantic analysis for the to_global/local/private call.
-// \param S Reference to the semantic analyzer.
-// \param BuiltinID ID of the builtin function.
-// \param Call A pointer to the builtin call.
-// \return True if a semantic error has been found, false otherwise.
-static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID,
-                                    CallExpr *Call) {
-  if (Call->getNumArgs() != 1) {
-    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_arg_num)
-        << Call->getDirectCallee() << Call->getSourceRange();
-    return true;
-  }
-
-  auto RT = Call->getArg(0)->getType();
-  if (!RT->isPointerType() || RT->getPointeeType()
-      .getAddressSpace() == LangAS::opencl_constant) {
-    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_invalid_arg)
-        << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange();
-    return true;
-  }
-
-  RT = RT->getPointeeType();
-  auto Qual = RT.getQualifiers();
-  switch (BuiltinID) {
-  case Builtin::BIto_global:
-    Qual.setAddressSpace(LangAS::opencl_global);
-    break;
-  case Builtin::BIto_local:
-    Qual.setAddressSpace(LangAS::opencl_local);
-    break;
-  case Builtin::BIto_private:
-    Qual.setAddressSpace(LangAS::opencl_private);
-    break;
-  default:
-    llvm_unreachable("Invalid builtin function");
-  }
-  Call->setType(S.Context.getPointerType(S.Context.getQualifiedType(
-      RT.getUnqualifiedType(), Qual)));
-
-  return false;
-}
-
-// Emit an error and return true if the current architecture is not in the list
-// of supported architectures.
-static bool
-CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall,
-                          ArrayRef<llvm::Triple::ArchType> SupportedArchs) {
-  llvm::Triple::ArchType CurArch =
-      S.getASTContext().getTargetInfo().getTriple().getArch();
-  if (llvm::is_contained(SupportedArchs, CurArch))
-    return false;
-  S.Diag(TheCall->getLocStart(), diag::err_builtin_target_unsupported)
-      << TheCall->getSourceRange();
-  return true;
-}
-
-ExprResult
-Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
-                               CallExpr *TheCall) {
-  ExprResult TheCallResult(TheCall);
-
-  // Find out if any arguments are required to be integer constant expressions.
-  unsigned ICEArguments = 0;
-  ASTContext::GetBuiltinTypeError Error;
-  Context.GetBuiltinType(BuiltinID, Error, &ICEArguments);
-  if (Error != ASTContext::GE_None)
-    ICEArguments = 0;  // Don't diagnose previously diagnosed errors.
-  
-  // If any arguments are required to be ICE's, check and diagnose.
-  for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
-    // Skip arguments not required to be ICE's.
-    if ((ICEArguments & (1 << ArgNo)) == 0) continue;
-    
-    llvm::APSInt Result;
-    if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
-      return true;
-    ICEArguments &= ~(1 << ArgNo);
-  }
-  
-  switch (BuiltinID) {
-  case Builtin::BI__builtin___CFStringMakeConstantString:
-    assert(TheCall->getNumArgs() == 1 &&
-           "Wrong # arguments to builtin CFStringMakeConstantString");
-    if (CheckObjCString(TheCall->getArg(0)))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_ms_va_start:
-  case Builtin::BI__builtin_stdarg_start:
-  case Builtin::BI__builtin_va_start:
-    if (SemaBuiltinVAStart(BuiltinID, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__va_start: {
-    switch (Context.getTargetInfo().getTriple().getArch()) {
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-      if (SemaBuiltinVAStartARMMicrosoft(TheCall))
-        return ExprError();
-      break;
-    default:
-      if (SemaBuiltinVAStart(BuiltinID, TheCall))
-        return ExprError();
-      break;
-    }
-    break;
-  }
-
-  // The acquire, release, and no fence variants are ARM and AArch64 only.
-  case Builtin::BI_interlockedbittestandset_acq:
-  case Builtin::BI_interlockedbittestandset_rel:
-  case Builtin::BI_interlockedbittestandset_nf:
-  case Builtin::BI_interlockedbittestandreset_acq:
-  case Builtin::BI_interlockedbittestandreset_rel:
-  case Builtin::BI_interlockedbittestandreset_nf:
-    if (CheckBuiltinTargetSupport(
-            *this, BuiltinID, TheCall,
-            {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
-      return ExprError();
-    break;
-
-  // The 64-bit bittest variants are x64, ARM, and AArch64 only.
-  case Builtin::BI_bittest64:
-  case Builtin::BI_bittestandcomplement64:
-  case Builtin::BI_bittestandreset64:
-  case Builtin::BI_bittestandset64:
-  case Builtin::BI_interlockedbittestandreset64:
-  case Builtin::BI_interlockedbittestandset64:
-    if (CheckBuiltinTargetSupport(*this, BuiltinID, TheCall,
-                                  {llvm::Triple::x86_64, llvm::Triple::arm,
-                                   llvm::Triple::thumb, llvm::Triple::aarch64}))
-      return ExprError();
-    break;
-
-  case Builtin::BI__builtin_isgreater:
-  case Builtin::BI__builtin_isgreaterequal:
-  case Builtin::BI__builtin_isless:
-  case Builtin::BI__builtin_islessequal:
-  case Builtin::BI__builtin_islessgreater:
-  case Builtin::BI__builtin_isunordered:
-    if (SemaBuiltinUnorderedCompare(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_fpclassify:
-    if (SemaBuiltinFPClassification(TheCall, 6))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_isfinite:
-  case Builtin::BI__builtin_isinf:
-  case Builtin::BI__builtin_isinf_sign:
-  case Builtin::BI__builtin_isnan:
-  case Builtin::BI__builtin_isnormal:
-    if (SemaBuiltinFPClassification(TheCall, 1))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_shufflevector:
-    return SemaBuiltinShuffleVector(TheCall);
-    // TheCall will be freed by the smart pointer here, but that's fine, since
-    // SemaBuiltinShuffleVector guts it, but then doesn't release it.
-  case Builtin::BI__builtin_prefetch:
-    if (SemaBuiltinPrefetch(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_alloca_with_align:
-    if (SemaBuiltinAllocaWithAlign(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__assume:
-  case Builtin::BI__builtin_assume:
-    if (SemaBuiltinAssume(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_assume_aligned:
-    if (SemaBuiltinAssumeAligned(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_object_size:
-    if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_longjmp:
-    if (SemaBuiltinLongjmp(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_setjmp:
-    if (SemaBuiltinSetjmp(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI_setjmp:
-  case Builtin::BI_setjmpex:
-    if (checkArgCount(*this, TheCall, 1))
-      return true;
-    break;
-  case Builtin::BI__builtin_classify_type:
-    if (checkArgCount(*this, TheCall, 1)) return true;
-    TheCall->setType(Context.IntTy);
-    break;
-  case Builtin::BI__builtin_constant_p:
-    if (checkArgCount(*this, TheCall, 1)) return true;
-    TheCall->setType(Context.IntTy);
-    break;
-  case Builtin::BI__sync_fetch_and_add:
-  case Builtin::BI__sync_fetch_and_add_1:
-  case Builtin::BI__sync_fetch_and_add_2:
-  case Builtin::BI__sync_fetch_and_add_4:
-  case Builtin::BI__sync_fetch_and_add_8:
-  case Builtin::BI__sync_fetch_and_add_16:
-  case Builtin::BI__sync_fetch_and_sub:
-  case Builtin::BI__sync_fetch_and_sub_1:
-  case Builtin::BI__sync_fetch_and_sub_2:
-  case Builtin::BI__sync_fetch_and_sub_4:
-  case Builtin::BI__sync_fetch_and_sub_8:
-  case Builtin::BI__sync_fetch_and_sub_16:
-  case Builtin::BI__sync_fetch_and_or:
-  case Builtin::BI__sync_fetch_and_or_1:
-  case Builtin::BI__sync_fetch_and_or_2:
-  case Builtin::BI__sync_fetch_and_or_4:
-  case Builtin::BI__sync_fetch_and_or_8:
-  case Builtin::BI__sync_fetch_and_or_16:
-  case Builtin::BI__sync_fetch_and_and:
-  case Builtin::BI__sync_fetch_and_and_1:
-  case Builtin::BI__sync_fetch_and_and_2:
-  case Builtin::BI__sync_fetch_and_and_4:
-  case Builtin::BI__sync_fetch_and_and_8:
-  case Builtin::BI__sync_fetch_and_and_16:
-  case Builtin::BI__sync_fetch_and_xor:
-  case Builtin::BI__sync_fetch_and_xor_1:
-  case Builtin::BI__sync_fetch_and_xor_2:
-  case Builtin::BI__sync_fetch_and_xor_4:
-  case Builtin::BI__sync_fetch_and_xor_8:
-  case Builtin::BI__sync_fetch_and_xor_16:
-  case Builtin::BI__sync_fetch_and_nand:
-  case Builtin::BI__sync_fetch_and_nand_1:
-  case Builtin::BI__sync_fetch_and_nand_2:
-  case Builtin::BI__sync_fetch_and_nand_4:
-  case Builtin::BI__sync_fetch_and_nand_8:
-  case Builtin::BI__sync_fetch_and_nand_16:
-  case Builtin::BI__sync_add_and_fetch:
-  case Builtin::BI__sync_add_and_fetch_1:
-  case Builtin::BI__sync_add_and_fetch_2:
-  case Builtin::BI__sync_add_and_fetch_4:
-  case Builtin::BI__sync_add_and_fetch_8:
-  case Builtin::BI__sync_add_and_fetch_16:
-  case Builtin::BI__sync_sub_and_fetch:
-  case Builtin::BI__sync_sub_and_fetch_1:
-  case Builtin::BI__sync_sub_and_fetch_2:
-  case Builtin::BI__sync_sub_and_fetch_4:
-  case Builtin::BI__sync_sub_and_fetch_8:
-  case Builtin::BI__sync_sub_and_fetch_16:
-  case Builtin::BI__sync_and_and_fetch:
-  case Builtin::BI__sync_and_and_fetch_1:
-  case Builtin::BI__sync_and_and_fetch_2:
-  case Builtin::BI__sync_and_and_fetch_4:
-  case Builtin::BI__sync_and_and_fetch_8:
-  case Builtin::BI__sync_and_and_fetch_16:
-  case Builtin::BI__sync_or_and_fetch:
-  case Builtin::BI__sync_or_and_fetch_1:
-  case Builtin::BI__sync_or_and_fetch_2:
-  case Builtin::BI__sync_or_and_fetch_4:
-  case Builtin::BI__sync_or_and_fetch_8:
-  case Builtin::BI__sync_or_and_fetch_16:
-  case Builtin::BI__sync_xor_and_fetch:
-  case Builtin::BI__sync_xor_and_fetch_1:
-  case Builtin::BI__sync_xor_and_fetch_2:
-  case Builtin::BI__sync_xor_and_fetch_4:
-  case Builtin::BI__sync_xor_and_fetch_8:
-  case Builtin::BI__sync_xor_and_fetch_16:
-  case Builtin::BI__sync_nand_and_fetch:
-  case Builtin::BI__sync_nand_and_fetch_1:
-  case Builtin::BI__sync_nand_and_fetch_2:
-  case Builtin::BI__sync_nand_and_fetch_4:
-  case Builtin::BI__sync_nand_and_fetch_8:
-  case Builtin::BI__sync_nand_and_fetch_16:
-  case Builtin::BI__sync_val_compare_and_swap:
-  case Builtin::BI__sync_val_compare_and_swap_1:
-  case Builtin::BI__sync_val_compare_and_swap_2:
-  case Builtin::BI__sync_val_compare_and_swap_4:
-  case Builtin::BI__sync_val_compare_and_swap_8:
-  case Builtin::BI__sync_val_compare_and_swap_16:
-  case Builtin::BI__sync_bool_compare_and_swap:
-  case Builtin::BI__sync_bool_compare_and_swap_1:
-  case Builtin::BI__sync_bool_compare_and_swap_2:
-  case Builtin::BI__sync_bool_compare_and_swap_4:
-  case Builtin::BI__sync_bool_compare_and_swap_8:
-  case Builtin::BI__sync_bool_compare_and_swap_16:
-  case Builtin::BI__sync_lock_test_and_set:
-  case Builtin::BI__sync_lock_test_and_set_1:
-  case Builtin::BI__sync_lock_test_and_set_2:
-  case Builtin::BI__sync_lock_test_and_set_4:
-  case Builtin::BI__sync_lock_test_and_set_8:
-  case Builtin::BI__sync_lock_test_and_set_16:
-  case Builtin::BI__sync_lock_release:
-  case Builtin::BI__sync_lock_release_1:
-  case Builtin::BI__sync_lock_release_2:
-  case Builtin::BI__sync_lock_release_4:
-  case Builtin::BI__sync_lock_release_8:
-  case Builtin::BI__sync_lock_release_16:
-  case Builtin::BI__sync_swap:
-  case Builtin::BI__sync_swap_1:
-  case Builtin::BI__sync_swap_2:
-  case Builtin::BI__sync_swap_4:
-  case Builtin::BI__sync_swap_8:
-  case Builtin::BI__sync_swap_16:
-    return SemaBuiltinAtomicOverloaded(TheCallResult);
-  case Builtin::BI__builtin_nontemporal_load:
-  case Builtin::BI__builtin_nontemporal_store:
-    return SemaBuiltinNontemporalOverloaded(TheCallResult);
-#define BUILTIN(ID, TYPE, ATTRS)
-#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
-  case Builtin::BI##ID: \
-    return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
-#include "clang/Basic/Builtins.def"
-  case Builtin::BI__annotation:
-    if (SemaBuiltinMSVCAnnotation(*this, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_annotation:
-    if (SemaBuiltinAnnotation(*this, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_addressof:
-    if (SemaBuiltinAddressof(*this, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_add_overflow:
-  case Builtin::BI__builtin_sub_overflow:
-  case Builtin::BI__builtin_mul_overflow:
-    if (SemaBuiltinOverflow(*this, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_operator_new:
-  case Builtin::BI__builtin_operator_delete: {
-    bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
-    ExprResult Res =
-        SemaBuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
-    if (Res.isInvalid())
-      CorrectDelayedTyposInExpr(TheCallResult.get());
-    return Res;
-  }
-  case Builtin::BI__builtin_dump_struct: {
-    // We first want to ensure we are called with 2 arguments
-    if (checkArgCount(*this, TheCall, 2))
-      return ExprError();
-    // Ensure that the first argument is of type 'struct XX *'
-    const Expr *PtrArg = TheCall->getArg(0)->IgnoreParenImpCasts();
-    const QualType PtrArgType = PtrArg->getType();
-    if (!PtrArgType->isPointerType() ||
-        !PtrArgType->getPointeeType()->isRecordType()) {
-      Diag(PtrArg->getLocStart(), diag::err_typecheck_convert_incompatible)
-          << PtrArgType << "structure pointer" << 1 << 0 << 3 << 1 << PtrArgType
-          << "structure pointer";
-      return ExprError();
+  // reserve_id_t, which is not defined in the builtin def file , we used int
+  // as return type and need to override the return type of these functions.
+  Call->setType(S.Context.OCLReserveIDTy);
+
+  return false;
+}
+
+// Performs a semantic analysis on {work_group_/sub_group_
+//        /_}commit_{read/write}_pipe
+// \param S Reference to the semantic analyzer.
+// \param Call The call to the builtin function to be analyzed.
+// \return True if a semantic error was found, false otherwise.
+static bool SemaBuiltinCommitRWPipe(Sema &S, CallExpr *Call) {
+  if (checkArgCount(S, Call, 2))
+    return true;
+
+  if (checkOpenCLPipeArg(S, Call))
+    return true;
+
+  // Check reserve_id_t.
+  if (!Call->getArg(1)->getType()->isReserveIDT()) {
+    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_invalid_arg)
+        << Call->getDirectCallee() << S.Context.OCLReserveIDTy
+        << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
+    return true;
+  }
+
+  return false;
+}
+
+// Performs a semantic analysis on the call to built-in Pipe
+//        Query Functions.
+// \param S Reference to the semantic analyzer.
+// \param Call The call to the builtin function to be analyzed.
+// \return True if a semantic error was found, false otherwise.
+static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) {
+  if (checkArgCount(S, Call, 1))
+    return true;
+
+  if (!Call->getArg(0)->getType()->isPipeType()) {
+    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_first_arg)
+        << Call->getDirectCallee() << Call->getArg(0)->getSourceRange();
+    return true;
+  }
+
+  return false;
+}
+
+// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
+// Performs semantic analysis for the to_global/local/private call.
+// \param S Reference to the semantic analyzer.
+// \param BuiltinID ID of the builtin function.
+// \param Call A pointer to the builtin call.
+// \return True if a semantic error has been found, false otherwise.
+static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID,
+                                    CallExpr *Call) {
+  if (Call->getNumArgs() != 1) {
+    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_arg_num)
+        << Call->getDirectCallee() << Call->getSourceRange();
+    return true;
+  }
+
+  auto RT = Call->getArg(0)->getType();
+  if (!RT->isPointerType() || RT->getPointeeType()
+      .getAddressSpace() == LangAS::opencl_constant) {
+    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_invalid_arg)
+        << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange();
+    return true;
+  }
+
+  RT = RT->getPointeeType();
+  auto Qual = RT.getQualifiers();
+  switch (BuiltinID) {
+  case Builtin::BIto_global:
+    Qual.setAddressSpace(LangAS::opencl_global);
+    break;
+  case Builtin::BIto_local:
+    Qual.setAddressSpace(LangAS::opencl_local);
+    break;
+  case Builtin::BIto_private:
+    Qual.setAddressSpace(LangAS::opencl_private);
+    break;
+  default:
+    llvm_unreachable("Invalid builtin function");
+  }
+  Call->setType(S.Context.getPointerType(S.Context.getQualifiedType(
+      RT.getUnqualifiedType(), Qual)));
+
+  return false;
+}
+
+// Emit an error and return true if the current architecture is not in the list
+// of supported architectures.
+static bool
+CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall,
+                          ArrayRef<llvm::Triple::ArchType> SupportedArchs) {
+  llvm::Triple::ArchType CurArch =
+      S.getASTContext().getTargetInfo().getTriple().getArch();
+  if (llvm::is_contained(SupportedArchs, CurArch))
+    return false;
+  S.Diag(TheCall->getLocStart(), diag::err_builtin_target_unsupported)
+      << TheCall->getSourceRange();
+  return true;
+}
+
+ExprResult
+Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
+                               CallExpr *TheCall) {
+  ExprResult TheCallResult(TheCall);
+
+  // Find out if any arguments are required to be integer constant expressions.
+  unsigned ICEArguments = 0;
+  ASTContext::GetBuiltinTypeError Error;
+  Context.GetBuiltinType(BuiltinID, Error, &ICEArguments);
+  if (Error != ASTContext::GE_None)
+    ICEArguments = 0;  // Don't diagnose previously diagnosed errors.
+  
+  // If any arguments are required to be ICE's, check and diagnose.
+  for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
+    // Skip arguments not required to be ICE's.
+    if ((ICEArguments & (1 << ArgNo)) == 0) continue;
+    
+    llvm::APSInt Result;
+    if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
+      return true;
+    ICEArguments &= ~(1 << ArgNo);
+  }
+  
+  switch (BuiltinID) {
+  case Builtin::BI__builtin___CFStringMakeConstantString:
+    assert(TheCall->getNumArgs() == 1 &&
+           "Wrong # arguments to builtin CFStringMakeConstantString");
+    if (CheckObjCString(TheCall->getArg(0)))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_ms_va_start:
+  case Builtin::BI__builtin_stdarg_start:
+  case Builtin::BI__builtin_va_start:
+    if (SemaBuiltinVAStart(BuiltinID, TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__va_start: {
+    switch (Context.getTargetInfo().getTriple().getArch()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::thumb:
+      if (SemaBuiltinVAStartARMMicrosoft(TheCall))
+        return ExprError();
+      break;
+    default:
+      if (SemaBuiltinVAStart(BuiltinID, TheCall))
+        return ExprError();
+      break;
+    }
+    break;
+  }
+
+  // The acquire, release, and no fence variants are ARM and AArch64 only.
+  case Builtin::BI_interlockedbittestandset_acq:
+  case Builtin::BI_interlockedbittestandset_rel:
+  case Builtin::BI_interlockedbittestandset_nf:
+  case Builtin::BI_interlockedbittestandreset_acq:
+  case Builtin::BI_interlockedbittestandreset_rel:
+  case Builtin::BI_interlockedbittestandreset_nf:
+    if (CheckBuiltinTargetSupport(
+            *this, BuiltinID, TheCall,
+            {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
+      return ExprError();
+    break;
+
+  // The 64-bit bittest variants are x64, ARM, and AArch64 only.
+  case Builtin::BI_bittest64:
+  case Builtin::BI_bittestandcomplement64:
+  case Builtin::BI_bittestandreset64:
+  case Builtin::BI_bittestandset64:
+  case Builtin::BI_interlockedbittestandreset64:
+  case Builtin::BI_interlockedbittestandset64:
+    if (CheckBuiltinTargetSupport(*this, BuiltinID, TheCall,
+                                  {llvm::Triple::x86_64, llvm::Triple::arm,
+                                   llvm::Triple::thumb, llvm::Triple::aarch64}))
+      return ExprError();
+    break;
+
+  case Builtin::BI__builtin_isgreater:
+  case Builtin::BI__builtin_isgreaterequal:
+  case Builtin::BI__builtin_isless:
+  case Builtin::BI__builtin_islessequal:
+  case Builtin::BI__builtin_islessgreater:
+  case Builtin::BI__builtin_isunordered:
+    if (SemaBuiltinUnorderedCompare(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_fpclassify:
+    if (SemaBuiltinFPClassification(TheCall, 6))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_isfinite:
+  case Builtin::BI__builtin_isinf:
+  case Builtin::BI__builtin_isinf_sign:
+  case Builtin::BI__builtin_isnan:
+  case Builtin::BI__builtin_isnormal:
+  case Builtin::BI__builtin_signbit:
+  case Builtin::BI__builtin_signbitf:
+  case Builtin::BI__builtin_signbitl:
+    if (SemaBuiltinFPClassification(TheCall, 1))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_shufflevector:
+    return SemaBuiltinShuffleVector(TheCall);
+    // TheCall will be freed by the smart pointer here, but that's fine, since
+    // SemaBuiltinShuffleVector guts it, but then doesn't release it.
+  case Builtin::BI__builtin_prefetch:
+    if (SemaBuiltinPrefetch(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_alloca_with_align:
+    if (SemaBuiltinAllocaWithAlign(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__assume:
+  case Builtin::BI__builtin_assume:
+    if (SemaBuiltinAssume(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_assume_aligned:
+    if (SemaBuiltinAssumeAligned(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_object_size:
+    if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_longjmp:
+    if (SemaBuiltinLongjmp(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_setjmp:
+    if (SemaBuiltinSetjmp(TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI_setjmp:
+  case Builtin::BI_setjmpex:
+    if (checkArgCount(*this, TheCall, 1))
+      return true;
+    break;
+  case Builtin::BI__builtin_classify_type:
+    if (checkArgCount(*this, TheCall, 1)) return true;
+    TheCall->setType(Context.IntTy);
+    break;
+  case Builtin::BI__builtin_constant_p:
+    if (checkArgCount(*this, TheCall, 1)) return true;
+    TheCall->setType(Context.IntTy);
+    break;
+  case Builtin::BI__sync_fetch_and_add:
+  case Builtin::BI__sync_fetch_and_add_1:
+  case Builtin::BI__sync_fetch_and_add_2:
+  case Builtin::BI__sync_fetch_and_add_4:
+  case Builtin::BI__sync_fetch_and_add_8:
+  case Builtin::BI__sync_fetch_and_add_16:
+  case Builtin::BI__sync_fetch_and_sub:
+  case Builtin::BI__sync_fetch_and_sub_1:
+  case Builtin::BI__sync_fetch_and_sub_2:
+  case Builtin::BI__sync_fetch_and_sub_4:
+  case Builtin::BI__sync_fetch_and_sub_8:
+  case Builtin::BI__sync_fetch_and_sub_16:
+  case Builtin::BI__sync_fetch_and_or:
+  case Builtin::BI__sync_fetch_and_or_1:
+  case Builtin::BI__sync_fetch_and_or_2:
+  case Builtin::BI__sync_fetch_and_or_4:
+  case Builtin::BI__sync_fetch_and_or_8:
+  case Builtin::BI__sync_fetch_and_or_16:
+  case Builtin::BI__sync_fetch_and_and:
+  case Builtin::BI__sync_fetch_and_and_1:
+  case Builtin::BI__sync_fetch_and_and_2:
+  case Builtin::BI__sync_fetch_and_and_4:
+  case Builtin::BI__sync_fetch_and_and_8:
+  case Builtin::BI__sync_fetch_and_and_16:
+  case Builtin::BI__sync_fetch_and_xor:
+  case Builtin::BI__sync_fetch_and_xor_1:
+  case Builtin::BI__sync_fetch_and_xor_2:
+  case Builtin::BI__sync_fetch_and_xor_4:
+  case Builtin::BI__sync_fetch_and_xor_8:
+  case Builtin::BI__sync_fetch_and_xor_16:
+  case Builtin::BI__sync_fetch_and_nand:
+  case Builtin::BI__sync_fetch_and_nand_1:
+  case Builtin::BI__sync_fetch_and_nand_2:
+  case Builtin::BI__sync_fetch_and_nand_4:
+  case Builtin::BI__sync_fetch_and_nand_8:
+  case Builtin::BI__sync_fetch_and_nand_16:
+  case Builtin::BI__sync_add_and_fetch:
+  case Builtin::BI__sync_add_and_fetch_1:
+  case Builtin::BI__sync_add_and_fetch_2:
+  case Builtin::BI__sync_add_and_fetch_4:
+  case Builtin::BI__sync_add_and_fetch_8:
+  case Builtin::BI__sync_add_and_fetch_16:
+  case Builtin::BI__sync_sub_and_fetch:
+  case Builtin::BI__sync_sub_and_fetch_1:
+  case Builtin::BI__sync_sub_and_fetch_2:
+  case Builtin::BI__sync_sub_and_fetch_4:
+  case Builtin::BI__sync_sub_and_fetch_8:
+  case Builtin::BI__sync_sub_and_fetch_16:
+  case Builtin::BI__sync_and_and_fetch:
+  case Builtin::BI__sync_and_and_fetch_1:
+  case Builtin::BI__sync_and_and_fetch_2:
+  case Builtin::BI__sync_and_and_fetch_4:
+  case Builtin::BI__sync_and_and_fetch_8:
+  case Builtin::BI__sync_and_and_fetch_16:
+  case Builtin::BI__sync_or_and_fetch:
+  case Builtin::BI__sync_or_and_fetch_1:
+  case Builtin::BI__sync_or_and_fetch_2:
+  case Builtin::BI__sync_or_and_fetch_4:
+  case Builtin::BI__sync_or_and_fetch_8:
+  case Builtin::BI__sync_or_and_fetch_16:
+  case Builtin::BI__sync_xor_and_fetch:
+  case Builtin::BI__sync_xor_and_fetch_1:
+  case Builtin::BI__sync_xor_and_fetch_2:
+  case Builtin::BI__sync_xor_and_fetch_4:
+  case Builtin::BI__sync_xor_and_fetch_8:
+  case Builtin::BI__sync_xor_and_fetch_16:
+  case Builtin::BI__sync_nand_and_fetch:
+  case Builtin::BI__sync_nand_and_fetch_1:
+  case Builtin::BI__sync_nand_and_fetch_2:
+  case Builtin::BI__sync_nand_and_fetch_4:
+  case Builtin::BI__sync_nand_and_fetch_8:
+  case Builtin::BI__sync_nand_and_fetch_16:
+  case Builtin::BI__sync_val_compare_and_swap:
+  case Builtin::BI__sync_val_compare_and_swap_1:
+  case Builtin::BI__sync_val_compare_and_swap_2:
+  case Builtin::BI__sync_val_compare_and_swap_4:
+  case Builtin::BI__sync_val_compare_and_swap_8:
+  case Builtin::BI__sync_val_compare_and_swap_16:
+  case Builtin::BI__sync_bool_compare_and_swap:
+  case Builtin::BI__sync_bool_compare_and_swap_1:
+  case Builtin::BI__sync_bool_compare_and_swap_2:
+  case Builtin::BI__sync_bool_compare_and_swap_4:
+  case Builtin::BI__sync_bool_compare_and_swap_8:
+  case Builtin::BI__sync_bool_compare_and_swap_16:
+  case Builtin::BI__sync_lock_test_and_set:
+  case Builtin::BI__sync_lock_test_and_set_1:
+  case Builtin::BI__sync_lock_test_and_set_2:
+  case Builtin::BI__sync_lock_test_and_set_4:
+  case Builtin::BI__sync_lock_test_and_set_8:
+  case Builtin::BI__sync_lock_test_and_set_16:
+  case Builtin::BI__sync_lock_release:
+  case Builtin::BI__sync_lock_release_1:
+  case Builtin::BI__sync_lock_release_2:
+  case Builtin::BI__sync_lock_release_4:
+  case Builtin::BI__sync_lock_release_8:
+  case Builtin::BI__sync_lock_release_16:
+  case Builtin::BI__sync_swap:
+  case Builtin::BI__sync_swap_1:
+  case Builtin::BI__sync_swap_2:
+  case Builtin::BI__sync_swap_4:
+  case Builtin::BI__sync_swap_8:
+  case Builtin::BI__sync_swap_16:
+    return SemaBuiltinAtomicOverloaded(TheCallResult);
+  case Builtin::BI__builtin_nontemporal_load:
+  case Builtin::BI__builtin_nontemporal_store:
+    return SemaBuiltinNontemporalOverloaded(TheCallResult);
+#define BUILTIN(ID, TYPE, ATTRS)
+#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
+  case Builtin::BI##ID: \
+    return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
+#include "clang/Basic/Builtins.def"
+  case Builtin::BI__annotation:
+    if (SemaBuiltinMSVCAnnotation(*this, TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_annotation:
+    if (SemaBuiltinAnnotation(*this, TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_addressof:
+    if (SemaBuiltinAddressof(*this, TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_add_overflow:
+  case Builtin::BI__builtin_sub_overflow:
+  case Builtin::BI__builtin_mul_overflow:
+    if (SemaBuiltinOverflow(*this, TheCall))
+      return ExprError();
+    break;
+  case Builtin::BI__builtin_operator_new:
+  case Builtin::BI__builtin_operator_delete: {
+    bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
+    ExprResult Res =
+        SemaBuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
+    if (Res.isInvalid())
+      CorrectDelayedTyposInExpr(TheCallResult.get());
+    return Res;
+  }
+  case Builtin::BI__builtin_dump_struct: {
+    // We first want to ensure we are called with 2 arguments
+    if (checkArgCount(*this, TheCall, 2))
+      return ExprError();
+    // Ensure that the first argument is of type 'struct XX *'
+    const Expr *PtrArg = TheCall->getArg(0)->IgnoreParenImpCasts();
+    const QualType PtrArgType = PtrArg->getType();
+    if (!PtrArgType->isPointerType() ||
+        !PtrArgType->getPointeeType()->isRecordType()) {
+      Diag(PtrArg->getLocStart(), diag::err_typecheck_convert_incompatible)
+          << PtrArgType << "structure pointer" << 1 << 0 << 3 << 1 << PtrArgType
+          << "structure pointer";
+      return ExprError();
     }
 
     // Ensure that the second argument is of type 'FunctionType'
@@ -4392,415 +4395,419 @@
   return false;
 }
 
-/// Check the arguments to '__builtin_va_start' or '__builtin_ms_va_start'
-/// for validity.  Emit an error and return true on failure; return false
-/// on success.
-bool Sema::SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {
-  Expr *Fn = TheCall->getCallee();
-
-  if (checkVAStartABI(*this, BuiltinID, Fn))
-    return true;
-
-  if (TheCall->getNumArgs() > 2) {
-    Diag(TheCall->getArg(2)->getLocStart(),
-         diag::err_typecheck_call_too_many_args)
-      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
-      << Fn->getSourceRange()
-      << SourceRange(TheCall->getArg(2)->getLocStart(),
-                     (*(TheCall->arg_end()-1))->getLocEnd());
-    return true;
-  }
-
-  if (TheCall->getNumArgs() < 2) {
-    return Diag(TheCall->getLocEnd(),
-      diag::err_typecheck_call_too_few_args_at_least)
-      << 0 /*function call*/ << 2 << TheCall->getNumArgs();
-  }
-
-  // Type-check the first argument normally.
-  if (checkBuiltinArgument(*this, TheCall, 0))
-    return true;
-
-  // Check that the current function is variadic, and get its last parameter.
-  ParmVarDecl *LastParam;
-  if (checkVAStartIsInVariadicFunction(*this, Fn, &LastParam))
-    return true;
-
-  // Verify that the second argument to the builtin is the last argument of the
-  // current function or method.
-  bool SecondArgIsLastNamedArgument = false;
-  const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();
-
-  // These are valid if SecondArgIsLastNamedArgument is false after the next
-  // block.
-  QualType Type;
-  SourceLocation ParamLoc;
-  bool IsCRegister = false;
-
-  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
-    if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
-      SecondArgIsLastNamedArgument = PV == LastParam;
-
-      Type = PV->getType();
-      ParamLoc = PV->getLocation();
-      IsCRegister =
-          PV->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus;
-    }
-  }
-
-  if (!SecondArgIsLastNamedArgument)
-    Diag(TheCall->getArg(1)->getLocStart(),
-         diag::warn_second_arg_of_va_start_not_last_named_param);
-  else if (IsCRegister || Type->isReferenceType() ||
-           Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
-             // Promotable integers are UB, but enumerations need a bit of
-             // extra checking to see what their promotable type actually is.
-             if (!Type->isPromotableIntegerType())
-               return false;
-             if (!Type->isEnumeralType())
-               return true;
-             const EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
-             return !(ED &&
-                      Context.typesAreCompatible(ED->getPromotionType(), Type));
-           }()) {
-    unsigned Reason = 0;
-    if (Type->isReferenceType())  Reason = 1;
-    else if (IsCRegister)         Reason = 2;
-    Diag(Arg->getLocStart(), diag::warn_va_start_type_is_undefined) << Reason;
-    Diag(ParamLoc, diag::note_parameter_type) << Type;
-  }
-
-  TheCall->setType(Context.VoidTy);
-  return false;
-}
-
-bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) {
-  // void __va_start(va_list *ap, const char *named_addr, size_t slot_size,
-  //                 const char *named_addr);
-
-  Expr *Func = Call->getCallee();
-
-  if (Call->getNumArgs() < 3)
-    return Diag(Call->getLocEnd(),
-                diag::err_typecheck_call_too_few_args_at_least)
-           << 0 /*function call*/ << 3 << Call->getNumArgs();
-
-  // Type-check the first argument normally.
-  if (checkBuiltinArgument(*this, Call, 0))
-    return true;
-
-  // Check that the current function is variadic.
-  if (checkVAStartIsInVariadicFunction(*this, Func))
-    return true;
-
-  // __va_start on Windows does not validate the parameter qualifiers
-
-  const Expr *Arg1 = Call->getArg(1)->IgnoreParens();
-  const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();
-
-  const Expr *Arg2 = Call->getArg(2)->IgnoreParens();
-  const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();
-
-  const QualType &ConstCharPtrTy =
-      Context.getPointerType(Context.CharTy.withConst());
-  if (!Arg1Ty->isPointerType() ||
-      Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy)
-    Diag(Arg1->getLocStart(), diag::err_typecheck_convert_incompatible)
-        << Arg1->getType() << ConstCharPtrTy
-        << 1 /* different class */
-        << 0 /* qualifier difference */
-        << 3 /* parameter mismatch */
-        << 2 << Arg1->getType() << ConstCharPtrTy;
-
-  const QualType SizeTy = Context.getSizeType();
-  if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)
-    Diag(Arg2->getLocStart(), diag::err_typecheck_convert_incompatible)
-        << Arg2->getType() << SizeTy
-        << 1 /* different class */
-        << 0 /* qualifier difference */
-        << 3 /* parameter mismatch */
-        << 3 << Arg2->getType() << SizeTy;
-
-  return false;
-}
-
-/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and
-/// friends.  This is declared to take (...), so we have to check everything.
-bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
-  if (TheCall->getNumArgs() < 2)
-    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
-      << 0 << 2 << TheCall->getNumArgs()/*function call*/;
-  if (TheCall->getNumArgs() > 2)
-    return Diag(TheCall->getArg(2)->getLocStart(),
-                diag::err_typecheck_call_too_many_args)
-      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
-      << SourceRange(TheCall->getArg(2)->getLocStart(),
-                     (*(TheCall->arg_end()-1))->getLocEnd());
-
-  ExprResult OrigArg0 = TheCall->getArg(0);
-  ExprResult OrigArg1 = TheCall->getArg(1);
-
-  // Do standard promotions between the two arguments, returning their common
-  // type.
-  QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);
-  if (OrigArg0.isInvalid() || OrigArg1.isInvalid())
-    return true;
-
-  // Make sure any conversions are pushed back into the call; this is
-  // type safe since unordered compare builtins are declared as "_Bool
-  // foo(...)".
-  TheCall->setArg(0, OrigArg0.get());
-  TheCall->setArg(1, OrigArg1.get());
-
-  if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent())
-    return false;
-
-  // If the common type isn't a real floating type, then the arguments were
-  // invalid for this operation.
-  if (Res.isNull() || !Res->isRealFloatingType())
-    return Diag(OrigArg0.get()->getLocStart(),
-                diag::err_typecheck_call_invalid_ordered_compare)
-      << OrigArg0.get()->getType() << OrigArg1.get()->getType()
-      << SourceRange(OrigArg0.get()->getLocStart(), OrigArg1.get()->getLocEnd());
-
-  return false;
-}
-
-/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like
-/// __builtin_isnan and friends.  This is declared to take (...), so we have
-/// to check everything. We expect the last argument to be a floating point
-/// value.
-bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
-  if (TheCall->getNumArgs() < NumArgs)
-    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
-      << 0 << NumArgs << TheCall->getNumArgs()/*function call*/;
-  if (TheCall->getNumArgs() > NumArgs)
-    return Diag(TheCall->getArg(NumArgs)->getLocStart(),
-                diag::err_typecheck_call_too_many_args)
-      << 0 /*function call*/ << NumArgs << TheCall->getNumArgs()
-      << SourceRange(TheCall->getArg(NumArgs)->getLocStart(),
-                     (*(TheCall->arg_end()-1))->getLocEnd());
-
-  Expr *OrigArg = TheCall->getArg(NumArgs-1);
-
-  if (OrigArg->isTypeDependent())
-    return false;
-
-  // This operation requires a non-_Complex floating-point number.
-  if (!OrigArg->getType()->isRealFloatingType())
-    return Diag(OrigArg->getLocStart(),
-                diag::err_typecheck_call_invalid_unary_fp)
-      << OrigArg->getType() << OrigArg->getSourceRange();
-
-  // If this is an implicit conversion from float -> float or double, remove it.
-  if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
-    // Only remove standard FloatCasts, leaving other casts inplace
-    if (Cast->getCastKind() == CK_FloatingCast) {
-      Expr *CastArg = Cast->getSubExpr();
-      if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
-          assert((Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
-                  Cast->getType()->isSpecificBuiltinType(BuiltinType::Float)) &&
-               "promotion from float to either float or double is the only expected cast here");
-        Cast->setSubExpr(nullptr);
-        TheCall->setArg(NumArgs-1, CastArg);
-      }
-    }
-  }
-  
-  return false;
-}
-
-// Customized Sema Checking for VSX builtins that have the following signature:
-// vector [...] builtinName(vector [...], vector [...], const int);
-// Which takes the same type of vectors (any legal vector type) for the first
-// two arguments and takes compile time constant for the third argument.
-// Example builtins are :
-// vector double vec_xxpermdi(vector double, vector double, int);
-// vector short vec_xxsldwi(vector short, vector short, int);
-bool Sema::SemaBuiltinVSX(CallExpr *TheCall) {
-  unsigned ExpectedNumArgs = 3;
-  if (TheCall->getNumArgs() < ExpectedNumArgs)
-    return Diag(TheCall->getLocEnd(),
-                diag::err_typecheck_call_too_few_args_at_least)
-           << 0 /*function call*/ <<  ExpectedNumArgs << TheCall->getNumArgs()
-           << TheCall->getSourceRange();
-
-  if (TheCall->getNumArgs() > ExpectedNumArgs)
-    return Diag(TheCall->getLocEnd(),
-                diag::err_typecheck_call_too_many_args_at_most)
-           << 0 /*function call*/ << ExpectedNumArgs << TheCall->getNumArgs()
-           << TheCall->getSourceRange();
-
-  // Check the third argument is a compile time constant
-  llvm::APSInt Value;
-  if(!TheCall->getArg(2)->isIntegerConstantExpr(Value, Context))
-    return Diag(TheCall->getLocStart(),
-                diag::err_vsx_builtin_nonconstant_argument)
-           << 3 /* argument index */ << TheCall->getDirectCallee()
-           << SourceRange(TheCall->getArg(2)->getLocStart(),
-                          TheCall->getArg(2)->getLocEnd());
-
-  QualType Arg1Ty = TheCall->getArg(0)->getType();
-  QualType Arg2Ty = TheCall->getArg(1)->getType();
-
-  // Check the type of argument 1 and argument 2 are vectors.
-  SourceLocation BuiltinLoc = TheCall->getLocStart();
-  if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||
-      (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {
-    return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
-           << TheCall->getDirectCallee()
-           << SourceRange(TheCall->getArg(0)->getLocStart(),
-                          TheCall->getArg(1)->getLocEnd());
-  }
-
-  // Check the first two arguments are the same type.
-  if (!Context.hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {
-    return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
-           << TheCall->getDirectCallee()
-           << SourceRange(TheCall->getArg(0)->getLocStart(),
-                          TheCall->getArg(1)->getLocEnd());
-  }
-
-  // When default clang type checking is turned off and the customized type
-  // checking is used, the returning type of the function must be explicitly
-  // set. Otherwise it is _Bool by default.
-  TheCall->setType(Arg1Ty);
-
-  return false;
-}
-
-/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
-// This is declared to take (...), so we have to check everything.
-ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
-  if (TheCall->getNumArgs() < 2)
-    return ExprError(Diag(TheCall->getLocEnd(),
-                          diag::err_typecheck_call_too_few_args_at_least)
-                     << 0 /*function call*/ << 2 << TheCall->getNumArgs()
-                     << TheCall->getSourceRange());
-
-  // Determine which of the following types of shufflevector we're checking:
-  // 1) unary, vector mask: (lhs, mask)
-  // 2) binary, scalar mask: (lhs, rhs, index, ..., index)
-  QualType resType = TheCall->getArg(0)->getType();
-  unsigned numElements = 0;
-
-  if (!TheCall->getArg(0)->isTypeDependent() &&
-      !TheCall->getArg(1)->isTypeDependent()) {
-    QualType LHSType = TheCall->getArg(0)->getType();
-    QualType RHSType = TheCall->getArg(1)->getType();
-
-    if (!LHSType->isVectorType() || !RHSType->isVectorType())
-      return ExprError(Diag(TheCall->getLocStart(),
-                            diag::err_vec_builtin_non_vector)
-                       << TheCall->getDirectCallee()
-                       << SourceRange(TheCall->getArg(0)->getLocStart(),
-                                      TheCall->getArg(1)->getLocEnd()));
-
-    numElements = LHSType->getAs<VectorType>()->getNumElements();
-    unsigned numResElements = TheCall->getNumArgs() - 2;
-
-    // Check to see if we have a call with 2 vector arguments, the unary shuffle
-    // with mask.  If so, verify that RHS is an integer vector type with the
-    // same number of elts as lhs.
-    if (TheCall->getNumArgs() == 2) {
-      if (!RHSType->hasIntegerRepresentation() ||
-          RHSType->getAs<VectorType>()->getNumElements() != numElements)
-        return ExprError(Diag(TheCall->getLocStart(),
-                              diag::err_vec_builtin_incompatible_vector)
-                         << TheCall->getDirectCallee()
-                         << SourceRange(TheCall->getArg(1)->getLocStart(),
-                                        TheCall->getArg(1)->getLocEnd()));
-    } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {
-      return ExprError(Diag(TheCall->getLocStart(),
-                            diag::err_vec_builtin_incompatible_vector)
-                       << TheCall->getDirectCallee()
-                       << SourceRange(TheCall->getArg(0)->getLocStart(),
-                                      TheCall->getArg(1)->getLocEnd()));
-    } else if (numElements != numResElements) {
-      QualType eltType = LHSType->getAs<VectorType>()->getElementType();
-      resType = Context.getVectorType(eltType, numResElements,
-                                      VectorType::GenericVector);
-    }
-  }
-
-  for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {
-    if (TheCall->getArg(i)->isTypeDependent() ||
-        TheCall->getArg(i)->isValueDependent())
-      continue;
-
-    llvm::APSInt Result(32);
-    if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context))
-      return ExprError(Diag(TheCall->getLocStart(),
-                            diag::err_shufflevector_nonconstant_argument)
-                       << TheCall->getArg(i)->getSourceRange());
-
-    // Allow -1 which will be translated to undef in the IR.
-    if (Result.isSigned() && Result.isAllOnesValue())
-      continue;
-
-    if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)
-      return ExprError(Diag(TheCall->getLocStart(),
-                            diag::err_shufflevector_argument_too_large)
-                       << TheCall->getArg(i)->getSourceRange());
-  }
-
-  SmallVector<Expr*, 32> exprs;
-
-  for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
-    exprs.push_back(TheCall->getArg(i));
-    TheCall->setArg(i, nullptr);
-  }
-
-  return new (Context) ShuffleVectorExpr(Context, exprs, resType,
-                                         TheCall->getCallee()->getLocStart(),
-                                         TheCall->getRParenLoc());
-}
-
-/// SemaConvertVectorExpr - Handle __builtin_convertvector
-ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
-                                       SourceLocation BuiltinLoc,
-                                       SourceLocation RParenLoc) {
-  ExprValueKind VK = VK_RValue;
-  ExprObjectKind OK = OK_Ordinary;
-  QualType DstTy = TInfo->getType();
-  QualType SrcTy = E->getType();
-
-  if (!SrcTy->isVectorType() && !SrcTy->isDependentType())
-    return ExprError(Diag(BuiltinLoc,
-                          diag::err_convertvector_non_vector)
-                     << E->getSourceRange());
-  if (!DstTy->isVectorType() && !DstTy->isDependentType())
-    return ExprError(Diag(BuiltinLoc,
-                          diag::err_convertvector_non_vector_type));
-
-  if (!SrcTy->isDependentType() && !DstTy->isDependentType()) {
-    unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements();
-    unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements();
-    if (SrcElts != DstElts)
-      return ExprError(Diag(BuiltinLoc,
-                            diag::err_convertvector_incompatible_vector)
-                       << E->getSourceRange());
-  }
-
-  return new (Context)
-      ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);
-}
-
-/// SemaBuiltinPrefetch - Handle __builtin_prefetch.
-// This is declared to take (const void*, ...) and can take two
-// optional constant int args.
-bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
-  unsigned NumArgs = TheCall->getNumArgs();
-
-  if (NumArgs > 3)
-    return Diag(TheCall->getLocEnd(),
-             diag::err_typecheck_call_too_many_args_at_most)
-             << 0 /*function call*/ << 3 << NumArgs
-             << TheCall->getSourceRange();
-
-  // Argument 0 is checked for us and the remaining arguments must be
-  // constant integers.
-  for (unsigned i = 1; i != NumArgs; ++i)
+/// Check the arguments to '__builtin_va_start' or '__builtin_ms_va_start'
+/// for validity.  Emit an error and return true on failure; return false
+/// on success.
+bool Sema::SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {
+  Expr *Fn = TheCall->getCallee();
+
+  if (checkVAStartABI(*this, BuiltinID, Fn))
+    return true;
+
+  if (TheCall->getNumArgs() > 2) {
+    Diag(TheCall->getArg(2)->getLocStart(),
+         diag::err_typecheck_call_too_many_args)
+      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
+      << Fn->getSourceRange()
+      << SourceRange(TheCall->getArg(2)->getLocStart(),
+                     (*(TheCall->arg_end()-1))->getLocEnd());
+    return true;
+  }
+
+  if (TheCall->getNumArgs() < 2) {
+    return Diag(TheCall->getLocEnd(),
+      diag::err_typecheck_call_too_few_args_at_least)
+      << 0 /*function call*/ << 2 << TheCall->getNumArgs();
+  }
+
+  // Type-check the first argument normally.
+  if (checkBuiltinArgument(*this, TheCall, 0))
+    return true;
+
+  // Check that the current function is variadic, and get its last parameter.
+  ParmVarDecl *LastParam;
+  if (checkVAStartIsInVariadicFunction(*this, Fn, &LastParam))
+    return true;
+
+  // Verify that the second argument to the builtin is the last argument of the
+  // current function or method.
+  bool SecondArgIsLastNamedArgument = false;
+  const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();
+
+  // These are valid if SecondArgIsLastNamedArgument is false after the next
+  // block.
+  QualType Type;
+  SourceLocation ParamLoc;
+  bool IsCRegister = false;
+
+  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
+    if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
+      SecondArgIsLastNamedArgument = PV == LastParam;
+
+      Type = PV->getType();
+      ParamLoc = PV->getLocation();
+      IsCRegister =
+          PV->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus;
+    }
+  }
+
+  if (!SecondArgIsLastNamedArgument)
+    Diag(TheCall->getArg(1)->getLocStart(),
+         diag::warn_second_arg_of_va_start_not_last_named_param);
+  else if (IsCRegister || Type->isReferenceType() ||
+           Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
+             // Promotable integers are UB, but enumerations need a bit of
+             // extra checking to see what their promotable type actually is.
+             if (!Type->isPromotableIntegerType())
+               return false;
+             if (!Type->isEnumeralType())
+               return true;
+             const EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
+             return !(ED &&
+                      Context.typesAreCompatible(ED->getPromotionType(), Type));
+           }()) {
+    unsigned Reason = 0;
+    if (Type->isReferenceType())  Reason = 1;
+    else if (IsCRegister)         Reason = 2;
+    Diag(Arg->getLocStart(), diag::warn_va_start_type_is_undefined) << Reason;
+    Diag(ParamLoc, diag::note_parameter_type) << Type;
+  }
+
+  TheCall->setType(Context.VoidTy);
+  return false;
+}
+
+bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) {
+  // void __va_start(va_list *ap, const char *named_addr, size_t slot_size,
+  //                 const char *named_addr);
+
+  Expr *Func = Call->getCallee();
+
+  if (Call->getNumArgs() < 3)
+    return Diag(Call->getLocEnd(),
+                diag::err_typecheck_call_too_few_args_at_least)
+           << 0 /*function call*/ << 3 << Call->getNumArgs();
+
+  // Type-check the first argument normally.
+  if (checkBuiltinArgument(*this, Call, 0))
+    return true;
+
+  // Check that the current function is variadic.
+  if (checkVAStartIsInVariadicFunction(*this, Func))
+    return true;
+
+  // __va_start on Windows does not validate the parameter qualifiers
+
+  const Expr *Arg1 = Call->getArg(1)->IgnoreParens();
+  const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();
+
+  const Expr *Arg2 = Call->getArg(2)->IgnoreParens();
+  const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();
+
+  const QualType &ConstCharPtrTy =
+      Context.getPointerType(Context.CharTy.withConst());
+  if (!Arg1Ty->isPointerType() ||
+      Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy)
+    Diag(Arg1->getLocStart(), diag::err_typecheck_convert_incompatible)
+        << Arg1->getType() << ConstCharPtrTy
+        << 1 /* different class */
+        << 0 /* qualifier difference */
+        << 3 /* parameter mismatch */
+        << 2 << Arg1->getType() << ConstCharPtrTy;
+
+  const QualType SizeTy = Context.getSizeType();
+  if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)
+    Diag(Arg2->getLocStart(), diag::err_typecheck_convert_incompatible)
+        << Arg2->getType() << SizeTy
+        << 1 /* different class */
+        << 0 /* qualifier difference */
+        << 3 /* parameter mismatch */
+        << 3 << Arg2->getType() << SizeTy;
+
+  return false;
+}
+
+/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and
+/// friends.  This is declared to take (...), so we have to check everything.
+bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
+  if (TheCall->getNumArgs() < 2)
+    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
+      << 0 << 2 << TheCall->getNumArgs()/*function call*/;
+  if (TheCall->getNumArgs() > 2)
+    return Diag(TheCall->getArg(2)->getLocStart(),
+                diag::err_typecheck_call_too_many_args)
+      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
+      << SourceRange(TheCall->getArg(2)->getLocStart(),
+                     (*(TheCall->arg_end()-1))->getLocEnd());
+
+  ExprResult OrigArg0 = TheCall->getArg(0);
+  ExprResult OrigArg1 = TheCall->getArg(1);
+
+  // Do standard promotions between the two arguments, returning their common
+  // type.
+  QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);
+  if (OrigArg0.isInvalid() || OrigArg1.isInvalid())
+    return true;
+
+  // Make sure any conversions are pushed back into the call; this is
+  // type safe since unordered compare builtins are declared as "_Bool
+  // foo(...)".
+  TheCall->setArg(0, OrigArg0.get());
+  TheCall->setArg(1, OrigArg1.get());
+
+  if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent())
+    return false;
+
+  // If the common type isn't a real floating type, then the arguments were
+  // invalid for this operation.
+  if (Res.isNull() || !Res->isRealFloatingType())
+    return Diag(OrigArg0.get()->getLocStart(),
+                diag::err_typecheck_call_invalid_ordered_compare)
+      << OrigArg0.get()->getType() << OrigArg1.get()->getType()
+      << SourceRange(OrigArg0.get()->getLocStart(), OrigArg1.get()->getLocEnd());
+
+  return false;
+}
+
+/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like
+/// __builtin_isnan and friends.  This is declared to take (...), so we have
+/// to check everything. We expect the last argument to be a floating point
+/// value.
+bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
+  if (TheCall->getNumArgs() < NumArgs)
+    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
+      << 0 << NumArgs << TheCall->getNumArgs()/*function call*/;
+  if (TheCall->getNumArgs() > NumArgs)
+    return Diag(TheCall->getArg(NumArgs)->getLocStart(),
+                diag::err_typecheck_call_too_many_args)
+      << 0 /*function call*/ << NumArgs << TheCall->getNumArgs()
+      << SourceRange(TheCall->getArg(NumArgs)->getLocStart(),
+                     (*(TheCall->arg_end()-1))->getLocEnd());
+
+  Expr *OrigArg = TheCall->getArg(NumArgs-1);
+
+  if (OrigArg->isTypeDependent())
+    return false;
+
+  // This operation requires a non-_Complex floating-point number.
+  if (!OrigArg->getType()->isRealFloatingType())
+    return Diag(OrigArg->getLocStart(),
+                diag::err_typecheck_call_invalid_unary_fp)
+      << OrigArg->getType() << OrigArg->getSourceRange();
+
+  // If this is an implicit conversion from float -> float, double, or
+  // long double, remove it.
+  if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
+    // Only remove standard FloatCasts, leaving other casts inplace
+    if (Cast->getCastKind() == CK_FloatingCast) {
+      Expr *CastArg = Cast->getSubExpr();
+      if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
+        assert(
+            (Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
+             Cast->getType()->isSpecificBuiltinType(BuiltinType::Float) ||
+             Cast->getType()->isSpecificBuiltinType(BuiltinType::LongDouble)) &&
+            "promotion from float to either float, double, or long double is "
+            "the only expected cast here");
+        Cast->setSubExpr(nullptr);
+        TheCall->setArg(NumArgs-1, CastArg);
+      }
+    }
+  }
+  
+  return false;
+}
+
+// Customized Sema Checking for VSX builtins that have the following signature:
+// vector [...] builtinName(vector [...], vector [...], const int);
+// Which takes the same type of vectors (any legal vector type) for the first
+// two arguments and takes compile time constant for the third argument.
+// Example builtins are :
+// vector double vec_xxpermdi(vector double, vector double, int);
+// vector short vec_xxsldwi(vector short, vector short, int);
+bool Sema::SemaBuiltinVSX(CallExpr *TheCall) {
+  unsigned ExpectedNumArgs = 3;
+  if (TheCall->getNumArgs() < ExpectedNumArgs)
+    return Diag(TheCall->getLocEnd(),
+                diag::err_typecheck_call_too_few_args_at_least)
+           << 0 /*function call*/ <<  ExpectedNumArgs << TheCall->getNumArgs()
+           << TheCall->getSourceRange();
+
+  if (TheCall->getNumArgs() > ExpectedNumArgs)
+    return Diag(TheCall->getLocEnd(),
+                diag::err_typecheck_call_too_many_args_at_most)
+           << 0 /*function call*/ << ExpectedNumArgs << TheCall->getNumArgs()
+           << TheCall->getSourceRange();
+
+  // Check the third argument is a compile time constant
+  llvm::APSInt Value;
+  if(!TheCall->getArg(2)->isIntegerConstantExpr(Value, Context))
+    return Diag(TheCall->getLocStart(),
+                diag::err_vsx_builtin_nonconstant_argument)
+           << 3 /* argument index */ << TheCall->getDirectCallee()
+           << SourceRange(TheCall->getArg(2)->getLocStart(),
+                          TheCall->getArg(2)->getLocEnd());
+
+  QualType Arg1Ty = TheCall->getArg(0)->getType();
+  QualType Arg2Ty = TheCall->getArg(1)->getType();
+
+  // Check the type of argument 1 and argument 2 are vectors.
+  SourceLocation BuiltinLoc = TheCall->getLocStart();
+  if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||
+      (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {
+    return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
+           << TheCall->getDirectCallee()
+           << SourceRange(TheCall->getArg(0)->getLocStart(),
+                          TheCall->getArg(1)->getLocEnd());
+  }
+
+  // Check the first two arguments are the same type.
+  if (!Context.hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {
+    return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
+           << TheCall->getDirectCallee()
+           << SourceRange(TheCall->getArg(0)->getLocStart(),
+                          TheCall->getArg(1)->getLocEnd());
+  }
+
+  // When default clang type checking is turned off and the customized type
+  // checking is used, the returning type of the function must be explicitly
+  // set. Otherwise it is _Bool by default.
+  TheCall->setType(Arg1Ty);
+
+  return false;
+}
+
+/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
+// This is declared to take (...), so we have to check everything.
+ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
+  if (TheCall->getNumArgs() < 2)
+    return ExprError(Diag(TheCall->getLocEnd(),
+                          diag::err_typecheck_call_too_few_args_at_least)
+                     << 0 /*function call*/ << 2 << TheCall->getNumArgs()
+                     << TheCall->getSourceRange());
+
+  // Determine which of the following types of shufflevector we're checking:
+  // 1) unary, vector mask: (lhs, mask)
+  // 2) binary, scalar mask: (lhs, rhs, index, ..., index)
+  QualType resType = TheCall->getArg(0)->getType();
+  unsigned numElements = 0;
+
+  if (!TheCall->getArg(0)->isTypeDependent() &&
+      !TheCall->getArg(1)->isTypeDependent()) {
+    QualType LHSType = TheCall->getArg(0)->getType();
+    QualType RHSType = TheCall->getArg(1)->getType();
+
+    if (!LHSType->isVectorType() || !RHSType->isVectorType())
+      return ExprError(Diag(TheCall->getLocStart(),
+                            diag::err_vec_builtin_non_vector)
+                       << TheCall->getDirectCallee()
+                       << SourceRange(TheCall->getArg(0)->getLocStart(),
+                                      TheCall->getArg(1)->getLocEnd()));
+
+    numElements = LHSType->getAs<VectorType>()->getNumElements();
+    unsigned numResElements = TheCall->getNumArgs() - 2;
+
+    // Check to see if we have a call with 2 vector arguments, the unary shuffle
+    // with mask.  If so, verify that RHS is an integer vector type with the
+    // same number of elts as lhs.
+    if (TheCall->getNumArgs() == 2) {
+      if (!RHSType->hasIntegerRepresentation() ||
+          RHSType->getAs<VectorType>()->getNumElements() != numElements)
+        return ExprError(Diag(TheCall->getLocStart(),
+                              diag::err_vec_builtin_incompatible_vector)
+                         << TheCall->getDirectCallee()
+                         << SourceRange(TheCall->getArg(1)->getLocStart(),
+                                        TheCall->getArg(1)->getLocEnd()));
+    } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {
+      return ExprError(Diag(TheCall->getLocStart(),
+                            diag::err_vec_builtin_incompatible_vector)
+                       << TheCall->getDirectCallee()
+                       << SourceRange(TheCall->getArg(0)->getLocStart(),
+                                      TheCall->getArg(1)->getLocEnd()));
+    } else if (numElements != numResElements) {
+      QualType eltType = LHSType->getAs<VectorType>()->getElementType();
+      resType = Context.getVectorType(eltType, numResElements,
+                                      VectorType::GenericVector);
+    }
+  }
+
+  for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {
+    if (TheCall->getArg(i)->isTypeDependent() ||
+        TheCall->getArg(i)->isValueDependent())
+      continue;
+
+    llvm::APSInt Result(32);
+    if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context))
+      return ExprError(Diag(TheCall->getLocStart(),
+                            diag::err_shufflevector_nonconstant_argument)
+                       << TheCall->getArg(i)->getSourceRange());
+
+    // Allow -1 which will be translated to undef in the IR.
+    if (Result.isSigned() && Result.isAllOnesValue())
+      continue;
+
+    if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)
+      return ExprError(Diag(TheCall->getLocStart(),
+                            diag::err_shufflevector_argument_too_large)
+                       << TheCall->getArg(i)->getSourceRange());
+  }
+
+  SmallVector<Expr*, 32> exprs;
+
+  for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
+    exprs.push_back(TheCall->getArg(i));
+    TheCall->setArg(i, nullptr);
+  }
+
+  return new (Context) ShuffleVectorExpr(Context, exprs, resType,
+                                         TheCall->getCallee()->getLocStart(),
+                                         TheCall->getRParenLoc());
+}
+
+/// SemaConvertVectorExpr - Handle __builtin_convertvector
+ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
+                                       SourceLocation BuiltinLoc,
+                                       SourceLocation RParenLoc) {
+  ExprValueKind VK = VK_RValue;
+  ExprObjectKind OK = OK_Ordinary;
+  QualType DstTy = TInfo->getType();
+  QualType SrcTy = E->getType();
+
+  if (!SrcTy->isVectorType() && !SrcTy->isDependentType())
+    return ExprError(Diag(BuiltinLoc,
+                          diag::err_convertvector_non_vector)
+                     << E->getSourceRange());
+  if (!DstTy->isVectorType() && !DstTy->isDependentType())
+    return ExprError(Diag(BuiltinLoc,
+                          diag::err_convertvector_non_vector_type));
+
+  if (!SrcTy->isDependentType() && !DstTy->isDependentType()) {
+    unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements();
+    unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements();
+    if (SrcElts != DstElts)
+      return ExprError(Diag(BuiltinLoc,
+                            diag::err_convertvector_incompatible_vector)
+                       << E->getSourceRange());
+  }
+
+  return new (Context)
+      ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);
+}
+
+/// SemaBuiltinPrefetch - Handle __builtin_prefetch.
+// This is declared to take (const void*, ...) and can take two
+// optional constant int args.
+bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
+  unsigned NumArgs = TheCall->getNumArgs();
+
+  if (NumArgs > 3)
+    return Diag(TheCall->getLocEnd(),
+             diag::err_typecheck_call_too_many_args_at_most)
+             << 0 /*function call*/ << 3 << NumArgs
+             << TheCall->getSourceRange();
+
+  // Argument 0 is checked for us and the remaining arguments must be
+  // constant integers.
+  for (unsigned i = 1; i != NumArgs; ++i)
     if (SemaBuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
       return true;
 
