1 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fno-experimental-new-pass-manager -o - %s | FileCheck %s
2 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fno-experimental-new-pass-manager -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s
3 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fno-experimental-new-pass-manager -fcxx-exceptions -fexceptions -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s
4 
5 // Test code generation for the named return value optimization.
6 class X {
7 public:
8   X();
9   X(const X&);
10   ~X();
11 };
12 
13 template<typename T> struct Y {
14   Y();
fY15   static Y f() {
16     Y y;
17     return y;
18   }
19 };
20 
21 // CHECK-LABEL: define void @_Z5test0v
22 // CHECK-EH-LABEL: define void @_Z5test0v
test0()23 X test0() {
24   X x;
25   // CHECK:          call {{.*}} @_ZN1XC1Ev
26   // CHECK-NEXT:     ret void
27 
28   // CHECK-EH:       call {{.*}} @_ZN1XC1Ev
29   // CHECK-EH-NEXT:  ret void
30   return x;
31 }
32 
33 // CHECK-LABEL: define void @_Z5test1b(
34 // CHECK-EH-LABEL: define void @_Z5test1b(
test1(bool B)35 X test1(bool B) {
36   // CHECK:      call {{.*}} @_ZN1XC1Ev
37   // CHECK-NEXT: ret void
38   X x;
39   if (B)
40     return (x);
41   return x;
42   // CHECK-EH:      call {{.*}} @_ZN1XC1Ev
43   // CHECK-EH-NEXT: ret void
44 }
45 
46 // CHECK-LABEL: define void @_Z5test2b
47 // CHECK-EH-LABEL: define void @_Z5test2b
48 // CHECK-EH-SAME:  personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
test2(bool B)49 X test2(bool B) {
50   // No NRVO.
51 
52   X x;
53   X y;
54   if (B)
55     return y;
56   return x;
57 
58   // CHECK: call {{.*}} @_ZN1XC1Ev
59   // CHECK-NEXT: {{.*}} getelementptr inbounds %class.X, %class.X* %y, i32 0, i32 0
60   // CHECK-NEXT: call void @llvm.lifetime.start
61   // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev
62   // CHECK: call {{.*}} @_ZN1XC1ERKS_
63   // CHECK: call {{.*}} @_ZN1XD1Ev
64   // CHECK-NEXT: call void @llvm.lifetime.end
65   // CHECK: call {{.*}} @_ZN1XD1Ev
66   // CHECK-NEXT: call void @llvm.lifetime.end
67   // CHECK: ret void
68 
69   // The block ordering in the -fexceptions IR is unfortunate.
70 
71   // CHECK-EH:      call void @llvm.lifetime.start
72   // CHECK-EH-NEXT: call {{.*}} @_ZN1XC1Ev
73   // CHECK-EH:      call void @llvm.lifetime.start
74   // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev
75   // -> %invoke.cont, %lpad
76 
77   // %invoke.cont:
78   // CHECK-EH:      br i1
79   // -> %if.then, %if.end
80 
81   // %if.then: returning 'x'
82   // CHECK-EH:      invoke {{.*}} @_ZN1XC1ERKS_
83   // -> %cleanup, %lpad1
84 
85   // %lpad: landing pad for ctor of 'y', dtor of 'y'
86   // CHECK-EH:      [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 }
87   // CHECK-EH-NEXT:   cleanup
88   // CHECK-EH-NEXT: br label
89   // -> %eh.cleanup
90 
91   // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
92   // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
93   // -> %eh.cleanup, %terminate.lpad
94   // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
95 
96   // %if.end: returning 'y'
97   // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
98   // -> %cleanup, %lpad1
99 
100   // %cleanup: normal cleanup for 'y'
101   // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
102   // -> %invoke.cont11, %lpad
103   // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
104 
105   // %invoke.cont11: normal cleanup for 'x'
106   // CHECK-EH:      call void @llvm.lifetime.end
107   // CHECK-EH-NEXT: call {{.*}} @_ZN1XD1Ev
108   // CHECK-EH-NEXT: call void @llvm.lifetime.end
109   // CHECK-EH-NEXT: ret void
110 
111   // %eh.cleanup:  EH cleanup for 'x'
112   // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
113   // -> %invoke.cont17, %terminate.lpad
114   // CHECK-EH-11: call   {{.*}} @_ZN1XD1Ev
115 
116   // %invoke.cont17: rethrow block for %eh.cleanup.
117   // This really should be elsewhere in the function.
118   // CHECK-EH:      resume { i8*, i32 }
119 
120   // %terminate.lpad: terminate landing pad.
121   // CHECK-EH-03:      [[T0:%.*]] = landingpad { i8*, i32 }
122   // CHECK-EH-03-NEXT:   catch i8* null
123   // CHECK-EH-03-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
124   // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
125   // CHECK-EH-03-NEXT: unreachable
126 
127 }
128 
129 // CHECK-LABEL: define void @_Z5test3b
test3(bool B)130 X test3(bool B) {
131   // CHECK: call {{.*}} @_ZN1XC1Ev
132   // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_
133   // CHECK: call {{.*}} @_ZN1XC1Ev
134   // CHECK: call {{.*}} @_ZN1XC1ERKS_
135   if (B) {
136     X y;
137     return y;
138   }
139   // FIXME: we should NRVO this variable too.
140   X x;
141   return x;
142 }
143 
144 extern "C" void exit(int) throw();
145 
146 // CHECK-LABEL: define void @_Z5test4b
test4(bool B)147 X test4(bool B) {
148   {
149     // CHECK: call {{.*}} @_ZN1XC1Ev
150     X x;
151     // CHECK: br i1
152     if (B)
153       return x;
154   }
155   // CHECK: call {{.*}} @_ZN1XD1Ev
156   // CHECK: call void @exit(i32 1)
157   exit(1);
158 }
159 
160 #ifdef __EXCEPTIONS
161 // CHECK-EH-LABEL: define void @_Z5test5
162 void may_throw();
test5()163 X test5() {
164   try {
165     may_throw();
166   } catch (X x) {
167     // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
168     // CHECK-EH: call void @__cxa_end_catch()
169     // CHECK-EH: ret void
170     return x;
171   }
172 }
173 #endif
174 
175 // rdar://problem/10430868
176 // CHECK-LABEL: define void @_Z5test6v
test6()177 X test6() {
178   X a __attribute__((aligned(8)));
179   return a;
180   // CHECK:      [[A:%.*]] = alloca [[X:%.*]], align 8
181   // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds %class.X, %class.X* [[A]], i32 0, i32 0
182   // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[PTR]])
183   // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* nonnull [[A]])
184   // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[A]])
185   // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* nonnull [[A]])
186   // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[PTR]])
187   // CHECK-NEXT: ret void
188 }
189 
190 // CHECK-LABEL: define void @_Z5test7b
test7(bool b)191 X test7(bool b) {
192   // CHECK: call {{.*}} @_ZN1XC1Ev
193   // CHECK-NEXT: ret
194   if (b) {
195     X x;
196     return x;
197   }
198   return X();
199 }
200 
201 // CHECK-LABEL: define void @_Z5test8b
test8(bool b)202 X test8(bool b) {
203   // CHECK: call {{.*}} @_ZN1XC1Ev
204   // CHECK-NEXT: ret
205   if (b) {
206     X x;
207     return x;
208   } else {
209     X y;
210     return y;
211   }
212 }
213 
test9()214 Y<int> test9() {
215   Y<int>::f();
216 }
217 
218 // CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
219 // CHECK: call {{.*}} @_ZN1YIiEC1Ev
220 
221 // CHECK-EH-03: attributes [[NR_NUW]] = { noreturn nounwind }
222