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,CHECK-LEGACY-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,CHECK-LEGACY-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,X64-NEWPM-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,AMDGCN-NEWPM-OPT
8 
9 namespace {
10 
11 static int ctorcalls;
12 static int dtorcalls;
13 
14 struct A {
A__anon30e720960111::A15   A() : i(0) { ctorcalls++; }
~A__anon30e720960111::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__anon30e720960111::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-LEGACY-OPT: ret i32 5
48   // X64-NEWPM-OPT: ret i32 5
49   // AMDGCN-NEWPM-OPT: [[RET:%.*]] = load i32, i32* addrspacecast (i32 addrspace(1)* @_ZN12_GLOBAL__N_19ctorcallsE to i32*), align 4
50   // AMDGCN-NEWPM-OPT: ret i32 [[RET]]
51   return ctorcalls;
52 }
53 
54 // CHECK-OPT-LABEL: define i32 @_Z12getDtorCallsv()
getDtorCalls()55 int getDtorCalls() {
56   // CHECK-LEGACY-OPT: ret i32 5
57   // X64-NEWPM-OPT: ret i32 5
58   // AMDGCN-NEWPM-OPT: [[RET:%.*]] = load i32, i32* addrspacecast (i32 addrspace(1)* @_ZN12_GLOBAL__N_19dtorcallsE to i32*), align 4
59   // AMDGCN-NEWPM-OPT: ret i32 [[RET]]
60   return dtorcalls;
61 }
62 
63 // CHECK-OPT-LABEL: define zeroext i1 @_Z7successv()
success()64 bool success() {
65   // CHECK-LEGACY-OPT: ret i1 true
66   // X64-NEWPM-OPT: ret i1 true
67   // AMDGCN-NEWPM-OPT: [[CTORS:%.*]] = load i32, i32* addrspacecast (i32 addrspace(1)* @_ZN12_GLOBAL__N_19ctorcallsE to i32*), align 4, !tbaa !2
68   // AMDGCN-NEWPM-OPT: [[DTORS:%.*]] = load i32, i32* addrspacecast (i32 addrspace(1)* @_ZN12_GLOBAL__N_19dtorcallsE to i32*), align 4, !tbaa !2
69   // AMDGCN-NEWPM-OPT: %cmp = icmp eq i32 [[CTORS]], [[DTORS]]
70   // AMDGCN-NEWPM-OPT: ret i1 %cmp
71   return ctorcalls == dtorcalls;
72 }
73 
74 struct X { ~X(); int f(); };
75 int g(int, int, int);
76 // CHECK-LABEL: @_Z16lifetime_nontriv
lifetime_nontriv(bool cond)77 int lifetime_nontriv(bool cond) {
78   // CHECK-NOOPT: store i1 false,
79   // CHECK-NOOPT: store i1 false,
80   // CHECK-NOOPT: store i1 false,
81   // CHECK-NOOPT: store i1 false,
82   // CHECK-NOOPT: store i1 false,
83   // CHECK-NOOPT: store i1 false,
84   // CHECK-NOOPT: br i1
85   //
86   // CHECK-NOOPT: call void @llvm.lifetime.start
87   // CHECK-NOOPT: store i1 true,
88   // CHECK-NOOPT: store i1 true,
89   // CHECK-NOOPT: call i32 @_ZN1X1fEv(
90   // CHECK-NOOPT: call void @llvm.lifetime.start
91   // CHECK-NOOPT: store i1 true,
92   // CHECK-NOOPT: store i1 true,
93   // CHECK-NOOPT: call i32 @_ZN1X1fEv(
94   // CHECK-NOOPT: call void @llvm.lifetime.start
95   // CHECK-NOOPT: store i1 true,
96   // CHECK-NOOPT: store i1 true,
97   // CHECK-NOOPT: call i32 @_ZN1X1fEv(
98   // CHECK-NOOPT: call i32 @_Z1giii(
99   // CHECK-NOOPT: br label
100   //
101   // CHECK-NOOPT: call i32 @_Z1giii(i32 1, i32 2, i32 3)
102   // CHECK-NOOPT: br label
103   //
104   // CHECK-NOOPT: load i1,
105   // CHECK-NOOPT: br i1
106   // CHECK-NOOPT: call void @_ZN1XD1Ev(
107   // CHECK-NOOPT: br label
108   //
109   // CHECK-NOOPT: load i1,
110   // CHECK-NOOPT: br i1
111   // CHECK-NOOPT: call void @llvm.lifetime.end
112   // CHECK-NOOPT: br label
113   //
114   // CHECK-NOOPT: load i1,
115   // CHECK-NOOPT: br i1
116   // CHECK-NOOPT: call void @_ZN1XD1Ev(
117   // CHECK-NOOPT: br label
118   //
119   // CHECK-NOOPT: load i1,
120   // CHECK-NOOPT: br i1
121   // CHECK-NOOPT: call void @llvm.lifetime.end
122   // CHECK-NOOPT: br label
123   //
124   // CHECK-NOOPT: load i1,
125   // CHECK-NOOPT: br i1
126   // CHECK-NOOPT: call void @_ZN1XD1Ev(
127   // CHECK-NOOPT: br label
128   //
129   // CHECK-NOOPT: load i1,
130   // CHECK-NOOPT: br i1
131   // CHECK-NOOPT: call void @llvm.lifetime.end
132   // CHECK-NOOPT: br label
133   //
134   // CHECK-NOOPT: ret
135 
136   // CHECK-OPT: br i1
137   //
138   // CHECK-OPT: call void @llvm.lifetime.start
139   // CHECK-OPT: call i32 @_ZN1X1fEv(
140   // CHECK-OPT: call void @llvm.lifetime.start
141   // CHECK-OPT: call i32 @_ZN1X1fEv(
142   // CHECK-OPT: call void @llvm.lifetime.start
143   // CHECK-OPT: call i32 @_ZN1X1fEv(
144   // CHECK-OPT: call i32 @_Z1giii(
145   // CHECK-OPT: call void @_ZN1XD1Ev(
146   // CHECK-OPT: call void @llvm.lifetime.end
147   // CHECK-OPT: call void @_ZN1XD1Ev(
148   // CHECK-OPT: call void @llvm.lifetime.end
149   // CHECK-OPT: call void @_ZN1XD1Ev(
150   // CHECK-OPT: call void @llvm.lifetime.end
151   // CHECK-OPT: br label
152   return cond ? g(X().f(), X().f(), X().f()) : g(1, 2, 3);
153 }
154 
155 struct Y { int f(); };
156 int g(int, int, int);
157 // CHECK-LABEL: @_Z13lifetime_triv
lifetime_triv(bool cond)158 int lifetime_triv(bool cond) {
159   // CHECK-NOOPT: call void @llvm.lifetime.start
160   // CHECK-NOOPT: call void @llvm.lifetime.start
161   // CHECK-NOOPT: call void @llvm.lifetime.start
162   // CHECK-NOOPT: br i1
163   //
164   // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
165   // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
166   // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
167   // CHECK-NOOPT: call i32 @_Z1giii(
168   // CHECK-NOOPT: br label
169   //
170   // CHECK-NOOPT: call i32 @_Z1giii(i32 1, i32 2, i32 3)
171   // CHECK-NOOPT: br label
172   //
173   // CHECK-NOOPT: call void @llvm.lifetime.end
174   // CHECK-NOOPT-NOT: br
175   // CHECK-NOOPT: call void @llvm.lifetime.end
176   // CHECK-NOOPT-NOT: br
177   // CHECK-NOOPT: call void @llvm.lifetime.end
178   //
179   // CHECK-NOOPT: ret
180 
181   // FIXME: LLVM isn't smart enough to remove the lifetime markers from the
182   // g(1, 2, 3) path here.
183 
184   // CHECK-OPT: call void @llvm.lifetime.start
185   // CHECK-OPT: call void @llvm.lifetime.start
186   // CHECK-OPT: call void @llvm.lifetime.start
187   // CHECK-OPT: br i1
188   //
189   // CHECK-OPT: call i32 @_ZN1Y1fEv(
190   // CHECK-OPT: call i32 @_ZN1Y1fEv(
191   // CHECK-OPT: call i32 @_ZN1Y1fEv(
192   // CHECK-OPT: call i32 @_Z1giii(
193   // CHECK-OPT: br label
194   //
195   // CHECK-OPT: call void @llvm.lifetime.end
196   // CHECK-OPT: call void @llvm.lifetime.end
197   // CHECK-OPT: call void @llvm.lifetime.end
198   return cond ? g(Y().f(), Y().f(), Y().f()) : g(1, 2, 3);
199 }
200 
~ZZ201 struct Z { ~Z() {} int f(); };
202 int g(int, int, int);
203 // CHECK-LABEL: @_Z22lifetime_nontriv_empty
lifetime_nontriv_empty(bool cond)204 int lifetime_nontriv_empty(bool cond) {
205   // CHECK-OPT: br i1
206   //
207   // CHECK-OPT: call void @llvm.lifetime.start
208   // CHECK-OPT: call i32 @_ZN1Z1fEv(
209   // CHECK-OPT: call void @llvm.lifetime.start
210   // CHECK-OPT: call i32 @_ZN1Z1fEv(
211   // CHECK-OPT: call void @llvm.lifetime.start
212   // CHECK-OPT: call i32 @_ZN1Z1fEv(
213   // CHECK-OPT: call i32 @_Z1giii(
214   // CHECK-OPT: call void @llvm.lifetime.end
215   // CHECK-OPT: call void @llvm.lifetime.end
216   // CHECK-OPT: call void @llvm.lifetime.end
217   // CHECK-OPT: br label
218   return cond ? g(Z().f(), Z().f(), Z().f()) : g(1, 2, 3);
219 }
220