1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4 ; This test is to verify that the instruction combiner is able to fold
5 ; a cttz/ctlz followed by a icmp + select into a single cttz/ctlz with
6 ; the 'is_zero_undef' flag cleared.
8 define i16 @test1(i16 %x) {
10 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)
11 ; CHECK-NEXT: ret i16 [[CT]]
13 %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
14 %tobool = icmp ne i16 %x, 0
15 %cond = select i1 %tobool, i16 %ct, i16 16
19 define i32 @test2(i32 %x) {
20 ; CHECK-LABEL: @test2(
21 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
22 ; CHECK-NEXT: ret i32 [[CT]]
24 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
25 %tobool = icmp ne i32 %x, 0
26 %cond = select i1 %tobool, i32 %ct, i32 32
30 define i64 @test3(i64 %x) {
31 ; CHECK-LABEL: @test3(
32 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false)
33 ; CHECK-NEXT: ret i64 [[CT]]
35 %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
36 %tobool = icmp ne i64 %x, 0
37 %cond = select i1 %tobool, i64 %ct, i64 64
41 define i16 @test4(i16 %x) {
42 ; CHECK-LABEL: @test4(
43 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)
44 ; CHECK-NEXT: ret i16 [[CT]]
46 %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
47 %tobool = icmp eq i16 %x, 0
48 %cond = select i1 %tobool, i16 16, i16 %ct
52 define i16 @test4_with_range(i16 %x) {
53 ; CHECK-LABEL: @test4_with_range(
54 ; CHECK-NEXT: [[CT:%.*]] = call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)
55 ; CHECK-NEXT: ret i16 [[CT]]
57 %ct = call range(i16 0, 16) i16 @llvm.ctlz.i16(i16 %x, i1 true)
58 %tobool = icmp eq i16 %x, 0
59 %cond = select i1 %tobool, i16 16, i16 %ct
63 define i32 @test5(i32 %x) {
64 ; CHECK-LABEL: @test5(
65 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
66 ; CHECK-NEXT: ret i32 [[CT]]
68 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
69 %tobool = icmp eq i32 %x, 0
70 %cond = select i1 %tobool, i32 32, i32 %ct
74 define i64 @test6(i64 %x) {
75 ; CHECK-LABEL: @test6(
76 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false)
77 ; CHECK-NEXT: ret i64 [[CT]]
79 %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
80 %tobool = icmp eq i64 %x, 0
81 %cond = select i1 %tobool, i64 64, i64 %ct
85 define i16 @test1b(i16 %x) {
86 ; CHECK-LABEL: @test1b(
87 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)
88 ; CHECK-NEXT: ret i16 [[CT]]
90 %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
91 %tobool = icmp ne i16 %x, 0
92 %cond = select i1 %tobool, i16 %ct, i16 16
96 define i32 @test2b(i32 %x) {
97 ; CHECK-LABEL: @test2b(
98 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
99 ; CHECK-NEXT: ret i32 [[CT]]
101 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
102 %tobool = icmp ne i32 %x, 0
103 %cond = select i1 %tobool, i32 %ct, i32 32
107 define i64 @test3b(i64 %x) {
108 ; CHECK-LABEL: @test3b(
109 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)
110 ; CHECK-NEXT: ret i64 [[CT]]
112 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
113 %tobool = icmp ne i64 %x, 0
114 %cond = select i1 %tobool, i64 %ct, i64 64
118 define i16 @test4b(i16 %x) {
119 ; CHECK-LABEL: @test4b(
120 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)
121 ; CHECK-NEXT: ret i16 [[CT]]
123 %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
124 %tobool = icmp eq i16 %x, 0
125 %cond = select i1 %tobool, i16 16, i16 %ct
129 define i16 @test4b_with_range(i16 %x) {
130 ; CHECK-LABEL: @test4b_with_range(
131 ; CHECK-NEXT: [[CT:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)
132 ; CHECK-NEXT: ret i16 [[CT]]
134 %ct = call range(i16 0, 16) i16 @llvm.cttz.i16(i16 %x, i1 true)
135 %tobool = icmp eq i16 %x, 0
136 %cond = select i1 %tobool, i16 16, i16 %ct
140 define i32 @test5b(i32 %x) {
141 ; CHECK-LABEL: @test5b(
143 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
144 ; CHECK-NEXT: ret i32 [[CT]]
147 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
148 %tobool = icmp eq i32 %x, 0
149 %cond = select i1 %tobool, i32 32, i32 %ct
153 define i64 @test6b(i64 %x) {
154 ; CHECK-LABEL: @test6b(
155 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)
156 ; CHECK-NEXT: ret i64 [[CT]]
158 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
159 %tobool = icmp eq i64 %x, 0
160 %cond = select i1 %tobool, i64 64, i64 %ct
164 define i32 @test1c(i16 %x) {
165 ; CHECK-LABEL: @test1c(
166 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)
167 ; CHECK-NEXT: [[CAST2:%.*]] = zext nneg i16 [[CT]] to i32
168 ; CHECK-NEXT: ret i32 [[CAST2]]
170 %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
171 %cast2 = zext i16 %ct to i32
172 %tobool = icmp ne i16 %x, 0
173 %cond = select i1 %tobool, i32 %cast2, i32 16
177 define i64 @test2c(i16 %x) {
178 ; CHECK-LABEL: @test2c(
179 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)
180 ; CHECK-NEXT: [[CONV:%.*]] = zext nneg i16 [[CT]] to i64
181 ; CHECK-NEXT: ret i64 [[CONV]]
183 %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
184 %conv = zext i16 %ct to i64
185 %tobool = icmp ne i16 %x, 0
186 %cond = select i1 %tobool, i64 %conv, i64 16
190 define i64 @test3c(i32 %x) {
191 ; CHECK-LABEL: @test3c(
192 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
193 ; CHECK-NEXT: [[CONV:%.*]] = zext nneg i32 [[CT]] to i64
194 ; CHECK-NEXT: ret i64 [[CONV]]
196 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
197 %conv = zext i32 %ct to i64
198 %tobool = icmp ne i32 %x, 0
199 %cond = select i1 %tobool, i64 %conv, i64 32
203 define i32 @test4c(i16 %x) {
204 ; CHECK-LABEL: @test4c(
205 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)
206 ; CHECK-NEXT: [[CAST:%.*]] = zext nneg i16 [[CT]] to i32
207 ; CHECK-NEXT: ret i32 [[CAST]]
209 %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
210 %cast = zext i16 %ct to i32
211 %tobool = icmp ne i16 %x, 0
212 %cond = select i1 %tobool, i32 %cast, i32 16
216 define i64 @test5c(i16 %x) {
217 ; CHECK-LABEL: @test5c(
218 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)
219 ; CHECK-NEXT: [[CAST:%.*]] = zext nneg i16 [[CT]] to i64
220 ; CHECK-NEXT: ret i64 [[CAST]]
222 %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
223 %cast = zext i16 %ct to i64
224 %tobool = icmp ne i16 %x, 0
225 %cond = select i1 %tobool, i64 %cast, i64 16
229 define i64 @test6c(i32 %x) {
230 ; CHECK-LABEL: @test6c(
231 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
232 ; CHECK-NEXT: [[CAST:%.*]] = zext nneg i32 [[CT]] to i64
233 ; CHECK-NEXT: ret i64 [[CAST]]
235 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
236 %cast = zext i32 %ct to i64
237 %tobool = icmp ne i32 %x, 0
238 %cond = select i1 %tobool, i64 %cast, i64 32
242 define i16 @test1d(i64 %x) {
243 ; CHECK-LABEL: @test1d(
244 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)
245 ; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[CT]] to i16
246 ; CHECK-NEXT: ret i16 [[CONV]]
248 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
249 %conv = trunc i64 %ct to i16
250 %tobool = icmp ne i64 %x, 0
251 %cond = select i1 %tobool, i16 %conv, i16 64
255 define i32 @test2d(i64 %x) {
256 ; CHECK-LABEL: @test2d(
257 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)
258 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32
259 ; CHECK-NEXT: ret i32 [[CAST]]
261 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
262 %cast = trunc i64 %ct to i32
263 %tobool = icmp ne i64 %x, 0
264 %cond = select i1 %tobool, i32 %cast, i32 64
268 define i16 @test3d(i32 %x) {
269 ; CHECK-LABEL: @test3d(
270 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
271 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i32 [[CT]] to i16
272 ; CHECK-NEXT: ret i16 [[CAST]]
274 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
275 %cast = trunc i32 %ct to i16
276 %tobool = icmp ne i32 %x, 0
277 %cond = select i1 %tobool, i16 %cast, i16 32
281 define i16 @test4d(i64 %x) {
282 ; CHECK-LABEL: @test4d(
283 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false)
284 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i16
285 ; CHECK-NEXT: ret i16 [[CAST]]
287 %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
288 %cast = trunc i64 %ct to i16
289 %tobool = icmp ne i64 %x, 0
290 %cond = select i1 %tobool, i16 %cast, i16 64
294 define i32 @test5d(i64 %x) {
295 ; CHECK-LABEL: @test5d(
296 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false)
297 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32
298 ; CHECK-NEXT: ret i32 [[CAST]]
300 %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
301 %cast = trunc i64 %ct to i32
302 %tobool = icmp ne i64 %x, 0
303 %cond = select i1 %tobool, i32 %cast, i32 64
307 ; Same as above, but the counting zeros on an inverted operand with opposite compare.
309 define i32 @not_op_ctlz(i64 %x) {
310 ; CHECK-LABEL: @not_op_ctlz(
311 ; CHECK-NEXT: [[N:%.*]] = xor i64 [[X:%.*]], -1
312 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[N]], i1 false)
313 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32
314 ; CHECK-NEXT: ret i32 [[CAST]]
317 %ct = tail call i64 @llvm.ctlz.i64(i64 %n, i1 true)
318 %cast = trunc i64 %ct to i32
319 %tobool = icmp eq i64 %x, -1
320 %r = select i1 %tobool, i32 64, i32 %cast
324 define i32 @not_op_cttz(i64 %x) {
325 ; CHECK-LABEL: @not_op_cttz(
326 ; CHECK-NEXT: [[N:%.*]] = xor i64 [[X:%.*]], -1
327 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[N]], i1 false)
328 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32
329 ; CHECK-NEXT: ret i32 [[CAST]]
332 %ct = tail call i64 @llvm.cttz.i64(i64 %n, i1 true)
333 %cast = trunc i64 %ct to i32
334 %tobool = icmp eq i64 %x, -1
335 %r = select i1 %tobool, i32 64, i32 %cast
341 define i32 @not_op_ctlz_wrong_xor_op1(i64 %x) {
342 ; CHECK-LABEL: @not_op_ctlz_wrong_xor_op1(
343 ; CHECK-NEXT: [[N:%.*]] = xor i64 [[X:%.*]], -2
344 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[N]], i1 true)
345 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32
346 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X]], -1
347 ; CHECK-NEXT: [[R:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]
348 ; CHECK-NEXT: ret i32 [[R]]
351 %ct = tail call i64 @llvm.ctlz.i64(i64 %n, i1 true)
352 %cast = trunc i64 %ct to i32
353 %tobool = icmp eq i64 %x, -1
354 %r = select i1 %tobool, i32 64, i32 %cast
360 define i32 @not_op_ctlz_wrong_xor_op0(i64 %x, i64 %y) {
361 ; CHECK-LABEL: @not_op_ctlz_wrong_xor_op0(
362 ; CHECK-NEXT: [[N:%.*]] = xor i64 [[Y:%.*]], -1
363 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[N]], i1 true)
364 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32
365 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], -1
366 ; CHECK-NEXT: [[R:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]
367 ; CHECK-NEXT: ret i32 [[R]]
370 %ct = tail call i64 @llvm.ctlz.i64(i64 %n, i1 true)
371 %cast = trunc i64 %ct to i32
372 %tobool = icmp eq i64 %x, -1
373 %r = select i1 %tobool, i32 64, i32 %cast
379 define i32 @not_op_cttz_wrong_cmp(i64 %x) {
380 ; CHECK-LABEL: @not_op_cttz_wrong_cmp(
381 ; CHECK-NEXT: [[N:%.*]] = xor i64 [[X:%.*]], -1
382 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[N]], i1 true)
383 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32
384 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X]], 0
385 ; CHECK-NEXT: [[R:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]
386 ; CHECK-NEXT: ret i32 [[R]]
389 %ct = tail call i64 @llvm.cttz.i64(i64 %n, i1 true)
390 %cast = trunc i64 %ct to i32
391 %tobool = icmp eq i64 %x, 0
392 %r = select i1 %tobool, i32 64, i32 %cast
396 define i16 @test6d(i32 %x) {
397 ; CHECK-LABEL: @test6d(
398 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
399 ; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i32 [[CT]] to i16
400 ; CHECK-NEXT: ret i16 [[CAST]]
402 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
403 %cast = trunc i32 %ct to i16
404 %tobool = icmp ne i32 %x, 0
405 %cond = select i1 %tobool, i16 %cast, i16 32
409 define i64 @select_bug1(i32 %x) {
410 ; CHECK-LABEL: @select_bug1(
411 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
412 ; CHECK-NEXT: [[CONV:%.*]] = zext nneg i32 [[CT]] to i64
413 ; CHECK-NEXT: ret i64 [[CONV]]
415 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
416 %conv = zext i32 %ct to i64
417 %tobool = icmp ne i32 %x, 0
418 %cond = select i1 %tobool, i64 %conv, i64 32
422 define i16 @select_bug2(i32 %x) {
423 ; CHECK-LABEL: @select_bug2(
424 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
425 ; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i32 [[CT]] to i16
426 ; CHECK-NEXT: ret i16 [[CONV]]
428 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
429 %conv = trunc i32 %ct to i16
430 %tobool = icmp ne i32 %x, 0
431 %cond = select i1 %tobool, i16 %conv, i16 32
435 define i128 @test7(i128 %x) {
436 ; CHECK-LABEL: @test7(
437 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i128 0, 129) i128 @llvm.ctlz.i128(i128 [[X:%.*]], i1 false)
438 ; CHECK-NEXT: ret i128 [[CT]]
440 %ct = tail call i128 @llvm.ctlz.i128(i128 %x, i1 true)
441 %tobool = icmp ne i128 %x, 0
442 %cond = select i1 %tobool, i128 %ct, i128 128
446 define i128 @test8(i128 %x) {
447 ; CHECK-LABEL: @test8(
448 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i128 0, 129) i128 @llvm.cttz.i128(i128 [[X:%.*]], i1 false)
449 ; CHECK-NEXT: ret i128 [[CT]]
451 %ct = tail call i128 @llvm.cttz.i128(i128 %x, i1 true)
452 %tobool = icmp ne i128 %x, 0
453 %cond = select i1 %tobool, i128 %ct, i128 128
457 define i32 @test_ctlz_not_bw(i32 %x) {
458 ; CHECK-LABEL: @test_ctlz_not_bw(
459 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true)
460 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0
461 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]
462 ; CHECK-NEXT: ret i32 [[RES]]
464 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
465 %cmp = icmp ne i32 %x, 0
466 %res = select i1 %cmp, i32 %ct, i32 123
470 define i32 @test_ctlz_not_bw_multiuse(i32 %x) {
471 ; CHECK-LABEL: @test_ctlz_not_bw_multiuse(
472 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
473 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0
474 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]
475 ; CHECK-NEXT: [[RES:%.*]] = or i32 [[SEL]], [[CT]]
476 ; CHECK-NEXT: ret i32 [[RES]]
478 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
479 %cmp = icmp ne i32 %x, 0
480 %sel = select i1 %cmp, i32 %ct, i32 123
481 %res = or i32 %sel, %ct
485 define i32 @test_cttz_not_bw(i32 %x) {
486 ; CHECK-LABEL: @test_cttz_not_bw(
487 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)
488 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0
489 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]
490 ; CHECK-NEXT: ret i32 [[RES]]
492 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
493 %cmp = icmp ne i32 %x, 0
494 %res = select i1 %cmp, i32 %ct, i32 123
498 define i32 @test_cttz_not_bw_multiuse(i32 %x) {
499 ; CHECK-LABEL: @test_cttz_not_bw_multiuse(
500 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
501 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0
502 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]
503 ; CHECK-NEXT: [[RES:%.*]] = or i32 [[SEL]], [[CT]]
504 ; CHECK-NEXT: ret i32 [[RES]]
506 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
507 %cmp = icmp ne i32 %x, 0
508 %sel = select i1 %cmp, i32 %ct, i32 123
509 %res = or i32 %sel, %ct
513 define <2 x i32> @test_ctlz_bw_vec(<2 x i32> %x) {
514 ; CHECK-LABEL: @test_ctlz_bw_vec(
515 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X:%.*]], i1 false)
516 ; CHECK-NEXT: ret <2 x i32> [[CT]]
518 %ct = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %x, i1 true)
519 %cmp = icmp ne <2 x i32> %x, zeroinitializer
520 %res = select <2 x i1> %cmp, <2 x i32> %ct, <2 x i32> <i32 32, i32 32>
524 define <2 x i32> @test_ctlz_not_bw_vec(<2 x i32> %x) {
525 ; CHECK-LABEL: @test_ctlz_not_bw_vec(
526 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X:%.*]], i1 true)
527 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer
528 ; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[CMP_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[CT]]
529 ; CHECK-NEXT: ret <2 x i32> [[RES]]
531 %ct = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %x, i1 false)
532 %cmp = icmp ne <2 x i32> %x, zeroinitializer
533 %res = select <2 x i1> %cmp, <2 x i32> %ct, <2 x i32> <i32 0, i32 0>
537 define <2 x i32> @test_cttz_bw_vec(<2 x i32> %x) {
538 ; CHECK-LABEL: @test_cttz_bw_vec(
539 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 false)
540 ; CHECK-NEXT: ret <2 x i32> [[CT]]
542 %ct = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %x, i1 true)
543 %cmp = icmp ne <2 x i32> %x, zeroinitializer
544 %res = select <2 x i1> %cmp, <2 x i32> %ct, <2 x i32> <i32 32, i32 32>
548 define <2 x i32> @test_cttz_not_bw_vec(<2 x i32> %x) {
549 ; CHECK-LABEL: @test_cttz_not_bw_vec(
550 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 true)
551 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer
552 ; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[CMP_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[CT]]
553 ; CHECK-NEXT: ret <2 x i32> [[RES]]
555 %ct = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %x, i1 false)
556 %cmp = icmp ne <2 x i32> %x, zeroinitializer
557 %res = select <2 x i1> %cmp, <2 x i32> %ct, <2 x i32> <i32 0, i32 0>
561 define i32 @test_multiuse_def(i32 %x, ptr %p) {
562 ; CHECK-LABEL: @test_multiuse_def(
563 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
564 ; CHECK-NEXT: store i32 [[CT]], ptr [[P:%.*]], align 4
565 ; CHECK-NEXT: ret i32 [[CT]]
567 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
568 %tobool = icmp ne i32 %x, 0
569 %cond = select i1 %tobool, i32 %ct, i32 32
570 store i32 %ct, ptr %p
574 define i32 @test_multiuse_undef(i32 %x, ptr %p) {
575 ; CHECK-LABEL: @test_multiuse_undef(
576 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
577 ; CHECK-NEXT: store i32 [[CT]], ptr [[P:%.*]], align 4
578 ; CHECK-NEXT: ret i32 [[CT]]
580 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
581 %tobool = icmp ne i32 %x, 0
582 %cond = select i1 %tobool, i32 %ct, i32 32
583 store i32 %ct, ptr %p
587 define i64 @test_multiuse_zext_def(i32 %x, ptr %p) {
588 ; CHECK-LABEL: @test_multiuse_zext_def(
589 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
590 ; CHECK-NEXT: [[CONV:%.*]] = zext nneg i32 [[CT]] to i64
591 ; CHECK-NEXT: store i64 [[CONV]], ptr [[P:%.*]], align 4
592 ; CHECK-NEXT: ret i64 [[CONV]]
594 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
595 %conv = zext i32 %ct to i64
596 %tobool = icmp ne i32 %x, 0
597 %cond = select i1 %tobool, i64 %conv, i64 32
598 store i64 %conv, ptr %p
602 define i64 @test_multiuse_zext_undef(i32 %x, ptr %p) {
603 ; CHECK-LABEL: @test_multiuse_zext_undef(
604 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
605 ; CHECK-NEXT: [[CONV:%.*]] = zext nneg i32 [[CT]] to i64
606 ; CHECK-NEXT: store i64 [[CONV]], ptr [[P:%.*]], align 4
607 ; CHECK-NEXT: ret i64 [[CONV]]
609 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
610 %conv = zext i32 %ct to i64
611 %tobool = icmp ne i32 %x, 0
612 %cond = select i1 %tobool, i64 %conv, i64 32
613 store i64 %conv, ptr %p
617 define i16 @test_multiuse_trunc_def(i64 %x, ptr %p) {
618 ; CHECK-LABEL: @test_multiuse_trunc_def(
619 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)
620 ; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[CT]] to i16
621 ; CHECK-NEXT: store i16 [[CONV]], ptr [[P:%.*]], align 2
622 ; CHECK-NEXT: ret i16 [[CONV]]
624 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
625 %conv = trunc i64 %ct to i16
626 %tobool = icmp ne i64 %x, 0
627 %cond = select i1 %tobool, i16 %conv, i16 64
628 store i16 %conv, ptr %p
632 define i16 @test_multiuse_trunc_undef(i64 %x, ptr %p) {
633 ; CHECK-LABEL: @test_multiuse_trunc_undef(
634 ; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)
635 ; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[CT]] to i16
636 ; CHECK-NEXT: store i16 [[CONV]], ptr [[P:%.*]], align 2
637 ; CHECK-NEXT: ret i16 [[CONV]]
639 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
640 %conv = trunc i64 %ct to i16
641 %tobool = icmp ne i64 %x, 0
642 %cond = select i1 %tobool, i16 %conv, i16 64
643 store i16 %conv, ptr %p
647 declare i16 @llvm.ctlz.i16(i16, i1)
648 declare i32 @llvm.ctlz.i32(i32, i1)
649 declare i64 @llvm.ctlz.i64(i64, i1)
650 declare i128 @llvm.ctlz.i128(i128, i1)
651 declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1)
652 declare i16 @llvm.cttz.i16(i16, i1)
653 declare i32 @llvm.cttz.i32(i32, i1)
654 declare i64 @llvm.cttz.i64(i64, i1)
655 declare i128 @llvm.cttz.i128(i128, i1)
656 declare <2 x i32> @llvm.cttz.v2i32(<2 x i32>, i1)