xref: /llvm-project/llvm/test/Transforms/LoopStrengthReduce/post-increment-insertion.ll (revision e7f4ad13ae57f7a5170cd9caab3b1253d444c2f5)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -loop-reduce -S | FileCheck %s
3; REQUIRES: x86-registered-target
4
5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
6target triple = "x86_64-unknown-linux-gnu"
7
8; FIXME: iv.next is supposed to be inserted in the backedge.
9define i32 @test_01(ptr %p, i64 %len, i32 %x) {
10; CHECK-LABEL: @test_01(
11; CHECK-NEXT:  entry:
12; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 -4
13; CHECK-NEXT:    br label [[LOOP:%.*]]
14; CHECK:       loop:
15; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ]
16; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[IV]], 0
17; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
18; CHECK:       backedge:
19; CHECK-NEXT:    [[TMP0:%.*]] = shl i64 [[IV]], 2
20; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 [[TMP0]]
21; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SCEVGEP1]] unordered, align 4
22; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
23; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], -1
24; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
25; CHECK:       exit:
26; CHECK-NEXT:    ret i32 -1
27; CHECK:       failure:
28; CHECK-NEXT:    unreachable
29;
30entry:
31  br label %loop
32
33loop:                                             ; preds = %backedge, %entry
34  %iv = phi i64 [ %iv.next, %backedge ], [ %len, %entry ]
35  %iv.next = add nsw i64 %iv, -1
36  %cond_1 = icmp eq i64 %iv, 0
37  br i1 %cond_1, label %exit, label %backedge
38
39backedge:                                         ; preds = %loop
40  %addr = getelementptr inbounds i32, ptr %p, i64 %iv.next
41  %loaded = load atomic i32, ptr %addr unordered, align 4
42  %cond_2 = icmp eq i32 %loaded, %x
43  br i1 %cond_2, label %failure, label %loop
44
45exit:                                             ; preds = %loop
46  ret i32 -1
47
48failure:                                          ; preds = %backedge
49  unreachable
50}
51
52define i32 @test_02(ptr %p, i64 %len, i32 %x) {
53; CHECK-LABEL: @test_02(
54; CHECK-NEXT:  entry:
55; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 -4
56; CHECK-NEXT:    br label [[LOOP:%.*]]
57; CHECK:       loop:
58; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ]
59; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[LSR_IV]], 0
60; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
61; CHECK:       backedge:
62; CHECK-NEXT:    [[TMP0:%.*]] = shl i64 [[LSR_IV]], 2
63; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 [[TMP0]]
64; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SCEVGEP1]] unordered, align 4
65; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
66; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -1
67; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
68; CHECK:       exit:
69; CHECK-NEXT:    ret i32 -1
70; CHECK:       failure:
71; CHECK-NEXT:    unreachable
72;
73entry:
74  %start = add i64 %len, -1
75  br label %loop
76
77loop:                                             ; preds = %backedge, %entry
78  %iv = phi i64 [ %iv.next, %backedge ], [ %start, %entry ]
79  %iv.next = add nsw i64 %iv, -1
80  %iv.offset = add i64 %iv, 1
81  %iv.next.offset = add i64 %iv.next, 1
82  %cond_1 = icmp eq i64 %iv.offset, 0
83  br i1 %cond_1, label %exit, label %backedge
84
85backedge:                                         ; preds = %loop
86  %addr = getelementptr inbounds i32, ptr %p, i64 %iv.next.offset
87  %loaded = load atomic i32, ptr %addr unordered, align 4
88  %cond_2 = icmp eq i32 %loaded, %x
89  br i1 %cond_2, label %failure, label %loop
90
91exit:                                             ; preds = %loop
92  ret i32 -1
93
94failure:                                          ; preds = %backedge
95  unreachable
96}
97
98define i32 @test_03(ptr %p, i64 %len, i32 %x) {
99; CHECK-LABEL: @test_03(
100; CHECK-NEXT:  entry:
101; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 -4
102; CHECK-NEXT:    br label [[LOOP:%.*]]
103; CHECK:       loop:
104; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ]
105; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[LSR_IV]], 0
106; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
107; CHECK:       backedge:
108; CHECK-NEXT:    [[TMP0:%.*]] = shl i64 [[LSR_IV]], 2
109; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 [[TMP0]]
110; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SCEVGEP1]] unordered, align 4
111; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
112; CHECK-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -1
113; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
114; CHECK:       exit:
115; CHECK-NEXT:    ret i32 -1
116; CHECK:       failure:
117; CHECK-NEXT:    unreachable
118;
119entry:
120  %start = add i64 %len, -100
121  br label %loop
122
123loop:                                             ; preds = %backedge, %entry
124  %iv = phi i64 [ %iv.next, %backedge ], [ %start, %entry ]
125  %iv.next = add nsw i64 %iv, -1
126  %iv.offset = add i64 %iv, 100
127  %iv.next.offset = add i64 %iv.next, 100
128  %cond_1 = icmp eq i64 %iv.offset, 0
129  br i1 %cond_1, label %exit, label %backedge
130
131backedge:                                         ; preds = %loop
132  %addr = getelementptr inbounds i32, ptr %p, i64 %iv.next.offset
133  %loaded = load atomic i32, ptr %addr unordered, align 4
134  %cond_2 = icmp eq i32 %loaded, %x
135  br i1 %cond_2, label %failure, label %loop
136
137exit:                                             ; preds = %loop
138  ret i32 -1
139
140failure:                                          ; preds = %backedge
141  unreachable
142}
143
144define i32 @test_04(ptr %p, i64 %len, i32 %x) {
145; CHECK-LABEL: @test_04(
146; CHECK-NEXT:  entry:
147; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 -4
148; CHECK-NEXT:    br label [[LOOP:%.*]]
149; CHECK:       loop:
150; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ]
151; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[IV]], 0
152; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
153; CHECK:       backedge:
154; CHECK-NEXT:    [[TMP0:%.*]] = shl i64 [[IV]], 2
155; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 [[TMP0]]
156; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SCEVGEP1]] unordered, align 4
157; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
158; CHECK-NEXT:    [[IV_NEXT]] = sub i64 [[IV]], 1
159; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
160; CHECK:       exit:
161; CHECK-NEXT:    ret i32 -1
162; CHECK:       failure:
163; CHECK-NEXT:    unreachable
164;
165entry:
166  br label %loop
167
168loop:                                             ; preds = %backedge, %entry
169  %iv = phi i64 [ %iv.next, %backedge ], [ %len, %entry ]
170  %iv.next = sub i64 %iv, 1
171  %cond_1 = icmp eq i64 %iv, 0
172  br i1 %cond_1, label %exit, label %backedge
173
174backedge:                                         ; preds = %loop
175  %addr = getelementptr inbounds i32, ptr %p, i64 %iv.next
176  %loaded = load atomic i32, ptr %addr unordered, align 4
177  %cond_2 = icmp eq i32 %loaded, %x
178  br i1 %cond_2, label %failure, label %loop
179
180exit:                                             ; preds = %loop
181  ret i32 -1
182
183failure:                                          ; preds = %backedge
184  unreachable
185}
186
187define i32 @test_05(ptr %p, i64 %len, i32 %x) {
188; CHECK-LABEL: @test_05(
189; CHECK-NEXT:  entry:
190; CHECK-NEXT:    br label [[LOOP:%.*]]
191; CHECK:       loop:
192; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ]
193; CHECK-NEXT:    [[IV_NEXT]] = mul i64 [[IV]], 2
194; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[IV]], 0
195; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
196; CHECK:       backedge:
197; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[IV_NEXT]]
198; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[ADDR]] unordered, align 4
199; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
200; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
201; CHECK:       exit:
202; CHECK-NEXT:    ret i32 -1
203; CHECK:       failure:
204; CHECK-NEXT:    unreachable
205;
206entry:
207  br label %loop
208
209loop:                                             ; preds = %backedge, %entry
210  %iv = phi i64 [ %iv.next, %backedge ], [ %len, %entry ]
211  %iv.next = mul i64 %iv, 2
212  %cond_1 = icmp eq i64 %iv, 0
213  br i1 %cond_1, label %exit, label %backedge
214
215backedge:                                         ; preds = %loop
216  %addr = getelementptr inbounds i32, ptr %p, i64 %iv.next
217  %loaded = load atomic i32, ptr %addr unordered, align 4
218  %cond_2 = icmp eq i32 %loaded, %x
219  br i1 %cond_2, label %failure, label %loop
220
221exit:                                             ; preds = %loop
222  ret i32 -1
223
224failure:                                          ; preds = %backedge
225  unreachable
226}
227
228define i32 @test_06(ptr %p, i64 %len, i32 %x, i64 %step) {
229; CHECK-LABEL: @test_06(
230; CHECK-NEXT:  entry:
231; CHECK-NEXT:    [[TMP0:%.*]] = shl i64 [[STEP:%.*]], 2
232; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP0]]
233; CHECK-NEXT:    br label [[LOOP:%.*]]
234; CHECK:       loop:
235; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ]
236; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], [[STEP]]
237; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[STEP]], [[IV_NEXT]]
238; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
239; CHECK:       backedge:
240; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[IV]], 2
241; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 [[TMP1]]
242; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SCEVGEP1]] unordered, align 4
243; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
244; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
245; CHECK:       exit:
246; CHECK-NEXT:    ret i32 -1
247; CHECK:       failure:
248; CHECK-NEXT:    unreachable
249;
250entry:
251  br label %loop
252
253loop:                                             ; preds = %backedge, %entry
254  %iv = phi i64 [ %iv.next, %backedge ], [ %len, %entry ]
255  %iv.next = add nsw i64 %iv, %step
256  %cond_1 = icmp eq i64 %iv, 0
257  br i1 %cond_1, label %exit, label %backedge
258
259backedge:                                         ; preds = %loop
260  %addr = getelementptr inbounds i32, ptr %p, i64 %iv.next
261  %loaded = load atomic i32, ptr %addr unordered, align 4
262  %cond_2 = icmp eq i32 %loaded, %x
263  br i1 %cond_2, label %failure, label %loop
264
265exit:                                             ; preds = %loop
266  ret i32 -1
267
268failure:                                          ; preds = %backedge
269  unreachable
270}
271