brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.5 KiB · 9676925 Raw
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