1 // REQUIRES: amdgpu-registered-target
2 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O2 -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,CHECK-NOOPT
3 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O2 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT
4 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=amdgcn-amd-amdhsa -O2 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT
5
6 namespace {
7
8 static int ctorcalls;
9 static int dtorcalls;
10
11 struct A {
A__anon49fae3590111::A12 A() : i(0) { ctorcalls++; }
~A__anon49fae3590111::A13 ~A() { dtorcalls++; }
14 int i;
15
operator <<(const A & a,int n)16 friend const A& operator<<(const A& a, int n) {
17 return a;
18 }
19 };
20
g(int)21 void g(int) { }
g(const A &)22 void g(const A&) { }
23
f1(bool b)24 void f1(bool b) {
25 g(b ? A().i : 0);
26 g(b || A().i);
27 g(b && A().i);
28 g(b ? A() << 1 : A() << 2);
29 }
30
31 struct Checker {
Checker__anon49fae3590111::Checker32 Checker() {
33 f1(true);
34 f1(false);
35 }
36 };
37
38 Checker c;
39
40 }
41
42 // CHECK-OPT-LABEL: define{{.*}} i32 @_Z12getCtorCallsv()
getCtorCalls()43 int getCtorCalls() {
44 // CHECK-OPT: ret i32 5
45 return ctorcalls;
46 }
47
48 // CHECK-OPT-LABEL: define{{.*}} i32 @_Z12getDtorCallsv()
getDtorCalls()49 int getDtorCalls() {
50 // CHECK-OPT: ret i32 5
51 return dtorcalls;
52 }
53
54 // CHECK-OPT-LABEL: define{{.*}} zeroext i1 @_Z7successv()
success()55 bool success() {
56 // CHECK-OPT: ret i1 true
57 return ctorcalls == dtorcalls;
58 }
59
60 struct X { ~X(); int f(); };
61 int g(int, int, int);
62 // CHECK-LABEL: @_Z16lifetime_nontriv
lifetime_nontriv(bool cond)63 int lifetime_nontriv(bool cond) {
64 // CHECK-NOOPT: store i1 false,
65 // CHECK-NOOPT: store i1 false,
66 // CHECK-NOOPT: store i1 false,
67 // CHECK-NOOPT: store i1 false,
68 // CHECK-NOOPT: store i1 false,
69 // CHECK-NOOPT: store i1 false,
70 // CHECK-NOOPT: br i1
71 //
72 // CHECK-NOOPT: call void @llvm.lifetime.start
73 // CHECK-NOOPT: store i1 true,
74 // CHECK-NOOPT: store i1 true,
75 // CHECK-NOOPT: call noundef i32 @_ZN1X1fEv(
76 // CHECK-NOOPT: call void @llvm.lifetime.start
77 // CHECK-NOOPT: store i1 true,
78 // CHECK-NOOPT: store i1 true,
79 // CHECK-NOOPT: call noundef i32 @_ZN1X1fEv(
80 // CHECK-NOOPT: call void @llvm.lifetime.start
81 // CHECK-NOOPT: store i1 true,
82 // CHECK-NOOPT: store i1 true,
83 // CHECK-NOOPT: call noundef i32 @_ZN1X1fEv(
84 // CHECK-NOOPT: call noundef i32 @_Z1giii(
85 // CHECK-NOOPT: br label
86 //
87 // CHECK-NOOPT: call noundef i32 @_Z1giii(i32 noundef 1, i32 noundef 2, i32 noundef 3)
88 // CHECK-NOOPT: br label
89 //
90 // CHECK-NOOPT: load i1,
91 // CHECK-NOOPT: br i1
92 // CHECK-NOOPT: call void @_ZN1XD1Ev(
93 // CHECK-NOOPT: br label
94 //
95 // CHECK-NOOPT: load i1,
96 // CHECK-NOOPT: br i1
97 // CHECK-NOOPT: call void @llvm.lifetime.end
98 // CHECK-NOOPT: br label
99 //
100 // CHECK-NOOPT: load i1,
101 // CHECK-NOOPT: br i1
102 // CHECK-NOOPT: call void @_ZN1XD1Ev(
103 // CHECK-NOOPT: br label
104 //
105 // CHECK-NOOPT: load i1,
106 // CHECK-NOOPT: br i1
107 // CHECK-NOOPT: call void @llvm.lifetime.end
108 // CHECK-NOOPT: br label
109 //
110 // CHECK-NOOPT: load i1,
111 // CHECK-NOOPT: br i1
112 // CHECK-NOOPT: call void @_ZN1XD1Ev(
113 // CHECK-NOOPT: br label
114 //
115 // CHECK-NOOPT: load i1,
116 // CHECK-NOOPT: br i1
117 // CHECK-NOOPT: call void @llvm.lifetime.end
118 // CHECK-NOOPT: br label
119 //
120 // CHECK-NOOPT: ret
121
122 // CHECK-OPT: br i1
123 //
124 // CHECK-OPT: call void @llvm.lifetime.start
125 // CHECK-OPT: call noundef i32 @_ZN1X1fEv(
126 // CHECK-OPT: call void @llvm.lifetime.start
127 // CHECK-OPT: call noundef i32 @_ZN1X1fEv(
128 // CHECK-OPT: call void @llvm.lifetime.start
129 // CHECK-OPT: call noundef i32 @_ZN1X1fEv(
130 // CHECK-OPT: call noundef i32 @_Z1giii(
131 // CHECK-OPT: call void @_ZN1XD1Ev(
132 // CHECK-OPT: call void @llvm.lifetime.end
133 // CHECK-OPT: call void @_ZN1XD1Ev(
134 // CHECK-OPT: call void @llvm.lifetime.end
135 // CHECK-OPT: call void @_ZN1XD1Ev(
136 // CHECK-OPT: call void @llvm.lifetime.end
137 // CHECK-OPT: br label
138 return cond ? g(X().f(), X().f(), X().f()) : g(1, 2, 3);
139 }
140
141 struct Y { int f(); };
142 int g(int, int, int);
143 // CHECK-LABEL: @_Z13lifetime_triv
lifetime_triv(bool cond)144 int lifetime_triv(bool cond) {
145 // CHECK-NOOPT: call void @llvm.lifetime.start
146 // CHECK-NOOPT: call void @llvm.lifetime.start
147 // CHECK-NOOPT: call void @llvm.lifetime.start
148 // CHECK-NOOPT: br i1
149 //
150 // CHECK-NOOPT: call noundef i32 @_ZN1Y1fEv(
151 // CHECK-NOOPT: call noundef i32 @_ZN1Y1fEv(
152 // CHECK-NOOPT: call noundef i32 @_ZN1Y1fEv(
153 // CHECK-NOOPT: call noundef i32 @_Z1giii(
154 // CHECK-NOOPT: br label
155 //
156 // CHECK-NOOPT: call noundef i32 @_Z1giii(i32 noundef 1, i32 noundef 2, i32 noundef 3)
157 // CHECK-NOOPT: br label
158 //
159 // CHECK-NOOPT: call void @llvm.lifetime.end
160 // CHECK-NOOPT-NOT: br
161 // CHECK-NOOPT: call void @llvm.lifetime.end
162 // CHECK-NOOPT-NOT: br
163 // CHECK-NOOPT: call void @llvm.lifetime.end
164 //
165 // CHECK-NOOPT: ret
166
167 // FIXME: LLVM isn't smart enough to remove the lifetime markers from the
168 // g(1, 2, 3) path here.
169
170 // CHECK-OPT: call void @llvm.lifetime.start
171 // CHECK-OPT: call void @llvm.lifetime.start
172 // CHECK-OPT: call void @llvm.lifetime.start
173 // CHECK-OPT: br i1
174 //
175 // CHECK-OPT: call noundef i32 @_ZN1Y1fEv(
176 // CHECK-OPT: call noundef i32 @_ZN1Y1fEv(
177 // CHECK-OPT: call noundef i32 @_ZN1Y1fEv(
178 // CHECK-OPT: call noundef i32 @_Z1giii(
179 // CHECK-OPT: br label
180 //
181 // CHECK-OPT: call void @llvm.lifetime.end
182 // CHECK-OPT: call void @llvm.lifetime.end
183 // CHECK-OPT: call void @llvm.lifetime.end
184 return cond ? g(Y().f(), Y().f(), Y().f()) : g(1, 2, 3);
185 }
186
~ZZ187 struct Z { ~Z() {} int f(); };
188 int g(int, int, int);
189 // CHECK-LABEL: @_Z22lifetime_nontriv_empty
lifetime_nontriv_empty(bool cond)190 int lifetime_nontriv_empty(bool cond) {
191 // CHECK-OPT: br i1
192 //
193 // CHECK-OPT: call void @llvm.lifetime.start
194 // CHECK-OPT: call noundef i32 @_ZN1Z1fEv(
195 // CHECK-OPT: call void @llvm.lifetime.start
196 // CHECK-OPT: call noundef i32 @_ZN1Z1fEv(
197 // CHECK-OPT: call void @llvm.lifetime.start
198 // CHECK-OPT: call noundef i32 @_ZN1Z1fEv(
199 // CHECK-OPT: call noundef i32 @_Z1giii(
200 // CHECK-OPT: call void @llvm.lifetime.end
201 // CHECK-OPT: call void @llvm.lifetime.end
202 // CHECK-OPT: call void @llvm.lifetime.end
203 // CHECK-OPT: br label
204 return cond ? g(Z().f(), Z().f(), Z().f()) : g(1, 2, 3);
205 }
206