Home | History | Annotate | Download | only in IndVarSimplify
      1 ; RUN: opt < %s -indvars -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, 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, 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 ; This test checks that SCEVExpander can handle an outer loop that has been
     42 ; simplified, and as a result the inner loop's exit test will be rewritten.
     43 define void @expandOuterRecurrence(i32 %arg) nounwind {
     44 entry:
     45   %sub1 = sub nsw i32 %arg, 1
     46   %cmp1 = icmp slt i32 0, %sub1
     47   br i1 %cmp1, label %outer, label %exit
     48 
     49 ; CHECK: outer:
     50 ; CHECK: icmp slt
     51 outer:
     52   %i = phi i32 [ 0, %entry ], [ %i.inc, %outer.inc ]
     53   %sub2 = sub nsw i32 %arg, %i
     54   %sub3 = sub nsw i32 %sub2, 1
     55   %cmp2 = icmp slt i32 0, %sub3
     56   br i1 %cmp2, label %inner.ph, label %outer.inc
     57 
     58 inner.ph:
     59   br label %inner
     60 
     61 ; CHECK: inner:
     62 ; CHECK: br i1
     63 inner:
     64   %j = phi i32 [ 0, %inner.ph ], [ %j.inc, %inner ]
     65   %j.inc = add nsw i32 %j, 1
     66   %cmp3 = icmp slt i32 %j.inc, %sub3
     67   br i1 %cmp3, label %inner, label %outer.inc
     68 
     69 ; CHECK: outer.inc:
     70 ; CHECK: icmp ne
     71 ; CHECK: br i1
     72 outer.inc:
     73   %i.inc = add nsw i32 %i, 1
     74   %cmp4 = icmp slt i32 %i.inc, %sub1
     75   br i1 %cmp4, label %outer, label %exit
     76 
     77 exit:
     78   ret void
     79 }
     80 
     81 ; Force SCEVExpander to look for an existing well-formed phi.
     82 ; Perform LFTR without generating extra preheader code.
     83 define void @guardedloop([0 x double]* %matrix, [0 x double]* %vector,
     84                          i32 %irow, i32 %ilead) nounwind {
     85 ; CHECK: entry:
     86 ; CHECK-NOT: zext
     87 ; CHECK-NOT: add
     88 ; CHECK: loop:
     89 ; CHECK: phi i64
     90 ; CHECK: phi i64
     91 ; CHECK-NOT: phi
     92 ; CHECK: icmp ne
     93 ; CHECK: br i1
     94 entry:
     95   %cmp = icmp slt i32 1, %irow
     96   br i1 %cmp, label %loop, label %return
     97 
     98 loop:
     99   %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
    100   %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
    101   %diagidx = add nsw i32 %rowidx, %i
    102   %diagidxw = sext i32 %diagidx to i64
    103   %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw
    104   %v1 = load double, double* %matrixp
    105   %iw = sext i32 %i to i64
    106   %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw
    107   %v2 = load double, double* %vectorp
    108   %row.inc = add nsw i32 %rowidx, %ilead
    109   %i.inc = add nsw i32 %i, 1
    110   %cmp196 = icmp slt i32 %i.inc, %irow
    111   br i1 %cmp196, label %loop, label %return
    112 
    113 return:
    114   ret void
    115 }
    116 
    117 ; Avoid generating extra code to materialize a trip count. Skip LFTR.
    118 define void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector,
    119                            i32 %irow, i32 %ilead) nounwind {
    120 entry:
    121   br label %loop
    122 
    123 ; CHECK: entry:
    124 ; CHECK-NOT: zext
    125 ; CHECK-NOT: add
    126 ; CHECK: loop:
    127 ; CHECK: phi i64
    128 ; CHECK: phi i64
    129 ; CHECK-NOT: phi
    130 ; CHECK: icmp slt
    131 ; CHECK: br i1
    132 loop:
    133   %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
    134   %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
    135   %diagidx = add nsw i32 %rowidx, %i
    136   %diagidxw = sext i32 %diagidx to i64
    137   %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw
    138   %v1 = load double, double* %matrixp
    139   %iw = sext i32 %i to i64
    140   %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw
    141   %v2 = load double, double* %vectorp
    142   %row.inc = add nsw i32 %rowidx, %ilead
    143   %i.inc = add nsw i32 %i, 1
    144   %cmp196 = icmp slt i32 %i.inc, %irow
    145   br i1 %cmp196, label %loop, label %return
    146 
    147 return:
    148   ret void
    149 }
    150 
    151 ; Remove %i which is only used by the exit test.
    152 ; Verify that SCEV can still compute a backedge count from the sign
    153 ; extended %n, used for pointer comparison by LFTR.
    154 ;
    155 ; TODO: Fix for PR13371 currently makes this impossible. See
    156 ; IndVarSimplify.cpp hasConcreteDef(). We may want to change to undef rules.
    157 define void @geplftr(i8* %base, i32 %x, i32 %y, i32 %n) nounwind {
    158 entry:
    159   %x.ext = sext i32 %x to i64
    160   %add.ptr = getelementptr inbounds i8, i8* %base, i64 %x.ext
    161   %y.ext = sext i32 %y to i64
    162   %add.ptr10 = getelementptr inbounds i8, i8* %add.ptr, i64 %y.ext
    163   %lim = add i32 %x, %n
    164   %cmp.ph = icmp ult i32 %x, %lim
    165   br i1 %cmp.ph, label %loop, label %exit
    166 ; CHECK-LABEL: @geplftr(
    167 ; CHECK: loop:
    168 ; CHECK: phi i8*
    169 ; DISABLE-NOT: phi      // This check is currently disabled
    170 ; CHECK: getelementptr
    171 ; CHECK: store
    172 ; DISABLE: icmp ne i8*  // This check is currently disabled
    173 ; CHECK: br i1
    174 loop:
    175   %i = phi i32 [ %x, %entry ], [ %inc, %loop ]
    176   %aptr = phi i8* [ %add.ptr10, %entry ], [ %incdec.ptr, %loop ]
    177   %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1
    178   store i8 3, i8* %aptr
    179   %inc = add i32 %i, 1
    180   %cmp = icmp ult i32 %inc, %lim
    181   br i1 %cmp, label %loop, label %exit
    182 
    183 exit:
    184   ret void
    185 }
    186 
    187 ; Exercise backedge taken count verification with a never-taken loop.
    188 define void @nevertaken() nounwind uwtable ssp {
    189 entry:
    190   br label %loop
    191 ; CHECK-LABEL: @nevertaken(
    192 ; CHECK: loop:
    193 ; CHECK-NOT: phi
    194 ; CHECK-NOT: add
    195 ; CHECK-NOT: icmp
    196 ; CHECK: exit:
    197 loop:
    198   %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
    199   %inc = add nsw i32 %i, 1
    200   %cmp = icmp sle i32 %inc, 0
    201   br i1 %cmp, label %loop, label %exit
    202 
    203 exit:
    204   ret void
    205 }
    206 
    207 ; Test LFTR on an IV whose recurrence start is a non-unit pointer type.
    208 define void @aryptriv([256 x i8]* %base, i32 %n) nounwind {
    209 entry:
    210   %ivstart = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 0
    211   %ivend = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 %n
    212   %cmp.ph = icmp ult i8* %ivstart, %ivend
    213   br i1 %cmp.ph, label %loop, label %exit
    214 
    215 ; CHECK: loop:
    216 ; CHECK: phi i8*
    217 ; CHECK-NOT: phi
    218 ; CHECK: getelementptr
    219 ; CHECK: store
    220 ; CHECK: icmp ne i8*
    221 ; CHECK: br i1
    222 loop:
    223   %aptr = phi i8* [ %ivstart, %entry ], [ %incdec.ptr, %loop ]
    224   %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1
    225   store i8 3, i8* %aptr
    226   %cmp = icmp ult i8* %incdec.ptr, %ivend
    227   br i1 %cmp, label %loop, label %exit
    228 
    229 exit:
    230   ret void
    231 }
    232