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