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