1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=loop-vectorize -force-vector-width=1 -force-vector-interleave=2 -S %s | FileCheck %s 3 4define void @test1_select_invariant(ptr %src.1, ptr %src.2, ptr %dst, i1 %c, i8 %n) { 5; CHECK-LABEL: @test1_select_invariant( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[PTR_SEL:%.*]] = select i1 [[C:%.*]], ptr [[SRC_1:%.*]], ptr [[SRC_2:%.*]] 8; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N:%.*]], -1 9; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32 10; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1 11; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP2]], 2 12; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 13; CHECK: vector.memcheck: 14; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[N]], -1 15; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i64 16; CHECK-NEXT: [[TMP5:%.*]] = add nuw nsw i64 [[TMP4]], 1 17; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[TMP5]] 18; CHECK-NEXT: [[UGLYGEP1:%.*]] = getelementptr i8, ptr [[PTR_SEL]], i64 1 19; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[DST]], [[UGLYGEP1]] 20; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[PTR_SEL]], [[UGLYGEP]] 21; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] 22; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 23; CHECK: vector.ph: 24; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP2]], 2 25; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP2]], [[N_MOD_VF]] 26; CHECK-NEXT: [[IND_END:%.*]] = trunc i32 [[N_VEC]] to i8 27; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 28; CHECK: vector.body: 29; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 30; CHECK-NEXT: [[OFFSET_IDX:%.*]] = trunc i32 [[INDEX]] to i8 31; CHECK-NEXT: [[INDUCTION:%.*]] = add i8 [[OFFSET_IDX]], 0 32; CHECK-NEXT: [[INDUCTION2:%.*]] = add i8 [[OFFSET_IDX]], 1 33; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[PTR_SEL]], align 8, !alias.scope !0 34; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION]] 35; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION2]] 36; CHECK-NEXT: store i8 [[TMP6]], ptr [[TMP7]], align 2, !alias.scope !3, !noalias !0 37; CHECK-NEXT: store i8 [[TMP6]], ptr [[TMP8]], align 2, !alias.scope !3, !noalias !0 38; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2 39; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] 40; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]] 41; CHECK: middle.block: 42; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP2]], [[N_VEC]] 43; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] 44; CHECK: scalar.ph: 45; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_MEMCHECK]] ], [ 0, [[ENTRY:%.*]] ] 46; CHECK-NEXT: br label [[LOOP:%.*]] 47; CHECK: loop: 48; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 49; CHECK-NEXT: [[L_1:%.*]] = load i8, ptr [[PTR_SEL]], align 8 50; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i8, ptr [[DST]], i8 [[IV]] 51; CHECK-NEXT: store i8 [[L_1]], ptr [[GEP_DST]], align 2 52; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 53; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[IV_NEXT]], [[N]] 54; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP8:![0-9]+]] 55; CHECK: exit: 56; CHECK-NEXT: ret void 57; 58entry: 59 %ptr.sel = select i1 %c, ptr %src.1, ptr %src.2 60 br label %loop 61 62loop: 63 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ] 64 %l.1 = load i8, ptr %ptr.sel, align 8 65 %gep.dst = getelementptr i8, ptr %dst, i8 %iv 66 store i8 %l.1, ptr %gep.dst, align 2 67 %iv.next = add nsw nuw i8 %iv, 1 68 %ec = icmp eq i8 %iv.next, %n 69 br i1 %ec, label %exit, label %loop 70 71exit: 72 ret void 73} 74 75define void @test_loop_dependent_select1(ptr %src.1, ptr %src.2, ptr %dst, i1 %c, i8 %n) { 76; CHECK-LABEL: @test_loop_dependent_select1( 77; CHECK-NEXT: entry: 78; CHECK-NEXT: [[SRC_23:%.*]] = ptrtoint ptr [[SRC_2:%.*]] to i64 79; CHECK-NEXT: [[SRC_12:%.*]] = ptrtoint ptr [[SRC_1:%.*]] to i64 80; CHECK-NEXT: [[DST1:%.*]] = ptrtoint ptr [[DST:%.*]] to i64 81; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N:%.*]], -1 82; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32 83; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1 84; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP2]], 2 85; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 86; CHECK: vector.memcheck: 87; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[DST1]], [[SRC_12]] 88; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP3]], 2 89; CHECK-NEXT: [[DIFF_CHECK_FR:%.*]] = freeze i1 [[DIFF_CHECK]] 90; CHECK-NEXT: [[TMP4:%.*]] = sub i64 [[DST1]], [[SRC_23]] 91; CHECK-NEXT: [[DIFF_CHECK5:%.*]] = icmp ult i64 [[TMP4]], 2 92; CHECK-NEXT: [[DIFF_CHECK5_FR:%.*]] = freeze i1 [[DIFF_CHECK5]] 93; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[DIFF_CHECK_FR]], [[DIFF_CHECK5_FR]] 94; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 95; CHECK: vector.ph: 96; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP2]], 2 97; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP2]], [[N_MOD_VF]] 98; CHECK-NEXT: [[IND_END:%.*]] = trunc i32 [[N_VEC]] to i8 99; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 100; CHECK: vector.body: 101; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 102; CHECK-NEXT: [[OFFSET_IDX:%.*]] = trunc i32 [[INDEX]] to i8 103; CHECK-NEXT: [[INDUCTION:%.*]] = add i8 [[OFFSET_IDX]], 0 104; CHECK-NEXT: [[INDUCTION6:%.*]] = add i8 [[OFFSET_IDX]], 1 105; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[SRC_1]], i8 [[INDUCTION]] 106; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[SRC_1]], i8 [[INDUCTION6]] 107; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[SRC_2]], i8 [[INDUCTION]] 108; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[SRC_2]], i8 [[INDUCTION6]] 109; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[C:%.*]], ptr [[TMP5]], ptr [[TMP7]] 110; CHECK-NEXT: [[TMP10:%.*]] = select i1 [[C]], ptr [[TMP6]], ptr [[TMP8]] 111; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP9]], align 8 112; CHECK-NEXT: [[TMP12:%.*]] = load i8, ptr [[TMP10]], align 8 113; CHECK-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION]] 114; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION6]] 115; CHECK-NEXT: store i8 [[TMP11]], ptr [[TMP13]], align 2 116; CHECK-NEXT: store i8 [[TMP12]], ptr [[TMP14]], align 2 117; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2 118; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] 119; CHECK-NEXT: br i1 [[TMP15]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]] 120; CHECK: middle.block: 121; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP2]], [[N_VEC]] 122; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] 123; CHECK: scalar.ph: 124; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_MEMCHECK]] ], [ 0, [[ENTRY:%.*]] ] 125; CHECK-NEXT: br label [[LOOP:%.*]] 126; CHECK: loop: 127; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 128; CHECK-NEXT: [[GEP_SRC_1:%.*]] = getelementptr i8, ptr [[SRC_1]], i8 [[IV]] 129; CHECK-NEXT: [[GEP_SRC_2:%.*]] = getelementptr i8, ptr [[SRC_2]], i8 [[IV]] 130; CHECK-NEXT: [[PTR_SEL:%.*]] = select i1 [[C]], ptr [[GEP_SRC_1]], ptr [[GEP_SRC_2]] 131; CHECK-NEXT: [[L_1:%.*]] = load i8, ptr [[PTR_SEL]], align 8 132; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i8, ptr [[DST]], i8 [[IV]] 133; CHECK-NEXT: store i8 [[L_1]], ptr [[GEP_DST]], align 2 134; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 135; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[IV_NEXT]], [[N]] 136; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP10:![0-9]+]] 137; CHECK: exit: 138; CHECK-NEXT: ret void 139; 140entry: 141 br label %loop 142 143loop: 144 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ] 145 %gep.src.1 = getelementptr i8, ptr %src.1, i8 %iv 146 %gep.src.2 = getelementptr i8, ptr %src.2, i8 %iv 147 %ptr.sel = select i1 %c, ptr %gep.src.1, ptr %gep.src.2 148 %l.1 = load i8, ptr %ptr.sel, align 8 149 %gep.dst = getelementptr i8, ptr %dst, i8 %iv 150 store i8 %l.1, ptr %gep.dst, align 2 151 %iv.next = add nsw nuw i8 %iv, 1 152 %ec = icmp eq i8 %iv.next, %n 153 br i1 %ec, label %exit, label %loop 154 155exit: 156 ret void 157} 158 159 160define void @test_loop_dependent_select2(ptr %src.1, ptr %src.2, ptr %dst, i8 %n, i8 %x) { 161; CHECK-LABEL: @test_loop_dependent_select2( 162; CHECK-NEXT: entry: 163; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N:%.*]], -1 164; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32 165; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1 166; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP2]], 2 167; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 168; CHECK: vector.memcheck: 169; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[N]], -1 170; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i64 171; CHECK-NEXT: [[TMP5:%.*]] = add nuw nsw i64 [[TMP4]], 1 172; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[TMP5]] 173; CHECK-NEXT: [[UGLYGEP1:%.*]] = getelementptr i8, ptr [[SRC_1:%.*]], i64 1 174; CHECK-NEXT: [[SRC_1_FR:%.*]] = freeze ptr [[SRC_1]] 175; CHECK-NEXT: [[UGLYGEP1_FR:%.*]] = freeze ptr [[UGLYGEP1]] 176; CHECK-NEXT: [[UGLYGEP2:%.*]] = getelementptr i8, ptr [[SRC_2:%.*]], i64 1 177; CHECK-NEXT: [[SRC_2_FR:%.*]] = freeze ptr [[SRC_2]] 178; CHECK-NEXT: [[UGLYGEP2_FR:%.*]] = freeze ptr [[UGLYGEP2]] 179; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[DST]], [[UGLYGEP1_FR]] 180; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[SRC_1_FR]], [[UGLYGEP]] 181; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] 182; CHECK-NEXT: [[BOUND03:%.*]] = icmp ult ptr [[DST]], [[UGLYGEP2_FR]] 183; CHECK-NEXT: [[BOUND14:%.*]] = icmp ult ptr [[SRC_2_FR]], [[UGLYGEP]] 184; CHECK-NEXT: [[FOUND_CONFLICT5:%.*]] = and i1 [[BOUND03]], [[BOUND14]] 185; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT5]] 186; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 187; CHECK: vector.ph: 188; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP2]], 2 189; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP2]], [[N_MOD_VF]] 190; CHECK-NEXT: [[IND_END:%.*]] = trunc i32 [[N_VEC]] to i8 191; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 192; CHECK: vector.body: 193; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 194; CHECK-NEXT: [[OFFSET_IDX:%.*]] = trunc i32 [[INDEX]] to i8 195; CHECK-NEXT: [[INDUCTION:%.*]] = add i8 [[OFFSET_IDX]], 0 196; CHECK-NEXT: [[INDUCTION6:%.*]] = add i8 [[OFFSET_IDX]], 1 197; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i8 [[INDUCTION]], [[X:%.*]] 198; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i8 [[INDUCTION6]], [[X]] 199; CHECK-NEXT: [[TMP8:%.*]] = select i1 [[TMP6]], ptr [[SRC_1]], ptr [[SRC_2]] 200; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[TMP7]], ptr [[SRC_1]], ptr [[SRC_2]] 201; CHECK-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP8]], align 8, !alias.scope !11 202; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP9]], align 8, !alias.scope !11 203; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION]] 204; CHECK-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION6]] 205; CHECK-NEXT: store i8 [[TMP10]], ptr [[TMP12]], align 2, !alias.scope !14, !noalias !16 206; CHECK-NEXT: store i8 [[TMP11]], ptr [[TMP13]], align 2, !alias.scope !14, !noalias !16 207; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2 208; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] 209; CHECK-NEXT: br i1 [[TMP14]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]] 210; CHECK: middle.block: 211; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP2]], [[N_VEC]] 212; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] 213; CHECK: scalar.ph: 214; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_MEMCHECK]] ], [ 0, [[ENTRY:%.*]] ] 215; CHECK-NEXT: br label [[LOOP:%.*]] 216; CHECK: loop: 217; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 218; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[IV]], [[X]] 219; CHECK-NEXT: [[PTR_SEL:%.*]] = select i1 [[C]], ptr [[SRC_1]], ptr [[SRC_2]] 220; CHECK-NEXT: [[L_1:%.*]] = load i8, ptr [[PTR_SEL]], align 8 221; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i8, ptr [[DST]], i8 [[IV]] 222; CHECK-NEXT: store i8 [[L_1]], ptr [[GEP_DST]], align 2 223; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 224; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[IV_NEXT]], [[N]] 225; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP19:![0-9]+]] 226; CHECK: exit: 227; CHECK-NEXT: ret void 228; 229entry: 230 br label %loop 231 232loop: 233 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ] 234 %c = icmp ult i8 %iv, %x 235 %ptr.sel = select i1 %c, ptr %src.1, ptr %src.2 236 %l.1 = load i8, ptr %ptr.sel, align 8 237 %gep.dst = getelementptr i8, ptr %dst, i8 %iv 238 store i8 %l.1, ptr %gep.dst, align 2 239 %iv.next = add nsw nuw i8 %iv, 1 240 %ec = icmp eq i8 %iv.next, %n 241 br i1 %ec, label %exit, label %loop 242 243exit: 244 ret void 245} 246 247define void @test_loop_dependent_select_first_ptr_noundef(ptr noundef %src.1, ptr %src.2, ptr %dst, i8 %n, i8 %x) { 248; CHECK-LABEL: @test_loop_dependent_select_first_ptr_noundef( 249; CHECK-NEXT: entry: 250; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N:%.*]], -1 251; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32 252; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1 253; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP2]], 2 254; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 255; CHECK: vector.memcheck: 256; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[N]], -1 257; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i64 258; CHECK-NEXT: [[TMP5:%.*]] = add nuw nsw i64 [[TMP4]], 1 259; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[TMP5]] 260; CHECK-NEXT: [[UGLYGEP1:%.*]] = getelementptr i8, ptr [[SRC_1:%.*]], i64 1 261; CHECK-NEXT: [[UGLYGEP2:%.*]] = getelementptr i8, ptr [[SRC_2:%.*]], i64 1 262; CHECK-NEXT: [[SRC_2_FR:%.*]] = freeze ptr [[SRC_2]] 263; CHECK-NEXT: [[UGLYGEP2_FR:%.*]] = freeze ptr [[UGLYGEP2]] 264; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[DST]], [[UGLYGEP1]] 265; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[SRC_1]], [[UGLYGEP]] 266; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] 267; CHECK-NEXT: [[BOUND03:%.*]] = icmp ult ptr [[DST]], [[UGLYGEP2_FR]] 268; CHECK-NEXT: [[BOUND14:%.*]] = icmp ult ptr [[SRC_2_FR]], [[UGLYGEP]] 269; CHECK-NEXT: [[FOUND_CONFLICT5:%.*]] = and i1 [[BOUND03]], [[BOUND14]] 270; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT5]] 271; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 272; CHECK: vector.ph: 273; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP2]], 2 274; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP2]], [[N_MOD_VF]] 275; CHECK-NEXT: [[IND_END:%.*]] = trunc i32 [[N_VEC]] to i8 276; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 277; CHECK: vector.body: 278; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 279; CHECK-NEXT: [[OFFSET_IDX:%.*]] = trunc i32 [[INDEX]] to i8 280; CHECK-NEXT: [[INDUCTION:%.*]] = add i8 [[OFFSET_IDX]], 0 281; CHECK-NEXT: [[INDUCTION6:%.*]] = add i8 [[OFFSET_IDX]], 1 282; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i8 [[INDUCTION]], [[X:%.*]] 283; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i8 [[INDUCTION6]], [[X]] 284; CHECK-NEXT: [[TMP8:%.*]] = select i1 [[TMP6]], ptr [[SRC_1]], ptr [[SRC_2]] 285; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[TMP7]], ptr [[SRC_1]], ptr [[SRC_2]] 286; CHECK-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP8]], align 8, !alias.scope !20 287; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP9]], align 8, !alias.scope !20 288; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION]] 289; CHECK-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION6]] 290; CHECK-NEXT: store i8 [[TMP10]], ptr [[TMP12]], align 2, !alias.scope !23, !noalias !25 291; CHECK-NEXT: store i8 [[TMP11]], ptr [[TMP13]], align 2, !alias.scope !23, !noalias !25 292; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2 293; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] 294; CHECK-NEXT: br i1 [[TMP14]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP27:![0-9]+]] 295; CHECK: middle.block: 296; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP2]], [[N_VEC]] 297; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] 298; CHECK: scalar.ph: 299; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_MEMCHECK]] ], [ 0, [[ENTRY:%.*]] ] 300; CHECK-NEXT: br label [[LOOP:%.*]] 301; CHECK: loop: 302; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 303; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[IV]], [[X]] 304; CHECK-NEXT: [[PTR_SEL:%.*]] = select i1 [[C]], ptr [[SRC_1]], ptr [[SRC_2]] 305; CHECK-NEXT: [[L_1:%.*]] = load i8, ptr [[PTR_SEL]], align 8 306; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i8, ptr [[DST]], i8 [[IV]] 307; CHECK-NEXT: store i8 [[L_1]], ptr [[GEP_DST]], align 2 308; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 309; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[IV_NEXT]], [[N]] 310; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP28:![0-9]+]] 311; CHECK: exit: 312; CHECK-NEXT: ret void 313; 314entry: 315 br label %loop 316 317loop: 318 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ] 319 %c = icmp ult i8 %iv, %x 320 %ptr.sel = select i1 %c, ptr %src.1, ptr %src.2 321 %l.1 = load i8, ptr %ptr.sel, align 8 322 %gep.dst = getelementptr i8, ptr %dst, i8 %iv 323 store i8 %l.1, ptr %gep.dst, align 2 324 %iv.next = add nsw nuw i8 %iv, 1 325 %ec = icmp eq i8 %iv.next, %n 326 br i1 %ec, label %exit, label %loop 327 328exit: 329 ret void 330} 331 332define void @test_loop_dependent_select_second_ptr_noundef(ptr %src.1, ptr noundef %src.2, ptr %dst, i8 %n, i8 %x) { 333; CHECK-LABEL: @test_loop_dependent_select_second_ptr_noundef( 334; CHECK-NEXT: entry: 335; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N:%.*]], -1 336; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32 337; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1 338; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP2]], 2 339; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 340; CHECK: vector.memcheck: 341; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[N]], -1 342; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i64 343; CHECK-NEXT: [[TMP5:%.*]] = add nuw nsw i64 [[TMP4]], 1 344; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 [[TMP5]] 345; CHECK-NEXT: [[UGLYGEP1:%.*]] = getelementptr i8, ptr [[SRC_1:%.*]], i64 1 346; CHECK-NEXT: [[SRC_1_FR:%.*]] = freeze ptr [[SRC_1]] 347; CHECK-NEXT: [[UGLYGEP1_FR:%.*]] = freeze ptr [[UGLYGEP1]] 348; CHECK-NEXT: [[UGLYGEP2:%.*]] = getelementptr i8, ptr [[SRC_2:%.*]], i64 1 349; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[DST]], [[UGLYGEP1_FR]] 350; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[SRC_1_FR]], [[UGLYGEP]] 351; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] 352; CHECK-NEXT: [[BOUND03:%.*]] = icmp ult ptr [[DST]], [[UGLYGEP2]] 353; CHECK-NEXT: [[BOUND14:%.*]] = icmp ult ptr [[SRC_2]], [[UGLYGEP]] 354; CHECK-NEXT: [[FOUND_CONFLICT5:%.*]] = and i1 [[BOUND03]], [[BOUND14]] 355; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT5]] 356; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 357; CHECK: vector.ph: 358; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP2]], 2 359; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP2]], [[N_MOD_VF]] 360; CHECK-NEXT: [[IND_END:%.*]] = trunc i32 [[N_VEC]] to i8 361; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 362; CHECK: vector.body: 363; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 364; CHECK-NEXT: [[OFFSET_IDX:%.*]] = trunc i32 [[INDEX]] to i8 365; CHECK-NEXT: [[INDUCTION:%.*]] = add i8 [[OFFSET_IDX]], 0 366; CHECK-NEXT: [[INDUCTION6:%.*]] = add i8 [[OFFSET_IDX]], 1 367; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i8 [[INDUCTION]], [[X:%.*]] 368; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i8 [[INDUCTION6]], [[X]] 369; CHECK-NEXT: [[TMP8:%.*]] = select i1 [[TMP6]], ptr [[SRC_1]], ptr [[SRC_2]] 370; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[TMP7]], ptr [[SRC_1]], ptr [[SRC_2]] 371; CHECK-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP8]], align 8, !alias.scope !29 372; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP9]], align 8, !alias.scope !29 373; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION]] 374; CHECK-NEXT: [[TMP13:%.*]] = getelementptr i8, ptr [[DST]], i8 [[INDUCTION6]] 375; CHECK-NEXT: store i8 [[TMP10]], ptr [[TMP12]], align 2, !alias.scope !32, !noalias !34 376; CHECK-NEXT: store i8 [[TMP11]], ptr [[TMP13]], align 2, !alias.scope !32, !noalias !34 377; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2 378; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] 379; CHECK-NEXT: br i1 [[TMP14]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP36:![0-9]+]] 380; CHECK: middle.block: 381; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP2]], [[N_VEC]] 382; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] 383; CHECK: scalar.ph: 384; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_MEMCHECK]] ], [ 0, [[ENTRY:%.*]] ] 385; CHECK-NEXT: br label [[LOOP:%.*]] 386; CHECK: loop: 387; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 388; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[IV]], [[X]] 389; CHECK-NEXT: [[PTR_SEL:%.*]] = select i1 [[C]], ptr [[SRC_1]], ptr [[SRC_2]] 390; CHECK-NEXT: [[L_1:%.*]] = load i8, ptr [[PTR_SEL]], align 8 391; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i8, ptr [[DST]], i8 [[IV]] 392; CHECK-NEXT: store i8 [[L_1]], ptr [[GEP_DST]], align 2 393; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 394; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[IV_NEXT]], [[N]] 395; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP37:![0-9]+]] 396; CHECK: exit: 397; CHECK-NEXT: ret void 398; 399entry: 400 br label %loop 401 402loop: 403 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ] 404 %c = icmp ult i8 %iv, %x 405 %ptr.sel = select i1 %c, ptr %src.1, ptr %src.2 406 %l.1 = load i8, ptr %ptr.sel, align 8 407 %gep.dst = getelementptr i8, ptr %dst, i8 %iv 408 store i8 %l.1, ptr %gep.dst, align 2 409 %iv.next = add nsw nuw i8 %iv, 1 410 %ec = icmp eq i8 %iv.next, %n 411 br i1 %ec, label %exit, label %loop 412 413exit: 414 ret void 415} 416