Revert rGe6ccb57bb3f6b761f2310e97fd6ca99eff42f73e "[SLP] Add cost model for `llvm...
[llvm-project.git] / llvm / test / Analysis / BasicAA / assume-index-positive.ll
blob6c25b8ac223d2b606e3f320b06faf3b032bd149e
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(double* %ptr, i32 %skip) {
7 ; CHECK-LABEL: Function: test1: 4 pointers, 1 call sites
8 ; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.1, double* %ptr
9 ; CHECK-NEXT:  NoAlias: double* %col.ptr.2, double* %ptr
10 ; CHECK-NEXT:  NoAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2
11 ; CHECK-NEXT:  NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr
12 ; CHECK-NEXT:  NoAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
13 ; CHECK-NEXT:  MustAlias:   double* %col.ptr.2, <6 x double>* %col.ptr.2.cast
14 ; CHECK-NEXT:  NoModRef:  Ptr: double* %ptr <->  call void @llvm.assume(i1 %gt)
15 ; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.1 <->  call void @llvm.assume(i1 %gt)
16 ; CHECK-NEXT:  NoModRef:  Ptr: double* %col.ptr.2   <->  call void @llvm.assume(i1 %gt)
17 ; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.2.cast    <->  call void @llvm.assume(i1 %gt)
19   load double, double* %ptr
20   %gt = icmp sgt i32 %skip, -1
21   call void @llvm.assume(i1 %gt)
22   %stride = add nsw nuw i32 %skip, 6
23   %col.ptr.1 = bitcast double* %ptr to <6 x double>*
24   %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
25   %col.ptr.2= getelementptr double, double* %ptr, i32 %stride
26   %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
27   load double, double* %col.ptr.2
28   %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
29   %res.1 = fadd <6 x double> %lv.1, %lv.1
30   %res.2 = fadd <6 x double> %lv.2, %lv.2
31   store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8
32   store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8
33   ret void
36 ; Same as @test1, but now we do not have an assume guaranteeing %skip >= 0.
37 define void @test2(double* %ptr, i32 %skip) {
38 ; CHECK-LABEL: Function: test2: 4 pointers, 0 call sites
39 ; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.1, double* %ptr
40 ; CHECK-NEXT:  MayAlias:    double* %col.ptr.2, double* %ptr
41 ; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.1, double* %col.ptr.2
42 ; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.2.cast, double* %ptr
43 ; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
44 ; CHECK-NEXT:  MustAlias:   double* %col.ptr.2, <6 x double>* %col.ptr.2.cast
46   load double, double* %ptr
47   %stride = add nsw nuw i32 %skip, 6
48   %col.ptr.1 = bitcast double* %ptr to <6 x double>*
49   %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
50   %col.ptr.2 = getelementptr double, double* %ptr, i32 %stride
51   load double, double* %col.ptr.2
52   %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
53   %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
54   %res.1 = fadd <6 x double> %lv.1, %lv.1
55   %res.2 = fadd <6 x double> %lv.2, %lv.2
56   store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8
57   store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8
58   ret void
61 ; Same as @test1, this time the assume just guarantees %skip > -3, which is
62 ; enough to derive NoAlias for %ptr and %col.ptr.2 (distance is more than 3
63 ; doubles, and we load 1 double), but not %col.ptr.1 and %col.ptr.2 (distance
64 ; is more than 3 doubles, and we load 6 doubles).
65 define void @test3(double* %ptr, i32 %skip) {
66 ; CHECK-LABEL: Function: test3: 4 pointers, 1 call sites
67 ; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.1, double* %ptr
68 ; CHECK-NEXT:  NoAlias:     double* %col.ptr.2, double* %ptr
69 ; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.1, double* %col.ptr.2
70 ; CHECK-NEXT:  NoAlias:     <6 x double>* %col.ptr.2.cast, double* %ptr
71 ; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
72 ; CHECK-NEXT:  MustAlias:   double* %col.ptr.2, <6 x double>* %col.ptr.2.cast
73 ; CHECK-NEXT:  NoModRef:  Ptr: double* %ptr <->  call void @llvm.assume(i1 %gt)
74 ; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.1 <->  call void @llvm.assume(i1 %gt)
75 ; CHECK-NEXT:  NoModRef:  Ptr: double* %col.ptr.2   <->  call void @llvm.assume(i1 %gt)
76 ; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.2.cast    <->  call void @llvm.assume(i1 %gt)
78   load double, double* %ptr
79   %gt = icmp sgt i32 %skip, -3
80   call void @llvm.assume(i1 %gt)
81   %stride = add nsw nuw i32 %skip, 6
82   %col.ptr.1 = bitcast double* %ptr to <6 x double>*
83   %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
84   %col.ptr.2 = getelementptr double, double* %ptr, i32 %stride
85   load double, double* %col.ptr.2
86   %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
87   %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
88   %res.1 = fadd <6 x double> %lv.1, %lv.1
89   %res.2 = fadd <6 x double> %lv.2, %lv.2
90   store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8
91   store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8
92   ret void
95 ; Same as @test1, but the assume uses the sge predicate for %skip >= 0.
96 define void @test4(double* %ptr, i32 %skip) {
97 ; CHECK-LABEL: Function: test4: 4 pointers, 1 call sites
98 ; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.1, double* %ptr
99 ; CHECK-NEXT:  NoAlias:     double* %col.ptr.2, double* %ptr
100 ; CHECK-NEXT:  NoAlias:     <6 x double>* %col.ptr.1, double* %col.ptr.2
101 ; CHECK-NEXT:  NoAlias:     <6 x double>* %col.ptr.2.cast, double* %ptr
102 ; CHECK-NEXT:  NoAlias:     <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
103 ; CHECK-NEXT:  MustAlias:   double* %col.ptr.2, <6 x double>* %col.ptr.2.cast
104 ; CHECK-NEXT:  NoModRef:  Ptr: double* %ptr <->  call void @llvm.assume(i1 %gt)
105 ; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.1 <->  call void @llvm.assume(i1 %gt)
106 ; CHECK-NEXT:  NoModRef:  Ptr: double* %col.ptr.2   <->  call void @llvm.assume(i1 %gt)
107 ; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.2.cast    <->  call void @llvm.assume(i1 %gt)
109   load double, double* %ptr
110   %gt = icmp sge i32 %skip, 0
111   call void @llvm.assume(i1 %gt)
112   %stride = add nsw nuw i32 %skip, 6
113   %col.ptr.1 = bitcast double* %ptr to <6 x double>*
114   %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
115   %col.ptr.2 = getelementptr double, double* %ptr, i32 %stride
116   load double, double* %col.ptr.2
117   %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
118   %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
119   %res.1 = fadd <6 x double> %lv.1, %lv.1
120   %res.2 = fadd <6 x double> %lv.2, %lv.2
121   store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8
122   store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8
123   ret void
126 define void @symmetry([0 x i8]* %ptr, i32 %a, i32 %b, i32 %c) {
127 ; CHECK-LABEL: Function: symmetry
128 ; CHECK: NoAlias: i8* %gep1, i8* %gep2
130   %b.cmp = icmp slt i32 %b, 0
131   call void @llvm.assume(i1 %b.cmp)
132   %gep1 = getelementptr [0 x i8], [0 x i8]* %ptr, i32 %a, i32 %b
133   load i8, i8* %gep1
134   call void @barrier()
135   %c.cmp = icmp sgt i32 %c, -1
136   call void @llvm.assume(i1 %c.cmp)
137   %c.off = add nuw nsw i32 %c, 1
138   %gep2 = getelementptr [0 x i8], [0 x i8]* %ptr, i32 %a, i32 %c.off
139   load i8, i8* %gep2
140   ret void
143 ; %ptr.neg and %ptr.shl may alias, as the shl renders the previously
144 ; non-negative value potentially negative.
145 define void @shl_of_non_negative(i8* %ptr, i64 %a) {
146 ; CHECK-LABEL: Function: shl_of_non_negative
147 ; CHECK: NoAlias: i8* %ptr.a, i8* %ptr.neg
148 ; CHECK: MayAlias: i8* %ptr.neg, i8* %ptr.shl
149   %a.cmp = icmp sge i64 %a, 0
150   call void @llvm.assume(i1 %a.cmp)
151   %ptr.neg = getelementptr i8, i8* %ptr, i64 -2
152   %ptr.a = getelementptr i8, i8* %ptr, i64 %a
153   %shl = shl i64 %a, 1
154   %ptr.shl = getelementptr i8, i8* %ptr, i64 %shl
155   load i8, i8* %ptr.a
156   load i8, i8* %ptr.neg
157   load i8, i8* %ptr.shl
158   ret void
161 ; Unlike the previous case, %ptr.neg and %ptr.shl can't alias, because
162 ; shl nsw of non-negative is non-negative.
163 define void @shl_nsw_of_non_negative(i8* %ptr, i64 %a) {
164 ; CHECK-LABEL: Function: shl_nsw_of_non_negative
165 ; CHECK: NoAlias: i8* %ptr.a, i8* %ptr.neg
166 ; CHECK: NoAlias: i8* %ptr.neg, i8* %ptr.shl
167   %a.cmp = icmp sge i64 %a, 0
168   call void @llvm.assume(i1 %a.cmp)
169   %ptr.neg = getelementptr i8, i8* %ptr, i64 -2
170   %ptr.a = getelementptr i8, i8* %ptr, i64 %a
171   %shl = shl nsw i64 %a, 1
172   %ptr.shl = getelementptr i8, i8* %ptr, i64 %shl
173   load i8, i8* %ptr.a
174   load i8, i8* %ptr.neg
175   load i8, i8* %ptr.shl
176   ret void
179 declare void @llvm.assume(i1 %cond)
180 declare void @barrier()