Add i8 and i64 testing for ctlz on x86. Also simplify the i16 test.
[oota-llvm.git] / test / CodeGen / X86 / clz.ll
1 ; RUN: llc < %s -march=x86-64 -mcpu=yonah | FileCheck %s
2
3 declare i32 @llvm.cttz.i32(i32, i1)
4 declare i8 @llvm.ctlz.i8(i8, i1)
5 declare i16 @llvm.ctlz.i16(i16, i1)
6 declare i32 @llvm.ctlz.i32(i32, i1)
7 declare i64 @llvm.ctlz.i64(i64, i1)
8
9 define i32 @cttz_i32(i32 %x)  {
10   %tmp = call i32 @llvm.cttz.i32( i32 %x, i1 true )
11   ret i32 %tmp
12 ; CHECK: cttz_i32:
13 ; CHECK: bsfl
14 ; CHECK-NOT: cmov
15 ; CHECK: ret
16 }
17
18 define i8 @ctlz_i8(i8 %x) {
19 entry:
20   %tmp2 = call i8 @llvm.ctlz.i8( i8 %x, i1 true )
21   ret i8 %tmp2
22 ; CHECK: ctlz_i8:
23 ; CHECK: bsrl
24 ; CHECK-NOT: cmov
25 ; CHECK: xorl $7,
26 ; CHECK: ret
27 }
28
29 define i16 @ctlz_i16(i16 %x) {
30 entry:
31   %tmp2 = call i16 @llvm.ctlz.i16( i16 %x, i1 true )
32   ret i16 %tmp2
33 ; CHECK: ctlz_i16:
34 ; CHECK: bsrw
35 ; CHECK-NOT: cmov
36 ; CHECK: xorl $15,
37 ; CHECK: ret
38 }
39
40 define i32 @ctlz_i32(i32 %x) {
41   %tmp = call i32 @llvm.ctlz.i32( i32 %x, i1 true )
42   ret i32 %tmp
43 ; CHECK: ctlz_i32:
44 ; CHECK: bsrl
45 ; CHECK-NOT: cmov
46 ; CHECK: xorl $31,
47 ; CHECK: ret
48 }
49
50 define i64 @ctlz_i64(i64 %x) {
51   %tmp = call i64 @llvm.ctlz.i64( i64 %x, i1 true )
52   ret i64 %tmp
53 ; CHECK: ctlz_i64:
54 ; CHECK: bsrq
55 ; CHECK-NOT: cmov
56 ; CHECK: xorq $63,
57 ; CHECK: ret
58 }
59
60 define i32 @ctlz_i32_cmov(i32 %n) {
61 entry:
62 ; Generate a cmov to handle zero inputs when necessary.
63 ; CHECK: ctlz_i32_cmov:
64 ; CHECK: bsrl
65 ; CHECK: cmov
66 ; CHECK: xorl $31,
67 ; CHECK: ret
68   %tmp1 = call i32 @llvm.ctlz.i32(i32 %n, i1 false)
69   ret i32 %tmp1
70 }
71
72 define i32 @ctlz_i32_fold_cmov(i32 %n) {
73 entry:
74 ; Don't generate the cmovne when the source is known non-zero (and bsr would
75 ; not set ZF).
76 ; rdar://9490949
77 ; CHECK: ctlz_i32_fold_cmov:
78 ; CHECK: bsrl
79 ; CHECK-NOT: cmov
80 ; CHECK: xorl $31,
81 ; CHECK: ret
82   %or = or i32 %n, 1
83   %tmp1 = call i32 @llvm.ctlz.i32(i32 %or, i1 false)
84   ret i32 %tmp1
85 }
86
87 define i32 @ctlz_bsr(i32 %n) {
88 entry:
89 ; Don't generate any xors when a 'ctlz' intrinsic is actually used to compute
90 ; the most significant bit, which is what 'bsr' does natively.
91 ; CHECK: ctlz_bsr:
92 ; CHECK: bsrl
93 ; CHECK-NOT: xorl
94 ; CHECK: ret
95   %ctlz = call i32 @llvm.ctlz.i32(i32 %n, i1 true)
96   %bsr = xor i32 %ctlz, 31
97   ret i32 %bsr
98 }
99
100 define i32 @ctlz_bsr_cmov(i32 %n) {
101 entry:
102 ; Same as ctlz_bsr, but ensure this happens even when there is a potential
103 ; zero.
104 ; CHECK: ctlz_bsr_cmov:
105 ; CHECK: bsrl
106 ; CHECK-NOT: xorl
107 ; CHECK: ret
108   %ctlz = call i32 @llvm.ctlz.i32(i32 %n, i1 false)
109   %bsr = xor i32 %ctlz, 31
110   ret i32 %bsr
111 }