416 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 52; This test verifies that the loop vectorizer will NOT vectorize loops that3; will produce a tail loop with the optimize for size or the minimize size4; attributes. This is a target-dependent version of the test.5; RUN: opt < %s -passes=loop-vectorize -force-vector-width=64 -S -mtriple=x86_64-unknown-linux -mcpu=skx | FileCheck %s6; RUN: opt < %s -passes=loop-vectorize -S -mtriple=x86_64-unknown-linux -mcpu=skx | FileCheck %s --check-prefix AUTOVF7 8target datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S128"9 10@tab = common global [32 x i8] zeroinitializer, align 111 12define i32 @foo_optsize() #0 {13; CHECK-LABEL: define i32 @foo_optsize(14; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {15; CHECK-NEXT: [[ENTRY:.*:]]16; CHECK-NEXT: br label %[[VECTOR_PH:.*]]17; CHECK: [[VECTOR_PH]]:18; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]19; CHECK: [[VECTOR_BODY]]:20; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]21; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <64 x i32> poison, i32 [[INDEX]], i64 022; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <64 x i32> [[BROADCAST_SPLATINSERT]], <64 x i32> poison, <64 x i32> zeroinitializer23; CHECK-NEXT: [[VEC_IV:%.*]] = add <64 x i32> [[BROADCAST_SPLAT]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, 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, i32 31, i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39, i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55, i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>24; CHECK-NEXT: [[TMP1:%.*]] = icmp ule <64 x i32> [[VEC_IV]], splat (i32 202)25; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [32 x i8], ptr @tab, i32 0, i32 [[INDEX]]26; CHECK-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <64 x i8> @llvm.masked.load.v64i8.p0(ptr align 1 [[TMP2]], <64 x i1> [[TMP1]], <64 x i8> poison)27; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <64 x i8> [[WIDE_MASKED_LOAD]], zeroinitializer28; CHECK-NEXT: [[TMP5:%.*]] = select <64 x i1> [[TMP4]], <64 x i8> splat (i8 2), <64 x i8> splat (i8 1)29; CHECK-NEXT: call void @llvm.masked.store.v64i8.p0(<64 x i8> [[TMP5]], ptr align 1 [[TMP2]], <64 x i1> [[TMP1]])30; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 6431; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 25632; CHECK-NEXT: br i1 [[TMP6]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]33; CHECK: [[MIDDLE_BLOCK]]:34; CHECK-NEXT: br label %[[FOR_END:.*]]35; CHECK: [[FOR_END]]:36; CHECK-NEXT: ret i32 037;38; AUTOVF-LABEL: define i32 @foo_optsize(39; AUTOVF-SAME: ) #[[ATTR0:[0-9]+]] {40; AUTOVF-NEXT: [[ENTRY:.*:]]41; AUTOVF-NEXT: br label %[[VECTOR_PH:.*]]42; AUTOVF: [[VECTOR_PH]]:43; AUTOVF-NEXT: br label %[[VECTOR_BODY:.*]]44; AUTOVF: [[VECTOR_BODY]]:45; AUTOVF-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]46; AUTOVF-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <32 x i32> poison, i32 [[INDEX]], i64 047; AUTOVF-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <32 x i32> [[BROADCAST_SPLATINSERT]], <32 x i32> poison, <32 x i32> zeroinitializer48; AUTOVF-NEXT: [[VEC_IV:%.*]] = add <32 x i32> [[BROADCAST_SPLAT]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, 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, i32 31>49; AUTOVF-NEXT: [[TMP1:%.*]] = icmp ule <32 x i32> [[VEC_IV]], splat (i32 202)50; AUTOVF-NEXT: [[TMP2:%.*]] = getelementptr inbounds [32 x i8], ptr @tab, i32 0, i32 [[INDEX]]51; AUTOVF-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <32 x i8> @llvm.masked.load.v32i8.p0(ptr align 1 [[TMP2]], <32 x i1> [[TMP1]], <32 x i8> poison)52; AUTOVF-NEXT: [[TMP4:%.*]] = icmp eq <32 x i8> [[WIDE_MASKED_LOAD]], zeroinitializer53; AUTOVF-NEXT: [[TMP5:%.*]] = select <32 x i1> [[TMP4]], <32 x i8> splat (i8 2), <32 x i8> splat (i8 1)54; AUTOVF-NEXT: call void @llvm.masked.store.v32i8.p0(<32 x i8> [[TMP5]], ptr align 1 [[TMP2]], <32 x i1> [[TMP1]])55; AUTOVF-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 3256; AUTOVF-NEXT: [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 22457; AUTOVF-NEXT: br i1 [[TMP6]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]58; AUTOVF: [[MIDDLE_BLOCK]]:59; AUTOVF-NEXT: br label %[[FOR_END:.*]]60; AUTOVF: [[FOR_END]]:61; AUTOVF-NEXT: ret i32 062;63 64entry:65 br label %for.body66 67for.body: ; preds = %for.body, %entry68 %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]69 %arrayidx = getelementptr inbounds [32 x i8], ptr @tab, i32 0, i32 %i.0870 %0 = load i8, ptr %arrayidx, align 171 %cmp1 = icmp eq i8 %0, 072 %. = select i1 %cmp1, i8 2, i8 173 store i8 %., ptr %arrayidx, align 174 %inc = add nsw i32 %i.08, 175 %exitcond = icmp eq i32 %i.08, 20276 br i1 %exitcond, label %for.end, label %for.body77 78for.end: ; preds = %for.body79 ret i32 080}81 82attributes #0 = { optsize }83 84define i32 @foo_minsize() #1 {85; CHECK-LABEL: define i32 @foo_minsize(86; CHECK-SAME: ) #[[ATTR1:[0-9]+]] {87; CHECK-NEXT: [[ENTRY:.*:]]88; CHECK-NEXT: br label %[[VECTOR_PH:.*]]89; CHECK: [[VECTOR_PH]]:90; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]91; CHECK: [[VECTOR_BODY]]:92; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]93; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <64 x i32> poison, i32 [[INDEX]], i64 094; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <64 x i32> [[BROADCAST_SPLATINSERT]], <64 x i32> poison, <64 x i32> zeroinitializer95; CHECK-NEXT: [[VEC_IV:%.*]] = add <64 x i32> [[BROADCAST_SPLAT]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, 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, i32 31, i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39, i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55, i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>96; CHECK-NEXT: [[TMP1:%.*]] = icmp ule <64 x i32> [[VEC_IV]], splat (i32 202)97; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [32 x i8], ptr @tab, i32 0, i32 [[INDEX]]98; CHECK-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <64 x i8> @llvm.masked.load.v64i8.p0(ptr align 1 [[TMP2]], <64 x i1> [[TMP1]], <64 x i8> poison)99; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <64 x i8> [[WIDE_MASKED_LOAD]], zeroinitializer100; CHECK-NEXT: [[TMP5:%.*]] = select <64 x i1> [[TMP4]], <64 x i8> splat (i8 2), <64 x i8> splat (i8 1)101; CHECK-NEXT: call void @llvm.masked.store.v64i8.p0(<64 x i8> [[TMP5]], ptr align 1 [[TMP2]], <64 x i1> [[TMP1]])102; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 64103; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 256104; CHECK-NEXT: br i1 [[TMP6]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]105; CHECK: [[MIDDLE_BLOCK]]:106; CHECK-NEXT: br label %[[FOR_END:.*]]107; CHECK: [[FOR_END]]:108; CHECK-NEXT: ret i32 0109;110; AUTOVF-LABEL: define i32 @foo_minsize(111; AUTOVF-SAME: ) #[[ATTR1:[0-9]+]] {112; AUTOVF-NEXT: [[ENTRY:.*:]]113; AUTOVF-NEXT: br label %[[VECTOR_PH:.*]]114; AUTOVF: [[VECTOR_PH]]:115; AUTOVF-NEXT: br label %[[VECTOR_BODY:.*]]116; AUTOVF: [[VECTOR_BODY]]:117; AUTOVF-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]118; AUTOVF-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <32 x i32> poison, i32 [[INDEX]], i64 0119; AUTOVF-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <32 x i32> [[BROADCAST_SPLATINSERT]], <32 x i32> poison, <32 x i32> zeroinitializer120; AUTOVF-NEXT: [[VEC_IV:%.*]] = add <32 x i32> [[BROADCAST_SPLAT]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, 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, i32 31>121; AUTOVF-NEXT: [[TMP1:%.*]] = icmp ule <32 x i32> [[VEC_IV]], splat (i32 202)122; AUTOVF-NEXT: [[TMP2:%.*]] = getelementptr inbounds [32 x i8], ptr @tab, i32 0, i32 [[INDEX]]123; AUTOVF-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <32 x i8> @llvm.masked.load.v32i8.p0(ptr align 1 [[TMP2]], <32 x i1> [[TMP1]], <32 x i8> poison)124; AUTOVF-NEXT: [[TMP4:%.*]] = icmp eq <32 x i8> [[WIDE_MASKED_LOAD]], zeroinitializer125; AUTOVF-NEXT: [[TMP5:%.*]] = select <32 x i1> [[TMP4]], <32 x i8> splat (i8 2), <32 x i8> splat (i8 1)126; AUTOVF-NEXT: call void @llvm.masked.store.v32i8.p0(<32 x i8> [[TMP5]], ptr align 1 [[TMP2]], <32 x i1> [[TMP1]])127; AUTOVF-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 32128; AUTOVF-NEXT: [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 224129; AUTOVF-NEXT: br i1 [[TMP6]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]130; AUTOVF: [[MIDDLE_BLOCK]]:131; AUTOVF-NEXT: br label %[[FOR_END:.*]]132; AUTOVF: [[FOR_END]]:133; AUTOVF-NEXT: ret i32 0134;135 136entry:137 br label %for.body138 139for.body: ; preds = %for.body, %entry140 %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ]141 %arrayidx = getelementptr inbounds [32 x i8], ptr @tab, i32 0, i32 %i.08142 %0 = load i8, ptr %arrayidx, align 1143 %cmp1 = icmp eq i8 %0, 0144 %. = select i1 %cmp1, i8 2, i8 1145 store i8 %., ptr %arrayidx, align 1146 %inc = add nsw i32 %i.08, 1147 %exitcond = icmp eq i32 %i.08, 202148 br i1 %exitcond, label %for.end, label %for.body149 150for.end: ; preds = %for.body151 ret i32 0152}153 154attributes #1 = { minsize }155 156 157; We can vectorize this one by refraining from versioning for stride==1.158define void @scev4stride1(ptr noalias nocapture %a, ptr noalias nocapture readonly %b, i32 %k) #2 {159; CHECK-LABEL: define void @scev4stride1(160; CHECK-SAME: ptr noalias captures(none) [[A:%.*]], ptr noalias readonly captures(none) [[B:%.*]], i32 [[K:%.*]]) #[[ATTR0]] {161; CHECK-NEXT: [[FOR_BODY_PREHEADER:.*:]]162; CHECK-NEXT: br label %[[VECTOR_PH:.*]]163; CHECK: [[VECTOR_PH]]:164; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <64 x i32> poison, i32 [[K]], i64 0165; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <64 x i32> [[BROADCAST_SPLATINSERT]], <64 x i32> poison, <64 x i32> zeroinitializer166; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]167; CHECK: [[VECTOR_BODY]]:168; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]169; CHECK-NEXT: [[VEC_IND:%.*]] = phi <64 x i32> [ <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, 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, i32 31, i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39, i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55, i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]170; CHECK-NEXT: [[TMP1:%.*]] = mul nsw <64 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]171; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[B]], <64 x i32> [[TMP1]]172; CHECK-NEXT: [[WIDE_MASKED_GATHER:%.*]] = call <64 x i32> @llvm.masked.gather.v64i32.v64p0(<64 x ptr> align 4 [[TMP2]], <64 x i1> splat (i1 true), <64 x i32> poison)173; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INDEX]]174; CHECK-NEXT: store <64 x i32> [[WIDE_MASKED_GATHER]], ptr [[TMP3]], align 4175; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 64176; CHECK-NEXT: [[VEC_IND_NEXT]] = add nuw nsw <64 x i32> [[VEC_IND]], splat (i32 64)177; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[INDEX_NEXT]], 256178; CHECK-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]179; CHECK: [[MIDDLE_BLOCK]]:180; CHECK-NEXT: br label %[[FOR_END_LOOPEXIT:.*]]181; CHECK: [[FOR_END_LOOPEXIT]]:182; CHECK-NEXT: ret void183;184; AUTOVF-LABEL: define void @scev4stride1(185; AUTOVF-SAME: ptr noalias captures(none) [[A:%.*]], ptr noalias readonly captures(none) [[B:%.*]], i32 [[K:%.*]]) #[[ATTR0]] {186; AUTOVF-NEXT: [[FOR_BODY_PREHEADER:.*:]]187; AUTOVF-NEXT: br label %[[VECTOR_PH:.*]]188; AUTOVF: [[VECTOR_PH]]:189; AUTOVF-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x i32> poison, i32 [[K]], i64 0190; AUTOVF-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x i32> [[BROADCAST_SPLATINSERT]], <8 x i32> poison, <8 x i32> zeroinitializer191; AUTOVF-NEXT: br label %[[VECTOR_BODY:.*]]192; AUTOVF: [[VECTOR_BODY]]:193; AUTOVF-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]194; AUTOVF-NEXT: [[VEC_IND:%.*]] = phi <8 x i32> [ <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]195; AUTOVF-NEXT: [[TMP1:%.*]] = mul nsw <8 x i32> [[VEC_IND]], [[BROADCAST_SPLAT]]196; AUTOVF-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[B]], <8 x i32> [[TMP1]]197; AUTOVF-NEXT: [[WIDE_MASKED_GATHER:%.*]] = call <8 x i32> @llvm.masked.gather.v8i32.v8p0(<8 x ptr> align 4 [[TMP2]], <8 x i1> splat (i1 true), <8 x i32> poison)198; AUTOVF-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INDEX]]199; AUTOVF-NEXT: store <8 x i32> [[WIDE_MASKED_GATHER]], ptr [[TMP3]], align 4200; AUTOVF-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 8201; AUTOVF-NEXT: [[VEC_IND_NEXT]] = add nuw nsw <8 x i32> [[VEC_IND]], splat (i32 8)202; AUTOVF-NEXT: [[TMP5:%.*]] = icmp eq i32 [[INDEX_NEXT]], 256203; AUTOVF-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]204; AUTOVF: [[MIDDLE_BLOCK]]:205; AUTOVF-NEXT: br label %[[FOR_END_LOOPEXIT:.*]]206; AUTOVF: [[FOR_END_LOOPEXIT]]:207; AUTOVF-NEXT: ret void208;209for.body.preheader:210 br label %for.body211 212for.body: ; preds = %for.body.preheader, %for.body213 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]214 %mul = mul nsw i32 %i.07, %k215 %arrayidx = getelementptr inbounds i32, ptr %b, i32 %mul216 %0 = load i32, ptr %arrayidx, align 4217 %arrayidx1 = getelementptr inbounds i32, ptr %a, i32 %i.07218 store i32 %0, ptr %arrayidx1, align 4219 %inc = add nuw nsw i32 %i.07, 1220 %exitcond = icmp eq i32 %inc, 256221 br i1 %exitcond, label %for.end.loopexit, label %for.body222 223for.end.loopexit: ; preds = %for.body224 ret void225}226 227attributes #2 = { optsize }228 229 230; PR39497231; We can't vectorize this one because we version for overflow check and tiny232; trip count leads to opt-for-size (which otherwise could fold the tail by233; masking).234define void @scev_predicate_no_vec(i32 %start, ptr %dst) {235; CHECK-LABEL: define void @scev_predicate_no_vec(236; CHECK-SAME: i32 [[START:%.*]], ptr [[DST:%.*]]) #[[ATTR2:[0-9]+]] {237; CHECK-NEXT: [[ENTRY:.*]]:238; CHECK-NEXT: br label %[[LOOP:.*]]239; CHECK: [[LOOP]]:240; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[ADD:%.*]], %[[LOOP]] ]241; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i32 [[IV]]242; CHECK-NEXT: store i32 [[IV]], ptr [[GEP]], align 4243; CHECK-NEXT: [[CONV:%.*]] = and i32 [[IV]], 65535244; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 4245; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[CONV]], 1246; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]247; CHECK: [[EXIT]]:248; CHECK-NEXT: ret void249;250; AUTOVF-LABEL: define void @scev_predicate_no_vec(251; AUTOVF-SAME: i32 [[START:%.*]], ptr [[DST:%.*]]) #[[ATTR2:[0-9]+]] {252; AUTOVF-NEXT: [[ENTRY:.*]]:253; AUTOVF-NEXT: br label %[[LOOP:.*]]254; AUTOVF: [[LOOP]]:255; AUTOVF-NEXT: [[IV:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[ADD:%.*]], %[[LOOP]] ]256; AUTOVF-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i32 [[IV]]257; AUTOVF-NEXT: store i32 [[IV]], ptr [[GEP]], align 4258; AUTOVF-NEXT: [[CONV:%.*]] = and i32 [[IV]], 65535259; AUTOVF-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 4260; AUTOVF-NEXT: [[ADD]] = add nuw nsw i32 [[CONV]], 1261; AUTOVF-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]262; AUTOVF: [[EXIT]]:263; AUTOVF-NEXT: ret void264;265entry:266 br label %loop267 268loop:269 %iv = phi i32 [ %start, %entry ], [ %add, %loop ]270 %gep = getelementptr inbounds i32, ptr %dst, i32 %iv271 store i32 %iv, ptr %gep272 %conv = and i32 %iv, 65535273 %cmp = icmp ult i32 %conv, 4274 %add = add nuw nsw i32 %conv, 1275 br i1 %cmp, label %loop, label %exit276 277exit:278 ret void279}280 281define void @can_prove_scev_predicate_is_always_true(ptr %dst) {282; CHECK-LABEL: define void @can_prove_scev_predicate_is_always_true(283; CHECK-SAME: ptr [[DST:%.*]]) #[[ATTR2]] {284; CHECK-NEXT: [[ENTRY:.*]]:285; CHECK-NEXT: br label %[[LOOP:.*]]286; CHECK: [[LOOP]]:287; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[ADD:%.*]], %[[LOOP]] ]288; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i32 [[IV]]289; CHECK-NEXT: store i32 [[IV]], ptr [[GEP]], align 4290; CHECK-NEXT: [[CONV:%.*]] = and i32 [[IV]], 65535291; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 4292; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[CONV]], 1293; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]294; CHECK: [[EXIT]]:295; CHECK-NEXT: ret void296;297; AUTOVF-LABEL: define void @can_prove_scev_predicate_is_always_true(298; AUTOVF-SAME: ptr [[DST:%.*]]) #[[ATTR2]] {299; AUTOVF-NEXT: [[ENTRY:.*]]:300; AUTOVF-NEXT: br label %[[LOOP:.*]]301; AUTOVF: [[LOOP]]:302; AUTOVF-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[ADD:%.*]], %[[LOOP]] ]303; AUTOVF-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i32 [[IV]]304; AUTOVF-NEXT: store i32 [[IV]], ptr [[GEP]], align 4305; AUTOVF-NEXT: [[CONV:%.*]] = and i32 [[IV]], 65535306; AUTOVF-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 4307; AUTOVF-NEXT: [[ADD]] = add nuw nsw i32 [[CONV]], 1308; AUTOVF-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]309; AUTOVF: [[EXIT]]:310; AUTOVF-NEXT: ret void311;312entry:313 br label %loop314 315loop:316 %iv = phi i32 [ 0, %entry ], [ %add, %loop ]317 %gep = getelementptr inbounds i32, ptr %dst, i32 %iv318 store i32 %iv, ptr %gep319 %conv = and i32 %iv, 65535320 %cmp = icmp ult i32 %conv, 4321 %add = add nuw nsw i32 %conv, 1322 br i1 %cmp, label %loop, label %exit323 324exit:325 ret void326}327 328define void @tail_folded_store_avx512(ptr %start, ptr %end) #3 {329; CHECK-LABEL: define void @tail_folded_store_avx512(330; CHECK-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) #[[ATTR3:[0-9]+]] {331; CHECK-NEXT: [[ENTRY:.*:]]332; CHECK-NEXT: [[END2:%.*]] = ptrtoint ptr [[END]] to i32333; CHECK-NEXT: [[START1:%.*]] = ptrtoint ptr [[START]] to i32334; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[START1]], -72335; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[END2]]336; CHECK-NEXT: [[TMP2:%.*]] = udiv i32 [[TMP1]], 72337; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i32 [[TMP2]], 1338; CHECK-NEXT: br label %[[VECTOR_PH:.*]]339; CHECK: [[VECTOR_PH]]:340; CHECK-NEXT: [[N_RND_UP:%.*]] = add i32 [[TMP3]], 63341; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[N_RND_UP]], 64342; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[N_RND_UP]], [[N_MOD_VF]]343; CHECK-NEXT: [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[TMP3]], 1344; CHECK-NEXT: [[BROADCAST_SPLATINSERT3:%.*]] = insertelement <64 x i32> poison, i32 [[TRIP_COUNT_MINUS_1]], i64 0345; CHECK-NEXT: [[BROADCAST_SPLAT4:%.*]] = shufflevector <64 x i32> [[BROADCAST_SPLATINSERT3]], <64 x i32> poison, <64 x i32> zeroinitializer346; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]347; CHECK: [[VECTOR_BODY]]:348; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]349; CHECK-NEXT: [[POINTER_PHI:%.*]] = phi ptr [ [[START]], %[[VECTOR_PH]] ], [ [[PTR_IND:%.*]], %[[VECTOR_BODY]] ]350; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[POINTER_PHI]], <64 x i32> <i32 0, i32 -72, i32 -144, i32 -216, i32 -288, i32 -360, i32 -432, i32 -504, i32 -576, i32 -648, i32 -720, i32 -792, i32 -864, i32 -936, i32 -1008, i32 -1080, i32 -1152, i32 -1224, i32 -1296, i32 -1368, i32 -1440, i32 -1512, i32 -1584, i32 -1656, i32 -1728, i32 -1800, i32 -1872, i32 -1944, i32 -2016, i32 -2088, i32 -2160, i32 -2232, i32 -2304, i32 -2376, i32 -2448, i32 -2520, i32 -2592, i32 -2664, i32 -2736, i32 -2808, i32 -2880, i32 -2952, i32 -3024, i32 -3096, i32 -3168, i32 -3240, i32 -3312, i32 -3384, i32 -3456, i32 -3528, i32 -3600, i32 -3672, i32 -3744, i32 -3816, i32 -3888, i32 -3960, i32 -4032, i32 -4104, i32 -4176, i32 -4248, i32 -4320, i32 -4392, i32 -4464, i32 -4536>351; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <64 x i32> poison, i32 [[INDEX]], i64 0352; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <64 x i32> [[BROADCAST_SPLATINSERT]], <64 x i32> poison, <64 x i32> zeroinitializer353; CHECK-NEXT: [[VEC_IV:%.*]] = add <64 x i32> [[BROADCAST_SPLAT]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, 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, i32 31, i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39, i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55, i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>354; CHECK-NEXT: [[TMP6:%.*]] = icmp ule <64 x i32> [[VEC_IV]], [[BROADCAST_SPLAT4]]355; CHECK-NEXT: call void @llvm.masked.scatter.v64p0.v64p0(<64 x ptr> zeroinitializer, <64 x ptr> align 8 [[TMP5]], <64 x i1> [[TMP6]])356; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 64357; CHECK-NEXT: [[PTR_IND]] = getelementptr i8, ptr [[POINTER_PHI]], i32 -4608358; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]359; CHECK-NEXT: br i1 [[TMP7]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]360; CHECK: [[MIDDLE_BLOCK]]:361; CHECK-NEXT: br label %[[EXIT:.*]]362; CHECK: [[EXIT]]:363; CHECK-NEXT: ret void364;365; AUTOVF-LABEL: define void @tail_folded_store_avx512(366; AUTOVF-SAME: ptr [[START:%.*]], ptr [[END:%.*]]) #[[ATTR3:[0-9]+]] {367; AUTOVF-NEXT: [[ENTRY:.*:]]368; AUTOVF-NEXT: [[END2:%.*]] = ptrtoint ptr [[END]] to i32369; AUTOVF-NEXT: [[START1:%.*]] = ptrtoint ptr [[START]] to i32370; AUTOVF-NEXT: [[TMP0:%.*]] = add i32 [[START1]], -72371; AUTOVF-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[END2]]372; AUTOVF-NEXT: [[TMP2:%.*]] = udiv i32 [[TMP1]], 72373; AUTOVF-NEXT: [[TMP3:%.*]] = add nuw nsw i32 [[TMP2]], 1374; AUTOVF-NEXT: br label %[[VECTOR_PH:.*]]375; AUTOVF: [[VECTOR_PH]]:376; AUTOVF-NEXT: [[N_RND_UP:%.*]] = add i32 [[TMP3]], 7377; AUTOVF-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[N_RND_UP]], 8378; AUTOVF-NEXT: [[N_VEC:%.*]] = sub i32 [[N_RND_UP]], [[N_MOD_VF]]379; AUTOVF-NEXT: [[TRIP_COUNT_MINUS_1:%.*]] = sub i32 [[TMP3]], 1380; AUTOVF-NEXT: [[BROADCAST_SPLATINSERT3:%.*]] = insertelement <8 x i32> poison, i32 [[TRIP_COUNT_MINUS_1]], i64 0381; AUTOVF-NEXT: [[BROADCAST_SPLAT4:%.*]] = shufflevector <8 x i32> [[BROADCAST_SPLATINSERT3]], <8 x i32> poison, <8 x i32> zeroinitializer382; AUTOVF-NEXT: br label %[[VECTOR_BODY:.*]]383; AUTOVF: [[VECTOR_BODY]]:384; AUTOVF-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]385; AUTOVF-NEXT: [[POINTER_PHI:%.*]] = phi ptr [ [[START]], %[[VECTOR_PH]] ], [ [[PTR_IND:%.*]], %[[VECTOR_BODY]] ]386; AUTOVF-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[POINTER_PHI]], <8 x i32> <i32 0, i32 -72, i32 -144, i32 -216, i32 -288, i32 -360, i32 -432, i32 -504>387; AUTOVF-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x i32> poison, i32 [[INDEX]], i64 0388; AUTOVF-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x i32> [[BROADCAST_SPLATINSERT]], <8 x i32> poison, <8 x i32> zeroinitializer389; AUTOVF-NEXT: [[VEC_IV:%.*]] = add <8 x i32> [[BROADCAST_SPLAT]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>390; AUTOVF-NEXT: [[TMP6:%.*]] = icmp ule <8 x i32> [[VEC_IV]], [[BROADCAST_SPLAT4]]391; AUTOVF-NEXT: call void @llvm.masked.scatter.v8p0.v8p0(<8 x ptr> zeroinitializer, <8 x ptr> align 8 [[TMP5]], <8 x i1> [[TMP6]])392; AUTOVF-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 8393; AUTOVF-NEXT: [[PTR_IND]] = getelementptr i8, ptr [[POINTER_PHI]], i32 -576394; AUTOVF-NEXT: [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]395; AUTOVF-NEXT: br i1 [[TMP7]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]396; AUTOVF: [[MIDDLE_BLOCK]]:397; AUTOVF-NEXT: br label %[[EXIT:.*]]398; AUTOVF: [[EXIT]]:399; AUTOVF-NEXT: ret void400;401entry:402 br label %loop403 404loop:405 %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop ]406 %ptr.iv.next = getelementptr nusw i8, ptr %ptr.iv, i64 -72407 store ptr null, ptr %ptr.iv, align 8408 %ec = icmp eq ptr %ptr.iv.next, %end409 br i1 %ec, label %exit, label %loop410 411exit:412 ret void413}414 415attributes #3 = { optsize "target-cpu"="skylake-avx512" }416