Add the necessary support to the ISel to allow targets to codegen the new
alignment information appropriately.  Includes code for PowerPC to support
fixed-size allocas with alignment larger than the stack.  Support for
arbitrarily aligned dynamic allocas coming soon.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24224 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index e38c740..9593220 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -258,6 +258,7 @@
   MachineFrameInfo *FFI = Fn.getFrameInfo();
 
   unsigned StackAlignment = TFI.getStackAlignment();
+  unsigned MaxAlign = StackAlignment;
 
   // Start at the beginning of the local area.
   // The Offset is the distance from the stack top in the direction
@@ -295,9 +296,11 @@
       Offset += FFI->getObjectSize(i);
 
     unsigned Align = FFI->getObjectAlignment(i);
-    assert(Align <= StackAlignment && "Cannot align stack object to higher "
-           "alignment boundary than the stack itself!");
-    Offset = (Offset+Align-1)/Align*Align;   // Adjust to Alignment boundary...
+    // If the alignment of this object is greater than that of the stack, then
+    // increase the stack alignment to match.
+    MaxAlign = std::max(MaxAlign, Align);
+    // Adjust to alignment boundary
+    Offset = (Offset+Align-1)/Align*Align;
 
     if (StackGrowsDown) {
       FFI->setObjectOffset(i, -Offset);        // Set the computed offset
@@ -315,6 +318,11 @@
 
   // Set the final value of the stack pointer...
   FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea());
+  // If we have a new stack alignment, set the preferred stack alignment so that
+  // the targets can do the appropriate thing to properly align the stack above
+  // the default alignment.
+  if (MaxAlign > StackAlignment)
+    FFI->setMaxAlignment(MaxAlign);
 }
 
 
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 3b5ef32..64256c9 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -147,7 +147,9 @@
       if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(AI->getArraySize())) {
         const Type *Ty = AI->getAllocatedType();
         uint64_t TySize = TLI.getTargetData().getTypeSize(Ty);
-        unsigned Align = TLI.getTargetData().getTypeAlignment(Ty);
+        unsigned Align = 
+          std::max((unsigned)TLI.getTargetData().getTypeAlignment(Ty),
+                   AI->getAlignment());
 
         // If the alignment of the value is smaller than the size of the value,
         // and if the size of the value is particularly small (<= 8 bytes),
@@ -636,7 +638,8 @@
 
   const Type *Ty = I.getAllocatedType();
   uint64_t TySize = TLI.getTargetData().getTypeSize(Ty);
-  unsigned Align = TLI.getTargetData().getTypeAlignment(Ty);
+  unsigned Align = std::max((unsigned)TLI.getTargetData().getTypeAlignment(Ty),
+                            I.getAlignment());
 
   SDOperand AllocSize = getValue(I.getArraySize());
   MVT::ValueType IntPtr = TLI.getPointerTy();