264 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 22; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,CHECK-NOBMI3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2,+bmi2,+bmi | FileCheck %s --check-prefixes=CHECK,CHECK-BMI2,CHECK-AVX24; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+avx512vl,+avx512vpopcntdq,+bmi2,+bmi | FileCheck %s --check-prefixes=CHECK,CHECK-BMI2,CHECK-AVX5125 6declare i32 @llvm.ctpop.i32(i32)7declare <4 x i64> @llvm.ctpop.v4i64(<4 x i64>)8define i1 @is_pow2_non_zero(i32 %xin) {9; CHECK-NOBMI-LABEL: is_pow2_non_zero:10; CHECK-NOBMI: # %bb.0:11; CHECK-NOBMI-NEXT: # kill: def $edi killed $edi def $rdi12; CHECK-NOBMI-NEXT: orl $256, %edi # imm = 0x10013; CHECK-NOBMI-NEXT: leal -1(%rdi), %eax14; CHECK-NOBMI-NEXT: testl %eax, %edi15; CHECK-NOBMI-NEXT: sete %al16; CHECK-NOBMI-NEXT: retq17;18; CHECK-BMI2-LABEL: is_pow2_non_zero:19; CHECK-BMI2: # %bb.0:20; CHECK-BMI2-NEXT: orl $256, %edi # imm = 0x10021; CHECK-BMI2-NEXT: blsrl %edi, %eax22; CHECK-BMI2-NEXT: sete %al23; CHECK-BMI2-NEXT: retq24 %x = or i32 %xin, 25625 %cnt = call i32 @llvm.ctpop.i32(i32 %x)26 %r = icmp eq i32 %cnt, 127 ret i1 %r28}29 30define i1 @is_pow2_non_zero_x_maybe_z(i32 %x) {31; CHECK-LABEL: is_pow2_non_zero_x_maybe_z:32; CHECK: # %bb.0:33; CHECK-NEXT: # kill: def $edi killed $edi def $rdi34; CHECK-NEXT: leal -1(%rdi), %eax35; CHECK-NEXT: xorl %eax, %edi36; CHECK-NEXT: cmpl %eax, %edi37; CHECK-NEXT: seta %al38; CHECK-NEXT: retq39 %cnt = call i32 @llvm.ctpop.i32(i32 %x)40 %r = icmp eq i32 %cnt, 141 ret i1 %r42}43 44define i1 @neither_pow2_non_zero(i32 %xin) {45; CHECK-NOBMI-LABEL: neither_pow2_non_zero:46; CHECK-NOBMI: # %bb.0:47; CHECK-NOBMI-NEXT: # kill: def $edi killed $edi def $rdi48; CHECK-NOBMI-NEXT: orl $256, %edi # imm = 0x10049; CHECK-NOBMI-NEXT: leal -1(%rdi), %eax50; CHECK-NOBMI-NEXT: testl %eax, %edi51; CHECK-NOBMI-NEXT: setne %al52; CHECK-NOBMI-NEXT: retq53;54; CHECK-BMI2-LABEL: neither_pow2_non_zero:55; CHECK-BMI2: # %bb.0:56; CHECK-BMI2-NEXT: orl $256, %edi # imm = 0x10057; CHECK-BMI2-NEXT: blsrl %edi, %eax58; CHECK-BMI2-NEXT: setne %al59; CHECK-BMI2-NEXT: retq60 %x = or i32 %xin, 25661 %cnt = call i32 @llvm.ctpop.i32(i32 %x)62 %r = icmp ne i32 %cnt, 163 ret i1 %r64}65 66define <4 x i1> @is_pow2_non_zero_4xv64(<4 x i64> %xin) {67; CHECK-NOBMI-LABEL: is_pow2_non_zero_4xv64:68; CHECK-NOBMI: # %bb.0:69; CHECK-NOBMI-NEXT: movdqa {{.*#+}} xmm2 = [256,256]70; CHECK-NOBMI-NEXT: por %xmm2, %xmm071; CHECK-NOBMI-NEXT: por %xmm2, %xmm172; CHECK-NOBMI-NEXT: pcmpeqd %xmm2, %xmm273; CHECK-NOBMI-NEXT: movdqa %xmm1, %xmm374; CHECK-NOBMI-NEXT: paddq %xmm2, %xmm375; CHECK-NOBMI-NEXT: paddq %xmm0, %xmm276; CHECK-NOBMI-NEXT: pand %xmm2, %xmm077; CHECK-NOBMI-NEXT: pand %xmm1, %xmm378; CHECK-NOBMI-NEXT: pxor %xmm1, %xmm179; CHECK-NOBMI-NEXT: pcmpeqd %xmm1, %xmm380; CHECK-NOBMI-NEXT: pcmpeqd %xmm1, %xmm081; CHECK-NOBMI-NEXT: movdqa %xmm0, %xmm182; CHECK-NOBMI-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,3],xmm3[1,3]83; CHECK-NOBMI-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm3[0,2]84; CHECK-NOBMI-NEXT: andps %xmm1, %xmm085; CHECK-NOBMI-NEXT: retq86;87; CHECK-AVX2-LABEL: is_pow2_non_zero_4xv64:88; CHECK-AVX2: # %bb.0:89; CHECK-AVX2-NEXT: vpbroadcastq {{.*#+}} ymm1 = [256,256,256,256]90; CHECK-AVX2-NEXT: vpor %ymm1, %ymm0, %ymm091; CHECK-AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm192; CHECK-AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm193; CHECK-AVX2-NEXT: vpand %ymm1, %ymm0, %ymm094; CHECK-AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm195; CHECK-AVX2-NEXT: vpcmpeqq %ymm1, %ymm0, %ymm096; CHECK-AVX2-NEXT: vextracti128 $1, %ymm0, %xmm197; CHECK-AVX2-NEXT: vpackssdw %xmm1, %xmm0, %xmm098; CHECK-AVX2-NEXT: vzeroupper99; CHECK-AVX2-NEXT: retq100;101; CHECK-AVX512-LABEL: is_pow2_non_zero_4xv64:102; CHECK-AVX512: # %bb.0:103; CHECK-AVX512-NEXT: vporq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %ymm0104; CHECK-AVX512-NEXT: vpopcntq %ymm0, %ymm0105; CHECK-AVX512-NEXT: vpcmpltq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %k1106; CHECK-AVX512-NEXT: vpcmpeqd %xmm0, %xmm0, %xmm0107; CHECK-AVX512-NEXT: vmovdqa32 %xmm0, %xmm0 {%k1} {z}108; CHECK-AVX512-NEXT: vzeroupper109; CHECK-AVX512-NEXT: retq110 %x = or <4 x i64> %xin, <i64 256, i64 256, i64 256, i64 256>111 %cnt = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %x)112 %r = icmp eq <4 x i64> %cnt, <i64 1, i64 1, i64 1, i64 1>113 ret <4 x i1> %r114}115 116define <4 x i1> @neither_pow2_non_zero_4xv64(<4 x i64> %xin) {117; CHECK-NOBMI-LABEL: neither_pow2_non_zero_4xv64:118; CHECK-NOBMI: # %bb.0:119; CHECK-NOBMI-NEXT: movdqa {{.*#+}} xmm2 = [256,256]120; CHECK-NOBMI-NEXT: por %xmm2, %xmm0121; CHECK-NOBMI-NEXT: por %xmm2, %xmm1122; CHECK-NOBMI-NEXT: pcmpeqd %xmm2, %xmm2123; CHECK-NOBMI-NEXT: movdqa %xmm1, %xmm3124; CHECK-NOBMI-NEXT: paddq %xmm2, %xmm3125; CHECK-NOBMI-NEXT: movdqa %xmm0, %xmm4126; CHECK-NOBMI-NEXT: paddq %xmm2, %xmm4127; CHECK-NOBMI-NEXT: pand %xmm4, %xmm0128; CHECK-NOBMI-NEXT: pand %xmm1, %xmm3129; CHECK-NOBMI-NEXT: pxor %xmm1, %xmm1130; CHECK-NOBMI-NEXT: pcmpeqd %xmm1, %xmm3131; CHECK-NOBMI-NEXT: pcmpeqd %xmm1, %xmm0132; CHECK-NOBMI-NEXT: movdqa %xmm0, %xmm1133; CHECK-NOBMI-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,3],xmm3[1,3]134; CHECK-NOBMI-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm3[0,2]135; CHECK-NOBMI-NEXT: andps %xmm1, %xmm0136; CHECK-NOBMI-NEXT: xorps %xmm2, %xmm0137; CHECK-NOBMI-NEXT: retq138;139; CHECK-AVX2-LABEL: neither_pow2_non_zero_4xv64:140; CHECK-AVX2: # %bb.0:141; CHECK-AVX2-NEXT: vpbroadcastq {{.*#+}} ymm1 = [256,256,256,256]142; CHECK-AVX2-NEXT: vpor %ymm1, %ymm0, %ymm0143; CHECK-AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1144; CHECK-AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm2145; CHECK-AVX2-NEXT: vpand %ymm2, %ymm0, %ymm0146; CHECK-AVX2-NEXT: vpxor %xmm2, %xmm2, %xmm2147; CHECK-AVX2-NEXT: vpcmpeqq %ymm2, %ymm0, %ymm0148; CHECK-AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0149; CHECK-AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1150; CHECK-AVX2-NEXT: vpackssdw %xmm1, %xmm0, %xmm0151; CHECK-AVX2-NEXT: vzeroupper152; CHECK-AVX2-NEXT: retq153;154; CHECK-AVX512-LABEL: neither_pow2_non_zero_4xv64:155; CHECK-AVX512: # %bb.0:156; CHECK-AVX512-NEXT: vporq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %ymm0157; CHECK-AVX512-NEXT: vpopcntq %ymm0, %ymm0158; CHECK-AVX512-NEXT: vpcmpgtq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %k1159; CHECK-AVX512-NEXT: vpcmpeqd %xmm0, %xmm0, %xmm0160; CHECK-AVX512-NEXT: vmovdqa32 %xmm0, %xmm0 {%k1} {z}161; CHECK-AVX512-NEXT: vzeroupper162; CHECK-AVX512-NEXT: retq163 %x = or <4 x i64> %xin, <i64 256, i64 256, i64 256, i64 256>164 %cnt = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %x)165 %r = icmp ne <4 x i64> %cnt, <i64 1, i64 1, i64 1, i64 1>166 ret <4 x i1> %r167}168 169define <4 x i1> @neither_pow2_non_zero_4xv64_x_maybe_z(<4 x i64> %x) {170; CHECK-NOBMI-LABEL: neither_pow2_non_zero_4xv64_x_maybe_z:171; CHECK-NOBMI: # %bb.0:172; CHECK-NOBMI-NEXT: pcmpeqd %xmm2, %xmm2173; CHECK-NOBMI-NEXT: movdqa %xmm0, %xmm3174; CHECK-NOBMI-NEXT: paddq %xmm2, %xmm3175; CHECK-NOBMI-NEXT: movdqa %xmm1, %xmm4176; CHECK-NOBMI-NEXT: paddq %xmm2, %xmm4177; CHECK-NOBMI-NEXT: movdqa {{.*#+}} xmm5 = [9223372039002259456,9223372039002259456]178; CHECK-NOBMI-NEXT: pxor %xmm5, %xmm4179; CHECK-NOBMI-NEXT: pxor %xmm4, %xmm1180; CHECK-NOBMI-NEXT: movdqa %xmm1, %xmm6181; CHECK-NOBMI-NEXT: pcmpgtd %xmm4, %xmm6182; CHECK-NOBMI-NEXT: pxor %xmm5, %xmm3183; CHECK-NOBMI-NEXT: pxor %xmm3, %xmm0184; CHECK-NOBMI-NEXT: movdqa %xmm0, %xmm5185; CHECK-NOBMI-NEXT: pcmpgtd %xmm3, %xmm5186; CHECK-NOBMI-NEXT: movdqa %xmm5, %xmm7187; CHECK-NOBMI-NEXT: shufps {{.*#+}} xmm7 = xmm7[0,2],xmm6[0,2]188; CHECK-NOBMI-NEXT: pcmpeqd %xmm4, %xmm1189; CHECK-NOBMI-NEXT: pcmpeqd %xmm3, %xmm0190; CHECK-NOBMI-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3]191; CHECK-NOBMI-NEXT: andps %xmm7, %xmm0192; CHECK-NOBMI-NEXT: shufps {{.*#+}} xmm5 = xmm5[1,3],xmm6[1,3]193; CHECK-NOBMI-NEXT: orps %xmm5, %xmm0194; CHECK-NOBMI-NEXT: xorps %xmm2, %xmm0195; CHECK-NOBMI-NEXT: retq196;197; CHECK-AVX2-LABEL: neither_pow2_non_zero_4xv64_x_maybe_z:198; CHECK-AVX2: # %bb.0:199; CHECK-AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1200; CHECK-AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm2201; CHECK-AVX2-NEXT: vpbroadcastq {{.*#+}} ymm3 = [9223372036854775808,9223372036854775808,9223372036854775808,9223372036854775808]202; CHECK-AVX2-NEXT: vpxor %ymm3, %ymm2, %ymm2203; CHECK-AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0204; CHECK-AVX2-NEXT: vpcmpgtq %ymm2, %ymm0, %ymm0205; CHECK-AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0206; CHECK-AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1207; CHECK-AVX2-NEXT: vpackssdw %xmm1, %xmm0, %xmm0208; CHECK-AVX2-NEXT: vzeroupper209; CHECK-AVX2-NEXT: retq210;211; CHECK-AVX512-LABEL: neither_pow2_non_zero_4xv64_x_maybe_z:212; CHECK-AVX512: # %bb.0:213; CHECK-AVX512-NEXT: vpopcntq %ymm0, %ymm0214; CHECK-AVX512-NEXT: vpcmpneqq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %k1215; CHECK-AVX512-NEXT: vpcmpeqd %xmm0, %xmm0, %xmm0216; CHECK-AVX512-NEXT: vmovdqa32 %xmm0, %xmm0 {%k1} {z}217; CHECK-AVX512-NEXT: vzeroupper218; CHECK-AVX512-NEXT: retq219 %cnt = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %x)220 %r = icmp ne <4 x i64> %cnt, <i64 1, i64 1, i64 1, i64 1>221 ret <4 x i1> %r222}223 224 225define i1 @ctpop32_eq_one_nonzero(i32 %x) {226; CHECK-NOBMI-LABEL: ctpop32_eq_one_nonzero:227; CHECK-NOBMI: # %bb.0: # %entry228; CHECK-NOBMI-NEXT: # kill: def $edi killed $edi def $rdi229; CHECK-NOBMI-NEXT: leal -1(%rdi), %eax230; CHECK-NOBMI-NEXT: testl %eax, %edi231; CHECK-NOBMI-NEXT: sete %al232; CHECK-NOBMI-NEXT: retq233;234; CHECK-BMI2-LABEL: ctpop32_eq_one_nonzero:235; CHECK-BMI2: # %bb.0: # %entry236; CHECK-BMI2-NEXT: blsrl %edi, %eax237; CHECK-BMI2-NEXT: sete %al238; CHECK-BMI2-NEXT: retq239entry:240 %popcnt = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)241 %cmp = icmp eq i32 %popcnt, 1242 ret i1 %cmp243}244 245define i1 @ctpop32_ne_one_nonzero(i32 %x) {246; CHECK-NOBMI-LABEL: ctpop32_ne_one_nonzero:247; CHECK-NOBMI: # %bb.0: # %entry248; CHECK-NOBMI-NEXT: # kill: def $edi killed $edi def $rdi249; CHECK-NOBMI-NEXT: leal -1(%rdi), %eax250; CHECK-NOBMI-NEXT: testl %eax, %edi251; CHECK-NOBMI-NEXT: setne %al252; CHECK-NOBMI-NEXT: retq253;254; CHECK-BMI2-LABEL: ctpop32_ne_one_nonzero:255; CHECK-BMI2: # %bb.0: # %entry256; CHECK-BMI2-NEXT: blsrl %edi, %eax257; CHECK-BMI2-NEXT: setne %al258; CHECK-BMI2-NEXT: retq259entry:260 %popcnt = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)261 %cmp = icmp ne i32 %popcnt, 1262 ret i1 %cmp263}264