1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+ssse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE 3; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX1 4; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx2 | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX2 5 6; Verify that the following shifts are lowered into a sequence of two shifts plus 7; a blend. On pre-avx2 targets, instead of scalarizing logical and arithmetic 8; packed shift right by a constant build_vector the backend should always try to 9; 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, %xmm1 15; SSE-NEXT: psrlw $3, %xmm1 16; SSE-NEXT: psrlw $2, %xmm0 17; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 18; SSE-NEXT: retq 19; 20; AVX1-LABEL: test1: 21; AVX1: # BB#0: 22; AVX1-NEXT: vpsrlw $3, %xmm0, %xmm1 23; AVX1-NEXT: vpsrlw $2, %xmm0, %xmm0 24; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 25; AVX1-NEXT: retq 26; 27; AVX2-LABEL: test1: 28; AVX2: # BB#0: 29; AVX2-NEXT: vpsrlw $3, %xmm0, %xmm1 30; AVX2-NEXT: vpsrlw $2, %xmm0, %xmm0 31; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 32; AVX2-NEXT: retq 33 %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> %lshr 35} 36 37define <8 x i16> @test2(<8 x i16> %a) { 38; SSE-LABEL: test2: 39; SSE: # BB#0: 40; SSE-NEXT: movdqa %xmm0, %xmm1 41; SSE-NEXT: psrlw $3, %xmm1 42; SSE-NEXT: psrlw $2, %xmm0 43; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 44; SSE-NEXT: retq 45; 46; AVX1-LABEL: test2: 47; AVX1: # BB#0: 48; AVX1-NEXT: vpsrlw $2, %xmm0, %xmm1 49; AVX1-NEXT: vpsrlw $3, %xmm0, %xmm0 50; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7] 51; AVX1-NEXT: retq 52; 53; AVX2-LABEL: test2: 54; AVX2: # BB#0: 55; AVX2-NEXT: vpsrlw $2, %xmm0, %xmm1 56; AVX2-NEXT: vpsrlw $3, %xmm0, %xmm0 57; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 58; AVX2-NEXT: retq 59 %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> %lshr 61} 62 63define <4 x i32> @test3(<4 x i32> %a) { 64; SSE-LABEL: test3: 65; SSE: # BB#0: 66; SSE-NEXT: movdqa %xmm0, %xmm1 67; SSE-NEXT: psrld $3, %xmm1 68; SSE-NEXT: psrld $2, %xmm0 69; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 70; SSE-NEXT: retq 71; 72; AVX1-LABEL: test3: 73; AVX1: # BB#0: 74; AVX1-NEXT: vpsrld $3, %xmm0, %xmm1 75; AVX1-NEXT: vpsrld $2, %xmm0, %xmm0 76; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 77; AVX1-NEXT: retq 78; 79; AVX2-LABEL: test3: 80; AVX2: # BB#0: 81; AVX2-NEXT: vpsrlvd {{.*}}(%rip), %xmm0, %xmm0 82; AVX2-NEXT: retq 83 %lshr = lshr <4 x i32> %a, <i32 3, i32 2, i32 2, i32 2> 84 ret <4 x i32> %lshr 85} 86 87define <4 x i32> @test4(<4 x i32> %a) { 88; SSE-LABEL: test4: 89; SSE: # BB#0: 90; SSE-NEXT: movdqa %xmm0, %xmm1 91; SSE-NEXT: psrld $3, %xmm1 92; SSE-NEXT: psrld $2, %xmm0 93; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 94; SSE-NEXT: retq 95; 96; AVX1-LABEL: test4: 97; AVX1: # BB#0: 98; AVX1-NEXT: vpsrld $2, %xmm0, %xmm1 99; AVX1-NEXT: vpsrld $3, %xmm0, %xmm0 100; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7] 101; AVX1-NEXT: retq 102; 103; AVX2-LABEL: test4: 104; AVX2: # BB#0: 105; AVX2-NEXT: vpsrlvd {{.*}}(%rip), %xmm0, %xmm0 106; AVX2-NEXT: retq 107 %lshr = lshr <4 x i32> %a, <i32 3, i32 3, i32 2, i32 2> 108 ret <4 x i32> %lshr 109} 110 111define <8 x i16> @test5(<8 x i16> %a) { 112; SSE-LABEL: test5: 113; SSE: # BB#0: 114; SSE-NEXT: movdqa %xmm0, %xmm1 115; SSE-NEXT: psraw $3, %xmm1 116; SSE-NEXT: psraw $2, %xmm0 117; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 118; SSE-NEXT: retq 119; 120; AVX1-LABEL: test5: 121; AVX1: # BB#0: 122; AVX1-NEXT: vpsraw $3, %xmm0, %xmm1 123; AVX1-NEXT: vpsraw $2, %xmm0, %xmm0 124; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 125; AVX1-NEXT: retq 126; 127; AVX2-LABEL: test5: 128; AVX2: # BB#0: 129; AVX2-NEXT: vpsraw $3, %xmm0, %xmm1 130; AVX2-NEXT: vpsraw $2, %xmm0, %xmm0 131; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 132; AVX2-NEXT: retq 133 %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> %lshr 135} 136 137define <8 x i16> @test6(<8 x i16> %a) { 138; SSE-LABEL: test6: 139; SSE: # BB#0: 140; SSE-NEXT: movdqa %xmm0, %xmm1 141; SSE-NEXT: psraw $3, %xmm1 142; SSE-NEXT: psraw $2, %xmm0 143; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 144; SSE-NEXT: retq 145; 146; AVX1-LABEL: test6: 147; AVX1: # BB#0: 148; AVX1-NEXT: vpsraw $2, %xmm0, %xmm1 149; AVX1-NEXT: vpsraw $3, %xmm0, %xmm0 150; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7] 151; AVX1-NEXT: retq 152; 153; AVX2-LABEL: test6: 154; AVX2: # BB#0: 155; AVX2-NEXT: vpsraw $2, %xmm0, %xmm1 156; AVX2-NEXT: vpsraw $3, %xmm0, %xmm0 157; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 158; AVX2-NEXT: retq 159 %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> %lshr 161} 162 163define <4 x i32> @test7(<4 x i32> %a) { 164; SSE-LABEL: test7: 165; SSE: # BB#0: 166; SSE-NEXT: movdqa %xmm0, %xmm1 167; SSE-NEXT: psrad $3, %xmm1 168; SSE-NEXT: psrad $2, %xmm0 169; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 170; SSE-NEXT: retq 171; 172; AVX1-LABEL: test7: 173; AVX1: # BB#0: 174; AVX1-NEXT: vpsrad $3, %xmm0, %xmm1 175; AVX1-NEXT: vpsrad $2, %xmm0, %xmm0 176; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 177; AVX1-NEXT: retq 178; 179; AVX2-LABEL: test7: 180; AVX2: # BB#0: 181; AVX2-NEXT: vpsravd {{.*}}(%rip), %xmm0, %xmm0 182; AVX2-NEXT: retq 183 %lshr = ashr <4 x i32> %a, <i32 3, i32 2, i32 2, i32 2> 184 ret <4 x i32> %lshr 185} 186 187define <4 x i32> @test8(<4 x i32> %a) { 188; SSE-LABEL: test8: 189; SSE: # BB#0: 190; SSE-NEXT: movdqa %xmm0, %xmm1 191; SSE-NEXT: psrad $3, %xmm1 192; SSE-NEXT: psrad $2, %xmm0 193; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 194; SSE-NEXT: retq 195; 196; AVX1-LABEL: test8: 197; AVX1: # BB#0: 198; AVX1-NEXT: vpsrad $2, %xmm0, %xmm1 199; AVX1-NEXT: vpsrad $3, %xmm0, %xmm0 200; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7] 201; AVX1-NEXT: retq 202; 203; AVX2-LABEL: test8: 204; AVX2: # BB#0: 205; AVX2-NEXT: vpsravd {{.*}}(%rip), %xmm0, %xmm0 206; AVX2-NEXT: retq 207 %lshr = ashr <4 x i32> %a, <i32 3, i32 3, i32 2, i32 2> 208 ret <4 x i32> %lshr 209} 210