xref: /llvm-project/llvm/test/Analysis/LoopAccessAnalysis/offset-range-known-via-assume.ll (revision f719cfa8685a30a3f4115cc0ce446262daf81244)
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
3
4target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
5
6declare void @llvm.assume(i1)
7
8declare void @use(ptr noundef)
9
10; %offset is known positive via assume, so we should be able to detect the
11; forward dependence.
12define void @offset_i8_known_positive_via_assume_forward_dep_1(ptr %A, i64 %offset, i64 %N) {
13; CHECK-LABEL: 'offset_i8_known_positive_via_assume_forward_dep_1'
14; CHECK-NEXT:    loop:
15; CHECK-NEXT:      Memory dependences are safe
16; CHECK-NEXT:      Dependences:
17; CHECK-NEXT:        Forward:
18; CHECK-NEXT:            %l = load i8, ptr %gep.off, align 4 ->
19; CHECK-NEXT:            store i8 %add, ptr %gep, align 4
20; CHECK-EMPTY:
21; CHECK-NEXT:      Run-time memory checks:
22; CHECK-NEXT:      Grouped accesses:
23; CHECK-EMPTY:
24; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
25; CHECK-NEXT:      SCEV assumptions:
26; CHECK-EMPTY:
27; CHECK-NEXT:      Expressions re-written:
28;
29entry:
30  %c = icmp sgt i64 %offset, 0
31  call void @llvm.assume(i1 %c)
32  %off = getelementptr inbounds i8, ptr %A, i64 %offset
33  call void @use(ptr noundef %off)
34  br label %loop
35
36loop:
37  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
38  %gep.off = getelementptr inbounds i8, ptr %off, i64 %iv
39  %l = load i8 , ptr %gep.off, align 4
40  %add = add nsw i8 %l, 5
41  %gep = getelementptr inbounds i8, ptr %A, i64 %iv
42  store i8 %add, ptr %gep, align 4
43  %iv.next = add nuw nsw i64 %iv, 1
44  %exitcond.not = icmp eq i64 %iv.next, %N
45  br i1 %exitcond.not, label %exit, label %loop
46
47exit:
48  ret void
49}
50
51define void @offset_i32_known_positive_via_assume_forward_dep_1(ptr %A, i64 %offset, i64 %N) {
52; CHECK-LABEL: 'offset_i32_known_positive_via_assume_forward_dep_1'
53; CHECK-NEXT:    loop:
54; CHECK-NEXT:      Memory dependences are safe with run-time checks
55; CHECK-NEXT:      Dependences:
56; CHECK-NEXT:      Run-time memory checks:
57; CHECK-NEXT:      Check 0:
58; CHECK-NEXT:        Comparing group ([[GRP1:0x[0-9a-f]+]]):
59; CHECK-NEXT:          %gep = getelementptr inbounds i32, ptr %A, i64 %iv
60; CHECK-NEXT:        Against group ([[GRP2:0x[0-9a-f]+]]):
61; CHECK-NEXT:          %gep.off = getelementptr inbounds i32, ptr %off, i64 %iv
62; CHECK-NEXT:      Grouped accesses:
63; CHECK-NEXT:        Group [[GRP1]]:
64; CHECK-NEXT:          (Low: %A High: (-3 + (4 * %N) + %A))
65; CHECK-NEXT:            Member: {%A,+,4}<nuw><%loop>
66; CHECK-NEXT:        Group [[GRP2]]:
67; CHECK-NEXT:          (Low: ((4 * %offset)<nsw> + %A) High: (-3 + (4 * %offset)<nsw> + (4 * %N) + %A))
68; CHECK-NEXT:            Member: {((4 * %offset)<nsw> + %A),+,4}<nw><%loop>
69; CHECK-EMPTY:
70; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
71; CHECK-NEXT:      SCEV assumptions:
72; CHECK-EMPTY:
73; CHECK-NEXT:      Expressions re-written:
74;
75entry:
76  %c = icmp sgt i64 %offset, 0
77  call void @llvm.assume(i1 %c)
78  %off = getelementptr inbounds i32, ptr %A, i64 %offset
79  call void @use(ptr noundef %off)
80
81  br label %loop
82
83loop:
84  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
85  %gep.off = getelementptr inbounds i32, ptr %off, i64 %iv
86  %l = load i8 , ptr %gep.off, align 4
87  %add = add nsw i8 %l, 5
88  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
89  store i8 %add, ptr %gep, align 4
90  %iv.next = add nuw nsw i64 %iv, 1
91  %exitcond.not = icmp eq i64 %iv.next, %N
92  br i1 %exitcond.not, label %exit, label %loop
93
94exit:
95  ret void
96}
97
98; %offset is known positive via assume, so we should be able to detect the
99; forward dependence.
100define void @offset_known_positive_via_assume_forward_dep_2(ptr %A, i64 %offset, i64 %N) {
101; CHECK-LABEL: 'offset_known_positive_via_assume_forward_dep_2'
102; CHECK-NEXT:    loop:
103; CHECK-NEXT:      Memory dependences are safe
104; CHECK-NEXT:      Dependences:
105; CHECK-NEXT:        Forward:
106; CHECK-NEXT:            %l = load i32, ptr %gep.off, align 4 ->
107; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
108; CHECK-EMPTY:
109; CHECK-NEXT:      Run-time memory checks:
110; CHECK-NEXT:      Grouped accesses:
111; CHECK-EMPTY:
112; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
113; CHECK-NEXT:      SCEV assumptions:
114; CHECK-EMPTY:
115; CHECK-NEXT:      Expressions re-written:
116;
117entry:
118  %c = icmp sgt i64 %offset, 0
119  call void @llvm.assume(i1 %c)
120  %c.2 = icmp slt i64 %offset, 20
121  call void @llvm.assume(i1 %c.2)
122  %off = getelementptr inbounds i32, ptr %A, i64 %offset
123  br label %loop
124
125loop:
126  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
127  %gep.off = getelementptr inbounds i32, ptr %off, i64 %iv
128  %l = load i32, ptr %gep.off, align 4
129  %add = add nsw i32 %l, 5
130  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
131  store i32 %add, ptr %gep, align 4
132  %iv.next = add nuw nsw i64 %iv, 1
133  %exitcond.not = icmp eq i64 %iv.next, %N
134  br i1 %exitcond.not, label %exit, label %loop
135
136exit:
137  ret void
138}
139
140; The range of %offset is known via assumes, but it may be positive or negative.
141define void @offset_may_be_negative_via_assume_unknown_dep(ptr %A, i64 %offset, i64 %N) {
142; CHECK-LABEL: 'offset_may_be_negative_via_assume_unknown_dep'
143; CHECK-NEXT:    loop:
144; CHECK-NEXT:      Memory dependences are safe with run-time checks
145; CHECK-NEXT:      Dependences:
146; CHECK-NEXT:      Run-time memory checks:
147; CHECK-NEXT:      Check 0:
148; CHECK-NEXT:        Comparing group ([[GRP3:0x[0-9a-f]+]]):
149; CHECK-NEXT:          %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv
150; CHECK-NEXT:        Against group ([[GRP4:0x[0-9a-f]+]]):
151; CHECK-NEXT:          %gep = getelementptr inbounds i32, ptr %off, i64 %iv
152; CHECK-NEXT:      Grouped accesses:
153; CHECK-NEXT:        Group [[GRP3]]:
154; CHECK-NEXT:          (Low: %A High: ((4 * %N) + %A))
155; CHECK-NEXT:            Member: {%A,+,4}<nuw><%loop>
156; CHECK-NEXT:        Group [[GRP4]]:
157; CHECK-NEXT:          (Low: ((4 * %offset)<nsw> + %A) High: ((4 * %offset)<nsw> + (4 * %N) + %A))
158; CHECK-NEXT:            Member: {((4 * %offset)<nsw> + %A),+,4}<nw><%loop>
159; CHECK-EMPTY:
160; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
161; CHECK-NEXT:      SCEV assumptions:
162; CHECK-EMPTY:
163; CHECK-NEXT:      Expressions re-written:
164;
165entry:
166  %c = icmp sgt i64 %offset, -4
167  call void @llvm.assume(i1 %c)
168  %c.2 = icmp slt i64 %offset, 20
169  call void @llvm.assume(i1 %c.2)
170  %off = getelementptr inbounds i32, ptr %A, i64 %offset
171  br label %loop
172
173loop:
174  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
175  %gep = getelementptr inbounds i32, ptr %off, i64 %iv
176  %l = load i32, ptr %gep, align 4
177  %add = add nsw i32 %l, 5
178  %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv
179  store i32 %add, ptr %gep.mul.2, align 4
180  %iv.next = add nuw nsw i64 %iv, 1
181  %exitcond.not = icmp eq i64 %iv.next, %N
182  br i1 %exitcond.not, label %exit, label %loop
183
184exit:
185  ret void
186}
187
188define void @offset_no_assumes(ptr %A, i64 %offset, i64 %N) {
189; CHECK-LABEL: 'offset_no_assumes'
190; CHECK-NEXT:    loop:
191; CHECK-NEXT:      Memory dependences are safe with run-time checks
192; CHECK-NEXT:      Dependences:
193; CHECK-NEXT:      Run-time memory checks:
194; CHECK-NEXT:      Check 0:
195; CHECK-NEXT:        Comparing group ([[GRP5:0x[0-9a-f]+]]):
196; CHECK-NEXT:          %gep = getelementptr inbounds i32, ptr %A, i64 %iv
197; CHECK-NEXT:        Against group ([[GRP6:0x[0-9a-f]+]]):
198; CHECK-NEXT:          %gep.off = getelementptr inbounds i32, ptr %off, i64 %iv
199; CHECK-NEXT:      Grouped accesses:
200; CHECK-NEXT:        Group [[GRP5]]:
201; CHECK-NEXT:          (Low: %A High: ((4 * %N) + %A))
202; CHECK-NEXT:            Member: {%A,+,4}<nuw><%loop>
203; CHECK-NEXT:        Group [[GRP6]]:
204; CHECK-NEXT:          (Low: ((4 * %offset)<nsw> + %A) High: ((4 * %offset)<nsw> + (4 * %N) + %A))
205; CHECK-NEXT:            Member: {((4 * %offset)<nsw> + %A),+,4}<nw><%loop>
206; CHECK-EMPTY:
207; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
208; CHECK-NEXT:      SCEV assumptions:
209; CHECK-EMPTY:
210; CHECK-NEXT:      Expressions re-written:
211;
212entry:
213  %off = getelementptr inbounds i32, ptr %A, i64 %offset
214  br label %loop
215
216loop:
217  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
218  %gep.off = getelementptr inbounds i32, ptr %off, i64 %iv
219  %l = load i32, ptr %gep.off, align 4
220  %add = add nsw i32 %l, 5
221  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
222  store i32 %add, ptr %gep, align 4
223  %iv.next = add nuw nsw i64 %iv, 1
224  %exitcond.not = icmp eq i64 %iv.next, %N
225  br i1 %exitcond.not, label %exit, label %loop
226
227exit:
228  ret void
229}
230