[llvm] r197653 - [stackprotector] Use analysis from the StackProtector pass for stack layout in PEI a nd LocalStackSlot passes.

Josh Magee joshua_magee at playstation.sony.com
Wed Dec 18 19:17:11 PST 2013


Author: jmagee
Date: Wed Dec 18 21:17:11 2013
New Revision: 197653

URL: http://llvm.org/viewvc/llvm-project?rev=197653&view=rev
Log:
[stackprotector] Use analysis from the StackProtector pass for stack layout in PEI a nd LocalStackSlot passes.

This changes the MachineFrameInfo API to use the new SSPLayoutKind information
produced by the StackProtector pass (instead of a boolean flag) and updates a
few pass dependencies (to preserve the SSP analysis).

The stack layout follows the same approach used prior to this change - i.e.,
only LargeArray stack objects will be placed near the canary and everything
else will be laid out normally.  After this change, structures containing large
arrays will also be placed near the canary - a case previously missed by the
old implementation.

Out of tree targets will need to update their usage of
MachineFrameInfo::CreateStackObject to remove the MayNeedSP argument. 

The next patch will implement the rules for sspstrong and sspreq.  The end goal
is to support ssp-strong stack layout rules.

WIP.

Differential Revision: http://llvm-reviews.chandlerc.com/D2158

Added:
    llvm/trunk/test/CodeGen/ARM/ssp-data-layout.ll
    llvm/trunk/test/CodeGen/X86/ssp-data-layout.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h
    llvm/trunk/include/llvm/CodeGen/StackProtector.h
    llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp
    llvm/trunk/lib/CodeGen/MachineFunction.cpp
    llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp
    llvm/trunk/lib/CodeGen/Passes.cpp
    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/lib/CodeGen/StackProtector.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
    llvm/trunk/lib/Target/NVPTX/NVPTXAllocaHoisting.h
    llvm/trunk/lib/Target/NVPTX/NVPTXLowerAggrCopies.h
    llvm/trunk/lib/Target/NVPTX/NVPTXSplitBBatBar.h
    llvm/trunk/lib/Target/X86/X86FastISel.cpp
    llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Wed Dec 18 21:17:11 2013
@@ -101,11 +101,6 @@ class MachineFrameInfo {
     // cannot alias any other memory objects.
     bool isSpillSlot;
 
-    // MayNeedSP - If true the stack object triggered the creation of the stack
-    // protector. We should allocate this object right after the stack
-    // protector.
-    bool MayNeedSP;
-
     /// Alloca - If this stack object is originated from an Alloca instruction
     /// this value saves the original IR allocation. Can be NULL.
     const AllocaInst *Alloca;
@@ -115,9 +110,9 @@ class MachineFrameInfo {
     bool PreAllocated;
 
     StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
-                bool isSS, bool NSP, const AllocaInst *Val)
+                bool isSS, const AllocaInst *Val)
       : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
-        isSpillSlot(isSS), MayNeedSP(NSP), Alloca(Val), PreAllocated(false) {}
+        isSpillSlot(isSS), Alloca(Val), PreAllocated(false) {}
   };
 
   const TargetMachine &TM;
@@ -406,14 +401,6 @@ public:
     return Objects[ObjectIdx+NumFixedObjects].Alloca;
   }
 
-  /// NeedsStackProtector - Returns true if the object may need stack
-  /// protectors.
-  bool MayNeedStackProtector(int ObjectIdx) const {
-    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
-           "Invalid Object Idx!");
-    return Objects[ObjectIdx+NumFixedObjects].MayNeedSP;
-  }
-
   /// getObjectOffset - Return the assigned stack offset of the specified object
   /// from the incoming stack pointer.
   ///
@@ -531,7 +518,7 @@ public:
   /// a nonnegative identifier to represent it.
   ///
   int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
-                        bool MayNeedSP = false, const AllocaInst *Alloca = 0);
+                        const AllocaInst *Alloca = 0);
 
   /// CreateSpillStackObject - Create a new statically sized stack object that
   /// represents a spill slot, returning a nonnegative identifier to represent
@@ -551,7 +538,7 @@ public:
   /// variable sized object is created, whether or not the index returned is
   /// actually used.
   ///
-  int CreateVariableSizedObject(unsigned Alignment);
+  int CreateVariableSizedObject(unsigned Alignment, const AllocaInst *Alloca);
 
   /// getCalleeSavedInfo - Returns a reference to call saved info vector for the
   /// current function.

Modified: llvm/trunk/include/llvm/CodeGen/StackProtector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/StackProtector.h?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/StackProtector.h (original)
+++ llvm/trunk/include/llvm/CodeGen/StackProtector.h Wed Dec 18 21:17:11 2013
@@ -20,11 +20,11 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/ADT/ValueMap.h"
+#include "llvm/Analysis/Dominators.h"
 #include "llvm/Pass.h"
 #include "llvm/Target/TargetLowering.h"
 
 namespace llvm {
-class DominatorTree;
 class Function;
 class Module;
 class PHINode;

Modified: llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp (original)
+++ llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp Wed Dec 18 21:17:11 2013
@@ -17,12 +17,14 @@
 #define DEBUG_TYPE "localstackalloc"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Instructions.h"
@@ -60,18 +62,27 @@ namespace {
 
   class LocalStackSlotPass: public MachineFunctionPass {
     SmallVector<int64_t,16> LocalOffsets;
+    /// StackObjSet - A set of stack object indexes
+    typedef SmallSetVector<int, 8> StackObjSet;
 
     void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset,
                            bool StackGrowsDown, unsigned &MaxAlign);
+    void AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
+                               SmallSet<int, 16> &ProtectedObjs,
+                               MachineFrameInfo *MFI, bool StackGrowsDown,
+                               int64_t &Offset, unsigned &MaxAlign);
     void calculateFrameObjectOffsets(MachineFunction &Fn);
     bool insertFrameReferenceRegisters(MachineFunction &Fn);
   public:
     static char ID; // Pass identification, replacement for typeid
-    explicit LocalStackSlotPass() : MachineFunctionPass(ID) { }
+    explicit LocalStackSlotPass() : MachineFunctionPass(ID) { 
+      initializeLocalStackSlotPassPass(*PassRegistry::getPassRegistry());
+    }
     bool runOnMachineFunction(MachineFunction &MF);
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesCFG();
+      AU.addRequired<StackProtector>();
       MachineFunctionPass::getAnalysisUsage(AU);
     }
 
@@ -81,8 +92,12 @@ namespace {
 
 char LocalStackSlotPass::ID = 0;
 char &llvm::LocalStackSlotAllocationID = LocalStackSlotPass::ID;
-INITIALIZE_PASS(LocalStackSlotPass, "localstackalloc",
-                "Local Stack Slot Allocation", false, false)
+INITIALIZE_PASS_BEGIN(LocalStackSlotPass, "localstackalloc",
+                      "Local Stack Slot Allocation", false, false)
+INITIALIZE_PASS_DEPENDENCY(StackProtector)
+INITIALIZE_PASS_END(LocalStackSlotPass, "localstackalloc",
+                    "Local Stack Slot Allocation", false, false)
+
 
 bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
   MachineFrameInfo *MFI = MF.getFrameInfo();
@@ -145,6 +160,22 @@ void LocalStackSlotPass::AdjustStackOffs
   ++NumAllocations;
 }
 
+/// AssignProtectedObjSet - Helper function to assign large stack objects (i.e.,
+/// those required to be close to the Stack Protector) to stack offsets.
+void LocalStackSlotPass::AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
+                                           SmallSet<int, 16> &ProtectedObjs,
+                                           MachineFrameInfo *MFI,
+                                           bool StackGrowsDown, int64_t &Offset,
+                                           unsigned &MaxAlign) {
+
+  for (StackObjSet::const_iterator I = UnassignedObjs.begin(),
+        E = UnassignedObjs.end(); I != E; ++I) {
+    int i = *I;
+    AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);
+    ProtectedObjs.insert(i);
+  }
+}
+
 /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the
 /// abstract stack objects.
 ///
@@ -156,11 +187,13 @@ void LocalStackSlotPass::calculateFrameO
     TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
   int64_t Offset = 0;
   unsigned MaxAlign = 0;
+  StackProtector *SP = &getAnalysis<StackProtector>();
 
   // Make sure that the stack protector comes before the local variables on the
   // stack.
-  SmallSet<int, 16> LargeStackObjs;
+  SmallSet<int, 16> ProtectedObjs;
   if (MFI->getStackProtectorIndex() >= 0) {
+    StackObjSet LargeArrayObjs;
     AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset,
                       StackGrowsDown, MaxAlign);
 
@@ -170,12 +203,21 @@ void LocalStackSlotPass::calculateFrameO
         continue;
       if (MFI->getStackProtectorIndex() == (int)i)
         continue;
-      if (!MFI->MayNeedStackProtector(i))
-        continue;
 
-      AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);
-      LargeStackObjs.insert(i);
+      switch (SP->getSSPLayout(MFI->getObjectAllocation(i))) {
+      case StackProtector::SSPLK_None:
+      case StackProtector::SSPLK_SmallArray:
+      case StackProtector::SSPLK_AddrOf:
+        continue;
+      case StackProtector::SSPLK_LargeArray:
+        LargeArrayObjs.insert(i);
+        continue;
+      }
+      llvm_unreachable("Unexpected SSPLayoutKind.");
     }
+
+    AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
+                          Offset, MaxAlign);
   }
 
   // Then assign frame offsets to stack objects that are not used to spill
@@ -185,7 +227,7 @@ void LocalStackSlotPass::calculateFrameO
       continue;
     if (MFI->getStackProtectorIndex() == (int)i)
       continue;
-    if (LargeStackObjs.count(i))
+    if (ProtectedObjs.count(i))
       continue;
 
     AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);

Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Wed Dec 18 21:17:11 2013
@@ -499,14 +499,13 @@ static inline unsigned clampStackAlignme
 /// a nonnegative identifier to represent it.
 ///
 int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment,
-                      bool isSS, bool MayNeedSP, const AllocaInst *Alloca) {
+                      bool isSS, const AllocaInst *Alloca) {
   assert(Size != 0 && "Cannot allocate zero size stack objects!");
   Alignment =
     clampStackAlignment(!getFrameLowering()->isStackRealignable() ||
                           !RealignOption,
                         Alignment, getFrameLowering()->getStackAlignment());
-  Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP,
-                                Alloca));
+  Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, Alloca));
   int Index = (int)Objects.size() - NumFixedObjects - 1;
   assert(Index >= 0 && "Bad frame index!");
   ensureMaxAlignment(Alignment);
@@ -523,7 +522,7 @@ int MachineFrameInfo::CreateSpillStackOb
     clampStackAlignment(!getFrameLowering()->isStackRealignable() ||
                           !RealignOption,
                         Alignment, getFrameLowering()->getStackAlignment()); 
-  CreateStackObject(Size, Alignment, true, false);
+  CreateStackObject(Size, Alignment, true);
   int Index = (int)Objects.size() - NumFixedObjects - 1;
   ensureMaxAlignment(Alignment);
   return Index;
@@ -534,13 +533,14 @@ int MachineFrameInfo::CreateSpillStackOb
 /// variable sized object is created, whether or not the index returned is
 /// actually used.
 ///
-int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment) {
+int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment,
+                                                const AllocaInst *Alloca) {
   HasVarSizedObjects = true;
   Alignment =
     clampStackAlignment(!getFrameLowering()->isStackRealignable() ||
                           !RealignOption,
                         Alignment, getFrameLowering()->getStackAlignment()); 
-  Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0));
+  Objects.push_back(StackObject(0, Alignment, 0, false, false, Alloca));
   ensureMaxAlignment(Alignment);
   return (int)Objects.size()-NumFixedObjects-1;
 }
@@ -565,7 +565,6 @@ int MachineFrameInfo::CreateFixedObject(
                         Align, getFrameLowering()->getStackAlignment()); 
   Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable,
                                               /*isSS*/   false,
-                                              /*NeedSP*/ false,
                                               /*Alloca*/ 0));
   return -++NumFixedObjects;
 }

Modified: llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp Wed Dec 18 21:17:11 2013
@@ -51,6 +51,7 @@ void MachineFunctionPass::getAnalysisUsa
   AU.addPreserved("domfrontier");
   AU.addPreserved("loops");
   AU.addPreserved("lda");
+  AU.addPreserved("stack-protector");
 
   FunctionPass::getAnalysisUsage(AU);
 }

Modified: llvm/trunk/lib/CodeGen/Passes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/Passes.cpp (original)
+++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Dec 18 21:17:11 2013
@@ -427,10 +427,10 @@ void TargetPassConfig::addCodeGenPrepare
 /// Add common passes that perform LLVM IR to IR transforms in preparation for
 /// instruction selection.
 void TargetPassConfig::addISelPrepare() {
-  addPass(createStackProtectorPass(TM));
-
   addPreISel();
 
+  addPass(createStackProtectorPass(TM));
+
   if (PrintISelInput)
     addPass(createPrintFunctionPass("\n\n"
                                     "*** Final LLVM Code input to ISel ***\n",

Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)
+++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Wed Dec 18 21:17:11 2013
@@ -20,6 +20,7 @@
 #include "PrologEpilogInserter.h"
 #include "llvm/ADT/IndexedMap.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineDominators.h"
@@ -30,6 +31,7 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
 #include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/CommandLine.h"
@@ -56,6 +58,7 @@ INITIALIZE_PASS_BEGIN(PEI, "prologepilog
                 "Prologue/Epilogue Insertion", false, false)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_DEPENDENCY(StackProtector)
 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
 INITIALIZE_PASS_END(PEI, "prologepilog",
                     "Prologue/Epilogue Insertion & Frame Finalization",
@@ -69,6 +72,7 @@ void PEI::getAnalysisUsage(AnalysisUsage
   AU.setPreservesCFG();
   AU.addPreserved<MachineLoopInfo>();
   AU.addPreserved<MachineDominatorTree>();
+  AU.addRequired<StackProtector>();
   AU.addRequired<TargetPassConfig>();
   MachineFunctionPass::getAnalysisUsage(AU);
 }
@@ -97,6 +101,9 @@ void PEI::calculateSets(MachineFunction
   return;
 }
 
+/// StackObjSet - A set of stack object indexes
+typedef SmallSetVector<int, 8> StackObjSet;
+
 /// runOnMachineFunction - Insert prolog/epilog code and replace abstract
 /// frame indexes with appropriate references.
 ///
@@ -412,11 +419,28 @@ AdjustStackOffset(MachineFrameInfo *MFI,
   }
 }
 
+/// AssignProtectedObjSet - Helper function to assign large stack objects (i.e.,
+/// those required to be close to the Stack Protector) to stack offsets.
+static void
+AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
+                      SmallSet<int, 16> &ProtectedObjs,
+                      MachineFrameInfo *MFI, bool StackGrowsDown,
+                      int64_t &Offset, unsigned &MaxAlign) {
+
+  for (StackObjSet::const_iterator I = UnassignedObjs.begin(),
+        E = UnassignedObjs.end(); I != E; ++I) {
+    int i = *I;
+    AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
+    ProtectedObjs.insert(i);
+  }
+}
+
 /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the
 /// abstract stack objects.
 ///
 void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
   const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering();
+  StackProtector *SP = &getAnalysis<StackProtector>();
 
   bool StackGrowsDown =
     TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
@@ -526,8 +550,9 @@ void PEI::calculateFrameObjectOffsets(Ma
 
   // Make sure that the stack protector comes before the local variables on the
   // stack.
-  SmallSet<int, 16> LargeStackObjs;
+  SmallSet<int, 16> ProtectedObjs;
   if (MFI->getStackProtectorIndex() >= 0) {
+    StackObjSet LargeArrayObjs;
     AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown,
                       Offset, MaxAlign);
 
@@ -544,12 +569,21 @@ void PEI::calculateFrameObjectOffsets(Ma
         continue;
       if (MFI->getStackProtectorIndex() == (int)i)
         continue;
-      if (!MFI->MayNeedStackProtector(i))
-        continue;
 
-      AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
-      LargeStackObjs.insert(i);
+      switch (SP->getSSPLayout(MFI->getObjectAllocation(i))) {
+      case StackProtector::SSPLK_None:
+      case StackProtector::SSPLK_SmallArray:
+      case StackProtector::SSPLK_AddrOf:
+        continue;
+      case StackProtector::SSPLK_LargeArray:
+        LargeArrayObjs.insert(i);
+        continue;
+      }
+      llvm_unreachable("Unexpected SSPLayoutKind.");
     }
+
+    AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
+                          Offset, MaxAlign);
   }
 
   // Then assign frame offsets to stack objects that are not used to spill
@@ -566,7 +600,7 @@ void PEI::calculateFrameObjectOffsets(Ma
       continue;
     if (MFI->getStackProtectorIndex() == (int)i)
       continue;
-    if (LargeStackObjs.count(i))
+    if (ProtectedObjs.count(i))
       continue;
 
     AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Wed Dec 18 21:17:11 2013
@@ -85,16 +85,8 @@ void FunctionLoweringInfo::set(const Fun
         TySize *= CUI->getZExtValue();   // Get total allocated size.
         if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects.
 
-        // The object may need to be placed onto the stack near the stack
-        // protector if one exists. Determine here if this object is a suitable
-        // candidate. I.e., it would trigger the creation of a stack protector.
-        bool MayNeedSP =
-          (AI->isArrayAllocation() ||
-           (TySize >= 8 && isa<ArrayType>(Ty) &&
-            cast<ArrayType>(Ty)->getElementType()->isIntegerTy(8)));
         StaticAllocaMap[AI] =
-          MF->getFrameInfo()->CreateStackObject(TySize, Align, false,
-                                                MayNeedSP, AI);
+          MF->getFrameInfo()->CreateStackObject(TySize, Align, false, AI);
       }
 
   for (; BB != EB; ++BB)

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Dec 18 21:17:11 2013
@@ -3380,7 +3380,7 @@ void SelectionDAGBuilder::visitAlloca(co
 
   // Inform the Frame Information that we have just allocated a variable-sized
   // object.
-  FuncInfo.MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1);
+  FuncInfo.MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1, &I);
 }
 
 void SelectionDAGBuilder::visitLoad(const LoadInst &I) {

Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/StackProtector.cpp (original)
+++ llvm/trunk/lib/CodeGen/StackProtector.cpp Wed Dec 18 21:17:11 2013
@@ -20,7 +20,6 @@
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/Constants.h"

Modified: llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp Wed Dec 18 21:17:11 2013
@@ -42,6 +42,7 @@ namespace {
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.addRequired<MachineFunctionAnalysis>();
       AU.addPreserved<MachineFunctionAnalysis>();
+      AU.addPreserved("stack-protector");
       FunctionPass::getAnalysisUsage(AU);
     }
   };

Modified: llvm/trunk/lib/Target/NVPTX/NVPTXAllocaHoisting.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/NVPTX/NVPTXAllocaHoisting.h?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/Target/NVPTX/NVPTXAllocaHoisting.h (original)
+++ llvm/trunk/lib/Target/NVPTX/NVPTXAllocaHoisting.h Wed Dec 18 21:17:11 2013
@@ -32,6 +32,7 @@ public:
 
   void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.addRequired<DataLayout>();
+    AU.addPreserved("stack-protector");
     AU.addPreserved<MachineFunctionAnalysis>();
   }
 

Modified: llvm/trunk/lib/Target/NVPTX/NVPTXLowerAggrCopies.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/NVPTX/NVPTXLowerAggrCopies.h?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/Target/NVPTX/NVPTXLowerAggrCopies.h (original)
+++ llvm/trunk/lib/Target/NVPTX/NVPTXLowerAggrCopies.h Wed Dec 18 21:17:11 2013
@@ -29,6 +29,7 @@ struct NVPTXLowerAggrCopies : public Fun
 
   void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.addRequired<DataLayout>();
+    AU.addPreserved("stack-protector");
     AU.addPreserved<MachineFunctionAnalysis>();
   }
 

Modified: llvm/trunk/lib/Target/NVPTX/NVPTXSplitBBatBar.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/NVPTX/NVPTXSplitBBatBar.h?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/Target/NVPTX/NVPTXSplitBBatBar.h (original)
+++ llvm/trunk/lib/Target/NVPTX/NVPTXSplitBBatBar.h Wed Dec 18 21:17:11 2013
@@ -26,6 +26,7 @@ struct NVPTXSplitBBatBar : public Functi
 
   NVPTXSplitBBatBar() : FunctionPass(ID) {}
   void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.addPreserved("stack-protector");
     AU.addPreserved<MachineFunctionAnalysis>();
   }
   virtual bool runOnFunction(Function &F);

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Dec 18 21:17:11 2013
@@ -1696,6 +1696,8 @@ bool X86FastISel::X86VisitIntrinsicCall(
     const Value *Op1 = I.getArgOperand(0); // The guard's value.
     const AllocaInst *Slot = cast<AllocaInst>(I.getArgOperand(1));
 
+    MFI.setStackProtectorIndex(FuncInfo.StaticAllocaMap[Slot]);
+
     // Grab the frame index.
     X86AddressMode AM;
     if (!X86SelectAddress(Slot, AM)) return false;

Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=197653&r1=197652&r2=197653&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Wed Dec 18 21:17:11 2013
@@ -1246,7 +1246,7 @@ XCoreTargetLowering::LowerCCCArguments(S
       unsigned Size = ArgDI->Flags.getByValSize();
       unsigned Align = std::max(StackSlotSize, ArgDI->Flags.getByValAlign());
       // Create a new object on the stack and copy the pointee into it.
-      int FI = MFI->CreateStackObject(Size, Align, false, false);
+      int FI = MFI->CreateStackObject(Size, Align, false);
       SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
       InVals.push_back(FIN);
       MemOps.push_back(DAG.getMemcpy(Chain, dl, FIN, ArgDI->SDV,

Added: llvm/trunk/test/CodeGen/ARM/ssp-data-layout.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ssp-data-layout.ll?rev=197653&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/ssp-data-layout.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/ssp-data-layout.ll Wed Dec 18 21:17:11 2013
@@ -0,0 +1,207 @@
+; RUN: llc < %s -disable-fp-elim -march=arm -o - | FileCheck %s
+;  This test is fairly fragile.  The goal is to ensure that "large" stack
+;  objects are allocated closest to the stack protector (i.e., farthest away 
+;  from the Stack Pointer.)  In standard SSP mode this means that large (>=
+;  ssp-buffer-size) arrays and structures containing such arrays are
+;  closet to the protector.  With sspstrong and sspreq this means large
+;  arrays/structures-with-arrays are closest, followed by small (< ssp-buffer-size)
+;  arrays/structures-with-arrays, and then addr-taken variables.
+;
+;  Ideally, we only want verify that the objects appear in the correct groups
+;  and that the groups have the correct relative stack offset.  The ordering
+;  within a group is not relevant to this test.  Unfortunately, there is not
+;  an elegant way to do this, so just match the offset for each object.
+
+%struct.struct_large_char = type { [8 x i8] }
+%struct.struct_large_char2 = type { [2 x i8], [8 x i8] }
+%struct.struct_small_char = type { [2 x i8] }
+%struct.struct_large_nonchar = type { [8 x i32] }
+%struct.struct_small_nonchar = type { [2 x i16] }
+
+define void @layout_ssp() ssp {
+entry:
+; Expected stack layout for ssp is
+;  180 large_char          . Group 1, nested arrays, arrays >= ssp-buffer-size
+;  172 struct_large_char   .
+;  168 scalar1             | Everything else
+;  164 scalar2
+;  160 scalar3
+;  156 addr-of
+;  152 small_nonchar (84+68)
+;  112 large_nonchar
+;  110 small_char
+;  108 struct_small_char
+;   72 struct_large_nonchar
+;   68 struct_small_nonchar
+
+; CHECK: layout_ssp:
+; r[[SP]] is used as an offset into the stack later
+; CHECK: add r[[SP:[0-9]+]], sp, #68
+
+; CHECK: bl get_scalar1
+; CHECK: str r0, [sp, #168]
+; CHECK: bl end_scalar1
+
+; CHECK: bl get_scalar2
+; CHECK: str r0, [sp, #164]
+; CHECK: bl end_scalar2
+
+; CHECK: bl get_scalar3
+; CHECK: str r0, [sp, #160]
+; CHECK: bl end_scalar3
+
+; CHECK: bl get_addrof
+; CHECK: str r0, [sp, #156]
+; CHECK: bl end_addrof
+
+; CHECK: get_small_nonchar
+; CHECK: strh r0, [r[[SP]], #84]
+; CHECK: bl end_small_nonchar
+
+; CHECK: bl get_large_nonchar
+; CHECK: str r0, [sp, #112]
+; CHECK: bl end_large_nonchar
+
+; CHECK: bl get_small_char
+; CHECK: strb r0, [sp, #110]
+; CHECK: bl end_small_char
+
+; CHECK: bl get_large_char
+; CHECK: strb r0, [sp, #180]
+; CHECK: bl end_large_char
+
+; CHECK: bl get_struct_large_char
+; CHECK: strb r0, [sp, #172]
+; CHECK: bl end_struct_large_char
+
+; CHECK: bl get_struct_small_char
+; CHECK: strb r0, [sp, #108]
+; CHECK: bl end_struct_small_char
+
+; CHECK: bl get_struct_large_nonchar
+; CHECK:str r0, [sp, #72]
+; CHECK: bl end_struct_large_nonchar
+
+; CHECK: bl get_struct_small_nonchar
+; CHECK: strh r0, [r[[SP]]]
+; CHECK: bl end_struct_small_nonchar
+  %x = alloca i32, align 4
+  %y = alloca i32, align 4
+  %z = alloca i32, align 4
+  %ptr = alloca i32, align 4
+  %small2 = alloca [2 x i16], align 2
+  %large2 = alloca [8 x i32], align 16
+  %small = alloca [2 x i8], align 1
+  %large = alloca [8 x i8], align 1
+  %a = alloca %struct.struct_large_char, align 1
+  %b = alloca %struct.struct_small_char, align 1
+  %c = alloca %struct.struct_large_nonchar, align 8
+  %d = alloca %struct.struct_small_nonchar, align 2
+  %call = call i32 @get_scalar1()
+  store i32 %call, i32* %x, align 4
+  call void @end_scalar1()
+  %call1 = call i32 @get_scalar2()
+  store i32 %call1, i32* %y, align 4
+  call void @end_scalar2()
+  %call2 = call i32 @get_scalar3()
+  store i32 %call2, i32* %z, align 4
+  call void @end_scalar3()
+  %call3 = call i32 @get_addrof()
+  store i32 %call3, i32* %ptr, align 4
+  call void @end_addrof()
+  %call4 = call signext i16 @get_small_nonchar()
+  %arrayidx = getelementptr inbounds [2 x i16]* %small2, i32 0, i64 0
+  store i16 %call4, i16* %arrayidx, align 2
+  call void @end_small_nonchar()
+  %call5 = call i32 @get_large_nonchar()
+  %arrayidx6 = getelementptr inbounds [8 x i32]* %large2, i32 0, i64 0
+  store i32 %call5, i32* %arrayidx6, align 4
+  call void @end_large_nonchar()
+  %call7 = call signext i8 @get_small_char()
+  %arrayidx8 = getelementptr inbounds [2 x i8]* %small, i32 0, i64 0
+  store i8 %call7, i8* %arrayidx8, align 1
+  call void @end_small_char()
+  %call9 = call signext i8 @get_large_char()
+  %arrayidx10 = getelementptr inbounds [8 x i8]* %large, i32 0, i64 0
+  store i8 %call9, i8* %arrayidx10, align 1
+  call void @end_large_char()
+  %call11 = call signext i8 @get_struct_large_char()
+  %foo = getelementptr inbounds %struct.struct_large_char* %a, i32 0, i32 0
+  %arrayidx12 = getelementptr inbounds [8 x i8]* %foo, i32 0, i64 0
+  store i8 %call11, i8* %arrayidx12, align 1
+  call void @end_struct_large_char()
+  %call13 = call signext i8 @get_struct_small_char()
+  %foo14 = getelementptr inbounds %struct.struct_small_char* %b, i32 0, i32 0
+  %arrayidx15 = getelementptr inbounds [2 x i8]* %foo14, i32 0, i64 0
+  store i8 %call13, i8* %arrayidx15, align 1
+  call void @end_struct_small_char()
+  %call16 = call i32 @get_struct_large_nonchar()
+  %foo17 = getelementptr inbounds %struct.struct_large_nonchar* %c, i32 0, i32 0
+  %arrayidx18 = getelementptr inbounds [8 x i32]* %foo17, i32 0, i64 0
+  store i32 %call16, i32* %arrayidx18, align 4
+  call void @end_struct_large_nonchar()
+  %call19 = call signext i16 @get_struct_small_nonchar()
+  %foo20 = getelementptr inbounds %struct.struct_small_nonchar* %d, i32 0, i32 0
+  %arrayidx21 = getelementptr inbounds [2 x i16]* %foo20, i32 0, i64 0
+  store i16 %call19, i16* %arrayidx21, align 2
+  call void @end_struct_small_nonchar()
+  %arraydecay = getelementptr inbounds [8 x i8]* %large, i32 0, i32 0
+  %arraydecay22 = getelementptr inbounds [2 x i8]* %small, i32 0, i32 0
+  %arraydecay23 = getelementptr inbounds [8 x i32]* %large2, i32 0, i32 0
+  %arraydecay24 = getelementptr inbounds [2 x i16]* %small2, i32 0, i32 0
+  %0 = load i32* %x, align 4
+  %1 = load i32* %y, align 4
+  %2 = load i32* %z, align 4
+  %coerce.dive = getelementptr %struct.struct_large_char* %a, i32 0, i32 0
+  %3 = bitcast [8 x i8]* %coerce.dive to i64*
+  %4 = load i64* %3, align 1
+  %coerce.dive25 = getelementptr %struct.struct_small_char* %b, i32 0, i32 0
+  %5 = bitcast [2 x i8]* %coerce.dive25 to i16*
+  %6 = load i16* %5, align 1
+  %coerce.dive26 = getelementptr %struct.struct_small_nonchar* %d, i32 0, i32 0
+  %7 = bitcast [2 x i16]* %coerce.dive26 to i32*
+  %8 = load i32* %7, align 1
+  call void @takes_all(i64 %4, i16 %6, %struct.struct_large_nonchar* byval align 8 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
+  ret void
+}
+
+declare i32 @get_scalar1()
+declare void @end_scalar1()
+
+declare i32 @get_scalar2()
+declare void @end_scalar2()
+
+declare i32 @get_scalar3()
+declare void @end_scalar3()
+
+declare i32 @get_addrof()
+declare void @end_addrof()
+
+declare signext i16 @get_small_nonchar()
+declare void @end_small_nonchar()
+
+declare i32 @get_large_nonchar()
+declare void @end_large_nonchar()
+
+declare signext i8 @get_small_char()
+declare void @end_small_char()
+
+declare signext i8 @get_large_char()
+declare void @end_large_char()
+
+declare signext i8 @get_struct_large_char()
+declare void @end_struct_large_char()
+
+declare signext i8 @get_struct_large_char2()
+declare void @end_struct_large_char2()
+
+declare signext i8 @get_struct_small_char()
+declare void @end_struct_small_char()
+
+declare i32 @get_struct_large_nonchar()
+declare void @end_struct_large_nonchar()
+
+declare signext i16 @get_struct_small_nonchar()
+declare void @end_struct_small_nonchar()
+
+declare void @takes_all(i64, i16, %struct.struct_large_nonchar* byval align 8, i32, i8*, i8*, i32*, i16*, i32*, i32, i32, i32)

Added: llvm/trunk/test/CodeGen/X86/ssp-data-layout.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/ssp-data-layout.ll?rev=197653&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/ssp-data-layout.ll (added)
+++ llvm/trunk/test/CodeGen/X86/ssp-data-layout.ll Wed Dec 18 21:17:11 2013
@@ -0,0 +1,238 @@
+; RUN: llc < %s -disable-fp-elim -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
+;  This test is fairly fragile.  The goal is to ensure that "large" stack
+;  objects are allocated closest to the stack protector (i.e., farthest away 
+;  from the Stack Pointer.)  In standard SSP mode this means that large (>=
+;  ssp-buffer-size) arrays and structures containing such arrays are
+;  closet to the protector.  With sspstrong and sspreq this means large
+;  arrays/structures-with-arrays are closest, followed by small (< ssp-buffer-size)
+;  arrays/structures-with-arrays, and then addr-taken variables.
+;
+;  Ideally, we only want verify that the objects appear in the correct groups
+;  and that the groups have the correct relative stack offset.  The ordering
+;  within a group is not relevant to this test.  Unfortunately, there is not
+;  an elegant way to do this, so just match the offset for each object.
+; RUN: llc < %s -disable-fp-elim -mtriple=x86_64-unknown-unknown -O0 -mcpu=corei7 -o - \
+; RUN:   | FileCheck --check-prefix=FAST-NON-LIN %s
+; FastISel was not setting the StackProtectorIndex when lowering
+; Intrinsic::stackprotector and as a result the stack re-arrangement code was
+; never applied.  This problem only shows up on non-Linux platforms because on
+; Linux the stack protector cookie is loaded from a special address space which
+; always triggers standard ISel.  Run a basic test to ensure that at -O0
+; on a non-linux target the data layout rules are triggered.
+
+%struct.struct_large_char = type { [8 x i8] }
+%struct.struct_large_char2 = type { [2 x i8], [8 x i8] }
+%struct.struct_small_char = type { [2 x i8] }
+%struct.struct_large_nonchar = type { [8 x i32] }
+%struct.struct_small_nonchar = type { [2 x i16] }
+
+define void @layout_ssp() ssp {
+entry:
+; Expected stack layout for ssp is
+;  -16 large_char          . Group 1, nested arrays, arrays >= ssp-buffer-size
+;  -24 struct_large_char   .
+;  -28 scalar1             | Everything else
+;  -32 scalar2
+;  -36 scalar3
+;  -40 addr-of
+;  -44 small_nonchar
+;  -80 large_nonchar
+;  -82 small_char
+;  -88 struct_small_char
+;  -120 struct_large_nonchar
+;  -128 struct_small_nonchar
+
+; CHECK: layout_ssp:
+; CHECK: call{{l|q}} get_scalar1
+; CHECK: movl %eax, -28(
+; CHECK: call{{l|q}} end_scalar1
+
+; CHECK: call{{l|q}} get_scalar2
+; CHECK: movl %eax, -32(
+; CHECK: call{{l|q}} end_scalar2
+
+; CHECK: call{{l|q}} get_scalar3
+; CHECK: movl %eax, -36(
+; CHECK: call{{l|q}} end_scalar3
+
+; CHECK: call{{l|q}} get_addrof
+; CHECK: movl %eax, -40(
+; CHECK: call{{l|q}} end_addrof
+
+; CHECK: get_small_nonchar
+; CHECK: movw %ax, -44(
+; CHECK: call{{l|q}} end_small_nonchar
+
+; CHECK: call{{l|q}} get_large_nonchar
+; CHECK: movl %eax, -80(
+; CHECK: call{{l|q}} end_large_nonchar
+
+; CHECK: call{{l|q}} get_small_char
+; CHECK: movb %al, -82(
+; CHECK: call{{l|q}} end_small_char
+
+; CHECK: call{{l|q}} get_large_char
+; CHECK: movb %al, -16(
+; CHECK: call{{l|q}} end_large_char
+
+; CHECK: call{{l|q}} get_struct_large_char
+; CHECK: movb %al, -24(
+; CHECK: call{{l|q}} end_struct_large_char
+
+; CHECK: call{{l|q}} get_struct_small_char
+; CHECK: movb %al, -88(
+; CHECK: call{{l|q}} end_struct_small_char
+
+; CHECK: call{{l|q}} get_struct_large_nonchar
+; CHECK: movl %eax, -120(
+; CHECK: call{{l|q}} end_struct_large_nonchar
+
+; CHECK: call{{l|q}} get_struct_small_nonchar
+; CHECK: movw %ax, -128(
+; CHECK: call{{l|q}} end_struct_small_nonchar
+  %x = alloca i32, align 4
+  %y = alloca i32, align 4
+  %z = alloca i32, align 4
+  %ptr = alloca i32, align 4
+  %small2 = alloca [2 x i16], align 2
+  %large2 = alloca [8 x i32], align 16
+  %small = alloca [2 x i8], align 1
+  %large = alloca [8 x i8], align 1
+  %a = alloca %struct.struct_large_char, align 1
+  %b = alloca %struct.struct_small_char, align 1
+  %c = alloca %struct.struct_large_nonchar, align 8
+  %d = alloca %struct.struct_small_nonchar, align 2
+  %call = call i32 @get_scalar1()
+  store i32 %call, i32* %x, align 4
+  call void @end_scalar1()
+  %call1 = call i32 @get_scalar2()
+  store i32 %call1, i32* %y, align 4
+  call void @end_scalar2()
+  %call2 = call i32 @get_scalar3()
+  store i32 %call2, i32* %z, align 4
+  call void @end_scalar3()
+  %call3 = call i32 @get_addrof()
+  store i32 %call3, i32* %ptr, align 4
+  call void @end_addrof()
+  %call4 = call signext i16 @get_small_nonchar()
+  %arrayidx = getelementptr inbounds [2 x i16]* %small2, i32 0, i64 0
+  store i16 %call4, i16* %arrayidx, align 2
+  call void @end_small_nonchar()
+  %call5 = call i32 @get_large_nonchar()
+  %arrayidx6 = getelementptr inbounds [8 x i32]* %large2, i32 0, i64 0
+  store i32 %call5, i32* %arrayidx6, align 4
+  call void @end_large_nonchar()
+  %call7 = call signext i8 @get_small_char()
+  %arrayidx8 = getelementptr inbounds [2 x i8]* %small, i32 0, i64 0
+  store i8 %call7, i8* %arrayidx8, align 1
+  call void @end_small_char()
+  %call9 = call signext i8 @get_large_char()
+  %arrayidx10 = getelementptr inbounds [8 x i8]* %large, i32 0, i64 0
+  store i8 %call9, i8* %arrayidx10, align 1
+  call void @end_large_char()
+  %call11 = call signext i8 @get_struct_large_char()
+  %foo = getelementptr inbounds %struct.struct_large_char* %a, i32 0, i32 0
+  %arrayidx12 = getelementptr inbounds [8 x i8]* %foo, i32 0, i64 0
+  store i8 %call11, i8* %arrayidx12, align 1
+  call void @end_struct_large_char()
+  %call13 = call signext i8 @get_struct_small_char()
+  %foo14 = getelementptr inbounds %struct.struct_small_char* %b, i32 0, i32 0
+  %arrayidx15 = getelementptr inbounds [2 x i8]* %foo14, i32 0, i64 0
+  store i8 %call13, i8* %arrayidx15, align 1
+  call void @end_struct_small_char()
+  %call16 = call i32 @get_struct_large_nonchar()
+  %foo17 = getelementptr inbounds %struct.struct_large_nonchar* %c, i32 0, i32 0
+  %arrayidx18 = getelementptr inbounds [8 x i32]* %foo17, i32 0, i64 0
+  store i32 %call16, i32* %arrayidx18, align 4
+  call void @end_struct_large_nonchar()
+  %call19 = call signext i16 @get_struct_small_nonchar()
+  %foo20 = getelementptr inbounds %struct.struct_small_nonchar* %d, i32 0, i32 0
+  %arrayidx21 = getelementptr inbounds [2 x i16]* %foo20, i32 0, i64 0
+  store i16 %call19, i16* %arrayidx21, align 2
+  call void @end_struct_small_nonchar()
+  %arraydecay = getelementptr inbounds [8 x i8]* %large, i32 0, i32 0
+  %arraydecay22 = getelementptr inbounds [2 x i8]* %small, i32 0, i32 0
+  %arraydecay23 = getelementptr inbounds [8 x i32]* %large2, i32 0, i32 0
+  %arraydecay24 = getelementptr inbounds [2 x i16]* %small2, i32 0, i32 0
+  %0 = load i32* %x, align 4
+  %1 = load i32* %y, align 4
+  %2 = load i32* %z, align 4
+  %coerce.dive = getelementptr %struct.struct_large_char* %a, i32 0, i32 0
+  %3 = bitcast [8 x i8]* %coerce.dive to i64*
+  %4 = load i64* %3, align 1
+  %coerce.dive25 = getelementptr %struct.struct_small_char* %b, i32 0, i32 0
+  %5 = bitcast [2 x i8]* %coerce.dive25 to i16*
+  %6 = load i16* %5, align 1
+  %coerce.dive26 = getelementptr %struct.struct_small_nonchar* %d, i32 0, i32 0
+  %7 = bitcast [2 x i16]* %coerce.dive26 to i32*
+  %8 = load i32* %7, align 1
+  call void @takes_all(i64 %4, i16 %6, %struct.struct_large_nonchar* byval align 8 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
+  ret void
+}
+
+define void @fast_non_linux() ssp {
+entry:
+; FAST-NON-LIN: fast_non_linux:
+; FAST-NON-LIN: call{{l|q}} get_scalar1
+; FAST-NON-LIN: movl %eax, -20(
+; FAST-NON-LIN: call{{l|q}} end_scalar1
+
+; FAST-NON-LIN: call{{l|q}} get_large_char
+; FAST-NON-LIN: movb %al, -16(
+; FAST-NON-LIN: call{{l|q}} end_large_char
+  %x = alloca i32, align 4
+  %large = alloca [8 x i8], align 1
+  %call = call i32 @get_scalar1()
+  store i32 %call, i32* %x, align 4
+  call void @end_scalar1()
+  %call1 = call signext i8 @get_large_char()
+  %arrayidx = getelementptr inbounds [8 x i8]* %large, i32 0, i64 0
+  store i8 %call1, i8* %arrayidx, align 1
+  call void @end_large_char()
+  %0 = load i32* %x, align 4
+  %arraydecay = getelementptr inbounds [8 x i8]* %large, i32 0, i32 0
+  call void @takes_two(i32 %0, i8* %arraydecay)
+  ret void
+}
+
+declare i32 @get_scalar1()
+declare void @end_scalar1()
+
+declare i32 @get_scalar2()
+declare void @end_scalar2()
+
+declare i32 @get_scalar3()
+declare void @end_scalar3()
+
+declare i32 @get_addrof()
+declare void @end_addrof()
+
+declare signext i16 @get_small_nonchar()
+declare void @end_small_nonchar()
+
+declare i32 @get_large_nonchar()
+declare void @end_large_nonchar()
+
+declare signext i8 @get_small_char()
+declare void @end_small_char()
+
+declare signext i8 @get_large_char()
+declare void @end_large_char()
+
+declare signext i8 @get_struct_large_char()
+declare void @end_struct_large_char()
+
+declare signext i8 @get_struct_large_char2()
+declare void @end_struct_large_char2()
+
+declare signext i8 @get_struct_small_char()
+declare void @end_struct_small_char()
+
+declare i32 @get_struct_large_nonchar()
+declare void @end_struct_large_nonchar()
+
+declare signext i16 @get_struct_small_nonchar()
+declare void @end_struct_small_nonchar()
+
+declare void @takes_all(i64, i16, %struct.struct_large_nonchar* byval align 8, i32, i8*, i8*, i32*, i16*, i32*, i32, i32, i32)
+declare void @takes_two(i32, i8*)





More information about the llvm-commits mailing list