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