diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -2459,9 +2459,11 @@
     address space 0, this property only affects the default value to be used
     when creating globals without additional contextual information (e.g. in
     LLVM passes).
-``A
``
-    Specifies the address space of objects created by '``alloca``'.
-    Defaults to the default address space of 0.
+``A::...``
+    Specifies the valid address spaces in which ``alloca`` can create
+    objects. The address space immediately following the ``A`` is
+    the default alloca address space.  If omitted, the default is that
+    ``alloca`` should return pointers in address space 0.
 ``p[n]::::``
     This specifies the *size* of a pointer and its ```` and
     ````\erred alignments for address space ``n``. The fourth parameter
@@ -9551,8 +9553,7 @@
 
 The '``alloca``' instruction allocates memory on the stack frame of the
 currently executing function, to be automatically released when this
-function returns to its caller. The object is always allocated in the
-address space for allocas indicated in the datalayout.
+function returns to its caller.
 
 Arguments:
 """"""""""
@@ -9583,6 +9584,12 @@
 pointer may not be unique. The order in which memory is allocated (ie.,
 which way the stack grows) is not specified.
 
+If not explicitly specified, the result is allocated in the default
+alloca address space for the target.  Note that the set of valid address
+spaces for alloca is specified in the target's datalayout; see
+:ref:`datalayout string` for more on alloca address
+spaces.
+
 If the returned pointer is used by :ref:`llvm.lifetime.start `,
 the returned object is initially dead.
 See :ref:`llvm.lifetime.start ` and
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -121,7 +121,7 @@
   /// Defaults to false.
   bool BigEndian;
 
-  unsigned AllocaAddrSpace;
+  SmallVector AllocaAddrSpaces;
   MaybeAlign StackNaturalAlign;
   unsigned ProgramAddrSpace;
   unsigned DefaultGlobalsAddrSpace;
@@ -211,7 +211,7 @@
     clear();
     StringRepresentation = DL.StringRepresentation;
     BigEndian = DL.isBigEndian();
-    AllocaAddrSpace = DL.AllocaAddrSpace;
+    AllocaAddrSpaces = DL.AllocaAddrSpaces;
     StackNaturalAlign = DL.StackNaturalAlign;
     FunctionPtrAlign = DL.FunctionPtrAlign;
     TheFunctionPtrAlignType = DL.TheFunctionPtrAlignType;
@@ -276,7 +276,17 @@
     return *StackNaturalAlign;
   }
 
-  unsigned getAllocaAddrSpace() const { return AllocaAddrSpace; }
+  /// Return the address spaces in which we can alloca.
+  ArrayRef getAllocaAddrSpaces() const { return AllocaAddrSpaces; }
+
+  /// Return true if we can alloca in the given address space.
+  bool isAllocaAddrSpace(unsigned AddrSpace) const {
+    ArrayRef AllocaSpaces = getAllocaAddrSpaces();
+    return is_contained(AllocaSpaces, AddrSpace);
+  }
+
+  // Return the default alloca address space.
+  unsigned getAllocaAddrSpace() const { return getAllocaAddrSpaces().front(); }
 
   /// Returns the alignment of function pointers, which may or may not be
   /// related to the alignment of functions.
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -180,7 +180,7 @@
 
   LayoutMap = nullptr;
   BigEndian = false;
-  AllocaAddrSpace = 0;
+  AllocaAddrSpaces.clear();
   StackNaturalAlign.reset();
   ProgramAddrSpace = 0;
   DefaultGlobalsAddrSpace = 0;
@@ -438,6 +438,7 @@
         if (Rest.empty())
           break;
         if (Error Err = split(Rest, ':', Split))
+
           return Err;
       }
       break;
@@ -476,9 +477,20 @@
         return Err;
       break;
     }
-    case 'A': { // Default stack/alloca address space.
-      if (Error Err = getAddrSpace(Tok, AllocaAddrSpace))
-        return Err;
+    case 'A': { // Alloca address spaces.  The first one is the default.
+      while (true) {
+        unsigned AddrSpace;
+        if (Error Err = getAddrSpace(Tok, AddrSpace))
+          return Err;
+        if (isAllocaAddrSpace(AddrSpace))
+          return reportError(
+              "Duplicate alloca address space in datalayout string");
+        AllocaAddrSpaces.push_back(AddrSpace);
+        if (Rest.empty())
+          break;
+        if (Error Err = split(Rest, ':', Split))
+          return Err;
+      }
       break;
     }
     case 'G': { // Default address space for global variables.
@@ -523,6 +535,10 @@
     }
   }
 
+  // If no alloca address spaces specified, default to address space 0.
+  if (AllocaAddrSpaces.empty())
+    AllocaAddrSpaces.push_back(0);
+
   return Error::success();
 }
 
@@ -534,7 +550,7 @@
 
 bool DataLayout::operator==(const DataLayout &Other) const {
   bool Ret = BigEndian == Other.BigEndian &&
-             AllocaAddrSpace == Other.AllocaAddrSpace &&
+             getAllocaAddrSpaces() == Other.getAllocaAddrSpaces() &&
              StackNaturalAlign == Other.StackNaturalAlign &&
              ProgramAddrSpace == Other.ProgramAddrSpace &&
              DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3802,10 +3802,8 @@
 void Verifier::visitAllocaInst(AllocaInst &AI) {
   SmallPtrSet Visited;
   PointerType *PTy = AI.getType();
-  // TODO: Relax this restriction?
-  Assert(PTy->getAddressSpace() == DL.getAllocaAddrSpace(),
-         "Allocation instruction pointer not in the stack address space!",
-         &AI);
+  Assert(DL.isAllocaAddrSpace(PTy->getAddressSpace()),
+         "Allocation instruction pointer not in a stack address space!", &AI);
   Assert(AI.getAllocatedType()->isSized(&Visited),
          "Cannot allocate unsized type", &AI);
   Assert(AI.getArraySize()->getType()->isIntegerTy(),
diff --git a/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll b/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll
--- a/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll
+++ b/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll
@@ -2,7 +2,7 @@
 
 target datalayout = "A1"
 
-; CHECK: Allocation instruction pointer not in the stack address space!
+; CHECK: Allocation instruction pointer not in a stack address space!
 ; CHECK-NEXT:  %alloca_scalar_no_align = alloca i32, align 4, addrspace(2)
 
 define void @use_alloca() {
diff --git a/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll b/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll
--- a/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll
+++ b/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll
@@ -2,7 +2,7 @@
 
 target datalayout = "A1"
 
-; CHECK: Allocation instruction pointer not in the stack address space!
+; CHECK: Allocation instruction pointer not in a stack address space!
 ; CHECK-NEXT:  %alloca_scalar_no_align = alloca i32, align 4, addrspace(2)
 
 define void @use_alloca() {
diff --git a/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll b/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll
--- a/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll
+++ b/llvm/test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll
@@ -2,7 +2,7 @@
 
 target datalayout = "A1"
 
-; CHECK: Allocation instruction pointer not in the stack address space!
+; CHECK: Allocation instruction pointer not in a stack address space!
 ; CHECK-NEXT:  %alloca_scalar_no_align = alloca i32, align 4, addrspace(2), !foo !0
 
 define void @use_alloca() {
diff --git a/llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll b/llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
--- a/llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
+++ b/llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
@@ -12,7 +12,7 @@
       metadata i8* undef,
       metadata !DILocalVariable(scope: !1),
       metadata !DIExpression())
-; ALL-NOT: Allocation instruction pointer not in the stack address space!
+; ALL-NOT: Allocation instruction pointer not in a stack address space!
 ; AS: llvm.dbg.value intrinsic requires a !dbg attachment
 ; AS: warning: ignoring invalid debug info in 
 ret void
diff --git a/llvm/test/CodeGen/AMDGPU/invalid-alloca.ll b/llvm/test/CodeGen/AMDGPU/invalid-alloca.ll
--- a/llvm/test/CodeGen/AMDGPU/invalid-alloca.ll
+++ b/llvm/test/CodeGen/AMDGPU/invalid-alloca.ll
@@ -5,7 +5,7 @@
 ; RUN: llvm-as < %s | not opt -data-layout=A5 2>&1 | FileCheck -check-prefixes=MISMATCH %s
 
 ; AS: assembly parsed, but does not verify as correct!
-; COMMON: Allocation instruction pointer not in the stack address space!
+; COMMON: Allocation instruction pointer not in a stack address space!
 ; COMMON:  %tmp = alloca i32
 ; MISMATCH: Explicit load/store type does not match pointee type of pointer operand
 ; LLC: error: {{.*}}input module cannot be verified
diff --git a/llvm/test/Verifier/alloca-alternate-addrspace-invalid-0.ll b/llvm/test/Verifier/alloca-alternate-addrspace-invalid-0.ll
new file mode 100644
--- /dev/null
+++ b/llvm/test/Verifier/alloca-alternate-addrspace-invalid-0.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-as %s 2>&1 | FileCheck %s
+
+target datalayout = "A1"
+
+define void @use_alloca() {
+; CHECK: Allocation instruction pointer not in a stack address space!
+  %alloca_scalar_no_align = alloca i32, addrspace(2)
+  ret void
+}
diff --git a/llvm/test/Verifier/alloca-alternate-addrspace-invalid-1.ll b/llvm/test/Verifier/alloca-alternate-addrspace-invalid-1.ll
new file mode 100644
--- /dev/null
+++ b/llvm/test/Verifier/alloca-alternate-addrspace-invalid-1.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-as %s 2>&1 | FileCheck %s
+
+target datalayout = "A1:3"
+
+define void @use_alloca() {
+; CHECK: Allocation instruction pointer not in a stack address space!
+  %alloca_scalar_no_align = alloca i32, addrspace(2)
+  ret void
+}
diff --git a/llvm/test/Verifier/alloca-alternate-addrspace-invalid-2.ll b/llvm/test/Verifier/alloca-alternate-addrspace-invalid-2.ll
new file mode 100644
--- /dev/null
+++ b/llvm/test/Verifier/alloca-alternate-addrspace-invalid-2.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+target datalayout = ""
+
+define void @use_alloca() {
+; CHECK: Allocation instruction pointer not in a stack address space!
+  %alloca_scalar_no_align = alloca i32, addrspace(2)
+  ret void
+}
diff --git a/llvm/test/Verifier/alloca-alternate-addrspace-valid.ll b/llvm/test/Verifier/alloca-alternate-addrspace-valid.ll
new file mode 100644
--- /dev/null
+++ b/llvm/test/Verifier/alloca-alternate-addrspace-valid.ll
@@ -0,0 +1,22 @@
+; RUN: llvm-as %s -o /dev/null
+
+; Should assemble without error.
+
+target datalayout = "A1:2:3"
+
+define void @use_alloca0() {
+  %alloca_scalar_no_align = alloca i32, addrspace(2)
+  ret void
+}
+
+define void @use_alloca1() {
+  %alloca_scalar_no_align = alloca i32, align 4, addrspace(2)
+  ret void
+}
+
+define void @use_alloca2() {
+  %alloca_scalar_no_align = alloca i32, align 4, addrspace(2), !foo !0
+  ret void
+}
+
+!0 = !{}