1 | // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm < %s | FileCheck %s |
2 | |
3 | void __attribute__((fastcall)) f1(void); |
4 | void __attribute__((stdcall)) f2(void); |
5 | void __attribute__((thiscall)) f3(void); |
6 | void __attribute__((fastcall)) f4(void) { |
7 | // CHECK-LABEL: define x86_fastcallcc void @f4() |
8 | f1(); |
9 | // CHECK: call x86_fastcallcc void @f1() |
10 | } |
11 | void __attribute__((stdcall)) f5(void) { |
12 | // CHECK-LABEL: define x86_stdcallcc void @f5() |
13 | f2(); |
14 | // CHECK: call x86_stdcallcc void @f2() |
15 | } |
16 | void __attribute__((thiscall)) f6(void) { |
17 | // CHECK-LABEL: define x86_thiscallcc void @f6() |
18 | f3(); |
19 | // CHECK: call x86_thiscallcc void @f3() |
20 | } |
21 | |
22 | // PR5280 |
23 | void (__attribute__((fastcall)) *pf1)(void) = f1; |
24 | void (__attribute__((stdcall)) *pf2)(void) = f2; |
25 | void (__attribute__((thiscall)) *pf3)(void) = f3; |
26 | void (__attribute__((fastcall)) *pf4)(void) = f4; |
27 | void (__attribute__((stdcall)) *pf5)(void) = f5; |
28 | void (__attribute__((thiscall)) *pf6)(void) = f6; |
29 | |
30 | int main(void) { |
31 | f4(); f5(); f6(); |
32 | // CHECK: call x86_fastcallcc void @f4() |
33 | // CHECK: call x86_stdcallcc void @f5() |
34 | // CHECK: call x86_thiscallcc void @f6() |
35 | pf1(); pf2(); pf3(); pf4(); pf5(); pf6(); |
36 | // CHECK: call x86_fastcallcc void %{{.*}}() |
37 | // CHECK: call x86_stdcallcc void %{{.*}}() |
38 | // CHECK: call x86_thiscallcc void %{{.*}}() |
39 | // CHECK: call x86_fastcallcc void %{{.*}}() |
40 | // CHECK: call x86_stdcallcc void %{{.*}}() |
41 | // CHECK: call x86_thiscallcc void %{{.*}}() |
42 | return 0; |
43 | } |
44 | |
45 | // PR7117 |
46 | void __attribute((stdcall)) f7(foo) int foo; {} |
47 | void f8(void) { |
48 | f7(0); |
49 | // CHECK: call x86_stdcallcc void @f7(i32 0) |
50 | } |
51 | |
52 | void __attribute__((fastcall)) foo1(int y); |
53 | void bar1(int y) { |
54 | // CHECK-LABEL: define void @bar1 |
55 | // CHECK: call x86_fastcallcc void @foo1(i32 inreg % |
56 | foo1(y); |
57 | } |
58 | |
59 | struct S1 { |
60 | int x; |
61 | }; |
62 | void __attribute__((fastcall)) foo2(struct S1 y); |
63 | void bar2(struct S1 y) { |
64 | // CHECK-LABEL: define void @bar2 |
65 | // CHECK: call x86_fastcallcc void @foo2(i32 inreg undef, i32 % |
66 | foo2(y); |
67 | } |
68 | |
69 | void __attribute__((fastcall)) foo3(int *y); |
70 | void bar3(int *y) { |
71 | // CHECK-LABEL: define void @bar3 |
72 | // CHECK: call x86_fastcallcc void @foo3(i32* inreg % |
73 | foo3(y); |
74 | } |
75 | |
76 | enum Enum {Eval}; |
77 | void __attribute__((fastcall)) foo4(enum Enum y); |
78 | void bar4(enum Enum y) { |
79 | // CHECK-LABEL: define void @bar4 |
80 | // CHECK: call x86_fastcallcc void @foo4(i32 inreg % |
81 | foo4(y); |
82 | } |
83 | |
84 | struct S2 { |
85 | int x1; |
86 | double x2; |
87 | double x3; |
88 | }; |
89 | void __attribute__((fastcall)) foo5(struct S2 y); |
90 | void bar5(struct S2 y) { |
91 | // CHECK-LABEL: define void @bar5 |
92 | // CHECK: call x86_fastcallcc void @foo5(%struct.S2* byval align 4 % |
93 | foo5(y); |
94 | } |
95 | |
96 | void __attribute__((fastcall)) foo6(long long y); |
97 | void bar6(long long y) { |
98 | // CHECK-LABEL: define void @bar6 |
99 | // CHECK: call x86_fastcallcc void @foo6(i64 % |
100 | foo6(y); |
101 | } |
102 | |
103 | void __attribute__((fastcall)) foo7(int a, struct S1 b, int c); |
104 | void bar7(int a, struct S1 b, int c) { |
105 | // CHECK-LABEL: define void @bar7 |
106 | // CHECK: call x86_fastcallcc void @foo7(i32 inreg %{{.*}}, i32 %{{.*}}, i32 %{{.*}} |
107 | foo7(a, b, c); |
108 | } |
109 | |
110 | void __attribute__((fastcall)) foo8(struct S1 a, int b); |
111 | void bar8(struct S1 a, int b) { |
112 | // CHECK-LABEL: define void @bar8 |
113 | // CHECK: call x86_fastcallcc void @foo8(i32 inreg undef, i32 %{{.*}}, i32 inreg % |
114 | foo8(a, b); |
115 | } |
116 | |
117 | void __attribute__((fastcall)) foo9(struct S2 a, int b); |
118 | void bar9(struct S2 a, int b) { |
119 | // CHECK-LABEL: define void @bar9 |
120 | // CHECK: call x86_fastcallcc void @foo9(%struct.S2* byval align 4 %{{.*}}, i32 % |
121 | foo9(a, b); |
122 | } |
123 | |
124 | void __attribute__((fastcall)) foo10(float y, int x); |
125 | void bar10(float y, int x) { |
126 | // CHECK-LABEL: define void @bar10 |
127 | // CHECK: call x86_fastcallcc void @foo10(float %{{.*}}, i32 inreg % |
128 | foo10(y, x); |
129 | } |
130 | |
131 | void __attribute__((fastcall)) foo11(double y, int x); |
132 | void bar11(double y, int x) { |
133 | // CHECK-LABEL: define void @bar11 |
134 | // CHECK: call x86_fastcallcc void @foo11(double %{{.*}}, i32 inreg % |
135 | foo11(y, x); |
136 | } |
137 | |
138 | struct S3 { |
139 | float x; |
140 | }; |
141 | void __attribute__((fastcall)) foo12(struct S3 y, int x); |
142 | void bar12(struct S3 y, int x) { |
143 | // CHECK-LABEL: define void @bar12 |
144 | // CHECK: call x86_fastcallcc void @foo12(float %{{.*}}, i32 inreg % |
145 | foo12(y, x); |
146 | } |
147 | |