diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 93d77287d7c..0748b9ab24a 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -493,11 +493,23 @@ public: return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL; } + /// CreateStackObjectWithMinAlign - Create a new statically sized stack + /// object, returning a nonnegative identifier to represent it. This function + /// takes a preferred alignment and a minimal alignment. + /// + int CreateStackObjectWithMinAlign(uint64_t Size, unsigned PrefAlignment, + unsigned MinAlignment, bool isSS, + bool MayNeedSP = false, const AllocaInst *Alloca = 0); + /// CreateStackObject - Create a new statically sized stack object, returning - /// a nonnegative identifier to represent it. + /// a nonnegative identifier to represent it. Will not emit an error when + /// Alignment can't be satisfied. /// int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, - bool MayNeedSP = false, const AllocaInst *Alloca = 0); + bool MayNeedSP = false, const AllocaInst *Alloca = 0) { + return CreateStackObjectWithMinAlign(Size, Alignment, 0, isSS, + MayNeedSP, Alloca); + } /// CreateSpillStackObject - Create a new statically sized stack object that /// represents a spill slot, returning a nonnegative identifier to represent @@ -517,7 +529,8 @@ public: /// variable sized object is created, whether or not the index returned is /// actually used. /// - int CreateVariableSizedObject(unsigned Alignment); + int CreateVariableSizedObject(unsigned PrefAlignment, unsigned MinAlignment, + const AllocaInst *Alloca = 0); /// getCalleeSavedInfo - Returns a reference to call saved info vector for the /// current function. diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 9647e83e24c..3d7d20d4160 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -473,24 +473,32 @@ void MachineFrameInfo::ensureMaxAlignment(unsigned 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'); +static inline unsigned clampStackAlignment(bool ShouldClamp, unsigned PrefAlign, + unsigned MinAlign, unsigned StackAlign, + const AllocaInst *Alloca = 0) { + if (!ShouldClamp || PrefAlign <= StackAlign) + return PrefAlign; + if (Alloca && MinAlign > StackAlign) + Alloca->getParent()->getContext().emitError(Alloca, + "Requested Minimal Alignment exceeds the Stack Alignment!"); + else + assert(MinAlign <= StackAlign && + "Requested Minimal Alignment exceeds the Stack Alignment!"); return StackAlign; } -/// CreateStackObject - Create a new statically sized stack object, returning -/// a nonnegative identifier to represent it. +/// CreateStackObjectWithMinAlign - Create a new statically sized stack +/// object, returning a nonnegative identifier to represent it. This function +/// takes a preferred alignment and a minimal alignment. /// -int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment, - bool isSS, bool MayNeedSP, const AllocaInst *Alloca) { +int MachineFrameInfo::CreateStackObjectWithMinAlign(uint64_t Size, + unsigned PrefAlignment, unsigned MinAlignment, + bool isSS, bool MayNeedSP, const AllocaInst *Alloca) { assert(Size != 0 && "Cannot allocate zero size stack objects!"); - Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, - Alignment, TFI.getStackAlignment()); + unsigned Alignment = clampStackAlignment( + !TFI.isStackRealignable() || !RealignOption, + PrefAlignment, MinAlignment, + TFI.getStackAlignment(), Alloca); Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP, Alloca)); int Index = (int)Objects.size() - NumFixedObjects - 1; @@ -506,7 +514,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()); + Alignment, 0, + TFI.getStackAlignment()); CreateStackObject(Size, Alignment, true, false); int Index = (int)Objects.size() - NumFixedObjects - 1; ensureMaxAlignment(Alignment); @@ -518,10 +527,13 @@ int MachineFrameInfo::CreateSpillStackObject(uint64_t Size, /// variable sized object is created, whether or not the index returned is /// actually used. /// -int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment) { +int MachineFrameInfo::CreateVariableSizedObject(unsigned PrefAlignment, + unsigned MinAlignment, const AllocaInst *Alloca) { HasVarSizedObjects = true; - Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, - Alignment, TFI.getStackAlignment()); + unsigned Alignment = clampStackAlignment( + !TFI.isStackRealignable() || !RealignOption, + PrefAlignment, MinAlignment, + TFI.getStackAlignment(), Alloca); Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0)); ensureMaxAlignment(Alignment); return (int)Objects.size()-NumFixedObjects-1; @@ -542,7 +554,7 @@ int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset, unsigned StackAlign = TFI.getStackAlignment(); unsigned Align = MinAlign(SPOffset, StackAlign); Align = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, - Align, TFI.getStackAlignment()); + Align, 0, TFI.getStackAlignment()); Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable, /*isSS*/ false, /*NeedSP*/ false, diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index b46edad7a3d..229c50be9a1 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -95,7 +95,8 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) { (TySize >= 8 && isa(Ty) && cast(Ty)->getElementType()->isIntegerTy(8))); StaticAllocaMap[AI] = - MF->getFrameInfo()->CreateStackObject(TySize, Align, false, + MF->getFrameInfo()->CreateStackObjectWithMinAlign(TySize, Align, + AI->getAlignment(), false, MayNeedSP, AI); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 8c22db35cb1..ee98b00e2b5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3259,7 +3259,8 @@ void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) { // 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.getAlignment(), &I); } void SelectionDAGBuilder::visitLoad(const LoadInst &I) { diff --git a/test/CodeGen/ARM/alloc-no-stack-realign-error.ll b/test/CodeGen/ARM/alloc-no-stack-realign-error.ll new file mode 100644 index 00000000000..96c00174dba --- /dev/null +++ b/test/CodeGen/ARM/alloc-no-stack-realign-error.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -mtriple=armv7-apple-ios -O0 -realign-stack=0 2>&1 | FileCheck %s + +; rdar://12713765 +@T3_retval = common global <16 x float> zeroinitializer, align 16 + +; If alignment for alloc is smaller than or equal to stack alignment, but the +; preferred type alignment is bigger, the alignment will be clamped. +; If alignment for alloca is bigger than stack alignment, the compiler +; will emit an error. +define void @test(<16 x float>* noalias sret %agg.result) nounwind ssp { +entry: +; CHECK: Requested Minimal Alignment exceeds the Stack Alignment! + %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 +} diff --git a/test/CodeGen/ARM/alloc-no-stack-realign.ll b/test/CodeGen/ARM/alloc-no-stack-realign.ll index 273041dee34..94adc9c67de 100644 --- a/test/CodeGen/ARM/alloc-no-stack-realign.ll +++ b/test/CodeGen/ARM/alloc-no-stack-realign.ll @@ -39,7 +39,7 @@ entry: ; 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 + %retval = alloca <16 x float>, align 4 %0 = load <16 x float>* @T3_retval, align 16 store <16 x float> %0, <16 x float>* %retval %1 = load <16 x float>* %retval