Dynamic stack realignment use of sp register as source/dest register

in "bic sp, sp, #15" leads to unpredicatble behaviour in Thumb2 mode.
Emit the following code instead:
mov r4, sp
bic r4, r4, #15
mov sp, r4

llvm-svn: 90724
This commit is contained in:
Anton Korobeynikov 2009-12-06 22:39:50 +00:00
parent f2eda5efd2
commit 75dfed4fa5
3 changed files with 29 additions and 6 deletions

View File

@ -578,6 +578,13 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
MFI->calculateMaxStackAlignment();
}
// Spill R4 if Thumb2 function requires stack realignment - it will be used as
// scratch register.
// FIXME: It will be better just to find spare register here.
if (needsStackRealignment(MF) &&
AFI->isThumb2Function())
MF.getRegInfo().setPhysRegUsed(ARM::R4);
// Don't spill FP if the frame can be eliminated. This is determined
// by scanning the callee-save registers to see if any is used.
const unsigned *CSRegs = getCalleeSavedRegs();
@ -1351,14 +1358,30 @@ emitPrologue(MachineFunction &MF) const {
// If we need dynamic stack realignment, do it here.
if (needsStackRealignment(MF)) {
unsigned Opc;
unsigned MaxAlign = MFI->getMaxAlignment();
assert (!AFI->isThumb1OnlyFunction());
Opc = AFI->isThumbFunction() ? ARM::t2BICri : ARM::BICri;
AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), ARM::SP)
if (!AFI->isThumbFunction()) {
// Emit bic sp, sp, MaxAlign
AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl,
TII.get(ARM::BICri), ARM::SP)
.addReg(ARM::SP, RegState::Kill)
.addImm(MaxAlign-1)));
} else {
// We cannot use sp as source/dest register here, thus we're emitting the
// following sequence:
// mov r4, sp
// bic r4, r4, MaxAlign
// mov sp, r4
// FIXME: It will be better just to find spare register here.
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::R4)
.addReg(ARM::SP, RegState::Kill);
AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl,
TII.get(ARM::t2BICri), ARM::R4)
.addReg(ARM::R4, RegState::Kill)
.addImm(MaxAlign-1)));
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
.addReg(ARM::R4, RegState::Kill);
}
}
}

View File

@ -18,7 +18,7 @@ define void @test2() {
define i32 @test3() {
; CHECK: test3:
; CHECK: sub.w sp, sp, #805306368
; CHECK: sub sp, #24
; CHECK: sub sp, #20
%retval = alloca i32, align 4
%tmp = alloca i32, align 4
%a = alloca [805306369 x i8], align 16

View File

@ -11,7 +11,7 @@ declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*) nounwind readonly
define arm_apcscc void @aaa(%quuz* %this, i8* %block) {
; CHECK: aaa:
; CHECK: bic sp, sp, #15
; CHECK: bic r4, r4, #15
; CHECK: vst1.64 {{.*}}sp, :128
; CHECK: vld1.64 {{.*}}sp, :128
entry: