1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE2 3; RUN: llc < %s -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSSE3 4; RUN: llc < %s -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE41 5; RUN: llc < %s -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX1 6; RUN: llc < %s -mcpu=x86-64 -mattr=+avx2 | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX2 7; 8; Verify that the DAG combiner correctly folds bitwise operations across 9; shuffles, nested shuffles with undef, pairs of nested shuffles, and other 10; basic and always-safe patterns. Also test that the DAG combiner will combine 11; target-specific shuffle instructions where reasonable. 12 13target triple = "x86_64-unknown-unknown" 14 15declare <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32>, i8) 16declare <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16>, i8) 17declare <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16>, i8) 18 19define <4 x i32> @combine_pshufd1(<4 x i32> %a) { 20; ALL-LABEL: combine_pshufd1: 21; ALL: # BB#0: # %entry 22; ALL-NEXT: retq 23entry: 24 %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27) 25 %c = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %b, i8 27) 26 ret <4 x i32> %c 27} 28 29define <4 x i32> @combine_pshufd2(<4 x i32> %a) { 30; ALL-LABEL: combine_pshufd2: 31; ALL: # BB#0: # %entry 32; ALL-NEXT: retq 33entry: 34 %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27) 35 %b.cast = bitcast <4 x i32> %b to <8 x i16> 36 %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b.cast, i8 -28) 37 %c.cast = bitcast <8 x i16> %c to <4 x i32> 38 %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 27) 39 ret <4 x i32> %d 40} 41 42define <4 x i32> @combine_pshufd3(<4 x i32> %a) { 43; ALL-LABEL: combine_pshufd3: 44; ALL: # BB#0: # %entry 45; ALL-NEXT: retq 46entry: 47 %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27) 48 %b.cast = bitcast <4 x i32> %b to <8 x i16> 49 %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b.cast, i8 -28) 50 %c.cast = bitcast <8 x i16> %c to <4 x i32> 51 %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 27) 52 ret <4 x i32> %d 53} 54 55define <4 x i32> @combine_pshufd4(<4 x i32> %a) { 56; SSE-LABEL: combine_pshufd4: 57; SSE: # BB#0: # %entry 58; SSE-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4] 59; SSE-NEXT: retq 60; 61; AVX-LABEL: combine_pshufd4: 62; AVX: # BB#0: # %entry 63; AVX-NEXT: vpshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4] 64; AVX-NEXT: retq 65entry: 66 %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 -31) 67 %b.cast = bitcast <4 x i32> %b to <8 x i16> 68 %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b.cast, i8 27) 69 %c.cast = bitcast <8 x i16> %c to <4 x i32> 70 %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 -31) 71 ret <4 x i32> %d 72} 73 74define <4 x i32> @combine_pshufd5(<4 x i32> %a) { 75; SSE-LABEL: combine_pshufd5: 76; SSE: # BB#0: # %entry 77; SSE-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7] 78; SSE-NEXT: retq 79; 80; AVX-LABEL: combine_pshufd5: 81; AVX: # BB#0: # %entry 82; AVX-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7] 83; AVX-NEXT: retq 84entry: 85 %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 -76) 86 %b.cast = bitcast <4 x i32> %b to <8 x i16> 87 %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b.cast, i8 27) 88 %c.cast = bitcast <8 x i16> %c to <4 x i32> 89 %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 -76) 90 ret <4 x i32> %d 91} 92 93define <4 x i32> @combine_pshufd6(<4 x i32> %a) { 94; SSE-LABEL: combine_pshufd6: 95; SSE: # BB#0: # %entry 96; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,0,0,0] 97; SSE-NEXT: retq 98; 99; AVX-LABEL: combine_pshufd6: 100; AVX: # BB#0: # %entry 101; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,0,0,0] 102; AVX-NEXT: retq 103entry: 104 %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 0) 105 %c = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %b, i8 8) 106 ret <4 x i32> %c 107} 108 109define <8 x i16> @combine_pshuflw1(<8 x i16> %a) { 110; ALL-LABEL: combine_pshuflw1: 111; ALL: # BB#0: # %entry 112; ALL-NEXT: retq 113entry: 114 %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27) 115 %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b, i8 27) 116 ret <8 x i16> %c 117} 118 119define <8 x i16> @combine_pshuflw2(<8 x i16> %a) { 120; ALL-LABEL: combine_pshuflw2: 121; ALL: # BB#0: # %entry 122; ALL-NEXT: retq 123entry: 124 %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27) 125 %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b, i8 -28) 126 %d = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %c, i8 27) 127 ret <8 x i16> %d 128} 129 130define <8 x i16> @combine_pshuflw3(<8 x i16> %a) { 131; SSE-LABEL: combine_pshuflw3: 132; SSE: # BB#0: # %entry 133; SSE-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4] 134; SSE-NEXT: retq 135; 136; AVX-LABEL: combine_pshuflw3: 137; AVX: # BB#0: # %entry 138; AVX-NEXT: vpshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4] 139; AVX-NEXT: retq 140entry: 141 %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27) 142 %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b, i8 27) 143 %d = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %c, i8 27) 144 ret <8 x i16> %d 145} 146 147define <8 x i16> @combine_pshufhw1(<8 x i16> %a) { 148; SSE-LABEL: combine_pshufhw1: 149; SSE: # BB#0: # %entry 150; SSE-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7] 151; SSE-NEXT: retq 152; 153; AVX-LABEL: combine_pshufhw1: 154; AVX: # BB#0: # %entry 155; AVX-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7] 156; AVX-NEXT: retq 157entry: 158 %b = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %a, i8 27) 159 %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b, i8 27) 160 %d = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %c, i8 27) 161 ret <8 x i16> %d 162} 163 164define <4 x i32> @combine_bitwise_ops_test1(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 165; SSE-LABEL: combine_bitwise_ops_test1: 166; SSE: # BB#0: 167; SSE-NEXT: pand %xmm1, %xmm0 168; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 169; SSE-NEXT: retq 170; 171; AVX-LABEL: combine_bitwise_ops_test1: 172; AVX: # BB#0: 173; AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 174; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 175; AVX-NEXT: retq 176 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 177 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 178 %and = and <4 x i32> %shuf1, %shuf2 179 ret <4 x i32> %and 180} 181 182define <4 x i32> @combine_bitwise_ops_test2(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 183; SSE-LABEL: combine_bitwise_ops_test2: 184; SSE: # BB#0: 185; SSE-NEXT: por %xmm1, %xmm0 186; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 187; SSE-NEXT: retq 188; 189; AVX-LABEL: combine_bitwise_ops_test2: 190; AVX: # BB#0: 191; AVX-NEXT: vpor %xmm1, %xmm0, %xmm0 192; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 193; AVX-NEXT: retq 194 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 195 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 196 %or = or <4 x i32> %shuf1, %shuf2 197 ret <4 x i32> %or 198} 199 200define <4 x i32> @combine_bitwise_ops_test3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 201; SSE-LABEL: combine_bitwise_ops_test3: 202; SSE: # BB#0: 203; SSE-NEXT: pxor %xmm1, %xmm0 204; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 205; SSE-NEXT: retq 206; 207; AVX-LABEL: combine_bitwise_ops_test3: 208; AVX: # BB#0: 209; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 210; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 211; AVX-NEXT: retq 212 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 213 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 214 %xor = xor <4 x i32> %shuf1, %shuf2 215 ret <4 x i32> %xor 216} 217 218define <4 x i32> @combine_bitwise_ops_test4(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 219; SSE-LABEL: combine_bitwise_ops_test4: 220; SSE: # BB#0: 221; SSE-NEXT: pand %xmm1, %xmm0 222; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 223; SSE-NEXT: retq 224; 225; AVX-LABEL: combine_bitwise_ops_test4: 226; AVX: # BB#0: 227; AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 228; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 229; AVX-NEXT: retq 230 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7> 231 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7> 232 %and = and <4 x i32> %shuf1, %shuf2 233 ret <4 x i32> %and 234} 235 236define <4 x i32> @combine_bitwise_ops_test5(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 237; SSE-LABEL: combine_bitwise_ops_test5: 238; SSE: # BB#0: 239; SSE-NEXT: por %xmm1, %xmm0 240; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 241; SSE-NEXT: retq 242; 243; AVX-LABEL: combine_bitwise_ops_test5: 244; AVX: # BB#0: 245; AVX-NEXT: vpor %xmm1, %xmm0, %xmm0 246; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 247; AVX-NEXT: retq 248 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7> 249 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7> 250 %or = or <4 x i32> %shuf1, %shuf2 251 ret <4 x i32> %or 252} 253 254define <4 x i32> @combine_bitwise_ops_test6(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 255; SSE-LABEL: combine_bitwise_ops_test6: 256; SSE: # BB#0: 257; SSE-NEXT: pxor %xmm1, %xmm0 258; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 259; SSE-NEXT: retq 260; 261; AVX-LABEL: combine_bitwise_ops_test6: 262; AVX: # BB#0: 263; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 264; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 265; AVX-NEXT: retq 266 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7> 267 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7> 268 %xor = xor <4 x i32> %shuf1, %shuf2 269 ret <4 x i32> %xor 270} 271 272 273; Verify that DAGCombiner moves the shuffle after the xor/and/or even if shuffles 274; are not performing a swizzle operations. 275 276define <4 x i32> @combine_bitwise_ops_test1b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 277; SSE2-LABEL: combine_bitwise_ops_test1b: 278; SSE2: # BB#0: 279; SSE2-NEXT: pand %xmm1, %xmm0 280; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 281; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 282; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 283; SSE2-NEXT: retq 284; 285; SSSE3-LABEL: combine_bitwise_ops_test1b: 286; SSSE3: # BB#0: 287; SSSE3-NEXT: pand %xmm1, %xmm0 288; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 289; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 290; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 291; SSSE3-NEXT: retq 292; 293; SSE41-LABEL: combine_bitwise_ops_test1b: 294; SSE41: # BB#0: 295; SSE41-NEXT: pand %xmm1, %xmm0 296; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 297; SSE41-NEXT: retq 298; 299; AVX1-LABEL: combine_bitwise_ops_test1b: 300; AVX1: # BB#0: 301; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 302; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 303; AVX1-NEXT: retq 304; 305; AVX2-LABEL: combine_bitwise_ops_test1b: 306; AVX2: # BB#0: 307; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 308; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] 309; AVX2-NEXT: retq 310 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 311 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 312 %and = and <4 x i32> %shuf1, %shuf2 313 ret <4 x i32> %and 314} 315 316define <4 x i32> @combine_bitwise_ops_test2b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 317; SSE2-LABEL: combine_bitwise_ops_test2b: 318; SSE2: # BB#0: 319; SSE2-NEXT: por %xmm1, %xmm0 320; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 321; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 322; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 323; SSE2-NEXT: retq 324; 325; SSSE3-LABEL: combine_bitwise_ops_test2b: 326; SSSE3: # BB#0: 327; SSSE3-NEXT: por %xmm1, %xmm0 328; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 329; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 330; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 331; SSSE3-NEXT: retq 332; 333; SSE41-LABEL: combine_bitwise_ops_test2b: 334; SSE41: # BB#0: 335; SSE41-NEXT: por %xmm1, %xmm0 336; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 337; SSE41-NEXT: retq 338; 339; AVX1-LABEL: combine_bitwise_ops_test2b: 340; AVX1: # BB#0: 341; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 342; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 343; AVX1-NEXT: retq 344; 345; AVX2-LABEL: combine_bitwise_ops_test2b: 346; AVX2: # BB#0: 347; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 348; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] 349; AVX2-NEXT: retq 350 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 351 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 352 %or = or <4 x i32> %shuf1, %shuf2 353 ret <4 x i32> %or 354} 355 356define <4 x i32> @combine_bitwise_ops_test3b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 357; SSE2-LABEL: combine_bitwise_ops_test3b: 358; SSE2: # BB#0: 359; SSE2-NEXT: xorps %xmm1, %xmm0 360; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 361; SSE2-NEXT: retq 362; 363; SSSE3-LABEL: combine_bitwise_ops_test3b: 364; SSSE3: # BB#0: 365; SSSE3-NEXT: xorps %xmm1, %xmm0 366; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 367; SSSE3-NEXT: retq 368; 369; SSE41-LABEL: combine_bitwise_ops_test3b: 370; SSE41: # BB#0: 371; SSE41-NEXT: pxor %xmm1, %xmm0 372; SSE41-NEXT: pxor %xmm1, %xmm1 373; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 374; SSE41-NEXT: retq 375; 376; AVX1-LABEL: combine_bitwise_ops_test3b: 377; AVX1: # BB#0: 378; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 379; AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1 380; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 381; AVX1-NEXT: retq 382; 383; AVX2-LABEL: combine_bitwise_ops_test3b: 384; AVX2: # BB#0: 385; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 386; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 387; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 388; AVX2-NEXT: retq 389 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 390 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 391 %xor = xor <4 x i32> %shuf1, %shuf2 392 ret <4 x i32> %xor 393} 394 395define <4 x i32> @combine_bitwise_ops_test4b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 396; SSE2-LABEL: combine_bitwise_ops_test4b: 397; SSE2: # BB#0: 398; SSE2-NEXT: pand %xmm1, %xmm0 399; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 400; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 401; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 402; SSE2-NEXT: retq 403; 404; SSSE3-LABEL: combine_bitwise_ops_test4b: 405; SSSE3: # BB#0: 406; SSSE3-NEXT: pand %xmm1, %xmm0 407; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 408; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 409; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 410; SSSE3-NEXT: retq 411; 412; SSE41-LABEL: combine_bitwise_ops_test4b: 413; SSE41: # BB#0: 414; SSE41-NEXT: pand %xmm1, %xmm0 415; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 416; SSE41-NEXT: retq 417; 418; AVX1-LABEL: combine_bitwise_ops_test4b: 419; AVX1: # BB#0: 420; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 421; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 422; AVX1-NEXT: retq 423; 424; AVX2-LABEL: combine_bitwise_ops_test4b: 425; AVX2: # BB#0: 426; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 427; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3] 428; AVX2-NEXT: retq 429 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7> 430 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7> 431 %and = and <4 x i32> %shuf1, %shuf2 432 ret <4 x i32> %and 433} 434 435define <4 x i32> @combine_bitwise_ops_test5b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 436; SSE2-LABEL: combine_bitwise_ops_test5b: 437; SSE2: # BB#0: 438; SSE2-NEXT: por %xmm1, %xmm0 439; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 440; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 441; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 442; SSE2-NEXT: retq 443; 444; SSSE3-LABEL: combine_bitwise_ops_test5b: 445; SSSE3: # BB#0: 446; SSSE3-NEXT: por %xmm1, %xmm0 447; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 448; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 449; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 450; SSSE3-NEXT: retq 451; 452; SSE41-LABEL: combine_bitwise_ops_test5b: 453; SSE41: # BB#0: 454; SSE41-NEXT: por %xmm1, %xmm0 455; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 456; SSE41-NEXT: retq 457; 458; AVX1-LABEL: combine_bitwise_ops_test5b: 459; AVX1: # BB#0: 460; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 461; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 462; AVX1-NEXT: retq 463; 464; AVX2-LABEL: combine_bitwise_ops_test5b: 465; AVX2: # BB#0: 466; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 467; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3] 468; AVX2-NEXT: retq 469 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7> 470 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7> 471 %or = or <4 x i32> %shuf1, %shuf2 472 ret <4 x i32> %or 473} 474 475define <4 x i32> @combine_bitwise_ops_test6b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 476; SSE2-LABEL: combine_bitwise_ops_test6b: 477; SSE2: # BB#0: 478; SSE2-NEXT: xorps %xmm1, %xmm0 479; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 480; SSE2-NEXT: retq 481; 482; SSSE3-LABEL: combine_bitwise_ops_test6b: 483; SSSE3: # BB#0: 484; SSSE3-NEXT: xorps %xmm1, %xmm0 485; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 486; SSSE3-NEXT: retq 487; 488; SSE41-LABEL: combine_bitwise_ops_test6b: 489; SSE41: # BB#0: 490; SSE41-NEXT: pxor %xmm1, %xmm0 491; SSE41-NEXT: pxor %xmm1, %xmm1 492; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5],xmm0[6,7] 493; SSE41-NEXT: retq 494; 495; AVX1-LABEL: combine_bitwise_ops_test6b: 496; AVX1: # BB#0: 497; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 498; AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1 499; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5],xmm0[6,7] 500; AVX1-NEXT: retq 501; 502; AVX2-LABEL: combine_bitwise_ops_test6b: 503; AVX2: # BB#0: 504; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 505; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 506; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3] 507; AVX2-NEXT: retq 508 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7> 509 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7> 510 %xor = xor <4 x i32> %shuf1, %shuf2 511 ret <4 x i32> %xor 512} 513 514define <4 x i32> @combine_bitwise_ops_test1c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 515; SSE2-LABEL: combine_bitwise_ops_test1c: 516; SSE2: # BB#0: 517; SSE2-NEXT: pand %xmm1, %xmm0 518; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 519; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 520; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 521; SSE2-NEXT: retq 522; 523; SSSE3-LABEL: combine_bitwise_ops_test1c: 524; SSSE3: # BB#0: 525; SSSE3-NEXT: pand %xmm1, %xmm0 526; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 527; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 528; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 529; SSSE3-NEXT: retq 530; 531; SSE41-LABEL: combine_bitwise_ops_test1c: 532; SSE41: # BB#0: 533; SSE41-NEXT: pand %xmm1, %xmm0 534; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 535; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 536; SSE41-NEXT: retq 537; 538; AVX1-LABEL: combine_bitwise_ops_test1c: 539; AVX1: # BB#0: 540; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 541; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 542; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 543; AVX1-NEXT: retq 544; 545; AVX2-LABEL: combine_bitwise_ops_test1c: 546; AVX2: # BB#0: 547; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 548; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] 549; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 550; AVX2-NEXT: retq 551 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 552 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 553 %and = and <4 x i32> %shuf1, %shuf2 554 ret <4 x i32> %and 555} 556 557define <4 x i32> @combine_bitwise_ops_test2c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 558; SSE2-LABEL: combine_bitwise_ops_test2c: 559; SSE2: # BB#0: 560; SSE2-NEXT: por %xmm1, %xmm0 561; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 562; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 563; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 564; SSE2-NEXT: retq 565; 566; SSSE3-LABEL: combine_bitwise_ops_test2c: 567; SSSE3: # BB#0: 568; SSSE3-NEXT: por %xmm1, %xmm0 569; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 570; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 571; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 572; SSSE3-NEXT: retq 573; 574; SSE41-LABEL: combine_bitwise_ops_test2c: 575; SSE41: # BB#0: 576; SSE41-NEXT: por %xmm1, %xmm0 577; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 578; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 579; SSE41-NEXT: retq 580; 581; AVX1-LABEL: combine_bitwise_ops_test2c: 582; AVX1: # BB#0: 583; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 584; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 585; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 586; AVX1-NEXT: retq 587; 588; AVX2-LABEL: combine_bitwise_ops_test2c: 589; AVX2: # BB#0: 590; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 591; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] 592; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 593; AVX2-NEXT: retq 594 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 595 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 596 %or = or <4 x i32> %shuf1, %shuf2 597 ret <4 x i32> %or 598} 599 600define <4 x i32> @combine_bitwise_ops_test3c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 601; SSE2-LABEL: combine_bitwise_ops_test3c: 602; SSE2: # BB#0: 603; SSE2-NEXT: pxor %xmm1, %xmm0 604; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,2] 605; SSE2-NEXT: pxor %xmm1, %xmm1 606; SSE2-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 607; SSE2-NEXT: retq 608; 609; SSSE3-LABEL: combine_bitwise_ops_test3c: 610; SSSE3: # BB#0: 611; SSSE3-NEXT: pxor %xmm1, %xmm0 612; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,2] 613; SSSE3-NEXT: pxor %xmm1, %xmm1 614; SSSE3-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 615; SSSE3-NEXT: retq 616; 617; SSE41-LABEL: combine_bitwise_ops_test3c: 618; SSE41: # BB#0: 619; SSE41-NEXT: pxor %xmm1, %xmm0 620; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 621; SSE41-NEXT: movq {{.*#+}} xmm0 = xmm0[0],zero 622; SSE41-NEXT: retq 623; 624; AVX-LABEL: combine_bitwise_ops_test3c: 625; AVX: # BB#0: 626; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 627; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 628; AVX-NEXT: vmovq {{.*#+}} xmm0 = xmm0[0],zero 629; AVX-NEXT: retq 630 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 631 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 632 %xor = xor <4 x i32> %shuf1, %shuf2 633 ret <4 x i32> %xor 634} 635 636define <4 x i32> @combine_bitwise_ops_test4c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 637; SSE2-LABEL: combine_bitwise_ops_test4c: 638; SSE2: # BB#0: 639; SSE2-NEXT: pand %xmm1, %xmm0 640; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 641; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 642; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 643; SSE2-NEXT: retq 644; 645; SSSE3-LABEL: combine_bitwise_ops_test4c: 646; SSSE3: # BB#0: 647; SSSE3-NEXT: pand %xmm1, %xmm0 648; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 649; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 650; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 651; SSSE3-NEXT: retq 652; 653; SSE41-LABEL: combine_bitwise_ops_test4c: 654; SSE41: # BB#0: 655; SSE41-NEXT: pand %xmm1, %xmm0 656; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 657; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 658; SSE41-NEXT: retq 659; 660; AVX1-LABEL: combine_bitwise_ops_test4c: 661; AVX1: # BB#0: 662; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 663; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 664; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 665; AVX1-NEXT: retq 666; 667; AVX2-LABEL: combine_bitwise_ops_test4c: 668; AVX2: # BB#0: 669; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 670; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3] 671; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 672; AVX2-NEXT: retq 673 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7> 674 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7> 675 %and = and <4 x i32> %shuf1, %shuf2 676 ret <4 x i32> %and 677} 678 679define <4 x i32> @combine_bitwise_ops_test5c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 680; SSE2-LABEL: combine_bitwise_ops_test5c: 681; SSE2: # BB#0: 682; SSE2-NEXT: por %xmm1, %xmm0 683; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 684; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 685; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 686; SSE2-NEXT: retq 687; 688; SSSE3-LABEL: combine_bitwise_ops_test5c: 689; SSSE3: # BB#0: 690; SSSE3-NEXT: por %xmm1, %xmm0 691; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 692; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 693; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 694; SSSE3-NEXT: retq 695; 696; SSE41-LABEL: combine_bitwise_ops_test5c: 697; SSE41: # BB#0: 698; SSE41-NEXT: por %xmm1, %xmm0 699; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 700; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 701; SSE41-NEXT: retq 702; 703; AVX1-LABEL: combine_bitwise_ops_test5c: 704; AVX1: # BB#0: 705; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 706; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 707; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 708; AVX1-NEXT: retq 709; 710; AVX2-LABEL: combine_bitwise_ops_test5c: 711; AVX2: # BB#0: 712; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 713; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3] 714; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 715; AVX2-NEXT: retq 716 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7> 717 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7> 718 %or = or <4 x i32> %shuf1, %shuf2 719 ret <4 x i32> %or 720} 721 722define <4 x i32> @combine_bitwise_ops_test6c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 723; SSE2-LABEL: combine_bitwise_ops_test6c: 724; SSE2: # BB#0: 725; SSE2-NEXT: pxor %xmm1, %xmm0 726; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 727; SSE2-NEXT: pxor %xmm0, %xmm0 728; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 729; SSE2-NEXT: retq 730; 731; SSSE3-LABEL: combine_bitwise_ops_test6c: 732; SSSE3: # BB#0: 733; SSSE3-NEXT: pxor %xmm1, %xmm0 734; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 735; SSSE3-NEXT: pxor %xmm0, %xmm0 736; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 737; SSSE3-NEXT: retq 738; 739; SSE41-LABEL: combine_bitwise_ops_test6c: 740; SSE41: # BB#0: 741; SSE41-NEXT: pxor %xmm1, %xmm0 742; SSE41-NEXT: pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3] 743; SSE41-NEXT: pxor %xmm0, %xmm0 744; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7] 745; SSE41-NEXT: retq 746; 747; AVX1-LABEL: combine_bitwise_ops_test6c: 748; AVX1: # BB#0: 749; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 750; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,3] 751; AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1 752; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7] 753; AVX1-NEXT: retq 754; 755; AVX2-LABEL: combine_bitwise_ops_test6c: 756; AVX2: # BB#0: 757; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 758; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,3] 759; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 760; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 761; AVX2-NEXT: retq 762 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7> 763 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7> 764 %xor = xor <4 x i32> %shuf1, %shuf2 765 ret <4 x i32> %xor 766} 767 768define <4 x i32> @combine_nested_undef_test1(<4 x i32> %A, <4 x i32> %B) { 769; SSE-LABEL: combine_nested_undef_test1: 770; SSE: # BB#0: 771; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 772; SSE-NEXT: retq 773; 774; AVX-LABEL: combine_nested_undef_test1: 775; AVX: # BB#0: 776; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 777; AVX-NEXT: retq 778 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1> 779 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 780 ret <4 x i32> %2 781} 782 783define <4 x i32> @combine_nested_undef_test2(<4 x i32> %A, <4 x i32> %B) { 784; SSE-LABEL: combine_nested_undef_test2: 785; SSE: # BB#0: 786; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,1,0,3] 787; SSE-NEXT: retq 788; 789; AVX-LABEL: combine_nested_undef_test2: 790; AVX: # BB#0: 791; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,1,0,3] 792; AVX-NEXT: retq 793 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 794 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 795 ret <4 x i32> %2 796} 797 798define <4 x i32> @combine_nested_undef_test3(<4 x i32> %A, <4 x i32> %B) { 799; SSE-LABEL: combine_nested_undef_test3: 800; SSE: # BB#0: 801; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,1,0,3] 802; SSE-NEXT: retq 803; 804; AVX-LABEL: combine_nested_undef_test3: 805; AVX: # BB#0: 806; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,1,0,3] 807; AVX-NEXT: retq 808 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 3> 809 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 810 ret <4 x i32> %2 811} 812 813define <4 x i32> @combine_nested_undef_test4(<4 x i32> %A, <4 x i32> %B) { 814; SSE-LABEL: combine_nested_undef_test4: 815; SSE: # BB#0: 816; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 817; SSE-NEXT: retq 818; 819; AVX1-LABEL: combine_nested_undef_test4: 820; AVX1: # BB#0: 821; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 822; AVX1-NEXT: retq 823; 824; AVX2-LABEL: combine_nested_undef_test4: 825; AVX2: # BB#0: 826; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 827; AVX2-NEXT: retq 828 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 7, i32 1> 829 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 4, i32 4, i32 0, i32 3> 830 ret <4 x i32> %2 831} 832 833define <4 x i32> @combine_nested_undef_test5(<4 x i32> %A, <4 x i32> %B) { 834; SSE-LABEL: combine_nested_undef_test5: 835; SSE: # BB#0: 836; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 837; SSE-NEXT: retq 838; 839; AVX-LABEL: combine_nested_undef_test5: 840; AVX: # BB#0: 841; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 842; AVX-NEXT: retq 843 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 5, i32 5, i32 2, i32 3> 844 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 4, i32 3> 845 ret <4 x i32> %2 846} 847 848define <4 x i32> @combine_nested_undef_test6(<4 x i32> %A, <4 x i32> %B) { 849; SSE-LABEL: combine_nested_undef_test6: 850; SSE: # BB#0: 851; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 852; SSE-NEXT: retq 853; 854; AVX-LABEL: combine_nested_undef_test6: 855; AVX: # BB#0: 856; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 857; AVX-NEXT: retq 858 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 4> 859 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 4> 860 ret <4 x i32> %2 861} 862 863define <4 x i32> @combine_nested_undef_test7(<4 x i32> %A, <4 x i32> %B) { 864; SSE-LABEL: combine_nested_undef_test7: 865; SSE: # BB#0: 866; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,0,2] 867; SSE-NEXT: retq 868; 869; AVX-LABEL: combine_nested_undef_test7: 870; AVX: # BB#0: 871; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,0,2] 872; AVX-NEXT: retq 873 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 874 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2> 875 ret <4 x i32> %2 876} 877 878define <4 x i32> @combine_nested_undef_test8(<4 x i32> %A, <4 x i32> %B) { 879; SSE-LABEL: combine_nested_undef_test8: 880; SSE: # BB#0: 881; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 882; SSE-NEXT: retq 883; 884; AVX-LABEL: combine_nested_undef_test8: 885; AVX: # BB#0: 886; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 887; AVX-NEXT: retq 888 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 889 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 4, i32 3, i32 4> 890 ret <4 x i32> %2 891} 892 893define <4 x i32> @combine_nested_undef_test9(<4 x i32> %A, <4 x i32> %B) { 894; SSE-LABEL: combine_nested_undef_test9: 895; SSE: # BB#0: 896; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,2] 897; SSE-NEXT: retq 898; 899; AVX-LABEL: combine_nested_undef_test9: 900; AVX: # BB#0: 901; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,3,2,2] 902; AVX-NEXT: retq 903 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 3, i32 2, i32 5> 904 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 2> 905 ret <4 x i32> %2 906} 907 908define <4 x i32> @combine_nested_undef_test10(<4 x i32> %A, <4 x i32> %B) { 909; SSE-LABEL: combine_nested_undef_test10: 910; SSE: # BB#0: 911; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,3] 912; SSE-NEXT: retq 913; 914; AVX-LABEL: combine_nested_undef_test10: 915; AVX: # BB#0: 916; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,1,3] 917; AVX-NEXT: retq 918 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 1, i32 5, i32 5> 919 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 4> 920 ret <4 x i32> %2 921} 922 923define <4 x i32> @combine_nested_undef_test11(<4 x i32> %A, <4 x i32> %B) { 924; SSE-LABEL: combine_nested_undef_test11: 925; SSE: # BB#0: 926; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,2,1] 927; SSE-NEXT: retq 928; 929; AVX-LABEL: combine_nested_undef_test11: 930; AVX: # BB#0: 931; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,1] 932; AVX-NEXT: retq 933 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 2, i32 5, i32 4> 934 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 0> 935 ret <4 x i32> %2 936} 937 938define <4 x i32> @combine_nested_undef_test12(<4 x i32> %A, <4 x i32> %B) { 939; SSE-LABEL: combine_nested_undef_test12: 940; SSE: # BB#0: 941; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 942; SSE-NEXT: retq 943; 944; AVX1-LABEL: combine_nested_undef_test12: 945; AVX1: # BB#0: 946; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 947; AVX1-NEXT: retq 948; 949; AVX2-LABEL: combine_nested_undef_test12: 950; AVX2: # BB#0: 951; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 952; AVX2-NEXT: retq 953 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 0, i32 2, i32 4> 954 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 4, i32 0, i32 4> 955 ret <4 x i32> %2 956} 957 958; The following pair of shuffles is folded into vector %A. 959define <4 x i32> @combine_nested_undef_test13(<4 x i32> %A, <4 x i32> %B) { 960; ALL-LABEL: combine_nested_undef_test13: 961; ALL: # BB#0: 962; ALL-NEXT: retq 963 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 4, i32 2, i32 6> 964 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 4, i32 0, i32 2, i32 4> 965 ret <4 x i32> %2 966} 967 968; The following pair of shuffles is folded into vector %B. 969define <4 x i32> @combine_nested_undef_test14(<4 x i32> %A, <4 x i32> %B) { 970; SSE-LABEL: combine_nested_undef_test14: 971; SSE: # BB#0: 972; SSE-NEXT: movaps %xmm1, %xmm0 973; SSE-NEXT: retq 974; 975; AVX-LABEL: combine_nested_undef_test14: 976; AVX: # BB#0: 977; AVX-NEXT: vmovaps %xmm1, %xmm0 978; AVX-NEXT: retq 979 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 4> 980 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 4, i32 1, i32 4> 981 ret <4 x i32> %2 982} 983 984 985; Verify that we don't optimize the following cases. We expect more than one shuffle. 986; 987; FIXME: Many of these already don't make sense, and the rest should stop 988; making sense with th enew vector shuffle lowering. Revisit at least testing for 989; it. 990 991define <4 x i32> @combine_nested_undef_test15(<4 x i32> %A, <4 x i32> %B) { 992; SSE2-LABEL: combine_nested_undef_test15: 993; SSE2: # BB#0: 994; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 995; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,1] 996; SSE2-NEXT: movaps %xmm1, %xmm0 997; SSE2-NEXT: retq 998; 999; SSSE3-LABEL: combine_nested_undef_test15: 1000; SSSE3: # BB#0: 1001; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 1002; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,1] 1003; SSSE3-NEXT: movaps %xmm1, %xmm0 1004; SSSE3-NEXT: retq 1005; 1006; SSE41-LABEL: combine_nested_undef_test15: 1007; SSE41: # BB#0: 1008; SSE41-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,0,1,1] 1009; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1010; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 1011; SSE41-NEXT: retq 1012; 1013; AVX1-LABEL: combine_nested_undef_test15: 1014; AVX1: # BB#0: 1015; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[0,0,1,1] 1016; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1017; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 1018; AVX1-NEXT: retq 1019; 1020; AVX2-LABEL: combine_nested_undef_test15: 1021; AVX2: # BB#0: 1022; AVX2-NEXT: vpbroadcastd %xmm1, %xmm1 1023; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1024; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3] 1025; AVX2-NEXT: retq 1026 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1> 1027 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1028 ret <4 x i32> %2 1029} 1030 1031define <4 x i32> @combine_nested_undef_test16(<4 x i32> %A, <4 x i32> %B) { 1032; SSE2-LABEL: combine_nested_undef_test16: 1033; SSE2: # BB#0: 1034; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] 1035; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,0,2,3] 1036; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1037; SSE2-NEXT: retq 1038; 1039; SSSE3-LABEL: combine_nested_undef_test16: 1040; SSSE3: # BB#0: 1041; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] 1042; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,0,2,3] 1043; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1044; SSSE3-NEXT: retq 1045; 1046; SSE41-LABEL: combine_nested_undef_test16: 1047; SSE41: # BB#0: 1048; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 1049; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 1050; SSE41-NEXT: retq 1051; 1052; AVX1-LABEL: combine_nested_undef_test16: 1053; AVX1: # BB#0: 1054; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 1055; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 1056; AVX1-NEXT: retq 1057; 1058; AVX2-LABEL: combine_nested_undef_test16: 1059; AVX2: # BB#0: 1060; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 1061; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 1062; AVX2-NEXT: retq 1063 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1064 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1065 ret <4 x i32> %2 1066} 1067 1068define <4 x i32> @combine_nested_undef_test17(<4 x i32> %A, <4 x i32> %B) { 1069; SSE2-LABEL: combine_nested_undef_test17: 1070; SSE2: # BB#0: 1071; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0] 1072; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2] 1073; SSE2-NEXT: retq 1074; 1075; SSSE3-LABEL: combine_nested_undef_test17: 1076; SSSE3: # BB#0: 1077; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0] 1078; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2] 1079; SSSE3-NEXT: retq 1080; 1081; SSE41-LABEL: combine_nested_undef_test17: 1082; SSE41: # BB#0: 1083; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 1084; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1085; SSE41-NEXT: retq 1086; 1087; AVX1-LABEL: combine_nested_undef_test17: 1088; AVX1: # BB#0: 1089; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 1090; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1091; AVX1-NEXT: retq 1092; 1093; AVX2-LABEL: combine_nested_undef_test17: 1094; AVX2: # BB#0: 1095; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 1096; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1097; AVX2-NEXT: retq 1098 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1> 1099 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1100 ret <4 x i32> %2 1101} 1102 1103define <4 x i32> @combine_nested_undef_test18(<4 x i32> %A, <4 x i32> %B) { 1104; SSE-LABEL: combine_nested_undef_test18: 1105; SSE: # BB#0: 1106; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,0,3] 1107; SSE-NEXT: retq 1108; 1109; AVX-LABEL: combine_nested_undef_test18: 1110; AVX: # BB#0: 1111; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm1[1,1,0,3] 1112; AVX-NEXT: retq 1113 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 1114 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 0, i32 3> 1115 ret <4 x i32> %2 1116} 1117 1118define <4 x i32> @combine_nested_undef_test19(<4 x i32> %A, <4 x i32> %B) { 1119; SSE2-LABEL: combine_nested_undef_test19: 1120; SSE2: # BB#0: 1121; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1122; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,0,0,0] 1123; SSE2-NEXT: retq 1124; 1125; SSSE3-LABEL: combine_nested_undef_test19: 1126; SSSE3: # BB#0: 1127; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1128; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,0,0,0] 1129; SSSE3-NEXT: retq 1130; 1131; SSE41-LABEL: combine_nested_undef_test19: 1132; SSE41: # BB#0: 1133; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 1134; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,0,0,0] 1135; SSE41-NEXT: retq 1136; 1137; AVX1-LABEL: combine_nested_undef_test19: 1138; AVX1: # BB#0: 1139; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 1140; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,0,0,0] 1141; AVX1-NEXT: retq 1142; 1143; AVX2-LABEL: combine_nested_undef_test19: 1144; AVX2: # BB#0: 1145; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3] 1146; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,0,0,0] 1147; AVX2-NEXT: retq 1148 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 5, i32 6> 1149 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 0, i32 0, i32 0> 1150 ret <4 x i32> %2 1151} 1152 1153define <4 x i32> @combine_nested_undef_test20(<4 x i32> %A, <4 x i32> %B) { 1154; SSE2-LABEL: combine_nested_undef_test20: 1155; SSE2: # BB#0: 1156; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3] 1157; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,3,1] 1158; SSE2-NEXT: movaps %xmm1, %xmm0 1159; SSE2-NEXT: retq 1160; 1161; SSSE3-LABEL: combine_nested_undef_test20: 1162; SSSE3: # BB#0: 1163; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3] 1164; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,3,1] 1165; SSSE3-NEXT: movaps %xmm1, %xmm0 1166; SSSE3-NEXT: retq 1167; 1168; SSE41-LABEL: combine_nested_undef_test20: 1169; SSE41: # BB#0: 1170; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7] 1171; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,3,0] 1172; SSE41-NEXT: retq 1173; 1174; AVX1-LABEL: combine_nested_undef_test20: 1175; AVX1: # BB#0: 1176; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7] 1177; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,3,0] 1178; AVX1-NEXT: retq 1179; 1180; AVX2-LABEL: combine_nested_undef_test20: 1181; AVX2: # BB#0: 1182; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 1183; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,3,0] 1184; AVX2-NEXT: retq 1185 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 3, i32 2, i32 4, i32 4> 1186 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1187 ret <4 x i32> %2 1188} 1189 1190define <4 x i32> @combine_nested_undef_test21(<4 x i32> %A, <4 x i32> %B) { 1191; SSE2-LABEL: combine_nested_undef_test21: 1192; SSE2: # BB#0: 1193; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 1194; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,0,3] 1195; SSE2-NEXT: retq 1196; 1197; SSSE3-LABEL: combine_nested_undef_test21: 1198; SSSE3: # BB#0: 1199; SSSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 1200; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,0,3] 1201; SSSE3-NEXT: retq 1202; 1203; SSE41-LABEL: combine_nested_undef_test21: 1204; SSE41: # BB#0: 1205; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1206; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1207; SSE41-NEXT: retq 1208; 1209; AVX1-LABEL: combine_nested_undef_test21: 1210; AVX1: # BB#0: 1211; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1212; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1213; AVX1-NEXT: retq 1214; 1215; AVX2-LABEL: combine_nested_undef_test21: 1216; AVX2: # BB#0: 1217; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1218; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 1219; AVX2-NEXT: retq 1220 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1> 1221 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3> 1222 ret <4 x i32> %2 1223} 1224 1225 1226; Test that we correctly combine shuffles according to rule 1227; shuffle(shuffle(x, y), undef) -> shuffle(y, undef) 1228 1229define <4 x i32> @combine_nested_undef_test22(<4 x i32> %A, <4 x i32> %B) { 1230; SSE-LABEL: combine_nested_undef_test22: 1231; SSE: # BB#0: 1232; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,3] 1233; SSE-NEXT: retq 1234; 1235; AVX-LABEL: combine_nested_undef_test22: 1236; AVX: # BB#0: 1237; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm1[1,1,1,3] 1238; AVX-NEXT: retq 1239 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 1240 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 3> 1241 ret <4 x i32> %2 1242} 1243 1244define <4 x i32> @combine_nested_undef_test23(<4 x i32> %A, <4 x i32> %B) { 1245; SSE-LABEL: combine_nested_undef_test23: 1246; SSE: # BB#0: 1247; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,1,0,3] 1248; SSE-NEXT: retq 1249; 1250; AVX-LABEL: combine_nested_undef_test23: 1251; AVX: # BB#0: 1252; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm1[0,1,0,3] 1253; AVX-NEXT: retq 1254 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 1255 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3> 1256 ret <4 x i32> %2 1257} 1258 1259define <4 x i32> @combine_nested_undef_test24(<4 x i32> %A, <4 x i32> %B) { 1260; SSE-LABEL: combine_nested_undef_test24: 1261; SSE: # BB#0: 1262; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,2,3] 1263; SSE-NEXT: retq 1264; 1265; AVX-LABEL: combine_nested_undef_test24: 1266; AVX: # BB#0: 1267; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm1[0,3,2,3] 1268; AVX-NEXT: retq 1269 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 7> 1270 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 3, i32 2, i32 4> 1271 ret <4 x i32> %2 1272} 1273 1274define <4 x i32> @combine_nested_undef_test25(<4 x i32> %A, <4 x i32> %B) { 1275; SSE-LABEL: combine_nested_undef_test25: 1276; SSE: # BB#0: 1277; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1278; SSE-NEXT: retq 1279; 1280; AVX1-LABEL: combine_nested_undef_test25: 1281; AVX1: # BB#0: 1282; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1283; AVX1-NEXT: retq 1284; 1285; AVX2-LABEL: combine_nested_undef_test25: 1286; AVX2: # BB#0: 1287; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 1288; AVX2-NEXT: retq 1289 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 5, i32 2, i32 4> 1290 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 1, i32 3, i32 1> 1291 ret <4 x i32> %2 1292} 1293 1294define <4 x i32> @combine_nested_undef_test26(<4 x i32> %A, <4 x i32> %B) { 1295; SSE-LABEL: combine_nested_undef_test26: 1296; SSE: # BB#0: 1297; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 1298; SSE-NEXT: retq 1299; 1300; AVX-LABEL: combine_nested_undef_test26: 1301; AVX: # BB#0: 1302; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 1303; AVX-NEXT: retq 1304 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 6, i32 7> 1305 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3> 1306 ret <4 x i32> %2 1307} 1308 1309define <4 x i32> @combine_nested_undef_test27(<4 x i32> %A, <4 x i32> %B) { 1310; SSE-LABEL: combine_nested_undef_test27: 1311; SSE: # BB#0: 1312; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1313; SSE-NEXT: retq 1314; 1315; AVX1-LABEL: combine_nested_undef_test27: 1316; AVX1: # BB#0: 1317; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1318; AVX1-NEXT: retq 1319; 1320; AVX2-LABEL: combine_nested_undef_test27: 1321; AVX2: # BB#0: 1322; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 1323; AVX2-NEXT: retq 1324 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 2, i32 1, i32 5, i32 4> 1325 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 3, i32 2> 1326 ret <4 x i32> %2 1327} 1328 1329define <4 x i32> @combine_nested_undef_test28(<4 x i32> %A, <4 x i32> %B) { 1330; SSE-LABEL: combine_nested_undef_test28: 1331; SSE: # BB#0: 1332; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,1,0] 1333; SSE-NEXT: retq 1334; 1335; AVX-LABEL: combine_nested_undef_test28: 1336; AVX: # BB#0: 1337; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,0] 1338; AVX-NEXT: retq 1339 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 1340 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 3, i32 2> 1341 ret <4 x i32> %2 1342} 1343 1344define <4 x float> @combine_test1(<4 x float> %a, <4 x float> %b) { 1345; SSE-LABEL: combine_test1: 1346; SSE: # BB#0: 1347; SSE-NEXT: movaps %xmm1, %xmm0 1348; SSE-NEXT: retq 1349; 1350; AVX-LABEL: combine_test1: 1351; AVX: # BB#0: 1352; AVX-NEXT: vmovaps %xmm1, %xmm0 1353; AVX-NEXT: retq 1354 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1355 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1356 ret <4 x float> %2 1357} 1358 1359define <4 x float> @combine_test2(<4 x float> %a, <4 x float> %b) { 1360; SSE2-LABEL: combine_test2: 1361; SSE2: # BB#0: 1362; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1363; SSE2-NEXT: movaps %xmm1, %xmm0 1364; SSE2-NEXT: retq 1365; 1366; SSSE3-LABEL: combine_test2: 1367; SSSE3: # BB#0: 1368; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1369; SSSE3-NEXT: movaps %xmm1, %xmm0 1370; SSSE3-NEXT: retq 1371; 1372; SSE41-LABEL: combine_test2: 1373; SSE41: # BB#0: 1374; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1375; SSE41-NEXT: retq 1376; 1377; AVX-LABEL: combine_test2: 1378; AVX: # BB#0: 1379; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1380; AVX-NEXT: retq 1381 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1382 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1383 ret <4 x float> %2 1384} 1385 1386define <4 x float> @combine_test3(<4 x float> %a, <4 x float> %b) { 1387; SSE-LABEL: combine_test3: 1388; SSE: # BB#0: 1389; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1390; SSE-NEXT: retq 1391; 1392; AVX-LABEL: combine_test3: 1393; AVX: # BB#0: 1394; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1395; AVX-NEXT: retq 1396 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 1397 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 1398 ret <4 x float> %2 1399} 1400 1401define <4 x float> @combine_test4(<4 x float> %a, <4 x float> %b) { 1402; SSE-LABEL: combine_test4: 1403; SSE: # BB#0: 1404; SSE-NEXT: unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1] 1405; SSE-NEXT: movapd %xmm1, %xmm0 1406; SSE-NEXT: retq 1407; 1408; AVX-LABEL: combine_test4: 1409; AVX: # BB#0: 1410; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 1411; AVX-NEXT: retq 1412 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 1413 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1414 ret <4 x float> %2 1415} 1416 1417define <4 x float> @combine_test5(<4 x float> %a, <4 x float> %b) { 1418; SSE2-LABEL: combine_test5: 1419; SSE2: # BB#0: 1420; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1421; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1422; SSE2-NEXT: retq 1423; 1424; SSSE3-LABEL: combine_test5: 1425; SSSE3: # BB#0: 1426; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1427; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1428; SSSE3-NEXT: retq 1429; 1430; SSE41-LABEL: combine_test5: 1431; SSE41: # BB#0: 1432; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1433; SSE41-NEXT: retq 1434; 1435; AVX-LABEL: combine_test5: 1436; AVX: # BB#0: 1437; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1438; AVX-NEXT: retq 1439 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1440 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 1441 ret <4 x float> %2 1442} 1443 1444define <4 x i32> @combine_test6(<4 x i32> %a, <4 x i32> %b) { 1445; SSE-LABEL: combine_test6: 1446; SSE: # BB#0: 1447; SSE-NEXT: movaps %xmm1, %xmm0 1448; SSE-NEXT: retq 1449; 1450; AVX-LABEL: combine_test6: 1451; AVX: # BB#0: 1452; AVX-NEXT: vmovaps %xmm1, %xmm0 1453; AVX-NEXT: retq 1454 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1455 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1456 ret <4 x i32> %2 1457} 1458 1459define <4 x i32> @combine_test7(<4 x i32> %a, <4 x i32> %b) { 1460; SSE2-LABEL: combine_test7: 1461; SSE2: # BB#0: 1462; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1463; SSE2-NEXT: movaps %xmm1, %xmm0 1464; SSE2-NEXT: retq 1465; 1466; SSSE3-LABEL: combine_test7: 1467; SSSE3: # BB#0: 1468; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1469; SSSE3-NEXT: movaps %xmm1, %xmm0 1470; SSSE3-NEXT: retq 1471; 1472; SSE41-LABEL: combine_test7: 1473; SSE41: # BB#0: 1474; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7] 1475; SSE41-NEXT: retq 1476; 1477; AVX1-LABEL: combine_test7: 1478; AVX1: # BB#0: 1479; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7] 1480; AVX1-NEXT: retq 1481; 1482; AVX2-LABEL: combine_test7: 1483; AVX2: # BB#0: 1484; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1485; AVX2-NEXT: retq 1486 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1487 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1488 ret <4 x i32> %2 1489} 1490 1491define <4 x i32> @combine_test8(<4 x i32> %a, <4 x i32> %b) { 1492; SSE-LABEL: combine_test8: 1493; SSE: # BB#0: 1494; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1495; SSE-NEXT: retq 1496; 1497; AVX-LABEL: combine_test8: 1498; AVX: # BB#0: 1499; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1500; AVX-NEXT: retq 1501 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 1502 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 1503 ret <4 x i32> %2 1504} 1505 1506define <4 x i32> @combine_test9(<4 x i32> %a, <4 x i32> %b) { 1507; SSE-LABEL: combine_test9: 1508; SSE: # BB#0: 1509; SSE-NEXT: punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1] 1510; SSE-NEXT: movdqa %xmm1, %xmm0 1511; SSE-NEXT: retq 1512; 1513; AVX-LABEL: combine_test9: 1514; AVX: # BB#0: 1515; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 1516; AVX-NEXT: retq 1517 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 1518 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1519 ret <4 x i32> %2 1520} 1521 1522define <4 x i32> @combine_test10(<4 x i32> %a, <4 x i32> %b) { 1523; SSE2-LABEL: combine_test10: 1524; SSE2: # BB#0: 1525; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1526; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1527; SSE2-NEXT: retq 1528; 1529; SSSE3-LABEL: combine_test10: 1530; SSSE3: # BB#0: 1531; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1532; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1533; SSSE3-NEXT: retq 1534; 1535; SSE41-LABEL: combine_test10: 1536; SSE41: # BB#0: 1537; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1538; SSE41-NEXT: retq 1539; 1540; AVX1-LABEL: combine_test10: 1541; AVX1: # BB#0: 1542; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1543; AVX1-NEXT: retq 1544; 1545; AVX2-LABEL: combine_test10: 1546; AVX2: # BB#0: 1547; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1548; AVX2-NEXT: retq 1549 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1550 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 1551 ret <4 x i32> %2 1552} 1553 1554define <4 x float> @combine_test11(<4 x float> %a, <4 x float> %b) { 1555; ALL-LABEL: combine_test11: 1556; ALL: # BB#0: 1557; ALL-NEXT: retq 1558 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1559 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1560 ret <4 x float> %2 1561} 1562 1563define <4 x float> @combine_test12(<4 x float> %a, <4 x float> %b) { 1564; SSE2-LABEL: combine_test12: 1565; SSE2: # BB#0: 1566; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1567; SSE2-NEXT: movaps %xmm1, %xmm0 1568; SSE2-NEXT: retq 1569; 1570; SSSE3-LABEL: combine_test12: 1571; SSSE3: # BB#0: 1572; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1573; SSSE3-NEXT: movaps %xmm1, %xmm0 1574; SSSE3-NEXT: retq 1575; 1576; SSE41-LABEL: combine_test12: 1577; SSE41: # BB#0: 1578; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1579; SSE41-NEXT: retq 1580; 1581; AVX-LABEL: combine_test12: 1582; AVX: # BB#0: 1583; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1584; AVX-NEXT: retq 1585 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7> 1586 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3> 1587 ret <4 x float> %2 1588} 1589 1590define <4 x float> @combine_test13(<4 x float> %a, <4 x float> %b) { 1591; SSE-LABEL: combine_test13: 1592; SSE: # BB#0: 1593; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1594; SSE-NEXT: retq 1595; 1596; AVX-LABEL: combine_test13: 1597; AVX: # BB#0: 1598; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1599; AVX-NEXT: retq 1600 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5> 1601 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3> 1602 ret <4 x float> %2 1603} 1604 1605define <4 x float> @combine_test14(<4 x float> %a, <4 x float> %b) { 1606; SSE-LABEL: combine_test14: 1607; SSE: # BB#0: 1608; SSE-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1609; SSE-NEXT: retq 1610; 1611; AVX-LABEL: combine_test14: 1612; AVX: # BB#0: 1613; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1614; AVX-NEXT: retq 1615 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5> 1616 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1617 ret <4 x float> %2 1618} 1619 1620define <4 x float> @combine_test15(<4 x float> %a, <4 x float> %b) { 1621; SSE2-LABEL: combine_test15: 1622; SSE2: # BB#0: 1623; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1624; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1625; SSE2-NEXT: retq 1626; 1627; SSSE3-LABEL: combine_test15: 1628; SSSE3: # BB#0: 1629; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1630; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1631; SSSE3-NEXT: retq 1632; 1633; SSE41-LABEL: combine_test15: 1634; SSE41: # BB#0: 1635; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1636; SSE41-NEXT: retq 1637; 1638; AVX-LABEL: combine_test15: 1639; AVX: # BB#0: 1640; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1641; AVX-NEXT: retq 1642 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7> 1643 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 1644 ret <4 x float> %2 1645} 1646 1647define <4 x i32> @combine_test16(<4 x i32> %a, <4 x i32> %b) { 1648; ALL-LABEL: combine_test16: 1649; ALL: # BB#0: 1650; ALL-NEXT: retq 1651 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1652 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1653 ret <4 x i32> %2 1654} 1655 1656define <4 x i32> @combine_test17(<4 x i32> %a, <4 x i32> %b) { 1657; SSE2-LABEL: combine_test17: 1658; SSE2: # BB#0: 1659; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1660; SSE2-NEXT: movaps %xmm1, %xmm0 1661; SSE2-NEXT: retq 1662; 1663; SSSE3-LABEL: combine_test17: 1664; SSSE3: # BB#0: 1665; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1666; SSSE3-NEXT: movaps %xmm1, %xmm0 1667; SSSE3-NEXT: retq 1668; 1669; SSE41-LABEL: combine_test17: 1670; SSE41: # BB#0: 1671; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7] 1672; SSE41-NEXT: retq 1673; 1674; AVX1-LABEL: combine_test17: 1675; AVX1: # BB#0: 1676; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7] 1677; AVX1-NEXT: retq 1678; 1679; AVX2-LABEL: combine_test17: 1680; AVX2: # BB#0: 1681; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1682; AVX2-NEXT: retq 1683 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7> 1684 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3> 1685 ret <4 x i32> %2 1686} 1687 1688define <4 x i32> @combine_test18(<4 x i32> %a, <4 x i32> %b) { 1689; SSE-LABEL: combine_test18: 1690; SSE: # BB#0: 1691; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1692; SSE-NEXT: retq 1693; 1694; AVX-LABEL: combine_test18: 1695; AVX: # BB#0: 1696; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1697; AVX-NEXT: retq 1698 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5> 1699 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3> 1700 ret <4 x i32> %2 1701} 1702 1703define <4 x i32> @combine_test19(<4 x i32> %a, <4 x i32> %b) { 1704; SSE-LABEL: combine_test19: 1705; SSE: # BB#0: 1706; SSE-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1707; SSE-NEXT: retq 1708; 1709; AVX-LABEL: combine_test19: 1710; AVX: # BB#0: 1711; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1712; AVX-NEXT: retq 1713 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5> 1714 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1715 ret <4 x i32> %2 1716} 1717 1718define <4 x i32> @combine_test20(<4 x i32> %a, <4 x i32> %b) { 1719; SSE2-LABEL: combine_test20: 1720; SSE2: # BB#0: 1721; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1722; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1723; SSE2-NEXT: retq 1724; 1725; SSSE3-LABEL: combine_test20: 1726; SSSE3: # BB#0: 1727; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1728; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1729; SSSE3-NEXT: retq 1730; 1731; SSE41-LABEL: combine_test20: 1732; SSE41: # BB#0: 1733; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1734; SSE41-NEXT: retq 1735; 1736; AVX1-LABEL: combine_test20: 1737; AVX1: # BB#0: 1738; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1739; AVX1-NEXT: retq 1740; 1741; AVX2-LABEL: combine_test20: 1742; AVX2: # BB#0: 1743; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1744; AVX2-NEXT: retq 1745 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7> 1746 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 1747 ret <4 x i32> %2 1748} 1749 1750define <4 x i32> @combine_test21(<8 x i32> %a, <4 x i32>* %ptr) { 1751; SSE-LABEL: combine_test21: 1752; SSE: # BB#0: 1753; SSE-NEXT: movdqa %xmm0, %xmm2 1754; SSE-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0] 1755; SSE-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1756; SSE-NEXT: movdqa %xmm2, (%rdi) 1757; SSE-NEXT: retq 1758; 1759; AVX1-LABEL: combine_test21: 1760; AVX1: # BB#0: 1761; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 1762; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm0[0],xmm1[0] 1763; AVX1-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1764; AVX1-NEXT: vmovdqa %xmm2, (%rdi) 1765; AVX1-NEXT: vzeroupper 1766; AVX1-NEXT: retq 1767; 1768; AVX2-LABEL: combine_test21: 1769; AVX2: # BB#0: 1770; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 1771; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm0[0],xmm1[0] 1772; AVX2-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1773; AVX2-NEXT: vmovdqa %xmm2, (%rdi) 1774; AVX2-NEXT: vzeroupper 1775; AVX2-NEXT: retq 1776 %1 = shufflevector <8 x i32> %a, <8 x i32> %a, <4 x i32> <i32 0, i32 1, i32 4, i32 5> 1777 %2 = shufflevector <8 x i32> %a, <8 x i32> %a, <4 x i32> <i32 2, i32 3, i32 6, i32 7> 1778 store <4 x i32> %1, <4 x i32>* %ptr, align 16 1779 ret <4 x i32> %2 1780} 1781 1782define <8 x float> @combine_test22(<2 x float>* %a, <2 x float>* %b) { 1783; SSE-LABEL: combine_test22: 1784; SSE: # BB#0: 1785; SSE-NEXT: movq {{.*#+}} xmm0 = mem[0],zero 1786; SSE-NEXT: movhpd (%rsi), %xmm0 1787; SSE-NEXT: retq 1788; 1789; AVX-LABEL: combine_test22: 1790; AVX: # BB#0: 1791; AVX-NEXT: vmovq {{.*#+}} xmm0 = mem[0],zero 1792; AVX-NEXT: vmovhpd (%rsi), %xmm0, %xmm0 1793; AVX-NEXT: retq 1794; Current AVX2 lowering of this is still awful, not adding a test case. 1795 %1 = load <2 x float>, <2 x float>* %a, align 8 1796 %2 = load <2 x float>, <2 x float>* %b, align 8 1797 %3 = shufflevector <2 x float> %1, <2 x float> %2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef> 1798 ret <8 x float> %3 1799} 1800 1801; Check some negative cases. 1802; FIXME: Do any of these really make sense? Are they redundant with the above tests? 1803 1804define <4 x float> @combine_test1b(<4 x float> %a, <4 x float> %b) { 1805; SSE-LABEL: combine_test1b: 1806; SSE: # BB#0: 1807; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,1,2,0] 1808; SSE-NEXT: movaps %xmm1, %xmm0 1809; SSE-NEXT: retq 1810; 1811; AVX-LABEL: combine_test1b: 1812; AVX: # BB#0: 1813; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[0,1,2,0] 1814; AVX-NEXT: retq 1815 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1816 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 0> 1817 ret <4 x float> %2 1818} 1819 1820define <4 x float> @combine_test2b(<4 x float> %a, <4 x float> %b) { 1821; SSE2-LABEL: combine_test2b: 1822; SSE2: # BB#0: 1823; SSE2-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0,0] 1824; SSE2-NEXT: movaps %xmm1, %xmm0 1825; SSE2-NEXT: retq 1826; 1827; SSSE3-LABEL: combine_test2b: 1828; SSSE3: # BB#0: 1829; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm1[0,0] 1830; SSSE3-NEXT: retq 1831; 1832; SSE41-LABEL: combine_test2b: 1833; SSE41: # BB#0: 1834; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm1[0,0] 1835; SSE41-NEXT: retq 1836; 1837; AVX-LABEL: combine_test2b: 1838; AVX: # BB#0: 1839; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm1[0,0] 1840; AVX-NEXT: retq 1841 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1842 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 0, i32 5> 1843 ret <4 x float> %2 1844} 1845 1846define <4 x float> @combine_test3b(<4 x float> %a, <4 x float> %b) { 1847; SSE2-LABEL: combine_test3b: 1848; SSE2: # BB#0: 1849; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0] 1850; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3] 1851; SSE2-NEXT: retq 1852; 1853; SSSE3-LABEL: combine_test3b: 1854; SSSE3: # BB#0: 1855; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0] 1856; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3] 1857; SSSE3-NEXT: retq 1858; 1859; SSE41-LABEL: combine_test3b: 1860; SSE41: # BB#0: 1861; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 1862; SSE41-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,3,2,3] 1863; SSE41-NEXT: retq 1864; 1865; AVX-LABEL: combine_test3b: 1866; AVX: # BB#0: 1867; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 1868; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,3,2,3] 1869; AVX-NEXT: retq 1870 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 0, i32 6, i32 3> 1871 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 7, i32 2, i32 7> 1872 ret <4 x float> %2 1873} 1874 1875define <4 x float> @combine_test4b(<4 x float> %a, <4 x float> %b) { 1876; SSE-LABEL: combine_test4b: 1877; SSE: # BB#0: 1878; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,1,2,3] 1879; SSE-NEXT: movaps %xmm1, %xmm0 1880; SSE-NEXT: retq 1881; 1882; AVX-LABEL: combine_test4b: 1883; AVX: # BB#0: 1884; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[1,1,2,3] 1885; AVX-NEXT: retq 1886 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1887 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 5, i32 5, i32 2, i32 7> 1888 ret <4 x float> %2 1889} 1890 1891 1892; Verify that we correctly fold shuffles even when we use illegal vector types. 1893 1894define <4 x i8> @combine_test1c(<4 x i8>* %a, <4 x i8>* %b) { 1895; SSE2-LABEL: combine_test1c: 1896; SSE2: # BB#0: 1897; SSE2-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1898; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] 1899; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1900; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1901; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1902; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1903; SSE2-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 1904; SSE2-NEXT: retq 1905; 1906; SSSE3-LABEL: combine_test1c: 1907; SSSE3: # BB#0: 1908; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1909; SSSE3-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] 1910; SSSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1911; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1912; SSSE3-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1913; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1914; SSSE3-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 1915; SSSE3-NEXT: retq 1916; 1917; SSE41-LABEL: combine_test1c: 1918; SSE41: # BB#0: 1919; SSE41-NEXT: pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1920; SSE41-NEXT: pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1921; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 1922; SSE41-NEXT: retq 1923; 1924; AVX1-LABEL: combine_test1c: 1925; AVX1: # BB#0: 1926; AVX1-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1927; AVX1-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1928; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7] 1929; AVX1-NEXT: retq 1930; 1931; AVX2-LABEL: combine_test1c: 1932; AVX2: # BB#0: 1933; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1934; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1935; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1936; AVX2-NEXT: retq 1937 %A = load <4 x i8>, <4 x i8>* %a 1938 %B = load <4 x i8>, <4 x i8>* %b 1939 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1940 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1941 ret <4 x i8> %2 1942} 1943 1944define <4 x i8> @combine_test2c(<4 x i8>* %a, <4 x i8>* %b) { 1945; SSE2-LABEL: combine_test2c: 1946; SSE2: # BB#0: 1947; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1948; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1949; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1950; SSE2-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1951; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] 1952; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1953; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1954; SSE2-NEXT: retq 1955; 1956; SSSE3-LABEL: combine_test2c: 1957; SSSE3: # BB#0: 1958; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1959; SSSE3-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1960; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1961; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1962; SSSE3-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] 1963; SSSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1964; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1965; SSSE3-NEXT: retq 1966; 1967; SSE41-LABEL: combine_test2c: 1968; SSE41: # BB#0: 1969; SSE41-NEXT: pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1970; SSE41-NEXT: pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1971; SSE41-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1972; SSE41-NEXT: retq 1973; 1974; AVX-LABEL: combine_test2c: 1975; AVX: # BB#0: 1976; AVX-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1977; AVX-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1978; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1979; AVX-NEXT: retq 1980 %A = load <4 x i8>, <4 x i8>* %a 1981 %B = load <4 x i8>, <4 x i8>* %b 1982 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 1, i32 5> 1983 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 1984 ret <4 x i8> %2 1985} 1986 1987define <4 x i8> @combine_test3c(<4 x i8>* %a, <4 x i8>* %b) { 1988; SSE2-LABEL: combine_test3c: 1989; SSE2: # BB#0: 1990; SSE2-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1991; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] 1992; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1993; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1994; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1995; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1996; SSE2-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1997; SSE2-NEXT: retq 1998; 1999; SSSE3-LABEL: combine_test3c: 2000; SSSE3: # BB#0: 2001; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 2002; SSSE3-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] 2003; SSSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 2004; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 2005; SSSE3-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 2006; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 2007; SSSE3-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 2008; SSSE3-NEXT: retq 2009; 2010; SSE41-LABEL: combine_test3c: 2011; SSE41: # BB#0: 2012; SSE41-NEXT: pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2013; SSE41-NEXT: pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2014; SSE41-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 2015; SSE41-NEXT: retq 2016; 2017; AVX-LABEL: combine_test3c: 2018; AVX: # BB#0: 2019; AVX-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2020; AVX-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2021; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2022; AVX-NEXT: retq 2023 %A = load <4 x i8>, <4 x i8>* %a 2024 %B = load <4 x i8>, <4 x i8>* %b 2025 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2026 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 2027 ret <4 x i8> %2 2028} 2029 2030define <4 x i8> @combine_test4c(<4 x i8>* %a, <4 x i8>* %b) { 2031; SSE2-LABEL: combine_test4c: 2032; SSE2: # BB#0: 2033; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 2034; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 2035; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 2036; SSE2-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 2037; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] 2038; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 2039; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 2040; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 2041; SSE2-NEXT: retq 2042; 2043; SSSE3-LABEL: combine_test4c: 2044; SSSE3: # BB#0: 2045; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 2046; SSSE3-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 2047; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 2048; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 2049; SSSE3-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] 2050; SSSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 2051; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 2052; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 2053; SSSE3-NEXT: retq 2054; 2055; SSE41-LABEL: combine_test4c: 2056; SSE41: # BB#0: 2057; SSE41-NEXT: pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2058; SSE41-NEXT: pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2059; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 2060; SSE41-NEXT: retq 2061; 2062; AVX1-LABEL: combine_test4c: 2063; AVX1: # BB#0: 2064; AVX1-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2065; AVX1-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2066; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 2067; AVX1-NEXT: retq 2068; 2069; AVX2-LABEL: combine_test4c: 2070; AVX2: # BB#0: 2071; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2072; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2073; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 2074; AVX2-NEXT: retq 2075 %A = load <4 x i8>, <4 x i8>* %a 2076 %B = load <4 x i8>, <4 x i8>* %b 2077 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 2078 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 2079 ret <4 x i8> %2 2080} 2081 2082 2083; The following test cases are generated from this C++ code 2084; 2085;__m128 blend_01(__m128 a, __m128 b) 2086;{ 2087; __m128 s = a; 2088; s = _mm_blend_ps( s, b, 1<<0 ); 2089; s = _mm_blend_ps( s, b, 1<<1 ); 2090; return s; 2091;} 2092; 2093;__m128 blend_02(__m128 a, __m128 b) 2094;{ 2095; __m128 s = a; 2096; s = _mm_blend_ps( s, b, 1<<0 ); 2097; s = _mm_blend_ps( s, b, 1<<2 ); 2098; return s; 2099;} 2100; 2101;__m128 blend_123(__m128 a, __m128 b) 2102;{ 2103; __m128 s = a; 2104; s = _mm_blend_ps( s, b, 1<<1 ); 2105; s = _mm_blend_ps( s, b, 1<<2 ); 2106; s = _mm_blend_ps( s, b, 1<<3 ); 2107; return s; 2108;} 2109 2110; Ideally, we should collapse the following shuffles into a single one. 2111 2112define <4 x float> @combine_blend_01(<4 x float> %a, <4 x float> %b) { 2113; SSE2-LABEL: combine_blend_01: 2114; SSE2: # BB#0: 2115; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2116; SSE2-NEXT: retq 2117; 2118; SSSE3-LABEL: combine_blend_01: 2119; SSSE3: # BB#0: 2120; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2121; SSSE3-NEXT: retq 2122; 2123; SSE41-LABEL: combine_blend_01: 2124; SSE41: # BB#0: 2125; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2126; SSE41-NEXT: retq 2127; 2128; AVX-LABEL: combine_blend_01: 2129; AVX: # BB#0: 2130; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2131; AVX-NEXT: retq 2132 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 undef, i32 2, i32 3> 2133 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 2134 ret <4 x float> %shuffle6 2135} 2136 2137define <4 x float> @combine_blend_02(<4 x float> %a, <4 x float> %b) { 2138; SSE2-LABEL: combine_blend_02: 2139; SSE2: # BB#0: 2140; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3] 2141; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,1,3] 2142; SSE2-NEXT: movaps %xmm1, %xmm0 2143; SSE2-NEXT: retq 2144; 2145; SSSE3-LABEL: combine_blend_02: 2146; SSSE3: # BB#0: 2147; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3] 2148; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,1,3] 2149; SSSE3-NEXT: movaps %xmm1, %xmm0 2150; SSSE3-NEXT: retq 2151; 2152; SSE41-LABEL: combine_blend_02: 2153; SSE41: # BB#0: 2154; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3] 2155; SSE41-NEXT: retq 2156; 2157; AVX-LABEL: combine_blend_02: 2158; AVX: # BB#0: 2159; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3] 2160; AVX-NEXT: retq 2161 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 undef, i32 3> 2162 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 2163 ret <4 x float> %shuffle6 2164} 2165 2166define <4 x float> @combine_blend_123(<4 x float> %a, <4 x float> %b) { 2167; SSE2-LABEL: combine_blend_123: 2168; SSE2: # BB#0: 2169; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 2170; SSE2-NEXT: movaps %xmm1, %xmm0 2171; SSE2-NEXT: retq 2172; 2173; SSSE3-LABEL: combine_blend_123: 2174; SSSE3: # BB#0: 2175; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 2176; SSSE3-NEXT: movaps %xmm1, %xmm0 2177; SSSE3-NEXT: retq 2178; 2179; SSE41-LABEL: combine_blend_123: 2180; SSE41: # BB#0: 2181; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 2182; SSE41-NEXT: retq 2183; 2184; AVX-LABEL: combine_blend_123: 2185; AVX: # BB#0: 2186; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 2187; AVX-NEXT: retq 2188 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef> 2189 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 undef> 2190 %shuffle12 = shufflevector <4 x float> %shuffle6, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 2191 ret <4 x float> %shuffle12 2192} 2193 2194define <4 x i32> @combine_test_movhl_1(<4 x i32> %a, <4 x i32> %b) { 2195; SSE-LABEL: combine_test_movhl_1: 2196; SSE: # BB#0: 2197; SSE-NEXT: punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1] 2198; SSE-NEXT: movdqa %xmm1, %xmm0 2199; SSE-NEXT: retq 2200; 2201; AVX-LABEL: combine_test_movhl_1: 2202; AVX: # BB#0: 2203; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2204; AVX-NEXT: retq 2205 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 7, i32 5, i32 3> 2206 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 1, i32 0, i32 3> 2207 ret <4 x i32> %2 2208} 2209 2210define <4 x i32> @combine_test_movhl_2(<4 x i32> %a, <4 x i32> %b) { 2211; SSE-LABEL: combine_test_movhl_2: 2212; SSE: # BB#0: 2213; SSE-NEXT: punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1] 2214; SSE-NEXT: movdqa %xmm1, %xmm0 2215; SSE-NEXT: retq 2216; 2217; AVX-LABEL: combine_test_movhl_2: 2218; AVX: # BB#0: 2219; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2220; AVX-NEXT: retq 2221 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 0, i32 3, i32 6> 2222 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 3, i32 7, i32 0, i32 2> 2223 ret <4 x i32> %2 2224} 2225 2226define <4 x i32> @combine_test_movhl_3(<4 x i32> %a, <4 x i32> %b) { 2227; SSE-LABEL: combine_test_movhl_3: 2228; SSE: # BB#0: 2229; SSE-NEXT: punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1] 2230; SSE-NEXT: movdqa %xmm1, %xmm0 2231; SSE-NEXT: retq 2232; 2233; AVX-LABEL: combine_test_movhl_3: 2234; AVX: # BB#0: 2235; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2236; AVX-NEXT: retq 2237 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 7, i32 6, i32 3, i32 2> 2238 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 0, i32 3, i32 2> 2239 ret <4 x i32> %2 2240} 2241 2242 2243; Verify that we fold shuffles according to rule: 2244; (shuffle(shuffle A, Undef, M0), B, M1) -> (shuffle A, B, M2) 2245 2246define <4 x float> @combine_undef_input_test1(<4 x float> %a, <4 x float> %b) { 2247; SSE2-LABEL: combine_undef_input_test1: 2248; SSE2: # BB#0: 2249; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2250; SSE2-NEXT: retq 2251; 2252; SSSE3-LABEL: combine_undef_input_test1: 2253; SSSE3: # BB#0: 2254; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2255; SSSE3-NEXT: retq 2256; 2257; SSE41-LABEL: combine_undef_input_test1: 2258; SSE41: # BB#0: 2259; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2260; SSE41-NEXT: retq 2261; 2262; AVX-LABEL: combine_undef_input_test1: 2263; AVX: # BB#0: 2264; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2265; AVX-NEXT: retq 2266 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2267 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 4, i32 5, i32 1, i32 2> 2268 ret <4 x float> %2 2269} 2270 2271define <4 x float> @combine_undef_input_test2(<4 x float> %a, <4 x float> %b) { 2272; SSE-LABEL: combine_undef_input_test2: 2273; SSE: # BB#0: 2274; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2275; SSE-NEXT: retq 2276; 2277; AVX-LABEL: combine_undef_input_test2: 2278; AVX: # BB#0: 2279; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2280; AVX-NEXT: retq 2281 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2282 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 2283 ret <4 x float> %2 2284} 2285 2286define <4 x float> @combine_undef_input_test3(<4 x float> %a, <4 x float> %b) { 2287; SSE-LABEL: combine_undef_input_test3: 2288; SSE: # BB#0: 2289; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2290; SSE-NEXT: retq 2291; 2292; AVX-LABEL: combine_undef_input_test3: 2293; AVX: # BB#0: 2294; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2295; AVX-NEXT: retq 2296 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2297 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 2298 ret <4 x float> %2 2299} 2300 2301define <4 x float> @combine_undef_input_test4(<4 x float> %a, <4 x float> %b) { 2302; SSE-LABEL: combine_undef_input_test4: 2303; SSE: # BB#0: 2304; SSE-NEXT: unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1] 2305; SSE-NEXT: movapd %xmm1, %xmm0 2306; SSE-NEXT: retq 2307; 2308; AVX-LABEL: combine_undef_input_test4: 2309; AVX: # BB#0: 2310; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2311; AVX-NEXT: retq 2312 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2313 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 2314 ret <4 x float> %2 2315} 2316 2317define <4 x float> @combine_undef_input_test5(<4 x float> %a, <4 x float> %b) { 2318; SSE2-LABEL: combine_undef_input_test5: 2319; SSE2: # BB#0: 2320; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 2321; SSE2-NEXT: movapd %xmm1, %xmm0 2322; SSE2-NEXT: retq 2323; 2324; SSSE3-LABEL: combine_undef_input_test5: 2325; SSSE3: # BB#0: 2326; SSSE3-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 2327; SSSE3-NEXT: movapd %xmm1, %xmm0 2328; SSSE3-NEXT: retq 2329; 2330; SSE41-LABEL: combine_undef_input_test5: 2331; SSE41: # BB#0: 2332; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 2333; SSE41-NEXT: retq 2334; 2335; AVX-LABEL: combine_undef_input_test5: 2336; AVX: # BB#0: 2337; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 2338; AVX-NEXT: retq 2339 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2340 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 6, i32 7> 2341 ret <4 x float> %2 2342} 2343 2344 2345; Verify that we fold shuffles according to rule: 2346; (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2) 2347 2348define <4 x float> @combine_undef_input_test6(<4 x float> %a) { 2349; ALL-LABEL: combine_undef_input_test6: 2350; ALL: # BB#0: 2351; ALL-NEXT: retq 2352 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2353 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 1, i32 2> 2354 ret <4 x float> %2 2355} 2356 2357define <4 x float> @combine_undef_input_test7(<4 x float> %a) { 2358; SSE2-LABEL: combine_undef_input_test7: 2359; SSE2: # BB#0: 2360; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2361; SSE2-NEXT: retq 2362; 2363; SSSE3-LABEL: combine_undef_input_test7: 2364; SSSE3: # BB#0: 2365; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2366; SSSE3-NEXT: retq 2367; 2368; SSE41-LABEL: combine_undef_input_test7: 2369; SSE41: # BB#0: 2370; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2371; SSE41-NEXT: retq 2372; 2373; AVX-LABEL: combine_undef_input_test7: 2374; AVX: # BB#0: 2375; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2376; AVX-NEXT: retq 2377 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2378 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 2379 ret <4 x float> %2 2380} 2381 2382define <4 x float> @combine_undef_input_test8(<4 x float> %a) { 2383; SSE2-LABEL: combine_undef_input_test8: 2384; SSE2: # BB#0: 2385; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2386; SSE2-NEXT: retq 2387; 2388; SSSE3-LABEL: combine_undef_input_test8: 2389; SSSE3: # BB#0: 2390; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2391; SSSE3-NEXT: retq 2392; 2393; SSE41-LABEL: combine_undef_input_test8: 2394; SSE41: # BB#0: 2395; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2396; SSE41-NEXT: retq 2397; 2398; AVX-LABEL: combine_undef_input_test8: 2399; AVX: # BB#0: 2400; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2401; AVX-NEXT: retq 2402 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2403 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 2404 ret <4 x float> %2 2405} 2406 2407define <4 x float> @combine_undef_input_test9(<4 x float> %a) { 2408; SSE-LABEL: combine_undef_input_test9: 2409; SSE: # BB#0: 2410; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1] 2411; SSE-NEXT: retq 2412; 2413; AVX-LABEL: combine_undef_input_test9: 2414; AVX: # BB#0: 2415; AVX-NEXT: vmovhlps {{.*#+}} xmm0 = xmm0[1,1] 2416; AVX-NEXT: retq 2417 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2418 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 2419 ret <4 x float> %2 2420} 2421 2422define <4 x float> @combine_undef_input_test10(<4 x float> %a) { 2423; ALL-LABEL: combine_undef_input_test10: 2424; ALL: # BB#0: 2425; ALL-NEXT: retq 2426 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2427 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 6, i32 7> 2428 ret <4 x float> %2 2429} 2430 2431define <4 x float> @combine_undef_input_test11(<4 x float> %a, <4 x float> %b) { 2432; SSE2-LABEL: combine_undef_input_test11: 2433; SSE2: # BB#0: 2434; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2435; SSE2-NEXT: retq 2436; 2437; SSSE3-LABEL: combine_undef_input_test11: 2438; SSSE3: # BB#0: 2439; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2440; SSSE3-NEXT: retq 2441; 2442; SSE41-LABEL: combine_undef_input_test11: 2443; SSE41: # BB#0: 2444; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2445; SSE41-NEXT: retq 2446; 2447; AVX-LABEL: combine_undef_input_test11: 2448; AVX: # BB#0: 2449; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2450; AVX-NEXT: retq 2451 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2452 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 6> 2453 ret <4 x float> %2 2454} 2455 2456define <4 x float> @combine_undef_input_test12(<4 x float> %a, <4 x float> %b) { 2457; SSE-LABEL: combine_undef_input_test12: 2458; SSE: # BB#0: 2459; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2460; SSE-NEXT: retq 2461; 2462; AVX-LABEL: combine_undef_input_test12: 2463; AVX: # BB#0: 2464; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2465; AVX-NEXT: retq 2466 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2467 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1> 2468 ret <4 x float> %2 2469} 2470 2471define <4 x float> @combine_undef_input_test13(<4 x float> %a, <4 x float> %b) { 2472; SSE-LABEL: combine_undef_input_test13: 2473; SSE: # BB#0: 2474; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2475; SSE-NEXT: retq 2476; 2477; AVX-LABEL: combine_undef_input_test13: 2478; AVX: # BB#0: 2479; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2480; AVX-NEXT: retq 2481 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2482 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 5, i32 0, i32 5> 2483 ret <4 x float> %2 2484} 2485 2486define <4 x float> @combine_undef_input_test14(<4 x float> %a, <4 x float> %b) { 2487; SSE-LABEL: combine_undef_input_test14: 2488; SSE: # BB#0: 2489; SSE-NEXT: unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1] 2490; SSE-NEXT: movapd %xmm1, %xmm0 2491; SSE-NEXT: retq 2492; 2493; AVX-LABEL: combine_undef_input_test14: 2494; AVX: # BB#0: 2495; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2496; AVX-NEXT: retq 2497 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2498 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5> 2499 ret <4 x float> %2 2500} 2501 2502define <4 x float> @combine_undef_input_test15(<4 x float> %a, <4 x float> %b) { 2503; SSE2-LABEL: combine_undef_input_test15: 2504; SSE2: # BB#0: 2505; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 2506; SSE2-NEXT: movapd %xmm1, %xmm0 2507; SSE2-NEXT: retq 2508; 2509; SSSE3-LABEL: combine_undef_input_test15: 2510; SSSE3: # BB#0: 2511; SSSE3-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 2512; SSSE3-NEXT: movapd %xmm1, %xmm0 2513; SSSE3-NEXT: retq 2514; 2515; SSE41-LABEL: combine_undef_input_test15: 2516; SSE41: # BB#0: 2517; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 2518; SSE41-NEXT: retq 2519; 2520; AVX-LABEL: combine_undef_input_test15: 2521; AVX: # BB#0: 2522; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 2523; AVX-NEXT: retq 2524 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2525 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2526 ret <4 x float> %2 2527} 2528 2529 2530; Verify that shuffles are canonicalized according to rules: 2531; shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B) 2532; 2533; This allows to trigger the following combine rule: 2534; (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2) 2535; 2536; As a result, all the shuffle pairs in each function below should be 2537; combined into a single legal shuffle operation. 2538 2539define <4 x float> @combine_undef_input_test16(<4 x float> %a) { 2540; ALL-LABEL: combine_undef_input_test16: 2541; ALL: # BB#0: 2542; ALL-NEXT: retq 2543 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2544 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 3> 2545 ret <4 x float> %2 2546} 2547 2548define <4 x float> @combine_undef_input_test17(<4 x float> %a) { 2549; SSE2-LABEL: combine_undef_input_test17: 2550; SSE2: # BB#0: 2551; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2552; SSE2-NEXT: retq 2553; 2554; SSSE3-LABEL: combine_undef_input_test17: 2555; SSSE3: # BB#0: 2556; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2557; SSSE3-NEXT: retq 2558; 2559; SSE41-LABEL: combine_undef_input_test17: 2560; SSE41: # BB#0: 2561; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2562; SSE41-NEXT: retq 2563; 2564; AVX-LABEL: combine_undef_input_test17: 2565; AVX: # BB#0: 2566; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2567; AVX-NEXT: retq 2568 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2569 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1> 2570 ret <4 x float> %2 2571} 2572 2573define <4 x float> @combine_undef_input_test18(<4 x float> %a) { 2574; SSE2-LABEL: combine_undef_input_test18: 2575; SSE2: # BB#0: 2576; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2577; SSE2-NEXT: retq 2578; 2579; SSSE3-LABEL: combine_undef_input_test18: 2580; SSSE3: # BB#0: 2581; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2582; SSSE3-NEXT: retq 2583; 2584; SSE41-LABEL: combine_undef_input_test18: 2585; SSE41: # BB#0: 2586; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2587; SSE41-NEXT: retq 2588; 2589; AVX-LABEL: combine_undef_input_test18: 2590; AVX: # BB#0: 2591; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2592; AVX-NEXT: retq 2593 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2594 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 0, i32 5> 2595 ret <4 x float> %2 2596} 2597 2598define <4 x float> @combine_undef_input_test19(<4 x float> %a) { 2599; SSE-LABEL: combine_undef_input_test19: 2600; SSE: # BB#0: 2601; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1] 2602; SSE-NEXT: retq 2603; 2604; AVX-LABEL: combine_undef_input_test19: 2605; AVX: # BB#0: 2606; AVX-NEXT: vmovhlps {{.*#+}} xmm0 = xmm0[1,1] 2607; AVX-NEXT: retq 2608 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2609 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5> 2610 ret <4 x float> %2 2611} 2612 2613define <4 x float> @combine_undef_input_test20(<4 x float> %a) { 2614; ALL-LABEL: combine_undef_input_test20: 2615; ALL: # BB#0: 2616; ALL-NEXT: retq 2617 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2618 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2619 ret <4 x float> %2 2620} 2621 2622; These tests are designed to test the ability to combine away unnecessary 2623; operations feeding into a shuffle. The AVX cases are the important ones as 2624; they leverage operations which cannot be done naturally on the entire vector 2625; and thus are decomposed into multiple smaller operations. 2626 2627define <8 x i32> @combine_unneeded_subvector1(<8 x i32> %a) { 2628; SSE-LABEL: combine_unneeded_subvector1: 2629; SSE: # BB#0: 2630; SSE-NEXT: paddd {{.*}}(%rip), %xmm1 2631; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,2,1,0] 2632; SSE-NEXT: movdqa %xmm0, %xmm1 2633; SSE-NEXT: retq 2634; 2635; AVX1-LABEL: combine_unneeded_subvector1: 2636; AVX1: # BB#0: 2637; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 2638; AVX1-NEXT: vpaddd {{.*}}(%rip), %xmm0, %xmm0 2639; AVX1-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[3,2,1,0] 2640; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 2641; AVX1-NEXT: retq 2642; 2643; AVX2-LABEL: combine_unneeded_subvector1: 2644; AVX2: # BB#0: 2645; AVX2-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 2646; AVX2-NEXT: vmovdqa {{.*#+}} ymm1 = [7,6,5,4,7,6,5,4] 2647; AVX2-NEXT: vpermd %ymm0, %ymm1, %ymm0 2648; AVX2-NEXT: retq 2649 %b = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8> 2650 %c = shufflevector <8 x i32> %b, <8 x i32> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 7, i32 6, i32 5, i32 4> 2651 ret <8 x i32> %c 2652} 2653 2654define <8 x i32> @combine_unneeded_subvector2(<8 x i32> %a, <8 x i32> %b) { 2655; SSE-LABEL: combine_unneeded_subvector2: 2656; SSE: # BB#0: 2657; SSE-NEXT: paddd {{.*}}(%rip), %xmm1 2658; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm3[3,2,1,0] 2659; SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm1[3,2,1,0] 2660; SSE-NEXT: retq 2661; 2662; AVX1-LABEL: combine_unneeded_subvector2: 2663; AVX1: # BB#0: 2664; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 2665; AVX1-NEXT: vpaddd {{.*}}(%rip), %xmm0, %xmm0 2666; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 2667; AVX1-NEXT: vperm2f128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3] 2668; AVX1-NEXT: vpermilps {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2669; AVX1-NEXT: retq 2670; 2671; AVX2-LABEL: combine_unneeded_subvector2: 2672; AVX2: # BB#0: 2673; AVX2-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 2674; AVX2-NEXT: vperm2i128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3] 2675; AVX2-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2676; AVX2-NEXT: retq 2677 %c = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8> 2678 %d = shufflevector <8 x i32> %b, <8 x i32> %c, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 15, i32 14, i32 13, i32 12> 2679 ret <8 x i32> %d 2680} 2681 2682define <4 x float> @combine_insertps1(<4 x float> %a, <4 x float> %b) { 2683; SSE2-LABEL: combine_insertps1: 2684; SSE2: # BB#0: 2685; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0] 2686; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3] 2687; SSE2-NEXT: movaps %xmm1, %xmm0 2688; SSE2-NEXT: retq 2689; 2690; SSSE3-LABEL: combine_insertps1: 2691; SSSE3: # BB#0: 2692; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0] 2693; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3] 2694; SSSE3-NEXT: movaps %xmm1, %xmm0 2695; SSSE3-NEXT: retq 2696; 2697; SSE41-LABEL: combine_insertps1: 2698; SSE41: # BB#0: 2699; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3] 2700; SSE41-NEXT: retq 2701; 2702; AVX-LABEL: combine_insertps1: 2703; AVX: # BB#0: 2704; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3] 2705; AVX-NEXT: retq 2706 2707 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 6, i32 2, i32 4> 2708 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 5, i32 1, i32 6, i32 3> 2709 ret <4 x float> %d 2710} 2711 2712define <4 x float> @combine_insertps2(<4 x float> %a, <4 x float> %b) { 2713; SSE2-LABEL: combine_insertps2: 2714; SSE2: # BB#0: 2715; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0] 2716; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3] 2717; SSE2-NEXT: movaps %xmm1, %xmm0 2718; SSE2-NEXT: retq 2719; 2720; SSSE3-LABEL: combine_insertps2: 2721; SSSE3: # BB#0: 2722; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0] 2723; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3] 2724; SSSE3-NEXT: movaps %xmm1, %xmm0 2725; SSSE3-NEXT: retq 2726; 2727; SSE41-LABEL: combine_insertps2: 2728; SSE41: # BB#0: 2729; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3] 2730; SSE41-NEXT: retq 2731; 2732; AVX-LABEL: combine_insertps2: 2733; AVX: # BB#0: 2734; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3] 2735; AVX-NEXT: retq 2736 2737 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 1, i32 6, i32 7> 2738 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2739 ret <4 x float> %d 2740} 2741 2742define <4 x float> @combine_insertps3(<4 x float> %a, <4 x float> %b) { 2743; SSE2-LABEL: combine_insertps3: 2744; SSE2: # BB#0: 2745; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 2746; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2] 2747; SSE2-NEXT: retq 2748; 2749; SSSE3-LABEL: combine_insertps3: 2750; SSSE3: # BB#0: 2751; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 2752; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2] 2753; SSSE3-NEXT: retq 2754; 2755; SSE41-LABEL: combine_insertps3: 2756; SSE41: # BB#0: 2757; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] 2758; SSE41-NEXT: retq 2759; 2760; AVX-LABEL: combine_insertps3: 2761; AVX: # BB#0: 2762; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] 2763; AVX-NEXT: retq 2764 2765 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5> 2766 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 5, i32 3> 2767 ret <4 x float> %d 2768} 2769 2770define <4 x float> @combine_insertps4(<4 x float> %a, <4 x float> %b) { 2771; SSE2-LABEL: combine_insertps4: 2772; SSE2: # BB#0: 2773; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0] 2774; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0] 2775; SSE2-NEXT: retq 2776; 2777; SSSE3-LABEL: combine_insertps4: 2778; SSSE3: # BB#0: 2779; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0] 2780; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0] 2781; SSSE3-NEXT: retq 2782; 2783; SSE41-LABEL: combine_insertps4: 2784; SSE41: # BB#0: 2785; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] 2786; SSE41-NEXT: retq 2787; 2788; AVX-LABEL: combine_insertps4: 2789; AVX: # BB#0: 2790; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] 2791; AVX-NEXT: retq 2792 2793 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5> 2794 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 6, i32 5> 2795 ret <4 x float> %d 2796} 2797 2798define <4 x float> @PR22377(<4 x float> %a, <4 x float> %b) { 2799; SSE-LABEL: PR22377: 2800; SSE: # BB#0: # %entry 2801; SSE-NEXT: movaps %xmm0, %xmm1 2802; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,3,1,3] 2803; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,0,2] 2804; SSE-NEXT: addps %xmm0, %xmm1 2805; SSE-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2806; SSE-NEXT: retq 2807; 2808; AVX-LABEL: PR22377: 2809; AVX: # BB#0: # %entry 2810; AVX-NEXT: vpermilps {{.*#+}} xmm1 = xmm0[1,3,1,3] 2811; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,2,0,2] 2812; AVX-NEXT: vaddps %xmm0, %xmm1, %xmm1 2813; AVX-NEXT: vunpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2814; AVX-NEXT: retq 2815entry: 2816 %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 1, i32 3, i32 1, i32 3> 2817 %s2 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2> 2818 %r2 = fadd <4 x float> %s1, %s2 2819 %s3 = shufflevector <4 x float> %s2, <4 x float> %r2, <4 x i32> <i32 0, i32 4, i32 1, i32 5> 2820 ret <4 x float> %s3 2821} 2822 2823define <4 x float> @PR22390(<4 x float> %a, <4 x float> %b) { 2824; SSE2-LABEL: PR22390: 2825; SSE2: # BB#0: # %entry 2826; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2827; SSE2-NEXT: movaps %xmm0, %xmm2 2828; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3] 2829; SSE2-NEXT: addps %xmm0, %xmm2 2830; SSE2-NEXT: movaps %xmm2, %xmm0 2831; SSE2-NEXT: retq 2832; 2833; SSSE3-LABEL: PR22390: 2834; SSSE3: # BB#0: # %entry 2835; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2836; SSSE3-NEXT: movaps %xmm0, %xmm2 2837; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3] 2838; SSSE3-NEXT: addps %xmm0, %xmm2 2839; SSSE3-NEXT: movaps %xmm2, %xmm0 2840; SSSE3-NEXT: retq 2841; 2842; SSE41-LABEL: PR22390: 2843; SSE41: # BB#0: # %entry 2844; SSE41-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2845; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3] 2846; SSE41-NEXT: addps %xmm1, %xmm0 2847; SSE41-NEXT: retq 2848; 2849; AVX-LABEL: PR22390: 2850; AVX: # BB#0: # %entry 2851; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2852; AVX-NEXT: vblendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3] 2853; AVX-NEXT: vaddps %xmm1, %xmm0, %xmm0 2854; AVX-NEXT: retq 2855entry: 2856 %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 3, i32 0, i32 1, i32 2> 2857 %s2 = shufflevector <4 x float> %s1, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 2, i32 3> 2858 %r2 = fadd <4 x float> %s1, %s2 2859 ret <4 x float> %r2 2860} 2861 2862define <8 x float> @PR22412(<8 x float> %a, <8 x float> %b) { 2863; SSE2-LABEL: PR22412: 2864; SSE2: # BB#0: # %entry 2865; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1] 2866; SSE2-NEXT: movapd %xmm2, %xmm0 2867; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm3[3,2] 2868; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[1,0],xmm2[3,2] 2869; SSE2-NEXT: movaps %xmm3, %xmm1 2870; SSE2-NEXT: retq 2871; 2872; SSSE3-LABEL: PR22412: 2873; SSSE3: # BB#0: # %entry 2874; SSSE3-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1] 2875; SSSE3-NEXT: movapd %xmm2, %xmm0 2876; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm3[3,2] 2877; SSSE3-NEXT: shufps {{.*#+}} xmm3 = xmm3[1,0],xmm2[3,2] 2878; SSSE3-NEXT: movaps %xmm3, %xmm1 2879; SSSE3-NEXT: retq 2880; 2881; SSE41-LABEL: PR22412: 2882; SSE41: # BB#0: # %entry 2883; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1] 2884; SSE41-NEXT: movapd %xmm0, %xmm1 2885; SSE41-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,0],xmm3[3,2] 2886; SSE41-NEXT: shufps {{.*#+}} xmm3 = xmm3[1,0],xmm0[3,2] 2887; SSE41-NEXT: movaps %xmm1, %xmm0 2888; SSE41-NEXT: movaps %xmm3, %xmm1 2889; SSE41-NEXT: retq 2890; 2891; AVX1-LABEL: PR22412: 2892; AVX1: # BB#0: # %entry 2893; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3] 2894; AVX1-NEXT: vperm2f128 {{.*#+}} ymm1 = ymm0[2,3,0,1] 2895; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,0],ymm1[3,2],ymm0[5,4],ymm1[7,6] 2896; AVX1-NEXT: retq 2897; 2898; AVX2-LABEL: PR22412: 2899; AVX2: # BB#0: # %entry 2900; AVX2-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3] 2901; AVX2-NEXT: vmovaps {{.*#+}} ymm1 = [1,0,7,6,5,4,3,2] 2902; AVX2-NEXT: vpermps %ymm0, %ymm1, %ymm0 2903; AVX2-NEXT: retq 2904entry: 2905 %s1 = shufflevector <8 x float> %a, <8 x float> %b, <8 x i32> <i32 0, i32 1, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 2906 %s2 = shufflevector <8 x float> %s1, <8 x float> undef, <8 x i32> <i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2> 2907 ret <8 x float> %s2 2908} 2909