[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / select-cmp-cttz-ctlz.ll
blob35b4087d767a731befe1ab68c50c33a3f07f6e84
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) {
9 ; CHECK-LABEL: @test1(
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
16   ret i16 %cond
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
27   ret i32 %cond
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
38   ret i64 %cond
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
49   ret i16 %cond
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
60   ret i16 %cond
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
71   ret i32 %cond
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
82   ret i64 %cond
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
93   ret i16 %cond
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
104   ret i32 %cond
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
115   ret i64 %cond
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
126   ret i16 %cond
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
137   ret i16 %cond
140 define i32 @test5b(i32 %x) {
141 ; CHECK-LABEL: @test5b(
142 ; CHECK-NEXT:  entry:
143 ; CHECK-NEXT:    [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)
144 ; CHECK-NEXT:    ret i32 [[CT]]
146 entry:
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
150   ret i32 %cond
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
161   ret i64 %cond
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
174   ret i32 %cond
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
187   ret i64 %cond
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
200   ret i64 %cond
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
213   ret i32 %cond
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
226   ret i64 %cond
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
239   ret i64 %cond
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
252   ret i16 %cond
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
265   ret i32 %cond
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
278   ret i16 %cond
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
291   ret i16 %cond
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
304   ret i32 %cond
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]]
316   %n = xor i64 %x, -1
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
321   ret i32 %r
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]]
331   %n = xor i64 %x, -1
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
336   ret i32 %r
339 ; negative test
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]]
350   %n = xor i64 %x, -2
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
355   ret i32 %r
358 ; negative test
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]]
369   %n = xor i64 %y, -1
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
374   ret i32 %r
377 ; negative test
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]]
388   %n = xor i64 %x, -1
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
393   ret i32 %r
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
406   ret i16 %cond
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
419   ret i64 %cond
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
432   ret i16 %cond
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
443   ret i128 %cond
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
454   ret i128 %cond
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
467   ret i32 %res
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
482   ret i32 %res
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
495   ret i32 %res
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
510   ret i32 %res
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>
521   ret <2 x i32> %res
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>
534   ret <2 x i32> %res
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>
545   ret <2 x i32> %res
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>
558   ret <2 x i32> %res
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
571   ret i32 %cond
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
584   ret i32 %cond
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
599   ret i64 %cond
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
614   ret i64 %cond
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
629   ret i16 %cond
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
644   ret i16 %cond
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)