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