Support 16-byte aligned stack on 32-bit Windows.

On Windows x86-32, the ABI only guarantees the stack to be 4-byte
aligned. We therefore need the stack pointer to be explicitly
aligned when using vectors. This demands using a frame pointer (to
access function arguments). Also, we had to change accessing spilled
variables from the stack pointer instead of the frame pointer so they
are also aligned. This change does not affect PNaCl. Projects using
the Microsoft ABI should define SUBZERO_USE_MICROSOFT_ABI.

BUG=swiftshader:29

Change-Id: I186ce9435244d6fa9494ec514a91122b6be130b3
Reviewed-on: https://chromium-review.googlesource.com/427348
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index 802abfc..f75ca29 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -1006,6 +1006,13 @@
   assert(EntryNode);
   // LLVM enforces power of 2 alignment.
   assert(llvm::isPowerOf2_32(StackAlignment));
+  // If the ABI's stack alignment is smaller than the vector size (16 bytes),
+  // conservatively use a frame pointer to allow for explicit alignment of the
+  // stack pointer. This needs to happen before register allocation so the frame
+  // pointer can be reserved.
+  if (getTarget()->needsStackPointerAlignment()) {
+    getTarget()->setHasFramePointer();
+  }
   // Determine if there are large alignment allocations in the entry block or
   // dynamic allocations (variable size in the entry block).
   bool HasLargeAlignment = false;
@@ -1083,7 +1090,7 @@
   // Add instructions to the head of the entry block in reverse order.
   InstList &Insts = getEntryNode()->getInsts();
   if (HasDynamicAllocation && HasLargeAlignment) {
-    // We are using a frame pointer, but fixed large-alignment alloca addresses,
+    // We are using a frame pointer, but fixed large-alignment alloca addresses
     // do not have a known offset from either the stack or frame pointer.
     // They grow up from a user pointer from an alloca.
     sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer);