Home | History | Annotate | Download | only in IndVarSimplify
      1 ;; RUN: opt -S < %s -indvars | FileCheck %s
      2 ; RUN: opt -lcssa -loop-simplify -S < %s | opt -S -passes='require<targetir>,require<scalar-evolution>,require<domtree>,loop(indvars)'
      3 
      4 ;; Check if llvm can narrow !range metadata based on loop entry
      5 ;; predicates.
      6 
      7 declare void @abort()
      8 
      9 define i1 @bounded_below_slt(i32* nocapture readonly %buffer) {
     10 ; CHECK-LABEL: bounded_below_slt
     11 entry:
     12   %length = load i32, i32* %buffer, !range !0
     13   %entry.pred = icmp eq i32 %length, 0
     14   br i1 %entry.pred, label %abort, label %loop.preheader
     15 
     16 loop.preheader:
     17   br label %loop
     18 
     19 loop:
     20 ; CHECK: loop
     21   %idx = phi i32 [ %idx.inc, %loop.next ], [ 0, %loop.preheader ]
     22   %oob.pred = icmp slt i32 %idx, %length
     23   br i1 %oob.pred, label %loop.next, label %oob
     24 ; CHECK: br i1 true, label %loop.next, label %oob
     25 
     26 loop.next:
     27 ; CHECK: loop.next
     28   %idx.inc = add i32 %idx, 1
     29   %exit.pred = icmp slt i32 %idx.inc, %length
     30   br i1 %exit.pred, label %loop, label %abort.loopexit
     31 
     32 abort.loopexit:
     33   br label %abort
     34 
     35 abort:
     36   ret i1 false
     37 
     38 oob:
     39   tail call void @abort()
     40   ret i1 false
     41 }
     42 
     43 define i1 @bounded_below_sle(i32* nocapture readonly %buffer) {
     44 ; CHECK-LABEL: bounded_below_sle
     45 entry:
     46   %length = load i32, i32* %buffer, !range !0
     47   %entry.pred = icmp eq i32 %length, 0
     48   br i1 %entry.pred, label %abort, label %loop.preheader
     49 
     50 loop.preheader:
     51   br label %loop
     52 
     53 loop:
     54 ; CHECK: loop
     55   %idx = phi i32 [ %idx.inc, %loop.next ], [ 0, %loop.preheader ]
     56   %oob.pred = icmp sle i32 %idx, %length
     57   br i1 %oob.pred, label %loop.next, label %oob
     58 ; CHECK: br i1 true, label %loop.next, label %oob
     59 
     60 loop.next:
     61 ; CHECK: loop.next
     62   %idx.inc = add i32 %idx, 1
     63   %exit.pred = icmp sle i32 %idx.inc, %length
     64   br i1 %exit.pred, label %loop, label %abort.loopexit
     65 
     66 abort.loopexit:
     67   br label %abort
     68 
     69 abort:
     70   ret i1 false
     71 
     72 oob:
     73   tail call void @abort()
     74   ret i1 false
     75 }
     76 
     77 ;; Assert that we're not making an incorrect transform.
     78 
     79 declare i32 @check(i8*)
     80 
     81 define void @NoChange() {
     82 ; CHECK-LABEL: NoChange
     83 entry:
     84   br label %loop.begin
     85 
     86 loop.begin:
     87 ; CHECK: loop.begin:
     88   %i.01 = phi i64 [ 2, %entry ], [ %add, %loop.end ]
     89   %cmp = icmp ugt i64 %i.01, 1
     90 ; CHECK: %cmp = icmp ugt i64 %i.01, 1
     91   br i1 %cmp, label %loop, label %loop.end
     92 
     93 loop:
     94 ; CHECK: loop
     95   %.sum = add i64 %i.01, -2
     96   %v = getelementptr inbounds i8, i8* null, i64 %.sum
     97   %r = tail call i32 @check(i8* %v)
     98   %c = icmp eq i32 %r, 0
     99   br i1 %c, label %loop.end, label %abort.now
    100 
    101 abort.now:
    102   tail call void @abort()
    103   unreachable
    104 
    105 loop.end:
    106   %add = add i64 %i.01, -1
    107   %eq = icmp eq i64 %add, 0
    108   br i1 %eq, label %exit, label %loop.begin
    109 
    110 exit:
    111   ret void
    112 }
    113 
    114 !0 = !{i32 0, i32 100}
    115