1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple x86_64-w64-mingw32 %s -o - | FileCheck %s 3 4declare void @foo(ptr byval({ float, double })) 5@G = external constant { float, double } 6 7define void @bar() { 8; Make sure we're creating a temporary stack slot, rather than just passing 9; the pointer through unmodified. 10; CHECK-LABEL: bar: 11; CHECK: # %bb.0: 12; CHECK-NEXT: subq $56, %rsp 13; CHECK-NEXT: .seh_stackalloc 56 14; CHECK-NEXT: .seh_endprologue 15; CHECK-NEXT: movq .refptr.G(%rip), %rax 16; CHECK-NEXT: movq (%rax), %rcx 17; CHECK-NEXT: movq 8(%rax), %rax 18; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) 19; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) 20; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rcx 21; CHECK-NEXT: callq foo 22; CHECK-NEXT: nop 23; CHECK-NEXT: addq $56, %rsp 24; CHECK-NEXT: retq 25; CHECK-NEXT: .seh_endproc 26 call void @foo(ptr byval({ float, double }) @G) 27 ret void 28} 29 30define void @baz(ptr byval({ float, double }) %arg) { 31; On Win64 the byval is effectively ignored on declarations, since we do 32; pass a real pointer in registers. However, by our semantics if we pass 33; the pointer on to another byval function, we do need to make a copy. 34; CHECK-LABEL: baz: 35; CHECK: # %bb.0: 36; CHECK-NEXT: subq $56, %rsp 37; CHECK-NEXT: .seh_stackalloc 56 38; CHECK-NEXT: .seh_endprologue 39; CHECK-NEXT: movq (%rcx), %rax 40; CHECK-NEXT: movq 8(%rcx), %rcx 41; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) 42; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) 43; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rcx 44; CHECK-NEXT: callq foo 45; CHECK-NEXT: nop 46; CHECK-NEXT: addq $56, %rsp 47; CHECK-NEXT: retq 48; CHECK-NEXT: .seh_endproc 49 call void @foo(ptr byval({ float, double }) %arg) 50 ret void 51} 52 53declare void @foo2(ptr byval({ float, double }), ptr byval({ float, double }), ptr byval({ float, double }), ptr byval({ float, double }), ptr byval({ float, double }), i64 %f) 54@data = external constant { float, double } 55 56define void @test() { 57; CHECK-LABEL: test: 58; CHECK: # %bb.0: 59; CHECK-NEXT: subq $136, %rsp 60; CHECK-NEXT: .seh_stackalloc 136 61; CHECK-NEXT: .seh_endprologue 62; CHECK-NEXT: movq .refptr.G(%rip), %rax 63; CHECK-NEXT: movq (%rax), %rcx 64; CHECK-NEXT: movq 8(%rax), %rax 65; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) 66; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) 67; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) 68; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) 69; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) 70; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) 71; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) 72; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) 73; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) 74; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) 75; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rax 76; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) 77; CHECK-NEXT: movq $10, {{[0-9]+}}(%rsp) 78; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rcx 79; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx 80; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %r8 81; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %r9 82; CHECK-NEXT: callq foo2 83; CHECK-NEXT: nop 84; CHECK-NEXT: addq $136, %rsp 85; CHECK-NEXT: retq 86; CHECK-NEXT: .seh_endproc 87 call void @foo2(ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, i64 10) 88 ret void 89} 90 91define i64 @receive_byval_arg_via_stack_arg(ptr byval(i64), ptr byval(i64), ptr byval(i64), ptr byval(i64), ptr byval(i64) %x) { 92; CHECK-LABEL: receive_byval_arg_via_stack_arg: 93; CHECK: # %bb.0: 94; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax 95; CHECK-NEXT: movq (%rax), %rax 96; CHECK-NEXT: retq 97 %r = load i64, ptr %x 98 ret i64 %r 99} 100