Stack Alignment: when creating stack objects in MachineFrameInfo, make sure
the alignment is clamped to TargetFrameLowering.getStackAlignment if the target does not support stack realignment or the option "realign-stack" is off. This will cause miscompile if the address is treated as aligned and add is replaced with or in DAGCombine. Added a bool StackRealignable to TargetFrameLowering to check whether stack realignment is implemented for the target. Also added a bool RealignOption to MachineFrameInfo to check whether the option "realign-stack" is on. rdar://12713765 llvm-svn: 169197
This commit is contained in:
parent
bac8ae6506
commit
f563941adc
|
@ -221,8 +221,11 @@ class MachineFrameInfo {
|
||||||
/// just allocate them normally.
|
/// just allocate them normally.
|
||||||
bool UseLocalStackAllocationBlock;
|
bool UseLocalStackAllocationBlock;
|
||||||
|
|
||||||
|
/// Whether the "realign-stack" option is on.
|
||||||
|
bool RealignOption;
|
||||||
public:
|
public:
|
||||||
explicit MachineFrameInfo(const TargetFrameLowering &tfi) : TFI(tfi) {
|
explicit MachineFrameInfo(const TargetFrameLowering &tfi, bool RealignOpt)
|
||||||
|
: TFI(tfi), RealignOption(RealignOpt) {
|
||||||
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
|
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
|
||||||
HasVarSizedObjects = false;
|
HasVarSizedObjects = false;
|
||||||
FrameAddressTaken = false;
|
FrameAddressTaken = false;
|
||||||
|
|
|
@ -47,11 +47,12 @@ private:
|
||||||
unsigned StackAlignment;
|
unsigned StackAlignment;
|
||||||
unsigned TransientStackAlignment;
|
unsigned TransientStackAlignment;
|
||||||
int LocalAreaOffset;
|
int LocalAreaOffset;
|
||||||
|
bool StackRealignable;
|
||||||
public:
|
public:
|
||||||
TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
|
TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
|
||||||
unsigned TransAl = 1)
|
unsigned TransAl = 1, bool StackReal = true)
|
||||||
: StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
|
: StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
|
||||||
LocalAreaOffset(LAO) {}
|
LocalAreaOffset(LAO), StackRealignable(StackReal) {}
|
||||||
|
|
||||||
virtual ~TargetFrameLowering();
|
virtual ~TargetFrameLowering();
|
||||||
|
|
||||||
|
@ -76,6 +77,12 @@ public:
|
||||||
return TransientStackAlignment;
|
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
|
/// getOffsetOfLocalArea - This method returns the offset of the local area
|
||||||
/// from the stack pointer on entrance to a function.
|
/// from the stack pointer on entrance to a function.
|
||||||
///
|
///
|
||||||
|
|
|
@ -58,7 +58,8 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM,
|
||||||
else
|
else
|
||||||
RegInfo = 0;
|
RegInfo = 0;
|
||||||
MFInfo = 0;
|
MFInfo = 0;
|
||||||
FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering());
|
FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering(),
|
||||||
|
TM.Options.RealignStack);
|
||||||
if (Fn->getFnAttributes().hasAttribute(Attributes::StackAlignment))
|
if (Fn->getFnAttributes().hasAttribute(Attributes::StackAlignment))
|
||||||
FrameInfo->ensureMaxAlignment(Fn->getAttributes().
|
FrameInfo->ensureMaxAlignment(Fn->getAttributes().
|
||||||
getFnAttributes().getStackAlignment());
|
getFnAttributes().getStackAlignment());
|
||||||
|
@ -448,15 +449,31 @@ MCSymbol *MachineFunction::getPICBaseSymbol() const {
|
||||||
/// ensureMaxAlignment - Make sure the function is at least Align bytes
|
/// ensureMaxAlignment - Make sure the function is at least Align bytes
|
||||||
/// aligned.
|
/// aligned.
|
||||||
void MachineFrameInfo::ensureMaxAlignment(unsigned Align) {
|
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;
|
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
|
/// CreateStackObject - Create a new statically sized stack object, returning
|
||||||
/// a nonnegative identifier to represent it.
|
/// a nonnegative identifier to represent it.
|
||||||
///
|
///
|
||||||
int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment,
|
int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment,
|
||||||
bool isSS, bool MayNeedSP, const AllocaInst *Alloca) {
|
bool isSS, bool MayNeedSP, const AllocaInst *Alloca) {
|
||||||
assert(Size != 0 && "Cannot allocate zero size stack objects!");
|
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,
|
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP,
|
||||||
Alloca));
|
Alloca));
|
||||||
int Index = (int)Objects.size() - NumFixedObjects - 1;
|
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,
|
int MachineFrameInfo::CreateSpillStackObject(uint64_t Size,
|
||||||
unsigned Alignment) {
|
unsigned Alignment) {
|
||||||
|
Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption,
|
||||||
|
Alignment, TFI.getStackAlignment());
|
||||||
CreateStackObject(Size, Alignment, true, false);
|
CreateStackObject(Size, Alignment, true, false);
|
||||||
int Index = (int)Objects.size() - NumFixedObjects - 1;
|
int Index = (int)Objects.size() - NumFixedObjects - 1;
|
||||||
ensureMaxAlignment(Alignment);
|
ensureMaxAlignment(Alignment);
|
||||||
|
@ -484,6 +503,8 @@ int MachineFrameInfo::CreateSpillStackObject(uint64_t Size,
|
||||||
///
|
///
|
||||||
int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment) {
|
int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment) {
|
||||||
HasVarSizedObjects = true;
|
HasVarSizedObjects = true;
|
||||||
|
Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption,
|
||||||
|
Alignment, TFI.getStackAlignment());
|
||||||
Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0));
|
Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0));
|
||||||
ensureMaxAlignment(Alignment);
|
ensureMaxAlignment(Alignment);
|
||||||
return (int)Objects.size()-NumFixedObjects-1;
|
return (int)Objects.size()-NumFixedObjects-1;
|
||||||
|
@ -503,6 +524,8 @@ int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset,
|
||||||
// object is 16-byte aligned.
|
// object is 16-byte aligned.
|
||||||
unsigned StackAlign = TFI.getStackAlignment();
|
unsigned StackAlign = TFI.getStackAlignment();
|
||||||
unsigned Align = MinAlign(SPOffset, StackAlign);
|
unsigned Align = MinAlign(SPOffset, StackAlign);
|
||||||
|
Align = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption,
|
||||||
|
Align, TFI.getStackAlignment());
|
||||||
Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable,
|
Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable,
|
||||||
/*isSS*/ false,
|
/*isSS*/ false,
|
||||||
/*NeedSP*/ false,
|
/*NeedSP*/ false,
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue