diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -338,6 +338,7 @@ 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 @@ 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 --- a/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll +++ b/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll @@ -30,14 +30,14 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 --- 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: }