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; AVX1-LABEL: combine_pshufd6: 100; AVX1: # BB#0: # %entry 101; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,0,0,0] 102; AVX1-NEXT: retq 103; 104; AVX2-LABEL: combine_pshufd6: 105; AVX2: # BB#0: # %entry 106; AVX2-NEXT: vbroadcastss %xmm0, %xmm0 107; AVX2-NEXT: retq 108entry: 109 %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 0) 110 %c = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %b, i8 8) 111 ret <4 x i32> %c 112} 113 114define <8 x i16> @combine_pshuflw1(<8 x i16> %a) { 115; ALL-LABEL: combine_pshuflw1: 116; ALL: # BB#0: # %entry 117; ALL-NEXT: retq 118entry: 119 %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27) 120 %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b, i8 27) 121 ret <8 x i16> %c 122} 123 124define <8 x i16> @combine_pshuflw2(<8 x i16> %a) { 125; ALL-LABEL: combine_pshuflw2: 126; ALL: # BB#0: # %entry 127; ALL-NEXT: retq 128entry: 129 %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27) 130 %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b, i8 -28) 131 %d = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %c, i8 27) 132 ret <8 x i16> %d 133} 134 135define <8 x i16> @combine_pshuflw3(<8 x i16> %a) { 136; SSE-LABEL: combine_pshuflw3: 137; SSE: # BB#0: # %entry 138; SSE-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4] 139; SSE-NEXT: retq 140; 141; AVX-LABEL: combine_pshuflw3: 142; AVX: # BB#0: # %entry 143; AVX-NEXT: vpshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4] 144; AVX-NEXT: retq 145entry: 146 %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27) 147 %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b, i8 27) 148 %d = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %c, i8 27) 149 ret <8 x i16> %d 150} 151 152define <8 x i16> @combine_pshufhw1(<8 x i16> %a) { 153; SSE-LABEL: combine_pshufhw1: 154; SSE: # BB#0: # %entry 155; SSE-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7] 156; SSE-NEXT: retq 157; 158; AVX-LABEL: combine_pshufhw1: 159; AVX: # BB#0: # %entry 160; AVX-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7] 161; AVX-NEXT: retq 162entry: 163 %b = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %a, i8 27) 164 %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b, i8 27) 165 %d = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %c, i8 27) 166 ret <8 x i16> %d 167} 168 169define <4 x i32> @combine_bitwise_ops_test1(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 170; SSE-LABEL: combine_bitwise_ops_test1: 171; SSE: # BB#0: 172; SSE-NEXT: pand %xmm1, %xmm0 173; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 174; SSE-NEXT: retq 175; 176; AVX-LABEL: combine_bitwise_ops_test1: 177; AVX: # BB#0: 178; AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 179; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 180; AVX-NEXT: retq 181 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 182 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 183 %and = and <4 x i32> %shuf1, %shuf2 184 ret <4 x i32> %and 185} 186 187define <4 x i32> @combine_bitwise_ops_test2(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 188; SSE-LABEL: combine_bitwise_ops_test2: 189; SSE: # BB#0: 190; SSE-NEXT: por %xmm1, %xmm0 191; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 192; SSE-NEXT: retq 193; 194; AVX-LABEL: combine_bitwise_ops_test2: 195; AVX: # BB#0: 196; AVX-NEXT: vpor %xmm1, %xmm0, %xmm0 197; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 198; AVX-NEXT: retq 199 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 200 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 201 %or = or <4 x i32> %shuf1, %shuf2 202 ret <4 x i32> %or 203} 204 205define <4 x i32> @combine_bitwise_ops_test3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 206; SSE-LABEL: combine_bitwise_ops_test3: 207; SSE: # BB#0: 208; SSE-NEXT: pxor %xmm1, %xmm0 209; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 210; SSE-NEXT: retq 211; 212; AVX-LABEL: combine_bitwise_ops_test3: 213; AVX: # BB#0: 214; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 215; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 216; AVX-NEXT: retq 217 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 218 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3> 219 %xor = xor <4 x i32> %shuf1, %shuf2 220 ret <4 x i32> %xor 221} 222 223define <4 x i32> @combine_bitwise_ops_test4(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 224; SSE-LABEL: combine_bitwise_ops_test4: 225; SSE: # BB#0: 226; SSE-NEXT: pand %xmm1, %xmm0 227; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 228; SSE-NEXT: retq 229; 230; AVX-LABEL: combine_bitwise_ops_test4: 231; AVX: # BB#0: 232; AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 233; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 234; AVX-NEXT: retq 235 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7> 236 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7> 237 %and = and <4 x i32> %shuf1, %shuf2 238 ret <4 x i32> %and 239} 240 241define <4 x i32> @combine_bitwise_ops_test5(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 242; SSE-LABEL: combine_bitwise_ops_test5: 243; SSE: # BB#0: 244; SSE-NEXT: por %xmm1, %xmm0 245; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 246; SSE-NEXT: retq 247; 248; AVX-LABEL: combine_bitwise_ops_test5: 249; AVX: # BB#0: 250; AVX-NEXT: vpor %xmm1, %xmm0, %xmm0 251; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 252; AVX-NEXT: retq 253 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7> 254 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7> 255 %or = or <4 x i32> %shuf1, %shuf2 256 ret <4 x i32> %or 257} 258 259define <4 x i32> @combine_bitwise_ops_test6(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 260; SSE-LABEL: combine_bitwise_ops_test6: 261; SSE: # BB#0: 262; SSE-NEXT: pxor %xmm1, %xmm0 263; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 264; SSE-NEXT: retq 265; 266; AVX-LABEL: combine_bitwise_ops_test6: 267; AVX: # BB#0: 268; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 269; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 270; AVX-NEXT: retq 271 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7> 272 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7> 273 %xor = xor <4 x i32> %shuf1, %shuf2 274 ret <4 x i32> %xor 275} 276 277 278; Verify that DAGCombiner moves the shuffle after the xor/and/or even if shuffles 279; are not performing a swizzle operations. 280 281define <4 x i32> @combine_bitwise_ops_test1b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 282; SSE2-LABEL: combine_bitwise_ops_test1b: 283; SSE2: # BB#0: 284; SSE2-NEXT: pand %xmm1, %xmm0 285; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 286; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 287; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 288; SSE2-NEXT: retq 289; 290; SSSE3-LABEL: combine_bitwise_ops_test1b: 291; SSSE3: # BB#0: 292; SSSE3-NEXT: pand %xmm1, %xmm0 293; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 294; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 295; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 296; SSSE3-NEXT: retq 297; 298; SSE41-LABEL: combine_bitwise_ops_test1b: 299; SSE41: # BB#0: 300; SSE41-NEXT: pand %xmm1, %xmm0 301; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 302; SSE41-NEXT: retq 303; 304; AVX1-LABEL: combine_bitwise_ops_test1b: 305; AVX1: # BB#0: 306; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 307; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 308; AVX1-NEXT: retq 309; 310; AVX2-LABEL: combine_bitwise_ops_test1b: 311; AVX2: # BB#0: 312; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 313; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] 314; AVX2-NEXT: retq 315 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 316 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 317 %and = and <4 x i32> %shuf1, %shuf2 318 ret <4 x i32> %and 319} 320 321define <4 x i32> @combine_bitwise_ops_test2b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 322; SSE2-LABEL: combine_bitwise_ops_test2b: 323; SSE2: # BB#0: 324; SSE2-NEXT: por %xmm1, %xmm0 325; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 326; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 327; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 328; SSE2-NEXT: retq 329; 330; SSSE3-LABEL: combine_bitwise_ops_test2b: 331; SSSE3: # BB#0: 332; SSSE3-NEXT: por %xmm1, %xmm0 333; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 334; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 335; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 336; SSSE3-NEXT: retq 337; 338; SSE41-LABEL: combine_bitwise_ops_test2b: 339; SSE41: # BB#0: 340; SSE41-NEXT: por %xmm1, %xmm0 341; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 342; SSE41-NEXT: retq 343; 344; AVX1-LABEL: combine_bitwise_ops_test2b: 345; AVX1: # BB#0: 346; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 347; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 348; AVX1-NEXT: retq 349; 350; AVX2-LABEL: combine_bitwise_ops_test2b: 351; AVX2: # BB#0: 352; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 353; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] 354; AVX2-NEXT: retq 355 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 356 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 357 %or = or <4 x i32> %shuf1, %shuf2 358 ret <4 x i32> %or 359} 360 361define <4 x i32> @combine_bitwise_ops_test3b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 362; SSE2-LABEL: combine_bitwise_ops_test3b: 363; SSE2: # BB#0: 364; SSE2-NEXT: xorps %xmm1, %xmm0 365; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 366; SSE2-NEXT: retq 367; 368; SSSE3-LABEL: combine_bitwise_ops_test3b: 369; SSSE3: # BB#0: 370; SSSE3-NEXT: xorps %xmm1, %xmm0 371; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 372; SSSE3-NEXT: retq 373; 374; SSE41-LABEL: combine_bitwise_ops_test3b: 375; SSE41: # BB#0: 376; SSE41-NEXT: pxor %xmm1, %xmm0 377; SSE41-NEXT: pxor %xmm1, %xmm1 378; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 379; SSE41-NEXT: retq 380; 381; AVX1-LABEL: combine_bitwise_ops_test3b: 382; AVX1: # BB#0: 383; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 384; AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1 385; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 386; AVX1-NEXT: retq 387; 388; AVX2-LABEL: combine_bitwise_ops_test3b: 389; AVX2: # BB#0: 390; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 391; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 392; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 393; AVX2-NEXT: retq 394 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 395 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7> 396 %xor = xor <4 x i32> %shuf1, %shuf2 397 ret <4 x i32> %xor 398} 399 400define <4 x i32> @combine_bitwise_ops_test4b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 401; SSE2-LABEL: combine_bitwise_ops_test4b: 402; SSE2: # BB#0: 403; SSE2-NEXT: pand %xmm1, %xmm0 404; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 405; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 406; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 407; SSE2-NEXT: retq 408; 409; SSSE3-LABEL: combine_bitwise_ops_test4b: 410; SSSE3: # BB#0: 411; SSSE3-NEXT: pand %xmm1, %xmm0 412; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 413; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 414; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 415; SSSE3-NEXT: retq 416; 417; SSE41-LABEL: combine_bitwise_ops_test4b: 418; SSE41: # BB#0: 419; SSE41-NEXT: pand %xmm1, %xmm0 420; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 421; SSE41-NEXT: retq 422; 423; AVX1-LABEL: combine_bitwise_ops_test4b: 424; AVX1: # BB#0: 425; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 426; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 427; AVX1-NEXT: retq 428; 429; AVX2-LABEL: combine_bitwise_ops_test4b: 430; AVX2: # BB#0: 431; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 432; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3] 433; AVX2-NEXT: retq 434 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7> 435 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7> 436 %and = and <4 x i32> %shuf1, %shuf2 437 ret <4 x i32> %and 438} 439 440define <4 x i32> @combine_bitwise_ops_test5b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 441; SSE2-LABEL: combine_bitwise_ops_test5b: 442; SSE2: # BB#0: 443; SSE2-NEXT: por %xmm1, %xmm0 444; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 445; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 446; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 447; SSE2-NEXT: retq 448; 449; SSSE3-LABEL: combine_bitwise_ops_test5b: 450; SSSE3: # BB#0: 451; SSSE3-NEXT: por %xmm1, %xmm0 452; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 453; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 454; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 455; SSSE3-NEXT: retq 456; 457; SSE41-LABEL: combine_bitwise_ops_test5b: 458; SSE41: # BB#0: 459; SSE41-NEXT: por %xmm1, %xmm0 460; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 461; SSE41-NEXT: retq 462; 463; AVX1-LABEL: combine_bitwise_ops_test5b: 464; AVX1: # BB#0: 465; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 466; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 467; AVX1-NEXT: retq 468; 469; AVX2-LABEL: combine_bitwise_ops_test5b: 470; AVX2: # BB#0: 471; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 472; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3] 473; AVX2-NEXT: retq 474 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7> 475 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7> 476 %or = or <4 x i32> %shuf1, %shuf2 477 ret <4 x i32> %or 478} 479 480define <4 x i32> @combine_bitwise_ops_test6b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 481; SSE2-LABEL: combine_bitwise_ops_test6b: 482; SSE2: # BB#0: 483; SSE2-NEXT: xorps %xmm1, %xmm0 484; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 485; SSE2-NEXT: retq 486; 487; SSSE3-LABEL: combine_bitwise_ops_test6b: 488; SSSE3: # BB#0: 489; SSSE3-NEXT: xorps %xmm1, %xmm0 490; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 491; SSSE3-NEXT: retq 492; 493; SSE41-LABEL: combine_bitwise_ops_test6b: 494; SSE41: # BB#0: 495; SSE41-NEXT: pxor %xmm1, %xmm0 496; SSE41-NEXT: pxor %xmm1, %xmm1 497; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5],xmm0[6,7] 498; SSE41-NEXT: retq 499; 500; AVX1-LABEL: combine_bitwise_ops_test6b: 501; AVX1: # BB#0: 502; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 503; AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1 504; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5],xmm0[6,7] 505; AVX1-NEXT: retq 506; 507; AVX2-LABEL: combine_bitwise_ops_test6b: 508; AVX2: # BB#0: 509; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 510; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 511; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3] 512; AVX2-NEXT: retq 513 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7> 514 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7> 515 %xor = xor <4 x i32> %shuf1, %shuf2 516 ret <4 x i32> %xor 517} 518 519define <4 x i32> @combine_bitwise_ops_test1c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 520; SSE2-LABEL: combine_bitwise_ops_test1c: 521; SSE2: # BB#0: 522; SSE2-NEXT: pand %xmm1, %xmm0 523; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 524; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 525; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 526; SSE2-NEXT: retq 527; 528; SSSE3-LABEL: combine_bitwise_ops_test1c: 529; SSSE3: # BB#0: 530; SSSE3-NEXT: pand %xmm1, %xmm0 531; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 532; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 533; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 534; SSSE3-NEXT: retq 535; 536; SSE41-LABEL: combine_bitwise_ops_test1c: 537; SSE41: # BB#0: 538; SSE41-NEXT: pand %xmm1, %xmm0 539; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 540; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 541; SSE41-NEXT: retq 542; 543; AVX1-LABEL: combine_bitwise_ops_test1c: 544; AVX1: # BB#0: 545; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 546; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 547; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 548; AVX1-NEXT: retq 549; 550; AVX2-LABEL: combine_bitwise_ops_test1c: 551; AVX2: # BB#0: 552; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 553; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] 554; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 555; AVX2-NEXT: retq 556 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 557 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 558 %and = and <4 x i32> %shuf1, %shuf2 559 ret <4 x i32> %and 560} 561 562define <4 x i32> @combine_bitwise_ops_test2c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 563; SSE2-LABEL: combine_bitwise_ops_test2c: 564; SSE2: # BB#0: 565; SSE2-NEXT: por %xmm1, %xmm0 566; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 567; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 568; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 569; SSE2-NEXT: retq 570; 571; SSSE3-LABEL: combine_bitwise_ops_test2c: 572; SSSE3: # BB#0: 573; SSSE3-NEXT: por %xmm1, %xmm0 574; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 575; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,3,2,3] 576; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 577; SSSE3-NEXT: retq 578; 579; SSE41-LABEL: combine_bitwise_ops_test2c: 580; SSE41: # BB#0: 581; SSE41-NEXT: por %xmm1, %xmm0 582; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 583; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 584; SSE41-NEXT: retq 585; 586; AVX1-LABEL: combine_bitwise_ops_test2c: 587; AVX1: # BB#0: 588; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 589; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] 590; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 591; AVX1-NEXT: retq 592; 593; AVX2-LABEL: combine_bitwise_ops_test2c: 594; AVX2: # BB#0: 595; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 596; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] 597; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 598; AVX2-NEXT: retq 599 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 600 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 601 %or = or <4 x i32> %shuf1, %shuf2 602 ret <4 x i32> %or 603} 604 605define <4 x i32> @combine_bitwise_ops_test3c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 606; SSE2-LABEL: combine_bitwise_ops_test3c: 607; SSE2: # BB#0: 608; SSE2-NEXT: pxor %xmm1, %xmm0 609; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,2] 610; SSE2-NEXT: psrldq {{.*#+}} xmm0 = xmm0[8,9,10,11,12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero 611; SSE2-NEXT: retq 612; 613; SSSE3-LABEL: combine_bitwise_ops_test3c: 614; SSSE3: # BB#0: 615; SSSE3-NEXT: pxor %xmm1, %xmm0 616; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,2] 617; SSSE3-NEXT: psrldq {{.*#+}} xmm0 = xmm0[8,9,10,11,12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero 618; SSSE3-NEXT: retq 619; 620; SSE41-LABEL: combine_bitwise_ops_test3c: 621; SSE41: # BB#0: 622; SSE41-NEXT: pxor %xmm1, %xmm0 623; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 624; SSE41-NEXT: movq {{.*#+}} xmm0 = xmm0[0],zero 625; SSE41-NEXT: retq 626; 627; AVX-LABEL: combine_bitwise_ops_test3c: 628; AVX: # BB#0: 629; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 630; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 631; AVX-NEXT: vmovq {{.*#+}} xmm0 = xmm0[0],zero 632; AVX-NEXT: retq 633 %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 634 %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7> 635 %xor = xor <4 x i32> %shuf1, %shuf2 636 ret <4 x i32> %xor 637} 638 639define <4 x i32> @combine_bitwise_ops_test4c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 640; SSE2-LABEL: combine_bitwise_ops_test4c: 641; SSE2: # BB#0: 642; SSE2-NEXT: pand %xmm1, %xmm0 643; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 644; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 645; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 646; SSE2-NEXT: retq 647; 648; SSSE3-LABEL: combine_bitwise_ops_test4c: 649; SSSE3: # BB#0: 650; SSSE3-NEXT: pand %xmm1, %xmm0 651; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 652; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 653; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 654; SSSE3-NEXT: retq 655; 656; SSE41-LABEL: combine_bitwise_ops_test4c: 657; SSE41: # BB#0: 658; SSE41-NEXT: pand %xmm1, %xmm0 659; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 660; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 661; SSE41-NEXT: retq 662; 663; AVX1-LABEL: combine_bitwise_ops_test4c: 664; AVX1: # BB#0: 665; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 666; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 667; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 668; AVX1-NEXT: retq 669; 670; AVX2-LABEL: combine_bitwise_ops_test4c: 671; AVX2: # BB#0: 672; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm0 673; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3] 674; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 675; AVX2-NEXT: retq 676 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7> 677 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7> 678 %and = and <4 x i32> %shuf1, %shuf2 679 ret <4 x i32> %and 680} 681 682define <4 x i32> @combine_bitwise_ops_test5c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 683; SSE2-LABEL: combine_bitwise_ops_test5c: 684; SSE2: # BB#0: 685; SSE2-NEXT: por %xmm1, %xmm0 686; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 687; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 688; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 689; SSE2-NEXT: retq 690; 691; SSSE3-LABEL: combine_bitwise_ops_test5c: 692; SSSE3: # BB#0: 693; SSSE3-NEXT: por %xmm1, %xmm0 694; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,3,2,3] 695; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 696; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 697; SSSE3-NEXT: retq 698; 699; SSE41-LABEL: combine_bitwise_ops_test5c: 700; SSE41: # BB#0: 701; SSE41-NEXT: por %xmm1, %xmm0 702; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 703; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 704; SSE41-NEXT: retq 705; 706; AVX1-LABEL: combine_bitwise_ops_test5c: 707; AVX1: # BB#0: 708; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 709; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] 710; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 711; AVX1-NEXT: retq 712; 713; AVX2-LABEL: combine_bitwise_ops_test5c: 714; AVX2: # BB#0: 715; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0 716; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3] 717; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 718; AVX2-NEXT: retq 719 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7> 720 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7> 721 %or = or <4 x i32> %shuf1, %shuf2 722 ret <4 x i32> %or 723} 724 725define <4 x i32> @combine_bitwise_ops_test6c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 726; SSE2-LABEL: combine_bitwise_ops_test6c: 727; SSE2: # BB#0: 728; SSE2-NEXT: pxor %xmm1, %xmm0 729; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3] 730; SSE2-NEXT: pslldq {{.*#+}} xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7] 731; SSE2-NEXT: retq 732; 733; SSSE3-LABEL: combine_bitwise_ops_test6c: 734; SSSE3: # BB#0: 735; SSSE3-NEXT: pxor %xmm1, %xmm0 736; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3] 737; SSSE3-NEXT: pslldq {{.*#+}} xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7] 738; SSSE3-NEXT: retq 739; 740; SSE41-LABEL: combine_bitwise_ops_test6c: 741; SSE41: # BB#0: 742; SSE41-NEXT: pxor %xmm1, %xmm0 743; SSE41-NEXT: pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3] 744; SSE41-NEXT: pxor %xmm0, %xmm0 745; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7] 746; SSE41-NEXT: retq 747; 748; AVX1-LABEL: combine_bitwise_ops_test6c: 749; AVX1: # BB#0: 750; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 751; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,3] 752; AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1 753; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7] 754; AVX1-NEXT: retq 755; 756; AVX2-LABEL: combine_bitwise_ops_test6c: 757; AVX2: # BB#0: 758; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 759; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,3] 760; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 761; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 762; AVX2-NEXT: retq 763 %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7> 764 %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7> 765 %xor = xor <4 x i32> %shuf1, %shuf2 766 ret <4 x i32> %xor 767} 768 769define <4 x i32> @combine_nested_undef_test1(<4 x i32> %A, <4 x i32> %B) { 770; SSE-LABEL: combine_nested_undef_test1: 771; SSE: # BB#0: 772; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 773; SSE-NEXT: retq 774; 775; AVX-LABEL: combine_nested_undef_test1: 776; AVX: # BB#0: 777; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 778; AVX-NEXT: retq 779 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1> 780 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 781 ret <4 x i32> %2 782} 783 784define <4 x i32> @combine_nested_undef_test2(<4 x i32> %A, <4 x i32> %B) { 785; SSE-LABEL: combine_nested_undef_test2: 786; SSE: # BB#0: 787; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,1,0,3] 788; SSE-NEXT: retq 789; 790; AVX-LABEL: combine_nested_undef_test2: 791; AVX: # BB#0: 792; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,1,0,3] 793; AVX-NEXT: retq 794 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 795 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 796 ret <4 x i32> %2 797} 798 799define <4 x i32> @combine_nested_undef_test3(<4 x i32> %A, <4 x i32> %B) { 800; SSE-LABEL: combine_nested_undef_test3: 801; SSE: # BB#0: 802; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,1,0,3] 803; SSE-NEXT: retq 804; 805; AVX-LABEL: combine_nested_undef_test3: 806; AVX: # BB#0: 807; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,1,0,3] 808; AVX-NEXT: retq 809 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 3> 810 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 811 ret <4 x i32> %2 812} 813 814define <4 x i32> @combine_nested_undef_test4(<4 x i32> %A, <4 x i32> %B) { 815; SSE-LABEL: combine_nested_undef_test4: 816; SSE: # BB#0: 817; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 818; SSE-NEXT: retq 819; 820; AVX1-LABEL: combine_nested_undef_test4: 821; AVX1: # BB#0: 822; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 823; AVX1-NEXT: retq 824; 825; AVX2-LABEL: combine_nested_undef_test4: 826; AVX2: # BB#0: 827; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 828; AVX2-NEXT: retq 829 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 7, i32 1> 830 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 4, i32 4, i32 0, i32 3> 831 ret <4 x i32> %2 832} 833 834define <4 x i32> @combine_nested_undef_test5(<4 x i32> %A, <4 x i32> %B) { 835; SSE-LABEL: combine_nested_undef_test5: 836; SSE: # BB#0: 837; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 838; SSE-NEXT: retq 839; 840; AVX-LABEL: combine_nested_undef_test5: 841; AVX: # BB#0: 842; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 843; AVX-NEXT: retq 844 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 5, i32 5, i32 2, i32 3> 845 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 4, i32 3> 846 ret <4 x i32> %2 847} 848 849define <4 x i32> @combine_nested_undef_test6(<4 x i32> %A, <4 x i32> %B) { 850; SSE-LABEL: combine_nested_undef_test6: 851; SSE: # BB#0: 852; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 853; SSE-NEXT: retq 854; 855; AVX-LABEL: combine_nested_undef_test6: 856; AVX: # BB#0: 857; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 858; AVX-NEXT: retq 859 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 4> 860 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 4> 861 ret <4 x i32> %2 862} 863 864define <4 x i32> @combine_nested_undef_test7(<4 x i32> %A, <4 x i32> %B) { 865; SSE-LABEL: combine_nested_undef_test7: 866; SSE: # BB#0: 867; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,0,2] 868; SSE-NEXT: retq 869; 870; AVX-LABEL: combine_nested_undef_test7: 871; AVX: # BB#0: 872; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,0,2] 873; AVX-NEXT: retq 874 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 875 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2> 876 ret <4 x i32> %2 877} 878 879define <4 x i32> @combine_nested_undef_test8(<4 x i32> %A, <4 x i32> %B) { 880; SSE-LABEL: combine_nested_undef_test8: 881; SSE: # BB#0: 882; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 883; SSE-NEXT: retq 884; 885; AVX-LABEL: combine_nested_undef_test8: 886; AVX: # BB#0: 887; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 888; AVX-NEXT: retq 889 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 890 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 4, i32 3, i32 4> 891 ret <4 x i32> %2 892} 893 894define <4 x i32> @combine_nested_undef_test9(<4 x i32> %A, <4 x i32> %B) { 895; SSE-LABEL: combine_nested_undef_test9: 896; SSE: # BB#0: 897; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,2] 898; SSE-NEXT: retq 899; 900; AVX-LABEL: combine_nested_undef_test9: 901; AVX: # BB#0: 902; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,3,2,2] 903; AVX-NEXT: retq 904 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 3, i32 2, i32 5> 905 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 2> 906 ret <4 x i32> %2 907} 908 909define <4 x i32> @combine_nested_undef_test10(<4 x i32> %A, <4 x i32> %B) { 910; SSE-LABEL: combine_nested_undef_test10: 911; SSE: # BB#0: 912; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,3] 913; SSE-NEXT: retq 914; 915; AVX-LABEL: combine_nested_undef_test10: 916; AVX: # BB#0: 917; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,1,3] 918; AVX-NEXT: retq 919 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 1, i32 5, i32 5> 920 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 4> 921 ret <4 x i32> %2 922} 923 924define <4 x i32> @combine_nested_undef_test11(<4 x i32> %A, <4 x i32> %B) { 925; SSE-LABEL: combine_nested_undef_test11: 926; SSE: # BB#0: 927; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,2,1] 928; SSE-NEXT: retq 929; 930; AVX-LABEL: combine_nested_undef_test11: 931; AVX: # BB#0: 932; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,1] 933; AVX-NEXT: retq 934 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 2, i32 5, i32 4> 935 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 0> 936 ret <4 x i32> %2 937} 938 939define <4 x i32> @combine_nested_undef_test12(<4 x i32> %A, <4 x i32> %B) { 940; SSE-LABEL: combine_nested_undef_test12: 941; SSE: # BB#0: 942; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 943; SSE-NEXT: retq 944; 945; AVX1-LABEL: combine_nested_undef_test12: 946; AVX1: # BB#0: 947; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 948; AVX1-NEXT: retq 949; 950; AVX2-LABEL: combine_nested_undef_test12: 951; AVX2: # BB#0: 952; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 953; AVX2-NEXT: retq 954 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 0, i32 2, i32 4> 955 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 4, i32 0, i32 4> 956 ret <4 x i32> %2 957} 958 959; The following pair of shuffles is folded into vector %A. 960define <4 x i32> @combine_nested_undef_test13(<4 x i32> %A, <4 x i32> %B) { 961; ALL-LABEL: combine_nested_undef_test13: 962; ALL: # BB#0: 963; ALL-NEXT: retq 964 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 4, i32 2, i32 6> 965 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 4, i32 0, i32 2, i32 4> 966 ret <4 x i32> %2 967} 968 969; The following pair of shuffles is folded into vector %B. 970define <4 x i32> @combine_nested_undef_test14(<4 x i32> %A, <4 x i32> %B) { 971; SSE-LABEL: combine_nested_undef_test14: 972; SSE: # BB#0: 973; SSE-NEXT: movaps %xmm1, %xmm0 974; SSE-NEXT: retq 975; 976; AVX-LABEL: combine_nested_undef_test14: 977; AVX: # BB#0: 978; AVX-NEXT: vmovaps %xmm1, %xmm0 979; AVX-NEXT: retq 980 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 4> 981 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 4, i32 1, i32 4> 982 ret <4 x i32> %2 983} 984 985 986; Verify that we don't optimize the following cases. We expect more than one shuffle. 987; 988; FIXME: Many of these already don't make sense, and the rest should stop 989; making sense with th enew vector shuffle lowering. Revisit at least testing for 990; it. 991 992define <4 x i32> @combine_nested_undef_test15(<4 x i32> %A, <4 x i32> %B) { 993; SSE2-LABEL: combine_nested_undef_test15: 994; SSE2: # BB#0: 995; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 996; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,1] 997; SSE2-NEXT: movaps %xmm1, %xmm0 998; SSE2-NEXT: retq 999; 1000; SSSE3-LABEL: combine_nested_undef_test15: 1001; SSSE3: # BB#0: 1002; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 1003; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,1] 1004; SSSE3-NEXT: movaps %xmm1, %xmm0 1005; SSSE3-NEXT: retq 1006; 1007; SSE41-LABEL: combine_nested_undef_test15: 1008; SSE41: # BB#0: 1009; SSE41-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,0,1,1] 1010; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1011; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 1012; SSE41-NEXT: retq 1013; 1014; AVX1-LABEL: combine_nested_undef_test15: 1015; AVX1: # BB#0: 1016; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[0,0,1,1] 1017; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1018; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 1019; AVX1-NEXT: retq 1020; 1021; AVX2-LABEL: combine_nested_undef_test15: 1022; AVX2: # BB#0: 1023; AVX2-NEXT: vpbroadcastd %xmm1, %xmm1 1024; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1025; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3] 1026; AVX2-NEXT: retq 1027 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1> 1028 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1029 ret <4 x i32> %2 1030} 1031 1032define <4 x i32> @combine_nested_undef_test16(<4 x i32> %A, <4 x i32> %B) { 1033; SSE2-LABEL: combine_nested_undef_test16: 1034; SSE2: # BB#0: 1035; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] 1036; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,0,2,3] 1037; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1038; SSE2-NEXT: retq 1039; 1040; SSSE3-LABEL: combine_nested_undef_test16: 1041; SSSE3: # BB#0: 1042; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] 1043; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,0,2,3] 1044; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1045; SSSE3-NEXT: retq 1046; 1047; SSE41-LABEL: combine_nested_undef_test16: 1048; SSE41: # BB#0: 1049; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 1050; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 1051; SSE41-NEXT: retq 1052; 1053; AVX1-LABEL: combine_nested_undef_test16: 1054; AVX1: # BB#0: 1055; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 1056; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 1057; AVX1-NEXT: retq 1058; 1059; AVX2-LABEL: combine_nested_undef_test16: 1060; AVX2: # BB#0: 1061; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 1062; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 1063; AVX2-NEXT: retq 1064 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1065 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1066 ret <4 x i32> %2 1067} 1068 1069define <4 x i32> @combine_nested_undef_test17(<4 x i32> %A, <4 x i32> %B) { 1070; SSE2-LABEL: combine_nested_undef_test17: 1071; SSE2: # BB#0: 1072; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0] 1073; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2] 1074; SSE2-NEXT: retq 1075; 1076; SSSE3-LABEL: combine_nested_undef_test17: 1077; SSSE3: # BB#0: 1078; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0] 1079; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2] 1080; SSSE3-NEXT: retq 1081; 1082; SSE41-LABEL: combine_nested_undef_test17: 1083; SSE41: # BB#0: 1084; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 1085; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1086; SSE41-NEXT: retq 1087; 1088; AVX1-LABEL: combine_nested_undef_test17: 1089; AVX1: # BB#0: 1090; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 1091; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1092; AVX1-NEXT: retq 1093; 1094; AVX2-LABEL: combine_nested_undef_test17: 1095; AVX2: # BB#0: 1096; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 1097; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 1098; AVX2-NEXT: retq 1099 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1> 1100 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1101 ret <4 x i32> %2 1102} 1103 1104define <4 x i32> @combine_nested_undef_test18(<4 x i32> %A, <4 x i32> %B) { 1105; SSE-LABEL: combine_nested_undef_test18: 1106; SSE: # BB#0: 1107; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,0,3] 1108; SSE-NEXT: retq 1109; 1110; AVX-LABEL: combine_nested_undef_test18: 1111; AVX: # BB#0: 1112; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm1[1,1,0,3] 1113; AVX-NEXT: retq 1114 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 1115 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 0, i32 3> 1116 ret <4 x i32> %2 1117} 1118 1119define <4 x i32> @combine_nested_undef_test19(<4 x i32> %A, <4 x i32> %B) { 1120; SSE2-LABEL: combine_nested_undef_test19: 1121; SSE2: # BB#0: 1122; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1123; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,0,0,0] 1124; SSE2-NEXT: retq 1125; 1126; SSSE3-LABEL: combine_nested_undef_test19: 1127; SSSE3: # BB#0: 1128; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1129; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,0,0,0] 1130; SSSE3-NEXT: retq 1131; 1132; SSE41-LABEL: combine_nested_undef_test19: 1133; SSE41: # BB#0: 1134; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 1135; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,0,0,0] 1136; SSE41-NEXT: retq 1137; 1138; AVX1-LABEL: combine_nested_undef_test19: 1139; AVX1: # BB#0: 1140; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 1141; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,0,0,0] 1142; AVX1-NEXT: retq 1143; 1144; AVX2-LABEL: combine_nested_undef_test19: 1145; AVX2: # BB#0: 1146; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3] 1147; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,0,0,0] 1148; AVX2-NEXT: retq 1149 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 5, i32 6> 1150 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 0, i32 0, i32 0> 1151 ret <4 x i32> %2 1152} 1153 1154define <4 x i32> @combine_nested_undef_test20(<4 x i32> %A, <4 x i32> %B) { 1155; SSE2-LABEL: combine_nested_undef_test20: 1156; SSE2: # BB#0: 1157; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3] 1158; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,3,1] 1159; SSE2-NEXT: movaps %xmm1, %xmm0 1160; SSE2-NEXT: retq 1161; 1162; SSSE3-LABEL: combine_nested_undef_test20: 1163; SSSE3: # BB#0: 1164; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3] 1165; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,3,1] 1166; SSSE3-NEXT: movaps %xmm1, %xmm0 1167; SSSE3-NEXT: retq 1168; 1169; SSE41-LABEL: combine_nested_undef_test20: 1170; SSE41: # BB#0: 1171; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7] 1172; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,3,0] 1173; SSE41-NEXT: retq 1174; 1175; AVX1-LABEL: combine_nested_undef_test20: 1176; AVX1: # BB#0: 1177; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7] 1178; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,3,0] 1179; AVX1-NEXT: retq 1180; 1181; AVX2-LABEL: combine_nested_undef_test20: 1182; AVX2: # BB#0: 1183; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 1184; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,3,0] 1185; AVX2-NEXT: retq 1186 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 3, i32 2, i32 4, i32 4> 1187 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1188 ret <4 x i32> %2 1189} 1190 1191define <4 x i32> @combine_nested_undef_test21(<4 x i32> %A, <4 x i32> %B) { 1192; SSE2-LABEL: combine_nested_undef_test21: 1193; SSE2: # BB#0: 1194; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 1195; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,0,3] 1196; SSE2-NEXT: retq 1197; 1198; SSSE3-LABEL: combine_nested_undef_test21: 1199; SSSE3: # BB#0: 1200; SSSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 1201; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,0,3] 1202; SSSE3-NEXT: retq 1203; 1204; SSE41-LABEL: combine_nested_undef_test21: 1205; SSE41: # BB#0: 1206; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1207; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1208; SSE41-NEXT: retq 1209; 1210; AVX1-LABEL: combine_nested_undef_test21: 1211; AVX1: # BB#0: 1212; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1213; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1214; AVX1-NEXT: retq 1215; 1216; AVX2-LABEL: combine_nested_undef_test21: 1217; AVX2: # BB#0: 1218; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1219; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 1220; AVX2-NEXT: retq 1221 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1> 1222 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3> 1223 ret <4 x i32> %2 1224} 1225 1226 1227; Test that we correctly combine shuffles according to rule 1228; shuffle(shuffle(x, y), undef) -> shuffle(y, undef) 1229 1230define <4 x i32> @combine_nested_undef_test22(<4 x i32> %A, <4 x i32> %B) { 1231; SSE-LABEL: combine_nested_undef_test22: 1232; SSE: # BB#0: 1233; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,3] 1234; SSE-NEXT: retq 1235; 1236; AVX-LABEL: combine_nested_undef_test22: 1237; AVX: # BB#0: 1238; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm1[1,1,1,3] 1239; AVX-NEXT: retq 1240 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 1241 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 3> 1242 ret <4 x i32> %2 1243} 1244 1245define <4 x i32> @combine_nested_undef_test23(<4 x i32> %A, <4 x i32> %B) { 1246; SSE-LABEL: combine_nested_undef_test23: 1247; SSE: # BB#0: 1248; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,1,0,3] 1249; SSE-NEXT: retq 1250; 1251; AVX-LABEL: combine_nested_undef_test23: 1252; AVX: # BB#0: 1253; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm1[0,1,0,3] 1254; AVX-NEXT: retq 1255 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 1256 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3> 1257 ret <4 x i32> %2 1258} 1259 1260define <4 x i32> @combine_nested_undef_test24(<4 x i32> %A, <4 x i32> %B) { 1261; SSE-LABEL: combine_nested_undef_test24: 1262; SSE: # BB#0: 1263; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,2,3] 1264; SSE-NEXT: retq 1265; 1266; AVX-LABEL: combine_nested_undef_test24: 1267; AVX: # BB#0: 1268; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm1[0,3,2,3] 1269; AVX-NEXT: retq 1270 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 7> 1271 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 3, i32 2, i32 4> 1272 ret <4 x i32> %2 1273} 1274 1275define <4 x i32> @combine_nested_undef_test25(<4 x i32> %A, <4 x i32> %B) { 1276; SSE-LABEL: combine_nested_undef_test25: 1277; SSE: # BB#0: 1278; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1279; SSE-NEXT: retq 1280; 1281; AVX1-LABEL: combine_nested_undef_test25: 1282; AVX1: # BB#0: 1283; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1284; AVX1-NEXT: retq 1285; 1286; AVX2-LABEL: combine_nested_undef_test25: 1287; AVX2: # BB#0: 1288; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 1289; AVX2-NEXT: retq 1290 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 5, i32 2, i32 4> 1291 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 1, i32 3, i32 1> 1292 ret <4 x i32> %2 1293} 1294 1295define <4 x i32> @combine_nested_undef_test26(<4 x i32> %A, <4 x i32> %B) { 1296; SSE-LABEL: combine_nested_undef_test26: 1297; SSE: # BB#0: 1298; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 1299; SSE-NEXT: retq 1300; 1301; AVX-LABEL: combine_nested_undef_test26: 1302; AVX: # BB#0: 1303; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 1304; AVX-NEXT: retq 1305 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 6, i32 7> 1306 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3> 1307 ret <4 x i32> %2 1308} 1309 1310define <4 x i32> @combine_nested_undef_test27(<4 x i32> %A, <4 x i32> %B) { 1311; SSE-LABEL: combine_nested_undef_test27: 1312; SSE: # BB#0: 1313; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1314; SSE-NEXT: retq 1315; 1316; AVX1-LABEL: combine_nested_undef_test27: 1317; AVX1: # BB#0: 1318; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1319; AVX1-NEXT: retq 1320; 1321; AVX2-LABEL: combine_nested_undef_test27: 1322; AVX2: # BB#0: 1323; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 1324; AVX2-NEXT: retq 1325 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 2, i32 1, i32 5, i32 4> 1326 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 3, i32 2> 1327 ret <4 x i32> %2 1328} 1329 1330define <4 x i32> @combine_nested_undef_test28(<4 x i32> %A, <4 x i32> %B) { 1331; SSE-LABEL: combine_nested_undef_test28: 1332; SSE: # BB#0: 1333; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,1,0] 1334; SSE-NEXT: retq 1335; 1336; AVX-LABEL: combine_nested_undef_test28: 1337; AVX: # BB#0: 1338; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,0] 1339; AVX-NEXT: retq 1340 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 1341 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 3, i32 2> 1342 ret <4 x i32> %2 1343} 1344 1345define <4 x float> @combine_test1(<4 x float> %a, <4 x float> %b) { 1346; SSE-LABEL: combine_test1: 1347; SSE: # BB#0: 1348; SSE-NEXT: movaps %xmm1, %xmm0 1349; SSE-NEXT: retq 1350; 1351; AVX-LABEL: combine_test1: 1352; AVX: # BB#0: 1353; AVX-NEXT: vmovaps %xmm1, %xmm0 1354; AVX-NEXT: retq 1355 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1356 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1357 ret <4 x float> %2 1358} 1359 1360define <4 x float> @combine_test2(<4 x float> %a, <4 x float> %b) { 1361; SSE2-LABEL: combine_test2: 1362; SSE2: # BB#0: 1363; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1364; SSE2-NEXT: movaps %xmm1, %xmm0 1365; SSE2-NEXT: retq 1366; 1367; SSSE3-LABEL: combine_test2: 1368; SSSE3: # BB#0: 1369; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1370; SSSE3-NEXT: movaps %xmm1, %xmm0 1371; SSSE3-NEXT: retq 1372; 1373; SSE41-LABEL: combine_test2: 1374; SSE41: # BB#0: 1375; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1376; SSE41-NEXT: retq 1377; 1378; AVX-LABEL: combine_test2: 1379; AVX: # BB#0: 1380; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1381; AVX-NEXT: retq 1382 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1383 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1384 ret <4 x float> %2 1385} 1386 1387define <4 x float> @combine_test3(<4 x float> %a, <4 x float> %b) { 1388; SSE-LABEL: combine_test3: 1389; SSE: # BB#0: 1390; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1391; SSE-NEXT: retq 1392; 1393; AVX-LABEL: combine_test3: 1394; AVX: # BB#0: 1395; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1396; AVX-NEXT: retq 1397 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 1398 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 1399 ret <4 x float> %2 1400} 1401 1402define <4 x float> @combine_test4(<4 x float> %a, <4 x float> %b) { 1403; SSE-LABEL: combine_test4: 1404; SSE: # BB#0: 1405; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1] 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 {{.*#+}} xmm0 = xmm0[0],mem[0] 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 {{.*#+}} xmm0 = xmm0[0],mem[0] 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; PR22359 1802define void @combine_test23(<8 x float> %v, <2 x float>* %ptr) { 1803; SSE-LABEL: combine_test23: 1804; SSE: # BB#0: 1805; SSE-NEXT: movups %xmm0, (%rdi) 1806; SSE-NEXT: retq 1807; 1808; AVX-LABEL: combine_test23: 1809; AVX: # BB#0: 1810; AVX-NEXT: vmovups %xmm0, (%rdi) 1811; AVX-NEXT: vzeroupper 1812; AVX-NEXT: retq 1813 %idx2 = getelementptr inbounds <2 x float>, <2 x float>* %ptr, i64 1 1814 %shuffle0 = shufflevector <8 x float> %v, <8 x float> undef, <2 x i32> <i32 0, i32 1> 1815 %shuffle1 = shufflevector <8 x float> %v, <8 x float> undef, <2 x i32> <i32 2, i32 3> 1816 store <2 x float> %shuffle0, <2 x float>* %ptr, align 8 1817 store <2 x float> %shuffle1, <2 x float>* %idx2, align 8 1818 ret void 1819} 1820 1821; Check some negative cases. 1822; FIXME: Do any of these really make sense? Are they redundant with the above tests? 1823 1824define <4 x float> @combine_test1b(<4 x float> %a, <4 x float> %b) { 1825; SSE-LABEL: combine_test1b: 1826; SSE: # BB#0: 1827; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,1,2,0] 1828; SSE-NEXT: movaps %xmm1, %xmm0 1829; SSE-NEXT: retq 1830; 1831; AVX-LABEL: combine_test1b: 1832; AVX: # BB#0: 1833; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[0,1,2,0] 1834; AVX-NEXT: retq 1835 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1836 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 0> 1837 ret <4 x float> %2 1838} 1839 1840define <4 x float> @combine_test2b(<4 x float> %a, <4 x float> %b) { 1841; SSE2-LABEL: combine_test2b: 1842; SSE2: # BB#0: 1843; SSE2-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0,0] 1844; SSE2-NEXT: movaps %xmm1, %xmm0 1845; SSE2-NEXT: retq 1846; 1847; SSSE3-LABEL: combine_test2b: 1848; SSSE3: # BB#0: 1849; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm1[0,0] 1850; SSSE3-NEXT: retq 1851; 1852; SSE41-LABEL: combine_test2b: 1853; SSE41: # BB#0: 1854; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm1[0,0] 1855; SSE41-NEXT: retq 1856; 1857; AVX-LABEL: combine_test2b: 1858; AVX: # BB#0: 1859; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm1[0,0] 1860; AVX-NEXT: retq 1861 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1862 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 0, i32 5> 1863 ret <4 x float> %2 1864} 1865 1866define <4 x float> @combine_test3b(<4 x float> %a, <4 x float> %b) { 1867; SSE2-LABEL: combine_test3b: 1868; SSE2: # BB#0: 1869; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0] 1870; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3] 1871; SSE2-NEXT: retq 1872; 1873; SSSE3-LABEL: combine_test3b: 1874; SSSE3: # BB#0: 1875; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0] 1876; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3] 1877; SSSE3-NEXT: retq 1878; 1879; SSE41-LABEL: combine_test3b: 1880; SSE41: # BB#0: 1881; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 1882; SSE41-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,3,2,3] 1883; SSE41-NEXT: retq 1884; 1885; AVX-LABEL: combine_test3b: 1886; AVX: # BB#0: 1887; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 1888; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,3,2,3] 1889; AVX-NEXT: retq 1890 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 0, i32 6, i32 3> 1891 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 7, i32 2, i32 7> 1892 ret <4 x float> %2 1893} 1894 1895define <4 x float> @combine_test4b(<4 x float> %a, <4 x float> %b) { 1896; SSE-LABEL: combine_test4b: 1897; SSE: # BB#0: 1898; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,1,2,3] 1899; SSE-NEXT: movaps %xmm1, %xmm0 1900; SSE-NEXT: retq 1901; 1902; AVX-LABEL: combine_test4b: 1903; AVX: # BB#0: 1904; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[1,1,2,3] 1905; AVX-NEXT: retq 1906 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1907 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 5, i32 5, i32 2, i32 7> 1908 ret <4 x float> %2 1909} 1910 1911 1912; Verify that we correctly fold shuffles even when we use illegal vector types. 1913 1914define <4 x i8> @combine_test1c(<4 x i8>* %a, <4 x i8>* %b) { 1915; SSE2-LABEL: combine_test1c: 1916; SSE2: # BB#0: 1917; SSE2-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1918; 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] 1919; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1920; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1921; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1922; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1923; SSE2-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 1924; SSE2-NEXT: retq 1925; 1926; SSSE3-LABEL: combine_test1c: 1927; SSSE3: # BB#0: 1928; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1929; 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] 1930; SSSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1931; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1932; SSSE3-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1933; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1934; SSSE3-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 1935; SSSE3-NEXT: retq 1936; 1937; SSE41-LABEL: combine_test1c: 1938; SSE41: # BB#0: 1939; SSE41-NEXT: pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1940; SSE41-NEXT: pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1941; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 1942; SSE41-NEXT: retq 1943; 1944; AVX1-LABEL: combine_test1c: 1945; AVX1: # BB#0: 1946; AVX1-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1947; AVX1-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1948; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7] 1949; AVX1-NEXT: retq 1950; 1951; AVX2-LABEL: combine_test1c: 1952; AVX2: # BB#0: 1953; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1954; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1955; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1956; AVX2-NEXT: retq 1957 %A = load <4 x i8>, <4 x i8>* %a 1958 %B = load <4 x i8>, <4 x i8>* %b 1959 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1960 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1961 ret <4 x i8> %2 1962} 1963 1964define <4 x i8> @combine_test2c(<4 x i8>* %a, <4 x i8>* %b) { 1965; SSE2-LABEL: combine_test2c: 1966; SSE2: # BB#0: 1967; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1968; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1969; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1970; SSE2-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1971; 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] 1972; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1973; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1974; SSE2-NEXT: retq 1975; 1976; SSSE3-LABEL: combine_test2c: 1977; SSSE3: # BB#0: 1978; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1979; SSSE3-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 1980; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 1981; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1982; 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] 1983; SSSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1984; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1985; SSSE3-NEXT: retq 1986; 1987; SSE41-LABEL: combine_test2c: 1988; SSE41: # BB#0: 1989; SSE41-NEXT: pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1990; SSE41-NEXT: pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1991; SSE41-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1992; SSE41-NEXT: retq 1993; 1994; AVX-LABEL: combine_test2c: 1995; AVX: # BB#0: 1996; AVX-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1997; AVX-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 1998; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1999; AVX-NEXT: retq 2000 %A = load <4 x i8>, <4 x i8>* %a 2001 %B = load <4 x i8>, <4 x i8>* %b 2002 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 1, i32 5> 2003 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 2004 ret <4 x i8> %2 2005} 2006 2007define <4 x i8> @combine_test3c(<4 x i8>* %a, <4 x i8>* %b) { 2008; SSE2-LABEL: combine_test3c: 2009; SSE2: # BB#0: 2010; SSE2-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 2011; 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] 2012; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 2013; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 2014; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 2015; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 2016; SSE2-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 2017; SSE2-NEXT: retq 2018; 2019; SSSE3-LABEL: combine_test3c: 2020; SSSE3: # BB#0: 2021; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 2022; 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] 2023; SSSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 2024; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 2025; SSSE3-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 2026; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 2027; SSSE3-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 2028; SSSE3-NEXT: retq 2029; 2030; SSE41-LABEL: combine_test3c: 2031; SSE41: # BB#0: 2032; SSE41-NEXT: pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2033; SSE41-NEXT: pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2034; SSE41-NEXT: punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1] 2035; SSE41-NEXT: retq 2036; 2037; AVX-LABEL: combine_test3c: 2038; AVX: # BB#0: 2039; AVX-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2040; AVX-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2041; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2042; AVX-NEXT: retq 2043 %A = load <4 x i8>, <4 x i8>* %a 2044 %B = load <4 x i8>, <4 x i8>* %b 2045 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2046 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 2047 ret <4 x i8> %2 2048} 2049 2050define <4 x i8> @combine_test4c(<4 x i8>* %a, <4 x i8>* %b) { 2051; SSE2-LABEL: combine_test4c: 2052; SSE2: # BB#0: 2053; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 2054; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 2055; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 2056; SSE2-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 2057; 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] 2058; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 2059; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 2060; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 2061; SSE2-NEXT: retq 2062; 2063; SSSE3-LABEL: combine_test4c: 2064; SSSE3: # BB#0: 2065; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 2066; SSSE3-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 2067; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] 2068; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 2069; 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] 2070; SSSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 2071; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 2072; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 2073; SSSE3-NEXT: retq 2074; 2075; SSE41-LABEL: combine_test4c: 2076; SSE41: # BB#0: 2077; SSE41-NEXT: pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2078; SSE41-NEXT: pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2079; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 2080; SSE41-NEXT: retq 2081; 2082; AVX1-LABEL: combine_test4c: 2083; AVX1: # BB#0: 2084; AVX1-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2085; AVX1-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2086; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 2087; AVX1-NEXT: retq 2088; 2089; AVX2-LABEL: combine_test4c: 2090; AVX2: # BB#0: 2091; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2092; AVX2-NEXT: vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero 2093; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 2094; AVX2-NEXT: retq 2095 %A = load <4 x i8>, <4 x i8>* %a 2096 %B = load <4 x i8>, <4 x i8>* %b 2097 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 2098 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 2099 ret <4 x i8> %2 2100} 2101 2102 2103; The following test cases are generated from this C++ code 2104; 2105;__m128 blend_01(__m128 a, __m128 b) 2106;{ 2107; __m128 s = a; 2108; s = _mm_blend_ps( s, b, 1<<0 ); 2109; s = _mm_blend_ps( s, b, 1<<1 ); 2110; return s; 2111;} 2112; 2113;__m128 blend_02(__m128 a, __m128 b) 2114;{ 2115; __m128 s = a; 2116; s = _mm_blend_ps( s, b, 1<<0 ); 2117; s = _mm_blend_ps( s, b, 1<<2 ); 2118; return s; 2119;} 2120; 2121;__m128 blend_123(__m128 a, __m128 b) 2122;{ 2123; __m128 s = a; 2124; s = _mm_blend_ps( s, b, 1<<1 ); 2125; s = _mm_blend_ps( s, b, 1<<2 ); 2126; s = _mm_blend_ps( s, b, 1<<3 ); 2127; return s; 2128;} 2129 2130; Ideally, we should collapse the following shuffles into a single one. 2131 2132define <4 x float> @combine_blend_01(<4 x float> %a, <4 x float> %b) { 2133; SSE2-LABEL: combine_blend_01: 2134; SSE2: # BB#0: 2135; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2136; SSE2-NEXT: retq 2137; 2138; SSSE3-LABEL: combine_blend_01: 2139; SSSE3: # BB#0: 2140; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2141; SSSE3-NEXT: retq 2142; 2143; SSE41-LABEL: combine_blend_01: 2144; SSE41: # BB#0: 2145; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2146; SSE41-NEXT: retq 2147; 2148; AVX-LABEL: combine_blend_01: 2149; AVX: # BB#0: 2150; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2151; AVX-NEXT: retq 2152 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 undef, i32 2, i32 3> 2153 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 2154 ret <4 x float> %shuffle6 2155} 2156 2157define <4 x float> @combine_blend_02(<4 x float> %a, <4 x float> %b) { 2158; SSE2-LABEL: combine_blend_02: 2159; SSE2: # BB#0: 2160; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3] 2161; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,1,3] 2162; SSE2-NEXT: movaps %xmm1, %xmm0 2163; SSE2-NEXT: retq 2164; 2165; SSSE3-LABEL: combine_blend_02: 2166; SSSE3: # BB#0: 2167; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3] 2168; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,1,3] 2169; SSSE3-NEXT: movaps %xmm1, %xmm0 2170; SSSE3-NEXT: retq 2171; 2172; SSE41-LABEL: combine_blend_02: 2173; SSE41: # BB#0: 2174; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3] 2175; SSE41-NEXT: retq 2176; 2177; AVX-LABEL: combine_blend_02: 2178; AVX: # BB#0: 2179; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3] 2180; AVX-NEXT: retq 2181 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 undef, i32 3> 2182 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 2183 ret <4 x float> %shuffle6 2184} 2185 2186define <4 x float> @combine_blend_123(<4 x float> %a, <4 x float> %b) { 2187; SSE2-LABEL: combine_blend_123: 2188; SSE2: # BB#0: 2189; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 2190; SSE2-NEXT: movaps %xmm1, %xmm0 2191; SSE2-NEXT: retq 2192; 2193; SSSE3-LABEL: combine_blend_123: 2194; SSSE3: # BB#0: 2195; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 2196; SSSE3-NEXT: movaps %xmm1, %xmm0 2197; SSSE3-NEXT: retq 2198; 2199; SSE41-LABEL: combine_blend_123: 2200; SSE41: # BB#0: 2201; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 2202; SSE41-NEXT: retq 2203; 2204; AVX-LABEL: combine_blend_123: 2205; AVX: # BB#0: 2206; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 2207; AVX-NEXT: retq 2208 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef> 2209 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 undef> 2210 %shuffle12 = shufflevector <4 x float> %shuffle6, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 2211 ret <4 x float> %shuffle12 2212} 2213 2214define <4 x i32> @combine_test_movhl_1(<4 x i32> %a, <4 x i32> %b) { 2215; SSE-LABEL: combine_test_movhl_1: 2216; SSE: # BB#0: 2217; SSE-NEXT: punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1] 2218; SSE-NEXT: movdqa %xmm1, %xmm0 2219; SSE-NEXT: retq 2220; 2221; AVX-LABEL: combine_test_movhl_1: 2222; AVX: # BB#0: 2223; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2224; AVX-NEXT: retq 2225 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 7, i32 5, i32 3> 2226 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 1, i32 0, i32 3> 2227 ret <4 x i32> %2 2228} 2229 2230define <4 x i32> @combine_test_movhl_2(<4 x i32> %a, <4 x i32> %b) { 2231; SSE-LABEL: combine_test_movhl_2: 2232; SSE: # BB#0: 2233; SSE-NEXT: punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1] 2234; SSE-NEXT: movdqa %xmm1, %xmm0 2235; SSE-NEXT: retq 2236; 2237; AVX-LABEL: combine_test_movhl_2: 2238; AVX: # BB#0: 2239; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2240; AVX-NEXT: retq 2241 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 0, i32 3, i32 6> 2242 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 3, i32 7, i32 0, i32 2> 2243 ret <4 x i32> %2 2244} 2245 2246define <4 x i32> @combine_test_movhl_3(<4 x i32> %a, <4 x i32> %b) { 2247; SSE-LABEL: combine_test_movhl_3: 2248; SSE: # BB#0: 2249; SSE-NEXT: punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1] 2250; SSE-NEXT: movdqa %xmm1, %xmm0 2251; SSE-NEXT: retq 2252; 2253; AVX-LABEL: combine_test_movhl_3: 2254; AVX: # BB#0: 2255; AVX-NEXT: vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2256; AVX-NEXT: retq 2257 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 7, i32 6, i32 3, i32 2> 2258 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 0, i32 3, i32 2> 2259 ret <4 x i32> %2 2260} 2261 2262 2263; Verify that we fold shuffles according to rule: 2264; (shuffle(shuffle A, Undef, M0), B, M1) -> (shuffle A, B, M2) 2265 2266define <4 x float> @combine_undef_input_test1(<4 x float> %a, <4 x float> %b) { 2267; SSE2-LABEL: combine_undef_input_test1: 2268; SSE2: # BB#0: 2269; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2270; SSE2-NEXT: retq 2271; 2272; SSSE3-LABEL: combine_undef_input_test1: 2273; SSSE3: # BB#0: 2274; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2275; SSSE3-NEXT: retq 2276; 2277; SSE41-LABEL: combine_undef_input_test1: 2278; SSE41: # BB#0: 2279; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2280; SSE41-NEXT: retq 2281; 2282; AVX-LABEL: combine_undef_input_test1: 2283; AVX: # BB#0: 2284; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2285; AVX-NEXT: retq 2286 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2287 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 4, i32 5, i32 1, i32 2> 2288 ret <4 x float> %2 2289} 2290 2291define <4 x float> @combine_undef_input_test2(<4 x float> %a, <4 x float> %b) { 2292; SSE-LABEL: combine_undef_input_test2: 2293; SSE: # BB#0: 2294; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2295; SSE-NEXT: retq 2296; 2297; AVX-LABEL: combine_undef_input_test2: 2298; AVX: # BB#0: 2299; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2300; AVX-NEXT: retq 2301 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2302 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 2303 ret <4 x float> %2 2304} 2305 2306define <4 x float> @combine_undef_input_test3(<4 x float> %a, <4 x float> %b) { 2307; SSE-LABEL: combine_undef_input_test3: 2308; SSE: # BB#0: 2309; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2310; SSE-NEXT: retq 2311; 2312; AVX-LABEL: combine_undef_input_test3: 2313; AVX: # BB#0: 2314; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2315; AVX-NEXT: retq 2316 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2317 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 2318 ret <4 x float> %2 2319} 2320 2321define <4 x float> @combine_undef_input_test4(<4 x float> %a, <4 x float> %b) { 2322; SSE-LABEL: combine_undef_input_test4: 2323; SSE: # BB#0: 2324; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2325; SSE-NEXT: retq 2326; 2327; AVX-LABEL: combine_undef_input_test4: 2328; AVX: # BB#0: 2329; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2330; AVX-NEXT: retq 2331 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2332 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 2333 ret <4 x float> %2 2334} 2335 2336define <4 x float> @combine_undef_input_test5(<4 x float> %a, <4 x float> %b) { 2337; SSE2-LABEL: combine_undef_input_test5: 2338; SSE2: # BB#0: 2339; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 2340; SSE2-NEXT: movapd %xmm1, %xmm0 2341; SSE2-NEXT: retq 2342; 2343; SSSE3-LABEL: combine_undef_input_test5: 2344; SSSE3: # BB#0: 2345; SSSE3-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 2346; SSSE3-NEXT: movapd %xmm1, %xmm0 2347; SSSE3-NEXT: retq 2348; 2349; SSE41-LABEL: combine_undef_input_test5: 2350; SSE41: # BB#0: 2351; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 2352; SSE41-NEXT: retq 2353; 2354; AVX-LABEL: combine_undef_input_test5: 2355; AVX: # BB#0: 2356; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 2357; AVX-NEXT: retq 2358 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2359 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 6, i32 7> 2360 ret <4 x float> %2 2361} 2362 2363 2364; Verify that we fold shuffles according to rule: 2365; (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2) 2366 2367define <4 x float> @combine_undef_input_test6(<4 x float> %a) { 2368; ALL-LABEL: combine_undef_input_test6: 2369; ALL: # BB#0: 2370; ALL-NEXT: retq 2371 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2372 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 1, i32 2> 2373 ret <4 x float> %2 2374} 2375 2376define <4 x float> @combine_undef_input_test7(<4 x float> %a) { 2377; SSE2-LABEL: combine_undef_input_test7: 2378; SSE2: # BB#0: 2379; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2380; SSE2-NEXT: retq 2381; 2382; SSSE3-LABEL: combine_undef_input_test7: 2383; SSSE3: # BB#0: 2384; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2385; SSSE3-NEXT: retq 2386; 2387; SSE41-LABEL: combine_undef_input_test7: 2388; SSE41: # BB#0: 2389; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2390; SSE41-NEXT: retq 2391; 2392; AVX-LABEL: combine_undef_input_test7: 2393; AVX: # BB#0: 2394; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2395; AVX-NEXT: retq 2396 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2397 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 2398 ret <4 x float> %2 2399} 2400 2401define <4 x float> @combine_undef_input_test8(<4 x float> %a) { 2402; SSE2-LABEL: combine_undef_input_test8: 2403; SSE2: # BB#0: 2404; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2405; SSE2-NEXT: retq 2406; 2407; SSSE3-LABEL: combine_undef_input_test8: 2408; SSSE3: # BB#0: 2409; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2410; SSSE3-NEXT: retq 2411; 2412; SSE41-LABEL: combine_undef_input_test8: 2413; SSE41: # BB#0: 2414; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2415; SSE41-NEXT: retq 2416; 2417; AVX-LABEL: combine_undef_input_test8: 2418; AVX: # BB#0: 2419; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2420; AVX-NEXT: retq 2421 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2422 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 2423 ret <4 x float> %2 2424} 2425 2426define <4 x float> @combine_undef_input_test9(<4 x float> %a) { 2427; SSE-LABEL: combine_undef_input_test9: 2428; SSE: # BB#0: 2429; SSE-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1,1] 2430; SSE-NEXT: retq 2431; 2432; AVX-LABEL: combine_undef_input_test9: 2433; AVX: # BB#0: 2434; AVX-NEXT: vpermilpd {{.*#+}} xmm0 = xmm0[1,1] 2435; AVX-NEXT: retq 2436 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2437 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 2438 ret <4 x float> %2 2439} 2440 2441define <4 x float> @combine_undef_input_test10(<4 x float> %a) { 2442; ALL-LABEL: combine_undef_input_test10: 2443; ALL: # BB#0: 2444; ALL-NEXT: retq 2445 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2446 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 6, i32 7> 2447 ret <4 x float> %2 2448} 2449 2450define <4 x float> @combine_undef_input_test11(<4 x float> %a, <4 x float> %b) { 2451; SSE2-LABEL: combine_undef_input_test11: 2452; SSE2: # BB#0: 2453; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2454; SSE2-NEXT: retq 2455; 2456; SSSE3-LABEL: combine_undef_input_test11: 2457; SSSE3: # BB#0: 2458; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2459; SSSE3-NEXT: retq 2460; 2461; SSE41-LABEL: combine_undef_input_test11: 2462; SSE41: # BB#0: 2463; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2464; SSE41-NEXT: retq 2465; 2466; AVX-LABEL: combine_undef_input_test11: 2467; AVX: # BB#0: 2468; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2469; AVX-NEXT: retq 2470 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2471 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 6> 2472 ret <4 x float> %2 2473} 2474 2475define <4 x float> @combine_undef_input_test12(<4 x float> %a, <4 x float> %b) { 2476; SSE-LABEL: combine_undef_input_test12: 2477; SSE: # BB#0: 2478; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2479; SSE-NEXT: retq 2480; 2481; AVX-LABEL: combine_undef_input_test12: 2482; AVX: # BB#0: 2483; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2484; AVX-NEXT: retq 2485 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2486 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1> 2487 ret <4 x float> %2 2488} 2489 2490define <4 x float> @combine_undef_input_test13(<4 x float> %a, <4 x float> %b) { 2491; SSE-LABEL: combine_undef_input_test13: 2492; SSE: # BB#0: 2493; SSE-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2494; SSE-NEXT: retq 2495; 2496; AVX-LABEL: combine_undef_input_test13: 2497; AVX: # BB#0: 2498; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2499; AVX-NEXT: retq 2500 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2501 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 5, i32 0, i32 5> 2502 ret <4 x float> %2 2503} 2504 2505define <4 x float> @combine_undef_input_test14(<4 x float> %a, <4 x float> %b) { 2506; SSE-LABEL: combine_undef_input_test14: 2507; SSE: # BB#0: 2508; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2509; SSE-NEXT: retq 2510; 2511; AVX-LABEL: combine_undef_input_test14: 2512; AVX: # BB#0: 2513; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2514; AVX-NEXT: retq 2515 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2516 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5> 2517 ret <4 x float> %2 2518} 2519 2520define <4 x float> @combine_undef_input_test15(<4 x float> %a, <4 x float> %b) { 2521; SSE2-LABEL: combine_undef_input_test15: 2522; SSE2: # BB#0: 2523; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 2524; SSE2-NEXT: movapd %xmm1, %xmm0 2525; SSE2-NEXT: retq 2526; 2527; SSSE3-LABEL: combine_undef_input_test15: 2528; SSSE3: # BB#0: 2529; SSSE3-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 2530; SSSE3-NEXT: movapd %xmm1, %xmm0 2531; SSSE3-NEXT: retq 2532; 2533; SSE41-LABEL: combine_undef_input_test15: 2534; SSE41: # BB#0: 2535; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 2536; SSE41-NEXT: retq 2537; 2538; AVX-LABEL: combine_undef_input_test15: 2539; AVX: # BB#0: 2540; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 2541; AVX-NEXT: retq 2542 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2543 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2544 ret <4 x float> %2 2545} 2546 2547 2548; Verify that shuffles are canonicalized according to rules: 2549; shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B) 2550; 2551; This allows to trigger the following combine rule: 2552; (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2) 2553; 2554; As a result, all the shuffle pairs in each function below should be 2555; combined into a single legal shuffle operation. 2556 2557define <4 x float> @combine_undef_input_test16(<4 x float> %a) { 2558; ALL-LABEL: combine_undef_input_test16: 2559; ALL: # BB#0: 2560; ALL-NEXT: retq 2561 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2562 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 3> 2563 ret <4 x float> %2 2564} 2565 2566define <4 x float> @combine_undef_input_test17(<4 x float> %a) { 2567; SSE2-LABEL: combine_undef_input_test17: 2568; SSE2: # BB#0: 2569; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2570; SSE2-NEXT: retq 2571; 2572; SSSE3-LABEL: combine_undef_input_test17: 2573; SSSE3: # BB#0: 2574; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2575; SSSE3-NEXT: retq 2576; 2577; SSE41-LABEL: combine_undef_input_test17: 2578; SSE41: # BB#0: 2579; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2580; SSE41-NEXT: retq 2581; 2582; AVX-LABEL: combine_undef_input_test17: 2583; AVX: # BB#0: 2584; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2585; AVX-NEXT: retq 2586 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2587 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1> 2588 ret <4 x float> %2 2589} 2590 2591define <4 x float> @combine_undef_input_test18(<4 x float> %a) { 2592; SSE2-LABEL: combine_undef_input_test18: 2593; SSE2: # BB#0: 2594; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2595; SSE2-NEXT: retq 2596; 2597; SSSE3-LABEL: combine_undef_input_test18: 2598; SSSE3: # BB#0: 2599; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2600; SSSE3-NEXT: retq 2601; 2602; SSE41-LABEL: combine_undef_input_test18: 2603; SSE41: # BB#0: 2604; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2605; SSE41-NEXT: retq 2606; 2607; AVX-LABEL: combine_undef_input_test18: 2608; AVX: # BB#0: 2609; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2610; AVX-NEXT: retq 2611 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2612 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 0, i32 5> 2613 ret <4 x float> %2 2614} 2615 2616define <4 x float> @combine_undef_input_test19(<4 x float> %a) { 2617; SSE-LABEL: combine_undef_input_test19: 2618; SSE: # BB#0: 2619; SSE-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1,1] 2620; SSE-NEXT: retq 2621; 2622; AVX-LABEL: combine_undef_input_test19: 2623; AVX: # BB#0: 2624; AVX-NEXT: vpermilpd {{.*#+}} xmm0 = xmm0[1,1] 2625; AVX-NEXT: retq 2626 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2627 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5> 2628 ret <4 x float> %2 2629} 2630 2631define <4 x float> @combine_undef_input_test20(<4 x float> %a) { 2632; ALL-LABEL: combine_undef_input_test20: 2633; ALL: # BB#0: 2634; ALL-NEXT: retq 2635 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2636 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2637 ret <4 x float> %2 2638} 2639 2640; These tests are designed to test the ability to combine away unnecessary 2641; operations feeding into a shuffle. The AVX cases are the important ones as 2642; they leverage operations which cannot be done naturally on the entire vector 2643; and thus are decomposed into multiple smaller operations. 2644 2645define <8 x i32> @combine_unneeded_subvector1(<8 x i32> %a) { 2646; SSE-LABEL: combine_unneeded_subvector1: 2647; SSE: # BB#0: 2648; SSE-NEXT: paddd {{.*}}(%rip), %xmm1 2649; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,2,1,0] 2650; SSE-NEXT: movdqa %xmm0, %xmm1 2651; SSE-NEXT: retq 2652; 2653; AVX1-LABEL: combine_unneeded_subvector1: 2654; AVX1: # BB#0: 2655; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 2656; AVX1-NEXT: vpaddd {{.*}}(%rip), %xmm0, %xmm0 2657; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 2658; AVX1-NEXT: vpermilps {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2659; AVX1-NEXT: vperm2f128 {{.*#+}} ymm0 = ymm0[2,3,2,3] 2660; AVX1-NEXT: retq 2661; 2662; AVX2-LABEL: combine_unneeded_subvector1: 2663; AVX2: # BB#0: 2664; AVX2-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 2665; AVX2-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2666; AVX2-NEXT: vperm2i128 {{.*#+}} ymm0 = ymm0[2,3,2,3] 2667; AVX2-NEXT: retq 2668 %b = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8> 2669 %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> 2670 ret <8 x i32> %c 2671} 2672 2673define <8 x i32> @combine_unneeded_subvector2(<8 x i32> %a, <8 x i32> %b) { 2674; SSE-LABEL: combine_unneeded_subvector2: 2675; SSE: # BB#0: 2676; SSE-NEXT: paddd {{.*}}(%rip), %xmm1 2677; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm3[3,2,1,0] 2678; SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm1[3,2,1,0] 2679; SSE-NEXT: retq 2680; 2681; AVX1-LABEL: combine_unneeded_subvector2: 2682; AVX1: # BB#0: 2683; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 2684; AVX1-NEXT: vpaddd {{.*}}(%rip), %xmm0, %xmm0 2685; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 2686; AVX1-NEXT: vperm2f128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3] 2687; AVX1-NEXT: vpermilps {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2688; AVX1-NEXT: retq 2689; 2690; AVX2-LABEL: combine_unneeded_subvector2: 2691; AVX2: # BB#0: 2692; AVX2-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 2693; AVX2-NEXT: vperm2i128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3] 2694; AVX2-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2695; AVX2-NEXT: retq 2696 %c = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8> 2697 %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> 2698 ret <8 x i32> %d 2699} 2700 2701define <4 x float> @combine_insertps1(<4 x float> %a, <4 x float> %b) { 2702; SSE2-LABEL: combine_insertps1: 2703; SSE2: # BB#0: 2704; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0] 2705; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3] 2706; SSE2-NEXT: movaps %xmm1, %xmm0 2707; SSE2-NEXT: retq 2708; 2709; SSSE3-LABEL: combine_insertps1: 2710; SSSE3: # BB#0: 2711; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0] 2712; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3] 2713; SSSE3-NEXT: movaps %xmm1, %xmm0 2714; SSSE3-NEXT: retq 2715; 2716; SSE41-LABEL: combine_insertps1: 2717; SSE41: # BB#0: 2718; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3] 2719; SSE41-NEXT: retq 2720; 2721; AVX-LABEL: combine_insertps1: 2722; AVX: # BB#0: 2723; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3] 2724; AVX-NEXT: retq 2725 2726 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 6, i32 2, i32 4> 2727 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 5, i32 1, i32 6, i32 3> 2728 ret <4 x float> %d 2729} 2730 2731define <4 x float> @combine_insertps2(<4 x float> %a, <4 x float> %b) { 2732; SSE2-LABEL: combine_insertps2: 2733; SSE2: # BB#0: 2734; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0] 2735; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3] 2736; SSE2-NEXT: movaps %xmm1, %xmm0 2737; SSE2-NEXT: retq 2738; 2739; SSSE3-LABEL: combine_insertps2: 2740; SSSE3: # BB#0: 2741; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0] 2742; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3] 2743; SSSE3-NEXT: movaps %xmm1, %xmm0 2744; SSSE3-NEXT: retq 2745; 2746; SSE41-LABEL: combine_insertps2: 2747; SSE41: # BB#0: 2748; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3] 2749; SSE41-NEXT: retq 2750; 2751; AVX-LABEL: combine_insertps2: 2752; AVX: # BB#0: 2753; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3] 2754; AVX-NEXT: retq 2755 2756 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 1, i32 6, i32 7> 2757 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2758 ret <4 x float> %d 2759} 2760 2761define <4 x float> @combine_insertps3(<4 x float> %a, <4 x float> %b) { 2762; SSE2-LABEL: combine_insertps3: 2763; SSE2: # BB#0: 2764; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 2765; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2] 2766; SSE2-NEXT: retq 2767; 2768; SSSE3-LABEL: combine_insertps3: 2769; SSSE3: # BB#0: 2770; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 2771; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2] 2772; SSSE3-NEXT: retq 2773; 2774; SSE41-LABEL: combine_insertps3: 2775; SSE41: # BB#0: 2776; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] 2777; SSE41-NEXT: retq 2778; 2779; AVX-LABEL: combine_insertps3: 2780; AVX: # BB#0: 2781; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] 2782; AVX-NEXT: retq 2783 2784 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5> 2785 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 5, i32 3> 2786 ret <4 x float> %d 2787} 2788 2789define <4 x float> @combine_insertps4(<4 x float> %a, <4 x float> %b) { 2790; SSE2-LABEL: combine_insertps4: 2791; SSE2: # BB#0: 2792; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0] 2793; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0] 2794; SSE2-NEXT: retq 2795; 2796; SSSE3-LABEL: combine_insertps4: 2797; SSSE3: # BB#0: 2798; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0] 2799; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0] 2800; SSSE3-NEXT: retq 2801; 2802; SSE41-LABEL: combine_insertps4: 2803; SSE41: # BB#0: 2804; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] 2805; SSE41-NEXT: retq 2806; 2807; AVX-LABEL: combine_insertps4: 2808; AVX: # BB#0: 2809; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] 2810; AVX-NEXT: retq 2811 2812 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5> 2813 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 6, i32 5> 2814 ret <4 x float> %d 2815} 2816 2817define void @combine_scalar_load_with_blend_with_zero(double* %a0, <4 x float>* %a1) { 2818; SSE-LABEL: combine_scalar_load_with_blend_with_zero: 2819; SSE: # BB#0: 2820; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 2821; SSE-NEXT: movapd %xmm0, (%rsi) 2822; SSE-NEXT: retq 2823; 2824; AVX-LABEL: combine_scalar_load_with_blend_with_zero: 2825; AVX: # BB#0: 2826; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 2827; AVX-NEXT: vmovapd %xmm0, (%rsi) 2828; AVX-NEXT: retq 2829 %1 = load double, double* %a0, align 8 2830 %2 = insertelement <2 x double> undef, double %1, i32 0 2831 %3 = insertelement <2 x double> %2, double 0.000000e+00, i32 1 2832 %4 = bitcast <2 x double> %3 to <4 x float> 2833 %5 = shufflevector <4 x float> %4, <4 x float> <float 0.000000e+00, float undef, float undef, float undef>, <4 x i32> <i32 0, i32 1, i32 4, i32 3> 2834 store <4 x float> %5, <4 x float>* %a1, align 16 2835 ret void 2836} 2837 2838; PR30371 2839define <4 x float> @combine_constant_insertion_v4f32(float %f) { 2840; SSE2-LABEL: combine_constant_insertion_v4f32: 2841; SSE2: # BB#0: 2842; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 2843; SSE2-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero 2844; SSE2-NEXT: unpcklps {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1] 2845; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 2846; SSE2-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2847; SSE2-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] 2848; SSE2-NEXT: retq 2849; 2850; SSSE3-LABEL: combine_constant_insertion_v4f32: 2851; SSSE3: # BB#0: 2852; SSSE3-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 2853; SSSE3-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero 2854; SSSE3-NEXT: unpcklps {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1] 2855; SSSE3-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 2856; SSSE3-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2857; SSSE3-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] 2858; SSSE3-NEXT: retq 2859; 2860; SSE41-LABEL: combine_constant_insertion_v4f32: 2861; SSE41: # BB#0: 2862; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3] 2863; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3] 2864; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0] 2865; SSE41-NEXT: retq 2866; 2867; AVX-LABEL: combine_constant_insertion_v4f32: 2868; AVX: # BB#0: 2869; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3] 2870; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3] 2871; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0] 2872; AVX-NEXT: retq 2873 %a0 = insertelement <4 x float> undef, float %f, i32 0 2874 %ret = shufflevector <4 x float> %a0, <4 x float> <float undef, float 4.0, float 5.0, float 3.0>, <4 x i32> <i32 0, i32 5, i32 6, i32 7> 2875 ret <4 x float> %ret 2876} 2877 2878define <4 x i32> @combine_constant_insertion_v4i32(i32 %f) { 2879; SSE2-LABEL: combine_constant_insertion_v4i32: 2880; SSE2: # BB#0: 2881; SSE2-NEXT: movl $30, %eax 2882; SSE2-NEXT: movd %eax, %xmm0 2883; SSE2-NEXT: movl $4, %eax 2884; SSE2-NEXT: movd %eax, %xmm1 2885; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 2886; SSE2-NEXT: movl $5, %eax 2887; SSE2-NEXT: movd %eax, %xmm2 2888; SSE2-NEXT: movd %edi, %xmm0 2889; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] 2890; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2891; SSE2-NEXT: retq 2892; 2893; SSSE3-LABEL: combine_constant_insertion_v4i32: 2894; SSSE3: # BB#0: 2895; SSSE3-NEXT: movl $30, %eax 2896; SSSE3-NEXT: movd %eax, %xmm0 2897; SSSE3-NEXT: movl $4, %eax 2898; SSSE3-NEXT: movd %eax, %xmm1 2899; SSSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 2900; SSSE3-NEXT: movl $5, %eax 2901; SSSE3-NEXT: movd %eax, %xmm2 2902; SSSE3-NEXT: movd %edi, %xmm0 2903; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] 2904; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2905; SSSE3-NEXT: retq 2906; 2907; SSE41-LABEL: combine_constant_insertion_v4i32: 2908; SSE41: # BB#0: 2909; SSE41-NEXT: movd %edi, %xmm0 2910; SSE41-NEXT: movl $4, %eax 2911; SSE41-NEXT: pinsrd $1, %eax, %xmm0 2912; SSE41-NEXT: movl $5, %eax 2913; SSE41-NEXT: pinsrd $2, %eax, %xmm0 2914; SSE41-NEXT: movl $30, %eax 2915; SSE41-NEXT: pinsrd $3, %eax, %xmm0 2916; SSE41-NEXT: retq 2917; 2918; AVX-LABEL: combine_constant_insertion_v4i32: 2919; AVX: # BB#0: 2920; AVX-NEXT: vmovd %edi, %xmm0 2921; AVX-NEXT: movl $4, %eax 2922; AVX-NEXT: vpinsrd $1, %eax, %xmm0, %xmm0 2923; AVX-NEXT: movl $5, %eax 2924; AVX-NEXT: vpinsrd $2, %eax, %xmm0, %xmm0 2925; AVX-NEXT: movl $30, %eax 2926; AVX-NEXT: vpinsrd $3, %eax, %xmm0, %xmm0 2927; AVX-NEXT: retq 2928 %a0 = insertelement <4 x i32> undef, i32 %f, i32 0 2929 %ret = shufflevector <4 x i32> %a0, <4 x i32> <i32 undef, i32 4, i32 5, i32 30>, <4 x i32> <i32 0, i32 5, i32 6, i32 7> 2930 ret <4 x i32> %ret 2931} 2932 2933define <4 x float> @PR22377(<4 x float> %a, <4 x float> %b) { 2934; SSE-LABEL: PR22377: 2935; SSE: # BB#0: # %entry 2936; SSE-NEXT: movaps %xmm0, %xmm1 2937; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,3,1,3] 2938; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,0,2] 2939; SSE-NEXT: addps %xmm0, %xmm1 2940; SSE-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2941; SSE-NEXT: retq 2942; 2943; AVX-LABEL: PR22377: 2944; AVX: # BB#0: # %entry 2945; AVX-NEXT: vpermilps {{.*#+}} xmm1 = xmm0[1,3,1,3] 2946; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,2,0,2] 2947; AVX-NEXT: vaddps %xmm0, %xmm1, %xmm1 2948; AVX-NEXT: vunpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2949; AVX-NEXT: retq 2950entry: 2951 %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 1, i32 3, i32 1, i32 3> 2952 %s2 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2> 2953 %r2 = fadd <4 x float> %s1, %s2 2954 %s3 = shufflevector <4 x float> %s2, <4 x float> %r2, <4 x i32> <i32 0, i32 4, i32 1, i32 5> 2955 ret <4 x float> %s3 2956} 2957 2958define <4 x float> @PR22390(<4 x float> %a, <4 x float> %b) { 2959; SSE2-LABEL: PR22390: 2960; SSE2: # BB#0: # %entry 2961; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2962; SSE2-NEXT: movaps %xmm0, %xmm2 2963; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3] 2964; SSE2-NEXT: addps %xmm0, %xmm2 2965; SSE2-NEXT: movaps %xmm2, %xmm0 2966; SSE2-NEXT: retq 2967; 2968; SSSE3-LABEL: PR22390: 2969; SSSE3: # BB#0: # %entry 2970; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2971; SSSE3-NEXT: movaps %xmm0, %xmm2 2972; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3] 2973; SSSE3-NEXT: addps %xmm0, %xmm2 2974; SSSE3-NEXT: movaps %xmm2, %xmm0 2975; SSSE3-NEXT: retq 2976; 2977; SSE41-LABEL: PR22390: 2978; SSE41: # BB#0: # %entry 2979; SSE41-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2980; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3] 2981; SSE41-NEXT: addps %xmm1, %xmm0 2982; SSE41-NEXT: retq 2983; 2984; AVX-LABEL: PR22390: 2985; AVX: # BB#0: # %entry 2986; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2987; AVX-NEXT: vblendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3] 2988; AVX-NEXT: vaddps %xmm1, %xmm0, %xmm0 2989; AVX-NEXT: retq 2990entry: 2991 %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 3, i32 0, i32 1, i32 2> 2992 %s2 = shufflevector <4 x float> %s1, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 2, i32 3> 2993 %r2 = fadd <4 x float> %s1, %s2 2994 ret <4 x float> %r2 2995} 2996 2997define <8 x float> @PR22412(<8 x float> %a, <8 x float> %b) { 2998; SSE2-LABEL: PR22412: 2999; SSE2: # BB#0: # %entry 3000; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1] 3001; SSE2-NEXT: movapd %xmm2, %xmm0 3002; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm3[3,2] 3003; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[1,0],xmm2[3,2] 3004; SSE2-NEXT: movaps %xmm3, %xmm1 3005; SSE2-NEXT: retq 3006; 3007; SSSE3-LABEL: PR22412: 3008; SSSE3: # BB#0: # %entry 3009; SSSE3-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1] 3010; SSSE3-NEXT: movapd %xmm2, %xmm0 3011; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm3[3,2] 3012; SSSE3-NEXT: shufps {{.*#+}} xmm3 = xmm3[1,0],xmm2[3,2] 3013; SSSE3-NEXT: movaps %xmm3, %xmm1 3014; SSSE3-NEXT: retq 3015; 3016; SSE41-LABEL: PR22412: 3017; SSE41: # BB#0: # %entry 3018; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1] 3019; SSE41-NEXT: movapd %xmm0, %xmm1 3020; SSE41-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,0],xmm3[3,2] 3021; SSE41-NEXT: shufps {{.*#+}} xmm3 = xmm3[1,0],xmm0[3,2] 3022; SSE41-NEXT: movaps %xmm1, %xmm0 3023; SSE41-NEXT: movaps %xmm3, %xmm1 3024; SSE41-NEXT: retq 3025; 3026; AVX1-LABEL: PR22412: 3027; AVX1: # BB#0: # %entry 3028; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3] 3029; AVX1-NEXT: vperm2f128 {{.*#+}} ymm1 = ymm0[2,3,0,1] 3030; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,0],ymm1[3,2],ymm0[5,4],ymm1[7,6] 3031; AVX1-NEXT: retq 3032; 3033; AVX2-LABEL: PR22412: 3034; AVX2: # BB#0: # %entry 3035; AVX2-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3] 3036; AVX2-NEXT: vpermilps {{.*#+}} ymm0 = ymm0[1,0,3,2,5,4,7,6] 3037; AVX2-NEXT: vpermpd {{.*#+}} ymm0 = ymm0[0,3,2,1] 3038; AVX2-NEXT: retq 3039entry: 3040 %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> 3041 %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> 3042 ret <8 x float> %s2 3043} 3044