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