diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h index bf75578fbc30..93d77287d7ca 100644 --- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h +++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h @@ -221,8 +221,11 @@ class MachineFrameInfo { /// just allocate them normally. bool UseLocalStackAllocationBlock; + /// Whether the "realign-stack" option is on. + bool RealignOption; public: - explicit MachineFrameInfo(const TargetFrameLowering &tfi) : TFI(tfi) { + explicit MachineFrameInfo(const TargetFrameLowering &tfi, bool RealignOpt) + : TFI(tfi), RealignOption(RealignOpt) { StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; HasVarSizedObjects = false; FrameAddressTaken = false; diff --git a/llvm/include/llvm/Target/TargetFrameLowering.h b/llvm/include/llvm/Target/TargetFrameLowering.h index 7e54f1447e34..1958f90f9b1b 100644 --- a/llvm/include/llvm/Target/TargetFrameLowering.h +++ b/llvm/include/llvm/Target/TargetFrameLowering.h @@ -47,11 +47,12 @@ private: unsigned StackAlignment; unsigned TransientStackAlignment; int LocalAreaOffset; + bool StackRealignable; public: TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO, - unsigned TransAl = 1) + unsigned TransAl = 1, bool StackReal = true) : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl), - LocalAreaOffset(LAO) {} + LocalAreaOffset(LAO), StackRealignable(StackReal) {} virtual ~TargetFrameLowering(); @@ -76,6 +77,12 @@ public: return TransientStackAlignment; } + /// isStackRealignable - This method returns whether the stack can be + /// realigned. + bool isStackRealignable() const { + return StackRealignable; + } + /// getOffsetOfLocalArea - This method returns the offset of the local area /// from the stack pointer on entrance to a function. /// diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index f13fe14aa1b3..e88c3c16fd1e 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -58,7 +58,8 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM, else RegInfo = 0; MFInfo = 0; - FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering()); + FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering(), + TM.Options.RealignStack); if (Fn->getFnAttributes().hasAttribute(Attributes::StackAlignment)) FrameInfo->ensureMaxAlignment(Fn->getAttributes(). getFnAttributes().getStackAlignment()); @@ -448,15 +449,31 @@ MCSymbol *MachineFunction::getPICBaseSymbol() const { /// ensureMaxAlignment - Make sure the function is at least Align bytes /// aligned. void MachineFrameInfo::ensureMaxAlignment(unsigned Align) { + if (!TFI.isStackRealignable() || !RealignOption) + assert(Align <= TFI.getStackAlignment() && + "For targets without stack realignment, Align is out of limit!"); if (MaxAlignment < Align) MaxAlignment = Align; } +/// clampStackAlignment - Clamp the alignment if requested and emit a warning. +static inline unsigned clampStackAlignment(bool ShouldClamp, unsigned Align, + unsigned StackAlign) { + if (!ShouldClamp || Align <= StackAlign) + return Align; + DEBUG(dbgs() << "Warning: requested alignment " << Align + << " exceeds the stack alignment " << StackAlign + << " when stack realignment is off" << '\n'); + return StackAlign; +} + /// CreateStackObject - Create a new statically sized stack object, returning /// a nonnegative identifier to represent it. /// int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, bool MayNeedSP, const AllocaInst *Alloca) { assert(Size != 0 && "Cannot allocate zero size stack objects!"); + Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, + Alignment, TFI.getStackAlignment()); Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP, Alloca)); int Index = (int)Objects.size() - NumFixedObjects - 1; @@ -471,6 +488,8 @@ int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment, /// int MachineFrameInfo::CreateSpillStackObject(uint64_t Size, unsigned Alignment) { + Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, + Alignment, TFI.getStackAlignment()); CreateStackObject(Size, Alignment, true, false); int Index = (int)Objects.size() - NumFixedObjects - 1; ensureMaxAlignment(Alignment); @@ -484,6 +503,8 @@ int MachineFrameInfo::CreateSpillStackObject(uint64_t Size, /// int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment) { HasVarSizedObjects = true; + Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, + Alignment, TFI.getStackAlignment()); Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0)); ensureMaxAlignment(Alignment); return (int)Objects.size()-NumFixedObjects-1; @@ -503,6 +524,8 @@ int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset, // object is 16-byte aligned. unsigned StackAlign = TFI.getStackAlignment(); unsigned Align = MinAlign(SPOffset, StackAlign); + Align = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, + Align, TFI.getStackAlignment()); Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable, /*isSS*/ false, /*NeedSP*/ false, diff --git a/llvm/test/CodeGen/ARM/alloc-no-stack-realign.ll b/llvm/test/CodeGen/ARM/alloc-no-stack-realign.ll new file mode 100644 index 000000000000..273041dee34e --- /dev/null +++ b/llvm/test/CodeGen/ARM/alloc-no-stack-realign.ll @@ -0,0 +1,48 @@ +; RUN: llc < %s -mtriple=armv7-apple-ios -O0 -realign-stack=0 | FileCheck %s -check-prefix=NO-REALIGN +; RUN: llc < %s -mtriple=armv7-apple-ios -O0 | FileCheck %s + +; rdar://12713765 +; When realign-stack is set to false, make sure we are not creating stack +; objects that are assumed to be 64-byte aligned. +@T3_retval = common global <16 x float> zeroinitializer, align 16 + +define void @test(<16 x float>* noalias sret %agg.result) nounwind ssp { +entry: +; CHECK: test +; CHECK: bic sp, sp, #63 +; CHECK: orr [[R2:r[0-9]+]], [[R1:r[0-9]+]], #48 +; CHECK: vst1.64 +; CHECK: orr [[R2:r[0-9]+]], [[R1:r[0-9]+]], #32 +; CHECK: vst1.64 +; CHECK: orr [[R2:r[0-9]+]], [[R1:r[0-9]+]], #16 +; CHECK: vst1.64 +; CHECK: vst1.64 +; CHECK: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #48 +; CHECK: vst1.64 +; CHECK: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #32 +; CHECK: vst1.64 +; CHECK: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #16 +; CHECK: vst1.64 +; CHECK: vst1.64 +; NO-REALIGN: test +; NO-REALIGN: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #48 +; NO-REALIGN: vst1.64 +; NO-REALIGN: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #32 +; NO-REALIGN: vst1.64 +; NO-REALIGN: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #16 +; NO-REALIGN: vst1.64 +; NO-REALIGN: vst1.64 +; NO-REALIGN: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #48 +; NO-REALIGN: vst1.64 +; NO-REALIGN: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #32 +; NO-REALIGN: vst1.64 +; NO-REALIGN: add [[R2:r[0-9]+]], [[R1:r[0-9]+]], #16 +; NO-REALIGN: vst1.64 +; NO-REALIGN: vst1.64 + %retval = alloca <16 x float>, align 16 + %0 = load <16 x float>* @T3_retval, align 16 + store <16 x float> %0, <16 x float>* %retval + %1 = load <16 x float>* %retval + store <16 x float> %1, <16 x float>* %agg.result, align 16 + ret void +}