1 ; RUN: opt -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info %s 2>&1 | FileCheck %s
3 ; %col.ptr.1 and %col.ptr.2 do not alias, if we know that %skip >= 0, because
4 ; the distance between %col.ptr.1 and %col.ptr.2 is %skip + 6 and we load 6
6 define void @test1(ptr %ptr, i32 %skip) {
7 ; CHECK-LABEL: Function: test1: 2 pointers, 1 call sites
8 ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2, <6 x double>* %ptr
10 %gt = icmp sgt i32 %skip, -1
11 call void @llvm.assume(i1 %gt)
12 %stride = add nsw nuw i32 %skip, 6
13 %lv.1 = load <6 x double>, ptr %ptr, align 8
14 %col.ptr.2 = getelementptr double, ptr %ptr, i32 %stride
15 %lv.2 = load <6 x double>, ptr %col.ptr.2, align 8
16 %res.1 = fadd <6 x double> %lv.1, %lv.1
17 %res.2 = fadd <6 x double> %lv.2, %lv.2
18 store <6 x double> %res.1, ptr %ptr, align 8
19 store <6 x double> %res.2, ptr %col.ptr.2, align 8
23 ; Same as @test1, but now we do not have an assume guaranteeing %skip >= 0.
24 define void @test2(ptr %ptr, i32 %skip) {
25 ; CHECK-LABEL: Function: test2: 2 pointers, 0 call sites
26 ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.2, <6 x double>* %ptr
28 %stride = add nsw nuw i32 %skip, 6
29 %lv.1 = load <6 x double>, ptr %ptr, align 8
30 %col.ptr.2 = getelementptr double, ptr %ptr, i32 %stride
31 %lv.2 = load <6 x double>, ptr %col.ptr.2, align 8
32 %res.1 = fadd <6 x double> %lv.1, %lv.1
33 %res.2 = fadd <6 x double> %lv.2, %lv.2
34 store <6 x double> %res.1, ptr %ptr, align 8
35 store <6 x double> %res.2, ptr %col.ptr.2, align 8
39 ; Same as @test1, this time the assume just guarantees %skip > -3, which is
40 ; enough to derive NoAlias for %ptr and %col.ptr.2 (distance is more than 3
41 ; doubles, and we load 1 double), but not %col.ptr.1 and %col.ptr.2 (distance
42 ; is more than 3 doubles, and we load 6 doubles).
43 define void @test3(ptr %ptr, i32 %skip) {
44 ; CHECK-LABEL: Function: test3: 2 pointers, 1 call sites
45 ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.2, <6 x double>* %ptr
47 %gt = icmp sgt i32 %skip, -3
48 call void @llvm.assume(i1 %gt)
49 %stride = add nsw nuw i32 %skip, 6
50 %lv.1 = load <6 x double>, ptr %ptr, align 8
51 %col.ptr.2 = getelementptr double, ptr %ptr, i32 %stride
52 %lv.2 = load <6 x double>, ptr %col.ptr.2, align 8
53 %res.1 = fadd <6 x double> %lv.1, %lv.1
54 %res.2 = fadd <6 x double> %lv.2, %lv.2
55 store <6 x double> %res.1, ptr %ptr, align 8
56 store <6 x double> %res.2, ptr %col.ptr.2, align 8
60 ; Same as @test1, but the assume uses the sge predicate for %skip >= 0.
61 define void @test4(ptr %ptr, i32 %skip) {
62 ; CHECK-LABEL: Function: test4: 2 pointers, 1 call sites
63 ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2, <6 x double>* %ptr
65 %gt = icmp sge i32 %skip, 0
66 call void @llvm.assume(i1 %gt)
67 %stride = add nsw nuw i32 %skip, 6
68 %lv.1 = load <6 x double>, ptr %ptr, align 8
69 %col.ptr.2 = getelementptr double, ptr %ptr, i32 %stride
70 %lv.2 = load <6 x double>, ptr %col.ptr.2, align 8
71 %res.1 = fadd <6 x double> %lv.1, %lv.1
72 %res.2 = fadd <6 x double> %lv.2, %lv.2
73 store <6 x double> %res.1, ptr %ptr, align 8
74 store <6 x double> %res.2, ptr %col.ptr.2, align 8
78 define void @symmetry(ptr %ptr, i32 %a, i32 %b, i32 %c) {
79 ; CHECK-LABEL: Function: symmetry
80 ; CHECK: NoAlias: i8* %gep1, i8* %gep2
82 %b.cmp = icmp slt i32 %b, 0
83 call void @llvm.assume(i1 %b.cmp)
84 %gep1 = getelementptr [0 x i8], ptr %ptr, i32 %a, i32 %b
87 %c.cmp = icmp sgt i32 %c, -1
88 call void @llvm.assume(i1 %c.cmp)
89 %c.off = add nuw nsw i32 %c, 1
90 %gep2 = getelementptr [0 x i8], ptr %ptr, i32 %a, i32 %c.off
95 ; %ptr.neg and %ptr.shl may alias, as the shl renders the previously
96 ; non-negative value potentially negative.
97 define void @shl_of_non_negative(ptr %ptr, i64 %a) {
98 ; CHECK-LABEL: Function: shl_of_non_negative
99 ; CHECK: NoAlias: i8* %ptr.a, i8* %ptr.neg
100 ; CHECK: MayAlias: i8* %ptr.neg, i8* %ptr.shl
102 %a.cmp = icmp sge i64 %a, 0
103 call void @llvm.assume(i1 %a.cmp)
104 %ptr.neg = getelementptr i8, ptr %ptr, i64 -2
105 %ptr.a = getelementptr i8, ptr %ptr, i64 %a
107 %ptr.shl = getelementptr i8, ptr %ptr, i64 %shl
109 load i8, ptr %ptr.neg
110 load i8, ptr %ptr.shl
114 ; Unlike the previous case, %ptr.neg and %ptr.shl can't alias, because
115 ; shl nsw of non-negative is non-negative.
116 define void @shl_nsw_of_non_negative(ptr %ptr, i64 %a) {
117 ; CHECK-LABEL: Function: shl_nsw_of_non_negative
118 ; CHECK: NoAlias: i8* %ptr.a, i8* %ptr.neg
119 ; CHECK: NoAlias: i8* %ptr.neg, i8* %ptr.shl
121 %a.cmp = icmp sge i64 %a, 0
122 call void @llvm.assume(i1 %a.cmp)
123 %ptr.neg = getelementptr i8, ptr %ptr, i64 -2
124 %ptr.a = getelementptr i8, ptr %ptr, i64 %a
125 %shl = shl nsw i64 %a, 1
126 %ptr.shl = getelementptr i8, ptr %ptr, i64 %shl
128 load i8, ptr %ptr.neg
129 load i8, ptr %ptr.shl
133 define void @test5(ptr %ptr, i32 %stride) {
134 ; CHECK-LABEL: Function: test5: 2 pointers, 1 call sites
135 ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.2, <6 x double>* %ptr
137 %gt = icmp sge i32 %stride, 5
138 call void @llvm.assume(i1 %gt)
139 %lv.1 = load <6 x double>, ptr %ptr, align 8
140 %col.ptr.2= getelementptr double, ptr %ptr, i32 %stride
141 %lv.2 = load <6 x double>, ptr %col.ptr.2, align 8
142 %res.1 = fadd <6 x double> %lv.1, %lv.1
143 %res.2 = fadd <6 x double> %lv.2, %lv.2
144 store <6 x double> %res.1, ptr %ptr, align 8
145 store <6 x double> %res.2, ptr %col.ptr.2, align 8
149 define void @test6(ptr %ptr, i32 %stride) {
150 ; CHECK-LABEL: Function: test6: 2 pointers, 1 call sites
151 ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2, <6 x double>* %ptr
153 %gt = icmp sge i32 %stride, 6
154 call void @llvm.assume(i1 %gt)
155 %lv.1 = load <6 x double>, ptr %ptr, align 8
156 %col.ptr.2= getelementptr double, ptr %ptr, i32 %stride
157 %lv.2 = load <6 x double>, ptr %col.ptr.2, align 8
158 %res.1 = fadd <6 x double> %lv.1, %lv.1
159 %res.2 = fadd <6 x double> %lv.2, %lv.2
160 store <6 x double> %res.1, ptr %ptr, align 8
161 store <6 x double> %res.2, ptr %col.ptr.2, align 8
165 define void @test7(ptr %ptr, i32 %stride) {
166 ; CHECK-LABEL: Function: test7: 2 pointers, 1 call sites
167 ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.2, <6 x double>* %ptr
169 %gt = icmp sge i32 %stride, 0
170 call void @llvm.assume(i1 %gt)
171 %lv.1 = load <6 x double>, ptr %ptr, align 8
172 %col.ptr.2= getelementptr double, ptr %ptr, i32 %stride
173 %lv.2 = load <6 x double>, ptr %col.ptr.2, align 8
174 %res.1 = fadd <6 x double> %lv.1, %lv.1
175 %res.2 = fadd <6 x double> %lv.2, %lv.2
176 store <6 x double> %res.1, ptr %ptr, align 8
177 store <6 x double> %res.2, ptr %col.ptr.2, align 8
181 declare void @llvm.assume(i1 %cond)
182 declare void @barrier()