[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Analysis / BasicAA / assume-index-positive.ll
blob3402886a06f0071c7c317771b70dc55e495d0aca
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
5 ; elements.
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
20   ret void
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
36   ret void
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
57   ret void
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
75   ret void
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
85   load i8, ptr %gep1
86   call void @barrier()
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
91   load i8, ptr %gep2
92   ret void
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
106   %shl = shl i64 %a, 1
107   %ptr.shl = getelementptr i8, ptr %ptr, i64 %shl
108   load i8, ptr %ptr.a
109   load i8, ptr %ptr.neg
110   load i8, ptr %ptr.shl
111   ret void
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
127   load i8, ptr %ptr.a
128   load i8, ptr %ptr.neg
129   load i8, ptr %ptr.shl
130   ret void
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
146   ret void
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
162   ret void
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
178   ret void
181 declare void @llvm.assume(i1 %cond)
182 declare void @barrier()