Teach ScalarEvolution to sharpen range information.
[oota-llvm.git] / test / Transforms / IndVarSimplify / sharpen-range.ll
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* %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* %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* 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 = metadata !{i32 0, i32 100}