Home | History | Annotate | Download | only in LoopDeletion
      1 ; Checks whether dead loops with multiple exits can be eliminated.
      2 ; Note that we loop simplify and LCSSA over the test cases to make sure the
      3 ; critical components remain after those passes and are visible to the loop
      4 ; deletion pass.
      5 ;
      6 ; RUN: opt < %s -loop-simplify -lcssa -S | FileCheck %s --check-prefixes=CHECK,BEFORE
      7 ; RUN: opt < %s -loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER
      8 ;
      9 ; RUN: opt < %s -passes=no-op-loop -S | FileCheck %s --check-prefixes=CHECK,BEFORE
     10 ; RUN: opt < %s -passes=loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER
     11 
     12 
     13 define void @foo(i64 %n, i64 %m) nounwind {
     14 ; CHECK-LABEL: @foo(
     15 
     16 entry:
     17   br label %bb
     18 ; CHECK:       entry:
     19 ; BEFORE-NEXT:   br label %bb
     20 ; AFTER-NEXT:    br label %return
     21 
     22 bb:
     23   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb2 ]
     24   %t0 = add i64 %x.0, 1
     25   %t1 = icmp slt i64 %x.0, %n
     26   br i1 %t1, label %bb2, label %return
     27 ; BEFORE:      bb:
     28 ; BEFORE:        br i1 {{.*}}, label %bb2, label %return
     29 ; AFTER-NOT:   bb:
     30 ; AFTER-NOT:     br
     31 
     32 bb2:
     33   %t2 = icmp slt i64 %x.0, %m
     34   br i1 %t1, label %bb, label %return
     35 ; BEFORE:      bb2:
     36 ; BEFORE:        br i1 {{.*}}, label %bb, label %return
     37 ; AFTER-NOT:   bb2:
     38 ; AFTER-NOT:     br
     39 
     40 return:
     41   ret void
     42 ; CHECK:       return:
     43 ; CHECK-NEXT:    ret void
     44 }
     45 
     46 define i64 @bar(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
     47 ; CHECK-LABEL: @bar(
     48 
     49 entry:
     50   br label %bb
     51 ; CHECK:       entry:
     52 ; BEFORE-NEXT:   br label %bb
     53 ; AFTER-NEXT:    br label %return
     54 
     55 bb:
     56   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]
     57   %t0 = add i64 %x.0, 1
     58   %t1 = icmp slt i64 %x.0, %n
     59   br i1 %t1, label %bb2, label %return
     60 ; BEFORE:      bb:
     61 ; BEFORE:        br i1 {{.*}}, label %bb2, label %return
     62 ; AFTER-NOT:   bb:
     63 ; AFTER-NOT:     br
     64 
     65 bb2:
     66   %t2 = icmp slt i64 %x.0, %m
     67   ; This unused division prevents unifying this loop exit path with others
     68   ; because it can be deleted but cannot be hoisted.
     69   %unused1 = udiv i64 42, %maybe_zero
     70   br i1 %t2, label %bb3, label %return
     71 ; BEFORE:      bb2:
     72 ; BEFORE:        br i1 {{.*}}, label %bb3, label %return
     73 ; AFTER-NOT:   bb2:
     74 ; AFTER-NOT:     br
     75 
     76 bb3:
     77   %t3 = icmp slt i64 %x.0, %m
     78   ; This unused division prevents unifying this loop exit path with others
     79   ; because it can be deleted but cannot be hoisted.
     80   %unused2 = sdiv i64 42, %maybe_zero
     81   br i1 %t3, label %bb, label %return
     82 ; BEFORE:      bb3:
     83 ; BEFORE:        br i1 {{.*}}, label %bb, label %return
     84 ; AFTER-NOT:   bb3:
     85 ; AFTER-NOT:     br
     86 
     87 return:
     88   %x.lcssa = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
     89   ret i64 %x.lcssa
     90 ; CHECK:       return:
     91 ; BEFORE-NEXT:   %[[X:.*]] = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
     92 ; AFTER-NEXT:    %[[X:.*]] = phi i64 [ 10, %entry ]
     93 ; CHECK-NEXT:    ret i64 %[[X]]
     94 }
     95 
     96 ; This function has a loop which looks like @bar's but that cannot be deleted
     97 ; because which path we exit through determines which value is selected.
     98 define i64 @baz(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
     99 ; CHECK-LABEL:  @baz(
    100 
    101 entry:
    102   br label %bb
    103 ; CHECK:       entry:
    104 ; CHECK-NEXT:    br label %bb
    105 
    106 bb:
    107   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]
    108   %t0 = add i64 %x.0, 1
    109   %t1 = icmp slt i64 %x.0, %n
    110   br i1 %t1, label %bb2, label %return
    111 ; CHECK:       bb:
    112 ; CHECK:         br i1 {{.*}}, label %bb2, label %return
    113 
    114 bb2:
    115   %t2 = icmp slt i64 %x.0, %m
    116   ; This unused division prevents unifying this loop exit path with others
    117   ; because it can be deleted but cannot be hoisted.
    118   %unused1 = udiv i64 42, %maybe_zero
    119   br i1 %t2, label %bb3, label %return
    120 ; CHECK:       bb2:
    121 ; CHECK:         br i1 {{.*}}, label %bb3, label %return
    122 
    123 bb3:
    124   %t3 = icmp slt i64 %x.0, %m
    125   ; This unused division prevents unifying this loop exit path with others
    126   ; because it can be deleted but cannot be hoisted.
    127   %unused2 = sdiv i64 42, %maybe_zero
    128   br i1 %t3, label %bb, label %return
    129 ; CHECK:       bb3:
    130 ; CHECK:         br i1 {{.*}}, label %bb, label %return
    131 
    132 return:
    133   %x.lcssa = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
    134   ret i64 %x.lcssa
    135 ; CHECK: return:
    136 ; CHECK-NEXT:  %[[X:.*]] = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
    137 ; CHECK-NEXT:  ret i64 %[[X]]
    138 }
    139