Home | History | Annotate | Download | only in PowerPC
      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