Revert r214881 because it broke lots of build-bots
authorJonathan Roelofs <jonathan@codesourcery.com>
Tue, 5 Aug 2014 17:36:05 +0000 (17:36 +0000)
committerJonathan Roelofs <jonathan@codesourcery.com>
Tue, 5 Aug 2014 17:36:05 +0000 (17:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214893 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMMachineFunctionInfo.h
lib/Target/ARM/Thumb1FrameLowering.cpp
test/CodeGen/ARM/thumb1_return_sequence.ll [deleted file]

index 3e53af42b897d74d455dfab0cb8b0d18d39517b5..8c4900b5b48f0d3c3182dbd6612aa5a7eaf15a85 100644 (file)
@@ -2113,10 +2113,6 @@ ARMTargetLowering::LowerReturn(SDValue Chain,
   RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
   bool isLittleEndian = Subtarget->isLittle();
 
-  MachineFunction &MF = DAG.getMachineFunction();
-  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
-  AFI->setReturnRegsCount(RVLocs.size());
-
   // Copy the result values into the output registers.
   for (unsigned i = 0, realRVLocIdx = 0;
        i != RVLocs.size();
index 5adb68992cb8ab4a8530dc80b16a4a035af638c6..d3fabc3ebb0401e4e0648eed19a3fff9fdc8bee6 100644 (file)
@@ -48,9 +48,6 @@ class ARMFunctionInfo : public MachineFunctionInfo {
   ///
   unsigned ArgRegsSaveSize;
 
-  /// ReturnRegsCount - Number of registers used up in the return.
-  unsigned ReturnRegsCount;
-
   /// HasStackFrame - True if this function has a stack frame. Set by
   /// processFunctionBeforeCalleeSavedScan().
   bool HasStackFrame;
@@ -130,8 +127,7 @@ public:
   ARMFunctionInfo() :
     isThumb(false),
     hasThumb2(false),
-    ArgRegsSaveSize(0), ReturnRegsCount(0), HasStackFrame(false),
-    RestoreSPFromFP(false),
+    ArgRegsSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
     LRSpilledForFarJump(false),
     FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
     GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
@@ -155,9 +151,6 @@ public:
   }
   void setArgRegsSaveSize(unsigned s) { ArgRegsSaveSize = s; }
 
-  unsigned getReturnRegsCount() const { return ReturnRegsCount; }
-  void setReturnRegsCount(unsigned s) { ReturnRegsCount = s; }
-
   bool hasStackFrame() const { return HasStackFrame; }
   void setHasStackFrame(bool s) { HasStackFrame = s; }
 
index 6deab4f0887c7949a7a6c2de54e29579a0e4abe5..05852d814aa540cc7c1e6a0ea405e47ac3e87616 100644 (file)
@@ -388,65 +388,28 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF,
     }
   }
 
-  bool IsV4PopReturn = false;
-  for (const CalleeSavedInfo &CSI : MFI->getCalleeSavedInfo())
-    if (CSI.getReg() == ARM::LR)
-      IsV4PopReturn = true;
-  IsV4PopReturn &= STI.hasV4TOps() && !STI.hasV5TOps();
-
-  // Unlike T2 and ARM mode, the T1 pop instruction cannot restore
-  // to LR, and we can't pop the value directly to the PC since
-  // we need to update the SP after popping the value. So instead
-  // we have to emit:
-  //   POP {r3}
-  //   ADD sp, #offset
-  //   BX r3
-  // If this would clobber a return value, then generate this sequence instead:
-  //   MOV ip, r3
-  //   POP {r3}
-  //   ADD sp, #offset
-  //   MOV lr, r3
-  //   MOV r3, ip
-  //   BX lr
-  if (ArgRegsSaveSize || IsV4PopReturn) {
+  if (ArgRegsSaveSize) {
+    // Unlike T2 and ARM mode, the T1 pop instruction cannot restore
+    // to LR, and we can't pop the value directly to the PC since
+    // we need to update the SP after popping the value. Therefore, we
+    // pop the old LR into R3 as a temporary.
+
     // Get the last instruction, tBX_RET
     MBBI = MBB.getLastNonDebugInstr();
     assert (MBBI->getOpcode() == ARM::tBX_RET);
-    DebugLoc dl = MBBI->getDebugLoc();
-
-    if (AFI->getReturnRegsCount() <= 3) {
-      // Epilogue: pop saved LR to R3 and branch off it. 
-      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
-        .addReg(ARM::R3, RegState::Define);
-
-      emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize);
-
-      MachineInstrBuilder MIB =
-        BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX))
-        .addReg(ARM::R3, RegState::Kill);
-      AddDefaultPred(MIB);
-      MIB.copyImplicitOps(&*MBBI);
-      // erase the old tBX_RET instruction
-      MBB.erase(MBBI);
-    } else {
-      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr))
-        .addReg(ARM::R12, RegState::Define)
-        .addReg(ARM::R3, RegState::Kill));
-
-      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
-        .addReg(ARM::R3, RegState::Define);
-
-      emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize);
-
-      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr))
-        .addReg(ARM::LR, RegState::Define)
-        .addReg(ARM::R3, RegState::Kill));
-
-      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr))
-        .addReg(ARM::R3, RegState::Define)
-        .addReg(ARM::R12, RegState::Kill));
-      // Keep the tBX_RET instruction
-    }
+    // Epilogue for vararg functions: pop LR to R3 and branch off it.
+    AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
+      .addReg(ARM::R3, RegState::Define);
+
+    emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize);
+
+    MachineInstrBuilder MIB =
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg))
+      .addReg(ARM::R3, RegState::Kill);
+    AddDefaultPred(MIB);
+    MIB.copyImplicitOps(&*MBBI);
+    // erase the old tBX_RET instruction
+    MBB.erase(MBBI);
   }
 }
 
@@ -513,9 +476,6 @@ restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
       // Special epilogue for vararg functions. See emitEpilogue
       if (isVarArg)
         continue;
-      // ARMv4T requires BX, see emitEpilogue
-      if (STI.hasV4TOps() && !STI.hasV5TOps())
-        continue;
       Reg = ARM::PC;
       (*MIB).setDesc(TII.get(ARM::tPOP_RET));
       MIB.copyImplicitOps(&*MI);
diff --git a/test/CodeGen/ARM/thumb1_return_sequence.ll b/test/CodeGen/ARM/thumb1_return_sequence.ll
deleted file mode 100644 (file)
index 155c658..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-; RUN: llc -mtriple=thumbv4t-none--eabi < %s | FileCheck %s --check-prefix=CHECK-V4T
-; RUN: llc -mtriple=thumbv5t-none--eabi < %s | FileCheck %s --check-prefix=CHECK-V5T
-
-; CHECK-V4T-LABEL: clobberframe
-; CHECK-V5T-LABEL: clobberframe
-define <4 x i32> @clobberframe() #0 {
-entry:
-; Prologue
-; --------
-; CHECK-V4T:    push {r4, r5, r7, lr}
-; CHECK-V4T:    sub sp,
-; CHECK-V5T:    push {r4, r5, r7, lr}
-
-  %b = alloca <4 x i32>, align 16
-  %a = alloca <4 x i32>, align 16
-  store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16
-  store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
-  %0 = load <4 x i32>* %a, align 16
-  ret <4 x i32> %0
-
-; Epilogue
-; --------
-; CHECK-V4T:         add sp,
-; CHECK-V4T-NEXT:    pop {r4, r5, r7}
-; CHECK-V4T-NEXT:    mov r12, r3
-; CHECK-V4T-NEXT:    pop {r3}
-; CHECK-V4T-NEXT:    mov lr, r3
-; CHECK-V4T-NEXT:    mov r3, r12
-; CHECK-V4T:         bx  lr
-; CHECK-V5T:         pop {r4, r5, r7, pc}
-}
-
-; CHECK-V4T-LABEL: clobbervariadicframe
-; CHECK-V5T-LABEL: clobbervariadicframe
-define <4 x i32> @clobbervariadicframe(i32 %i, ...) #0 {
-entry:
-; Prologue
-; --------
-; CHECK-V4T:    sub sp,
-; CHECK-V4T:    push {r4, r5, r7, lr}
-; CHECK-V5T:    sub sp,
-; CHECK-V5T:    push {r4, r5, r7, lr}
-
-  %b = alloca <4 x i32>, align 16
-  %a = alloca <4 x i32>, align 16
-  store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16
-  store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
-  %0 = load <4 x i32>* %a, align 16
-  ret <4 x i32> %0
-
-; Epilogue
-; --------
-; CHECK-V4T:         pop {r4, r5, r7}
-; CHECK-V4T-NEXT:    mov r12, r3
-; CHECK-V4T-NEXT:    pop {r3}
-; CHECK-V4T-NEXT:    add sp,
-; CHECK-V4T-NEXT:    mov lr, r3
-; CHECK-V4T-NEXT:    mov r3, r12
-; CHECK-V4T:         bx  lr
-; CHECK-V5T:         add sp,
-; CHECK-V5T-NEXT:    pop {r4, r5, r7}
-; CHECK-V5T-NEXT:    mov r12, r3
-; CHECK-V5T-NEXT:    pop {r3}
-; CHECK-V5T-NEXT:    add sp,
-; CHECK-V5T-NEXT:    mov lr, r3
-; CHECK-V5T-NEXT:    mov r3, r12
-; CHECK-V5T-NEXT:    bx lr
-}
-
-; CHECK-V4T-LABEL: simpleframe
-; CHECK-V5T-LABEL: simpleframe
-define i32 @simpleframe() #0 {
-entry:
-; Prologue
-; --------
-; CHECK-V4T:    push    {r4, lr}
-; CHECK-V5T:    push    {r4, lr}
-
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %d = alloca i32, align 4
-  store i32 1, i32* %a, align 4
-  store i32 2, i32* %b, align 4
-  store i32 3, i32* %c, align 4
-  store i32 4, i32* %d, align 4
-  %0 = load i32* %a, align 4
-  %inc = add nsw i32 %0, 1
-  store i32 %inc, i32* %a, align 4
-  %1 = load i32* %b, align 4
-  %inc1 = add nsw i32 %1, 1
-  store i32 %inc1, i32* %b, align 4
-  %2 = load i32* %c, align 4
-  %inc2 = add nsw i32 %2, 1
-  store i32 %inc2, i32* %c, align 4
-  %3 = load i32* %d, align 4
-  %inc3 = add nsw i32 %3, 1
-  store i32 %inc3, i32* %d, align 4
-  %4 = load i32* %a, align 4
-  %5 = load i32* %b, align 4
-  %add = add nsw i32 %4, %5
-  %6 = load i32* %c, align 4
-  %add4 = add nsw i32 %add, %6
-  %7 = load i32* %d, align 4
-  %add5 = add nsw i32 %add4, %7
-  ret i32 %add5
-
-; Epilogue
-; --------
-; CHECK-V4T:    pop {r4}
-; CHECK-V4T:    pop {r3}
-; CHECK-V4T:    bx r3
-; CHECK-V5T:    pop {r4, pc}
-}
-
-; CHECK-V4T-LABEL: simplevariadicframe
-; CHECK-V5T-LABEL: simplevariadicframe
-define i32 @simplevariadicframe(i32 %i, ...) #0 {
-entry:
-; Prologue
-; --------
-; CHECK-V4T:    sub sp,
-; CHECK-V4T:    push {r4, r5, r7, lr}
-; CHECK-V4T:    sub sp,
-; CHECK-V5T:    sub sp,
-; CHECK-V5T:    push {r4, r5, r7, lr}
-; CHECK-V5T:    sub sp,
-
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %d = alloca i32, align 4
-  store i32 1, i32* %a, align 4
-  store i32 2, i32* %b, align 4
-  store i32 3, i32* %c, align 4
-  store i32 4, i32* %d, align 4
-  %0 = load i32* %a, align 4
-  %inc = add nsw i32 %0, 1
-  store i32 %inc, i32* %a, align 4
-  %1 = load i32* %b, align 4
-  %inc1 = add nsw i32 %1, 1
-  store i32 %inc1, i32* %b, align 4
-  %2 = load i32* %c, align 4
-  %inc2 = add nsw i32 %2, 1
-  store i32 %inc2, i32* %c, align 4
-  %3 = load i32* %d, align 4
-  %inc3 = add nsw i32 %3, 1
-  store i32 %inc3, i32* %d, align 4
-  %4 = load i32* %a, align 4
-  %5 = load i32* %b, align 4
-  %add = add nsw i32 %4, %5
-  %6 = load i32* %c, align 4
-  %add4 = add nsw i32 %add, %6
-  %7 = load i32* %d, align 4
-  %add5 = add nsw i32 %add4, %7
-  %add6 = add nsw i32 %add5, %i
-  ret i32 %add6
-
-; Epilogue
-; --------
-; CHECK-V4T:         add sp,
-; CHECK-V4T-NEXT:    pop {r4, r5, r7}
-; CHECK-V4T-NEXT:    pop {r3}
-; CHECK-V4T-NEXT:    add sp,
-; CHECK-V4T-NEXT:    bx r3
-; CHECK-V5T:         add sp,
-; CHECK-V5T-NEXT:    pop {r4, r5, r7}
-; CHECK-V5T-NEXT:    pop {r3}
-; CHECK-V5T-NEXT:    add sp,
-; CHECK-V5T-NEXT:    bx r3
-}
-
-; CHECK-V4T-LABEL: noframe
-; CHECK-V5T-LABEL: noframe
-define i32 @noframe() #0 {
-entry:
-; Prologue
-; --------
-; CHECK-V4T-NOT: push
-; CHECK-V5T-NOT: push
-    ret i32 0;
-; Epilogue
-; --------
-; CHECK-V4T-NOT: pop
-; CHECK-V5T-NOT: pop
-; CHECK-V4T:    bx  lr
-; CHECK-V5T:    bx  lr
-}
-
-; CHECK-V4T-LABEL: novariadicframe
-; CHECK-V5T-LABEL: novariadicframe
-define i32 @novariadicframe(i32 %i) #0 {
-entry:
-; Prologue
-; --------
-; CHECK-V4T-NOT: push
-; CHECK-V5T-NOT: push
-    ret i32 %i;
-; Epilogue
-; --------
-; CHECK-V4T-NOT: pop
-; CHECK-V5T-NOT: pop
-; CHECK-V4T:    bx  lr
-; CHECK-V5T:    bx  lr
-}