1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -loop-unroll -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; Verify that the unrolling pass removes existing unroll count metadata 4*9880d681SAndroid Build Coastguard Worker; and adds a disable unrolling node after unrolling is complete. 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 7*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu" 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; #pragma clang loop vectorize(enable) unroll_count(4) vectorize_width(8) 10*9880d681SAndroid Build Coastguard Worker; 11*9880d681SAndroid Build Coastguard Worker; Unroll count metadata should be replaced with unroll(disable). Vectorize 12*9880d681SAndroid Build Coastguard Worker; metadata should be untouched. 13*9880d681SAndroid Build Coastguard Worker; 14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @unroll_count_4( 15*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]] 16*9880d681SAndroid Build Coastguard Workerdefine void @unroll_count_4(i32* nocapture %a) { 17*9880d681SAndroid Build Coastguard Workerentry: 18*9880d681SAndroid Build Coastguard Worker br label %for.body 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 21*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 22*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 23*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %arrayidx, align 4 24*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %0, 1 25*9880d681SAndroid Build Coastguard Worker store i32 %inc, i32* %arrayidx, align 4 26*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 27*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvars.iv.next, 64 28*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !1 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 31*9880d681SAndroid Build Coastguard Worker ret void 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker!1 = !{!1, !2, !3, !4} 34*9880d681SAndroid Build Coastguard Worker!2 = !{!"llvm.loop.vectorize.enable", i1 true} 35*9880d681SAndroid Build Coastguard Worker!3 = !{!"llvm.loop.unroll.count", i32 4} 36*9880d681SAndroid Build Coastguard Worker!4 = !{!"llvm.loop.vectorize.width", i32 8} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; #pragma clang loop unroll(full) 39*9880d681SAndroid Build Coastguard Worker; 40*9880d681SAndroid Build Coastguard Worker; An unroll disable metadata node is only added for the unroll count case. 41*9880d681SAndroid Build Coastguard Worker; In this case, the loop has a full unroll metadata but can't be fully unrolled 42*9880d681SAndroid Build Coastguard Worker; because the trip count is dynamic. The full unroll metadata should remain 43*9880d681SAndroid Build Coastguard Worker; after unrolling. 44*9880d681SAndroid Build Coastguard Worker; 45*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @unroll_full( 46*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]] 47*9880d681SAndroid Build Coastguard Workerdefine void @unroll_full(i32* nocapture %a, i32 %b) { 48*9880d681SAndroid Build Coastguard Workerentry: 49*9880d681SAndroid Build Coastguard Worker %cmp3 = icmp sgt i32 %b, 0 50*9880d681SAndroid Build Coastguard Worker br i1 %cmp3, label %for.body, label %for.end, !llvm.loop !5 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 53*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] 54*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 55*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %arrayidx, align 4 56*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %0, 1 57*9880d681SAndroid Build Coastguard Worker store i32 %inc, i32* %arrayidx, align 4 58*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 59*9880d681SAndroid Build Coastguard Worker %lftr.wideiv = trunc i64 %indvars.iv.next to i32 60*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %lftr.wideiv, %b 61*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !5 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 64*9880d681SAndroid Build Coastguard Worker ret void 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker!5 = !{!5, !6} 67*9880d681SAndroid Build Coastguard Worker!6 = !{!"llvm.loop.unroll.full"} 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; #pragma clang loop unroll(disable) 70*9880d681SAndroid Build Coastguard Worker; 71*9880d681SAndroid Build Coastguard Worker; Unroll metadata should not change. 72*9880d681SAndroid Build Coastguard Worker; 73*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @unroll_disable( 74*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_3:.*]] 75*9880d681SAndroid Build Coastguard Workerdefine void @unroll_disable(i32* nocapture %a) { 76*9880d681SAndroid Build Coastguard Workerentry: 77*9880d681SAndroid Build Coastguard Worker br label %for.body 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 80*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 81*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 82*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %arrayidx, align 4 83*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %0, 1 84*9880d681SAndroid Build Coastguard Worker store i32 %inc, i32* %arrayidx, align 4 85*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 86*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvars.iv.next, 64 87*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !7 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 90*9880d681SAndroid Build Coastguard Worker ret void 91*9880d681SAndroid Build Coastguard Worker} 92*9880d681SAndroid Build Coastguard Worker!7 = !{!7, !8} 93*9880d681SAndroid Build Coastguard Worker!8 = !{!"llvm.loop.unroll.disable"} 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker; This function contains two loops which share the same llvm.loop metadata node 96*9880d681SAndroid Build Coastguard Worker; with an llvm.loop.unroll.count 2 hint. Both loops should be unrolled. This 97*9880d681SAndroid Build Coastguard Worker; verifies that adding disable metadata to a loop after unrolling doesn't affect 98*9880d681SAndroid Build Coastguard Worker; other loops which previously shared the same llvm.loop metadata. 99*9880d681SAndroid Build Coastguard Worker; 100*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @shared_metadata( 101*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 102*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 103*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_4:.*]] 104*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 105*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 106*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_5:.*]] 107*9880d681SAndroid Build Coastguard Workerdefine void @shared_metadata(i32* nocapture %List) #0 { 108*9880d681SAndroid Build Coastguard Workerentry: 109*9880d681SAndroid Build Coastguard Worker br label %for.body3 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Workerfor.body3: ; preds = %for.body3, %entry 112*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body3 ] 113*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %List, i64 %indvars.iv 114*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %arrayidx, align 4 115*9880d681SAndroid Build Coastguard Worker %add4 = add nsw i32 %0, 10 116*9880d681SAndroid Build Coastguard Worker store i32 %add4, i32* %arrayidx, align 4 117*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 118*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvars.iv.next, 4 119*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.body3.1.preheader, label %for.body3, !llvm.loop !9 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Workerfor.body3.1.preheader: ; preds = %for.body3 122*9880d681SAndroid Build Coastguard Worker br label %for.body3.1 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Workerfor.body3.1: ; preds = %for.body3.1.preheader, %for.body3.1 125*9880d681SAndroid Build Coastguard Worker %indvars.iv.1 = phi i64 [ %1, %for.body3.1 ], [ 0, %for.body3.1.preheader ] 126*9880d681SAndroid Build Coastguard Worker %1 = add nsw i64 %indvars.iv.1, 1 127*9880d681SAndroid Build Coastguard Worker %arrayidx.1 = getelementptr inbounds i32, i32* %List, i64 %1 128*9880d681SAndroid Build Coastguard Worker %2 = load i32, i32* %arrayidx.1, align 4 129*9880d681SAndroid Build Coastguard Worker %add4.1 = add nsw i32 %2, 10 130*9880d681SAndroid Build Coastguard Worker store i32 %add4.1, i32* %arrayidx.1, align 4 131*9880d681SAndroid Build Coastguard Worker %exitcond.1 = icmp eq i64 %1, 4 132*9880d681SAndroid Build Coastguard Worker br i1 %exitcond.1, label %for.inc5.1, label %for.body3.1, !llvm.loop !9 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Workerfor.inc5.1: ; preds = %for.body3.1 135*9880d681SAndroid Build Coastguard Worker ret void 136*9880d681SAndroid Build Coastguard Worker} 137*9880d681SAndroid Build Coastguard Worker!9 = !{!9, !10} 138*9880d681SAndroid Build Coastguard Worker!10 = !{!"llvm.loop.unroll.count", i32 2} 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Worker; CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[VEC_ENABLE:.*]], ![[WIDTH_8:.*]], ![[UNROLL_DISABLE:.*]]} 142*9880d681SAndroid Build Coastguard Worker; CHECK: ![[VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true} 143*9880d681SAndroid Build Coastguard Worker; CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8} 144*9880d681SAndroid Build Coastguard Worker; CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"} 145*9880d681SAndroid Build Coastguard Worker; CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNROLL_FULL:.*]]} 146*9880d681SAndroid Build Coastguard Worker; CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"} 147*9880d681SAndroid Build Coastguard Worker; CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNROLL_DISABLE:.*]]} 148*9880d681SAndroid Build Coastguard Worker; CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[UNROLL_DISABLE:.*]]} 149*9880d681SAndroid Build Coastguard Worker; CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[UNROLL_DISABLE:.*]]} 150