[llvm] a90228b - [AArch64][Windows] Fix the slot offset of the swift async context register.

Hiroshi Yamauchi via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 27 12:33:03 PDT 2023


Author: Hiroshi Yamauchi
Date: 2023-07-27T12:32:43-07:00
New Revision: a90228b911d3c70833a4abe63b81e02a7a8da1f5

URL: https://github.com/llvm/llvm-project/commit/a90228b911d3c70833a4abe63b81e02a7a8da1f5
DIFF: https://github.com/llvm/llvm-project/commit/a90228b911d3c70833a4abe63b81e02a7a8da1f5.diff

LOG: [AArch64][Windows] Fix the slot offset of the swift async context register.

This fixes a code gen issue where savings the swift async context
register (x22) accidentally overwrites the saved value of another
callee-saved register, corrupts its value and causes a crash.

Differential Revision: https://reviews.llvm.org/D156391

Added: 
    llvm/test/CodeGen/AArch64/swift-async-context-slot-offset-win.ll

Modified: 
    llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index d66800664c0ca6..a623339af65f2f 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2699,7 +2699,8 @@ static void computeCalleeSaveRegisterPairs(
     // Swift's async context is directly before FP, so allocate an extra
     // 8 bytes for it.
     if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
-        RPI.Reg2 == AArch64::FP)
+        ((!IsWindows && RPI.Reg2 == AArch64::FP) ||
+         (IsWindows && RPI.Reg2 == AArch64::LR)))
       ByteOffset += StackFillDir * 8;
 
     assert(!(RPI.isScalable() && RPI.isPaired()) &&
@@ -2728,7 +2729,8 @@ static void computeCalleeSaveRegisterPairs(
     // The FP, LR pair goes 8 bytes into our expanded 24-byte slot so that the
     // Swift context can directly precede FP.
     if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
-        RPI.Reg2 == AArch64::FP)
+        ((!IsWindows && RPI.Reg2 == AArch64::FP) ||
+         (IsWindows && RPI.Reg2 == AArch64::LR)))
       Offset += 8;
     RPI.Offset = Offset / Scale;
 

diff  --git a/llvm/test/CodeGen/AArch64/swift-async-context-slot-offset-win.ll b/llvm/test/CodeGen/AArch64/swift-async-context-slot-offset-win.ll
new file mode 100644
index 00000000000000..86e459a4af7172
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/swift-async-context-slot-offset-win.ll
@@ -0,0 +1,32 @@
+; RUN: llc -mtriple aarch64-unknown-windows-msvc -filetype asm %s -o - | FileCheck %s
+
+; Check that the slot offset of the async context (x22) doesn't
+; conflict with that of another callee-saved register (x21 here) and
+; saving it won't overwrite the saved value of the callee-saved
+; register.
+;
+; CHECK:        sub     sp, sp, #64
+; CHECK:        str     x19, [sp, #16]
+; CHECK:        str     x21, [sp, #24]
+; CHECK-NOT:    stp     x29, x30, [sp, #32]
+; CHECK:        stp     x29, x30, [sp, #40]
+; CHECK-NOT:    str     x22, [sp, #24]
+; CHECK:        str     x22, [sp, #32]
+
+declare ptr @llvm.swift.async.context.addr()
+declare swiftcc i64 @foo(i64 %0, i64 %1)
+declare swifttailcc void @tail(ptr swiftasync %0, ptr swiftself dereferenceable(8) %1, i64 %2)
+define internal swifttailcc void @test(ptr swiftasync %0, ptr swiftself %1, i64 %2) {
+entry:
+  %3 = load ptr, ptr %0, align 8
+  %4 = call ptr @llvm.swift.async.context.addr()
+  store ptr %3, ptr %4, align 8
+  %5 = call swiftcc i64 @foo(i64 %2, i64 %2)
+  %6 = call swiftcc i64 @foo(i64 %2, i64 %5)
+  %7 = call swiftcc i64 @foo(i64 %5, i64 %2)
+  %8 = call swiftcc i64 @foo(i64 %7, i64 %6)
+  %9 = call swiftcc i64 @foo(i64 %2, i64 %8)
+  %10 = call ptr @llvm.swift.async.context.addr()
+  musttail call swifttailcc void @tail(ptr swiftasync %10, ptr swiftself %1, i64 %2)
+  ret void
+}


        


More information about the llvm-commits mailing list