diff options
author | Martin Storsjö <martin@martin.st> | 2023-03-30 13:31:58 +0300 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2023-04-03 21:47:57 -0700 |
commit | 79e743f16cd9e4187d18dd8320d0144f56695867 (patch) | |
tree | 89a6d75c9e47d97030f2ed892957f02e4a8c6dd5 | |
parent | c163d43e220792637d2274407c925ba2c99bd66c (diff) |
[ARM] Handle generating SEH unwind info for t2STR_PRE/t2LDR_POST
This fixes compiling some uncommon cases.
Differential Revision: https://reviews.llvm.org/D147212
(cherry picked from commit c5383536cb6824391f99f8f5963fc1427dd1673f)
-rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 28 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll | 28 |
2 files changed, 56 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index 5fa7068c89eb..ae5a45ff5985 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -357,6 +357,34 @@ static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI, .setMIFlags(Flags); break; + case ARM::t2STR_PRE: + if (MBBI->getOperand(0).getReg() == ARM::SP && + MBBI->getOperand(2).getReg() == ARM::SP && + MBBI->getOperand(3).getImm() == -4) { + unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg()); + MIB = BuildMI(MF, DL, TII.get(ARM::SEH_SaveRegs)) + .addImm(1 << Reg) + .addImm(/*Wide=*/1) + .setMIFlags(Flags); + } else { + report_fatal_error("No matching SEH Opcode for t2STR_PRE"); + } + break; + + case ARM::t2LDR_POST: + if (MBBI->getOperand(1).getReg() == ARM::SP && + MBBI->getOperand(2).getReg() == ARM::SP && + MBBI->getOperand(3).getImm() == 4) { + unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg()); + MIB = BuildMI(MF, DL, TII.get(ARM::SEH_SaveRegs)) + .addImm(1 << Reg) + .addImm(/*Wide=*/1) + .setMIFlags(Flags); + } else { + report_fatal_error("No matching SEH Opcode for t2LDR_POST"); + } + break; + case ARM::t2LDMIA_RET: case ARM::t2LDMIA_UPD: case ARM::t2STMDB_UPD: { diff --git a/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll b/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll index e97da669d65a..1756d9305281 100644 --- a/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll +++ b/llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll @@ -311,3 +311,31 @@ entry: } declare arm_aapcs_vfpcc void @useptr(ptr noundef) + +; CHECK-LABEL: func_fp: +; CHECK-NEXT: .seh_proc func_fp +; CHECK-NEXT: @ %bb.0: @ %entry +; CHECK-NEXT: str r11, [sp, #-4]! +; CHECK-NEXT: .seh_save_regs_w {r11} +; CHECK-NEXT: mov r11, sp +; CHECK-NEXT: .seh_save_sp r11 +; CHECK-NEXT: .seh_endprologue + +; CHECK-NEXT: mov r0, r11 + +; CHECK-NEXT: .seh_startepilogue +; CHECK-NEXT: ldr r11, [sp], #4 +; CHECK-NEXT: .seh_save_regs_w {r11} +; CHECK-NEXT: bx lr +; CHECK-NEXT: .seh_nop +; CHECK-NEXT: .seh_endepilogue +; CHECK-NEXT: .seh_endproc + +define arm_aapcs_vfpcc i32 @func_fp() { +entry: + %0 = tail call ptr @llvm.frameaddress.p0(i32 0) + %1 = ptrtoint ptr %0 to i32 + ret i32 %1 +} + +declare ptr @llvm.frameaddress.p0(i32 immarg) |