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: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
19 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
20 ; CHECK: exit.loopexit:
21 ; CHECK-NEXT: br label [[EXIT]]
23 ; CHECK-NEXT: ret void
26 %cmp0 = icmp ult i64 %n, %m
27 br i1 %cmp0, label %loop, label %exit
29 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
30 %iv.next = add i64 %iv, 1
31 %cmp1 = icmp ult i64 %iv, %n
32 br i1 %cmp1, label %latch, label %exit
34 call void @side_effect()
35 %cmp2 = icmp ult i64 %iv, %m
36 br i1 %cmp2, label %loop, label %exit
41 define void @ugt(i64 %n, i64 %m) {
44 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i64 [[N:%.*]], [[M:%.*]]
45 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
46 ; CHECK: loop.preheader:
47 ; CHECK-NEXT: br label [[LOOP:%.*]]
49 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
50 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
51 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
52 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
54 ; CHECK-NEXT: call void @side_effect()
55 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
56 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
57 ; CHECK: exit.loopexit:
58 ; CHECK-NEXT: br label [[EXIT]]
60 ; CHECK-NEXT: ret void
63 %cmp0 = icmp ugt i64 %n, %m
64 br i1 %cmp0, label %loop, label %exit
66 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
67 %iv.next = add i64 %iv, 1
68 %cmp1 = icmp ult i64 %iv, %n
69 br i1 %cmp1, label %latch, label %exit
71 call void @side_effect()
72 %cmp2 = icmp ult i64 %iv, %m
73 br i1 %cmp2, label %loop, label %exit
78 define void @ule(i64 %n, i64 %m) {
81 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ule i64 [[N:%.*]], [[M:%.*]]
82 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
83 ; CHECK: loop.preheader:
84 ; CHECK-NEXT: br label [[LOOP:%.*]]
86 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
87 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
88 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
89 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
91 ; CHECK-NEXT: call void @side_effect()
92 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
93 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
94 ; CHECK: exit.loopexit:
95 ; CHECK-NEXT: br label [[EXIT]]
97 ; CHECK-NEXT: ret void
100 %cmp0 = icmp ule i64 %n, %m
101 br i1 %cmp0, label %loop, label %exit
103 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
104 %iv.next = add i64 %iv, 1
105 %cmp1 = icmp ult i64 %iv, %n
106 br i1 %cmp1, label %latch, label %exit
108 call void @side_effect()
109 %cmp2 = icmp ult i64 %iv, %m
110 br i1 %cmp2, label %loop, label %exit
115 define void @uge(i64 %n, i64 %m) {
118 ; CHECK-NEXT: [[CMP0:%.*]] = icmp uge i64 [[N:%.*]], [[M:%.*]]
119 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
120 ; CHECK: loop.preheader:
121 ; CHECK-NEXT: br label [[LOOP:%.*]]
123 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
124 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
125 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
126 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
128 ; CHECK-NEXT: call void @side_effect()
129 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
130 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
131 ; CHECK: exit.loopexit:
132 ; CHECK-NEXT: br label [[EXIT]]
134 ; CHECK-NEXT: ret void
137 %cmp0 = icmp uge i64 %n, %m
138 br i1 %cmp0, label %loop, label %exit
140 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
141 %iv.next = add i64 %iv, 1
142 %cmp1 = icmp ult i64 %iv, %n
143 br i1 %cmp1, label %latch, label %exit
145 call void @side_effect()
146 %cmp2 = icmp ult i64 %iv, %m
147 br i1 %cmp2, label %loop, label %exit
153 define void @ult_const_max(i64 %n) {
154 ; CHECK-LABEL: @ult_const_max(
156 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ult i64 [[N:%.*]], 20
157 ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
158 ; CHECK: loop.preheader:
159 ; CHECK-NEXT: br label [[LOOP:%.*]]
161 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
162 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
163 ; CHECK-NEXT: [[UDIV:%.*]] = udiv i64 [[IV]], 10
164 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[UDIV]], 2
165 ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
167 ; CHECK-NEXT: call void @side_effect()
168 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[N]]
169 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
170 ; CHECK: exit.loopexit:
171 ; CHECK-NEXT: br label [[EXIT]]
173 ; CHECK-NEXT: ret void
176 %cmp0 = icmp ult i64 %n, 20
177 br i1 %cmp0, label %loop, label %exit
179 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
180 %iv.next = add i64 %iv, 1
181 %udiv = udiv i64 %iv, 10
182 %cmp1 = icmp ult i64 %udiv, 2
183 br i1 %cmp1, label %latch, label %exit
185 call void @side_effect()
186 %cmp2 = icmp ult i64 %iv, %n
187 br i1 %cmp2, label %loop, label %exit
193 declare void @side_effect()