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