1; RUN: opt < %s -S -loop-unroll -unroll-count=4 | FileCheck -check-prefix=CHECK_COUNT4 %s 2; RUN: opt < %s -S -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 29; CHECK_COUNT4-NEXT: add 30; CHECK_COUNT4-NEXT: add 31; CHECK_COUNT4-NEXT: add 32; CHECK_COUNT4-NEXT: icmp 33 34 35;///////////////////// TEST 2 ////////////////////////////// 36 37; This test shows that with optnone attribute, the loop is not unrolled 38; even if an unroll factor was specified. 39 40define void @Test2() nounwind optnone noinline { 41entry: 42 br label %loop 43 44loop: 45 %iv = phi i32 [ 0, %entry ], [ %inc, %loop ] 46 %inc = add i32 %iv, 1 47 %exitcnd = icmp uge i32 %inc, 1024 48 br i1 %exitcnd, label %exit, label %loop 49 50exit: 51 ret void 52} 53 54; CHECK_COUNT4-LABEL: @Test2 55; CHECK_COUNT4: phi 56; CHECK_COUNT4-NEXT: add 57; CHECK_COUNT4-NEXT: icmp 58 59 60;///////////////////// TEST 3 ////////////////////////////// 61 62; This test shows that this loop is fully unrolled by default. 63 64@tab = common global [24 x i32] zeroinitializer, align 4 65 66define i32 @Test3() { 67entry: 68 br label %for.body 69 70for.body: ; preds = %for.body, %entry 71 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 72 %arrayidx = getelementptr inbounds [24 x i32], [24 x i32]* @tab, i32 0, i32 %i.05 73 store i32 %i.05, i32* %arrayidx, align 4 74 %inc = add nuw nsw i32 %i.05, 1 75 %exitcond = icmp eq i32 %inc, 24 76 br i1 %exitcond, label %for.end, label %for.body 77 78for.end: ; preds = %for.body 79 ret i32 42 80} 81 82; CHECK_NOCOUNT-LABEL: @Test3 83; CHECK_NOCOUNT: 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: store 105; CHECK_NOCOUNT-NEXT: store 106; CHECK_NOCOUNT-NEXT: store 107; CHECK_NOCOUNT-NEXT: ret 108 109 110;///////////////////// TEST 4 ////////////////////////////// 111 112; This test shows that with optsize attribute, this loop is not unrolled. 113 114define i32 @Test4() optsize { 115entry: 116 br label %for.body 117 118for.body: ; preds = %for.body, %entry 119 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 120 %arrayidx = getelementptr inbounds [24 x i32], [24 x i32]* @tab, i32 0, i32 %i.05 121 store i32 %i.05, i32* %arrayidx, align 4 122 %inc = add nuw nsw i32 %i.05, 1 123 %exitcond = icmp eq i32 %inc, 24 124 br i1 %exitcond, label %for.end, label %for.body 125 126for.end: ; preds = %for.body 127 ret i32 42 128} 129 130; CHECK_NOCOUNT-LABEL: @Test4 131; CHECK_NOCOUNT: phi 132; CHECK_NOCOUNT: icmp 133 134;///////////////////// TEST 5 ////////////////////////////// 135 136; This test shows that with PGO, this loop is cold and not unrolled. 137 138define i32 @Test5() !prof !14 { 139entry: 140 br label %for.body 141 142for.body: ; preds = %for.body, %entry 143 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 144 %arrayidx = getelementptr inbounds [24 x i32], [24 x i32]* @tab, i32 0, i32 %i.05 145 store i32 %i.05, i32* %arrayidx, align 4 146 %inc = add nuw nsw i32 %i.05, 1 147 %exitcond = icmp eq i32 %inc, 24 148 br i1 %exitcond, label %for.end, label %for.body 149 150for.end: ; preds = %for.body 151 ret i32 42 152} 153 154; PGSO-LABEL: @Test5 155; PGSO: phi 156; PGSO: icmp 157; NPGSO-LABEL: @Test5 158; NPGSO-NOT: phi 159; NPGSO-NOT: icmp 160 161!llvm.module.flags = !{!0} 162!0 = !{i32 1, !"ProfileSummary", !1} 163!1 = !{!2, !3, !4, !5, !6, !7, !8, !9} 164!2 = !{!"ProfileFormat", !"InstrProf"} 165!3 = !{!"TotalCount", i64 10000} 166!4 = !{!"MaxCount", i64 10} 167!5 = !{!"MaxInternalCount", i64 1} 168!6 = !{!"MaxFunctionCount", i64 1000} 169!7 = !{!"NumCounts", i64 3} 170!8 = !{!"NumFunctions", i64 3} 171!9 = !{!"DetailedSummary", !10} 172!10 = !{!11, !12, !13} 173!11 = !{i32 10000, i64 100, i32 1} 174!12 = !{i32 999000, i64 100, i32 1} 175!13 = !{i32 999999, i64 1, i32 2} 176!14 = !{!"function_entry_count", i64 0} 177