1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4declare void @use(i1)
5
6define void @iv_known_non_negative_iv_constant_trip_count_uge() {
7; CHECK-LABEL: @iv_known_non_negative_iv_constant_trip_count_uge(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
10; CHECK:       loop.header:
11; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
12; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[IV]], 2
13; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]]
14; CHECK:       loop.latch:
15; CHECK-NEXT:    call void @use(i1 true)
16; CHECK-NEXT:    call void @use(i1 true)
17; CHECK-NEXT:    call void @use(i1 false)
18; CHECK-NEXT:    call void @use(i1 false)
19; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
20; CHECK-NEXT:    br label [[LOOP_HEADER]]
21; CHECK:       exit.1:
22; CHECK-NEXT:    ret void
23;
24entry:
25  br label %loop.header
26
27loop.header:
28  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ]
29  %cmp = icmp uge i8 %iv, 2
30  br i1 %cmp, label %loop.latch, label %exit.1
31
32loop.latch:
33  %t.1 = icmp uge i8 %iv, 2
34  call void @use(i1 %t.1)
35  %t.2 = icmp sge i8 %iv, 2
36  call void @use(i1 %t.2)
37  %f.1 = icmp ult i8 %iv, 2
38  call void @use(i1 %f.1)
39  %f.2 = icmp slt i8 %iv, 2
40  call void @use(i1 %f.2)
41  %iv.next = add nsw nuw i8 %iv, 1
42  br label %loop.header
43
44exit.1:
45  ret void
46}
47
48define void @iv_known_non_negative_iv_variable_trip_count_uge(i8 %N) {
49; CHECK-LABEL: @iv_known_non_negative_iv_variable_trip_count_uge(
50; CHECK-NEXT:  entry:
51; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
52; CHECK:       loop.header:
53; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
54; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[IV]], [[N:%.*]]
55; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]]
56; CHECK:       loop.latch:
57; CHECK-NEXT:    call void @use(i1 true)
58; CHECK-NEXT:    call void @use(i1 true)
59; CHECK-NEXT:    call void @use(i1 false)
60; CHECK-NEXT:    call void @use(i1 false)
61; CHECK-NEXT:    [[C_0:%.*]] = icmp ugt i8 [[IV]], 2
62; CHECK-NEXT:    call void @use(i1 [[C_0]])
63; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
64; CHECK-NEXT:    br label [[LOOP_HEADER]]
65; CHECK:       exit.1:
66; CHECK-NEXT:    ret void
67;
68entry:
69  br label %loop.header
70
71loop.header:
72  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ]
73  %cmp = icmp uge i8 %iv, %N
74  br i1 %cmp, label %loop.latch, label %exit.1
75
76loop.latch:
77  %t.1 = icmp uge i8 %iv, %N
78  call void @use(i1 %t.1)
79  %t.2 = icmp sge i8 %iv, %N
80  call void @use(i1 %t.2)
81  %f.1 = icmp ult i8 %iv, %N
82  call void @use(i1 %f.1)
83  %f.2 = icmp slt i8 %iv, %N
84  call void @use(i1 %f.2)
85  %c.0 = icmp ugt i8 %iv, 2
86  call void @use(i1 %c.0)
87  %iv.next = add nsw nuw i8 %iv, 1
88  br label %loop.header
89
90exit.1:
91  ret void
92}
93
94define void @iv_known_non_negative_iv_variable_trip_count_uge_operands_swapped(i8 %N) {
95; CHECK-LABEL: @iv_known_non_negative_iv_variable_trip_count_uge_operands_swapped(
96; CHECK-NEXT:  entry:
97; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
98; CHECK:       loop.header:
99; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
100; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[N:%.*]], [[IV]]
101; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]]
102; CHECK:       loop.latch:
103; CHECK-NEXT:    call void @use(i1 true)
104; CHECK-NEXT:    [[T_2:%.*]] = icmp sge i8 [[N]], [[IV]]
105; CHECK-NEXT:    call void @use(i1 [[T_2]])
106; CHECK-NEXT:    call void @use(i1 false)
107; CHECK-NEXT:    [[F_2:%.*]] = icmp slt i8 [[N]], [[IV]]
108; CHECK-NEXT:    call void @use(i1 [[F_2]])
109; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
110; CHECK-NEXT:    br label [[LOOP_HEADER]]
111; CHECK:       exit.1:
112; CHECK-NEXT:    ret void
113;
114entry:
115  br label %loop.header
116
117loop.header:
118  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ]
119  %cmp = icmp uge i8 %N, %iv
120  br i1 %cmp, label %loop.latch, label %exit.1
121
122loop.latch:
123  %t.1 = icmp uge i8 %N, %iv
124  call void @use(i1 %t.1)
125  %t.2 = icmp sge i8 %N, %iv
126  call void @use(i1 %t.2)
127  %f.1 = icmp ult i8 %N, %iv
128  call void @use(i1 %f.1)
129  %f.2 = icmp slt i8 %N, %iv
130  call void @use(i1 %f.2)
131  %iv.next = add nsw nuw i8 %iv, 1
132  br label %loop.header
133
134exit.1:
135  ret void
136}
137
138define void @iv_known_non_negative_iv_variable_trip_count_ugt(i8 %N) {
139; CHECK-LABEL: @iv_known_non_negative_iv_variable_trip_count_ugt(
140; CHECK-NEXT:  entry:
141; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
142; CHECK:       loop.header:
143; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
144; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[IV]], [[N:%.*]]
145; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]]
146; CHECK:       loop.latch:
147; CHECK-NEXT:    call void @use(i1 true)
148; CHECK-NEXT:    call void @use(i1 true)
149; CHECK-NEXT:    call void @use(i1 false)
150; CHECK-NEXT:    call void @use(i1 false)
151; CHECK-NEXT:    [[C_0:%.*]] = icmp ugt i8 [[IV]], 2
152; CHECK-NEXT:    call void @use(i1 [[C_0]])
153; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
154; CHECK-NEXT:    br label [[LOOP_HEADER]]
155; CHECK:       exit.1:
156; CHECK-NEXT:    ret void
157;
158entry:
159  br label %loop.header
160
161loop.header:
162  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ]
163  %cmp = icmp ugt i8 %iv, %N
164  br i1 %cmp, label %loop.latch, label %exit.1
165
166loop.latch:
167  %t.1 = icmp ugt i8 %iv, %N
168  call void @use(i1 %t.1)
169  %t.2 = icmp sgt i8 %iv, %N
170  call void @use(i1 %t.2)
171  %f.1 = icmp ult i8 %iv, %N
172  call void @use(i1 %f.1)
173  %f.2 = icmp slt i8 %iv, %N
174  call void @use(i1 %f.2)
175  %c.0 = icmp ugt i8 %iv, 2
176  call void @use(i1 %c.0)
177  %iv.next = add nsw nuw i8 %iv, 1
178  br label %loop.header
179
180exit.1:
181  ret void
182}
183
184define void @iv_known_non_negative_iv_variable_trip_count_ugt_operands_swapped(i8 %N) {
185; CHECK-LABEL: @iv_known_non_negative_iv_variable_trip_count_ugt_operands_swapped(
186; CHECK-NEXT:  entry:
187; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
188; CHECK:       loop.header:
189; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
190; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[N:%.*]], [[IV]]
191; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]]
192; CHECK:       loop.latch:
193; CHECK-NEXT:    call void @use(i1 true)
194; CHECK-NEXT:    [[T_2:%.*]] = icmp sgt i8 [[N]], [[IV]]
195; CHECK-NEXT:    call void @use(i1 [[T_2]])
196; CHECK-NEXT:    call void @use(i1 false)
197; CHECK-NEXT:    [[F_2:%.*]] = icmp slt i8 [[N]], [[IV]]
198; CHECK-NEXT:    call void @use(i1 [[F_2]])
199; CHECK-NEXT:    [[C_0:%.*]] = icmp ugt i8 [[IV]], 2
200; CHECK-NEXT:    call void @use(i1 [[C_0]])
201; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
202; CHECK-NEXT:    br label [[LOOP_HEADER]]
203; CHECK:       exit.1:
204; CHECK-NEXT:    ret void
205;
206entry:
207  br label %loop.header
208
209loop.header:
210  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ]
211  %cmp = icmp ugt i8 %N, %iv
212  br i1 %cmp, label %loop.latch, label %exit.1
213
214loop.latch:
215  %t.1 = icmp ugt i8 %N, %iv
216  call void @use(i1 %t.1)
217  %t.2 = icmp sgt i8 %N, %iv
218  call void @use(i1 %t.2)
219  %f.1 = icmp ult i8 %N, %iv
220  call void @use(i1 %f.1)
221  %f.2 = icmp slt i8 %N, %iv
222  call void @use(i1 %f.2)
223  %c.0 = icmp ugt i8 %iv, 2
224  call void @use(i1 %c.0)
225  %iv.next = add nsw nuw i8 %iv, 1
226  br label %loop.header
227
228exit.1:
229  ret void
230}
231