summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2023-03-30 13:31:58 +0300
committerTom Stellard <tstellar@redhat.com>2023-04-03 21:47:57 -0700
commit79e743f16cd9e4187d18dd8320d0144f56695867 (patch)
tree89a6d75c9e47d97030f2ed892957f02e4a8c6dd5
parentc163d43e220792637d2274407c925ba2c99bd66c (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.cpp28
-rw-r--r--llvm/test/CodeGen/ARM/Windows/wineh-opcodes.ll28
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)