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