1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
2; RUN: opt -attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4; RUN: opt -attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
6;
7; Test cases specifically designed for the "no-capture" argument attribute.
8; We use FIXME's to indicate problems and missing attributes.
9;
10target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
11declare i32* @unknown()
12
13; TEST comparison against NULL
14;
15; int is_null_return(int *p) {
16;   return p == 0;
17; }
18;
19; no-capture is missing on %p because it is not dereferenceable
20define i32 @is_null_return(i32* %p) #0 {
21; CHECK-LABEL: define {{[^@]+}}@is_null_return
22; CHECK-SAME: (i32* nofree readnone [[P:%.*]])
23; CHECK-NEXT:  entry:
24; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32* [[P]], null
25; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
26; CHECK-NEXT:    ret i32 [[CONV]]
27;
28entry:
29  %cmp = icmp eq i32* %p, null
30  %conv = zext i1 %cmp to i32
31  ret i32 %conv
32}
33
34; TEST comparison against NULL in control flow
35;
36; int is_null_control(int *p) {
37;   if (p == 0)
38;     return 1;
39;   if (0 == p)
40;     return 1;
41;   return 0;
42; }
43;
44; no-capture is missing on %p because it is not dereferenceable
45define i32 @is_null_control(i32* %p) #0 {
46; CHECK-LABEL: define {{[^@]+}}@is_null_control
47; CHECK-SAME: (i32* nofree [[P:%.*]])
48; CHECK-NEXT:  entry:
49; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
50; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32* [[P]], null
51; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
52; CHECK:       if.then:
53; CHECK-NEXT:    store i32 1, i32* [[RETVAL]], align 4
54; CHECK-NEXT:    br label [[RETURN:%.*]]
55; CHECK:       if.end:
56; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32* null, [[P]]
57; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
58; CHECK:       if.then2:
59; CHECK-NEXT:    store i32 1, i32* [[RETVAL]], align 4
60; CHECK-NEXT:    br label [[RETURN]]
61; CHECK:       if.end3:
62; CHECK-NEXT:    store i32 0, i32* [[RETVAL]], align 4
63; CHECK-NEXT:    br label [[RETURN]]
64; CHECK:       return:
65; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[RETVAL]], align 4
66; CHECK-NEXT:    ret i32 [[TMP0]]
67;
68entry:
69  %retval = alloca i32, align 4
70  %cmp = icmp eq i32* %p, null
71  br i1 %cmp, label %if.then, label %if.end
72
73if.then:                                          ; preds = %entry
74  store i32 1, i32* %retval, align 4
75  br label %return
76
77if.end:                                           ; preds = %entry
78  %cmp1 = icmp eq i32* null, %p
79  br i1 %cmp1, label %if.then2, label %if.end3
80
81if.then2:                                         ; preds = %if.end
82  store i32 1, i32* %retval, align 4
83  br label %return
84
85if.end3:                                          ; preds = %if.end
86  store i32 0, i32* %retval, align 4
87  br label %return
88
89return:                                           ; preds = %if.end3, %if.then2, %if.then
90  %0 = load i32, i32* %retval, align 4
91  ret i32 %0
92}
93
94; TEST singleton SCC
95;
96; double *srec0(double *a) {
97;   srec0(a);
98;   return 0;
99; }
100;
101define double* @srec0(double* %a) #0 {
102; CHECK-LABEL: define {{[^@]+}}@srec0
103; CHECK-SAME: (double* nocapture nofree readnone [[A:%.*]])
104; CHECK-NEXT:  entry:
105; CHECK-NEXT:    unreachable
106;
107entry:
108  %call = call double* @srec0(double* %a)
109  ret double* null
110}
111
112; TEST singleton SCC with lots of nested recursive calls
113;
114; int* srec16(int* a) {
115;   return srec16(srec16(srec16(srec16(
116;          srec16(srec16(srec16(srec16(
117;          srec16(srec16(srec16(srec16(
118;          srec16(srec16(srec16(srec16(
119;                        a
120;          ))))))))))))))));
121; }
122;
123; Other arguments are possible here due to the no-return behavior.
124;
125define i32* @srec16(i32* %a) #0 {
126; CHECK-LABEL: define {{[^@]+}}@srec16
127; CHECK-SAME: (i32* nocapture nofree readnone [[A:%.*]])
128; CHECK-NEXT:  entry:
129; CHECK-NEXT:    unreachable
130;
131entry:
132  %call = call i32* @srec16(i32* %a)
133  %call1 = call i32* @srec16(i32* %call)
134  %call2 = call i32* @srec16(i32* %call1)
135  %call3 = call i32* @srec16(i32* %call2)
136  %call4 = call i32* @srec16(i32* %call3)
137  %call5 = call i32* @srec16(i32* %call4)
138  %call6 = call i32* @srec16(i32* %call5)
139  %call7 = call i32* @srec16(i32* %call6)
140  %call8 = call i32* @srec16(i32* %call7)
141  %call9 = call i32* @srec16(i32* %call8)
142  %call10 = call i32* @srec16(i32* %call9)
143  %call11 = call i32* @srec16(i32* %call10)
144  %call12 = call i32* @srec16(i32* %call11)
145  %call13 = call i32* @srec16(i32* %call12)
146  %call14 = call i32* @srec16(i32* %call13)
147  %call15 = call i32* @srec16(i32* %call14)
148  ret i32* %call15
149}
150
151; TEST SCC with various calls, casts, and comparisons agains NULL
152;
153; float *scc_A(int *a) {
154;   return (float*)(a ? (int*)scc_A((int*)scc_B((double*)scc_C((short*)a))) : a);
155; }
156;
157; long *scc_B(double *a) {
158;   return (long*)(a ? scc_C((short*)scc_B((double*)scc_A((int*)a))) : a);
159; }
160;
161; void *scc_C(short *a) {
162;   return scc_A((int*)(scc_A(a) ? scc_B((double*)a) : scc_C(a)));
163; }
164define float* @scc_A(i32* dereferenceable_or_null(4) %a) {
165; CHECK-LABEL: define {{[^@]+}}@scc_A
166; CHECK-SAME: (i32* nofree readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]])
167; CHECK-NEXT:  entry:
168; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32* [[A]], null
169; CHECK-NEXT:    br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
170; CHECK:       cond.true:
171; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[A]] to i16*
172; CHECK-NEXT:    [[CALL:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0]])
173; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i8* [[CALL]] to double*
174; CHECK-NEXT:    [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1]])
175; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i32*
176; CHECK-NEXT:    [[CALL2:%.*]] = call float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP2]])
177; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float* [[CALL2]] to i32*
178; CHECK-NEXT:    br label [[COND_END:%.*]]
179; CHECK:       cond.false:
180; CHECK-NEXT:    br label [[COND_END]]
181; CHECK:       cond.end:
182; CHECK-NEXT:    [[COND:%.*]] = phi i32* [ [[TMP3]], [[COND_TRUE]] ], [ [[A]], [[COND_FALSE]] ]
183; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[COND]] to float*
184; CHECK-NEXT:    ret float* [[TMP4]]
185;
186entry:
187  %tobool = icmp ne i32* %a, null
188  br i1 %tobool, label %cond.true, label %cond.false
189
190cond.true:                                        ; preds = %entry
191  %0 = bitcast i32* %a to i16*
192  %call = call i8* @scc_C(i16* %0)
193  %1 = bitcast i8* %call to double*
194  %call1 = call i64* @scc_B(double* %1)
195  %2 = bitcast i64* %call1 to i32*
196  %call2 = call float* @scc_A(i32* %2)
197  %3 = bitcast float* %call2 to i32*
198  br label %cond.end
199
200cond.false:                                       ; preds = %entry
201  br label %cond.end
202
203cond.end:                                         ; preds = %cond.false, %cond.true
204  %cond = phi i32* [ %3, %cond.true ], [ %a, %cond.false ]
205  %4 = bitcast i32* %cond to float*
206  ret float* %4
207}
208
209define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
210; CHECK-LABEL: define {{[^@]+}}@scc_B
211; CHECK-SAME: (double* nofree readnone returned dereferenceable_or_null(8) "no-capture-maybe-returned" [[A:%.*]])
212; CHECK-NEXT:  entry:
213; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne double* [[A]], null
214; CHECK-NEXT:    br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
215; CHECK:       cond.true:
216; CHECK-NEXT:    [[TMP0:%.*]] = bitcast double* [[A]] to i32*
217; CHECK-NEXT:    [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0]])
218; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float* [[CALL]] to double*
219; CHECK-NEXT:    [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1]])
220; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i16*
221; CHECK-NEXT:    [[CALL2:%.*]] = call i8* @scc_C(i16* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP2]])
222; CHECK-NEXT:    br label [[COND_END:%.*]]
223; CHECK:       cond.false:
224; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double* [[A]] to i8*
225; CHECK-NEXT:    br label [[COND_END]]
226; CHECK:       cond.end:
227; CHECK-NEXT:    [[COND:%.*]] = phi i8* [ [[CALL2]], [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
228; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i8* [[COND]] to i64*
229; CHECK-NEXT:    ret i64* [[TMP4]]
230;
231entry:
232  %tobool = icmp ne double* %a, null
233  br i1 %tobool, label %cond.true, label %cond.false
234
235cond.true:                                        ; preds = %entry
236  %0 = bitcast double* %a to i32*
237  %call = call float* @scc_A(i32* %0)
238  %1 = bitcast float* %call to double*
239  %call1 = call i64* @scc_B(double* %1)
240  %2 = bitcast i64* %call1 to i16*
241  %call2 = call i8* @scc_C(i16* %2)
242  br label %cond.end
243
244cond.false:                                       ; preds = %entry
245  %3 = bitcast double* %a to i8*
246  br label %cond.end
247
248cond.end:                                         ; preds = %cond.false, %cond.true
249  %cond = phi i8* [ %call2, %cond.true ], [ %3, %cond.false ]
250  %4 = bitcast i8* %cond to i64*
251  ret i64* %4
252}
253
254define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
255; CHECK-LABEL: define {{[^@]+}}@scc_C
256; CHECK-SAME: (i16* nofree readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]])
257; CHECK-NEXT:  entry:
258; CHECK-NEXT:    [[BC:%.*]] = bitcast i16* [[A]] to i32*
259; CHECK-NEXT:    [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[BC]])
260; CHECK-NEXT:    [[BC2:%.*]] = bitcast float* [[CALL]] to i8*
261; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8* [[BC2]], null
262; CHECK-NEXT:    br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
263; CHECK:       cond.true:
264; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[A]] to double*
265; CHECK-NEXT:    [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0]])
266; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8*
267; CHECK-NEXT:    br label [[COND_END:%.*]]
268; CHECK:       cond.false:
269; CHECK-NEXT:    [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[A]])
270; CHECK-NEXT:    br label [[COND_END]]
271; CHECK:       cond.end:
272; CHECK-NEXT:    [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [ [[CALL2]], [[COND_FALSE]] ]
273; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[COND]] to i32*
274; CHECK-NEXT:    [[CALL3:%.*]] = call float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP2]])
275; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8*
276; CHECK-NEXT:    ret i8* [[TMP3]]
277;
278entry:
279  %bc = bitcast i16* %a to i32*
280  %call = call float* @scc_A(i32* %bc)
281  %bc2 = bitcast float* %call to i8*
282  %tobool = icmp ne i8* %bc2, null
283  br i1 %tobool, label %cond.true, label %cond.false
284
285cond.true:                                        ; preds = %entry
286  %0 = bitcast i16* %a to double*
287  %call1 = call i64* @scc_B(double* %0)
288  %1 = bitcast i64* %call1 to i8*
289  br label %cond.end
290
291cond.false:                                       ; preds = %entry
292  %call2 = call i8* @scc_C(i16* %a)
293  br label %cond.end
294
295cond.end:                                         ; preds = %cond.false, %cond.true
296  %cond = phi i8* [ %1, %cond.true ], [ %call2, %cond.false ]
297  %2 = bitcast i8* %cond to i32*
298  %call3 = call float* @scc_A(i32* %2)
299  %3 = bitcast float* %call3 to i8*
300  ret i8* %3
301}
302
303
304; TEST call to external function, marked no-capture
305;
306; void external_no_capture(int /* no-capture */ *p);
307; void test_external_no_capture(int *p) {
308;   external_no_capture(p);
309; }
310;
311declare void @external_no_capture(i32* nocapture)
312
313define void @test_external_no_capture(i32* %p) #0 {
314; CHECK-LABEL: define {{[^@]+}}@test_external_no_capture
315; CHECK-SAME: (i32* nocapture [[P:%.*]])
316; CHECK-NEXT:  entry:
317; CHECK-NEXT:    call void @external_no_capture(i32* nocapture [[P]])
318; CHECK-NEXT:    ret void
319;
320entry:
321  call void @external_no_capture(i32* %p)
322  ret void
323}
324
325; TEST call to external var-args function, marked no-capture
326;
327; void test_var_arg_call(char *p, int a) {
328;   printf(p, a);
329; }
330;
331define void @test_var_arg_call(i8* %p, i32 %a) #0 {
332; CHECK-LABEL: define {{[^@]+}}@test_var_arg_call
333; CHECK-SAME: (i8* nocapture [[P:%.*]], i32 [[A:%.*]])
334; CHECK-NEXT:  entry:
335; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, ...) @printf(i8* nocapture [[P]], i32 [[A]])
336; CHECK-NEXT:    ret void
337;
338entry:
339  %call = call i32 (i8*, ...) @printf(i8* %p, i32 %a)
340  ret void
341}
342
343declare i32 @printf(i8* nocapture, ...)
344
345
346; TEST "captured" only through return
347;
348; long *not_captured_but_returned_0(long *a) {
349;   *a1 = 0;
350;   return a;
351; }
352;
353; There should *not* be a no-capture attribute on %a
354define i64* @not_captured_but_returned_0(i64* %a) #0 {
355; CHECK-LABEL: define {{[^@]+}}@not_captured_but_returned_0
356; CHECK-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]])
357; CHECK-NEXT:  entry:
358; CHECK-NEXT:    store i64 0, i64* [[A]], align 8
359; CHECK-NEXT:    ret i64* [[A]]
360;
361entry:
362  store i64 0, i64* %a, align 8
363  ret i64* %a
364}
365
366; TEST "captured" only through return
367;
368; long *not_captured_but_returned_1(long *a) {
369;   *(a+1) = 1;
370;   return a + 1;
371; }
372;
373; There should *not* be a no-capture attribute on %a
374define i64* @not_captured_but_returned_1(i64* %a) #0 {
375; CHECK-LABEL: define {{[^@]+}}@not_captured_but_returned_1
376; CHECK-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A:%.*]])
377; CHECK-NEXT:  entry:
378; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i64, i64* [[A]], i64 1
379; CHECK-NEXT:    store i64 1, i64* [[ADD_PTR]], align 8
380; CHECK-NEXT:    ret i64* [[ADD_PTR]]
381;
382entry:
383  %add.ptr = getelementptr inbounds i64, i64* %a, i64 1
384  store i64 1, i64* %add.ptr, align 8
385  ret i64* %add.ptr
386}
387
388; TEST calls to "captured" only through return functions
389;
390; void test_not_captured_but_returned_calls(long *a) {
391;   not_captured_but_returned_0(a);
392;   not_captured_but_returned_1(a);
393; }
394;
395define void @test_not_captured_but_returned_calls(i64* %a) #0 {
396; IS__TUNIT____-LABEL: define {{[^@]+}}@test_not_captured_but_returned_calls
397; IS__TUNIT____-SAME: (i64* nocapture nofree writeonly align 8 [[A:%.*]])
398; IS__TUNIT____-NEXT:  entry:
399; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
400; IS__TUNIT____-NEXT:    [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
401; IS__TUNIT____-NEXT:    ret void
402;
403; IS__CGSCC____-LABEL: define {{[^@]+}}@test_not_captured_but_returned_calls
404; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]])
405; IS__CGSCC____-NEXT:  entry:
406; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]])
407; IS__CGSCC____-NEXT:    [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]])
408; IS__CGSCC____-NEXT:    ret void
409;
410entry:
411  %call = call i64* @not_captured_but_returned_0(i64* %a)
412  %call1 = call i64* @not_captured_but_returned_1(i64* %a)
413  ret void
414}
415
416; TEST "captured" only through transitive return
417;
418; long* negative_test_not_captured_but_returned_call_0a(long *a) {
419;   return not_captured_but_returned_0(a);
420; }
421;
422; There should *not* be a no-capture attribute on %a
423define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 {
424; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a
425; IS__TUNIT____-SAME: (i64* nofree returned writeonly align 8 "no-capture-maybe-returned" [[A:%.*]])
426; IS__TUNIT____-NEXT:  entry:
427; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
428; IS__TUNIT____-NEXT:    ret i64* [[CALL]]
429;
430; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a
431; IS__CGSCC____-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) [[A:%.*]])
432; IS__CGSCC____-NEXT:  entry:
433; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A]])
434; IS__CGSCC____-NEXT:    ret i64* [[CALL]]
435;
436entry:
437  %call = call i64* @not_captured_but_returned_0(i64* %a)
438  ret i64* %call
439}
440
441; TEST captured through write
442;
443; void negative_test_not_captured_but_returned_call_0b(long *a) {
444;   *a = (long)not_captured_but_returned_0(a);
445; }
446;
447; There should *not* be a no-capture attribute on %a
448define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
449; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0b
450; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 [[A:%.*]])
451; IS__TUNIT____-NEXT:  entry:
452; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
453; IS__TUNIT____-NEXT:    [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
454; IS__TUNIT____-NEXT:    store i64 [[TMP0]], i64* [[A]], align 8
455; IS__TUNIT____-NEXT:    ret void
456;
457; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0b
458; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A:%.*]])
459; IS__CGSCC____-NEXT:  entry:
460; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A]])
461; IS__CGSCC____-NEXT:    [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
462; IS__CGSCC____-NEXT:    store i64 [[TMP0]], i64* [[A]], align 8
463; IS__CGSCC____-NEXT:    ret void
464;
465entry:
466  %call = call i64* @not_captured_but_returned_0(i64* %a)
467  %0 = ptrtoint i64* %call to i64
468  store i64 %0, i64* %a, align 8
469  ret void
470}
471
472; TEST "captured" only through transitive return
473;
474; long* negative_test_not_captured_but_returned_call_1a(long *a) {
475;   return not_captured_but_returned_1(a);
476; }
477;
478; There should *not* be a no-capture attribute on %a
479define i64* @negative_test_not_captured_but_returned_call_1a(i64* %a) #0 {
480; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1a
481; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A:%.*]])
482; IS__TUNIT____-NEXT:  entry:
483; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
484; IS__TUNIT____-NEXT:    ret i64* [[CALL]]
485;
486; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1a
487; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]])
488; IS__CGSCC____-NEXT:  entry:
489; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]])
490; IS__CGSCC____-NEXT:    ret i64* [[CALL]]
491;
492entry:
493  %call = call i64* @not_captured_but_returned_1(i64* %a)
494  ret i64* %call
495}
496
497; TEST captured through write
498;
499; void negative_test_not_captured_but_returned_call_1b(long *a) {
500;   *a = (long)not_captured_but_returned_1(a);
501; }
502;
503; There should *not* be a no-capture attribute on %a
504define void @negative_test_not_captured_but_returned_call_1b(i64* %a) #0 {
505; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b
506; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 [[A:%.*]])
507; IS__TUNIT____-NEXT:  entry:
508; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
509; IS__TUNIT____-NEXT:    [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
510; IS__TUNIT____-NEXT:    store i64 [[TMP0]], i64* [[CALL]], align 8
511; IS__TUNIT____-NEXT:    ret void
512;
513; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b
514; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]])
515; IS__CGSCC____-NEXT:  entry:
516; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]])
517; IS__CGSCC____-NEXT:    [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
518; IS__CGSCC____-NEXT:    store i64 [[TMP0]], i64* [[CALL]], align 8
519; IS__CGSCC____-NEXT:    ret void
520;
521entry:
522  %call = call i64* @not_captured_but_returned_1(i64* %a)
523  %0 = ptrtoint i64* %call to i64
524  store i64 %0, i64* %call, align 8
525  ret void
526}
527
528; TEST return argument or unknown call result
529;
530; int* ret_arg_or_unknown(int* b) {
531;   if (b == 0)
532;     return b;
533;   return unknown();
534; }
535;
536; Verify we do *not* assume b is returned or not captured.
537;
538
539define i32* @ret_arg_or_unknown(i32* %b) #0 {
540; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown
541; CHECK-SAME: (i32* [[B:%.*]])
542; CHECK-NEXT:  entry:
543; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32* [[B]], null
544; CHECK-NEXT:    br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
545; CHECK:       ret_arg:
546; CHECK-NEXT:    ret i32* [[B]]
547; CHECK:       ret_unknown:
548; CHECK-NEXT:    [[CALL:%.*]] = call i32* @unknown()
549; CHECK-NEXT:    ret i32* [[CALL]]
550;
551entry:
552  %cmp = icmp eq i32* %b, null
553  br i1 %cmp, label %ret_arg, label %ret_unknown
554
555ret_arg:
556  ret i32* %b
557
558ret_unknown:
559  %call = call i32* @unknown()
560  ret i32* %call
561}
562
563define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
564; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
565; CHECK-SAME: (i32* [[B:%.*]])
566; CHECK-NEXT:  entry:
567; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32* [[B]], null
568; CHECK-NEXT:    br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
569; CHECK:       ret_arg:
570; CHECK-NEXT:    br label [[R:%.*]]
571; CHECK:       ret_unknown:
572; CHECK-NEXT:    [[CALL:%.*]] = call i32* @unknown()
573; CHECK-NEXT:    br label [[R]]
574; CHECK:       r:
575; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
576; CHECK-NEXT:    ret i32* [[PHI]]
577;
578entry:
579  %cmp = icmp eq i32* %b, null
580  br i1 %cmp, label %ret_arg, label %ret_unknown
581
582ret_arg:
583  br label %r
584
585ret_unknown:
586  %call = call i32* @unknown()
587  br label %r
588
589r:
590  %phi = phi i32* [ %b, %ret_arg ], [ %call, %ret_unknown ]
591  ret i32* %phi
592}
593
594
595; TEST not captured by readonly external function
596;
597declare i32* @readonly_unknown(i32*, i32*) readonly
598
599define void @not_captured_by_readonly_call(i32* %b) #0 {
600; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call
601; CHECK-SAME: (i32* nocapture readonly [[B:%.*]])
602; CHECK-NEXT:  entry:
603; CHECK-NEXT:    [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[B]])
604; CHECK-NEXT:    ret void
605;
606entry:
607  %call = call i32* @readonly_unknown(i32* %b, i32* %b)
608  ret void
609}
610
611
612; TEST not captured by readonly external function if return chain is known
613;
614; Make sure the returned flag on %r is strong enough to justify nocapture on %b but **not** on %r.
615;
616define i32* @not_captured_by_readonly_call_not_returned_either1(i32* %b, i32* returned %r) {
617; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either1
618; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]])
619; CHECK-NEXT:  entry:
620; CHECK-NEXT:    [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]])
621; CHECK-NEXT:    ret i32* [[CALL]]
622;
623entry:
624  %call = call i32* @readonly_unknown(i32* %b, i32* %r) nounwind
625  ret i32* %call
626}
627
628declare i32* @readonly_unknown_r1a(i32*, i32* returned) readonly
629define i32* @not_captured_by_readonly_call_not_returned_either2(i32* %b, i32* %r) {
630; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either2
631; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]])
632; CHECK-NEXT:  entry:
633; CHECK-NEXT:    [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]])
634; CHECK-NEXT:    ret i32* [[CALL]]
635;
636entry:
637  %call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r) nounwind
638  ret i32* %call
639}
640
641declare i32* @readonly_unknown_r1b(i32*, i32* returned) readonly nounwind
642define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r) {
643; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3
644; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]])
645; CHECK-NEXT:  entry:
646; CHECK-NEXT:    [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]])
647; CHECK-NEXT:    ret i32* [[CALL]]
648;
649entry:
650  %call = call i32* @readonly_unknown_r1b(i32* %b, i32* %r)
651  ret i32* %call
652}
653
654define i32* @not_captured_by_readonly_call_not_returned_either4(i32* %b, i32* %r) nounwind {
655; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either4
656; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]])
657; CHECK-NEXT:  entry:
658; CHECK-NEXT:    [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]])
659; CHECK-NEXT:    ret i32* [[CALL]]
660;
661entry:
662  %call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r)
663  ret i32* %call
664}
665
666
667declare i32* @unknown_i32p(i32*)
668define void @nocapture_is_not_subsumed_1(i32* nocapture %b) {
669; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_1
670; CHECK-SAME: (i32* nocapture [[B:%.*]])
671; CHECK-NEXT:  entry:
672; CHECK-NEXT:    [[CALL:%.*]] = call i32* @unknown_i32p(i32* [[B]])
673; CHECK-NEXT:    store i32 0, i32* [[CALL]], align 4
674; CHECK-NEXT:    ret void
675;
676entry:
677  %call = call i32* @unknown_i32p(i32* %b)
678  store i32 0, i32* %call
679  ret void
680}
681
682declare i32* @readonly_i32p(i32*) readonly
683define void @nocapture_is_not_subsumed_2(i32* nocapture %b) {
684; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2
685; CHECK-SAME: (i32* nocapture [[B:%.*]])
686; CHECK-NEXT:  entry:
687; CHECK-NEXT:    [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B]])
688; CHECK-NEXT:    store i32 0, i32* [[CALL]], align 4
689; CHECK-NEXT:    ret void
690;
691entry:
692  %call = call i32* @readonly_i32p(i32* %b)
693  store i32 0, i32* %call
694  ret void
695}
696
697attributes #0 = { noinline nounwind uwtable }
698