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=16 -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=16 -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 ; FIXME: Figure out why we need 16 iterations here.
8 declare void @deref_phi_user(i32* %a);
11 ; take mininimum of return values
13 define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
14 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
15 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test1
16 ; IS__TUNIT____-SAME: (i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
17 ; IS__TUNIT____-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
18 ; IS__TUNIT____-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
19 ; IS__TUNIT____-NEXT: ret i32* [[TMP5]]
21 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
22 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
23 ; IS__CGSCC____-SAME: (i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
24 ; IS__CGSCC____-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
25 ; IS__CGSCC____-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
26 ; IS__CGSCC____-NEXT: ret i32* [[TMP5]]
28 %4 = bitcast double* %1 to i32*
29 %5 = select i1 %2, i32* %0, i32* %4
34 define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
35 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
36 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
37 ; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0]] {
38 ; IS__TUNIT____-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
39 ; IS__TUNIT____-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
40 ; IS__TUNIT____-NEXT: ret i32* [[TMP5]]
42 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
43 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
44 ; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0]] {
45 ; IS__CGSCC____-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
46 ; IS__CGSCC____-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
47 ; IS__CGSCC____-NEXT: ret i32* [[TMP5]]
49 %4 = bitcast double* %1 to i32*
50 %5 = select i1 %2, i32* %0, i32* %4
56 define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr {
57 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
58 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_1
59 ; IS__TUNIT____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
60 ; IS__TUNIT____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
61 ; IS__TUNIT____-NEXT: ret i32* [[RET]]
63 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
64 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_1
65 ; IS__CGSCC____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
66 ; IS__CGSCC____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
67 ; IS__CGSCC____-NEXT: ret i32* [[RET]]
69 %ret = getelementptr inbounds i32, i32* %0, i64 1
73 define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr {
74 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
75 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_2
76 ; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
77 ; IS__TUNIT____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4
78 ; IS__TUNIT____-NEXT: ret i32* [[RET]]
80 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
81 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_2
82 ; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
83 ; IS__CGSCC____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4
84 ; IS__CGSCC____-NEXT: ret i32* [[RET]]
86 %ret = getelementptr inbounds i32, i32* %0, i64 4
90 define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr {
91 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
92 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_3
93 ; IS__TUNIT____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0]] {
94 ; IS__TUNIT____-NEXT: [[RET1:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
95 ; IS__TUNIT____-NEXT: [[RET2:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 2
96 ; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[RET1]], i32* [[RET2]]
97 ; IS__TUNIT____-NEXT: ret i32* [[RET]]
99 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
100 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_3
101 ; IS__CGSCC____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) local_unnamed_addr #[[ATTR0]] {
102 ; IS__CGSCC____-NEXT: [[RET1:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
103 ; IS__CGSCC____-NEXT: [[RET2:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 2
104 ; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[RET1]], i32* [[RET2]]
105 ; IS__CGSCC____-NEXT: ret i32* [[RET]]
107 %ret1 = getelementptr inbounds i32, i32* %0, i64 1
108 %ret2 = getelementptr inbounds i32, i32* %1, i64 2
109 %ret = select i1 %2, i32* %ret1, i32* %ret2
114 ; Better than known in IR.
116 define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_addr {
117 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
118 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test4
119 ; IS__TUNIT____-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
120 ; IS__TUNIT____-NEXT: ret i32* [[TMP0]]
122 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
123 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test4
124 ; IS__CGSCC____-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
125 ; IS__CGSCC____-NEXT: ret i32* [[TMP0]]
131 ; loop in which dereferenceabily "grows"
132 define void @deref_phi_growing(i32* dereferenceable(4000) %a) {
133 ; CHECK-LABEL: define {{[^@]+}}@deref_phi_growing
134 ; CHECK-SAME: (i32* nonnull dereferenceable(4000) [[A:%.*]]) {
136 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
138 ; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
139 ; CHECK-NEXT: [[A_ADDR_0:%.*]] = phi i32* [ [[A]], [[ENTRY]] ], [ [[INCDEC_PTR:%.*]], [[FOR_INC]] ]
140 ; CHECK-NEXT: call void @deref_phi_user(i32* nonnull dereferenceable(4000) [[A_ADDR_0]])
141 ; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[A_ADDR_0]], align 4
142 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[TMP]]
143 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
144 ; CHECK: for.cond.cleanup:
145 ; CHECK-NEXT: br label [[FOR_END:%.*]]
147 ; CHECK-NEXT: br label [[FOR_INC]]
149 ; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i32, i32* [[A_ADDR_0]], i64 -1
150 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1
151 ; CHECK-NEXT: br label [[FOR_COND]]
153 ; CHECK-NEXT: ret void
158 for.cond: ; preds = %for.inc, %entry
159 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
160 %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ]
161 call void @deref_phi_user(i32* %a.addr.0)
162 %tmp = load i32, i32* %a.addr.0, align 4
163 %cmp = icmp slt i32 %i.0, %tmp
164 br i1 %cmp, label %for.body, label %for.cond.cleanup
166 for.cond.cleanup: ; preds = %for.cond
169 for.body: ; preds = %for.cond
172 for.inc: ; preds = %for.body
173 %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 -1
174 %inc = add nuw nsw i32 %i.0, 1
177 for.end: ; preds = %for.cond.cleanup
182 ; loop in which dereferenceabily "shrinks"
183 define void @deref_phi_shrinking(i32* dereferenceable(4000) %a) {
184 ; CHECK-LABEL: define {{[^@]+}}@deref_phi_shrinking
185 ; CHECK-SAME: (i32* nonnull dereferenceable(4000) [[A:%.*]]) {
187 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
189 ; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
190 ; CHECK-NEXT: [[A_ADDR_0:%.*]] = phi i32* [ [[A]], [[ENTRY]] ], [ [[INCDEC_PTR:%.*]], [[FOR_INC]] ]
191 ; CHECK-NEXT: call void @deref_phi_user(i32* nonnull [[A_ADDR_0]])
192 ; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[A_ADDR_0]], align 4
193 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[TMP]]
194 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
195 ; CHECK: for.cond.cleanup:
196 ; CHECK-NEXT: br label [[FOR_END:%.*]]
198 ; CHECK-NEXT: br label [[FOR_INC]]
200 ; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i32, i32* [[A_ADDR_0]], i64 1
201 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1
202 ; CHECK-NEXT: br label [[FOR_COND]]
204 ; CHECK-NEXT: ret void
209 for.cond: ; preds = %for.inc, %entry
210 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
211 %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ]
212 call void @deref_phi_user(i32* %a.addr.0)
213 %tmp = load i32, i32* %a.addr.0, align 4
214 %cmp = icmp slt i32 %i.0, %tmp
215 br i1 %cmp, label %for.body, label %for.cond.cleanup
217 for.cond.cleanup: ; preds = %for.cond
220 for.body: ; preds = %for.cond
223 for.inc: ; preds = %for.body
224 %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 1
225 %inc = add nuw nsw i32 %i.0, 1
228 for.end: ; preds = %for.cond.cleanup
233 ; share known infomation in must-be-executed-context
234 declare i32* @unkown_ptr() willreturn nounwind
235 declare i32 @unkown_f(i32*) willreturn nounwind
236 define i32* @f7_0(i32* %ptr) {
237 ; CHECK: Function Attrs: nounwind willreturn
238 ; CHECK-LABEL: define {{[^@]+}}@f7_0
239 ; CHECK-SAME: (i32* noundef nonnull returned dereferenceable(8) [[PTR:%.*]]) #[[ATTR1:[0-9]+]] {
240 ; CHECK-NEXT: [[T:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull dereferenceable(8) [[PTR]]) #[[ATTR1]]
241 ; CHECK-NEXT: ret i32* [[PTR]]
243 %T = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
247 define void @f7_1(i32* %ptr, i1 %c) {
248 ; CHECK: Function Attrs: nounwind willreturn
249 ; CHECK-LABEL: define {{[^@]+}}@f7_1
250 ; CHECK-SAME: (i32* noundef nonnull align 4 dereferenceable(4) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR1]] {
251 ; CHECK-NEXT: [[A:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(4) [[PTR]]) #[[ATTR1]]
252 ; CHECK-NEXT: [[B:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(4) [[PTR]]) #[[ATTR1]]
253 ; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
255 ; CHECK-NEXT: [[C:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(8) [[PTR]]) #[[ATTR1]]
256 ; CHECK-NEXT: [[D:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(8) [[PTR]]) #[[ATTR1]]
257 ; CHECK-NEXT: [[E:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(8) [[PTR]]) #[[ATTR1]]
258 ; CHECK-NEXT: ret void
260 ; CHECK-NEXT: ret void
262 %A = tail call i32 @unkown_f(i32* %ptr)
263 %ptr.0 = load i32, i32* %ptr
265 ; FIXME: this should be %B = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
266 %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr)
267 br i1%c, label %if.true, label %if.false
269 %C = tail call i32 @unkown_f(i32* %ptr)
270 %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
271 %E = tail call i32 @unkown_f(i32* %ptr)
277 define void @f7_2(i1 %c) {
278 ; CHECK: Function Attrs: nounwind willreturn
279 ; CHECK-LABEL: define {{[^@]+}}@f7_2
280 ; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
281 ; CHECK-NEXT: [[PTR:%.*]] = tail call nonnull align 4 dereferenceable(4) i32* @unkown_ptr() #[[ATTR1]]
282 ; CHECK-NEXT: [[A:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(4) [[PTR]]) #[[ATTR1]]
283 ; CHECK-NEXT: [[ARG_A_0:%.*]] = load i32, i32* [[PTR]], align 4
284 ; CHECK-NEXT: [[B:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(4) [[PTR]]) #[[ATTR1]]
285 ; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
287 ; CHECK-NEXT: [[C:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(8) [[PTR]]) #[[ATTR1]]
288 ; CHECK-NEXT: [[D:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(8) [[PTR]]) #[[ATTR1]]
289 ; CHECK-NEXT: [[E:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(8) [[PTR]]) #[[ATTR1]]
290 ; CHECK-NEXT: ret void
292 ; CHECK-NEXT: ret void
294 %ptr = tail call i32* @unkown_ptr()
295 %A = tail call i32 @unkown_f(i32* %ptr)
296 %arg_a.0 = load i32, i32* %ptr
298 %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr)
299 br i1%c, label %if.true, label %if.false
301 %C = tail call i32 @unkown_f(i32* %ptr)
302 %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
303 %E = tail call i32 @unkown_f(i32* %ptr)
309 define i32* @f7_3() {
310 ; CHECK: Function Attrs: nounwind willreturn
311 ; CHECK-LABEL: define {{[^@]+}}@f7_3
312 ; CHECK-SAME: () #[[ATTR1]] {
313 ; CHECK-NEXT: [[PTR:%.*]] = tail call noundef nonnull align 16 dereferenceable(4) i32* @unkown_ptr() #[[ATTR1]]
314 ; CHECK-NEXT: store i32 10, i32* [[PTR]], align 16
315 ; CHECK-NEXT: ret i32* [[PTR]]
317 %ptr = tail call i32* @unkown_ptr()
318 store i32 10, i32* %ptr, align 16
322 ; FIXME: This should have a return dereferenceable(8) but we need to make sure it will work in loops as well.
323 define i32* @test_for_minus_index(i32* %p) {
324 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
325 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_for_minus_index
326 ; IS__TUNIT____-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2:[0-9]+]] {
327 ; IS__TUNIT____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 -2
328 ; IS__TUNIT____-NEXT: store i32 1, i32* [[Q]], align 4
329 ; IS__TUNIT____-NEXT: ret i32* [[Q]]
331 ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
332 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_for_minus_index
333 ; IS__CGSCC____-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2:[0-9]+]] {
334 ; IS__CGSCC____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 -2
335 ; IS__CGSCC____-NEXT: store i32 1, i32* [[Q]], align 4
336 ; IS__CGSCC____-NEXT: ret i32* [[Q]]
338 %q = getelementptr inbounds i32, i32* %p, i32 -2
343 define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100) %0) {
344 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
345 ; IS__TUNIT____-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull
346 ; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]]) #[[ATTR2]] {
347 ; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP0]], align 4
348 ; IS__TUNIT____-NEXT: ret void
350 ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
351 ; IS__CGSCC____-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull
352 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]]) #[[ATTR2]] {
353 ; IS__CGSCC____-NEXT: store i32 1, i32* [[TMP0]], align 4
354 ; IS__CGSCC____-NEXT: ret void
361 ; Use Constant range in deereferenceable
362 ; void g(int *p, long long int *range){
363 ; int r = *range ; // [10, 99]
364 ; fill_range(p, *range);
367 ; FIXME: %ptr should be dereferenceable(31)
368 define void @test8(i8* %ptr) #0 {
369 ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
370 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test8
371 ; IS__TUNIT_OPM-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
372 ; IS__TUNIT_OPM-NEXT: br label [[TMP1:%.*]]
374 ; IS__TUNIT_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
375 ; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
376 ; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
377 ; IS__TUNIT_OPM-NEXT: store i8 32, i8* [[TMP3]], align 1
378 ; IS__TUNIT_OPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
379 ; IS__TUNIT_OPM-NEXT: br label [[TMP5]]
381 ; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
382 ; IS__TUNIT_OPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
384 ; IS__TUNIT_OPM-NEXT: ret void
386 ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
387 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test8
388 ; IS__TUNIT_NPM-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(21) [[PTR:%.*]]) #[[ATTR2]] {
389 ; IS__TUNIT_NPM-NEXT: br label [[TMP1:%.*]]
391 ; IS__TUNIT_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
392 ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
393 ; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
394 ; IS__TUNIT_NPM-NEXT: store i8 32, i8* [[TMP3]], align 1
395 ; IS__TUNIT_NPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
396 ; IS__TUNIT_NPM-NEXT: br label [[TMP5]]
398 ; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
399 ; IS__TUNIT_NPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
401 ; IS__TUNIT_NPM-NEXT: ret void
403 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
404 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8
405 ; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
406 ; IS__CGSCC_OPM-NEXT: br label [[TMP1:%.*]]
408 ; IS__CGSCC_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
409 ; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
410 ; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
411 ; IS__CGSCC_OPM-NEXT: store i8 32, i8* [[TMP3]], align 1
412 ; IS__CGSCC_OPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
413 ; IS__CGSCC_OPM-NEXT: br label [[TMP5]]
415 ; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
416 ; IS__CGSCC_OPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
418 ; IS__CGSCC_OPM-NEXT: ret void
420 ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
421 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test8
422 ; IS__CGSCC_NPM-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(21) [[PTR:%.*]]) #[[ATTR2]] {
423 ; IS__CGSCC_NPM-NEXT: br label [[TMP1:%.*]]
425 ; IS__CGSCC_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
426 ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
427 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
428 ; IS__CGSCC_NPM-NEXT: store i8 32, i8* [[TMP3]], align 1
429 ; IS__CGSCC_NPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
430 ; IS__CGSCC_NPM-NEXT: br label [[TMP5]]
432 ; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
433 ; IS__CGSCC_NPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
435 ; IS__CGSCC_NPM-NEXT: ret void
439 %i.0 = phi i32 [ 20, %0 ], [ %4, %5 ]
440 %2 = sext i32 %i.0 to i64
441 %3 = getelementptr inbounds i8, i8* %ptr, i64 %2
442 store i8 32, i8* %3, align 1
443 %4 = add nsw i32 %i.0, 1
446 %6 = icmp slt i32 %4, 30
447 br i1 %6, label %1, label %7
453 ; 8.2 (negative case)
454 define void @test8_neg(i32 %i, i8* %ptr) #0 {
455 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
456 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_neg
457 ; IS__TUNIT____-SAME: (i32 [[I:%.*]], i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR2]] {
458 ; IS__TUNIT____-NEXT: [[TMP1:%.*]] = sext i32 [[I]] to i64
459 ; IS__TUNIT____-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP1]]
460 ; IS__TUNIT____-NEXT: store i8 65, i8* [[TMP2]], align 1
461 ; IS__TUNIT____-NEXT: ret void
463 ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
464 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_neg
465 ; IS__CGSCC____-SAME: (i32 [[I:%.*]], i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR2]] {
466 ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = sext i32 [[I]] to i64
467 ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP1]]
468 ; IS__CGSCC____-NEXT: store i8 65, i8* [[TMP2]], align 1
469 ; IS__CGSCC____-NEXT: ret void
471 %1 = sext i32 %i to i64
472 %2 = getelementptr inbounds i8, i8* %ptr, i64 %1
473 store i8 65, i8* %2, align 1
477 ; void fill_range(int* p, long long int start){
478 ; for(long long int i = start;i<start+10;i++){
479 ; // If p[i] is inbounds, p is dereferenceable(40) at least.
484 ; NOTE: %p should not be dereferenceable
485 define internal void @fill_range_not_inbounds(i32* %p, i64 %start){
486 ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
487 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
488 ; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR3]] {
489 ; IS__TUNIT_OPM-NEXT: entry:
490 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
491 ; IS__TUNIT_OPM-NEXT: br label [[FOR_BODY:%.*]]
492 ; IS__TUNIT_OPM: for.cond.cleanup:
493 ; IS__TUNIT_OPM-NEXT: ret void
494 ; IS__TUNIT_OPM: for.body:
495 ; IS__TUNIT_OPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
496 ; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
497 ; IS__TUNIT_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
498 ; IS__TUNIT_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
499 ; IS__TUNIT_OPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
500 ; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
501 ; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
503 ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
504 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
505 ; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] {
506 ; IS__TUNIT_NPM-NEXT: entry:
507 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
508 ; IS__TUNIT_NPM-NEXT: br label [[FOR_BODY:%.*]]
509 ; IS__TUNIT_NPM: for.cond.cleanup:
510 ; IS__TUNIT_NPM-NEXT: ret void
511 ; IS__TUNIT_NPM: for.body:
512 ; IS__TUNIT_NPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
513 ; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
514 ; IS__TUNIT_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
515 ; IS__TUNIT_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
516 ; IS__TUNIT_NPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
517 ; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
518 ; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
520 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
521 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
522 ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR3]] {
523 ; IS__CGSCC_OPM-NEXT: entry:
524 ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
525 ; IS__CGSCC_OPM-NEXT: br label [[FOR_BODY:%.*]]
526 ; IS__CGSCC_OPM: for.cond.cleanup:
527 ; IS__CGSCC_OPM-NEXT: ret void
528 ; IS__CGSCC_OPM: for.body:
529 ; IS__CGSCC_OPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
530 ; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
531 ; IS__CGSCC_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
532 ; IS__CGSCC_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
533 ; IS__CGSCC_OPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
534 ; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
535 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
537 ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
538 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
539 ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] {
540 ; IS__CGSCC_NPM-NEXT: entry:
541 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
542 ; IS__CGSCC_NPM-NEXT: br label [[FOR_BODY:%.*]]
543 ; IS__CGSCC_NPM: for.cond.cleanup:
544 ; IS__CGSCC_NPM-NEXT: ret void
545 ; IS__CGSCC_NPM: for.body:
546 ; IS__CGSCC_NPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
547 ; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
548 ; IS__CGSCC_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
549 ; IS__CGSCC_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
550 ; IS__CGSCC_NPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
551 ; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
552 ; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
555 %0 = add nsw i64 %start, 9
558 for.cond.cleanup: ; preds = %for.body
561 for.body: ; preds = %entry, %for.body
562 %i.06 = phi i64 [ %start, %entry ], [ %inc, %for.body ]
563 %conv = trunc i64 %i.06 to i32
564 %arrayidx = getelementptr i32, i32* %p, i64 %i.06
565 store i32 %conv, i32* %arrayidx, align 4
566 %inc = add nsw i64 %i.06, 1
567 %cmp = icmp slt i64 %i.06, %0
568 br i1 %cmp, label %for.body, label %for.cond.cleanup
571 ; FIXME: %p should be dereferenceable(40)
572 define internal void @fill_range_inbounds(i32* %p, i64 %start){
573 ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
574 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fill_range_inbounds
575 ; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR3]] {
576 ; IS__TUNIT_OPM-NEXT: entry:
577 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
578 ; IS__TUNIT_OPM-NEXT: br label [[FOR_BODY:%.*]]
579 ; IS__TUNIT_OPM: for.cond.cleanup:
580 ; IS__TUNIT_OPM-NEXT: ret void
581 ; IS__TUNIT_OPM: for.body:
582 ; IS__TUNIT_OPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
583 ; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
584 ; IS__TUNIT_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
585 ; IS__TUNIT_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
586 ; IS__TUNIT_OPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
587 ; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
588 ; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
590 ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
591 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fill_range_inbounds
592 ; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] {
593 ; IS__TUNIT_NPM-NEXT: entry:
594 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
595 ; IS__TUNIT_NPM-NEXT: br label [[FOR_BODY:%.*]]
596 ; IS__TUNIT_NPM: for.cond.cleanup:
597 ; IS__TUNIT_NPM-NEXT: ret void
598 ; IS__TUNIT_NPM: for.body:
599 ; IS__TUNIT_NPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
600 ; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
601 ; IS__TUNIT_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
602 ; IS__TUNIT_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
603 ; IS__TUNIT_NPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
604 ; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
605 ; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
607 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
608 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fill_range_inbounds
609 ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR3]] {
610 ; IS__CGSCC_OPM-NEXT: entry:
611 ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
612 ; IS__CGSCC_OPM-NEXT: br label [[FOR_BODY:%.*]]
613 ; IS__CGSCC_OPM: for.cond.cleanup:
614 ; IS__CGSCC_OPM-NEXT: ret void
615 ; IS__CGSCC_OPM: for.body:
616 ; IS__CGSCC_OPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
617 ; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
618 ; IS__CGSCC_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
619 ; IS__CGSCC_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
620 ; IS__CGSCC_OPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
621 ; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
622 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
624 ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
625 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fill_range_inbounds
626 ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] {
627 ; IS__CGSCC_NPM-NEXT: entry:
628 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
629 ; IS__CGSCC_NPM-NEXT: br label [[FOR_BODY:%.*]]
630 ; IS__CGSCC_NPM: for.cond.cleanup:
631 ; IS__CGSCC_NPM-NEXT: ret void
632 ; IS__CGSCC_NPM: for.body:
633 ; IS__CGSCC_NPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
634 ; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
635 ; IS__CGSCC_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
636 ; IS__CGSCC_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
637 ; IS__CGSCC_NPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
638 ; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
639 ; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
642 %0 = add nsw i64 %start, 9
645 for.cond.cleanup: ; preds = %for.body
648 for.body: ; preds = %entry, %for.body
649 %i.06 = phi i64 [ %start, %entry ], [ %inc, %for.body ]
650 %conv = trunc i64 %i.06 to i32
651 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.06
652 store i32 %conv, i32* %arrayidx, align 4
653 %inc = add nsw i64 %i.06, 1
654 %cmp = icmp slt i64 %i.06, %0
655 br i1 %cmp, label %for.body, label %for.cond.cleanup
658 define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range) {
659 ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind
660 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@call_fill_range
661 ; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR4:[0-9]+]] {
662 ; IS__TUNIT_OPM-NEXT: entry:
663 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]]
664 ; IS__TUNIT_OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6:[0-9]+]]
665 ; IS__TUNIT_OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6]]
666 ; IS__TUNIT_OPM-NEXT: ret void
668 ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
669 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@call_fill_range
670 ; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] {
671 ; IS__TUNIT_NPM-NEXT: entry:
672 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]]
673 ; IS__TUNIT_NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6:[0-9]+]]
674 ; IS__TUNIT_NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6]]
675 ; IS__TUNIT_NPM-NEXT: ret void
677 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind
678 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_fill_range
679 ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR4:[0-9]+]] {
680 ; IS__CGSCC_OPM-NEXT: entry:
681 ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]]
682 ; IS__CGSCC_OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR7:[0-9]+]]
683 ; IS__CGSCC_OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR7]]
684 ; IS__CGSCC_OPM-NEXT: ret void
686 ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
687 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_fill_range
688 ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] {
689 ; IS__CGSCC_NPM-NEXT: entry:
690 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]]
691 ; IS__CGSCC_NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6:[0-9]+]]
692 ; IS__CGSCC_NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6]]
693 ; IS__CGSCC_NPM-NEXT: ret void
696 %0 = load i64, i64* %range, align 8, !range !0
697 tail call void @fill_range_inbounds(i32* %p, i64 %0)
698 tail call void @fill_range_not_inbounds(i32* %p, i64 %0)
702 declare void @use0() willreturn nounwind
703 declare void @use1(i8*) willreturn nounwind
704 declare void @use2(i8*, i8*) willreturn nounwind
705 declare void @use3(i8*, i8*, i8*) willreturn nounwind
709 ; fun2(dereferenceable(8) %a, dereferenceable(8) %b)
711 ; fun2(dereferenceable(4) %a, %b)
712 ; We can say that %a is dereferenceable(4) but %b is not.
713 define void @simple-path(i8* %a, i8 * %b, i8 %c) {
714 ; CHECK: Function Attrs: nounwind willreturn
715 ; CHECK-LABEL: define {{[^@]+}}@simple-path
716 ; CHECK-SAME: (i8* nonnull dereferenceable(4) [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR1]] {
717 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
718 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
720 ; CHECK-NEXT: tail call void @use2(i8* nonnull dereferenceable(8) [[A]], i8* nonnull dereferenceable(8) [[B]]) #[[ATTR1]]
721 ; CHECK-NEXT: ret void
723 ; CHECK-NEXT: tail call void @use2(i8* nonnull dereferenceable(4) [[A]], i8* [[B]]) #[[ATTR1]]
724 ; CHECK-NEXT: ret void
726 %cmp = icmp eq i8 %c, 0
727 br i1 %cmp, label %if.then, label %if.else
729 tail call void @use2(i8* dereferenceable(8) %a, i8* dereferenceable(8) %b)
732 tail call void @use2(i8* dereferenceable(4) %a, i8* %b)
738 ; fun1(dereferenceable(4) %a)
740 ; ... (willreturn & nounwind)
741 ; fun1(dereferenceable(12) %a)
743 ; ... (willreturn & nounwind)
744 ; fun1(dereferenceable(16) %a)
745 ; fun1(dereferenceable(8) %a)
747 ; %a is dereferenceable(12)
748 define void @complex-path(i8* %a, i8* %b, i8 %c) {
749 ; CHECK: Function Attrs: nounwind willreturn
750 ; CHECK-LABEL: define {{[^@]+}}@complex-path
751 ; CHECK-SAME: (i8* noundef nonnull dereferenceable(12) [[A:%.*]], i8* nocapture nofree readnone [[B:%.*]], i8 [[C:%.*]]) #[[ATTR1]] {
752 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
753 ; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(12) [[A]]) #[[ATTR1]]
754 ; CHECK-NEXT: br i1 [[CMP]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]]
756 ; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(12) [[A]]) #[[ATTR1]]
757 ; CHECK-NEXT: br label [[CONT2:%.*]]
759 ; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(16) [[A]]) #[[ATTR1]]
760 ; CHECK-NEXT: br label [[CONT2]]
762 ; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(12) [[A]]) #[[ATTR1]]
763 ; CHECK-NEXT: ret void
765 %cmp = icmp eq i8 %c, 0
766 tail call void @use1(i8* dereferenceable(4) %a)
767 br i1 %cmp, label %cont.then, label %cont.else
769 tail call void @use1(i8* dereferenceable(12) %a)
772 tail call void @use1(i8* dereferenceable(16) %a)
775 tail call void @use1(i8* dereferenceable(8) %a)
779 ; void rec-branch-1(int a, int b, int c, int *ptr) {
793 ; FIXME: %ptr should be dereferenceable(4)
794 define dso_local void @rec-branch-1(i32 %a, i32 %b, i32 %c, i32* %ptr) {
795 ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
796 ; IS__TUNIT____-LABEL: define {{[^@]+}}@rec-branch-1
797 ; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR2]] {
798 ; IS__TUNIT____-NEXT: entry:
799 ; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
800 ; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]]
801 ; IS__TUNIT____: if.then:
802 ; IS__TUNIT____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0
803 ; IS__TUNIT____-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
804 ; IS__TUNIT____: if.then2:
805 ; IS__TUNIT____-NEXT: store i32 1, i32* [[PTR]], align 4
806 ; IS__TUNIT____-NEXT: br label [[IF_END8:%.*]]
807 ; IS__TUNIT____: if.else:
808 ; IS__TUNIT____-NEXT: store i32 2, i32* [[PTR]], align 4
809 ; IS__TUNIT____-NEXT: br label [[IF_END8]]
810 ; IS__TUNIT____: if.else3:
811 ; IS__TUNIT____-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0
812 ; IS__TUNIT____-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
813 ; IS__TUNIT____: if.then5:
814 ; IS__TUNIT____-NEXT: store i32 3, i32* [[PTR]], align 4
815 ; IS__TUNIT____-NEXT: br label [[IF_END8]]
816 ; IS__TUNIT____: if.else6:
817 ; IS__TUNIT____-NEXT: store i32 4, i32* [[PTR]], align 4
818 ; IS__TUNIT____-NEXT: br label [[IF_END8]]
819 ; IS__TUNIT____: if.end8:
820 ; IS__TUNIT____-NEXT: ret void
822 ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
823 ; IS__CGSCC____-LABEL: define {{[^@]+}}@rec-branch-1
824 ; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR2]] {
825 ; IS__CGSCC____-NEXT: entry:
826 ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
827 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]]
828 ; IS__CGSCC____: if.then:
829 ; IS__CGSCC____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0
830 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
831 ; IS__CGSCC____: if.then2:
832 ; IS__CGSCC____-NEXT: store i32 1, i32* [[PTR]], align 4
833 ; IS__CGSCC____-NEXT: br label [[IF_END8:%.*]]
834 ; IS__CGSCC____: if.else:
835 ; IS__CGSCC____-NEXT: store i32 2, i32* [[PTR]], align 4
836 ; IS__CGSCC____-NEXT: br label [[IF_END8]]
837 ; IS__CGSCC____: if.else3:
838 ; IS__CGSCC____-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0
839 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
840 ; IS__CGSCC____: if.then5:
841 ; IS__CGSCC____-NEXT: store i32 3, i32* [[PTR]], align 4
842 ; IS__CGSCC____-NEXT: br label [[IF_END8]]
843 ; IS__CGSCC____: if.else6:
844 ; IS__CGSCC____-NEXT: store i32 4, i32* [[PTR]], align 4
845 ; IS__CGSCC____-NEXT: br label [[IF_END8]]
846 ; IS__CGSCC____: if.end8:
847 ; IS__CGSCC____-NEXT: ret void
850 %tobool = icmp eq i32 %a, 0
851 br i1 %tobool, label %if.else3, label %if.then
853 if.then: ; preds = %entry
854 %tobool1 = icmp eq i32 %b, 0
855 br i1 %tobool1, label %if.else, label %if.then2
857 if.then2: ; preds = %if.then
858 store i32 1, i32* %ptr, align 4
861 if.else: ; preds = %if.then
862 store i32 2, i32* %ptr, align 4
865 if.else3: ; preds = %entry
866 %tobool4 = icmp eq i32 %c, 0
867 br i1 %tobool4, label %if.else6, label %if.then5
869 if.then5: ; preds = %if.else3
870 store i32 3, i32* %ptr, align 4
873 if.else6: ; preds = %if.else3
874 store i32 4, i32* %ptr, align 4
877 if.end8: ; preds = %if.then5, %if.else6, %if.then2, %if.else
881 ; void rec-branch-2(int a, int b, int c, int *ptr) {
891 ; rec-branch-2(1, 1, 1, ptr);
894 ; FIXME: %ptr should be dereferenceable(4)
895 define dso_local void @rec-branch-2(i32 %a, i32 %b, i32 %c, i32* %ptr) {
896 ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
897 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@rec-branch-2
898 ; IS__TUNIT_OPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR3]] {
899 ; IS__TUNIT_OPM-NEXT: entry:
900 ; IS__TUNIT_OPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
901 ; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]]
902 ; IS__TUNIT_OPM: if.then:
903 ; IS__TUNIT_OPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0
904 ; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
905 ; IS__TUNIT_OPM: if.then2:
906 ; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[PTR]], align 4
907 ; IS__TUNIT_OPM-NEXT: br label [[IF_END8:%.*]]
908 ; IS__TUNIT_OPM: if.else:
909 ; IS__TUNIT_OPM-NEXT: store i32 2, i32* [[PTR]], align 4
910 ; IS__TUNIT_OPM-NEXT: br label [[IF_END8]]
911 ; IS__TUNIT_OPM: if.else3:
912 ; IS__TUNIT_OPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0
913 ; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
914 ; IS__TUNIT_OPM: if.then5:
915 ; IS__TUNIT_OPM-NEXT: store i32 3, i32* [[PTR]], align 4
916 ; IS__TUNIT_OPM-NEXT: br label [[IF_END8]]
917 ; IS__TUNIT_OPM: if.else6:
918 ; IS__TUNIT_OPM-NEXT: tail call void @rec-branch-2(i32 noundef 1, i32 noundef 1, i32 noundef 1, i32* nocapture nofree writeonly [[PTR]]) #[[ATTR6]]
919 ; IS__TUNIT_OPM-NEXT: br label [[IF_END8]]
920 ; IS__TUNIT_OPM: if.end8:
921 ; IS__TUNIT_OPM-NEXT: ret void
923 ; IS________NPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
924 ; IS________NPM-LABEL: define {{[^@]+}}@rec-branch-2
925 ; IS________NPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR4:[0-9]+]] {
926 ; IS________NPM-NEXT: entry:
927 ; IS________NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
928 ; IS________NPM-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]]
929 ; IS________NPM: if.then:
930 ; IS________NPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0
931 ; IS________NPM-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
932 ; IS________NPM: if.then2:
933 ; IS________NPM-NEXT: store i32 1, i32* [[PTR]], align 4
934 ; IS________NPM-NEXT: br label [[IF_END8:%.*]]
935 ; IS________NPM: if.else:
936 ; IS________NPM-NEXT: store i32 2, i32* [[PTR]], align 4
937 ; IS________NPM-NEXT: br label [[IF_END8]]
938 ; IS________NPM: if.else3:
939 ; IS________NPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0
940 ; IS________NPM-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
941 ; IS________NPM: if.then5:
942 ; IS________NPM-NEXT: store i32 3, i32* [[PTR]], align 4
943 ; IS________NPM-NEXT: br label [[IF_END8]]
944 ; IS________NPM: if.else6:
945 ; IS________NPM-NEXT: tail call void @rec-branch-2(i32 noundef 1, i32 noundef 1, i32 noundef 1, i32* nocapture nofree writeonly [[PTR]]) #[[ATTR7:[0-9]+]]
946 ; IS________NPM-NEXT: br label [[IF_END8]]
947 ; IS________NPM: if.end8:
948 ; IS________NPM-NEXT: ret void
950 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
951 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@rec-branch-2
952 ; IS__CGSCC_OPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR5:[0-9]+]] {
953 ; IS__CGSCC_OPM-NEXT: entry:
954 ; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
955 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]]
956 ; IS__CGSCC_OPM: if.then:
957 ; IS__CGSCC_OPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0
958 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
959 ; IS__CGSCC_OPM: if.then2:
960 ; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[PTR]], align 4
961 ; IS__CGSCC_OPM-NEXT: br label [[IF_END8:%.*]]
962 ; IS__CGSCC_OPM: if.else:
963 ; IS__CGSCC_OPM-NEXT: store i32 2, i32* [[PTR]], align 4
964 ; IS__CGSCC_OPM-NEXT: br label [[IF_END8]]
965 ; IS__CGSCC_OPM: if.else3:
966 ; IS__CGSCC_OPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0
967 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
968 ; IS__CGSCC_OPM: if.then5:
969 ; IS__CGSCC_OPM-NEXT: store i32 3, i32* [[PTR]], align 4
970 ; IS__CGSCC_OPM-NEXT: br label [[IF_END8]]
971 ; IS__CGSCC_OPM: if.else6:
972 ; IS__CGSCC_OPM-NEXT: tail call void @rec-branch-2(i32 noundef 1, i32 noundef 1, i32 noundef 1, i32* nocapture nofree writeonly [[PTR]]) #[[ATTR8:[0-9]+]]
973 ; IS__CGSCC_OPM-NEXT: br label [[IF_END8]]
974 ; IS__CGSCC_OPM: if.end8:
975 ; IS__CGSCC_OPM-NEXT: ret void
978 %tobool = icmp eq i32 %a, 0
979 br i1 %tobool, label %if.else3, label %if.then
981 if.then: ; preds = %entry
982 %tobool1 = icmp eq i32 %b, 0
983 br i1 %tobool1, label %if.else, label %if.then2
985 if.then2: ; preds = %if.then
986 store i32 1, i32* %ptr, align 4
989 if.else: ; preds = %if.then
990 store i32 2, i32* %ptr, align 4
993 if.else3: ; preds = %entry
994 %tobool4 = icmp eq i32 %c, 0
995 br i1 %tobool4, label %if.else6, label %if.then5
997 if.then5: ; preds = %if.else3
998 store i32 3, i32* %ptr, align 4
1001 if.else6: ; preds = %if.else3
1002 tail call void @rec-branch-2(i32 1, i32 1, i32 1, i32* %ptr)
1005 if.end8: ; preds = %if.then5, %if.else6, %if.then2, %if.else
1009 declare void @unknown()
1010 define void @nonnull_assume_pos(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4) {
1011 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_pos
1012 ; ATTRIBUTOR-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]])
1013 ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #6 [ "nonnull"(i8* undef), "dereferenceable"(i8* undef, i64 1), "dereferenceable"(i8* undef, i64 2), "dereferenceable"(i8* undef, i64 101), "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8* undef, i64 42) ]
1014 ; ATTRIBUTOR-NEXT: call void @unknown()
1015 ; ATTRIBUTOR-NEXT: ret void
1017 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
1018 ; IS__TUNIT_OPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) {
1019 ; IS__TUNIT_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7:[0-9]+]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
1020 ; IS__TUNIT_OPM-NEXT: call void @unknown()
1021 ; IS__TUNIT_OPM-NEXT: ret void
1023 ; IS________NPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
1024 ; IS________NPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) {
1025 ; IS________NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8:[0-9]+]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
1026 ; IS________NPM-NEXT: call void @unknown()
1027 ; IS________NPM-NEXT: ret void
1029 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
1030 ; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]]) {
1031 ; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR9:[0-9]+]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
1032 ; IS__CGSCC_OPM-NEXT: call void @unknown()
1033 ; IS__CGSCC_OPM-NEXT: ret void
1035 call void @llvm.assume(i1 true) [ "nonnull"(i8* %arg3), "dereferenceable"(i8* %arg1, i64 1), "dereferenceable"(i8* %arg1, i64 2), "dereferenceable"(i8* %arg1, i64 101), "dereferenceable_or_null"(i8* %arg2, i64 31), "dereferenceable_or_null"(i8* %arg4, i64 42)]
1036 call void @unknown()
1039 define void @nonnull_assume_neg(i8* %arg1, i8* %arg2, i8* %arg3) {
1040 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_neg
1041 ; ATTRIBUTOR-SAME: (i8* nocapture nofree readnone [[ARG1:%.*]], i8* nocapture nofree readnone [[ARG2:%.*]], i8* nocapture nofree readnone [[ARG3:%.*]])
1042 ; ATTRIBUTOR-NEXT: call void @unknown()
1043 ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* undef, i64 101), "dereferenceable"(i8* undef, i64 -2), "dereferenceable_or_null"(i8* undef, i64 31) ]
1044 ; ATTRIBUTOR-NEXT: ret void
1046 ; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_neg
1047 ; CHECK-SAME: (i8* nocapture nofree readnone [[ARG1:%.*]], i8* nocapture nofree readnone [[ARG2:%.*]], i8* nocapture nofree readnone [[ARG3:%.*]]) {
1048 ; CHECK-NEXT: call void @unknown()
1049 ; CHECK-NEXT: call void @llvm.assume(i1 noundef true) [ "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable"(i8* [[ARG2]], i64 -2), "dereferenceable_or_null"(i8* [[ARG3]], i64 31) ]
1050 ; CHECK-NEXT: ret void
1052 call void @unknown()
1053 call void @llvm.assume(i1 true) ["dereferenceable"(i8* %arg1, i64 101), "dereferenceable"(i8* %arg2, i64 -2), "dereferenceable_or_null"(i8* %arg3, i64 31)]
1056 define void @nonnull_assume_call(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4) {
1057 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_call
1058 ; ATTRIBUTOR-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8* [[ARG4:%.*]])
1059 ; ATTRIBUTOR-NEXT: call void @unknown()
1060 ; ATTRIBUTOR-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32* @unkown_ptr()
1061 ; ATTRIBUTOR-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]])
1062 ; ATTRIBUTOR-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(42) [[ARG4]])
1063 ; ATTRIBUTOR-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]])
1064 ; ATTRIBUTOR-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(31) [[ARG2]])
1065 ; ATTRIBUTOR-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]])
1066 ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
1067 ; ATTRIBUTOR-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]])
1068 ; ATTRIBUTOR-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(31) [[ARG2]])
1069 ; ATTRIBUTOR-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]])
1070 ; ATTRIBUTOR-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(42) [[ARG4]])
1071 ; ATTRIBUTOR-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]])
1072 ; ATTRIBUTOR-NEXT: call void @unknown()
1073 ; ATTRIBUTOR-NEXT: ret void
1075 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_assume_call
1076 ; IS__TUNIT_OPM-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8* [[ARG4:%.*]]) {
1077 ; IS__TUNIT_OPM-NEXT: call void @unknown()
1078 ; IS__TUNIT_OPM-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32* @unkown_ptr() #[[ATTR8:[0-9]+]]
1079 ; IS__TUNIT_OPM-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR8]]
1080 ; IS__TUNIT_OPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR8]]
1081 ; IS__TUNIT_OPM-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR8]]
1082 ; IS__TUNIT_OPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR8]]
1083 ; IS__TUNIT_OPM-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR8]]
1084 ; IS__TUNIT_OPM-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
1085 ; IS__TUNIT_OPM-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR8]]
1086 ; IS__TUNIT_OPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR8]]
1087 ; IS__TUNIT_OPM-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR8]]
1088 ; IS__TUNIT_OPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR8]]
1089 ; IS__TUNIT_OPM-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR8]]
1090 ; IS__TUNIT_OPM-NEXT: call void @unknown()
1091 ; IS__TUNIT_OPM-NEXT: ret void
1093 ; IS________NPM-LABEL: define {{[^@]+}}@nonnull_assume_call
1094 ; IS________NPM-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8* [[ARG4:%.*]]) {
1095 ; IS________NPM-NEXT: call void @unknown()
1096 ; IS________NPM-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32* @unkown_ptr() #[[ATTR9:[0-9]+]]
1097 ; IS________NPM-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR9]]
1098 ; IS________NPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR9]]
1099 ; IS________NPM-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR9]]
1100 ; IS________NPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR9]]
1101 ; IS________NPM-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR9]]
1102 ; IS________NPM-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
1103 ; IS________NPM-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR9]]
1104 ; IS________NPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR9]]
1105 ; IS________NPM-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR9]]
1106 ; IS________NPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR9]]
1107 ; IS________NPM-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR9]]
1108 ; IS________NPM-NEXT: call void @unknown()
1109 ; IS________NPM-NEXT: ret void
1111 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_call
1112 ; IS__CGSCC_OPM-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8* [[ARG4:%.*]]) {
1113 ; IS__CGSCC_OPM-NEXT: call void @unknown()
1114 ; IS__CGSCC_OPM-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32* @unkown_ptr() #[[ATTR10:[0-9]+]]
1115 ; IS__CGSCC_OPM-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR10]]
1116 ; IS__CGSCC_OPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR10]]
1117 ; IS__CGSCC_OPM-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR10]]
1118 ; IS__CGSCC_OPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR10]]
1119 ; IS__CGSCC_OPM-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR10]]
1120 ; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
1121 ; IS__CGSCC_OPM-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2) [[ARG1]]) #[[ATTR10]]
1122 ; IS__CGSCC_OPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(31) [[ARG2]]) #[[ATTR10]]
1123 ; IS__CGSCC_OPM-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]]) #[[ATTR10]]
1124 ; IS__CGSCC_OPM-NEXT: call void @unknown_use8(i8* dereferenceable_or_null(42) [[ARG4]]) #[[ATTR10]]
1125 ; IS__CGSCC_OPM-NEXT: call void @unknown_use32(i32* nonnull dereferenceable(101) [[P]]) #[[ATTR10]]
1126 ; IS__CGSCC_OPM-NEXT: call void @unknown()
1127 ; IS__CGSCC_OPM-NEXT: ret void
1129 call void @unknown()
1130 %p = call i32* @unkown_ptr()
1131 call void @unknown_use32(i32* %p)
1132 call void @unknown_use8(i8* %arg4)
1133 call void @unknown_use8(i8* %arg3)
1134 call void @unknown_use8(i8* %arg2)
1135 call void @unknown_use8(i8* %arg1)
1136 call void @llvm.assume(i1 true) [ "nonnull"(i8* %arg3), "dereferenceable"(i8* %arg1, i64 1), "dereferenceable"(i8* %arg1, i64 2), "dereferenceable"(i32* %p, i64 101), "dereferenceable_or_null"(i8* %arg2, i64 31), "dereferenceable_or_null"(i8* %arg4, i64 42)]
1137 call void @unknown_use8(i8* %arg1)
1138 call void @unknown_use8(i8* %arg2)
1139 call void @unknown_use8(i8* %arg3)
1140 call void @unknown_use8(i8* %arg4)
1141 call void @unknown_use32(i32* %p)
1142 call void @unknown()
1145 declare void @unknown_use8(i8*) willreturn nounwind
1146 declare void @unknown_use32(i32*) willreturn nounwind
1147 declare void @llvm.assume(i1)
1149 !0 = !{i64 10, i64 100}
1152 ; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
1153 ; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nounwind willreturn }
1154 ; IS__TUNIT_OPM: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind willreturn writeonly }
1155 ; IS__TUNIT_OPM: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind writeonly }
1156 ; IS__TUNIT_OPM: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind }
1157 ; IS__TUNIT_OPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
1158 ; IS__TUNIT_OPM: attributes #[[ATTR6]] = { nofree nosync nounwind writeonly }
1159 ; IS__TUNIT_OPM: attributes #[[ATTR7]] = { willreturn }
1160 ; IS__TUNIT_OPM: attributes #[[ATTR8]] = { nounwind }
1162 ; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
1163 ; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nounwind willreturn }
1164 ; IS__TUNIT_NPM: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind willreturn writeonly }
1165 ; IS__TUNIT_NPM: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind willreturn }
1166 ; IS__TUNIT_NPM: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind writeonly }
1167 ; IS__TUNIT_NPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
1168 ; IS__TUNIT_NPM: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn writeonly }
1169 ; IS__TUNIT_NPM: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly }
1170 ; IS__TUNIT_NPM: attributes #[[ATTR8]] = { willreturn }
1171 ; IS__TUNIT_NPM: attributes #[[ATTR9]] = { nounwind }
1173 ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
1174 ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nounwind willreturn }
1175 ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
1176 ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind writeonly }
1177 ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind }
1178 ; IS__CGSCC_OPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind writeonly }
1179 ; IS__CGSCC_OPM: attributes #[[ATTR6:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
1180 ; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nosync nounwind writeonly }
1181 ; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree nosync nounwind writeonly }
1182 ; IS__CGSCC_OPM: attributes #[[ATTR9]] = { willreturn }
1183 ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nounwind }
1185 ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
1186 ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nounwind willreturn }
1187 ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
1188 ; IS__CGSCC_NPM: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn }
1189 ; IS__CGSCC_NPM: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind writeonly }
1190 ; IS__CGSCC_NPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
1191 ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nosync nounwind willreturn writeonly }
1192 ; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly }
1193 ; IS__CGSCC_NPM: attributes #[[ATTR8]] = { willreturn }
1194 ; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nounwind }
1196 ; CHECK: [[META0:![0-9]+]] = !{i64 10, i64 100}