1; RUN: opt < %s -loop-unroll -unroll-runtime -unroll-allow-partial -S | FileCheck %s 2 3declare void @f() convergent 4 5; Although this loop contains a convergent instruction, it should be 6; fully unrolled. 7; 8; CHECK-LABEL: @full_unroll( 9define i32 @full_unroll() { 10entry: 11 br label %l3 12 13l3: 14 %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ] 15; CHECK: call void @f() 16; CHECK: call void @f() 17; CHECK: call void @f() 18; CHECK-NOT: call void @f() 19 call void @f() ;convergent 20 %inc = add nsw i32 %x.0, 1 21 %exitcond = icmp eq i32 %inc, 3 22 br i1 %exitcond, label %exit, label %l3 23 24exit: 25 ret i32 0 26} 27 28; This loop contains a convergent instruction, but it should be partially 29; unrolled. The unroll count is the largest power of 2 that divides the 30; multiple -- 4, in this case. 31; 32; CHECK-LABEL: @runtime_unroll( 33define i32 @runtime_unroll(i32 %n) { 34entry: 35 %loop_ctl = mul nsw i32 %n, 12 36 br label %l3 37 38l3: 39 %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ] 40; CHECK: call void @f() 41; CHECK: call void @f() 42; CHECK: call void @f() 43; CHECK: call void @f() 44; CHECK-NOT: call void @f() 45 call void @f() convergent 46 %inc = add nsw i32 %x.0, 1 47 %exitcond = icmp eq i32 %inc, %loop_ctl 48 br i1 %exitcond, label %exit, label %l3 49 50exit: 51 ret i32 0 52} 53 54; This loop contains a convergent instruction, so its partial unroll 55; count must divide its trip multiple. This overrides its unroll 56; pragma -- we unroll exactly 8 times, even though 16 is requested. 57; CHECK-LABEL: @pragma_unroll 58define i32 @pragma_unroll(i32 %n) { 59entry: 60 %loop_ctl = mul nsw i32 %n, 24 61 br label %l3, !llvm.loop !0 62 63l3: 64 %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ] 65; CHECK: call void @f() 66; CHECK: call void @f() 67; CHECK: call void @f() 68; CHECK: call void @f() 69; CHECK: call void @f() 70; CHECK: call void @f() 71; CHECK: call void @f() 72; CHECK: call void @f() 73; CHECK-NOT: call void @f() 74 call void @f() convergent 75 %inc = add nsw i32 %x.0, 1 76 %exitcond = icmp eq i32 %inc, %loop_ctl 77 br i1 %exitcond, label %exit, label %l3, !llvm.loop !0 78 79exit: 80 ret i32 0 81} 82 83; This loop contains a convergent instruction. Since the pragma loop unroll 84; count 2 divides trip count 4. The loop unroll should respect the pragma. 85; CHECK-LABEL: @pragma_unroll_divisible_trip_count 86define void @pragma_unroll_divisible_trip_count() { 87entry: 88 br label %l3, !llvm.loop !1 89 90l3: 91 %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ] 92; CHECK: call void @f() 93; CHECK: call void @f() 94; CHECK-NOT: call void @f() 95 call void @f() convergent 96 %inc = add nsw i32 %x.0, 1 97 %exitcond = icmp eq i32 %inc, 4 98 br i1 %exitcond, label %exit, label %l3, !llvm.loop !1 99 100exit: 101 ret void 102} 103 104; This loop contains a convergent instruction. Since the pragma loop unroll 105; count 2 divides trip multiple 2. The loop unroll should respect the pragma. 106; CHECK-LABEL: @pragma_unroll_divisible_trip_multiple 107define i32 @pragma_unroll_divisible_trip_multiple(i32 %n) { 108entry: 109 %loop_ctl = mul nsw i32 %n, 2 110 br label %l3, !llvm.loop !1 111 112l3: 113 %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ] 114; CHECK: call void @f() 115; CHECK: call void @f() 116; CHECK-NOT: call void @f() 117 call void @f() convergent 118 %inc = add nsw i32 %x.0, 1 119 %exitcond = icmp eq i32 %inc, %loop_ctl 120 br i1 %exitcond, label %exit, label %l3, !llvm.loop !1 121 122exit: 123 ret i32 0 124} 125 126; This loop contains a convergent instruction. Since the pragma loop unroll 127; count 2 is unknown to divide runtime trip count, the loop is not unrolled 128; since remainder is forbidden for unrolling convergent loop. 129; ToDo: Forbidding remainder for unrolling convergent loop may be relaxed 130; in the future. 131; CHECK-LABEL: @pragma_unroll_indivisible_runtime_trip_count 132define i32 @pragma_unroll_indivisible_runtime_trip_count(i32 %n) { 133entry: 134 br label %l3, !llvm.loop !1 135 136l3: 137 %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ] 138; CHECK: call void @f() 139; CHECK-NOT: call void @f() 140 call void @f() convergent 141 %inc = add nsw i32 %x.0, 1 142 %exitcond = icmp eq i32 %inc, %n 143 br i1 %exitcond, label %exit, label %l3, !llvm.loop !1 144 145exit: 146 ret i32 0 147} 148 149; This loop contains a convergent instruction. Since the pragma loop unroll 150; count 2 does not divide trip count 5, the loop is not unrolled by 2 151; since remainder is forbidden for unrolling convergent loop. Instead, the 152; loop gets fully unrolled. 153; ToDo: Forbidding remainder for unrolling convergent loop may be relaxed 154; in the future. 155; CHECK-LABEL: @pragma_unroll_indivisible_trip_count 156define i32 @pragma_unroll_indivisible_trip_count() { 157entry: 158 br label %l3, !llvm.loop !1 159 160l3: 161 %x.0 = phi i32 [ 0, %entry ], [ %inc, %l3 ] 162; CHECK: call void @f() 163; CHECK: call void @f() 164; CHECK: call void @f() 165; CHECK: call void @f() 166; CHECK: call void @f() 167; CHECK-NOT: call void @f() 168 call void @f() convergent 169 %inc = add nsw i32 %x.0, 1 170 %exitcond = icmp eq i32 %inc, 5 171 br i1 %exitcond, label %exit, label %l3, !llvm.loop !1 172 173exit: 174 ret i32 0 175} 176 177!0 = !{!0, !{!"llvm.loop.unroll.count", i32 16}} 178!1 = !{!1, !{!"llvm.loop.unroll.count", i32 2}} 179 180