1;; RUN: opt -S < %s -indvars | FileCheck %s
2
3;; Check if llvm can narrow !range metadata based on loop entry
4;; predicates.
5
6declare void @abort()
7
8define i1 @bounded_below_slt(i32* nocapture readonly %buffer) {
9; CHECK-LABEL: bounded_below_slt
10entry:
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
15loop.preheader:
16  br label %loop
17
18loop:
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
25loop.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
31abort.loopexit:
32  br label %abort
33
34abort:
35  ret i1 false
36
37oob:
38  tail call void @abort()
39  ret i1 false
40}
41
42define i1 @bounded_below_sle(i32* nocapture readonly %buffer) {
43; CHECK-LABEL: bounded_below_sle
44entry:
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
49loop.preheader:
50  br label %loop
51
52loop:
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
59loop.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
65abort.loopexit:
66  br label %abort
67
68abort:
69  ret i1 false
70
71oob:
72  tail call void @abort()
73  ret i1 false
74}
75
76;; Assert that we're not making an incorrect transform.
77
78declare i32 @check(i8*)
79
80define void @NoChange() {
81; CHECK-LABEL: NoChange
82entry:
83  br label %loop.begin
84
85loop.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
92loop:
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
100abort.now:
101  tail call void @abort()
102  unreachable
103
104loop.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
109exit:
110  ret void
111}
112
113!0 = !{i32 0, i32 100}
114