314 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+ssse3 | FileCheck %s --check-prefix=SSE3; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX14; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX25 6; Verify that the following shifts are lowered into a sequence of two shifts plus7; a blend. On pre-avx2 targets, instead of scalarizing logical and arithmetic8; packed shift right by a constant build_vector the backend should always try to9; emit a simpler sequence of two shifts + blend when possible.10 11define <8 x i16> @test1(<8 x i16> %a) {12; SSE-LABEL: test1:13; SSE: # %bb.0:14; SSE-NEXT: movdqa %xmm0, %xmm115; SSE-NEXT: psrlw $3, %xmm116; SSE-NEXT: psrlw $2, %xmm017; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]18; SSE-NEXT: retq19;20; AVX1-LABEL: test1:21; AVX1: # %bb.0:22; AVX1-NEXT: vpsrlw $3, %xmm0, %xmm123; AVX1-NEXT: vpsrlw $2, %xmm0, %xmm024; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]25; AVX1-NEXT: retq26;27; AVX2-LABEL: test1:28; AVX2: # %bb.0:29; AVX2-NEXT: vpsrlw $3, %xmm0, %xmm130; AVX2-NEXT: vpsrlw $2, %xmm0, %xmm031; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]32; AVX2-NEXT: retq33 %lshr = lshr <8 x i16> %a, <i16 3, i16 3, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2>34 ret <8 x i16> %lshr35}36 37define <8 x i16> @test2(<8 x i16> %a) {38; SSE-LABEL: test2:39; SSE: # %bb.0:40; SSE-NEXT: movdqa %xmm0, %xmm141; SSE-NEXT: psrlw $3, %xmm142; SSE-NEXT: psrlw $2, %xmm043; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]44; SSE-NEXT: retq45;46; AVX1-LABEL: test2:47; AVX1: # %bb.0:48; AVX1-NEXT: vpsrlw $2, %xmm0, %xmm149; AVX1-NEXT: vpsrlw $3, %xmm0, %xmm050; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]51; AVX1-NEXT: retq52;53; AVX2-LABEL: test2:54; AVX2: # %bb.0:55; AVX2-NEXT: vpsrlw $2, %xmm0, %xmm156; AVX2-NEXT: vpsrlw $3, %xmm0, %xmm057; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]58; AVX2-NEXT: retq59 %lshr = lshr <8 x i16> %a, <i16 3, i16 3, i16 3, i16 3, i16 2, i16 2, i16 2, i16 2>60 ret <8 x i16> %lshr61}62 63define <4 x i32> @test3(<4 x i32> %a) {64; SSE-LABEL: test3:65; SSE: # %bb.0:66; SSE-NEXT: movdqa %xmm0, %xmm167; SSE-NEXT: psrld $3, %xmm168; SSE-NEXT: psrld $2, %xmm069; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]70; SSE-NEXT: retq71;72; AVX1-LABEL: test3:73; AVX1: # %bb.0:74; AVX1-NEXT: vpsrld $3, %xmm0, %xmm175; AVX1-NEXT: vpsrld $2, %xmm0, %xmm076; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]77; AVX1-NEXT: retq78;79; AVX2-LABEL: test3:80; AVX2: # %bb.0:81; AVX2-NEXT: vpsrlvd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm082; AVX2-NEXT: retq83 %lshr = lshr <4 x i32> %a, <i32 3, i32 2, i32 2, i32 2>84 ret <4 x i32> %lshr85}86 87define <4 x i32> @test4(<4 x i32> %a) {88; SSE-LABEL: test4:89; SSE: # %bb.0:90; SSE-NEXT: movdqa %xmm0, %xmm191; SSE-NEXT: psrld $3, %xmm192; SSE-NEXT: psrld $2, %xmm093; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]94; SSE-NEXT: retq95;96; AVX1-LABEL: test4:97; AVX1: # %bb.0:98; AVX1-NEXT: vpsrld $2, %xmm0, %xmm199; AVX1-NEXT: vpsrld $3, %xmm0, %xmm0100; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]101; AVX1-NEXT: retq102;103; AVX2-LABEL: test4:104; AVX2: # %bb.0:105; AVX2-NEXT: vpsrlvd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0106; AVX2-NEXT: retq107 %lshr = lshr <4 x i32> %a, <i32 3, i32 3, i32 2, i32 2>108 ret <4 x i32> %lshr109}110 111define <8 x i16> @test5(<8 x i16> %a) {112; SSE-LABEL: test5:113; SSE: # %bb.0:114; SSE-NEXT: movdqa %xmm0, %xmm1115; SSE-NEXT: psraw $3, %xmm1116; SSE-NEXT: psraw $2, %xmm0117; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]118; SSE-NEXT: retq119;120; AVX1-LABEL: test5:121; AVX1: # %bb.0:122; AVX1-NEXT: vpsraw $3, %xmm0, %xmm1123; AVX1-NEXT: vpsraw $2, %xmm0, %xmm0124; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]125; AVX1-NEXT: retq126;127; AVX2-LABEL: test5:128; AVX2: # %bb.0:129; AVX2-NEXT: vpsraw $3, %xmm0, %xmm1130; AVX2-NEXT: vpsraw $2, %xmm0, %xmm0131; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]132; AVX2-NEXT: retq133 %lshr = ashr <8 x i16> %a, <i16 3, i16 3, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2>134 ret <8 x i16> %lshr135}136 137define <8 x i16> @test6(<8 x i16> %a) {138; SSE-LABEL: test6:139; SSE: # %bb.0:140; SSE-NEXT: movdqa %xmm0, %xmm1141; SSE-NEXT: psraw $3, %xmm1142; SSE-NEXT: psraw $2, %xmm0143; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]144; SSE-NEXT: retq145;146; AVX1-LABEL: test6:147; AVX1: # %bb.0:148; AVX1-NEXT: vpsraw $2, %xmm0, %xmm1149; AVX1-NEXT: vpsraw $3, %xmm0, %xmm0150; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]151; AVX1-NEXT: retq152;153; AVX2-LABEL: test6:154; AVX2: # %bb.0:155; AVX2-NEXT: vpsraw $2, %xmm0, %xmm1156; AVX2-NEXT: vpsraw $3, %xmm0, %xmm0157; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]158; AVX2-NEXT: retq159 %lshr = ashr <8 x i16> %a, <i16 3, i16 3, i16 3, i16 3, i16 2, i16 2, i16 2, i16 2>160 ret <8 x i16> %lshr161}162 163define <4 x i32> @test7(<4 x i32> %a) {164; SSE-LABEL: test7:165; SSE: # %bb.0:166; SSE-NEXT: movdqa %xmm0, %xmm1167; SSE-NEXT: psrad $3, %xmm1168; SSE-NEXT: psrad $2, %xmm0169; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]170; SSE-NEXT: retq171;172; AVX1-LABEL: test7:173; AVX1: # %bb.0:174; AVX1-NEXT: vpsrad $3, %xmm0, %xmm1175; AVX1-NEXT: vpsrad $2, %xmm0, %xmm0176; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]177; AVX1-NEXT: retq178;179; AVX2-LABEL: test7:180; AVX2: # %bb.0:181; AVX2-NEXT: vpsravd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0182; AVX2-NEXT: retq183 %lshr = ashr <4 x i32> %a, <i32 3, i32 2, i32 2, i32 2>184 ret <4 x i32> %lshr185}186 187define <4 x i32> @test8(<4 x i32> %a) {188; SSE-LABEL: test8:189; SSE: # %bb.0:190; SSE-NEXT: movdqa %xmm0, %xmm1191; SSE-NEXT: psrad $3, %xmm1192; SSE-NEXT: psrad $2, %xmm0193; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]194; SSE-NEXT: retq195;196; AVX1-LABEL: test8:197; AVX1: # %bb.0:198; AVX1-NEXT: vpsrad $2, %xmm0, %xmm1199; AVX1-NEXT: vpsrad $3, %xmm0, %xmm0200; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]201; AVX1-NEXT: retq202;203; AVX2-LABEL: test8:204; AVX2: # %bb.0:205; AVX2-NEXT: vpsravd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0206; AVX2-NEXT: retq207 %lshr = ashr <4 x i32> %a, <i32 3, i32 3, i32 2, i32 2>208 ret <4 x i32> %lshr209}210 211define <8 x i16> @test9(<8 x i16> %a) {212; SSE-LABEL: test9:213; SSE: # %bb.0:214; SSE-NEXT: movdqa %xmm0, %xmm1215; SSE-NEXT: psraw $3, %xmm1216; SSE-NEXT: movdqa {{.*#+}} xmm2 = [65535,0,65535,65535,65535,0,0,0]217; SSE-NEXT: psraw $1, %xmm0218; SSE-NEXT: pand %xmm2, %xmm0219; SSE-NEXT: pandn %xmm1, %xmm2220; SSE-NEXT: por %xmm2, %xmm0221; SSE-NEXT: retq222;223; AVX-LABEL: test9:224; AVX: # %bb.0:225; AVX-NEXT: vpsraw $3, %xmm0, %xmm1226; AVX-NEXT: vpsraw $1, %xmm0, %xmm0227; AVX-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3,4],xmm1[5,6,7]228; AVX-NEXT: retq229 %lshr = ashr <8 x i16> %a, <i16 1, i16 3, i16 1, i16 1, i16 1, i16 3, i16 3, i16 3>230 ret <8 x i16> %lshr231}232 233define <8 x i32> @test10(ptr %a) {234; SSE-LABEL: test10:235; SSE: # %bb.0:236; SSE-NEXT: movdqa (%rdi), %xmm0237; SSE-NEXT: psrad $1, %xmm0238; SSE-NEXT: retq239;240; AVX1-LABEL: test10:241; AVX1: # %bb.0:242; AVX1-NEXT: vmovdqa (%rdi), %xmm0243; AVX1-NEXT: vpsrad $1, %xmm0, %xmm0244; AVX1-NEXT: retq245;246; AVX2-LABEL: test10:247; AVX2: # %bb.0:248; AVX2-NEXT: vmovdqa (%rdi), %ymm0249; AVX2-NEXT: vpsrad $1, %ymm0, %ymm0250; AVX2-NEXT: retq251 %ld = load <8 x i32>, ptr %a, align 32252 %ashr = ashr <8 x i32> %ld, <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>253 ret <8 x i32> %ashr254}255 256; test11 vs test12 - show difference between v16i16 that is repeated/non-repeated at v8i16 level (for PBLENDW masks).257 258define <16 x i16> @test11(<16 x i16> %a) {259; SSE-LABEL: test11:260; SSE: # %bb.0:261; SSE-NEXT: pmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [2,8,2,2,2,8,8,8]262; SSE-NEXT: pmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 # [8,8,8,2,2,2,8,2]263; SSE-NEXT: retq264;265; AVX1-LABEL: test11:266; AVX1: # %bb.0:267; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1268; AVX1-NEXT: vpaddw %xmm1, %xmm1, %xmm2269; AVX1-NEXT: vpsllw $3, %xmm1, %xmm1270; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1,2],xmm2[3,4,5],xmm1[6],xmm2[7]271; AVX1-NEXT: vpsllw $3, %xmm0, %xmm2272; AVX1-NEXT: vpaddw %xmm0, %xmm0, %xmm0273; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2,3,4],xmm2[5,6,7]274; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0275; AVX1-NEXT: retq276;277; AVX2-LABEL: test11:278; AVX2: # %bb.0:279; AVX2-NEXT: vpmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [2,8,2,2,2,8,8,8,8,8,8,2,2,2,8,2]280; AVX2-NEXT: retq281 %lshr = shl <16 x i16> %a, <i16 1, i16 3, i16 1, i16 1, i16 1, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 1, i16 1, i16 1, i16 3, i16 1>282 ret <16 x i16> %lshr283}284 285define <16 x i16> @test12(<16 x i16> %a) {286; SSE-LABEL: test12:287; SSE: # %bb.0:288; SSE-NEXT: movdqa {{.*#+}} xmm2 = [2,8,2,2,2,8,8,8]289; SSE-NEXT: pmullw %xmm2, %xmm0290; SSE-NEXT: pmullw %xmm2, %xmm1291; SSE-NEXT: retq292;293; AVX1-LABEL: test12:294; AVX1: # %bb.0:295; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1296; AVX1-NEXT: vpsllw $3, %xmm1, %xmm2297; AVX1-NEXT: vpaddw %xmm1, %xmm1, %xmm1298; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2,3,4],xmm2[5,6,7]299; AVX1-NEXT: vpsllw $3, %xmm0, %xmm2300; AVX1-NEXT: vpaddw %xmm0, %xmm0, %xmm0301; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2,3,4],xmm2[5,6,7]302; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0303; AVX1-NEXT: retq304;305; AVX2-LABEL: test12:306; AVX2: # %bb.0:307; AVX2-NEXT: vpsllw $3, %ymm0, %ymm1308; AVX2-NEXT: vpaddw %ymm0, %ymm0, %ymm0309; AVX2-NEXT: vpblendw {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2,3,4],ymm1[5,6,7],ymm0[8],ymm1[9],ymm0[10,11,12],ymm1[13,14,15]310; AVX2-NEXT: retq311 %lshr = shl <16 x i16> %a, <i16 1, i16 3, i16 1, i16 1, i16 1, i16 3, i16 3, i16 3, i16 1, i16 3, i16 1, i16 1, i16 1, i16 3, i16 3, i16 3>312 ret <16 x i16> %lshr313}314