summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-12-06 22:39:50 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-12-06 22:39:50 +0000
commit7cca606aaa6fee6ff4f548aa3686608b6be1f208 (patch)
treed31df77e7d6b41f9c521287a790e60eb923633a7
parent08bc2701a22cae61d202c0960a390d8410434e5c (diff)
downloadllvm-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.cpp31
-rw-r--r--test/CodeGen/Thumb2/large-stack.ll2
-rw-r--r--test/CodeGen/Thumb2/thumb2-spill-q.ll2
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: