706 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 52; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s | FileCheck %s3 4; Test cases for selecting the index with the minimum value.5 6define i64 @test_vectorize_select_smin_idx(ptr %src, i64 %n) {7; CHECK-LABEL: define i64 @test_vectorize_select_smin_idx(8; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {9; CHECK-NEXT: [[ENTRY:.*]]:10; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 411; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]12; CHECK: [[VECTOR_PH]]:13; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N]], 414; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]]15; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]16; CHECK: [[VECTOR_BODY]]:17; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]18; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]19; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i64> [ splat (i64 -9223372036854775808), %[[VECTOR_PH]] ], [ [[TMP3:%.*]], %[[VECTOR_BODY]] ]20; CHECK-NEXT: [[VEC_PHI1:%.*]] = phi <4 x i64> [ zeroinitializer, %[[VECTOR_PH]] ], [ [[TMP2:%.*]], %[[VECTOR_BODY]] ]21; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]22; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[GEP]], align 423; CHECK-NEXT: [[TMP1:%.*]] = icmp sge <4 x i64> [[VEC_PHI1]], [[WIDE_LOAD]]24; CHECK-NEXT: [[TMP2]] = call <4 x i64> @llvm.smin.v4i64(<4 x i64> [[VEC_PHI1]], <4 x i64> [[WIDE_LOAD]])25; CHECK-NEXT: [[TMP3]] = select <4 x i1> [[TMP1]], <4 x i64> [[VEC_IND]], <4 x i64> [[VEC_PHI]]26; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[IV]], 427; CHECK-NEXT: [[VEC_IND_NEXT]] = add nuw nsw <4 x i64> [[VEC_IND]], splat (i64 4)28; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]29; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]30; CHECK: [[MIDDLE_BLOCK]]:31; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vector.reduce.smin.v4i64(<4 x i64> [[TMP2]])32; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[TMP5]], i64 033; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer34; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i64> [[TMP2]], [[BROADCAST_SPLAT]]35; CHECK-NEXT: [[TMP7:%.*]] = select <4 x i1> [[TMP6]], <4 x i64> [[TMP3]], <4 x i64> splat (i64 -9223372036854775808)36; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.vector.reduce.smax.v4i64(<4 x i64> [[TMP7]])37; CHECK-NEXT: [[RDX_SELECT_CMP:%.*]] = icmp ne i64 [[TMP8]], -922337203685477580838; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[RDX_SELECT_CMP]], i64 [[TMP8]], i64 039; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]40; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]41; CHECK: [[SCALAR_PH]]:42; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]43; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i64 [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]44; CHECK-NEXT: [[BC_MERGE_RDX2:%.*]] = phi i64 [ [[TMP5]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]45; CHECK-NEXT: br label %[[LOOP:.*]]46; CHECK: [[LOOP]]:47; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]48; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ [[BC_MERGE_RDX]], %[[SCALAR_PH]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]49; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ [[BC_MERGE_RDX2]], %[[SCALAR_PH]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]50; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV1]]51; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP1]], align 452; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]53; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])54; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV1]], i64 [[MIN_IDX]]55; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 156; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]57; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]58; CHECK: [[EXIT]]:59; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ], [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ]60; CHECK-NEXT: ret i64 [[RES]]61;62entry:63 br label %loop64 65loop:66 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]67 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]68 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]69 %gep = getelementptr i64, ptr %src, i64 %iv70 %l = load i64, ptr %gep71 %cmp = icmp sge i64 %min.val, %l72 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)73 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx74 %iv.next = add nuw nsw i64 %iv, 175 %exitcond.not = icmp eq i64 %iv.next, %n76 br i1 %exitcond.not, label %exit, label %loop77 78exit:79 %res = phi i64 [ %min.idx.next, %loop ]80 ret i64 %res81}82 83define i64 @test_vectorize_select_smin_idx_cond_flipped(ptr %src, i64 %n) {84; CHECK-LABEL: define i64 @test_vectorize_select_smin_idx_cond_flipped(85; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {86; CHECK-NEXT: [[ENTRY:.*]]:87; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 488; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]89; CHECK: [[VECTOR_PH]]:90; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N]], 491; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]]92; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]93; CHECK: [[VECTOR_BODY]]:94; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]95; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]96; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i64> [ splat (i64 -9223372036854775808), %[[VECTOR_PH]] ], [ [[TMP3:%.*]], %[[VECTOR_BODY]] ]97; CHECK-NEXT: [[VEC_PHI1:%.*]] = phi <4 x i64> [ zeroinitializer, %[[VECTOR_PH]] ], [ [[TMP2:%.*]], %[[VECTOR_BODY]] ]98; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV1]]99; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[GEP1]], align 4100; CHECK-NEXT: [[TMP1:%.*]] = icmp sle <4 x i64> [[WIDE_LOAD]], [[VEC_PHI1]]101; CHECK-NEXT: [[TMP2]] = call <4 x i64> @llvm.smin.v4i64(<4 x i64> [[VEC_PHI1]], <4 x i64> [[WIDE_LOAD]])102; CHECK-NEXT: [[TMP3]] = select <4 x i1> [[TMP1]], <4 x i64> [[VEC_IND]], <4 x i64> [[VEC_PHI]]103; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[IV1]], 4104; CHECK-NEXT: [[VEC_IND_NEXT]] = add nuw nsw <4 x i64> [[VEC_IND]], splat (i64 4)105; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]106; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]107; CHECK: [[MIDDLE_BLOCK]]:108; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vector.reduce.smin.v4i64(<4 x i64> [[TMP2]])109; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[TMP5]], i64 0110; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer111; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i64> [[TMP2]], [[BROADCAST_SPLAT]]112; CHECK-NEXT: [[TMP7:%.*]] = select <4 x i1> [[TMP6]], <4 x i64> [[TMP3]], <4 x i64> splat (i64 -9223372036854775808)113; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.vector.reduce.smax.v4i64(<4 x i64> [[TMP7]])114; CHECK-NEXT: [[RDX_SELECT_CMP:%.*]] = icmp ne i64 [[TMP8]], -9223372036854775808115; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[RDX_SELECT_CMP]], i64 [[TMP8]], i64 0116; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]117; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]118; CHECK: [[SCALAR_PH]]:119; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]120; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i64 [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]121; CHECK-NEXT: [[BC_MERGE_RDX2:%.*]] = phi i64 [ [[TMP5]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]122; CHECK-NEXT: br label %[[LOOP:.*]]123; CHECK: [[LOOP]]:124; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]125; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ [[BC_MERGE_RDX]], %[[SCALAR_PH]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]126; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ [[BC_MERGE_RDX2]], %[[SCALAR_PH]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]127; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]128; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4129; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[L]], [[MIN_VAL]]130; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])131; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]132; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1133; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]134; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]135; CHECK: [[EXIT]]:136; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ], [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ]137; CHECK-NEXT: ret i64 [[RES]]138;139entry:140 br label %loop141 142loop:143 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]144 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]145 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]146 %gep = getelementptr i64, ptr %src, i64 %iv147 %l = load i64, ptr %gep148 %cmp = icmp sle i64 %l, %min.val149 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)150 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx151 %iv.next = add nuw nsw i64 %iv, 1152 %exitcond.not = icmp eq i64 %iv.next, %n153 br i1 %exitcond.not, label %exit, label %loop154 155exit:156 %res = phi i64 [ %min.idx.next, %loop ]157 ret i64 %res158}159 160define i64 @test_vectorize_select_smin_idx_select_ops_flipped(ptr %src, i64 %n) {161; CHECK-LABEL: define i64 @test_vectorize_select_smin_idx_select_ops_flipped(162; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {163; CHECK-NEXT: [[ENTRY:.*]]:164; CHECK-NEXT: br label %[[LOOP:.*]]165; CHECK: [[LOOP]]:166; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]167; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]168; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]169; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV1]]170; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP1]], align 4171; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[L]], [[MIN_VAL]]172; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])173; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[MIN_IDX]], i64 [[IV1]]174; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 1175; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]176; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]177; CHECK: [[EXIT]]:178; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]179; CHECK-NEXT: ret i64 [[RES]]180;181entry:182 br label %loop183 184loop:185 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]186 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]187 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]188 %gep = getelementptr i64, ptr %src, i64 %iv189 %l = load i64, ptr %gep190 %cmp = icmp sle i64 %l, %min.val191 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)192 %min.idx.next = select i1 %cmp, i64 %min.idx, i64 %iv193 %iv.next = add nuw nsw i64 %iv, 1194 %exitcond.not = icmp eq i64 %iv.next, %n195 br i1 %exitcond.not, label %exit, label %loop196 197exit:198 %res = phi i64 [ %min.idx.next, %loop ]199 ret i64 %res200}201 202define i64 @test_vectorize_select_smin_via_select_idx(ptr %src, i64 %n) {203; CHECK-LABEL: define i64 @test_vectorize_select_smin_via_select_idx(204; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {205; CHECK-NEXT: [[ENTRY:.*]]:206; CHECK-NEXT: br label %[[LOOP:.*]]207; CHECK: [[LOOP]]:208; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]209; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]210; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]211; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]212; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4213; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]214; CHECK-NEXT: [[MIN_VAL_NEXT]] = select i1 [[CMP]], i64 [[L]], i64 [[MIN_VAL]]215; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]216; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1217; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]218; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]219; CHECK: [[EXIT]]:220; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]221; CHECK-NEXT: ret i64 [[RES]]222;223entry:224 br label %loop225 226loop:227 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]228 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]229 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]230 %gep = getelementptr i64, ptr %src, i64 %iv231 %l = load i64, ptr %gep232 %cmp = icmp sge i64 %min.val, %l233 %min.val.next = select i1 %cmp, i64 %l, i64 %min.val234 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx235 %iv.next = add nuw nsw i64 %iv, 1236 %exitcond.not = icmp eq i64 %iv.next, %n237 br i1 %exitcond.not, label %exit, label %loop238 239exit:240 %res = phi i64 [ %min.idx.next, %loop ]241 ret i64 %res242}243 244define i64 @test_vectorize_select_smin_idx_all_exit_inst(ptr %src, ptr %smin, i64 %n) {245; CHECK-LABEL: define i64 @test_vectorize_select_smin_idx_all_exit_inst(246; CHECK-SAME: ptr [[SRC:%.*]], ptr [[SMIN:%.*]], i64 [[N:%.*]]) {247; CHECK-NEXT: [[ENTRY:.*]]:248; CHECK-NEXT: br label %[[LOOP:.*]]249; CHECK: [[LOOP]]:250; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]251; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]252; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]253; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]254; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4255; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]256; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])257; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]258; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1259; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]260; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]261; CHECK: [[EXIT]]:262; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]263; CHECK-NEXT: [[RES_SMIN:%.*]] = phi i64 [ [[MIN_VAL_NEXT]], %[[LOOP]] ]264; CHECK-NEXT: store i64 [[RES_SMIN]], ptr [[SMIN]], align 4265; CHECK-NEXT: ret i64 [[RES]]266;267entry:268 br label %loop269 270loop:271 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]272 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]273 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]274 %gep = getelementptr i64, ptr %src, i64 %iv275 %l = load i64, ptr %gep276 %cmp = icmp sge i64 %min.val, %l277 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)278 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx279 %iv.next = add nuw nsw i64 %iv, 1280 %exitcond.not = icmp eq i64 %iv.next, %n281 br i1 %exitcond.not, label %exit, label %loop282 283exit:284 %res = phi i64 [ %min.idx.next, %loop ]285 %res.smin = phi i64 [ %min.val.next, %loop ]286 store i64 %res.smin, ptr %smin287 ret i64 %res288}289 290define i64 @test_vectorize_select_smin_idx_min_ops_switched(ptr %src, i64 %n) {291; CHECK-LABEL: define i64 @test_vectorize_select_smin_idx_min_ops_switched(292; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {293; CHECK-NEXT: [[ENTRY:.*]]:294; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4295; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]296; CHECK: [[VECTOR_PH]]:297; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N]], 4298; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]]299; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]300; CHECK: [[VECTOR_BODY]]:301; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]302; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]303; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i64> [ splat (i64 -9223372036854775808), %[[VECTOR_PH]] ], [ [[TMP3:%.*]], %[[VECTOR_BODY]] ]304; CHECK-NEXT: [[VEC_PHI1:%.*]] = phi <4 x i64> [ zeroinitializer, %[[VECTOR_PH]] ], [ [[TMP2:%.*]], %[[VECTOR_BODY]] ]305; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]306; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[GEP]], align 4307; CHECK-NEXT: [[TMP1:%.*]] = icmp sge <4 x i64> [[VEC_PHI1]], [[WIDE_LOAD]]308; CHECK-NEXT: [[TMP2]] = call <4 x i64> @llvm.smin.v4i64(<4 x i64> [[WIDE_LOAD]], <4 x i64> [[VEC_PHI1]])309; CHECK-NEXT: [[TMP3]] = select <4 x i1> [[TMP1]], <4 x i64> [[VEC_IND]], <4 x i64> [[VEC_PHI]]310; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[IV]], 4311; CHECK-NEXT: [[VEC_IND_NEXT]] = add nuw nsw <4 x i64> [[VEC_IND]], splat (i64 4)312; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]313; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]314; CHECK: [[MIDDLE_BLOCK]]:315; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vector.reduce.smin.v4i64(<4 x i64> [[TMP2]])316; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[TMP5]], i64 0317; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer318; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i64> [[TMP2]], [[BROADCAST_SPLAT]]319; CHECK-NEXT: [[TMP7:%.*]] = select <4 x i1> [[TMP6]], <4 x i64> [[TMP3]], <4 x i64> splat (i64 -9223372036854775808)320; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.vector.reduce.smax.v4i64(<4 x i64> [[TMP7]])321; CHECK-NEXT: [[RDX_SELECT_CMP:%.*]] = icmp ne i64 [[TMP8]], -9223372036854775808322; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[RDX_SELECT_CMP]], i64 [[TMP8]], i64 0323; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]324; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]325; CHECK: [[SCALAR_PH]]:326; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]327; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i64 [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]328; CHECK-NEXT: [[BC_MERGE_RDX2:%.*]] = phi i64 [ [[TMP5]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]329; CHECK-NEXT: br label %[[LOOP:.*]]330; CHECK: [[LOOP]]:331; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]332; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ [[BC_MERGE_RDX]], %[[SCALAR_PH]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]333; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ [[BC_MERGE_RDX2]], %[[SCALAR_PH]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]334; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV1]]335; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP1]], align 4336; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]337; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[L]], i64 [[MIN_VAL]])338; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV1]], i64 [[MIN_IDX]]339; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 1340; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]341; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT]], label %[[LOOP]], !llvm.loop [[LOOP7:![0-9]+]]342; CHECK: [[EXIT]]:343; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ], [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ]344; CHECK-NEXT: ret i64 [[RES]]345;346entry:347 br label %loop348 349loop:350 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]351 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]352 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]353 %gep = getelementptr i64, ptr %src, i64 %iv354 %l = load i64, ptr %gep355 %cmp = icmp sge i64 %min.val, %l356 %min.val.next = tail call i64 @llvm.smin.i64(i64 %l, i64 %min.val)357 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx358 %iv.next = add nuw nsw i64 %iv, 1359 %exitcond.not = icmp eq i64 %iv.next, %n360 br i1 %exitcond.not, label %exit, label %loop361 362exit:363 %res = phi i64 [ %min.idx.next, %loop ]364 ret i64 %res365}366 367define i64 @test_not_vectorize_select_no_min_reduction(ptr %src, i64 %n) {368; CHECK-LABEL: define i64 @test_not_vectorize_select_no_min_reduction(369; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {370; CHECK-NEXT: [[ENTRY:.*]]:371; CHECK-NEXT: br label %[[LOOP:.*]]372; CHECK: [[LOOP]]:373; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]374; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]375; CHECK-NEXT: [[RED_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[RED_VAL_NEXT:%.*]], %[[LOOP]] ]376; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]377; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4378; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[RED_VAL]], [[L]]379; CHECK-NEXT: [[RED_VAL_NEXT]] = add i64 [[RED_VAL]], [[L]]380; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]381; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1382; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]383; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]384; CHECK: [[EXIT]]:385; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]386; CHECK-NEXT: ret i64 [[RES]]387;388entry:389 br label %loop390 391loop:392 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]393 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]394 %red.val = phi i64 [ 0, %entry ], [ %red.val.next, %loop ]395 %gep = getelementptr i64, ptr %src, i64 %iv396 %l = load i64, ptr %gep397 %cmp = icmp sge i64 %red.val, %l398 %red.val.next = add i64 %red.val, %l399 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx400 %iv.next = add nuw nsw i64 %iv, 1401 %exitcond.not = icmp eq i64 %iv.next, %n402 br i1 %exitcond.not, label %exit, label %loop403 404exit:405 %res = phi i64 [ %min.idx.next, %loop ]406 ret i64 %res407}408 409define i64 @test_cmp_and_smin_use_different_values(ptr %src, i64 %x, i64 %n) {410; CHECK-LABEL: define i64 @test_cmp_and_smin_use_different_values(411; CHECK-SAME: ptr [[SRC:%.*]], i64 [[X:%.*]], i64 [[N:%.*]]) {412; CHECK-NEXT: [[ENTRY:.*]]:413; CHECK-NEXT: br label %[[LOOP:.*]]414; CHECK: [[LOOP]]:415; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]416; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]417; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]418; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]419; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4420; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[X]]421; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])422; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]423; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1424; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]425; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]426; CHECK: [[EXIT]]:427; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]428; CHECK-NEXT: ret i64 [[RES]]429;430entry:431 br label %loop432 433loop:434 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]435 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]436 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]437 %gep = getelementptr i64, ptr %src, i64 %iv438 %l = load i64, ptr %gep439 %cmp = icmp sge i64 %min.val, %x440 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)441 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx442 %iv.next = add nuw nsw i64 %iv, 1443 %exitcond.not = icmp eq i64 %iv.next, %n444 br i1 %exitcond.not, label %exit, label %loop445 446exit:447 %res = phi i64 [ %min.idx.next, %loop ]448 ret i64 %res449}450 451define i32 @test_vectorize_select_smin_idx_with_trunc(ptr %src, i64 %n) {452; CHECK-LABEL: define i32 @test_vectorize_select_smin_idx_with_trunc(453; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {454; CHECK-NEXT: [[ENTRY:.*]]:455; CHECK-NEXT: br label %[[LOOP:.*]]456; CHECK: [[LOOP]]:457; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]458; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]459; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]460; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]461; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4462; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]463; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])464; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[IV]] to i32465; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i32 [[TRUNC]], i32 [[MIN_IDX]]466; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1467; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]468; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]469; CHECK: [[EXIT]]:470; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]471; CHECK-NEXT: ret i32 [[RES]]472;473entry:474 br label %loop475 476loop:477 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]478 %min.idx = phi i32 [ 0, %entry ], [ %min.idx.next, %loop ]479 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]480 %gep = getelementptr i64, ptr %src, i64 %iv481 %l = load i64, ptr %gep482 %cmp = icmp sge i64 %min.val, %l483 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)484 %trunc = trunc i64 %iv to i32485 %min.idx.next = select i1 %cmp, i32 %trunc, i32 %min.idx486 %iv.next = add nuw nsw i64 %iv, 1487 %exitcond.not = icmp eq i64 %iv.next, %n488 br i1 %exitcond.not, label %exit, label %loop489 490exit:491 %res = phi i32 [ %min.idx.next, %loop ]492 ret i32 %res493}494 495define ptr @test_with_ptr_index(ptr %start, ptr %end) {496; CHECK-LABEL: define ptr @test_with_ptr_index(497; CHECK-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) {498; CHECK-NEXT: [[ENTRY:.*]]:499; CHECK-NEXT: br label %[[LOOP:.*]]500; CHECK: [[LOOP]]:501; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]502; CHECK-NEXT: [[MIN_IDX:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]503; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]504; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[IV]], align 4505; CHECK-NEXT: [[CMP7_US:%.*]] = icmp sle i64 [[L]], [[MIN_VAL]]506; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])507; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP7_US]], ptr [[IV]], ptr [[MIN_IDX]]508; CHECK-NEXT: [[IV_NEXT]] = getelementptr i32, ptr [[IV]], i64 1509; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq ptr [[IV_NEXT]], [[END]]510; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]511; CHECK: [[EXIT]]:512; CHECK-NEXT: [[RES:%.*]] = phi ptr [ [[MIN_IDX_NEXT]], %[[LOOP]] ]513; CHECK-NEXT: ret ptr [[RES]]514;515entry:516 br label %loop517 518loop:519 %iv = phi ptr [ %start, %entry ], [ %iv.next, %loop ]520 %min.idx = phi ptr [ null, %entry ], [ %min.idx.next, %loop ]521 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]522 %l = load i64, ptr %iv523 %cmp7.us = icmp sle i64 %l, %min.val524 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)525 %min.idx.next = select i1 %cmp7.us, ptr %iv, ptr %min.idx526 %iv.next = getelementptr i32, ptr %iv, i64 1527 %exitcond.not = icmp eq ptr %iv.next, %end528 br i1 %exitcond.not, label %exit, label %loop529 530exit:531 %res = phi ptr [ %min.idx.next, %loop ]532 ret ptr %res533}534 535define i64 @test_no_vectorize_select_iv_decrement(ptr %src) {536; CHECK-LABEL: define i64 @test_no_vectorize_select_iv_decrement(537; CHECK-SAME: ptr [[SRC:%.*]]) {538; CHECK-NEXT: [[ENTRY:.*]]:539; CHECK-NEXT: br label %[[LOOP:.*]]540; CHECK: [[LOOP]]:541; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1000, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]542; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]543; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]544; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]545; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4546; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]547; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])548; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]549; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], -1550; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 0551; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]552; CHECK: [[EXIT]]:553; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]554; CHECK-NEXT: ret i64 [[RES]]555;556entry:557 br label %loop558 559loop:560 %iv = phi i64 [ 1000, %entry ], [ %iv.next, %loop ]561 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]562 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]563 %gep = getelementptr i64, ptr %src, i64 %iv564 %l = load i64, ptr %gep565 %cmp = icmp sge i64 %min.val, %l566 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)567 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx568 %iv.next = add nuw nsw i64 %iv, -1569 %exitcond.not = icmp eq i64 %iv.next, 0570 br i1 %exitcond.not, label %exit, label %loop571 572exit:573 %res = phi i64 [ %min.idx.next, %loop ]574 ret i64 %res575}576 577define i64 @test_no_vectorize_select_iv_sub(ptr %src) {578; CHECK-LABEL: define i64 @test_no_vectorize_select_iv_sub(579; CHECK-SAME: ptr [[SRC:%.*]]) {580; CHECK-NEXT: [[ENTRY:.*]]:581; CHECK-NEXT: br label %[[LOOP:.*]]582; CHECK: [[LOOP]]:583; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1000, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]584; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]585; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]586; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]587; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4588; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]589; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])590; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]591; CHECK-NEXT: [[IV_NEXT]] = sub i64 [[IV]], 1592; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 0593; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]594; CHECK: [[EXIT]]:595; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]596; CHECK-NEXT: ret i64 [[RES]]597;598entry:599 br label %loop600 601loop:602 %iv = phi i64 [ 1000, %entry ], [ %iv.next, %loop ]603 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]604 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]605 %gep = getelementptr i64, ptr %src, i64 %iv606 %l = load i64, ptr %gep607 %cmp = icmp sge i64 %min.val, %l608 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)609 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx610 %iv.next = sub i64 %iv, 1611 %exitcond.not = icmp eq i64 %iv.next, 0612 br i1 %exitcond.not, label %exit, label %loop613 614exit:615 %res = phi i64 [ %min.idx.next, %loop ]616 ret i64 %res617}618 619define i64 @test_no_vectorize_select_iv_mul(ptr %src) {620; CHECK-LABEL: define i64 @test_no_vectorize_select_iv_mul(621; CHECK-SAME: ptr [[SRC:%.*]]) {622; CHECK-NEXT: [[ENTRY:.*]]:623; CHECK-NEXT: br label %[[LOOP:.*]]624; CHECK: [[LOOP]]:625; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]626; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]627; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]628; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]629; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4630; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]631; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])632; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]633; CHECK-NEXT: [[IV_NEXT]] = mul i64 [[IV]], 2634; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 128635; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]636; CHECK: [[EXIT]]:637; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]638; CHECK-NEXT: ret i64 [[RES]]639;640entry:641 br label %loop642 643loop:644 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]645 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]646 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]647 %gep = getelementptr i64, ptr %src, i64 %iv648 %l = load i64, ptr %gep649 %cmp = icmp sge i64 %min.val, %l650 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)651 %min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx652 %iv.next = mul i64 %iv, 2653 %exitcond.not = icmp eq i64 %iv.next, 128654 br i1 %exitcond.not, label %exit, label %loop655 656exit:657 %res = phi i64 [ %min.idx.next, %loop ]658 ret i64 %res659}660 661define i64 @test_vectorize_select_smin_idx_inc(ptr %src, i64 %n) {662; CHECK-LABEL: define i64 @test_vectorize_select_smin_idx_inc(663; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {664; CHECK-NEXT: [[ENTRY:.*]]:665; CHECK-NEXT: br label %[[LOOP:.*]]666; CHECK: [[LOOP]]:667; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]668; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]669; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]670; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]671; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 4672; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]673; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])674; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1675; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV_NEXT]], i64 [[MIN_IDX]]676; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]677; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]678; CHECK: [[EXIT]]:679; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]680; CHECK-NEXT: ret i64 [[RES]]681;682entry:683 br label %loop684 685loop:686 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]687 %min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]688 %min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]689 %gep = getelementptr i64, ptr %src, i64 %iv690 %l = load i64, ptr %gep691 %cmp = icmp sge i64 %min.val, %l692 %min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)693 %iv.next = add nuw nsw i64 %iv, 1694 %min.idx.next = select i1 %cmp, i64 %iv.next, i64 %min.idx695 %exitcond.not = icmp eq i64 %iv.next, %n696 br i1 %exitcond.not, label %exit, label %loop697 698exit:699 %res = phi i64 [ %min.idx.next, %loop ]700 ret i64 %res701}702 703 704declare i64 @llvm.smin.i64(i64, i64)705declare i16 @llvm.smin.i16(i16, i16)706