1; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefix=FNATTR
2;
3; Test cases specifically designed for the "returned" argument attribute.
4; We use FIXME's to indicate problems and missing attributes.
5;
6
7; TEST SCC test returning an integer value argument
8;
9;
10; FNATTR: define i32 @sink_r0(i32 returned %r)
11; FNATTR: define i32 @scc_r1(i32 %a, i32 %r, i32 %b)
12; FNATTR: define i32 @scc_r2(i32 %a, i32 %b, i32 %r)
13; FNATTR: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
14;
15;
16; int scc_r1(int a, int b, int r);
17; int scc_r2(int a, int b, int r);
18;
19; __attribute__((noinline)) int sink_r0(int r) {
20;   return r;
21; }
22;
23; __attribute__((noinline)) int scc_r1(int a, int r, int b) {
24;   return scc_r2(r, a, sink_r0(r));
25; }
26;
27; __attribute__((noinline)) int scc_r2(int a, int b, int r) {
28;   if (a > b)
29;     return scc_r2(b, a, sink_r0(r));
30;   if (a < b)
31;     return scc_r1(sink_r0(b), scc_r2(scc_r1(a, b, r), scc_r1(a, scc_r2(r, r, r), r), scc_r2(a, b, r)), scc_r1(a, b, r));
32;   return a == b ? r : scc_r2(a, b, r);
33; }
34; __attribute__((noinline)) int scc_rX(int a, int b, int r) {
35;   if (a > b)
36;     return scc_r2(b, a, sink_r0(r));
37;   if (a < b)                                                                         // V Diff to scc_r2
38;     return scc_r1(sink_r0(b), scc_r2(scc_r1(a, b, r), scc_r1(a, scc_r2(r, r, r), r), scc_r1(a, b, r)), scc_r1(a, b, r));
39;   return a == b ? r : scc_r2(a, b, r);
40; }
41target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
42
43define i32 @sink_r0(i32 %r) #0 {
44entry:
45  ret i32 %r
46}
47
48define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 {
49entry:
50  %call = call i32 @sink_r0(i32 %r)
51  %call1 = call i32 @scc_r2(i32 %r, i32 %a, i32 %call)
52  ret i32 %call1
53}
54
55define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
56entry:
57  %cmp = icmp sgt i32 %a, %b
58  br i1 %cmp, label %if.then, label %if.end
59
60if.then:                                          ; preds = %entry
61  %call = call i32 @sink_r0(i32 %r)
62  %call1 = call i32 @scc_r2(i32 %b, i32 %a, i32 %call)
63  br label %return
64
65if.end:                                           ; preds = %entry
66  %cmp2 = icmp slt i32 %a, %b
67  br i1 %cmp2, label %if.then3, label %if.end12
68
69if.then3:                                         ; preds = %if.end
70  %call4 = call i32 @sink_r0(i32 %b)
71  %call5 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
72  %call6 = call i32 @scc_r2(i32 %r, i32 %r, i32 %r)
73  %call7 = call i32 @scc_r1(i32 %a, i32 %call6, i32 %r)
74  %call8 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
75  %call9 = call i32 @scc_r2(i32 %call5, i32 %call7, i32 %call8)
76  %call10 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
77  %call11 = call i32 @scc_r1(i32 %call4, i32 %call9, i32 %call10)
78  br label %return
79
80if.end12:                                         ; preds = %if.end
81  %cmp13 = icmp eq i32 %a, %b
82  br i1 %cmp13, label %cond.true, label %cond.false
83
84cond.true:                                        ; preds = %if.end12
85  br label %cond.end
86
87cond.false:                                       ; preds = %if.end12
88  %call14 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
89  br label %cond.end
90
91cond.end:                                         ; preds = %cond.false, %cond.true
92  %cond = phi i32 [ %r, %cond.true ], [ %call14, %cond.false ]
93  br label %return
94
95return:                                           ; preds = %cond.end, %if.then3, %if.then
96  %retval.0 = phi i32 [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
97  ret i32 %retval.0
98}
99
100define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
101entry:
102  %cmp = icmp sgt i32 %a, %b
103  br i1 %cmp, label %if.then, label %if.end
104
105if.then:                                          ; preds = %entry
106  %call = call i32 @sink_r0(i32 %r)
107  %call1 = call i32 @scc_r2(i32 %b, i32 %a, i32 %call)
108  br label %return
109
110if.end:                                           ; preds = %entry
111  %cmp2 = icmp slt i32 %a, %b
112  br i1 %cmp2, label %if.then3, label %if.end12
113
114if.then3:                                         ; preds = %if.end
115  %call4 = call i32 @sink_r0(i32 %b)
116  %call5 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
117  %call6 = call i32 @scc_r2(i32 %r, i32 %r, i32 %r)
118  %call7 = call i32 @scc_r1(i32 %a, i32 %call6, i32 %r)
119  %call8 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
120  %call9 = call i32 @scc_r2(i32 %call5, i32 %call7, i32 %call8)
121  %call10 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
122  %call11 = call i32 @scc_r1(i32 %call4, i32 %call9, i32 %call10)
123  br label %return
124
125if.end12:                                         ; preds = %if.end
126  %cmp13 = icmp eq i32 %a, %b
127  br i1 %cmp13, label %cond.true, label %cond.false
128
129cond.true:                                        ; preds = %if.end12
130  br label %cond.end
131
132cond.false:                                       ; preds = %if.end12
133  %call14 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
134  br label %cond.end
135
136cond.end:                                         ; preds = %cond.false, %cond.true
137  %cond = phi i32 [ %r, %cond.true ], [ %call14, %cond.false ]
138  br label %return
139
140return:                                           ; preds = %cond.end, %if.then3, %if.then
141  %retval.0 = phi i32 [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
142  ret i32 %retval.0
143}
144
145
146; TEST SCC test returning a pointer value argument
147;
148; FNATTR: define double* @ptr_sink_r0(double* readnone returned %r)
149; FNATTR: define double* @ptr_scc_r1(double* %a, double* readnone %r, double* nocapture readnone %b)
150; FNATTR: define double* @ptr_scc_r2(double* readnone %a, double* readnone %b, double* readnone %r)
151;
152;
153; double* ptr_scc_r1(double* a, double* b, double* r);
154; double* ptr_scc_r2(double* a, double* b, double* r);
155;
156; __attribute__((noinline)) double* ptr_sink_r0(double* r) {
157;   return r;
158; }
159;
160; __attribute__((noinline)) double* ptr_scc_r1(double* a, double* r, double* b) {
161;   return ptr_scc_r2(r, a, ptr_sink_r0(r));
162; }
163;
164; __attribute__((noinline)) double* ptr_scc_r2(double* a, double* b, double* r) {
165;   if (a > b)
166;     return ptr_scc_r2(b, a, ptr_sink_r0(r));
167;   if (a < b)
168;     return ptr_scc_r1(ptr_sink_r0(b), ptr_scc_r2(ptr_scc_r1(a, b, r), ptr_scc_r1(a, ptr_scc_r2(r, r, r), r), ptr_scc_r2(a, b, r)), ptr_scc_r1(a, b, r));
169;   return a == b ? r : ptr_scc_r2(a, b, r);
170; }
171define double* @ptr_sink_r0(double* %r) #0 {
172entry:
173  ret double* %r
174}
175
176define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
177entry:
178  %call = call double* @ptr_sink_r0(double* %r)
179  %call1 = call double* @ptr_scc_r2(double* %r, double* %a, double* %call)
180  ret double* %call1
181}
182
183define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
184entry:
185  %cmp = icmp ugt double* %a, %b
186  br i1 %cmp, label %if.then, label %if.end
187
188if.then:                                          ; preds = %entry
189  %call = call double* @ptr_sink_r0(double* %r)
190  %call1 = call double* @ptr_scc_r2(double* %b, double* %a, double* %call)
191  br label %return
192
193if.end:                                           ; preds = %entry
194  %cmp2 = icmp ult double* %a, %b
195  br i1 %cmp2, label %if.then3, label %if.end12
196
197if.then3:                                         ; preds = %if.end
198  %call4 = call double* @ptr_sink_r0(double* %b)
199  %call5 = call double* @ptr_scc_r1(double* %a, double* %b, double* %r)
200  %call6 = call double* @ptr_scc_r2(double* %r, double* %r, double* %r)
201  %call7 = call double* @ptr_scc_r1(double* %a, double* %call6, double* %r)
202  %call8 = call double* @ptr_scc_r2(double* %a, double* %b, double* %r)
203  %call9 = call double* @ptr_scc_r2(double* %call5, double* %call7, double* %call8)
204  %call10 = call double* @ptr_scc_r1(double* %a, double* %b, double* %r)
205  %call11 = call double* @ptr_scc_r1(double* %call4, double* %call9, double* %call10)
206  br label %return
207
208if.end12:                                         ; preds = %if.end
209  %cmp13 = icmp eq double* %a, %b
210  br i1 %cmp13, label %cond.true, label %cond.false
211
212cond.true:                                        ; preds = %if.end12
213  br label %cond.end
214
215cond.false:                                       ; preds = %if.end12
216  %call14 = call double* @ptr_scc_r2(double* %a, double* %b, double* %r)
217  br label %cond.end
218
219cond.end:                                         ; preds = %cond.false, %cond.true
220  %cond = phi double* [ %r, %cond.true ], [ %call14, %cond.false ]
221  br label %return
222
223return:                                           ; preds = %cond.end, %if.then3, %if.then
224  %retval.0 = phi double* [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
225  ret double* %retval.0
226}
227
228
229; TEST a no-return singleton SCC
230;
231; int* rt0(int *a) {
232;   return *a ? a : rt0(a);
233; }
234;
235; FNATTR:  define i32* @rt0(i32* readonly %a)
236define i32* @rt0(i32* %a) #0 {
237entry:
238  %v = load i32, i32* %a, align 4
239  %tobool = icmp ne i32 %v, 0
240  %call = call i32* @rt0(i32* %a)
241  %sel = select i1 %tobool, i32* %a, i32* %call
242  ret i32* %sel
243}
244
245; TEST a no-return singleton SCC
246;
247; int* rt1(int *a) {
248;   return *a ? undef : rt1(a);
249; }
250;
251; FNATTR:  define noalias i32* @rt1(i32* nocapture readonly %a)
252define i32* @rt1(i32* %a) #0 {
253entry:
254  %v = load i32, i32* %a, align 4
255  %tobool = icmp ne i32 %v, 0
256  %call = call i32* @rt1(i32* %a)
257  %sel = select i1 %tobool, i32* undef, i32* %call
258  ret i32* %sel
259}
260
261; TEST another SCC test
262;
263; FNATTR:  define i32* @rt2_helper(i32* %a)
264; FNATTR:  define i32* @rt2(i32* readnone %a, i32* readnone %b)
265define i32* @rt2_helper(i32* %a) #0 {
266entry:
267  %call = call i32* @rt2(i32* %a, i32* %a)
268  ret i32* %call
269}
270
271define i32* @rt2(i32* %a, i32 *%b) #0 {
272entry:
273  %cmp = icmp eq i32* %a, null
274  br i1 %cmp, label %if.then, label %if.end
275
276if.then:
277  %call = call i32* @rt2_helper(i32* %a)
278  br label %if.end
279
280if.end:
281  %sel = phi i32* [ %b, %entry], [%call, %if.then]
282  ret i32* %sel
283}
284
285; TEST another SCC test
286;
287; FNATTR:  define i32* @rt3_helper(i32* %a, i32* %b)
288; FNATTR:  define i32* @rt3(i32* readnone %a, i32* readnone %b)
289define i32* @rt3_helper(i32* %a, i32* %b) #0 {
290entry:
291  %call = call i32* @rt3(i32* %a, i32* %b)
292  ret i32* %call
293}
294
295define i32* @rt3(i32* %a, i32 *%b) #0 {
296entry:
297  %cmp = icmp eq i32* %a, null
298  br i1 %cmp, label %if.then, label %if.end
299
300if.then:
301  %call = call i32* @rt3_helper(i32* %a, i32* %b)
302  br label %if.end
303
304if.end:
305  %sel = phi i32* [ %b, %entry], [%call, %if.then]
306  ret i32* %sel
307}
308
309; TEST address taken function with call to an external functions
310;
311;  void unknown_fn(void *);
312;
313;  int* calls_unknown_fn(int *r) {
314;    unknown_fn(&calls_unknown_fn);
315;    return r;
316;  }
317;
318;
319; FNATTR:     define i32* @calls_unknown_fn(i32* readnone returned %r)
320declare void @unknown_fn(i32* (i32*)*) #0
321
322define i32* @calls_unknown_fn(i32* %r) #0 {
323  tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn)
324  ret i32* %r
325}
326
327
328; TEST return call to a function that might be redifined at link time
329;
330;  int *maybe_redefined_fn2(int *r) {
331;    return r;
332;  }
333;
334;  int *calls_maybe_redefined_fn2(int *r) {
335;    return maybe_redefined_fn2(r);
336;  }
337;
338; Verify the maybe-redefined function is not annotated:
339;
340;
341; FNATTR:     define i32* @calls_maybe_redefined_fn2(i32* %r)
342define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
343entry:
344  ret i32* %r
345}
346
347define i32* @calls_maybe_redefined_fn2(i32* %r) #0 {
348entry:
349  %call = call i32* @maybe_redefined_fn2(i32* %r)
350  ret i32* %call
351}
352
353
354; TEST returned argument goes through select and phi
355;
356; double select_and_phi(double b) {
357;   double x = b;
358;   if (b > 0)
359;     x = b;
360;   return b == 0? b : x;
361; }
362;
363;
364; FNATTR:     define double @select_and_phi(double %b)
365define double @select_and_phi(double %b) #0 {
366entry:
367  %cmp = fcmp ogt double %b, 0.000000e+00
368  br i1 %cmp, label %if.then, label %if.end
369
370if.then:                                          ; preds = %entry
371  br label %if.end
372
373if.end:                                           ; preds = %if.then, %entry
374  %phi = phi double [ %b, %if.then ], [ %b, %entry ]
375  %cmp1 = fcmp oeq double %b, 0.000000e+00
376  %sel = select i1 %cmp1, double %b, double %phi
377  ret double %sel
378}
379
380
381; TEST returned argument goes through recursion, select, and phi
382;
383; double recursion_select_and_phi(int a, double b) {
384;   double x = b;
385;   if (a-- > 0)
386;     x = recursion_select_and_phi(a, b);
387;   return b == 0? b : x;
388; }
389;
390;
391; FNATTR:     define double @recursion_select_and_phi(i32 %a, double %b)
392;
393define double @recursion_select_and_phi(i32 %a, double %b) #0 {
394entry:
395  %dec = add nsw i32 %a, -1
396  %cmp = icmp sgt i32 %a, 0
397  br i1 %cmp, label %if.then, label %if.end
398
399if.then:                                          ; preds = %entry
400  %call = call double @recursion_select_and_phi(i32 %dec, double %b)
401  br label %if.end
402
403if.end:                                           ; preds = %if.then, %entry
404  %phi = phi double [ %call, %if.then ], [ %b, %entry ]
405  %cmp1 = fcmp oeq double %b, 0.000000e+00
406  %sel = select i1 %cmp1, double %b, double %phi
407  ret double %sel
408}
409
410
411; TEST returned argument goes through bitcasts
412;
413; double* bitcast(int* b) {
414;   return (double*)b;
415; }
416;
417;
418; FNATTR:     define double* @bitcast(i32* readnone %b)
419;
420define double* @bitcast(i32* %b) #0 {
421entry:
422  %bc0 = bitcast i32* %b to double*
423  ret double* %bc0
424}
425
426
427; TEST returned argument goes through select and phi interleaved with bitcasts
428;
429; double* bitcasts_select_and_phi(int* b) {
430;   double* x = b;
431;   if (b == 0)
432;     x = b;
433;   return b != 0 ? b : x;
434; }
435;
436;
437; FNATTR:     define double* @bitcasts_select_and_phi(i32* readnone %b)
438;
439define double* @bitcasts_select_and_phi(i32* %b) #0 {
440entry:
441  %bc0 = bitcast i32* %b to double*
442  %cmp = icmp eq double* %bc0, null
443  br i1 %cmp, label %if.then, label %if.end
444
445if.then:                                          ; preds = %entry
446  %bc1 = bitcast i32* %b to double*
447  br label %if.end
448
449if.end:                                           ; preds = %if.then, %entry
450  %phi = phi double* [ %bc1, %if.then ], [ %bc0, %entry ]
451  %bc2 = bitcast double* %phi to i8*
452  %bc3 = bitcast i32* %b to i8*
453  %cmp2 = icmp ne double* %bc0, null
454  %sel = select i1 %cmp2, i8* %bc2, i8* %bc3
455  %bc4 = bitcast i8* %sel to double*
456  ret double* %bc4
457}
458
459
460; TEST return argument or argument or undef
461;
462; double* ret_arg_arg_undef(int* b) {
463;   if (b == 0)
464;     return (double*)b;
465;   if (b == 0)
466;     return (double*)b;
467;   /* return undef */
468; }
469;
470;
471; FNATTR:     define double* @ret_arg_arg_undef(i32* readnone %b)
472;
473define double* @ret_arg_arg_undef(i32* %b) #0 {
474entry:
475  %bc0 = bitcast i32* %b to double*
476  %cmp = icmp eq double* %bc0, null
477  br i1 %cmp, label %ret_arg0, label %if.end
478
479ret_arg0:
480  %bc1 = bitcast i32* %b to double*
481  ret double* %bc1
482
483if.end:
484  br i1 %cmp, label %ret_arg1, label %ret_undef
485
486ret_arg1:
487  ret double* %bc0
488
489ret_undef:
490  ret double *undef
491}
492
493
494; TEST return undef or argument or argument
495;
496; double* ret_undef_arg_arg(int* b) {
497;   if (b == 0)
498;     return (double*)b;
499;   if (b == 0)
500;     return (double*)b;
501;   /* return undef */
502; }
503;
504;
505; FNATTR:     define double* @ret_undef_arg_arg(i32* readnone %b)
506;
507define double* @ret_undef_arg_arg(i32* %b) #0 {
508entry:
509  %bc0 = bitcast i32* %b to double*
510  %cmp = icmp eq double* %bc0, null
511  br i1 %cmp, label %ret_undef, label %if.end
512
513ret_undef:
514  ret double *undef
515
516if.end:
517  br i1 %cmp, label %ret_arg0, label %ret_arg1
518
519ret_arg0:
520  ret double* %bc0
521
522ret_arg1:
523  %bc1 = bitcast i32* %b to double*
524  ret double* %bc1
525}
526
527
528; TEST return undef or argument or undef
529;
530; double* ret_undef_arg_undef(int* b) {
531;   if (b == 0)
532;     /* return undef */
533;   if (b == 0)
534;     return (double*)b;
535;   /* return undef */
536; }
537;
538;
539; FNATTR:     define double* @ret_undef_arg_undef(i32* readnone %b)
540define double* @ret_undef_arg_undef(i32* %b) #0 {
541entry:
542  %bc0 = bitcast i32* %b to double*
543  %cmp = icmp eq double* %bc0, null
544  br i1 %cmp, label %ret_undef0, label %if.end
545
546ret_undef0:
547  ret double *undef
548
549if.end:
550  br i1 %cmp, label %ret_arg, label %ret_undef1
551
552ret_arg:
553  ret double* %bc0
554
555ret_undef1:
556  ret double *undef
557}
558
559; TEST return argument or unknown call result
560;
561; int* ret_arg_or_unknown(int* b) {
562;   if (b == 0)
563;     return b;
564;   return unknown();
565; }
566;
567; Verify we do not assume b is returned
568;
569; FNATTR:     define i32* @ret_arg_or_unknown(i32* %b)
570; FNATTR:     define i32* @ret_arg_or_unknown_through_phi(i32* %b)
571declare i32* @unknown(i32*)
572
573define i32* @ret_arg_or_unknown(i32* %b) #0 {
574entry:
575  %cmp = icmp eq i32* %b, null
576  br i1 %cmp, label %ret_arg, label %ret_unknown
577
578ret_arg:
579  ret i32* %b
580
581ret_unknown:
582  %call = call i32* @unknown(i32* %b)
583  ret i32* %call
584}
585
586define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
587entry:
588  %cmp = icmp eq i32* %b, null
589  br i1 %cmp, label %ret_arg, label %ret_unknown
590
591ret_arg:
592  br label %r
593
594ret_unknown:
595  %call = call i32* @unknown(i32* %b)
596  br label %r
597
598r:
599  %phi = phi i32* [ %b, %ret_arg ], [ %call, %ret_unknown ]
600  ret i32* %phi
601}
602
603; TEST inconsistent IR in dead code.
604;
605; FNATTR:     define i32 @deadblockcall1(i32 %A)
606; FNATTR:     define i32 @deadblockcall2(i32 %A)
607; FNATTR:     define i32 @deadblockphi1(i32 %A)
608; FNATTR:     define i32 @deadblockphi2(i32 %A)
609define i32 @deadblockcall1(i32 %A) #0 {
610entry:
611  ret i32 %A
612unreachableblock:
613  %B = call i32 @deadblockcall1(i32 %B)
614  ret i32 %B
615}
616
617declare i32 @deadblockcall_helper(i32 returned %A);
618
619define i32 @deadblockcall2(i32 %A) #0 {
620entry:
621  ret i32 %A
622unreachableblock1:
623  %B = call i32 @deadblockcall_helper(i32 %B)
624  ret i32 %B
625unreachableblock2:
626  %C = call i32 @deadblockcall1(i32 %C)
627  ret i32 %C
628}
629
630define i32 @deadblockphi1(i32 %A) #0 {
631entry:
632  br label %r
633unreachableblock1:
634  %B = call i32 @deadblockcall_helper(i32 %B)
635  ret i32 %B
636unreachableblock2:
637  %C = call i32 @deadblockcall1(i32 %C)
638  br label %r
639r:
640  %PHI = phi i32 [%A, %entry], [%C, %unreachableblock2]
641  ret i32 %PHI
642}
643
644define i32 @deadblockphi2(i32 %A) #0 {
645entry:
646  br label %r
647unreachableblock1:
648  %B = call i32 @deadblockcall_helper(i32 %B)
649  br label %unreachableblock3
650unreachableblock2:
651  %C = call i32 @deadblockcall1(i32 %C)
652  br label %unreachableblock3
653unreachableblock3:
654  %PHI1 = phi i32 [%B, %unreachableblock1], [%C, %unreachableblock2]
655  br label %r
656r:
657  %PHI2 = phi i32 [%A, %entry], [%PHI1, %unreachableblock3]
658  ret i32 %PHI2
659}
660
661declare void @noreturn() noreturn;
662
663define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
664entry:
665  br i1 %c, label %r, label %unreachablecall
666unreachablecall:
667  call void @noreturn();
668  %B = call i32 @deadblockcall_helper(i32 0)
669  br label %unreachableblock3
670unreachableblock2:
671  %C = call i32 @deadblockcall1(i32 %C)
672  br label %unreachableblock3
673unreachableblock3:
674  %PHI1 = phi i32 [%B, %unreachablecall], [%C, %unreachableblock2]
675  br label %r
676r:
677  %PHI2 = phi i32 [%A, %entry], [%PHI1, %unreachableblock3]
678  ret i32 %PHI2
679}
680
681attributes #0 = { noinline nounwind uwtable }
682