1cee313d2SEric Christopher; This test verifies that the loop vectorizer will not vectorizes low trip count 2cee313d2SEric Christopher; loops that require runtime checks (Trip count is computed with profile info). 3cee313d2SEric Christopher; REQUIRES: asserts 4*2e14900dSBjorn Pettersson; RUN: opt < %s -passes=loop-vectorize -loop-vectorize-with-block-frequency -S | FileCheck %s 5cee313d2SEric Christopher 6cee313d2SEric Christophertarget datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S128" 7cee313d2SEric Christopher 8cee313d2SEric Christopher@tab = common global [32 x i8] zeroinitializer, align 1 9cee313d2SEric Christopher 10cee313d2SEric Christopherdefine i32 @foo_low_trip_count1(i32 %bound) { 11cee313d2SEric Christopher; Simple loop with low tripcount. Should not be vectorized. 12872f7000SDávid Bolvanský 13cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count1( 14872f7000SDávid Bolvanský; CHECK-NOT: <{{[0-9]+}} x i8> 15cee313d2SEric Christopher 16cee313d2SEric Christopherentry: 17cee313d2SEric Christopher br label %for.body 18cee313d2SEric Christopher 19cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 20cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 21cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 22cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 23cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 24cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 25cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 26cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 27cee313d2SEric Christopher %exitcond = icmp eq i32 %i.08, %bound 28cee313d2SEric Christopher br i1 %exitcond, label %for.end, label %for.body, !prof !1 29cee313d2SEric Christopher 30cee313d2SEric Christopherfor.end: ; preds = %for.body 31cee313d2SEric Christopher ret i32 0 32cee313d2SEric Christopher} 33cee313d2SEric Christopher 34cee313d2SEric Christopherdefine i32 @foo_low_trip_count2(i32 %bound) !prof !0 { 35cee313d2SEric Christopher; The loop has a same invocation count with the function, but has a low 36cee313d2SEric Christopher; trip_count per invocation and not worth to vectorize. 37872f7000SDávid Bolvanský 38cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count2( 39872f7000SDávid Bolvanský; CHECK-NOT: <{{[0-9]+}} x i8> 40cee313d2SEric Christopher 41cee313d2SEric Christopherentry: 42cee313d2SEric Christopher br label %for.body 43cee313d2SEric Christopher 44cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 45cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 46cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 47cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 48cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 49cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 50cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 51cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 52cee313d2SEric Christopher %exitcond = icmp eq i32 %i.08, %bound 53cee313d2SEric Christopher br i1 %exitcond, label %for.end, label %for.body, !prof !1 54cee313d2SEric Christopher 55cee313d2SEric Christopherfor.end: ; preds = %for.body 56cee313d2SEric Christopher ret i32 0 57cee313d2SEric Christopher} 58cee313d2SEric Christopher 59cee313d2SEric Christopherdefine i32 @foo_low_trip_count3(i1 %cond, i32 %bound) !prof !0 { 60cee313d2SEric Christopher; The loop has low invocation count compare to the function invocation count, 61cee313d2SEric Christopher; but has a high trip count per invocation. Vectorize it. 62872f7000SDávid Bolvanský 63cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count3( 64872f7000SDávid Bolvanský; CHECK: [[VECTOR_BODY:vector\.body]]: 65872f7000SDávid Bolvanský; CHECK: br i1 [[TMP9:%.*]], label [[MIDDLE_BLOCK:%.*]], label %[[VECTOR_BODY]], !prof [[LP3:\!.*]], 66872f7000SDávid Bolvanský; CHECK: [[FOR_BODY:for\.body]]: 67872f7000SDávid Bolvanský; CHECK: br i1 [[EXITCOND:%.*]], label [[FOR_END_LOOPEXIT:%.*]], label %[[FOR_BODY]], !prof [[LP6:\!.*]], 68cee313d2SEric Christopherentry: 69cee313d2SEric Christopher br i1 %cond, label %for.preheader, label %for.end, !prof !2 70cee313d2SEric Christopher 71cee313d2SEric Christopherfor.preheader: 72cee313d2SEric Christopher br label %for.body 73cee313d2SEric Christopher 74cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 75cee313d2SEric Christopher %i.08 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ] 76cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 77cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 78cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 79cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 80cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 81cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 82cee313d2SEric Christopher %exitcond = icmp eq i32 %i.08, %bound 83cee313d2SEric Christopher br i1 %exitcond, label %for.end, label %for.body, !prof !3 84cee313d2SEric Christopher 85cee313d2SEric Christopherfor.end: ; preds = %for.body 86cee313d2SEric Christopher ret i32 0 87cee313d2SEric Christopher} 88cee313d2SEric Christopher 89cee313d2SEric Christopherdefine i32 @foo_low_trip_count_icmp_sgt(i32 %bound) { 90cee313d2SEric Christopher; Simple loop with low tripcount and inequality test for exit. 91cee313d2SEric Christopher; Should not be vectorized. 92872f7000SDávid Bolvanský 93cee313d2SEric Christopher; CHECK-LABEL: @foo_low_trip_count_icmp_sgt( 94872f7000SDávid Bolvanský; CHECK-NOT: <{{[0-9]+}} x i8> 95cee313d2SEric Christopher 96cee313d2SEric Christopherentry: 97cee313d2SEric Christopher br label %for.body 98cee313d2SEric Christopher 99cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 100cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 101cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 102cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 103cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 104cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 105cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 106cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 107cee313d2SEric Christopher %exitcond = icmp sgt i32 %i.08, %bound 108cee313d2SEric Christopher br i1 %exitcond, label %for.end, label %for.body, !prof !1 109cee313d2SEric Christopher 110cee313d2SEric Christopherfor.end: ; preds = %for.body 111cee313d2SEric Christopher ret i32 0 112cee313d2SEric Christopher} 113cee313d2SEric Christopher 114cee313d2SEric Christopherdefine i32 @const_low_trip_count() { 115cee313d2SEric Christopher; Simple loop with constant, small trip count and no profiling info. 116872f7000SDávid Bolvanský 117872f7000SDávid Bolvanský; CHECK-LABEL: @const_low_trip_count 118872f7000SDávid Bolvanský; CHECK-NOT: <{{[0-9]+}} x i8> 119cee313d2SEric Christopher 120cee313d2SEric Christopherentry: 121cee313d2SEric Christopher br label %for.body 122cee313d2SEric Christopher 123cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 124cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 125cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 126cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 127cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 128cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 129cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 130cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 131cee313d2SEric Christopher %exitcond = icmp slt i32 %i.08, 2 132cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %for.end 133cee313d2SEric Christopher 134cee313d2SEric Christopherfor.end: ; preds = %for.body 135cee313d2SEric Christopher ret i32 0 136cee313d2SEric Christopher} 137cee313d2SEric Christopher 138cee313d2SEric Christopherdefine i32 @const_large_trip_count() { 139cee313d2SEric Christopher; Simple loop with constant large trip count and no profiling info. 140872f7000SDávid Bolvanský 141872f7000SDávid Bolvanský; CHECK-LABEL: @const_large_trip_count 142872f7000SDávid Bolvanský; CHECK: <{{[0-9]+}} x i8> 143cee313d2SEric Christopher 144cee313d2SEric Christopherentry: 145cee313d2SEric Christopher br label %for.body 146cee313d2SEric Christopher 147cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 148cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 149cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 150cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 151cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 152cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 153cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 154cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 155cee313d2SEric Christopher %exitcond = icmp slt i32 %i.08, 1000 156cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %for.end 157cee313d2SEric Christopher 158cee313d2SEric Christopherfor.end: ; preds = %for.body 159cee313d2SEric Christopher ret i32 0 160cee313d2SEric Christopher} 161cee313d2SEric Christopher 162cee313d2SEric Christopherdefine i32 @const_small_trip_count_step() { 163cee313d2SEric Christopher; Simple loop with static, small trip count and no profiling info. 164872f7000SDávid Bolvanský 165872f7000SDávid Bolvanský; CHECK-LABEL: @const_small_trip_count_step 166872f7000SDávid Bolvanský; CHECK-NOT: <{{[0-9]+}} x i8> 167cee313d2SEric Christopher 168cee313d2SEric Christopherentry: 169cee313d2SEric Christopher br label %for.body 170cee313d2SEric Christopher 171cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 172cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 173cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 174cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 175cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 176cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 177cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 178cee313d2SEric Christopher %inc = add nsw i32 %i.08, 5 179cee313d2SEric Christopher %exitcond = icmp slt i32 %i.08, 10 180cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %for.end 181cee313d2SEric Christopher 182cee313d2SEric Christopherfor.end: ; preds = %for.body 183cee313d2SEric Christopher ret i32 0 184cee313d2SEric Christopher} 185cee313d2SEric Christopher 186cee313d2SEric Christopherdefine i32 @const_trip_over_profile() { 187cee313d2SEric Christopher; constant trip count takes precedence over profile data 188872f7000SDávid Bolvanský 189872f7000SDávid Bolvanský; CHECK-LABEL: @const_trip_over_profile 190872f7000SDávid Bolvanský; CHECK: <{{[0-9]+}} x i8> 191cee313d2SEric Christopher 192cee313d2SEric Christopherentry: 193cee313d2SEric Christopher br label %for.body 194cee313d2SEric Christopher 195cee313d2SEric Christopherfor.body: ; preds = %for.body, %entry 196cee313d2SEric Christopher %i.08 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 197cee313d2SEric Christopher %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @tab, i32 0, i32 %i.08 198cee313d2SEric Christopher %0 = load i8, i8* %arrayidx, align 1 199cee313d2SEric Christopher %cmp1 = icmp eq i8 %0, 0 200cee313d2SEric Christopher %. = select i1 %cmp1, i8 2, i8 1 201cee313d2SEric Christopher store i8 %., i8* %arrayidx, align 1 202cee313d2SEric Christopher %inc = add nsw i32 %i.08, 1 203cee313d2SEric Christopher %exitcond = icmp slt i32 %i.08, 1000 204cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %for.end, !prof !1 205cee313d2SEric Christopher 206cee313d2SEric Christopherfor.end: ; preds = %for.body 207cee313d2SEric Christopher ret i32 0 208cee313d2SEric Christopher} 209cee313d2SEric Christopher 210872f7000SDávid Bolvanský; CHECK: [[LP3]] = !{!"branch_weights", i32 10, i32 2490} 211872f7000SDávid Bolvanský; CHECK: [[LP6]] = !{!"branch_weights", i32 10, i32 0} 212af7e1588SEvgeniy Brevnov; original loop has latchExitWeight=10 and backedgeTakenWeight=10,000, 213af7e1588SEvgeniy Brevnov; therefore estimatedBackedgeTakenCount=1,000 and estimatedTripCount=1,001. 214af7e1588SEvgeniy Brevnov; Vectorizing by 4 produces estimatedTripCounts of 1,001/4=250 and 1,001%4=1 215af7e1588SEvgeniy Brevnov; for vectorized and remainder loops, respectively, therefore their 216af7e1588SEvgeniy Brevnov; estimatedBackedgeTakenCounts are 249 and 0, and so the weights recorded with 217af7e1588SEvgeniy Brevnov; loop invocation weights of 10 are the above {10, 2490} and {10, 0}. 218af7e1588SEvgeniy Brevnov 219cee313d2SEric Christopher!0 = !{!"function_entry_count", i64 100} 2205c31b8b9SArthur Eubanks!1 = !{!"branch_weights", i32 100, i32 0} 2215c31b8b9SArthur Eubanks!2 = !{!"branch_weights", i32 10, i32 90} 2225c31b8b9SArthur Eubanks!3 = !{!"branch_weights", i32 10, i32 10000} 223