[ARM] Make narrow push/pop in SEH prologues/epilogues where applicable
authorMartin Storsjö <martin@martin.st>
Wed, 1 Jun 2022 19:38:41 +0000 (22:38 +0300)
committerMartin Storsjö <martin@martin.st>
Fri, 3 Jun 2022 19:33:55 +0000 (22:33 +0300)
We intentionally disable Thumb2SizeReduction for SEH
prologues/epilogues, to avoid needing to guess what will happen with
the instructions in a potential future pass in frame lowering.

But for this specific case, where we know we can express the
intent with a narrow instruction, change to that instruction form
directly in frame lowering.

Differential Revision: https://reviews.llvm.org/D126948

llvm/lib/Target/ARM/ARMFrameLowering.cpp
llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll
llvm/test/DebugInfo/COFF/ARMNT/arm-register-variables.ll

index bb3e247..a660c99 100644 (file)
@@ -338,6 +338,7 @@ static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI,
   case ARM::t2LDMIA_UPD:
   case ARM::t2STMDB_UPD: {
     unsigned Mask = 0;
+    bool Wide = false;
     for (unsigned i = 4, NumOps = MBBI->getNumOperands(); i != NumOps; ++i) {
       const MachineOperand &MO = MBBI->getOperand(i);
       if (!MO.isReg() || MO.isImplicit())
@@ -345,13 +346,40 @@ static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI,
       unsigned Reg = RegInfo->getSEHRegNum(MO.getReg());
       if (Reg == 15)
         Reg = 14;
+      if (Reg >= 8 && Reg <= 13)
+        Wide = true;
+      else if (Opc == ARM::t2LDMIA_UPD && Reg == 14)
+        Wide = true;
       Mask |= 1 << Reg;
     }
+    if (!Wide) {
+      unsigned NewOpc;
+      switch (Opc) {
+      case ARM::t2LDMIA_RET:
+        NewOpc = ARM::tPOP_RET;
+        break;
+      case ARM::t2LDMIA_UPD:
+        NewOpc = ARM::tPOP;
+        break;
+      case ARM::t2STMDB_UPD:
+        NewOpc = ARM::tPUSH;
+        break;
+      default:
+        llvm_unreachable("");
+      }
+      MachineInstrBuilder NewInstr =
+          BuildMI(MF, DL, TII.get(NewOpc)).setMIFlags(MBBI->getFlags());
+      for (unsigned i = 2, NumOps = MBBI->getNumOperands(); i != NumOps; ++i)
+        NewInstr.add(MBBI->getOperand(i));
+      MachineBasicBlock::iterator NewMBBI = MBB->insertAfter(MBBI, NewInstr);
+      MBB->erase(MBBI);
+      MBBI = NewMBBI;
+    }
     unsigned SEHOpc =
         (Opc == ARM::t2LDMIA_RET) ? ARM::SEH_SaveRegs_Ret : ARM::SEH_SaveRegs;
     MIB = BuildMI(MF, DL, TII.get(SEHOpc))
               .addImm(Mask)
-              .addImm(/*Wide=*/1)
+              .addImm(Wide ? 1 : 0)
               .setMIFlags(Flags);
     break;
   }
index bfa2860..ded0d8f 100644 (file)
@@ -30,14 +30,14 @@ entry:
 ; CHECK-LABEL: clobberR4NoFrame:
 ; CHECK-NEXT: .seh_proc clobberR4NoFrame
 ; CHECK-NEXT: @ %bb.0:                                @ %entry
-; CHECK-NEXT:         push.w  {r4, lr}
-; CHECK-NEXT:         .seh_save_regs_w  {r4, lr}
+; CHECK-NEXT:         push    {r4, lr}
+; CHECK-NEXT:         .seh_save_regs  {r4, lr}
 ; CHECK-NEXT:         .seh_endprologue
 ; CHECK-NEXT:         bl      other
 
 ; CHECK:              .seh_startepilogue
-; CHECK-NEXT:         pop.w   {r4, pc}
-; CHECK-NEXT:         .seh_save_regs_w  {r4, lr}
+; CHECK-NEXT:         pop     {r4, pc}
+; CHECK-NEXT:         .seh_save_regs  {r4, lr}
 ; CHECK-NEXT:         .seh_endepilogue
 ; CHECK-NEXT:         .seh_endproc
 
@@ -51,8 +51,8 @@ entry:
 ; CHECK-LABEL: clobberR4Tail:
 ; CHECK-NEXT: .seh_proc clobberR4Tail
 ; CHECK-NEXT: @ %bb.0:                                @ %entry
-; CHECK-NEXT:         push.w  {r4, lr}
-; CHECK-NEXT:         .seh_save_regs_w  {r4, lr}
+; CHECK-NEXT:         push    {r4, lr}
+; CHECK-NEXT:         .seh_save_regs  {r4, lr}
 ; CHECK-NEXT:         .seh_endprologue
 
 ; CHECK:              .seh_startepilogue
@@ -215,8 +215,8 @@ entry:
 ; CHECK-LABEL: func5000:
 ; CHECK-NEXT: .seh_proc func5000
 ; CHECK-NEXT: @ %bb.0:                                @ %entry
-; CHECK-NEXT:         push.w  {r4, r5, r6, lr}
-; CHECK-NEXT:         .seh_save_regs_w  {r4-r6, lr}
+; CHECK-NEXT:         push    {r4, r5, r6, lr}
+; CHECK-NEXT:         .seh_save_regs  {r4-r6, lr}
 ; CHECK-NEXT:         movw    r4, #1250
 ; CHECK-NEXT:         .seh_nop_w
 ; CHECK-NEXT:         bl      __chkstk
@@ -230,8 +230,8 @@ entry:
 ; CHECK-NEXT:         .seh_stackalloc_w       4992
 ; CHECK-NEXT:         add     sp, #8
 ; CHECK-NEXT:         .seh_stackalloc 8
-; CHECK-NEXT:         pop.w   {r4, r5, r6, pc}
-; CHECK-NEXT:         .seh_save_regs_w  {r4-r6, lr}
+; CHECK-NEXT:         pop     {r4, r5, r6, pc}
+; CHECK-NEXT:         .seh_save_regs  {r4-r6, lr}
 ; CHECK-NEXT:         .seh_endepilogue
 ; CHECK-NEXT:         .seh_endproc
 
@@ -247,8 +247,8 @@ entry:
 ; CHECK-LABEL: func262144:
 ; CHECK-NEXT: .seh_proc func262144
 ; CHECK-NEXT: @ %bb.0:                                @ %entry
-; CHECK-NEXT:         push.w  {r4, r5, r6, lr}
-; CHECK-NEXT:         .seh_save_regs_w  {r4-r6, lr}
+; CHECK-NEXT:         push    {r4, r5, r6, lr}
+; CHECK-NEXT:         .seh_save_regs  {r4-r6, lr}
 ; CHECK-NEXT:         movw    r4, #0
 ; CHECK-NEXT:         .seh_nop_w
 ; CHECK-NEXT:         movt    r4, #1
@@ -262,8 +262,8 @@ entry:
 ; CHECK:              .seh_startepilogue
 ; CHECK-NEXT:         add.w   sp, sp, #262144
 ; CHECK-NEXT:         .seh_stackalloc_w       262144
-; CHECK-NEXT:         pop.w   {r4, r5, r6, pc}
-; CHECK-NEXT:         .seh_save_regs_w  {r4-r6, lr}
+; CHECK-NEXT:         pop     {r4, r5, r6, pc}
+; CHECK-NEXT:         .seh_save_regs  {r4-r6, lr}
 ; CHECK-NEXT:         .seh_endepilogue
 ; CHECK-NEXT:         .seh_endproc
 
@@ -279,8 +279,8 @@ entry:
 ; CHECK-LABEL: func270000:
 ; CHECK-NEXT: .seh_proc func270000
 ; CHECK-NEXT: @ %bb.0:                                @ %entry
-; CHECK-NEXT:         push.w  {r4, r5, r6, lr}
-; CHECK-NEXT:         .seh_save_regs_w  {r4-r6, lr}
+; CHECK-NEXT:         push    {r4, r5, r6, lr}
+; CHECK-NEXT:         .seh_save_regs  {r4-r6, lr}
 ; CHECK-NEXT:         movw    r4, #1964
 ; CHECK-NEXT:         .seh_nop_w
 ; CHECK-NEXT:         movt    r4, #1
@@ -296,8 +296,8 @@ entry:
 ; CHECK-NEXT:         .seh_stackalloc_w       268288
 ; CHECK-NEXT:         add.w   sp, sp, #1712
 ; CHECK-NEXT:         .seh_stackalloc_w       1712
-; CHECK-NEXT:         pop.w   {r4, r5, r6, pc}
-; CHECK-NEXT:         .seh_save_regs_w  {r4-r6, lr}
+; CHECK-NEXT:         pop     {r4, r5, r6, pc}
+; CHECK-NEXT:         .seh_save_regs  {r4-r6, lr}
 ; CHECK-NEXT:         .seh_endepilogue
 ; CHECK-NEXT:         .seh_endproc
 
index 0291384..781a4c6 100644 (file)
@@ -44,9 +44,9 @@
 ; OBJ-NEXT:   OffsetInParent: 0
 ; OBJ-NEXT:   BasePointerOffset: 12
 ; OBJ-NEXT:   LocalVariableAddrRange {
-; OBJ-NEXT:     OffsetStart: .text+0xA
+; OBJ-NEXT:     OffsetStart: .text+0x8
 ; OBJ-NEXT:     ISectStart: 0x0
-; OBJ-NEXT:     Range: 0x1C
+; OBJ-NEXT:     Range: 0x1A
 ; OBJ-NEXT:   }
 ; OBJ-NEXT: }