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