[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / IndVarSimplify / backedge-on-min-max.ll
blobbc846c49a8a4b499ca0f0f64ce7f5b76f350c204
1 ; RUN: opt < %s -indvars -S | FileCheck %s
2 ; RUN: opt -lcssa -loop-simplify -S < %s | opt -S -passes='require<targetir>,require<scalar-evolution>,require<domtree>,loop(indvars)'
4 ;; --- signed ---
6 define void @min.signed.1(i32* %a, i32 %a_len, i32 %n) {
7 ; CHECK-LABEL: @min.signed.1
8  entry:
9   %smin.cmp = icmp slt i32 %a_len, %n
10   %smin = select i1 %smin.cmp, i32 %a_len, i32 %n
11   %entry.cond = icmp slt i32 0, %smin
12   br i1 %entry.cond, label %loop, label %exit
14  loop:
15   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
16   %idx.inc = add i32 %idx, 1
17   %in.bounds = icmp slt i32 %idx, %a_len
18   br i1 %in.bounds, label %ok, label %latch
19 ; CHECK: br i1 true, label %ok, label %latch
21  ok:
22   %addr = getelementptr i32, i32* %a, i32 %idx
23   store i32 %idx, i32* %addr
24   br label %latch
26  latch:
27   %be.cond = icmp slt i32 %idx.inc, %smin
28   br i1 %be.cond, label %loop, label %exit
30  exit:
31   ret void
34 define void @min.signed.2(i32* %a, i32 %a_len, i32 %n) {
35 ; CHECK-LABEL: @min.signed.2
36  entry:
37   %smin.cmp = icmp slt i32 %a_len, %n
38   %smin = select i1 %smin.cmp, i32 %a_len, i32 %n
39   %entry.cond = icmp slt i32 0, %smin
40   br i1 %entry.cond, label %loop, label %exit
42  loop:
43   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
44   %idx.inc = add i32 %idx, 1
45   %in.bounds = icmp sgt i32 %a_len, %idx
46   br i1 %in.bounds, label %ok, label %latch
47 ; CHECK: br i1 true, label %ok, label %latch
49  ok:
50   %addr = getelementptr i32, i32* %a, i32 %idx
51   store i32 %idx, i32* %addr
52   br label %latch
54  latch:
55   %be.cond = icmp slt i32 %idx.inc, %smin
56   br i1 %be.cond, label %loop, label %exit
58  exit:
59   ret void
62 define void @min.signed.3(i32* %a, i32 %n) {
63 ; CHECK-LABEL: @min.signed.3
64  entry:
65   %smin.cmp = icmp slt i32 42, %n
66   %smin = select i1 %smin.cmp, i32 42, i32 %n
67   %entry.cond = icmp slt i32 0, %smin
68   br i1 %entry.cond, label %loop, label %exit
70  loop:
71   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
72   %idx.inc = add i32 %idx, 1
73   %in.bounds = icmp slt i32 %idx, 42
74   br i1 %in.bounds, label %ok, label %latch
75 ; CHECK: br i1 true, label %ok, label %latch
77  ok:
78   %addr = getelementptr i32, i32* %a, i32 %idx
79   store i32 %idx, i32* %addr
80   br label %latch
82  latch:
83   %be.cond = icmp slt i32 %idx.inc, %smin
84   br i1 %be.cond, label %loop, label %exit
86  exit:
87   ret void
90 define void @min.signed.4(i32* %a, i32 %n) {
91 ; CHECK-LABEL: @min.signed.4
92  entry:
93   %smin.cmp = icmp slt i32 42, %n
94   %smin = select i1 %smin.cmp, i32 42, i32 %n
95   %entry.cond = icmp slt i32 0, %smin
96   br i1 %entry.cond, label %loop, label %exit
98  loop:
99   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
100   %idx.inc = add i32 %idx, 1
101   %in.bounds = icmp sgt i32 42, %idx
102   br i1 %in.bounds, label %ok, label %latch
103 ; CHECK: br i1 true, label %ok, label %latch
105  ok:
106   %addr = getelementptr i32, i32* %a, i32 %idx
107   store i32 %idx, i32* %addr
108   br label %latch
110  latch:
111   %be.cond = icmp slt i32 %idx.inc, %smin
112   br i1 %be.cond, label %loop, label %exit
114  exit:
115   ret void
118 define void @max.signed.1(i32* %a, i32 %a_len, i32 %n) {
119 ; CHECK-LABEL: @max.signed.1
120  entry:
121   %smax.cmp = icmp sgt i32 %a_len, %n
122   %smax = select i1 %smax.cmp, i32 %a_len, i32 %n
123   %entry.cond = icmp sgt i32 0, %smax
124   br i1 %entry.cond, label %loop, label %exit
126  loop:
127   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
128   %idx.inc = add i32 %idx, 1
129   %in.bounds = icmp sgt i32 %idx, %a_len
130   br i1 %in.bounds, label %ok, label %latch
131 ; CHECK: br i1 true, label %ok, label %latch
133  ok:
134   %addr = getelementptr i32, i32* %a, i32 %idx
135   store i32 %idx, i32* %addr
136   br label %latch
138  latch:
139   %be.cond = icmp sgt i32 %idx.inc, %smax
140   br i1 %be.cond, label %loop, label %exit
142  exit:
143   ret void
146 define void @max.signed.2(i32* %a, i32 %a_len, i32 %n) {
147 ; CHECK-LABEL: @max.signed.2
148  entry:
149   %smax.cmp = icmp sgt i32 %a_len, %n
150   %smax = select i1 %smax.cmp, i32 %a_len, i32 %n
151   %entry.cond = icmp sgt i32 0, %smax
152   br i1 %entry.cond, label %loop, label %exit
154  loop:
155   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
156   %idx.inc = add i32 %idx, 1
157   %in.bounds = icmp slt i32 %a_len, %idx
158   br i1 %in.bounds, label %ok, label %latch
159 ; CHECK: br i1 true, label %ok, label %latch
161  ok:
162   %addr = getelementptr i32, i32* %a, i32 %idx
163   store i32 %idx, i32* %addr
164   br label %latch
166  latch:
167   %be.cond = icmp sgt i32 %idx.inc, %smax
168   br i1 %be.cond, label %loop, label %exit
170  exit:
171   ret void
174 define void @max.signed.3(i32* %a, i32 %n, i32 %init) {
175 ; CHECK-LABEL: @max.signed.3
176  entry:
177   %smax.cmp = icmp sgt i32 42, %n
178   %smax = select i1 %smax.cmp, i32 42, i32 %n
179   %entry.cond = icmp sgt i32 %init, %smax
180   br i1 %entry.cond, label %loop, label %exit
182  loop:
183   %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
184   %idx.inc = add i32 %idx, 1
185   %in.bounds = icmp sgt i32 %idx, 42
186   br i1 %in.bounds, label %ok, label %latch
187 ; CHECK: br i1 true, label %ok, label %latch
189  ok:
190   %addr = getelementptr i32, i32* %a, i32 %idx
191   store i32 %idx, i32* %addr
192   br label %latch
194  latch:
195   %be.cond = icmp sgt i32 %idx.inc, %smax
196   br i1 %be.cond, label %loop, label %exit
198  exit:
199   ret void
202 define void @max.signed.4(i32* %a, i32 %n, i32 %init) {
203 ; CHECK-LABEL: @max.signed.4
204  entry:
205   %smax.cmp = icmp sgt i32 42, %n
206   %smax = select i1 %smax.cmp, i32 42, i32 %n
207   %entry.cond = icmp sgt i32 %init, %smax
208   br i1 %entry.cond, label %loop, label %exit
210  loop:
211   %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
212   %idx.inc = add i32 %idx, 1
213   %in.bounds = icmp slt i32 42, %idx
214   br i1 %in.bounds, label %ok, label %latch
215 ; CHECK: br i1 true, label %ok, label %latch
217  ok:
218   %addr = getelementptr i32, i32* %a, i32 %idx
219   store i32 %idx, i32* %addr
220   br label %latch
222  latch:
223   %be.cond = icmp sgt i32 %idx.inc, %smax
224   br i1 %be.cond, label %loop, label %exit
226  exit:
227   ret void
230 ;; --- unsigned ---
232 define void @min.unsigned.1(i32* %a, i32 %a_len, i32 %n) {
233 ; CHECK-LABEL: @min.unsigned.1
234  entry:
235   %umin.cmp = icmp ult i32 %a_len, %n
236   %umin = select i1 %umin.cmp, i32 %a_len, i32 %n
237   %entry.cond = icmp ult i32 5, %umin
238   br i1 %entry.cond, label %loop, label %exit
240  loop:
241   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
242   %idx.inc = add i32 %idx, 1
243   %in.bounds = icmp ult i32 %idx, %a_len
244   br i1 %in.bounds, label %ok, label %latch
245 ; CHECK: br i1 true, label %ok, label %latch
247  ok:
248   %addr = getelementptr i32, i32* %a, i32 %idx
249   store i32 %idx, i32* %addr
250   br label %latch
252  latch:
253   %be.cond = icmp ult i32 %idx.inc, %umin
254   br i1 %be.cond, label %loop, label %exit
256  exit:
257   ret void
260 define void @min.unsigned.2(i32* %a, i32 %a_len, i32 %n) {
261 ; CHECK-LABEL: @min.unsigned.2
262  entry:
263   %umin.cmp = icmp ult i32 %a_len, %n
264   %umin = select i1 %umin.cmp, i32 %a_len, i32 %n
265   %entry.cond = icmp ult i32 5, %umin
266   br i1 %entry.cond, label %loop, label %exit
268  loop:
269   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
270   %idx.inc = add i32 %idx, 1
271   %in.bounds = icmp ugt i32 %a_len, %idx
272   br i1 %in.bounds, label %ok, label %latch
273 ; CHECK: br i1 true, label %ok, label %latch
275  ok:
276   %addr = getelementptr i32, i32* %a, i32 %idx
277   store i32 %idx, i32* %addr
278   br label %latch
280  latch:
281   %be.cond = icmp ult i32 %idx.inc, %umin
282   br i1 %be.cond, label %loop, label %exit
284  exit:
285   ret void
288 define void @min.unsigned.3(i32* %a, i32 %n) {
289 ; CHECK-LABEL: @min.unsigned.3
290  entry:
291   %umin.cmp = icmp ult i32 42, %n
292   %umin = select i1 %umin.cmp, i32 42, i32 %n
293   %entry.cond = icmp ult i32 5, %umin
294   br i1 %entry.cond, label %loop, label %exit
296  loop:
297   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
298   %idx.inc = add i32 %idx, 1
299   %in.bounds = icmp ult i32 %idx, 42
300   br i1 %in.bounds, label %ok, label %latch
301 ; CHECK: br i1 true, label %ok, label %latch
303  ok:
304   %addr = getelementptr i32, i32* %a, i32 %idx
305   store i32 %idx, i32* %addr
306   br label %latch
308  latch:
309   %be.cond = icmp ult i32 %idx.inc, %umin
310   br i1 %be.cond, label %loop, label %exit
312  exit:
313   ret void
316 define void @min.unsigned.4(i32* %a, i32 %n) {
317 ; CHECK-LABEL: @min.unsigned.4
318  entry:
319   %umin.cmp = icmp ult i32 42, %n
320   %umin = select i1 %umin.cmp, i32 42, i32 %n
321   %entry.cond = icmp ult i32 5, %umin
322   br i1 %entry.cond, label %loop, label %exit
324  loop:
325   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
326   %idx.inc = add i32 %idx, 1
327   %in.bounds = icmp ugt i32 42, %idx
328   br i1 %in.bounds, label %ok, label %latch
329 ; CHECK: br i1 true, label %ok, label %latch
331  ok:
332   %addr = getelementptr i32, i32* %a, i32 %idx
333   store i32 %idx, i32* %addr
334   br label %latch
336  latch:
337   %be.cond = icmp ult i32 %idx.inc, %umin
338   br i1 %be.cond, label %loop, label %exit
340  exit:
341   ret void
344 define void @max.unsigned.1(i32* %a, i32 %a_len, i32 %n) {
345 ; CHECK-LABEL: @max.unsigned.1
346  entry:
347   %umax.cmp = icmp ugt i32 %a_len, %n
348   %umax = select i1 %umax.cmp, i32 %a_len, i32 %n
349   %entry.cond = icmp ugt i32 5, %umax
350   br i1 %entry.cond, label %loop, label %exit
352  loop:
353   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
354   %idx.inc = add i32 %idx, 1
355   %in.bounds = icmp ugt i32 %idx, %a_len
356   br i1 %in.bounds, label %ok, label %latch
357 ; CHECK: br i1 true, label %ok, label %latch
359  ok:
360   %addr = getelementptr i32, i32* %a, i32 %idx
361   store i32 %idx, i32* %addr
362   br label %latch
364  latch:
365   %be.cond = icmp ugt i32 %idx.inc, %umax
366   br i1 %be.cond, label %loop, label %exit
368  exit:
369   ret void
372 define void @max.unsigned.2(i32* %a, i32 %a_len, i32 %n) {
373 ; CHECK-LABEL: @max.unsigned.2
374  entry:
375   %umax.cmp = icmp ugt i32 %a_len, %n
376   %umax = select i1 %umax.cmp, i32 %a_len, i32 %n
377   %entry.cond = icmp ugt i32 5, %umax
378   br i1 %entry.cond, label %loop, label %exit
380  loop:
381   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
382   %idx.inc = add i32 %idx, 1
383   %in.bounds = icmp ult i32 %a_len, %idx
384   br i1 %in.bounds, label %ok, label %latch
385 ; CHECK: br i1 true, label %ok, label %latch
387  ok:
388   %addr = getelementptr i32, i32* %a, i32 %idx
389   store i32 %idx, i32* %addr
390   br label %latch
392  latch:
393   %be.cond = icmp ugt i32 %idx.inc, %umax
394   br i1 %be.cond, label %loop, label %exit
396  exit:
397   ret void
400 define void @max.unsigned.3(i32* %a, i32 %n, i32 %init) {
401 ; CHECK-LABEL: @max.unsigned.3
402  entry:
403   %umax.cmp = icmp ugt i32 42, %n
404   %umax = select i1 %umax.cmp, i32 42, i32 %n
405   %entry.cond = icmp ugt i32 %init, %umax
406   br i1 %entry.cond, label %loop, label %exit
408  loop:
409   %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
410   %idx.inc = add i32 %idx, 1
411   %in.bounds = icmp ugt i32 %idx, 42
412   br i1 %in.bounds, label %ok, label %latch
413 ; CHECK: br i1 true, label %ok, label %latch
415  ok:
416   %addr = getelementptr i32, i32* %a, i32 %idx
417   store i32 %idx, i32* %addr
418   br label %latch
420  latch:
421   %be.cond = icmp ugt i32 %idx.inc, %umax
422   br i1 %be.cond, label %loop, label %exit
424  exit:
425   ret void
428 define void @max.unsigned.4(i32* %a, i32 %n, i32 %init) {
429 ; CHECK-LABEL: @max.unsigned.4
430  entry:
431   %umax.cmp = icmp ugt i32 42, %n
432   %umax = select i1 %umax.cmp, i32 42, i32 %n
433   %entry.cond = icmp ugt i32 %init, %umax
434   br i1 %entry.cond, label %loop, label %exit
436  loop:
437   %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
438   %idx.inc = add i32 %idx, 1
439   %in.bounds = icmp ult i32 42, %idx
440   br i1 %in.bounds, label %ok, label %latch
441 ; CHECK: br i1 true, label %ok, label %latch
443  ok:
444   %addr = getelementptr i32, i32* %a, i32 %idx
445   store i32 %idx, i32* %addr
446   br label %latch
448  latch:
449   %be.cond = icmp ugt i32 %idx.inc, %umax
450   br i1 %be.cond, label %loop, label %exit
452  exit:
453   ret void