1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -indvars -S < %s | FileCheck %s
4 define void @ult(i64 %n, i64 %m) {
7 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ult i64 [[N:%.*]], [[M:%.*]]
8 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
9 ; CHECK: loop.preheader:
10 ; CHECK-NEXT: br label [[LOOP:%.*]]
12 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
13 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
14 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
15 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
17 ; CHECK-NEXT: call void @side_effect()
18 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT_LOOPEXIT]]
19 ; CHECK: exit.loopexit:
20 ; CHECK-NEXT: br label [[EXIT]]
22 ; CHECK-NEXT: ret void
25 %cmp0 = icmp ult i64 %n, %m
26 br i1 %cmp0, label %loop, label %exit
28 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
29 %iv.next = add i64 %iv, 1
30 %cmp1 = icmp ult i64 %iv, %n
31 br i1 %cmp1, label %latch, label %exit
33 call void @side_effect()
34 %cmp2 = icmp ult i64 %iv, %m
35 br i1 %cmp2, label %loop, label %exit
40 define void @ugt(i64 %n, i64 %m) {
43 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i64 [[N:%.*]], [[M:%.*]]
44 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
45 ; CHECK: loop.preheader:
46 ; CHECK-NEXT: br label [[LOOP:%.*]]
48 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
49 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
50 ; CHECK-NEXT: br i1 true, label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
52 ; CHECK-NEXT: call void @side_effect()
53 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
54 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
55 ; CHECK: exit.loopexit:
56 ; CHECK-NEXT: br label [[EXIT]]
58 ; CHECK-NEXT: ret void
61 %cmp0 = icmp ugt i64 %n, %m
62 br i1 %cmp0, label %loop, label %exit
64 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
65 %iv.next = add i64 %iv, 1
66 %cmp1 = icmp ult i64 %iv, %n
67 br i1 %cmp1, label %latch, label %exit
69 call void @side_effect()
70 %cmp2 = icmp ult i64 %iv, %m
71 br i1 %cmp2, label %loop, label %exit
76 define void @ule(i64 %n, i64 %m) {
79 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ule i64 [[N:%.*]], [[M:%.*]]
80 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
81 ; CHECK: loop.preheader:
82 ; CHECK-NEXT: br label [[LOOP:%.*]]
84 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
85 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
86 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
87 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
89 ; CHECK-NEXT: call void @side_effect()
90 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
91 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
92 ; CHECK: exit.loopexit:
93 ; CHECK-NEXT: br label [[EXIT]]
95 ; CHECK-NEXT: ret void
98 %cmp0 = icmp ule i64 %n, %m
99 br i1 %cmp0, label %loop, label %exit
101 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
102 %iv.next = add i64 %iv, 1
103 %cmp1 = icmp ult i64 %iv, %n
104 br i1 %cmp1, label %latch, label %exit
106 call void @side_effect()
107 %cmp2 = icmp ult i64 %iv, %m
108 br i1 %cmp2, label %loop, label %exit
113 define void @uge(i64 %n, i64 %m) {
116 ; CHECK-NEXT: [[CMP0:%.*]] = icmp uge i64 [[N:%.*]], [[M:%.*]]
117 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
118 ; CHECK: loop.preheader:
119 ; CHECK-NEXT: br label [[LOOP:%.*]]
121 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
122 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
123 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
124 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
126 ; CHECK-NEXT: call void @side_effect()
127 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
128 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
129 ; CHECK: exit.loopexit:
130 ; CHECK-NEXT: br label [[EXIT]]
132 ; CHECK-NEXT: ret void
135 %cmp0 = icmp uge i64 %n, %m
136 br i1 %cmp0, label %loop, label %exit
138 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
139 %iv.next = add i64 %iv, 1
140 %cmp1 = icmp ult i64 %iv, %n
141 br i1 %cmp1, label %latch, label %exit
143 call void @side_effect()
144 %cmp2 = icmp ult i64 %iv, %m
145 br i1 %cmp2, label %loop, label %exit
151 define void @ult_const_max(i64 %n) {
152 ; CHECK-LABEL: @ult_const_max(
154 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ult i64 [[N:%.*]], 20
155 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
156 ; CHECK: loop.preheader:
157 ; CHECK-NEXT: br label [[LOOP:%.*]]
159 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
160 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
161 ; CHECK-NEXT: br i1 true, label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
163 ; CHECK-NEXT: call void @side_effect()
164 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[N]]
165 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
166 ; CHECK: exit.loopexit:
167 ; CHECK-NEXT: br label [[EXIT]]
169 ; CHECK-NEXT: ret void
172 %cmp0 = icmp ult i64 %n, 20
173 br i1 %cmp0, label %loop, label %exit
175 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
176 %iv.next = add i64 %iv, 1
177 %udiv = udiv i64 %iv, 10
178 %cmp1 = icmp ult i64 %udiv, 2
179 br i1 %cmp1, label %latch, label %exit
181 call void @side_effect()
182 %cmp2 = icmp ult i64 %iv, %n
183 br i1 %cmp2, label %loop, label %exit
188 define void @mixed_width(i32 %len) {
189 ; CHECK-LABEL: @mixed_width(
191 ; CHECK-NEXT: [[LEN_ZEXT:%.*]] = zext i32 [[LEN:%.*]] to i64
192 ; CHECK-NEXT: br label [[LOOP:%.*]]
194 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
195 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
196 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[LEN_ZEXT]]
197 ; CHECK-NEXT: br i1 [[CMP1]], label [[BACKEDGE]], label [[EXIT:%.*]]
199 ; CHECK-NEXT: call void @side_effect()
200 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT]]
202 ; CHECK-NEXT: ret void
205 %len.zext = zext i32 %len to i64
208 %iv = phi i64 [0, %entry], [%iv.next, %backedge]
209 %iv2 = phi i32 [0, %entry], [%iv2.next, %backedge]
210 %iv.next = add i64 %iv, 1
211 %iv2.next = add i32 %iv2, 1
212 %cmp1 = icmp ult i64 %iv, %len.zext
213 br i1 %cmp1, label %backedge, label %exit
216 call void @side_effect()
217 %cmp2 = icmp ult i32 %iv2, %len
218 br i1 %cmp2, label %loop, label %exit
223 declare void @side_effect()