From bd52506d24275733002da6f91c3715cde63fe2c0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20Storsj=C3=B6?= Date: Wed, 1 Jun 2022 22:38:41 +0300 Subject: [PATCH] [ARM] Make narrow push/pop in SEH prologues/epilogues where applicable 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 | 30 +++++++++++++++++- llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll | 36 +++++++++++----------- .../DebugInfo/COFF/ARMNT/arm-register-variables.ll | 4 +-- 3 files changed, 49 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index bb3e247..a660c99 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -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; } diff --git a/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll b/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll index bfa2860..ded0d8f 100644 --- a/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll +++ b/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll @@ -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 diff --git a/llvm/test/DebugInfo/COFF/ARMNT/arm-register-variables.ll b/llvm/test/DebugInfo/COFF/ARMNT/arm-register-variables.ll index 0291384..781a4c6 100644 --- a/llvm/test/DebugInfo/COFF/ARMNT/arm-register-variables.ll +++ b/llvm/test/DebugInfo/COFF/ARMNT/arm-register-variables.ll @@ -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: } -- 2.7.4