1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -print-schedule -mcpu=x86-64 -mattr=+lzcnt | FileCheck %s --check-prefix=CHECK --check-prefix=GENERIC
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -print-schedule -mcpu=haswell   | FileCheck %s --check-prefix=CHECK --check-prefix=HASWELL
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -print-schedule -mcpu=broadwell | FileCheck %s --check-prefix=CHECK --check-prefix=BROADWELL
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -print-schedule -mcpu=skylake   | FileCheck %s --check-prefix=CHECK --check-prefix=SKYLAKE
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -print-schedule -mcpu=knl       | FileCheck %s --check-prefix=CHECK --check-prefix=HASWELL
7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -print-schedule -mcpu=btver2    | FileCheck %s --check-prefix=CHECK --check-prefix=BTVER2
8; RUN: llc < %s -mtriple=x86_64-unknown-unknown -print-schedule -mcpu=znver1    | FileCheck %s --check-prefix=CHECK --check-prefix=ZNVER1
9
10define i16 @test_ctlz_i16(i16 zeroext %a0, i16 *%a1) {
11; GENERIC-LABEL: test_ctlz_i16:
12; GENERIC:       # %bb.0:
13; GENERIC-NEXT:    lzcntw (%rsi), %cx # sched: [8:1.00]
14; GENERIC-NEXT:    lzcntw %di, %ax # sched: [3:1.00]
15; GENERIC-NEXT:    orl %ecx, %eax # sched: [1:0.33]
16; GENERIC-NEXT:    # kill: def $ax killed $ax killed $eax
17; GENERIC-NEXT:    retq # sched: [1:1.00]
18;
19; HASWELL-LABEL: test_ctlz_i16:
20; HASWELL:       # %bb.0:
21; HASWELL-NEXT:    lzcntw (%rsi), %cx # sched: [8:1.00]
22; HASWELL-NEXT:    lzcntw %di, %ax # sched: [3:1.00]
23; HASWELL-NEXT:    orl %ecx, %eax # sched: [1:0.25]
24; HASWELL-NEXT:    # kill: def $ax killed $ax killed $eax
25; HASWELL-NEXT:    retq # sched: [7:1.00]
26;
27; BROADWELL-LABEL: test_ctlz_i16:
28; BROADWELL:       # %bb.0:
29; BROADWELL-NEXT:    lzcntw (%rsi), %cx # sched: [8:1.00]
30; BROADWELL-NEXT:    lzcntw %di, %ax # sched: [3:1.00]
31; BROADWELL-NEXT:    orl %ecx, %eax # sched: [1:0.25]
32; BROADWELL-NEXT:    # kill: def $ax killed $ax killed $eax
33; BROADWELL-NEXT:    retq # sched: [7:1.00]
34;
35; SKYLAKE-LABEL: test_ctlz_i16:
36; SKYLAKE:       # %bb.0:
37; SKYLAKE-NEXT:    lzcntw (%rsi), %cx # sched: [8:1.00]
38; SKYLAKE-NEXT:    lzcntw %di, %ax # sched: [3:1.00]
39; SKYLAKE-NEXT:    orl %ecx, %eax # sched: [1:0.25]
40; SKYLAKE-NEXT:    # kill: def $ax killed $ax killed $eax
41; SKYLAKE-NEXT:    retq # sched: [7:1.00]
42;
43; BTVER2-LABEL: test_ctlz_i16:
44; BTVER2:       # %bb.0:
45; BTVER2-NEXT:    lzcntw (%rsi), %cx # sched: [4:1.00]
46; BTVER2-NEXT:    lzcntw %di, %ax # sched: [1:0.50]
47; BTVER2-NEXT:    orl %ecx, %eax # sched: [1:0.50]
48; BTVER2-NEXT:    # kill: def $ax killed $ax killed $eax
49; BTVER2-NEXT:    retq # sched: [4:1.00]
50;
51; ZNVER1-LABEL: test_ctlz_i16:
52; ZNVER1:       # %bb.0:
53; ZNVER1-NEXT:    lzcntw (%rsi), %cx # sched: [6:0.50]
54; ZNVER1-NEXT:    lzcntw %di, %ax # sched: [2:0.25]
55; ZNVER1-NEXT:    orl %ecx, %eax # sched: [1:0.25]
56; ZNVER1-NEXT:    # kill: def $ax killed $ax killed $eax
57; ZNVER1-NEXT:    retq # sched: [1:0.50]
58  %1 = load i16, i16 *%a1
59  %2 = tail call i16 @llvm.ctlz.i16( i16 %1, i1 false )
60  %3 = tail call i16 @llvm.ctlz.i16( i16 %a0, i1 false )
61  %4 = or i16 %2, %3
62  ret i16 %4
63}
64declare i16 @llvm.ctlz.i16(i16, i1)
65
66define i32 @test_ctlz_i32(i32 %a0, i32 *%a1) {
67; GENERIC-LABEL: test_ctlz_i32:
68; GENERIC:       # %bb.0:
69; GENERIC-NEXT:    lzcntl (%rsi), %ecx # sched: [8:1.00]
70; GENERIC-NEXT:    lzcntl %edi, %eax # sched: [3:1.00]
71; GENERIC-NEXT:    orl %ecx, %eax # sched: [1:0.33]
72; GENERIC-NEXT:    retq # sched: [1:1.00]
73;
74; HASWELL-LABEL: test_ctlz_i32:
75; HASWELL:       # %bb.0:
76; HASWELL-NEXT:    lzcntl (%rsi), %ecx # sched: [8:1.00]
77; HASWELL-NEXT:    lzcntl %edi, %eax # sched: [3:1.00]
78; HASWELL-NEXT:    orl %ecx, %eax # sched: [1:0.25]
79; HASWELL-NEXT:    retq # sched: [7:1.00]
80;
81; BROADWELL-LABEL: test_ctlz_i32:
82; BROADWELL:       # %bb.0:
83; BROADWELL-NEXT:    lzcntl (%rsi), %ecx # sched: [8:1.00]
84; BROADWELL-NEXT:    lzcntl %edi, %eax # sched: [3:1.00]
85; BROADWELL-NEXT:    orl %ecx, %eax # sched: [1:0.25]
86; BROADWELL-NEXT:    retq # sched: [7:1.00]
87;
88; SKYLAKE-LABEL: test_ctlz_i32:
89; SKYLAKE:       # %bb.0:
90; SKYLAKE-NEXT:    lzcntl (%rsi), %ecx # sched: [8:1.00]
91; SKYLAKE-NEXT:    lzcntl %edi, %eax # sched: [3:1.00]
92; SKYLAKE-NEXT:    orl %ecx, %eax # sched: [1:0.25]
93; SKYLAKE-NEXT:    retq # sched: [7:1.00]
94;
95; BTVER2-LABEL: test_ctlz_i32:
96; BTVER2:       # %bb.0:
97; BTVER2-NEXT:    lzcntl (%rsi), %ecx # sched: [4:1.00]
98; BTVER2-NEXT:    lzcntl %edi, %eax # sched: [1:0.50]
99; BTVER2-NEXT:    orl %ecx, %eax # sched: [1:0.50]
100; BTVER2-NEXT:    retq # sched: [4:1.00]
101;
102; ZNVER1-LABEL: test_ctlz_i32:
103; ZNVER1:       # %bb.0:
104; ZNVER1-NEXT:    lzcntl (%rsi), %ecx # sched: [6:0.50]
105; ZNVER1-NEXT:    lzcntl %edi, %eax # sched: [2:0.25]
106; ZNVER1-NEXT:    orl %ecx, %eax # sched: [1:0.25]
107; ZNVER1-NEXT:    retq # sched: [1:0.50]
108  %1 = load i32, i32 *%a1
109  %2 = tail call i32 @llvm.ctlz.i32( i32 %1, i1 false )
110  %3 = tail call i32 @llvm.ctlz.i32( i32 %a0, i1 false )
111  %4 = or i32 %2, %3
112  ret i32 %4
113}
114declare i32 @llvm.ctlz.i32(i32, i1)
115
116define i64 @test_ctlz_i64(i64 %a0, i64 *%a1) {
117; GENERIC-LABEL: test_ctlz_i64:
118; GENERIC:       # %bb.0:
119; GENERIC-NEXT:    lzcntq (%rsi), %rcx # sched: [8:1.00]
120; GENERIC-NEXT:    lzcntq %rdi, %rax # sched: [3:1.00]
121; GENERIC-NEXT:    orq %rcx, %rax # sched: [1:0.33]
122; GENERIC-NEXT:    retq # sched: [1:1.00]
123;
124; HASWELL-LABEL: test_ctlz_i64:
125; HASWELL:       # %bb.0:
126; HASWELL-NEXT:    lzcntq (%rsi), %rcx # sched: [8:1.00]
127; HASWELL-NEXT:    lzcntq %rdi, %rax # sched: [3:1.00]
128; HASWELL-NEXT:    orq %rcx, %rax # sched: [1:0.25]
129; HASWELL-NEXT:    retq # sched: [7:1.00]
130;
131; BROADWELL-LABEL: test_ctlz_i64:
132; BROADWELL:       # %bb.0:
133; BROADWELL-NEXT:    lzcntq (%rsi), %rcx # sched: [8:1.00]
134; BROADWELL-NEXT:    lzcntq %rdi, %rax # sched: [3:1.00]
135; BROADWELL-NEXT:    orq %rcx, %rax # sched: [1:0.25]
136; BROADWELL-NEXT:    retq # sched: [7:1.00]
137;
138; SKYLAKE-LABEL: test_ctlz_i64:
139; SKYLAKE:       # %bb.0:
140; SKYLAKE-NEXT:    lzcntq (%rsi), %rcx # sched: [8:1.00]
141; SKYLAKE-NEXT:    lzcntq %rdi, %rax # sched: [3:1.00]
142; SKYLAKE-NEXT:    orq %rcx, %rax # sched: [1:0.25]
143; SKYLAKE-NEXT:    retq # sched: [7:1.00]
144;
145; BTVER2-LABEL: test_ctlz_i64:
146; BTVER2:       # %bb.0:
147; BTVER2-NEXT:    lzcntq (%rsi), %rcx # sched: [4:1.00]
148; BTVER2-NEXT:    lzcntq %rdi, %rax # sched: [1:0.50]
149; BTVER2-NEXT:    orq %rcx, %rax # sched: [1:0.50]
150; BTVER2-NEXT:    retq # sched: [4:1.00]
151;
152; ZNVER1-LABEL: test_ctlz_i64:
153; ZNVER1:       # %bb.0:
154; ZNVER1-NEXT:    lzcntq (%rsi), %rcx # sched: [6:0.50]
155; ZNVER1-NEXT:    lzcntq %rdi, %rax # sched: [2:0.25]
156; ZNVER1-NEXT:    orq %rcx, %rax # sched: [1:0.25]
157; ZNVER1-NEXT:    retq # sched: [1:0.50]
158  %1 = load i64, i64 *%a1
159  %2 = tail call i64 @llvm.ctlz.i64( i64 %1, i1 false )
160  %3 = tail call i64 @llvm.ctlz.i64( i64 %a0, i1 false )
161  %4 = or i64 %2, %3
162  ret i64 %4
163}
164declare i64 @llvm.ctlz.i64(i64, i1)
165