Changeset View
Changeset View
Standalone View
Standalone View
llvm/test/CodeGen/AArch64/arm64ec-varargs.ll
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | ||||
; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s | FileCheck %s | ; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s | FileCheck %s | ||||
; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s -global-isel=1 -global-isel-abort=0 | FileCheck %s | ; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s -global-isel=1 -global-isel-abort=0 | FileCheck %s | ||||
define void @varargs_callee(double %x, ...) nounwind { | define dso_local void @varargs_callee(double %x, ...) nounwind { | ||||
; CHECK-LABEL: varargs_callee: | ; CHECK-LABEL: varargs_callee: | ||||
; CHECK: // %bb.0: | ; CHECK: // %bb.0: | ||||
; CHECK-NEXT: sub sp, sp, #48 | ; CHECK-NEXT: sub sp, sp, #48 | ||||
; CHECK-NEXT: stp x1, x2, [x4, #-24]! | ; CHECK-NEXT: stp x1, x2, [x4, #-24]! | ||||
; CHECK-NEXT: str x3, [x4, #16] | ; CHECK-NEXT: str x3, [x4, #16] | ||||
; CHECK-NEXT: str x4, [sp, #8] | ; CHECK-NEXT: str x4, [sp, #8] | ||||
; CHECK-NEXT: add sp, sp, #48 | ; CHECK-NEXT: add sp, sp, #48 | ||||
; CHECK-NEXT: ret | ; CHECK-NEXT: ret | ||||
%list = alloca i8*, align 8 | %list = alloca i8*, align 8 | ||||
%listx = bitcast i8** %list to i8* | %listx = bitcast i8** %list to i8* | ||||
call void @llvm.va_start(i8* nonnull %listx) | call void @llvm.va_start(i8* nonnull %listx) | ||||
ret void | ret void | ||||
} | } | ||||
define void @varargs_callee_manyargs(i64, i64, i64, i64, i64, ...) nounwind { | define dso_local void @varargs_callee_manyargs(i64, i64, i64, i64, i64, ...) nounwind { | ||||
; CHECK-LABEL: varargs_callee_manyargs: | ; CHECK-LABEL: varargs_callee_manyargs: | ||||
; CHECK: // %bb.0: | ; CHECK: // %bb.0: | ||||
; CHECK-NEXT: sub sp, sp, #16 | ; CHECK-NEXT: sub sp, sp, #16 | ||||
; CHECK-NEXT: add x8, x4, #8 | ; CHECK-NEXT: add x8, x4, #8 | ||||
; CHECK-NEXT: str x8, [sp, #8] | ; CHECK-NEXT: str x8, [sp, #8] | ||||
; CHECK-NEXT: add sp, sp, #16 | ; CHECK-NEXT: add sp, sp, #16 | ||||
; CHECK-NEXT: ret | ; CHECK-NEXT: ret | ||||
%list = alloca i8*, align 8 | %list = alloca i8*, align 8 | ||||
%listx = bitcast i8** %list to i8* | %listx = bitcast i8** %list to i8* | ||||
call void @llvm.va_start(i8* nonnull %listx) | call void @llvm.va_start(i8* nonnull %listx) | ||||
ret void | ret void | ||||
} | } | ||||
define void @varargs_caller() nounwind { | define dso_local void @varargs_caller() nounwind { | ||||
; CHECK-LABEL: varargs_caller: | ; CHECK-LABEL: varargs_caller: | ||||
; CHECK: // %bb.0: | ; CHECK: // %bb.0: | ||||
; CHECK-NEXT: sub sp, sp, #48 | ; CHECK-NEXT: sub sp, sp, #48 | ||||
; CHECK-NEXT: mov x4, sp | ; CHECK-NEXT: mov x4, sp | ||||
; CHECK-NEXT: add x8, sp, #16 | ; CHECK-NEXT: add x8, sp, #16 | ||||
; CHECK-NEXT: mov x9, #4617315517961601024 | ; CHECK-NEXT: mov x9, #4617315517961601024 | ||||
; CHECK-NEXT: mov x0, #4607182418800017408 | ; CHECK-NEXT: mov x0, #4607182418800017408 | ||||
; CHECK-NEXT: mov w1, #2 | ; CHECK-NEXT: mov w1, #2 | ||||
; CHECK-NEXT: mov x2, #4613937818241073152 | ; CHECK-NEXT: mov x2, #4613937818241073152 | ||||
; CHECK-NEXT: mov w3, #4 | ; CHECK-NEXT: mov w3, #4 | ||||
; CHECK-NEXT: mov w5, #16 | ; CHECK-NEXT: mov w5, #16 | ||||
; CHECK-NEXT: stp xzr, x30, [sp, #24] // 8-byte Folded Spill | ; CHECK-NEXT: stp xzr, x30, [sp, #24] // 8-byte Folded Spill | ||||
; CHECK-NEXT: stp x8, xzr, [sp, #8] | ; CHECK-NEXT: stp x8, xzr, [sp, #8] | ||||
; CHECK-NEXT: str x9, [sp] | ; CHECK-NEXT: str x9, [sp] | ||||
; CHECK-NEXT: bl varargs_callee | ; CHECK-NEXT: bl varargs_callee | ||||
; CHECK-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload | ; CHECK-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload | ||||
; CHECK-NEXT: add sp, sp, #48 | ; CHECK-NEXT: add sp, sp, #48 | ||||
; CHECK-NEXT: ret | ; CHECK-NEXT: ret | ||||
call void (double, ...) @varargs_callee(double 1.0, i32 2, double 3.0, i32 4, double 5.0, <2 x double> <double 0.0, double 0.0>) | call void (double, ...) @varargs_callee(double 1.0, i32 2, double 3.0, i32 4, double 5.0, <2 x double> <double 0.0, double 0.0>) | ||||
ret void | ret void | ||||
} | } | ||||
define <2 x double> @varargs_many_argscallee(double %a, double %b, double %c, | define dso_local <2 x double> @varargs_many_argscallee(double %a, double %b, double %c, | ||||
; CHECK-LABEL: varargs_many_argscallee: | ; CHECK-LABEL: varargs_many_argscallee: | ||||
; CHECK: // %bb.0: | ; CHECK: // %bb.0: | ||||
; CHECK-NEXT: ldr x8, [x4] | ; CHECK-NEXT: ldr x8, [x4] | ||||
; CHECK-NEXT: ldr q0, [x3] | ; CHECK-NEXT: ldr q0, [x3] | ||||
; CHECK-NEXT: ldr q1, [x8] | ; CHECK-NEXT: ldr q1, [x8] | ||||
; CHECK-NEXT: fadd v0.2d, v0.2d, v1.2d | ; CHECK-NEXT: fadd v0.2d, v0.2d, v1.2d | ||||
; CHECK-NEXT: ret | ; CHECK-NEXT: ret | ||||
<2 x double> %d, <2 x double> %e, ...) nounwind { | <2 x double> %d, <2 x double> %e, ...) nounwind { | ||||
%rval = fadd <2 x double> %d, %e | %rval = fadd <2 x double> %d, %e | ||||
ret <2 x double> %rval | ret <2 x double> %rval | ||||
} | } | ||||
define void @varargs_many_argscalleer() nounwind { | define dso_local void @varargs_many_argscalleer() nounwind { | ||||
; CHECK-LABEL: varargs_many_argscalleer: | ; CHECK-LABEL: varargs_many_argscalleer: | ||||
; CHECK: // %bb.0: | ; CHECK: // %bb.0: | ||||
; CHECK-NEXT: sub sp, sp, #64 | ; CHECK-NEXT: sub sp, sp, #64 | ||||
; CHECK-NEXT: movi v0.2d, #0000000000000000 | ; CHECK-NEXT: movi v0.2d, #0000000000000000 | ||||
; CHECK-NEXT: mov x4, sp | ; CHECK-NEXT: mov x4, sp | ||||
; CHECK-NEXT: mov x8, #4618441417868443648 | ; CHECK-NEXT: mov x8, #4618441417868443648 | ||||
; CHECK-NEXT: add x9, sp, #16 | ; CHECK-NEXT: add x9, sp, #16 | ||||
; CHECK-NEXT: add x3, sp, #32 | ; CHECK-NEXT: add x3, sp, #32 | ||||
Show All 20 Lines |