1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
4 declare void @llvm.assume(i1)
5 declare i8 @llvm.umin(i8, i8)
6 declare i8 @llvm.umax(i8, i8)
7 declare i8 @llvm.smin(i8, i8)
8 declare i8 @llvm.smax(i8, i8)
10 ; If we don't know anything about the arguments, we can't do anything.
12 define i8 @test0(i8 %x, i8 %y) {
13 ; CHECK-LABEL: @test0(
14 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
15 ; CHECK-NEXT: ret i8 [[R]]
17 %r = call i8 @llvm.umin(i8 %x, i8 %y)
20 define i8 @test1(i8 %x, i8 %y) {
21 ; CHECK-LABEL: @test1(
22 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
23 ; CHECK-NEXT: ret i8 [[R]]
25 %r = call i8 @llvm.umax(i8 %x, i8 %y)
28 define i8 @test2(i8 %x, i8 %y) {
29 ; CHECK-LABEL: @test2(
30 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
31 ; CHECK-NEXT: ret i8 [[R]]
33 %r = call i8 @llvm.smin(i8 %x, i8 %y)
36 define i8 @test3(i8 %x, i8 %y) {
37 ; CHECK-LABEL: @test3(
38 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
39 ; CHECK-NEXT: ret i8 [[R]]
41 %r = call i8 @llvm.smax(i8 %x, i8 %y)
45 ; However, if we do know the ranges of arguments, we sometimes can tell that either one is always picked.
47 define i8 @test4(i8 %x) {
48 ; CHECK-LABEL: @test4(
49 ; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 43
50 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
51 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)
52 ; CHECK-NEXT: ret i8 [[R]]
54 %lim = icmp ule i8 %x, 43
55 call void @llvm.assume(i1 %lim)
56 %r = call i8 @llvm.umin(i8 %x, i8 42)
59 define i8 @test5(i8 %x) {
60 ; CHECK-LABEL: @test5(
61 ; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 42
62 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
63 ; CHECK-NEXT: ret i8 [[X]]
65 %lim = icmp ule i8 %x, 42
66 call void @llvm.assume(i1 %lim)
67 %r = call i8 @llvm.umin(i8 %x, i8 42)
70 define i8 @test6(i8 %x) {
71 ; CHECK-LABEL: @test6(
72 ; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 42
73 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
74 ; CHECK-NEXT: ret i8 42
76 %lim = icmp uge i8 %x, 42
77 call void @llvm.assume(i1 %lim)
78 %r = call i8 @llvm.umin(i8 %x, i8 42)
81 define i8 @test7(i8 %x) {
82 ; CHECK-LABEL: @test7(
83 ; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 41
84 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
85 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)
86 ; CHECK-NEXT: ret i8 [[R]]
88 %lim = icmp uge i8 %x, 41
89 call void @llvm.assume(i1 %lim)
90 %r = call i8 @llvm.umin(i8 %x, i8 42)
94 define i8 @test8(i8 %x) {
95 ; CHECK-LABEL: @test8(
96 ; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 41
97 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
98 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)
99 ; CHECK-NEXT: ret i8 [[R]]
101 %lim = icmp uge i8 %x, 41
102 call void @llvm.assume(i1 %lim)
103 %r = call i8 @llvm.umax(i8 %x, i8 42)
106 define i8 @test9(i8 %x) {
107 ; CHECK-LABEL: @test9(
108 ; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 42
109 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
110 ; CHECK-NEXT: ret i8 [[X]]
112 %lim = icmp uge i8 %x, 42
113 call void @llvm.assume(i1 %lim)
114 %r = call i8 @llvm.umax(i8 %x, i8 42)
117 define i8 @test10(i8 %x) {
118 ; CHECK-LABEL: @test10(
119 ; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 42
120 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
121 ; CHECK-NEXT: ret i8 42
123 %lim = icmp ule i8 %x, 42
124 call void @llvm.assume(i1 %lim)
125 %r = call i8 @llvm.umax(i8 %x, i8 42)
128 define i8 @test11(i8 %x) {
129 ; CHECK-LABEL: @test11(
130 ; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 43
131 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
132 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)
133 ; CHECK-NEXT: ret i8 [[R]]
135 %lim = icmp ule i8 %x, 43
136 call void @llvm.assume(i1 %lim)
137 %r = call i8 @llvm.umax(i8 %x, i8 42)
141 define i8 @test12(i8 %x) {
142 ; CHECK-LABEL: @test12(
143 ; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 43
144 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
145 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42)
146 ; CHECK-NEXT: ret i8 [[R]]
148 %lim = icmp sle i8 %x, 43
149 call void @llvm.assume(i1 %lim)
150 %r = call i8 @llvm.smin(i8 %x, i8 42)
153 define i8 @test13(i8 %x) {
154 ; CHECK-LABEL: @test13(
155 ; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 42
156 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
157 ; CHECK-NEXT: ret i8 [[X]]
159 %lim = icmp sle i8 %x, 42
160 call void @llvm.assume(i1 %lim)
161 %r = call i8 @llvm.smin(i8 %x, i8 42)
164 define i8 @test14(i8 %x) {
165 ; CHECK-LABEL: @test14(
166 ; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42
167 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
168 ; CHECK-NEXT: ret i8 42
170 %lim = icmp sge i8 %x, 42
171 call void @llvm.assume(i1 %lim)
172 %r = call i8 @llvm.smin(i8 %x, i8 42)
175 define i8 @test15(i8 %x) {
176 ; CHECK-LABEL: @test15(
177 ; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 41
178 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
179 ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)
180 ; CHECK-NEXT: ret i8 [[TMP1]]
182 %lim = icmp sge i8 %x, 41
183 call void @llvm.assume(i1 %lim)
184 %r = call i8 @llvm.smin(i8 %x, i8 42)
188 define i8 @test16(i8 %x) {
189 ; CHECK-LABEL: @test16(
190 ; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 41
191 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
192 ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)
193 ; CHECK-NEXT: ret i8 [[TMP1]]
195 %lim = icmp sge i8 %x, 41
196 call void @llvm.assume(i1 %lim)
197 %r = call i8 @llvm.smax(i8 %x, i8 42)
200 define i8 @test17(i8 %x) {
201 ; CHECK-LABEL: @test17(
202 ; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42
203 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
204 ; CHECK-NEXT: ret i8 [[X]]
206 %lim = icmp sge i8 %x, 42
207 call void @llvm.assume(i1 %lim)
208 %r = call i8 @llvm.smax(i8 %x, i8 42)
211 define i8 @test18(i8 %x) {
212 ; CHECK-LABEL: @test18(
213 ; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 42
214 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
215 ; CHECK-NEXT: ret i8 42
217 %lim = icmp sle i8 %x, 42
218 call void @llvm.assume(i1 %lim)
219 %r = call i8 @llvm.smax(i8 %x, i8 42)
222 define i8 @test19(i8 %x) {
223 ; CHECK-LABEL: @test19(
224 ; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 43
225 ; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
226 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 42)
227 ; CHECK-NEXT: ret i8 [[R]]
229 %lim = icmp sle i8 %x, 43
230 call void @llvm.assume(i1 %lim)
231 %r = call i8 @llvm.smax(i8 %x, i8 42)
235 declare void @body(i32)
237 define void @test_bidirectional() {
238 ; CHECK-LABEL: @test_bidirectional(
240 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
242 ; CHECK-NEXT: [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
243 ; CHECK-NEXT: call void @body(i32 65535)
244 ; CHECK-NEXT: [[INC]] = add nsw i32 [[INDVAR]], 1
245 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INDVAR]], 65535
246 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]
248 ; CHECK-NEXT: ret void
254 %indvar = phi i32 [ 0, %entry ], [ %inc, %for.body ]
255 %smax = call i32 @llvm.smax.i32(i32 %indvar, i32 65535)
256 call void @body(i32 %smax)
257 %inc = add nsw i32 %indvar, 1
258 %cmp = icmp slt i32 %indvar, 65535
259 br i1 %cmp, label %for.body, label %exit
265 define i64 @test_at_use(i1 %cond, i64 %x) {
266 ; CHECK-LABEL: @test_at_use(
268 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[IF_END:%.*]]
270 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[X:%.*]], 0
271 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]]
273 ; CHECK-NEXT: ret i64 0
275 ; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[X]], [[BB1]] ], [ 0, [[ENTRY:%.*]] ]
276 ; CHECK-NEXT: ret i64 [[PHI]]
279 br i1 %cond, label %bb1, label %if.end
282 %val = call i64 @llvm.smax.i64(i64 %x, i64 -1)
283 %cmp = icmp slt i64 %x, 0
284 br i1 %cmp, label %if.then, label %if.end
290 %phi = phi i64 [%val, %bb1], [0, %entry]
294 define i8 @test_smax_to_umax_nneg(i8 %a, i8 %b) {
295 ; CHECK-LABEL: @test_smax_to_umax_nneg(
296 ; CHECK-NEXT: [[NNEG_A:%.*]] = and i8 [[A:%.*]], 127
297 ; CHECK-NEXT: [[NNEG_B:%.*]] = and i8 [[B:%.*]], 127
298 ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])
299 ; CHECK-NEXT: ret i8 [[TMP1]]
301 %nneg_a = and i8 %a, 127
302 %nneg_b = and i8 %b, 127
303 %ret = call i8 @llvm.smax.i8(i8 %nneg_a, i8 %nneg_b)
307 define i8 @test_smax_to_umax_neg(i8 %a, i8 %b) {
308 ; CHECK-LABEL: @test_smax_to_umax_neg(
309 ; CHECK-NEXT: [[NEG_A:%.*]] = or i8 [[A:%.*]], -128
310 ; CHECK-NEXT: [[NEG_B:%.*]] = or i8 [[B:%.*]], -128
311 ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[NEG_A]], i8 [[NEG_B]])
312 ; CHECK-NEXT: ret i8 [[TMP1]]
314 %neg_a = or i8 %a, 128
315 %neg_b = or i8 %b, 128
316 %ret = call i8 @llvm.smax.i8(i8 %neg_a, i8 %neg_b)
320 define i8 @test_smin_to_umin_nneg(i8 %a, i8 %b) {
321 ; CHECK-LABEL: @test_smin_to_umin_nneg(
322 ; CHECK-NEXT: [[NNEG_A:%.*]] = and i8 [[A:%.*]], 127
323 ; CHECK-NEXT: [[NNEG_B:%.*]] = and i8 [[B:%.*]], 127
324 ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])
325 ; CHECK-NEXT: ret i8 [[TMP1]]
327 %nneg_a = and i8 %a, 127
328 %nneg_b = and i8 %b, 127
329 %ret = call i8 @llvm.smin.i8(i8 %nneg_a, i8 %nneg_b)
333 define i8 @test_smin_to_umin_neg(i8 %a, i8 %b) {
334 ; CHECK-LABEL: @test_smin_to_umin_neg(
335 ; CHECK-NEXT: [[NEG_A:%.*]] = or i8 [[A:%.*]], -128
336 ; CHECK-NEXT: [[NEG_B:%.*]] = or i8 [[B:%.*]], -128
337 ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[NEG_A]], i8 [[NEG_B]])
338 ; CHECK-NEXT: ret i8 [[TMP1]]
340 %neg_a = or i8 %a, 128
341 %neg_b = or i8 %b, 128
342 %ret = call i8 @llvm.smin.i8(i8 %neg_a, i8 %neg_b)
346 define i8 @test_umax_nneg(i8 %a, i8 %b) {
347 ; CHECK-LABEL: @test_umax_nneg(
348 ; CHECK-NEXT: [[NNEG_A:%.*]] = and i8 [[A:%.*]], 127
349 ; CHECK-NEXT: [[NNEG_B:%.*]] = and i8 [[B:%.*]], 127
350 ; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umax.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])
351 ; CHECK-NEXT: ret i8 [[RET]]
353 %nneg_a = and i8 %a, 127
354 %nneg_b = and i8 %b, 127
355 %ret = call i8 @llvm.umax.i8(i8 %nneg_a, i8 %nneg_b)