diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
index d6053b9..0bac27b 100644
--- a/docs/LanguageExtensions.html
+++ b/docs/LanguageExtensions.html
@@ -100,6 +100,7 @@
   <li><a href="#__builtin_shufflevector">__builtin_shufflevector</a></li>
   <li><a href="#__builtin_unreachable">__builtin_unreachable</a></li>
   <li><a href="#__sync_swap">__sync_swap</a></li>
+  <li><a href="#overflow-builtins">Arithmetic with overflow builtins</a></li>
  </ul>
 </li>
 <li><a href="#targetspecific">Target-Specific Extensions</a>
@@ -1422,6 +1423,47 @@ relying on the platform specific implementation details of
 __sync_lock_test_and_set(). The __sync_swap() builtin is a full barrier.
 </p>
 
+<!-- ======================================================================= -->
+<h3><a name="overflow-builtins">Arithmetic with overflow builtins</a></h3>
+<!-- ======================================================================= -->
+
+Arithmetic with overflow builtins are used to perform arithmetic operations
+with overflow detection.
+
+<p><b>Syntax:</b></p>
+
+<pre>
+bool __builtin_add_with_overflow(<i>type</i> *ptr, <i>type</i> a, <i>type</i> b);
+bool __builtin_sub_with_overflow(<i>type</i> *ptr, <i>type</i> a, <i>type</i> b);
+bool __builtin_mul_with_overflow(<i>type</i> *ptr, <i>type</i> a, <i>type</i> b);
+</pre>
+
+<p><b>Example of Use:</b></p>
+
+<pre>
+void *malloc_array(size_t n, size_t size) {
+  size_t bytes;
+  if (__builtin_mul_with_overflow(&amp;bytes, n, size))
+    return NULL;
+  return malloc(bytes);
+}
+</pre>
+
+<p><b>Description:</b></p>
+
+<p>
+<tt>__builtin_<i>op</i>_with_overflow(ptr, a, b)</tt> stores the result of
+<tt>a <i>op</i> b</tt> in <tt>ptr</tt>, and returns true if an overflow
+occurred during the arithmetic operation.  Note that <tt><i>type</i></tt>
+is inferred from <tt>*ptr</tt>.  These builtins help developers write
+more efficient and correct code by avoiding ad hoc overflow checks.
+</p>
+
+<p>
+Query for this feature with
+<tt>__has_builtin(__builtin_<i>op</i>_with_overflow)</tt>.
+</p>
+
 
 <!-- ======================================================================= -->
 <h2 id="targetspecific">Target-Specific Extensions</h2>
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index f811316..b17ab4d 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -617,6 +617,11 @@ BUILTIN(__sync_fetch_and_max, "iiD*i", "n")
 BUILTIN(__sync_fetch_and_umin, "UiUiD*Ui", "n")
 BUILTIN(__sync_fetch_and_umax, "UiUiD*Ui", "n")
 
+// Overflow builtins.
+BUILTIN(__builtin_add_with_overflow, "v.", "t")
+BUILTIN(__builtin_sub_with_overflow, "v.", "t")
+BUILTIN(__builtin_mul_with_overflow, "v.", "t")
+
 // Random libc builtins.
 BUILTIN(__builtin_abort, "v", "Fnr")
 BUILTIN(__builtin_index, "c*cC*i", "Fn")
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index f5a72ca..358be35 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4501,6 +4501,15 @@ def err_atomic_op_logical_needs_atomic_int : Error<
   "first argument to logical atomic operation must be a pointer to atomic "
   "integer (%0 invalid)">;
 
+def err_overflow_builtin_must_be_pointer : Error<
+  "first argument to overflow builtin must be a pointer (%0 invalid)">;
+def err_overflow_builtin_must_be_pointer_int : Error<
+  "first argument to overflow builtin must be a pointer to integer "
+  "(%0 invalid)">;
+def err_overflow_builtin_pointer_size : Error<
+  "first argument to overflow builtin must be a pointer to 1,2,4 or 8 byte "
+  "type (%0 invalid)">;
+
 def err_deleted_function_use : Error<"attempt to use a deleted function">;
 
 def err_kern_type_not_void_return : Error<
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index b639332..69c32fe 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -6684,6 +6684,7 @@ private:
   ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
   ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
                                      AtomicExpr::AtomicOp Op);
+  bool SemaOverflowOpsOverloaded(CallExpr *TheCall);
   bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
                               llvm::APSInt &Result);
 
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index eb849f6..85d627e 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -143,6 +143,32 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
   return RValue::get(Result);
 }
 
+static RValue EmitOverflow(CodeGenFunction &CGF,
+                           const CallExpr *E,
+                           Intrinsic::ID SID,
+                           Intrinsic::ID UID) {
+    QualType T = E->getArg(1)->getType();
+    llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
+    unsigned AddrSpace =
+      cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace();
+
+    llvm::IntegerType *IntType =
+      llvm::IntegerType::get(CGF.getLLVMContext(),
+                             CGF.getContext().getTypeSize(T));
+    llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
+
+    Value *P, *V0, *V1;
+    P = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
+    V0 = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(1)), T, IntType);
+    V1 = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType);
+
+    Intrinsic::ID ID = T->hasSignedIntegerRepresentation()? SID: UID;
+    Function *F = CGF.CGM.getIntrinsic(ID, IntType);
+    CallInst *Result = CGF.Builder.CreateCall2(F, V0, V1);
+    CGF.Builder.CreateStore(CGF.Builder.CreateExtractValue(Result, 0), P);
+    return RValue::get(CGF.Builder.CreateExtractValue(Result, 1));
+}
+
 /// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy,
 /// which must be a scalar floating point type.
 static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) {
@@ -1032,6 +1058,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
     return RValue::get(0);
   }
 
+  // Overflow builtins.
+  case Builtin::BI__builtin_add_with_overflow:
+    return EmitOverflow(*this, E, Intrinsic::sadd_with_overflow,
+                        Intrinsic::uadd_with_overflow);
+  case Builtin::BI__builtin_sub_with_overflow:
+    return EmitOverflow(*this, E, Intrinsic::ssub_with_overflow,
+                        Intrinsic::usub_with_overflow);
+  case Builtin::BI__builtin_mul_with_overflow:
+    return EmitOverflow(*this, E, Intrinsic::smul_with_overflow,
+                        Intrinsic::umul_with_overflow);
+
     // Library functions with special handling.
   case Builtin::BIsqrt:
   case Builtin::BIsqrtf:
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 74832fd..e9bd916 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -63,7 +63,7 @@ static bool checkArgCount(Sema &S, CallExpr *call, unsigned desiredArgCount) {
     
   return S.Diag(range.getBegin(), diag::err_typecheck_call_too_many_args)
     << 0 /*function call*/ << desiredArgCount << argCount
-    << call->getArg(1)->getSourceRange();
+    << range;
 }
 
 /// CheckBuiltinAnnotationString - Checks that string argument to the builtin
@@ -274,6 +274,12 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
     return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Or);
   case Builtin::BI__atomic_fetch_xor:
     return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Xor);
+  case Builtin::BI__builtin_add_with_overflow:
+  case Builtin::BI__builtin_sub_with_overflow:
+  case Builtin::BI__builtin_mul_with_overflow:
+    if (SemaOverflowOpsOverloaded(TheCall))
+      return ExprError();
+    break;
   case Builtin::BI__builtin_annotation:
     if (CheckBuiltinAnnotationString(*this, TheCall->getArg(1)))
       return ExprError();
@@ -504,6 +510,54 @@ bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
   return false;
 }
 
+bool Sema::SemaOverflowOpsOverloaded(CallExpr *TheCall) {
+  DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
+  // All these operations take the following form:
+  // bool __builtin_*_with_overflow(T*, T, T);
+
+  if (checkArgCount(*this, TheCall, 3))
+    return true;
+
+  Expr *Ptr = TheCall->getArg(0);
+  Ptr = DefaultFunctionArrayLvalueConversion(Ptr).get();
+  const PointerType *pointerType = Ptr->getType()->getAs<PointerType>();
+  if (!pointerType)
+    return Diag(DRE->getLocStart(), diag::err_overflow_builtin_must_be_pointer)
+      << Ptr->getType() << Ptr->getSourceRange();
+
+  QualType ValTy = pointerType->getPointeeType();
+  if (!ValTy->isIntegerType())
+    return Diag(DRE->getLocStart(), diag::err_overflow_builtin_must_be_pointer_int)
+      << Ptr->getType() << Ptr->getSourceRange();
+
+  switch (Context.getTypeSizeInChars(ValTy).getQuantity()) {
+  case 1:
+  case 2:
+  case 4:
+  case 8:
+    break;
+  default:
+    return Diag(DRE->getLocStart(), diag::err_overflow_builtin_pointer_size)
+      << Ptr->getType() << Ptr->getSourceRange();
+  }
+
+  // The first argument --- the pointer --- has a fixed type; we
+  // deduce the types of the rest of the arguments accordingly.  Walk
+  // the remaining arguments, converting them to the deduced value type.
+  for (unsigned i = 1; i != 3; ++i) {
+    ExprResult Arg = TheCall->getArg(i);
+    InitializedEntity Entity =
+        InitializedEntity::InitializeParameter(Context, ValTy, false);
+    Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg);
+    if (Arg.isInvalid())
+      return true;
+    TheCall->setArg(i, Arg.get());
+  }
+
+  TheCall->setType(Context.BoolTy);
+  return false;
+}
+
 ExprResult
 Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op) {
   CallExpr *TheCall = cast<CallExpr>(TheCallResult.get());
diff --git a/test/CodeGen/overflow.c b/test/CodeGen/overflow.c
new file mode 100644
index 0000000..b2a501f
--- /dev/null
+++ b/test/CodeGen/overflow.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s
+
+#include <stddef.h>
+
+void f(void) {
+  extern int c, a, b;
+  extern unsigned z, x, y;
+
+  // CHECK: llvm.sadd.with.overflow.i32
+  __builtin_add_with_overflow(&c, a, b);
+
+  // CHECK: llvm.uadd.with.overflow.i32
+  __builtin_add_with_overflow(&z, x, y);
+
+  // CHECK: llvm.ssub.with.overflow.i32
+  __builtin_sub_with_overflow(&c, a, b);
+
+  // CHECK: llvm.usub.with.overflow.i32
+  __builtin_sub_with_overflow(&z, x, y);
+
+  // CHECK: llvm.smul.with.overflow.i32
+  __builtin_mul_with_overflow(&c, a, b);
+
+  // CHECK: llvm.umul.with.overflow.i32
+  __builtin_mul_with_overflow(&z, x, y);
+}
diff --git a/test/Sema/overflow.c b/test/Sema/overflow.c
new file mode 100644
index 0000000..48634f5
--- /dev/null
+++ b/test/Sema/overflow.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+// Sema tests for __builtin_*_with_overflow
+
+void f(int *p, int a, int b) {
+  __builtin_add_with_overflow(0);          // expected-error {{too few arguments to function call}}
+  __builtin_add_with_overflow(0, 0);       // expected-error {{too few arguments to function call}}
+  __builtin_add_with_overflow(0, 0, 0, 0); // expected-error {{too many arguments to function call}}
+
+  __builtin_add_with_overflow(0, 0, 0);          // expected-error {{must be a pointer}}
+  __builtin_add_with_overflow((float *)p, a, b); // expected-error {{must be a pointer to integer}}
+
+  __builtin_add_with_overflow(p, a, b);
+}
