diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp --- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -206,10 +206,6 @@ /// T2JumpTables - Keep track of all the Thumb2 jumptable instructions. SmallVector T2JumpTables; - /// HasFarJump - True if any far jump instruction has been emitted during - /// the branch fix up pass. - bool HasFarJump; - MachineFunction *MF; MachineConstantPool *MCP; const ARMBaseInstrInfo *TII; @@ -270,7 +266,6 @@ bool fixupImmediateBr(ImmBranch &Br); bool fixupConditionalBr(ImmBranch &Br); bool fixupUnconditionalBr(ImmBranch &Br); - bool undoLRSpillRestore(); bool optimizeThumb2Instructions(); bool optimizeThumb2Branches(); bool reorderThumb2JumpTables(); @@ -363,7 +358,6 @@ isThumb1 = AFI->isThumb1OnlyFunction(); isThumb2 = AFI->isThumb2Function(); - HasFarJump = false; bool GenerateTBB = isThumb2 || (isThumb1 && SynthesizeThumb1TBB); // Renumber all of the machine basic blocks in the function, guaranteeing that @@ -456,11 +450,6 @@ // After a while, this might be made debug-only, but it is not expensive. verify(); - // If LR has been forced spilled and no far jump (i.e. BL) has been issued, - // undo the spill / restore of LR if possible. - if (isThumb && !HasFarJump && AFI->isLRSpilledForFarJump()) - MadeChange |= undoLRSpillRestore(); - // Save the mapping between original and cloned constpool entries. for (unsigned i = 0, e = CPEntries.size(); i != e; ++i) { for (unsigned j = 0, je = CPEntries[i].size(); j != je; ++j) { @@ -1633,7 +1622,6 @@ BBInfoVector &BBInfo = BBUtils->getBBInfo(); BBInfo[MBB->getNumber()].Size += 2; BBUtils->adjustBBOffsetsAfter(MBB); - HasFarJump = true; ++NumUBrFixed; LLVM_DEBUG(dbgs() << " Changed B to long jump " << *MI); @@ -1735,34 +1723,6 @@ return true; } -/// undoLRSpillRestore - Remove Thumb push / pop instructions that only spills -/// LR / restores LR to pc. FIXME: This is done here because it's only possible -/// to do this if tBfar is not used. -bool ARMConstantIslands::undoLRSpillRestore() { - bool MadeChange = false; - for (unsigned i = 0, e = PushPopMIs.size(); i != e; ++i) { - MachineInstr *MI = PushPopMIs[i]; - // First two operands are predicates. - if (MI->getOpcode() == ARM::tPOP_RET && - MI->getOperand(2).getReg() == ARM::PC && - MI->getNumExplicitOperands() == 3) { - // Create the new insn and copy the predicate from the old. - BuildMI(MI->getParent(), MI->getDebugLoc(), TII->get(ARM::tBX_RET)) - .add(MI->getOperand(0)) - .add(MI->getOperand(1)); - MI->eraseFromParent(); - MadeChange = true; - } else if (MI->getOpcode() == ARM::tPUSH && - MI->getOperand(2).getReg() == ARM::LR && - MI->getNumExplicitOperands() == 3) { - // Just remove the push. - MI->eraseFromParent(); - MadeChange = true; - } - } - return MadeChange; -} - bool ARMConstantIslands::optimizeThumb2Instructions() { bool MadeChange = false; diff --git a/llvm/test/CodeGen/Thumb/remove-unneeded-push-pop.ll b/llvm/test/CodeGen/Thumb/remove-unneeded-push-pop.ll --- a/llvm/test/CodeGen/Thumb/remove-unneeded-push-pop.ll +++ b/llvm/test/CodeGen/Thumb/remove-unneeded-push-pop.ll @@ -5,8 +5,15 @@ define hidden void @foo() { entry: -; CHECK-NOT: push {lr} -; CHECK-NOT: pop {pc} +; undoLRSpillRestore() in ARMConstantIsland is not safe, as PrologEpilogInserter +; ensures stack alignment when LR is spilled. +; This test previously check 'push {lr}' gets erased, as mis-alignment happened when +; 'pop {pc}' is erased. However, erasing 'push {lr}' will cause the stack mis-aligned +; when StackAlignment is 8 (functions contain call/alloc). +; Therefore, we keep LR spill/restore. +; +; CHECK: push {lr} +; CHECK: pop {pc} store i32 24654, i32* @f, align 4 br label %if.end diff --git a/llvm/test/CodeGen/Thumb/stack-mis-alignment.ll b/llvm/test/CodeGen/Thumb/stack-mis-alignment.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/Thumb/stack-mis-alignment.ll @@ -0,0 +1,18 @@ +; RUN: llc -O0 < %s | FileCheck %s + +; For noreturn function with StackAlignment 8 (function contains call/alloc), +; check that lr is saved to keep the stack aligned. +; CHECK: push {lr} + +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "thumbv5e-none-linux-gnueabi" + +define dso_local i32 @f() noreturn nounwind { +entry: + call i32 @llvm.arm.space(i32 2048, i32 undef) + tail call i32 @exit(i32 0) + unreachable +} + +declare i32 @llvm.arm.space(i32, i32) +declare dso_local i32 @exit(i32)