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