59d67928c6fad043620eda0be20f15f9d5bbccc5
[oota-llvm.git] / test / CodeGen / X86 / vector-ctpop.ll
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=avx2                | FileCheck -check-prefix=AVX2 %s
2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=avx  -mattr=-popcnt | FileCheck -check-prefix=AVX1-NOPOPCNT %s
3 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=avx2 -mattr=-popcnt | FileCheck -check-prefix=AVX2-NOPOPCNT %s
4
5 ; Vector version of:
6 ; v = v - ((v >> 1) & 0x55555555)
7 ; v = (v & 0x33333333) + ((v >> 2) & 0x33333333)
8 ; v = (v + (v >> 4) & 0xF0F0F0F)
9 ; v = v + (v >> 8)
10 ; v = v + (v >> 16)
11 ; v = v + (v >> 32) ; i64 only
12
13 define <8 x i32> @test0(<8 x i32> %x) {
14 ; AVX2-LABEL: @test0
15 entry:
16 ; AVX2:  vpsrld  $1, %ymm
17 ; AVX2-NEXT:  vpbroadcastd
18 ; AVX2-NEXT:  vpand
19 ; AVX2-NEXT:  vpsubd
20 ; AVX2-NEXT:  vpbroadcastd
21 ; AVX2-NEXT:  vpand
22 ; AVX2-NEXT:  vpsrld  $2
23 ; AVX2-NEXT:  vpand
24 ; AVX2-NEXT:  vpaddd
25 ; AVX2-NEXT:  vpsrld  $4
26 ; AVX2-NEXT:  vpaddd
27 ; AVX2-NEXT:  vpbroadcastd
28 ; AVX2-NEXT:    vpand
29 ; AVX2-NEXT:    vpsrld  $8
30 ; AVX2-NEXT:    vpaddd
31 ; AVX2-NEXT:    vpsrld  $16
32 ; AVX2-NEXT:    vpaddd
33 ; AVX2-NEXT:    vpbroadcastd
34 ; AVX2-NEXT:    vpand
35   %y = call <8 x i32> @llvm.ctpop.v8i32(<8 x i32> %x)
36   ret <8 x i32> %y
37 }
38
39 define <4 x i64> @test1(<4 x i64> %x) {
40 ; AVX2-NOPOPCNT-LABEL: @test1
41 entry:
42 ;       AVX2-NOPOPCNT: vpsrlq   $1, %ymm
43 ;       AVX2-NOPOPCNT-NEXT: vpbroadcastq
44 ;       AVX2-NOPOPCNT-NEXT: vpand
45 ;       AVX2-NOPOPCNT-NEXT: vpsubq
46 ;       AVX2-NOPOPCNT-NEXT: vpbroadcastq
47 ;       AVX2-NOPOPCNT-NEXT: vpand
48 ;       AVX2-NOPOPCNT-NEXT: vpsrlq      $2
49 ;       AVX2-NOPOPCNT-NEXT: vpand
50 ;       AVX2-NOPOPCNT-NEXT: vpaddq
51 ;       AVX2-NOPOPCNT-NEXT: vpsrlq      $4
52 ;       AVX2-NOPOPCNT-NEXT: vpaddq
53 ;       AVX2-NOPOPCNT-NEXT: vpbroadcastq
54 ;       AVX2-NOPOPCNT-NEXT: vpand
55 ;       AVX2-NOPOPCNT-NEXT: vpsrlq      $8
56 ;       AVX2-NOPOPCNT-NEXT: vpaddq
57 ;       AVX2-NOPOPCNT-NEXT: vpsrlq      $16
58 ;       AVX2-NOPOPCNT-NEXT: vpaddq
59 ;       AVX2-NOPOPCNT-NEXT: vpsrlq      $32
60 ;       AVX2-NOPOPCNT-NEXT: vpaddq
61 ;       AVX2-NOPOPCNT-NEXT: vpbroadcastq
62 ;       AVX2-NOPOPCNT-NEXT: vpand
63   %y = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %x)
64   ret <4 x i64> %y
65 }
66
67 define <4 x i32> @test2(<4 x i32> %x) {
68 ; AVX2-NOPOPCNT-LABEL: @test2
69 ; AVX1-NOPOPCNT-LABEL: @test2
70 entry:
71 ; AVX2-NOPOPCNT:        vpsrld  $1, %xmm
72 ; AVX2-NOPOPCNT-NEXT:   vpbroadcastd
73 ; AVX2-NOPOPCNT-NEXT:   vpand
74 ; AVX2-NOPOPCNT-NEXT:   vpsubd
75 ; AVX2-NOPOPCNT-NEXT:   vpbroadcastd
76 ; AVX2-NOPOPCNT-NEXT:   vpand
77 ; AVX2-NOPOPCNT-NEXT:   vpsrld  $2
78 ; AVX2-NOPOPCNT-NEXT:   vpand
79 ; AVX2-NOPOPCNT-NEXT:   vpaddd
80 ; AVX2-NOPOPCNT-NEXT:   vpsrld  $4
81 ; AVX2-NOPOPCNT-NEXT:   vpaddd
82 ; AVX2-NOPOPCNT-NEXT:   vpbroadcastd
83 ; AVX2-NOPOPCNT-NEXT:   vpand
84 ; AVX2-NOPOPCNT-NEXT:   vpsrld  $8
85 ; AVX2-NOPOPCNT-NEXT:   vpaddd
86 ; AVX2-NOPOPCNT-NEXT:   vpsrld  $16
87 ; AVX2-NOPOPCNT-NEXT:   vpaddd
88 ; AVX2-NOPOPCNT-NEXT:   vpbroadcastd
89 ; AVX2-NOPOPCNT-NEXT:   vpand
90 ; AVX1-NOPOPCNT:        vpsrld  $1, %xmm
91 ; AVX1-NOPOPCNT-NEXT:   vpand
92 ; AVX1-NOPOPCNT-NEXT:   vpsubd
93 ; AVX1-NOPOPCNT-NEXT:   vmovdqa
94 ; AVX1-NOPOPCNT-NEXT:   vpand
95 ; AVX1-NOPOPCNT-NEXT:   vpsrld  $2
96 ; AVX1-NOPOPCNT-NEXT:   vpand
97 ; AVX1-NOPOPCNT-NEXT:   vpaddd
98 ; AVX1-NOPOPCNT-NEXT:   vpsrld  $4
99 ; AVX1-NOPOPCNT-NEXT:   vpaddd
100 ; AVX1-NOPOPCNT-NEXT:   vpand
101 ; AVX1-NOPOPCNT-NEXT:   vpsrld  $8
102 ; AVX1-NOPOPCNT-NEXT:   vpaddd
103 ; AVX1-NOPOPCNT-NEXT:   vpsrld  $16
104 ; AVX1-NOPOPCNT-NEXT:   vpaddd
105 ; AVX1-NOPOPCNT-NEXT:   vpand
106   %y = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %x)
107   ret <4 x i32> %y
108 }
109
110 define <2 x i64> @test3(<2 x i64> %x) {
111 ; AVX2-NOPOPCNT-LABEL: @test3
112 ; AVX1-NOPOPCNT-LABEL: @test3
113 entry:
114 ; AVX2-NOPOPCNT:        vpsrlq  $1, %xmm
115 ; AVX2-NOPOPCNT-NEXT:   vpand
116 ; AVX2-NOPOPCNT-NEXT:   vpsubq
117 ; AVX2-NOPOPCNT-NEXT:   vmovdqa
118 ; AVX2-NOPOPCNT-NEXT:   vpand
119 ; AVX2-NOPOPCNT-NEXT:   vpsrlq  $2
120 ; AVX2-NOPOPCNT-NEXT:   vpand
121 ; AVX2-NOPOPCNT-NEXT:   vpaddq
122 ; AVX2-NOPOPCNT-NEXT:   vpsrlq  $4
123 ; AVX2-NOPOPCNT-NEXT:   vpaddq
124 ; AVX2-NOPOPCNT-NEXT:   vpand
125 ; AVX2-NOPOPCNT-NEXT:   vpsrlq  $8
126 ; AVX2-NOPOPCNT-NEXT:   vpaddq
127 ; AVX2-NOPOPCNT-NEXT:   vpsrlq  $16
128 ; AVX2-NOPOPCNT-NEXT:   vpaddq
129 ; AVX2-NOPOPCNT-NEXT:   vpsrlq  $32
130 ; AVX2-NOPOPCNT-NEXT:   vpaddq
131 ; AVX2-NOPOPCNT-NEXT:   vpand
132 ; AVX1-NOPOPCNT:        vpsrlq  $1, %xmm
133 ; AVX1-NOPOPCNT-NEXT:   vpand
134 ; AVX1-NOPOPCNT-NEXT:   vpsubq
135 ; AVX1-NOPOPCNT-NEXT:   vmovdqa
136 ; AVX1-NOPOPCNT-NEXT:   vpand
137 ; AVX1-NOPOPCNT-NEXT:   vpsrlq  $2
138 ; AVX1-NOPOPCNT-NEXT:   vpand
139 ; AVX1-NOPOPCNT-NEXT:   vpaddq
140 ; AVX1-NOPOPCNT-NEXT:   vpsrlq  $4
141 ; AVX1-NOPOPCNT-NEXT:   vpaddq
142 ; AVX1-NOPOPCNT-NEXT:   vpand
143 ; AVX1-NOPOPCNT-NEXT:   vpsrlq  $8
144 ; AVX1-NOPOPCNT-NEXT:   vpaddq
145 ; AVX1-NOPOPCNT-NEXT:   vpsrlq  $16
146 ; AVX1-NOPOPCNT-NEXT:   vpaddq
147 ; AVX1-NOPOPCNT-NEXT:   vpsrlq  $32
148 ; AVX1-NOPOPCNT-NEXT:   vpaddq
149 ; AVX1-NOPOPCNT-NEXT:   vpand
150   %y = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %x)
151   ret <2 x i64> %y
152 }
153
154 declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>)
155 declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>)
156
157 declare <8 x i32> @llvm.ctpop.v8i32(<8 x i32>)
158 declare <4 x i64> @llvm.ctpop.v4i64(<4 x i64>)
159