1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare i5 @llvm.umin.i5(i5, i5)
5 declare <2 x i8> @llvm.umin.v2i8(<2 x i8>, <2 x i8>)
7 define i32 @max_na_b_minux_na(i32 %A, i32 %B) {
8 ; CHECK-LABEL: @max_na_b_minux_na(
9 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
10 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[NOT]], i32 [[B:%.*]])
11 ; CHECK-NEXT: [[TMP2:%.*]] = sub i32 0, [[TMP1]]
12 ; CHECK-NEXT: ret i32 [[TMP2]]
15 %l0 = icmp ult i32 %not, %B
16 %l1 = select i1 %l0, i32 %not, i32 %B
17 %x = sub i32 %l1, %not
21 define i32 @na_minus_max_na_b(i32 %A, i32 %B) {
22 ; CHECK-LABEL: @na_minus_max_na_b(
23 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
24 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[NOT]], i32 [[B:%.*]])
25 ; CHECK-NEXT: ret i32 [[TMP1]]
28 %l0 = icmp ult i32 %not, %B
29 %l1 = select i1 %l0, i32 %not, i32 %B
30 %x = sub i32 %not, %l1
34 define i5 @sub_umin(i5 %a, i5 %b) {
35 ; CHECK-LABEL: @sub_umin(
36 ; CHECK-NEXT: [[UMIN:%.*]] = call i5 @llvm.umin.i5(i5 [[A:%.*]], i5 [[B:%.*]])
37 ; CHECK-NEXT: [[R:%.*]] = sub i5 [[A]], [[UMIN]]
38 ; CHECK-NEXT: ret i5 [[R]]
40 %umin = call i5 @llvm.umin.i5(i5 %a, i5 %b)
45 define <2 x i8> @sub_umin_commute_vec(<2 x i8> %a, <2 x i8> %b) {
46 ; CHECK-LABEL: @sub_umin_commute_vec(
47 ; CHECK-NEXT: [[UMIN:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[B:%.*]], <2 x i8> [[A:%.*]])
48 ; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[B]], [[UMIN]]
49 ; CHECK-NEXT: ret <2 x i8> [[R]]
51 %umin = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %b, <2 x i8> %a)
52 %r = sub <2 x i8> %b, %umin
56 define i5 @sub_umin_uses(i5 %a, i5 %b, i5* %p) {
57 ; CHECK-LABEL: @sub_umin_uses(
58 ; CHECK-NEXT: [[UMIN:%.*]] = call i5 @llvm.umin.i5(i5 [[A:%.*]], i5 [[B:%.*]])
59 ; CHECK-NEXT: store i5 [[UMIN]], i5* [[P:%.*]], align 1
60 ; CHECK-NEXT: [[R:%.*]] = sub i5 [[A]], [[UMIN]]
61 ; CHECK-NEXT: ret i5 [[R]]
63 %umin = call i5 @llvm.umin.i5(i5 %a, i5 %b)
64 store i5 %umin, i5* %p
69 define i5 @sub_umin_no_common_op(i5 %a, i5 %b, i5 %c) {
70 ; CHECK-LABEL: @sub_umin_no_common_op(
71 ; CHECK-NEXT: [[UMIN:%.*]] = call i5 @llvm.umin.i5(i5 [[A:%.*]], i5 [[B:%.*]])
72 ; CHECK-NEXT: [[R:%.*]] = sub i5 [[C:%.*]], [[UMIN]]
73 ; CHECK-NEXT: ret i5 [[R]]
75 %umin = call i5 @llvm.umin.i5(i5 %a, i5 %b)
80 define i32 @max_b_na_minus_na(i32 %A, i32 %B) {
81 ; CHECK-LABEL: @max_b_na_minus_na(
82 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
83 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[NOT]], i32 [[B:%.*]])
84 ; CHECK-NEXT: [[TMP2:%.*]] = sub i32 0, [[TMP1]]
85 ; CHECK-NEXT: ret i32 [[TMP2]]
88 %l0 = icmp ugt i32 %not, %B
89 %l1 = select i1 %l0, i32 %B, i32 %not
90 %x = sub i32 %l1, %not
94 define i32 @na_minus_max_b_na(i32 %A, i32 %B) {
95 ; CHECK-LABEL: @na_minus_max_b_na(
96 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
97 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[NOT]], i32 [[B:%.*]])
98 ; CHECK-NEXT: ret i32 [[TMP1]]
100 %not = xor i32 %A, -1
101 %l0 = icmp ugt i32 %not, %B
102 %l1 = select i1 %l0, i32 %B, i32 %not
103 %x = sub i32 %not, %l1
108 define i32 @max_na_bi_minux_na(i32 %A, i32 %Bi) {
109 ; CHECK-LABEL: @max_na_bi_minux_na(
110 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[BI:%.*]], i32 [[A:%.*]])
111 ; CHECK-NEXT: [[TMP2:%.*]] = sub i32 0, [[TMP1]]
112 ; CHECK-NEXT: ret i32 [[TMP2]]
115 %not = xor i32 %A, -1
116 %l0 = icmp ult i32 %not, %B
117 %l1 = select i1 %l0, i32 %not, i32 %B
118 %x = sub i32 %l1, %not
122 define i32 @na_minus_max_na_bi(i32 %A, i32 %Bi) {
123 ; CHECK-LABEL: @na_minus_max_na_bi(
124 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[BI:%.*]], i32 [[A:%.*]])
125 ; CHECK-NEXT: ret i32 [[TMP1]]
128 %not = xor i32 %A, -1
129 %l0 = icmp ult i32 %not, %B
130 %l1 = select i1 %l0, i32 %not, i32 %B
131 %x = sub i32 %not, %l1
135 define i32 @max_bi_na_minus_na(i32 %A, i32 %Bi) {
136 ; CHECK-LABEL: @max_bi_na_minus_na(
137 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[BI:%.*]], i32 [[A:%.*]])
138 ; CHECK-NEXT: [[TMP2:%.*]] = sub i32 0, [[TMP1]]
139 ; CHECK-NEXT: ret i32 [[TMP2]]
142 %not = xor i32 %A, -1
143 %l0 = icmp ugt i32 %not, %B
144 %l1 = select i1 %l0, i32 %B, i32 %not
145 %x = sub i32 %l1, %not
149 define i32 @na_minus_max_bi_na(i32 %A, i32 %Bi) {
150 ; CHECK-LABEL: @na_minus_max_bi_na(
151 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[BI:%.*]], i32 [[A:%.*]])
152 ; CHECK-NEXT: ret i32 [[TMP1]]
155 %not = xor i32 %A, -1
156 %l0 = icmp ugt i32 %not, %B
157 %l1 = select i1 %l0, i32 %B, i32 %not
158 %x = sub i32 %not, %l1
163 define i32 @max_na_bi_minux_na_use(i32 %A, i32 %Bi) {
164 ; CHECK-LABEL: @max_na_bi_minux_na_use(
165 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], -32
166 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 -32
167 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
168 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]]
169 ; CHECK-NEXT: call void @use32(i32 [[L1]])
170 ; CHECK-NEXT: ret i32 [[X]]
172 %not = xor i32 %A, -1
173 %l0 = icmp ult i32 %not, 31
174 %l1 = select i1 %l0, i32 %not, i32 31
175 %x = sub i32 %l1, %not
176 call void @use32(i32 %l1)
180 define i32 @na_minus_max_na_bi_use(i32 %A, i32 %Bi) {
181 ; CHECK-LABEL: @na_minus_max_na_bi_use(
182 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], -32
183 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 -32
184 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
185 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]]
186 ; CHECK-NEXT: call void @use32(i32 [[L1]])
187 ; CHECK-NEXT: ret i32 [[X]]
189 %not = xor i32 %A, -1
190 %l0 = icmp ult i32 %not, 31
191 %l1 = select i1 %l0, i32 %not, i32 31
192 %x = sub i32 %not, %l1
193 call void @use32(i32 %l1)
197 define i32 @max_bi_na_minus_na_use(i32 %A, i32 %Bi) {
198 ; CHECK-LABEL: @max_bi_na_minus_na_use(
199 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[BI:%.*]], [[A:%.*]]
200 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
201 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
202 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]]
203 ; CHECK-NEXT: call void @use32(i32 [[L1]])
204 ; CHECK-NEXT: ret i32 [[X]]
206 %not = xor i32 %A, -1
208 %l0 = icmp ult i32 %B, %not
209 %l1 = select i1 %l0, i32 %B, i32 %not
210 %x = sub i32 %l1, %not
211 call void @use32(i32 %l1)
215 define i32 @na_minus_max_bi_na_use(i32 %A, i32 %Bi) {
216 ; CHECK-LABEL: @na_minus_max_bi_na_use(
217 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[BI:%.*]], [[A:%.*]]
218 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
219 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
220 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]]
221 ; CHECK-NEXT: call void @use32(i32 [[L1]])
222 ; CHECK-NEXT: ret i32 [[X]]
224 %not = xor i32 %A, -1
226 %l0 = icmp ult i32 %B, %not
227 %l1 = select i1 %l0, i32 %B, i32 %not
228 %x = sub i32 %not, %l1
229 call void @use32(i32 %l1)
234 define i32 @max_na_bi_minux_na_use2(i32 %A, i32 %Bi) {
235 ; CHECK-LABEL: @max_na_bi_minux_na_use2(
236 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
237 ; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], 31
238 ; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31
239 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[L1]], [[NOT]]
240 ; CHECK-NEXT: call void @use32(i32 [[L1]])
241 ; CHECK-NEXT: call void @use32(i32 [[NOT]])
242 ; CHECK-NEXT: ret i32 [[X]]
244 %not = xor i32 %A, -1
245 %l0 = icmp ult i32 %not, 31
246 %l1 = select i1 %l0, i32 %not, i32 31
247 %x = sub i32 %l1, %not
248 call void @use32(i32 %l1)
249 call void @use32(i32 %not)
253 define i32 @na_minus_max_na_bi_use2(i32 %A, i32 %Bi) {
254 ; CHECK-LABEL: @na_minus_max_na_bi_use2(
255 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
256 ; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], 31
257 ; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31
258 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[NOT]], [[L1]]
259 ; CHECK-NEXT: call void @use32(i32 [[L1]])
260 ; CHECK-NEXT: call void @use32(i32 [[NOT]])
261 ; CHECK-NEXT: ret i32 [[X]]
263 %not = xor i32 %A, -1
264 %l0 = icmp ult i32 %not, 31
265 %l1 = select i1 %l0, i32 %not, i32 31
266 %x = sub i32 %not, %l1
267 call void @use32(i32 %l1)
268 call void @use32(i32 %not)
272 define i32 @max_bi_na_minus_na_use2(i32 %A, i32 %Bi) {
273 ; CHECK-LABEL: @max_bi_na_minus_na_use2(
274 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
275 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[BI:%.*]], [[A]]
276 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
277 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
278 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]]
279 ; CHECK-NEXT: call void @use32(i32 [[L1]])
280 ; CHECK-NEXT: call void @use32(i32 [[NOT]])
281 ; CHECK-NEXT: ret i32 [[X]]
283 %not = xor i32 %A, -1
285 %l0 = icmp ult i32 %B, %not
286 %l1 = select i1 %l0, i32 %B, i32 %not
287 %x = sub i32 %l1, %not
288 call void @use32(i32 %l1)
289 call void @use32(i32 %not)
293 define i32 @na_minus_max_bi_na_use2(i32 %A, i32 %Bi) {
294 ; CHECK-LABEL: @na_minus_max_bi_na_use2(
295 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1
296 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[BI:%.*]], [[A]]
297 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]]
298 ; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1
299 ; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]]
300 ; CHECK-NEXT: call void @use32(i32 [[L1]])
301 ; CHECK-NEXT: call void @use32(i32 [[NOT]])
302 ; CHECK-NEXT: ret i32 [[X]]
304 %not = xor i32 %A, -1
306 %l0 = icmp ult i32 %B, %not
307 %l1 = select i1 %l0, i32 %B, i32 %not
308 %x = sub i32 %not, %l1
309 call void @use32(i32 %l1)
310 call void @use32(i32 %not)
314 define i8 @umin_not_sub(i8 %x, i8 %y) {
315 ; CHECK-LABEL: @umin_not_sub(
316 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
317 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Y]]
318 ; CHECK-NEXT: [[MINXY:%.*]] = xor i8 [[TMP2]], -1
319 ; CHECK-NEXT: [[SUBX:%.*]] = sub i8 [[TMP2]], [[X]]
320 ; CHECK-NEXT: [[SUBY:%.*]] = sub i8 [[TMP2]], [[Y]]
321 ; CHECK-NEXT: call void @use8(i8 [[SUBX]])
322 ; CHECK-NEXT: call void @use8(i8 [[SUBY]])
323 ; CHECK-NEXT: ret i8 [[MINXY]]
327 %cmpxy = icmp ult i8 %nx, %ny
328 %minxy = select i1 %cmpxy, i8 %nx, i8 %ny
329 %subx = sub i8 %nx, %minxy
330 %suby = sub i8 %ny, %minxy
331 call void @use8(i8 %subx)
332 call void @use8(i8 %suby)
336 define i8 @umin_not_sub_rev(i8 %x, i8 %y) {
337 ; CHECK-LABEL: @umin_not_sub_rev(
338 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
339 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Y]]
340 ; CHECK-NEXT: [[MINXY:%.*]] = xor i8 [[TMP2]], -1
341 ; CHECK-NEXT: [[SUBX:%.*]] = sub i8 [[X]], [[TMP2]]
342 ; CHECK-NEXT: [[SUBY:%.*]] = sub i8 [[Y]], [[TMP2]]
343 ; CHECK-NEXT: call void @use8(i8 [[SUBX]])
344 ; CHECK-NEXT: call void @use8(i8 [[SUBY]])
345 ; CHECK-NEXT: ret i8 [[MINXY]]
349 %cmpxy = icmp ult i8 %nx, %ny
350 %minxy = select i1 %cmpxy, i8 %nx, i8 %ny
351 %subx = sub i8 %minxy, %nx
352 %suby = sub i8 %minxy, %ny
353 call void @use8(i8 %subx)
354 call void @use8(i8 %suby)
358 define void @umin3_not_all_ops_extra_uses_invert_subs(i8 %x, i8 %y, i8 %z) {
359 ; CHECK-LABEL: @umin3_not_all_ops_extra_uses_invert_subs(
360 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Z:%.*]]
361 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Z]]
362 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i8 [[TMP2]], [[Y:%.*]]
363 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[Y]]
364 ; CHECK-NEXT: [[TMP5:%.*]] = xor i8 [[TMP4]], -1
365 ; CHECK-NEXT: [[XMIN:%.*]] = sub i8 [[TMP4]], [[X]]
366 ; CHECK-NEXT: [[YMIN:%.*]] = sub i8 [[TMP4]], [[Y]]
367 ; CHECK-NEXT: [[ZMIN:%.*]] = sub i8 [[TMP4]], [[Z]]
368 ; CHECK-NEXT: call void @use8(i8 [[TMP5]])
369 ; CHECK-NEXT: call void @use8(i8 [[XMIN]])
370 ; CHECK-NEXT: call void @use8(i8 [[YMIN]])
371 ; CHECK-NEXT: call void @use8(i8 [[ZMIN]])
372 ; CHECK-NEXT: ret void
377 %cmpxz = icmp ult i8 %xn, %zn
378 %minxz = select i1 %cmpxz, i8 %xn, i8 %zn
379 %cmpxyz = icmp ult i8 %minxz, %yn
380 %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn
381 %xmin = sub i8 %xn, %minxyz
382 %ymin = sub i8 %yn, %minxyz
383 %zmin = sub i8 %zn, %minxyz
384 call void @use8(i8 %minxyz)
385 call void @use8(i8 %xmin)
386 call void @use8(i8 %ymin)
387 call void @use8(i8 %zmin)
391 declare void @use8(i8)
392 declare void @use32(i32 %u)