1*67e74705SXin Li // RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li // CHECK: @i = global [[INT:i[0-9]+]] 0
4*67e74705SXin Li volatile int i, j, k;
5*67e74705SXin Li volatile int ar[5];
6*67e74705SXin Li volatile char c;
7*67e74705SXin Li // CHECK: @ci = global [[CINT:.*]] zeroinitializer
8*67e74705SXin Li volatile _Complex int ci;
9*67e74705SXin Li volatile struct S {
10*67e74705SXin Li #ifdef __cplusplus
11*67e74705SXin Li void operator =(volatile struct S&o) volatile;
12*67e74705SXin Li #endif
13*67e74705SXin Li int i;
14*67e74705SXin Li } a, b;
15*67e74705SXin Li
16*67e74705SXin Li //void operator =(volatile struct S&o1, volatile struct S&o2) volatile;
17*67e74705SXin Li int printf(const char *, ...);
18*67e74705SXin Li
19*67e74705SXin Li
20*67e74705SXin Li // CHECK: define {{.*}}void @{{.*}}test
test()21*67e74705SXin Li void test() {
22*67e74705SXin Li
23*67e74705SXin Li asm("nop"); // CHECK: call void asm
24*67e74705SXin Li
25*67e74705SXin Li // should not load
26*67e74705SXin Li i;
27*67e74705SXin Li
28*67e74705SXin Li (float)(ci);
29*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
30*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
31*67e74705SXin Li // CHECK-NEXT: sitofp [[INT]]
32*67e74705SXin Li
33*67e74705SXin Li // These are not uses in C++:
34*67e74705SXin Li // [expr.static.cast]p6:
35*67e74705SXin Li // The lvalue-to-rvalue . . . conversions are not applied to the expression.
36*67e74705SXin Li (void)ci;
37*67e74705SXin Li (void)a;
38*67e74705SXin Li
39*67e74705SXin Li (void)(ci=ci);
40*67e74705SXin Li // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
41*67e74705SXin Li // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
42*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
43*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
44*67e74705SXin Li
45*67e74705SXin Li (void)(i=j);
46*67e74705SXin Li // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* @j
47*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i
48*67e74705SXin Li
49*67e74705SXin Li ci+=ci;
50*67e74705SXin Li // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
51*67e74705SXin Li // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
52*67e74705SXin Li // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
53*67e74705SXin Li // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
54*67e74705SXin Li // Not sure why they're ordered this way.
55*67e74705SXin Li // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
56*67e74705SXin Li // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
57*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
58*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
59*67e74705SXin Li
60*67e74705SXin Li // Note that C++ requires an extra load volatile over C from the LHS of the '+'.
61*67e74705SXin Li (ci += ci) + ci;
62*67e74705SXin Li // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
63*67e74705SXin Li // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
64*67e74705SXin Li // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
65*67e74705SXin Li // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
66*67e74705SXin Li // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
67*67e74705SXin Li // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
68*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
69*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
70*67e74705SXin Li // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
71*67e74705SXin Li // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
72*67e74705SXin Li // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
73*67e74705SXin Li // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
74*67e74705SXin Li // These additions can be elided.
75*67e74705SXin Li // CHECK-NEXT: add [[INT]] [[R1]], [[R2]]
76*67e74705SXin Li // CHECK-NEXT: add [[INT]] [[I1]], [[I2]]
77*67e74705SXin Li
78*67e74705SXin Li asm("nop"); // CHECK-NEXT: call void asm
79*67e74705SXin Li
80*67e74705SXin Li // Extra load volatile in C++.
81*67e74705SXin Li (i += j) + k;
82*67e74705SXin Li // CHECK-NEXT: load volatile
83*67e74705SXin Li // CHECK-NEXT: load volatile
84*67e74705SXin Li // CHECK-NEXT: add nsw [[INT]]
85*67e74705SXin Li // CHECK-NEXT: store volatile
86*67e74705SXin Li // CHECK-NEXT: load volatile
87*67e74705SXin Li // CHECK-NEXT: load volatile
88*67e74705SXin Li // CHECK-NEXT: add nsw [[INT]]
89*67e74705SXin Li
90*67e74705SXin Li asm("nop"); // CHECK-NEXT: call void asm
91*67e74705SXin Li
92*67e74705SXin Li // Extra load volatile in C++.
93*67e74705SXin Li (i += j) + 1;
94*67e74705SXin Li // CHECK-NEXT: load volatile
95*67e74705SXin Li // CHECK-NEXT: load volatile
96*67e74705SXin Li // CHECK-NEXT: add nsw [[INT]]
97*67e74705SXin Li // CHECK-NEXT: store volatile
98*67e74705SXin Li // CHECK-NEXT: load volatile
99*67e74705SXin Li // CHECK-NEXT: add nsw [[INT]]
100*67e74705SXin Li
101*67e74705SXin Li asm("nop"); // CHECK-NEXT: call void asm
102*67e74705SXin Li
103*67e74705SXin Li ci+ci;
104*67e74705SXin Li // CHECK-NEXT: load volatile
105*67e74705SXin Li // CHECK-NEXT: load volatile
106*67e74705SXin Li // CHECK-NEXT: load volatile
107*67e74705SXin Li // CHECK-NEXT: load volatile
108*67e74705SXin Li // CHECK-NEXT: add [[INT]]
109*67e74705SXin Li // CHECK-NEXT: add [[INT]]
110*67e74705SXin Li
111*67e74705SXin Li __real i;
112*67e74705SXin Li
113*67e74705SXin Li +ci;
114*67e74705SXin Li // CHECK-NEXT: load volatile
115*67e74705SXin Li // CHECK-NEXT: load volatile
116*67e74705SXin Li
117*67e74705SXin Li asm("nop"); // CHECK-NEXT: call void asm
118*67e74705SXin Li
119*67e74705SXin Li (void)(i=i);
120*67e74705SXin Li // CHECK-NEXT: load volatile
121*67e74705SXin Li // CHECK-NEXT: store volatile
122*67e74705SXin Li
123*67e74705SXin Li (float)(i=i);
124*67e74705SXin Li // CHECK-NEXT: load volatile
125*67e74705SXin Li // CHECK-NEXT: store volatile
126*67e74705SXin Li // CHECK-NEXT: load volatile
127*67e74705SXin Li // CHECK-NEXT: sitofp
128*67e74705SXin Li
129*67e74705SXin Li (void)i;
130*67e74705SXin Li
131*67e74705SXin Li i=i;
132*67e74705SXin Li // CHECK-NEXT: load volatile
133*67e74705SXin Li // CHECK-NEXT: store volatile
134*67e74705SXin Li
135*67e74705SXin Li // Extra load volatile in C++.
136*67e74705SXin Li i=i=i;
137*67e74705SXin Li // CHECK-NEXT: load volatile
138*67e74705SXin Li // CHECK-NEXT: store volatile
139*67e74705SXin Li // CHECK-NEXT: load volatile
140*67e74705SXin Li // CHECK-NEXT: store volatile
141*67e74705SXin Li
142*67e74705SXin Li (void)__builtin_choose_expr(0, i=i, j=j);
143*67e74705SXin Li // CHECK-NEXT: load volatile
144*67e74705SXin Li // CHECK-NEXT: store volatile
145*67e74705SXin Li
146*67e74705SXin Li k ? (i=i) : (j=j);
147*67e74705SXin Li // CHECK-NEXT: load volatile
148*67e74705SXin Li // CHECK-NEXT: icmp
149*67e74705SXin Li // CHECK-NEXT: br i1
150*67e74705SXin Li // CHECK: load volatile
151*67e74705SXin Li // CHECK-NEXT: store volatile
152*67e74705SXin Li // CHECK-NEXT: br label
153*67e74705SXin Li // CHECK: load volatile
154*67e74705SXin Li // CHECK-NEXT: store volatile
155*67e74705SXin Li // CHECK-NEXT: br label
156*67e74705SXin Li // CHECK: phi
157*67e74705SXin Li
158*67e74705SXin Li (void)(i,(i=i));
159*67e74705SXin Li // CHECK-NEXT: load volatile
160*67e74705SXin Li // CHECK-NEXT: store volatile
161*67e74705SXin Li
162*67e74705SXin Li i=i,k;
163*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i
164*67e74705SXin Li // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
165*67e74705SXin Li
166*67e74705SXin Li (i=j,k=j);
167*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
168*67e74705SXin Li // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
169*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
170*67e74705SXin Li // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @k
171*67e74705SXin Li
172*67e74705SXin Li (i=j,k);
173*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
174*67e74705SXin Li // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
175*67e74705SXin Li
176*67e74705SXin Li (i,j);
177*67e74705SXin Li
178*67e74705SXin Li // Extra load in C++.
179*67e74705SXin Li i=c=k;
180*67e74705SXin Li // CHECK-NEXT: load volatile
181*67e74705SXin Li // CHECK-NEXT: trunc
182*67e74705SXin Li // CHECK-NEXT: store volatile
183*67e74705SXin Li // CHECK-NEXT: load volatile
184*67e74705SXin Li // CHECK-NEXT: sext
185*67e74705SXin Li // CHECK-NEXT: store volatile
186*67e74705SXin Li
187*67e74705SXin Li i+=k;
188*67e74705SXin Li // CHECK-NEXT: load volatile
189*67e74705SXin Li // CHECK-NEXT: load volatile
190*67e74705SXin Li // CHECK-NEXT: add nsw [[INT]]
191*67e74705SXin Li // CHECK-NEXT: store volatile
192*67e74705SXin Li
193*67e74705SXin Li ci;
194*67e74705SXin Li
195*67e74705SXin Li asm("nop"); // CHECK-NEXT: call void asm
196*67e74705SXin Li
197*67e74705SXin Li (int)ci;
198*67e74705SXin Li // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
199*67e74705SXin Li // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
200*67e74705SXin Li
201*67e74705SXin Li (bool)ci;
202*67e74705SXin Li // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
203*67e74705SXin Li // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
204*67e74705SXin Li // CHECK-NEXT: icmp ne
205*67e74705SXin Li // CHECK-NEXT: icmp ne
206*67e74705SXin Li // CHECK-NEXT: or i1
207*67e74705SXin Li
208*67e74705SXin Li ci=ci;
209*67e74705SXin Li // CHECK-NEXT: load volatile
210*67e74705SXin Li // CHECK-NEXT: load volatile
211*67e74705SXin Li // CHECK-NEXT: store volatile
212*67e74705SXin Li // CHECK-NEXT: store volatile
213*67e74705SXin Li
214*67e74705SXin Li asm("nop"); // CHECK-NEXT: call void asm
215*67e74705SXin Li
216*67e74705SXin Li // Extra load in C++.
217*67e74705SXin Li ci=ci=ci;
218*67e74705SXin Li // CHECK-NEXT: load volatile
219*67e74705SXin Li // CHECK-NEXT: load volatile
220*67e74705SXin Li // CHECK-NEXT: store volatile
221*67e74705SXin Li // CHECK-NEXT: store volatile
222*67e74705SXin Li // CHECK-NEXT: load volatile
223*67e74705SXin Li // CHECK-NEXT: load volatile
224*67e74705SXin Li // CHECK-NEXT: store volatile
225*67e74705SXin Li // CHECK-NEXT: store volatile
226*67e74705SXin Li
227*67e74705SXin Li __imag ci = __imag ci = __imag ci;
228*67e74705SXin Li // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
229*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
230*67e74705SXin Li // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
231*67e74705SXin Li // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
232*67e74705SXin Li
233*67e74705SXin Li __real (i = j);
234*67e74705SXin Li // CHECK-NEXT: load volatile
235*67e74705SXin Li // CHECK-NEXT: store volatile
236*67e74705SXin Li
237*67e74705SXin Li __imag i;
238*67e74705SXin Li
239*67e74705SXin Li // ============================================================
240*67e74705SXin Li // FIXME: Test cases we get wrong.
241*67e74705SXin Li
242*67e74705SXin Li // A use. We load all of a into a copy of a, then load i. gcc forgets to do
243*67e74705SXin Li // the assignment.
244*67e74705SXin Li // (a = a).i;
245*67e74705SXin Li
246*67e74705SXin Li // ============================================================
247*67e74705SXin Li // Test cases where we intentionally differ from gcc, due to suspected bugs in
248*67e74705SXin Li // gcc.
249*67e74705SXin Li
250*67e74705SXin Li // Not a use. gcc forgets to do the assignment.
251*67e74705SXin Li // CHECK-NEXT: call {{.*}}void
252*67e74705SXin Li ((a=a),a);
253*67e74705SXin Li
254*67e74705SXin Li // Not a use. gcc gets this wrong, it doesn't emit the copy!
255*67e74705SXin Li // CHECK-NEXT: call {{.*}}void
256*67e74705SXin Li (void)(a=a);
257*67e74705SXin Li
258*67e74705SXin Li // Not a use. gcc got this wrong in 4.2 and omitted the side effects
259*67e74705SXin Li // entirely, but it is fixed in 4.4.0.
260*67e74705SXin Li __imag (i = j);
261*67e74705SXin Li // CHECK-NEXT: load volatile
262*67e74705SXin Li // CHECK-NEXT: store volatile
263*67e74705SXin Li
264*67e74705SXin Li // C++ does an extra load here. Note that we have to do full loads.
265*67e74705SXin Li (float)(ci=ci);
266*67e74705SXin Li // CHECK-NEXT: load volatile
267*67e74705SXin Li // CHECK-NEXT: load volatile
268*67e74705SXin Li // CHECK-NEXT: store volatile
269*67e74705SXin Li // CHECK-NEXT: store volatile
270*67e74705SXin Li // CHECK-NEXT: load volatile
271*67e74705SXin Li // CHECK-NEXT: load volatile
272*67e74705SXin Li // CHECK-NEXT: sitofp
273*67e74705SXin Li
274*67e74705SXin Li // Not a use, bug? gcc treats this as not a use, that's probably a
275*67e74705SXin Li // bug due to tree folding ignoring volatile.
276*67e74705SXin Li (int)(ci=ci);
277*67e74705SXin Li // CHECK-NEXT: load volatile
278*67e74705SXin Li // CHECK-NEXT: load volatile
279*67e74705SXin Li // CHECK-NEXT: store volatile
280*67e74705SXin Li // CHECK-NEXT: store volatile
281*67e74705SXin Li // CHECK-NEXT: load volatile
282*67e74705SXin Li // CHECK-NEXT: load volatile
283*67e74705SXin Li
284*67e74705SXin Li // A use.
285*67e74705SXin Li (float)(i=i);
286*67e74705SXin Li // CHECK-NEXT: load volatile
287*67e74705SXin Li // CHECK-NEXT: store volatile
288*67e74705SXin Li // CHECK-NEXT: load volatile
289*67e74705SXin Li // CHECK-NEXT: sitofp
290*67e74705SXin Li
291*67e74705SXin Li // A use. gcc treats this as not a use, that's probably a bug due to tree
292*67e74705SXin Li // folding ignoring volatile.
293*67e74705SXin Li (int)(i=i);
294*67e74705SXin Li // CHECK-NEXT: load volatile
295*67e74705SXin Li // CHECK-NEXT: store volatile
296*67e74705SXin Li // CHECK-NEXT: load volatile
297*67e74705SXin Li
298*67e74705SXin Li // A use.
299*67e74705SXin Li -(i=j);
300*67e74705SXin Li // CHECK-NEXT: load volatile
301*67e74705SXin Li // CHECK-NEXT: store volatile
302*67e74705SXin Li // CHECK-NEXT: load volatile
303*67e74705SXin Li // CHECK-NEXT: sub
304*67e74705SXin Li
305*67e74705SXin Li // A use. gcc treats this a not a use, that's probably a bug due to tree
306*67e74705SXin Li // folding ignoring volatile.
307*67e74705SXin Li +(i=k);
308*67e74705SXin Li // CHECK-NEXT: load volatile
309*67e74705SXin Li // CHECK-NEXT: store volatile
310*67e74705SXin Li // CHECK-NEXT: load volatile
311*67e74705SXin Li
312*67e74705SXin Li // A use. gcc treats this a not a use, that's probably a bug due to tree
313*67e74705SXin Li // folding ignoring volatile.
314*67e74705SXin Li __real (ci=ci);
315*67e74705SXin Li // CHECK-NEXT: load volatile
316*67e74705SXin Li // CHECK-NEXT: load volatile
317*67e74705SXin Li // CHECK-NEXT: store volatile
318*67e74705SXin Li // CHECK-NEXT: store volatile
319*67e74705SXin Li
320*67e74705SXin Li // A use.
321*67e74705SXin Li i + 0;
322*67e74705SXin Li // CHECK-NEXT: load volatile
323*67e74705SXin Li // CHECK-NEXT: add
324*67e74705SXin Li
325*67e74705SXin Li // A use.
326*67e74705SXin Li (i=j) + i;
327*67e74705SXin Li // CHECK-NEXT: load volatile
328*67e74705SXin Li // CHECK-NEXT: store volatile
329*67e74705SXin Li // CHECK-NEXT: load volatile
330*67e74705SXin Li // CHECK-NEXT: load volatile
331*67e74705SXin Li // CHECK-NEXT: add
332*67e74705SXin Li
333*67e74705SXin Li // A use. gcc treats this as not a use, that's probably a bug due to tree
334*67e74705SXin Li // folding ignoring volatile.
335*67e74705SXin Li (i=j) + 0;
336*67e74705SXin Li // CHECK-NEXT: load volatile
337*67e74705SXin Li // CHECK-NEXT: store volatile
338*67e74705SXin Li // CHECK-NEXT: load volatile
339*67e74705SXin Li // CHECK-NEXT: add
340*67e74705SXin Li
341*67e74705SXin Li (i,j)=k;
342*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k
343*67e74705SXin Li // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
344*67e74705SXin Li
345*67e74705SXin Li (j=k,i)=i;
346*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i
347*67e74705SXin Li // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k
348*67e74705SXin Li // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
349*67e74705SXin Li // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
350*67e74705SXin Li
351*67e74705SXin Li // CHECK-NEXT: ret void
352*67e74705SXin Li }
353