Home | History | Annotate | Download | only in LoopUnroll
      1 ; RUN: opt < %s -S -loop-unroll -unroll-force-peel-count=3 -verify-dom-info -simplifycfg -instcombine | FileCheck %s
      2 
      3 ; Basic loop peeling - check that we can peel-off the first 3 loop iterations
      4 ; when explicitly requested.
      5 ; CHECK-LABEL: @basic
      6 ; CHECK: %[[CMP0:.*]] = icmp sgt i32 %k, 0
      7 ; CHECK: br i1 %[[CMP0]], label %[[NEXT0:.*]], label %for.end
      8 ; CHECK: [[NEXT0]]:
      9 ; CHECK: store i32 0, i32* %p, align 4
     10 ; CHECK: %[[CMP1:.*]] = icmp eq i32 %k, 1
     11 ; CHECK: br i1 %[[CMP1]], label %for.end, label %[[NEXT1:.*]]
     12 ; CHECK: [[NEXT1]]:
     13 ; CHECK: %[[INC1:.*]] = getelementptr inbounds i32, i32* %p, i64 1
     14 ; CHECK: store i32 1, i32* %[[INC1]], align 4
     15 ; CHECK: %[[CMP2:.*]] = icmp sgt i32 %k, 2
     16 ; CHECK: br i1 %[[CMP2]], label %[[NEXT2:.*]], label %for.end
     17 ; CHECK: [[NEXT2]]:
     18 ; CHECK: %[[INC2:.*]] = getelementptr inbounds i32, i32* %p, i64 2
     19 ; CHECK: store i32 2, i32* %[[INC2]], align 4
     20 ; CHECK: %[[CMP3:.*]] = icmp eq i32 %k, 3
     21 ; CHECK: br i1 %[[CMP3]], label %for.end, label %[[LOOP_PH:.*]]
     22 ; CHECK: for.end:
     23 ; CHECK: ret void
     24 
     25 define void @basic(i32* %p, i32 %k) #0 {
     26 entry:
     27   %cmp3 = icmp slt i32 0, %k
     28   br i1 %cmp3, label %for.body.lr.ph, label %for.end
     29 
     30 for.body.lr.ph:                                   ; preds = %entry
     31   br label %for.body
     32 
     33 for.body:                                         ; preds = %for.body.lr.ph, %for.body
     34   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
     35   %p.addr.04 = phi i32* [ %p, %for.body.lr.ph ], [ %incdec.ptr, %for.body ]
     36   %incdec.ptr = getelementptr inbounds i32, i32* %p.addr.04, i32 1
     37   store i32 %i.05, i32* %p.addr.04, align 4
     38   %inc = add nsw i32 %i.05, 1
     39   %cmp = icmp slt i32 %inc, %k
     40   br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
     41 
     42 for.cond.for.end_crit_edge:                       ; preds = %for.body
     43   br label %for.end
     44 
     45 for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
     46   ret void
     47 }
     48 
     49 ; Make sure peeling works correctly when a value defined in a loop is used
     50 ; in later code - we need to correctly plumb the phi depending on which
     51 ; iteration is actually used.
     52 ; CHECK-LABEL: @output
     53 ; CHECK: %[[CMP0:.*]] = icmp sgt i32 %k, 0
     54 ; CHECK: br i1 %[[CMP0]], label %[[NEXT0:.*]], label %for.end
     55 ; CHECK: [[NEXT0]]:
     56 ; CHECK: store i32 0, i32* %p, align 4
     57 ; CHECK: %[[CMP1:.*]] = icmp eq i32 %k, 1
     58 ; CHECK: br i1 %[[CMP1]], label %for.end, label %[[NEXT1:.*]]
     59 ; CHECK: [[NEXT1]]:
     60 ; CHECK: %[[INC1:.*]] = getelementptr inbounds i32, i32* %p, i64 1
     61 ; CHECK: store i32 1, i32* %[[INC1]], align 4
     62 ; CHECK: %[[CMP2:.*]] = icmp sgt i32 %k, 2
     63 ; CHECK: br i1 %[[CMP2]], label %[[NEXT2:.*]], label %for.end
     64 ; CHECK: [[NEXT2]]:
     65 ; CHECK: %[[INC2:.*]] = getelementptr inbounds i32, i32* %p, i64 2
     66 ; CHECK: store i32 2, i32* %[[INC2]], align 4
     67 ; CHECK: %[[CMP3:.*]] = icmp eq i32 %k, 3
     68 ; CHECK: br i1 %[[CMP3]], label %for.end, label %[[LOOP_PH:.*]]
     69 ; CHECK: for.end:
     70 ; CHECK: %ret = phi i32 [ 0, %entry ], [ 1, %[[NEXT0]] ], [ 2, %[[NEXT1]] ], [ 3, %[[NEXT2]] ], [ %inc, %for.body ]
     71 ; CHECK: ret i32 %ret
     72 define i32 @output(i32* %p, i32 %k) #0 {
     73 entry:
     74   %cmp3 = icmp slt i32 0, %k
     75   br i1 %cmp3, label %for.body.lr.ph, label %for.end
     76 
     77 for.body.lr.ph:                                   ; preds = %entry
     78   br label %for.body
     79 
     80 for.body:                                         ; preds = %for.body.lr.ph, %for.body
     81   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
     82   %p.addr.04 = phi i32* [ %p, %for.body.lr.ph ], [ %incdec.ptr, %for.body ]
     83   %incdec.ptr = getelementptr inbounds i32, i32* %p.addr.04, i32 1
     84   store i32 %i.05, i32* %p.addr.04, align 4
     85   %inc = add nsw i32 %i.05, 1
     86   %cmp = icmp slt i32 %inc, %k
     87   br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
     88 
     89 for.cond.for.end_crit_edge:                       ; preds = %for.body
     90   br label %for.end
     91 
     92 for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
     93   %ret = phi i32 [ 0, %entry], [ %inc, %for.cond.for.end_crit_edge ]
     94   ret i32 %ret
     95 }
     96