xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll (revision a7f35d54eef95e308ed13af5f46dbfc6c559cb9b)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=indvars < %s | FileCheck %s
3
4; Check that we replace signed comparisons between non-negative values with
5; unsigned comparisons if we can.
6
7target datalayout = "n8:16:32:64"
8
9define i32 @test_01(i32 %a, i32 %b, ptr %p) {
10; CHECK-LABEL: @test_01(
11; CHECK-NEXT:  entry:
12; CHECK-NEXT:    br label [[LOOP_ENTRY:%.*]]
13; CHECK:       loop.entry:
14; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BE:%.*]] ]
15; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[IV]], 100
16; CHECK-NEXT:    br i1 [[CMP1]], label [[B1:%.*]], label [[B2:%.*]]
17; CHECK:       b1:
18; CHECK-NEXT:    store i32 [[IV]], ptr [[P:%.*]], align 4
19; CHECK-NEXT:    br label [[MERGE:%.*]]
20; CHECK:       b2:
21; CHECK-NEXT:    store i32 [[A:%.*]], ptr [[P]], align 4
22; CHECK-NEXT:    br label [[MERGE]]
23; CHECK:       merge:
24; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[IV]], 100
25; CHECK-NEXT:    br i1 [[CMP2]], label [[B3:%.*]], label [[B4:%.*]]
26; CHECK:       b3:
27; CHECK-NEXT:    store i32 [[IV]], ptr [[P]], align 4
28; CHECK-NEXT:    br label [[LOOP_BE]]
29; CHECK:       b4:
30; CHECK-NEXT:    store i32 [[B:%.*]], ptr [[P]], align 4
31; CHECK-NEXT:    br label [[LOOP_BE]]
32; CHECK:       loop.be:
33; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
34; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 1000
35; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP_ENTRY]], label [[EXIT:%.*]]
36; CHECK:       exit:
37; CHECK-NEXT:    ret i32 999
38;
39
40entry:
41  br label %loop.entry
42
43loop.entry:
44  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.be ]
45  %cmp1 = icmp slt i32 %iv, 100
46  br i1 %cmp1, label %b1, label %b2
47
48b1:
49  store i32 %iv, ptr %p
50  br label %merge
51
52b2:
53  store i32 %a, ptr %p
54  br label %merge
55
56merge:
57  %cmp2 = icmp ult i32 %iv, 100
58  br i1 %cmp2, label %b3, label %b4
59
60b3:
61  store i32 %iv, ptr %p
62  br label %loop.be
63
64b4:
65  store i32 %b, ptr %p
66  br label %loop.be
67
68loop.be:
69  %iv.next = add i32 %iv, 1
70  %cmp3 = icmp slt i32 %iv.next, 1000
71  br i1 %cmp3, label %loop.entry, label %exit
72
73exit:
74  ret i32 %iv
75}
76
77define i32 @test_02(i32 %a, i32 %b, ptr %p) {
78; CHECK-LABEL: @test_02(
79; CHECK-NEXT:  entry:
80; CHECK-NEXT:    br label [[LOOP_ENTRY:%.*]]
81; CHECK:       loop.entry:
82; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BE:%.*]] ]
83; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 100, [[IV]]
84; CHECK-NEXT:    br i1 [[CMP1]], label [[B1:%.*]], label [[B2:%.*]]
85; CHECK:       b1:
86; CHECK-NEXT:    store i32 [[IV]], ptr [[P:%.*]], align 4
87; CHECK-NEXT:    br label [[MERGE:%.*]]
88; CHECK:       b2:
89; CHECK-NEXT:    store i32 [[A:%.*]], ptr [[P]], align 4
90; CHECK-NEXT:    br label [[MERGE]]
91; CHECK:       merge:
92; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i32 100, [[IV]]
93; CHECK-NEXT:    br i1 [[CMP2]], label [[B3:%.*]], label [[B4:%.*]]
94; CHECK:       b3:
95; CHECK-NEXT:    store i32 [[IV]], ptr [[P]], align 4
96; CHECK-NEXT:    br label [[LOOP_BE]]
97; CHECK:       b4:
98; CHECK-NEXT:    store i32 [[B:%.*]], ptr [[P]], align 4
99; CHECK-NEXT:    br label [[LOOP_BE]]
100; CHECK:       loop.be:
101; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
102; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 1000
103; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP_ENTRY]], label [[EXIT:%.*]]
104; CHECK:       exit:
105; CHECK-NEXT:    ret i32 999
106;
107
108entry:
109  br label %loop.entry
110
111loop.entry:
112  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.be ]
113  %cmp1 = icmp sgt i32 100, %iv
114  br i1 %cmp1, label %b1, label %b2
115
116b1:
117  store i32 %iv, ptr %p
118  br label %merge
119
120b2:
121  store i32 %a, ptr %p
122  br label %merge
123
124merge:
125  %cmp2 = icmp ugt i32 100, %iv
126  br i1 %cmp2, label %b3, label %b4
127
128b3:
129  store i32 %iv, ptr %p
130  br label %loop.be
131
132b4:
133  store i32 %b, ptr %p
134  br label %loop.be
135
136loop.be:
137  %iv.next = add i32 %iv, 1
138  %cmp3 = icmp sgt i32 1000, %iv.next
139  br i1 %cmp3, label %loop.entry, label %exit
140
141exit:
142  ret i32 %iv
143}
144
145define i32 @test_03(ptr %p, ptr %capacity_p, ptr %num_elements_p) {
146; CHECK-LABEL: @test_03(
147; CHECK-NEXT:  entry:
148; CHECK-NEXT:    [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P:%.*]], align 4, !range [[RNG0:![0-9]+]]
149; CHECK-NEXT:    [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P:%.*]], align 4, !range [[RNG0]]
150; CHECK-NEXT:    br label [[LOOP:%.*]]
151; CHECK:       loop:
152; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
153; CHECK-NEXT:    [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]]
154; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp slt i32 [[BYTES_TO_WRITE]], 4
155; CHECK-NEXT:    br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]]
156; CHECK:       backedge:
157; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]
158; CHECK-NEXT:    store i32 1, ptr [[EL_PTR]], align 4
159; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4
160; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]]
161; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
162; CHECK:       exit:
163; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ]
164; CHECK-NEXT:    ret i32 [[IV_NEXT_LCSSA]]
165; CHECK:       out_of_bounds:
166; CHECK-NEXT:    ret i32 -1
167;
168entry:
169  %capacity = load i32, ptr %capacity_p, !range !0
170  %num_elements = load i32, ptr %num_elements_p, !range !0
171  br label %loop
172
173loop:
174  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
175  %bytes_to_write = sub i32 %capacity, %iv
176  %capacity_check = icmp slt i32 %bytes_to_write, 4
177  br i1 %capacity_check, label %out_of_bounds, label %backedge
178
179backedge:
180  %el.ptr = getelementptr i32, ptr %p, i32 %iv
181  store i32 1, ptr %el.ptr
182  %iv.next = add nuw nsw i32 %iv, 4
183  %loop_cond = icmp slt i32 %iv.next, %num_elements
184  br i1 %loop_cond, label %loop, label %exit
185
186exit:
187  ret i32 %iv.next
188
189out_of_bounds:
190  ret i32 -1
191}
192
193define i32 @test_04(ptr %p, ptr %capacity_p, ptr %num_elements_p) {
194; CHECK-LABEL: @test_04(
195; CHECK-NEXT:  entry:
196; CHECK-NEXT:    [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P:%.*]], align 4, !range [[RNG0]]
197; CHECK-NEXT:    [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P:%.*]], align 4, !range [[RNG0]]
198; CHECK-NEXT:    br label [[LOOP:%.*]]
199; CHECK:       loop:
200; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
201; CHECK-NEXT:    [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]]
202; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp sle i32 [[BYTES_TO_WRITE]], 3
203; CHECK-NEXT:    br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]]
204; CHECK:       backedge:
205; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]
206; CHECK-NEXT:    store i32 1, ptr [[EL_PTR]], align 4
207; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4
208; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]]
209; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
210; CHECK:       exit:
211; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ]
212; CHECK-NEXT:    ret i32 [[IV_NEXT_LCSSA]]
213; CHECK:       out_of_bounds:
214; CHECK-NEXT:    ret i32 -1
215;
216entry:
217  %capacity = load i32, ptr %capacity_p, !range !0
218  %num_elements = load i32, ptr %num_elements_p, !range !0
219  br label %loop
220
221loop:
222  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
223  %bytes_to_write = sub i32 %capacity, %iv
224  %capacity_check = icmp sle i32 %bytes_to_write, 3
225  br i1 %capacity_check, label %out_of_bounds, label %backedge
226
227backedge:
228  %el.ptr = getelementptr i32, ptr %p, i32 %iv
229  store i32 1, ptr %el.ptr
230  %iv.next = add nuw nsw i32 %iv, 4
231  %loop_cond = icmp slt i32 %iv.next, %num_elements
232  br i1 %loop_cond, label %loop, label %exit
233
234exit:
235  ret i32 %iv.next
236
237out_of_bounds:
238  ret i32 -1
239}
240
241define i32 @test_05(ptr %p, ptr %capacity_p, ptr %num_elements_p) {
242; CHECK-LABEL: @test_05(
243; CHECK-NEXT:  entry:
244; CHECK-NEXT:    [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P:%.*]], align 4, !range [[RNG0]]
245; CHECK-NEXT:    [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P:%.*]], align 4, !range [[RNG0]]
246; CHECK-NEXT:    br label [[LOOP:%.*]]
247; CHECK:       loop:
248; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
249; CHECK-NEXT:    [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]]
250; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp ult i32 [[BYTES_TO_WRITE]], 4
251; CHECK-NEXT:    br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]]
252; CHECK:       backedge:
253; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]
254; CHECK-NEXT:    store i32 1, ptr [[EL_PTR]], align 4
255; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4
256; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]]
257; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
258; CHECK:       exit:
259; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ]
260; CHECK-NEXT:    ret i32 [[IV_NEXT_LCSSA]]
261; CHECK:       out_of_bounds:
262; CHECK-NEXT:    ret i32 -1
263;
264entry:
265  %capacity = load i32, ptr %capacity_p, !range !0
266  %num_elements = load i32, ptr %num_elements_p, !range !0
267  br label %loop
268
269loop:
270  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
271  %bytes_to_write = sub i32 %capacity, %iv
272  %capacity_check = icmp ult i32 %bytes_to_write, 4
273  br i1 %capacity_check, label %out_of_bounds, label %backedge
274
275backedge:
276  %el.ptr = getelementptr i32, ptr %p, i32 %iv
277  store i32 1, ptr %el.ptr
278  %iv.next = add nuw nsw i32 %iv, 4
279  %loop_cond = icmp slt i32 %iv.next, %num_elements
280  br i1 %loop_cond, label %loop, label %exit
281
282exit:
283  ret i32 %iv.next
284
285out_of_bounds:
286  ret i32 -1
287}
288
289define i32 @test_06(ptr %p, ptr %capacity_p, ptr %num_elements_p) {
290; CHECK-LABEL: @test_06(
291; CHECK-NEXT:  entry:
292; CHECK-NEXT:    [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P:%.*]], align 4, !range [[RNG0]]
293; CHECK-NEXT:    [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P:%.*]], align 4, !range [[RNG0]]
294; CHECK-NEXT:    br label [[LOOP:%.*]]
295; CHECK:       loop:
296; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
297; CHECK-NEXT:    [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]]
298; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp ule i32 [[BYTES_TO_WRITE]], 3
299; CHECK-NEXT:    br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]]
300; CHECK:       backedge:
301; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]
302; CHECK-NEXT:    store i32 1, ptr [[EL_PTR]], align 4
303; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4
304; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]]
305; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
306; CHECK:       exit:
307; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ]
308; CHECK-NEXT:    ret i32 [[IV_NEXT_LCSSA]]
309; CHECK:       out_of_bounds:
310; CHECK-NEXT:    ret i32 -1
311;
312entry:
313  %capacity = load i32, ptr %capacity_p, !range !0
314  %num_elements = load i32, ptr %num_elements_p, !range !0
315  br label %loop
316
317loop:
318  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
319  %bytes_to_write = sub i32 %capacity, %iv
320  %capacity_check = icmp ule i32 %bytes_to_write, 3
321  br i1 %capacity_check, label %out_of_bounds, label %backedge
322
323backedge:
324  %el.ptr = getelementptr i32, ptr %p, i32 %iv
325  store i32 1, ptr %el.ptr
326  %iv.next = add nuw nsw i32 %iv, 4
327  %loop_cond = icmp slt i32 %iv.next, %num_elements
328  br i1 %loop_cond, label %loop, label %exit
329
330exit:
331  ret i32 %iv.next
332
333out_of_bounds:
334  ret i32 -1
335}
336
337!0 = !{i32 1, i32 2147483648}
338