blob: b24e0a9f77aeb1cad0d46fe958945a519e324bd1 [file] [log] [blame]
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
Johannes Doerfertd4bfce52021-07-15 18:24:58 -05002; 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
Arthur Eubanks4a100292020-07-28 17:57:21 -07004; 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
Johannes Doerferte2b53a42020-04-17 21:09:16 -05005; 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
Johannes Doerfert63adbb92020-02-09 20:21:56 -06006; FIXME: Figure out why we need 16 iterations here.
Hideto Ueno19c07af2019-07-23 08:16:17 +00007
Johannes Doerfert785fad32019-08-23 17:29:23 +00008declare void @deref_phi_user(i32* %a);
9
Hideto Ueno19c07af2019-07-23 08:16:17 +000010; TEST 1
11; take mininimum of return values
12;
Tim Northovera009a602019-08-03 14:28:34 +000013define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
sstefan1e3d646c2020-07-19 21:55:43 +020014; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
15; IS__TUNIT____-LABEL: define {{[^@]+}}@test1
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060016; 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]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +020017; 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]]
20;
21; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
22; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060023; 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]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +020024; 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]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -050027;
Hideto Ueno19c07af2019-07-23 08:16:17 +000028 %4 = bitcast double* %1 to i32*
29 %5 = select i1 %2, i32* %0, i32* %4
30 ret i32* %5
31}
32
33; TEST 2
Tim Northovera009a602019-08-03 14:28:34 +000034define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
sstefan1e3d646c2020-07-19 21:55:43 +020035; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
36; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060037; 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]] {
sstefan1e3d646c2020-07-19 21:55:43 +020038; 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]]
41;
42; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
43; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060044; 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]] {
sstefan1e3d646c2020-07-19 21:55:43 +020045; 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]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -050048;
Hideto Ueno19c07af2019-07-23 08:16:17 +000049 %4 = bitcast double* %1 to i32*
50 %5 = select i1 %2, i32* %0, i32* %4
51 ret i32* %5
52}
53
54; TEST 3
55; GEP inbounds
Tim Northovera009a602019-08-03 14:28:34 +000056define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr {
sstefan1e3d646c2020-07-19 21:55:43 +020057; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
58; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_1
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060059; IS__TUNIT____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
sstefan1e3d646c2020-07-19 21:55:43 +020060; IS__TUNIT____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
61; IS__TUNIT____-NEXT: ret i32* [[RET]]
62;
63; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
64; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_1
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060065; IS__CGSCC____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
sstefan1e3d646c2020-07-19 21:55:43 +020066; IS__CGSCC____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
67; IS__CGSCC____-NEXT: ret i32* [[RET]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -050068;
Hideto Ueno19c07af2019-07-23 08:16:17 +000069 %ret = getelementptr inbounds i32, i32* %0, i64 1
70 ret i32* %ret
71}
72
Tim Northovera009a602019-08-03 14:28:34 +000073define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr {
sstefan1e3d646c2020-07-19 21:55:43 +020074; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
75; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_2
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060076; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
sstefan1e3d646c2020-07-19 21:55:43 +020077; IS__TUNIT____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4
78; IS__TUNIT____-NEXT: ret i32* [[RET]]
79;
80; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
81; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_2
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060082; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
sstefan1e3d646c2020-07-19 21:55:43 +020083; IS__CGSCC____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4
84; IS__CGSCC____-NEXT: ret i32* [[RET]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -050085;
Hideto Ueno19c07af2019-07-23 08:16:17 +000086 %ret = getelementptr inbounds i32, i32* %0, i64 4
87 ret i32* %ret
88}
89
Tim Northovera009a602019-08-03 14:28:34 +000090define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr {
sstefan1e3d646c2020-07-19 21:55:43 +020091; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
92; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_3
Johannes Doerfert9c2074d2021-03-11 23:21:32 -060093; 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]] {
sstefan1e3d646c2020-07-19 21:55:43 +020094; 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]]
98;
99; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
100; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_3
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600101; 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]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200102; 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]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500106;
Hideto Ueno19c07af2019-07-23 08:16:17 +0000107 %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
110 ret i32* %ret
111}
112
113; TEST 4
114; Better than known in IR.
115
Tim Northovera009a602019-08-03 14:28:34 +0000116define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_addr {
sstefan1e3d646c2020-07-19 21:55:43 +0200117; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
118; IS__TUNIT____-LABEL: define {{[^@]+}}@test4
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600119; IS__TUNIT____-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200120; IS__TUNIT____-NEXT: ret i32* [[TMP0]]
121;
122; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
123; IS__CGSCC____-LABEL: define {{[^@]+}}@test4
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600124; IS__CGSCC____-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200125; IS__CGSCC____-NEXT: ret i32* [[TMP0]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500126;
Hideto Ueno19c07af2019-07-23 08:16:17 +0000127 ret i32* %0
128}
129
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +0000130; TEST 5
131; loop in which dereferenceabily "grows"
Johannes Doerfert785fad32019-08-23 17:29:23 +0000132define void @deref_phi_growing(i32* dereferenceable(4000) %a) {
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500133; CHECK-LABEL: define {{[^@]+}}@deref_phi_growing
sstefan16ce5b74b2020-08-29 19:31:13 +0200134; CHECK-SAME: (i32* nonnull dereferenceable(4000) [[A:%.*]]) {
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500135; CHECK-NEXT: entry:
136; CHECK-NEXT: br label [[FOR_COND:%.*]]
137; CHECK: 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:%.*]]
146; CHECK: for.body:
147; CHECK-NEXT: br label [[FOR_INC]]
148; CHECK: 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]]
152; CHECK: for.end:
153; CHECK-NEXT: ret void
154;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +0000155entry:
156 br label %for.cond
157
158for.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 ]
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +0000161 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
165
166for.cond.cleanup: ; preds = %for.cond
167 br label %for.end
168
169for.body: ; preds = %for.cond
170 br label %for.inc
171
172for.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
175 br label %for.cond
176
177for.end: ; preds = %for.cond.cleanup
178 ret void
179}
Johannes Doerfert785fad32019-08-23 17:29:23 +0000180
181; TEST 6
182; loop in which dereferenceabily "shrinks"
183define void @deref_phi_shrinking(i32* dereferenceable(4000) %a) {
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500184; CHECK-LABEL: define {{[^@]+}}@deref_phi_shrinking
sstefan16ce5b74b2020-08-29 19:31:13 +0200185; CHECK-SAME: (i32* nonnull dereferenceable(4000) [[A:%.*]]) {
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500186; CHECK-NEXT: entry:
187; CHECK-NEXT: br label [[FOR_COND:%.*]]
188; CHECK: 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:%.*]]
197; CHECK: for.body:
198; CHECK-NEXT: br label [[FOR_INC]]
199; CHECK: 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]]
203; CHECK: for.end:
204; CHECK-NEXT: ret void
205;
Johannes Doerfert785fad32019-08-23 17:29:23 +0000206entry:
207 br label %for.cond
208
209for.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 ]
Johannes Doerfert785fad32019-08-23 17:29:23 +0000212 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
216
217for.cond.cleanup: ; preds = %for.cond
218 br label %for.end
219
220for.body: ; preds = %for.cond
221 br label %for.inc
222
223for.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
226 br label %for.cond
227
228for.end: ; preds = %for.cond.cleanup
229 ret void
230}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000231
232; TEST 7
233; share known infomation in must-be-executed-context
234declare i32* @unkown_ptr() willreturn nounwind
235declare i32 @unkown_f(i32*) willreturn nounwind
236define i32* @f7_0(i32* %ptr) {
sstefan1e3d646c2020-07-19 21:55:43 +0200237; CHECK: Function Attrs: nounwind willreturn
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500238; CHECK-LABEL: define {{[^@]+}}@f7_0
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600239; 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]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500241; CHECK-NEXT: ret i32* [[PTR]]
242;
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000243 %T = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
244 ret i32* %ptr
Johannes Doerfertb6e58082020-02-20 02:06:14 -0600245}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000246
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000247define void @f7_1(i32* %ptr, i1 %c) {
sstefan1e3d646c2020-07-19 21:55:43 +0200248; CHECK: Function Attrs: nounwind willreturn
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500249; CHECK-LABEL: define {{[^@]+}}@f7_1
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600250; 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]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500253; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
254; CHECK: if.true:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600255; 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]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500258; CHECK-NEXT: ret void
259; CHECK: if.false:
260; CHECK-NEXT: ret void
261;
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000262 %A = tail call i32 @unkown_f(i32* %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000263 %ptr.0 = load i32, i32* %ptr
264 ; deref 4 hold
Johannes Doerfertb6e58082020-02-20 02:06:14 -0600265; FIXME: this should be %B = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000266 %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000267 br i1%c, label %if.true, label %if.false
268if.true:
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000269 %C = tail call i32 @unkown_f(i32* %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000270 %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000271 %E = tail call i32 @unkown_f(i32* %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000272 ret void
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000273if.false:
274 ret void
275}
276
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000277define void @f7_2(i1 %c) {
Shinji Okumurae21a22a2020-08-22 05:06:14 +0900278; CHECK: Function Attrs: nounwind willreturn
279; CHECK-LABEL: define {{[^@]+}}@f7_2
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600280; 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]]
Shinji Okumurae21a22a2020-08-22 05:06:14 +0900283; CHECK-NEXT: [[ARG_A_0:%.*]] = load i32, i32* [[PTR]], align 4
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600284; CHECK-NEXT: [[B:%.*]] = tail call i32 @unkown_f(i32* noundef nonnull align 4 dereferenceable(4) [[PTR]]) #[[ATTR1]]
Shinji Okumurae21a22a2020-08-22 05:06:14 +0900285; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
286; CHECK: if.true:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600287; 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]]
Shinji Okumurae21a22a2020-08-22 05:06:14 +0900290; CHECK-NEXT: ret void
291; CHECK: if.false:
292; CHECK-NEXT: ret void
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500293;
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000294 %ptr = tail call i32* @unkown_ptr()
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000295 %A = tail call i32 @unkown_f(i32* %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000296 %arg_a.0 = load i32, i32* %ptr
297 ; deref 4 hold
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000298 %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000299 br i1%c, label %if.true, label %if.false
300if.true:
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000301 %C = tail call i32 @unkown_f(i32* %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000302 %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000303 %E = tail call i32 @unkown_f(i32* %ptr)
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000304 ret void
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000305if.false:
306 ret void
307}
308
309define i32* @f7_3() {
sstefan1e3d646c2020-07-19 21:55:43 +0200310; CHECK: Function Attrs: nounwind willreturn
sstefan16ce5b74b2020-08-29 19:31:13 +0200311; CHECK-LABEL: define {{[^@]+}}@f7_3
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600312; CHECK-SAME: () #[[ATTR1]] {
313; CHECK-NEXT: [[PTR:%.*]] = tail call noundef nonnull align 16 dereferenceable(4) i32* @unkown_ptr() #[[ATTR1]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500314; CHECK-NEXT: store i32 10, i32* [[PTR]], align 16
315; CHECK-NEXT: ret i32* [[PTR]]
316;
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000317 %ptr = tail call i32* @unkown_ptr()
318 store i32 10, i32* %ptr, align 16
319 ret i32* %ptr
320}
321
Florian Hahn0c22cb02020-04-09 11:07:36 +0100322; FIXME: This should have a return dereferenceable(8) but we need to make sure it will work in loops as well.
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500323define i32* @test_for_minus_index(i32* %p) {
sstefan1e3d646c2020-07-19 21:55:43 +0200324; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
325; IS__TUNIT____-LABEL: define {{[^@]+}}@test_for_minus_index
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600326; IS__TUNIT____-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2:[0-9]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200327; 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]]
330;
331; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
332; IS__CGSCC____-LABEL: define {{[^@]+}}@test_for_minus_index
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600333; IS__CGSCC____-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2:[0-9]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200334; 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]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500337;
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000338 %q = getelementptr inbounds i32, i32* %p, i32 -2
339 store i32 1, i32* %q
340 ret i32* %q
341}
Hideto Uenodfedae52019-11-29 06:45:07 +0000342
343define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100) %0) {
sstefan1e3d646c2020-07-19 21:55:43 +0200344; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
345; IS__TUNIT____-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600346; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200347; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP0]], align 4
348; IS__TUNIT____-NEXT: ret void
349;
350; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
351; IS__CGSCC____-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600352; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200353; IS__CGSCC____-NEXT: store i32 1, i32* [[TMP0]], align 4
354; IS__CGSCC____-NEXT: ret void
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500355;
Hideto Uenodfedae52019-11-29 06:45:07 +0000356 store i32 1, i32* %0
357 ret void
358}
Hideto Ueno188f9a32020-01-15 15:25:52 +0900359
360; TEST 8
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);
365; }
366
Kuter Dinele5780772020-05-13 12:49:15 -0500367; FIXME: %ptr should be dereferenceable(31)
368define void @test8(i8* %ptr) #0 {
sstefan1e3d646c2020-07-19 21:55:43 +0200369; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
370; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test8
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600371; IS__TUNIT_OPM-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200372; IS__TUNIT_OPM-NEXT: br label [[TMP1:%.*]]
373; IS__TUNIT_OPM: 1:
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]]
380; IS__TUNIT_OPM: 5:
381; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
382; IS__TUNIT_OPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
383; IS__TUNIT_OPM: 7:
384; IS__TUNIT_OPM-NEXT: ret void
Johannes Doerfert6045a802020-05-13 17:43:01 -0500385;
sstefan1e3d646c2020-07-19 21:55:43 +0200386; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
387; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test8
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600388; IS__TUNIT_NPM-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(21) [[PTR:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200389; IS__TUNIT_NPM-NEXT: br label [[TMP1:%.*]]
390; IS__TUNIT_NPM: 1:
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]]
397; IS__TUNIT_NPM: 5:
398; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
399; IS__TUNIT_NPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
400; IS__TUNIT_NPM: 7:
401; IS__TUNIT_NPM-NEXT: ret void
402;
403; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
404; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600405; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200406; IS__CGSCC_OPM-NEXT: br label [[TMP1:%.*]]
407; IS__CGSCC_OPM: 1:
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]]
414; IS__CGSCC_OPM: 5:
415; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
416; IS__CGSCC_OPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
417; IS__CGSCC_OPM: 7:
418; IS__CGSCC_OPM-NEXT: ret void
419;
420; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
421; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test8
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600422; IS__CGSCC_NPM-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(21) [[PTR:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200423; IS__CGSCC_NPM-NEXT: br label [[TMP1:%.*]]
424; IS__CGSCC_NPM: 1:
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]]
431; IS__CGSCC_NPM: 5:
432; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
433; IS__CGSCC_NPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
434; IS__CGSCC_NPM: 7:
435; IS__CGSCC_NPM-NEXT: ret void
Johannes Doerfert6045a802020-05-13 17:43:01 -0500436;
Kuter Dinele5780772020-05-13 12:49:15 -0500437 br label %1
4381: ; preds = %5, %0
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
444 br label %5
4455: ; preds = %1
446 %6 = icmp slt i32 %4, 30
447 br i1 %6, label %1, label %7
448
4497: ; preds = %5
450 ret void
451}
452
453; 8.2 (negative case)
454define void @test8_neg(i32 %i, i8* %ptr) #0 {
sstefan1e3d646c2020-07-19 21:55:43 +0200455; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
456; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_neg
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600457; IS__TUNIT____-SAME: (i32 [[I:%.*]], i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200458; 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
462;
463; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
464; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_neg
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600465; IS__CGSCC____-SAME: (i32 [[I:%.*]], i8* nocapture nofree nonnull writeonly [[PTR:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200466; 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
Johannes Doerfert6045a802020-05-13 17:43:01 -0500470;
Kuter Dinele5780772020-05-13 12:49:15 -0500471 %1 = sext i32 %i to i64
472 %2 = getelementptr inbounds i8, i8* %ptr, i64 %1
473 store i8 65, i8* %2, align 1
474 ret void
475}
476
Hideto Ueno188f9a32020-01-15 15:25:52 +0900477; 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.
480; p[i] = i;
481; }
482; }
483
Florian Hahn0c22cb02020-04-09 11:07:36 +0100484; NOTE: %p should not be dereferenceable
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500485define internal void @fill_range_not_inbounds(i32* %p, i64 %start){
sstefan1e3d646c2020-07-19 21:55:43 +0200486; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
487; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600488; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR3]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200489; 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:%.*]]
502;
503; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
504; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600505; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200506; 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:%.*]]
519;
520; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
521; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600522; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR3]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200523; 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:%.*]]
536;
537; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
538; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600539; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200540; 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:%.*]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500553;
Hideto Ueno188f9a32020-01-15 15:25:52 +0900554entry:
555 %0 = add nsw i64 %start, 9
556 br label %for.body
557
558for.cond.cleanup: ; preds = %for.body
559 ret void
560
561for.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
569}
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500570
Florian Hahn0c22cb02020-04-09 11:07:36 +0100571; FIXME: %p should be dereferenceable(40)
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500572define internal void @fill_range_inbounds(i32* %p, i64 %start){
sstefan1e3d646c2020-07-19 21:55:43 +0200573; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
574; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fill_range_inbounds
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600575; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR3]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200576; 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:%.*]]
589;
590; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
591; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fill_range_inbounds
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600592; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200593; 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:%.*]]
606;
607; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
608; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fill_range_inbounds
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600609; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR3]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200610; 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:%.*]]
623;
624; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
625; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fill_range_inbounds
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600626; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200627; 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:%.*]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500640;
Hideto Ueno188f9a32020-01-15 15:25:52 +0900641entry:
642 %0 = add nsw i64 %start, 9
643 br label %for.body
644
645for.cond.cleanup: ; preds = %for.body
646 ret void
647
648for.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
656}
657
658define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range) {
sstefan1e3d646c2020-07-19 21:55:43 +0200659; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind
660; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@call_fill_range
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600661; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR4:[0-9]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200662; IS__TUNIT_OPM-NEXT: entry:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600663; 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]]
sstefan1e3d646c2020-07-19 21:55:43 +0200666; IS__TUNIT_OPM-NEXT: ret void
667;
668; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
669; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@call_fill_range
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600670; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200671; IS__TUNIT_NPM-NEXT: entry:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600672; 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]]
sstefan1e3d646c2020-07-19 21:55:43 +0200675; IS__TUNIT_NPM-NEXT: ret void
676;
677; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind
678; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_fill_range
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600679; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR4:[0-9]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200680; IS__CGSCC_OPM-NEXT: entry:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600681; 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]]
sstefan1e3d646c2020-07-19 21:55:43 +0200684; IS__CGSCC_OPM-NEXT: ret void
685;
686; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
687; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_fill_range
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600688; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200689; IS__CGSCC_NPM-NEXT: entry:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600690; 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]]
sstefan1e3d646c2020-07-19 21:55:43 +0200693; IS__CGSCC_NPM-NEXT: ret void
Hideto Ueno188f9a32020-01-15 15:25:52 +0900694;
695entry:
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)
699 ret void
700}
701
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900702declare void @use0() willreturn nounwind
703declare void @use1(i8*) willreturn nounwind
704declare void @use2(i8*, i8*) willreturn nounwind
705declare void @use3(i8*, i8*, i8*) willreturn nounwind
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500706
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900707; simple path test
708; if(..)
709; fun2(dereferenceable(8) %a, dereferenceable(8) %b)
710; else
711; fun2(dereferenceable(4) %a, %b)
712; We can say that %a is dereferenceable(4) but %b is not.
713define void @simple-path(i8* %a, i8 * %b, i8 %c) {
sstefan1e3d646c2020-07-19 21:55:43 +0200714; CHECK: Function Attrs: nounwind willreturn
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500715; CHECK-LABEL: define {{[^@]+}}@simple-path
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600716; CHECK-SAME: (i8* nonnull dereferenceable(4) [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR1]] {
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500717; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
718; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
719; CHECK: if.then:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600720; CHECK-NEXT: tail call void @use2(i8* nonnull dereferenceable(8) [[A]], i8* nonnull dereferenceable(8) [[B]]) #[[ATTR1]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500721; CHECK-NEXT: ret void
722; CHECK: if.else:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600723; CHECK-NEXT: tail call void @use2(i8* nonnull dereferenceable(4) [[A]], i8* [[B]]) #[[ATTR1]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500724; CHECK-NEXT: ret void
725;
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900726 %cmp = icmp eq i8 %c, 0
727 br i1 %cmp, label %if.then, label %if.else
728if.then:
729 tail call void @use2(i8* dereferenceable(8) %a, i8* dereferenceable(8) %b)
730 ret void
731if.else:
732 tail call void @use2(i8* dereferenceable(4) %a, i8* %b)
733 ret void
734}
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500735
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900736; More complex test
737; {
738; fun1(dereferenceable(4) %a)
739; if(..)
740; ... (willreturn & nounwind)
741; fun1(dereferenceable(12) %a)
742; else
743; ... (willreturn & nounwind)
744; fun1(dereferenceable(16) %a)
745; fun1(dereferenceable(8) %a)
746; }
747; %a is dereferenceable(12)
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900748define void @complex-path(i8* %a, i8* %b, i8 %c) {
sstefan1e3d646c2020-07-19 21:55:43 +0200749; CHECK: Function Attrs: nounwind willreturn
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500750; CHECK-LABEL: define {{[^@]+}}@complex-path
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600751; CHECK-SAME: (i8* noundef nonnull dereferenceable(12) [[A:%.*]], i8* nocapture nofree readnone [[B:%.*]], i8 [[C:%.*]]) #[[ATTR1]] {
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500752; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600753; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(12) [[A]]) #[[ATTR1]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500754; CHECK-NEXT: br i1 [[CMP]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]]
755; CHECK: cont.then:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600756; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(12) [[A]]) #[[ATTR1]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500757; CHECK-NEXT: br label [[CONT2:%.*]]
758; CHECK: cont.else:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600759; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(16) [[A]]) #[[ATTR1]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500760; CHECK-NEXT: br label [[CONT2]]
761; CHECK: cont2:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600762; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(12) [[A]]) #[[ATTR1]]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500763; CHECK-NEXT: ret void
764;
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900765 %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
768cont.then:
769 tail call void @use1(i8* dereferenceable(12) %a)
770 br label %cont2
771cont.else:
772 tail call void @use1(i8* dereferenceable(16) %a)
773 br label %cont2
774cont2:
775 tail call void @use1(i8* dereferenceable(8) %a)
776 ret void
777}
778
779; void rec-branch-1(int a, int b, int c, int *ptr) {
780; if (a) {
781; if (b)
782; *ptr = 1;
783; else
784; *ptr = 2;
785; } else {
786; if (c)
787; *ptr = 3;
788; else
789; *ptr = 4;
790; }
791; }
792;
793; FIXME: %ptr should be dereferenceable(4)
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900794define dso_local void @rec-branch-1(i32 %a, i32 %b, i32 %c, i32* %ptr) {
sstefan1e3d646c2020-07-19 21:55:43 +0200795; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
796; IS__TUNIT____-LABEL: define {{[^@]+}}@rec-branch-1
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600797; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200798; 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
821;
822; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
823; IS__CGSCC____-LABEL: define {{[^@]+}}@rec-branch-1
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600824; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR2]] {
sstefan1e3d646c2020-07-19 21:55:43 +0200825; 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
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500848;
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900849entry:
850 %tobool = icmp eq i32 %a, 0
851 br i1 %tobool, label %if.else3, label %if.then
852
853if.then: ; preds = %entry
854 %tobool1 = icmp eq i32 %b, 0
855 br i1 %tobool1, label %if.else, label %if.then2
856
857if.then2: ; preds = %if.then
858 store i32 1, i32* %ptr, align 4
859 br label %if.end8
860
861if.else: ; preds = %if.then
862 store i32 2, i32* %ptr, align 4
863 br label %if.end8
864
865if.else3: ; preds = %entry
866 %tobool4 = icmp eq i32 %c, 0
867 br i1 %tobool4, label %if.else6, label %if.then5
868
869if.then5: ; preds = %if.else3
870 store i32 3, i32* %ptr, align 4
871 br label %if.end8
872
873if.else6: ; preds = %if.else3
874 store i32 4, i32* %ptr, align 4
875 br label %if.end8
876
877if.end8: ; preds = %if.then5, %if.else6, %if.then2, %if.else
878 ret void
879}
880
881; void rec-branch-2(int a, int b, int c, int *ptr) {
882; if (a) {
883; if (b)
884; *ptr = 1;
885; else
886; *ptr = 2;
887; } else {
888; if (c)
889; *ptr = 3;
890; else
891; rec-branch-2(1, 1, 1, ptr);
892; }
893; }
894; FIXME: %ptr should be dereferenceable(4)
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900895define dso_local void @rec-branch-2(i32 %a, i32 %b, i32 %c, i32* %ptr) {
sstefan16ce5b74b2020-08-29 19:31:13 +0200896; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
897; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@rec-branch-2
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600898; IS__TUNIT_OPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR3]] {
sstefan16ce5b74b2020-08-29 19:31:13 +0200899; 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:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600918; 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]]
sstefan16ce5b74b2020-08-29 19:31:13 +0200919; IS__TUNIT_OPM-NEXT: br label [[IF_END8]]
920; IS__TUNIT_OPM: if.end8:
921; IS__TUNIT_OPM-NEXT: ret void
922;
923; IS________NPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
924; IS________NPM-LABEL: define {{[^@]+}}@rec-branch-2
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600925; IS________NPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR4:[0-9]+]] {
sstefan16ce5b74b2020-08-29 19:31:13 +0200926; 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:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600945; 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]+]]
sstefan16ce5b74b2020-08-29 19:31:13 +0200946; IS________NPM-NEXT: br label [[IF_END8]]
947; IS________NPM: if.end8:
948; IS________NPM-NEXT: ret void
949;
950; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
951; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@rec-branch-2
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600952; IS__CGSCC_OPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR5:[0-9]+]] {
sstefan16ce5b74b2020-08-29 19:31:13 +0200953; 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:
Johannes Doerfert9c2074d2021-03-11 23:21:32 -0600972; 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]+]]
sstefan16ce5b74b2020-08-29 19:31:13 +0200973; IS__CGSCC_OPM-NEXT: br label [[IF_END8]]
974; IS__CGSCC_OPM: if.end8:
975; IS__CGSCC_OPM-NEXT: ret void
Johannes Doerfert3ca54f42020-04-08 19:04:57 -0500976;
Hideto Uenobdcbdb42020-03-09 14:19:32 +0900977entry:
978 %tobool = icmp eq i32 %a, 0
979 br i1 %tobool, label %if.else3, label %if.then
980
981if.then: ; preds = %entry
982 %tobool1 = icmp eq i32 %b, 0
983 br i1 %tobool1, label %if.else, label %if.then2
984
985if.then2: ; preds = %if.then
986 store i32 1, i32* %ptr, align 4
987 br label %if.end8
988
989if.else: ; preds = %if.then
990 store i32 2, i32* %ptr, align 4
991 br label %if.end8
992
993if.else3: ; preds = %entry
994 %tobool4 = icmp eq i32 %c, 0
995 br i1 %tobool4, label %if.else6, label %if.then5
996
997if.then5: ; preds = %if.else3
998 store i32 3, i32* %ptr, align 4
999 br label %if.end8
1000
1001if.else6: ; preds = %if.else3
1002 tail call void @rec-branch-2(i32 1, i32 1, i32 1, i32* %ptr)
1003 br label %if.end8
1004
1005if.end8: ; preds = %if.then5, %if.else6, %if.then2, %if.else
1006 ret void
1007}
1008
Johannes Doerfert5699d082020-02-20 02:06:48 -06001009declare void @unknown()
1010define 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
1016;
Johannes Doerfert3ca54f42020-04-08 19:04:57 -05001017; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
sstefan16ce5b74b2020-08-29 19:31:13 +02001018; 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:%.*]]) {
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001019; 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) ]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -05001020; IS__TUNIT_OPM-NEXT: call void @unknown()
1021; IS__TUNIT_OPM-NEXT: ret void
1022;
1023; IS________NPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
sstefan16ce5b74b2020-08-29 19:31:13 +02001024; 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:%.*]]) {
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001025; 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) ]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -05001026; IS________NPM-NEXT: call void @unknown()
1027; IS________NPM-NEXT: ret void
1028;
1029; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
sstefan16ce5b74b2020-08-29 19:31:13 +02001030; 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:%.*]]) {
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001031; 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) ]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -05001032; IS__CGSCC_OPM-NEXT: call void @unknown()
1033; IS__CGSCC_OPM-NEXT: ret void
1034;
Johannes Doerfert5699d082020-02-20 02:06:48 -06001035 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()
1037 ret void
1038}
1039define 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
1045;
Johannes Doerfert3ca54f42020-04-08 19:04:57 -05001046; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_neg
sstefan16ce5b74b2020-08-29 19:31:13 +02001047; CHECK-SAME: (i8* nocapture nofree readnone [[ARG1:%.*]], i8* nocapture nofree readnone [[ARG2:%.*]], i8* nocapture nofree readnone [[ARG3:%.*]]) {
Johannes Doerfert3ca54f42020-04-08 19:04:57 -05001048; CHECK-NEXT: call void @unknown()
Shinji Okumura7a15dfd2020-08-30 05:34:24 +09001049; 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) ]
Johannes Doerfert3ca54f42020-04-08 19:04:57 -05001050; CHECK-NEXT: ret void
1051;
Johannes Doerfert5699d082020-02-20 02:06:48 -06001052 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)]
1054 ret void
1055}
1056define 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
1074;
sstefan16ce5b74b2020-08-29 19:31:13 +02001075; 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()
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001078; 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]]
Shinji Okumura7a15dfd2020-08-30 05:34:24 +09001084; 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) ]
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001085; 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]]
sstefan16ce5b74b2020-08-29 19:31:13 +02001090; IS__TUNIT_OPM-NEXT: call void @unknown()
1091; IS__TUNIT_OPM-NEXT: ret void
1092;
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()
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001096; 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]]
Shinji Okumura7a15dfd2020-08-30 05:34:24 +09001102; 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) ]
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001103; 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]]
sstefan16ce5b74b2020-08-29 19:31:13 +02001108; IS________NPM-NEXT: call void @unknown()
1109; IS________NPM-NEXT: ret void
1110;
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()
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001114; 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]]
Shinji Okumura7a15dfd2020-08-30 05:34:24 +09001120; 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) ]
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001121; 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]]
sstefan16ce5b74b2020-08-29 19:31:13 +02001126; IS__CGSCC_OPM-NEXT: call void @unknown()
1127; IS__CGSCC_OPM-NEXT: ret void
Johannes Doerfert3ca54f42020-04-08 19:04:57 -05001128;
Johannes Doerfert5699d082020-02-20 02:06:48 -06001129 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()
1143 ret void
1144}
1145declare void @unknown_use8(i8*) willreturn nounwind
1146declare void @unknown_use32(i32*) willreturn nounwind
1147declare void @llvm.assume(i1)
1148
Hideto Ueno188f9a32020-01-15 15:25:52 +09001149!0 = !{i64 10, i64 100}
1150
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001151;.
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 }
Nikita Popovca28e3232021-03-20 18:11:17 +01001157; IS__TUNIT_OPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001158; IS__TUNIT_OPM: attributes #[[ATTR6]] = { nofree nosync nounwind writeonly }
1159; IS__TUNIT_OPM: attributes #[[ATTR7]] = { willreturn }
1160; IS__TUNIT_OPM: attributes #[[ATTR8]] = { nounwind }
1161;.
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 }
Nikita Popovca28e3232021-03-20 18:11:17 +01001167; IS__TUNIT_NPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001168; 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 }
1172;.
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 }
Nikita Popovca28e3232021-03-20 18:11:17 +01001179; IS__CGSCC_OPM: attributes #[[ATTR6:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001180; 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 }
1184;.
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 }
Nikita Popovca28e3232021-03-20 18:11:17 +01001190; IS__CGSCC_NPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn }
Johannes Doerfert9c2074d2021-03-11 23:21:32 -06001191; 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 }
1195;.
1196; CHECK: [[META0:![0-9]+]] = !{i64 10, i64 100}
1197;.