[llvm] [AArch64][GISel][FastISel] Fix Windows "sret inreg". (PR #225190)
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 12:46:17 PDT 2026
https://github.com/efriedma-quic updated https://github.com/llvm/llvm-project/pull/225190
>From 6334946555f5a23a91ffcc018187b604eeed2ba2 Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at qti.qualcomm.com>
Date: Mon, 21 Sep 2026 13:30:30 -0700
Subject: [PATCH 1/2] [AArch64][GISel][FastISel] Fix Windows "sret inreg".
5dc8aeb26d2896c65cbea0d3b87f090241444bb6 added a special case to
SelectionDAG ISel for "sret inreg" parameters: they are copied to x0 on
return. There was a review comment suggesting that GISel and FastISel
also needed fixes, but through some mixup the followup never happened.
Fixes #225060
---
llvm/lib/Target/AArch64/AArch64FastISel.cpp | 3 +
.../AArch64/GISel/AArch64CallLowering.cpp | 11 +-
.../CodeGen/AArch64/arm64-windows-calls.ll | 359 +++++++++++++-----
.../CodeGen/AArch64/arm64-windows-tailcall.ll | 62 ++-
4 files changed, 323 insertions(+), 112 deletions(-)
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 912ae1bca65334..d311226eec4e6b 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -768,9 +768,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..ced7e3acf6303a 100644
--- a/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll
@@ -1,15 +1,60 @@
; 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-SDAG %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=arm64-windows -fast-isel=0 -global-isel=1 -global-isel-abort=0 | FileCheck -check-prefixes=CHECK,CHECK-GISEL %s
; Returns <= 8 bytes should be in X0.
%struct.S1 = type { i32, i32 }
-define dso_local i64 @"?f1"() {
+define dso_local i64 @f1() {
+; CHECK-SDAG-LABEL: f1:
+; CHECK-SDAG: .seh_proc f1
+; CHECK-SDAG-NEXT: // %bb.0: // %entry
+; CHECK-SDAG-NEXT: sub sp, sp, #16
+; CHECK-SDAG-NEXT: .seh_stackalloc 16
+; CHECK-SDAG-NEXT: .seh_endprologue
+; CHECK-SDAG-NEXT: mov x0, xzr
+; CHECK-SDAG-NEXT: str xzr, [sp, #8]
+; CHECK-SDAG-NEXT: .seh_startepilogue
+; CHECK-SDAG-NEXT: add sp, sp, #16
+; CHECK-SDAG-NEXT: .seh_stackalloc 16
+; CHECK-SDAG-NEXT: .seh_endepilogue
+; CHECK-SDAG-NEXT: ret
+; CHECK-SDAG-NEXT: .seh_endfunclet
+; CHECK-SDAG-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-GISEL-LABEL: f1:
+; CHECK-GISEL: .seh_proc f1
+; CHECK-GISEL-NEXT: // %bb.0: // %entry
+; CHECK-GISEL-NEXT: sub sp, sp, #16
+; CHECK-GISEL-NEXT: .seh_stackalloc 16
+; CHECK-GISEL-NEXT: .seh_endprologue
+; CHECK-GISEL-NEXT: str xzr, [sp, #8]
+; CHECK-GISEL-NEXT: mov x0, xzr
+; CHECK-GISEL-NEXT: .seh_startepilogue
+; CHECK-GISEL-NEXT: add sp, sp, #16
+; CHECK-GISEL-NEXT: .seh_stackalloc 16
+; CHECK-GISEL-NEXT: .seh_endepilogue
+; CHECK-GISEL-NEXT: ret
+; CHECK-GISEL-NEXT: .seh_endfunclet
+; CHECK-GISEL-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 +66,42 @@ 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-GISEL-LABEL: f2:
+; CHECK-GISEL: .seh_proc f2
+; CHECK-GISEL-NEXT: // %bb.0: // %entry
+; CHECK-GISEL-NEXT: sub sp, sp, #16
+; CHECK-GISEL-NEXT: .seh_stackalloc 16
+; CHECK-GISEL-NEXT: .seh_endprologue
+; CHECK-GISEL-NEXT: stp xzr, xzr, [sp]
+; CHECK-GISEL-NEXT: mov x0, xzr
+; CHECK-GISEL-NEXT: mov x1, xzr
+; CHECK-GISEL-NEXT: .seh_startepilogue
+; CHECK-GISEL-NEXT: add sp, sp, #16
+; CHECK-GISEL-NEXT: .seh_stackalloc 16
+; CHECK-GISEL-NEXT: .seh_endepilogue
+; CHECK-GISEL-NEXT: ret
+; CHECK-GISEL-NEXT: .seh_endfunclet
+; CHECK-GISEL-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 +117,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 +140,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 +155,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 +226,53 @@ 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-NOTGISEL-LABEL: call_copy_pod:
+; CHECK-NOTGISEL: .seh_proc call_copy_pod
+; CHECK-NOTGISEL-NEXT: // %bb.0:
+; CHECK-NOTGISEL-NEXT: sub sp, sp, #16
+; CHECK-NOTGISEL-NEXT: .seh_stackalloc 16
+; CHECK-NOTGISEL-NEXT: stp x19, x30, [sp] // 16-byte Folded Spill
+; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 0
+; CHECK-NOTGISEL-NEXT: .seh_endprologue
+; CHECK-NOTGISEL-NEXT: adrp x19, Pod
+; CHECK-NOTGISEL-NEXT: add x19, x19, :lo12:Pod
+; CHECK-NOTGISEL-NEXT: mov x0, x19
+; CHECK-NOTGISEL-NEXT: bl copy_pod
+; CHECK-NOTGISEL-NEXT: stp d0, d1, [x19]
+; CHECK-NOTGISEL-NEXT: .seh_startepilogue
+; CHECK-NOTGISEL-NEXT: ldp x19, x30, [sp] // 16-byte Folded Reload
+; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 0
+; 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-GISEL-LABEL: call_copy_pod:
+; CHECK-GISEL: .seh_proc call_copy_pod
+; CHECK-GISEL-NEXT: // %bb.0:
+; CHECK-GISEL-NEXT: stp x19, x20, [sp, #-32]! // 16-byte Folded Spill
+; CHECK-GISEL-NEXT: .seh_save_regp_x x19, 32
+; CHECK-GISEL-NEXT: str x30, [sp, #16] // 8-byte Spill
+; CHECK-GISEL-NEXT: .seh_save_reg x30, 16
+; CHECK-GISEL-NEXT: .seh_endprologue
+; CHECK-GISEL-NEXT: adrp x19, Pod
+; CHECK-GISEL-NEXT: add x19, x19, :lo12:Pod
+; CHECK-GISEL-NEXT: adrp x20, Pod
+; CHECK-GISEL-NEXT: mov x0, x19
+; CHECK-GISEL-NEXT: bl copy_pod
+; CHECK-GISEL-NEXT: str d0, [x20, :lo12:Pod]
+; CHECK-GISEL-NEXT: str d1, [x19, #8]
+; CHECK-GISEL-NEXT: .seh_startepilogue
+; CHECK-GISEL-NEXT: ldr x30, [sp, #16] // 8-byte Reload
+; CHECK-GISEL-NEXT: .seh_save_reg x30, 16
+; CHECK-GISEL-NEXT: ldp x19, x20, [sp], #32 // 16-byte Folded Reload
+; CHECK-GISEL-NEXT: .seh_save_regp_x x19, 32
+; CHECK-GISEL-NEXT: .seh_endepilogue
+; CHECK-GISEL-NEXT: ret
+; CHECK-GISEL-NEXT: .seh_endfunclet
+; CHECK-GISEL-NEXT: .seh_endproc
%x = call %struct.Pod @copy_pod(ptr @Pod)
store %struct.Pod %x, ptr @Pod
ret void
@@ -170,30 +281,61 @@ 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-NOTGISEL-LABEL: call_copy_notcxx14aggregate:
+; CHECK-NOTGISEL: .seh_proc call_copy_notcxx14aggregate
+; CHECK-NOTGISEL-NEXT: // %bb.0:
+; CHECK-NOTGISEL-NEXT: sub sp, sp, #32
+; CHECK-NOTGISEL-NEXT: .seh_stackalloc 32
+; CHECK-NOTGISEL-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 16
+; CHECK-NOTGISEL-NEXT: .seh_endprologue
+; CHECK-NOTGISEL-NEXT: adrp x19, NotCXX14Aggregate
+; CHECK-NOTGISEL-NEXT: add x19, x19, :lo12:NotCXX14Aggregate
+; CHECK-NOTGISEL-NEXT: mov x0, sp
+; CHECK-NOTGISEL-NEXT: mov x1, x19
+; CHECK-NOTGISEL-NEXT: bl copy_notcxx14aggregate
+; CHECK-NOTGISEL-NEXT: ldp d0, d1, [sp]
+; CHECK-NOTGISEL-NEXT: stp d0, d1, [x19]
+; CHECK-NOTGISEL-NEXT: .seh_startepilogue
+; CHECK-NOTGISEL-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 16
+; CHECK-NOTGISEL-NEXT: add sp, sp, #32
+; CHECK-NOTGISEL-NEXT: .seh_stackalloc 32
+; CHECK-NOTGISEL-NEXT: .seh_endepilogue
+; CHECK-NOTGISEL-NEXT: ret
+; CHECK-NOTGISEL-NEXT: .seh_endfunclet
+; CHECK-NOTGISEL-NEXT: .seh_endproc
+;
+; CHECK-GISEL-LABEL: call_copy_notcxx14aggregate:
+; CHECK-GISEL: .seh_proc call_copy_notcxx14aggregate
+; CHECK-GISEL-NEXT: // %bb.0:
+; CHECK-GISEL-NEXT: sub sp, sp, #48
+; CHECK-GISEL-NEXT: .seh_stackalloc 48
+; CHECK-GISEL-NEXT: stp x19, x20, [sp, #16] // 16-byte Folded Spill
+; CHECK-GISEL-NEXT: .seh_save_regp x19, 16
+; CHECK-GISEL-NEXT: str x30, [sp, #32] // 8-byte Spill
+; CHECK-GISEL-NEXT: .seh_save_reg x30, 32
+; CHECK-GISEL-NEXT: .seh_endprologue
+; CHECK-GISEL-NEXT: adrp x19, NotCXX14Aggregate
+; CHECK-GISEL-NEXT: add x19, x19, :lo12:NotCXX14Aggregate
+; CHECK-GISEL-NEXT: mov x0, sp
+; CHECK-GISEL-NEXT: mov x1, x19
+; CHECK-GISEL-NEXT: adrp x20, NotCXX14Aggregate
+; CHECK-GISEL-NEXT: bl copy_notcxx14aggregate
+; CHECK-GISEL-NEXT: ldp x8, x9, [sp]
+; CHECK-GISEL-NEXT: str x8, [x20, :lo12:NotCXX14Aggregate]
+; CHECK-GISEL-NEXT: str x9, [x19, #8]
+; CHECK-GISEL-NEXT: .seh_startepilogue
+; CHECK-GISEL-NEXT: ldr x30, [sp, #32] // 8-byte Reload
+; CHECK-GISEL-NEXT: .seh_save_reg x30, 32
+; CHECK-GISEL-NEXT: ldp x19, x20, [sp, #16] // 16-byte Folded Reload
+; CHECK-GISEL-NEXT: .seh_save_regp x19, 16
+; CHECK-GISEL-NEXT: add sp, sp, #48
+; CHECK-GISEL-NEXT: .seh_stackalloc 48
+; CHECK-GISEL-NEXT: .seh_endepilogue
+; CHECK-GISEL-NEXT: ret
+; CHECK-GISEL-NEXT: .seh_endfunclet
+; CHECK-GISEL-NEXT: .seh_endproc
%x = alloca %struct.NotCXX14Aggregate
call void @copy_notcxx14aggregate(ptr %x, ptr @NotCXX14Aggregate)
%x1 = load %struct.NotCXX14Aggregate, ptr %x
@@ -204,28 +346,53 @@ define void @call_copy_notcxx14aggregate() {
@NotPod = external global %struct.NotPod
define void @call_copy_notpod() {
-; CHECK-LABEL: call_copy_notpod:
-; CHECK: .seh_proc call_copy_notpod
-; 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, NotPod
-; CHECK-NEXT: add x19, x19, :lo12:NotPod
-; CHECK-NEXT: mov x0, x19
-; CHECK-NEXT: bl copy_notpod
-; CHECK-NEXT: stp x0, x1, [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-NOTGISEL-LABEL: call_copy_notpod:
+; CHECK-NOTGISEL: .seh_proc call_copy_notpod
+; CHECK-NOTGISEL-NEXT: // %bb.0:
+; CHECK-NOTGISEL-NEXT: sub sp, sp, #16
+; CHECK-NOTGISEL-NEXT: .seh_stackalloc 16
+; CHECK-NOTGISEL-NEXT: stp x19, x30, [sp] // 16-byte Folded Spill
+; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 0
+; CHECK-NOTGISEL-NEXT: .seh_endprologue
+; CHECK-NOTGISEL-NEXT: adrp x19, NotPod
+; CHECK-NOTGISEL-NEXT: add x19, x19, :lo12:NotPod
+; CHECK-NOTGISEL-NEXT: mov x0, x19
+; CHECK-NOTGISEL-NEXT: bl copy_notpod
+; CHECK-NOTGISEL-NEXT: stp x0, x1, [x19]
+; CHECK-NOTGISEL-NEXT: .seh_startepilogue
+; CHECK-NOTGISEL-NEXT: ldp x19, x30, [sp] // 16-byte Folded Reload
+; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 0
+; 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-GISEL-LABEL: call_copy_notpod:
+; CHECK-GISEL: .seh_proc call_copy_notpod
+; CHECK-GISEL-NEXT: // %bb.0:
+; CHECK-GISEL-NEXT: stp x19, x20, [sp, #-32]! // 16-byte Folded Spill
+; CHECK-GISEL-NEXT: .seh_save_regp_x x19, 32
+; CHECK-GISEL-NEXT: str x30, [sp, #16] // 8-byte Spill
+; CHECK-GISEL-NEXT: .seh_save_reg x30, 16
+; CHECK-GISEL-NEXT: .seh_endprologue
+; CHECK-GISEL-NEXT: adrp x19, NotPod
+; CHECK-GISEL-NEXT: add x19, x19, :lo12:NotPod
+; CHECK-GISEL-NEXT: adrp x20, NotPod
+; CHECK-GISEL-NEXT: mov x0, x19
+; CHECK-GISEL-NEXT: bl copy_notpod
+; CHECK-GISEL-NEXT: str x0, [x20, :lo12:NotPod]
+; CHECK-GISEL-NEXT: str x1, [x19, #8]
+; CHECK-GISEL-NEXT: .seh_startepilogue
+; CHECK-GISEL-NEXT: ldr x30, [sp, #16] // 8-byte Reload
+; CHECK-GISEL-NEXT: .seh_save_reg x30, 16
+; CHECK-GISEL-NEXT: ldp x19, x20, [sp], #32 // 16-byte Folded Reload
+; CHECK-GISEL-NEXT: .seh_save_regp_x x19, 32
+; CHECK-GISEL-NEXT: .seh_endepilogue
+; CHECK-GISEL-NEXT: ret
+; CHECK-GISEL-NEXT: .seh_endfunclet
+; CHECK-GISEL-NEXT: .seh_endproc
%x = call [2 x i64] @copy_notpod(ptr @NotPod)
store [2 x i64] %x, ptr @NotPod
ret void
diff --git a/llvm/test/CodeGen/AArch64/arm64-windows-tailcall.ll b/llvm/test/CodeGen/AArch64/arm64-windows-tailcall.ll
index cd0a77a280aec2..e81bcd07badc09 100644
--- a/llvm/test/CodeGen/AArch64/arm64-windows-tailcall.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-windows-tailcall.ll
@@ -1,15 +1,32 @@
-; FIXME: Add tests for global-isel/fast-isel.
-
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc < %s -mtriple=arm64-windows | FileCheck %s
+; RUN: llc < %s -mtriple=arm64-windows -fast-isel=1 -global-isel=0 | FileCheck %s
+; RUN: llc < %s -mtriple=arm64-windows -fast-isel=0 -global-isel=1 -global-isel-abort=0 | FileCheck %s
%class.C = type { [1 x i32] }
-define dso_local void @"?bar"(ptr inreg noalias sret(%class.C) %agg.result) {
+define dso_local void @bar(ptr inreg noalias sret(%class.C) %agg.result) {
+; CHECK-LABEL: bar:
+; CHECK: .seh_proc bar
+; CHECK-NEXT: // %bb.0: // %entry
+; 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: mov x19, x0
+; CHECK-NEXT: bl "?foo"
+; CHECK-NEXT: mov x0, 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
entry:
-; CHECK-LABEL: bar
-; CHECK: mov x19, x0
-; CHECK: bl "?foo"
-; CHECK: mov x0, x19
tail call void @"?foo"(ptr dereferenceable(4) %agg.result)
ret void
@@ -22,10 +39,28 @@ declare void @inreg_callee(ptr, ptr inreg sret(%class.C))
define void @inreg_caller_1(ptr %a, ptr inreg sret(%class.C) %b) {
; A different value is passed to the inreg parameter, so tail call is not possible.
-; CHECK-LABEL: inreg_caller_1
-; CHECK: mov x19, x1
-; CHECK: bl inreg_callee
-; CHECK: mov x0, x19
+; CHECK-LABEL: inreg_caller_1:
+; CHECK: .seh_proc inreg_caller_1
+; 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: mov x19, x1
+; CHECK-NEXT: mov x1, x0
+; CHECK-NEXT: mov x0, x19
+; CHECK-NEXT: bl inreg_callee
+; CHECK-NEXT: mov x0, 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
tail call void @inreg_callee(ptr %b, ptr inreg sret(%class.C) %a)
ret void
@@ -34,8 +69,9 @@ define void @inreg_caller_1(ptr %a, ptr inreg sret(%class.C) %b) {
define void @inreg_caller_2(ptr %a, ptr inreg sret(%class.C) %b) {
; The inreg attribute and value line up between caller and callee, so it can
; be tail called.
-; CHECK-LABEL: inreg_caller_2
-; CHECK: b inreg_callee
+; CHECK-LABEL: inreg_caller_2:
+; CHECK: // %bb.0:
+; CHECK-NEXT: b inreg_callee
tail call void @inreg_callee(ptr %a, ptr inreg sret(%class.C) %b)
ret void
>From c423c4f6d4b4d3ba9fb91bd3afc68bf4b075bbaa Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at qti.qualcomm.com>
Date: Tue, 22 Sep 2026 12:45:01 -0700
Subject: [PATCH 2/2] Shorten prefixes. Add a couple RUN lines for Arm64EC.
(We had coverage for globalisel for the interesting bits, which are
varags calls, but might as well make sure we have coverage for regular
calls as well.)
---
.../CodeGen/AArch64/arm64-windows-calls.ll | 681 +++++++++++++-----
1 file changed, 487 insertions(+), 194 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll b/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll
index ced7e3acf6303a..3305a6dce3029e 100644
--- a/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-windows-calls.ll
@@ -1,27 +1,61 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc < %s -mtriple=arm64-windows | FileCheck -check-prefixes=CHECK,CHECK-NOTGISEL,CHECK-SDAG %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=arm64-windows -fast-isel=0 -global-isel=1 -global-isel-abort=0 | FileCheck -check-prefixes=CHECK,CHECK-GISEL %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() {
-; CHECK-SDAG-LABEL: f1:
-; CHECK-SDAG: .seh_proc f1
-; CHECK-SDAG-NEXT: // %bb.0: // %entry
-; CHECK-SDAG-NEXT: sub sp, sp, #16
-; CHECK-SDAG-NEXT: .seh_stackalloc 16
-; CHECK-SDAG-NEXT: .seh_endprologue
-; CHECK-SDAG-NEXT: mov x0, xzr
-; CHECK-SDAG-NEXT: str xzr, [sp, #8]
-; CHECK-SDAG-NEXT: .seh_startepilogue
-; CHECK-SDAG-NEXT: add sp, sp, #16
-; CHECK-SDAG-NEXT: .seh_stackalloc 16
-; CHECK-SDAG-NEXT: .seh_endepilogue
-; CHECK-SDAG-NEXT: ret
-; CHECK-SDAG-NEXT: .seh_endfunclet
-; CHECK-SDAG-NEXT: .seh_endproc
+; 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
@@ -39,21 +73,22 @@ define dso_local i64 @f1() {
; CHECK-FAST-NEXT: .seh_endfunclet
; CHECK-FAST-NEXT: .seh_endproc
;
-; CHECK-GISEL-LABEL: f1:
-; CHECK-GISEL: .seh_proc f1
-; CHECK-GISEL-NEXT: // %bb.0: // %entry
-; CHECK-GISEL-NEXT: sub sp, sp, #16
-; CHECK-GISEL-NEXT: .seh_stackalloc 16
-; CHECK-GISEL-NEXT: .seh_endprologue
-; CHECK-GISEL-NEXT: str xzr, [sp, #8]
-; CHECK-GISEL-NEXT: mov x0, xzr
-; CHECK-GISEL-NEXT: .seh_startepilogue
-; CHECK-GISEL-NEXT: add sp, sp, #16
-; CHECK-GISEL-NEXT: .seh_stackalloc 16
-; CHECK-GISEL-NEXT: .seh_endepilogue
-; CHECK-GISEL-NEXT: ret
-; CHECK-GISEL-NEXT: .seh_endfunclet
-; CHECK-GISEL-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:
%retval = alloca %struct.S1, align 4
@@ -84,22 +119,40 @@ define dso_local [2 x i64] @f2() {
; CHECK-NOTGISEL-NEXT: .seh_endfunclet
; CHECK-NOTGISEL-NEXT: .seh_endproc
;
-; CHECK-GISEL-LABEL: f2:
-; CHECK-GISEL: .seh_proc f2
-; CHECK-GISEL-NEXT: // %bb.0: // %entry
-; CHECK-GISEL-NEXT: sub sp, sp, #16
-; CHECK-GISEL-NEXT: .seh_stackalloc 16
-; CHECK-GISEL-NEXT: .seh_endprologue
-; CHECK-GISEL-NEXT: stp xzr, xzr, [sp]
-; CHECK-GISEL-NEXT: mov x0, xzr
-; CHECK-GISEL-NEXT: mov x1, xzr
-; CHECK-GISEL-NEXT: .seh_startepilogue
-; CHECK-GISEL-NEXT: add sp, sp, #16
-; CHECK-GISEL-NEXT: .seh_stackalloc 16
-; CHECK-GISEL-NEXT: .seh_endepilogue
-; CHECK-GISEL-NEXT: ret
-; CHECK-GISEL-NEXT: .seh_endfunclet
-; CHECK-GISEL-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
@@ -226,53 +279,131 @@ define dso_local [2 x i64] @copy_notpod(ptr %x) {
@Pod = external global %struct.Pod
define void @call_copy_pod() {
-; CHECK-NOTGISEL-LABEL: call_copy_pod:
-; CHECK-NOTGISEL: .seh_proc call_copy_pod
-; CHECK-NOTGISEL-NEXT: // %bb.0:
-; CHECK-NOTGISEL-NEXT: sub sp, sp, #16
-; CHECK-NOTGISEL-NEXT: .seh_stackalloc 16
-; CHECK-NOTGISEL-NEXT: stp x19, x30, [sp] // 16-byte Folded Spill
-; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 0
-; CHECK-NOTGISEL-NEXT: .seh_endprologue
-; CHECK-NOTGISEL-NEXT: adrp x19, Pod
-; CHECK-NOTGISEL-NEXT: add x19, x19, :lo12:Pod
-; CHECK-NOTGISEL-NEXT: mov x0, x19
-; CHECK-NOTGISEL-NEXT: bl copy_pod
-; CHECK-NOTGISEL-NEXT: stp d0, d1, [x19]
-; CHECK-NOTGISEL-NEXT: .seh_startepilogue
-; CHECK-NOTGISEL-NEXT: ldp x19, x30, [sp] // 16-byte Folded Reload
-; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 0
-; 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-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-GISEL-LABEL: call_copy_pod:
-; CHECK-GISEL: .seh_proc call_copy_pod
-; CHECK-GISEL-NEXT: // %bb.0:
-; CHECK-GISEL-NEXT: stp x19, x20, [sp, #-32]! // 16-byte Folded Spill
-; CHECK-GISEL-NEXT: .seh_save_regp_x x19, 32
-; CHECK-GISEL-NEXT: str x30, [sp, #16] // 8-byte Spill
-; CHECK-GISEL-NEXT: .seh_save_reg x30, 16
-; CHECK-GISEL-NEXT: .seh_endprologue
-; CHECK-GISEL-NEXT: adrp x19, Pod
-; CHECK-GISEL-NEXT: add x19, x19, :lo12:Pod
-; CHECK-GISEL-NEXT: adrp x20, Pod
-; CHECK-GISEL-NEXT: mov x0, x19
-; CHECK-GISEL-NEXT: bl copy_pod
-; CHECK-GISEL-NEXT: str d0, [x20, :lo12:Pod]
-; CHECK-GISEL-NEXT: str d1, [x19, #8]
-; CHECK-GISEL-NEXT: .seh_startepilogue
-; CHECK-GISEL-NEXT: ldr x30, [sp, #16] // 8-byte Reload
-; CHECK-GISEL-NEXT: .seh_save_reg x30, 16
-; CHECK-GISEL-NEXT: ldp x19, x20, [sp], #32 // 16-byte Folded Reload
-; CHECK-GISEL-NEXT: .seh_save_regp_x x19, 32
-; CHECK-GISEL-NEXT: .seh_endepilogue
-; CHECK-GISEL-NEXT: ret
-; CHECK-GISEL-NEXT: .seh_endfunclet
-; CHECK-GISEL-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
@@ -281,61 +412,145 @@ define void @call_copy_pod() {
@NotCXX14Aggregate = external global %struct.NotCXX14Aggregate
define void @call_copy_notcxx14aggregate() {
-; CHECK-NOTGISEL-LABEL: call_copy_notcxx14aggregate:
-; CHECK-NOTGISEL: .seh_proc call_copy_notcxx14aggregate
-; CHECK-NOTGISEL-NEXT: // %bb.0:
-; CHECK-NOTGISEL-NEXT: sub sp, sp, #32
-; CHECK-NOTGISEL-NEXT: .seh_stackalloc 32
-; CHECK-NOTGISEL-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
-; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 16
-; CHECK-NOTGISEL-NEXT: .seh_endprologue
-; CHECK-NOTGISEL-NEXT: adrp x19, NotCXX14Aggregate
-; CHECK-NOTGISEL-NEXT: add x19, x19, :lo12:NotCXX14Aggregate
-; CHECK-NOTGISEL-NEXT: mov x0, sp
-; CHECK-NOTGISEL-NEXT: mov x1, x19
-; CHECK-NOTGISEL-NEXT: bl copy_notcxx14aggregate
-; CHECK-NOTGISEL-NEXT: ldp d0, d1, [sp]
-; CHECK-NOTGISEL-NEXT: stp d0, d1, [x19]
-; CHECK-NOTGISEL-NEXT: .seh_startepilogue
-; CHECK-NOTGISEL-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload
-; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 16
-; CHECK-NOTGISEL-NEXT: add sp, sp, #32
-; CHECK-NOTGISEL-NEXT: .seh_stackalloc 32
-; CHECK-NOTGISEL-NEXT: .seh_endepilogue
-; CHECK-NOTGISEL-NEXT: ret
-; CHECK-NOTGISEL-NEXT: .seh_endfunclet
-; CHECK-NOTGISEL-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-GISEL-LABEL: call_copy_notcxx14aggregate:
-; CHECK-GISEL: .seh_proc call_copy_notcxx14aggregate
-; CHECK-GISEL-NEXT: // %bb.0:
-; CHECK-GISEL-NEXT: sub sp, sp, #48
-; CHECK-GISEL-NEXT: .seh_stackalloc 48
-; CHECK-GISEL-NEXT: stp x19, x20, [sp, #16] // 16-byte Folded Spill
-; CHECK-GISEL-NEXT: .seh_save_regp x19, 16
-; CHECK-GISEL-NEXT: str x30, [sp, #32] // 8-byte Spill
-; CHECK-GISEL-NEXT: .seh_save_reg x30, 32
-; CHECK-GISEL-NEXT: .seh_endprologue
-; CHECK-GISEL-NEXT: adrp x19, NotCXX14Aggregate
-; CHECK-GISEL-NEXT: add x19, x19, :lo12:NotCXX14Aggregate
-; CHECK-GISEL-NEXT: mov x0, sp
-; CHECK-GISEL-NEXT: mov x1, x19
-; CHECK-GISEL-NEXT: adrp x20, NotCXX14Aggregate
-; CHECK-GISEL-NEXT: bl copy_notcxx14aggregate
-; CHECK-GISEL-NEXT: ldp x8, x9, [sp]
-; CHECK-GISEL-NEXT: str x8, [x20, :lo12:NotCXX14Aggregate]
-; CHECK-GISEL-NEXT: str x9, [x19, #8]
-; CHECK-GISEL-NEXT: .seh_startepilogue
-; CHECK-GISEL-NEXT: ldr x30, [sp, #32] // 8-byte Reload
-; CHECK-GISEL-NEXT: .seh_save_reg x30, 32
-; CHECK-GISEL-NEXT: ldp x19, x20, [sp, #16] // 16-byte Folded Reload
-; CHECK-GISEL-NEXT: .seh_save_regp x19, 16
-; CHECK-GISEL-NEXT: add sp, sp, #48
-; CHECK-GISEL-NEXT: .seh_stackalloc 48
-; CHECK-GISEL-NEXT: .seh_endepilogue
-; CHECK-GISEL-NEXT: ret
-; CHECK-GISEL-NEXT: .seh_endfunclet
-; CHECK-GISEL-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] // 8-byte Spill
+; CHECK-GI-NEXT: .seh_save_reg x30, 32
+; CHECK-GI-NEXT: .seh_endprologue
+; CHECK-GI-NEXT: adrp x19, NotCXX14Aggregate
+; CHECK-GI-NEXT: add x19, x19, :lo12:NotCXX14Aggregate
+; CHECK-GI-NEXT: mov x0, sp
+; CHECK-GI-NEXT: mov x1, x19
+; CHECK-GI-NEXT: adrp x20, NotCXX14Aggregate
+; CHECK-GI-NEXT: bl copy_notcxx14aggregate
+; CHECK-GI-NEXT: ldp x8, x9, [sp]
+; CHECK-GI-NEXT: str x8, [x20, :lo12:NotCXX14Aggregate]
+; CHECK-GI-NEXT: str x9, [x19, #8]
+; CHECK-GI-NEXT: .seh_startepilogue
+; CHECK-GI-NEXT: ldr x30, [sp, #32] // 8-byte Reload
+; CHECK-GI-NEXT: .seh_save_reg x30, 32
+; CHECK-GI-NEXT: ldp x19, x20, [sp, #16] // 16-byte Folded Reload
+; CHECK-GI-NEXT: .seh_save_regp x19, 16
+; CHECK-GI-NEXT: add sp, sp, #48
+; CHECK-GI-NEXT: .seh_stackalloc 48
+; CHECK-GI-NEXT: .seh_endepilogue
+; CHECK-GI-NEXT: ret
+; CHECK-GI-NEXT: .seh_endfunclet
+; CHECK-GI-NEXT: .seh_endproc
+;
+; CHECK-FAST-LABEL: call_copy_notcxx14aggregate:
+; CHECK-FAST: .seh_proc call_copy_notcxx14aggregate
+; CHECK-FAST-NEXT: // %bb.0:
+; CHECK-FAST-NEXT: sub sp, sp, #32
+; CHECK-FAST-NEXT: .seh_stackalloc 32
+; CHECK-FAST-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-FAST-NEXT: .seh_save_lrpair x19, 16
+; CHECK-FAST-NEXT: .seh_endprologue
+; CHECK-FAST-NEXT: adrp x19, NotCXX14Aggregate
+; CHECK-FAST-NEXT: add x19, x19, :lo12:NotCXX14Aggregate
+; CHECK-FAST-NEXT: mov x0, sp
+; CHECK-FAST-NEXT: mov x1, x19
+; CHECK-FAST-NEXT: bl copy_notcxx14aggregate
+; CHECK-FAST-NEXT: ldp d0, d1, [sp]
+; CHECK-FAST-NEXT: stp d0, d1, [x19]
+; CHECK-FAST-NEXT: .seh_startepilogue
+; CHECK-FAST-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-FAST-NEXT: .seh_save_lrpair x19, 16
+; CHECK-FAST-NEXT: add sp, sp, #32
+; CHECK-FAST-NEXT: .seh_stackalloc 32
+; 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_notcxx14aggregate:
+; CHECK-EC-GI: .seh_proc call_copy_notcxx14aggregate
+; CHECK-EC-GI-NEXT: // %bb.0:
+; CHECK-EC-GI-NEXT: sub sp, sp, #32
+; CHECK-EC-GI-NEXT: .seh_stackalloc 32
+; CHECK-EC-GI-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
+; CHECK-EC-GI-NEXT: .seh_save_lrpair x19, 16
+; CHECK-EC-GI-NEXT: .seh_endprologue
+; CHECK-EC-GI-NEXT: adrp x19, NotCXX14Aggregate
+; CHECK-EC-GI-NEXT: add x19, x19, :lo12:NotCXX14Aggregate
+; CHECK-EC-GI-NEXT: mov x0, sp
+; CHECK-EC-GI-NEXT: mov x1, x19
+; CHECK-EC-GI-NEXT: .weak_anti_dep copy_notcxx14aggregate
+; CHECK-EC-GI-NEXT: copy_notcxx14aggregate = "#copy_notcxx14aggregate"
+; CHECK-EC-GI-NEXT: .weak_anti_dep "#copy_notcxx14aggregate"
+; CHECK-EC-GI-NEXT: "#copy_notcxx14aggregate" = copy_notcxx14aggregate
+; CHECK-EC-GI-NEXT: bl "#copy_notcxx14aggregate"
+; CHECK-EC-GI-NEXT: ldp d0, d1, [sp]
+; CHECK-EC-GI-NEXT: stp d0, d1, [x19]
+; CHECK-EC-GI-NEXT: .seh_startepilogue
+; CHECK-EC-GI-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload
+; CHECK-EC-GI-NEXT: .seh_save_lrpair x19, 16
+; CHECK-EC-GI-NEXT: add sp, sp, #32
+; CHECK-EC-GI-NEXT: .seh_stackalloc 32
+; CHECK-EC-GI-NEXT: .seh_endepilogue
+; CHECK-EC-GI-NEXT: ret
+; CHECK-EC-GI-NEXT: .seh_endfunclet
+; CHECK-EC-GI-NEXT: .seh_endproc
+
%x = alloca %struct.NotCXX14Aggregate
call void @copy_notcxx14aggregate(ptr %x, ptr @NotCXX14Aggregate)
%x1 = load %struct.NotCXX14Aggregate, ptr %x
@@ -346,53 +561,131 @@ define void @call_copy_notcxx14aggregate() {
@NotPod = external global %struct.NotPod
define void @call_copy_notpod() {
-; CHECK-NOTGISEL-LABEL: call_copy_notpod:
-; CHECK-NOTGISEL: .seh_proc call_copy_notpod
-; CHECK-NOTGISEL-NEXT: // %bb.0:
-; CHECK-NOTGISEL-NEXT: sub sp, sp, #16
-; CHECK-NOTGISEL-NEXT: .seh_stackalloc 16
-; CHECK-NOTGISEL-NEXT: stp x19, x30, [sp] // 16-byte Folded Spill
-; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 0
-; CHECK-NOTGISEL-NEXT: .seh_endprologue
-; CHECK-NOTGISEL-NEXT: adrp x19, NotPod
-; CHECK-NOTGISEL-NEXT: add x19, x19, :lo12:NotPod
-; CHECK-NOTGISEL-NEXT: mov x0, x19
-; CHECK-NOTGISEL-NEXT: bl copy_notpod
-; CHECK-NOTGISEL-NEXT: stp x0, x1, [x19]
-; CHECK-NOTGISEL-NEXT: .seh_startepilogue
-; CHECK-NOTGISEL-NEXT: ldp x19, x30, [sp] // 16-byte Folded Reload
-; CHECK-NOTGISEL-NEXT: .seh_save_lrpair x19, 0
-; 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-SD-LABEL: call_copy_notpod:
+; CHECK-SD: .seh_proc call_copy_notpod
+; 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, NotPod
+; CHECK-SD-NEXT: add x19, x19, :lo12:NotPod
+; CHECK-SD-NEXT: mov x0, x19
+; CHECK-SD-NEXT: bl copy_notpod
+; CHECK-SD-NEXT: stp x0, x1, [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_notpod:
+; CHECK-EC-SD: .seh_proc call_copy_notpod
+; 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, NotPod
+; CHECK-EC-SD-NEXT: add x19, x19, :lo12:NotPod
+; CHECK-EC-SD-NEXT: mov x0, x19
+; CHECK-EC-SD-NEXT: .weak_anti_dep copy_notpod
+; CHECK-EC-SD-NEXT: copy_notpod = "#copy_notpod"
+; CHECK-EC-SD-NEXT: .weak_anti_dep "#copy_notpod"
+; CHECK-EC-SD-NEXT: "#copy_notpod" = copy_notpod
+; CHECK-EC-SD-NEXT: bl "#copy_notpod"
+; CHECK-EC-SD-NEXT: stp x0, x1, [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_notpod:
+; CHECK-GI: .seh_proc call_copy_notpod
+; 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, NotPod
+; CHECK-GI-NEXT: add x19, x19, :lo12:NotPod
+; CHECK-GI-NEXT: adrp x20, NotPod
+; CHECK-GI-NEXT: mov x0, x19
+; CHECK-GI-NEXT: bl copy_notpod
+; CHECK-GI-NEXT: str x0, [x20, :lo12:NotPod]
+; CHECK-GI-NEXT: str x1, [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-GISEL-LABEL: call_copy_notpod:
-; CHECK-GISEL: .seh_proc call_copy_notpod
-; CHECK-GISEL-NEXT: // %bb.0:
-; CHECK-GISEL-NEXT: stp x19, x20, [sp, #-32]! // 16-byte Folded Spill
-; CHECK-GISEL-NEXT: .seh_save_regp_x x19, 32
-; CHECK-GISEL-NEXT: str x30, [sp, #16] // 8-byte Spill
-; CHECK-GISEL-NEXT: .seh_save_reg x30, 16
-; CHECK-GISEL-NEXT: .seh_endprologue
-; CHECK-GISEL-NEXT: adrp x19, NotPod
-; CHECK-GISEL-NEXT: add x19, x19, :lo12:NotPod
-; CHECK-GISEL-NEXT: adrp x20, NotPod
-; CHECK-GISEL-NEXT: mov x0, x19
-; CHECK-GISEL-NEXT: bl copy_notpod
-; CHECK-GISEL-NEXT: str x0, [x20, :lo12:NotPod]
-; CHECK-GISEL-NEXT: str x1, [x19, #8]
-; CHECK-GISEL-NEXT: .seh_startepilogue
-; CHECK-GISEL-NEXT: ldr x30, [sp, #16] // 8-byte Reload
-; CHECK-GISEL-NEXT: .seh_save_reg x30, 16
-; CHECK-GISEL-NEXT: ldp x19, x20, [sp], #32 // 16-byte Folded Reload
-; CHECK-GISEL-NEXT: .seh_save_regp_x x19, 32
-; CHECK-GISEL-NEXT: .seh_endepilogue
-; CHECK-GISEL-NEXT: ret
-; CHECK-GISEL-NEXT: .seh_endfunclet
-; CHECK-GISEL-NEXT: .seh_endproc
+; CHECK-FAST-LABEL: call_copy_notpod:
+; CHECK-FAST: .seh_proc call_copy_notpod
+; 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, NotPod
+; CHECK-FAST-NEXT: add x19, x19, :lo12:NotPod
+; CHECK-FAST-NEXT: mov x0, x19
+; CHECK-FAST-NEXT: bl copy_notpod
+; CHECK-FAST-NEXT: stp x0, x1, [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_notpod:
+; CHECK-EC-GI: .seh_proc call_copy_notpod
+; 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, NotPod
+; CHECK-EC-GI-NEXT: add x19, x19, :lo12:NotPod
+; CHECK-EC-GI-NEXT: mov x0, x19
+; CHECK-EC-GI-NEXT: .weak_anti_dep copy_notpod
+; CHECK-EC-GI-NEXT: copy_notpod = "#copy_notpod"
+; CHECK-EC-GI-NEXT: .weak_anti_dep "#copy_notpod"
+; CHECK-EC-GI-NEXT: "#copy_notpod" = copy_notpod
+; CHECK-EC-GI-NEXT: bl "#copy_notpod"
+; CHECK-EC-GI-NEXT: stp x0, x1, [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 [2 x i64] @copy_notpod(ptr @NotPod)
store [2 x i64] %x, ptr @NotPod
ret void
More information about the llvm-commits
mailing list