]> granicus.if.org Git - llvm/commitdiff
Bug fix on function epilog optimization (ARM backend)
authorOliver Stannard <oliver.stannard@linaro.org>
Tue, 3 Sep 2019 09:51:19 +0000 (09:51 +0000)
committerOliver Stannard <oliver.stannard@linaro.org>
Tue, 3 Sep 2019 09:51:19 +0000 (09:51 +0000)
To save a 'add sp,#val' instruction by adding registers to the final pop instruction,
the first register transferred by this pop instruction need to be found.
If the function to be optimized has a non-void return value, the operand list contains
r0 (implicit) which prevents the optimization to take place.
Therefore implicit register references should be skipped in the search loop,
because this registers are never popped from the stack.

Patch by Rainer Herbertz (rOptimizer)!

Differential revision: https://reviews.llvm.org/D66730

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370728 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMBaseInstrInfo.cpp
test/CodeGen/ARM/fold-stack-adjust.ll

index d166a6d7eeb92b8423e3fdd9cbd9531524a211e1..680729dd29b9cac714ad3f3da62686cabc8b7562 100644 (file)
@@ -2420,7 +2420,8 @@ bool llvm::tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget,
     MachineOperand &MO = MI->getOperand(i);
     RegList.push_back(MO);
 
-    if (MO.isReg() && TRI->getEncodingValue(MO.getReg()) < FirstRegEnc)
+    if (MO.isReg() && !MO.isImplicit() &&
+        TRI->getEncodingValue(MO.getReg()) < FirstRegEnc)
       FirstRegEnc = TRI->getEncodingValue(MO.getReg());
   }
 
@@ -2430,7 +2431,7 @@ bool llvm::tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget,
   for (int CurRegEnc = FirstRegEnc - 1; CurRegEnc >= 0 && RegsNeeded;
        --CurRegEnc) {
     unsigned CurReg = RegClass->getRegister(CurRegEnc);
-    if (IsT1PushPop && CurReg > ARM::R7)
+    if (IsT1PushPop && CurRegEnc > TRI->getEncodingValue(ARM::R7))
       continue;
     if (!IsPop) {
       // Pushing any register is completely harmless, mark the register involved
index b8ff910fd178472ec3623c08623d6a97ce2e855e..6256138e9a020668efdd4204fd9305db4afea059 100644 (file)
@@ -42,6 +42,19 @@ define void @check_simple() minsize {
   ret void
 }
 
+define i32 @check_simple_ret() minsize {
+; CHECK-FNSTART-LABEL: check_simple_ret:
+; CHECK: push {r5, r6, r7, lr}
+; CHECK-NOT: sub sp,
+; ...
+; CHECK-NOT: add sp,
+; CHECK: pop {r2, r3, r7, pc}
+
+  %var = alloca i8, i32 8
+  call void @bar(i8* %var)
+  ret i32 0
+}
+
 define void @check_simple_too_big() minsize {
 ; CHECK-FNSTART-LABEL: check_simple_too_big:
 ; CHECK: push {r7, lr}