[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / IndVarSimplify / eliminate-exit.ll
blob726f3cd7f2f26573f313dfeace68445181a5b641
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) {
5 ; CHECK-LABEL: @ult(
6 ; CHECK-NEXT:  entry:
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:%.*]]
11 ; CHECK:       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:%.*]]
16 ; CHECK:       latch:
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]]
21 ; CHECK:       exit:
22 ; CHECK-NEXT:    ret void
24 entry:
25   %cmp0 = icmp ult i64 %n, %m
26   br i1 %cmp0, label %loop, label %exit
27 loop:
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
32 latch:
33   call void @side_effect()
34   %cmp2 = icmp ult i64 %iv, %m
35   br i1 %cmp2, label %loop, label %exit
36 exit:
37   ret void
40 define void @ugt(i64 %n, i64 %m) {
41 ; CHECK-LABEL: @ugt(
42 ; CHECK-NEXT:  entry:
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:%.*]]
47 ; CHECK:       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:%.*]]
51 ; CHECK:       latch:
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]]
57 ; CHECK:       exit:
58 ; CHECK-NEXT:    ret void
60 entry:
61   %cmp0 = icmp ugt i64 %n, %m
62   br i1 %cmp0, label %loop, label %exit
63 loop:
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
68 latch:
69   call void @side_effect()
70   %cmp2 = icmp ult i64 %iv, %m
71   br i1 %cmp2, label %loop, label %exit
72 exit:
73   ret void
76 define void @ule(i64 %n, i64 %m) {
77 ; CHECK-LABEL: @ule(
78 ; CHECK-NEXT:  entry:
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:%.*]]
83 ; CHECK:       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:%.*]]
88 ; CHECK:       latch:
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]]
94 ; CHECK:       exit:
95 ; CHECK-NEXT:    ret void
97 entry:
98   %cmp0 = icmp ule i64 %n, %m
99   br i1 %cmp0, label %loop, label %exit
100 loop:
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
105 latch:
106   call void @side_effect()
107   %cmp2 = icmp ult i64 %iv, %m
108   br i1 %cmp2, label %loop, label %exit
109 exit:
110   ret void
113 define void @uge(i64 %n, i64 %m) {
114 ; CHECK-LABEL: @uge(
115 ; CHECK-NEXT:  entry:
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:%.*]]
120 ; CHECK:       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:%.*]]
125 ; CHECK:       latch:
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]]
131 ; CHECK:       exit:
132 ; CHECK-NEXT:    ret void
134 entry:
135   %cmp0 = icmp uge i64 %n, %m
136   br i1 %cmp0, label %loop, label %exit
137 loop:
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
142 latch:
143   call void @side_effect()
144   %cmp2 = icmp ult i64 %iv, %m
145   br i1 %cmp2, label %loop, label %exit
146 exit:
147   ret void
151 define void @ult_const_max(i64 %n) {
152 ; CHECK-LABEL: @ult_const_max(
153 ; CHECK-NEXT:  entry:
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:%.*]]
158 ; CHECK:       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:%.*]]
162 ; CHECK:       latch:
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]]
168 ; CHECK:       exit:
169 ; CHECK-NEXT:    ret void
171 entry:
172   %cmp0 = icmp ult i64 %n, 20
173   br i1 %cmp0, label %loop, label %exit
174 loop:
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
180 latch:
181   call void @side_effect()
182   %cmp2 = icmp ult i64 %iv, %n
183   br i1 %cmp2, label %loop, label %exit
184 exit:
185   ret void
188 define void @mixed_width(i32 %len) {
189 ; CHECK-LABEL: @mixed_width(
190 ; CHECK-NEXT:  entry:
191 ; CHECK-NEXT:    [[LEN_ZEXT:%.*]] = zext i32 [[LEN:%.*]] to i64
192 ; CHECK-NEXT:    br label [[LOOP:%.*]]
193 ; CHECK:       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:%.*]]
198 ; CHECK:       backedge:
199 ; CHECK-NEXT:    call void @side_effect()
200 ; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[EXIT]]
201 ; CHECK:       exit:
202 ; CHECK-NEXT:    ret void
204 entry:
205   %len.zext = zext i32 %len to i64
206   br label %loop
207 loop:
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
215 backedge:
216   call void @side_effect()
217   %cmp2 = icmp ult i32 %iv2, %len
218   br i1 %cmp2, label %loop, label %exit
219 exit:
220   ret void
223 declare void @side_effect()