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
6 declare void @exit(i32 %code)
8 ; FIXME: We can remove 2nd check here because it is implied by check
9 ; against the shifted value.
10 define void @test_01(i32* %p, i32 %shift) {
11 ; CHECK-LABEL: @test_01(
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:%.*]]
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:%.*]]
21 ; CHECK-NEXT: [[LESS_THAN_X:%.*]] = icmp ult i32 [[IV]], [[X]]
22 ; CHECK-NEXT: br i1 [[LESS_THAN_X]], label [[BACKEDGE]], label [[NEVER_HAPPENS:%.*]]
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:%.*]]
28 ; CHECK-NEXT: ret void
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
37 %x = load i32, i32* %p, !range !0
38 %x.shifted = lshr i32 %x, %shift
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
47 %less.than.x = icmp slt i32 %iv, %x
48 br i1 %less.than.x, label %backedge, label %never_happens
51 %iv.next = add nuw nsw i32 %iv, 1
52 %loop.cond = call i1 @cond()
53 br i1 %loop.cond, label %loop, label %done
59 call void @exit(i32 1)
63 call void @exit(i32 0)
67 ; FIXME: We can remove 2nd check here because it is implied by check
68 ; against the shifted value.
69 define void @test_02(i32* %p, i32 %shift) {
70 ; CHECK-LABEL: @test_02(
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:%.*]]
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:%.*]]
80 ; CHECK-NEXT: [[LESS_THAN_X:%.*]] = icmp ugt i32 [[X]], [[IV]]
81 ; CHECK-NEXT: br i1 [[LESS_THAN_X]], label [[BACKEDGE]], label [[NEVER_HAPPENS:%.*]]
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:%.*]]
87 ; CHECK-NEXT: ret void
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
96 %x = load i32, i32* %p, !range !0
97 %x.shifted = lshr i32 %x, %shift
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
106 %less.than.x = icmp sgt i32 %x, %iv
107 br i1 %less.than.x, label %backedge, label %never_happens
110 %iv.next = add nuw nsw i32 %iv, 1
111 %loop.cond = call i1 @cond()
112 br i1 %loop.cond, label %loop, label %done
118 call void @exit(i32 1)
122 call void @exit(i32 0)
126 ; FIXME: We can remove 2nd check here because it is implied by check
127 ; against the shifted value.
128 define void @test_03(i32* %p, i32 %shift) {
129 ; CHECK-LABEL: @test_03(
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:%.*]]
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:%.*]]
139 ; CHECK-NEXT: [[LESS_THAN_X:%.*]] = icmp ult i32 [[IV]], [[X]]
140 ; CHECK-NEXT: br i1 [[LESS_THAN_X]], label [[BACKEDGE]], label [[NEVER_HAPPENS:%.*]]
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:%.*]]
146 ; CHECK-NEXT: ret void
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
155 %x = load i32, i32* %p, !range !0
156 %x.shifted = lshr i32 %x, %shift
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
165 %less.than.x = icmp ult i32 %iv, %x
166 br i1 %less.than.x, label %backedge, label %never_happens
169 %iv.next = add nuw nsw i32 %iv, 1
170 %loop.cond = call i1 @cond()
171 br i1 %loop.cond, label %loop, label %done
177 call void @exit(i32 1)
181 call void @exit(i32 0)
185 ; FIXME: We can remove 2nd check here because it is implied by check
186 ; against the shifted value.
187 define void @test_04(i32* %p, i32 %shift) {
188 ; CHECK-LABEL: @test_04(
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:%.*]]
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:%.*]]
198 ; CHECK-NEXT: [[LESS_THAN_X:%.*]] = icmp ugt i32 [[X]], [[IV]]
199 ; CHECK-NEXT: br i1 [[LESS_THAN_X]], label [[BACKEDGE]], label [[NEVER_HAPPENS:%.*]]
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:%.*]]
205 ; CHECK-NEXT: ret void
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
214 %x = load i32, i32* %p, !range !0
215 %x.shifted = lshr i32 %x, %shift
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
224 %less.than.x = icmp ugt i32 %x, %iv
225 br i1 %less.than.x, label %backedge, label %never_happens
228 %iv.next = add nuw nsw i32 %iv, 1
229 %loop.cond = call i1 @cond()
230 br i1 %loop.cond, label %loop, label %done
236 call void @exit(i32 1)
240 call void @exit(i32 0)
244 !0 = !{i32 0, i32 2147483647}