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