Home | History | Annotate | Download | only in LoopPredication
      1 ; RUN: opt -S -loop-predication -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
      2 ; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
      3 
      4 declare void @llvm.experimental.guard(i1, ...)
      5 
      6 define i32 @signed_reverse_loop_n_to_lower_limit(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
      7 ; CHECK-LABEL: @signed_reverse_loop_n_to_lower_limit(
      8 entry:
      9   %tmp5 = icmp eq i32 %n, 0
     10   br i1 %tmp5, label %exit, label %loop.preheader
     11 
     12 ; CHECK:       loop.preheader:
     13 ; CHECK-NEXT:    [[range_start:%.*]] = add i32 %n, -1
     14 ; CHECK-NEXT:    [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
     15 ; CHECK-NEXT:    [[no_wrap_check:%.*]] = icmp sge i32 %lowerlimit, 1
     16 ; CHECK-NEXT:    [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
     17 loop.preheader:
     18   br label %loop
     19 
     20 ; CHECK: loop:
     21 ; CHECK:    call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
     22 loop:
     23   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
     24   %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
     25   %i.next = add nsw i32 %i, -1
     26   %within.bounds = icmp ult i32 %i.next, %length
     27   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
     28   %i.i64 = zext i32 %i.next to i64
     29   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
     30   %array.i = load i32, i32* %array.i.ptr, align 4
     31   %loop.acc.next = add i32 %loop.acc, %array.i
     32   %continue = icmp sgt i32 %i, %lowerlimit
     33   br i1 %continue, label %loop, label %exit
     34 
     35 exit:
     36   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
     37   ret i32 %result
     38 }
     39 
     40 define i32 @unsigned_reverse_loop_n_to_lower_limit(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
     41 ; CHECK-LABEL: @unsigned_reverse_loop_n_to_lower_limit(
     42 entry:
     43   %tmp5 = icmp eq i32 %n, 0
     44   br i1 %tmp5, label %exit, label %loop.preheader
     45 
     46 ; CHECK:       loop.preheader:
     47 ; CHECK-NEXT:    [[range_start:%.*]] = add i32 %n, -1
     48 ; CHECK-NEXT:    [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
     49 ; CHECK-NEXT:    [[no_wrap_check:%.*]] = icmp uge i32 %lowerlimit, 1
     50 ; CHECK-NEXT:    [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
     51 loop.preheader:
     52   br label %loop
     53 
     54 ; CHECK: loop:
     55 ; CHECK:    call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
     56 loop:
     57   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
     58   %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
     59   %i.next = add nsw i32 %i, -1
     60   %within.bounds = icmp ult i32 %i.next, %length
     61   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
     62   %i.i64 = zext i32 %i.next to i64
     63   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
     64   %array.i = load i32, i32* %array.i.ptr, align 4
     65   %loop.acc.next = add i32 %loop.acc, %array.i
     66   %continue = icmp ugt i32 %i, %lowerlimit
     67   br i1 %continue, label %loop, label %exit
     68 
     69 exit:
     70   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
     71   ret i32 %result
     72 }
     73 
     74 
     75 ; if we predicated the loop, the guard will definitely fail and we will
     76 ; deoptimize early on.
     77 define i32 @unsigned_reverse_loop_n_to_0(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
     78 ; CHECK-LABEL: @unsigned_reverse_loop_n_to_0(
     79 entry:
     80   %tmp5 = icmp eq i32 %n, 0
     81   br i1 %tmp5, label %exit, label %loop.preheader
     82 
     83 ; CHECK:       loop.preheader:
     84 ; CHECK-NEXT:    [[range_start:%.*]] = add i32 %n, -1
     85 ; CHECK-NEXT:    [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
     86 ; CHECK-NEXT:    [[wide_cond:%.*]] = and i1 [[first_iteration_check]], false
     87 loop.preheader:
     88   br label %loop
     89 
     90 ; CHECK: loop:
     91 ; CHECK:    call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
     92 loop:
     93   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
     94   %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
     95   %i.next = add nsw i32 %i, -1
     96   %within.bounds = icmp ult i32 %i.next, %length
     97   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
     98   %i.i64 = zext i32 %i.next to i64
     99   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
    100   %array.i = load i32, i32* %array.i.ptr, align 4
    101   %loop.acc.next = add i32 %loop.acc, %array.i
    102   %continue = icmp ugt i32 %i, 0
    103   br i1 %continue, label %loop, label %exit
    104 
    105 exit:
    106   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
    107   ret i32 %result
    108 }
    109 
    110 ; do not loop predicate when the range has step -1 and latch has step 1.
    111 define i32 @reverse_loop_range_step_increment(i32 %n, i32* %array, i32 %length) {
    112 ; CHECK-LABEL: @reverse_loop_range_step_increment(
    113 entry:
    114   %tmp5 = icmp eq i32 %n, 0
    115   br i1 %tmp5, label %exit, label %loop.preheader
    116 
    117 loop.preheader:
    118   br label %loop
    119 
    120 ; CHECK: loop:
    121 ; CHECK: llvm.experimental.guard(i1 %within.bounds, i32 9)
    122 loop:
    123   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
    124   %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
    125   %irc = phi i32 [ %i.inc, %loop ], [ 1, %loop.preheader ]
    126   %i.inc = add nuw nsw i32 %irc, 1
    127   %within.bounds = icmp ult i32 %irc, %length
    128   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
    129   %i.i64 = zext i32 %irc to i64
    130   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
    131   %array.i = load i32, i32* %array.i.ptr, align 4
    132   %i.next = add nsw i32 %i, -1
    133   %loop.acc.next = add i32 %loop.acc, %array.i
    134   %continue = icmp ugt i32 %i, 65534
    135   br i1 %continue, label %loop, label %exit
    136 
    137 exit:
    138   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
    139   ret i32 %result
    140 }
    141 
    142 define i32 @signed_reverse_loop_n_to_lower_limit_equal(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
    143 ; CHECK-LABEL: @signed_reverse_loop_n_to_lower_limit_equal(
    144 entry:
    145   %tmp5 = icmp eq i32 %n, 0
    146   br i1 %tmp5, label %exit, label %loop.preheader
    147 
    148 ; CHECK:       loop.preheader:
    149 ; CHECK-NEXT:    [[range_start:%.*]] = add i32 %n, -1
    150 ; CHECK-NEXT:    [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
    151 ; CHECK-NEXT:    [[no_wrap_check:%.*]] = icmp sgt i32 %lowerlimit, 1
    152 ; CHECK-NEXT:    [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
    153 loop.preheader:
    154   br label %loop
    155 
    156 ; CHECK: loop:
    157 ; CHECK:    call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
    158 loop:
    159   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
    160   %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
    161   %i.next = add nsw i32 %i, -1
    162   %within.bounds = icmp ult i32 %i.next, %length
    163   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
    164   %i.i64 = zext i32 %i.next to i64
    165   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
    166   %array.i = load i32, i32* %array.i.ptr, align 4
    167   %loop.acc.next = add i32 %loop.acc, %array.i
    168   %continue = icmp sge i32 %i, %lowerlimit
    169   br i1 %continue, label %loop, label %exit
    170 
    171 exit:
    172   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
    173   ret i32 %result
    174 }
    175 
    176 define i32 @unsigned_reverse_loop_n_to_lower_limit_equal(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
    177 ; CHECK-LABEL: @unsigned_reverse_loop_n_to_lower_limit_equal(
    178 entry:
    179   %tmp5 = icmp eq i32 %n, 0
    180   br i1 %tmp5, label %exit, label %loop.preheader
    181 
    182 ; CHECK:       loop.preheader:
    183 ; CHECK-NEXT:    [[range_start:%.*]] = add i32 %n, -1
    184 ; CHECK-NEXT:    [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
    185 ; CHECK-NEXT:    [[no_wrap_check:%.*]] = icmp ugt i32 %lowerlimit, 1
    186 ; CHECK-NEXT:    [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
    187 loop.preheader:
    188   br label %loop
    189 
    190 ; CHECK: loop:
    191 ; CHECK:    call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
    192 loop:
    193   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
    194   %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
    195   %i.next = add nsw i32 %i, -1
    196   %within.bounds = icmp ult i32 %i.next, %length
    197   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
    198   %i.i64 = zext i32 %i.next to i64
    199   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
    200   %array.i = load i32, i32* %array.i.ptr, align 4
    201   %loop.acc.next = add i32 %loop.acc, %array.i
    202   %continue = icmp uge i32 %i, %lowerlimit
    203   br i1 %continue, label %loop, label %exit
    204 
    205 exit:
    206   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
    207   ret i32 %result
    208 }
    209 
    210 
    211 ; if we predicated the loop, the guard will definitely fail and we will
    212 ; deoptimize early on.
    213 define i32 @unsigned_reverse_loop_n_to_1(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
    214 ; CHECK-LABEL: @unsigned_reverse_loop_n_to_1(
    215 entry:
    216   %tmp5 = icmp eq i32 %n, 0
    217   br i1 %tmp5, label %exit, label %loop.preheader
    218 
    219 ; CHECK:       loop.preheader:
    220 ; CHECK-NEXT:    [[range_start:%.*]] = add i32 %n, -1
    221 ; CHECK-NEXT:    [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
    222 ; CHECK-NEXT:    [[wide_cond:%.*]] = and i1 [[first_iteration_check]], false
    223 loop.preheader:
    224   br label %loop
    225 
    226 ; CHECK: loop:
    227 ; CHECK:    call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
    228 loop:
    229   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
    230   %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
    231   %i.next = add nsw i32 %i, -1
    232   %within.bounds = icmp ult i32 %i.next, %length
    233   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
    234   %i.i64 = zext i32 %i.next to i64
    235   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
    236   %array.i = load i32, i32* %array.i.ptr, align 4
    237   %loop.acc.next = add i32 %loop.acc, %array.i
    238   %continue = icmp uge i32 %i, 1
    239   br i1 %continue, label %loop, label %exit
    240 
    241 exit:
    242   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
    243   ret i32 %result
    244 }
    245 
    246