From: Quentin Colombet Date: Mon, 30 Nov 2015 20:37:58 +0000 (+0000) Subject: [ARM] For old thumb ISA like v4t, we cannot use PC directly in pop. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=ddaf09c1921d4306b865fae11bf9cfdca6b62731 [ARM] For old thumb ISA like v4t, we cannot use PC directly in pop. Fix the epilogue emission to account for that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254325 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp index f5d4cb8a3ca..064cff6f570 100644 --- a/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -422,25 +422,12 @@ bool Thumb1FrameLowering::emitPopSpecialFixUp(MachineBasicBlock &MBB, const ThumbRegisterInfo *RegInfo = static_cast(STI.getRegisterInfo()); - // If MBBI is a return instruction, we may be able to directly restore - // LR in the PC. - // This is possible if we do not need to emit any SP update. - // Otherwise, we need a temporary register to pop the value - // and copy that value into LR. + // When we need a special fix up for POP, this means that + // we either cannot use PC in POP or we have to update + // SP after poping the return address. + // In other words, we cannot use a pop {pc} like construction + // here, no matter what. auto MBBI = MBB.getFirstTerminator(); - if (!ArgRegsSaveSize && MBBI != MBB.end() && - MBBI->getOpcode() == ARM::tBX_RET) { - if (!DoIt) - return true; - MachineInstrBuilder MIB = - AddDefaultPred( - BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII.get(ARM::tPOP_RET))) - .addReg(ARM::PC, RegState::Define); - MIB.copyImplicitOps(&*MBBI); - // erase the old tBX_RET instruction - MBB.erase(MBBI); - return true; - } // Look for a temporary register to use. // First, compute the liveness information. diff --git a/test/CodeGen/ARM/thumb1_return_sequence.ll b/test/CodeGen/ARM/thumb1_return_sequence.ll index 5b9c19ab5eb..67d1cad2cf6 100644 --- a/test/CodeGen/ARM/thumb1_return_sequence.ll +++ b/test/CodeGen/ARM/thumb1_return_sequence.ll @@ -23,9 +23,22 @@ entry: ; -------- ; CHECK-V4T: add sp, ; CHECK-V4T-NEXT: pop {[[SAVED]]} -; We do not have any SP update to insert so we can just optimize -; the pop sequence. -; CHECK-V4T-NEXT: pop {pc} +; The ISA for v4 does not support pop pc, so make sure we do not emit +; one even when we do not need to update SP. +; CHECK-V4T-NOT: pop {pc} +; We may only use lo register to pop, but in that case, all the scratch +; ones are used. +; r12 is the only register we are allowed to clobber for AAPCS. +; Use it to save a lo register. +; CHECK-V4T-NEXT: mov [[TEMP_REG:r12]], [[POP_REG:r[0-7]]] +; Pop the value of LR. +; CHECK-V4T-NEXT: pop {[[POP_REG]]} +; Copy the value of LR in the right register. +; CHECK-V4T-NEXT: mov lr, [[POP_REG]] +; Restore the value that was in the register we used to pop the value of LR. +; CHECK-V4T-NEXT: mov [[POP_REG]], [[TEMP_REG]] +; Return. +; CHECK-V4T-NEXT: bx lr ; CHECK-V5T: pop {[[SAVED]], pc} } @@ -93,7 +106,13 @@ entry: ; Epilogue ; -------- ; CHECK-V4T: pop {[[SAVED]]} -; CHECK-V4T: pop {pc} +; The ISA for v4 does not support pop pc, so make sure we do not emit +; one even when we do not need to update SP. +; CHECK-V4T-NOT: pop {pc} +; Pop the value of LR into a scratch lo register other than r0 (it is +; used for the return value). +; CHECK-V4T-NEXT: pop {[[POP_REG:r[1-3]]]} +; CHECK-V4T-NEXT: bx [[POP_REG]] ; CHECK-V5T: pop {[[SAVED]], pc} }