Aaron Ballman | 82bfa19 | 2012-10-02 14:26:08 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm < %s | FileCheck %s |
Anton Korobeynikov | f1c9c09 | 2008-11-11 20:21:14 +0000 | [diff] [blame] | 2 | |
| 3 | void __attribute__((fastcall)) f1(void); |
| 4 | void __attribute__((stdcall)) f2(void); |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 5 | void __attribute__((thiscall)) f3(void); |
| 6 | void __attribute__((fastcall)) f4(void) { |
| 7 | // CHECK: define x86_fastcallcc void @f4() |
Anton Korobeynikov | f1c9c09 | 2008-11-11 20:21:14 +0000 | [diff] [blame] | 8 | f1(); |
Charles Davis | d82bf2d | 2010-02-05 20:45:48 +0000 | [diff] [blame] | 9 | // CHECK: call x86_fastcallcc void @f1() |
Anton Korobeynikov | f1c9c09 | 2008-11-11 20:21:14 +0000 | [diff] [blame] | 10 | } |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 11 | void __attribute__((stdcall)) f5(void) { |
| 12 | // CHECK: define x86_stdcallcc void @f5() |
Anton Korobeynikov | f1c9c09 | 2008-11-11 20:21:14 +0000 | [diff] [blame] | 13 | f2(); |
Charles Davis | d82bf2d | 2010-02-05 20:45:48 +0000 | [diff] [blame] | 14 | // CHECK: call x86_stdcallcc void @f2() |
Anton Korobeynikov | f1c9c09 | 2008-11-11 20:21:14 +0000 | [diff] [blame] | 15 | } |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 16 | void __attribute__((thiscall)) f6(void) { |
| 17 | // CHECK: define x86_thiscallcc void @f6() |
| 18 | f3(); |
| 19 | // CHECK: call x86_thiscallcc void @f3() |
| 20 | } |
Anton Korobeynikov | f1c9c09 | 2008-11-11 20:21:14 +0000 | [diff] [blame] | 21 | |
Charles Davis | 16c4f3c | 2010-02-05 18:13:10 +0000 | [diff] [blame] | 22 | // PR5280 |
| 23 | void (__attribute__((fastcall)) *pf1)(void) = f1; |
| 24 | void (__attribute__((stdcall)) *pf2)(void) = f2; |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 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; |
Charles Davis | 16c4f3c | 2010-02-05 18:13:10 +0000 | [diff] [blame] | 29 | |
Anton Korobeynikov | f1c9c09 | 2008-11-11 20:21:14 +0000 | [diff] [blame] | 30 | int main(void) { |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 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(); |
John McCall | 04a67a6 | 2010-02-05 21:31:56 +0000 | [diff] [blame] | 36 | // CHECK: call x86_fastcallcc void %{{.*}}() |
| 37 | // CHECK: call x86_stdcallcc void %{{.*}}() |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 38 | // CHECK: call x86_thiscallcc void %{{.*}}() |
John McCall | 04a67a6 | 2010-02-05 21:31:56 +0000 | [diff] [blame] | 39 | // CHECK: call x86_fastcallcc void %{{.*}}() |
| 40 | // CHECK: call x86_stdcallcc void %{{.*}}() |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 41 | // CHECK: call x86_thiscallcc void %{{.*}}() |
Anton Korobeynikov | f1c9c09 | 2008-11-11 20:21:14 +0000 | [diff] [blame] | 42 | return 0; |
| 43 | } |
| 44 | |
Eli Friedman | 9a0fcfe | 2010-05-17 02:50:18 +0000 | [diff] [blame] | 45 | // PR7117 |
Douglas Gregor | f813a2c | 2010-05-18 16:57:00 +0000 | [diff] [blame] | 46 | void __attribute((stdcall)) f7(foo) int foo; {} |
| 47 | void f8(void) { |
| 48 | f7(0); |
John McCall | 01f151e | 2011-09-21 08:08:30 +0000 | [diff] [blame] | 49 | // CHECK: call x86_stdcallcc void @f7(i32 0) |
Eli Friedman | 9a0fcfe | 2010-05-17 02:50:18 +0000 | [diff] [blame] | 50 | } |
Rafael Espindola | b693269 | 2012-10-24 01:58:58 +0000 | [diff] [blame] | 51 | |
| 52 | void __attribute__((fastcall)) foo1(int y); |
| 53 | void bar1(int y) { |
| 54 | // CHECK: 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: define void @bar2 |
Rafael Espindola | e4aeeaa | 2012-10-24 01:59:00 +0000 | [diff] [blame] | 65 | // CHECK: call x86_fastcallcc void @foo2(i32 inreg undef, i32 % |
Rafael Espindola | b693269 | 2012-10-24 01:58:58 +0000 | [diff] [blame] | 66 | foo2(y); |
| 67 | } |
| 68 | |
| 69 | void __attribute__((fastcall)) foo3(int *y); |
| 70 | void bar3(int *y) { |
| 71 | // CHECK: 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: 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: 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: 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: 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: define void @bar8 |
Rafael Espindola | e4aeeaa | 2012-10-24 01:59:00 +0000 | [diff] [blame] | 113 | // CHECK: call x86_fastcallcc void @foo8(i32 inreg undef, i32 %{{.*}}, i32 inreg % |
Rafael Espindola | b693269 | 2012-10-24 01:58:58 +0000 | [diff] [blame] | 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: 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: 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: 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: define void @bar12 |
| 144 | // CHECK: call x86_fastcallcc void @foo12(float %{{.*}}, i32 inreg % |
| 145 | foo12(y, x); |
| 146 | } |