xref: /llvm-project/llvm/test/Transforms/PhaseOrdering/min_max_loop.ll (revision 93de97d750548cd90c53efd4367dbd0367aa30fd)
1; RUN: opt < %s -O3 -S | FileCheck %s
2; See issue #55013 and PR #70845 for more details.
3; This test comes from the following C program, compiled with clang
4;
5;; short vecreduce_smin_v2i16(int n, short* v)
6;; {
7;;   short p = 0;
8;;   for (int i = 0; i < n; ++i)
9;;     p = p > v[i] ? v[i] : p;
10;;   return p;
11;; }
12;
13;; short vecreduce_smax_v2i16(int n, short* v)
14;; {
15;;   short p = 0;
16;;   for (int i = 0; i < n; ++i)
17;;     p = p < v[i] ? v[i] : p;
18;;   return p;
19;; }
20
21define i16 @vecreduce_smin_v2i16(i32 %n, ptr %v) {
22; CHECK-LABEL: define range(i16 -32768, 1) i16 @vecreduce_smin_v2i16(
23; CHECK:    @llvm.smin.v2i16
24
25entry:
26  br label %for.cond
27
28for.cond:                                         ; preds = %for.inc, %entry
29  %p.0 = phi i16 [ 0, %entry ], [ %conv8, %for.inc ]
30  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
31  %cmp = icmp slt i32 %i.0, %n
32  br i1 %cmp, label %for.body, label %for.end
33
34for.body:                                         ; preds = %for.cond
35  %conv = sext i16 %p.0 to i32
36  %idxprom = sext i32 %i.0 to i64
37  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %idxprom
38  %0 = load i16, ptr %arrayidx, align 2
39  %conv1 = sext i16 %0 to i32
40  %cmp2 = icmp sgt i32 %conv, %conv1
41  br i1 %cmp2, label %cond.true, label %cond.false
42
43cond.true:                                        ; preds = %for.body
44  %idxprom4 = sext i32 %i.0 to i64
45  %arrayidx5 = getelementptr inbounds i16, ptr %v, i64 %idxprom4
46  %1 = load i16, ptr %arrayidx5, align 2
47  %conv6 = sext i16 %1 to i32
48  br label %cond.end
49
50cond.false:                                       ; preds = %for.body
51  %conv7 = sext i16 %p.0 to i32
52  br label %cond.end
53
54cond.end:                                         ; preds = %cond.false, %cond.true
55  %cond = phi i32 [ %conv6, %cond.true ], [ %conv7, %cond.false ]
56  %conv8 = trunc i32 %cond to i16
57  br label %for.inc
58
59for.inc:                                          ; preds = %cond.end
60  %inc = add nsw i32 %i.0, 1
61  br label %for.cond
62
63for.end:                                          ; preds = %for.cond
64  ret i16 %p.0
65}
66
67define i16 @vecreduce_smax_v2i16(i32 %n, ptr %v) {
68; CHECK-LABEL: define range(i16 0, -32768) i16 @vecreduce_smax_v2i16(
69; CHECK:  @llvm.smax.v2i16
70
71entry:
72  br label %for.cond
73
74for.cond:                                         ; preds = %for.inc, %entry
75  %p.0 = phi i16 [ 0, %entry ], [ %conv8, %for.inc ]
76  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
77  %cmp = icmp slt i32 %i.0, %n
78  br i1 %cmp, label %for.body, label %for.end
79
80for.body:                                         ; preds = %for.cond
81  %conv = sext i16 %p.0 to i32
82  %idxprom = sext i32 %i.0 to i64
83  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %idxprom
84  %0 = load i16, ptr %arrayidx, align 2
85  %conv1 = sext i16 %0 to i32
86  %cmp2 = icmp slt i32 %conv, %conv1
87  br i1 %cmp2, label %cond.true, label %cond.false
88
89cond.true:                                        ; preds = %for.body
90  %idxprom4 = sext i32 %i.0 to i64
91  %arrayidx5 = getelementptr inbounds i16, ptr %v, i64 %idxprom4
92  %1 = load i16, ptr %arrayidx5, align 2
93  %conv6 = sext i16 %1 to i32
94  br label %cond.end
95
96cond.false:                                       ; preds = %for.body
97  %conv7 = sext i16 %p.0 to i32
98  br label %cond.end
99
100cond.end:                                         ; preds = %cond.false, %cond.true
101  %cond = phi i32 [ %conv6, %cond.true ], [ %conv7, %cond.false ]
102  %conv8 = trunc i32 %cond to i16
103  br label %for.inc
104
105for.inc:                                          ; preds = %cond.end
106  %inc = add nsw i32 %i.0, 1
107  br label %for.cond
108
109for.end:                                          ; preds = %for.cond
110  ret i16 %p.0
111}
112