[llvm] 19d2e42 - ARM: don't return by popping PC if we have to adjust the stack afterwards.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 21 01:35:24 PDT 2021


Author: Tim Northover
Date: 2021-07-21T09:35:14+01:00
New Revision: 19d2e42be2cd586456ae03374b5fd3e22d9d14f2

URL: https://github.com/llvm/llvm-project/commit/19d2e42be2cd586456ae03374b5fd3e22d9d14f2
DIFF: https://github.com/llvm/llvm-project/commit/19d2e42be2cd586456ae03374b5fd3e22d9d14f2.diff

LOG: ARM: don't return by popping PC if we have to adjust the stack afterwards.

In mandatory tail calling conventions we might have to deallocate stack
space used by our arguments before return. This happens after popping
CSRs, so the pop cannot be turned into the return itself in this case.

The else branch here was already a nop, so removing it as a tidy-up.

Added: 
    

Modified: 
    llvm/lib/Target/ARM/ARMFrameLowering.cpp
    llvm/test/CodeGen/ARM/tailcc-call.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index a2ad626313294..025e43444f9c5 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -1229,19 +1229,16 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
       // The aligned reloads from area DPRCS2 are not inserted here.
       if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
         continue;
-
       if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
-          !isCmseEntry && !isTrap && STI.hasV5TOps()) {
-        if (MBB.succ_empty()) {
-          Reg = ARM::PC;
-          // Fold the return instruction into the LDM.
-          DeleteRet = true;
-          LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
-          // We 'restore' LR into PC so it is not live out of the return block:
-          // Clear Restored bit.
-          Info.setRestored(false);
-        } else
-          LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
+          !isCmseEntry && !isTrap && AFI->getArgumentStackToRestore() == 0 &&
+          STI.hasV5TOps() && MBB.succ_empty()) {
+        Reg = ARM::PC;
+        // Fold the return instruction into the LDM.
+        DeleteRet = true;
+        LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
+        // We 'restore' LR into PC so it is not live out of the return block:
+        // Clear Restored bit.
+        Info.setRestored(false);
       }
 
       // If NoGap is true, pop consecutive registers and then leave the rest

diff  --git a/llvm/test/CodeGen/ARM/tailcc-call.ll b/llvm/test/CodeGen/ARM/tailcc-call.ll
index ced6f02978dd0..1c1dfde03e565 100644
--- a/llvm/test/CodeGen/ARM/tailcc-call.ll
+++ b/llvm/test/CodeGen/ARM/tailcc-call.ll
@@ -191,3 +191,15 @@ define tailcc void @fromtail_toC() {
   call void @Ccallee_stack4([4 x i32] undef, i32 42)
   ret void
 }
+
+; Don't try to return by popping pc if there's stack to reclaim.
+define tailcc void @notail_stackclean([4 x i32], i32) {
+; COMMON-LABEL: notail_stackclean:
+; COMMON: pop {r7, lr}
+; COMMON: add sp, #8
+; COMMON: bx lr
+
+
+  call void @callee_stack0()
+  ret void
+}


        


More information about the llvm-commits mailing list