1176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
2176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=X64
3176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall v1(int a, int b) {}
5176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01v1@@8"(i32 inreg %a, i32 inreg %b)
6176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01v1@@16"(i32 %a, i32 %b)
7176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
8176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall v2(char a, char b) {}
9176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01v2@@8"(i8 inreg signext %a, i8 inreg signext %b)
10176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01v2@@16"(i8 %a, i8 %b)
11176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
12176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct Small { int a; };
13176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall v3(int a, struct Small b, int c) {}
14176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01v3@@12"(i32 inreg %a, %struct.Small* byval align 4 %b, i32 inreg %c)
15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01v3@@24"(i32 %a, i32 %b.coerce, i32 %c)
16176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
17176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct Large { int a[5]; };
18176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall v4(int a, struct Large b, int c) {}
19176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01v4@@28"(i32 inreg %a, %struct.Large* byval align 4 %b, i32 inreg %c)
20176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01v4@@40"(i32 %a, %struct.Large* %b, i32 %c)
21176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
22176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct HFA2 { double x, y; };
23176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct HFA4 { double w, x, y, z; };
24176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct HFA5 { double v, w, x, y, z; };
25176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
26176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall hfa1(int a, struct HFA4 b, int c) {}
27176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01hfa1@@40"(i32 inreg %a, double %b.0, double %b.1, double %b.2, double %b.3, i32 inreg %c)
28176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01hfa1@@48"(i32 %a, double %b.0, double %b.1, double %b.2, double %b.3, i32 %c)
29176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
30176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// HFAs that would require more than six total SSE registers are passed
31176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// indirectly. Additional vector arguments can consume the rest of the SSE
32176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// registers.
33176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall hfa2(struct HFA4 a, struct HFA4 b, double c) {}
34176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01hfa2@@72"(double %a.0, double %a.1, double %a.2, double %a.3, %struct.HFA4* inreg %b, double %c)
35176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01hfa2@@72"(double %a.0, double %a.1, double %a.2, double %a.3, %struct.HFA4* align 8 %b, double %c)
36176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
37176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Ensure that we pass builtin types directly while counting them against the
38176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// SSE register usage.
39176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall hfa3(double a, double b, double c, double d, double e, struct HFA2 f) {}
40176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01hfa3@@56"(double %a, double %b, double %c, double %d, double %e, %struct.HFA2* inreg %f)
41176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01hfa3@@56"(double %a, double %b, double %c, double %d, double %e, %struct.HFA2* align 8 %f)
42176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
43176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Aggregates with more than four elements are not HFAs and are passed byval.
44176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Because they are not classified as homogeneous, they don't get special
45176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// handling to ensure alignment.
46176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall hfa4(struct HFA5 a) {}
47176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01hfa4@@40"(%struct.HFA5* byval align 4)
48176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01hfa4@@40"(%struct.HFA5* %a)
49176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
50176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Return HFAs of 4 or fewer elements in registers.
51176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic struct HFA2 g_hfa2;
52176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct HFA2 __vectorcall hfa5(void) { return g_hfa2; }
53176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc %struct.HFA2 @"\01hfa5@@0"()
54176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc %struct.HFA2 @"\01hfa5@@0"()
55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestypedef float __attribute__((vector_size(16))) v4f32;
57176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct HVA2 { v4f32 x, y; };
58176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct HVA4 { v4f32 w, x, y, z; };
59176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall hva1(int a, struct HVA4 b, int c) {}
61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01hva1@@72"(i32 inreg %a, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, i32 inreg %c)
62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01hva1@@80"(i32 %a, <4 x float> %b.0, <4 x float> %b.1, <4 x float> %b.2, <4 x float> %b.3, i32 %c)
63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall hva2(struct HVA4 a, struct HVA4 b, v4f32 c) {}
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01hva2@@144"(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, %struct.HVA4* inreg %b, <4 x float> %c)
66176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01hva2@@144"(<4 x float> %a.0, <4 x float> %a.1, <4 x float> %a.2, <4 x float> %a.3, %struct.HVA4* align 16 %b, <4 x float> %c)
67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
68176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall hva3(v4f32 a, v4f32 b, v4f32 c, v4f32 d, v4f32 e, struct HVA2 f) {}
69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01hva3@@112"(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, <4 x float> %e, %struct.HVA2* inreg %f)
70176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01hva3@@112"(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, <4 x float> %e, %struct.HVA2* align 16 %f)
71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestypedef float __attribute__((ext_vector_type(3))) v3f32;
73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct OddSizeHVA { v3f32 x, y; };
74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
75176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid __vectorcall odd_size_hva(struct OddSizeHVA a) {}
76176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: define x86_vectorcallcc void @"\01odd_size_hva@@32"(<3 x float> %a.0, <3 x float> %a.1)
77176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// X64: define x86_vectorcallcc void @"\01odd_size_hva@@32"(<3 x float> %a.0, <3 x float> %a.1)
78