blob: aad287dc3206ca4bc5b9e6ecde47370a556566b8 [file] [log] [blame]
Ulrich Weigand92309972012-10-24 12:22:56 +00001// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s
2// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
Douglas Gregord86c4772010-05-15 06:46:45 +00003
4// Test code generation for the named return value optimization.
5class X {
6public:
7 X();
8 X(const X&);
9 ~X();
10};
11
Stephen Hines6bcf27b2014-05-29 04:14:42 -070012template<typename T> struct Y {
13 Y();
14 static Y f() {
15 Y y;
16 return y;
17 }
18};
19
Stephen Lin93ab6bf2013-08-15 06:47:53 +000020// CHECK-LABEL: define void @_Z5test0v
21// CHECK-EH-LABEL: define void @_Z5test0v
Douglas Gregord86c4772010-05-15 06:46:45 +000022X test0() {
23 X x;
Eli Friedman12e9f8e2011-06-14 21:20:53 +000024 // CHECK: call {{.*}} @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +000025 // CHECK-NEXT: ret void
26
Eli Friedman12e9f8e2011-06-14 21:20:53 +000027 // CHECK-EH: call {{.*}} @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +000028 // CHECK-EH-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000029 return x;
30}
31
Stephen Lin93ab6bf2013-08-15 06:47:53 +000032// CHECK-LABEL: define void @_Z5test1b(
33// CHECK-EH-LABEL: define void @_Z5test1b(
Douglas Gregord86c4772010-05-15 06:46:45 +000034X test1(bool B) {
Eli Friedman12e9f8e2011-06-14 21:20:53 +000035 // CHECK: tail call {{.*}} @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +000036 // CHECK-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000037 X x;
Douglas Gregord86c4772010-05-15 06:46:45 +000038 if (B)
39 return (x);
40 return x;
Eli Friedman12e9f8e2011-06-14 21:20:53 +000041 // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +000042 // CHECK-EH-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000043}
44
Stephen Lin93ab6bf2013-08-15 06:47:53 +000045// CHECK-LABEL: define void @_Z5test2b
46// CHECK-EH-LABEL: define void @_Z5test2b
Douglas Gregord86c4772010-05-15 06:46:45 +000047X test2(bool B) {
John McCallf1549f62010-07-06 01:34:17 +000048 // No NRVO.
49
Douglas Gregord86c4772010-05-15 06:46:45 +000050 X x;
Douglas Gregord86c4772010-05-15 06:46:45 +000051 X y;
Douglas Gregord86c4772010-05-15 06:46:45 +000052 if (B)
53 return y;
Douglas Gregord86c4772010-05-15 06:46:45 +000054 return x;
John McCallf1549f62010-07-06 01:34:17 +000055
Eli Friedman12e9f8e2011-06-14 21:20:53 +000056 // CHECK: call {{.*}} @_ZN1XC1Ev
57 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev
58 // CHECK: call {{.*}} @_ZN1XC1ERKS_
59 // CHECK: call {{.*}} @_ZN1XC1ERKS_
60 // CHECK: call {{.*}} @_ZN1XD1Ev
61 // CHECK: call {{.*}} @_ZN1XD1Ev
Douglas Gregord86c4772010-05-15 06:46:45 +000062 // CHECK: ret void
John McCallf1549f62010-07-06 01:34:17 +000063
64 // The block ordering in the -fexceptions IR is unfortunate.
65
Eli Friedman12e9f8e2011-06-14 21:20:53 +000066 // CHECK-EH: call {{.*}} @_ZN1XC1Ev
67 // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev
John McCallda65ea82010-07-13 20:32:21 +000068 // -> %invoke.cont, %lpad
John McCallf1549f62010-07-06 01:34:17 +000069
John McCallda65ea82010-07-13 20:32:21 +000070 // %invoke.cont:
John McCallf1549f62010-07-06 01:34:17 +000071 // CHECK-EH: br i1
72 // -> %if.then, %if.end
73
74 // %if.then: returning 'x'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000075 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
John McCallda65ea82010-07-13 20:32:21 +000076 // -> %cleanup, %lpad1
John McCallf1549f62010-07-06 01:34:17 +000077
78 // %lpad: landing pad for ctor of 'y', dtor of 'y'
Bill Wendling285cfd82011-09-19 20:31:14 +000079 // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
80 // CHECK-EH-NEXT: cleanup
81 // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
82 // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
John McCallf1549f62010-07-06 01:34:17 +000083 // CHECK-EH-NEXT: br label
84 // -> %eh.cleanup
85
John McCallda65ea82010-07-13 20:32:21 +000086 // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000087 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
John McCallf1549f62010-07-06 01:34:17 +000088 // -> %eh.cleanup, %terminate.lpad
89
90 // %if.end: returning 'y'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000091 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
John McCallda65ea82010-07-13 20:32:21 +000092 // -> %cleanup, %lpad1
John McCallf1549f62010-07-06 01:34:17 +000093
94 // %cleanup: normal cleanup for 'y'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000095 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
John McCallda65ea82010-07-13 20:32:21 +000096 // -> %invoke.cont11, %lpad
97
98 // %invoke.cont11: normal cleanup for 'x'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000099 // CHECK-EH: call {{.*}} @_ZN1XD1Ev
John McCallda65ea82010-07-13 20:32:21 +0000100 // CHECK-EH-NEXT: ret void
John McCallf1549f62010-07-06 01:34:17 +0000101
102 // %eh.cleanup: EH cleanup for 'x'
Eli Friedman12e9f8e2011-06-14 21:20:53 +0000103 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
John McCallda65ea82010-07-13 20:32:21 +0000104 // -> %invoke.cont17, %terminate.lpad
105
106 // %invoke.cont17: rethrow block for %eh.cleanup.
107 // This really should be elsewhere in the function.
Bill Wendling285cfd82011-09-19 20:31:14 +0000108 // CHECK-EH: resume { i8*, i32 }
John McCallf1549f62010-07-06 01:34:17 +0000109
110 // %terminate.lpad: terminate landing pad.
John McCall66b22772013-02-12 03:51:46 +0000111 // CHECK-EH: [[T0:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
Bill Wendling285cfd82011-09-19 20:31:14 +0000112 // CHECK-EH-NEXT: catch i8* null
John McCall66b22772013-02-12 03:51:46 +0000113 // CHECK-EH-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
Bill Wendling4e1125f2013-02-22 09:10:20 +0000114 // CHECK-EH-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
John McCallf1549f62010-07-06 01:34:17 +0000115 // CHECK-EH-NEXT: unreachable
116
Douglas Gregord86c4772010-05-15 06:46:45 +0000117}
118
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700119// CHECK-LABEL: define void @_Z5test3b
Douglas Gregord86c4772010-05-15 06:46:45 +0000120X test3(bool B) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700121 // CHECK: tail call {{.*}} @_ZN1XC1Ev
122 // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_
123 // CHECK: call {{.*}} @_ZN1XC1Ev
124 // CHECK: call {{.*}} @_ZN1XC1ERKS_
125 if (B) {
Douglas Gregord86c4772010-05-15 06:46:45 +0000126 X y;
127 return y;
128 }
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700129 // FIXME: we should NRVO this variable too.
Douglas Gregord86c4772010-05-15 06:46:45 +0000130 X x;
131 return x;
132}
Douglas Gregor3d91bbc2010-05-17 15:52:46 +0000133
134extern "C" void exit(int) throw();
135
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000136// CHECK-LABEL: define void @_Z5test4b
Douglas Gregor3d91bbc2010-05-17 15:52:46 +0000137X test4(bool B) {
138 {
Eli Friedman12e9f8e2011-06-14 21:20:53 +0000139 // CHECK: tail call {{.*}} @_ZN1XC1Ev
Douglas Gregor3d91bbc2010-05-17 15:52:46 +0000140 X x;
141 // CHECK: br i1
142 if (B)
143 return x;
144 }
Eli Friedman12e9f8e2011-06-14 21:20:53 +0000145 // CHECK: tail call {{.*}} @_ZN1XD1Ev
Douglas Gregor3d91bbc2010-05-17 15:52:46 +0000146 // CHECK: tail call void @exit(i32 1)
147 exit(1);
148}
Douglas Gregorf5d8f462011-01-21 18:05:27 +0000149
Anders Carlssone41721e2011-02-19 19:23:03 +0000150#ifdef __EXCEPTIONS
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000151// CHECK-EH-LABEL: define void @_Z5test5
Douglas Gregorf5d8f462011-01-21 18:05:27 +0000152void may_throw();
153X test5() {
154 try {
155 may_throw();
156 } catch (X x) {
Eli Friedman12e9f8e2011-06-14 21:20:53 +0000157 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
Douglas Gregorf5d8f462011-01-21 18:05:27 +0000158 // CHECK-EH: call void @__cxa_end_catch()
159 // CHECK-EH: ret void
160 return x;
161 }
162}
Anders Carlssone41721e2011-02-19 19:23:03 +0000163#endif
John McCall1cd76e82011-11-11 03:57:31 +0000164
165// rdar://problem/10430868
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000166// CHECK-LABEL: define void @_Z5test6v
John McCall1cd76e82011-11-11 03:57:31 +0000167X test6() {
168 X a __attribute__((aligned(8)));
169 return a;
170 // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8
Eli Friedman194428c2011-11-11 23:36:04 +0000171 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]])
Stephen Hines176edba2014-12-01 14:53:08 -0800172 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* dereferenceable({{[0-9]+}}) [[A]])
Eli Friedman194428c2011-11-11 23:36:04 +0000173 // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]])
John McCall1cd76e82011-11-11 03:57:31 +0000174 // CHECK-NEXT: ret void
175}
Bill Wendling4e1125f2013-02-22 09:10:20 +0000176
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700177// CHECK-LABEL: define void @_Z5test7b
178X test7(bool b) {
179 // CHECK: tail call {{.*}} @_ZN1XC1Ev
180 // CHECK-NEXT: ret
181 if (b) {
182 X x;
183 return x;
184 }
185 return X();
186}
187
188// CHECK-LABEL: define void @_Z5test8b
189X test8(bool b) {
190 // CHECK: tail call {{.*}} @_ZN1XC1Ev
191 // CHECK-NEXT: ret
192 if (b) {
193 X x;
194 return x;
195 } else {
196 X y;
197 return y;
198 }
199}
200
201Y<int> test9() {
202 Y<int>::f();
203}
204
205// CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
206// CHECK: tail call {{.*}} @_ZN1YIiEC1Ev
207
Bill Wendling4e1125f2013-02-22 09:10:20 +0000208// CHECK-EH: attributes [[NR_NUW]] = { noreturn nounwind }