1; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s 2 3%struct.__va_list_tag = type { i32, i32, ptr, ptr } 4 5declare void @llvm.va_end(ptr) #0 6declare void @llvm.va_start(ptr) #10 7 8define void @hardf(ptr %fmt, ...) #1 { 9; CHECK-LABEL: hardf 10; When using XMM registers to pass floating-point parameters, 11; we need to spill those for va_start. 12; CHECK: testb %al, %al 13; CHECK: movaps %xmm0, {{.*}}%rsp 14; CHECK: movaps %xmm1, {{.*}}%rsp 15; CHECK: movaps %xmm2, {{.*}}%rsp 16; CHECK: movaps %xmm3, {{.*}}%rsp 17; CHECK: movaps %xmm4, {{.*}}%rsp 18; CHECK: movaps %xmm5, {{.*}}%rsp 19; CHECK: movaps %xmm6, {{.*}}%rsp 20; CHECK: movaps %xmm7, {{.*}}%rsp 21 %va = alloca [1 x %struct.__va_list_tag], align 16 22 call void @llvm.va_start(ptr %va) 23 call void @llvm.va_end(ptr nonnull %va) 24 ret void 25} 26 27define void @softf(ptr %fmt, ...) #2 { 28; CHECK-LABEL: softf 29; For software floating point, floats are passed in general 30; purpose registers, so no need to spill XMM registers. 31; CHECK-NOT: %xmm 32; CHECK: retq 33 %va = alloca [1 x %struct.__va_list_tag], align 16 34 call void @llvm.va_start(ptr %va) 35 call void @llvm.va_end(ptr nonnull %va) 36 ret void 37} 38 39define void @noimplf(ptr %fmt, ...) #3 { 40; CHECK-LABEL: noimplf 41; Even with noimplicitfloat, when using the hardware float API, we 42; need to emit code to spill the XMM registers (PR36507). 43; CHECK: testb %al, %al 44; CHECK: movaps %xmm0, {{.*}}%rsp 45; CHECK: movaps %xmm1, {{.*}}%rsp 46; CHECK: movaps %xmm2, {{.*}}%rsp 47; CHECK: movaps %xmm3, {{.*}}%rsp 48; CHECK: movaps %xmm4, {{.*}}%rsp 49; CHECK: movaps %xmm5, {{.*}}%rsp 50; CHECK: movaps %xmm6, {{.*}}%rsp 51; CHECK: movaps %xmm7, {{.*}}%rsp 52 %va = alloca [1 x %struct.__va_list_tag], align 16 53 call void @llvm.va_start(ptr %va) 54 call void @llvm.va_end(ptr nonnull %va) 55 ret void 56} 57 58define void @noimplsoftf(ptr %fmt, ...) #4 { 59; CHECK-LABEL: noimplsoftf 60; Combining noimplicitfloat and use-soft-float should not assert (PR48528). 61; CHECK-NOT: %xmm 62; CHECK: retq 63 %va = alloca [1 x %struct.__va_list_tag], align 16 64 call void @llvm.va_start(ptr %va) 65 call void @llvm.va_end(ptr nonnull %va) 66 ret void 67} 68 69attributes #0 = { nounwind } 70attributes #1 = { nounwind uwtable } 71attributes #2 = { nounwind uwtable "use-soft-float"="true" } 72attributes #3 = { noimplicitfloat nounwind uwtable } 73attributes #4 = { noimplicitfloat nounwind uwtable "use-soft-float"="true" } 74