diff --git a/docs/LangRef.rst b/docs/LangRef.rst
index 659f02a..148a999 100644
--- a/docs/LangRef.rst
+++ b/docs/LangRef.rst
@@ -2859,7 +2859,7 @@ The '``llvm.used``' Global Variable
 
 The ``@llvm.used`` global is an array with i8\* element type which has
 :ref:`appending linkage <linkage_appending>`. This array contains a list of
-pointers to global variables and functions which may optionally have a
+pointers to global variables, functions and aliases which may optionally have a
 pointer cast formed of bitcast or getelementptr. For example, a legal
 use of it is:
 
@@ -2873,13 +2873,13 @@ use of it is:
        i8* bitcast (i32* @Y to i8*)
     ], section "llvm.metadata"
 
-If a global variable appears in the ``@llvm.used`` list, then the
-compiler, assembler, and linker are required to treat the symbol as if
-there is a reference to the global that it cannot see. For example, if a
-variable has internal linkage and no references other than that from the
-``@llvm.used`` list, it cannot be deleted. This is commonly used to
-represent references from inline asms and other things the compiler
-cannot "see", and corresponds to "``attribute((used))``" in GNU C.
+If a symbol appears in the ``@llvm.used`` list, then the compiler, assembler,
+and linker are required to treat the symbol as if there is a reference to the
+symbol that it cannot see. For example, if a variable has internal linkage and
+no references other than that from the ``@llvm.used`` list, it cannot be
+deleted. This is commonly used to represent references from inline asms and
+other things the compiler cannot "see", and corresponds to
+"``attribute((used))``" in GNU C.
 
 On some targets, the code generator must emit a directive to the
 assembler or object file to prevent the assembler and linker from
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index 8bfbb32..8fd9581 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -446,6 +446,32 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
     }
   }
 
+  if (GV.hasName() && (GV.getName() == "llvm.used")) {
+    Assert1(!GV.hasInitializer() || GV.hasAppendingLinkage(),
+            "invalid linkage for intrinsic global variable", &GV);
+    Type *GVType = cast<PointerType>(GV.getType())->getElementType();
+    if (ArrayType *ATy = dyn_cast<ArrayType>(GVType)) {
+      PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType());
+      Assert1(PTy, "wrong type for intrinsic global variable", &GV);
+      IntegerType *IntTy = dyn_cast<IntegerType>(PTy->getElementType());
+      Assert1(IntTy && IntTy->getBitWidth() == 8,
+              "wrong type for intrinsic global variable", &GV);
+      if (GV.hasInitializer()) {
+        Constant *Init = GV.getInitializer();
+        ConstantArray *InitArray = dyn_cast<ConstantArray>(Init);
+        Assert1(InitArray, "wrong initalizer for intrinsic global variable",
+                Init);
+        for (unsigned i = 0, e = InitArray->getNumOperands(); i != e; ++i) {
+          Value *V = Init->getOperand(i)->stripPointerCasts();
+          // stripPointerCasts strips aliases, so we only need to check for
+          // variables and functions.
+          Assert1(isa<GlobalVariable>(V) || isa<Function>(V),
+                  "invalid llvm.used member", V);
+        }
+      }
+    }
+  }
+
   visitGlobalValue(GV);
 }
 
diff --git a/test/Feature/aliases.ll b/test/Feature/aliases.ll
index d44dff4..1393812 100644
--- a/test/Feature/aliases.ll
+++ b/test/Feature/aliases.ll
@@ -2,6 +2,8 @@
 ; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
 ; RUN: diff %t1.ll %t2.ll
 
+@llvm.used = appending global [1 x i8*] [i8* bitcast (i32* @foo1 to i8*)], section "llvm.metadata"
+
 @bar = external global i32
 @foo1 = alias i32* @bar
 @foo2 = alias i32* @bar
diff --git a/test/Verifier/llvm.used-invalid-init.ll b/test/Verifier/llvm.used-invalid-init.ll
new file mode 100644
index 0000000..b0887c9
--- /dev/null
+++ b/test/Verifier/llvm.used-invalid-init.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+@llvm.used = appending global [1 x i8*] zeroinitializer, section "llvm.metadata"
+
+; CHECK: wrong initalizer for intrinsic global variable
+; CHECK-NEXT: [1 x i8*] zeroinitializer
diff --git a/test/Verifier/llvm.used-invalid-init2.ll b/test/Verifier/llvm.used-invalid-init2.ll
new file mode 100644
index 0000000..ee8a970
--- /dev/null
+++ b/test/Verifier/llvm.used-invalid-init2.ll
@@ -0,0 +1,7 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+@a = global i8 42
+@llvm.used = appending global [2 x i8*] [i8* @a, i8* null], section "llvm.metadata"
+
+; CHECK: invalid llvm.used member
+; CHECK-NEXT: i8* null
diff --git a/test/Verifier/llvm.used-invalid-type.ll b/test/Verifier/llvm.used-invalid-type.ll
new file mode 100644
index 0000000..2de5c86
--- /dev/null
+++ b/test/Verifier/llvm.used-invalid-type.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+@llvm.used = appending global [1 x i32] [i32 0], section "llvm.metadata"
+
+; CHECK:       wrong type for intrinsic global variable
+; CHECK-NEXT: [1 x i32]* @llvm.used
diff --git a/test/Verifier/llvm.used-invalid-type2.ll b/test/Verifier/llvm.used-invalid-type2.ll
new file mode 100644
index 0000000..c1b697b
--- /dev/null
+++ b/test/Verifier/llvm.used-invalid-type2.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+@llvm.used = appending global [1 x i32*] [i32* null], section "llvm.metadata"
+
+; CHECK:       wrong type for intrinsic global variable
+; CHECK-NEXT: [1 x i32*]* @llvm.used
