Home | History | Annotate | Download | only in IndVarSimplify
      1 ; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
      2 ;
      3 ; Make sure that indvars can perform LFTR without a canonical IV.
      4 
      5 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
      6 
      7 ; Perform LFTR using the original pointer-type IV.
      8 
      9 ;  for(char* p = base; p < base + n; ++p) {
     10 ;    *p = p-base;
     11 ;  }
     12 define void @ptriv(i8* %base, i32 %n) nounwind {
     13 entry:
     14   %idx.ext = sext i32 %n to i64
     15   %add.ptr = getelementptr inbounds i8* %base, i64 %idx.ext
     16   %cmp1 = icmp ult i8* %base, %add.ptr
     17   br i1 %cmp1, label %for.body, label %for.end
     18 
     19 ; CHECK: for.body:
     20 ; CHECK: phi i8*
     21 ; CHECK-NOT: phi
     22 ; CHECK-NOT: add
     23 ; CHECK: icmp ne i8*
     24 ; CHECK: br i1
     25 for.body:
     26   %p.02 = phi i8* [ %base, %entry ], [ %incdec.ptr, %for.body ]
     27   ; cruft to make the IV useful
     28   %sub.ptr.lhs.cast = ptrtoint i8* %p.02 to i64
     29   %sub.ptr.rhs.cast = ptrtoint i8* %base to i64
     30   %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
     31   %conv = trunc i64 %sub.ptr.sub to i8
     32   store i8 %conv, i8* %p.02
     33   %incdec.ptr = getelementptr inbounds i8* %p.02, i32 1
     34   %cmp = icmp ult i8* %incdec.ptr, %add.ptr
     35   br i1 %cmp, label %for.body, label %for.end
     36 
     37 for.end:
     38   ret void
     39 }
     40 
     41 ; It would be nice if SCEV and any loop analysis could assume that
     42 ; preheaders exist. Unfortunately it is not always the case. This test
     43 ; checks that SCEVExpander can handle an outer loop that has not yet
     44 ; been simplified. As a result, the inner loop's exit test will not be
     45 ; rewritten.
     46 define void @expandOuterRecurrence(i32 %arg) nounwind {
     47 entry:
     48   %sub1 = sub nsw i32 %arg, 1
     49   %cmp1 = icmp slt i32 0, %sub1
     50   br i1 %cmp1, label %outer, label %exit
     51 
     52 outer:
     53   %i = phi i32 [ 0, %entry ], [ %i.inc, %outer.inc ]
     54   %sub2 = sub nsw i32 %arg, %i
     55   %sub3 = sub nsw i32 %sub2, 1
     56   %cmp2 = icmp slt i32 0, %sub3
     57   br i1 %cmp2, label %inner.ph, label %outer.inc
     58 
     59 inner.ph:
     60   br label %inner
     61 
     62 ; CHECK: inner:
     63 ; CHECK: icmp slt
     64 ; CHECK: br i1
     65 inner:
     66   %j = phi i32 [ 0, %inner.ph ], [ %j.inc, %inner ]
     67   %j.inc = add nsw i32 %j, 1
     68   %cmp3 = icmp slt i32 %j.inc, %sub3
     69   br i1 %cmp3, label %inner, label %outer.inc
     70 
     71 ; CHECK: outer.inc:
     72 ; CHECK: icmp ne
     73 ; CHECK: br i1
     74 outer.inc:
     75   %i.inc = add nsw i32 %i, 1
     76   %cmp4 = icmp slt i32 %i.inc, %sub1
     77   br i1 %cmp4, label %outer, label %exit
     78 
     79 exit:
     80   ret void
     81 }
     82 
     83 ; Force SCEVExpander to look for an existing well-formed phi.
     84 ; Perform LFTR without generating extra preheader code.
     85 define void @guardedloop([0 x double]* %matrix, [0 x double]* %vector,
     86                          i32 %irow, i32 %ilead) nounwind {
     87 ; CHECK: entry:
     88 ; CHECK-NOT: zext
     89 ; CHECK-NOT: add
     90 ; CHECK: loop:
     91 ; CHECK: phi i64
     92 ; CHECK: phi i64
     93 ; CHECK-NOT: phi
     94 ; CHECK: icmp ne
     95 ; CHECK: br i1
     96 entry:
     97   %cmp = icmp slt i32 1, %irow
     98   br i1 %cmp, label %loop, label %return
     99 
    100 loop:
    101   %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
    102   %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
    103   %diagidx = add nsw i32 %rowidx, %i
    104   %diagidxw = sext i32 %diagidx to i64
    105   %matrixp = getelementptr inbounds [0 x double]* %matrix, i32 0, i64 %diagidxw
    106   %v1 = load double* %matrixp
    107   %iw = sext i32 %i to i64
    108   %vectorp = getelementptr inbounds [0 x double]* %vector, i32 0, i64 %iw
    109   %v2 = load double* %vectorp
    110   %row.inc = add nsw i32 %rowidx, %ilead
    111   %i.inc = add nsw i32 %i, 1
    112   %cmp196 = icmp slt i32 %i.inc, %irow
    113   br i1 %cmp196, label %loop, label %return
    114 
    115 return:
    116   ret void
    117 }
    118 
    119 ; Avoid generating extra code to materialize a trip count. Skip LFTR.
    120 define void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector,
    121                            i32 %irow, i32 %ilead) nounwind {
    122 entry:
    123   br label %loop
    124 
    125 ; CHECK: entry:
    126 ; CHECK-NOT: zext
    127 ; CHECK-NOT: add
    128 ; CHECK: loop:
    129 ; CHECK: phi i64
    130 ; CHECK: phi i64
    131 ; CHECK-NOT: phi
    132 ; CHECK: icmp slt
    133 ; CHECK: br i1
    134 loop:
    135   %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
    136   %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
    137   %diagidx = add nsw i32 %rowidx, %i
    138   %diagidxw = sext i32 %diagidx to i64
    139   %matrixp = getelementptr inbounds [0 x double]* %matrix, i32 0, i64 %diagidxw
    140   %v1 = load double* %matrixp
    141   %iw = sext i32 %i to i64
    142   %vectorp = getelementptr inbounds [0 x double]* %vector, i32 0, i64 %iw
    143   %v2 = load double* %vectorp
    144   %row.inc = add nsw i32 %rowidx, %ilead
    145   %i.inc = add nsw i32 %i, 1
    146   %cmp196 = icmp slt i32 %i.inc, %irow
    147   br i1 %cmp196, label %loop, label %return
    148 
    149 return:
    150   ret void
    151 }
    152 
    153 ; Remove %i which is only used by the exit test.
    154 ; Verify that SCEV can still compute a backedge count from the sign
    155 ; extended %n, used for pointer comparison by LFTR.
    156 define void @geplftr(i8* %base, i32 %x, i32 %y, i32 %n) nounwind {
    157 entry:
    158   %x.ext = sext i32 %x to i64
    159   %add.ptr = getelementptr inbounds i8* %base, i64 %x.ext
    160   %y.ext = sext i32 %y to i64
    161   %add.ptr10 = getelementptr inbounds i8* %add.ptr, i64 %y.ext
    162   %lim = add i32 %x, %n
    163   %cmp.ph = icmp ult i32 %x, %lim
    164   br i1 %cmp.ph, label %loop, label %exit
    165 
    166 ; CHECK: loop:
    167 ; CHECK: phi i8*
    168 ; CHECK-NOT: phi
    169 ; CHECK: getelementptr
    170 ; CHECK: store
    171 ; CHECK: icmp ne i8*
    172 ; CHECK: br i1
    173 loop:
    174   %i = phi i32 [ %x, %entry ], [ %inc, %loop ]
    175   %aptr = phi i8* [ %add.ptr10, %entry ], [ %incdec.ptr, %loop ]
    176   %incdec.ptr = getelementptr inbounds i8* %aptr, i32 1
    177   store i8 3, i8* %aptr
    178   %inc = add i32 %i, 1
    179   %cmp = icmp ult i32 %inc, %lim
    180   br i1 %cmp, label %loop, label %exit
    181 
    182 exit:
    183   ret void
    184 }
    185 
    186 ; Exercise backedge taken count verification with a never-taken loop.
    187 define void @nevertaken() nounwind uwtable ssp {
    188 entry:
    189   br label %loop
    190 
    191 ; CHECK: loop:
    192 ; CHECK-NOT: phi
    193 ; CHECK-NOT: add
    194 ; CHECK-NOT: icmp
    195 ; CHECK: exit:
    196 loop:
    197   %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
    198   %inc = add nsw i32 %i, 1
    199   %cmp = icmp sle i32 %inc, 0
    200   br i1 %cmp, label %loop, label %exit
    201 
    202 exit:
    203   ret void
    204 }
    205 
    206 ; Test LFTR on an IV whose recurrence start is a non-unit pointer type.
    207 define void @aryptriv([256 x i8]* %base, i32 %n) nounwind {
    208 entry:
    209   %ivstart = getelementptr inbounds [256 x i8]* %base, i32 0, i32 0
    210   %ivend = getelementptr inbounds [256 x i8]* %base, i32 0, i32 %n
    211   %cmp.ph = icmp ult i8* %ivstart, %ivend
    212   br i1 %cmp.ph, label %loop, label %exit
    213 
    214 ; CHECK: loop:
    215 ; CHECK: phi i8*
    216 ; CHECK-NOT: phi
    217 ; CHECK: getelementptr
    218 ; CHECK: store
    219 ; CHECK: icmp ne i8*
    220 ; CHECK: br i1
    221 loop:
    222   %aptr = phi i8* [ %ivstart, %entry ], [ %incdec.ptr, %loop ]
    223   %incdec.ptr = getelementptr inbounds i8* %aptr, i32 1
    224   store i8 3, i8* %aptr
    225   %cmp = icmp ult i8* %incdec.ptr, %ivend
    226   br i1 %cmp, label %loop, label %exit
    227 
    228 exit:
    229   ret void
    230 }
    231