diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index df41aeb..eafafc6 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -580,6 +580,12 @@ def Constructor : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
+def Convergent : InheritableAttr {
+  let Spellings = [GNU<"convergent">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
+}
+
 def CUDAConstant : InheritableAttr {
   let Spellings = [GNU<"constant">];
   let Subjects = SubjectList<[Var]>;
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 50ea7f7..3e69c79 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1626,6 +1626,8 @@ void CodeGenModule::ConstructAttributeList(
       FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
     if (TargetDecl->hasAttr<NoDuplicateAttr>())
       FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
+    if (TargetDecl->hasAttr<ConvergentAttr>())
+      FuncAttrs.addAttribute(llvm::Attribute::Convergent);
 
     if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
       AddAttributesFromFunctionProtoType(
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index cbc95dc..847ed6c 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -5426,6 +5426,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case AttributeList::AT_Constructor:
     handleConstructorAttr(S, D, Attr);
     break;
+  case AttributeList::AT_Convergent:
+    handleSimpleAttribute<ConvergentAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_CXX11NoReturn:
     handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr);
     break;
diff --git a/test/CodeGen/attr-convergent.c b/test/CodeGen/attr-convergent.c
new file mode 100644
index 0000000..d759e75
--- /dev/null
+++ b/test/CodeGen/attr-convergent.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -o - | FileCheck %s
+
+int f0(void) __attribute__((convergent));
+
+int f1(void) {
+  return f0();
+}
+
+// CHECK: define i32 @f1() [[ATTR_1:#[0-9]+]] {
+// CHECK:   [[RET:%.+]] = call i32 @f0() [[ATTR_CS:#[0-9]+]]
+// CHECK:   ret i32 [[RET]]
+// CHECK: }
+
+// CHECK: declare i32 @f0() [[ATTR_0:#[0-9]+]]
+
+// CHECK-NOT: attributes [[ATTR_1]] = { convergent {{.*}} }
+// CHECK:     attributes [[ATTR_0]] = { convergent {{.*}} }
+// CHECK:     attributes [[ATTR_CS]] = { convergent }
diff --git a/test/Sema/attr-convergent.c b/test/Sema/attr-convergent.c
new file mode 100644
index 0000000..d9a9db9
--- /dev/null
+++ b/test/Sema/attr-convergent.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int t0 __attribute__((convergent)); // expected-warning {{'convergent' attribute only applies to functions}}
+
+void t1() __attribute__((convergent));
+
+void t2() __attribute__((convergent(2))); // expected-error {{'convergent' attribute takes no arguments}}
