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