[ARM] For old thumb ISA like v4t, we cannot use PC directly in pop.
authorQuentin Colombet <qcolombet@apple.com>
Mon, 30 Nov 2015 20:37:58 +0000 (20:37 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Mon, 30 Nov 2015 20:37:58 +0000 (20:37 +0000)
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

lib/Target/ARM/Thumb1FrameLowering.cpp
test/CodeGen/ARM/thumb1_return_sequence.ll

index f5d4cb8a3ca1ff83b3f886ff671d3cd522d29ea8..064cff6f570407ffca6c4a2db1140aa9d645913a 100644 (file)
@@ -422,25 +422,12 @@ bool Thumb1FrameLowering::emitPopSpecialFixUp(MachineBasicBlock &MBB,
   const ThumbRegisterInfo *RegInfo =
       static_cast<const ThumbRegisterInfo *>(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.
index 5b9c19ab5eb26a12102bfd23ec7025f1dca719cb..67d1cad2cf68f6f7b6adad6f9815dc45a6289d6d 100644 (file)
@@ -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}
 }