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