1; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=SSE2 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=SSSE3 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE41 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2 6 7; AVX128 tests: 8 9define <4 x float> @vsel_float(<4 x float> %v1, <4 x float> %v2) { 10; SSE2-LABEL: vsel_float: 11; SSE2: # BB#0: # %entry 12; SSE2-NEXT: andps {{.*}}(%rip), %xmm1 13; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 14; SSE2-NEXT: orps %xmm1, %xmm0 15; SSE2-NEXT: retq 16; 17; SSSE3-LABEL: vsel_float: 18; SSSE3: # BB#0: # %entry 19; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1 20; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 21; SSSE3-NEXT: orps %xmm1, %xmm0 22; SSSE3-NEXT: retq 23; 24; SSE41-LABEL: vsel_float: 25; SSE41: # BB#0: # %entry 26; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 27; SSE41-NEXT: retq 28; 29; AVX-LABEL: vsel_float: 30; AVX: # BB#0: # %entry 31; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 32; AVX-NEXT: retq 33entry: 34 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x float> %v1, <4 x float> %v2 35 ret <4 x float> %vsel 36} 37 38define <4 x float> @vsel_float2(<4 x float> %v1, <4 x float> %v2) { 39; SSE2-LABEL: vsel_float2: 40; SSE2: # BB#0: # %entry 41; SSE2-NEXT: movss %xmm0, %xmm1 42; SSE2-NEXT: movaps %xmm1, %xmm0 43; SSE2-NEXT: retq 44; 45; SSSE3-LABEL: vsel_float2: 46; SSSE3: # BB#0: # %entry 47; SSSE3-NEXT: movss %xmm0, %xmm1 48; SSSE3-NEXT: movaps %xmm1, %xmm0 49; SSSE3-NEXT: retq 50; 51; SSE41-LABEL: vsel_float2: 52; SSE41: # BB#0: # %entry 53; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 54; SSE41-NEXT: retq 55; 56; AVX-LABEL: vsel_float2: 57; AVX: # BB#0: # %entry 58; AVX-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 59; AVX-NEXT: retq 60entry: 61 %vsel = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %v1, <4 x float> %v2 62 ret <4 x float> %vsel 63} 64 65define <4 x i8> @vsel_4xi8(<4 x i8> %v1, <4 x i8> %v2) { 66; SSE2-LABEL: vsel_4xi8: 67; SSE2: # BB#0: # %entry 68; SSE2-NEXT: andps {{.*}}(%rip), %xmm1 69; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 70; SSE2-NEXT: orps %xmm1, %xmm0 71; SSE2-NEXT: retq 72; 73; SSSE3-LABEL: vsel_4xi8: 74; SSSE3: # BB#0: # %entry 75; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1 76; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 77; SSSE3-NEXT: orps %xmm1, %xmm0 78; SSSE3-NEXT: retq 79; 80; SSE41-LABEL: vsel_4xi8: 81; SSE41: # BB#0: # %entry 82; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5],xmm0[6,7] 83; SSE41-NEXT: retq 84; 85; AVX1-LABEL: vsel_4xi8: 86; AVX1: # BB#0: # %entry 87; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5],xmm0[6,7] 88; AVX1-NEXT: retq 89; 90; AVX2-LABEL: vsel_4xi8: 91; AVX2: # BB#0: # %entry 92; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2],xmm0[3] 93; AVX2-NEXT: retq 94entry: 95 %vsel = select <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x i8> %v1, <4 x i8> %v2 96 ret <4 x i8> %vsel 97} 98 99define <4 x i16> @vsel_4xi16(<4 x i16> %v1, <4 x i16> %v2) { 100; SSE2-LABEL: vsel_4xi16: 101; SSE2: # BB#0: # %entry 102; SSE2-NEXT: andps {{.*}}(%rip), %xmm1 103; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 104; SSE2-NEXT: orps %xmm1, %xmm0 105; SSE2-NEXT: retq 106; 107; SSSE3-LABEL: vsel_4xi16: 108; SSSE3: # BB#0: # %entry 109; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1 110; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 111; SSSE3-NEXT: orps %xmm1, %xmm0 112; SSSE3-NEXT: retq 113; 114; SSE41-LABEL: vsel_4xi16: 115; SSE41: # BB#0: # %entry 116; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 117; SSE41-NEXT: retq 118; 119; AVX1-LABEL: vsel_4xi16: 120; AVX1: # BB#0: # %entry 121; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7] 122; AVX1-NEXT: retq 123; 124; AVX2-LABEL: vsel_4xi16: 125; AVX2: # BB#0: # %entry 126; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3] 127; AVX2-NEXT: retq 128entry: 129 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x i16> %v1, <4 x i16> %v2 130 ret <4 x i16> %vsel 131} 132 133define <4 x i32> @vsel_i32(<4 x i32> %v1, <4 x i32> %v2) { 134; SSE2-LABEL: vsel_i32: 135; SSE2: # BB#0: # %entry 136; SSE2-NEXT: andps {{.*}}(%rip), %xmm1 137; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 138; SSE2-NEXT: orps %xmm1, %xmm0 139; SSE2-NEXT: retq 140; 141; SSSE3-LABEL: vsel_i32: 142; SSSE3: # BB#0: # %entry 143; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1 144; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 145; SSSE3-NEXT: orps %xmm1, %xmm0 146; SSSE3-NEXT: retq 147; 148; SSE41-LABEL: vsel_i32: 149; SSE41: # BB#0: # %entry 150; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 151; SSE41-NEXT: retq 152; 153; AVX1-LABEL: vsel_i32: 154; AVX1: # BB#0: # %entry 155; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] 156; AVX1-NEXT: retq 157; 158; AVX2-LABEL: vsel_i32: 159; AVX2: # BB#0: # %entry 160; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 161; AVX2-NEXT: retq 162entry: 163 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> %v1, <4 x i32> %v2 164 ret <4 x i32> %vsel 165} 166 167define <2 x double> @vsel_double(<2 x double> %v1, <2 x double> %v2) { 168; SSE2-LABEL: vsel_double: 169; SSE2: # BB#0: # %entry 170; SSE2-NEXT: movsd %xmm0, %xmm1 171; SSE2-NEXT: movaps %xmm1, %xmm0 172; SSE2-NEXT: retq 173; 174; SSSE3-LABEL: vsel_double: 175; SSSE3: # BB#0: # %entry 176; SSSE3-NEXT: movsd %xmm0, %xmm1 177; SSSE3-NEXT: movaps %xmm1, %xmm0 178; SSSE3-NEXT: retq 179; 180; SSE41-LABEL: vsel_double: 181; SSE41: # BB#0: # %entry 182; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 183; SSE41-NEXT: retq 184; 185; AVX-LABEL: vsel_double: 186; AVX: # BB#0: # %entry 187; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] 188; AVX-NEXT: retq 189entry: 190 %vsel = select <2 x i1> <i1 true, i1 false>, <2 x double> %v1, <2 x double> %v2 191 ret <2 x double> %vsel 192} 193 194define <2 x i64> @vsel_i64(<2 x i64> %v1, <2 x i64> %v2) { 195; SSE2-LABEL: vsel_i64: 196; SSE2: # BB#0: # %entry 197; SSE2-NEXT: movsd %xmm0, %xmm1 198; SSE2-NEXT: movaps %xmm1, %xmm0 199; SSE2-NEXT: retq 200; 201; SSSE3-LABEL: vsel_i64: 202; SSSE3: # BB#0: # %entry 203; SSSE3-NEXT: movsd %xmm0, %xmm1 204; SSSE3-NEXT: movaps %xmm1, %xmm0 205; SSSE3-NEXT: retq 206; 207; SSE41-LABEL: vsel_i64: 208; SSE41: # BB#0: # %entry 209; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7] 210; SSE41-NEXT: retq 211; 212; AVX1-LABEL: vsel_i64: 213; AVX1: # BB#0: # %entry 214; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7] 215; AVX1-NEXT: retq 216; 217; AVX2-LABEL: vsel_i64: 218; AVX2: # BB#0: # %entry 219; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 220; AVX2-NEXT: retq 221entry: 222 %vsel = select <2 x i1> <i1 true, i1 false>, <2 x i64> %v1, <2 x i64> %v2 223 ret <2 x i64> %vsel 224} 225 226define <8 x i16> @vsel_8xi16(<8 x i16> %v1, <8 x i16> %v2) { 227; SSE2-LABEL: vsel_8xi16: 228; SSE2: # BB#0: # %entry 229; SSE2-NEXT: andps {{.*}}(%rip), %xmm1 230; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 231; SSE2-NEXT: orps %xmm1, %xmm0 232; SSE2-NEXT: retq 233; 234; SSSE3-LABEL: vsel_8xi16: 235; SSSE3: # BB#0: # %entry 236; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1 237; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 238; SSSE3-NEXT: orps %xmm1, %xmm0 239; SSSE3-NEXT: retq 240; 241; SSE41-LABEL: vsel_8xi16: 242; SSE41: # BB#0: # %entry 243; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3],xmm0[4],xmm1[5,6,7] 244; SSE41-NEXT: retq 245; 246; AVX-LABEL: vsel_8xi16: 247; AVX: # BB#0: # %entry 248; AVX-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3],xmm0[4],xmm1[5,6,7] 249; AVX-NEXT: retq 250entry: 251 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x i16> %v1, <8 x i16> %v2 252 ret <8 x i16> %vsel 253} 254 255define <16 x i8> @vsel_i8(<16 x i8> %v1, <16 x i8> %v2) { 256; SSE2-LABEL: vsel_i8: 257; SSE2: # BB#0: # %entry 258; SSE2-NEXT: andps {{.*}}(%rip), %xmm1 259; SSE2-NEXT: andps {{.*}}(%rip), %xmm0 260; SSE2-NEXT: orps %xmm1, %xmm0 261; SSE2-NEXT: retq 262; 263; SSSE3-LABEL: vsel_i8: 264; SSSE3: # BB#0: # %entry 265; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1 266; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0 267; SSSE3-NEXT: orps %xmm1, %xmm0 268; SSSE3-NEXT: retq 269; 270; SSE41-LABEL: vsel_i8: 271; SSE41: # BB#0: # %entry 272; SSE41-NEXT: movdqa %xmm0, %xmm2 273; SSE41-NEXT: movaps {{.*#+}} xmm0 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0] 274; SSE41-NEXT: pblendvb %xmm2, %xmm1 275; SSE41-NEXT: movdqa %xmm1, %xmm0 276; SSE41-NEXT: retq 277; 278; AVX-LABEL: vsel_i8: 279; AVX: # BB#0: # %entry 280; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0] 281; AVX-NEXT: vpblendvb %xmm2, %xmm0, %xmm1, %xmm0 282; AVX-NEXT: retq 283entry: 284 %vsel = select <16 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <16 x i8> %v1, <16 x i8> %v2 285 ret <16 x i8> %vsel 286} 287 288 289; AVX256 tests: 290 291define <8 x float> @vsel_float8(<8 x float> %v1, <8 x float> %v2) { 292; SSE2-LABEL: vsel_float8: 293; SSE2: # BB#0: # %entry 294; SSE2-NEXT: movss %xmm0, %xmm2 295; SSE2-NEXT: movss %xmm1, %xmm3 296; SSE2-NEXT: movaps %xmm2, %xmm0 297; SSE2-NEXT: movaps %xmm3, %xmm1 298; SSE2-NEXT: retq 299; 300; SSSE3-LABEL: vsel_float8: 301; SSSE3: # BB#0: # %entry 302; SSSE3-NEXT: movss %xmm0, %xmm2 303; SSSE3-NEXT: movss %xmm1, %xmm3 304; SSSE3-NEXT: movaps %xmm2, %xmm0 305; SSSE3-NEXT: movaps %xmm3, %xmm1 306; SSSE3-NEXT: retq 307; 308; SSE41-LABEL: vsel_float8: 309; SSE41: # BB#0: # %entry 310; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3] 311; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3] 312; SSE41-NEXT: retq 313; 314; AVX-LABEL: vsel_float8: 315; AVX: # BB#0: # %entry 316; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7] 317; AVX-NEXT: retq 318entry: 319 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x float> %v1, <8 x float> %v2 320 ret <8 x float> %vsel 321} 322 323define <8 x i32> @vsel_i328(<8 x i32> %v1, <8 x i32> %v2) { 324; SSE2-LABEL: vsel_i328: 325; SSE2: # BB#0: # %entry 326; SSE2-NEXT: movss %xmm0, %xmm2 327; SSE2-NEXT: movss %xmm1, %xmm3 328; SSE2-NEXT: movaps %xmm2, %xmm0 329; SSE2-NEXT: movaps %xmm3, %xmm1 330; SSE2-NEXT: retq 331; 332; SSSE3-LABEL: vsel_i328: 333; SSSE3: # BB#0: # %entry 334; SSSE3-NEXT: movss %xmm0, %xmm2 335; SSSE3-NEXT: movss %xmm1, %xmm3 336; SSSE3-NEXT: movaps %xmm2, %xmm0 337; SSSE3-NEXT: movaps %xmm3, %xmm1 338; SSSE3-NEXT: retq 339; 340; SSE41-LABEL: vsel_i328: 341; SSE41: # BB#0: # %entry 342; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3,4,5,6,7] 343; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3,4,5,6,7] 344; SSE41-NEXT: retq 345; 346; AVX1-LABEL: vsel_i328: 347; AVX1: # BB#0: # %entry 348; AVX1-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7] 349; AVX1-NEXT: retq 350; 351; AVX2-LABEL: vsel_i328: 352; AVX2: # BB#0: # %entry 353; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7] 354; AVX2-NEXT: retq 355entry: 356 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x i32> %v1, <8 x i32> %v2 357 ret <8 x i32> %vsel 358} 359 360define <8 x double> @vsel_double8(<8 x double> %v1, <8 x double> %v2) { 361; SSE2-LABEL: vsel_double8: 362; SSE2: # BB#0: # %entry 363; SSE2-NEXT: movsd %xmm0, %xmm4 364; SSE2-NEXT: movsd %xmm2, %xmm6 365; SSE2-NEXT: movaps %xmm4, %xmm0 366; SSE2-NEXT: movaps %xmm5, %xmm1 367; SSE2-NEXT: movaps %xmm6, %xmm2 368; SSE2-NEXT: movaps %xmm7, %xmm3 369; SSE2-NEXT: retq 370; 371; SSSE3-LABEL: vsel_double8: 372; SSSE3: # BB#0: # %entry 373; SSSE3-NEXT: movsd %xmm0, %xmm4 374; SSSE3-NEXT: movsd %xmm2, %xmm6 375; SSSE3-NEXT: movaps %xmm4, %xmm0 376; SSSE3-NEXT: movaps %xmm5, %xmm1 377; SSSE3-NEXT: movaps %xmm6, %xmm2 378; SSSE3-NEXT: movaps %xmm7, %xmm3 379; SSSE3-NEXT: retq 380; 381; SSE41-LABEL: vsel_double8: 382; SSE41: # BB#0: # %entry 383; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm4[1] 384; SSE41-NEXT: blendpd {{.*#+}} xmm2 = xmm2[0],xmm6[1] 385; SSE41-NEXT: movaps %xmm5, %xmm1 386; SSE41-NEXT: movaps %xmm7, %xmm3 387; SSE41-NEXT: retq 388; 389; AVX-LABEL: vsel_double8: 390; AVX: # BB#0: # %entry 391; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3] 392; AVX-NEXT: vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3] 393; AVX-NEXT: retq 394entry: 395 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x double> %v1, <8 x double> %v2 396 ret <8 x double> %vsel 397} 398 399define <8 x i64> @vsel_i648(<8 x i64> %v1, <8 x i64> %v2) { 400; SSE2-LABEL: vsel_i648: 401; SSE2: # BB#0: # %entry 402; SSE2-NEXT: movsd %xmm0, %xmm4 403; SSE2-NEXT: movsd %xmm2, %xmm6 404; SSE2-NEXT: movaps %xmm4, %xmm0 405; SSE2-NEXT: movaps %xmm5, %xmm1 406; SSE2-NEXT: movaps %xmm6, %xmm2 407; SSE2-NEXT: movaps %xmm7, %xmm3 408; SSE2-NEXT: retq 409; 410; SSSE3-LABEL: vsel_i648: 411; SSSE3: # BB#0: # %entry 412; SSSE3-NEXT: movsd %xmm0, %xmm4 413; SSSE3-NEXT: movsd %xmm2, %xmm6 414; SSSE3-NEXT: movaps %xmm4, %xmm0 415; SSSE3-NEXT: movaps %xmm5, %xmm1 416; SSSE3-NEXT: movaps %xmm6, %xmm2 417; SSSE3-NEXT: movaps %xmm7, %xmm3 418; SSSE3-NEXT: retq 419; 420; SSE41-LABEL: vsel_i648: 421; SSE41: # BB#0: # %entry 422; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm4[4,5,6,7] 423; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0,1,2,3],xmm6[4,5,6,7] 424; SSE41-NEXT: movaps %xmm5, %xmm1 425; SSE41-NEXT: movaps %xmm7, %xmm3 426; SSE41-NEXT: retq 427; 428; AVX1-LABEL: vsel_i648: 429; AVX1: # BB#0: # %entry 430; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3] 431; AVX1-NEXT: vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3] 432; AVX1-NEXT: retq 433; 434; AVX2-LABEL: vsel_i648: 435; AVX2: # BB#0: # %entry 436; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0,1],ymm2[2,3,4,5,6,7] 437; AVX2-NEXT: vpblendd {{.*#+}} ymm1 = ymm1[0,1],ymm3[2,3,4,5,6,7] 438; AVX2-NEXT: retq 439entry: 440 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x i64> %v1, <8 x i64> %v2 441 ret <8 x i64> %vsel 442} 443 444define <4 x double> @vsel_double4(<4 x double> %v1, <4 x double> %v2) { 445; SSE2-LABEL: vsel_double4: 446; SSE2: # BB#0: # %entry 447; SSE2-NEXT: movsd %xmm0, %xmm2 448; SSE2-NEXT: movsd %xmm1, %xmm3 449; SSE2-NEXT: movaps %xmm2, %xmm0 450; SSE2-NEXT: movaps %xmm3, %xmm1 451; SSE2-NEXT: retq 452; 453; SSSE3-LABEL: vsel_double4: 454; SSSE3: # BB#0: # %entry 455; SSSE3-NEXT: movsd %xmm0, %xmm2 456; SSSE3-NEXT: movsd %xmm1, %xmm3 457; SSSE3-NEXT: movaps %xmm2, %xmm0 458; SSSE3-NEXT: movaps %xmm3, %xmm1 459; SSSE3-NEXT: retq 460; 461; SSE41-LABEL: vsel_double4: 462; SSE41: # BB#0: # %entry 463; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1] 464; SSE41-NEXT: blendpd {{.*#+}} xmm1 = xmm1[0],xmm3[1] 465; SSE41-NEXT: retq 466; 467; AVX-LABEL: vsel_double4: 468; AVX: # BB#0: # %entry 469; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3] 470; AVX-NEXT: retq 471entry: 472 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x double> %v1, <4 x double> %v2 473 ret <4 x double> %vsel 474} 475 476define <2 x double> @testa(<2 x double> %x, <2 x double> %y) { 477; SSE2-LABEL: testa: 478; SSE2: # BB#0: # %entry 479; SSE2-NEXT: movapd %xmm1, %xmm2 480; SSE2-NEXT: cmplepd %xmm0, %xmm2 481; SSE2-NEXT: andpd %xmm2, %xmm0 482; SSE2-NEXT: andnpd %xmm1, %xmm2 483; SSE2-NEXT: orpd %xmm2, %xmm0 484; SSE2-NEXT: retq 485; 486; SSSE3-LABEL: testa: 487; SSSE3: # BB#0: # %entry 488; SSSE3-NEXT: movapd %xmm1, %xmm2 489; SSSE3-NEXT: cmplepd %xmm0, %xmm2 490; SSSE3-NEXT: andpd %xmm2, %xmm0 491; SSSE3-NEXT: andnpd %xmm1, %xmm2 492; SSSE3-NEXT: orpd %xmm2, %xmm0 493; SSSE3-NEXT: retq 494; 495; SSE41-LABEL: testa: 496; SSE41: # BB#0: # %entry 497; SSE41-NEXT: movapd %xmm0, %xmm2 498; SSE41-NEXT: movapd %xmm1, %xmm0 499; SSE41-NEXT: cmplepd %xmm2, %xmm0 500; SSE41-NEXT: blendvpd %xmm2, %xmm1 501; SSE41-NEXT: movapd %xmm1, %xmm0 502; SSE41-NEXT: retq 503; 504; AVX-LABEL: testa: 505; AVX: # BB#0: # %entry 506; AVX-NEXT: vcmplepd %xmm0, %xmm1, %xmm2 507; AVX-NEXT: vblendvpd %xmm2, %xmm0, %xmm1, %xmm0 508; AVX-NEXT: retq 509entry: 510 %max_is_x = fcmp oge <2 x double> %x, %y 511 %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y 512 ret <2 x double> %max 513} 514 515define <2 x double> @testb(<2 x double> %x, <2 x double> %y) { 516; SSE2-LABEL: testb: 517; SSE2: # BB#0: # %entry 518; SSE2-NEXT: movapd %xmm1, %xmm2 519; SSE2-NEXT: cmpnlepd %xmm0, %xmm2 520; SSE2-NEXT: andpd %xmm2, %xmm0 521; SSE2-NEXT: andnpd %xmm1, %xmm2 522; SSE2-NEXT: orpd %xmm2, %xmm0 523; SSE2-NEXT: retq 524; 525; SSSE3-LABEL: testb: 526; SSSE3: # BB#0: # %entry 527; SSSE3-NEXT: movapd %xmm1, %xmm2 528; SSSE3-NEXT: cmpnlepd %xmm0, %xmm2 529; SSSE3-NEXT: andpd %xmm2, %xmm0 530; SSSE3-NEXT: andnpd %xmm1, %xmm2 531; SSSE3-NEXT: orpd %xmm2, %xmm0 532; SSSE3-NEXT: retq 533; 534; SSE41-LABEL: testb: 535; SSE41: # BB#0: # %entry 536; SSE41-NEXT: movapd %xmm0, %xmm2 537; SSE41-NEXT: movapd %xmm1, %xmm0 538; SSE41-NEXT: cmpnlepd %xmm2, %xmm0 539; SSE41-NEXT: blendvpd %xmm2, %xmm1 540; SSE41-NEXT: movapd %xmm1, %xmm0 541; SSE41-NEXT: retq 542; 543; AVX-LABEL: testb: 544; AVX: # BB#0: # %entry 545; AVX-NEXT: vcmpnlepd %xmm0, %xmm1, %xmm2 546; AVX-NEXT: vblendvpd %xmm2, %xmm0, %xmm1, %xmm0 547; AVX-NEXT: retq 548entry: 549 %min_is_x = fcmp ult <2 x double> %x, %y 550 %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y 551 ret <2 x double> %min 552} 553 554; If we can figure out a blend has a constant mask, we should emit the 555; blend instruction with an immediate mask 556define <4 x double> @constant_blendvpd_avx(<4 x double> %xy, <4 x double> %ab) { 557; SSE2-LABEL: constant_blendvpd_avx: 558; SSE2: # BB#0: # %entry 559; SSE2-NEXT: movsd %xmm1, %xmm3 560; SSE2-NEXT: movaps %xmm2, %xmm0 561; SSE2-NEXT: movaps %xmm3, %xmm1 562; SSE2-NEXT: retq 563; 564; SSSE3-LABEL: constant_blendvpd_avx: 565; SSSE3: # BB#0: # %entry 566; SSSE3-NEXT: movsd %xmm1, %xmm3 567; SSSE3-NEXT: movaps %xmm2, %xmm0 568; SSSE3-NEXT: movaps %xmm3, %xmm1 569; SSSE3-NEXT: retq 570; 571; SSE41-LABEL: constant_blendvpd_avx: 572; SSE41: # BB#0: # %entry 573; SSE41-NEXT: blendpd {{.*#+}} xmm1 = xmm1[0],xmm3[1] 574; SSE41-NEXT: movaps %xmm2, %xmm0 575; SSE41-NEXT: retq 576; 577; AVX-LABEL: constant_blendvpd_avx: 578; AVX: # BB#0: # %entry 579; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2],ymm1[3] 580; AVX-NEXT: retq 581entry: 582 %select = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x double> %xy, <4 x double> %ab 583 ret <4 x double> %select 584} 585 586define <8 x float> @constant_blendvps_avx(<8 x float> %xyzw, <8 x float> %abcd) { 587; SSE2-LABEL: constant_blendvps_avx: 588; SSE2: # BB#0: # %entry 589; SSE2-NEXT: movaps {{.*#+}} xmm4 = [4294967295,4294967295,4294967295,0] 590; SSE2-NEXT: andps %xmm4, %xmm2 591; SSE2-NEXT: movaps {{.*#+}} xmm5 = [0,0,0,4294967295] 592; SSE2-NEXT: andps %xmm5, %xmm0 593; SSE2-NEXT: orps %xmm2, %xmm0 594; SSE2-NEXT: andps %xmm4, %xmm3 595; SSE2-NEXT: andps %xmm5, %xmm1 596; SSE2-NEXT: orps %xmm3, %xmm1 597; SSE2-NEXT: retq 598; 599; SSSE3-LABEL: constant_blendvps_avx: 600; SSSE3: # BB#0: # %entry 601; SSSE3-NEXT: movaps {{.*#+}} xmm4 = [4294967295,4294967295,4294967295,0] 602; SSSE3-NEXT: andps %xmm4, %xmm2 603; SSSE3-NEXT: movaps {{.*#+}} xmm5 = [0,0,0,4294967295] 604; SSSE3-NEXT: andps %xmm5, %xmm0 605; SSSE3-NEXT: orps %xmm2, %xmm0 606; SSSE3-NEXT: andps %xmm4, %xmm3 607; SSSE3-NEXT: andps %xmm5, %xmm1 608; SSSE3-NEXT: orps %xmm3, %xmm1 609; SSSE3-NEXT: retq 610; 611; SSE41-LABEL: constant_blendvps_avx: 612; SSE41: # BB#0: # %entry 613; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[3] 614; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm3[0,1,2],xmm1[3] 615; SSE41-NEXT: retq 616; 617; AVX-LABEL: constant_blendvps_avx: 618; AVX: # BB#0: # %entry 619; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm1[0,1,2],ymm0[3],ymm1[4,5,6],ymm0[7] 620; AVX-NEXT: retq 621entry: 622 %select = select <8 x i1> <i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false, i1 true>, <8 x float> %xyzw, <8 x float> %abcd 623 ret <8 x float> %select 624} 625 626define <32 x i8> @constant_pblendvb_avx2(<32 x i8> %xyzw, <32 x i8> %abcd) { 627; SSE2-LABEL: constant_pblendvb_avx2: 628; SSE2: # BB#0: # %entry 629; SSE2-NEXT: movaps {{.*#+}} xmm4 = [255,255,0,255,0,0,0,255,255,255,0,255,0,0,0,255] 630; SSE2-NEXT: andps %xmm4, %xmm2 631; SSE2-NEXT: movaps {{.*#+}} xmm5 = [0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0] 632; SSE2-NEXT: andps %xmm5, %xmm0 633; SSE2-NEXT: orps %xmm2, %xmm0 634; SSE2-NEXT: andps %xmm4, %xmm3 635; SSE2-NEXT: andps %xmm5, %xmm1 636; SSE2-NEXT: orps %xmm3, %xmm1 637; SSE2-NEXT: retq 638; 639; SSSE3-LABEL: constant_pblendvb_avx2: 640; SSSE3: # BB#0: # %entry 641; SSSE3-NEXT: movaps {{.*#+}} xmm4 = [255,255,0,255,0,0,0,255,255,255,0,255,0,0,0,255] 642; SSSE3-NEXT: andps %xmm4, %xmm2 643; SSSE3-NEXT: movaps {{.*#+}} xmm5 = [0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0] 644; SSSE3-NEXT: andps %xmm5, %xmm0 645; SSSE3-NEXT: orps %xmm2, %xmm0 646; SSSE3-NEXT: andps %xmm4, %xmm3 647; SSSE3-NEXT: andps %xmm5, %xmm1 648; SSSE3-NEXT: orps %xmm3, %xmm1 649; SSSE3-NEXT: retq 650; 651; SSE41-LABEL: constant_pblendvb_avx2: 652; SSE41: # BB#0: # %entry 653; SSE41-NEXT: movdqa %xmm0, %xmm4 654; SSE41-NEXT: movaps {{.*#+}} xmm0 = [0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0] 655; SSE41-NEXT: pblendvb %xmm4, %xmm2 656; SSE41-NEXT: pblendvb %xmm1, %xmm3 657; SSE41-NEXT: movdqa %xmm2, %xmm0 658; SSE41-NEXT: movdqa %xmm3, %xmm1 659; SSE41-NEXT: retq 660; 661; AVX1-LABEL: constant_pblendvb_avx2: 662; AVX1: # BB#0: # %entry 663; AVX1-NEXT: vandps {{.*}}(%rip), %ymm1, %ymm1 664; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 665; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm0 666; AVX1-NEXT: retq 667; 668; AVX2-LABEL: constant_pblendvb_avx2: 669; AVX2: # BB#0: # %entry 670; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0] 671; AVX2-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0 672; AVX2-NEXT: retq 673entry: 674 %select = select <32 x i1> <i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false>, <32 x i8> %xyzw, <32 x i8> %abcd 675 ret <32 x i8> %select 676} 677 678declare <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float>, <8 x float>, <8 x float>) 679declare <4 x double> @llvm.x86.avx.blendv.pd.256(<4 x double>, <4 x double>, <4 x double>) 680 681;; 4 tests for shufflevectors that optimize to blend + immediate 682define <4 x float> @blend_shufflevector_4xfloat(<4 x float> %a, <4 x float> %b) { 683; SSE2-LABEL: blend_shufflevector_4xfloat: 684; SSE2: # BB#0: # %entry 685; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3] 686; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3] 687; SSE2-NEXT: retq 688; 689; SSSE3-LABEL: blend_shufflevector_4xfloat: 690; SSSE3: # BB#0: # %entry 691; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3] 692; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3] 693; SSSE3-NEXT: retq 694; 695; SSE41-LABEL: blend_shufflevector_4xfloat: 696; SSE41: # BB#0: # %entry 697; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 698; SSE41-NEXT: retq 699; 700; AVX-LABEL: blend_shufflevector_4xfloat: 701; AVX: # BB#0: # %entry 702; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 703; AVX-NEXT: retq 704entry: 705 %select = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 706 ret <4 x float> %select 707} 708 709define <8 x float> @blend_shufflevector_8xfloat(<8 x float> %a, <8 x float> %b) { 710; SSE2-LABEL: blend_shufflevector_8xfloat: 711; SSE2: # BB#0: # %entry 712; SSE2-NEXT: movss %xmm0, %xmm2 713; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0] 714; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2] 715; SSE2-NEXT: movaps %xmm2, %xmm0 716; SSE2-NEXT: movaps %xmm3, %xmm1 717; SSE2-NEXT: retq 718; 719; SSSE3-LABEL: blend_shufflevector_8xfloat: 720; SSSE3: # BB#0: # %entry 721; SSSE3-NEXT: movss %xmm0, %xmm2 722; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0] 723; SSSE3-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2] 724; SSSE3-NEXT: movaps %xmm2, %xmm0 725; SSSE3-NEXT: movaps %xmm3, %xmm1 726; SSSE3-NEXT: retq 727; 728; SSE41-LABEL: blend_shufflevector_8xfloat: 729; SSE41: # BB#0: # %entry 730; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3] 731; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm3[0,1],xmm1[2],xmm3[3] 732; SSE41-NEXT: retq 733; 734; AVX-LABEL: blend_shufflevector_8xfloat: 735; AVX: # BB#0: # %entry 736; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3,4,5],ymm0[6],ymm1[7] 737; AVX-NEXT: retq 738entry: 739 %select = shufflevector <8 x float> %a, <8 x float> %b, <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 6, i32 15> 740 ret <8 x float> %select 741} 742 743define <4 x double> @blend_shufflevector_4xdouble(<4 x double> %a, <4 x double> %b) { 744; SSE2-LABEL: blend_shufflevector_4xdouble: 745; SSE2: # BB#0: # %entry 746; SSE2-NEXT: movsd %xmm0, %xmm2 747; SSE2-NEXT: movaps %xmm2, %xmm0 748; SSE2-NEXT: retq 749; 750; SSSE3-LABEL: blend_shufflevector_4xdouble: 751; SSSE3: # BB#0: # %entry 752; SSSE3-NEXT: movsd %xmm0, %xmm2 753; SSSE3-NEXT: movaps %xmm2, %xmm0 754; SSSE3-NEXT: retq 755; 756; SSE41-LABEL: blend_shufflevector_4xdouble: 757; SSE41: # BB#0: # %entry 758; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1] 759; SSE41-NEXT: retq 760; 761; AVX-LABEL: blend_shufflevector_4xdouble: 762; AVX: # BB#0: # %entry 763; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2,3] 764; AVX-NEXT: retq 765entry: 766 %select = shufflevector <4 x double> %a, <4 x double> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 767 ret <4 x double> %select 768} 769 770define <4 x i64> @blend_shufflevector_4xi64(<4 x i64> %a, <4 x i64> %b) { 771; SSE2-LABEL: blend_shufflevector_4xi64: 772; SSE2: # BB#0: # %entry 773; SSE2-NEXT: movsd %xmm2, %xmm0 774; SSE2-NEXT: movaps %xmm3, %xmm1 775; SSE2-NEXT: retq 776; 777; SSSE3-LABEL: blend_shufflevector_4xi64: 778; SSSE3: # BB#0: # %entry 779; SSSE3-NEXT: movsd %xmm2, %xmm0 780; SSSE3-NEXT: movaps %xmm3, %xmm1 781; SSSE3-NEXT: retq 782; 783; SSE41-LABEL: blend_shufflevector_4xi64: 784; SSE41: # BB#0: # %entry 785; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1,2,3],xmm0[4,5,6,7] 786; SSE41-NEXT: movaps %xmm3, %xmm1 787; SSE41-NEXT: retq 788; 789; AVX1-LABEL: blend_shufflevector_4xi64: 790; AVX1: # BB#0: # %entry 791; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm1[0],ymm0[1],ymm1[2,3] 792; AVX1-NEXT: retq 793; 794; AVX2-LABEL: blend_shufflevector_4xi64: 795; AVX2: # BB#0: # %entry 796; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2,3],ymm1[4,5,6,7] 797; AVX2-NEXT: retq 798entry: 799 %select = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7> 800 ret <4 x i64> %select 801} 802