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!0 = !{!0, !{!"llvm.loop.unroll.count", i32 16}} 84