blob: 3ed32d3002fcbf5552333844f4851c4df8cfb247 [file] [log] [blame]
Johannes Doerferta41b2392019-08-21 21:42:46 +00001; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR
Hideto Ueno19c07af2019-07-23 08:16:17 +00002
3
Johannes Doerfert785fad32019-08-23 17:29:23 +00004declare void @deref_phi_user(i32* %a);
5
Hideto Ueno19c07af2019-07-23 08:16:17 +00006; TEST 1
7; take mininimum of return values
8;
Tim Northovera009a602019-08-03 14:28:34 +00009define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
10; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test1(i32* nonnull dereferenceable(4) %0, double* nonnull dereferenceable(8) %1, i1 zeroext %2)
Hideto Ueno19c07af2019-07-23 08:16:17 +000011 %4 = bitcast double* %1 to i32*
12 %5 = select i1 %2, i32* %0, i32* %4
13 ret i32* %5
14}
15
16; TEST 2
Tim Northovera009a602019-08-03 14:28:34 +000017define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
18; ATTRIBUTOR: define dereferenceable_or_null(4) i32* @test2(i32* dereferenceable_or_null(4) %0, double* nonnull dereferenceable(8) %1, i1 zeroext %2)
Hideto Ueno19c07af2019-07-23 08:16:17 +000019 %4 = bitcast double* %1 to i32*
20 %5 = select i1 %2, i32* %0, i32* %4
21 ret i32* %5
22}
23
24; TEST 3
25; GEP inbounds
Tim Northovera009a602019-08-03 14:28:34 +000026define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +000027; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_1(i32* nonnull dereferenceable(8) %0)
Hideto Ueno19c07af2019-07-23 08:16:17 +000028 %ret = getelementptr inbounds i32, i32* %0, i64 1
29 ret i32* %ret
30}
31
Tim Northovera009a602019-08-03 14:28:34 +000032define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr {
Hideto Ueno19c07af2019-07-23 08:16:17 +000033; FIXME: Argument should be mark dereferenceable because of GEP `inbounds`.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +000034; ATTRIBUTOR: define nonnull dereferenceable(16) i32* @test3_2(i32* dereferenceable_or_null(32) %0)
Hideto Ueno19c07af2019-07-23 08:16:17 +000035 %ret = getelementptr inbounds i32, i32* %0, i64 4
36 ret i32* %ret
37}
38
Tim Northovera009a602019-08-03 14:28:34 +000039define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +000040; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_3(i32* nonnull dereferenceable(8) %0, i32* nonnull dereferenceable(16) %1, i1 %2) local_unnamed_addr
Hideto Ueno19c07af2019-07-23 08:16:17 +000041 %ret1 = getelementptr inbounds i32, i32* %0, i64 1
42 %ret2 = getelementptr inbounds i32, i32* %1, i64 2
43 %ret = select i1 %2, i32* %ret1, i32* %ret2
44 ret i32* %ret
45}
46
47; TEST 4
48; Better than known in IR.
49
Tim Northovera009a602019-08-03 14:28:34 +000050define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_addr {
51; ATTRIBUTOR: define nonnull dereferenceable(8) i32* @test4(i32* nonnull returned dereferenceable(8) %0)
Hideto Ueno19c07af2019-07-23 08:16:17 +000052 ret i32* %0
53}
54
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +000055; TEST 5
56; loop in which dereferenceabily "grows"
Johannes Doerfert785fad32019-08-23 17:29:23 +000057define void @deref_phi_growing(i32* dereferenceable(4000) %a) {
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +000058entry:
59 br label %for.cond
60
61for.cond: ; preds = %for.inc, %entry
62 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
63 %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ]
64; CHECK: call void @deref_phi_user(i32* dereferenceable(4000) %a.addr.0)
65 call void @deref_phi_user(i32* %a.addr.0)
66 %tmp = load i32, i32* %a.addr.0, align 4
67 %cmp = icmp slt i32 %i.0, %tmp
68 br i1 %cmp, label %for.body, label %for.cond.cleanup
69
70for.cond.cleanup: ; preds = %for.cond
71 br label %for.end
72
73for.body: ; preds = %for.cond
74 br label %for.inc
75
76for.inc: ; preds = %for.body
77 %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 -1
78 %inc = add nuw nsw i32 %i.0, 1
79 br label %for.cond
80
81for.end: ; preds = %for.cond.cleanup
82 ret void
83}
Johannes Doerfert785fad32019-08-23 17:29:23 +000084
85; TEST 6
86; loop in which dereferenceabily "shrinks"
87define void @deref_phi_shrinking(i32* dereferenceable(4000) %a) {
88entry:
89 br label %for.cond
90
91for.cond: ; preds = %for.inc, %entry
92 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
93 %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ]
94; CHECK: call void @deref_phi_user(i32* %a.addr.0)
95 call void @deref_phi_user(i32* %a.addr.0)
96 %tmp = load i32, i32* %a.addr.0, align 4
97 %cmp = icmp slt i32 %i.0, %tmp
98 br i1 %cmp, label %for.body, label %for.cond.cleanup
99
100for.cond.cleanup: ; preds = %for.cond
101 br label %for.end
102
103for.body: ; preds = %for.cond
104 br label %for.inc
105
106for.inc: ; preds = %for.body
107 %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 1
108 %inc = add nuw nsw i32 %i.0, 1
109 br label %for.cond
110
111for.end: ; preds = %for.cond.cleanup
112 ret void
113}