xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-wrapping.ll (revision e6a1657fa30c747f4412fc47f567660ebe861a9e)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5
6
7declare void @use(i8)
8declare void @use.i1(i1)
9declare void @llvm.assume(i1)
10declare i1 @cond()
11
12define void @test_iv_wraps_1(i8 %len.n, i8 %a) {
13; CHECK-LABEL: @test_iv_wraps_1(
14; CHECK-NEXT:  loop.ph:
15; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
16; CHECK:       loop.header:
17; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ -1, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
18; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], 1
19; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
20; CHECK:       loop.latch:
21; CHECK-NEXT:    [[T_1:%.*]] = icmp uge i8 [[IV]], -1
22; CHECK-NEXT:    call void @use.i1(i1 [[T_1]])
23; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
24; CHECK-NEXT:    br label [[LOOP_HEADER]]
25; CHECK:       exit:
26; CHECK-NEXT:    ret void
27;
28loop.ph:
29  br label %loop.header
30
31loop.header:
32  %iv = phi i8 [ 255, %loop.ph ], [ %iv.next, %loop.latch ]
33  %c = icmp eq i8 %iv, 1
34  br i1 %c, label %exit, label %loop.latch
35
36loop.latch:
37  %t.1 = icmp uge i8 %iv, 255
38  call void @use.i1(i1 %t.1)
39  %iv.next = add i8 %iv, 1
40  br label %loop.header
41
42exit:
43  ret void
44}
45
46define void @test_iv_nuw_nsw_1_uge_start(i8 %len.n, i8 %a) {
47; CHECK-LABEL: @test_iv_nuw_nsw_1_uge_start(
48; CHECK-NEXT:  loop.ph:
49; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
50; CHECK:       loop.header:
51; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ -1, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
52; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], 1
53; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
54; CHECK:       for.body:
55; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
56; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
57; CHECK:       loop.latch:
58; CHECK-NEXT:    call void @use.i1(i1 true)
59; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
60; CHECK-NEXT:    br label [[LOOP_HEADER]]
61; CHECK:       exit:
62; CHECK-NEXT:    ret void
63;
64loop.ph:
65  br label %loop.header
66
67loop.header:
68  %iv = phi i8 [ 255, %loop.ph ], [ %iv.next, %loop.latch ]
69  %c = icmp eq i8 %iv, 1
70  br i1 %c, label %exit, label %for.body
71
72for.body:
73  %c.2 = call i1 @cond()
74  br i1 %c.2, label %loop.latch, label %exit
75
76loop.latch:
77  %t.1 = icmp uge i8 %iv, 255
78  call void @use.i1(i1 %t.1)
79  %iv.next = add nsw nuw i8 %iv, 1
80  br label %loop.header
81
82exit:
83  ret void
84}
85
86define void @test_iv_nuw_nsw_2_uge_start(i8 %len.n, i8 %a) {
87; CHECK-LABEL: @test_iv_nuw_nsw_2_uge_start(
88; CHECK-NEXT:  loop.ph:
89; CHECK-NEXT:    [[START:%.*]] = add i8 -2, 1
90; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
91; CHECK:       loop.header:
92; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
93; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], 1
94; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
95; CHECK:       for.body:
96; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
97; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
98; CHECK:       loop.latch:
99; CHECK-NEXT:    call void @use.i1(i1 true)
100; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
101; CHECK-NEXT:    br label [[LOOP_HEADER]]
102; CHECK:       exit:
103; CHECK-NEXT:    ret void
104;
105loop.ph:
106  %start = add i8 254, 1
107  br label %loop.header
108
109loop.header:
110  %iv = phi i8 [ %start, %loop.ph ], [ %iv.next, %loop.latch ]
111  %c = icmp eq i8 %iv, 1
112  br i1 %c, label %exit, label %for.body
113
114for.body:
115  %c.2 = call i1 @cond()
116  br i1 %c.2, label %loop.latch, label %exit
117
118loop.latch:
119  %t.1 = icmp uge i8 %iv, 255
120  call void @use.i1(i1 %t.1)
121  %iv.next = add nsw nuw i8 %iv, 1
122  br label %loop.header
123
124exit:
125  ret void
126}
127
128define void @test_iv_nsw_nuw_1_ult_end(i8 %len.n, i8 %a) {
129; CHECK-LABEL: @test_iv_nsw_nuw_1_ult_end(
130; CHECK-NEXT:  loop.ph:
131; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
132; CHECK:       loop.header:
133; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ -2, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
134; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], 1
135; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
136; CHECK:       for.body:
137; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
138; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
139; CHECK:       loop.latch:
140; CHECK-NEXT:    call void @use.i1(i1 false)
141; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
142; CHECK-NEXT:    br label [[LOOP_HEADER]]
143; CHECK:       exit:
144; CHECK-NEXT:    ret void
145;
146loop.ph:
147  br label %loop.header
148
149loop.header:
150  %iv = phi i8 [ 254, %loop.ph ], [ %iv.next, %loop.latch ]
151  %c = icmp eq i8 %iv, 1
152  br i1 %c, label %exit, label %for.body
153
154for.body:
155  %c.2 = call i1 @cond()
156  br i1 %c.2, label %loop.latch, label %exit
157
158loop.latch:
159  %t.1 = icmp ult i8 %iv, 1
160  call void @use.i1(i1 %t.1)
161  %iv.next = add nsw nuw i8 %iv, 1
162  br label %loop.header
163
164exit:
165  ret void
166}
167
168
169define void @test_iv_nsw_nuw_2_ult_end(i8 %len.n, i8 %a, i8 %b) {
170; CHECK-LABEL: @test_iv_nsw_nuw_2_ult_end(
171; CHECK-NEXT:  loop.ph:
172; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
173; CHECK:       loop.header:
174; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
175; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
176; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
177; CHECK:       for.body:
178; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
179; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
180; CHECK:       loop.latch:
181; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8 [[IV]], [[B]]
182; CHECK-NEXT:    call void @use.i1(i1 [[T_1]])
183; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
184; CHECK-NEXT:    br label [[LOOP_HEADER]]
185; CHECK:       exit:
186; CHECK-NEXT:    ret void
187;
188loop.ph:
189  br label %loop.header
190
191loop.header:
192  %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
193  %c = icmp eq i8 %iv, %b
194  br i1 %c, label %exit, label %for.body
195
196for.body:
197  %c.2 = call i1 @cond()
198  br i1 %c.2, label %loop.latch, label %exit
199
200loop.latch:
201  %t.1 = icmp ult i8 %iv, %b
202  call void @use.i1(i1 %t.1)
203  %iv.next = add nsw nuw i8 %iv, 1
204  br label %loop.header
205
206exit:
207  ret void
208}
209
210define void @test_iv_nsw_nuw_3_ult_start_var(i8 %len.n, i8 %a, i8 %b) {
211; CHECK-LABEL: @test_iv_nsw_nuw_3_ult_start_var(
212; CHECK-NEXT:  loop.ph:
213; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
214; CHECK:       loop.header:
215; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
216; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
217; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
218; CHECK:       for.body:
219; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
220; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
221; CHECK:       loop.latch:
222; CHECK-NEXT:    call void @use.i1(i1 false)
223; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
224; CHECK-NEXT:    br label [[LOOP_HEADER]]
225; CHECK:       exit:
226; CHECK-NEXT:    ret void
227;
228loop.ph:
229  br label %loop.header
230
231loop.header:
232  %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
233  %c = icmp eq i8 %iv, %b
234  br i1 %c, label %exit, label %for.body
235
236for.body:
237  %c.2 = call i1 @cond()
238  br i1 %c.2, label %loop.latch, label %exit
239
240loop.latch:
241  %t.1 = icmp ult i8 %iv, %a
242  call void @use.i1(i1 %t.1)
243  %iv.next = add nsw nuw i8 %iv, 1
244  br label %loop.header
245
246exit:
247  ret void
248}
249
250define void @test_iv_nsw_nuw_inc_2_ult_start_var(i8 %len.n, i8 %a, i8 %b) {
251; CHECK-LABEL: @test_iv_nsw_nuw_inc_2_ult_start_var(
252; CHECK-NEXT:  loop.ph:
253; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
254; CHECK:       loop.header:
255; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
256; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
257; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
258; CHECK:       for.body:
259; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
260; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
261; CHECK:       loop.latch:
262; CHECK-NEXT:    call void @use.i1(i1 false)
263; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 2
264; CHECK-NEXT:    br label [[LOOP_HEADER]]
265; CHECK:       exit:
266; CHECK-NEXT:    ret void
267;
268loop.ph:
269  br label %loop.header
270
271loop.header:
272  %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
273  %c = icmp eq i8 %iv, %b
274  br i1 %c, label %exit, label %for.body
275
276for.body:
277  %c.2 = call i1 @cond()
278  br i1 %c.2, label %loop.latch, label %exit
279
280loop.latch:
281  %t.1 = icmp ult i8 %iv, %a
282  call void @use.i1(i1 %t.1)
283  %iv.next = add nsw nuw i8 %iv, 2
284  br label %loop.header
285
286exit:
287  ret void
288}
289