1; RUN: opt < %s -S -passes=loop-unroll -unroll-count=4 | FileCheck -check-prefix=CHECK_COUNT4 %s 2; RUN: opt < %s -S -passes=loop-unroll | FileCheck -check-prefix=CHECK_NOCOUNT %s 3; RUN: opt < %s -S -passes='require<profile-summary>,function(loop-unroll)' -pgso | FileCheck -check-prefix=PGSO %s 4; RUN: opt < %s -S -passes='require<profile-summary>,function(loop-unroll)' -pgso=false | FileCheck -check-prefix=NPGSO %s 5 6 7;///////////////////// TEST 1 ////////////////////////////// 8 9; This test shows that the loop is unrolled according to the specified 10; unroll factor. 11 12define void @Test1() nounwind { 13entry: 14 br label %loop 15 16loop: 17 %iv = phi i32 [ 0, %entry ], [ %inc, %loop ] 18 %inc = add i32 %iv, 1 19 %exitcnd = icmp uge i32 %inc, 1024 20 br i1 %exitcnd, label %exit, label %loop 21 22exit: 23 ret void 24} 25 26; CHECK_COUNT4-LABEL: @Test1 27; CHECK_COUNT4: phi 28; CHECK_COUNT4-NEXT: add{{.*}}, 4 29; CHECK_COUNT4-NEXT: icmp 30 31 32;///////////////////// TEST 2 ////////////////////////////// 33 34; This test shows that with optnone attribute, the loop is not unrolled 35; even if an unroll factor was specified. 36 37define void @Test2() nounwind optnone noinline { 38entry: 39 br label %loop 40 41loop: 42 %iv = phi i32 [ 0, %entry ], [ %inc, %loop ] 43 %inc = add i32 %iv, 1 44 %exitcnd = icmp uge i32 %inc, 1024 45 br i1 %exitcnd, label %exit, label %loop 46 47exit: 48 ret void 49} 50 51; CHECK_COUNT4-LABEL: @Test2 52; CHECK_COUNT4: phi 53; CHECK_COUNT4-NEXT: add 54; CHECK_COUNT4-NEXT: icmp 55 56 57;///////////////////// TEST 3 ////////////////////////////// 58 59; This test shows that this loop is fully unrolled by default. 60 61@tab = common global [24 x i32] zeroinitializer, align 4 62 63define i32 @Test3() { 64entry: 65 br label %for.body 66 67for.body: ; preds = %for.body, %entry 68 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 69 %arrayidx = getelementptr inbounds [24 x i32], ptr @tab, i32 0, i32 %i.05 70 store i32 %i.05, ptr %arrayidx, align 4 71 %inc = add nuw nsw i32 %i.05, 1 72 %exitcond = icmp eq i32 %inc, 24 73 br i1 %exitcond, label %for.end, label %for.body 74 75for.end: ; preds = %for.body 76 ret i32 42 77} 78 79; CHECK_NOCOUNT-LABEL: @Test3 80; CHECK_NOCOUNT: store 81; CHECK_NOCOUNT-NEXT: store 82; CHECK_NOCOUNT-NEXT: store 83; CHECK_NOCOUNT-NEXT: store 84; CHECK_NOCOUNT-NEXT: store 85; CHECK_NOCOUNT-NEXT: store 86; CHECK_NOCOUNT-NEXT: store 87; CHECK_NOCOUNT-NEXT: store 88; CHECK_NOCOUNT-NEXT: store 89; CHECK_NOCOUNT-NEXT: store 90; CHECK_NOCOUNT-NEXT: store 91; CHECK_NOCOUNT-NEXT: store 92; CHECK_NOCOUNT-NEXT: store 93; CHECK_NOCOUNT-NEXT: store 94; CHECK_NOCOUNT-NEXT: store 95; CHECK_NOCOUNT-NEXT: store 96; CHECK_NOCOUNT-NEXT: store 97; CHECK_NOCOUNT-NEXT: store 98; CHECK_NOCOUNT-NEXT: store 99; CHECK_NOCOUNT-NEXT: store 100; CHECK_NOCOUNT-NEXT: store 101; CHECK_NOCOUNT-NEXT: store 102; CHECK_NOCOUNT-NEXT: store 103; CHECK_NOCOUNT-NEXT: store 104; CHECK_NOCOUNT-NEXT: ret 105 106 107;///////////////////// TEST 4 ////////////////////////////// 108 109; This test shows that with optsize attribute, this loop is not unrolled. 110 111define i32 @Test4() optsize { 112entry: 113 br label %for.body 114 115for.body: ; preds = %for.body, %entry 116 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 117 %arrayidx = getelementptr inbounds [24 x i32], ptr @tab, i32 0, i32 %i.05 118 store i32 %i.05, ptr %arrayidx, align 4 119 %inc = add nuw nsw i32 %i.05, 1 120 %exitcond = icmp eq i32 %inc, 24 121 br i1 %exitcond, label %for.end, label %for.body 122 123for.end: ; preds = %for.body 124 ret i32 42 125} 126 127; CHECK_NOCOUNT-LABEL: @Test4 128; CHECK_NOCOUNT: phi 129; CHECK_NOCOUNT: icmp 130 131;///////////////////// TEST 5 ////////////////////////////// 132 133; This test shows that with PGO, this loop is cold and not unrolled. 134 135define i32 @Test5() !prof !14 { 136entry: 137 br label %for.body 138 139for.body: ; preds = %for.body, %entry 140 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 141 %arrayidx = getelementptr inbounds [24 x i32], ptr @tab, i32 0, i32 %i.05 142 store i32 %i.05, ptr %arrayidx, align 4 143 %inc = add nuw nsw i32 %i.05, 1 144 %exitcond = icmp eq i32 %inc, 24 145 br i1 %exitcond, label %for.end, label %for.body 146 147for.end: ; preds = %for.body 148 ret i32 42 149} 150 151; PGSO-LABEL: @Test5 152; PGSO: phi 153; PGSO: icmp 154; NPGSO-LABEL: @Test5 155; NPGSO-NOT: phi 156; NPGSO-NOT: icmp 157 158;///////////////////// TEST 6 ////////////////////////////// 159 160; This test tests that unroll hints take precedence over PGSO and that this loop 161; gets unrolled even though it's cold. 162 163define i32 @Test6() !prof !14 { 164entry: 165 br label %for.body 166 167for.body: ; preds = %for.body, %entry 168 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 169 %arrayidx = getelementptr inbounds [24 x i32], ptr @tab, i32 0, i32 %i.05 170 store i32 %i.05, ptr %arrayidx, align 4 171 %inc = add nuw nsw i32 %i.05, 1 172 %exitcond = icmp eq i32 %inc, 24 173 br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !15 174 175for.end: ; preds = %for.body 176 ret i32 42 177} 178 179; PGSO-LABEL: @Test6 180; PGSO: store 181; PGSO: store 182; PGSO: store 183; PGSO: store 184; NPGSO-LABEL: @Test6 185; NPGSO: store 186; NPGSO: store 187; NPGSO: store 188; NPGSO: store 189 190!llvm.module.flags = !{!0} 191!0 = !{i32 1, !"ProfileSummary", !1} 192!1 = !{!2, !3, !4, !5, !6, !7, !8, !9} 193!2 = !{!"ProfileFormat", !"InstrProf"} 194!3 = !{!"TotalCount", i64 10000} 195!4 = !{!"MaxCount", i64 10} 196!5 = !{!"MaxInternalCount", i64 1} 197!6 = !{!"MaxFunctionCount", i64 1000} 198!7 = !{!"NumCounts", i64 3} 199!8 = !{!"NumFunctions", i64 3} 200!9 = !{!"DetailedSummary", !10} 201!10 = !{!11, !12, !13} 202!11 = !{i32 10000, i64 100, i32 1} 203!12 = !{i32 999000, i64 100, i32 1} 204!13 = !{i32 999999, i64 1, i32 2} 205!14 = !{!"function_entry_count", i64 0} 206!15 = !{!15, !16} 207!16 = !{!"llvm.loop.unroll.count", i32 4} 208