[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / FunctionAttrs / arg_returned.ll
blobd927cdf79278f46be1abecd148ac378cfddf9b91
1 ; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefix=FNATTR
2 ; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
3 ; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -functionattrs -S < %s | FileCheck %s --check-prefix=BOTH
5 ; Test cases specifically designed for the "returned" argument attribute.
6 ; We use FIXME's to indicate problems and missing attributes.
9 ; TEST SCC test returning an integer value argument
11 ; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
12 ; BOTH-NEXT: define i32 @sink_r0(i32 returned %r)
13 ; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
14 ; BOTH-NEXT: define i32 @scc_r1(i32 %a, i32 returned %r, i32 %b)
15 ; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
16 ; BOTH-NEXT: define i32 @scc_r2(i32 %a, i32 %b, i32 returned %r)
17 ; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
18 ; BOTH-NEXT: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
20 ; FNATTR: define i32 @sink_r0(i32 returned %r)
21 ; FNATTR: define i32 @scc_r1(i32 %a, i32 %r, i32 %b)
22 ; FNATTR: define i32 @scc_r2(i32 %a, i32 %b, i32 %r)
23 ; FNATTR: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
25 ; ATTRIBUTOR: define i32 @sink_r0(i32 returned %r)
26 ; ATTRIBUTOR: define i32 @scc_r1(i32 %a, i32 returned %r, i32 %b)
27 ; ATTRIBUTOR: define i32 @scc_r2(i32 %a, i32 %b, i32 returned %r)
28 ; ATTRIBUTOR: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
30 ; int scc_r1(int a, int b, int r);
31 ; int scc_r2(int a, int b, int r);
33 ; __attribute__((noinline)) int sink_r0(int r) {
34 ;   return r;
35 ; }
37 ; __attribute__((noinline)) int scc_r1(int a, int r, int b) {
38 ;   return scc_r2(r, a, sink_r0(r));
39 ; }
41 ; __attribute__((noinline)) int scc_r2(int a, int b, int r) {
42 ;   if (a > b)
43 ;     return scc_r2(b, a, sink_r0(r));
44 ;   if (a < b)
45 ;     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));
46 ;   return a == b ? r : scc_r2(a, b, r);
47 ; }
48 ; __attribute__((noinline)) int scc_rX(int a, int b, int r) {
49 ;   if (a > b)
50 ;     return scc_r2(b, a, sink_r0(r));
51 ;   if (a < b)                                                                         // V Diff to scc_r2
52 ;     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));
53 ;   return a == b ? r : scc_r2(a, b, r);
54 ; }
55 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
57 define i32 @sink_r0(i32 %r) #0 {
58 entry:
59   ret i32 %r
62 define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 {
63 entry:
64   %call = call i32 @sink_r0(i32 %r)
65   %call1 = call i32 @scc_r2(i32 %r, i32 %a, i32 %call)
66   ret i32 %call1
69 define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
70 entry:
71   %cmp = icmp sgt i32 %a, %b
72   br i1 %cmp, label %if.then, label %if.end
74 if.then:                                          ; preds = %entry
75   %call = call i32 @sink_r0(i32 %r)
76   %call1 = call i32 @scc_r2(i32 %b, i32 %a, i32 %call)
77   br label %return
79 if.end:                                           ; preds = %entry
80   %cmp2 = icmp slt i32 %a, %b
81   br i1 %cmp2, label %if.then3, label %if.end12
83 if.then3:                                         ; preds = %if.end
84   %call4 = call i32 @sink_r0(i32 %b)
85   %call5 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
86   %call6 = call i32 @scc_r2(i32 %r, i32 %r, i32 %r)
87   %call7 = call i32 @scc_r1(i32 %a, i32 %call6, i32 %r)
88   %call8 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
89   %call9 = call i32 @scc_r2(i32 %call5, i32 %call7, i32 %call8)
90   %call10 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
91   %call11 = call i32 @scc_r1(i32 %call4, i32 %call9, i32 %call10)
92   br label %return
94 if.end12:                                         ; preds = %if.end
95   %cmp13 = icmp eq i32 %a, %b
96   br i1 %cmp13, label %cond.true, label %cond.false
98 cond.true:                                        ; preds = %if.end12
99   br label %cond.end
101 cond.false:                                       ; preds = %if.end12
102   %call14 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
103   br label %cond.end
105 cond.end:                                         ; preds = %cond.false, %cond.true
106   %cond = phi i32 [ %r, %cond.true ], [ %call14, %cond.false ]
107   br label %return
109 return:                                           ; preds = %cond.end, %if.then3, %if.then
110   %retval.0 = phi i32 [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
111   ret i32 %retval.0
114 define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
115 entry:
116   %cmp = icmp sgt i32 %a, %b
117   br i1 %cmp, label %if.then, label %if.end
119 if.then:                                          ; preds = %entry
120   %call = call i32 @sink_r0(i32 %r)
121   %call1 = call i32 @scc_r2(i32 %b, i32 %a, i32 %call)
122   br label %return
124 if.end:                                           ; preds = %entry
125   %cmp2 = icmp slt i32 %a, %b
126   br i1 %cmp2, label %if.then3, label %if.end12
128 if.then3:                                         ; preds = %if.end
129   %call4 = call i32 @sink_r0(i32 %b)
130   %call5 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
131   %call6 = call i32 @scc_r2(i32 %r, i32 %r, i32 %r)
132   %call7 = call i32 @scc_r1(i32 %a, i32 %call6, i32 %r)
133   %call8 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
134   %call9 = call i32 @scc_r2(i32 %call5, i32 %call7, i32 %call8)
135   %call10 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
136   %call11 = call i32 @scc_r1(i32 %call4, i32 %call9, i32 %call10)
137   br label %return
139 if.end12:                                         ; preds = %if.end
140   %cmp13 = icmp eq i32 %a, %b
141   br i1 %cmp13, label %cond.true, label %cond.false
143 cond.true:                                        ; preds = %if.end12
144   br label %cond.end
146 cond.false:                                       ; preds = %if.end12
147   %call14 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
148   br label %cond.end
150 cond.end:                                         ; preds = %cond.false, %cond.true
151   %cond = phi i32 [ %r, %cond.true ], [ %call14, %cond.false ]
152   br label %return
154 return:                                           ; preds = %cond.end, %if.then3, %if.then
155   %retval.0 = phi i32 [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
156   ret i32 %retval.0
160 ; TEST SCC test returning a pointer value argument
162 ; FNATTR: define double* @ptr_sink_r0(double* readnone returned %r)
163 ; FNATTR: define double* @ptr_scc_r1(double* %a, double* readnone %r, double* nocapture readnone %b)
164 ; FNATTR: define double* @ptr_scc_r2(double* readnone %a, double* readnone %b, double* readnone %r)
166 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
167 ; ATTRIBUTOR-NEXT: define double* @ptr_sink_r0(double* readnone returned "no-capture-maybe-returned" %r)
168 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
169 ; ATTRIBUTOR-NEXT: define double* @ptr_scc_r1(double* readnone %a, double* readnone returned %r, double* nocapture readnone %b)
170 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
171 ; ATTRIBUTOR-NEXT: define double* @ptr_scc_r2(double* readnone %a, double* readnone %b, double* readnone returned %r)
173 ; double* ptr_scc_r1(double* a, double* b, double* r);
174 ; double* ptr_scc_r2(double* a, double* b, double* r);
176 ; __attribute__((noinline)) double* ptr_sink_r0(double* r) {
177 ;   return r;
178 ; }
180 ; __attribute__((noinline)) double* ptr_scc_r1(double* a, double* r, double* b) {
181 ;   return ptr_scc_r2(r, a, ptr_sink_r0(r));
182 ; }
184 ; __attribute__((noinline)) double* ptr_scc_r2(double* a, double* b, double* r) {
185 ;   if (a > b)
186 ;     return ptr_scc_r2(b, a, ptr_sink_r0(r));
187 ;   if (a < b)
188 ;     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));
189 ;   return a == b ? r : ptr_scc_r2(a, b, r);
190 ; }
191 define double* @ptr_sink_r0(double* %r) #0 {
192 entry:
193   ret double* %r
196 define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
197 entry:
198   %call = call double* @ptr_sink_r0(double* %r)
199   %call1 = call double* @ptr_scc_r2(double* %r, double* %a, double* %call)
200   ret double* %call1
203 define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
204 entry:
205   %cmp = icmp ugt double* %a, %b
206   br i1 %cmp, label %if.then, label %if.end
208 if.then:                                          ; preds = %entry
209   %call = call double* @ptr_sink_r0(double* %r)
210   %call1 = call double* @ptr_scc_r2(double* %b, double* %a, double* %call)
211   br label %return
213 if.end:                                           ; preds = %entry
214   %cmp2 = icmp ult double* %a, %b
215   br i1 %cmp2, label %if.then3, label %if.end12
217 if.then3:                                         ; preds = %if.end
218   %call4 = call double* @ptr_sink_r0(double* %b)
219   %call5 = call double* @ptr_scc_r1(double* %a, double* %b, double* %r)
220   %call6 = call double* @ptr_scc_r2(double* %r, double* %r, double* %r)
221   %call7 = call double* @ptr_scc_r1(double* %a, double* %call6, double* %r)
222   %call8 = call double* @ptr_scc_r2(double* %a, double* %b, double* %r)
223   %call9 = call double* @ptr_scc_r2(double* %call5, double* %call7, double* %call8)
224   %call10 = call double* @ptr_scc_r1(double* %a, double* %b, double* %r)
225   %call11 = call double* @ptr_scc_r1(double* %call4, double* %call9, double* %call10)
226   br label %return
228 if.end12:                                         ; preds = %if.end
229   %cmp13 = icmp eq double* %a, %b
230   br i1 %cmp13, label %cond.true, label %cond.false
232 cond.true:                                        ; preds = %if.end12
233   br label %cond.end
235 cond.false:                                       ; preds = %if.end12
236   %call14 = call double* @ptr_scc_r2(double* %a, double* %b, double* %r)
237   br label %cond.end
239 cond.end:                                         ; preds = %cond.false, %cond.true
240   %cond = phi double* [ %r, %cond.true ], [ %call14, %cond.false ]
241   br label %return
243 return:                                           ; preds = %cond.end, %if.then3, %if.then
244   %retval.0 = phi double* [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
245   ret double* %retval.0
249 ; TEST a no-return singleton SCC
251 ; int* rt0(int *a) {
252 ;   return *a ? a : rt0(a);
253 ; }
255 ; FNATTR:  define i32* @rt0(i32* readonly %a)
256 ; BOTH: Function Attrs: nofree noinline noreturn nosync nounwind readonly uwtable
257 ; BOTH-NEXT:    define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @rt0(i32* nocapture nonnull readonly dereferenceable(4) %a)
258 define i32* @rt0(i32* %a) #0 {
259 entry:
260   %v = load i32, i32* %a, align 4
261   %tobool = icmp ne i32 %v, 0
262   %call = call i32* @rt0(i32* %a)
263   %sel = select i1 %tobool, i32* %a, i32* %call
264   ret i32* %sel
267 ; TEST a no-return singleton SCC
269 ; int* rt1(int *a) {
270 ;   return *a ? undef : rt1(a);
271 ; }
273 ; FNATTR:  define noalias i32* @rt1(i32* nocapture readonly %a)
274 ; BOTH: Function Attrs: nofree noinline noreturn nosync nounwind readonly uwtable
275 ; BOTH-NEXT:    define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @rt1(i32* nocapture nonnull readonly dereferenceable(4) %a)
276 define i32* @rt1(i32* %a) #0 {
277 entry:
278   %v = load i32, i32* %a, align 4
279   %tobool = icmp ne i32 %v, 0
280   %call = call i32* @rt1(i32* %a)
281   %sel = select i1 %tobool, i32* undef, i32* %call
282   ret i32* %sel
285 ; TEST another SCC test
287 ; FNATTR:  define i32* @rt2_helper(i32* %a)
288 ; FNATTR:  define i32* @rt2(i32* readnone %a, i32* readnone %b)
289 ; BOTH:    define i32* @rt2_helper(i32* readnone returned %a)
290 ; BOTH:    define i32* @rt2(i32* readnone %a, i32* readnone "no-capture-maybe-returned" %b)
291 define i32* @rt2_helper(i32* %a) #0 {
292 entry:
293   %call = call i32* @rt2(i32* %a, i32* %a)
294   ret i32* %call
297 define i32* @rt2(i32* %a, i32 *%b) #0 {
298 entry:
299   %cmp = icmp eq i32* %a, null
300   br i1 %cmp, label %if.then, label %if.end
302 if.then:
303   %call = call i32* @rt2_helper(i32* %a)
304   br label %if.end
306 if.end:
307   %sel = phi i32* [ %b, %entry], [%call, %if.then]
308   ret i32* %sel
311 ; TEST another SCC test
313 ; FNATTR:  define i32* @rt3_helper(i32* %a, i32* %b)
314 ; FNATTR:  define i32* @rt3(i32* readnone %a, i32* readnone %b)
315 ; BOTH:    define i32* @rt3_helper(i32* readnone %a, i32* readnone returned "no-capture-maybe-returned" %b)
316 ; BOTH:    define i32* @rt3(i32* readnone %a, i32* readnone returned "no-capture-maybe-returned" %b)
317 define i32* @rt3_helper(i32* %a, i32* %b) #0 {
318 entry:
319   %call = call i32* @rt3(i32* %a, i32* %b)
320   ret i32* %call
323 define i32* @rt3(i32* %a, i32 *%b) #0 {
324 entry:
325   %cmp = icmp eq i32* %a, null
326   br i1 %cmp, label %if.then, label %if.end
328 if.then:
329   %call = call i32* @rt3_helper(i32* %a, i32* %b)
330   br label %if.end
332 if.end:
333   %sel = phi i32* [ %b, %entry], [%call, %if.then]
334   ret i32* %sel
337 ; TEST address taken function with call to an external functions
339 ;  void unknown_fn(void *);
341 ;  int* calls_unknown_fn(int *r) {
342 ;    unknown_fn(&calls_unknown_fn);
343 ;    return r;
344 ;  }
346 ; BOTH: declare void @unknown_fn(i32* (i32*)*)
348 ; BOTH:       Function Attrs: noinline nounwind uwtable
349 ; BOTH-NEXT:  define i32* @calls_unknown_fn(i32* readnone returned "no-capture-maybe-returned" %r)
350 ; FNATTR:     define i32* @calls_unknown_fn(i32* readnone returned %r)
351 ; ATTRIBUTOR: define i32* @calls_unknown_fn(i32* readnone returned "no-capture-maybe-returned" %r)
352 declare void @unknown_fn(i32* (i32*)*) #0
354 define i32* @calls_unknown_fn(i32* %r) #0 {
355   tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn)
356   ret i32* %r
360 ; TEST call to a function that might be redifined at link time
362 ;  int *maybe_redefined_fn(int *r) {
363 ;    return r;
364 ;  }
366 ;  int *calls_maybe_redefined_fn(int *r) {
367 ;    maybe_redefined_fn(r);
368 ;    return r;
369 ;  }
371 ; Verify the maybe-redefined function is not annotated:
373 ; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
374 ; ATTRIBUTOR: define linkonce_odr i32* @maybe_redefined_fn(i32* %r)
376 ; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
377 ; ATTRIBUTOR: define i32* @calls_maybe_redefined_fn(i32* returned %r)
379 ; BOTH: Function Attrs: noinline nounwind uwtable
380 ; BOTH-NEXT: define linkonce_odr i32* @maybe_redefined_fn(i32* %r)
382 ; BOTH: Function Attrs: noinline nounwind uwtable
383 ; BOTH-NEXT: define i32* @calls_maybe_redefined_fn(i32* returned %r)
384 define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 {
385 entry:
386   ret i32* %r
389 define i32* @calls_maybe_redefined_fn(i32* %r) #0 {
390 entry:
391   %call = call i32* @maybe_redefined_fn(i32* %r)
392   ret i32* %r
395 ; TEST return call to a function that might be redifined at link time
397 ;  int *maybe_redefined_fn2(int *r) {
398 ;    return r;
399 ;  }
401 ;  int *calls_maybe_redefined_fn2(int *r) {
402 ;    return maybe_redefined_fn2(r);
403 ;  }
405 ; Verify the maybe-redefined function is not annotated:
407 ; BOTH: Function Attrs: noinline nounwind uwtable
408 ; BOTH-NEXT: define linkonce_odr i32* @maybe_redefined_fn2(i32* %r)
409 ; BOTH: Function Attrs: noinline nounwind uwtable
410 ; BOTH-NEXT: define i32* @calls_maybe_redefined_fn2(i32* %r)
412 ; FNATTR:     define i32* @calls_maybe_redefined_fn2(i32* %r)
413 ; ATTRIBUTOR: define i32* @calls_maybe_redefined_fn2(i32* %r)
414 define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
415 entry:
416   ret i32* %r
419 define i32* @calls_maybe_redefined_fn2(i32* %r) #0 {
420 entry:
421   %call = call i32* @maybe_redefined_fn2(i32* %r)
422   ret i32* %call
426 ; TEST returned argument goes through select and phi
428 ; double select_and_phi(double b) {
429 ;   double x = b;
430 ;   if (b > 0)
431 ;     x = b;
432 ;   return b == 0? b : x;
433 ; }
435 ; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
436 ; BOTH-NEXT: define double @select_and_phi(double returned %b)
438 ; FNATTR:     define double @select_and_phi(double %b)
439 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
440 ; ATTRIBUTOR-NEXT: define double @select_and_phi(double returned %b)
441 define double @select_and_phi(double %b) #0 {
442 entry:
443   %cmp = fcmp ogt double %b, 0.000000e+00
444   br i1 %cmp, label %if.then, label %if.end
446 if.then:                                          ; preds = %entry
447   br label %if.end
449 if.end:                                           ; preds = %if.then, %entry
450   %phi = phi double [ %b, %if.then ], [ %b, %entry ]
451   %cmp1 = fcmp oeq double %b, 0.000000e+00
452   %sel = select i1 %cmp1, double %b, double %phi
453   ret double %sel
457 ; TEST returned argument goes through recursion, select, and phi
459 ; double recursion_select_and_phi(int a, double b) {
460 ;   double x = b;
461 ;   if (a-- > 0)
462 ;     x = recursion_select_and_phi(a, b);
463 ;   return b == 0? b : x;
464 ; }
466 ; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
467 ; BOTH-NEXT: define double @recursion_select_and_phi(i32 %a, double returned %b)
469 ; FNATTR:     define double @recursion_select_and_phi(i32 %a, double %b)
471 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
472 ; ATTRIBUTOR-NEXT: define double @recursion_select_and_phi(i32 %a, double returned %b)
473 define double @recursion_select_and_phi(i32 %a, double %b) #0 {
474 entry:
475   %dec = add nsw i32 %a, -1
476   %cmp = icmp sgt i32 %a, 0
477   br i1 %cmp, label %if.then, label %if.end
479 if.then:                                          ; preds = %entry
480   %call = call double @recursion_select_and_phi(i32 %dec, double %b)
481   br label %if.end
483 if.end:                                           ; preds = %if.then, %entry
484   %phi = phi double [ %call, %if.then ], [ %b, %entry ]
485   %cmp1 = fcmp oeq double %b, 0.000000e+00
486   %sel = select i1 %cmp1, double %b, double %phi
487   ret double %sel
491 ; TEST returned argument goes through bitcasts
493 ; double* bitcast(int* b) {
494 ;   return (double*)b;
495 ; }
497 ; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
498 ; BOTH-NEXT:  define double* @bitcast(i32* readnone returned "no-capture-maybe-returned" %b)
500 ; FNATTR:     define double* @bitcast(i32* readnone %b)
502 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
503 ; ATTRIBUTOR-NEXT: define double* @bitcast(i32* readnone returned "no-capture-maybe-returned" %b)
504 define double* @bitcast(i32* %b) #0 {
505 entry:
506   %bc0 = bitcast i32* %b to double*
507   ret double* %bc0
511 ; TEST returned argument goes through select and phi interleaved with bitcasts
513 ; double* bitcasts_select_and_phi(int* b) {
514 ;   double* x = b;
515 ;   if (b == 0)
516 ;     x = b;
517 ;   return b != 0 ? b : x;
518 ; }
520 ; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
521 ; BOTH-NEXT: define double* @bitcasts_select_and_phi(i32* readnone returned %b)
523 ; FNATTR:     define double* @bitcasts_select_and_phi(i32* readnone %b)
525 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
526 ; ATTRIBUTOR-NEXT: define double* @bitcasts_select_and_phi(i32* readnone returned %b)
527 define double* @bitcasts_select_and_phi(i32* %b) #0 {
528 entry:
529   %bc0 = bitcast i32* %b to double*
530   %cmp = icmp eq double* %bc0, null
531   br i1 %cmp, label %if.then, label %if.end
533 if.then:                                          ; preds = %entry
534   %bc1 = bitcast i32* %b to double*
535   br label %if.end
537 if.end:                                           ; preds = %if.then, %entry
538   %phi = phi double* [ %bc1, %if.then ], [ %bc0, %entry ]
539   %bc2 = bitcast double* %phi to i8*
540   %bc3 = bitcast i32* %b to i8*
541   %cmp2 = icmp ne double* %bc0, null
542   %sel = select i1 %cmp2, i8* %bc2, i8* %bc3
543   %bc4 = bitcast i8* %sel to double*
544   ret double* %bc4
548 ; TEST return argument or argument or undef
550 ; double* ret_arg_arg_undef(int* b) {
551 ;   if (b == 0)
552 ;     return (double*)b;
553 ;   if (b == 0)
554 ;     return (double*)b;
555 ;   /* return undef */
556 ; }
558 ; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
559 ; BOTH-NEXT:  define double* @ret_arg_arg_undef(i32* readnone returned %b)
561 ; FNATTR:     define double* @ret_arg_arg_undef(i32* readnone %b)
563 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
564 ; ATTRIBUTOR-NEXT: define double* @ret_arg_arg_undef(i32* readnone returned %b)
565 define double* @ret_arg_arg_undef(i32* %b) #0 {
566 entry:
567   %bc0 = bitcast i32* %b to double*
568   %cmp = icmp eq double* %bc0, null
569   br i1 %cmp, label %ret_arg0, label %if.end
571 ret_arg0:
572   %bc1 = bitcast i32* %b to double*
573   ret double* %bc1
575 if.end:
576   br i1 %cmp, label %ret_arg1, label %ret_undef
578 ret_arg1:
579   ret double* %bc0
581 ret_undef:
582   ret double *undef
586 ; TEST return undef or argument or argument
588 ; double* ret_undef_arg_arg(int* b) {
589 ;   if (b == 0)
590 ;     return (double*)b;
591 ;   if (b == 0)
592 ;     return (double*)b;
593 ;   /* return undef */
594 ; }
596 ; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
597 ; BOTH-NEXT:  define double* @ret_undef_arg_arg(i32* readnone returned %b)
599 ; FNATTR:     define double* @ret_undef_arg_arg(i32* readnone %b)
601 ; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
602 ; ATTRIBUTOR-NEXT: define double* @ret_undef_arg_arg(i32* readnone returned %b)
603 define double* @ret_undef_arg_arg(i32* %b) #0 {
604 entry:
605   %bc0 = bitcast i32* %b to double*
606   %cmp = icmp eq double* %bc0, null
607   br i1 %cmp, label %ret_undef, label %if.end
609 ret_undef:
610   ret double *undef
612 if.end:
613   br i1 %cmp, label %ret_arg0, label %ret_arg1
615 ret_arg0:
616   ret double* %bc0
618 ret_arg1:
619   %bc1 = bitcast i32* %b to double*
620   ret double* %bc1
624 ; TEST return undef or argument or undef
626 ; double* ret_undef_arg_undef(int* b) {
627 ;   if (b == 0)
628 ;     /* return undef */
629 ;   if (b == 0)
630 ;     return (double*)b;
631 ;   /* return undef */
632 ; }
634 ; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
635 ; BOTH-NEXT:  define double* @ret_undef_arg_undef(i32* readnone returned %b)
637 ; FNATTR:     define double* @ret_undef_arg_undef(i32* readnone %b)
638 ; ATTRIBUTOR: define double* @ret_undef_arg_undef(i32* readnone returned %b)
639 define double* @ret_undef_arg_undef(i32* %b) #0 {
640 entry:
641   %bc0 = bitcast i32* %b to double*
642   %cmp = icmp eq double* %bc0, null
643   br i1 %cmp, label %ret_undef0, label %if.end
645 ret_undef0:
646   ret double *undef
648 if.end:
649   br i1 %cmp, label %ret_arg, label %ret_undef1
651 ret_arg:
652   ret double* %bc0
654 ret_undef1:
655   ret double *undef
658 ; TEST return argument or unknown call result
660 ; int* ret_arg_or_unknown(int* b) {
661 ;   if (b == 0)
662 ;     return b;
663 ;   return unknown();
664 ; }
666 ; Verify we do not assume b is returned
668 ; FNATTR:     define i32* @ret_arg_or_unknown(i32* %b)
669 ; FNATTR:     define i32* @ret_arg_or_unknown_through_phi(i32* %b)
670 ; ATTRIBUTOR: define i32* @ret_arg_or_unknown(i32* %b)
671 ; ATTRIBUTOR: define i32* @ret_arg_or_unknown_through_phi(i32* %b)
672 ; BOTH:       define i32* @ret_arg_or_unknown(i32* %b)
673 ; BOTH:       define i32* @ret_arg_or_unknown_through_phi(i32* %b)
674 declare i32* @unknown(i32*)
676 define i32* @ret_arg_or_unknown(i32* %b) #0 {
677 entry:
678   %cmp = icmp eq i32* %b, null
679   br i1 %cmp, label %ret_arg, label %ret_unknown
681 ret_arg:
682   ret i32* %b
684 ret_unknown:
685   %call = call i32* @unknown(i32* %b)
686   ret i32* %call
689 define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
690 entry:
691   %cmp = icmp eq i32* %b, null
692   br i1 %cmp, label %ret_arg, label %ret_unknown
694 ret_arg:
695   br label %r
697 ret_unknown:
698   %call = call i32* @unknown(i32* %b)
699   br label %r
702   %phi = phi i32* [ %b, %ret_arg ], [ %call, %ret_unknown ]
703   ret i32* %phi
706 ; TEST inconsistent IR in dead code.
708 ; FNATTR:     define i32 @deadblockcall1(i32 %A)
709 ; FNATTR:     define i32 @deadblockcall2(i32 %A)
710 ; FNATTR:     define i32 @deadblockphi1(i32 %A)
711 ; FNATTR:     define i32 @deadblockphi2(i32 %A)
712 ; ATTRIBUTOR: define i32 @deadblockcall1(i32 returned %A)
713 ; ATTRIBUTOR: define i32 @deadblockcall2(i32 returned %A)
714 ; ATTRIBUTOR: define i32 @deadblockphi1(i32 returned %A)
715 ; ATTRIBUTOR: define i32 @deadblockphi2(i32 returned %A)
716 ; BOTH:       define i32 @deadblockcall1(i32 returned %A)
717 ; BOTH:       define i32 @deadblockcall2(i32 returned %A)
718 ; BOTH:       define i32 @deadblockphi1(i32 returned %A)
719 ; BOTH:       define i32 @deadblockphi2(i32 returned %A)
720 define i32 @deadblockcall1(i32 %A) #0 {
721 entry:
722   ret i32 %A
723 unreachableblock:
724   %B = call i32 @deadblockcall1(i32 %B)
725   ret i32 %B
728 declare i32 @deadblockcall_helper(i32 returned %A);
730 define i32 @deadblockcall2(i32 %A) #0 {
731 entry:
732   ret i32 %A
733 unreachableblock1:
734   %B = call i32 @deadblockcall_helper(i32 %B)
735   ret i32 %B
736 unreachableblock2:
737   %C = call i32 @deadblockcall1(i32 %C)
738   ret i32 %C
741 define i32 @deadblockphi1(i32 %A) #0 {
742 entry:
743   br label %r
744 unreachableblock1:
745   %B = call i32 @deadblockcall_helper(i32 %B)
746   ret i32 %B
747 unreachableblock2:
748   %C = call i32 @deadblockcall1(i32 %C)
749   br label %r
751   %PHI = phi i32 [%A, %entry], [%C, %unreachableblock2]
752   ret i32 %PHI
755 define i32 @deadblockphi2(i32 %A) #0 {
756 entry:
757   br label %r
758 unreachableblock1:
759   %B = call i32 @deadblockcall_helper(i32 %B)
760   br label %unreachableblock3
761 unreachableblock2:
762   %C = call i32 @deadblockcall1(i32 %C)
763   br label %unreachableblock3
764 unreachableblock3:
765   %PHI1 = phi i32 [%B, %unreachableblock1], [%C, %unreachableblock2]
766   br label %r
768   %PHI2 = phi i32 [%A, %entry], [%PHI1, %unreachableblock3]
769   ret i32 %PHI2
772 declare void @noreturn() noreturn;
774 define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
775 entry:
776   br i1 %c, label %r, label %unreachablecall
777 unreachablecall:
778   call void @noreturn();
779   %B = call i32 @deadblockcall_helper(i32 0)
780   br label %unreachableblock3
781 unreachableblock2:
782   %C = call i32 @deadblockcall1(i32 %C)
783   br label %unreachableblock3
784 unreachableblock3:
785   %PHI1 = phi i32 [%B, %unreachablecall], [%C, %unreachableblock2]
786   br label %r
788   %PHI2 = phi i32 [%A, %entry], [%PHI1, %unreachableblock3]
789   ret i32 %PHI2
792 define weak_odr i32 @non_exact_0() {
793   ret i32 0
795 define weak_odr i32 @non_exact_1(i32 %a) {
796   ret i32 %a
798 define weak_odr i32 @non_exact_2(i32 returned %a) {
799   ret i32 %a
801 define weak_odr i32* @non_exact_3(i32* align 32 returned %a) {
802   ret i32* %a
804 define i32 @exact(i32* %a) {
805   %c0 = call i32 @non_exact_0()
806   %c1 = call i32 @non_exact_1(i32 1)
807   %c2 = call i32 @non_exact_2(i32 2)
808   %c3 = call i32* @non_exact_3(i32* %a)
809 ; We can use the information of the weak function non_exact_3 because it was
810 ; given to us and not derived (the alignment of the returned argument).
811 ; ATTRIBUTOR:  %c4 = load i32, i32* %c3, align 32
812   %c4 = load i32, i32* %c3
813 ; FIXME: %c2 and %c3 should be replaced but not %c0 or %c1!
814 ; ATTRIBUTOR:  %add1 = add i32 %c0, %c1
815 ; ATTRIBUTOR:  %add2 = add i32 %add1, %c2
816 ; ATTRIBUTOR:  %add3 = add i32 %add2, %c4
817   %add1 = add i32 %c0, %c1
818   %add2 = add i32 %add1, %c2
819   %add3 = add i32 %add2, %c4
820   ret i32 %add3
823 @G = external global i8
824 define i32* @ret_const() #0 {
825   %bc = bitcast i8* @G to i32*
826   ret i32* %bc
828 define i32* @use_const() #0 {
829   %c = call i32* @ret_const()
830   ; ATTRIBUTOR: ret i32* bitcast (i8* @G to i32*)
831   ret i32* %c
833 define i32* @dont_use_const() #0 {
834   %c = musttail call i32* @ret_const()
835   ; ATTRIBUTOR: ret i32* %c
836   ret i32* %c
839 attributes #0 = { noinline nounwind uwtable }
841 ; BOTH-NOT: attributes #
842 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn }
843 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline nosync nounwind readnone uwtable }
844 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline noreturn nosync nounwind readonly uwtable }
845 ; BOTH-DAG: attributes #{{[0-9]*}} = { noinline nounwind uwtable }
846 ; BOTH-DAG: attributes #{{[0-9]*}} = { noreturn }
847 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline norecurse nosync nounwind readnone uwtable }
848 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree nosync readnone willreturn }
849 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree nosync readnone }
850 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noreturn nosync readonly }
851 ; BOTH-NOT: attributes #