Add gfx950 mfma instructions to ROCDL dialect (#123361)
[llvm-project.git] / llvm / test / Analysis / LoopAccessAnalysis / nssw-predicate-implied.ll
blobc502c7c1176c0d653fdc2bdd7b6e76f95e2a45fa
1 ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -passes='print<access-info>' %s -disable-output 2>&1 | FileCheck %s
4 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
6 ; {0,+,3} [nssw] implies {0,+,2} [nssw]
7 define void @wrap_check_iv.3_implies_iv.2(i32 noundef %N, ptr %dst, ptr %src) {
8 ; CHECK-LABEL: 'wrap_check_iv.3_implies_iv.2'
9 ; CHECK-NEXT:    loop:
10 ; CHECK-NEXT:      Memory dependences are safe with run-time checks
11 ; CHECK-NEXT:      Dependences:
12 ; CHECK-NEXT:      Run-time memory checks:
13 ; CHECK-NEXT:      Check 0:
14 ; CHECK-NEXT:        Comparing group ([[GRP1:0x[0-9a-f]+]]):
15 ; CHECK-NEXT:          %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
16 ; CHECK-NEXT:        Against group ([[GRP2:0x[0-9a-f]+]]):
17 ; CHECK-NEXT:          %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
18 ; CHECK-NEXT:      Grouped accesses:
19 ; CHECK-NEXT:        Group [[GRP1]]:
20 ; CHECK-NEXT:          (Low: %dst High: (4 + (12 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst))
21 ; CHECK-NEXT:            Member: {%dst,+,12}<%loop>
22 ; CHECK-NEXT:        Group [[GRP2]]:
23 ; CHECK-NEXT:          (Low: %src High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src))
24 ; CHECK-NEXT:            Member: {%src,+,8}<%loop>
25 ; CHECK-EMPTY:
26 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
27 ; CHECK-NEXT:      SCEV assumptions:
28 ; CHECK-NEXT:      {0,+,3}<%loop> Added Flags: <nssw>
29 ; CHECK-EMPTY:
30 ; CHECK-NEXT:      Expressions re-written:
31 ; CHECK-NEXT:      [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2:
32 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %src)
33 ; CHECK-NEXT:        --> {%src,+,8}<%loop>
34 ; CHECK-NEXT:      [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3:
35 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,3}<%loop> to i64))<nsw> + %dst)
36 ; CHECK-NEXT:        --> {%dst,+,12}<%loop>
38 entry:
39   br label %loop
41 loop:
42   %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ]
43   %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ]
44   %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ]
45   %ext.iv.2 = sext i32 %iv.2 to i64
46   %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
47   %l = load i32, ptr %gep.iv.2, align 4
48   %ext.iv.3 = sext i32 %iv.3 to i64
49   %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
50   store i32 %l, ptr %gep.iv.3, align 4
51   %iv.1.next = add nuw nsw i32 %iv.1, 1
52   %iv.2.next = add i32 %iv.2, 2
53   %iv.3.next = add i32 %iv.3, 3
54   %ec = icmp eq i32 %iv.1.next, %N
55   br i1 %ec, label %exit, label %loop
57 exit:
58   ret void
61 ; {2,+,2} [nssw]  implies {0,+,2} [nssw].
62 define void @wrap_check_iv.3_implies_iv.2_different_start(i32 noundef %N, ptr %dst, ptr %src) {
63 ; CHECK-LABEL: 'wrap_check_iv.3_implies_iv.2_different_start'
64 ; CHECK-NEXT:    loop:
65 ; CHECK-NEXT:      Memory dependences are safe with run-time checks
66 ; CHECK-NEXT:      Dependences:
67 ; CHECK-NEXT:      Run-time memory checks:
68 ; CHECK-NEXT:      Check 0:
69 ; CHECK-NEXT:        Comparing group ([[GRP3:0x[0-9a-f]+]]):
70 ; CHECK-NEXT:          %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
71 ; CHECK-NEXT:        Against group ([[GRP4:0x[0-9a-f]+]]):
72 ; CHECK-NEXT:          %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
73 ; CHECK-NEXT:      Grouped accesses:
74 ; CHECK-NEXT:        Group [[GRP3]]:
75 ; CHECK-NEXT:          (Low: (12 + %dst) High: (16 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst))
76 ; CHECK-NEXT:            Member: {(12 + %dst),+,8}<%loop>
77 ; CHECK-NEXT:        Group [[GRP4]]:
78 ; CHECK-NEXT:          (Low: %src High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src))
79 ; CHECK-NEXT:            Member: {%src,+,8}<%loop>
80 ; CHECK-EMPTY:
81 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
82 ; CHECK-NEXT:      SCEV assumptions:
83 ; CHECK-NEXT:      {2,+,2}<%loop> Added Flags: <nssw>
84 ; CHECK-EMPTY:
85 ; CHECK-NEXT:      Expressions re-written:
86 ; CHECK-NEXT:      [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2:
87 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %src)
88 ; CHECK-NEXT:        --> {%src,+,8}<%loop>
89 ; CHECK-NEXT:      [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3:
90 ; CHECK-NEXT:        (4 + (4 * (sext i32 {2,+,2}<%loop> to i64))<nsw> + %dst)
91 ; CHECK-NEXT:        --> {(12 + %dst),+,8}<%loop>
93 entry:
94   br label %loop
96 loop:
97   %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ]
98   %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ]
99   %iv.3 = phi i32 [ 3, %entry ], [ %iv.3.next, %loop ]
100   %ext.iv.2 = sext i32 %iv.2 to i64
101   %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
102   %l = load i32, ptr %gep.iv.2, align 4
103   %ext.iv.3 = sext i32 %iv.3 to i64
104   %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
105   store i32 %l, ptr %gep.iv.3, align 4
106   %iv.1.next = add nuw nsw i32 %iv.1, 1
107   %iv.2.next = add i32 %iv.2, 2
108   %iv.3.next = add i32 %iv.3, 2
109   %ec = icmp eq i32 %iv.1.next, %N
110   br i1 %ec, label %exit, label %loop
112 exit:
113   ret void
116 ; {0,+,3} [nssw] implies {0,+,2} [nssw].
117 define void @wrap_check_iv.3_implies_iv.2_predicates_added_in_different_order(i32 noundef %N, ptr %dst, ptr %src) {
118 ; CHECK-LABEL: 'wrap_check_iv.3_implies_iv.2_predicates_added_in_different_order'
119 ; CHECK-NEXT:    loop:
120 ; CHECK-NEXT:      Memory dependences are safe with run-time checks
121 ; CHECK-NEXT:      Dependences:
122 ; CHECK-NEXT:      Run-time memory checks:
123 ; CHECK-NEXT:      Check 0:
124 ; CHECK-NEXT:        Comparing group ([[GRP5:0x[0-9a-f]+]]):
125 ; CHECK-NEXT:          %gep.iv.2 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.2
126 ; CHECK-NEXT:        Against group ([[GRP6:0x[0-9a-f]+]]):
127 ; CHECK-NEXT:          %gep.iv.3 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.3
128 ; CHECK-NEXT:      Grouped accesses:
129 ; CHECK-NEXT:        Group [[GRP5]]:
130 ; CHECK-NEXT:          (Low: %dst High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst))
131 ; CHECK-NEXT:            Member: {%dst,+,8}<%loop>
132 ; CHECK-NEXT:        Group [[GRP6]]:
133 ; CHECK-NEXT:          (Low: %src High: (4 + (12 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src))
134 ; CHECK-NEXT:            Member: {%src,+,12}<%loop>
135 ; CHECK-EMPTY:
136 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
137 ; CHECK-NEXT:      SCEV assumptions:
138 ; CHECK-NEXT:      {0,+,3}<%loop> Added Flags: <nssw>
139 ; CHECK-EMPTY:
140 ; CHECK-NEXT:      Expressions re-written:
141 ; CHECK-NEXT:      [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.3:
142 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,3}<%loop> to i64))<nsw> + %src)
143 ; CHECK-NEXT:        --> {%src,+,12}<%loop>
144 ; CHECK-NEXT:      [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.2:
145 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %dst)
146 ; CHECK-NEXT:        --> {%dst,+,8}<%loop>
148 entry:
149   br label %loop
151 loop:
152   %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ]
153   %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ]
154   %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ]
155   %ext.iv.3 = sext i32 %iv.3 to i64
156   %gep.iv.3 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.3
157   %l = load i32, ptr %gep.iv.3, align 4
158   %ext.iv.2 = sext i32 %iv.2 to i64
159   %gep.iv.2 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.2
160   store i32 %l, ptr %gep.iv.2, align 4
161   %iv.1.next = add nuw nsw i32 %iv.1, 1
162   %iv.2.next = add i32 %iv.2, 2
163   %iv.3.next = add i32 %iv.3, 3
164   %ec = icmp eq i32 %iv.1.next, %N
165   br i1 %ec, label %exit, label %loop
167 exit:
168   ret void
171 define void @wrap_check_iv.3_does_not_implies_iv.2_due_to_start(i32 noundef %N, ptr %dst, ptr %src) {
172 ; CHECK-LABEL: 'wrap_check_iv.3_does_not_implies_iv.2_due_to_start'
173 ; CHECK-NEXT:    loop:
174 ; CHECK-NEXT:      Memory dependences are safe with run-time checks
175 ; CHECK-NEXT:      Dependences:
176 ; CHECK-NEXT:      Run-time memory checks:
177 ; CHECK-NEXT:      Check 0:
178 ; CHECK-NEXT:        Comparing group ([[GRP7:0x[0-9a-f]+]]):
179 ; CHECK-NEXT:          %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
180 ; CHECK-NEXT:        Against group ([[GRP8:0x[0-9a-f]+]]):
181 ; CHECK-NEXT:          %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
182 ; CHECK-NEXT:      Grouped accesses:
183 ; CHECK-NEXT:        Group [[GRP7]]:
184 ; CHECK-NEXT:          (Low: %dst High: (4 + (12 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst))
185 ; CHECK-NEXT:            Member: {%dst,+,12}<%loop>
186 ; CHECK-NEXT:        Group [[GRP8]]:
187 ; CHECK-NEXT:          (Low: (40 + %src) High: (44 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src))
188 ; CHECK-NEXT:            Member: {(40 + %src),+,8}<%loop>
189 ; CHECK-EMPTY:
190 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
191 ; CHECK-NEXT:      SCEV assumptions:
192 ; CHECK-NEXT:      {0,+,3}<%loop> Added Flags: <nssw>
193 ; CHECK-NEXT:      {10,+,2}<%loop> Added Flags: <nssw>
194 ; CHECK-EMPTY:
195 ; CHECK-NEXT:      Expressions re-written:
196 ; CHECK-NEXT:      [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2:
197 ; CHECK-NEXT:        ((4 * (sext i32 {10,+,2}<%loop> to i64))<nsw> + %src)
198 ; CHECK-NEXT:        --> {(40 + %src),+,8}<%loop>
199 ; CHECK-NEXT:      [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3:
200 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,3}<%loop> to i64))<nsw> + %dst)
201 ; CHECK-NEXT:        --> {%dst,+,12}<%loop>
203 entry:
204   br label %loop
206 loop:
207   %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ]
208   %iv.2 = phi i32 [ 10, %entry ], [ %iv.2.next, %loop ]
209   %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ]
210   %ext.iv.2 = sext i32 %iv.2 to i64
211   %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
212   %l = load i32, ptr %gep.iv.2, align 4
213   %ext.iv.3 = sext i32 %iv.3 to i64
214   %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
215   store i32 %l, ptr %gep.iv.3, align 4
216   %iv.1.next = add nuw nsw i32 %iv.1, 1
217   %iv.2.next = add i32 %iv.2, 2
218   %iv.3.next = add i32 %iv.3, 3
219   %ec = icmp eq i32 %iv.1.next, %N
220   br i1 %ec, label %exit, label %loop
222 exit:
223   ret void
226 define void @wrap_check_iv.3_does_not_imply_iv.2_due_to_start_negative(i32 noundef %N, ptr %dst, ptr %src) {
227 ; CHECK-LABEL: 'wrap_check_iv.3_does_not_imply_iv.2_due_to_start_negative'
228 ; CHECK-NEXT:    loop:
229 ; CHECK-NEXT:      Memory dependences are safe with run-time checks
230 ; CHECK-NEXT:      Dependences:
231 ; CHECK-NEXT:      Run-time memory checks:
232 ; CHECK-NEXT:      Check 0:
233 ; CHECK-NEXT:        Comparing group ([[GRP9:0x[0-9a-f]+]]):
234 ; CHECK-NEXT:          %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
235 ; CHECK-NEXT:        Against group ([[GRP10:0x[0-9a-f]+]]):
236 ; CHECK-NEXT:          %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
237 ; CHECK-NEXT:      Grouped accesses:
238 ; CHECK-NEXT:        Group [[GRP9]]:
239 ; CHECK-NEXT:          (Low: (-4 + %dst) High: ((12 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %dst))
240 ; CHECK-NEXT:            Member: {(-4 + %dst),+,12}<%loop>
241 ; CHECK-NEXT:        Group [[GRP10]]:
242 ; CHECK-NEXT:          (Low: %src High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src))
243 ; CHECK-NEXT:            Member: {%src,+,8}<%loop>
244 ; CHECK-EMPTY:
245 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
246 ; CHECK-NEXT:      SCEV assumptions:
247 ; CHECK-NEXT:      {-1,+,3}<%loop> Added Flags: <nssw>
248 ; CHECK-NEXT:      {0,+,2}<%loop> Added Flags: <nssw>
249 ; CHECK-EMPTY:
250 ; CHECK-NEXT:      Expressions re-written:
251 ; CHECK-NEXT:      [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2:
252 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %src)
253 ; CHECK-NEXT:        --> {%src,+,8}<%loop>
254 ; CHECK-NEXT:      [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3:
255 ; CHECK-NEXT:        ((4 * (sext i32 {-1,+,3}<%loop> to i64))<nsw> + %dst)
256 ; CHECK-NEXT:        --> {(-4 + %dst),+,12}<%loop>
258 entry:
259   br label %loop
261 loop:
262   %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ]
263   %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ]
264   %iv.3 = phi i32 [ -1, %entry ], [ %iv.3.next, %loop ]
265   %ext.iv.2 = sext i32 %iv.2 to i64
266   %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
267   %l = load i32, ptr %gep.iv.2, align 4
268   %ext.iv.3 = sext i32 %iv.3 to i64
269   %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
270   store i32 %l, ptr %gep.iv.3, align 4
271   %iv.1.next = add nuw nsw i32 %iv.1, 1
272   %iv.2.next = add i32 %iv.2, 2
273   %iv.3.next = add i32 %iv.3, 3
274   %ec = icmp eq i32 %iv.1.next, %N
275   br i1 %ec, label %exit, label %loop
277 exit:
278   ret void
281 define void @wrap_check_iv.3_does_not_imply_iv.2_due_to_negative_step(i32 noundef %N, ptr %dst, ptr %src) {
282 ; CHECK-LABEL: 'wrap_check_iv.3_does_not_imply_iv.2_due_to_negative_step'
283 ; CHECK-NEXT:    loop:
284 ; CHECK-NEXT:      Memory dependences are safe with run-time checks
285 ; CHECK-NEXT:      Dependences:
286 ; CHECK-NEXT:      Run-time memory checks:
287 ; CHECK-NEXT:      Check 0:
288 ; CHECK-NEXT:        Comparing group ([[GRP11:0x[0-9a-f]+]]):
289 ; CHECK-NEXT:          %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
290 ; CHECK-NEXT:        Against group ([[GRP12:0x[0-9a-f]+]]):
291 ; CHECK-NEXT:          %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
292 ; CHECK-NEXT:      Grouped accesses:
293 ; CHECK-NEXT:        Group [[GRP11]]:
294 ; CHECK-NEXT:          (Low: ((-4 * (zext i32 (-1 + %N) to i64))<nsw> + %dst) High: (4 + %dst))
295 ; CHECK-NEXT:            Member: {%dst,+,-4}<%loop>
296 ; CHECK-NEXT:        Group [[GRP12]]:
297 ; CHECK-NEXT:          (Low: %src High: (4 + (8 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %src))
298 ; CHECK-NEXT:            Member: {%src,+,8}<%loop>
299 ; CHECK-EMPTY:
300 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
301 ; CHECK-NEXT:      SCEV assumptions:
302 ; CHECK-NEXT:      {0,+,-1}<%loop> Added Flags: <nssw>
303 ; CHECK-NEXT:      {0,+,2}<%loop> Added Flags: <nssw>
304 ; CHECK-EMPTY:
305 ; CHECK-NEXT:      Expressions re-written:
306 ; CHECK-NEXT:      [PSE] %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2:
307 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,2}<%loop> to i64))<nsw> + %src)
308 ; CHECK-NEXT:        --> {%src,+,8}<%loop>
309 ; CHECK-NEXT:      [PSE] %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3:
310 ; CHECK-NEXT:        ((4 * (sext i32 {0,+,-1}<%loop> to i64))<nsw> + %dst)
311 ; CHECK-NEXT:        --> {%dst,+,-4}<%loop>
313 entry:
314   br label %loop
316 loop:
317   %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop ]
318   %iv.2 = phi i32 [ 0, %entry ], [ %iv.2.next, %loop ]
319   %iv.3 = phi i32 [ 0, %entry ], [ %iv.3.next, %loop ]
320   %ext.iv.2 = sext i32 %iv.2 to i64
321   %gep.iv.2 = getelementptr inbounds i32, ptr %src, i64 %ext.iv.2
322   %l = load i32, ptr %gep.iv.2, align 4
323   %ext.iv.3 = sext i32 %iv.3 to i64
324   %gep.iv.3 = getelementptr inbounds i32, ptr %dst, i64 %ext.iv.3
325   store i32 %l, ptr %gep.iv.3, align 4
326   %iv.1.next = add nuw nsw i32 %iv.1, 1
327   %iv.2.next = add i32 %iv.2, 2
328   %iv.3.next = add i32 %iv.3, -1
329   %ec = icmp eq i32 %iv.1.next, %N
330   br i1 %ec, label %exit, label %loop
332 exit:
333   ret void