diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-12-06 22:39:50 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-12-06 22:39:50 +0000 |
commit | 7cca606aaa6fee6ff4f548aa3686608b6be1f208 (patch) | |
tree | d31df77e7d6b41f9c521287a790e60eb923633a7 | |
parent | 08bc2701a22cae61d202c0960a390d8410434e5c (diff) | |
download | llvm-7cca606aaa6fee6ff4f548aa3686608b6be1f208.tar.gz llvm-7cca606aaa6fee6ff4f548aa3686608b6be1f208.tar.bz2 llvm-7cca606aaa6fee6ff4f548aa3686608b6be1f208.tar.xz |
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90724 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMBaseRegisterInfo.cpp | 31 | ||||
-rw-r--r-- | test/CodeGen/Thumb2/large-stack.ll | 2 | ||||
-rw-r--r-- | test/CodeGen/Thumb2/thumb2-spill-q.ll | 2 |
3 files changed, 29 insertions, 6 deletions
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index ff11576030..9b5f79fb10 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -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); + } } } diff --git a/test/CodeGen/Thumb2/large-stack.ll b/test/CodeGen/Thumb2/large-stack.ll index 6f5996174a..da44cdea0f 100644 --- a/test/CodeGen/Thumb2/large-stack.ll +++ b/test/CodeGen/Thumb2/large-stack.ll @@ -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 diff --git a/test/CodeGen/Thumb2/thumb2-spill-q.ll b/test/CodeGen/Thumb2/thumb2-spill-q.ll index aef167b07f..2b087893fd 100644 --- a/test/CodeGen/Thumb2/thumb2-spill-q.ll +++ b/test/CodeGen/Thumb2/thumb2-spill-q.ll @@ -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: |