Index: test/Feature/alignment.ll
===================================================================
--- test/Feature/alignment.ll	(revision 95872)
+++ test/Feature/alignment.ll	(working copy)
@@ -19,3 +19,7 @@
         ret i32* %X
 }
 
+define void @test3() alignstack(16) {
+        ret void
+}
+
Index: include/llvm/Attributes.h
===================================================================
--- include/llvm/Attributes.h	(revision 95872)
+++ include/llvm/Attributes.h	(working copy)
@@ -60,6 +60,11 @@
 const Attributes Naked           = 1<<24; ///< Naked function
 const Attributes InlineHint      = 1<<25; ///< source said inlining was
                                           ///desirable
+const Attributes StackAlignment  = 31<<26; ///< Alignment of stack for
+                                           ///function (5 bits) stored as log2
+                                           ///of alignment with +1 bias
+                                           ///0 means unaligned (different from
+                                           ///alignstack(1))
 
 /// @brief Attributes that only apply to function parameters.
 const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
@@ -68,7 +73,7 @@
 /// be used on return values or function parameters.
 const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
   NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
-  NoRedZone | NoImplicitFloat | Naked | InlineHint;
+  NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment;
 
 /// @brief Parameter attributes that do not apply to vararg call arguments.
 const Attributes VarArgsIncompatible = StructRet;
@@ -105,7 +110,29 @@
   return 1U << ((Align >> 16) - 1);
 }
 
+/// This turns an int stack alignment (which must be a power of 2) into
+/// the form used internally in Attributes.
+inline Attributes constructStackAlignmentFromInt(unsigned i) {
+  // Default alignment, allow the target to define how to align it.
+  if (i == 0)
+    return 0;
 
+  assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+  assert(i <= 0x40000000 && "Alignment too large.");
+  return (Log2_32(i)+1) << 26;
+}
+
+/// This returns the stack alignment field of an attribute as a byte alignment
+/// value.
+inline unsigned getStackAlignmentFromAttrs(Attributes A) {
+  Attributes StackAlign = A & Attribute::StackAlignment;
+  if (StackAlign == 0)
+    return 0;
+
+  return 1U << ((StackAlign >> 26) - 1);
+}
+
+
 /// The set of Attributes set in Attributes is converted to a
 /// string of equivalent mnemonics. This is, presumably, for writing out
 /// the mnemonics for the assembly writer.
Index: lib/VMCore/Attributes.cpp
===================================================================
--- lib/VMCore/Attributes.cpp	(revision 95872)
+++ lib/VMCore/Attributes.cpp	(working copy)
@@ -70,6 +70,11 @@
     Result += "noimplicitfloat ";
   if (Attrs & Attribute::Naked)
     Result += "naked ";
+  if (Attrs & Attribute::StackAlignment) {
+    Result += "alignstack(";
+    Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs));
+    Result += ") ";
+  }
   if (Attrs & Attribute::Alignment) {
     Result += "align ";
     Result += utostr(Attribute::getAlignmentFromAttrs(Attrs));
Index: lib/AsmParser/LLParser.cpp
===================================================================
--- lib/AsmParser/LLParser.cpp	(revision 95872)
+++ lib/AsmParser/LLParser.cpp	(working copy)
@@ -956,6 +956,14 @@
     case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
     case lltok::kw_naked:           Attrs |= Attribute::Naked; break;
 
+    case lltok::kw_alignstack: {
+      unsigned Alignment;
+      if (ParseOptionalStackAlignment(Alignment))
+        return true;
+      Attrs |= Attribute::constructStackAlignmentFromInt(Alignment);
+      continue;
+    }
+
     case lltok::kw_align: {
       unsigned Alignment;
       if (ParseOptionalAlignment(Alignment))
@@ -963,6 +971,7 @@
       Attrs |= Attribute::constructAlignmentFromInt(Alignment);
       continue;
     }
+
     }
     Lex.Lex();
   }
@@ -1131,6 +1140,25 @@
   return false;
 }
 
+/// ParseOptionalStackAlignment
+///   ::= /* empty */
+///   ::= 'alignstack' '(' 4 ')'
+bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) {
+  Alignment = 0;
+  if (!EatIfPresent(lltok::kw_alignstack))
+    return false;
+  LocTy ParenLoc = Lex.getLoc();
+  if (!EatIfPresent(lltok::lparen))
+    return Error(ParenLoc, "expected '('");
+  LocTy AlignLoc = Lex.getLoc();
+  if (ParseUInt32(Alignment)) return true;
+  ParenLoc = Lex.getLoc();
+  if (!EatIfPresent(lltok::rparen))
+    return Error(ParenLoc, "expected ')'");
+  if (!isPowerOf2_32(Alignment))
+    return Error(AlignLoc, "stack alignment is not a power of two");
+  return false;
+}
 
 /// ParseIndexList - This parses the index list for an insert/extractvalue
 /// instruction.  This sets AteExtraComma in the case where we eat an extra
Index: lib/AsmParser/LLParser.h
===================================================================
--- lib/AsmParser/LLParser.h	(revision 95872)
+++ lib/AsmParser/LLParser.h	(working copy)
@@ -169,6 +169,7 @@
     bool ParseOptionalVisibility(unsigned &Visibility);
     bool ParseOptionalCallingConv(CallingConv::ID &CC);
     bool ParseOptionalAlignment(unsigned &Alignment);
+    bool ParseOptionalStackAlignment(unsigned &Alignment);
     bool ParseInstructionMetadata(SmallVectorImpl<std::pair<unsigned,
                                                             MDNode *> > &);
     bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma);
