Clang Project

clang_source_code/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
6namespace {
7
8static int ctorcalls;
9static int dtorcalls;
10  
11struct 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
21void g(int) { }
22void g(const A&) { }
23
24void 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
31struct Checker {
32  Checker() {
33    f1(true);
34    f1(false);
35  }
36};
37
38Checker c;
39
40}
41
42// CHECK-OPT-LABEL: define i32 @_Z12getCtorCallsv()
43int getCtorCalls() {
44  // CHECK-OPT: ret i32 5
45  return ctorcalls;
46}
47
48// CHECK-OPT-LABEL: define i32 @_Z12getDtorCallsv()
49int getDtorCalls() {
50  // CHECK-OPT: ret i32 5
51  return dtorcalls;
52}
53
54// CHECK-OPT-LABEL: define zeroext i1 @_Z7successv()
55bool success() {
56  // CHECK-OPT: ret i1 true
57  return ctorcalls == dtorcalls;
58}
59
60struct X { ~X(); int f(); };
61int g(int, int, int);
62// CHECK-LABEL: @_Z16lifetime_nontriv
63int 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
141struct Y { int f(); };
142int g(int, int, int);
143// CHECK-LABEL: @_Z13lifetime_triv
144int 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
187struct Z { ~Z() {} int f(); };
188int g(int, int, int);
189// CHECK-LABEL: @_Z22lifetime_nontriv_empty
190int 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}
206