1; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 < %s | FileCheck %s 2 3; If there is an exit edge known to be frequently taken, 4; we should not transform this loop. 5 6; A loop having a hot exit edge (exit in false branch) 7define signext i64 @func() { 8; CHECK: @func 9; CHECK-NOT: mtctr 10; CHECK-NOT: bdnz 11 12entry: 13 %a = alloca [1000 x i32], align 4 14 br label %for.body 15 16for.body: 17 %i.013 = phi i64 [ 0, %entry ], [ %inc, %if.end ] 18 %b.012 = phi i64 [ 0, %entry ], [ %xor, %if.end ] 19 %arrayidx = getelementptr inbounds [1000 x i32], ptr %a, i64 0, i64 %i.013 20 %0 = load i32, ptr %arrayidx, align 4 21 %tobool = icmp eq i32 %0, 0 22 br i1 %tobool, label %if.end, label %cleanup, !prof !1 23 24if.end: 25 %xor = xor i64 %i.013, %b.012 26 %inc = add nuw nsw i64 %i.013, 1 27 %cmp = icmp ult i64 %inc, 1000 28 br i1 %cmp, label %for.body, label %cleanup 29 30cleanup: 31 %res = phi i64 [ %b.012, %for.body ], [ %xor, %if.end ] 32 ret i64 %res 33} 34 35; A loop having a cold exit edge (exit in false branch) 36define signext i64 @func2() { 37; CHECK: @func2 38; CHECK: mtctr 39; CHECK: bdnz 40 41entry: 42 %a = alloca [1000 x i32], align 4 43 br label %for.body 44 45for.body: 46 %i.013 = phi i64 [ 0, %entry ], [ %inc, %if.end ] 47 %b.012 = phi i64 [ 0, %entry ], [ %xor, %if.end ] 48 %arrayidx = getelementptr inbounds [1000 x i32], ptr %a, i64 0, i64 %i.013 49 %0 = load i32, ptr %arrayidx, align 4 50 %tobool = icmp eq i32 %0, 0 51 br i1 %tobool, label %if.end, label %cleanup, !prof !2 52 53if.end: 54 %xor = xor i64 %i.013, %b.012 55 %inc = add nuw nsw i64 %i.013, 1 56 %cmp = icmp ult i64 %inc, 1000 57 br i1 %cmp, label %for.body, label %cleanup 58 59cleanup: 60 %res = phi i64 [ %b.012, %for.body ], [ %xor, %if.end ] 61 ret i64 %res 62} 63 64; A loop having an exit edge without profile data (exit in false branch) 65define signext i64 @func3() { 66; CHECK: @func3 67; CHECK: mtctr 68; CHECK: bdnz 69 70entry: 71 %a = alloca [1000 x i32], align 4 72 br label %for.body 73 74for.body: 75 %i.013 = phi i64 [ 0, %entry ], [ %inc, %if.end ] 76 %b.012 = phi i64 [ 0, %entry ], [ %xor, %if.end ] 77 %arrayidx = getelementptr inbounds [1000 x i32], ptr %a, i64 0, i64 %i.013 78 %0 = load i32, ptr %arrayidx, align 4 79 %tobool = icmp eq i32 %0, 0 80 br i1 %tobool, label %if.end, label %cleanup 81 82if.end: 83 %xor = xor i64 %i.013, %b.012 84 %inc = add nuw nsw i64 %i.013, 1 85 %cmp = icmp ult i64 %inc, 1000 86 br i1 %cmp, label %for.body, label %cleanup 87 88cleanup: 89 %res = phi i64 [ %b.012, %for.body ], [ %xor, %if.end ] 90 ret i64 %res 91} 92 93; A loop having a hot exit edge (exit in true branch) 94define signext i64 @func4() { 95; CHECK: @func4 96; CHECK-NOT: mtctr 97; CHECK-NOT: bdnz 98 99entry: 100 %a = alloca [1000 x i32], align 4 101 br label %for.body 102 103for.body: 104 %i.013 = phi i64 [ 0, %entry ], [ %inc, %if.end ] 105 %b.012 = phi i64 [ 0, %entry ], [ %xor, %if.end ] 106 %arrayidx = getelementptr inbounds [1000 x i32], ptr %a, i64 0, i64 %i.013 107 %0 = load i32, ptr %arrayidx, align 4 108 %tobool = icmp ne i32 %0, 0 109 br i1 %tobool, label %cleanup, label %if.end, !prof !2 110 111if.end: 112 %xor = xor i64 %i.013, %b.012 113 %inc = add nuw nsw i64 %i.013, 1 114 %cmp = icmp ult i64 %inc, 1000 115 br i1 %cmp, label %for.body, label %cleanup 116 117cleanup: 118 %res = phi i64 [ %b.012, %for.body ], [ %xor, %if.end ] 119 ret i64 %res 120} 121 122; A loop having a cold exit edge (exit in true branch) 123define signext i64 @func5() { 124; CHECK: @func5 125; CHECK: mtctr 126; CHECK: bdnz 127 128entry: 129 %a = alloca [1000 x i32], align 4 130 br label %for.body 131 132for.body: 133 %i.013 = phi i64 [ 0, %entry ], [ %inc, %if.end ] 134 %b.012 = phi i64 [ 0, %entry ], [ %xor, %if.end ] 135 %arrayidx = getelementptr inbounds [1000 x i32], ptr %a, i64 0, i64 %i.013 136 %0 = load i32, ptr %arrayidx, align 4 137 %tobool = icmp ne i32 %0, 0 138 br i1 %tobool, label %cleanup, label %if.end, !prof !1 139 140if.end: 141 %xor = xor i64 %i.013, %b.012 142 %inc = add nuw nsw i64 %i.013, 1 143 %cmp = icmp ult i64 %inc, 1000 144 br i1 %cmp, label %for.body, label %cleanup 145 146cleanup: 147 %res = phi i64 [ %b.012, %for.body ], [ %xor, %if.end ] 148 ret i64 %res 149} 150 151; A loop having an exit edge without profile data (exit in true branch) 152define signext i64 @func6() { 153; CHECK: @func6 154; CHECK: mtctr 155; CHECK: bdnz 156 157entry: 158 %a = alloca [1000 x i32], align 4 159 br label %for.body 160 161for.body: 162 %i.013 = phi i64 [ 0, %entry ], [ %inc, %if.end ] 163 %b.012 = phi i64 [ 0, %entry ], [ %xor, %if.end ] 164 %arrayidx = getelementptr inbounds [1000 x i32], ptr %a, i64 0, i64 %i.013 165 %0 = load i32, ptr %arrayidx, align 4 166 %tobool = icmp ne i32 %0, 0 167 br i1 %tobool, label %cleanup, label %if.end 168 169if.end: 170 %xor = xor i64 %i.013, %b.012 171 %inc = add nuw nsw i64 %i.013, 1 172 %cmp = icmp ult i64 %inc, 1000 173 br i1 %cmp, label %for.body, label %cleanup 174 175cleanup: 176 %res = phi i64 [ %b.012, %for.body ], [ %xor, %if.end ] 177 ret i64 %res 178} 179 180!1 = !{!"branch_weights", i32 1, i32 2000} 181!2 = !{!"branch_weights", i32 2000, i32 1} 182