blob: 6b40cde3e57534dbfd4a0cef473fe53e4c416bbf [file] [log] [blame]
Artur Pilipenko8fb3d572017-01-25 16:00:44 +00001; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
2; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
3
4declare void @llvm.experimental.guard(i1, ...)
5
6define i32 @signed_loop_0_to_n_nested_0_to_l_inner_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
7; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_inner_index_check
8entry:
9 %tmp5 = icmp sle i32 %n, 0
10 br i1 %tmp5, label %exit, label %outer.loop.preheader
11
12outer.loop.preheader:
13; CHECK: outer.loop.preheader:
14; CHECK: [[iteration_count:[^ ]+]] = add i32 %l, -1
15 br label %outer.loop
16
17outer.loop:
18 %outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
19 %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
20 %tmp6 = icmp sle i32 %l, 0
21 br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
22
23inner.loop.preheader:
24; CHECK: inner.loop.preheader:
25; CHECK: [[wide_cond:[^ ]+]] = icmp slt i32 [[iteration_count]], %length
26 br label %inner.loop
27
28inner.loop:
29; CHECK: inner.loop:
30; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
31 %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
32 %j = phi i32 [ %j.next, %inner.loop ], [ 0, %inner.loop.preheader ]
33
34 %within.bounds = icmp slt i32 %j, %length
35 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
36
37 %j.i64 = zext i32 %j to i64
38 %array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
39 %array.j = load i32, i32* %array.j.ptr, align 4
40 %inner.loop.acc.next = add i32 %inner.loop.acc, %array.j
41
42 %j.next = add nsw i32 %j, 1
43 %inner.continue = icmp slt i32 %j.next, %l
44 br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
45
46outer.loop.inc:
47 %outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
48 %i.next = add nsw i32 %i, 1
49 %outer.continue = icmp slt i32 %i.next, %n
50 br i1 %outer.continue, label %outer.loop, label %exit
51
52exit:
53 %result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
54 ret i32 %result
55}
56
57define i32 @signed_loop_0_to_n_nested_0_to_l_outer_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
58; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_outer_index_check
59entry:
60 %tmp5 = icmp sle i32 %n, 0
61 br i1 %tmp5, label %exit, label %outer.loop.preheader
62
63outer.loop.preheader:
64; CHECK: outer.loop.preheader:
65; CHECK: [[iteration_count:[^ ]+]] = add i32 %n, -1
66; CHECK: [[wide_cond:[^ ]+]] = icmp slt i32 [[iteration_count]], %length
67 br label %outer.loop
68
69outer.loop:
70 %outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
71 %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
72 %tmp6 = icmp sle i32 %l, 0
73 br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
74
75inner.loop.preheader:
76 br label %inner.loop
77
78inner.loop:
79; CHECK: inner.loop:
80; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
81
82 %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
83 %j = phi i32 [ %j.next, %inner.loop ], [ 0, %inner.loop.preheader ]
84
85 %within.bounds = icmp slt i32 %i, %length
86 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
87
88 %i.i64 = zext i32 %i to i64
89 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
90 %array.i = load i32, i32* %array.i.ptr, align 4
91 %inner.loop.acc.next = add i32 %inner.loop.acc, %array.i
92
93 %j.next = add nsw i32 %j, 1
94 %inner.continue = icmp slt i32 %j.next, %l
95 br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
96
97outer.loop.inc:
98 %outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
99 %i.next = add nsw i32 %i, 1
100 %outer.continue = icmp slt i32 %i.next, %n
101 br i1 %outer.continue, label %outer.loop, label %exit
102
103exit:
104 %result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
105 ret i32 %result
106}
107
108define i32 @signed_loop_0_to_n_nested_i_to_l_inner_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
109; CHECK-LABEL: @signed_loop_0_to_n_nested_i_to_l_inner_index_check
110entry:
111 %tmp5 = icmp sle i32 %n, 0
112 br i1 %tmp5, label %exit, label %outer.loop.preheader
113
114outer.loop.preheader:
115 br label %outer.loop
116
117outer.loop:
118; CHECK: outer.loop:
119; CHECK: [[i_1:[^ ]+]] = add i32 %i, 1
120; CHECK-NEXT: [[l_sgt_i_1:[^ ]+]] = icmp sgt i32 %l, [[i_1]]
121; CHECK-NEXT: [[smax:[^ ]+]] = select i1 [[l_sgt_i_1]], i32 %l, i32 [[i_1]]
122; CHECK-NEXT: [[max_j:[^ ]+]] = add i32 [[smax]], -1
123 %outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
124 %i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
125 %tmp6 = icmp sle i32 %l, 0
126 br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
127
128inner.loop.preheader:
129; CHECK: inner.loop.preheader:
130; CHECK: [[wide_cond:[^ ]+]] = icmp slt i32 [[max_j]], %length
131 br label %inner.loop
132
133inner.loop:
134; CHECK: inner.loop:
135; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
136 %inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
137 %j = phi i32 [ %j.next, %inner.loop ], [ %i, %inner.loop.preheader ]
138
139 %within.bounds = icmp slt i32 %j, %length
140 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
141
142 %j.i64 = zext i32 %j to i64
143 %array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
144 %array.j = load i32, i32* %array.j.ptr, align 4
145 %inner.loop.acc.next = add i32 %inner.loop.acc, %array.j
146
147 %j.next = add nsw i32 %j, 1
148 %inner.continue = icmp slt i32 %j.next, %l
149 br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
150
151outer.loop.inc:
152 %outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
153 %i.next = add nsw i32 %i, 1
154 %outer.continue = icmp slt i32 %i.next, %n
155 br i1 %outer.continue, label %outer.loop, label %exit
156
157exit:
158 %result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
159 ret i32 %result
160}