]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGenCXX/conditional-temporaries.cpp
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / test / CodeGenCXX / conditional-temporaries.cpp
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 {
12   A() : i(0) { ctorcalls++; }
13   ~A() { dtorcalls++; }
14   int i;
15   
16   friend const A& operator<<(const A& a, int n) {
17     return a;
18   }
19 };
20
21 void g(int) { }
22 void g(const A&) { }
23
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 {
32   Checker() {
33     f1(true);
34     f1(false);
35   }
36 };
37
38 Checker c;
39
40 }
41
42 // CHECK-OPT-LABEL: define i32 @_Z12getCtorCallsv()
43 int getCtorCalls() {
44   // CHECK-OPT: ret i32 5
45   return ctorcalls;
46 }
47
48 // CHECK-OPT-LABEL: define i32 @_Z12getDtorCallsv()
49 int getDtorCalls() {
50   // CHECK-OPT: ret i32 5
51   return dtorcalls;
52 }
53
54 // CHECK-OPT-LABEL: define zeroext i1 @_Z7successv()
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
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 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 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 i32 @_ZN1X1fEv(
84   // CHECK-NOOPT: call i32 @_Z1giii(
85   // CHECK-NOOPT: br label
86   //
87   // CHECK-NOOPT: call i32 @_Z1giii(i32 1, i32 2, i32 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 i32 @_ZN1X1fEv(
126   // CHECK-OPT: call void @llvm.lifetime.start
127   // CHECK-OPT: call i32 @_ZN1X1fEv(
128   // CHECK-OPT: call void @llvm.lifetime.start
129   // CHECK-OPT: call i32 @_ZN1X1fEv(
130   // CHECK-OPT: call 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
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 i32 @_ZN1Y1fEv(
151   // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
152   // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
153   // CHECK-NOOPT: call i32 @_Z1giii(
154   // CHECK-NOOPT: br label
155   //
156   // CHECK-NOOPT: call i32 @_Z1giii(i32 1, i32 2, i32 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 i32 @_ZN1Y1fEv(
176   // CHECK-OPT: call i32 @_ZN1Y1fEv(
177   // CHECK-OPT: call i32 @_ZN1Y1fEv(
178   // CHECK-OPT: call 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
187 struct Z { ~Z() {} int f(); };
188 int g(int, int, int);
189 // CHECK-LABEL: @_Z22lifetime_nontriv_empty
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 i32 @_ZN1Z1fEv(
195   // CHECK-OPT: call void @llvm.lifetime.start
196   // CHECK-OPT: call i32 @_ZN1Z1fEv(
197   // CHECK-OPT: call void @llvm.lifetime.start
198   // CHECK-OPT: call i32 @_ZN1Z1fEv(
199   // CHECK-OPT: call 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 }