xref: /llvm-project/llvm/test/Transforms/LoopVectorize/select-min-index.ll (revision b3cba9be41bfa89bc0ec212706c6028a901e127a)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s | FileCheck %s --check-prefix=CHECK-VF4IC1
3; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=2 -S %s | FileCheck %s --check-prefix=CHECK-VF4IC2
4; RUN: opt -passes=loop-vectorize -force-vector-width=1 -force-vector-interleave=2 -S %s | FileCheck %s --check-prefix=CHECK-VF1IC2
5
6; Test cases for selecting the index with the minimum value.
7
8define i64 @test_vectorize_select_umin_idx(ptr %src, i64 %n) {
9; CHECK-VF4IC1-LABEL: define i64 @test_vectorize_select_umin_idx(
10; CHECK-VF4IC1-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
11; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
12; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
13; CHECK-VF4IC1:       [[LOOP]]:
14; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
15; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
16; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
17; CHECK-VF4IC1-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
18; CHECK-VF4IC1-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
19; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
20; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
21; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
22; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
23; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
24; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
25; CHECK-VF4IC1:       [[EXIT]]:
26; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
27; CHECK-VF4IC1-NEXT:    ret i64 [[RES]]
28;
29; CHECK-VF4IC2-LABEL: define i64 @test_vectorize_select_umin_idx(
30; CHECK-VF4IC2-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
31; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
32; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
33; CHECK-VF4IC2:       [[LOOP]]:
34; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
35; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
36; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
37; CHECK-VF4IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
38; CHECK-VF4IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
39; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
40; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
41; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
42; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
43; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
44; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
45; CHECK-VF4IC2:       [[EXIT]]:
46; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
47; CHECK-VF4IC2-NEXT:    ret i64 [[RES]]
48;
49; CHECK-VF1IC2-LABEL: define i64 @test_vectorize_select_umin_idx(
50; CHECK-VF1IC2-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
51; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
52; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
53; CHECK-VF1IC2:       [[LOOP]]:
54; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
55; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
56; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
57; CHECK-VF1IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
58; CHECK-VF1IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
59; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
60; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
61; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
62; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
63; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
64; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
65; CHECK-VF1IC2:       [[EXIT]]:
66; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
67; CHECK-VF1IC2-NEXT:    ret i64 [[RES]]
68;
69entry:
70  br label %loop
71
72loop:
73  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
74  %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
75  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
76  %gep = getelementptr i64, ptr %src, i64 %iv
77  %l = load i64, ptr %gep
78  %cmp = icmp ugt i64 %min.val, %l
79  %min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
80  %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
81  %iv.next = add nuw nsw i64 %iv, 1
82  %exitcond.not = icmp eq i64 %iv.next, %n
83  br i1 %exitcond.not, label %exit, label %loop
84
85exit:
86  %res = phi i64 [ %min.idx.next, %loop ]
87  ret i64 %res
88}
89
90define i64 @test_vectorize_select_umin_idx_all_exit_inst(ptr %src, ptr %umin, i64 %n) {
91; CHECK-VF4IC1-LABEL: define i64 @test_vectorize_select_umin_idx_all_exit_inst(
92; CHECK-VF4IC1-SAME: ptr [[SRC:%.*]], ptr [[UMIN:%.*]], i64 [[N:%.*]]) {
93; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
94; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
95; CHECK-VF4IC1:       [[LOOP]]:
96; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
97; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
98; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
99; CHECK-VF4IC1-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
100; CHECK-VF4IC1-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
101; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
102; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
103; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
104; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
105; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
106; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
107; CHECK-VF4IC1:       [[EXIT]]:
108; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
109; CHECK-VF4IC1-NEXT:    [[RES_UMIN:%.*]] = phi i64 [ [[MIN_VAL_NEXT]], %[[LOOP]] ]
110; CHECK-VF4IC1-NEXT:    store i64 [[RES_UMIN]], ptr [[UMIN]], align 4
111; CHECK-VF4IC1-NEXT:    ret i64 [[RES]]
112;
113; CHECK-VF4IC2-LABEL: define i64 @test_vectorize_select_umin_idx_all_exit_inst(
114; CHECK-VF4IC2-SAME: ptr [[SRC:%.*]], ptr [[UMIN:%.*]], i64 [[N:%.*]]) {
115; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
116; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
117; CHECK-VF4IC2:       [[LOOP]]:
118; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
119; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
120; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
121; CHECK-VF4IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
122; CHECK-VF4IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
123; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
124; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
125; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
126; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
127; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
128; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
129; CHECK-VF4IC2:       [[EXIT]]:
130; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
131; CHECK-VF4IC2-NEXT:    [[RES_UMIN:%.*]] = phi i64 [ [[MIN_VAL_NEXT]], %[[LOOP]] ]
132; CHECK-VF4IC2-NEXT:    store i64 [[RES_UMIN]], ptr [[UMIN]], align 4
133; CHECK-VF4IC2-NEXT:    ret i64 [[RES]]
134;
135; CHECK-VF1IC2-LABEL: define i64 @test_vectorize_select_umin_idx_all_exit_inst(
136; CHECK-VF1IC2-SAME: ptr [[SRC:%.*]], ptr [[UMIN:%.*]], i64 [[N:%.*]]) {
137; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
138; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
139; CHECK-VF1IC2:       [[LOOP]]:
140; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
141; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
142; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
143; CHECK-VF1IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
144; CHECK-VF1IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
145; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
146; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
147; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
148; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
149; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
150; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
151; CHECK-VF1IC2:       [[EXIT]]:
152; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
153; CHECK-VF1IC2-NEXT:    [[RES_UMIN:%.*]] = phi i64 [ [[MIN_VAL_NEXT]], %[[LOOP]] ]
154; CHECK-VF1IC2-NEXT:    store i64 [[RES_UMIN]], ptr [[UMIN]], align 4
155; CHECK-VF1IC2-NEXT:    ret i64 [[RES]]
156;
157entry:
158  br label %loop
159
160loop:
161  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
162  %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
163  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
164  %gep = getelementptr i64, ptr %src, i64 %iv
165  %l = load i64, ptr %gep
166  %cmp = icmp ugt i64 %min.val, %l
167  %min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
168  %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
169  %iv.next = add nuw nsw i64 %iv, 1
170  %exitcond.not = icmp eq i64 %iv.next, %n
171  br i1 %exitcond.not, label %exit, label %loop
172
173exit:
174  %res = phi i64 [ %min.idx.next, %loop ]
175  %res.umin = phi i64 [ %min.val.next, %loop ]
176  store i64 %res.umin, ptr %umin
177  ret i64 %res
178}
179
180define i64 @test_vectorize_select_umin_idx_min_ops_switched(ptr %src, i64 %n) {
181; CHECK-VF4IC1-LABEL: define i64 @test_vectorize_select_umin_idx_min_ops_switched(
182; CHECK-VF4IC1-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
183; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
184; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
185; CHECK-VF4IC1:       [[LOOP]]:
186; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
187; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
188; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
189; CHECK-VF4IC1-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
190; CHECK-VF4IC1-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
191; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
192; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[L]], i64 [[MIN_VAL]])
193; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
194; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
195; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
196; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
197; CHECK-VF4IC1:       [[EXIT]]:
198; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
199; CHECK-VF4IC1-NEXT:    ret i64 [[RES]]
200;
201; CHECK-VF4IC2-LABEL: define i64 @test_vectorize_select_umin_idx_min_ops_switched(
202; CHECK-VF4IC2-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
203; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
204; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
205; CHECK-VF4IC2:       [[LOOP]]:
206; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
207; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
208; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
209; CHECK-VF4IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
210; CHECK-VF4IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
211; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
212; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[L]], i64 [[MIN_VAL]])
213; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
214; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
215; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
216; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
217; CHECK-VF4IC2:       [[EXIT]]:
218; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
219; CHECK-VF4IC2-NEXT:    ret i64 [[RES]]
220;
221; CHECK-VF1IC2-LABEL: define i64 @test_vectorize_select_umin_idx_min_ops_switched(
222; CHECK-VF1IC2-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
223; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
224; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
225; CHECK-VF1IC2:       [[LOOP]]:
226; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
227; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
228; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
229; CHECK-VF1IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
230; CHECK-VF1IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
231; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
232; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[L]], i64 [[MIN_VAL]])
233; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
234; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
235; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
236; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
237; CHECK-VF1IC2:       [[EXIT]]:
238; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
239; CHECK-VF1IC2-NEXT:    ret i64 [[RES]]
240;
241entry:
242  br label %loop
243
244loop:
245  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
246  %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
247  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
248  %gep = getelementptr i64, ptr %src, i64 %iv
249  %l = load i64, ptr %gep
250  %cmp = icmp ugt i64 %min.val, %l
251  %min.val.next = tail call i64 @llvm.umin.i64(i64 %l, i64 %min.val)
252  %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
253  %iv.next = add nuw nsw i64 %iv, 1
254  %exitcond.not = icmp eq i64 %iv.next, %n
255  br i1 %exitcond.not, label %exit, label %loop
256
257exit:
258  %res = phi i64 [ %min.idx.next, %loop ]
259  ret i64 %res
260}
261
262define i64 @test_not_vectorize_select_no_min_reduction(ptr %src, i64 %n) {
263; CHECK-VF4IC1-LABEL: define i64 @test_not_vectorize_select_no_min_reduction(
264; CHECK-VF4IC1-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
265; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
266; CHECK-VF4IC1-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4
267; CHECK-VF4IC1-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
268; CHECK-VF4IC1:       [[VECTOR_PH]]:
269; CHECK-VF4IC1-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[N]], 4
270; CHECK-VF4IC1-NEXT:    [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]]
271; CHECK-VF4IC1-NEXT:    br label %[[VECTOR_BODY:.*]]
272; CHECK-VF4IC1:       [[VECTOR_BODY]]:
273; CHECK-VF4IC1-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
274; CHECK-VF4IC1-NEXT:    [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
275; CHECK-VF4IC1-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i64> [ splat (i64 -9223372036854775808), %[[VECTOR_PH]] ], [ [[TMP6:%.*]], %[[VECTOR_BODY]] ]
276; CHECK-VF4IC1-NEXT:    [[VECTOR_RECUR:%.*]] = phi <4 x i64> [ <i64 poison, i64 poison, i64 poison, i64 0>, %[[VECTOR_PH]] ], [ [[TMP3:%.*]], %[[VECTOR_BODY]] ]
277; CHECK-VF4IC1-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
278; CHECK-VF4IC1-NEXT:    [[TMP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[TMP0]]
279; CHECK-VF4IC1-NEXT:    [[TMP2:%.*]] = getelementptr i64, ptr [[TMP1]], i32 0
280; CHECK-VF4IC1-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 4
281; CHECK-VF4IC1-NEXT:    [[TMP3]] = add <4 x i64> [[WIDE_LOAD]], splat (i64 1)
282; CHECK-VF4IC1-NEXT:    [[TMP4:%.*]] = shufflevector <4 x i64> [[VECTOR_RECUR]], <4 x i64> [[TMP3]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
283; CHECK-VF4IC1-NEXT:    [[TMP5:%.*]] = icmp ugt <4 x i64> [[TMP4]], [[WIDE_LOAD]]
284; CHECK-VF4IC1-NEXT:    [[TMP6]] = select <4 x i1> [[TMP5]], <4 x i64> [[VEC_IND]], <4 x i64> [[VEC_PHI]]
285; CHECK-VF4IC1-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
286; CHECK-VF4IC1-NEXT:    [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4)
287; CHECK-VF4IC1-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
288; CHECK-VF4IC1-NEXT:    br i1 [[TMP7]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
289; CHECK-VF4IC1:       [[MIDDLE_BLOCK]]:
290; CHECK-VF4IC1-NEXT:    [[TMP8:%.*]] = call i64 @llvm.vector.reduce.smax.v4i64(<4 x i64> [[TMP6]])
291; CHECK-VF4IC1-NEXT:    [[RDX_SELECT_CMP:%.*]] = icmp ne i64 [[TMP8]], -9223372036854775808
292; CHECK-VF4IC1-NEXT:    [[RDX_SELECT:%.*]] = select i1 [[RDX_SELECT_CMP]], i64 [[TMP8]], i64 0
293; CHECK-VF4IC1-NEXT:    [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i64> [[TMP3]], i32 3
294; CHECK-VF4IC1-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
295; CHECK-VF4IC1-NEXT:    br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]
296; CHECK-VF4IC1:       [[SCALAR_PH]]:
297; CHECK-VF4IC1-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
298; CHECK-VF4IC1-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i64 [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
299; CHECK-VF4IC1-NEXT:    [[SCALAR_RECUR_INIT:%.*]] = phi i64 [ [[VECTOR_RECUR_EXTRACT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
300; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
301; CHECK-VF4IC1:       [[LOOP]]:
302; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
303; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ [[BC_MERGE_RDX]], %[[SCALAR_PH]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
304; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ [[SCALAR_RECUR_INIT]], %[[SCALAR_PH]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
305; CHECK-VF4IC1-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
306; CHECK-VF4IC1-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
307; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
308; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = add i64 [[L]], 1
309; CHECK-VF4IC1-NEXT:    [[FOO:%.*]] = call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
310; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
311; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
312; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
313; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
314; CHECK-VF4IC1:       [[EXIT]]:
315; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ], [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ]
316; CHECK-VF4IC1-NEXT:    ret i64 [[RES]]
317;
318; CHECK-VF4IC2-LABEL: define i64 @test_not_vectorize_select_no_min_reduction(
319; CHECK-VF4IC2-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
320; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
321; CHECK-VF4IC2-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 8
322; CHECK-VF4IC2-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
323; CHECK-VF4IC2:       [[VECTOR_PH]]:
324; CHECK-VF4IC2-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[N]], 8
325; CHECK-VF4IC2-NEXT:    [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]]
326; CHECK-VF4IC2-NEXT:    br label %[[VECTOR_BODY:.*]]
327; CHECK-VF4IC2:       [[VECTOR_BODY]]:
328; CHECK-VF4IC2-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
329; CHECK-VF4IC2-NEXT:    [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
330; CHECK-VF4IC2-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i64> [ splat (i64 -9223372036854775808), %[[VECTOR_PH]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ]
331; CHECK-VF4IC2-NEXT:    [[VEC_PHI1:%.*]] = phi <4 x i64> [ splat (i64 -9223372036854775808), %[[VECTOR_PH]] ], [ [[TMP11:%.*]], %[[VECTOR_BODY]] ]
332; CHECK-VF4IC2-NEXT:    [[VECTOR_RECUR:%.*]] = phi <4 x i64> [ <i64 poison, i64 poison, i64 poison, i64 0>, %[[VECTOR_PH]] ], [ [[TMP5:%.*]], %[[VECTOR_BODY]] ]
333; CHECK-VF4IC2-NEXT:    [[STEP_ADD:%.*]] = add <4 x i64> [[VEC_IND]], splat (i64 4)
334; CHECK-VF4IC2-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
335; CHECK-VF4IC2-NEXT:    [[TMP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[TMP0]]
336; CHECK-VF4IC2-NEXT:    [[TMP2:%.*]] = getelementptr i64, ptr [[TMP1]], i32 0
337; CHECK-VF4IC2-NEXT:    [[TMP3:%.*]] = getelementptr i64, ptr [[TMP1]], i32 4
338; CHECK-VF4IC2-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 4
339; CHECK-VF4IC2-NEXT:    [[WIDE_LOAD2:%.*]] = load <4 x i64>, ptr [[TMP3]], align 4
340; CHECK-VF4IC2-NEXT:    [[TMP4:%.*]] = add <4 x i64> [[WIDE_LOAD]], splat (i64 1)
341; CHECK-VF4IC2-NEXT:    [[TMP5]] = add <4 x i64> [[WIDE_LOAD2]], splat (i64 1)
342; CHECK-VF4IC2-NEXT:    [[TMP6:%.*]] = shufflevector <4 x i64> [[VECTOR_RECUR]], <4 x i64> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
343; CHECK-VF4IC2-NEXT:    [[TMP7:%.*]] = shufflevector <4 x i64> [[TMP4]], <4 x i64> [[TMP5]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
344; CHECK-VF4IC2-NEXT:    [[TMP8:%.*]] = icmp ugt <4 x i64> [[TMP6]], [[WIDE_LOAD]]
345; CHECK-VF4IC2-NEXT:    [[TMP9:%.*]] = icmp ugt <4 x i64> [[TMP7]], [[WIDE_LOAD2]]
346; CHECK-VF4IC2-NEXT:    [[TMP10]] = select <4 x i1> [[TMP8]], <4 x i64> [[VEC_IND]], <4 x i64> [[VEC_PHI]]
347; CHECK-VF4IC2-NEXT:    [[TMP11]] = select <4 x i1> [[TMP9]], <4 x i64> [[STEP_ADD]], <4 x i64> [[VEC_PHI1]]
348; CHECK-VF4IC2-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
349; CHECK-VF4IC2-NEXT:    [[VEC_IND_NEXT]] = add <4 x i64> [[STEP_ADD]], splat (i64 4)
350; CHECK-VF4IC2-NEXT:    [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
351; CHECK-VF4IC2-NEXT:    br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
352; CHECK-VF4IC2:       [[MIDDLE_BLOCK]]:
353; CHECK-VF4IC2-NEXT:    [[RDX_MINMAX:%.*]] = call <4 x i64> @llvm.smax.v4i64(<4 x i64> [[TMP10]], <4 x i64> [[TMP11]])
354; CHECK-VF4IC2-NEXT:    [[TMP13:%.*]] = call i64 @llvm.vector.reduce.smax.v4i64(<4 x i64> [[RDX_MINMAX]])
355; CHECK-VF4IC2-NEXT:    [[RDX_SELECT_CMP:%.*]] = icmp ne i64 [[TMP13]], -9223372036854775808
356; CHECK-VF4IC2-NEXT:    [[RDX_SELECT:%.*]] = select i1 [[RDX_SELECT_CMP]], i64 [[TMP13]], i64 0
357; CHECK-VF4IC2-NEXT:    [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i64> [[TMP5]], i32 3
358; CHECK-VF4IC2-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
359; CHECK-VF4IC2-NEXT:    br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]
360; CHECK-VF4IC2:       [[SCALAR_PH]]:
361; CHECK-VF4IC2-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
362; CHECK-VF4IC2-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i64 [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
363; CHECK-VF4IC2-NEXT:    [[SCALAR_RECUR_INIT:%.*]] = phi i64 [ [[VECTOR_RECUR_EXTRACT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
364; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
365; CHECK-VF4IC2:       [[LOOP]]:
366; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
367; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ [[BC_MERGE_RDX]], %[[SCALAR_PH]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
368; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ [[SCALAR_RECUR_INIT]], %[[SCALAR_PH]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
369; CHECK-VF4IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
370; CHECK-VF4IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
371; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
372; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = add i64 [[L]], 1
373; CHECK-VF4IC2-NEXT:    [[FOO:%.*]] = call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
374; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
375; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
376; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
377; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
378; CHECK-VF4IC2:       [[EXIT]]:
379; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ], [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ]
380; CHECK-VF4IC2-NEXT:    ret i64 [[RES]]
381;
382; CHECK-VF1IC2-LABEL: define i64 @test_not_vectorize_select_no_min_reduction(
383; CHECK-VF1IC2-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
384; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
385; CHECK-VF1IC2-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 2
386; CHECK-VF1IC2-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
387; CHECK-VF1IC2:       [[VECTOR_PH]]:
388; CHECK-VF1IC2-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[N]], 2
389; CHECK-VF1IC2-NEXT:    [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]]
390; CHECK-VF1IC2-NEXT:    br label %[[VECTOR_BODY:.*]]
391; CHECK-VF1IC2:       [[VECTOR_BODY]]:
392; CHECK-VF1IC2-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
393; CHECK-VF1IC2-NEXT:    [[VEC_PHI:%.*]] = phi i64 [ -9223372036854775808, %[[VECTOR_PH]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ]
394; CHECK-VF1IC2-NEXT:    [[VEC_PHI1:%.*]] = phi i64 [ -9223372036854775808, %[[VECTOR_PH]] ], [ [[TMP11:%.*]], %[[VECTOR_BODY]] ]
395; CHECK-VF1IC2-NEXT:    [[VECTOR_RECUR:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[TMP7:%.*]], %[[VECTOR_BODY]] ]
396; CHECK-VF1IC2-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
397; CHECK-VF1IC2-NEXT:    [[TMP1:%.*]] = add i64 [[INDEX]], 1
398; CHECK-VF1IC2-NEXT:    [[TMP2:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[TMP0]]
399; CHECK-VF1IC2-NEXT:    [[TMP3:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[TMP1]]
400; CHECK-VF1IC2-NEXT:    [[TMP4:%.*]] = load i64, ptr [[TMP2]], align 4
401; CHECK-VF1IC2-NEXT:    [[TMP5:%.*]] = load i64, ptr [[TMP3]], align 4
402; CHECK-VF1IC2-NEXT:    [[TMP6:%.*]] = add i64 [[TMP4]], 1
403; CHECK-VF1IC2-NEXT:    [[TMP7]] = add i64 [[TMP5]], 1
404; CHECK-VF1IC2-NEXT:    [[TMP8:%.*]] = icmp ugt i64 [[VECTOR_RECUR]], [[TMP4]]
405; CHECK-VF1IC2-NEXT:    [[TMP9:%.*]] = icmp ugt i64 [[TMP6]], [[TMP5]]
406; CHECK-VF1IC2-NEXT:    [[TMP10]] = select i1 [[TMP8]], i64 [[TMP0]], i64 [[VEC_PHI]]
407; CHECK-VF1IC2-NEXT:    [[TMP11]] = select i1 [[TMP9]], i64 [[TMP1]], i64 [[VEC_PHI1]]
408; CHECK-VF1IC2-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
409; CHECK-VF1IC2-NEXT:    [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
410; CHECK-VF1IC2-NEXT:    br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
411; CHECK-VF1IC2:       [[MIDDLE_BLOCK]]:
412; CHECK-VF1IC2-NEXT:    [[RDX_MINMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP10]], i64 [[TMP11]])
413; CHECK-VF1IC2-NEXT:    [[RDX_SELECT_CMP:%.*]] = icmp ne i64 [[RDX_MINMAX]], -9223372036854775808
414; CHECK-VF1IC2-NEXT:    [[RDX_SELECT:%.*]] = select i1 [[RDX_SELECT_CMP]], i64 [[RDX_MINMAX]], i64 0
415; CHECK-VF1IC2-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
416; CHECK-VF1IC2-NEXT:    br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]
417; CHECK-VF1IC2:       [[SCALAR_PH]]:
418; CHECK-VF1IC2-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
419; CHECK-VF1IC2-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i64 [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
420; CHECK-VF1IC2-NEXT:    [[SCALAR_RECUR_INIT:%.*]] = phi i64 [ [[TMP7]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
421; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
422; CHECK-VF1IC2:       [[LOOP]]:
423; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
424; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ [[BC_MERGE_RDX]], %[[SCALAR_PH]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
425; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ [[SCALAR_RECUR_INIT]], %[[SCALAR_PH]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
426; CHECK-VF1IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
427; CHECK-VF1IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
428; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
429; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = add i64 [[L]], 1
430; CHECK-VF1IC2-NEXT:    [[FOO:%.*]] = call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
431; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
432; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
433; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
434; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
435; CHECK-VF1IC2:       [[EXIT]]:
436; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ], [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ]
437; CHECK-VF1IC2-NEXT:    ret i64 [[RES]]
438;
439entry:
440  br label %loop
441
442loop:
443  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
444  %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
445  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
446  %gep = getelementptr i64, ptr %src, i64 %iv
447  %l = load i64, ptr %gep
448  %cmp = icmp ugt i64 %min.val, %l
449  %min.val.next = add i64 %l, 1
450  %foo = call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
451  %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
452  %iv.next = add nuw nsw i64 %iv, 1
453  %exitcond.not = icmp eq i64 %iv.next, %n
454  br i1 %exitcond.not, label %exit, label %loop
455
456exit:
457  %res = phi i64 [ %min.idx.next, %loop ]
458  ret i64 %res
459}
460
461
462define i64 @test_not_vectorize_cmp_value(i64 %x, i64 %n) {
463; CHECK-VF4IC1-LABEL: define i64 @test_not_vectorize_cmp_value(
464; CHECK-VF4IC1-SAME: i64 [[X:%.*]], i64 [[N:%.*]]) {
465; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
466; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
467; CHECK-VF4IC1:       [[LOOP]]:
468; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
469; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
470; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
471; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[X]]
472; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
473; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
474; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
475; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
476; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
477; CHECK-VF4IC1:       [[EXIT]]:
478; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
479; CHECK-VF4IC1-NEXT:    ret i64 [[RES]]
480;
481; CHECK-VF4IC2-LABEL: define i64 @test_not_vectorize_cmp_value(
482; CHECK-VF4IC2-SAME: i64 [[X:%.*]], i64 [[N:%.*]]) {
483; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
484; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
485; CHECK-VF4IC2:       [[LOOP]]:
486; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
487; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
488; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
489; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[X]]
490; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
491; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
492; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
493; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
494; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
495; CHECK-VF4IC2:       [[EXIT]]:
496; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
497; CHECK-VF4IC2-NEXT:    ret i64 [[RES]]
498;
499; CHECK-VF1IC2-LABEL: define i64 @test_not_vectorize_cmp_value(
500; CHECK-VF1IC2-SAME: i64 [[X:%.*]], i64 [[N:%.*]]) {
501; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
502; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
503; CHECK-VF1IC2:       [[LOOP]]:
504; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
505; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
506; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
507; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[X]]
508; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
509; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
510; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
511; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
512; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
513; CHECK-VF1IC2:       [[EXIT]]:
514; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
515; CHECK-VF1IC2-NEXT:    ret i64 [[RES]]
516;
517entry:
518  br label %loop
519
520loop:
521  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
522  %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
523  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
524  %cmp = icmp ugt i64 %min.val, %x
525  %min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 0)
526  %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
527  %iv.next = add nuw nsw i64 %iv, 1
528  %exitcond.not = icmp eq i64 %iv.next, %n
529  br i1 %exitcond.not, label %exit, label %loop
530
531exit:
532  %res = phi i64 [ %min.idx.next, %loop ]
533  ret i64 %res
534}
535
536define i32 @test_vectorize_select_umin_idx_with_trunc(i64 %n) {
537; CHECK-VF4IC1-LABEL: define i32 @test_vectorize_select_umin_idx_with_trunc(
538; CHECK-VF4IC1-SAME: i64 [[N:%.*]]) {
539; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
540; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
541; CHECK-VF4IC1:       [[LOOP]]:
542; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
543; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
544; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
545; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], 0
546; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
547; CHECK-VF4IC1-NEXT:    [[TRUNC:%.*]] = trunc i64 [[IV]] to i32
548; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i32 [[TRUNC]], i32 [[MIN_IDX]]
549; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
550; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
551; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
552; CHECK-VF4IC1:       [[EXIT]]:
553; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i32 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
554; CHECK-VF4IC1-NEXT:    ret i32 [[RES]]
555;
556; CHECK-VF4IC2-LABEL: define i32 @test_vectorize_select_umin_idx_with_trunc(
557; CHECK-VF4IC2-SAME: i64 [[N:%.*]]) {
558; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
559; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
560; CHECK-VF4IC2:       [[LOOP]]:
561; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
562; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
563; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
564; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], 0
565; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
566; CHECK-VF4IC2-NEXT:    [[TRUNC:%.*]] = trunc i64 [[IV]] to i32
567; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i32 [[TRUNC]], i32 [[MIN_IDX]]
568; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
569; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
570; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
571; CHECK-VF4IC2:       [[EXIT]]:
572; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i32 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
573; CHECK-VF4IC2-NEXT:    ret i32 [[RES]]
574;
575; CHECK-VF1IC2-LABEL: define i32 @test_vectorize_select_umin_idx_with_trunc(
576; CHECK-VF1IC2-SAME: i64 [[N:%.*]]) {
577; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
578; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
579; CHECK-VF1IC2:       [[LOOP]]:
580; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
581; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
582; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
583; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], 0
584; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
585; CHECK-VF1IC2-NEXT:    [[TRUNC:%.*]] = trunc i64 [[IV]] to i32
586; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i32 [[TRUNC]], i32 [[MIN_IDX]]
587; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
588; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
589; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
590; CHECK-VF1IC2:       [[EXIT]]:
591; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i32 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
592; CHECK-VF1IC2-NEXT:    ret i32 [[RES]]
593;
594entry:
595  br label %loop
596
597loop:
598  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
599  %min.idx = phi i32 [ 0, %entry ], [ %min.idx.next, %loop ]
600  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
601  %cmp = icmp ugt i64 %min.val, 0
602  %min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 0)
603  %trunc = trunc i64 %iv to i32
604  %min.idx.next = select i1 %cmp, i32 %trunc, i32 %min.idx
605  %iv.next = add nuw nsw i64 %iv, 1
606  %exitcond.not = icmp eq i64 %iv.next, %n
607  br i1 %exitcond.not, label %exit, label %loop
608
609exit:
610  %res = phi i32 [ %min.idx.next, %loop ]
611  ret i32 %res
612}
613
614define ptr @test_with_ptr_index(ptr %start, ptr %end) {
615; CHECK-VF4IC1-LABEL: define ptr @test_with_ptr_index(
616; CHECK-VF4IC1-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) {
617; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
618; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
619; CHECK-VF4IC1:       [[LOOP]]:
620; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
621; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
622; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
623; CHECK-VF4IC1-NEXT:    [[CMP7_US:%.*]] = icmp ult i64 0, 0
624; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
625; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP7_US]], ptr [[IV]], ptr [[MIN_IDX]]
626; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = getelementptr i32, ptr [[IV]], i64 1
627; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq ptr [[IV_NEXT]], [[END]]
628; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
629; CHECK-VF4IC1:       [[EXIT]]:
630; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi ptr [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
631; CHECK-VF4IC1-NEXT:    ret ptr [[RES]]
632;
633; CHECK-VF4IC2-LABEL: define ptr @test_with_ptr_index(
634; CHECK-VF4IC2-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) {
635; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
636; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
637; CHECK-VF4IC2:       [[LOOP]]:
638; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
639; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
640; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
641; CHECK-VF4IC2-NEXT:    [[CMP7_US:%.*]] = icmp ult i64 0, 0
642; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
643; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP7_US]], ptr [[IV]], ptr [[MIN_IDX]]
644; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = getelementptr i32, ptr [[IV]], i64 1
645; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq ptr [[IV_NEXT]], [[END]]
646; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
647; CHECK-VF4IC2:       [[EXIT]]:
648; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi ptr [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
649; CHECK-VF4IC2-NEXT:    ret ptr [[RES]]
650;
651; CHECK-VF1IC2-LABEL: define ptr @test_with_ptr_index(
652; CHECK-VF1IC2-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) {
653; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
654; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
655; CHECK-VF1IC2:       [[LOOP]]:
656; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
657; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
658; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
659; CHECK-VF1IC2-NEXT:    [[CMP7_US:%.*]] = icmp ult i64 0, 0
660; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 0)
661; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP7_US]], ptr [[IV]], ptr [[MIN_IDX]]
662; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = getelementptr i32, ptr [[IV]], i64 1
663; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq ptr [[IV_NEXT]], [[END]]
664; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
665; CHECK-VF1IC2:       [[EXIT]]:
666; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi ptr [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
667; CHECK-VF1IC2-NEXT:    ret ptr [[RES]]
668;
669entry:
670  br label %loop
671
672loop:
673  %iv = phi ptr [ %start, %entry ], [ %iv.next, %loop ]
674  %min.idx = phi ptr [ null, %entry ], [ %min.idx.next, %loop ]
675  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
676  %cmp7.us = icmp ult i64 0, 0
677  %min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 0)
678  %min.idx.next = select i1 %cmp7.us, ptr %iv, ptr %min.idx
679  %iv.next = getelementptr i32, ptr %iv, i64 1
680  %exitcond.not = icmp eq ptr %iv.next, %end
681  br i1 %exitcond.not, label %exit, label %loop
682
683exit:
684  %res = phi ptr [ %min.idx.next, %loop ]
685  ret ptr %res
686}
687
688define void @pointer_index(ptr %start) {
689; CHECK-VF4IC1-LABEL: define void @pointer_index(
690; CHECK-VF4IC1-SAME: ptr [[START:%.*]]) {
691; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
692; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
693; CHECK-VF4IC1:       [[LOOP]]:
694; CHECK-VF4IC1-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
695; CHECK-VF4IC1-NEXT:    [[PTR_IDX:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_SELECT:%.*]], %[[LOOP]] ]
696; CHECK-VF4IC1-NEXT:    [[CMP_I_I_I_I2531:%.*]] = icmp ult i16 0, 0
697; CHECK-VF4IC1-NEXT:    [[PTR_SELECT]] = select i1 [[CMP_I_I_I_I2531]], ptr [[PTR_IV]], ptr [[PTR_IDX]]
698; CHECK-VF4IC1-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i64 1
699; CHECK-VF4IC1-NEXT:    [[CMP_I_I10_NOT_I_I_I:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], null
700; CHECK-VF4IC1-NEXT:    br i1 [[CMP_I_I10_NOT_I_I_I]], label %[[EXIT:.*]], label %[[LOOP]]
701; CHECK-VF4IC1:       [[EXIT]]:
702; CHECK-VF4IC1-NEXT:    ret void
703;
704; CHECK-VF4IC2-LABEL: define void @pointer_index(
705; CHECK-VF4IC2-SAME: ptr [[START:%.*]]) {
706; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
707; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
708; CHECK-VF4IC2:       [[LOOP]]:
709; CHECK-VF4IC2-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
710; CHECK-VF4IC2-NEXT:    [[PTR_IDX:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_SELECT:%.*]], %[[LOOP]] ]
711; CHECK-VF4IC2-NEXT:    [[CMP_I_I_I_I2531:%.*]] = icmp ult i16 0, 0
712; CHECK-VF4IC2-NEXT:    [[PTR_SELECT]] = select i1 [[CMP_I_I_I_I2531]], ptr [[PTR_IV]], ptr [[PTR_IDX]]
713; CHECK-VF4IC2-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i64 1
714; CHECK-VF4IC2-NEXT:    [[CMP_I_I10_NOT_I_I_I:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], null
715; CHECK-VF4IC2-NEXT:    br i1 [[CMP_I_I10_NOT_I_I_I]], label %[[EXIT:.*]], label %[[LOOP]]
716; CHECK-VF4IC2:       [[EXIT]]:
717; CHECK-VF4IC2-NEXT:    ret void
718;
719; CHECK-VF1IC2-LABEL: define void @pointer_index(
720; CHECK-VF1IC2-SAME: ptr [[START:%.*]]) {
721; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
722; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
723; CHECK-VF1IC2:       [[LOOP]]:
724; CHECK-VF1IC2-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
725; CHECK-VF1IC2-NEXT:    [[PTR_IDX:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_SELECT:%.*]], %[[LOOP]] ]
726; CHECK-VF1IC2-NEXT:    [[CMP_I_I_I_I2531:%.*]] = icmp ult i16 0, 0
727; CHECK-VF1IC2-NEXT:    [[PTR_SELECT]] = select i1 [[CMP_I_I_I_I2531]], ptr [[PTR_IV]], ptr [[PTR_IDX]]
728; CHECK-VF1IC2-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i64 1
729; CHECK-VF1IC2-NEXT:    [[CMP_I_I10_NOT_I_I_I:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], null
730; CHECK-VF1IC2-NEXT:    br i1 [[CMP_I_I10_NOT_I_I_I]], label %[[EXIT:.*]], label %[[LOOP]]
731; CHECK-VF1IC2:       [[EXIT]]:
732; CHECK-VF1IC2-NEXT:    ret void
733;
734entry:
735  br label %loop
736
737loop:
738  %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop ]
739  %ptr.idx = phi ptr [ %start, %entry ], [ %ptr.select, %loop ]
740  %cmp.i.i.i.i2531 = icmp ult i16 0, 0
741  %ptr.select = select i1 %cmp.i.i.i.i2531, ptr %ptr.iv, ptr %ptr.idx
742  %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i64 1
743  %cmp.i.i10.not.i.i.i = icmp eq ptr %ptr.iv.next, null
744  br i1 %cmp.i.i10.not.i.i.i, label %exit, label %loop
745
746exit:
747  ret void
748}
749
750define ptr @pointer_index_2(ptr %start, ptr %end) {
751; CHECK-VF4IC1-LABEL: define ptr @pointer_index_2(
752; CHECK-VF4IC1-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) {
753; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
754; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
755; CHECK-VF4IC1:       [[LOOP]]:
756; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i16 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
757; CHECK-VF4IC1-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
758; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
759; CHECK-VF4IC1-NEXT:    [[CMP_I_I_I_I:%.*]] = icmp ult i16 0, [[MIN_VAL]]
760; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = call i16 @llvm.umin.i16(i16 0, i16 [[MIN_VAL]])
761; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP_I_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_IDX]]
762; CHECK-VF4IC1-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i64 1
763; CHECK-VF4IC1-NEXT:    [[EXIT_COND:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
764; CHECK-VF4IC1-NEXT:    br i1 [[EXIT_COND]], label %[[EXIT:.*]], label %[[LOOP]]
765; CHECK-VF4IC1:       [[EXIT]]:
766; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi ptr [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
767; CHECK-VF4IC1-NEXT:    ret ptr [[RES]]
768;
769; CHECK-VF4IC2-LABEL: define ptr @pointer_index_2(
770; CHECK-VF4IC2-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) {
771; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
772; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
773; CHECK-VF4IC2:       [[LOOP]]:
774; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i16 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
775; CHECK-VF4IC2-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
776; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
777; CHECK-VF4IC2-NEXT:    [[CMP_I_I_I_I:%.*]] = icmp ult i16 0, [[MIN_VAL]]
778; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = call i16 @llvm.umin.i16(i16 0, i16 [[MIN_VAL]])
779; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP_I_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_IDX]]
780; CHECK-VF4IC2-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i64 1
781; CHECK-VF4IC2-NEXT:    [[EXIT_COND:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
782; CHECK-VF4IC2-NEXT:    br i1 [[EXIT_COND]], label %[[EXIT:.*]], label %[[LOOP]]
783; CHECK-VF4IC2:       [[EXIT]]:
784; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi ptr [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
785; CHECK-VF4IC2-NEXT:    ret ptr [[RES]]
786;
787; CHECK-VF1IC2-LABEL: define ptr @pointer_index_2(
788; CHECK-VF1IC2-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) {
789; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
790; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
791; CHECK-VF1IC2:       [[LOOP]]:
792; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i16 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
793; CHECK-VF1IC2-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP]] ]
794; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
795; CHECK-VF1IC2-NEXT:    [[CMP_I_I_I_I:%.*]] = icmp ult i16 0, [[MIN_VAL]]
796; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = call i16 @llvm.umin.i16(i16 0, i16 [[MIN_VAL]])
797; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP_I_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_IDX]]
798; CHECK-VF1IC2-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i64 1
799; CHECK-VF1IC2-NEXT:    [[EXIT_COND:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
800; CHECK-VF1IC2-NEXT:    br i1 [[EXIT_COND]], label %[[EXIT:.*]], label %[[LOOP]]
801; CHECK-VF1IC2:       [[EXIT]]:
802; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi ptr [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
803; CHECK-VF1IC2-NEXT:    ret ptr [[RES]]
804;
805entry:
806  br label %loop
807
808loop:
809  %min.val  = phi i16 [ 0, %entry ], [ %min.val.next, %loop ]
810  %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop ]
811  %min.idx = phi ptr [ %start, %entry ], [ %min.idx.next, %loop ]
812  %cmp.i.i.i.i = icmp ult i16 0, %min.val
813  %min.val.next = call i16 @llvm.umin.i16(i16 0, i16 %min.val)
814  %min.idx.next = select i1 %cmp.i.i.i.i, ptr %ptr.iv, ptr %min.idx
815  %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i64 1
816  %exit.cond = icmp eq ptr %ptr.iv.next, %end
817  br i1 %exit.cond, label %exit, label %loop
818
819exit:
820  %res = phi ptr [ %min.idx.next, %loop ]
821  ret ptr %res
822}
823
824define i64 @test_no_vectorize_select_iv_decrement(ptr %src) {
825; CHECK-VF4IC1-LABEL: define i64 @test_no_vectorize_select_iv_decrement(
826; CHECK-VF4IC1-SAME: ptr [[SRC:%.*]]) {
827; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
828; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
829; CHECK-VF4IC1:       [[LOOP]]:
830; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ 1000, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
831; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
832; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
833; CHECK-VF4IC1-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
834; CHECK-VF4IC1-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
835; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
836; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
837; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
838; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], -1
839; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 0
840; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
841; CHECK-VF4IC1:       [[EXIT]]:
842; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
843; CHECK-VF4IC1-NEXT:    ret i64 [[RES]]
844;
845; CHECK-VF4IC2-LABEL: define i64 @test_no_vectorize_select_iv_decrement(
846; CHECK-VF4IC2-SAME: ptr [[SRC:%.*]]) {
847; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
848; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
849; CHECK-VF4IC2:       [[LOOP]]:
850; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ 1000, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
851; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
852; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
853; CHECK-VF4IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
854; CHECK-VF4IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
855; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
856; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
857; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
858; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], -1
859; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 0
860; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
861; CHECK-VF4IC2:       [[EXIT]]:
862; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
863; CHECK-VF4IC2-NEXT:    ret i64 [[RES]]
864;
865; CHECK-VF1IC2-LABEL: define i64 @test_no_vectorize_select_iv_decrement(
866; CHECK-VF1IC2-SAME: ptr [[SRC:%.*]]) {
867; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
868; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
869; CHECK-VF1IC2:       [[LOOP]]:
870; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ 1000, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
871; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
872; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
873; CHECK-VF1IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
874; CHECK-VF1IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
875; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
876; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
877; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
878; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], -1
879; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 0
880; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
881; CHECK-VF1IC2:       [[EXIT]]:
882; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
883; CHECK-VF1IC2-NEXT:    ret i64 [[RES]]
884;
885entry:
886  br label %loop
887
888loop:
889  %iv = phi i64 [ 1000, %entry ], [ %iv.next, %loop ]
890  %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
891  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
892  %gep = getelementptr i64, ptr %src, i64 %iv
893  %l = load i64, ptr %gep
894  %cmp = icmp ugt i64 %min.val, %l
895  %min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
896  %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
897  %iv.next = add nuw nsw i64 %iv, -1
898  %exitcond.not = icmp eq i64 %iv.next, 0
899  br i1 %exitcond.not, label %exit, label %loop
900
901exit:
902  %res = phi i64 [ %min.idx.next, %loop ]
903  ret i64 %res
904}
905
906define i64 @test_no_vectorize_select_iv_sub(ptr %src) {
907; CHECK-VF4IC1-LABEL: define i64 @test_no_vectorize_select_iv_sub(
908; CHECK-VF4IC1-SAME: ptr [[SRC:%.*]]) {
909; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
910; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
911; CHECK-VF4IC1:       [[LOOP]]:
912; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ 1000, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
913; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
914; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
915; CHECK-VF4IC1-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
916; CHECK-VF4IC1-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
917; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
918; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
919; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
920; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = sub i64 [[IV]], 1
921; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 0
922; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
923; CHECK-VF4IC1:       [[EXIT]]:
924; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
925; CHECK-VF4IC1-NEXT:    ret i64 [[RES]]
926;
927; CHECK-VF4IC2-LABEL: define i64 @test_no_vectorize_select_iv_sub(
928; CHECK-VF4IC2-SAME: ptr [[SRC:%.*]]) {
929; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
930; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
931; CHECK-VF4IC2:       [[LOOP]]:
932; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ 1000, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
933; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
934; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
935; CHECK-VF4IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
936; CHECK-VF4IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
937; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
938; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
939; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
940; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = sub i64 [[IV]], 1
941; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 0
942; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
943; CHECK-VF4IC2:       [[EXIT]]:
944; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
945; CHECK-VF4IC2-NEXT:    ret i64 [[RES]]
946;
947; CHECK-VF1IC2-LABEL: define i64 @test_no_vectorize_select_iv_sub(
948; CHECK-VF1IC2-SAME: ptr [[SRC:%.*]]) {
949; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
950; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
951; CHECK-VF1IC2:       [[LOOP]]:
952; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ 1000, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
953; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
954; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
955; CHECK-VF1IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
956; CHECK-VF1IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
957; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
958; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
959; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
960; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = sub i64 [[IV]], 1
961; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 0
962; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
963; CHECK-VF1IC2:       [[EXIT]]:
964; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
965; CHECK-VF1IC2-NEXT:    ret i64 [[RES]]
966;
967entry:
968  br label %loop
969
970loop:
971  %iv = phi i64 [ 1000, %entry ], [ %iv.next, %loop ]
972  %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
973  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
974  %gep = getelementptr i64, ptr %src, i64 %iv
975  %l = load i64, ptr %gep
976  %cmp = icmp ugt i64 %min.val, %l
977  %min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
978  %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
979  %iv.next = sub i64 %iv, 1
980  %exitcond.not = icmp eq i64 %iv.next, 0
981  br i1 %exitcond.not, label %exit, label %loop
982
983exit:
984  %res = phi i64 [ %min.idx.next, %loop ]
985  ret i64 %res
986}
987
988define i64 @test_no_vectorize_select_iv_mul(ptr %src) {
989; CHECK-VF4IC1-LABEL: define i64 @test_no_vectorize_select_iv_mul(
990; CHECK-VF4IC1-SAME: ptr [[SRC:%.*]]) {
991; CHECK-VF4IC1-NEXT:  [[ENTRY:.*]]:
992; CHECK-VF4IC1-NEXT:    br label %[[LOOP:.*]]
993; CHECK-VF4IC1:       [[LOOP]]:
994; CHECK-VF4IC1-NEXT:    [[IV:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
995; CHECK-VF4IC1-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
996; CHECK-VF4IC1-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
997; CHECK-VF4IC1-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
998; CHECK-VF4IC1-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
999; CHECK-VF4IC1-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
1000; CHECK-VF4IC1-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
1001; CHECK-VF4IC1-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
1002; CHECK-VF4IC1-NEXT:    [[IV_NEXT]] = mul i64 [[IV]], 2
1003; CHECK-VF4IC1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 128
1004; CHECK-VF4IC1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
1005; CHECK-VF4IC1:       [[EXIT]]:
1006; CHECK-VF4IC1-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
1007; CHECK-VF4IC1-NEXT:    ret i64 [[RES]]
1008;
1009; CHECK-VF4IC2-LABEL: define i64 @test_no_vectorize_select_iv_mul(
1010; CHECK-VF4IC2-SAME: ptr [[SRC:%.*]]) {
1011; CHECK-VF4IC2-NEXT:  [[ENTRY:.*]]:
1012; CHECK-VF4IC2-NEXT:    br label %[[LOOP:.*]]
1013; CHECK-VF4IC2:       [[LOOP]]:
1014; CHECK-VF4IC2-NEXT:    [[IV:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
1015; CHECK-VF4IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
1016; CHECK-VF4IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
1017; CHECK-VF4IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
1018; CHECK-VF4IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
1019; CHECK-VF4IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
1020; CHECK-VF4IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
1021; CHECK-VF4IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
1022; CHECK-VF4IC2-NEXT:    [[IV_NEXT]] = mul i64 [[IV]], 2
1023; CHECK-VF4IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 128
1024; CHECK-VF4IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
1025; CHECK-VF4IC2:       [[EXIT]]:
1026; CHECK-VF4IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
1027; CHECK-VF4IC2-NEXT:    ret i64 [[RES]]
1028;
1029; CHECK-VF1IC2-LABEL: define i64 @test_no_vectorize_select_iv_mul(
1030; CHECK-VF1IC2-SAME: ptr [[SRC:%.*]]) {
1031; CHECK-VF1IC2-NEXT:  [[ENTRY:.*]]:
1032; CHECK-VF1IC2-NEXT:    br label %[[LOOP:.*]]
1033; CHECK-VF1IC2:       [[LOOP]]:
1034; CHECK-VF1IC2-NEXT:    [[IV:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
1035; CHECK-VF1IC2-NEXT:    [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
1036; CHECK-VF1IC2-NEXT:    [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
1037; CHECK-VF1IC2-NEXT:    [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
1038; CHECK-VF1IC2-NEXT:    [[L:%.*]] = load i64, ptr [[GEP]], align 4
1039; CHECK-VF1IC2-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
1040; CHECK-VF1IC2-NEXT:    [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
1041; CHECK-VF1IC2-NEXT:    [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
1042; CHECK-VF1IC2-NEXT:    [[IV_NEXT]] = mul i64 [[IV]], 2
1043; CHECK-VF1IC2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 128
1044; CHECK-VF1IC2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
1045; CHECK-VF1IC2:       [[EXIT]]:
1046; CHECK-VF1IC2-NEXT:    [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
1047; CHECK-VF1IC2-NEXT:    ret i64 [[RES]]
1048;
1049entry:
1050  br label %loop
1051
1052loop:
1053  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
1054  %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
1055  %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
1056  %gep = getelementptr i64, ptr %src, i64 %iv
1057  %l = load i64, ptr %gep
1058  %cmp = icmp ugt i64 %min.val, %l
1059  %min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
1060  %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
1061  %iv.next = mul i64 %iv, 2
1062  %exitcond.not = icmp eq i64 %iv.next, 128
1063  br i1 %exitcond.not, label %exit, label %loop
1064
1065exit:
1066  %res = phi i64 [ %min.idx.next, %loop ]
1067  ret i64 %res
1068}
1069
1070declare i64 @llvm.umin.i64(i64, i64)
1071declare i16 @llvm.umin.i16(i16, i16)
1072;.
1073; CHECK-VF4IC1: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
1074; CHECK-VF4IC1: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
1075; CHECK-VF4IC1: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
1076; CHECK-VF4IC1: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
1077;.
1078; CHECK-VF4IC2: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
1079; CHECK-VF4IC2: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
1080; CHECK-VF4IC2: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
1081; CHECK-VF4IC2: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
1082;.
1083; CHECK-VF1IC2: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
1084; CHECK-VF1IC2: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
1085; CHECK-VF1IC2: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
1086; CHECK-VF1IC2: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]}
1087;.
1088