xref: /llvm-project/llvm/test/Analysis/LoopAccessAnalysis/nssw-predicate-implied.ll (revision df8efbdbbfcde53b0f9f4f8ceb16b50eecd6e6d3)
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
3
4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
5
6; {0,+,3} [nssw] implies {0,+,2} [nssw]
7define 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>
37;
38entry:
39  br label %loop
40
41loop:
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
56
57exit:
58  ret void
59}
60
61; {2,+,2} [nssw]  implies {0,+,2} [nssw].
62define 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>
92;
93entry:
94  br label %loop
95
96loop:
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
111
112exit:
113  ret void
114}
115
116; {0,+,3} [nssw] implies {0,+,2} [nssw].
117define 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>
147;
148entry:
149  br label %loop
150
151loop:
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
166
167exit:
168  ret void
169}
170
171define 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>
202;
203entry:
204  br label %loop
205
206loop:
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
221
222exit:
223  ret void
224}
225
226define 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>
257;
258entry:
259  br label %loop
260
261loop:
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
276
277exit:
278  ret void
279}
280
281define 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>
312;
313entry:
314  br label %loop
315
316loop:
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
331
332exit:
333  ret void
334}
335