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,3] 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,3] 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; AVX-LABEL: combine_nested_undef_test15: 868; AVX: # %bb.0: 869; AVX-NEXT: vpermilps {{.*#+}} xmm1 = xmm1[0,0,1,1] 870; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[3,1,0,1] 871; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3] 872; AVX-NEXT: retq 873 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1> 874 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 875 ret <4 x i32> %2 876} 877 878define <4 x i32> @combine_nested_undef_test16(<4 x i32> %A, <4 x i32> %B) { 879; SSE2-LABEL: combine_nested_undef_test16: 880; SSE2: # %bb.0: 881; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] 882; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,0,2,3] 883; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 884; SSE2-NEXT: retq 885; 886; SSSE3-LABEL: combine_nested_undef_test16: 887; SSSE3: # %bb.0: 888; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] 889; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,0,2,3] 890; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 891; SSSE3-NEXT: retq 892; 893; SSE41-LABEL: combine_nested_undef_test16: 894; SSE41: # %bb.0: 895; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] 896; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 897; SSE41-NEXT: retq 898; 899; AVX-LABEL: combine_nested_undef_test16: 900; AVX: # %bb.0: 901; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[2,3,0,1] 902; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 903; AVX-NEXT: retq 904 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 905 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 906 ret <4 x i32> %2 907} 908 909define <4 x i32> @combine_nested_undef_test17(<4 x i32> %A, <4 x i32> %B) { 910; SSE2-LABEL: combine_nested_undef_test17: 911; SSE2: # %bb.0: 912; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0] 913; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2] 914; SSE2-NEXT: retq 915; 916; SSSE3-LABEL: combine_nested_undef_test17: 917; SSSE3: # %bb.0: 918; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0] 919; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2] 920; SSSE3-NEXT: retq 921; 922; SSE41-LABEL: combine_nested_undef_test17: 923; SSE41: # %bb.0: 924; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7] 925; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1] 926; SSE41-NEXT: retq 927; 928; AVX-LABEL: combine_nested_undef_test17: 929; AVX: # %bb.0: 930; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 931; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[3,1,0,1] 932; AVX-NEXT: retq 933 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1> 934 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 935 ret <4 x i32> %2 936} 937 938define <4 x i32> @combine_nested_undef_test18(<4 x i32> %A, <4 x i32> %B) { 939; SSE-LABEL: combine_nested_undef_test18: 940; SSE: # %bb.0: 941; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,0,3] 942; SSE-NEXT: retq 943; 944; AVX-LABEL: combine_nested_undef_test18: 945; AVX: # %bb.0: 946; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[1,1,0,3] 947; AVX-NEXT: retq 948 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 949 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 0, i32 3> 950 ret <4 x i32> %2 951} 952 953define <4 x i32> @combine_nested_undef_test19(<4 x i32> %A, <4 x i32> %B) { 954; SSE2-LABEL: combine_nested_undef_test19: 955; SSE2: # %bb.0: 956; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 957; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,0,0,0] 958; SSE2-NEXT: retq 959; 960; SSSE3-LABEL: combine_nested_undef_test19: 961; SSSE3: # %bb.0: 962; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 963; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,0,0,0] 964; SSSE3-NEXT: retq 965; 966; SSE41-LABEL: combine_nested_undef_test19: 967; SSE41: # %bb.0: 968; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 969; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,0,0,0] 970; SSE41-NEXT: retq 971; 972; AVX-LABEL: combine_nested_undef_test19: 973; AVX: # %bb.0: 974; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3] 975; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[1,0,0,0] 976; AVX-NEXT: retq 977 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 5, i32 6> 978 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 0, i32 0, i32 0> 979 ret <4 x i32> %2 980} 981 982define <4 x i32> @combine_nested_undef_test20(<4 x i32> %A, <4 x i32> %B) { 983; SSE2-LABEL: combine_nested_undef_test20: 984; SSE2: # %bb.0: 985; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3] 986; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,3,1] 987; SSE2-NEXT: movaps %xmm1, %xmm0 988; SSE2-NEXT: retq 989; 990; SSSE3-LABEL: combine_nested_undef_test20: 991; SSSE3: # %bb.0: 992; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3] 993; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,3,1] 994; SSSE3-NEXT: movaps %xmm1, %xmm0 995; SSSE3-NEXT: retq 996; 997; SSE41-LABEL: combine_nested_undef_test20: 998; SSE41: # %bb.0: 999; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7] 1000; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,3,0] 1001; SSE41-NEXT: retq 1002; 1003; AVX-LABEL: combine_nested_undef_test20: 1004; AVX: # %bb.0: 1005; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 1006; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,2,3,0] 1007; AVX-NEXT: retq 1008 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 3, i32 2, i32 4, i32 4> 1009 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3> 1010 ret <4 x i32> %2 1011} 1012 1013define <4 x i32> @combine_nested_undef_test21(<4 x i32> %A, <4 x i32> %B) { 1014; SSE2-LABEL: combine_nested_undef_test21: 1015; SSE2: # %bb.0: 1016; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 1017; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,0,3] 1018; SSE2-NEXT: retq 1019; 1020; SSSE3-LABEL: combine_nested_undef_test21: 1021; SSSE3: # %bb.0: 1022; SSSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 1023; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,0,3] 1024; SSSE3-NEXT: retq 1025; 1026; SSE41-LABEL: combine_nested_undef_test21: 1027; SSE41: # %bb.0: 1028; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7] 1029; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1030; SSE41-NEXT: retq 1031; 1032; AVX1-LABEL: combine_nested_undef_test21: 1033; AVX1: # %bb.0: 1034; AVX1-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1035; AVX1-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,1,0,1] 1036; AVX1-NEXT: retq 1037; 1038; AVX2-LABEL: combine_nested_undef_test21: 1039; AVX2: # %bb.0: 1040; AVX2-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1041; AVX2-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 1042; AVX2-NEXT: retq 1043 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1> 1044 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3> 1045 ret <4 x i32> %2 1046} 1047 1048 1049; Test that we correctly combine shuffles according to rule 1050; shuffle(shuffle(x, y), undef) -> shuffle(y, undef) 1051 1052define <4 x i32> @combine_nested_undef_test22(<4 x i32> %A, <4 x i32> %B) { 1053; SSE-LABEL: combine_nested_undef_test22: 1054; SSE: # %bb.0: 1055; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,3] 1056; SSE-NEXT: retq 1057; 1058; AVX-LABEL: combine_nested_undef_test22: 1059; AVX: # %bb.0: 1060; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[1,1,1,3] 1061; AVX-NEXT: retq 1062 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 1063 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 3> 1064 ret <4 x i32> %2 1065} 1066 1067define <4 x i32> @combine_nested_undef_test23(<4 x i32> %A, <4 x i32> %B) { 1068; SSE-LABEL: combine_nested_undef_test23: 1069; SSE: # %bb.0: 1070; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,1,0,3] 1071; SSE-NEXT: retq 1072; 1073; AVX-LABEL: combine_nested_undef_test23: 1074; AVX: # %bb.0: 1075; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[0,1,0,3] 1076; AVX-NEXT: retq 1077 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7> 1078 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3> 1079 ret <4 x i32> %2 1080} 1081 1082define <4 x i32> @combine_nested_undef_test24(<4 x i32> %A, <4 x i32> %B) { 1083; SSE-LABEL: combine_nested_undef_test24: 1084; SSE: # %bb.0: 1085; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,3,2,3] 1086; SSE-NEXT: retq 1087; 1088; AVX-LABEL: combine_nested_undef_test24: 1089; AVX: # %bb.0: 1090; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[0,3,2,3] 1091; AVX-NEXT: retq 1092 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 7> 1093 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 3, i32 2, i32 4> 1094 ret <4 x i32> %2 1095} 1096 1097define <4 x i32> @combine_nested_undef_test25(<4 x i32> %A, <4 x i32> %B) { 1098; SSE-LABEL: combine_nested_undef_test25: 1099; SSE: # %bb.0: 1100; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1101; SSE-NEXT: retq 1102; 1103; AVX1-LABEL: combine_nested_undef_test25: 1104; AVX1: # %bb.0: 1105; AVX1-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,1,0,1] 1106; AVX1-NEXT: retq 1107; 1108; AVX2-LABEL: combine_nested_undef_test25: 1109; AVX2: # %bb.0: 1110; AVX2-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 1111; AVX2-NEXT: retq 1112 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 5, i32 2, i32 4> 1113 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 1, i32 3, i32 1> 1114 ret <4 x i32> %2 1115} 1116 1117define <4 x i32> @combine_nested_undef_test26(<4 x i32> %A, <4 x i32> %B) { 1118; SSE-LABEL: combine_nested_undef_test26: 1119; SSE: # %bb.0: 1120; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] 1121; SSE-NEXT: retq 1122; 1123; AVX-LABEL: combine_nested_undef_test26: 1124; AVX: # %bb.0: 1125; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[2,3,2,3] 1126; AVX-NEXT: retq 1127 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 6, i32 7> 1128 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3> 1129 ret <4 x i32> %2 1130} 1131 1132define <4 x i32> @combine_nested_undef_test27(<4 x i32> %A, <4 x i32> %B) { 1133; SSE-LABEL: combine_nested_undef_test27: 1134; SSE: # %bb.0: 1135; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 1136; SSE-NEXT: retq 1137; 1138; AVX1-LABEL: combine_nested_undef_test27: 1139; AVX1: # %bb.0: 1140; AVX1-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,1,0,1] 1141; AVX1-NEXT: retq 1142; 1143; AVX2-LABEL: combine_nested_undef_test27: 1144; AVX2: # %bb.0: 1145; AVX2-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 1146; AVX2-NEXT: retq 1147 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 2, i32 1, i32 5, i32 4> 1148 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 3, i32 2> 1149 ret <4 x i32> %2 1150} 1151 1152define <4 x i32> @combine_nested_undef_test28(<4 x i32> %A, <4 x i32> %B) { 1153; SSE-LABEL: combine_nested_undef_test28: 1154; SSE: # %bb.0: 1155; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,1,0] 1156; SSE-NEXT: retq 1157; 1158; AVX-LABEL: combine_nested_undef_test28: 1159; AVX: # %bb.0: 1160; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,1,1,0] 1161; AVX-NEXT: retq 1162 %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 1163 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 3, i32 2> 1164 ret <4 x i32> %2 1165} 1166 1167define <4 x float> @combine_test1(<4 x float> %a, <4 x float> %b) { 1168; SSE-LABEL: combine_test1: 1169; SSE: # %bb.0: 1170; SSE-NEXT: movaps %xmm1, %xmm0 1171; SSE-NEXT: retq 1172; 1173; AVX-LABEL: combine_test1: 1174; AVX: # %bb.0: 1175; AVX-NEXT: vmovaps %xmm1, %xmm0 1176; AVX-NEXT: retq 1177 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1178 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1179 ret <4 x float> %2 1180} 1181 1182define <4 x float> @combine_test2(<4 x float> %a, <4 x float> %b) { 1183; SSE2-LABEL: combine_test2: 1184; SSE2: # %bb.0: 1185; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1186; SSE2-NEXT: movaps %xmm1, %xmm0 1187; SSE2-NEXT: retq 1188; 1189; SSSE3-LABEL: combine_test2: 1190; SSSE3: # %bb.0: 1191; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1192; SSSE3-NEXT: movaps %xmm1, %xmm0 1193; SSSE3-NEXT: retq 1194; 1195; SSE41-LABEL: combine_test2: 1196; SSE41: # %bb.0: 1197; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1198; SSE41-NEXT: retq 1199; 1200; AVX-LABEL: combine_test2: 1201; AVX: # %bb.0: 1202; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1203; AVX-NEXT: retq 1204 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1205 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1206 ret <4 x float> %2 1207} 1208 1209define <4 x float> @combine_test3(<4 x float> %a, <4 x float> %b) { 1210; SSE-LABEL: combine_test3: 1211; SSE: # %bb.0: 1212; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1213; SSE-NEXT: retq 1214; 1215; AVX-LABEL: combine_test3: 1216; AVX: # %bb.0: 1217; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1218; AVX-NEXT: retq 1219 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 1220 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 1221 ret <4 x float> %2 1222} 1223 1224define <4 x float> @combine_test4(<4 x float> %a, <4 x float> %b) { 1225; SSE-LABEL: combine_test4: 1226; SSE: # %bb.0: 1227; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1] 1228; SSE-NEXT: retq 1229; 1230; AVX-LABEL: combine_test4: 1231; AVX: # %bb.0: 1232; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 1233; AVX-NEXT: retq 1234 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 1235 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1236 ret <4 x float> %2 1237} 1238 1239define <4 x float> @combine_test5(<4 x float> %a, <4 x float> %b) { 1240; SSE2-LABEL: combine_test5: 1241; SSE2: # %bb.0: 1242; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1243; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1244; SSE2-NEXT: retq 1245; 1246; SSSE3-LABEL: combine_test5: 1247; SSSE3: # %bb.0: 1248; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1249; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1250; SSSE3-NEXT: retq 1251; 1252; SSE41-LABEL: combine_test5: 1253; SSE41: # %bb.0: 1254; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1255; SSE41-NEXT: retq 1256; 1257; AVX-LABEL: combine_test5: 1258; AVX: # %bb.0: 1259; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1260; AVX-NEXT: retq 1261 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1262 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 1263 ret <4 x float> %2 1264} 1265 1266define <4 x i32> @combine_test6(<4 x i32> %a, <4 x i32> %b) { 1267; SSE-LABEL: combine_test6: 1268; SSE: # %bb.0: 1269; SSE-NEXT: movaps %xmm1, %xmm0 1270; SSE-NEXT: retq 1271; 1272; AVX-LABEL: combine_test6: 1273; AVX: # %bb.0: 1274; AVX-NEXT: vmovaps %xmm1, %xmm0 1275; AVX-NEXT: retq 1276 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1277 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1278 ret <4 x i32> %2 1279} 1280 1281define <4 x i32> @combine_test7(<4 x i32> %a, <4 x i32> %b) { 1282; SSE2-LABEL: combine_test7: 1283; SSE2: # %bb.0: 1284; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1285; SSE2-NEXT: movaps %xmm1, %xmm0 1286; SSE2-NEXT: retq 1287; 1288; SSSE3-LABEL: combine_test7: 1289; SSSE3: # %bb.0: 1290; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1291; SSSE3-NEXT: movaps %xmm1, %xmm0 1292; SSSE3-NEXT: retq 1293; 1294; SSE41-LABEL: combine_test7: 1295; SSE41: # %bb.0: 1296; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1297; SSE41-NEXT: retq 1298; 1299; AVX-LABEL: combine_test7: 1300; AVX: # %bb.0: 1301; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1302; AVX-NEXT: retq 1303 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1304 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1305 ret <4 x i32> %2 1306} 1307 1308define <4 x i32> @combine_test8(<4 x i32> %a, <4 x i32> %b) { 1309; SSE-LABEL: combine_test8: 1310; SSE: # %bb.0: 1311; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1312; SSE-NEXT: retq 1313; 1314; AVX-LABEL: combine_test8: 1315; AVX: # %bb.0: 1316; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1317; AVX-NEXT: retq 1318 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 1319 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 1320 ret <4 x i32> %2 1321} 1322 1323define <4 x i32> @combine_test9(<4 x i32> %a, <4 x i32> %b) { 1324; SSE-LABEL: combine_test9: 1325; SSE: # %bb.0: 1326; SSE-NEXT: unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1] 1327; SSE-NEXT: movaps %xmm1, %xmm0 1328; SSE-NEXT: retq 1329; 1330; AVX-LABEL: combine_test9: 1331; AVX: # %bb.0: 1332; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 1333; AVX-NEXT: retq 1334 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 1335 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1336 ret <4 x i32> %2 1337} 1338 1339define <4 x i32> @combine_test10(<4 x i32> %a, <4 x i32> %b) { 1340; SSE2-LABEL: combine_test10: 1341; SSE2: # %bb.0: 1342; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1343; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1344; SSE2-NEXT: retq 1345; 1346; SSSE3-LABEL: combine_test10: 1347; SSSE3: # %bb.0: 1348; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1349; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1350; SSSE3-NEXT: retq 1351; 1352; SSE41-LABEL: combine_test10: 1353; SSE41: # %bb.0: 1354; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1355; SSE41-NEXT: retq 1356; 1357; AVX-LABEL: combine_test10: 1358; AVX: # %bb.0: 1359; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1360; AVX-NEXT: retq 1361 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1362 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 1363 ret <4 x i32> %2 1364} 1365 1366define <4 x float> @combine_test11(<4 x float> %a, <4 x float> %b) { 1367; CHECK-LABEL: combine_test11: 1368; CHECK: # %bb.0: 1369; CHECK-NEXT: retq 1370 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1371 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1372 ret <4 x float> %2 1373} 1374 1375define <4 x float> @combine_test12(<4 x float> %a, <4 x float> %b) { 1376; SSE2-LABEL: combine_test12: 1377; SSE2: # %bb.0: 1378; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1379; SSE2-NEXT: movaps %xmm1, %xmm0 1380; SSE2-NEXT: retq 1381; 1382; SSSE3-LABEL: combine_test12: 1383; SSSE3: # %bb.0: 1384; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1385; SSSE3-NEXT: movaps %xmm1, %xmm0 1386; SSSE3-NEXT: retq 1387; 1388; SSE41-LABEL: combine_test12: 1389; SSE41: # %bb.0: 1390; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1391; SSE41-NEXT: retq 1392; 1393; AVX-LABEL: combine_test12: 1394; AVX: # %bb.0: 1395; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1396; AVX-NEXT: retq 1397 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7> 1398 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3> 1399 ret <4 x float> %2 1400} 1401 1402define <4 x float> @combine_test13(<4 x float> %a, <4 x float> %b) { 1403; SSE-LABEL: combine_test13: 1404; SSE: # %bb.0: 1405; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1406; SSE-NEXT: retq 1407; 1408; AVX-LABEL: combine_test13: 1409; AVX: # %bb.0: 1410; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1411; AVX-NEXT: retq 1412 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5> 1413 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3> 1414 ret <4 x float> %2 1415} 1416 1417define <4 x float> @combine_test14(<4 x float> %a, <4 x float> %b) { 1418; SSE-LABEL: combine_test14: 1419; SSE: # %bb.0: 1420; SSE-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1421; SSE-NEXT: retq 1422; 1423; AVX-LABEL: combine_test14: 1424; AVX: # %bb.0: 1425; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1426; AVX-NEXT: retq 1427 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5> 1428 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1429 ret <4 x float> %2 1430} 1431 1432define <4 x float> @combine_test15(<4 x float> %a, <4 x float> %b) { 1433; SSE2-LABEL: combine_test15: 1434; SSE2: # %bb.0: 1435; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1436; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1437; SSE2-NEXT: retq 1438; 1439; SSSE3-LABEL: combine_test15: 1440; SSSE3: # %bb.0: 1441; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1442; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1443; SSSE3-NEXT: retq 1444; 1445; SSE41-LABEL: combine_test15: 1446; SSE41: # %bb.0: 1447; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1448; SSE41-NEXT: retq 1449; 1450; AVX-LABEL: combine_test15: 1451; AVX: # %bb.0: 1452; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1453; AVX-NEXT: retq 1454 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7> 1455 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 1456 ret <4 x float> %2 1457} 1458 1459define <4 x i32> @combine_test16(<4 x i32> %a, <4 x i32> %b) { 1460; CHECK-LABEL: combine_test16: 1461; CHECK: # %bb.0: 1462; CHECK-NEXT: retq 1463 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1464 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1465 ret <4 x i32> %2 1466} 1467 1468define <4 x i32> @combine_test17(<4 x i32> %a, <4 x i32> %b) { 1469; SSE2-LABEL: combine_test17: 1470; SSE2: # %bb.0: 1471; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1472; SSE2-NEXT: movaps %xmm1, %xmm0 1473; SSE2-NEXT: retq 1474; 1475; SSSE3-LABEL: combine_test17: 1476; SSSE3: # %bb.0: 1477; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1478; SSSE3-NEXT: movaps %xmm1, %xmm0 1479; SSSE3-NEXT: retq 1480; 1481; SSE41-LABEL: combine_test17: 1482; SSE41: # %bb.0: 1483; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1484; SSE41-NEXT: retq 1485; 1486; AVX-LABEL: combine_test17: 1487; AVX: # %bb.0: 1488; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1489; AVX-NEXT: retq 1490 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7> 1491 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3> 1492 ret <4 x i32> %2 1493} 1494 1495define <4 x i32> @combine_test18(<4 x i32> %a, <4 x i32> %b) { 1496; SSE-LABEL: combine_test18: 1497; SSE: # %bb.0: 1498; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1499; SSE-NEXT: retq 1500; 1501; AVX-LABEL: combine_test18: 1502; AVX: # %bb.0: 1503; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1504; AVX-NEXT: retq 1505 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5> 1506 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3> 1507 ret <4 x i32> %2 1508} 1509 1510define <4 x i32> @combine_test19(<4 x i32> %a, <4 x i32> %b) { 1511; SSE-LABEL: combine_test19: 1512; SSE: # %bb.0: 1513; SSE-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1514; SSE-NEXT: retq 1515; 1516; AVX-LABEL: combine_test19: 1517; AVX: # %bb.0: 1518; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1519; AVX-NEXT: retq 1520 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5> 1521 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1522 ret <4 x i32> %2 1523} 1524 1525define <4 x i32> @combine_test20(<4 x i32> %a, <4 x i32> %b) { 1526; SSE2-LABEL: combine_test20: 1527; SSE2: # %bb.0: 1528; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1529; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1530; SSE2-NEXT: retq 1531; 1532; SSSE3-LABEL: combine_test20: 1533; SSSE3: # %bb.0: 1534; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0] 1535; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3] 1536; SSSE3-NEXT: retq 1537; 1538; SSE41-LABEL: combine_test20: 1539; SSE41: # %bb.0: 1540; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1541; SSE41-NEXT: retq 1542; 1543; AVX-LABEL: combine_test20: 1544; AVX: # %bb.0: 1545; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3] 1546; AVX-NEXT: retq 1547 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7> 1548 %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 1549 ret <4 x i32> %2 1550} 1551 1552define <4 x i32> @combine_test21(<8 x i32> %a, <4 x i32>* %ptr) { 1553; SSE-LABEL: combine_test21: 1554; SSE: # %bb.0: 1555; SSE-NEXT: movaps %xmm0, %xmm2 1556; SSE-NEXT: movlhps {{.*#+}} xmm2 = xmm2[0],xmm1[0] 1557; SSE-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1558; SSE-NEXT: movaps %xmm2, (%rdi) 1559; SSE-NEXT: retq 1560; 1561; AVX-LABEL: combine_test21: 1562; AVX: # %bb.0: 1563; AVX-NEXT: vextractf128 $1, %ymm0, %xmm1 1564; AVX-NEXT: vmovlhps {{.*#+}} xmm2 = xmm0[0],xmm1[0] 1565; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] 1566; AVX-NEXT: vmovaps %xmm2, (%rdi) 1567; AVX-NEXT: vzeroupper 1568; AVX-NEXT: retq 1569 %1 = shufflevector <8 x i32> %a, <8 x i32> %a, <4 x i32> <i32 0, i32 1, i32 4, i32 5> 1570 %2 = shufflevector <8 x i32> %a, <8 x i32> %a, <4 x i32> <i32 2, i32 3, i32 6, i32 7> 1571 store <4 x i32> %1, <4 x i32>* %ptr, align 16 1572 ret <4 x i32> %2 1573} 1574 1575define <8 x float> @combine_test22(<2 x float>* %a, <2 x float>* %b) { 1576; SSE-LABEL: combine_test22: 1577; SSE: # %bb.0: 1578; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 1579; SSE-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1] 1580; SSE-NEXT: retq 1581; 1582; AVX-LABEL: combine_test22: 1583; AVX: # %bb.0: 1584; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 1585; AVX-NEXT: vmovhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1] 1586; AVX-NEXT: retq 1587; Current AVX2 lowering of this is still awful, not adding a test case. 1588 %1 = load <2 x float>, <2 x float>* %a, align 8 1589 %2 = load <2 x float>, <2 x float>* %b, align 8 1590 %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> 1591 ret <8 x float> %3 1592} 1593 1594; PR22359 1595define void @combine_test23(<8 x float> %v, <2 x float>* %ptr) { 1596; SSE-LABEL: combine_test23: 1597; SSE: # %bb.0: 1598; SSE-NEXT: movups %xmm0, (%rdi) 1599; SSE-NEXT: retq 1600; 1601; AVX-LABEL: combine_test23: 1602; AVX: # %bb.0: 1603; AVX-NEXT: vmovups %xmm0, (%rdi) 1604; AVX-NEXT: vzeroupper 1605; AVX-NEXT: retq 1606 %idx2 = getelementptr inbounds <2 x float>, <2 x float>* %ptr, i64 1 1607 %shuffle0 = shufflevector <8 x float> %v, <8 x float> undef, <2 x i32> <i32 0, i32 1> 1608 %shuffle1 = shufflevector <8 x float> %v, <8 x float> undef, <2 x i32> <i32 2, i32 3> 1609 store <2 x float> %shuffle0, <2 x float>* %ptr, align 8 1610 store <2 x float> %shuffle1, <2 x float>* %idx2, align 8 1611 ret void 1612} 1613 1614; Check some negative cases. 1615; FIXME: Do any of these really make sense? Are they redundant with the above tests? 1616 1617define <4 x float> @combine_test1b(<4 x float> %a, <4 x float> %b) { 1618; SSE-LABEL: combine_test1b: 1619; SSE: # %bb.0: 1620; SSE-NEXT: movaps %xmm1, %xmm0 1621; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0] 1622; SSE-NEXT: retq 1623; 1624; AVX-LABEL: combine_test1b: 1625; AVX: # %bb.0: 1626; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[0,1,2,0] 1627; AVX-NEXT: retq 1628 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1629 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 0> 1630 ret <4 x float> %2 1631} 1632 1633define <4 x float> @combine_test2b(<4 x float> %a, <4 x float> %b) { 1634; SSE2-LABEL: combine_test2b: 1635; SSE2: # %bb.0: 1636; SSE2-NEXT: movaps %xmm1, %xmm0 1637; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1638; SSE2-NEXT: retq 1639; 1640; SSSE3-LABEL: combine_test2b: 1641; SSSE3: # %bb.0: 1642; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm1[0,0] 1643; SSSE3-NEXT: retq 1644; 1645; SSE41-LABEL: combine_test2b: 1646; SSE41: # %bb.0: 1647; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm1[0,0] 1648; SSE41-NEXT: retq 1649; 1650; AVX-LABEL: combine_test2b: 1651; AVX: # %bb.0: 1652; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm1[0,0] 1653; AVX-NEXT: retq 1654 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1655 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 0, i32 5> 1656 ret <4 x float> %2 1657} 1658 1659define <4 x float> @combine_test3b(<4 x float> %a, <4 x float> %b) { 1660; SSE2-LABEL: combine_test3b: 1661; SSE2: # %bb.0: 1662; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0] 1663; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3] 1664; SSE2-NEXT: retq 1665; 1666; SSSE3-LABEL: combine_test3b: 1667; SSSE3: # %bb.0: 1668; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0] 1669; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3] 1670; SSSE3-NEXT: retq 1671; 1672; SSE41-LABEL: combine_test3b: 1673; SSE41: # %bb.0: 1674; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 1675; SSE41-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,3,2,3] 1676; SSE41-NEXT: retq 1677; 1678; AVX-LABEL: combine_test3b: 1679; AVX: # %bb.0: 1680; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 1681; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,3,2,3] 1682; AVX-NEXT: retq 1683 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 0, i32 6, i32 3> 1684 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 7, i32 2, i32 7> 1685 ret <4 x float> %2 1686} 1687 1688define <4 x float> @combine_test4b(<4 x float> %a, <4 x float> %b) { 1689; SSE-LABEL: combine_test4b: 1690; SSE: # %bb.0: 1691; SSE-NEXT: movaps %xmm1, %xmm0 1692; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1],xmm1[2,3] 1693; SSE-NEXT: retq 1694; 1695; AVX-LABEL: combine_test4b: 1696; AVX: # %bb.0: 1697; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm1[1,1,2,3] 1698; AVX-NEXT: retq 1699 %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1700 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 5, i32 5, i32 2, i32 7> 1701 ret <4 x float> %2 1702} 1703 1704 1705; Verify that we correctly fold shuffles even when we use illegal vector types. 1706 1707define <4 x i8> @combine_test1c(<4 x i8>* %a, <4 x i8>* %b) { 1708; SSE2-LABEL: combine_test1c: 1709; SSE2: # %bb.0: 1710; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 1711; SSE2-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero 1712; SSE2-NEXT: movaps {{.*#+}} xmm0 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255] 1713; SSE2-NEXT: andps %xmm0, %xmm2 1714; SSE2-NEXT: andnps %xmm1, %xmm0 1715; SSE2-NEXT: orps %xmm2, %xmm0 1716; SSE2-NEXT: retq 1717; 1718; SSSE3-LABEL: combine_test1c: 1719; SSSE3: # %bb.0: 1720; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1721; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1722; 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] 1723; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[1,2,4,6,u,u,u,u,u,u,u,u,u,u,u,u] 1724; SSSE3-NEXT: retq 1725; 1726; SSE41-LABEL: combine_test1c: 1727; SSE41: # %bb.0: 1728; SSE41-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1729; SSE41-NEXT: movd {{.*#+}} xmm2 = mem[0],zero,zero,zero 1730; SSE41-NEXT: movaps {{.*#+}} xmm0 = <0,255,255,255,u,u,u,u,u,u,u,u,u,u,u,u> 1731; SSE41-NEXT: pblendvb %xmm0, %xmm2, %xmm1 1732; SSE41-NEXT: movdqa %xmm1, %xmm0 1733; SSE41-NEXT: retq 1734; 1735; AVX-LABEL: combine_test1c: 1736; AVX: # %bb.0: 1737; AVX-NEXT: vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1738; AVX-NEXT: vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1739; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = <0,255,255,255,u,u,u,u,u,u,u,u,u,u,u,u> 1740; AVX-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0 1741; AVX-NEXT: retq 1742 %A = load <4 x i8>, <4 x i8>* %a 1743 %B = load <4 x i8>, <4 x i8>* %b 1744 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 1745 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1746 ret <4 x i8> %2 1747} 1748 1749define <4 x i8> @combine_test2c(<4 x i8>* %a, <4 x i8>* %b) { 1750; SSE-LABEL: combine_test2c: 1751; SSE: # %bb.0: 1752; SSE-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1753; SSE-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1754; SSE-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3] 1755; SSE-NEXT: retq 1756; 1757; AVX-LABEL: combine_test2c: 1758; AVX: # %bb.0: 1759; AVX-NEXT: vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1760; AVX-NEXT: vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1761; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3] 1762; AVX-NEXT: retq 1763 %A = load <4 x i8>, <4 x i8>* %a 1764 %B = load <4 x i8>, <4 x i8>* %b 1765 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 1, i32 5> 1766 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 1767 ret <4 x i8> %2 1768} 1769 1770define <4 x i8> @combine_test3c(<4 x i8>* %a, <4 x i8>* %b) { 1771; SSE-LABEL: combine_test3c: 1772; SSE: # %bb.0: 1773; SSE-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1774; SSE-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1775; SSE-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1776; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3] 1777; SSE-NEXT: retq 1778; 1779; AVX-LABEL: combine_test3c: 1780; AVX: # %bb.0: 1781; AVX-NEXT: vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1782; AVX-NEXT: vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1783; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1784; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,3] 1785; AVX-NEXT: retq 1786 %A = load <4 x i8>, <4 x i8>* %a 1787 %B = load <4 x i8>, <4 x i8>* %b 1788 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 1789 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 1790 ret <4 x i8> %2 1791} 1792 1793define <4 x i8> @combine_test4c(<4 x i8>* %a, <4 x i8>* %b) { 1794; SSE2-LABEL: combine_test4c: 1795; SSE2: # %bb.0: 1796; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 1797; SSE2-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero 1798; SSE2-NEXT: movaps {{.*#+}} xmm0 = [255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255] 1799; SSE2-NEXT: andps %xmm0, %xmm2 1800; SSE2-NEXT: andnps %xmm1, %xmm0 1801; SSE2-NEXT: orps %xmm2, %xmm0 1802; SSE2-NEXT: retq 1803; 1804; SSSE3-LABEL: combine_test4c: 1805; SSSE3: # %bb.0: 1806; SSSE3-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1807; SSSE3-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1808; 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] 1809; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0,3,4,6,u,u,u,u,u,u,u,u,u,u,u,u] 1810; SSSE3-NEXT: retq 1811; 1812; SSE41-LABEL: combine_test4c: 1813; SSE41: # %bb.0: 1814; SSE41-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1815; SSE41-NEXT: movd {{.*#+}} xmm2 = mem[0],zero,zero,zero 1816; SSE41-NEXT: movaps {{.*#+}} xmm0 = <255,0,255,255,u,u,u,u,u,u,u,u,u,u,u,u> 1817; SSE41-NEXT: pblendvb %xmm0, %xmm2, %xmm1 1818; SSE41-NEXT: movdqa %xmm1, %xmm0 1819; SSE41-NEXT: retq 1820; 1821; AVX-LABEL: combine_test4c: 1822; AVX: # %bb.0: 1823; AVX-NEXT: vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero 1824; AVX-NEXT: vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero 1825; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = <255,0,255,255,u,u,u,u,u,u,u,u,u,u,u,u> 1826; AVX-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0 1827; AVX-NEXT: retq 1828 %A = load <4 x i8>, <4 x i8>* %a 1829 %B = load <4 x i8>, <4 x i8>* %b 1830 %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 1831 %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 1832 ret <4 x i8> %2 1833} 1834 1835 1836; The following test cases are generated from this C++ code 1837; 1838;__m128 blend_01(__m128 a, __m128 b) 1839;{ 1840; __m128 s = a; 1841; s = _mm_blend_ps( s, b, 1<<0 ); 1842; s = _mm_blend_ps( s, b, 1<<1 ); 1843; return s; 1844;} 1845; 1846;__m128 blend_02(__m128 a, __m128 b) 1847;{ 1848; __m128 s = a; 1849; s = _mm_blend_ps( s, b, 1<<0 ); 1850; s = _mm_blend_ps( s, b, 1<<2 ); 1851; return s; 1852;} 1853; 1854;__m128 blend_123(__m128 a, __m128 b) 1855;{ 1856; __m128 s = a; 1857; s = _mm_blend_ps( s, b, 1<<1 ); 1858; s = _mm_blend_ps( s, b, 1<<2 ); 1859; s = _mm_blend_ps( s, b, 1<<3 ); 1860; return s; 1861;} 1862 1863; Ideally, we should collapse the following shuffles into a single one. 1864 1865define <4 x float> @combine_blend_01(<4 x float> %a, <4 x float> %b) { 1866; SSE2-LABEL: combine_blend_01: 1867; SSE2: # %bb.0: 1868; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 1869; SSE2-NEXT: retq 1870; 1871; SSSE3-LABEL: combine_blend_01: 1872; SSSE3: # %bb.0: 1873; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 1874; SSSE3-NEXT: retq 1875; 1876; SSE41-LABEL: combine_blend_01: 1877; SSE41: # %bb.0: 1878; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 1879; SSE41-NEXT: retq 1880; 1881; AVX-LABEL: combine_blend_01: 1882; AVX: # %bb.0: 1883; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 1884; AVX-NEXT: retq 1885 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 undef, i32 2, i32 3> 1886 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 1887 ret <4 x float> %shuffle6 1888} 1889 1890define <4 x float> @combine_blend_02(<4 x float> %a, <4 x float> %b) { 1891; SSE2-LABEL: combine_blend_02: 1892; SSE2: # %bb.0: 1893; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3] 1894; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,1,3] 1895; SSE2-NEXT: movaps %xmm1, %xmm0 1896; SSE2-NEXT: retq 1897; 1898; SSSE3-LABEL: combine_blend_02: 1899; SSSE3: # %bb.0: 1900; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3] 1901; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2,1,3] 1902; SSSE3-NEXT: movaps %xmm1, %xmm0 1903; SSSE3-NEXT: retq 1904; 1905; SSE41-LABEL: combine_blend_02: 1906; SSE41: # %bb.0: 1907; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3] 1908; SSE41-NEXT: retq 1909; 1910; AVX-LABEL: combine_blend_02: 1911; AVX: # %bb.0: 1912; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3] 1913; AVX-NEXT: retq 1914 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 undef, i32 3> 1915 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3> 1916 ret <4 x float> %shuffle6 1917} 1918 1919define <4 x float> @combine_blend_123(<4 x float> %a, <4 x float> %b) { 1920; SSE2-LABEL: combine_blend_123: 1921; SSE2: # %bb.0: 1922; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1923; SSE2-NEXT: movaps %xmm1, %xmm0 1924; SSE2-NEXT: retq 1925; 1926; SSSE3-LABEL: combine_blend_123: 1927; SSSE3: # %bb.0: 1928; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 1929; SSSE3-NEXT: movaps %xmm1, %xmm0 1930; SSSE3-NEXT: retq 1931; 1932; SSE41-LABEL: combine_blend_123: 1933; SSE41: # %bb.0: 1934; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1935; SSE41-NEXT: retq 1936; 1937; AVX-LABEL: combine_blend_123: 1938; AVX: # %bb.0: 1939; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 1940; AVX-NEXT: retq 1941 %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef> 1942 %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 undef> 1943 %shuffle12 = shufflevector <4 x float> %shuffle6, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 1944 ret <4 x float> %shuffle12 1945} 1946 1947define <4 x i32> @combine_test_movhl_1(<4 x i32> %a, <4 x i32> %b) { 1948; SSE-LABEL: combine_test_movhl_1: 1949; SSE: # %bb.0: 1950; SSE-NEXT: unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1] 1951; SSE-NEXT: movaps %xmm1, %xmm0 1952; SSE-NEXT: retq 1953; 1954; AVX-LABEL: combine_test_movhl_1: 1955; AVX: # %bb.0: 1956; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 1957; AVX-NEXT: retq 1958 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 7, i32 5, i32 3> 1959 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 1, i32 0, i32 3> 1960 ret <4 x i32> %2 1961} 1962 1963define <4 x i32> @combine_test_movhl_2(<4 x i32> %a, <4 x i32> %b) { 1964; SSE-LABEL: combine_test_movhl_2: 1965; SSE: # %bb.0: 1966; SSE-NEXT: unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1] 1967; SSE-NEXT: movaps %xmm1, %xmm0 1968; SSE-NEXT: retq 1969; 1970; AVX-LABEL: combine_test_movhl_2: 1971; AVX: # %bb.0: 1972; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 1973; AVX-NEXT: retq 1974 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 0, i32 3, i32 6> 1975 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 3, i32 7, i32 0, i32 2> 1976 ret <4 x i32> %2 1977} 1978 1979define <4 x i32> @combine_test_movhl_3(<4 x i32> %a, <4 x i32> %b) { 1980; SSE-LABEL: combine_test_movhl_3: 1981; SSE: # %bb.0: 1982; SSE-NEXT: unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1] 1983; SSE-NEXT: movaps %xmm1, %xmm0 1984; SSE-NEXT: retq 1985; 1986; AVX-LABEL: combine_test_movhl_3: 1987; AVX: # %bb.0: 1988; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 1989; AVX-NEXT: retq 1990 %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 7, i32 6, i32 3, i32 2> 1991 %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 0, i32 3, i32 2> 1992 ret <4 x i32> %2 1993} 1994 1995 1996; Verify that we fold shuffles according to rule: 1997; (shuffle(shuffle A, Undef, M0), B, M1) -> (shuffle A, B, M2) 1998 1999define <4 x float> @combine_undef_input_test1(<4 x float> %a, <4 x float> %b) { 2000; SSE2-LABEL: combine_undef_input_test1: 2001; SSE2: # %bb.0: 2002; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2003; SSE2-NEXT: retq 2004; 2005; SSSE3-LABEL: combine_undef_input_test1: 2006; SSSE3: # %bb.0: 2007; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2008; SSSE3-NEXT: retq 2009; 2010; SSE41-LABEL: combine_undef_input_test1: 2011; SSE41: # %bb.0: 2012; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 2013; SSE41-NEXT: retq 2014; 2015; AVX-LABEL: combine_undef_input_test1: 2016; AVX: # %bb.0: 2017; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 2018; AVX-NEXT: retq 2019 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2020 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 4, i32 5, i32 1, i32 2> 2021 ret <4 x float> %2 2022} 2023 2024define <4 x float> @combine_undef_input_test2(<4 x float> %a, <4 x float> %b) { 2025; SSE-LABEL: combine_undef_input_test2: 2026; SSE: # %bb.0: 2027; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2028; SSE-NEXT: retq 2029; 2030; AVX-LABEL: combine_undef_input_test2: 2031; AVX: # %bb.0: 2032; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2033; AVX-NEXT: retq 2034 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2035 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 2036 ret <4 x float> %2 2037} 2038 2039define <4 x float> @combine_undef_input_test3(<4 x float> %a, <4 x float> %b) { 2040; SSE-LABEL: combine_undef_input_test3: 2041; SSE: # %bb.0: 2042; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2043; SSE-NEXT: retq 2044; 2045; AVX-LABEL: combine_undef_input_test3: 2046; AVX: # %bb.0: 2047; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2048; AVX-NEXT: retq 2049 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2050 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 2051 ret <4 x float> %2 2052} 2053 2054define <4 x float> @combine_undef_input_test4(<4 x float> %a, <4 x float> %b) { 2055; SSE-LABEL: combine_undef_input_test4: 2056; SSE: # %bb.0: 2057; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2058; SSE-NEXT: retq 2059; 2060; AVX-LABEL: combine_undef_input_test4: 2061; AVX: # %bb.0: 2062; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2063; AVX-NEXT: retq 2064 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2065 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 2066 ret <4 x float> %2 2067} 2068 2069define <4 x float> @combine_undef_input_test5(<4 x float> %a, <4 x float> %b) { 2070; SSE2-LABEL: combine_undef_input_test5: 2071; SSE2: # %bb.0: 2072; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 2073; SSE2-NEXT: retq 2074; 2075; SSSE3-LABEL: combine_undef_input_test5: 2076; SSSE3: # %bb.0: 2077; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 2078; SSSE3-NEXT: retq 2079; 2080; SSE41-LABEL: combine_undef_input_test5: 2081; SSE41: # %bb.0: 2082; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 2083; SSE41-NEXT: retq 2084; 2085; AVX-LABEL: combine_undef_input_test5: 2086; AVX: # %bb.0: 2087; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 2088; AVX-NEXT: retq 2089 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2090 %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 6, i32 7> 2091 ret <4 x float> %2 2092} 2093 2094 2095; Verify that we fold shuffles according to rule: 2096; (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2) 2097 2098define <4 x float> @combine_undef_input_test6(<4 x float> %a) { 2099; CHECK-LABEL: combine_undef_input_test6: 2100; CHECK: # %bb.0: 2101; CHECK-NEXT: retq 2102 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2103 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 1, i32 2> 2104 ret <4 x float> %2 2105} 2106 2107define <4 x float> @combine_undef_input_test7(<4 x float> %a) { 2108; SSE2-LABEL: combine_undef_input_test7: 2109; SSE2: # %bb.0: 2110; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2111; SSE2-NEXT: retq 2112; 2113; SSSE3-LABEL: combine_undef_input_test7: 2114; SSSE3: # %bb.0: 2115; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2116; SSSE3-NEXT: retq 2117; 2118; SSE41-LABEL: combine_undef_input_test7: 2119; SSE41: # %bb.0: 2120; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2121; SSE41-NEXT: retq 2122; 2123; AVX-LABEL: combine_undef_input_test7: 2124; AVX: # %bb.0: 2125; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2126; AVX-NEXT: retq 2127 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2128 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 1, i32 2, i32 4, i32 5> 2129 ret <4 x float> %2 2130} 2131 2132define <4 x float> @combine_undef_input_test8(<4 x float> %a) { 2133; SSE2-LABEL: combine_undef_input_test8: 2134; SSE2: # %bb.0: 2135; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2136; SSE2-NEXT: retq 2137; 2138; SSSE3-LABEL: combine_undef_input_test8: 2139; SSSE3: # %bb.0: 2140; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2141; SSSE3-NEXT: retq 2142; 2143; SSE41-LABEL: combine_undef_input_test8: 2144; SSE41: # %bb.0: 2145; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2146; SSE41-NEXT: retq 2147; 2148; AVX-LABEL: combine_undef_input_test8: 2149; AVX: # %bb.0: 2150; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2151; AVX-NEXT: retq 2152 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2153 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 4, i32 1> 2154 ret <4 x float> %2 2155} 2156 2157define <4 x float> @combine_undef_input_test9(<4 x float> %a) { 2158; SSE-LABEL: combine_undef_input_test9: 2159; SSE: # %bb.0: 2160; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1] 2161; SSE-NEXT: retq 2162; 2163; AVX-LABEL: combine_undef_input_test9: 2164; AVX: # %bb.0: 2165; AVX-NEXT: vpermilpd {{.*#+}} xmm0 = xmm0[1,1] 2166; AVX-NEXT: retq 2167 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2168 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1> 2169 ret <4 x float> %2 2170} 2171 2172define <4 x float> @combine_undef_input_test10(<4 x float> %a) { 2173; CHECK-LABEL: combine_undef_input_test10: 2174; CHECK: # %bb.0: 2175; CHECK-NEXT: retq 2176 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2177 %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 6, i32 7> 2178 ret <4 x float> %2 2179} 2180 2181define <4 x float> @combine_undef_input_test11(<4 x float> %a, <4 x float> %b) { 2182; SSE2-LABEL: combine_undef_input_test11: 2183; SSE2: # %bb.0: 2184; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2185; SSE2-NEXT: retq 2186; 2187; SSSE3-LABEL: combine_undef_input_test11: 2188; SSSE3: # %bb.0: 2189; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 2190; SSSE3-NEXT: retq 2191; 2192; SSE41-LABEL: combine_undef_input_test11: 2193; SSE41: # %bb.0: 2194; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 2195; SSE41-NEXT: retq 2196; 2197; AVX-LABEL: combine_undef_input_test11: 2198; AVX: # %bb.0: 2199; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 2200; AVX-NEXT: retq 2201 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2202 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 6> 2203 ret <4 x float> %2 2204} 2205 2206define <4 x float> @combine_undef_input_test12(<4 x float> %a, <4 x float> %b) { 2207; SSE-LABEL: combine_undef_input_test12: 2208; SSE: # %bb.0: 2209; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2210; SSE-NEXT: retq 2211; 2212; AVX-LABEL: combine_undef_input_test12: 2213; AVX: # %bb.0: 2214; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2215; AVX-NEXT: retq 2216 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2217 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1> 2218 ret <4 x float> %2 2219} 2220 2221define <4 x float> @combine_undef_input_test13(<4 x float> %a, <4 x float> %b) { 2222; SSE-LABEL: combine_undef_input_test13: 2223; SSE: # %bb.0: 2224; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2225; SSE-NEXT: retq 2226; 2227; AVX-LABEL: combine_undef_input_test13: 2228; AVX: # %bb.0: 2229; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2230; AVX-NEXT: retq 2231 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2232 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 5, i32 0, i32 5> 2233 ret <4 x float> %2 2234} 2235 2236define <4 x float> @combine_undef_input_test14(<4 x float> %a, <4 x float> %b) { 2237; SSE-LABEL: combine_undef_input_test14: 2238; SSE: # %bb.0: 2239; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2240; SSE-NEXT: retq 2241; 2242; AVX-LABEL: combine_undef_input_test14: 2243; AVX: # %bb.0: 2244; AVX-NEXT: vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1] 2245; AVX-NEXT: retq 2246 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2247 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5> 2248 ret <4 x float> %2 2249} 2250 2251define <4 x float> @combine_undef_input_test15(<4 x float> %a, <4 x float> %b) { 2252; SSE2-LABEL: combine_undef_input_test15: 2253; SSE2: # %bb.0: 2254; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 2255; SSE2-NEXT: retq 2256; 2257; SSSE3-LABEL: combine_undef_input_test15: 2258; SSSE3: # %bb.0: 2259; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 2260; SSSE3-NEXT: retq 2261; 2262; SSE41-LABEL: combine_undef_input_test15: 2263; SSE41: # %bb.0: 2264; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 2265; SSE41-NEXT: retq 2266; 2267; AVX-LABEL: combine_undef_input_test15: 2268; AVX: # %bb.0: 2269; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 2270; AVX-NEXT: retq 2271 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2272 %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2273 ret <4 x float> %2 2274} 2275 2276 2277; Verify that shuffles are canonicalized according to rules: 2278; shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B) 2279; 2280; This allows to trigger the following combine rule: 2281; (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2) 2282; 2283; As a result, all the shuffle pairs in each function below should be 2284; combined into a single legal shuffle operation. 2285 2286define <4 x float> @combine_undef_input_test16(<4 x float> %a) { 2287; CHECK-LABEL: combine_undef_input_test16: 2288; CHECK: # %bb.0: 2289; CHECK-NEXT: retq 2290 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1> 2291 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 3> 2292 ret <4 x float> %2 2293} 2294 2295define <4 x float> @combine_undef_input_test17(<4 x float> %a) { 2296; SSE2-LABEL: combine_undef_input_test17: 2297; SSE2: # %bb.0: 2298; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2299; SSE2-NEXT: retq 2300; 2301; SSSE3-LABEL: combine_undef_input_test17: 2302; SSSE3: # %bb.0: 2303; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2304; SSSE3-NEXT: retq 2305; 2306; SSE41-LABEL: combine_undef_input_test17: 2307; SSE41: # %bb.0: 2308; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2309; SSE41-NEXT: retq 2310; 2311; AVX-LABEL: combine_undef_input_test17: 2312; AVX: # %bb.0: 2313; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2314; AVX-NEXT: retq 2315 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7> 2316 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1> 2317 ret <4 x float> %2 2318} 2319 2320define <4 x float> @combine_undef_input_test18(<4 x float> %a) { 2321; SSE2-LABEL: combine_undef_input_test18: 2322; SSE2: # %bb.0: 2323; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0] 2324; SSE2-NEXT: retq 2325; 2326; SSSE3-LABEL: combine_undef_input_test18: 2327; SSSE3: # %bb.0: 2328; SSSE3-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2329; SSSE3-NEXT: retq 2330; 2331; SSE41-LABEL: combine_undef_input_test18: 2332; SSE41: # %bb.0: 2333; SSE41-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0] 2334; SSE41-NEXT: retq 2335; 2336; AVX-LABEL: combine_undef_input_test18: 2337; AVX: # %bb.0: 2338; AVX-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 2339; AVX-NEXT: retq 2340 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7> 2341 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 0, i32 5> 2342 ret <4 x float> %2 2343} 2344 2345define <4 x float> @combine_undef_input_test19(<4 x float> %a) { 2346; SSE-LABEL: combine_undef_input_test19: 2347; SSE: # %bb.0: 2348; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1] 2349; SSE-NEXT: retq 2350; 2351; AVX-LABEL: combine_undef_input_test19: 2352; AVX: # %bb.0: 2353; AVX-NEXT: vpermilpd {{.*#+}} xmm0 = xmm0[1,1] 2354; AVX-NEXT: retq 2355 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5> 2356 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5> 2357 ret <4 x float> %2 2358} 2359 2360define <4 x float> @combine_undef_input_test20(<4 x float> %a) { 2361; CHECK-LABEL: combine_undef_input_test20: 2362; CHECK: # %bb.0: 2363; CHECK-NEXT: retq 2364 %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3> 2365 %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2366 ret <4 x float> %2 2367} 2368 2369; These tests are designed to test the ability to combine away unnecessary 2370; operations feeding into a shuffle. The AVX cases are the important ones as 2371; they leverage operations which cannot be done naturally on the entire vector 2372; and thus are decomposed into multiple smaller operations. 2373 2374define <8 x i32> @combine_unneeded_subvector1(<8 x i32> %a) { 2375; SSE-LABEL: combine_unneeded_subvector1: 2376; SSE: # %bb.0: 2377; SSE-NEXT: paddd {{.*}}(%rip), %xmm1 2378; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,2,1,0] 2379; SSE-NEXT: movdqa %xmm0, %xmm1 2380; SSE-NEXT: retq 2381; 2382; AVX1-LABEL: combine_unneeded_subvector1: 2383; AVX1: # %bb.0: 2384; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 2385; AVX1-NEXT: vpaddd {{.*}}(%rip), %xmm0, %xmm0 2386; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 2387; AVX1-NEXT: vpermilps {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2388; AVX1-NEXT: vperm2f128 {{.*#+}} ymm0 = ymm0[2,3,2,3] 2389; AVX1-NEXT: retq 2390; 2391; AVX2-SLOW-LABEL: combine_unneeded_subvector1: 2392; AVX2-SLOW: # %bb.0: 2393; AVX2-SLOW-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 2394; AVX2-SLOW-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2395; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[2,3,2,3] 2396; AVX2-SLOW-NEXT: retq 2397; 2398; AVX2-FAST-LABEL: combine_unneeded_subvector1: 2399; AVX2-FAST: # %bb.0: 2400; AVX2-FAST-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 2401; AVX2-FAST-NEXT: vbroadcasti128 {{.*#+}} ymm1 = [7,6,5,4,7,6,5,4] 2402; AVX2-FAST-NEXT: # ymm1 = mem[0,1,0,1] 2403; AVX2-FAST-NEXT: vpermd %ymm0, %ymm1, %ymm0 2404; AVX2-FAST-NEXT: retq 2405 %b = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8> 2406 %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> 2407 ret <8 x i32> %c 2408} 2409 2410define <8 x i32> @combine_unneeded_subvector2(<8 x i32> %a, <8 x i32> %b) { 2411; SSE-LABEL: combine_unneeded_subvector2: 2412; SSE: # %bb.0: 2413; SSE-NEXT: paddd {{.*}}(%rip), %xmm1 2414; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm3[3,2,1,0] 2415; SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm1[3,2,1,0] 2416; SSE-NEXT: retq 2417; 2418; AVX1-LABEL: combine_unneeded_subvector2: 2419; AVX1: # %bb.0: 2420; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 2421; AVX1-NEXT: vpaddd {{.*}}(%rip), %xmm0, %xmm0 2422; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 2423; AVX1-NEXT: vperm2f128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3] 2424; AVX1-NEXT: vpermilps {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2425; AVX1-NEXT: retq 2426; 2427; AVX2-LABEL: combine_unneeded_subvector2: 2428; AVX2: # %bb.0: 2429; AVX2-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 2430; AVX2-NEXT: vperm2i128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3] 2431; AVX2-NEXT: vpshufd {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4] 2432; AVX2-NEXT: retq 2433 %c = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8> 2434 %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> 2435 ret <8 x i32> %d 2436} 2437 2438define <4 x float> @combine_insertps1(<4 x float> %a, <4 x float> %b) { 2439; SSE2-LABEL: combine_insertps1: 2440; SSE2: # %bb.0: 2441; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0] 2442; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3] 2443; SSE2-NEXT: movaps %xmm1, %xmm0 2444; SSE2-NEXT: retq 2445; 2446; SSSE3-LABEL: combine_insertps1: 2447; SSSE3: # %bb.0: 2448; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0] 2449; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3] 2450; SSSE3-NEXT: movaps %xmm1, %xmm0 2451; SSSE3-NEXT: retq 2452; 2453; SSE41-LABEL: combine_insertps1: 2454; SSE41: # %bb.0: 2455; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3] 2456; SSE41-NEXT: retq 2457; 2458; AVX-LABEL: combine_insertps1: 2459; AVX: # %bb.0: 2460; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3] 2461; AVX-NEXT: retq 2462 2463 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 6, i32 2, i32 4> 2464 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 5, i32 1, i32 6, i32 3> 2465 ret <4 x float> %d 2466} 2467 2468define <4 x float> @combine_insertps2(<4 x float> %a, <4 x float> %b) { 2469; SSE2-LABEL: combine_insertps2: 2470; SSE2: # %bb.0: 2471; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0] 2472; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3] 2473; SSE2-NEXT: movaps %xmm1, %xmm0 2474; SSE2-NEXT: retq 2475; 2476; SSSE3-LABEL: combine_insertps2: 2477; SSSE3: # %bb.0: 2478; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0] 2479; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3] 2480; SSSE3-NEXT: movaps %xmm1, %xmm0 2481; SSSE3-NEXT: retq 2482; 2483; SSE41-LABEL: combine_insertps2: 2484; SSE41: # %bb.0: 2485; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3] 2486; SSE41-NEXT: retq 2487; 2488; AVX-LABEL: combine_insertps2: 2489; AVX: # %bb.0: 2490; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3] 2491; AVX-NEXT: retq 2492 2493 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 1, i32 6, i32 7> 2494 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 4, i32 6, i32 2, i32 3> 2495 ret <4 x float> %d 2496} 2497 2498define <4 x float> @combine_insertps3(<4 x float> %a, <4 x float> %b) { 2499; SSE2-LABEL: combine_insertps3: 2500; SSE2: # %bb.0: 2501; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 2502; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2] 2503; SSE2-NEXT: retq 2504; 2505; SSSE3-LABEL: combine_insertps3: 2506; SSSE3: # %bb.0: 2507; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0] 2508; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2] 2509; SSSE3-NEXT: retq 2510; 2511; SSE41-LABEL: combine_insertps3: 2512; SSE41: # %bb.0: 2513; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] 2514; SSE41-NEXT: retq 2515; 2516; AVX-LABEL: combine_insertps3: 2517; AVX: # %bb.0: 2518; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3] 2519; AVX-NEXT: retq 2520 2521 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5> 2522 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 5, i32 3> 2523 ret <4 x float> %d 2524} 2525 2526define <4 x float> @combine_insertps4(<4 x float> %a, <4 x float> %b) { 2527; SSE2-LABEL: combine_insertps4: 2528; SSE2: # %bb.0: 2529; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0] 2530; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0] 2531; SSE2-NEXT: retq 2532; 2533; SSSE3-LABEL: combine_insertps4: 2534; SSSE3: # %bb.0: 2535; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0] 2536; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0] 2537; SSSE3-NEXT: retq 2538; 2539; SSE41-LABEL: combine_insertps4: 2540; SSE41: # %bb.0: 2541; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] 2542; SSE41-NEXT: retq 2543; 2544; AVX-LABEL: combine_insertps4: 2545; AVX: # %bb.0: 2546; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0] 2547; AVX-NEXT: retq 2548 2549 %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5> 2550 %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 6, i32 5> 2551 ret <4 x float> %d 2552} 2553 2554define void @combine_scalar_load_with_blend_with_zero(double* %a0, <4 x float>* %a1) { 2555; SSE-LABEL: combine_scalar_load_with_blend_with_zero: 2556; SSE: # %bb.0: 2557; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 2558; SSE-NEXT: movaps %xmm0, (%rsi) 2559; SSE-NEXT: retq 2560; 2561; AVX-LABEL: combine_scalar_load_with_blend_with_zero: 2562; AVX: # %bb.0: 2563; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 2564; AVX-NEXT: vmovaps %xmm0, (%rsi) 2565; AVX-NEXT: retq 2566 %1 = load double, double* %a0, align 8 2567 %2 = insertelement <2 x double> undef, double %1, i32 0 2568 %3 = insertelement <2 x double> %2, double 0.000000e+00, i32 1 2569 %4 = bitcast <2 x double> %3 to <4 x float> 2570 %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> 2571 store <4 x float> %5, <4 x float>* %a1, align 16 2572 ret void 2573} 2574 2575; PR30371 2576define <4 x float> @combine_constant_insertion_v4f32(float %f) { 2577; SSE2-LABEL: combine_constant_insertion_v4f32: 2578; SSE2: # %bb.0: 2579; SSE2-NEXT: movaps {{.*#+}} xmm1 = <u,4.0E+0,5.0E+0,3.0E+0> 2580; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 2581; SSE2-NEXT: movaps %xmm1, %xmm0 2582; SSE2-NEXT: retq 2583; 2584; SSSE3-LABEL: combine_constant_insertion_v4f32: 2585; SSSE3: # %bb.0: 2586; SSSE3-NEXT: movaps {{.*#+}} xmm1 = <u,4.0E+0,5.0E+0,3.0E+0> 2587; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 2588; SSSE3-NEXT: movaps %xmm1, %xmm0 2589; SSSE3-NEXT: retq 2590; 2591; SSE41-LABEL: combine_constant_insertion_v4f32: 2592; SSE41: # %bb.0: 2593; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],mem[1,2,3] 2594; SSE41-NEXT: retq 2595; 2596; AVX-LABEL: combine_constant_insertion_v4f32: 2597; AVX: # %bb.0: 2598; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],mem[1,2,3] 2599; AVX-NEXT: retq 2600 %a0 = insertelement <4 x float> undef, float %f, i32 0 2601 %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> 2602 ret <4 x float> %ret 2603} 2604 2605define <4 x i32> @combine_constant_insertion_v4i32(i32 %f) { 2606; SSE2-LABEL: combine_constant_insertion_v4i32: 2607; SSE2: # %bb.0: 2608; SSE2-NEXT: movd %edi, %xmm1 2609; SSE2-NEXT: movaps {{.*#+}} xmm0 = <u,4,5,30> 2610; SSE2-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 2611; SSE2-NEXT: retq 2612; 2613; SSSE3-LABEL: combine_constant_insertion_v4i32: 2614; SSSE3: # %bb.0: 2615; SSSE3-NEXT: movd %edi, %xmm1 2616; SSSE3-NEXT: movaps {{.*#+}} xmm0 = <u,4,5,30> 2617; SSSE3-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 2618; SSSE3-NEXT: retq 2619; 2620; SSE41-LABEL: combine_constant_insertion_v4i32: 2621; SSE41: # %bb.0: 2622; SSE41-NEXT: movdqa {{.*#+}} xmm0 = <u,4,5,30> 2623; SSE41-NEXT: pinsrd $0, %edi, %xmm0 2624; SSE41-NEXT: retq 2625; 2626; AVX-LABEL: combine_constant_insertion_v4i32: 2627; AVX: # %bb.0: 2628; AVX-NEXT: vmovdqa {{.*#+}} xmm0 = <u,4,5,30> 2629; AVX-NEXT: vpinsrd $0, %edi, %xmm0, %xmm0 2630; AVX-NEXT: retq 2631 %a0 = insertelement <4 x i32> undef, i32 %f, i32 0 2632 %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> 2633 ret <4 x i32> %ret 2634} 2635 2636define <4 x float> @PR22377(<4 x float> %a, <4 x float> %b) { 2637; SSE2-LABEL: PR22377: 2638; SSE2: # %bb.0: # %entry 2639; SSE2-NEXT: movaps %xmm0, %xmm1 2640; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,3],xmm0[2,3] 2641; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,0,2] 2642; SSE2-NEXT: addps %xmm0, %xmm1 2643; SSE2-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 2644; SSE2-NEXT: retq 2645; 2646; SSSE3-LABEL: PR22377: 2647; SSSE3: # %bb.0: # %entry 2648; SSSE3-NEXT: movaps %xmm0, %xmm1 2649; SSSE3-NEXT: haddps %xmm0, %xmm1 2650; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,1] 2651; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3] 2652; SSSE3-NEXT: retq 2653; 2654; SSE41-LABEL: PR22377: 2655; SSE41: # %bb.0: # %entry 2656; SSE41-NEXT: movaps %xmm0, %xmm1 2657; SSE41-NEXT: haddps %xmm0, %xmm1 2658; SSE41-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,1] 2659; SSE41-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3] 2660; SSE41-NEXT: retq 2661; 2662; AVX-LABEL: PR22377: 2663; AVX: # %bb.0: # %entry 2664; AVX-NEXT: vhaddps %xmm0, %xmm0, %xmm1 2665; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,1] 2666; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[0,2,1,3] 2667; AVX-NEXT: retq 2668entry: 2669 %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 1, i32 3, i32 1, i32 3> 2670 %s2 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2> 2671 %r2 = fadd <4 x float> %s1, %s2 2672 %s3 = shufflevector <4 x float> %s2, <4 x float> %r2, <4 x i32> <i32 0, i32 4, i32 1, i32 5> 2673 ret <4 x float> %s3 2674} 2675 2676define <4 x float> @PR22390(<4 x float> %a, <4 x float> %b) { 2677; SSE2-LABEL: PR22390: 2678; SSE2: # %bb.0: # %entry 2679; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2680; SSE2-NEXT: movaps %xmm0, %xmm2 2681; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3] 2682; SSE2-NEXT: addps %xmm0, %xmm2 2683; SSE2-NEXT: movaps %xmm2, %xmm0 2684; SSE2-NEXT: retq 2685; 2686; SSSE3-LABEL: PR22390: 2687; SSSE3: # %bb.0: # %entry 2688; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2689; SSSE3-NEXT: movaps %xmm0, %xmm2 2690; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3] 2691; SSSE3-NEXT: addps %xmm0, %xmm2 2692; SSSE3-NEXT: movaps %xmm2, %xmm0 2693; SSSE3-NEXT: retq 2694; 2695; SSE41-LABEL: PR22390: 2696; SSE41: # %bb.0: # %entry 2697; SSE41-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2698; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3] 2699; SSE41-NEXT: addps %xmm1, %xmm0 2700; SSE41-NEXT: retq 2701; 2702; AVX-LABEL: PR22390: 2703; AVX: # %bb.0: # %entry 2704; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[3,0,1,2] 2705; AVX-NEXT: vblendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3] 2706; AVX-NEXT: vaddps %xmm1, %xmm0, %xmm0 2707; AVX-NEXT: retq 2708entry: 2709 %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 3, i32 0, i32 1, i32 2> 2710 %s2 = shufflevector <4 x float> %s1, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 2, i32 3> 2711 %r2 = fadd <4 x float> %s1, %s2 2712 ret <4 x float> %r2 2713} 2714 2715define <8 x float> @PR22412(<8 x float> %a, <8 x float> %b) { 2716; SSE-LABEL: PR22412: 2717; SSE: # %bb.0: # %entry 2718; SSE-NEXT: movaps %xmm3, %xmm1 2719; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,0],xmm3[3,2] 2720; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,0],xmm2[3,2] 2721; SSE-NEXT: retq 2722; 2723; AVX1-LABEL: PR22412: 2724; AVX1: # %bb.0: # %entry 2725; AVX1-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm1[2,3,0,1] 2726; AVX1-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0,1,2,3],ymm1[4,5,6,7] 2727; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,0],ymm2[3,2],ymm0[5,4],ymm2[7,6] 2728; AVX1-NEXT: retq 2729; 2730; AVX2-LABEL: PR22412: 2731; AVX2: # %bb.0: # %entry 2732; AVX2-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0,1,2,3],ymm1[4,5,6,7] 2733; AVX2-NEXT: vpermpd {{.*#+}} ymm1 = ymm1[2,3,0,1] 2734; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,0],ymm1[3,2],ymm0[5,4],ymm1[7,6] 2735; AVX2-NEXT: retq 2736entry: 2737 %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> 2738 %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> 2739 ret <8 x float> %s2 2740} 2741 2742define <4 x float> @PR30264(<4 x float> %x) { 2743; SSE2-LABEL: PR30264: 2744; SSE2: # %bb.0: 2745; SSE2-NEXT: xorps %xmm1, %xmm1 2746; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,0],xmm0[0,0] 2747; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],mem[2,3] 2748; SSE2-NEXT: movaps %xmm1, %xmm0 2749; SSE2-NEXT: retq 2750; 2751; SSSE3-LABEL: PR30264: 2752; SSSE3: # %bb.0: 2753; SSSE3-NEXT: xorps %xmm1, %xmm1 2754; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,0],xmm0[0,0] 2755; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],mem[2,3] 2756; SSSE3-NEXT: movaps %xmm1, %xmm0 2757; SSSE3-NEXT: retq 2758; 2759; SSE41-LABEL: PR30264: 2760; SSE41: # %bb.0: 2761; SSE41-NEXT: movaps {{.*#+}} xmm1 = <u,u,4.0E+0,1.0E+0> 2762; SSE41-NEXT: insertps {{.*#+}} xmm1 = xmm0[0],zero,xmm1[2,3] 2763; SSE41-NEXT: movaps %xmm1, %xmm0 2764; SSE41-NEXT: retq 2765; 2766; AVX-LABEL: PR30264: 2767; AVX: # %bb.0: 2768; AVX-NEXT: vmovaps {{.*#+}} xmm1 = <u,u,4.0E+0,1.0E+0> 2769; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],zero,xmm1[2,3] 2770; AVX-NEXT: retq 2771 %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> 2772 %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> 2773 ret <4 x float> %shuf2 2774} 2775 2776define <8 x i16> @PR39549(<16 x i8> %x) { 2777; SSE-LABEL: PR39549: 2778; SSE: # %bb.0: 2779; SSE-NEXT: punpckhbw {{.*#+}} xmm0 = xmm0[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] 2780; SSE-NEXT: psraw $8, %xmm0 2781; SSE-NEXT: retq 2782; 2783; AVX-LABEL: PR39549: 2784; AVX: # %bb.0: 2785; AVX-NEXT: vpunpckhbw {{.*#+}} xmm0 = xmm0[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] 2786; AVX-NEXT: vpsraw $8, %xmm0, %xmm0 2787; AVX-NEXT: retq 2788 %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> 2789 %b = bitcast <16 x i8> %a to <8 x i16> 2790 %c = shl <8 x i16> %b, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8> 2791 %d = ashr <8 x i16> %c, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8> 2792 ret <8 x i16> %d 2793} 2794 2795define <4 x i32> @PR41545(<4 x i32> %a0, <16 x i8> %a1) { 2796; SSE-LABEL: PR41545: 2797; SSE: # %bb.0: 2798; SSE-NEXT: paddd %xmm1, %xmm0 2799; SSE-NEXT: retq 2800; 2801; AVX-LABEL: PR41545: 2802; AVX: # %bb.0: 2803; AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 2804; AVX-NEXT: retq 2805 %1 = shufflevector <16 x i8> %a1, <16 x i8> undef, <4 x i32> <i32 0, i32 4, i32 8, i32 12> 2806 %2 = shufflevector <16 x i8> %a1, <16 x i8> undef, <4 x i32> <i32 1, i32 5, i32 9, i32 13> 2807 %3 = shufflevector <16 x i8> %a1, <16 x i8> undef, <4 x i32> <i32 2, i32 6, i32 10, i32 14> 2808 %4 = shufflevector <16 x i8> %a1, <16 x i8> undef, <4 x i32> <i32 3, i32 7, i32 11, i32 15> 2809 %5 = zext <4 x i8> %1 to <4 x i32> 2810 %6 = zext <4 x i8> %2 to <4 x i32> 2811 %7 = zext <4 x i8> %3 to <4 x i32> 2812 %8 = zext <4 x i8> %4 to <4 x i32> 2813 %9 = shl <4 x i32> %6, <i32 8, i32 8, i32 8, i32 8> 2814 %10 = shl <4 x i32> %7, <i32 16, i32 16, i32 16, i32 16> 2815 %11 = shl <4 x i32> %8, <i32 24, i32 24, i32 24, i32 24> 2816 %12 = or <4 x i32> %5, %9 2817 %13 = or <4 x i32> %12, %10 2818 %14 = or <4 x i32> %13, %11 2819 %15 = add <4 x i32> %a0, %14 2820 ret <4 x i32> %15 2821} 2822 2823define <8 x i16> @shuffle_extract_insert(<8 x i16> %a) { 2824; SSE-LABEL: shuffle_extract_insert: 2825; SSE: # %bb.0: 2826; SSE-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[2,1,0,3,4,5,6,7] 2827; SSE-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,6,5,4,7] 2828; SSE-NEXT: retq 2829; 2830; AVX1-LABEL: shuffle_extract_insert: 2831; AVX1: # %bb.0: 2832; AVX1-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[2,1,0,3,4,5,6,7] 2833; AVX1-NEXT: vpshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,6,5,4,7] 2834; AVX1-NEXT: retq 2835; 2836; AVX2-SLOW-LABEL: shuffle_extract_insert: 2837; AVX2-SLOW: # %bb.0: 2838; AVX2-SLOW-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[2,1,0,3,4,5,6,7] 2839; AVX2-SLOW-NEXT: vpshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,6,5,4,7] 2840; AVX2-SLOW-NEXT: retq 2841; 2842; AVX2-FAST-LABEL: shuffle_extract_insert: 2843; AVX2-FAST: # %bb.0: 2844; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[4,5,2,3,0,1,6,7,12,13,10,11,8,9,14,15] 2845; AVX2-FAST-NEXT: retq 2846 %a0 = extractelement <8 x i16> %a, i32 0 2847 %a1 = extractelement <8 x i16> %a, i32 1 2848 %a3 = extractelement <8 x i16> %a, i32 3 2849 %a4 = extractelement <8 x i16> %a, i32 4 2850 %a5 = extractelement <8 x i16> %a, i32 5 2851 %a6 = extractelement <8 x i16> %a, i32 6 2852 %a7 = extractelement <8 x i16> %a, i32 7 2853 %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> 2854 %2 = insertelement <8 x i16> %1, i16 %a1, i32 1 2855 %3 = insertelement <8 x i16> %2, i16 %a0, i32 2 2856 %4 = insertelement <8 x i16> %3, i16 %a3, i32 3 2857 %5 = insertelement <8 x i16> %4, i16 %a6, i32 4 2858 %6 = insertelement <8 x i16> %5, i16 %a5, i32 5 2859 %7 = insertelement <8 x i16> %6, i16 %a4, i32 6 2860 %8 = insertelement <8 x i16> %7, i16 %a7, i32 7 2861 ret <8 x i16> %8 2862} 2863 2864define <8 x i16> @shuffle_extract_insert_double(<8 x i16> %a, <8 x i16> %b) { 2865; SSE2-LABEL: shuffle_extract_insert_double: 2866; SSE2: # %bb.0: 2867; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = xmm1[0,3,2,3,4,5,6,7] 2868; SSE2-NEXT: pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,7,5,6,7] 2869; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] 2870; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = xmm1[0,1,3,2,4,5,6,7] 2871; SSE2-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7] 2872; SSE2-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7] 2873; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 2874; SSE2-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[1,0,3,2,4,5,6,7] 2875; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3] 2876; SSE2-NEXT: retq 2877; 2878; SSSE3-LABEL: shuffle_extract_insert_double: 2879; SSSE3: # %bb.0: 2880; SSSE3-NEXT: pshufb {{.*#+}} xmm1 = xmm1[0,1,6,7,10,11,14,15,14,15,10,11,12,13,14,15] 2881; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[4,5,0,1,12,13,8,9,8,9,12,13,12,13,14,15] 2882; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3] 2883; SSSE3-NEXT: retq 2884; 2885; SSE41-LABEL: shuffle_extract_insert_double: 2886; SSE41: # %bb.0: 2887; SSE41-NEXT: pshufb {{.*#+}} xmm1 = xmm1[0,1,6,7,10,11,14,15,14,15,10,11,12,13,14,15] 2888; SSE41-NEXT: pshufb {{.*#+}} xmm0 = xmm0[4,5,0,1,12,13,8,9,8,9,12,13,12,13,14,15] 2889; SSE41-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3] 2890; SSE41-NEXT: retq 2891; 2892; AVX-LABEL: shuffle_extract_insert_double: 2893; AVX: # %bb.0: 2894; AVX-NEXT: vpshufb {{.*#+}} xmm1 = xmm1[0,1,6,7,10,11,14,15,14,15,10,11,12,13,14,15] 2895; AVX-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[4,5,0,1,12,13,8,9,8,9,12,13,12,13,14,15] 2896; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3] 2897; AVX-NEXT: retq 2898 %a0 = extractelement <8 x i16> %a, i32 0 2899 %a4 = extractelement <8 x i16> %a, i32 4 2900 %a6 = extractelement <8 x i16> %a, i32 6 2901 %b11 = extractelement <8 x i16> %b, i32 3 2902 %b13 = extractelement <8 x i16> %b, i32 5 2903 %b15 = extractelement <8 x i16> %b, i32 7 2904 %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> 2905 %2 = insertelement <8 x i16> %1, i16 %a0, i32 2 2906 %3 = insertelement <8 x i16> %2, i16 %b11, i32 3 2907 %4 = insertelement <8 x i16> %3, i16 %a6, i32 4 2908 %5 = insertelement <8 x i16> %4, i16 %b13, i32 5 2909 %6 = insertelement <8 x i16> %5, i16 %a4, i32 6 2910 %7 = insertelement <8 x i16> %6, i16 %b15, i32 7 2911 ret <8 x i16> %7 2912} 2913 2914define <8 x i16> @shuffle_extract_concat_insert(<4 x i16> %lhsa, <4 x i16> %rhsa, <8 x i16> %b) { 2915; SSE2-LABEL: shuffle_extract_concat_insert: 2916; SSE2: # %bb.0: 2917; SSE2-NEXT: movd %xmm1, %eax 2918; SSE2-NEXT: pextrw $2, %xmm1, %ecx 2919; SSE2-NEXT: pextrw $5, %xmm2, %edx 2920; SSE2-NEXT: pextrw $7, %xmm2, %esi 2921; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] 2922; SSE2-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,7,6,7] 2923; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 2924; SSE2-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[2,1,0,3,4,5,6,7] 2925; SSE2-NEXT: pinsrw $4, %ecx, %xmm0 2926; SSE2-NEXT: pinsrw $5, %edx, %xmm0 2927; SSE2-NEXT: pinsrw $6, %eax, %xmm0 2928; SSE2-NEXT: pinsrw $7, %esi, %xmm0 2929; SSE2-NEXT: retq 2930; 2931; SSSE3-LABEL: shuffle_extract_concat_insert: 2932; SSSE3: # %bb.0: 2933; SSSE3-NEXT: pextrw $2, %xmm1, %eax 2934; SSSE3-NEXT: pextrw $5, %xmm2, %ecx 2935; SSSE3-NEXT: pextrw $7, %xmm2, %edx 2936; SSSE3-NEXT: movd %xmm1, %esi 2937; SSSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] 2938; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[8,9,2,3,0,1,14,15,8,9,14,15,12,13,14,15] 2939; SSSE3-NEXT: pinsrw $4, %eax, %xmm0 2940; SSSE3-NEXT: pinsrw $5, %ecx, %xmm0 2941; SSSE3-NEXT: pinsrw $6, %esi, %xmm0 2942; SSSE3-NEXT: pinsrw $7, %edx, %xmm0 2943; SSSE3-NEXT: retq 2944; 2945; SSE41-LABEL: shuffle_extract_concat_insert: 2946; SSE41: # %bb.0: 2947; SSE41-NEXT: movd %xmm1, %eax 2948; SSE41-NEXT: pextrw $2, %xmm1, %ecx 2949; SSE41-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] 2950; SSE41-NEXT: pshufb {{.*#+}} xmm0 = xmm0[8,9,2,3,0,1,14,15,8,9,14,15,12,13,14,15] 2951; SSE41-NEXT: pinsrw $4, %ecx, %xmm0 2952; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3,4],xmm2[5],xmm0[6,7] 2953; SSE41-NEXT: pinsrw $6, %eax, %xmm0 2954; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,5,6],xmm2[7] 2955; SSE41-NEXT: retq 2956; 2957; AVX-LABEL: shuffle_extract_concat_insert: 2958; AVX: # %bb.0: 2959; AVX-NEXT: vmovd %xmm1, %eax 2960; AVX-NEXT: vpextrw $2, %xmm1, %ecx 2961; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] 2962; AVX-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[8,9,2,3,0,1,14,15,8,9,14,15,12,13,14,15] 2963; AVX-NEXT: vpinsrw $4, %ecx, %xmm0, %xmm0 2964; AVX-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3,4],xmm2[5],xmm0[6,7] 2965; AVX-NEXT: vpinsrw $6, %eax, %xmm0, %xmm0 2966; AVX-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,5,6],xmm2[7] 2967; AVX-NEXT: retq 2968 %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> 2969 %a0 = extractelement <8 x i16> %a, i32 0 2970 %a4 = extractelement <8 x i16> %a, i32 4 2971 %a6 = extractelement <8 x i16> %a, i32 6 2972 %b11 = extractelement <8 x i16> %b, i32 3 2973 %b13 = extractelement <8 x i16> %b, i32 5 2974 %b15 = extractelement <8 x i16> %b, i32 7 2975 %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> 2976 %2 = insertelement <8 x i16> %1, i16 %a0, i32 2 2977 %3 = insertelement <8 x i16> %2, i16 %b11, i32 3 2978 %4 = insertelement <8 x i16> %3, i16 %a6, i32 4 2979 %5 = insertelement <8 x i16> %4, i16 %b13, i32 5 2980 %6 = insertelement <8 x i16> %5, i16 %a4, i32 6 2981 %7 = insertelement <8 x i16> %6, i16 %b15, i32 7 2982 ret <8 x i16> %7 2983} 2984 2985define void @PR43024() { 2986; SSE2-LABEL: PR43024: 2987; SSE2: # %bb.0: 2988; SSE2-NEXT: movaps {{.*#+}} xmm0 = [NaN,NaN,0.0E+0,0.0E+0] 2989; SSE2-NEXT: movaps %xmm0, (%rax) 2990; SSE2-NEXT: movaps %xmm0, %xmm1 2991; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,1],xmm0[2,3] 2992; SSE2-NEXT: addss %xmm0, %xmm1 2993; SSE2-NEXT: xorps %xmm0, %xmm0 2994; SSE2-NEXT: addss %xmm0, %xmm1 2995; SSE2-NEXT: addss %xmm0, %xmm1 2996; SSE2-NEXT: movss %xmm1, (%rax) 2997; SSE2-NEXT: retq 2998; 2999; SSSE3-LABEL: PR43024: 3000; SSSE3: # %bb.0: 3001; SSSE3-NEXT: movaps {{.*#+}} xmm0 = [NaN,NaN,0.0E+0,0.0E+0] 3002; SSSE3-NEXT: movaps %xmm0, (%rax) 3003; SSSE3-NEXT: movshdup {{.*#+}} xmm1 = xmm0[1,1,3,3] 3004; SSSE3-NEXT: addss %xmm0, %xmm1 3005; SSSE3-NEXT: xorps %xmm0, %xmm0 3006; SSSE3-NEXT: addss %xmm0, %xmm1 3007; SSSE3-NEXT: addss %xmm0, %xmm1 3008; SSSE3-NEXT: movss %xmm1, (%rax) 3009; SSSE3-NEXT: retq 3010; 3011; SSE41-LABEL: PR43024: 3012; SSE41: # %bb.0: 3013; SSE41-NEXT: movaps {{.*#+}} xmm0 = [NaN,NaN,0.0E+0,0.0E+0] 3014; SSE41-NEXT: movaps %xmm0, (%rax) 3015; SSE41-NEXT: movshdup {{.*#+}} xmm1 = xmm0[1,1,3,3] 3016; SSE41-NEXT: addss %xmm0, %xmm1 3017; SSE41-NEXT: xorps %xmm0, %xmm0 3018; SSE41-NEXT: addss %xmm0, %xmm1 3019; SSE41-NEXT: addss %xmm0, %xmm1 3020; SSE41-NEXT: movss %xmm1, (%rax) 3021; SSE41-NEXT: retq 3022; 3023; AVX-LABEL: PR43024: 3024; AVX: # %bb.0: 3025; AVX-NEXT: vmovaps {{.*#+}} xmm0 = [NaN,NaN,0.0E+0,0.0E+0] 3026; AVX-NEXT: vmovaps %xmm0, (%rax) 3027; AVX-NEXT: vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3] 3028; AVX-NEXT: vaddss %xmm1, %xmm0, %xmm0 3029; AVX-NEXT: vxorps %xmm1, %xmm1, %xmm1 3030; AVX-NEXT: vaddss %xmm1, %xmm0, %xmm0 3031; AVX-NEXT: vaddss %xmm1, %xmm0, %xmm0 3032; AVX-NEXT: vmovss %xmm0, (%rax) 3033; AVX-NEXT: retq 3034 store <4 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x0, float 0x0>, <4 x float>* undef, align 16 3035 %1 = load <4 x float>, <4 x float>* undef, align 16 3036 %2 = fmul <4 x float> %1, <float 0x0, float 0x0, float 0x0, float 0x0> 3037 %3 = shufflevector <4 x float> %2, <4 x float> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 3038 %4 = fadd <4 x float> %2, %3 3039 %5 = fadd <4 x float> zeroinitializer, %4 3040 %6 = shufflevector <4 x float> %2, <4 x float> undef, <4 x i32> <i32 3, i32 undef, i32 undef, i32 undef> 3041 %7 = fadd <4 x float> %6, %5 3042 %8 = extractelement <4 x float> %7, i32 0 3043 store float %8, float* undef, align 8 3044 ret void 3045} 3046