[PATCH] D130676: [AArch64] Treat x18 as callee-saved in functions with Windows calling convention on Darwin

Vladislav Dzhidzhoev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 27 17:37:43 PDT 2022


dzhidzhoev created this revision.
dzhidzhoev added reviewers: mstorsjo, efriedma, t.p.northover, sdesmalen, MatzeB, arsenm.
Herald added subscribers: hiraditya, kristof.beyls.
Herald added a project: All.
dzhidzhoev requested review of this revision.
Herald added subscribers: llvm-commits, wdng.
Herald added a project: LLVM.

rGcf97e0ec42b8 <https://reviews.llvm.org/rGcf97e0ec42b800ade5a18401a35ada96f355693f> makes $x18 to be treated as callee-saved in functions with
Windows calling convention on non-Windows OSes.

Here we mark $x18 as callee-saved for functions with Windows calling
convention on Darwin, as well as on other non-Windows platforms, in
order to prevent some miscompilations (like miscompilation of
win64cc-darwin-backup-x18.ll).

Since getCalleeSavedRegs doesn't return x18 in list of callee-saved
registers, assignCalleeSavedSpillSlots and determineCalleeSaves 
consider different sets of registers as callee-saved. It causes an
error:

  Assertion failed: ((!HasCalleeSavedStackSize || getCalleeSavedStackSize() == Size) && "Invalid size calculated for callee saves"), function getCalleeSavedStackSize, file 
  AArch64MachineFunctionInfo.h, line 292.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130676

Files:
  llvm/lib/Target/AArch64/AArch64CallingConvention.td
  llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
  llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
  llvm/test/CodeGen/AArch64/win64cc-darwin-backup-x18.ll


Index: llvm/test/CodeGen/AArch64/win64cc-darwin-backup-x18.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/win64cc-darwin-backup-x18.ll
@@ -0,0 +1,31 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+
+;; Testing that x18 is backed up and restored, and that x29 (if used) still
+;; points to the x29,x30 pair on the stack.
+
+; RUN: llc < %s -mtriple=arm64-apple-darwin | FileCheck %s
+; RUN: llc < %s -mtriple=arm64-apple-darwin -mattr=+reserve-x18 | FileCheck %s
+
+declare dso_local void @other()
+
+define win64cc void @func(i32 noundef %0) #0 {
+; CHECK-LABEL: func:
+; CHECK:         ; %bb.0: ; %entry
+; CHECK-NEXT:    str x18, [sp, #-32]! ; 8-byte Folded Spill
+; CHECK-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
+; CHECK:         ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
+; CHECK-NEXT:    ldr x18, [sp], #32 ; 8-byte Folded Reload
+; CHECK-NEXT:    ret
+entry:
+  %al = alloca i32, align 4
+  store i32 %0, ptr %al, align 4
+  tail call void @other()
+  ret void
+}
+
+define i32 @main() {
+  call win64cc void @func(i32 noundef 17)
+  ret i32 0
+}
+
+attributes #0 = { nounwind }
Index: llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -135,6 +135,8 @@
     return CSR_Darwin_AArch64_AAPCS_SwiftTail_SaveList;
   if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
     return CSR_Darwin_AArch64_RT_MostRegs_SaveList;
+  if (MF->getFunction().getCallingConv() == CallingConv::Win64)
+    return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
   return CSR_Darwin_AArch64_AAPCS_SaveList;
 }
 
Index: llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2522,8 +2522,8 @@
   (void)CC;
   // MachO's compact unwind format relies on all registers being stored in
   // pairs.
-  assert((!produceCompactUnwindFrame(MF) ||
-          CC == CallingConv::PreserveMost || CC == CallingConv::CXX_FAST_TLS ||
+  assert((!produceCompactUnwindFrame(MF) || CC == CallingConv::PreserveMost ||
+          CC == CallingConv::CXX_FAST_TLS || CC == CallingConv::Win64 ||
           (Count & 1) == 0) &&
          "Odd number of callee-saved regs to spill!");
   int ByteOffset = AFI->getCalleeSavedStackSize();
@@ -2608,8 +2608,8 @@
 
     // MachO's compact unwind format relies on all registers being stored in
     // adjacent register pairs.
-    assert((!produceCompactUnwindFrame(MF) ||
-            CC == CallingConv::PreserveMost || CC == CallingConv::CXX_FAST_TLS ||
+    assert((!produceCompactUnwindFrame(MF) || CC == CallingConv::PreserveMost ||
+            CC == CallingConv::CXX_FAST_TLS || CC == CallingConv::Win64 ||
             (RPI.isPaired() &&
              ((RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP) ||
               RPI.Reg1 + 1 == RPI.Reg2))) &&
Index: llvm/lib/Target/AArch64/AArch64CallingConvention.td
===================================================================
--- llvm/lib/Target/AArch64/AArch64CallingConvention.td
+++ llvm/lib/Target/AArch64/AArch64CallingConvention.td
@@ -444,6 +444,15 @@
 def CSR_Darwin_AArch64_AAVPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21,
                                                  X22, X23, X24, X25, X26, X27,
                                                  X28, (sequence "Q%u", 8, 23))>;
+
+// For Windows calling convention on a non-windows OS, where X18 is treated
+// as reserved, back up X18 when entering non-windows code (marked with the
+// Windows calling convention) and restore when returning regardless of
+// whether the individual function uses it - it might call other functions
+// that clobber it.
+def CSR_Darwin_AArch64_AAPCS_Win64
+    : CalleeSavedRegs<(add CSR_Darwin_AArch64_AAPCS, X18)>;
+
 def CSR_Darwin_AArch64_AAPCS_ThisReturn
     : CalleeSavedRegs<(add CSR_Darwin_AArch64_AAPCS, X0)>;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D130676.448218.patch
Type: text/x-patch
Size: 4180 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220728/72e169f8/attachment.bin>


More information about the llvm-commits mailing list