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