[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Attributor / memory_locations.ll
blob53d2894b53cb0b7f640247788b42d1d2c6a5e4ea
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -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=13 -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 -enable-new-pm=0 -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 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
8 @G = external dso_local global i32, align 4
10 declare noalias i8* @malloc(i64) inaccessiblememonly
13 ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = external dso_local global i32, align 4
15 define dso_local i8* @internal_only(i32 %arg) {
16 ; CHECK: Function Attrs: inaccessiblememonly
17 ; CHECK-LABEL: define {{[^@]+}}@internal_only
18 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
19 ; CHECK-NEXT:  entry:
20 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i64
21 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]])
22 ; CHECK-NEXT:    ret i8* [[CALL]]
24 entry:
25   %conv = sext i32 %arg to i64
26   %call = call i8* @malloc(i64 %conv)
27   ret i8* %call
30 define dso_local i8* @internal_only_rec(i32 %arg) {
31 ; CHECK: Function Attrs: inaccessiblememonly
32 ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec
33 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
34 ; CHECK-NEXT:  entry:
35 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[ARG]], 2
36 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 1
37 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
38 ; CHECK:       if.then:
39 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[ARG]], 2
40 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_only_rec(i32 [[DIV]])
41 ; CHECK-NEXT:    br label [[RETURN:%.*]]
42 ; CHECK:       if.end:
43 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i64
44 ; CHECK-NEXT:    [[CALL1:%.*]] = call noalias i8* @malloc(i64 [[CONV]])
45 ; CHECK-NEXT:    br label [[RETURN]]
46 ; CHECK:       return:
47 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ [[CALL]], [[IF_THEN]] ], [ [[CALL1]], [[IF_END]] ]
48 ; CHECK-NEXT:    ret i8* [[RETVAL_0]]
50 entry:
51   %rem = srem i32 %arg, 2
52   %cmp = icmp eq i32 %rem, 1
53   br i1 %cmp, label %if.then, label %if.end
55 if.then:                                          ; preds = %entry
56   %div = sdiv i32 %arg, 2
57   %call = call i8* @internal_only_rec(i32 %div)
58   br label %return
60 if.end:                                           ; preds = %entry
61   %conv = sext i32 %arg to i64
62   %call1 = call i8* @malloc(i64 %conv)
63   br label %return
65 return:                                           ; preds = %if.end, %if.then
66   %retval.0 = phi i8* [ %call, %if.then ], [ %call1, %if.end ]
67   ret i8* %retval.0
70 define dso_local i8* @internal_only_rec_static_helper(i32 %arg) {
71 ; CHECK: Function Attrs: inaccessiblememonly
72 ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_helper
73 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
74 ; CHECK-NEXT:  entry:
75 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_only_rec_static(i32 [[ARG]])
76 ; CHECK-NEXT:    ret i8* [[CALL]]
78 entry:
79   %call = call i8* @internal_only_rec_static(i32 %arg)
80   ret i8* %call
83 define internal i8* @internal_only_rec_static(i32 %arg) {
84 ; CHECK: Function Attrs: inaccessiblememonly
85 ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static
86 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
87 ; CHECK-NEXT:  entry:
88 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[ARG]], 2
89 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 1
90 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
91 ; CHECK:       if.then:
92 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[ARG]], 2
93 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_only_rec(i32 [[DIV]])
94 ; CHECK-NEXT:    br label [[RETURN:%.*]]
95 ; CHECK:       if.end:
96 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i64
97 ; CHECK-NEXT:    [[CALL1:%.*]] = call noalias i8* @malloc(i64 [[CONV]])
98 ; CHECK-NEXT:    br label [[RETURN]]
99 ; CHECK:       return:
100 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ [[CALL]], [[IF_THEN]] ], [ [[CALL1]], [[IF_END]] ]
101 ; CHECK-NEXT:    ret i8* [[RETVAL_0]]
103 entry:
104   %rem = srem i32 %arg, 2
105   %cmp = icmp eq i32 %rem, 1
106   br i1 %cmp, label %if.then, label %if.end
108 if.then:                                          ; preds = %entry
109   %div = sdiv i32 %arg, 2
110   %call = call i8* @internal_only_rec(i32 %div)
111   br label %return
113 if.end:                                           ; preds = %entry
114   %conv = sext i32 %arg to i64
115   %call1 = call i8* @malloc(i64 %conv)
116   br label %return
118 return:                                           ; preds = %if.end, %if.then
119   %retval.0 = phi i8* [ %call, %if.then ], [ %call1, %if.end ]
120   ret i8* %retval.0
123 define dso_local i8* @internal_only_rec_static_helper_malloc_noescape(i32 %arg) {
124 ; FIXME: This is actually inaccessiblememonly because the malloced memory does not escape
125 ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_helper_malloc_noescape
126 ; CHECK-SAME: (i32 [[ARG:%.*]]) {
127 ; CHECK-NEXT:  entry:
128 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_only_rec_static_malloc_noescape(i32 [[ARG]])
129 ; CHECK-NEXT:    ret i8* [[CALL]]
131 entry:
132   %call = call i8* @internal_only_rec_static_malloc_noescape(i32 %arg)
133   ret i8* %call
136 define internal i8* @internal_only_rec_static_malloc_noescape(i32 %arg) {
137 ; FIXME: This is actually inaccessiblememonly because the malloced memory does not escape
138 ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_malloc_noescape
139 ; CHECK-SAME: (i32 [[ARG:%.*]]) {
140 ; CHECK-NEXT:  entry:
141 ; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[ARG]], 2
142 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 1
143 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
144 ; CHECK:       if.then:
145 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[ARG]], 2
146 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_only_rec(i32 [[DIV]])
147 ; CHECK-NEXT:    br label [[RETURN:%.*]]
148 ; CHECK:       if.end:
149 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i64
150 ; CHECK-NEXT:    [[CALL1:%.*]] = call noalias i8* @malloc(i64 [[CONV]])
151 ; CHECK-NEXT:    store i8 0, i8* [[CALL1]], align 1
152 ; CHECK-NEXT:    br label [[RETURN]]
153 ; CHECK:       return:
154 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ [[CALL]], [[IF_THEN]] ], [ null, [[IF_END]] ]
155 ; CHECK-NEXT:    ret i8* [[RETVAL_0]]
157 entry:
158   %rem = srem i32 %arg, 2
159   %cmp = icmp eq i32 %rem, 1
160   br i1 %cmp, label %if.then, label %if.end
162 if.then:                                          ; preds = %entry
163   %div = sdiv i32 %arg, 2
164   %call = call i8* @internal_only_rec(i32 %div)
165   br label %return
167 if.end:                                           ; preds = %entry
168   %conv = sext i32 %arg to i64
169   %call1 = call i8* @malloc(i64 %conv)
170   store i8 0, i8* %call1
171   br label %return
173 return:                                           ; preds = %if.end, %if.then
174   %retval.0 = phi i8* [ %call, %if.then ], [ null, %if.end ]
175   ret i8* %retval.0
178 define dso_local i8* @internal_argmem_only_read(i32* %arg) {
179 ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
180 ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_read
181 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1:[0-9]+]] {
182 ; CHECK-NEXT:  entry:
183 ; CHECK-NEXT:    [[TMP:%.*]] = load i32, i32* [[ARG]], align 4
184 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP]] to i64
185 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]])
186 ; CHECK-NEXT:    ret i8* [[CALL]]
188 entry:
189   %tmp = load i32, i32* %arg, align 4
190   %conv = sext i32 %tmp to i64
191   %call = call i8* @malloc(i64 %conv)
192   ret i8* %call
195 define dso_local i8* @internal_argmem_only_write(i32* %arg) {
196 ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
197 ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_write
198 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {
199 ; CHECK-NEXT:  entry:
200 ; CHECK-NEXT:    store i32 10, i32* [[ARG]], align 4
201 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias dereferenceable_or_null(10) i8* @malloc(i64 noundef 10)
202 ; CHECK-NEXT:    ret i8* [[CALL]]
204 entry:
205   store i32 10, i32* %arg, align 4
206   %call = call dereferenceable_or_null(10) i8* @malloc(i64 10)
207   ret i8* %call
210 define dso_local i8* @internal_argmem_only_rec(i32* %arg) {
211 ; IS__TUNIT____: Function Attrs: inaccessiblemem_or_argmemonly
212 ; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_argmem_only_rec
213 ; IS__TUNIT____-SAME: (i32* nocapture nofree [[ARG:%.*]]) #[[ATTR1]] {
214 ; IS__TUNIT____-NEXT:  entry:
215 ; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_argmem_only_rec_1(i32* nocapture nofree align 4 [[ARG]])
216 ; IS__TUNIT____-NEXT:    ret i8* [[CALL]]
218 ; IS__CGSCC____: Function Attrs: inaccessiblemem_or_argmemonly
219 ; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_argmem_only_rec
220 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {
221 ; IS__CGSCC____-NEXT:  entry:
222 ; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_argmem_only_rec_1(i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ARG]])
223 ; IS__CGSCC____-NEXT:    ret i8* [[CALL]]
225 entry:
226   %call = call i8* @internal_argmem_only_rec_1(i32* %arg)
227   ret i8* %call
230 define internal i8* @internal_argmem_only_rec_1(i32* %arg) {
231 ; IS__TUNIT____: Function Attrs: inaccessiblemem_or_argmemonly
232 ; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_argmem_only_rec_1
233 ; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {
234 ; IS__TUNIT____-NEXT:  entry:
235 ; IS__TUNIT____-NEXT:    [[TMP:%.*]] = load i32, i32* [[ARG]], align 4
236 ; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP]], 0
237 ; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
238 ; IS__TUNIT____:       if.then:
239 ; IS__TUNIT____-NEXT:    br label [[RETURN:%.*]]
240 ; IS__TUNIT____:       if.end:
241 ; IS__TUNIT____-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARG]], align 4
242 ; IS__TUNIT____-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP1]], 1
243 ; IS__TUNIT____-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
244 ; IS__TUNIT____:       if.then2:
245 ; IS__TUNIT____-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 -1
246 ; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_argmem_only_rec_2(i32* nocapture nofree nonnull align 4 dereferenceable(4) [[ADD_PTR]])
247 ; IS__TUNIT____-NEXT:    br label [[RETURN]]
248 ; IS__TUNIT____:       if.end3:
249 ; IS__TUNIT____-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4
250 ; IS__TUNIT____-NEXT:    [[CONV:%.*]] = sext i32 [[TMP2]] to i64
251 ; IS__TUNIT____-NEXT:    [[CALL4:%.*]] = call noalias i8* @malloc(i64 [[CONV]])
252 ; IS__TUNIT____-NEXT:    br label [[RETURN]]
253 ; IS__TUNIT____:       return:
254 ; IS__TUNIT____-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ null, [[IF_THEN]] ], [ [[CALL]], [[IF_THEN2]] ], [ [[CALL4]], [[IF_END3]] ]
255 ; IS__TUNIT____-NEXT:    ret i8* [[RETVAL_0]]
257 ; IS__CGSCC____: Function Attrs: inaccessiblemem_or_argmemonly
258 ; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_argmem_only_rec_1
259 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {
260 ; IS__CGSCC____-NEXT:  entry:
261 ; IS__CGSCC____-NEXT:    [[TMP:%.*]] = load i32, i32* [[ARG]], align 4
262 ; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP]], 0
263 ; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
264 ; IS__CGSCC____:       if.then:
265 ; IS__CGSCC____-NEXT:    br label [[RETURN:%.*]]
266 ; IS__CGSCC____:       if.end:
267 ; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = load i32, i32* [[ARG]], align 4
268 ; IS__CGSCC____-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP1]], 1
269 ; IS__CGSCC____-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
270 ; IS__CGSCC____:       if.then2:
271 ; IS__CGSCC____-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 -1
272 ; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_argmem_only_rec_2(i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ADD_PTR]])
273 ; IS__CGSCC____-NEXT:    br label [[RETURN]]
274 ; IS__CGSCC____:       if.end3:
275 ; IS__CGSCC____-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4
276 ; IS__CGSCC____-NEXT:    [[CONV:%.*]] = sext i32 [[TMP2]] to i64
277 ; IS__CGSCC____-NEXT:    [[CALL4:%.*]] = call noalias i8* @malloc(i64 [[CONV]])
278 ; IS__CGSCC____-NEXT:    br label [[RETURN]]
279 ; IS__CGSCC____:       return:
280 ; IS__CGSCC____-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ null, [[IF_THEN]] ], [ [[CALL]], [[IF_THEN2]] ], [ [[CALL4]], [[IF_END3]] ]
281 ; IS__CGSCC____-NEXT:    ret i8* [[RETVAL_0]]
283 entry:
284   %tmp = load i32, i32* %arg, align 4
285   %cmp = icmp eq i32 %tmp, 0
286   br i1 %cmp, label %if.then, label %if.end
288 if.then:                                          ; preds = %entry
289   br label %return
291 if.end:                                           ; preds = %entry
292   %tmp1 = load i32, i32* %arg, align 4
293   %cmp1 = icmp eq i32 %tmp1, 1
294   br i1 %cmp1, label %if.then2, label %if.end3
296 if.then2:                                         ; preds = %if.end
297   %add.ptr = getelementptr inbounds i32, i32* %arg, i64 -1
298   %call = call i8* @internal_argmem_only_rec_2(i32* nonnull %add.ptr)
299   br label %return
301 if.end3:                                          ; preds = %if.end
302   %tmp2 = load i32, i32* %arg, align 4
303   %conv = sext i32 %tmp2 to i64
304   %call4 = call i8* @malloc(i64 %conv)
305   br label %return
307 return:                                           ; preds = %if.end3, %if.then2, %if.then
308   %retval.0 = phi i8* [ null, %if.then ], [ %call, %if.then2 ], [ %call4, %if.end3 ]
309   ret i8* %retval.0
312 define internal i8* @internal_argmem_only_rec_2(i32* %arg) {
313 ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
314 ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_2
315 ; CHECK-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {
316 ; CHECK-NEXT:  entry:
317 ; CHECK-NEXT:    store i32 0, i32* [[ARG]], align 4
318 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 -1
319 ; CHECK-NEXT:    [[CALL:%.*]] = call noalias i8* @internal_argmem_only_rec_1(i32* nocapture nofree nonnull align 4 dereferenceable(4) [[ADD_PTR]])
320 ; CHECK-NEXT:    ret i8* [[CALL]]
322 entry:
323   store i32 0, i32* %arg, align 4
324   %add.ptr = getelementptr inbounds i32, i32* %arg, i64 -1
325   %call = call i8* @internal_argmem_only_rec_1(i32* nonnull %add.ptr)
326   ret i8* %call
329 declare i8* @unknown_ptr() readnone
330 declare i8* @argmem_only(i8* %arg) argmemonly
331 declare i8* @inaccesible_argmem_only_decl(i8* %arg) inaccessiblemem_or_argmemonly
332 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) nounwind argmemonly willreturn
334 define void @callerA1(i8* %arg) {
335 ; CHECK: Function Attrs: argmemonly
336 ; CHECK-LABEL: define {{[^@]+}}@callerA1
337 ; CHECK-SAME: (i8* [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {
338 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @argmem_only(i8* [[ARG]])
339 ; CHECK-NEXT:    ret void
341   call i8* @argmem_only(i8* %arg)
342   ret void
344 define void @callerA2(i8* %arg) {
345 ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
346 ; CHECK-LABEL: define {{[^@]+}}@callerA2
347 ; CHECK-SAME: (i8* [[ARG:%.*]]) #[[ATTR1]] {
348 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @inaccesible_argmem_only_decl(i8* [[ARG]])
349 ; CHECK-NEXT:    ret void
351   call i8* @inaccesible_argmem_only_decl(i8* %arg)
352   ret void
354 define void @callerB1() {
355 ; CHECK: Function Attrs: readnone
356 ; CHECK-LABEL: define {{[^@]+}}@callerB1
357 ; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
358 ; CHECK-NEXT:    [[STACK:%.*]] = alloca i8, align 1
359 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @argmem_only(i8* noundef nonnull dereferenceable(1) [[STACK]])
360 ; CHECK-NEXT:    ret void
362   %stack = alloca i8
363   call i8* @argmem_only(i8* %stack)
364   ret void
366 define void @callerB2() {
367 ; CHECK: Function Attrs: inaccessiblememonly
368 ; CHECK-LABEL: define {{[^@]+}}@callerB2
369 ; CHECK-SAME: () #[[ATTR0]] {
370 ; CHECK-NEXT:    [[STACK:%.*]] = alloca i8, align 1
371 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @inaccesible_argmem_only_decl(i8* noundef nonnull dereferenceable(1) [[STACK]])
372 ; CHECK-NEXT:    ret void
374   %stack = alloca i8
375   call i8* @inaccesible_argmem_only_decl(i8* %stack)
376   ret void
378 define void @callerC1() {
379 ; CHECK-LABEL: define {{[^@]+}}@callerC1() {
380 ; CHECK-NEXT:    [[UNKNOWN:%.*]] = call i8* @unknown_ptr()
381 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @argmem_only(i8* [[UNKNOWN]])
382 ; CHECK-NEXT:    ret void
384   %unknown = call i8* @unknown_ptr()
385   call i8* @argmem_only(i8* %unknown)
386   ret void
388 define void @callerC2() {
389 ; CHECK-LABEL: define {{[^@]+}}@callerC2() {
390 ; CHECK-NEXT:    [[UNKNOWN:%.*]] = call i8* @unknown_ptr()
391 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @inaccesible_argmem_only_decl(i8* [[UNKNOWN]])
392 ; CHECK-NEXT:    ret void
394   %unknown = call i8* @unknown_ptr()
395   call i8* @inaccesible_argmem_only_decl(i8* %unknown)
396   ret void
398 define void @callerD1() {
399 ; CHECK-LABEL: define {{[^@]+}}@callerD1() {
400 ; CHECK-NEXT:    [[UNKNOWN:%.*]] = call i8* @argmem_only(i8* noalias nocapture noundef align 536870912 null)
401 ; CHECK-NEXT:    store i8 0, i8* [[UNKNOWN]], align 1
402 ; CHECK-NEXT:    ret void
404   %unknown = call i8* @argmem_only(i8* null)
405   store i8 0, i8* %unknown
406   ret void
408 define void @callerD2() {
409 ; CHECK-LABEL: define {{[^@]+}}@callerD2() {
410 ; CHECK-NEXT:    [[UNKNOWN:%.*]] = call i8* @inaccesible_argmem_only_decl(i8* noalias nocapture noundef align 536870912 null)
411 ; CHECK-NEXT:    store i8 0, i8* [[UNKNOWN]], align 1
412 ; CHECK-NEXT:    ret void
414   %unknown = call i8* @inaccesible_argmem_only_decl(i8* null)
415   store i8 0, i8* %unknown
416   ret void
419 define void @callerE(i8* %arg) {
420 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
421 ; IS__TUNIT____-LABEL: define {{[^@]+}}@callerE
422 ; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
423 ; IS__TUNIT____-NEXT:    ret void
425 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
426 ; IS__CGSCC____-LABEL: define {{[^@]+}}@callerE
427 ; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
428 ; IS__CGSCC____-NEXT:    ret void
430   call void @llvm.lifetime.start.p0i8(i64 4, i8* %arg)
431   ret void
435 define void @write_global() {
436 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
437 ; IS__TUNIT____-LABEL: define {{[^@]+}}@write_global
438 ; IS__TUNIT____-SAME: () #[[ATTR6:[0-9]+]] {
439 ; IS__TUNIT____-NEXT:    store i32 0, i32* @G, align 4
440 ; IS__TUNIT____-NEXT:    ret void
442 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
443 ; IS__CGSCC____-LABEL: define {{[^@]+}}@write_global
444 ; IS__CGSCC____-SAME: () #[[ATTR6:[0-9]+]] {
445 ; IS__CGSCC____-NEXT:    store i32 0, i32* @G, align 4
446 ; IS__CGSCC____-NEXT:    ret void
448   store i32 0, i32* @G, align 4
449   ret void
451 define void @write_global_via_arg(i32* %GPtr) {
452 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
453 ; IS__TUNIT____-LABEL: define {{[^@]+}}@write_global_via_arg
454 ; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[GPTR:%.*]]) #[[ATTR7:[0-9]+]] {
455 ; IS__TUNIT____-NEXT:    store i32 0, i32* [[GPTR]], align 4
456 ; IS__TUNIT____-NEXT:    ret void
458 ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
459 ; IS__CGSCC____-LABEL: define {{[^@]+}}@write_global_via_arg
460 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[GPTR:%.*]]) #[[ATTR7:[0-9]+]] {
461 ; IS__CGSCC____-NEXT:    store i32 0, i32* [[GPTR]], align 4
462 ; IS__CGSCC____-NEXT:    ret void
464   store i32 0, i32* %GPtr, align 4
465   ret void
467 define internal void @write_global_via_arg_internal(i32* %GPtr) {
468 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
469 ; IS__TUNIT____-LABEL: define {{[^@]+}}@write_global_via_arg_internal
470 ; IS__TUNIT____-SAME: () #[[ATTR6]] {
471 ; IS__TUNIT____-NEXT:    store i32 0, i32* @G, align 4
472 ; IS__TUNIT____-NEXT:    ret void
474 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
475 ; IS__CGSCC____-LABEL: define {{[^@]+}}@write_global_via_arg_internal
476 ; IS__CGSCC____-SAME: () #[[ATTR6]] {
477 ; IS__CGSCC____-NEXT:    store i32 0, i32* @G, align 4
478 ; IS__CGSCC____-NEXT:    ret void
480   store i32 0, i32* %GPtr, align 4
481   ret void
484 define void @writeonly_global() {
485 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
486 ; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global
487 ; IS__TUNIT____-SAME: () #[[ATTR6]] {
488 ; IS__TUNIT____-NEXT:    call void @write_global() #[[ATTR6]]
489 ; IS__TUNIT____-NEXT:    ret void
491 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
492 ; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global
493 ; IS__CGSCC____-SAME: () #[[ATTR6]] {
494 ; IS__CGSCC____-NEXT:    call void @write_global() #[[ATTR10:[0-9]+]]
495 ; IS__CGSCC____-NEXT:    ret void
497   call void @write_global()
498   ret void
500 define void @writeonly_global_via_arg() {
501 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
502 ; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global_via_arg
503 ; IS__TUNIT____-SAME: () #[[ATTR6]] {
504 ; IS__TUNIT____-NEXT:    call void @write_global_via_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) @G) #[[ATTR6]]
505 ; IS__TUNIT____-NEXT:    ret void
507 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
508 ; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global_via_arg
509 ; IS__CGSCC____-SAME: () #[[ATTR6]] {
510 ; IS__CGSCC____-NEXT:    call void @write_global_via_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) @G) #[[ATTR10]]
511 ; IS__CGSCC____-NEXT:    ret void
513   call void @write_global_via_arg(i32* @G)
514   ret void
517 define void @writeonly_global_via_arg_internal() {
519 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
520 ; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal
521 ; IS__TUNIT____-SAME: () #[[ATTR6]] {
522 ; IS__TUNIT____-NEXT:    call void @write_global_via_arg_internal() #[[ATTR6]]
523 ; IS__TUNIT____-NEXT:    ret void
525 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
526 ; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal
527 ; IS__CGSCC____-SAME: () #[[ATTR6]] {
528 ; IS__CGSCC____-NEXT:    call void @write_global_via_arg_internal() #[[ATTR10]]
529 ; IS__CGSCC____-NEXT:    ret void
531   call void @write_global_via_arg_internal(i32* @G)
532   ret void
535 define i8 @recursive_not_readnone(i8* %ptr, i1 %c) {
536 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind writeonly
537 ; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone
538 ; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8:[0-9]+]] {
539 ; IS__TUNIT____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
540 ; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
541 ; IS__TUNIT____:       t:
542 ; IS__TUNIT____-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR10:[0-9]+]], !range [[RNG0:![0-9]+]]
543 ; IS__TUNIT____-NEXT:    ret i8 1
544 ; IS__TUNIT____:       f:
545 ; IS__TUNIT____-NEXT:    store i8 1, i8* [[PTR]], align 1
546 ; IS__TUNIT____-NEXT:    ret i8 0
548 ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind writeonly
549 ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone
550 ; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8:[0-9]+]] {
551 ; IS__CGSCC____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
552 ; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
553 ; IS__CGSCC____:       t:
554 ; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11:[0-9]+]], !range [[RNG0:![0-9]+]]
555 ; IS__CGSCC____-NEXT:    ret i8 1
556 ; IS__CGSCC____:       f:
557 ; IS__CGSCC____-NEXT:    store i8 1, i8* [[PTR]], align 1
558 ; IS__CGSCC____-NEXT:    ret i8 0
560   %alloc = alloca i8
561   br i1 %c, label %t, label %f
563   call i8 @recursive_not_readnone(i8* %alloc, i1 false)
564   %r = load i8, i8* %alloc
565   ret i8 %r
567   store i8 1, i8* %ptr
568   ret i8 0
571 define internal i8 @recursive_not_readnone_internal(i8* %ptr, i1 %c) {
572 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind writeonly
573 ; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal
574 ; IS__TUNIT____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
575 ; IS__TUNIT____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
576 ; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
577 ; IS__TUNIT____:       t:
578 ; IS__TUNIT____-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR10]], !range [[RNG0]]
579 ; IS__TUNIT____-NEXT:    ret i8 1
580 ; IS__TUNIT____:       f:
581 ; IS__TUNIT____-NEXT:    store i8 1, i8* [[PTR]], align 1
582 ; IS__TUNIT____-NEXT:    ret i8 0
584 ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind writeonly
585 ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal
586 ; IS__CGSCC____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
587 ; IS__CGSCC____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
588 ; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
589 ; IS__CGSCC____:       t:
590 ; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]], !range [[RNG0]]
591 ; IS__CGSCC____-NEXT:    ret i8 1
592 ; IS__CGSCC____:       f:
593 ; IS__CGSCC____-NEXT:    store i8 1, i8* [[PTR]], align 1
594 ; IS__CGSCC____-NEXT:    ret i8 0
596   %alloc = alloca i8
597   br i1 %c, label %t, label %f
599   call i8 @recursive_not_readnone_internal(i8* %alloc, i1 false)
600   %r = load i8, i8* %alloc
601   ret i8 %r
603   store i8 1, i8* %ptr
604   ret i8 0
607 define i8 @readnone_caller(i1 %c) {
608 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
609 ; IS__TUNIT____-LABEL: define {{[^@]+}}@readnone_caller
610 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] {
611 ; IS__TUNIT____-NEXT:    [[A:%.*]] = alloca i8, align 1
612 ; IS__TUNIT____-NEXT:    [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[A]], i1 [[C]]) #[[ATTR10]], !range [[RNG0]]
613 ; IS__TUNIT____-NEXT:    ret i8 [[R]]
615 ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone
616 ; IS__CGSCC____-LABEL: define {{[^@]+}}@readnone_caller
617 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] {
618 ; IS__CGSCC____-NEXT:    [[A:%.*]] = alloca i8, align 1
619 ; IS__CGSCC____-NEXT:    [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[A]], i1 [[C]]) #[[ATTR12:[0-9]+]], !range [[RNG0]]
620 ; IS__CGSCC____-NEXT:    ret i8 [[R]]
622   %a = alloca i8
623   %r = call i8 @recursive_not_readnone_internal(i8* %a, i1 %c)
624   ret i8 %r
627 define internal i8 @recursive_readnone_internal2(i8* %ptr, i1 %c) {
628 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind writeonly
629 ; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_readnone_internal2
630 ; IS__TUNIT____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
631 ; IS__TUNIT____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
632 ; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
633 ; IS__TUNIT____:       t:
634 ; IS__TUNIT____-NEXT:    [[TMP1:%.*]] = call i8 @recursive_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR10]], !range [[RNG0]]
635 ; IS__TUNIT____-NEXT:    ret i8 1
636 ; IS__TUNIT____:       f:
637 ; IS__TUNIT____-NEXT:    store i8 1, i8* [[PTR]], align 1
638 ; IS__TUNIT____-NEXT:    ret i8 0
640 ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind writeonly
641 ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_readnone_internal2
642 ; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
643 ; IS__CGSCC____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
644 ; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
645 ; IS__CGSCC____:       t:
646 ; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = call i8 @recursive_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]], !range [[RNG0]]
647 ; IS__CGSCC____-NEXT:    ret i8 1
648 ; IS__CGSCC____:       f:
649 ; IS__CGSCC____-NEXT:    store i8 1, i8* [[PTR]], align 1
650 ; IS__CGSCC____-NEXT:    ret i8 0
652   %alloc = alloca i8
653   br i1 %c, label %t, label %f
655   call i8 @recursive_readnone_internal2(i8* %alloc, i1 false)
656   %r = load i8, i8* %alloc
657   ret i8 %r
659   store i8 1, i8* %ptr
660   ret i8 0
663 define i8 @readnone_caller2(i1 %c) {
664 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
665 ; IS__TUNIT____-LABEL: define {{[^@]+}}@readnone_caller2
666 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR9]] {
667 ; IS__TUNIT____-NEXT:    [[R:%.*]] = call noundef i8 @recursive_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR10]], !range [[RNG0]]
668 ; IS__TUNIT____-NEXT:    ret i8 [[R]]
670 ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone
671 ; IS__CGSCC____-LABEL: define {{[^@]+}}@readnone_caller2
672 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR9]] {
673 ; IS__CGSCC____-NEXT:    [[R:%.*]] = call noundef i8 @recursive_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR12]], !range [[RNG0]]
674 ; IS__CGSCC____-NEXT:    ret i8 [[R]]
676   %r = call i8 @recursive_readnone_internal2(i8* undef, i1 %c)
677   ret i8 %r
680 define internal i8 @recursive_not_readnone_internal3(i8* %ptr, i1 %c) {
681 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind writeonly
682 ; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3
683 ; IS__TUNIT____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
684 ; IS__TUNIT____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
685 ; IS__TUNIT____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
686 ; IS__TUNIT____:       t:
687 ; IS__TUNIT____-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR10]], !range [[RNG0]]
688 ; IS__TUNIT____-NEXT:    ret i8 1
689 ; IS__TUNIT____:       f:
690 ; IS__TUNIT____-NEXT:    store i8 1, i8* [[PTR]], align 1
691 ; IS__TUNIT____-NEXT:    ret i8 0
693 ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind writeonly
694 ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3
695 ; IS__CGSCC____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
696 ; IS__CGSCC____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
697 ; IS__CGSCC____-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
698 ; IS__CGSCC____:       t:
699 ; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]], !range [[RNG0]]
700 ; IS__CGSCC____-NEXT:    ret i8 1
701 ; IS__CGSCC____:       f:
702 ; IS__CGSCC____-NEXT:    store i8 1, i8* [[PTR]], align 1
703 ; IS__CGSCC____-NEXT:    ret i8 0
705   %alloc = alloca i8
706   br i1 %c, label %t, label %f
708   call i8 @recursive_not_readnone_internal3(i8* %alloc, i1 false)
709   %r = load i8, i8* %alloc
710   ret i8 %r
712   store i8 1, i8* %ptr
713   ret i8 0
716 define i8 @readnone_caller3(i1 %c) {
717 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
718 ; IS__TUNIT____-LABEL: define {{[^@]+}}@readnone_caller3
719 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR9]] {
720 ; IS__TUNIT____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
721 ; IS__TUNIT____-NEXT:    [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 [[C]]) #[[ATTR10]], !range [[RNG0]]
722 ; IS__TUNIT____-NEXT:    ret i8 [[R]]
724 ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone
725 ; IS__CGSCC____-LABEL: define {{[^@]+}}@readnone_caller3
726 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR9]] {
727 ; IS__CGSCC____-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1
728 ; IS__CGSCC____-NEXT:    [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 [[C]]) #[[ATTR12]], !range [[RNG0]]
729 ; IS__CGSCC____-NEXT:    ret i8 [[R]]
731   %alloc = alloca i8
732   %r = call i8 @recursive_not_readnone_internal3(i8* %alloc, i1 %c)
733   ret i8 %r
736 define internal void @argmemonly_before_ipconstprop(i32* %p) argmemonly {
737 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
738 ; IS__TUNIT____-LABEL: define {{[^@]+}}@argmemonly_before_ipconstprop
739 ; IS__TUNIT____-SAME: () #[[ATTR6]] {
740 ; IS__TUNIT____-NEXT:    store i32 0, i32* @G, align 4
741 ; IS__TUNIT____-NEXT:    ret void
743 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
744 ; IS__CGSCC____-LABEL: define {{[^@]+}}@argmemonly_before_ipconstprop
745 ; IS__CGSCC____-SAME: () #[[ATTR6]] {
746 ; IS__CGSCC____-NEXT:    store i32 0, i32* @G, align 4
747 ; IS__CGSCC____-NEXT:    ret void
749   store i32 0, i32* %p
750   ret void
753 define void @argmemonky_caller() {
754 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
755 ; IS__TUNIT____-LABEL: define {{[^@]+}}@argmemonky_caller
756 ; IS__TUNIT____-SAME: () #[[ATTR6]] {
757 ; IS__TUNIT____-NEXT:    call void @argmemonly_before_ipconstprop() #[[ATTR6]]
758 ; IS__TUNIT____-NEXT:    ret void
760 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
761 ; IS__CGSCC____-LABEL: define {{[^@]+}}@argmemonky_caller
762 ; IS__CGSCC____-SAME: () #[[ATTR6]] {
763 ; IS__CGSCC____-NEXT:    call void @argmemonly_before_ipconstprop() #[[ATTR10]]
764 ; IS__CGSCC____-NEXT:    ret void
766   call void @argmemonly_before_ipconstprop(i32* @G)
767   ret void
770 ; IS__TUNIT____: attributes #[[ATTR0]] = { inaccessiblememonly }
771 ; IS__TUNIT____: attributes #[[ATTR1]] = { inaccessiblemem_or_argmemonly }
772 ; IS__TUNIT____: attributes #[[ATTR2]] = { readnone }
773 ; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly }
774 ; IS__TUNIT____: attributes #[[ATTR4:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
775 ; IS__TUNIT____: attributes #[[ATTR5]] = { nofree nosync nounwind readnone willreturn }
776 ; IS__TUNIT____: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn writeonly }
777 ; IS__TUNIT____: attributes #[[ATTR7]] = { argmemonly nofree nosync nounwind willreturn writeonly }
778 ; IS__TUNIT____: attributes #[[ATTR8]] = { argmemonly nofree nosync nounwind writeonly }
779 ; IS__TUNIT____: attributes #[[ATTR9]] = { nofree nosync nounwind readnone }
780 ; IS__TUNIT____: attributes #[[ATTR10]] = { nofree nosync nounwind writeonly }
782 ; IS__CGSCC____: attributes #[[ATTR0]] = { inaccessiblememonly }
783 ; IS__CGSCC____: attributes #[[ATTR1]] = { inaccessiblemem_or_argmemonly }
784 ; IS__CGSCC____: attributes #[[ATTR2]] = { readnone }
785 ; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly }
786 ; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
787 ; IS__CGSCC____: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind readnone willreturn }
788 ; IS__CGSCC____: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn writeonly }
789 ; IS__CGSCC____: attributes #[[ATTR7]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
790 ; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree nosync nounwind writeonly }
791 ; IS__CGSCC____: attributes #[[ATTR9]] = { nofree nosync nounwind readnone }
792 ; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind willreturn writeonly }
793 ; IS__CGSCC____: attributes #[[ATTR11]] = { nofree nosync nounwind writeonly }
794 ; IS__CGSCC____: attributes #[[ATTR12]] = { nounwind writeonly }
796 ; CHECK: [[META0:![0-9]+]] = !{i8 0, i8 2}