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