-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[AArch64] Fix missing register definitions in homogeneous epilog lowering #171118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ring The lowering for HOM_Epilog did not transfer explicit register defs from the pseudo-instruction to the generated helper calls. MachineVerifier would complain if a following tail call uses one of the restored CSRs. This scenario occurs in code generated by the Swift compiler, where X20 is used to pass swiftself. This patch fixes the issue by adding the missing defs back to the helper call as implicit defs.
|
@llvm/pr-subscribers-backend-aarch64 Author: Zhaoxuan Jiang (nocchijiang) ChangesThe lowering for HOM_Epilog did not transfer explicit register defs from the pseudo-instruction to the generated helper calls. MachineVerifier would complain if a following tail call uses one of the restored CSRs. This scenario occurs in code generated by the Swift compiler, where X20 is used to pass swiftself. This patch fixes the issue by adding the missing defs back to the helper call as implicit defs. Full diff: https://github.com/llvm/llvm-project/pull/171118.diff 2 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64LowerHomogeneousPrologEpilog.cpp b/llvm/lib/Target/AArch64/AArch64LowerHomogeneousPrologEpilog.cpp
index 03dd1cd702d17..d69f12e7c0a7c 100644
--- a/llvm/lib/Target/AArch64/AArch64LowerHomogeneousPrologEpilog.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LowerHomogeneousPrologEpilog.cpp
@@ -483,16 +483,17 @@ bool AArch64LowerHomogeneousPE::lowerEpilog(
assert(MI.getOpcode() == AArch64::HOM_Epilog);
auto Return = NextMBBI;
+ MachineInstr *HelperCall = nullptr;
if (shouldUseFrameHelper(MBB, NextMBBI, Regs, FrameHelperType::EpilogTail)) {
// When MBB ends with a return, emit a tail-call to the epilog helper
auto *EpilogTailHelper =
getOrCreateFrameHelper(M, MMI, Regs, FrameHelperType::EpilogTail);
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::TCRETURNdi))
- .addGlobalAddress(EpilogTailHelper)
- .addImm(0)
- .setMIFlag(MachineInstr::FrameDestroy)
- .copyImplicitOps(MI)
- .copyImplicitOps(*Return);
+ HelperCall = BuildMI(MBB, MBBI, DL, TII->get(AArch64::TCRETURNdi))
+ .addGlobalAddress(EpilogTailHelper)
+ .addImm(0)
+ .setMIFlag(MachineInstr::FrameDestroy)
+ .copyImplicitOps(MI)
+ .copyImplicitOps(*Return);
NextMBBI = std::next(Return);
Return->removeFromParent();
} else if (shouldUseFrameHelper(MBB, NextMBBI, Regs,
@@ -500,10 +501,10 @@ bool AArch64LowerHomogeneousPE::lowerEpilog(
// The default epilog helper case.
auto *EpilogHelper =
getOrCreateFrameHelper(M, MMI, Regs, FrameHelperType::Epilog);
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
- .addGlobalAddress(EpilogHelper)
- .setMIFlag(MachineInstr::FrameDestroy)
- .copyImplicitOps(MI);
+ HelperCall = BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
+ .addGlobalAddress(EpilogHelper)
+ .setMIFlag(MachineInstr::FrameDestroy)
+ .copyImplicitOps(MI);
} else {
// Fall back to no-helper.
for (int I = 0; I < Size - 2; I += 2)
@@ -512,6 +513,12 @@ bool AArch64LowerHomogeneousPE::lowerEpilog(
emitLoad(MF, MBB, MBBI, *TII, Regs[Size - 2], Regs[Size - 1], Size, true);
}
+ // Make sure all explicit definitions are preserved in the helper call;
+ // implicit ones are already handled by copyImplicitOps.
+ if (HelperCall)
+ for (auto &Def : MBBI->defs())
+ HelperCall->addRegisterDefined(Def.getReg(),
+ MF.getRegInfo().getTargetRegisterInfo());
MBBI->removeFromParent();
return true;
}
diff --git a/llvm/test/CodeGen/AArch64/arm64-homogeneous-prolog-epilog-tail-call.mir b/llvm/test/CodeGen/AArch64/arm64-homogeneous-prolog-epilog-tail-call.mir
new file mode 100644
index 0000000000000..8a09df4693118
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/arm64-homogeneous-prolog-epilog-tail-call.mir
@@ -0,0 +1,28 @@
+# RUN: llc -verify-machineinstrs -mtriple=arm64-applie-ios7.0 -start-before=aarch64-lower-homogeneous-prolog-epilog -homogeneous-prolog-epilog %s
+#
+# This test ensures defined registers are preserved after lowering homogeneous
+# epilog into helper calls. Without the fix, the verifier would complain about
+# X20 being used by use_x20 without being defined.
+--- |
+ define void @foo() {
+ entry:
+ ret void
+ }
+ declare void @use_x20()
+...
+---
+name: foo
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x0' }
+ - { reg: '$x20' }
+body: |
+ bb.0:
+ liveins: $x0, $x20, $lr, $x19, $x20
+ frame-setup HOM_Prolog $lr, $fp, $x19, $x20, 16
+ $sp = frame-setup SUBXri $sp, 32, 0
+ bb.1:
+ $sp = frame-destroy ADDXri $sp, 32, 0
+ $lr, $fp, $x19, $x20 = frame-destroy HOM_Epilog
+ TCRETURNdi @use_x20, 0, csr_aarch64_aapcs, implicit $sp, implicit $x20
|
|
Thanks for the fix! |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/55/builds/21168 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/169/builds/17824 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/85/builds/16494 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/164/builds/16458 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/24/builds/15465 Here is the relevant piece of the build log for the reference |
The test introduced in #171118 has `llc` inadvertently producing an output into the same dir as the test file itself. Most build bots don't clean up the local git repo, which is assumed to not be written by build + test, and patch on top (for build performance reasons), which means the produced output from the aforementioned PR is treated as a test from here onwards, by all bots. Since it's missing `RUN` lines, we get errors, for example https://lab.llvm.org/buildbot/#/builders/108/builds/20674 This patch fixes the `llc` line and also removes the `.s`. This avoids all bot maintainers go restart their bots. Then, the cleanup is removed in #171256.
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/25/builds/13909 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/52/builds/13439 Here is the relevant piece of the build log for the reference |
…ring (llvm#171118) The lowering for HOM_Epilog did not transfer explicit register defs from the pseudo-instruction to the generated helper calls. MachineVerifier would complain if a following tail call uses one of the restored CSRs. This scenario occurs in code generated by the Swift compiler, where X20 is used to pass swiftself. This patch fixes the issue by adding the missing defs back to the helper call as implicit defs.
The test introduced in llvm#171118 has `llc` inadvertently producing an output into the same dir as the test file itself. Most build bots don't clean up the local git repo, which is assumed to not be written by build + test, and patch on top (for build performance reasons), which means the produced output from the aforementioned PR is treated as a test from here onwards, by all bots. Since it's missing `RUN` lines, we get errors, for example https://lab.llvm.org/buildbot/#/builders/108/builds/20674 This patch fixes the `llc` line and also removes the `.s`. This avoids all bot maintainers go restart their bots. Then, the cleanup is removed in llvm#171256.
The lowering for HOM_Epilog did not transfer explicit register defs from the pseudo-instruction to the generated helper calls. MachineVerifier would complain if a following tail call uses one of the restored CSRs. This scenario occurs in code generated by the Swift compiler, where X20 is used to pass swiftself.
This patch fixes the issue by adding the missing defs back to the helper call as implicit defs.