[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