1*cee313d2SEric Christopher; This test verifies that the loop vectorizer will not vectorizes low trip count 2*cee313d2SEric Christopher; loops that require runtime checks (Trip count is computed with profile info). 3*cee313d2SEric Christopher; REQUIRES: asserts 4*cee313d2SEric Christopher; RUN: opt < %s -loop-vectorize -loop-vectorize-with-block-frequency -S | FileCheck %s 5*cee313d2SEric Christopher 6*cee313d2SEric Christophertarget datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S128" 7*cee313d2SEric Christopher 8*cee313d2SEric Christopher@tab = common global [32 x i8] zeroinitializer, align 1 9*cee313d2SEric Christopher 10*cee313d2SEric Christopherdefine i32 @foo_low_trip_count1(i32 %bound) { 11*cee313d2SEric Christopher; Simple loop with low tripcount. Should not be vectorized. 12*cee313d2SEric Christopher 13*cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count1( 14*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8> 15*cee313d2SEric Christopher 16*cee313d2SEric Christopherentry: 17*cee313d2SEric Christopher br label %for.body 18*cee313d2SEric Christopher 19*cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 20*cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 21*cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 22*cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 23*cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 24*cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 25*cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 26*cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 27*cee313d2SEric Christopher %exitcond = icmp eq i32 %i.08, %bound 28*cee313d2SEric Christopher br i1 %exitcond, label %for.end, label %for.body, !prof !1 29*cee313d2SEric Christopher 30*cee313d2SEric Christopherfor.end: ; preds = %for.body 31*cee313d2SEric Christopher ret i32 0 32*cee313d2SEric Christopher} 33*cee313d2SEric Christopher 34*cee313d2SEric Christopherdefine i32 @foo_low_trip_count2(i32 %bound) !prof !0 { 35*cee313d2SEric Christopher; The loop has a same invocation count with the function, but has a low 36*cee313d2SEric Christopher; trip_count per invocation and not worth to vectorize. 37*cee313d2SEric Christopher 38*cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count2( 39*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8> 40*cee313d2SEric Christopher 41*cee313d2SEric Christopherentry: 42*cee313d2SEric Christopher br label %for.body 43*cee313d2SEric Christopher 44*cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 45*cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 46*cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 47*cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 48*cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 49*cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 50*cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 51*cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 52*cee313d2SEric Christopher %exitcond = icmp eq i32 %i.08, %bound 53*cee313d2SEric Christopher br i1 %exitcond, label %for.end, label %for.body, !prof !1 54*cee313d2SEric Christopher 55*cee313d2SEric Christopherfor.end: ; preds = %for.body 56*cee313d2SEric Christopher ret i32 0 57*cee313d2SEric Christopher} 58*cee313d2SEric Christopher 59*cee313d2SEric Christopherdefine i32 @foo_low_trip_count3(i1 %cond, i32 %bound) !prof !0 { 60*cee313d2SEric Christopher; The loop has low invocation count compare to the function invocation count, 61*cee313d2SEric Christopher; but has a high trip count per invocation. Vectorize it. 62*cee313d2SEric Christopher 63*cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count3( 64*cee313d2SEric Christopher; CHECK: vector.body: 65*cee313d2SEric Christopher 66*cee313d2SEric Christopherentry: 67*cee313d2SEric Christopher br i1 %cond, label %for.preheader, label %for.end, !prof !2 68*cee313d2SEric Christopher 69*cee313d2SEric Christopherfor.preheader: 70*cee313d2SEric Christopher br label %for.body 71*cee313d2SEric Christopher 72*cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 73*cee313d2SEric Christopher %i.08 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ] 74*cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 75*cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 76*cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 77*cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 78*cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 79*cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 80*cee313d2SEric Christopher %exitcond = icmp eq i32 %i.08, %bound 81*cee313d2SEric Christopher br i1 %exitcond, label %for.end, label %for.body, !prof !3 82*cee313d2SEric Christopher 83*cee313d2SEric Christopherfor.end: ; preds = %for.body 84*cee313d2SEric Christopher ret i32 0 85*cee313d2SEric Christopher} 86*cee313d2SEric Christopher 87*cee313d2SEric Christopherdefine i32 @foo_low_trip_count_icmp_sgt(i32 %bound) { 88*cee313d2SEric Christopher; Simple loop with low tripcount and inequality test for exit. 89*cee313d2SEric Christopher; Should not be vectorized. 90*cee313d2SEric Christopher 91*cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count_icmp_sgt( 92*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8> 93*cee313d2SEric Christopher 94*cee313d2SEric Christopherentry: 95*cee313d2SEric Christopher br label %for.body 96*cee313d2SEric Christopher 97*cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 98*cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 99*cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 100*cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 101*cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 102*cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 103*cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 104*cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 105*cee313d2SEric Christopher %exitcond = icmp sgt i32 %i.08, %bound 106*cee313d2SEric Christopher br i1 %exitcond, label %for.end, label %for.body, !prof !1 107*cee313d2SEric Christopher 108*cee313d2SEric Christopherfor.end: ; preds = %for.body 109*cee313d2SEric Christopher ret i32 0 110*cee313d2SEric Christopher} 111*cee313d2SEric Christopher 112*cee313d2SEric Christopherdefine i32 @const_low_trip_count() { 113*cee313d2SEric Christopher; Simple loop with constant, small trip count and no profiling info. 114*cee313d2SEric Christopher 115*cee313d2SEric Christopher; CHECK-LABEL: @const_low_trip_count 116*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8> 117*cee313d2SEric Christopher 118*cee313d2SEric Christopherentry: 119*cee313d2SEric Christopher br label %for.body 120*cee313d2SEric Christopher 121*cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 122*cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 123*cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 124*cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 125*cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 126*cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 127*cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 128*cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 129*cee313d2SEric Christopher %exitcond = icmp slt i32 %i.08, 2 130*cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %for.end 131*cee313d2SEric Christopher 132*cee313d2SEric Christopherfor.end: ; preds = %for.body 133*cee313d2SEric Christopher ret i32 0 134*cee313d2SEric Christopher} 135*cee313d2SEric Christopher 136*cee313d2SEric Christopherdefine i32 @const_large_trip_count() { 137*cee313d2SEric Christopher; Simple loop with constant large trip count and no profiling info. 138*cee313d2SEric Christopher 139*cee313d2SEric Christopher; CHECK-LABEL: @const_large_trip_count 140*cee313d2SEric Christopher; CHECK: <{{[0-9]+}} x i8> 141*cee313d2SEric Christopher 142*cee313d2SEric Christopherentry: 143*cee313d2SEric Christopher br label %for.body 144*cee313d2SEric Christopher 145*cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 146*cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 147*cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 148*cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 149*cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 150*cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 151*cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 152*cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 153*cee313d2SEric Christopher %exitcond = icmp slt i32 %i.08, 1000 154*cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %for.end 155*cee313d2SEric Christopher 156*cee313d2SEric Christopherfor.end: ; preds = %for.body 157*cee313d2SEric Christopher ret i32 0 158*cee313d2SEric Christopher} 159*cee313d2SEric Christopher 160*cee313d2SEric Christopherdefine i32 @const_small_trip_count_step() { 161*cee313d2SEric Christopher; Simple loop with static, small trip count and no profiling info. 162*cee313d2SEric Christopher 163*cee313d2SEric Christopher; CHECK-LABEL: @const_small_trip_count_step 164*cee313d2SEric Christopher; CHECK-NOT: <{{[0-9]+}} x i8> 165*cee313d2SEric Christopher 166*cee313d2SEric Christopherentry: 167*cee313d2SEric Christopher br label %for.body 168*cee313d2SEric Christopher 169*cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 170*cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 171*cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 172*cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 173*cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 174*cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 175*cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 176*cee313d2SEric Christopher %inc = add nsw i32 %i.08, 5 177*cee313d2SEric Christopher %exitcond = icmp slt i32 %i.08, 10 178*cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %for.end 179*cee313d2SEric Christopher 180*cee313d2SEric Christopherfor.end: ; preds = %for.body 181*cee313d2SEric Christopher ret i32 0 182*cee313d2SEric Christopher} 183*cee313d2SEric Christopher 184*cee313d2SEric Christopherdefine i32 @const_trip_over_profile() { 185*cee313d2SEric Christopher; constant trip count takes precedence over profile data 186*cee313d2SEric Christopher 187*cee313d2SEric Christopher; CHECK-LABEL: @const_trip_over_profile 188*cee313d2SEric Christopher; CHECK: <{{[0-9]+}} x i8> 189*cee313d2SEric Christopher 190*cee313d2SEric Christopherentry: 191*cee313d2SEric Christopher br label %for.body 192*cee313d2SEric Christopher 193*cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 194*cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 195*cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 196*cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 197*cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 198*cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 199*cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 200*cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 201*cee313d2SEric Christopher %exitcond = icmp slt i32 %i.08, 1000 202*cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %for.end, !prof !1 203*cee313d2SEric Christopher 204*cee313d2SEric Christopherfor.end: ; preds = %for.body 205*cee313d2SEric Christopher ret i32 0 206*cee313d2SEric Christopher} 207*cee313d2SEric Christopher 208*cee313d2SEric Christopher!0 = !{!"function_entry_count", i64 100} 209*cee313d2SEric Christopher!1 = !{!"branch_weights", i32 100, i32 0} 210*cee313d2SEric Christopher!2 = !{!"branch_weights", i32 10, i32 90} 211*cee313d2SEric Christopher!3 = !{!"branch_weights", i32 10, i32 10000} 212