Skip to content

Commit 6b6d4e7

Browse files
committed
[InstCombine][NFC] Add Tests for Minimum over Trailing/Leading Bits Counts
1 parent f15266e commit 6b6d4e7

File tree

1 file changed

+382
-0
lines changed

1 file changed

+382
-0
lines changed
Lines changed: 382 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,382 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
define i8 @umin_cttz_i8_zero_undefined(i8 %X) {
5+
; CHECK-LABEL: define i8 @umin_cttz_i8_zero_undefined(
6+
; CHECK-SAME: i8 [[X:%.*]]) {
7+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[X]], i1 true)
8+
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umin.i8(i8 [[CTTZ]], i8 6)
9+
; CHECK-NEXT: ret i8 [[RET]]
10+
;
11+
%cttz = call i8 @llvm.cttz.i8(i8 %X, i1 true)
12+
%ret = call i8 @llvm.umin.i8(i8 %cttz, i8 6)
13+
ret i8 %ret
14+
}
15+
16+
define i8 @umin_cttz_i8_zero_defined(i8 %X) {
17+
; CHECK-LABEL: define i8 @umin_cttz_i8_zero_defined(
18+
; CHECK-SAME: i8 [[X:%.*]]) {
19+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[X]], i1 false)
20+
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umin.i8(i8 [[CTTZ]], i8 6)
21+
; CHECK-NEXT: ret i8 [[RET]]
22+
;
23+
%cttz = call i8 @llvm.cttz.i8(i8 %X, i1 false)
24+
%ret = call i8 @llvm.umin.i8(i8 %cttz, i8 6)
25+
ret i8 %ret
26+
}
27+
28+
define i8 @umin_cttz_i8_commuted_zero_undefined(i8 %X) {
29+
; CHECK-LABEL: define i8 @umin_cttz_i8_commuted_zero_undefined(
30+
; CHECK-SAME: i8 [[X:%.*]]) {
31+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[X]], i1 true)
32+
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umin.i8(i8 [[CTTZ]], i8 6)
33+
; CHECK-NEXT: ret i8 [[RET]]
34+
;
35+
%cttz = call i8 @llvm.cttz.i8(i8 %X, i1 true)
36+
%ret = call i8 @llvm.umin.i8(i8 6, i8 %cttz)
37+
ret i8 %ret
38+
}
39+
40+
define i8 @umin_cttz_i8_negative_ge_bitwidth_zero_undefined(i8 %X) {
41+
; CHECK-LABEL: define i8 @umin_cttz_i8_negative_ge_bitwidth_zero_undefined(
42+
; CHECK-SAME: i8 [[X:%.*]]) {
43+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[X]], i1 true)
44+
; CHECK-NEXT: ret i8 [[CTTZ]]
45+
;
46+
%cttz = call i8 @llvm.cttz.i8(i8 %X, i1 true)
47+
%ret = call i8 @llvm.umin.i8(i8 %cttz, i8 10)
48+
ret i8 %ret
49+
}
50+
51+
define i16 @umin_cttz_i16_zero_undefined(i16 %X) {
52+
; CHECK-LABEL: define i16 @umin_cttz_i16_zero_undefined(
53+
; CHECK-SAME: i16 [[X:%.*]]) {
54+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X]], i1 true)
55+
; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.umin.i16(i16 [[CTTZ]], i16 6)
56+
; CHECK-NEXT: ret i16 [[RET]]
57+
;
58+
%cttz = call i16 @llvm.cttz.i16(i16 %X, i1 true)
59+
%ret = call i16 @llvm.umin.i16(i16 %cttz, i16 6)
60+
ret i16 %ret
61+
}
62+
63+
define i32 @umin_cttz_i32_zero_undefined(i32 %X) {
64+
; CHECK-LABEL: define i32 @umin_cttz_i32_zero_undefined(
65+
; CHECK-SAME: i32 [[X:%.*]]) {
66+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X]], i1 true)
67+
; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umin.i32(i32 [[CTTZ]], i32 6)
68+
; CHECK-NEXT: ret i32 [[RET]]
69+
;
70+
%cttz = call i32 @llvm.cttz.i32(i32 %X, i1 true)
71+
%ret = call i32 @llvm.umin.i32(i32 %cttz, i32 6)
72+
ret i32 %ret
73+
}
74+
75+
define i64 @umin_cttz_i64_zero_undefined(i64 %X) {
76+
; CHECK-LABEL: define i64 @umin_cttz_i64_zero_undefined(
77+
; CHECK-SAME: i64 [[X:%.*]]) {
78+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X]], i1 true)
79+
; CHECK-NEXT: [[RET:%.*]] = call i64 @llvm.umin.i64(i64 [[CTTZ]], i64 6)
80+
; CHECK-NEXT: ret i64 [[RET]]
81+
;
82+
%cttz = call i64 @llvm.cttz.i64(i64 %X, i1 true)
83+
%ret = call i64 @llvm.umin.i64(i64 %cttz, i64 6)
84+
ret i64 %ret
85+
}
86+
87+
define i1 @umin_cttz_i1_zero_undefined(i1 %X) {
88+
; CHECK-LABEL: define i1 @umin_cttz_i1_zero_undefined(
89+
; CHECK-SAME: i1 [[X:%.*]]) {
90+
; CHECK-NEXT: ret i1 false
91+
;
92+
%cttz = call i1 @llvm.cttz.i1(i1 %X, i1 true)
93+
%ret = call i1 @llvm.umin.i1(i1 %cttz, i1 1)
94+
ret i1 %ret
95+
}
96+
97+
define i1 @umin_cttz_i1_zero_defined(i1 %X) {
98+
; CHECK-LABEL: define i1 @umin_cttz_i1_zero_defined(
99+
; CHECK-SAME: i1 [[X:%.*]]) {
100+
; CHECK-NEXT: [[CTTZ:%.*]] = xor i1 [[X]], true
101+
; CHECK-NEXT: ret i1 [[CTTZ]]
102+
;
103+
%cttz = call i1 @llvm.cttz.i1(i1 %X, i1 false)
104+
%ret = call i1 @llvm.umin.i1(i1 %cttz, i1 1)
105+
ret i1 %ret
106+
}
107+
108+
define <2 x i32> @umin_cttz_2xi32_splat_zero_undefined(<2 x i32> %X) {
109+
; CHECK-LABEL: define <2 x i32> @umin_cttz_2xi32_splat_zero_undefined(
110+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
111+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X]], i1 true)
112+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTTZ]], <2 x i32> <i32 6, i32 6>)
113+
; CHECK-NEXT: ret <2 x i32> [[RET]]
114+
;
115+
%cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %X, i1 true)
116+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %cttz, <2 x i32> <i32 6, i32 6>)
117+
ret <2 x i32> %ret
118+
}
119+
120+
define <2 x i32> @umin_cttz_2xi32_splat_poison_zero_undefined(<2 x i32> %X) {
121+
; CHECK-LABEL: define <2 x i32> @umin_cttz_2xi32_splat_poison_zero_undefined(
122+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
123+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X]], i1 true)
124+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTTZ]], <2 x i32> <i32 6, i32 poison>)
125+
; CHECK-NEXT: ret <2 x i32> [[RET]]
126+
;
127+
%cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %X, i1 true)
128+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %cttz, <2 x i32> <i32 6, i32 poison>)
129+
ret <2 x i32> %ret
130+
}
131+
132+
define <2 x i32> @umin_cttz_2xi32_no_splat_all_lt_bitwidth_zero_undefined(<2 x i32> %X) {
133+
; CHECK-LABEL: define <2 x i32> @umin_cttz_2xi32_no_splat_all_lt_bitwidth_zero_undefined(
134+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
135+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X]], i1 true)
136+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTTZ]], <2 x i32> <i32 6, i32 0>)
137+
; CHECK-NEXT: ret <2 x i32> [[RET]]
138+
;
139+
%cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %X, i1 true)
140+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %cttz, <2 x i32> <i32 6, i32 0>)
141+
ret <2 x i32> %ret
142+
}
143+
144+
define <2 x i32> @umin_cttz_2xi32_negative_no_splat_some_lt_bitwidth_zero_undefined(<2 x i32> %X) {
145+
; CHECK-LABEL: define <2 x i32> @umin_cttz_2xi32_negative_no_splat_some_lt_bitwidth_zero_undefined(
146+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
147+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X]], i1 true)
148+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTTZ]], <2 x i32> <i32 6, i32 64>)
149+
; CHECK-NEXT: ret <2 x i32> [[RET]]
150+
;
151+
%cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %X, i1 true)
152+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %cttz, <2 x i32> <i32 6, i32 64>)
153+
ret <2 x i32> %ret
154+
}
155+
156+
define <2 x i32> @umin_cttz_2xi32_negative_no_splat_none_lt_bitwidth_zero_undefined(<2 x i32> %X) {
157+
; CHECK-LABEL: define <2 x i32> @umin_cttz_2xi32_negative_no_splat_none_lt_bitwidth_zero_undefined(
158+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
159+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X]], i1 true)
160+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTTZ]], <2 x i32> <i32 32, i32 64>)
161+
; CHECK-NEXT: ret <2 x i32> [[RET]]
162+
;
163+
%cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %X, i1 true)
164+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %cttz, <2 x i32> <i32 32, i32 64>)
165+
ret <2 x i32> %ret
166+
}
167+
168+
define i16 @umin_cttz_i16_negative_non_constant(i16 %X, i16 %Y) {
169+
; CHECK-LABEL: define i16 @umin_cttz_i16_negative_non_constant(
170+
; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {
171+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X]], i1 true)
172+
; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.umin.i16(i16 [[CTTZ]], i16 [[Y]])
173+
; CHECK-NEXT: ret i16 [[RET]]
174+
;
175+
%cttz = call i16 @llvm.cttz.i16(i16 %X, i1 true)
176+
%ret = call i16 @llvm.umin.i16(i16 %cttz, i16 %Y)
177+
ret i16 %ret
178+
}
179+
180+
define i16 @umin_cttz_i16_negative_two_uses(i16 %X) {
181+
; CHECK-LABEL: define i16 @umin_cttz_i16_negative_two_uses(
182+
; CHECK-SAME: i16 [[X:%.*]]) {
183+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X]], i1 true)
184+
; CHECK-NEXT: [[OP0:%.*]] = call i16 @llvm.umin.i16(i16 [[CTTZ]], i16 6)
185+
; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i16 [[CTTZ]], [[OP0]]
186+
; CHECK-NEXT: ret i16 [[RET]]
187+
;
188+
%cttz = call i16 @llvm.cttz.i16(i16 %X, i1 true)
189+
%op0 = call i16 @llvm.umin.i16(i16 %cttz, i16 6)
190+
%ret = add i16 %cttz, %op0
191+
ret i16 %ret
192+
}
193+
194+
define i8 @umin_ctlz_i8_zero_undefined(i8 %X) {
195+
; CHECK-LABEL: define i8 @umin_ctlz_i8_zero_undefined(
196+
; CHECK-SAME: i8 [[X:%.*]]) {
197+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[X]], i1 true)
198+
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umin.i8(i8 [[CTLZ]], i8 6)
199+
; CHECK-NEXT: ret i8 [[RET]]
200+
;
201+
%ctlz = call i8 @llvm.ctlz.i8(i8 %X, i1 true)
202+
%ret = call i8 @llvm.umin.i8(i8 %ctlz, i8 6)
203+
ret i8 %ret
204+
}
205+
206+
define i8 @umin_ctlz_i8_zero_defined(i8 %X) {
207+
; CHECK-LABEL: define i8 @umin_ctlz_i8_zero_defined(
208+
; CHECK-SAME: i8 [[X:%.*]]) {
209+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[X]], i1 false)
210+
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umin.i8(i8 [[CTLZ]], i8 6)
211+
; CHECK-NEXT: ret i8 [[RET]]
212+
;
213+
%ctlz = call i8 @llvm.ctlz.i8(i8 %X, i1 false)
214+
%ret = call i8 @llvm.umin.i8(i8 %ctlz, i8 6)
215+
ret i8 %ret
216+
}
217+
218+
define i8 @umin_ctlz_i8_commuted_zero_undefined(i8 %X) {
219+
; CHECK-LABEL: define i8 @umin_ctlz_i8_commuted_zero_undefined(
220+
; CHECK-SAME: i8 [[X:%.*]]) {
221+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[X]], i1 true)
222+
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umin.i8(i8 [[CTLZ]], i8 6)
223+
; CHECK-NEXT: ret i8 [[RET]]
224+
;
225+
%ctlz = call i8 @llvm.ctlz.i8(i8 %X, i1 true)
226+
%ret = call i8 @llvm.umin.i8(i8 6, i8 %ctlz)
227+
ret i8 %ret
228+
}
229+
230+
define i8 @umin_ctlz_i8_negative_ge_bitwidth_zero_undefined(i8 %X) {
231+
; CHECK-LABEL: define i8 @umin_ctlz_i8_negative_ge_bitwidth_zero_undefined(
232+
; CHECK-SAME: i8 [[X:%.*]]) {
233+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[X]], i1 true)
234+
; CHECK-NEXT: ret i8 [[CTLZ]]
235+
;
236+
%ctlz = call i8 @llvm.ctlz.i8(i8 %X, i1 true)
237+
%ret = call i8 @llvm.umin.i8(i8 %ctlz, i8 10)
238+
ret i8 %ret
239+
}
240+
241+
define i16 @umin_ctlz_i16_zero_undefined(i16 %X) {
242+
; CHECK-LABEL: define i16 @umin_ctlz_i16_zero_undefined(
243+
; CHECK-SAME: i16 [[X:%.*]]) {
244+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X]], i1 true)
245+
; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.umin.i16(i16 [[CTLZ]], i16 6)
246+
; CHECK-NEXT: ret i16 [[RET]]
247+
;
248+
%ctlz = call i16 @llvm.ctlz.i16(i16 %X, i1 true)
249+
%ret = call i16 @llvm.umin.i16(i16 %ctlz, i16 6)
250+
ret i16 %ret
251+
}
252+
253+
define i32 @umin_ctlz_i32_zero_undefined(i32 %X) {
254+
; CHECK-LABEL: define i32 @umin_ctlz_i32_zero_undefined(
255+
; CHECK-SAME: i32 [[X:%.*]]) {
256+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
257+
; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umin.i32(i32 [[CTLZ]], i32 6)
258+
; CHECK-NEXT: ret i32 [[RET]]
259+
;
260+
%ctlz = call i32 @llvm.ctlz.i32(i32 %X, i1 true)
261+
%ret = call i32 @llvm.umin.i32(i32 %ctlz, i32 6)
262+
ret i32 %ret
263+
}
264+
265+
define i64 @umin_ctlz_i64_zero_undefined(i64 %X) {
266+
; CHECK-LABEL: define i64 @umin_ctlz_i64_zero_undefined(
267+
; CHECK-SAME: i64 [[X:%.*]]) {
268+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
269+
; CHECK-NEXT: [[RET:%.*]] = call i64 @llvm.umin.i64(i64 [[CTLZ]], i64 6)
270+
; CHECK-NEXT: ret i64 [[RET]]
271+
;
272+
%ctlz = call i64 @llvm.ctlz.i64(i64 %X, i1 true)
273+
%ret = call i64 @llvm.umin.i64(i64 %ctlz, i64 6)
274+
ret i64 %ret
275+
}
276+
277+
define i1 @umin_ctlz_i1_zero_undefined(i1 %X) {
278+
; CHECK-LABEL: define i1 @umin_ctlz_i1_zero_undefined(
279+
; CHECK-SAME: i1 [[X:%.*]]) {
280+
; CHECK-NEXT: ret i1 false
281+
;
282+
%ctlz = call i1 @llvm.ctlz.i1(i1 %X, i1 true)
283+
%ret = call i1 @llvm.umin.i1(i1 %ctlz, i1 1)
284+
ret i1 %ret
285+
}
286+
287+
define i1 @umin_ctlz_i1_zero_defined(i1 %X) {
288+
; CHECK-LABEL: define i1 @umin_ctlz_i1_zero_defined(
289+
; CHECK-SAME: i1 [[X:%.*]]) {
290+
; CHECK-NEXT: [[CTLZ:%.*]] = xor i1 [[X]], true
291+
; CHECK-NEXT: ret i1 [[CTLZ]]
292+
;
293+
%ctlz = call i1 @llvm.ctlz.i1(i1 %X, i1 false)
294+
%ret = call i1 @llvm.umin.i1(i1 %ctlz, i1 1)
295+
ret i1 %ret
296+
}
297+
298+
define <2 x i32> @umin_ctlz_2xi32_splat_zero_undefined(<2 x i32> %X) {
299+
; CHECK-LABEL: define <2 x i32> @umin_ctlz_2xi32_splat_zero_undefined(
300+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
301+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X]], i1 true)
302+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTLZ]], <2 x i32> <i32 6, i32 6>)
303+
; CHECK-NEXT: ret <2 x i32> [[RET]]
304+
;
305+
%ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %X, i1 true)
306+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %ctlz, <2 x i32> <i32 6, i32 6>)
307+
ret <2 x i32> %ret
308+
}
309+
310+
define <2 x i32> @umin_ctlz_2xi32_splat_poison_zero_undefined(<2 x i32> %X) {
311+
; CHECK-LABEL: define <2 x i32> @umin_ctlz_2xi32_splat_poison_zero_undefined(
312+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
313+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X]], i1 true)
314+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTLZ]], <2 x i32> <i32 6, i32 poison>)
315+
; CHECK-NEXT: ret <2 x i32> [[RET]]
316+
;
317+
%ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %X, i1 true)
318+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %ctlz, <2 x i32> <i32 6, i32 poison>)
319+
ret <2 x i32> %ret
320+
}
321+
322+
define <2 x i32> @umin_ctlz_2xi32_no_splat_all_lt_bitwidth_zero_undefined(<2 x i32> %X) {
323+
; CHECK-LABEL: define <2 x i32> @umin_ctlz_2xi32_no_splat_all_lt_bitwidth_zero_undefined(
324+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
325+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X]], i1 true)
326+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTLZ]], <2 x i32> <i32 6, i32 0>)
327+
; CHECK-NEXT: ret <2 x i32> [[RET]]
328+
;
329+
%ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %X, i1 true)
330+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %ctlz, <2 x i32> <i32 6, i32 0>)
331+
ret <2 x i32> %ret
332+
}
333+
334+
define <2 x i32> @umin_ctlz_2xi32_negative_no_splat_some_lt_bitwidth_zero_undefined(<2 x i32> %X) {
335+
; CHECK-LABEL: define <2 x i32> @umin_ctlz_2xi32_negative_no_splat_some_lt_bitwidth_zero_undefined(
336+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
337+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X]], i1 true)
338+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTLZ]], <2 x i32> <i32 6, i32 64>)
339+
; CHECK-NEXT: ret <2 x i32> [[RET]]
340+
;
341+
%ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %X, i1 true)
342+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %ctlz, <2 x i32> <i32 6, i32 64>)
343+
ret <2 x i32> %ret
344+
}
345+
346+
define <2 x i32> @umin_ctlz_2xi32_negative_no_splat_none_lt_bitwidth_zero_undefined(<2 x i32> %X) {
347+
; CHECK-LABEL: define <2 x i32> @umin_ctlz_2xi32_negative_no_splat_none_lt_bitwidth_zero_undefined(
348+
; CHECK-SAME: <2 x i32> [[X:%.*]]) {
349+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X]], i1 true)
350+
; CHECK-NEXT: [[RET:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[CTLZ]], <2 x i32> <i32 32, i32 64>)
351+
; CHECK-NEXT: ret <2 x i32> [[RET]]
352+
;
353+
%ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %X, i1 true)
354+
%ret = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %ctlz, <2 x i32> <i32 32, i32 64>)
355+
ret <2 x i32> %ret
356+
}
357+
358+
define i16 @umin_ctlz_i16_negative_non_constant(i16 %X, i16 %Y) {
359+
; CHECK-LABEL: define i16 @umin_ctlz_i16_negative_non_constant(
360+
; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {
361+
; CHECK-NEXT: [[CTLZ:%.*]] = call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X]], i1 true)
362+
; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.umin.i16(i16 [[CTLZ]], i16 [[Y]])
363+
; CHECK-NEXT: ret i16 [[RET]]
364+
;
365+
%ctlz = call i16 @llvm.ctlz.i16(i16 %X, i1 true)
366+
%ret = call i16 @llvm.umin.i16(i16 %ctlz, i16 %Y)
367+
ret i16 %ret
368+
}
369+
370+
define i16 @umin_ctlz_i16_negative_two_uses(i16 %X) {
371+
; CHECK-LABEL: define i16 @umin_ctlz_i16_negative_two_uses(
372+
; CHECK-SAME: i16 [[X:%.*]]) {
373+
; CHECK-NEXT: [[CTTZ:%.*]] = call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X]], i1 true)
374+
; CHECK-NEXT: [[OP0:%.*]] = call i16 @llvm.umin.i16(i16 [[CTTZ]], i16 6)
375+
; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i16 [[CTTZ]], [[OP0]]
376+
; CHECK-NEXT: ret i16 [[RET]]
377+
;
378+
%ctlz = call i16 @llvm.ctlz.i16(i16 %X, i1 true)
379+
%op0 = call i16 @llvm.umin.i16(i16 %ctlz, i16 6)
380+
%ret = add i16 %ctlz, %op0
381+
ret i16 %ret
382+
}

0 commit comments

Comments
 (0)