Home | History | Annotate | Download | only in X86
      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 
    160