1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S < %s -indvars | FileCheck %s
3; RUN: opt -S < %s -passes=indvars | FileCheck %s
4
5declare i1 @cond()
6declare void @exit(i32 %code)
7
8define void @test_01(i32* %p, i32 %shift) {
9; CHECK-LABEL: @test_01(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range [[RNG0:![0-9]+]]
12; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X]], [[SHIFT:%.*]]
13; CHECK-NEXT:    br label [[LOOP:%.*]]
14; CHECK:       loop:
15; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
16; CHECK-NEXT:    [[LESS_THAN_SHIFTED:%.*]] = icmp slt i32 [[IV]], [[X_SHIFTED]]
17; CHECK-NEXT:    br i1 [[LESS_THAN_SHIFTED]], label [[GUARDED:%.*]], label [[FAILURE:%.*]]
18; CHECK:       guarded:
19; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[NEVER_HAPPENS:%.*]]
20; CHECK:       backedge:
21; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
22; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
23; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
24; CHECK:       done:
25; CHECK-NEXT:    ret void
26; CHECK:       failure:
27; CHECK-NEXT:    call void @exit(i32 1)
28; CHECK-NEXT:    unreachable
29; CHECK:       never_happens:
30; CHECK-NEXT:    call void @exit(i32 0)
31; CHECK-NEXT:    unreachable
32;
33entry:
34  %x = load i32, i32* %p, !range !0
35  %x.shifted = lshr i32 %x, %shift
36  br label %loop
37
38loop:
39  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
40  %less.than.shifted = icmp slt i32 %iv, %x.shifted
41  br i1 %less.than.shifted, label %guarded, label %failure
42
43guarded:
44  %less.than.x = icmp slt i32 %iv, %x
45  br i1 %less.than.x, label %backedge, label %never_happens
46
47backedge:
48  %iv.next = add nuw nsw i32 %iv, 1
49  %loop.cond = call i1 @cond()
50  br i1 %loop.cond, label %loop, label %done
51
52done:
53  ret void
54
55failure:
56  call void @exit(i32 1)
57  unreachable
58
59never_happens:
60  call void @exit(i32 0)
61  unreachable
62}
63
64define void @test_02(i32* %p, i32 %shift) {
65; CHECK-LABEL: @test_02(
66; CHECK-NEXT:  entry:
67; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range [[RNG0]]
68; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X]], [[SHIFT:%.*]]
69; CHECK-NEXT:    br label [[LOOP:%.*]]
70; CHECK:       loop:
71; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
72; CHECK-NEXT:    [[LESS_THAN_SHIFTED:%.*]] = icmp sgt i32 [[X_SHIFTED]], [[IV]]
73; CHECK-NEXT:    br i1 [[LESS_THAN_SHIFTED]], label [[GUARDED:%.*]], label [[FAILURE:%.*]]
74; CHECK:       guarded:
75; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[NEVER_HAPPENS:%.*]]
76; CHECK:       backedge:
77; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
78; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
79; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
80; CHECK:       done:
81; CHECK-NEXT:    ret void
82; CHECK:       failure:
83; CHECK-NEXT:    call void @exit(i32 1)
84; CHECK-NEXT:    unreachable
85; CHECK:       never_happens:
86; CHECK-NEXT:    call void @exit(i32 0)
87; CHECK-NEXT:    unreachable
88;
89entry:
90  %x = load i32, i32* %p, !range !0
91  %x.shifted = lshr i32 %x, %shift
92  br label %loop
93
94loop:
95  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
96  %less.than.shifted = icmp sgt i32 %x.shifted, %iv
97  br i1 %less.than.shifted, label %guarded, label %failure
98
99guarded:
100  %less.than.x = icmp sgt i32 %x, %iv
101  br i1 %less.than.x, label %backedge, label %never_happens
102
103backedge:
104  %iv.next = add nuw nsw i32 %iv, 1
105  %loop.cond = call i1 @cond()
106  br i1 %loop.cond, label %loop, label %done
107
108done:
109  ret void
110
111failure:
112  call void @exit(i32 1)
113  unreachable
114
115never_happens:
116  call void @exit(i32 0)
117  unreachable
118}
119
120define void @test_03(i32* %p, i32 %shift) {
121; CHECK-LABEL: @test_03(
122; CHECK-NEXT:  entry:
123; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range [[RNG0]]
124; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X]], [[SHIFT:%.*]]
125; CHECK-NEXT:    br label [[LOOP:%.*]]
126; CHECK:       loop:
127; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
128; CHECK-NEXT:    [[LESS_THAN_SHIFTED:%.*]] = icmp ult i32 [[IV]], [[X_SHIFTED]]
129; CHECK-NEXT:    br i1 [[LESS_THAN_SHIFTED]], label [[GUARDED:%.*]], label [[FAILURE:%.*]]
130; CHECK:       guarded:
131; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[NEVER_HAPPENS:%.*]]
132; CHECK:       backedge:
133; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
134; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
135; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
136; CHECK:       done:
137; CHECK-NEXT:    ret void
138; CHECK:       failure:
139; CHECK-NEXT:    call void @exit(i32 1)
140; CHECK-NEXT:    unreachable
141; CHECK:       never_happens:
142; CHECK-NEXT:    call void @exit(i32 0)
143; CHECK-NEXT:    unreachable
144;
145entry:
146  %x = load i32, i32* %p, !range !0
147  %x.shifted = lshr i32 %x, %shift
148  br label %loop
149
150loop:
151  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
152  %less.than.shifted = icmp ult i32 %iv, %x.shifted
153  br i1 %less.than.shifted, label %guarded, label %failure
154
155guarded:
156  %less.than.x = icmp ult i32 %iv, %x
157  br i1 %less.than.x, label %backedge, label %never_happens
158
159backedge:
160  %iv.next = add nuw nsw i32 %iv, 1
161  %loop.cond = call i1 @cond()
162  br i1 %loop.cond, label %loop, label %done
163
164done:
165  ret void
166
167failure:
168  call void @exit(i32 1)
169  unreachable
170
171never_happens:
172  call void @exit(i32 0)
173  unreachable
174}
175
176define void @test_04(i32* %p, i32 %shift) {
177; CHECK-LABEL: @test_04(
178; CHECK-NEXT:  entry:
179; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range [[RNG0]]
180; CHECK-NEXT:    [[X_SHIFTED:%.*]] = lshr i32 [[X]], [[SHIFT:%.*]]
181; CHECK-NEXT:    br label [[LOOP:%.*]]
182; CHECK:       loop:
183; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
184; CHECK-NEXT:    [[LESS_THAN_SHIFTED:%.*]] = icmp ugt i32 [[X_SHIFTED]], [[IV]]
185; CHECK-NEXT:    br i1 [[LESS_THAN_SHIFTED]], label [[GUARDED:%.*]], label [[FAILURE:%.*]]
186; CHECK:       guarded:
187; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[NEVER_HAPPENS:%.*]]
188; CHECK:       backedge:
189; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
190; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
191; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
192; CHECK:       done:
193; CHECK-NEXT:    ret void
194; CHECK:       failure:
195; CHECK-NEXT:    call void @exit(i32 1)
196; CHECK-NEXT:    unreachable
197; CHECK:       never_happens:
198; CHECK-NEXT:    call void @exit(i32 0)
199; CHECK-NEXT:    unreachable
200;
201entry:
202  %x = load i32, i32* %p, !range !0
203  %x.shifted = lshr i32 %x, %shift
204  br label %loop
205
206loop:
207  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
208  %less.than.shifted = icmp ugt i32 %x.shifted, %iv
209  br i1 %less.than.shifted, label %guarded, label %failure
210
211guarded:
212  %less.than.x = icmp ugt i32 %x, %iv
213  br i1 %less.than.x, label %backedge, label %never_happens
214
215backedge:
216  %iv.next = add nuw nsw i32 %iv, 1
217  %loop.cond = call i1 @cond()
218  br i1 %loop.cond, label %loop, label %done
219
220done:
221  ret void
222
223failure:
224  call void @exit(i32 1)
225  unreachable
226
227never_happens:
228  call void @exit(i32 0)
229  unreachable
230}
231
232!0 = !{i32 0, i32 2147483647}
233