1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=arm64ec-pc-windows-msvc -arm64ec-generate-thunks=false < %s | FileCheck %s 3; RUN: llc -mtriple=arm64ec-pc-windows-msvc -arm64ec-generate-thunks=false < %s -global-isel=1 -global-isel-abort=0 | FileCheck %s 4 5define void @varargs_callee(double %x, ...) nounwind { 6; CHECK-LABEL: varargs_callee: 7; CHECK: // %bb.0: 8; CHECK-NEXT: sub sp, sp, #48 9; CHECK-NEXT: stp x1, x2, [x4, #-24]! 10; CHECK-NEXT: str x3, [x4, #16] 11; CHECK-NEXT: str x4, [sp, #8] 12; CHECK-NEXT: add sp, sp, #48 13; CHECK-NEXT: ret 14 %list = alloca ptr, align 8 15 call void @llvm.va_start(ptr nonnull %list) 16 ret void 17} 18 19define void @varargs_callee_manyargs(i64, i64, i64, i64, i64, ...) nounwind { 20; CHECK-LABEL: varargs_callee_manyargs: 21; CHECK: // %bb.0: 22; CHECK-NEXT: sub sp, sp, #16 23; CHECK-NEXT: add x8, x4, #8 24; CHECK-NEXT: str x8, [sp, #8] 25; CHECK-NEXT: add sp, sp, #16 26; CHECK-NEXT: ret 27 %list = alloca ptr, align 8 28 call void @llvm.va_start(ptr nonnull %list) 29 ret void 30} 31 32define void @varargs_caller() nounwind { 33; CHECK-LABEL: varargs_caller: 34; CHECK: // %bb.0: 35; CHECK-NEXT: sub sp, sp, #48 36; CHECK-NEXT: mov x4, sp 37; CHECK-NEXT: add x8, sp, #16 38; CHECK-NEXT: mov x9, #4617315517961601024 // =0x4014000000000000 39; CHECK-NEXT: mov x0, #4607182418800017408 // =0x3ff0000000000000 40; CHECK-NEXT: mov w1, #2 // =0x2 41; CHECK-NEXT: mov x2, #4613937818241073152 // =0x4008000000000000 42; CHECK-NEXT: mov w3, #4 // =0x4 43; CHECK-NEXT: mov w5, #16 // =0x10 44; CHECK-NEXT: stp xzr, x30, [sp, #24] // 8-byte Folded Spill 45; CHECK-NEXT: stp x9, x8, [sp] 46; CHECK-NEXT: str xzr, [sp, #16] 47; CHECK-NEXT: .weak_anti_dep varargs_callee 48; CHECK-NEXT: .set varargs_callee, "#varargs_callee"@WEAKREF 49; CHECK-NEXT: .weak_anti_dep "#varargs_callee" 50; CHECK-NEXT: .set "#varargs_callee", varargs_callee@WEAKREF 51; CHECK-NEXT: bl "#varargs_callee" 52; CHECK-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload 53; CHECK-NEXT: add sp, sp, #48 54; CHECK-NEXT: ret 55 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>) 56 ret void 57} 58 59define <2 x double> @varargs_many_argscallee(double %a, double %b, double %c, 60; CHECK-LABEL: varargs_many_argscallee: 61; CHECK: // %bb.0: 62; CHECK-NEXT: ldr x8, [x4] 63; CHECK-NEXT: ldr q0, [x3] 64; CHECK-NEXT: ldr q1, [x8] 65; CHECK-NEXT: fadd v0.2d, v0.2d, v1.2d 66; CHECK-NEXT: ret 67 <2 x double> %d, <2 x double> %e, ...) nounwind { 68 %rval = fadd <2 x double> %d, %e 69 ret <2 x double> %rval 70} 71 72define void @varargs_many_argscalleer() nounwind { 73; CHECK-LABEL: varargs_many_argscalleer: 74; CHECK: // %bb.0: 75; CHECK-NEXT: sub sp, sp, #64 76; CHECK-NEXT: movi v0.2d, #0000000000000000 77; CHECK-NEXT: mov x8, #4618441417868443648 // =0x4018000000000000 78; CHECK-NEXT: add x9, sp, #16 79; CHECK-NEXT: add x3, sp, #32 80; CHECK-NEXT: mov x0, #4607182418800017408 // =0x3ff0000000000000 81; CHECK-NEXT: mov x1, #4611686018427387904 // =0x4000000000000000 82; CHECK-NEXT: mov x2, #4613937818241073152 // =0x4008000000000000 83; CHECK-NEXT: mov x4, sp 84; CHECK-NEXT: mov w5, #16 // =0x10 85; CHECK-NEXT: str x30, [sp, #48] // 8-byte Folded Spill 86; CHECK-NEXT: stp x9, x8, [sp] 87; CHECK-NEXT: stp q0, q0, [sp, #16] 88; CHECK-NEXT: .weak_anti_dep varargs_many_argscallee 89; CHECK-NEXT: .set varargs_many_argscallee, "#varargs_many_argscallee"@WEAKREF 90; CHECK-NEXT: .weak_anti_dep "#varargs_many_argscallee" 91; CHECK-NEXT: .set "#varargs_many_argscallee", varargs_many_argscallee@WEAKREF 92; CHECK-NEXT: bl "#varargs_many_argscallee" 93; CHECK-NEXT: ldr x30, [sp, #48] // 8-byte Folded Reload 94; CHECK-NEXT: add sp, sp, #64 95; CHECK-NEXT: ret 96 call <2 x double> (double, double, double, <2 x double>, <2 x double>, ...) 97 @varargs_many_argscallee(double 1., double 2., double 3., 98 <2 x double> zeroinitializer, 99 <2 x double> zeroinitializer, double 6.) 100 ret void 101} 102 103define void @varargs_caller_tail() nounwind { 104; CHECK-LABEL: varargs_caller_tail: 105; CHECK: // %bb.0: 106; CHECK-NEXT: sub sp, sp, #48 107; CHECK-NEXT: mov x4, sp 108; CHECK-NEXT: add x8, sp, #16 109; CHECK-NEXT: mov x9, #4617315517961601024 // =0x4014000000000000 110; CHECK-NEXT: mov x0, #4607182418800017408 // =0x3ff0000000000000 111; CHECK-NEXT: mov w1, #2 // =0x2 112; CHECK-NEXT: mov x2, #4613937818241073152 // =0x4008000000000000 113; CHECK-NEXT: mov w3, #4 // =0x4 114; CHECK-NEXT: mov w5, #16 // =0x10 115; CHECK-NEXT: stp xzr, x30, [sp, #24] // 8-byte Folded Spill 116; CHECK-NEXT: stp x9, x8, [sp] 117; CHECK-NEXT: str xzr, [sp, #16] 118; CHECK-NEXT: .weak_anti_dep varargs_callee 119; CHECK-NEXT:.set varargs_callee, "#varargs_callee"@WEAKREF 120; CHECK-NEXT: .weak_anti_dep "#varargs_callee" 121; CHECK-NEXT:.set "#varargs_callee", varargs_callee@WEAKREF 122; CHECK-NEXT: bl "#varargs_callee" 123; CHECK-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload 124; CHECK-NEXT: add x4, sp, #48 125; CHECK-NEXT: mov x0, #4607182418800017408 // =0x3ff0000000000000 126; CHECK-NEXT: mov w1, #4 // =0x4 127; CHECK-NEXT: mov w2, #3 // =0x3 128; CHECK-NEXT: mov w3, #2 // =0x2 129; CHECK-NEXT: mov x5, xzr 130; CHECK-NEXT: add sp, sp, #48 131; CHECK-NEXT: .weak_anti_dep varargs_callee 132; CHECK-NEXT:.set varargs_callee, "#varargs_callee"@WEAKREF 133; CHECK-NEXT: .weak_anti_dep "#varargs_callee" 134; CHECK-NEXT:.set "#varargs_callee", varargs_callee@WEAKREF 135; CHECK-NEXT: b "#varargs_callee" 136 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>) 137 tail call void (double, ...) @varargs_callee(double 1.0, i32 4, i32 3, i32 2) 138 ret void 139} 140 141declare void @llvm.va_start(ptr) 142