1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -p loop-vectorize -mtriple=x86_64-apple-macosx -S %s | FileCheck %s 3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" 5 6define i32 @iv_used_widened_and_truncated(ptr %dst, i64 %N) #0 { 7; CHECK-LABEL: define i32 @iv_used_widened_and_truncated( 8; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] { 9; CHECK-NEXT: iter.check: 10; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 11; CHECK-NEXT: [[MIN_ITERS_CHECK1:%.*]] = icmp ult i64 [[TMP0]], 4 12; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK1]], label [[VEC_EPILOG_SCALAR_PH:%.*]], label [[ENTRY:%.*]] 13; CHECK: vector.main.loop.iter.check: 14; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 32 15; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 16; CHECK: vector.ph: 17; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 32 18; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]] 19; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 20; CHECK: vector.body: 21; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 22; CHECK-NEXT: [[VEC_IND:%.*]] = phi <8 x i64> [ <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 23; CHECK-NEXT: [[VEC_IND4:%.*]] = phi <8 x i32> [ <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT9:%.*]], [[VECTOR_BODY]] ] 24; CHECK-NEXT: [[STEP_ADD:%.*]] = add <8 x i64> [[VEC_IND]], splat (i64 8) 25; CHECK-NEXT: [[STEP_ADD1:%.*]] = add <8 x i64> [[STEP_ADD]], splat (i64 8) 26; CHECK-NEXT: [[STEP_ADD2:%.*]] = add <8 x i64> [[STEP_ADD1]], splat (i64 8) 27; CHECK-NEXT: [[STEP_ADD5:%.*]] = add <8 x i32> [[VEC_IND4]], splat (i32 8) 28; CHECK-NEXT: [[STEP_ADD6:%.*]] = add <8 x i32> [[STEP_ADD5]], splat (i32 8) 29; CHECK-NEXT: [[STEP_ADD7:%.*]] = add <8 x i32> [[STEP_ADD6]], splat (i32 8) 30; CHECK-NEXT: [[TMP1:%.*]] = getelementptr { i32, [8 x i32] }, ptr [[DST]], <8 x i64> [[VEC_IND]] 31; CHECK-NEXT: [[TMP2:%.*]] = getelementptr { i32, [8 x i32] }, ptr [[DST]], <8 x i64> [[STEP_ADD]] 32; CHECK-NEXT: [[TMP3:%.*]] = getelementptr { i32, [8 x i32] }, ptr [[DST]], <8 x i64> [[STEP_ADD1]] 33; CHECK-NEXT: [[TMP4:%.*]] = getelementptr { i32, [8 x i32] }, ptr [[DST]], <8 x i64> [[STEP_ADD2]] 34; CHECK-NEXT: call void @llvm.masked.scatter.v8i32.v8p0(<8 x i32> [[VEC_IND4]], <8 x ptr> [[TMP1]], i32 8, <8 x i1> splat (i1 true)) 35; CHECK-NEXT: call void @llvm.masked.scatter.v8i32.v8p0(<8 x i32> [[STEP_ADD5]], <8 x ptr> [[TMP2]], i32 8, <8 x i1> splat (i1 true)) 36; CHECK-NEXT: call void @llvm.masked.scatter.v8i32.v8p0(<8 x i32> [[STEP_ADD6]], <8 x ptr> [[TMP3]], i32 8, <8 x i1> splat (i1 true)) 37; CHECK-NEXT: call void @llvm.masked.scatter.v8i32.v8p0(<8 x i32> [[STEP_ADD7]], <8 x ptr> [[TMP4]], i32 8, <8 x i1> splat (i1 true)) 38; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32 39; CHECK-NEXT: [[VEC_IND_NEXT]] = add <8 x i64> [[STEP_ADD2]], splat (i64 8) 40; CHECK-NEXT: [[VEC_IND_NEXT9]] = add <8 x i32> [[STEP_ADD7]], splat (i32 8) 41; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 42; CHECK-NEXT: br i1 [[TMP5]], label [[MIDDLE_BLOCK1:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] 43; CHECK: middle.block: 44; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]] 45; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]] 46; CHECK: vec.epilog.iter.check: 47; CHECK-NEXT: [[N_VEC_REMAINING:%.*]] = sub i64 [[TMP0]], [[N_VEC]] 48; CHECK-NEXT: [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp ult i64 [[N_VEC_REMAINING]], 4 49; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[SCALAR_PH]] 50; CHECK: vec.epilog.ph: 51; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ] 52; CHECK-NEXT: [[N_MOD_VF8:%.*]] = urem i64 [[TMP0]], 4 53; CHECK-NEXT: [[N_VEC9:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF8]] 54; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[VEC_EPILOG_RESUME_VAL]], i64 0 55; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i64> [[DOTSPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer 56; CHECK-NEXT: [[INDUCTION:%.*]] = add <4 x i64> [[DOTSPLAT]], <i64 0, i64 1, i64 2, i64 3> 57; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[VEC_EPILOG_RESUME_VAL]] to i32 58; CHECK-NEXT: [[DOTSPLATINSERT14:%.*]] = insertelement <4 x i32> poison, i32 [[TMP6]], i64 0 59; CHECK-NEXT: [[DOTSPLAT15:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT14]], <4 x i32> poison, <4 x i32> zeroinitializer 60; CHECK-NEXT: [[INDUCTION16:%.*]] = add <4 x i32> [[DOTSPLAT15]], <i32 0, i32 1, i32 2, i32 3> 61; CHECK-NEXT: br label [[LOOP:%.*]] 62; CHECK: vec.epilog.vector.body: 63; CHECK-NEXT: [[INDEX11:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDEX_NEXT19:%.*]], [[LOOP]] ] 64; CHECK-NEXT: [[VEC_IND12:%.*]] = phi <4 x i64> [ [[INDUCTION]], [[SCALAR_PH]] ], [ [[VEC_IND_NEXT13:%.*]], [[LOOP]] ] 65; CHECK-NEXT: [[VEC_IND17:%.*]] = phi <4 x i32> [ [[INDUCTION16]], [[SCALAR_PH]] ], [ [[VEC_IND_NEXT18:%.*]], [[LOOP]] ] 66; CHECK-NEXT: [[TMP7:%.*]] = getelementptr { i32, [8 x i32] }, ptr [[DST]], <4 x i64> [[VEC_IND12]] 67; CHECK-NEXT: call void @llvm.masked.scatter.v4i32.v4p0(<4 x i32> [[VEC_IND17]], <4 x ptr> [[TMP7]], i32 8, <4 x i1> splat (i1 true)) 68; CHECK-NEXT: [[INDEX_NEXT19]] = add nuw i64 [[INDEX11]], 4 69; CHECK-NEXT: [[VEC_IND_NEXT13]] = add <4 x i64> [[VEC_IND12]], splat (i64 4) 70; CHECK-NEXT: [[VEC_IND_NEXT18]] = add <4 x i32> [[VEC_IND17]], splat (i32 4) 71; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT19]], [[N_VEC9]] 72; CHECK-NEXT: br i1 [[TMP8]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[LOOP]], !llvm.loop [[LOOP3:![0-9]+]] 73; CHECK: vec.epilog.middle.block: 74; CHECK-NEXT: [[CMP_N20:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC9]] 75; CHECK-NEXT: br i1 [[CMP_N20]], label [[EXIT]], label [[VEC_EPILOG_SCALAR_PH]] 76; CHECK: vec.epilog.scalar.ph: 77; CHECK-NEXT: [[BC_RESUME_VAL10:%.*]] = phi i64 [ [[N_VEC9]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ 0, [[ITER_CHECK:%.*]] ], [ [[N_VEC]], [[MIDDLE_BLOCK]] ] 78; CHECK-NEXT: br label [[LOOP1:%.*]] 79; CHECK: loop: 80; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL10]], [[VEC_EPILOG_SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP1]] ] 81; CHECK-NEXT: [[GEP:%.*]] = getelementptr { i32, [8 x i32] }, ptr [[DST]], i64 [[IV]] 82; CHECK-NEXT: [[T:%.*]] = trunc i64 [[IV]] to i32 83; CHECK-NEXT: store i32 [[T]], ptr [[GEP]], align 8 84; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 85; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[IV]], [[N]] 86; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[LOOP1]], !llvm.loop [[LOOP4:![0-9]+]] 87; CHECK: exit: 88; CHECK-NEXT: ret i32 0 89; 90entry: 91 br label %loop 92 93loop: 94 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 95 %gep = getelementptr { i32, [ 8 x i32 ]}, ptr %dst, i64 %iv 96 %t = trunc i64 %iv to i32 97 store i32 %t, ptr %gep, align 8 98 %iv.next = add i64 %iv, 1 99 %c = icmp eq i64 %iv, %N 100 br i1 %c, label %exit, label %loop 101 102exit: 103 ret i32 0 104} 105 106define void @multiple_truncated_ivs_with_wide_uses(i1 %c, ptr %A, ptr %B) { 107; CHECK-LABEL: define void @multiple_truncated_ivs_with_wide_uses( 108; CHECK-SAME: i1 [[C:%.*]], ptr [[A:%.*]], ptr [[B:%.*]]) { 109; CHECK-NEXT: entry: 110; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 111; CHECK: vector.memcheck: 112; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 130 113; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[B]], i64 260 114; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[A]], [[SCEVGEP1]] 115; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[B]], [[SCEVGEP]] 116; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] 117; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 118; CHECK: vector.ph: 119; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 120; CHECK: vector.body: 121; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 122; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i16> [ <i16 0, i16 1, i16 2, i16 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 123; CHECK-NEXT: [[VEC_IND3:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT6:%.*]], [[VECTOR_BODY]] ] 124; CHECK-NEXT: [[STEP_ADD:%.*]] = add <4 x i16> [[VEC_IND]], splat (i16 4) 125; CHECK-NEXT: [[STEP_ADD4:%.*]] = add <4 x i32> [[VEC_IND3]], splat (i32 4) 126; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 127; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C]], <4 x i16> [[VEC_IND]], <4 x i16> splat (i16 10) 128; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C]], <4 x i16> [[STEP_ADD]], <4 x i16> splat (i16 10) 129; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i16, ptr [[A]], i64 [[TMP0]] 130; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i16, ptr [[TMP4]], i32 0 131; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i16, ptr [[TMP4]], i32 4 132; CHECK-NEXT: store <4 x i16> [[TMP1]], ptr [[TMP6]], align 2, !alias.scope [[META5:![0-9]+]], !noalias [[META8:![0-9]+]] 133; CHECK-NEXT: store <4 x i16> [[TMP2]], ptr [[TMP7]], align 2, !alias.scope [[META5]], !noalias [[META8]] 134; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i32, ptr [[B]], i64 [[TMP0]] 135; CHECK-NEXT: [[TMP10:%.*]] = getelementptr i32, ptr [[TMP8]], i32 0 136; CHECK-NEXT: [[TMP11:%.*]] = getelementptr i32, ptr [[TMP8]], i32 4 137; CHECK-NEXT: store <4 x i32> [[VEC_IND3]], ptr [[TMP10]], align 4, !alias.scope [[META8]] 138; CHECK-NEXT: store <4 x i32> [[STEP_ADD4]], ptr [[TMP11]], align 4, !alias.scope [[META8]] 139; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8 140; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i16> [[STEP_ADD]], splat (i16 4) 141; CHECK-NEXT: [[VEC_IND_NEXT6]] = add <4 x i32> [[STEP_ADD4]], splat (i32 4) 142; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 64 143; CHECK-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]] 144; CHECK: middle.block: 145; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]] 146; CHECK: scalar.ph: 147; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 64, [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_MEMCHECK]] ], [ 0, [[ENTRY:%.*]] ] 148; CHECK-NEXT: br label [[LOOP:%.*]] 149; CHECK: loop: 150; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 151; CHECK-NEXT: [[IV_16:%.*]] = trunc i64 [[IV]] to i16 152; CHECK-NEXT: [[IV_32:%.*]] = trunc i64 [[IV]] to i32 153; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i16 [[IV_16]], i16 10 154; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i16, ptr [[A]], i64 [[IV]] 155; CHECK-NEXT: store i16 [[SEL]], ptr [[GEP_A]], align 2 156; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr i32, ptr [[B]], i64 [[IV]] 157; CHECK-NEXT: store i32 [[IV_32]], ptr [[GEP_B]], align 4 158; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 159; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 64 160; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP11:![0-9]+]] 161; CHECK: exit: 162; CHECK-NEXT: ret void 163; 164entry: 165 br label %loop 166 167loop: 168 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 169 %iv.16 = trunc i64 %iv to i16 170 %iv.32 = trunc i64 %iv to i32 171 %sel = select i1 %c, i16 %iv.16, i16 10 172 %gep.A = getelementptr i16, ptr %A, i64 %iv 173 store i16 %sel, ptr %gep.A 174 %gep.B = getelementptr i32, ptr %B, i64 %iv 175 store i32 %iv.32, ptr %gep.B 176 %iv.next = add i64 %iv, 1 177 %ec = icmp eq i64 %iv, 64 178 br i1 %ec, label %exit, label %loop 179 180exit: 181 ret void 182} 183 184define void @truncated_ivs_with_wide_and_scalar_uses(i1 %c, ptr %dst) { 185; CHECK-LABEL: define void @truncated_ivs_with_wide_and_scalar_uses( 186; CHECK-SAME: i1 [[C:%.*]], ptr [[DST:%.*]]) { 187; CHECK-NEXT: entry: 188; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 189; CHECK: vector.ph: 190; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 191; CHECK: vector.body: 192; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 193; CHECK-NEXT: [[VEC_IND:%.*]] = phi <8 x i16> [ <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 194; CHECK-NEXT: [[STEP_ADD:%.*]] = add <8 x i16> [[VEC_IND]], splat (i16 8) 195; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[INDEX]] to i32 196; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 0 197; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i16, ptr [[DST]], i32 [[TMP1]] 198; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[C]], <8 x i16> [[VEC_IND]], <8 x i16> splat (i16 10) 199; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[C]], <8 x i16> [[STEP_ADD]], <8 x i16> splat (i16 10) 200; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i16, ptr [[TMP3]], i32 0 201; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i16, ptr [[TMP3]], i32 8 202; CHECK-NEXT: store <8 x i16> [[TMP5]], ptr [[TMP7]], align 2 203; CHECK-NEXT: store <8 x i16> [[TMP6]], ptr [[TMP8]], align 2 204; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16 205; CHECK-NEXT: [[VEC_IND_NEXT]] = add <8 x i16> [[STEP_ADD]], splat (i16 8) 206; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], 64 207; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]] 208; CHECK: middle.block: 209; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]] 210; CHECK: scalar.ph: 211; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 64, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] 212; CHECK-NEXT: br label [[LOOP:%.*]] 213; CHECK: loop: 214; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 215; CHECK-NEXT: [[IV_16:%.*]] = trunc i64 [[IV]] to i16 216; CHECK-NEXT: [[IV_32:%.*]] = trunc i64 [[IV]] to i32 217; CHECK-NEXT: [[GEP:%.*]] = getelementptr i16, ptr [[DST]], i32 [[IV_32]] 218; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i16 [[IV_16]], i16 10 219; CHECK-NEXT: store i16 [[SEL]], ptr [[GEP]], align 2 220; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 221; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 64 222; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP13:![0-9]+]] 223; CHECK: exit: 224; CHECK-NEXT: ret void 225; 226entry: 227 br label %loop 228 229loop: 230 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 231 %iv.16 = trunc i64 %iv to i16 232 %iv.32 = trunc i64 %iv to i32 233 %gep = getelementptr i16, ptr %dst, i32 %iv.32 234 %sel = select i1 %c, i16 %iv.16, i16 10 235 store i16 %sel, ptr %gep 236 %iv.next = add i64 %iv, 1 237 %ec = icmp eq i64 %iv, 64 238 br i1 %ec, label %exit, label %loop 239 240exit: 241 ret void 242} 243 244define void @multiple_pointer_ivs_with_scalar_uses_only(ptr %A, ptr %B) #0 { 245; CHECK-LABEL: define void @multiple_pointer_ivs_with_scalar_uses_only( 246; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) #[[ATTR0]] { 247; CHECK-NEXT: entry: 248; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 249; CHECK: vector.memcheck: 250; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[A]], i64 8589934391 251; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[B]], i64 4294967196 252; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[A]], [[SCEVGEP1]] 253; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[B]], [[SCEVGEP]] 254; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] 255; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 256; CHECK: vector.ph: 257; CHECK-NEXT: [[IND_END:%.*]] = getelementptr i8, ptr [[A]], i64 8589934368 258; CHECK-NEXT: [[IND_END3:%.*]] = getelementptr i8, ptr [[B]], i64 4294967184 259; CHECK-NEXT: [[IND_END5:%.*]] = getelementptr i8, ptr [[B]], i64 4294967184 260; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 261; CHECK: vector.body: 262; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 263; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <16 x i32> [ <i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 2048>, [[VECTOR_PH]] ], [ [[TMP22:%.*]], [[VECTOR_BODY]] ] 264; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 2 265; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0 266; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 2 267; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 4 268; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 6 269; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], 8 270; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[OFFSET_IDX]], 10 271; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[OFFSET_IDX]], 12 272; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[OFFSET_IDX]], 14 273; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[OFFSET_IDX]], 16 274; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[OFFSET_IDX]], 18 275; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[OFFSET_IDX]], 20 276; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[OFFSET_IDX]], 22 277; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[OFFSET_IDX]], 24 278; CHECK-NEXT: [[TMP13:%.*]] = add i64 [[OFFSET_IDX]], 26 279; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[OFFSET_IDX]], 28 280; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[OFFSET_IDX]], 30 281; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP0]] 282; CHECK-NEXT: [[NEXT_GEP7:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]] 283; CHECK-NEXT: [[NEXT_GEP8:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]] 284; CHECK-NEXT: [[NEXT_GEP9:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP3]] 285; CHECK-NEXT: [[NEXT_GEP10:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP4]] 286; CHECK-NEXT: [[NEXT_GEP11:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP5]] 287; CHECK-NEXT: [[NEXT_GEP12:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP6]] 288; CHECK-NEXT: [[NEXT_GEP13:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP7]] 289; CHECK-NEXT: [[NEXT_GEP14:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP8]] 290; CHECK-NEXT: [[NEXT_GEP15:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP9]] 291; CHECK-NEXT: [[NEXT_GEP16:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP10]] 292; CHECK-NEXT: [[NEXT_GEP17:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP11]] 293; CHECK-NEXT: [[NEXT_GEP18:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP12]] 294; CHECK-NEXT: [[NEXT_GEP19:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP13]] 295; CHECK-NEXT: [[NEXT_GEP20:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP14]] 296; CHECK-NEXT: [[NEXT_GEP21:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP15]] 297; CHECK-NEXT: [[TMP16:%.*]] = add i64 [[INDEX]], 0 298; CHECK-NEXT: [[NEXT_GEP22:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP16]] 299; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[INDEX]], 0 300; CHECK-NEXT: [[NEXT_GEP23:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP17]] 301; CHECK-NEXT: [[TMP18:%.*]] = getelementptr i8, ptr [[NEXT_GEP23]], i32 0 302; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <16 x i8>, ptr [[TMP18]], align 1, !alias.scope [[META14:![0-9]+]] 303; CHECK-NEXT: [[TMP19:%.*]] = zext <16 x i8> [[WIDE_LOAD]] to <16 x i32> 304; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr [[NEXT_GEP22]], i32 0 305; CHECK-NEXT: [[WIDE_LOAD24:%.*]] = load <16 x i8>, ptr [[TMP20]], align 1, !alias.scope [[META14]] 306; CHECK-NEXT: [[TMP21:%.*]] = zext <16 x i8> [[WIDE_LOAD24]] to <16 x i32> 307; CHECK-NEXT: [[TMP22]] = add <16 x i32> [[TMP19]], [[TMP21]] 308; CHECK-NEXT: [[TMP23:%.*]] = shufflevector <16 x i32> [[VECTOR_RECUR]], <16 x i32> [[TMP22]], <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30> 309; CHECK-NEXT: [[TMP24:%.*]] = lshr <16 x i32> [[TMP23]], splat (i32 1) 310; CHECK-NEXT: [[TMP25:%.*]] = trunc <16 x i32> [[TMP24]] to <16 x i8> 311; CHECK-NEXT: [[TMP26:%.*]] = extractelement <16 x i8> [[TMP25]], i32 0 312; CHECK-NEXT: store i8 [[TMP26]], ptr [[NEXT_GEP]], align 1, !alias.scope [[META17:![0-9]+]], !noalias [[META14]] 313; CHECK-NEXT: [[TMP27:%.*]] = extractelement <16 x i8> [[TMP25]], i32 1 314; CHECK-NEXT: store i8 [[TMP27]], ptr [[NEXT_GEP7]], align 1, !alias.scope [[META17]], !noalias [[META14]] 315; CHECK-NEXT: [[TMP28:%.*]] = extractelement <16 x i8> [[TMP25]], i32 2 316; CHECK-NEXT: store i8 [[TMP28]], ptr [[NEXT_GEP8]], align 1, !alias.scope [[META17]], !noalias [[META14]] 317; CHECK-NEXT: [[TMP29:%.*]] = extractelement <16 x i8> [[TMP25]], i32 3 318; CHECK-NEXT: store i8 [[TMP29]], ptr [[NEXT_GEP9]], align 1, !alias.scope [[META17]], !noalias [[META14]] 319; CHECK-NEXT: [[TMP30:%.*]] = extractelement <16 x i8> [[TMP25]], i32 4 320; CHECK-NEXT: store i8 [[TMP30]], ptr [[NEXT_GEP10]], align 1, !alias.scope [[META17]], !noalias [[META14]] 321; CHECK-NEXT: [[TMP31:%.*]] = extractelement <16 x i8> [[TMP25]], i32 5 322; CHECK-NEXT: store i8 [[TMP31]], ptr [[NEXT_GEP11]], align 1, !alias.scope [[META17]], !noalias [[META14]] 323; CHECK-NEXT: [[TMP32:%.*]] = extractelement <16 x i8> [[TMP25]], i32 6 324; CHECK-NEXT: store i8 [[TMP32]], ptr [[NEXT_GEP12]], align 1, !alias.scope [[META17]], !noalias [[META14]] 325; CHECK-NEXT: [[TMP33:%.*]] = extractelement <16 x i8> [[TMP25]], i32 7 326; CHECK-NEXT: store i8 [[TMP33]], ptr [[NEXT_GEP13]], align 1, !alias.scope [[META17]], !noalias [[META14]] 327; CHECK-NEXT: [[TMP34:%.*]] = extractelement <16 x i8> [[TMP25]], i32 8 328; CHECK-NEXT: store i8 [[TMP34]], ptr [[NEXT_GEP14]], align 1, !alias.scope [[META17]], !noalias [[META14]] 329; CHECK-NEXT: [[TMP35:%.*]] = extractelement <16 x i8> [[TMP25]], i32 9 330; CHECK-NEXT: store i8 [[TMP35]], ptr [[NEXT_GEP15]], align 1, !alias.scope [[META17]], !noalias [[META14]] 331; CHECK-NEXT: [[TMP36:%.*]] = extractelement <16 x i8> [[TMP25]], i32 10 332; CHECK-NEXT: store i8 [[TMP36]], ptr [[NEXT_GEP16]], align 1, !alias.scope [[META17]], !noalias [[META14]] 333; CHECK-NEXT: [[TMP37:%.*]] = extractelement <16 x i8> [[TMP25]], i32 11 334; CHECK-NEXT: store i8 [[TMP37]], ptr [[NEXT_GEP17]], align 1, !alias.scope [[META17]], !noalias [[META14]] 335; CHECK-NEXT: [[TMP38:%.*]] = extractelement <16 x i8> [[TMP25]], i32 12 336; CHECK-NEXT: store i8 [[TMP38]], ptr [[NEXT_GEP18]], align 1, !alias.scope [[META17]], !noalias [[META14]] 337; CHECK-NEXT: [[TMP39:%.*]] = extractelement <16 x i8> [[TMP25]], i32 13 338; CHECK-NEXT: store i8 [[TMP39]], ptr [[NEXT_GEP19]], align 1, !alias.scope [[META17]], !noalias [[META14]] 339; CHECK-NEXT: [[TMP40:%.*]] = extractelement <16 x i8> [[TMP25]], i32 14 340; CHECK-NEXT: store i8 [[TMP40]], ptr [[NEXT_GEP20]], align 1, !alias.scope [[META17]], !noalias [[META14]] 341; CHECK-NEXT: [[TMP41:%.*]] = extractelement <16 x i8> [[TMP25]], i32 15 342; CHECK-NEXT: store i8 [[TMP41]], ptr [[NEXT_GEP21]], align 1, !alias.scope [[META17]], !noalias [[META14]] 343; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16 344; CHECK-NEXT: [[TMP42:%.*]] = icmp eq i64 [[INDEX_NEXT]], 4294967184 345; CHECK-NEXT: br i1 [[TMP42]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]] 346; CHECK: middle.block: 347; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <16 x i32> [[TMP22]], i32 15 348; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]] 349; CHECK: scalar.ph: 350; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ -12, [[MIDDLE_BLOCK]] ], [ 100, [[VECTOR_MEMCHECK]] ], [ 100, [[ENTRY:%.*]] ] 351; CHECK-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi i32 [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ], [ 2048, [[VECTOR_MEMCHECK]] ], [ 2048, [[ENTRY]] ] 352; CHECK-NEXT: [[BC_RESUME_VAL2:%.*]] = phi ptr [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[A]], [[VECTOR_MEMCHECK]] ], [ [[A]], [[ENTRY]] ] 353; CHECK-NEXT: [[BC_RESUME_VAL4:%.*]] = phi ptr [ [[IND_END3]], [[MIDDLE_BLOCK]] ], [ [[B]], [[VECTOR_MEMCHECK]] ], [ [[B]], [[ENTRY]] ] 354; CHECK-NEXT: [[BC_RESUME_VAL6:%.*]] = phi ptr [ [[IND_END5]], [[MIDDLE_BLOCK]] ], [ [[B]], [[VECTOR_MEMCHECK]] ], [ [[B]], [[ENTRY]] ] 355; CHECK-NEXT: br label [[LOOP:%.*]] 356; CHECK: loop: 357; CHECK-NEXT: [[IV_1:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[DEC:%.*]], [[LOOP]] ] 358; CHECK-NEXT: [[SCALAR_RECUR:%.*]] = phi i32 [ [[SCALAR_RECUR_INIT]], [[SCALAR_PH]] ], [ [[ADD38:%.*]], [[LOOP]] ] 359; CHECK-NEXT: [[PTR_IV_1:%.*]] = phi ptr [ [[BC_RESUME_VAL2]], [[SCALAR_PH]] ], [ [[OUTPTR_0:%.*]], [[LOOP]] ] 360; CHECK-NEXT: [[PTR_IV_2:%.*]] = phi ptr [ [[BC_RESUME_VAL4]], [[SCALAR_PH]] ], [ [[INCDEC_PTR36:%.*]], [[LOOP]] ] 361; CHECK-NEXT: [[PTR_IV_3:%.*]] = phi ptr [ [[BC_RESUME_VAL6]], [[SCALAR_PH]] ], [ [[INCDEC_PTR33:%.*]], [[LOOP]] ] 362; CHECK-NEXT: [[INCDEC_PTR33]] = getelementptr i8, ptr [[PTR_IV_3]], i64 1 363; CHECK-NEXT: [[TMP43:%.*]] = load i8, ptr [[PTR_IV_3]], align 1 364; CHECK-NEXT: [[CONV34:%.*]] = zext i8 [[TMP43]] to i32 365; CHECK-NEXT: [[INCDEC_PTR36]] = getelementptr i8, ptr [[PTR_IV_2]], i64 1 366; CHECK-NEXT: [[TMP44:%.*]] = load i8, ptr [[PTR_IV_2]], align 1 367; CHECK-NEXT: [[CONV37:%.*]] = zext i8 [[TMP44]] to i32 368; CHECK-NEXT: [[ADD38]] = add i32 [[CONV34]], [[CONV37]] 369; CHECK-NEXT: [[SHR42:%.*]] = lshr i32 [[SCALAR_RECUR]], 1 370; CHECK-NEXT: [[CONV43:%.*]] = trunc i32 [[SHR42]] to i8 371; CHECK-NEXT: store i8 [[CONV43]], ptr [[PTR_IV_1]], align 1 372; CHECK-NEXT: [[DEC]] = add i32 [[IV_1]], 1 373; CHECK-NEXT: [[OUTPTR_0]] = getelementptr i8, ptr [[PTR_IV_1]], i64 2 374; CHECK-NEXT: [[CMP30_NOT:%.*]] = icmp eq i32 [[DEC]], 0 375; CHECK-NEXT: br i1 [[CMP30_NOT]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP20:![0-9]+]] 376; CHECK: exit: 377; CHECK-NEXT: ret void 378; 379entry: 380 br label %loop 381 382loop: 383 %iv.1 = phi i32 [ 100, %entry ], [ %dec, %loop ] 384 %iv.2 = phi i32 [ 2048, %entry ], [ %add38, %loop ] 385 %ptr.iv.1 = phi ptr [ %A, %entry ], [ %outptr.0, %loop ] 386 %ptr.iv.2 = phi ptr [ %B, %entry ], [ %incdec.ptr36, %loop ] 387 %ptr.iv.3 = phi ptr [ %B, %entry ], [ %incdec.ptr33, %loop ] 388 %incdec.ptr33 = getelementptr i8, ptr %ptr.iv.3, i64 1 389 %0 = load i8, ptr %ptr.iv.3, align 1 390 %conv34 = zext i8 %0 to i32 391 %incdec.ptr36 = getelementptr i8, ptr %ptr.iv.2, i64 1 392 %1 = load i8, ptr %ptr.iv.2, align 1 393 %conv37 = zext i8 %1 to i32 394 %add38 = add i32 %conv34, %conv37 395 %shr42 = lshr i32 %iv.2, 1 396 %conv43 = trunc i32 %shr42 to i8 397 store i8 %conv43, ptr %ptr.iv.1, align 1 398 %dec = add i32 %iv.1, 1 399 %outptr.0 = getelementptr i8, ptr %ptr.iv.1, i64 2 400 %cmp30.not = icmp eq i32 %dec, 0 401 br i1 %cmp30.not, label %exit, label %loop 402 403exit: 404 ret void 405} 406 407define i16 @iv_and_step_trunc() { 408; CHECK-LABEL: define i16 @iv_and_step_trunc() { 409; CHECK-NEXT: entry: 410; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 411; CHECK: vector.ph: 412; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 413; CHECK: vector.body: 414; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 415; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 416; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <2 x i16> [ <i16 poison, i16 0>, [[VECTOR_PH]] ], [ [[TMP2:%.*]], [[VECTOR_BODY]] ] 417; CHECK-NEXT: [[VEC_IND1:%.*]] = phi <2 x i16> [ <i16 0, i16 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT2:%.*]], [[VECTOR_BODY]] ] 418; CHECK-NEXT: [[TMP0:%.*]] = add <2 x i64> [[VEC_IND]], splat (i64 1) 419; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i64> [[TMP0]] to <2 x i16> 420; CHECK-NEXT: [[TMP2]] = mul <2 x i16> [[VEC_IND1]], [[TMP1]] 421; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 422; CHECK-NEXT: [[VEC_IND_NEXT2]] = add <2 x i16> [[VEC_IND1]], splat (i16 2) 423; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 424; CHECK-NEXT: br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP21:![0-9]+]] 425; CHECK: middle.block: 426; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT_FOR_PHI:%.*]] = extractelement <2 x i16> [[TMP2]], i32 0 427; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <2 x i16> [[TMP2]], i32 1 428; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]] 429; CHECK: scalar.ph: 430; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 2, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] 431; CHECK-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi i16 [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ] 432; CHECK-NEXT: br label [[LOOP:%.*]] 433; CHECK: loop: 434; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 435; CHECK-NEXT: [[SCALAR_RECUR:%.*]] = phi i16 [ [[SCALAR_RECUR_INIT]], [[SCALAR_PH]] ], [ [[REC_NEXT:%.*]], [[LOOP]] ] 436; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 437; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[IV]] to i16 438; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[IV_NEXT]] to i16 439; CHECK-NEXT: [[REC_NEXT]] = mul i16 [[TMP3]], [[TMP4]] 440; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 1 441; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP22:![0-9]+]] 442; CHECK: exit: 443; CHECK-NEXT: [[REC_LCSSA:%.*]] = phi i16 [ [[SCALAR_RECUR]], [[LOOP]] ], [ [[VECTOR_RECUR_EXTRACT_FOR_PHI]], [[MIDDLE_BLOCK]] ] 444; CHECK-NEXT: ret i16 [[REC_LCSSA]] 445; 446entry: 447 br label %loop 448 449loop: 450 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 451 %rec = phi i16 [ 0, %entry ], [ %rec.next, %loop ] 452 %iv.next = add i64 %iv, 1 453 %0 = trunc i64 %iv to i16 454 %1 = trunc i64 %iv.next to i16 455 %rec.next = mul i16 %0, %1 456 %ec = icmp eq i64 %iv, 1 457 br i1 %ec, label %exit, label %loop 458 459exit: 460 ret i16 %rec 461} 462 463define i32 @test_scalar_predicated_cost(i64 %x, i64 %y, ptr %A) #0 { 464; CHECK-LABEL: define i32 @test_scalar_predicated_cost( 465; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[A:%.*]]) #[[ATTR0]] { 466; CHECK-NEXT: iter.check: 467; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 468; CHECK: vector.main.loop.iter.check: 469; CHECK-NEXT: br i1 false, label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH1:%.*]] 470; CHECK: vector.ph: 471; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x i64> poison, i64 [[Y]], i64 0 472; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x i64> [[BROADCAST_SPLATINSERT]], <8 x i64> poison, <8 x i32> zeroinitializer 473; CHECK-NEXT: [[BROADCAST_SPLATINSERT4:%.*]] = insertelement <8 x i64> poison, i64 [[X]], i64 0 474; CHECK-NEXT: [[BROADCAST_SPLAT5:%.*]] = shufflevector <8 x i64> [[BROADCAST_SPLATINSERT4]], <8 x i64> poison, <8 x i32> zeroinitializer 475; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 476; CHECK: vector.body: 477; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH1]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 478; CHECK-NEXT: [[VEC_IND:%.*]] = phi <8 x i64> [ <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>, [[VECTOR_PH1]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 479; CHECK-NEXT: [[STEP_ADD:%.*]] = add <8 x i64> [[VEC_IND]], splat (i64 8) 480; CHECK-NEXT: [[STEP_ADD1:%.*]] = add <8 x i64> [[STEP_ADD]], splat (i64 8) 481; CHECK-NEXT: [[STEP_ADD2:%.*]] = add <8 x i64> [[STEP_ADD1]], splat (i64 8) 482; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 483; CHECK-NEXT: [[TMP4:%.*]] = icmp ule <8 x i64> [[VEC_IND]], [[BROADCAST_SPLAT]] 484; CHECK-NEXT: [[TMP5:%.*]] = icmp ule <8 x i64> [[STEP_ADD]], [[BROADCAST_SPLAT]] 485; CHECK-NEXT: [[TMP6:%.*]] = icmp ule <8 x i64> [[STEP_ADD1]], [[BROADCAST_SPLAT]] 486; CHECK-NEXT: [[TMP7:%.*]] = icmp ule <8 x i64> [[STEP_ADD2]], [[BROADCAST_SPLAT]] 487; CHECK-NEXT: [[TMP8:%.*]] = xor <8 x i1> [[TMP4]], splat (i1 true) 488; CHECK-NEXT: [[TMP9:%.*]] = xor <8 x i1> [[TMP5]], splat (i1 true) 489; CHECK-NEXT: [[TMP10:%.*]] = xor <8 x i1> [[TMP6]], splat (i1 true) 490; CHECK-NEXT: [[TMP11:%.*]] = xor <8 x i1> [[TMP7]], splat (i1 true) 491; CHECK-NEXT: [[TMP12:%.*]] = or <8 x i64> [[BROADCAST_SPLAT5]], [[VEC_IND]] 492; CHECK-NEXT: [[TMP13:%.*]] = or <8 x i64> [[BROADCAST_SPLAT5]], [[STEP_ADD]] 493; CHECK-NEXT: [[TMP14:%.*]] = or <8 x i64> [[BROADCAST_SPLAT5]], [[STEP_ADD1]] 494; CHECK-NEXT: [[TMP15:%.*]] = or <8 x i64> [[BROADCAST_SPLAT5]], [[STEP_ADD2]] 495; CHECK-NEXT: [[TMP16:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]] 496; CHECK-NEXT: [[TMP20:%.*]] = trunc <8 x i64> [[TMP12]] to <8 x i32> 497; CHECK-NEXT: [[TMP21:%.*]] = trunc <8 x i64> [[TMP13]] to <8 x i32> 498; CHECK-NEXT: [[TMP22:%.*]] = trunc <8 x i64> [[TMP14]] to <8 x i32> 499; CHECK-NEXT: [[TMP23:%.*]] = trunc <8 x i64> [[TMP15]] to <8 x i32> 500; CHECK-NEXT: [[TMP24:%.*]] = getelementptr i32, ptr [[TMP16]], i32 0 501; CHECK-NEXT: [[TMP25:%.*]] = getelementptr i32, ptr [[TMP16]], i32 8 502; CHECK-NEXT: [[TMP26:%.*]] = getelementptr i32, ptr [[TMP16]], i32 16 503; CHECK-NEXT: [[TMP27:%.*]] = getelementptr i32, ptr [[TMP16]], i32 24 504; CHECK-NEXT: call void @llvm.masked.store.v8i32.p0(<8 x i32> [[TMP20]], ptr [[TMP24]], i32 4, <8 x i1> [[TMP8]]) 505; CHECK-NEXT: call void @llvm.masked.store.v8i32.p0(<8 x i32> [[TMP21]], ptr [[TMP25]], i32 4, <8 x i1> [[TMP9]]) 506; CHECK-NEXT: call void @llvm.masked.store.v8i32.p0(<8 x i32> [[TMP22]], ptr [[TMP26]], i32 4, <8 x i1> [[TMP10]]) 507; CHECK-NEXT: call void @llvm.masked.store.v8i32.p0(<8 x i32> [[TMP23]], ptr [[TMP27]], i32 4, <8 x i1> [[TMP11]]) 508; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32 509; CHECK-NEXT: [[VEC_IND_NEXT]] = add <8 x i64> [[STEP_ADD2]], splat (i64 8) 510; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], 96 511; CHECK-NEXT: br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP23:![0-9]+]] 512; CHECK: middle.block: 513; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[VEC_EPILOG_ITER_CHECK:%.*]] 514; CHECK: vec.epilog.iter.check: 515; CHECK-NEXT: br i1 false, label [[SCALAR_PH]], label [[VEC_EPILOG_PH]] 516; CHECK: vec.epilog.ph: 517; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ 96, [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_PH]] ] 518; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[VEC_EPILOG_RESUME_VAL]], i64 0 519; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i64> [[DOTSPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer 520; CHECK-NEXT: [[INDUCTION:%.*]] = add <4 x i64> [[DOTSPLAT]], <i64 0, i64 1, i64 2, i64 3> 521; CHECK-NEXT: [[BROADCAST_SPLATINSERT7:%.*]] = insertelement <4 x i64> poison, i64 [[Y]], i64 0 522; CHECK-NEXT: [[BROADCAST_SPLAT8:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT7]], <4 x i64> poison, <4 x i32> zeroinitializer 523; CHECK-NEXT: [[BROADCAST_SPLATINSERT9:%.*]] = insertelement <4 x i64> poison, i64 [[X]], i64 0 524; CHECK-NEXT: [[BROADCAST_SPLAT10:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT9]], <4 x i64> poison, <4 x i32> zeroinitializer 525; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 526; CHECK: vec.epilog.vector.body: 527; CHECK-NEXT: [[INDEX4:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT11:%.*]], [[LOOP_HEADER]] ] 528; CHECK-NEXT: [[VEC_IND5:%.*]] = phi <4 x i64> [ [[INDUCTION]], [[VEC_EPILOG_PH]] ], [ [[VEC_IND_NEXT6:%.*]], [[LOOP_HEADER]] ] 529; CHECK-NEXT: [[TMP31:%.*]] = add i64 [[INDEX4]], 0 530; CHECK-NEXT: [[TMP32:%.*]] = icmp ule <4 x i64> [[VEC_IND5]], [[BROADCAST_SPLAT8]] 531; CHECK-NEXT: [[TMP33:%.*]] = xor <4 x i1> [[TMP32]], splat (i1 true) 532; CHECK-NEXT: [[TMP34:%.*]] = or <4 x i64> [[BROADCAST_SPLAT10]], [[VEC_IND5]] 533; CHECK-NEXT: [[TMP35:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP31]] 534; CHECK-NEXT: [[TMP36:%.*]] = trunc <4 x i64> [[TMP34]] to <4 x i32> 535; CHECK-NEXT: [[TMP29:%.*]] = getelementptr i32, ptr [[TMP35]], i32 0 536; CHECK-NEXT: call void @llvm.masked.store.v4i32.p0(<4 x i32> [[TMP36]], ptr [[TMP29]], i32 4, <4 x i1> [[TMP33]]) 537; CHECK-NEXT: [[INDEX_NEXT11]] = add nuw i64 [[INDEX4]], 4 538; CHECK-NEXT: [[VEC_IND_NEXT6]] = add <4 x i64> [[VEC_IND5]], splat (i64 4) 539; CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[INDEX_NEXT11]], 100 540; CHECK-NEXT: br i1 [[TMP30]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[LOOP_HEADER]], !llvm.loop [[LOOP24:![0-9]+]] 541; CHECK: vec.epilog.middle.block: 542; CHECK-NEXT: br i1 false, label [[EXIT]], label [[SCALAR_PH]] 543; CHECK: vec.epilog.scalar.ph: 544; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 100, [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ 0, [[ITER_CHECK:%.*]] ], [ 96, [[VEC_EPILOG_ITER_CHECK]] ] 545; CHECK-NEXT: br label [[LOOP_HEADER1:%.*]] 546; CHECK: loop.header: 547; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 548; CHECK-NEXT: [[CMP9_NOT:%.*]] = icmp ule i64 [[IV]], [[Y]] 549; CHECK-NEXT: br i1 [[CMP9_NOT]], label [[LOOP_LATCH]], label [[IF_THEN:%.*]] 550; CHECK: if.then: 551; CHECK-NEXT: [[OR:%.*]] = or i64 [[X]], [[IV]] 552; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 553; CHECK-NEXT: [[T:%.*]] = trunc i64 [[OR]] to i32 554; CHECK-NEXT: store i32 [[T]], ptr [[GEP]], align 4 555; CHECK-NEXT: br label [[LOOP_LATCH]] 556; CHECK: loop.latch: 557; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 558; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 100 559; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP_HEADER1]], !llvm.loop [[LOOP25:![0-9]+]] 560; CHECK: exit: 561; CHECK-NEXT: ret i32 0 562; 563entry: 564 br label %loop.header 565 566loop.header: 567 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 568 %cmp9.not = icmp ule i64 %iv, %y 569 br i1 %cmp9.not, label %loop.latch, label %if.then 570 571if.then: 572 %or = or i64 %x, %iv 573 %gep = getelementptr i32, ptr %A, i64 %iv 574 %t = trunc i64 %or to i32 575 store i32 %t, ptr %gep, align 4 576 br label %loop.latch 577 578loop.latch: 579 %iv.next = add i64 %iv, 1 580 %ec = icmp eq i64 %iv, 100 581 br i1 %ec, label %exit, label %loop.header 582 583exit: 584 ret i32 0 585} 586 587define void @wide_iv_trunc(ptr %dst, i64 %N) { 588; CHECK-LABEL: define void @wide_iv_trunc( 589; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) { 590; CHECK-NEXT: entry: 591; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[N]], 8 592; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] 593; CHECK: loop.preheader: 594; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 595; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 596; CHECK: vector.ph: 597; CHECK-NEXT: [[N_RND_UP:%.*]] = add i64 [[TMP0]], 3 598; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N_RND_UP]], 4 599; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N_RND_UP]], [[N_MOD_VF]] 600; CHECK-NEXT: [[TRIP_COUNT_MINUS_1:%.*]] = sub i64 [[TMP0]], 1 601; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[TRIP_COUNT_MINUS_1]], i64 0 602; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer 603; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 604; CHECK: vector.body: 605; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE6:%.*]] ] 606; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_STORE_CONTINUE6]] ] 607; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDEX]] to i32 608; CHECK-NEXT: [[TMP2:%.*]] = icmp ule <4 x i64> [[VEC_IND]], [[BROADCAST_SPLAT]] 609; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i1> [[TMP2]], i32 0 610; CHECK-NEXT: br i1 [[TMP3]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] 611; CHECK: pred.store.if: 612; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[TMP1]], 0 613; CHECK-NEXT: store i32 [[TMP4]], ptr [[DST]], align 4 614; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]] 615; CHECK: pred.store.continue: 616; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i1> [[TMP2]], i32 1 617; CHECK-NEXT: br i1 [[TMP5]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2:%.*]] 618; CHECK: pred.store.if1: 619; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP1]], 1 620; CHECK-NEXT: store i32 [[TMP6]], ptr [[DST]], align 4 621; CHECK-NEXT: br label [[PRED_STORE_CONTINUE2]] 622; CHECK: pred.store.continue2: 623; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i1> [[TMP2]], i32 2 624; CHECK-NEXT: br i1 [[TMP7]], label [[PRED_STORE_IF3:%.*]], label [[PRED_STORE_CONTINUE4:%.*]] 625; CHECK: pred.store.if3: 626; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[TMP1]], 2 627; CHECK-NEXT: store i32 [[TMP8]], ptr [[DST]], align 4 628; CHECK-NEXT: br label [[PRED_STORE_CONTINUE4]] 629; CHECK: pred.store.continue4: 630; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i1> [[TMP2]], i32 3 631; CHECK-NEXT: br i1 [[TMP9]], label [[PRED_STORE_IF5:%.*]], label [[PRED_STORE_CONTINUE6]] 632; CHECK: pred.store.if5: 633; CHECK-NEXT: [[TMP10:%.*]] = add i32 [[TMP1]], 3 634; CHECK-NEXT: store i32 [[TMP10]], ptr [[DST]], align 4 635; CHECK-NEXT: br label [[PRED_STORE_CONTINUE6]] 636; CHECK: pred.store.continue6: 637; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 638; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], splat (i64 4) 639; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 640; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]] 641; CHECK: middle.block: 642; CHECK-NEXT: br i1 true, label [[EXIT_LOOPEXIT:%.*]], label [[SCALAR_PH]] 643; CHECK: scalar.ph: 644; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[LOOP_PREHEADER]] ] 645; CHECK-NEXT: br label [[LOOP:%.*]] 646; CHECK: loop: 647; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] 648; CHECK-NEXT: [[IV_TRUNC:%.*]] = trunc i64 [[IV]] to i32 649; CHECK-NEXT: store i32 [[IV_TRUNC]], ptr [[DST]], align 4 650; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 651; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[N]] 652; CHECK-NEXT: br i1 [[EC]], label [[EXIT_LOOPEXIT]], label [[LOOP]], !llvm.loop [[LOOP27:![0-9]+]] 653; CHECK: exit.loopexit: 654; CHECK-NEXT: br label [[EXIT]] 655; CHECK: exit: 656; CHECK-NEXT: ret void 657; 658entry: 659 %cmp = icmp ult i64 %N, 8 660 br i1 %cmp, label %loop, label %exit 661 662loop: 663 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 664 %iv.trunc = trunc i64 %iv to i32 665 store i32 %iv.trunc, ptr %dst, align 4 666 %iv.next = add i64 %iv, 1 667 %ec = icmp eq i64 %iv, %N 668 br i1 %ec, label %exit, label %loop 669 670exit: 671 ret void 672} 673 674define void @wide_iv_trunc_reuse(ptr %dst) { 675; CHECK-LABEL: define void @wide_iv_trunc_reuse( 676; CHECK-SAME: ptr [[DST:%.*]]) { 677; CHECK-NEXT: entry: 678; CHECK-NEXT: br label [[LOOP:%.*]] 679; CHECK: loop: 680; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 681; CHECK-NEXT: [[IV_2:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV_TRUNC:%.*]], [[LOOP]] ] 682; CHECK-NEXT: store i32 [[IV_2]], ptr [[DST]], align 4 683; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 684; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 0 685; CHECK-NEXT: [[IV_TRUNC]] = trunc i64 [[IV]] to i32 686; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]] 687; CHECK: exit: 688; CHECK-NEXT: ret void 689; 690entry: 691 br label %loop 692 693loop: 694 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ] 695 %iv.2 = phi i32 [ 0, %entry ], [ %iv.trunc, %loop ] 696 store i32 %iv.2, ptr %dst, align 4 697 %iv.next = add i64 %iv, 1 698 %ec = icmp eq i64 %iv, 0 699 %iv.trunc = trunc i64 %iv to i32 700 br i1 %ec, label %exit, label %loop 701 702exit: 703 ret void 704} 705 706define void @wombat(i32 %arg, ptr %dst) #1 { 707; CHECK-LABEL: define void @wombat( 708; CHECK-SAME: i32 [[ARG:%.*]], ptr [[DST:%.*]]) #[[ATTR1:[0-9]+]] { 709; CHECK-NEXT: entry: 710; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[ARG]], 3 711; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[ARG]] to i64 712; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 713; CHECK: vector.ph: 714; CHECK-NEXT: [[TMP0:%.*]] = mul i32 56, [[ARG]] 715; CHECK-NEXT: [[IND_END:%.*]] = add i32 [[MUL]], [[TMP0]] 716; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x i32> poison, i32 [[MUL]], i64 0 717; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT]], <8 x i32> poison, <8 x i32> zeroinitializer 718; CHECK-NEXT: [[DOTSPLATINSERT1:%.*]] = insertelement <8 x i32> poison, i32 [[ARG]], i64 0 719; CHECK-NEXT: [[DOTSPLAT2:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT1]], <8 x i32> poison, <8 x i32> zeroinitializer 720; CHECK-NEXT: [[TMP1:%.*]] = mul <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>, [[DOTSPLAT2]] 721; CHECK-NEXT: [[INDUCTION:%.*]] = add <8 x i32> [[DOTSPLAT]], [[TMP1]] 722; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[ARG]], 8 723; CHECK-NEXT: [[DOTSPLATINSERT3:%.*]] = insertelement <8 x i32> poison, i32 [[TMP2]], i64 0 724; CHECK-NEXT: [[DOTSPLAT4:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT3]], <8 x i32> poison, <8 x i32> zeroinitializer 725; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 726; CHECK: vector.body: 727; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 728; CHECK-NEXT: [[VEC_IND:%.*]] = phi <8 x i32> [ [[INDUCTION]], [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 729; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 4, [[INDEX]] 730; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 0 731; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, ptr [[DST]], i64 [[TMP3]] 732; CHECK-NEXT: [[TMP5:%.*]] = and <8 x i32> [[VEC_IND]], splat (i32 12) 733; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[TMP4]], i32 0 734; CHECK-NEXT: store <8 x i32> [[TMP5]], ptr [[TMP6]], align 4 735; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8 736; CHECK-NEXT: [[VEC_IND_NEXT]] = add <8 x i32> [[VEC_IND]], [[DOTSPLAT4]] 737; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 56 738; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]] 739; CHECK: middle.block: 740; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]] 741; CHECK: scalar.ph: 742; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 60, [[MIDDLE_BLOCK]] ], [ 4, [[ENTRY:%.*]] ] 743; CHECK-NEXT: [[BC_RESUME_VAL5:%.*]] = phi i32 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[MUL]], [[ENTRY]] ] 744; CHECK-NEXT: br label [[LOOP:%.*]] 745; CHECK: loop: 746; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[ADD:%.*]], [[LOOP]] ] 747; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ [[BC_RESUME_VAL5]], [[SCALAR_PH]] ], [ [[TRUNC:%.*]], [[LOOP]] ] 748; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i32, ptr [[DST]], i64 [[PHI]] 749; CHECK-NEXT: [[AND:%.*]] = and i32 [[PHI2]], 12 750; CHECK-NEXT: store i32 [[AND]], ptr [[GETELEMENTPTR]], align 4 751; CHECK-NEXT: [[MUL3:%.*]] = mul i64 [[PHI]], [[ZEXT]] 752; CHECK-NEXT: [[ADD]] = add i64 [[PHI]], 1 753; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[PHI]], 65 754; CHECK-NEXT: [[TRUNC]] = trunc i64 [[MUL3]] to i32 755; CHECK-NEXT: br i1 [[ICMP]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP29:![0-9]+]] 756; CHECK: exit: 757; CHECK-NEXT: ret void 758; 759entry: 760 %mul = mul i32 %arg, 3 761 %zext = zext i32 %arg to i64 762 br label %loop 763 764loop: 765 %phi = phi i64 [ 4, %entry ], [ %add, %loop ] 766 %phi2 = phi i32 [ %mul, %entry ], [ %trunc, %loop ] 767 %getelementptr = getelementptr i32, ptr %dst, i64 %phi 768 %and = and i32 %phi2, 12 769 store i32 %and, ptr %getelementptr, align 4 770 %mul3 = mul i64 %phi, %zext 771 %add = add i64 %phi, 1 772 %icmp = icmp ugt i64 %phi, 65 773 %trunc = trunc i64 %mul3 to i32 774 br i1 %icmp, label %exit, label %loop 775 776exit: 777 ret void 778} 779 780define void @wombat2(i32 %arg, ptr %dst) #1 { 781; CHECK-LABEL: define void @wombat2( 782; CHECK-SAME: i32 [[ARG:%.*]], ptr [[DST:%.*]]) #[[ATTR1]] { 783; CHECK-NEXT: entry: 784; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[ARG]], 3 785; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[ARG]] to i64 786; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 787; CHECK: vector.ph: 788; CHECK-NEXT: [[TMP0:%.*]] = mul i32 56, [[ARG]] 789; CHECK-NEXT: [[IND_END:%.*]] = add i32 [[MUL]], [[TMP0]] 790; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x i32> poison, i32 [[MUL]], i64 0 791; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT]], <8 x i32> poison, <8 x i32> zeroinitializer 792; CHECK-NEXT: [[DOTSPLATINSERT1:%.*]] = insertelement <8 x i32> poison, i32 [[ARG]], i64 0 793; CHECK-NEXT: [[DOTSPLAT2:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT1]], <8 x i32> poison, <8 x i32> zeroinitializer 794; CHECK-NEXT: [[TMP1:%.*]] = mul <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>, [[DOTSPLAT2]] 795; CHECK-NEXT: [[INDUCTION:%.*]] = add <8 x i32> [[DOTSPLAT]], [[TMP1]] 796; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[ARG]], 8 797; CHECK-NEXT: [[DOTSPLATINSERT3:%.*]] = insertelement <8 x i32> poison, i32 [[TMP2]], i64 0 798; CHECK-NEXT: [[DOTSPLAT4:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT3]], <8 x i32> poison, <8 x i32> zeroinitializer 799; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 800; CHECK: vector.body: 801; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 802; CHECK-NEXT: [[VEC_IND:%.*]] = phi <8 x i32> [ [[INDUCTION]], [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 803; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 4, [[INDEX]] 804; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 0 805; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, ptr [[DST]], i64 [[TMP3]] 806; CHECK-NEXT: [[TMP5:%.*]] = and <8 x i32> [[VEC_IND]], splat (i32 12) 807; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[TMP4]], i32 0 808; CHECK-NEXT: store <8 x i32> [[TMP5]], ptr [[TMP6]], align 4 809; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8 810; CHECK-NEXT: [[VEC_IND_NEXT]] = add <8 x i32> [[VEC_IND]], [[DOTSPLAT4]] 811; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 56 812; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP30:![0-9]+]] 813; CHECK: middle.block: 814; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]] 815; CHECK: scalar.ph: 816; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 60, [[MIDDLE_BLOCK]] ], [ 4, [[ENTRY:%.*]] ] 817; CHECK-NEXT: [[BC_RESUME_VAL5:%.*]] = phi i32 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[MUL]], [[ENTRY]] ] 818; CHECK-NEXT: br label [[LOOP:%.*]] 819; CHECK: loop: 820; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[ADD:%.*]], [[LOOP]] ] 821; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ [[BC_RESUME_VAL5]], [[SCALAR_PH]] ], [ [[TRUNC_1:%.*]], [[LOOP]] ] 822; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i32, ptr [[DST]], i64 [[PHI]] 823; CHECK-NEXT: [[AND:%.*]] = and i32 [[PHI2]], 12 824; CHECK-NEXT: store i32 [[AND]], ptr [[GETELEMENTPTR]], align 4 825; CHECK-NEXT: [[MUL3:%.*]] = mul i64 [[PHI]], [[ZEXT]] 826; CHECK-NEXT: [[ADD]] = add i64 [[PHI]], 1 827; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[PHI]], 65 828; CHECK-NEXT: [[TRUNC_0:%.*]] = trunc i64 [[MUL3]] to i60 829; CHECK-NEXT: [[TRUNC_1]] = trunc i60 [[TRUNC_0]] to i32 830; CHECK-NEXT: br i1 [[ICMP]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP31:![0-9]+]] 831; CHECK: exit: 832; CHECK-NEXT: ret void 833; 834entry: 835 %mul = mul i32 %arg, 3 836 %zext = zext i32 %arg to i64 837 br label %loop 838 839loop: 840 %phi = phi i64 [ 4, %entry ], [ %add, %loop ] 841 %phi2 = phi i32 [ %mul, %entry ], [ %trunc.1, %loop ] 842 %getelementptr = getelementptr i32, ptr %dst, i64 %phi 843 %and = and i32 %phi2, 12 844 store i32 %and, ptr %getelementptr, align 4 845 %mul3 = mul i64 %phi, %zext 846 %add = add i64 %phi, 1 847 %icmp = icmp ugt i64 %phi, 65 848 %trunc.0 = trunc i64 %mul3 to i60 849 %trunc.1 = trunc i60 %trunc.0 to i32 850 br i1 %icmp, label %exit, label %loop 851 852exit: 853 ret void 854} 855 856 857define void @with_dead_use(i32 %arg, ptr %dst) #1 { 858; CHECK-LABEL: define void @with_dead_use( 859; CHECK-SAME: i32 [[ARG:%.*]], ptr [[DST:%.*]]) #[[ATTR1]] { 860; CHECK-NEXT: entry: 861; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[ARG]], 3 862; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[ARG]] to i64 863; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 864; CHECK: vector.ph: 865; CHECK-NEXT: [[TMP0:%.*]] = mul i32 56, [[ARG]] 866; CHECK-NEXT: [[IND_END:%.*]] = add i32 [[MUL]], [[TMP0]] 867; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x i32> poison, i32 [[MUL]], i64 0 868; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT]], <8 x i32> poison, <8 x i32> zeroinitializer 869; CHECK-NEXT: [[DOTSPLATINSERT1:%.*]] = insertelement <8 x i32> poison, i32 [[ARG]], i64 0 870; CHECK-NEXT: [[DOTSPLAT2:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT1]], <8 x i32> poison, <8 x i32> zeroinitializer 871; CHECK-NEXT: [[TMP1:%.*]] = mul <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>, [[DOTSPLAT2]] 872; CHECK-NEXT: [[INDUCTION:%.*]] = add <8 x i32> [[DOTSPLAT]], [[TMP1]] 873; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[ARG]], 8 874; CHECK-NEXT: [[DOTSPLATINSERT3:%.*]] = insertelement <8 x i32> poison, i32 [[TMP2]], i64 0 875; CHECK-NEXT: [[DOTSPLAT4:%.*]] = shufflevector <8 x i32> [[DOTSPLATINSERT3]], <8 x i32> poison, <8 x i32> zeroinitializer 876; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 877; CHECK: vector.body: 878; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 879; CHECK-NEXT: [[VEC_IND:%.*]] = phi <8 x i32> [ [[INDUCTION]], [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 880; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 4, [[INDEX]] 881; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 0 882; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, ptr [[DST]], i64 [[TMP3]] 883; CHECK-NEXT: [[TMP5:%.*]] = and <8 x i32> [[VEC_IND]], splat (i32 12) 884; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[TMP4]], i32 0 885; CHECK-NEXT: store <8 x i32> [[TMP5]], ptr [[TMP6]], align 4 886; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8 887; CHECK-NEXT: [[VEC_IND_NEXT]] = add <8 x i32> [[VEC_IND]], [[DOTSPLAT4]] 888; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 56 889; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP32:![0-9]+]] 890; CHECK: middle.block: 891; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]] 892; CHECK: scalar.ph: 893; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 60, [[MIDDLE_BLOCK]] ], [ 4, [[ENTRY:%.*]] ] 894; CHECK-NEXT: [[BC_RESUME_VAL5:%.*]] = phi i32 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[MUL]], [[ENTRY]] ] 895; CHECK-NEXT: br label [[LOOP:%.*]] 896; CHECK: loop: 897; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[ADD:%.*]], [[LOOP]] ] 898; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ [[BC_RESUME_VAL5]], [[SCALAR_PH]] ], [ [[TRUNC:%.*]], [[LOOP]] ] 899; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i32, ptr [[DST]], i64 [[PHI]] 900; CHECK-NEXT: [[AND:%.*]] = and i32 [[PHI2]], 12 901; CHECK-NEXT: store i32 [[AND]], ptr [[GETELEMENTPTR]], align 4 902; CHECK-NEXT: [[MUL3:%.*]] = mul i64 [[PHI]], [[ZEXT]] 903; CHECK-NEXT: [[ADD]] = add i64 [[PHI]], 1 904; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[PHI]], 65 905; CHECK-NEXT: [[TRUNC]] = trunc i64 [[MUL3]] to i32 906; CHECK-NEXT: [[DEAD_AND:%.*]] = and i32 [[TRUNC]], 123 907; CHECK-NEXT: br i1 [[ICMP]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP33:![0-9]+]] 908; CHECK: exit: 909; CHECK-NEXT: ret void 910; 911entry: 912 %mul = mul i32 %arg, 3 913 %zext = zext i32 %arg to i64 914 br label %loop 915 916loop: 917 %phi = phi i64 [ 4, %entry ], [ %add, %loop ] 918 %phi2 = phi i32 [ %mul, %entry ], [ %trunc, %loop ] 919 %getelementptr = getelementptr i32, ptr %dst, i64 %phi 920 %and = and i32 %phi2, 12 921 store i32 %and, ptr %getelementptr, align 4 922 %mul3 = mul i64 %phi, %zext 923 %add = add i64 %phi, 1 924 %icmp = icmp ugt i64 %phi, 65 925 %trunc = trunc i64 %mul3 to i32 926 %dead.and = and i32 %trunc, 123 927 br i1 %icmp, label %exit, label %loop 928 929exit: 930 ret void 931} 932 933attributes #0 = { "min-legal-vector-width"="0" "target-cpu"="skylake-avx512" } 934attributes #1 = { "target-cpu"="skylake-avx512" "target-features"="-avx512f" } 935;. 936; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]} 937; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1} 938; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"} 939; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]], [[META2]]} 940; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META2]], [[META1]]} 941; CHECK: [[META5]] = !{[[META6:![0-9]+]]} 942; CHECK: [[META6]] = distinct !{[[META6]], [[META7:![0-9]+]]} 943; CHECK: [[META7]] = distinct !{[[META7]], !"LVerDomain"} 944; CHECK: [[META8]] = !{[[META9:![0-9]+]]} 945; CHECK: [[META9]] = distinct !{[[META9]], [[META7]]} 946; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META1]], [[META2]]} 947; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META1]]} 948; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META1]], [[META2]]} 949; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META2]], [[META1]]} 950; CHECK: [[META14]] = !{[[META15:![0-9]+]]} 951; CHECK: [[META15]] = distinct !{[[META15]], [[META16:![0-9]+]]} 952; CHECK: [[META16]] = distinct !{[[META16]], !"LVerDomain"} 953; CHECK: [[META17]] = !{[[META18:![0-9]+]]} 954; CHECK: [[META18]] = distinct !{[[META18]], [[META16]]} 955; CHECK: [[LOOP19]] = distinct !{[[LOOP19]], [[META1]], [[META2]]} 956; CHECK: [[LOOP20]] = distinct !{[[LOOP20]], [[META1]]} 957; CHECK: [[LOOP21]] = distinct !{[[LOOP21]], [[META1]], [[META2]]} 958; CHECK: [[LOOP22]] = distinct !{[[LOOP22]], [[META2]], [[META1]]} 959; CHECK: [[LOOP23]] = distinct !{[[LOOP23]], [[META1]], [[META2]]} 960; CHECK: [[LOOP24]] = distinct !{[[LOOP24]], [[META1]], [[META2]]} 961; CHECK: [[LOOP25]] = distinct !{[[LOOP25]], [[META2]], [[META1]]} 962; CHECK: [[LOOP26]] = distinct !{[[LOOP26]], [[META1]], [[META2]]} 963; CHECK: [[LOOP27]] = distinct !{[[LOOP27]], [[META2]], [[META1]]} 964; CHECK: [[LOOP28]] = distinct !{[[LOOP28]], [[META1]], [[META2]]} 965; CHECK: [[LOOP29]] = distinct !{[[LOOP29]], [[META2]], [[META1]]} 966; CHECK: [[LOOP30]] = distinct !{[[LOOP30]], [[META1]], [[META2]]} 967; CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META2]], [[META1]]} 968; CHECK: [[LOOP32]] = distinct !{[[LOOP32]], [[META1]], [[META2]]} 969; CHECK: [[LOOP33]] = distinct !{[[LOOP33]], [[META2]], [[META1]]} 970;. 971