1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-windows -verify-machineinstrs | FileCheck %s --check-prefixes=DAGISEL 3; RUN: llc < %s -mtriple=aarch64-windows -verify-machineinstrs -O0 -fast-isel | FileCheck %s --check-prefixes=O0,FASTISEL 4; RUN: llc < %s -mtriple=aarch64-windows -verify-machineinstrs -O0 -global-isel | FileCheck %s --check-prefixes=O0,GISEL 5 6; Check that non-vararg functions compilation is not broken 7define win64cc float @foo(float %arg) nounwind { 8; DAGISEL-LABEL: foo: 9; DAGISEL: // %bb.0: // %entry 10; DAGISEL-NEXT: ret 11; 12; O0-LABEL: foo: 13; O0: // %bb.0: // %entry 14; O0-NEXT: ret 15entry: 16 ret float %arg 17} 18 19define win64cc void @float_va_fn(float %a, i32 %b, ...) nounwind { 20; DAGISEL-LABEL: float_va_fn: 21; DAGISEL: // %bb.0: // %entry 22; DAGISEL-NEXT: str x30, [sp, #-64]! // 8-byte Folded Spill 23; DAGISEL-NEXT: fmov s0, w0 24; DAGISEL-NEXT: add x8, sp, #16 25; DAGISEL-NEXT: add x0, sp, #16 26; DAGISEL-NEXT: stp x2, x3, [sp, #16] 27; DAGISEL-NEXT: stp x4, x5, [sp, #32] 28; DAGISEL-NEXT: stp x6, x7, [sp, #48] 29; DAGISEL-NEXT: str x8, [sp, #8] 30; DAGISEL-NEXT: bl f_va_list 31; DAGISEL-NEXT: ldr x30, [sp], #64 // 8-byte Folded Reload 32; DAGISEL-NEXT: ret 33; 34; O0-LABEL: float_va_fn: 35; O0: // %bb.0: // %entry 36; O0-NEXT: sub sp, sp, #80 37; O0-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 38; O0-NEXT: str x7, [sp, #72] 39; O0-NEXT: str x6, [sp, #64] 40; O0-NEXT: str x5, [sp, #56] 41; O0-NEXT: str x4, [sp, #48] 42; O0-NEXT: str x3, [sp, #40] 43; O0-NEXT: str x2, [sp, #32] 44; O0-NEXT: fmov s0, w0 45; O0-NEXT: add x8, sp, #32 46; O0-NEXT: str x8, [sp, #8] 47; O0-NEXT: ldr x0, [sp, #8] 48; O0-NEXT: bl f_va_list 49; O0-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 50; O0-NEXT: add sp, sp, #80 51; O0-NEXT: ret 52entry: 53 %ap = alloca ptr, align 8 54 call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %ap) 55 call void @llvm.va_start(ptr nonnull %ap) 56 %0 = load ptr, ptr %ap, align 8 57 call void @f_va_list(float %a, ptr %0) 58 call void @llvm.va_end(ptr nonnull %ap) 59 call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %ap) 60 ret void 61} 62 63declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) 64declare void @llvm.va_start(ptr) 65declare void @f_va_list(float, ptr) 66declare void @llvm.va_end(ptr) 67declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) 68 69define win64cc void @double_va_fn(double %a, i32 %b, ...) nounwind { 70; DAGISEL-LABEL: double_va_fn: 71; DAGISEL: // %bb.0: // %entry 72; DAGISEL-NEXT: str x30, [sp, #-64]! // 8-byte Folded Spill 73; DAGISEL-NEXT: fmov d0, x0 74; DAGISEL-NEXT: add x8, sp, #16 75; DAGISEL-NEXT: add x0, sp, #16 76; DAGISEL-NEXT: stp x2, x3, [sp, #16] 77; DAGISEL-NEXT: stp x4, x5, [sp, #32] 78; DAGISEL-NEXT: stp x6, x7, [sp, #48] 79; DAGISEL-NEXT: str x8, [sp, #8] 80; DAGISEL-NEXT: bl d_va_list 81; DAGISEL-NEXT: ldr x30, [sp], #64 // 8-byte Folded Reload 82; DAGISEL-NEXT: ret 83; 84; O0-LABEL: double_va_fn: 85; O0: // %bb.0: // %entry 86; O0-NEXT: sub sp, sp, #80 87; O0-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 88; O0-NEXT: str x7, [sp, #72] 89; O0-NEXT: str x6, [sp, #64] 90; O0-NEXT: str x5, [sp, #56] 91; O0-NEXT: str x4, [sp, #48] 92; O0-NEXT: str x3, [sp, #40] 93; O0-NEXT: str x2, [sp, #32] 94; O0-NEXT: fmov d0, x0 95; O0-NEXT: add x8, sp, #32 96; O0-NEXT: str x8, [sp, #8] 97; O0-NEXT: ldr x0, [sp, #8] 98; O0-NEXT: bl d_va_list 99; O0-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 100; O0-NEXT: add sp, sp, #80 101; O0-NEXT: ret 102entry: 103 %ap = alloca ptr, align 8 104 call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %ap) 105 call void @llvm.va_start(ptr nonnull %ap) 106 %0 = load ptr, ptr %ap, align 8 107 call void @d_va_list(double %a, ptr %0) 108 call void @llvm.va_end(ptr nonnull %ap) 109 call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %ap) 110 ret void 111} 112 113declare void @d_va_list(double, ptr) 114 115define void @call_f_va() nounwind { 116; DAGISEL-LABEL: call_f_va: 117; DAGISEL: // %bb.0: // %entry 118; DAGISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 119; DAGISEL-NEXT: mov w0, #1065353216 // =0x3f800000 120; DAGISEL-NEXT: mov w1, #2 // =0x2 121; DAGISEL-NEXT: mov x2, #4613937818241073152 // =0x4008000000000000 122; DAGISEL-NEXT: mov w3, #4 // =0x4 123; DAGISEL-NEXT: bl other_f_va_fn 124; DAGISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 125; DAGISEL-NEXT: ret 126; 127; FASTISEL-LABEL: call_f_va: 128; FASTISEL: // %bb.0: // %entry 129; FASTISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 130; FASTISEL-NEXT: mov w0, #1065353216 // =0x3f800000 131; FASTISEL-NEXT: mov w1, #2 // =0x2 132; FASTISEL-NEXT: mov x2, #4613937818241073152 // =0x4008000000000000 133; FASTISEL-NEXT: mov w3, #4 // =0x4 134; FASTISEL-NEXT: bl other_f_va_fn 135; FASTISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 136; FASTISEL-NEXT: ret 137; 138; GISEL-LABEL: call_f_va: 139; GISEL: // %bb.0: // %entry 140; GISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 141; GISEL-NEXT: fmov s0, #1.00000000 142; GISEL-NEXT: fmov w0, s0 143; GISEL-NEXT: mov w1, #2 // =0x2 144; GISEL-NEXT: fmov d0, #3.00000000 145; GISEL-NEXT: fmov x2, d0 146; GISEL-NEXT: mov w3, #4 // =0x4 147; GISEL-NEXT: bl other_f_va_fn 148; GISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 149; GISEL-NEXT: ret 150entry: 151 tail call win64cc void (float, i32, ...) @other_f_va_fn(float 1.000000e+00, i32 2, double 3.000000e+00, i32 4) 152 ret void 153} 154 155declare win64cc void @other_f_va_fn(float, i32, ...) 156 157define void @call_d_va() nounwind { 158; DAGISEL-LABEL: call_d_va: 159; DAGISEL: // %bb.0: // %entry 160; DAGISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 161; DAGISEL-NEXT: mov x0, #4607182418800017408 // =0x3ff0000000000000 162; DAGISEL-NEXT: mov w1, #2 // =0x2 163; DAGISEL-NEXT: mov x2, #4613937818241073152 // =0x4008000000000000 164; DAGISEL-NEXT: mov w3, #4 // =0x4 165; DAGISEL-NEXT: bl other_d_va_fn 166; DAGISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 167; DAGISEL-NEXT: ret 168; 169; FASTISEL-LABEL: call_d_va: 170; FASTISEL: // %bb.0: // %entry 171; FASTISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 172; FASTISEL-NEXT: mov x0, #4607182418800017408 // =0x3ff0000000000000 173; FASTISEL-NEXT: mov w1, #2 // =0x2 174; FASTISEL-NEXT: mov x2, #4613937818241073152 // =0x4008000000000000 175; FASTISEL-NEXT: mov w3, #4 // =0x4 176; FASTISEL-NEXT: bl other_d_va_fn 177; FASTISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 178; FASTISEL-NEXT: ret 179; 180; GISEL-LABEL: call_d_va: 181; GISEL: // %bb.0: // %entry 182; GISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 183; GISEL-NEXT: fmov d0, #1.00000000 184; GISEL-NEXT: fmov x0, d0 185; GISEL-NEXT: mov w1, #2 // =0x2 186; GISEL-NEXT: fmov d0, #3.00000000 187; GISEL-NEXT: fmov x2, d0 188; GISEL-NEXT: mov w3, #4 // =0x4 189; GISEL-NEXT: bl other_d_va_fn 190; GISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 191; GISEL-NEXT: ret 192entry: 193 tail call win64cc void (double, i32, ...) @other_d_va_fn(double 1.000000e+00, i32 2, double 3.000000e+00, i32 4) 194 ret void 195} 196 197declare win64cc void @other_d_va_fn(double, i32, ...) 198 199define void @call_d_non_va() nounwind { 200; DAGISEL-LABEL: call_d_non_va: 201; DAGISEL: // %bb.0: // %entry 202; DAGISEL-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 203; DAGISEL-NEXT: fmov d0, #1.00000000 204; DAGISEL-NEXT: fmov d1, #3.00000000 205; DAGISEL-NEXT: mov w0, #2 // =0x2 206; DAGISEL-NEXT: mov w1, #4 // =0x4 207; DAGISEL-NEXT: bl other_d_non_va_fn 208; DAGISEL-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 209; DAGISEL-NEXT: ret 210; 211; O0-LABEL: call_d_non_va: 212; O0: // %bb.0: // %entry 213; O0-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 214; O0-NEXT: fmov d0, #1.00000000 215; O0-NEXT: mov w0, #2 // =0x2 216; O0-NEXT: fmov d1, #3.00000000 217; O0-NEXT: mov w1, #4 // =0x4 218; O0-NEXT: bl other_d_non_va_fn 219; O0-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 220; O0-NEXT: ret 221entry: 222 tail call win64cc void (double, i32, double, i32) @other_d_non_va_fn(double 1.000000e+00, i32 2, double 3.000000e+00, i32 4) 223 ret void 224} 225 226declare win64cc void @other_d_non_va_fn(double, i32, double, i32) 227