[PR #12] [MERGED] Fix register clobbering on aarch64 GHC when mixing tail/non-tail calls #12

Closed
opened 2026-02-18 19:21:14 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/RPCS3/llvm-mirror/pull/12
Author: @sguo35
Created: 5/25/2022
Status: Merged
Merged: 5/28/2022
Merged by: @undefined

Base: masterHead: master


📝 Commits (1)

  • bb4b60a Fix register clobbering on aarch64 GHC when mixing tail/non-tail calls

📊 Changes

5 files changed (+10 additions, -20 deletions)

View changed files

📝 lib/Target/AArch64/AArch64CallingConvention.td (+3 -0)
📝 lib/Target/AArch64/AArch64FrameLowering.cpp (+0 -14)
📝 lib/Target/AArch64/AArch64ISelLowering.cpp (+1 -1)
📝 lib/Target/AArch64/AArch64RegisterInfo.cpp (+5 -5)
📝 lib/Target/AArch64/GISel/AArch64CallLowering.cpp (+1 -0)

📄 Description

When we make L2 syscalls LLVM compiles Calls to branch-and-link instruction on arm64, whereas it uses call instruction on x86. The latter pushes the return address to the stack regardless of calling convention, so GHC doesn't need to save any registers even when calling between C++/JIT code.

But GHC assumes every call is a tail call+GHC CC and therefore doesn't need to save any registers, even though we call to non-GHC code e.g. L2 syscall function, using normal BLR+ret in arm64. So when we call to rpcs3 C++ code from JITed code, under GHC we don't save the previous LR in the JITed code before replacing it with the BLR call, which causes returns from syscalls to potentially return to wrong code.

This fixes that bug by re-enabling prologue/epilogue generation logic for GHC. Tail calls within JITed code are still proper tail calls but if we mark rpcs3 handling of JIT -> C++ calls as non-tail, then prologue/epilogue is properly emitted for those calls from JIT code.

Combined with virtual memory fixes and aarch64 specific intrinsics this gets the ppu_thread.elf test to pass on macOS arm64.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/RPCS3/llvm-mirror/pull/12 **Author:** [@sguo35](https://github.com/sguo35) **Created:** 5/25/2022 **Status:** ✅ Merged **Merged:** 5/28/2022 **Merged by:** [@undefined](undefined) **Base:** `master` ← **Head:** `master` --- ### 📝 Commits (1) - [`bb4b60a`](https://github.com/RPCS3/llvm-mirror/commit/bb4b60ad568be43416b9d4061948ec5af2ad8c8b) Fix register clobbering on aarch64 GHC when mixing tail/non-tail calls ### 📊 Changes **5 files changed** (+10 additions, -20 deletions) <details> <summary>View changed files</summary> 📝 `lib/Target/AArch64/AArch64CallingConvention.td` (+3 -0) 📝 `lib/Target/AArch64/AArch64FrameLowering.cpp` (+0 -14) 📝 `lib/Target/AArch64/AArch64ISelLowering.cpp` (+1 -1) 📝 `lib/Target/AArch64/AArch64RegisterInfo.cpp` (+5 -5) 📝 `lib/Target/AArch64/GISel/AArch64CallLowering.cpp` (+1 -0) </details> ### 📄 Description When we make L2 syscalls LLVM compiles Calls to branch-and-link instruction on arm64, whereas it uses call instruction on x86. The latter pushes the return address to the stack regardless of calling convention, so GHC doesn't need to save any registers even when calling between C++/JIT code. But GHC assumes every call is a tail call+GHC CC and therefore doesn't need to save any registers, even though we call to non-GHC code e.g. L2 syscall function, using normal BLR+ret in arm64. So when we call to rpcs3 C++ code from JITed code, under GHC we don't save the previous LR in the JITed code before replacing it with the BLR call, which causes returns from syscalls to potentially return to wrong code. This fixes that bug by re-enabling prologue/epilogue generation logic for GHC. Tail calls within JITed code are still proper tail calls but if we mark rpcs3 handling of JIT -> C++ calls as non-tail, then prologue/epilogue is properly emitted for those calls from JIT code. Combined with virtual memory fixes and aarch64 specific intrinsics this gets the `ppu_thread.elf` test to pass on macOS arm64. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-18 19:21:14 -05:00
yindo closed this issue 2026-02-18 19:21:14 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RPCS3/llvm-mirror#12