[llvm-branch-commits] [llvm] release/23.x: [AArch64][GISel][FastISel] Fix Windows "sret inreg". (#225190) (PR #225548)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Sep 22 15:55:44 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: llvmbot

<details>
<summary>Changes</summary>

Backport 8890be35705834c5af8e21424d7900639be03180

Requested by: @<!-- -->efriedma-quic

---

Patch is 33.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/225548.diff


4 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64FastISel.cpp (+3) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp (+8-3) 
- (modified) llvm/test/CodeGen/AArch64/arm64-windows-calls.ll (+556-96) 
- (modified) llvm/test/CodeGen/AArch64/arm64-windows-tailcall.ll (+49-13) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index b6deb703893fdb..caa0983ca5fb15 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -3851,6 +3851,9 @@ bool AArch64FastISel::selectRet(const Instruction *I) {
   if (!FuncInfo.CanLowerReturn)
     return false;
 
+  if (FuncInfo.MF->getInfo<AArch64FunctionInfo>()->getSRetReturnReg())
+    return false;
+
   if (F.isVarArg())
     return false;
 
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
index b0a409d153fd21..76439176474749 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -715,9 +715,14 @@ bool AArch64CallLowering::lowerFormalArguments(
       F.getCallingConv() == CallingConv::ARM64EC_Thunk_X64)
     return false;
 
-  bool IsWin64 =
-      Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg()) &&
-      !Subtarget.isWindowsArm64EC();
+  bool IsWin64 = Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg());
+
+  // If an argument is marked "sret" and "inreg", it must be returned in x0.
+  // Bail for now.
+  if (IsWin64 && any_of(F.args(), [](const Argument &A) {
+        return A.hasStructRetAttr() && A.hasInRegAttr();
+      }))
+    return false;
 
   SmallVector<ArgInfo, 8> SplitArgs;
   SmallVector<std::pair<Register, Register>> BoolArgs;
diff --git a/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll b/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll
index 41f00a6c41b3b9..3305a6dce3029e 100644
--- a/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll
@@ -1,15 +1,95 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; FIXME: Add tests for global-isel/fast-isel.
 
-; RUN: llc < %s -mtriple=arm64-windows | FileCheck %s
+; RUN: llc < %s -mtriple=arm64-windows | FileCheck -check-prefixes=CHECK,CHECK-NOTGISEL,CHECK-SD %s
+; RUN: llc < %s -mtriple=arm64ec-windows-msvc -arm64ec-generate-thunks=false | FileCheck -check-prefixes=CHECK,CHECK-NOTGISEL,CHECK-EC-SD %s
+; RUN: llc < %s -mtriple=arm64-windows -fast-isel=0 -global-isel=1 -global-isel-abort=0 | FileCheck -check-prefixes=CHECK,CHECK-GI %s
+; RUN: llc < %s -mtriple=arm64-windows -fast-isel=1 -global-isel=0 | FileCheck -check-prefixes=CHECK,CHECK-NOTGISEL,CHECK-FAST %s
+; RUN: llc < %s -mtriple=arm64ec-windows-msvc -arm64ec-generate-thunks=false -fast-isel=0 -global-isel=1 -global-isel-abort=0 | FileCheck -check-prefixes=CHECK,CHECK-EC-GI %s
 
 ; Returns <= 8 bytes should be in X0.
 %struct.S1 = type { i32, i32 }
-define dso_local i64 @"?f1"() {
+define dso_local i64 @f1() {
+; CHECK-SD-LABEL: f1:
+; CHECK-SD:       .seh_proc f1
+; CHECK-SD-NEXT:  // %bb.0: // %entry
+; CHECK-SD-NEXT:    sub sp, sp, #16
+; CHECK-SD-NEXT:    .seh_stackalloc 16
+; CHECK-SD-NEXT:    .seh_endprologue
+; CHECK-SD-NEXT:    mov x0, xzr
+; CHECK-SD-NEXT:    str xzr, [sp, #8]
+; CHECK-SD-NEXT:    .seh_startepilogue
+; CHECK-SD-NEXT:    add sp, sp, #16
+; CHECK-SD-NEXT:    .seh_stackalloc 16
+; CHECK-SD-NEXT:    .seh_endepilogue
+; CHECK-SD-NEXT:    ret
+; CHECK-SD-NEXT:    .seh_endfunclet
+; CHECK-SD-NEXT:    .seh_endproc
+;
+; CHECK-EC-SD-LABEL: f1:
+; CHECK-EC-SD:       .seh_proc f1
+; CHECK-EC-SD-NEXT:  // %bb.0: // %entry
+; CHECK-EC-SD-NEXT:    sub sp, sp, #16
+; CHECK-EC-SD-NEXT:    .seh_stackalloc 16
+; CHECK-EC-SD-NEXT:    .seh_endprologue
+; CHECK-EC-SD-NEXT:    mov x0, xzr
+; CHECK-EC-SD-NEXT:    str xzr, [sp, #8]
+; CHECK-EC-SD-NEXT:    .seh_startepilogue
+; CHECK-EC-SD-NEXT:    add sp, sp, #16
+; CHECK-EC-SD-NEXT:    .seh_stackalloc 16
+; CHECK-EC-SD-NEXT:    .seh_endepilogue
+; CHECK-EC-SD-NEXT:    ret
+; CHECK-EC-SD-NEXT:    .seh_endfunclet
+; CHECK-EC-SD-NEXT:    .seh_endproc
+;
+; CHECK-GI-LABEL: f1:
+; CHECK-GI:       .seh_proc f1
+; CHECK-GI-NEXT:  // %bb.0: // %entry
+; CHECK-GI-NEXT:    sub sp, sp, #16
+; CHECK-GI-NEXT:    .seh_stackalloc 16
+; CHECK-GI-NEXT:    .seh_endprologue
+; CHECK-GI-NEXT:    str xzr, [sp, #8]
+; CHECK-GI-NEXT:    mov x0, xzr
+; CHECK-GI-NEXT:    .seh_startepilogue
+; CHECK-GI-NEXT:    add sp, sp, #16
+; CHECK-GI-NEXT:    .seh_stackalloc 16
+; CHECK-GI-NEXT:    .seh_endepilogue
+; CHECK-GI-NEXT:    ret
+; CHECK-GI-NEXT:    .seh_endfunclet
+; CHECK-GI-NEXT:    .seh_endproc
+;
+; CHECK-FAST-LABEL: f1:
+; CHECK-FAST:       .seh_proc f1
+; CHECK-FAST-NEXT:  // %bb.0: // %entry
+; CHECK-FAST-NEXT:    sub sp, sp, #16
+; CHECK-FAST-NEXT:    .seh_stackalloc 16
+; CHECK-FAST-NEXT:    .seh_endprologue
+; CHECK-FAST-NEXT:    str xzr, [sp, #8]
+; CHECK-FAST-NEXT:    ldr x0, [sp, #8]
+; CHECK-FAST-NEXT:    .seh_startepilogue
+; CHECK-FAST-NEXT:    add sp, sp, #16
+; CHECK-FAST-NEXT:    .seh_stackalloc 16
+; CHECK-FAST-NEXT:    .seh_endepilogue
+; CHECK-FAST-NEXT:    ret
+; CHECK-FAST-NEXT:    .seh_endfunclet
+; CHECK-FAST-NEXT:    .seh_endproc
+;
+; CHECK-EC-GI-LABEL: f1:
+; CHECK-EC-GI:       .seh_proc f1
+; CHECK-EC-GI-NEXT:  // %bb.0: // %entry
+; CHECK-EC-GI-NEXT:    sub sp, sp, #16
+; CHECK-EC-GI-NEXT:    .seh_stackalloc 16
+; CHECK-EC-GI-NEXT:    .seh_endprologue
+; CHECK-EC-GI-NEXT:    str xzr, [sp, #8]
+; CHECK-EC-GI-NEXT:    mov x0, xzr
+; CHECK-EC-GI-NEXT:    .seh_startepilogue
+; CHECK-EC-GI-NEXT:    add sp, sp, #16
+; CHECK-EC-GI-NEXT:    .seh_stackalloc 16
+; CHECK-EC-GI-NEXT:    .seh_endepilogue
+; CHECK-EC-GI-NEXT:    ret
+; CHECK-EC-GI-NEXT:    .seh_endfunclet
+; CHECK-EC-GI-NEXT:    .seh_endproc
+
 entry:
-; CHECK-LABEL: f1
-; CHECK-DAG: str xzr, [sp, #8]
-; CHECK-DAG: mov x0, xzr
 
   %retval = alloca %struct.S1, align 4
   store i32 0, ptr %retval, align 4
@@ -21,18 +101,60 @@ entry:
 
 ; Returns <= 16 bytes should be in X0/X1.
 %struct.S2 = type { i32, i32, i32, i32 }
-define dso_local [2 x i64] @"?f2"() {
+define dso_local [2 x i64] @f2() {
+; CHECK-NOTGISEL-LABEL: f2:
+; CHECK-NOTGISEL:       .seh_proc f2
+; CHECK-NOTGISEL-NEXT:  // %bb.0: // %entry
+; CHECK-NOTGISEL-NEXT:    sub sp, sp, #16
+; CHECK-NOTGISEL-NEXT:    .seh_stackalloc 16
+; CHECK-NOTGISEL-NEXT:    .seh_endprologue
+; CHECK-NOTGISEL-NEXT:    mov x0, xzr
+; CHECK-NOTGISEL-NEXT:    mov x1, xzr
+; CHECK-NOTGISEL-NEXT:    stp xzr, xzr, [sp]
+; CHECK-NOTGISEL-NEXT:    .seh_startepilogue
+; CHECK-NOTGISEL-NEXT:    add sp, sp, #16
+; CHECK-NOTGISEL-NEXT:    .seh_stackalloc 16
+; CHECK-NOTGISEL-NEXT:    .seh_endepilogue
+; CHECK-NOTGISEL-NEXT:    ret
+; CHECK-NOTGISEL-NEXT:    .seh_endfunclet
+; CHECK-NOTGISEL-NEXT:    .seh_endproc
+;
+; CHECK-GI-LABEL: f2:
+; CHECK-GI:       .seh_proc f2
+; CHECK-GI-NEXT:  // %bb.0: // %entry
+; CHECK-GI-NEXT:    sub sp, sp, #16
+; CHECK-GI-NEXT:    .seh_stackalloc 16
+; CHECK-GI-NEXT:    .seh_endprologue
+; CHECK-GI-NEXT:    stp xzr, xzr, [sp]
+; CHECK-GI-NEXT:    mov x0, xzr
+; CHECK-GI-NEXT:    mov x1, xzr
+; CHECK-GI-NEXT:    .seh_startepilogue
+; CHECK-GI-NEXT:    add sp, sp, #16
+; CHECK-GI-NEXT:    .seh_stackalloc 16
+; CHECK-GI-NEXT:    .seh_endepilogue
+; CHECK-GI-NEXT:    ret
+; CHECK-GI-NEXT:    .seh_endfunclet
+; CHECK-GI-NEXT:    .seh_endproc
+;
+; CHECK-EC-GI-LABEL: f2:
+; CHECK-EC-GI:       .seh_proc f2
+; CHECK-EC-GI-NEXT:  // %bb.0: // %entry
+; CHECK-EC-GI-NEXT:    sub sp, sp, #16
+; CHECK-EC-GI-NEXT:    .seh_stackalloc 16
+; CHECK-EC-GI-NEXT:    .seh_endprologue
+; CHECK-EC-GI-NEXT:    stp xzr, xzr, [sp]
+; CHECK-EC-GI-NEXT:    mov x0, xzr
+; CHECK-EC-GI-NEXT:    mov x1, xzr
+; CHECK-EC-GI-NEXT:    .seh_startepilogue
+; CHECK-EC-GI-NEXT:    add sp, sp, #16
+; CHECK-EC-GI-NEXT:    .seh_stackalloc 16
+; CHECK-EC-GI-NEXT:    .seh_endepilogue
+; CHECK-EC-GI-NEXT:    ret
+; CHECK-EC-GI-NEXT:    .seh_endfunclet
+; CHECK-EC-GI-NEXT:    .seh_endproc
+
 entry:
 ; FIXME: Missed optimization, the entire SP push/pop could be removed
-; CHECK-LABEL: f2
-; CHECK:         sub     sp, sp, #16
-; CHECK-NEXT:    .seh_stackalloc 16
-; CHECK-NEXT:    .seh_endprologue
-; CHECK-DAG:     stp     xzr, xzr, [sp]
-; CHECK-DAG:     mov     x0, xzr
-; CHECK-DAG:     mov     x1, xzr
-; CHECK:         .seh_startepilogue
-; CHECK-NEXT:    add     sp, sp, #16
 
   %retval = alloca %struct.S2, align 4
   store i32 0, ptr %retval, align 4
@@ -48,11 +170,13 @@ entry:
 
 ; Arguments > 16 bytes should be passed in X8.
 %struct.S3 = type { i32, i32, i32, i32, i32 }
-define dso_local void @"?f3"(ptr noalias sret(%struct.S3) %agg.result) {
+define dso_local void @f3(ptr noalias sret(%struct.S3) %agg.result) {
+; CHECK-LABEL: f3:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    stp xzr, xzr, [x8]
+; CHECK-NEXT:    str wzr, [x8, #16]
+; CHECK-NEXT:    ret
 entry:
-; CHECK-LABEL: f3
-; CHECK: stp xzr, xzr, [x8]
-; CHECK: str wzr, [x8, #16]
 
   store i32 0, ptr %agg.result, align 4
   %b = getelementptr inbounds %struct.S3, ptr %agg.result, i32 0, i32 1
@@ -69,11 +193,13 @@ entry:
 ; InReg arguments to non-instance methods must be passed in X0 and returns in
 ; X0.
 %class.B = type { i32 }
-define dso_local void @"?f4"(ptr inreg noalias nocapture sret(%class.B) %agg.result) {
+define dso_local void @f4(ptr inreg noalias nocapture sret(%class.B) %agg.result) {
+; CHECK-LABEL: f4:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    mov w8, #1 // =0x1
+; CHECK-NEXT:    str w8, [x0]
+; CHECK-NEXT:    ret
 entry:
-; CHECK-LABEL: f4
-; CHECK: mov w8, #1
-; CHECK: str w8, [x0]
   store i32 1, ptr %agg.result, align 4
   ret void
 }
@@ -82,11 +208,24 @@ entry:
 %class.C = type { i8 }
 %class.A = type { i8 }
 
-define dso_local void @"?inst at C"(ptr %this, ptr inreg noalias sret(%class.A) %agg.result) {
+define dso_local void @inst(ptr %this, ptr inreg noalias sret(%class.A) %agg.result) {
+; CHECK-LABEL: inst:
+; CHECK:       .seh_proc inst
+; CHECK-NEXT:  // %bb.0: // %entry
+; CHECK-NEXT:    sub sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    mov x8, x0
+; CHECK-NEXT:    mov x0, x1
+; CHECK-NEXT:    str x8, [sp, #8]
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    add sp, sp, #16
+; CHECK-NEXT:    .seh_stackalloc 16
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    ret
+; CHECK-NEXT:    .seh_endfunclet
+; CHECK-NEXT:    .seh_endproc
 entry:
-; CHECK-LABEL: inst at C
-; CHECK-DAG: mov x0, x1
-; CHECK-DAG: str x8, [sp, #8]
 
   %this.addr = alloca ptr, align 8
   store ptr %this, ptr %this.addr, align 8
@@ -140,28 +279,131 @@ define dso_local [2 x i64] @copy_notpod(ptr %x) {
 @Pod = external global %struct.Pod
 
 define void @call_copy_pod() {
-; CHECK-LABEL: call_copy_pod:
-; CHECK:       .seh_proc call_copy_pod
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    sub sp, sp, #16
-; CHECK-NEXT:    .seh_stackalloc 16
-; CHECK-NEXT:    stp x19, x30, [sp] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_lrpair x19, 0
-; CHECK-NEXT:    .seh_endprologue
-; CHECK-NEXT:    adrp x19, Pod
-; CHECK-NEXT:    add x19, x19, :lo12:Pod
-; CHECK-NEXT:    mov x0, x19
-; CHECK-NEXT:    bl copy_pod
-; CHECK-NEXT:    stp d0, d1, [x19]
-; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    ldp x19, x30, [sp] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_lrpair x19, 0
-; CHECK-NEXT:    add sp, sp, #16
-; CHECK-NEXT:    .seh_stackalloc 16
-; CHECK-NEXT:    .seh_endepilogue
-; CHECK-NEXT:    ret
-; CHECK-NEXT:    .seh_endfunclet
-; CHECK-NEXT:    .seh_endproc
+; CHECK-SD-LABEL: call_copy_pod:
+; CHECK-SD:       .seh_proc call_copy_pod
+; CHECK-SD-NEXT:  // %bb.0:
+; CHECK-SD-NEXT:    sub sp, sp, #16
+; CHECK-SD-NEXT:    .seh_stackalloc 16
+; CHECK-SD-NEXT:    stp x19, x30, [sp] // 16-byte Folded Spill
+; CHECK-SD-NEXT:    .seh_save_lrpair x19, 0
+; CHECK-SD-NEXT:    .seh_endprologue
+; CHECK-SD-NEXT:    adrp x19, Pod
+; CHECK-SD-NEXT:    add x19, x19, :lo12:Pod
+; CHECK-SD-NEXT:    mov x0, x19
+; CHECK-SD-NEXT:    bl copy_pod
+; CHECK-SD-NEXT:    stp d0, d1, [x19]
+; CHECK-SD-NEXT:    .seh_startepilogue
+; CHECK-SD-NEXT:    ldp x19, x30, [sp] // 16-byte Folded Reload
+; CHECK-SD-NEXT:    .seh_save_lrpair x19, 0
+; CHECK-SD-NEXT:    add sp, sp, #16
+; CHECK-SD-NEXT:    .seh_stackalloc 16
+; CHECK-SD-NEXT:    .seh_endepilogue
+; CHECK-SD-NEXT:    ret
+; CHECK-SD-NEXT:    .seh_endfunclet
+; CHECK-SD-NEXT:    .seh_endproc
+;
+; CHECK-EC-SD-LABEL: call_copy_pod:
+; CHECK-EC-SD:       .seh_proc call_copy_pod
+; CHECK-EC-SD-NEXT:  // %bb.0:
+; CHECK-EC-SD-NEXT:    sub sp, sp, #16
+; CHECK-EC-SD-NEXT:    .seh_stackalloc 16
+; CHECK-EC-SD-NEXT:    stp x19, x30, [sp] // 16-byte Folded Spill
+; CHECK-EC-SD-NEXT:    .seh_save_lrpair x19, 0
+; CHECK-EC-SD-NEXT:    .seh_endprologue
+; CHECK-EC-SD-NEXT:    adrp x19, Pod
+; CHECK-EC-SD-NEXT:    add x19, x19, :lo12:Pod
+; CHECK-EC-SD-NEXT:    mov x0, x19
+; CHECK-EC-SD-NEXT:    .weak_anti_dep copy_pod
+; CHECK-EC-SD-NEXT:  copy_pod = "#copy_pod"
+; CHECK-EC-SD-NEXT:    .weak_anti_dep "#copy_pod"
+; CHECK-EC-SD-NEXT:  "#copy_pod" = copy_pod
+; CHECK-EC-SD-NEXT:    bl "#copy_pod"
+; CHECK-EC-SD-NEXT:    stp d0, d1, [x19]
+; CHECK-EC-SD-NEXT:    .seh_startepilogue
+; CHECK-EC-SD-NEXT:    ldp x19, x30, [sp] // 16-byte Folded Reload
+; CHECK-EC-SD-NEXT:    .seh_save_lrpair x19, 0
+; CHECK-EC-SD-NEXT:    add sp, sp, #16
+; CHECK-EC-SD-NEXT:    .seh_stackalloc 16
+; CHECK-EC-SD-NEXT:    .seh_endepilogue
+; CHECK-EC-SD-NEXT:    ret
+; CHECK-EC-SD-NEXT:    .seh_endfunclet
+; CHECK-EC-SD-NEXT:    .seh_endproc
+;
+; CHECK-GI-LABEL: call_copy_pod:
+; CHECK-GI:       .seh_proc call_copy_pod
+; CHECK-GI-NEXT:  // %bb.0:
+; CHECK-GI-NEXT:    stp x19, x20, [sp, #-32]! // 16-byte Folded Spill
+; CHECK-GI-NEXT:    .seh_save_regp_x x19, 32
+; CHECK-GI-NEXT:    str x30, [sp, #16] // 8-byte Spill
+; CHECK-GI-NEXT:    .seh_save_reg x30, 16
+; CHECK-GI-NEXT:    .seh_endprologue
+; CHECK-GI-NEXT:    adrp x19, Pod
+; CHECK-GI-NEXT:    add x19, x19, :lo12:Pod
+; CHECK-GI-NEXT:    adrp x20, Pod
+; CHECK-GI-NEXT:    mov x0, x19
+; CHECK-GI-NEXT:    bl copy_pod
+; CHECK-GI-NEXT:    str d0, [x20, :lo12:Pod]
+; CHECK-GI-NEXT:    str d1, [x19, #8]
+; CHECK-GI-NEXT:    .seh_startepilogue
+; CHECK-GI-NEXT:    ldr x30, [sp, #16] // 8-byte Reload
+; CHECK-GI-NEXT:    .seh_save_reg x30, 16
+; CHECK-GI-NEXT:    ldp x19, x20, [sp], #32 // 16-byte Folded Reload
+; CHECK-GI-NEXT:    .seh_save_regp_x x19, 32
+; CHECK-GI-NEXT:    .seh_endepilogue
+; CHECK-GI-NEXT:    ret
+; CHECK-GI-NEXT:    .seh_endfunclet
+; CHECK-GI-NEXT:    .seh_endproc
+;
+; CHECK-FAST-LABEL: call_copy_pod:
+; CHECK-FAST:       .seh_proc call_copy_pod
+; CHECK-FAST-NEXT:  // %bb.0:
+; CHECK-FAST-NEXT:    sub sp, sp, #16
+; CHECK-FAST-NEXT:    .seh_stackalloc 16
+; CHECK-FAST-NEXT:    stp x19, x30, [sp] // 16-byte Folded Spill
+; CHECK-FAST-NEXT:    .seh_save_lrpair x19, 0
+; CHECK-FAST-NEXT:    .seh_endprologue
+; CHECK-FAST-NEXT:    adrp x19, Pod
+; CHECK-FAST-NEXT:    add x19, x19, :lo12:Pod
+; CHECK-FAST-NEXT:    mov x0, x19
+; CHECK-FAST-NEXT:    bl copy_pod
+; CHECK-FAST-NEXT:    stp d0, d1, [x19]
+; CHECK-FAST-NEXT:    .seh_startepilogue
+; CHECK-FAST-NEXT:    ldp x19, x30, [sp] // 16-byte Folded Reload
+; CHECK-FAST-NEXT:    .seh_save_lrpair x19, 0
+; CHECK-FAST-NEXT:    add sp, sp, #16
+; CHECK-FAST-NEXT:    .seh_stackalloc 16
+; CHECK-FAST-NEXT:    .seh_endepilogue
+; CHECK-FAST-NEXT:    ret
+; CHECK-FAST-NEXT:    .seh_endfunclet
+; CHECK-FAST-NEXT:    .seh_endproc
+;
+; CHECK-EC-GI-LABEL: call_copy_pod:
+; CHECK-EC-GI:       .seh_proc call_copy_pod
+; CHECK-EC-GI-NEXT:  // %bb.0:
+; CHECK-EC-GI-NEXT:    sub sp, sp, #16
+; CHECK-EC-GI-NEXT:    .seh_stackalloc 16
+; CHECK-EC-GI-NEXT:    stp x19, x30, [sp] // 16-byte Folded Spill
+; CHECK-EC-GI-NEXT:    .seh_save_lrpair x19, 0
+; CHECK-EC-GI-NEXT:    .seh_endprologue
+; CHECK-EC-GI-NEXT:    adrp x19, Pod
+; CHECK-EC-GI-NEXT:    add x19, x19, :lo12:Pod
+; CHECK-EC-GI-NEXT:    mov x0, x19
+; CHECK-EC-GI-NEXT:    .weak_anti_dep copy_pod
+; CHECK-EC-GI-NEXT:  copy_pod = "#copy_pod"
+; CHECK-EC-GI-NEXT:    .weak_anti_dep "#copy_pod"
+; CHECK-EC-GI-NEXT:  "#copy_pod" = copy_pod
+; CHECK-EC-GI-NEXT:    bl "#copy_pod"
+; CHECK-EC-GI-NEXT:    stp d0, d1, [x19]
+; CHECK-EC-GI-NEXT:    .seh_startepilogue
+; CHECK-EC-GI-NEXT:    ldp x19, x30, [sp] // 16-byte Folded Reload
+; CHECK-EC-GI-NEXT:    .seh_save_lrpair x19, 0
+; CHECK-EC-GI-NEXT:    add sp, sp, #16
+; CHECK-EC-GI-NEXT:    .seh_stackalloc 16
+; CHECK-EC-GI-NEXT:    .seh_endepilogue
+; CHECK-EC-GI-NEXT:    ret
+; CHECK-EC-GI-NEXT:    .seh_endfunclet
+; CHECK-EC-GI-NEXT:    .seh_endproc
+
   %x = call %struct.Pod @copy_pod(ptr @Pod)
   store %struct.Pod %x, ptr @Pod
   ret void
@@ -170,30 +412,145 @@ define void @call_copy_pod() {
 @NotCXX14Aggregate = external global %struct.NotCXX14Aggregate
 
 define void @call_copy_notcxx14aggregate() {
-; CHECK-LABEL: call_copy_notcxx14aggregate:
-; CHECK:       .seh_proc call_copy_notcxx14aggregate
-; CHECK-NEXT:  // %bb.0:
-; CHECK-NEXT:    sub sp, sp, #32
-; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    stp x19, x30, [sp, #16] // 16-byte Folded Spill
-; CHECK-NEXT:    .seh_save_lrpair x19, 16
-; CHECK-NEXT:    .seh_endprologue
-; CHECK-NEXT:    adrp x19, NotCXX14Aggregate
-; CHECK-NEXT:    add x19, x19, :lo12:NotCXX14Aggregate
-; CHECK-NEXT:    mov x0, sp
-; CHECK-NEXT:    mov x1, x19
-; CHECK-NEXT:    bl copy_notcxx14aggregate
-; CHECK-NEXT:    ldp d0, d1, [sp]
-; CHECK-NEXT:    stp d0, d1, [x19]
-; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    ldp x19, x30, [sp, #16] // 16-byte Folded Reload
-; CHECK-NEXT:    .seh_save_lrpair x19, 16
-; CHECK-NEXT:    add sp, sp, #32
-; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    .seh_endepilogue
-; CHECK-NEXT:    ret
-; CHECK-NEXT:    .seh_endfunclet
-; CHECK-NEXT:    .seh_endproc
+; CHECK-SD-LABEL: call_copy_notcxx14aggregate:
+; CHECK-SD:       .seh_proc call_copy_notcxx14aggregate
+; CHECK-SD-NEXT:  // %bb.0:
+; CHECK-SD-NEXT:    sub sp, sp, #32
+; CHECK-SD-NEXT:    .seh_stackalloc 32
+; CHECK-SD-NEXT:    stp x19, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-SD-NEXT:    .seh_save_lrpair x19, 16
+; CHECK-SD-NEXT:    .seh_endprologue
+; CHECK-SD-NEXT:    adrp x19, NotCXX14Aggregate
+; CHECK-SD-NEXT:    add x19, x19, :lo12:NotCXX14Aggregate
+; CHECK-SD-NEXT:    mov x0, sp
+; CHECK-SD-NEXT:    mov x1, x19
+; CHECK-SD-NEXT:    bl copy_notcxx14aggregate
+; CHECK-SD-NEXT:    ldp d0, d1, [sp]
+; CHECK-SD-NEXT:    stp d0, d1, [x19]
+; CHECK-SD-NEXT:    .seh_startepilogue
+; CHECK-SD-NEXT:    ldp x19, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-SD-NEXT:    .seh_save_lrpair x19, 16
+; CHECK-SD-NEXT:    add sp, sp, #32
+; CHECK-SD-NEXT:    .seh_stackalloc 32
+; CHECK-SD-NEXT:    .seh_endepilogue
+; CHECK-SD-NEXT:    ret
+; CHECK-SD-NEXT:    .seh_endfunclet
+; CHECK-SD-NEXT:    .seh_endproc
+;
+; CHECK-EC-SD-LABEL: call_copy_notcxx14aggregate:
+; CHECK-EC-SD:       .seh_proc call_copy_notcxx14aggregate
+; CHECK-EC-SD-NEXT:  // %bb.0:
+; CHECK-EC-SD-NEXT:    sub sp, sp, #32
+; CHECK-EC-SD-NEXT:    .seh_stackalloc 32
+; CHECK-EC-SD-NEXT:    stp x19, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-EC-SD-NEXT:    .seh_save_lrpair x19, 16
+; CHECK-EC-SD-NEXT:    .seh_endprologue
+; CHECK-EC-SD-NEXT:    adrp x19, NotCXX14Aggregate
+; CHECK-EC-SD-NEXT:    add x19, x19, :lo12:NotCXX14Aggregate
+; CHECK-EC-SD-NEXT:    mov x0, sp
+; CHECK-EC-SD-NEXT:    mov x1, x19
+; CHECK-EC-SD-NEXT:    .weak_anti_dep copy_notcxx14aggregate
+; CHECK-EC-SD-NEXT:  copy_notcxx14aggregate = "#copy_notcxx14aggregate"
+; CHECK-EC-SD-NEXT:    .weak_anti_dep "#copy_notcxx14aggregate"
+; CHECK-EC-SD-NEXT:  "#copy_notcxx14aggregate" = copy_notcxx14aggregate
+; CHECK-EC-SD-NEXT:    bl "#copy_notcxx14aggregate"
+; CHECK-EC-SD-NEXT:    ldp d0, d1, [sp]
+; CHECK-EC-SD-NEXT:    stp d0, d1, [x19]
+; CHECK-EC-SD-NEXT:    .seh_startepilogue
+; CHECK-EC-SD-NEXT:    ldp x19, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-EC-SD-NEXT:    .seh_save_lrpair x19, 16
+; CHECK-EC-SD-NEXT:    add sp, sp, #32
+; CHECK-EC-SD-NEXT:    .seh_stackalloc 32
+; CHECK-EC-SD-NEXT:    .seh_endepilogue
+; CHECK-EC-SD-NEXT:    ret
+; CHECK-EC-SD-NEXT:    .seh_endfunclet
+; CHECK-EC-SD-NEXT:    .seh_endproc
+;
+; CHECK-GI-LABEL: call_copy_notcxx14aggregate:
+; CHECK-GI:       .seh_proc call_copy_notcxx14aggregate
+; CHECK-GI-NEXT:  // %bb.0:
+; CHECK-GI-NEXT:    sub sp, sp, #48
+; CHECK-GI-NEXT:    .seh_stackalloc 48
+; CHECK-GI-NEXT:    stp x19, x20, [sp, #16] // 16-byte Folded Spill
+; CHECK-GI-NEXT:    .seh_save_regp x19, 16
+; CHECK-GI-NEXT:    str x30, [sp, #32] /...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/225548


More information about the llvm-branch-commits mailing list