[PATCH] D125648: [ARM SEH 6] [ARM] Add SEH opcodes in frame lowering

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun May 22 15:01:24 PDT 2022


mstorsjo added a comment.

Since the beginning, I've had to disable PostRAScheduler, because it would reshuffle instructions independently of their associated `SEH_*` machineinstructions. I tried to compare it to the AArch64 implementation, but there, PostRAScheduler doesn't seem to be executed at all, so that didn't give any extra info about how to avoid it. So for this case, I tweaked `ARMSubtarget::enablePostRAScheduler` to disable the pass when producing SEH.

Compared to the AArch64 case, the ends of epilogues are slightly more problematic here. On AArch64, the epilogue end is before the `ret` instruction. On ARM, e.g. an `bx lr` (`ARM::tBX_RET`) is now followed by a `ARM::SEH_Nop` and `ARM::SEH_EpilogEnd`. As the `ARM::tBX_RET` is a terminator, the `SEH_Nop` and `SEH_EpilogEnd` that follows it also must be terminators, otherwise the machine instruction verifier bails out. Due to this, I've added a separate `ARM::SEH_Nop_Ret` which is marked a terminator.

After updating to use separate nop instructions, the end of an epilogue `tBX_RET`, `SEH_EpilogEnd (nop=1)`  was changed into `tBX_RET`, `SEH_Nop_Ret`, `SEH_EpilogEnd`. This causes the machine block placement pass to do tail merging of multiple such epilogues in one function (where it previously didn't), which loses the `SEH_Nop_ Ret` and `SEH_EpilogEnd` for all but one of those epilogues.

What's the correct way of making sure that tail merging doesn't try to touch the `SEH_*` instructions? This doesn't seem to be happening on AArch64.

I looked into making a bundle of the `rBX_RET`, `SEH_Nop_Ret`, `SEH_EpilogEnd` (with an `finalizeBundle` over those three instructions), but that later breaks assembly output with a failed assert `"Cannot print this instruction."`. I presume that would require something to unbundle them later?

When looking into the tail merging pass, I noticed that if `MachineInstr::isCFIInstruction()` would return true for the `SEH_*` instructions, it could be handled differently and maybe the pass wouldn't break them. But it doesn't seem trivial to test out making that return true for the `SEH_*` instructions, so I don't know if that would fix any of these issues or not.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125648/new/

https://reviews.llvm.org/D125648



More information about the llvm-commits mailing list