blob: 747ab6db63eb38771732af981e4a179a5875ac0d [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
12// CHECK: define void @_Z5test0v
Douglas Gregorb5b30b92010-05-15 16:39:56 +000013// CHECK-EH: define void @_Z5test0v
Douglas Gregord86c4772010-05-15 06:46:45 +000014X test0() {
15 X x;
Eli Friedman12e9f8e2011-06-14 21:20:53 +000016 // CHECK: call {{.*}} @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +000017 // CHECK-NEXT: ret void
18
Eli Friedman12e9f8e2011-06-14 21:20:53 +000019 // CHECK-EH: call {{.*}} @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +000020 // CHECK-EH-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000021 return x;
22}
23
24// CHECK: define void @_Z5test1b(
John McCallf1549f62010-07-06 01:34:17 +000025// CHECK-EH: define void @_Z5test1b(
Douglas Gregord86c4772010-05-15 06:46:45 +000026X test1(bool B) {
Eli Friedman12e9f8e2011-06-14 21:20:53 +000027 // CHECK: tail call {{.*}} @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +000028 // CHECK-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000029 X x;
Douglas Gregord86c4772010-05-15 06:46:45 +000030 if (B)
31 return (x);
32 return x;
Eli Friedman12e9f8e2011-06-14 21:20:53 +000033 // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +000034 // CHECK-EH-NEXT: ret void
Douglas Gregord86c4772010-05-15 06:46:45 +000035}
36
37// CHECK: define void @_Z5test2b
Douglas Gregorb5b30b92010-05-15 16:39:56 +000038// CHECK-EH: define void @_Z5test2b
Douglas Gregord86c4772010-05-15 06:46:45 +000039X test2(bool B) {
John McCallf1549f62010-07-06 01:34:17 +000040 // No NRVO.
41
Douglas Gregord86c4772010-05-15 06:46:45 +000042 X x;
Douglas Gregord86c4772010-05-15 06:46:45 +000043 X y;
Douglas Gregord86c4772010-05-15 06:46:45 +000044 if (B)
45 return y;
Douglas Gregord86c4772010-05-15 06:46:45 +000046 return x;
John McCallf1549f62010-07-06 01:34:17 +000047
Eli Friedman12e9f8e2011-06-14 21:20:53 +000048 // CHECK: call {{.*}} @_ZN1XC1Ev
49 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev
50 // CHECK: call {{.*}} @_ZN1XC1ERKS_
51 // CHECK: call {{.*}} @_ZN1XC1ERKS_
52 // CHECK: call {{.*}} @_ZN1XD1Ev
53 // CHECK: call {{.*}} @_ZN1XD1Ev
Douglas Gregord86c4772010-05-15 06:46:45 +000054 // CHECK: ret void
John McCallf1549f62010-07-06 01:34:17 +000055
56 // The block ordering in the -fexceptions IR is unfortunate.
57
Eli Friedman12e9f8e2011-06-14 21:20:53 +000058 // CHECK-EH: call {{.*}} @_ZN1XC1Ev
59 // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev
John McCallda65ea82010-07-13 20:32:21 +000060 // -> %invoke.cont, %lpad
John McCallf1549f62010-07-06 01:34:17 +000061
John McCallda65ea82010-07-13 20:32:21 +000062 // %invoke.cont:
John McCallf1549f62010-07-06 01:34:17 +000063 // CHECK-EH: br i1
64 // -> %if.then, %if.end
65
66 // %if.then: returning 'x'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000067 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
John McCallda65ea82010-07-13 20:32:21 +000068 // -> %cleanup, %lpad1
John McCallf1549f62010-07-06 01:34:17 +000069
70 // %lpad: landing pad for ctor of 'y', dtor of 'y'
Bill Wendling285cfd82011-09-19 20:31:14 +000071 // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
72 // CHECK-EH-NEXT: cleanup
73 // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
74 // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
John McCallf1549f62010-07-06 01:34:17 +000075 // CHECK-EH-NEXT: br label
76 // -> %eh.cleanup
77
John McCallda65ea82010-07-13 20:32:21 +000078 // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000079 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
John McCallf1549f62010-07-06 01:34:17 +000080 // -> %eh.cleanup, %terminate.lpad
81
82 // %if.end: returning 'y'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000083 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
John McCallda65ea82010-07-13 20:32:21 +000084 // -> %cleanup, %lpad1
John McCallf1549f62010-07-06 01:34:17 +000085
86 // %cleanup: normal cleanup for 'y'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000087 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
John McCallda65ea82010-07-13 20:32:21 +000088 // -> %invoke.cont11, %lpad
89
90 // %invoke.cont11: normal cleanup for 'x'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000091 // CHECK-EH: call {{.*}} @_ZN1XD1Ev
John McCallda65ea82010-07-13 20:32:21 +000092 // CHECK-EH-NEXT: ret void
John McCallf1549f62010-07-06 01:34:17 +000093
94 // %eh.cleanup: EH cleanup for 'x'
Eli Friedman12e9f8e2011-06-14 21:20:53 +000095 // CHECK-EH: invoke {{.*}} @_ZN1XD1Ev
John McCallda65ea82010-07-13 20:32:21 +000096 // -> %invoke.cont17, %terminate.lpad
97
98 // %invoke.cont17: rethrow block for %eh.cleanup.
99 // This really should be elsewhere in the function.
Bill Wendling285cfd82011-09-19 20:31:14 +0000100 // CHECK-EH: resume { i8*, i32 }
John McCallf1549f62010-07-06 01:34:17 +0000101
102 // %terminate.lpad: terminate landing pad.
John McCall66b22772013-02-12 03:51:46 +0000103 // CHECK-EH: [[T0:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
Bill Wendling285cfd82011-09-19 20:31:14 +0000104 // CHECK-EH-NEXT: catch i8* null
John McCall66b22772013-02-12 03:51:46 +0000105 // CHECK-EH-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
Bill Wendling4e1125f2013-02-22 09:10:20 +0000106 // CHECK-EH-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
John McCallf1549f62010-07-06 01:34:17 +0000107 // CHECK-EH-NEXT: unreachable
108
Douglas Gregord86c4772010-05-15 06:46:45 +0000109}
110
111X test3(bool B) {
112 // FIXME: We don't manage to apply NRVO here, although we could.
113 {
114 X y;
115 return y;
116 }
117 X x;
118 return x;
119}
Douglas Gregor3d91bbc2010-05-17 15:52:46 +0000120
121extern "C" void exit(int) throw();
122
123// CHECK: define void @_Z5test4b
124X test4(bool B) {
125 {
Eli Friedman12e9f8e2011-06-14 21:20:53 +0000126 // CHECK: tail call {{.*}} @_ZN1XC1Ev
Douglas Gregor3d91bbc2010-05-17 15:52:46 +0000127 X x;
128 // CHECK: br i1
129 if (B)
130 return x;
131 }
Eli Friedman12e9f8e2011-06-14 21:20:53 +0000132 // CHECK: tail call {{.*}} @_ZN1XD1Ev
Douglas Gregor3d91bbc2010-05-17 15:52:46 +0000133 // CHECK: tail call void @exit(i32 1)
134 exit(1);
135}
Douglas Gregorf5d8f462011-01-21 18:05:27 +0000136
Anders Carlssone41721e2011-02-19 19:23:03 +0000137#ifdef __EXCEPTIONS
Douglas Gregorf5d8f462011-01-21 18:05:27 +0000138// CHECK-EH: define void @_Z5test5
139void may_throw();
140X test5() {
141 try {
142 may_throw();
143 } catch (X x) {
Eli Friedman12e9f8e2011-06-14 21:20:53 +0000144 // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
Douglas Gregorf5d8f462011-01-21 18:05:27 +0000145 // CHECK-EH: call void @__cxa_end_catch()
146 // CHECK-EH: ret void
147 return x;
148 }
149}
Anders Carlssone41721e2011-02-19 19:23:03 +0000150#endif
John McCall1cd76e82011-11-11 03:57:31 +0000151
152// rdar://problem/10430868
153// CHECK: define void @_Z5test6v
154X test6() {
155 X a __attribute__((aligned(8)));
156 return a;
157 // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8
Eli Friedman194428c2011-11-11 23:36:04 +0000158 // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]])
159 // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]])
160 // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]])
John McCall1cd76e82011-11-11 03:57:31 +0000161 // CHECK-NEXT: ret void
162}
Bill Wendling4e1125f2013-02-22 09:10:20 +0000163
164// CHECK-EH: attributes [[NR_NUW]] = { noreturn nounwind }