227 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=CHECK,VTEST,VTEST-AVX13; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=CHECK,VTEST,VTEST-AVX24; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,+prefer-movmsk-over-vtest | FileCheck %s --check-prefixes=CHECK,MOVMSK,MOVMSK-AVX15; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2,+prefer-movmsk-over-vtest | FileCheck %s --check-prefixes=CHECK,MOVMSK,MOVMSK-AVX26 7declare i32 @llvm.x86.avx.movmsk.pd.256(<4 x double>)8declare i32 @llvm.x86.avx.movmsk.ps.256(<8 x float>)9 10; Use widest possible vector for movmsk comparisons (PR37087)11 12define i1 @movmskps_noneof_bitcast_v4f64(<4 x double> %a0) {13; VTEST-LABEL: movmskps_noneof_bitcast_v4f64:14; VTEST: # %bb.0:15; VTEST-NEXT: vxorpd %xmm1, %xmm1, %xmm116; VTEST-NEXT: vcmpeqpd %ymm1, %ymm0, %ymm017; VTEST-NEXT: vtestpd %ymm0, %ymm018; VTEST-NEXT: sete %al19; VTEST-NEXT: vzeroupper20; VTEST-NEXT: retq21;22; MOVMSK-LABEL: movmskps_noneof_bitcast_v4f64:23; MOVMSK: # %bb.0:24; MOVMSK-NEXT: vxorpd %xmm1, %xmm1, %xmm125; MOVMSK-NEXT: vcmpeqpd %ymm1, %ymm0, %ymm026; MOVMSK-NEXT: vmovmskpd %ymm0, %eax27; MOVMSK-NEXT: testl %eax, %eax28; MOVMSK-NEXT: sete %al29; MOVMSK-NEXT: vzeroupper30; MOVMSK-NEXT: retq31 %1 = fcmp oeq <4 x double> %a0, zeroinitializer32 %2 = sext <4 x i1> %1 to <4 x i64>33 %3 = bitcast <4 x i64> %2 to <8 x float>34 %4 = tail call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %3)35 %5 = icmp eq i32 %4, 036 ret i1 %537}38 39define i1 @movmskps_allof_bitcast_v4f64(<4 x double> %a0) {40; VTEST-AVX1-LABEL: movmskps_allof_bitcast_v4f64:41; VTEST-AVX1: # %bb.0:42; VTEST-AVX1-NEXT: vxorpd %xmm1, %xmm1, %xmm143; VTEST-AVX1-NEXT: vcmpeqpd %ymm1, %ymm0, %ymm044; VTEST-AVX1-NEXT: vcmptrueps %ymm1, %ymm1, %ymm145; VTEST-AVX1-NEXT: vtestpd %ymm1, %ymm046; VTEST-AVX1-NEXT: setb %al47; VTEST-AVX1-NEXT: vzeroupper48; VTEST-AVX1-NEXT: retq49;50; VTEST-AVX2-LABEL: movmskps_allof_bitcast_v4f64:51; VTEST-AVX2: # %bb.0:52; VTEST-AVX2-NEXT: vxorpd %xmm1, %xmm1, %xmm153; VTEST-AVX2-NEXT: vcmpeqpd %ymm1, %ymm0, %ymm054; VTEST-AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm155; VTEST-AVX2-NEXT: vtestpd %ymm1, %ymm056; VTEST-AVX2-NEXT: setb %al57; VTEST-AVX2-NEXT: vzeroupper58; VTEST-AVX2-NEXT: retq59;60; MOVMSK-LABEL: movmskps_allof_bitcast_v4f64:61; MOVMSK: # %bb.0:62; MOVMSK-NEXT: vxorpd %xmm1, %xmm1, %xmm163; MOVMSK-NEXT: vcmpeqpd %ymm1, %ymm0, %ymm064; MOVMSK-NEXT: vmovmskpd %ymm0, %eax65; MOVMSK-NEXT: cmpl $15, %eax66; MOVMSK-NEXT: sete %al67; MOVMSK-NEXT: vzeroupper68; MOVMSK-NEXT: retq69 %1 = fcmp oeq <4 x double> %a0, zeroinitializer70 %2 = sext <4 x i1> %1 to <4 x i64>71 %3 = bitcast <4 x i64> %2 to <8 x float>72 %4 = tail call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %3)73 %5 = icmp eq i32 %4, 25574 ret i1 %575}76 77;78; Avoid sign extension ops when just extracting the sign bits.79;80 81define i32 @movmskpd_cmpgt_v4i64(<4 x i64> %a0) {82; CHECK-LABEL: movmskpd_cmpgt_v4i64:83; CHECK: # %bb.0:84; CHECK-NEXT: vmovmskpd %ymm0, %eax85; CHECK-NEXT: vzeroupper86; CHECK-NEXT: retq87 %1 = icmp sgt <4 x i64> zeroinitializer, %a088 %2 = sext <4 x i1> %1 to <4 x i64>89 %3 = bitcast <4 x i64> %2 to <4 x double>90 %4 = tail call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> %3)91 ret i32 %492}93 94define i32 @movmskps_ashr_v8i32(<8 x i32> %a0) {95; CHECK-LABEL: movmskps_ashr_v8i32:96; CHECK: # %bb.0:97; CHECK-NEXT: vmovmskps %ymm0, %eax98; CHECK-NEXT: vzeroupper99; CHECK-NEXT: retq100 %1 = ashr <8 x i32> %a0, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>101 %2 = bitcast <8 x i32> %1 to <8 x float>102 %3 = tail call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %2)103 ret i32 %3104}105 106define i32 @movmskps_sext_v4i64(<4 x i32> %a0) {107; VTEST-AVX1-LABEL: movmskps_sext_v4i64:108; VTEST-AVX1: # %bb.0:109; VTEST-AVX1-NEXT: vpmovsxdq %xmm0, %xmm1110; VTEST-AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]111; VTEST-AVX1-NEXT: vpmovsxdq %xmm0, %xmm0112; VTEST-AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0113; VTEST-AVX1-NEXT: vmovmskpd %ymm0, %eax114; VTEST-AVX1-NEXT: vzeroupper115; VTEST-AVX1-NEXT: retq116;117; VTEST-AVX2-LABEL: movmskps_sext_v4i64:118; VTEST-AVX2: # %bb.0:119; VTEST-AVX2-NEXT: vpmovsxdq %xmm0, %ymm0120; VTEST-AVX2-NEXT: vmovmskpd %ymm0, %eax121; VTEST-AVX2-NEXT: vzeroupper122; VTEST-AVX2-NEXT: retq123;124; MOVMSK-AVX1-LABEL: movmskps_sext_v4i64:125; MOVMSK-AVX1: # %bb.0:126; MOVMSK-AVX1-NEXT: vpmovsxdq %xmm0, %xmm1127; MOVMSK-AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]128; MOVMSK-AVX1-NEXT: vpmovsxdq %xmm0, %xmm0129; MOVMSK-AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0130; MOVMSK-AVX1-NEXT: vmovmskpd %ymm0, %eax131; MOVMSK-AVX1-NEXT: vzeroupper132; MOVMSK-AVX1-NEXT: retq133;134; MOVMSK-AVX2-LABEL: movmskps_sext_v4i64:135; MOVMSK-AVX2: # %bb.0:136; MOVMSK-AVX2-NEXT: vpmovsxdq %xmm0, %ymm0137; MOVMSK-AVX2-NEXT: vmovmskpd %ymm0, %eax138; MOVMSK-AVX2-NEXT: vzeroupper139; MOVMSK-AVX2-NEXT: retq140 %1 = sext <4 x i32> %a0 to <4 x i64>141 %2 = bitcast <4 x i64> %1 to <4 x double>142 %3 = tail call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> %2)143 ret i32 %3144}145 146define i32 @movmskps_sext_v8i32(<8 x i16> %a0) {147; VTEST-AVX1-LABEL: movmskps_sext_v8i32:148; VTEST-AVX1: # %bb.0:149; VTEST-AVX1-NEXT: vpmovsxwd %xmm0, %xmm1150; VTEST-AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]151; VTEST-AVX1-NEXT: vpmovsxwd %xmm0, %xmm0152; VTEST-AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0153; VTEST-AVX1-NEXT: vmovmskps %ymm0, %eax154; VTEST-AVX1-NEXT: vzeroupper155; VTEST-AVX1-NEXT: retq156;157; VTEST-AVX2-LABEL: movmskps_sext_v8i32:158; VTEST-AVX2: # %bb.0:159; VTEST-AVX2-NEXT: vpmovsxwd %xmm0, %ymm0160; VTEST-AVX2-NEXT: vmovmskps %ymm0, %eax161; VTEST-AVX2-NEXT: vzeroupper162; VTEST-AVX2-NEXT: retq163;164; MOVMSK-AVX1-LABEL: movmskps_sext_v8i32:165; MOVMSK-AVX1: # %bb.0:166; MOVMSK-AVX1-NEXT: vpmovsxwd %xmm0, %xmm1167; MOVMSK-AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]168; MOVMSK-AVX1-NEXT: vpmovsxwd %xmm0, %xmm0169; MOVMSK-AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0170; MOVMSK-AVX1-NEXT: vmovmskps %ymm0, %eax171; MOVMSK-AVX1-NEXT: vzeroupper172; MOVMSK-AVX1-NEXT: retq173;174; MOVMSK-AVX2-LABEL: movmskps_sext_v8i32:175; MOVMSK-AVX2: # %bb.0:176; MOVMSK-AVX2-NEXT: vpmovsxwd %xmm0, %ymm0177; MOVMSK-AVX2-NEXT: vmovmskps %ymm0, %eax178; MOVMSK-AVX2-NEXT: vzeroupper179; MOVMSK-AVX2-NEXT: retq180 %1 = sext <8 x i16> %a0 to <8 x i32>181 %2 = bitcast <8 x i32> %1 to <8 x float>182 %3 = tail call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %2)183 ret i32 %3184}185 186define i32 @movmskps_concat_v4f32(<4 x float> %a0, <4 x float> %a1) {187; VTEST-LABEL: movmskps_concat_v4f32:188; VTEST: # %bb.0:189; VTEST-NEXT: vorps %xmm1, %xmm0, %xmm0190; VTEST-NEXT: xorl %eax, %eax191; VTEST-NEXT: vtestps %xmm0, %xmm0192; VTEST-NEXT: setne %al193; VTEST-NEXT: negl %eax194; VTEST-NEXT: retq195;196; MOVMSK-LABEL: movmskps_concat_v4f32:197; MOVMSK: # %bb.0:198; MOVMSK-NEXT: vorps %xmm1, %xmm0, %xmm0199; MOVMSK-NEXT: vmovmskps %xmm0, %ecx200; MOVMSK-NEXT: xorl %eax, %eax201; MOVMSK-NEXT: negl %ecx202; MOVMSK-NEXT: sbbl %eax, %eax203; MOVMSK-NEXT: retq204 %1 = shufflevector <4 x float> %a0, <4 x float> %a1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>205 %2 = tail call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %1)206 %3 = icmp ne i32 %2, 0207 %4 = sext i1 %3 to i32208 ret i32 %4209}210 211define i32 @movmskps_demanded_concat_v4f32(<4 x float> %a0, <4 x float> %a1) {212; CHECK-LABEL: movmskps_demanded_concat_v4f32:213; CHECK: # %bb.0:214; CHECK-NEXT: vmovmskps %xmm0, %ecx215; CHECK-NEXT: andl $3, %ecx216; CHECK-NEXT: xorl %eax, %eax217; CHECK-NEXT: negl %ecx218; CHECK-NEXT: sbbl %eax, %eax219; CHECK-NEXT: retq220 %1 = shufflevector <4 x float> %a0, <4 x float> %a1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>221 %2 = tail call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %1)222 %3 = and i32 %2, 3223 %4 = icmp ne i32 %3, 0224 %5 = sext i1 %4 to i32225 ret i32 %5226}227