1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2 6 7; Verify that we don't emit packed vector shifts instructions if the 8; condition used by the vector select is a vector of constants. 9 10define <4 x float> @test1(<4 x float> %a, <4 x float> %b) { 11; SSE2-LABEL: test1: 12; SSE2: # %bb.0: 13; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3] 14; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3] 15; SSE2-NEXT: retq 16; 17; SSE41-LABEL: test1: 18; SSE41: # %bb.0: 19; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 20; SSE41-NEXT: retq 21; 22; AVX-LABEL: test1: 23; AVX: # %bb.0: 24; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] 25; AVX-NEXT: retq 26 %1 = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x float> %a, <4 x float> %b 27 ret <4 x float> %1 28} 29 30define <4 x float> @test2(<4 x float> %a, <4 x float> %b) { 31; SSE2-LABEL: test2: 32; SSE2: # %bb.0: 33; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 34; SSE2-NEXT: movapd %xmm1, %xmm0 35; SSE2-NEXT: retq 36; 37; SSE41-LABEL: test2: 38; SSE41: # %bb.0: 39; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 40; SSE41-NEXT: retq 41; 42; AVX-LABEL: test2: 43; AVX: # %bb.0: 44; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 45; AVX-NEXT: retq 46 %1 = select <4 x i1> <i1 true, i1 true, i1 false, i1 false>, <4 x float> %a, <4 x float> %b 47 ret <4 x float> %1 48} 49 50define <4 x float> @test3(<4 x float> %a, <4 x float> %b) { 51; SSE2-LABEL: test3: 52; SSE2: # %bb.0: 53; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 54; SSE2-NEXT: retq 55; 56; SSE41-LABEL: test3: 57; SSE41: # %bb.0: 58; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 59; SSE41-NEXT: retq 60; 61; AVX-LABEL: test3: 62; AVX: # %bb.0: 63; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 64; AVX-NEXT: retq 65 %1 = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x float> %a, <4 x float> %b 66 ret <4 x float> %1 67} 68 69define <4 x float> @test4(<4 x float> %a, <4 x float> %b) { 70; SSE-LABEL: test4: 71; SSE: # %bb.0: 72; SSE-NEXT: movaps %xmm1, %xmm0 73; SSE-NEXT: retq 74; 75; AVX-LABEL: test4: 76; AVX: # %bb.0: 77; AVX-NEXT: vmovaps %xmm1, %xmm0 78; AVX-NEXT: retq 79 %1 = select <4 x i1> <i1 false, i1 false, i1 false, i1 false>, <4 x float> %a, <4 x float> %b 80 ret <4 x float> %1 81} 82 83define <4 x float> @test5(<4 x float> %a, <4 x float> %b) { 84; SSE-LABEL: test5: 85; SSE: # %bb.0: 86; SSE-NEXT: retq 87; 88; AVX-LABEL: test5: 89; AVX: # %bb.0: 90; AVX-NEXT: retq 91 %1 = select <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x float> %a, <4 x float> %b 92 ret <4 x float> %1 93} 94 95define <8 x i16> @test6(<8 x i16> %a, <8 x i16> %b) { 96; SSE-LABEL: test6: 97; SSE: # %bb.0: 98; SSE-NEXT: retq 99; 100; AVX-LABEL: test6: 101; AVX: # %bb.0: 102; AVX-NEXT: retq 103 %1 = select <8 x i1> <i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false>, <8 x i16> %a, <8 x i16> %a 104 ret <8 x i16> %1 105} 106 107define <8 x i16> @test7(<8 x i16> %a, <8 x i16> %b) { 108; SSE2-LABEL: test7: 109; SSE2: # %bb.0: 110; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 111; SSE2-NEXT: movapd %xmm1, %xmm0 112; SSE2-NEXT: retq 113; 114; SSE41-LABEL: test7: 115; SSE41: # %bb.0: 116; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 117; SSE41-NEXT: retq 118; 119; AVX-LABEL: test7: 120; AVX: # %bb.0: 121; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 122; AVX-NEXT: retq 123 %1 = select <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false>, <8 x i16> %a, <8 x i16> %b 124 ret <8 x i16> %1 125} 126 127define <8 x i16> @test8(<8 x i16> %a, <8 x i16> %b) { 128; SSE2-LABEL: test8: 129; SSE2: # %bb.0: 130; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 131; SSE2-NEXT: retq 132; 133; SSE41-LABEL: test8: 134; SSE41: # %bb.0: 135; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 136; SSE41-NEXT: retq 137; 138; AVX-LABEL: test8: 139; AVX: # %bb.0: 140; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 141; AVX-NEXT: retq 142 %1 = select <8 x i1> <i1 false, i1 false, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true>, <8 x i16> %a, <8 x i16> %b 143 ret <8 x i16> %1 144} 145 146define <8 x i16> @test9(<8 x i16> %a, <8 x i16> %b) { 147; SSE-LABEL: test9: 148; SSE: # %bb.0: 149; SSE-NEXT: movaps %xmm1, %xmm0 150; SSE-NEXT: retq 151; 152; AVX-LABEL: test9: 153; AVX: # %bb.0: 154; AVX-NEXT: vmovaps %xmm1, %xmm0 155; AVX-NEXT: retq 156 %1 = select <8 x i1> <i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <8 x i16> %a, <8 x i16> %b 157 ret <8 x i16> %1 158} 159 160define <8 x i16> @test10(<8 x i16> %a, <8 x i16> %b) { 161; SSE-LABEL: test10: 162; SSE: # %bb.0: 163; SSE-NEXT: retq 164; 165; AVX-LABEL: test10: 166; AVX: # %bb.0: 167; AVX-NEXT: retq 168 %1 = select <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i16> %a, <8 x i16> %b 169 ret <8 x i16> %1 170} 171 172define <8 x i16> @test11(<8 x i16> %a, <8 x i16> %b) { 173; SSE2-LABEL: test11: 174; SSE2: # %bb.0: 175; SSE2-NEXT: movaps {{.*#+}} xmm2 = [0,65535,65535,0,0,65535,65535,0] 176; SSE2-NEXT: andps %xmm2, %xmm0 177; SSE2-NEXT: andnps %xmm1, %xmm2 178; SSE2-NEXT: orps %xmm2, %xmm0 179; SSE2-NEXT: retq 180; 181; SSE41-LABEL: test11: 182; SSE41: # %bb.0: 183; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1,2],xmm1[3,4],xmm0[5,6],xmm1[7] 184; SSE41-NEXT: retq 185; 186; AVX-LABEL: test11: 187; AVX: # %bb.0: 188; AVX-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1,2],xmm1[3,4],xmm0[5,6],xmm1[7] 189; AVX-NEXT: retq 190 %1 = select <8 x i1> <i1 false, i1 true, i1 true, i1 false, i1 undef, i1 true, i1 true, i1 undef>, <8 x i16> %a, <8 x i16> %b 191 ret <8 x i16> %1 192} 193 194define <8 x i16> @test12(<8 x i16> %a, <8 x i16> %b) { 195; SSE-LABEL: test12: 196; SSE: # %bb.0: 197; SSE-NEXT: movaps %xmm1, %xmm0 198; SSE-NEXT: retq 199; 200; AVX-LABEL: test12: 201; AVX: # %bb.0: 202; AVX-NEXT: vmovaps %xmm1, %xmm0 203; AVX-NEXT: retq 204 %1 = select <8 x i1> <i1 false, i1 false, i1 undef, i1 false, i1 false, i1 false, i1 false, i1 undef>, <8 x i16> %a, <8 x i16> %b 205 ret <8 x i16> %1 206} 207 208define <8 x i16> @test13(<8 x i16> %a, <8 x i16> %b) { 209; SSE-LABEL: test13: 210; SSE: # %bb.0: 211; SSE-NEXT: movaps %xmm1, %xmm0 212; SSE-NEXT: retq 213; 214; AVX-LABEL: test13: 215; AVX: # %bb.0: 216; AVX-NEXT: vmovaps %xmm1, %xmm0 217; AVX-NEXT: retq 218 %1 = select <8 x i1> <i1 undef, i1 undef, i1 undef, i1 undef, i1 undef, i1 undef, i1 undef, i1 undef>, <8 x i16> %a, <8 x i16> %b 219 ret <8 x i16> %1 220} 221 222; Fold (vselect (build_vector AllOnes), N1, N2) -> N1 223define <4 x float> @test14(<4 x float> %a, <4 x float> %b) { 224; SSE-LABEL: test14: 225; SSE: # %bb.0: 226; SSE-NEXT: retq 227; 228; AVX-LABEL: test14: 229; AVX: # %bb.0: 230; AVX-NEXT: retq 231 %1 = select <4 x i1> <i1 true, i1 undef, i1 true, i1 undef>, <4 x float> %a, <4 x float> %b 232 ret <4 x float> %1 233} 234 235define <8 x i16> @test15(<8 x i16> %a, <8 x i16> %b) { 236; SSE-LABEL: test15: 237; SSE: # %bb.0: 238; SSE-NEXT: retq 239; 240; AVX-LABEL: test15: 241; AVX: # %bb.0: 242; AVX-NEXT: retq 243 %1 = select <8 x i1> <i1 true, i1 true, i1 true, i1 undef, i1 undef, i1 true, i1 true, i1 undef>, <8 x i16> %a, <8 x i16> %b 244 ret <8 x i16> %1 245} 246 247; Fold (vselect (build_vector AllZeros), N1, N2) -> N2 248define <4 x float> @test16(<4 x float> %a, <4 x float> %b) { 249; SSE-LABEL: test16: 250; SSE: # %bb.0: 251; SSE-NEXT: movaps %xmm1, %xmm0 252; SSE-NEXT: retq 253; 254; AVX-LABEL: test16: 255; AVX: # %bb.0: 256; AVX-NEXT: vmovaps %xmm1, %xmm0 257; AVX-NEXT: retq 258 %1 = select <4 x i1> <i1 false, i1 undef, i1 false, i1 undef>, <4 x float> %a, <4 x float> %b 259 ret <4 x float> %1 260} 261 262define <8 x i16> @test17(<8 x i16> %a, <8 x i16> %b) { 263; SSE-LABEL: test17: 264; SSE: # %bb.0: 265; SSE-NEXT: movaps %xmm1, %xmm0 266; SSE-NEXT: retq 267; 268; AVX-LABEL: test17: 269; AVX: # %bb.0: 270; AVX-NEXT: vmovaps %xmm1, %xmm0 271; AVX-NEXT: retq 272 %1 = select <8 x i1> <i1 false, i1 false, i1 false, i1 undef, i1 undef, i1 false, i1 false, i1 undef>, <8 x i16> %a, <8 x i16> %b 273 ret <8 x i16> %1 274} 275 276define <4 x float> @test18(<4 x float> %a, <4 x float> %b) { 277; SSE2-LABEL: test18: 278; SSE2: # %bb.0: 279; SSE2-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 280; SSE2-NEXT: retq 281; 282; SSE41-LABEL: test18: 283; SSE41: # %bb.0: 284; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 285; SSE41-NEXT: retq 286; 287; AVX-LABEL: test18: 288; AVX: # %bb.0: 289; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 290; AVX-NEXT: retq 291 %1 = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> %a, <4 x float> %b 292 ret <4 x float> %1 293} 294 295define <4 x i32> @test19(<4 x i32> %a, <4 x i32> %b) { 296; SSE2-LABEL: test19: 297; SSE2: # %bb.0: 298; SSE2-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 299; SSE2-NEXT: retq 300; 301; SSE41-LABEL: test19: 302; SSE41: # %bb.0: 303; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 304; SSE41-NEXT: retq 305; 306; AVX-LABEL: test19: 307; AVX: # %bb.0: 308; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3] 309; AVX-NEXT: retq 310 %1 = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x i32> %a, <4 x i32> %b 311 ret <4 x i32> %1 312} 313 314define <2 x double> @test20(<2 x double> %a, <2 x double> %b) { 315; SSE2-LABEL: test20: 316; SSE2: # %bb.0: 317; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 318; SSE2-NEXT: retq 319; 320; SSE41-LABEL: test20: 321; SSE41: # %bb.0: 322; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 323; SSE41-NEXT: retq 324; 325; AVX-LABEL: test20: 326; AVX: # %bb.0: 327; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 328; AVX-NEXT: retq 329 %1 = select <2 x i1> <i1 false, i1 true>, <2 x double> %a, <2 x double> %b 330 ret <2 x double> %1 331} 332 333define <2 x i64> @test21(<2 x i64> %a, <2 x i64> %b) { 334; SSE2-LABEL: test21: 335; SSE2: # %bb.0: 336; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1] 337; SSE2-NEXT: retq 338; 339; SSE41-LABEL: test21: 340; SSE41: # %bb.0: 341; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 342; SSE41-NEXT: retq 343; 344; AVX-LABEL: test21: 345; AVX: # %bb.0: 346; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3] 347; AVX-NEXT: retq 348 %1 = select <2 x i1> <i1 false, i1 true>, <2 x i64> %a, <2 x i64> %b 349 ret <2 x i64> %1 350} 351 352define <4 x float> @test22(<4 x float> %a, <4 x float> %b) { 353; SSE2-LABEL: test22: 354; SSE2: # %bb.0: 355; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 356; SSE2-NEXT: movaps %xmm1, %xmm0 357; SSE2-NEXT: retq 358; 359; SSE41-LABEL: test22: 360; SSE41: # %bb.0: 361; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 362; SSE41-NEXT: retq 363; 364; AVX-LABEL: test22: 365; AVX: # %bb.0: 366; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 367; AVX-NEXT: retq 368 %1 = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %a, <4 x float> %b 369 ret <4 x float> %1 370} 371 372define <4 x i32> @test23(<4 x i32> %a, <4 x i32> %b) { 373; SSE2-LABEL: test23: 374; SSE2: # %bb.0: 375; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 376; SSE2-NEXT: movaps %xmm1, %xmm0 377; SSE2-NEXT: retq 378; 379; SSE41-LABEL: test23: 380; SSE41: # %bb.0: 381; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 382; SSE41-NEXT: retq 383; 384; AVX-LABEL: test23: 385; AVX: # %bb.0: 386; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3] 387; AVX-NEXT: retq 388 %1 = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x i32> %a, <4 x i32> %b 389 ret <4 x i32> %1 390} 391 392define <2 x double> @test24(<2 x double> %a, <2 x double> %b) { 393; SSE2-LABEL: test24: 394; SSE2: # %bb.0: 395; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 396; SSE2-NEXT: movapd %xmm1, %xmm0 397; SSE2-NEXT: retq 398; 399; SSE41-LABEL: test24: 400; SSE41: # %bb.0: 401; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 402; SSE41-NEXT: retq 403; 404; AVX-LABEL: test24: 405; AVX: # %bb.0: 406; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 407; AVX-NEXT: retq 408 %1 = select <2 x i1> <i1 true, i1 false>, <2 x double> %a, <2 x double> %b 409 ret <2 x double> %1 410} 411 412define <2 x i64> @test25(<2 x i64> %a, <2 x i64> %b) { 413; SSE2-LABEL: test25: 414; SSE2: # %bb.0: 415; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1] 416; SSE2-NEXT: movapd %xmm1, %xmm0 417; SSE2-NEXT: retq 418; 419; SSE41-LABEL: test25: 420; SSE41: # %bb.0: 421; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 422; SSE41-NEXT: retq 423; 424; AVX-LABEL: test25: 425; AVX: # %bb.0: 426; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] 427; AVX-NEXT: retq 428 %1 = select <2 x i1> <i1 true, i1 false>, <2 x i64> %a, <2 x i64> %b 429 ret <2 x i64> %1 430} 431 432define <4 x float> @select_of_shuffles_0(<2 x float> %a0, <2 x float> %b0, <2 x float> %a1, <2 x float> %b1) { 433; SSE-LABEL: select_of_shuffles_0: 434; SSE: # %bb.0: 435; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm2[0] 436; SSE-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm3[0] 437; SSE-NEXT: subps %xmm1, %xmm0 438; SSE-NEXT: retq 439; 440; AVX-LABEL: select_of_shuffles_0: 441; AVX: # %bb.0: 442; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm2[0] 443; AVX-NEXT: vmovlhps {{.*#+}} xmm1 = xmm1[0],xmm3[0] 444; AVX-NEXT: vsubps %xmm1, %xmm0, %xmm0 445; AVX-NEXT: retq 446 %1 = shufflevector <2 x float> %a0, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> 447 %2 = shufflevector <2 x float> %a1, <2 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 0, i32 1> 448 %3 = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x float> %2, <4 x float> %1 449 %4 = shufflevector <2 x float> %b0, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> 450 %5 = shufflevector <2 x float> %b1, <2 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 0, i32 1> 451 %6 = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x float> %5, <4 x float> %4 452 %7 = fsub <4 x float> %3, %6 453 ret <4 x float> %7 454} 455 456; PR20677 457define <16 x double> @select_illegal(<16 x double> %a, <16 x double> %b) { 458; SSE-LABEL: select_illegal: 459; SSE: # %bb.0: 460; SSE-NEXT: movq %rdi, %rax 461; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm4 462; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm5 463; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm6 464; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm7 465; SSE-NEXT: movaps %xmm7, 112(%rdi) 466; SSE-NEXT: movaps %xmm6, 96(%rdi) 467; SSE-NEXT: movaps %xmm5, 80(%rdi) 468; SSE-NEXT: movaps %xmm4, 64(%rdi) 469; SSE-NEXT: movaps %xmm3, 48(%rdi) 470; SSE-NEXT: movaps %xmm2, 32(%rdi) 471; SSE-NEXT: movaps %xmm1, 16(%rdi) 472; SSE-NEXT: movaps %xmm0, (%rdi) 473; SSE-NEXT: retq 474; 475; AVX-LABEL: select_illegal: 476; AVX: # %bb.0: 477; AVX-NEXT: vmovaps %ymm7, %ymm3 478; AVX-NEXT: vmovaps %ymm6, %ymm2 479; AVX-NEXT: retq 480 %sel = select <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <16 x double> %a, <16 x double> %b 481 ret <16 x double> %sel 482} 483 484; Make sure we can optimize the condition MSB when it is used by 2 selects. 485; The v2i1 here will be passed as v2i64 and we will emit a sign_extend_inreg to fill the upper bits. 486; We should be able to remove the sra from the sign_extend_inreg to leave only shl. 487define <2 x i64> @shrunkblend_2uses(<2 x i1> %cond, <2 x i64> %a, <2 x i64> %b, <2 x i64> %c, <2 x i64> %d) { 488; SSE2-LABEL: shrunkblend_2uses: 489; SSE2: # %bb.0: 490; SSE2-NEXT: psllq $63, %xmm0 491; SSE2-NEXT: psrad $31, %xmm0 492; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 493; SSE2-NEXT: movdqa %xmm0, %xmm5 494; SSE2-NEXT: pandn %xmm2, %xmm5 495; SSE2-NEXT: pand %xmm0, %xmm1 496; SSE2-NEXT: por %xmm1, %xmm5 497; SSE2-NEXT: pand %xmm0, %xmm3 498; SSE2-NEXT: pandn %xmm4, %xmm0 499; SSE2-NEXT: por %xmm3, %xmm0 500; SSE2-NEXT: paddq %xmm5, %xmm0 501; SSE2-NEXT: retq 502; 503; SSE41-LABEL: shrunkblend_2uses: 504; SSE41: # %bb.0: 505; SSE41-NEXT: psllq $63, %xmm0 506; SSE41-NEXT: blendvpd %xmm0, %xmm1, %xmm2 507; SSE41-NEXT: blendvpd %xmm0, %xmm3, %xmm4 508; SSE41-NEXT: paddq %xmm2, %xmm4 509; SSE41-NEXT: movdqa %xmm4, %xmm0 510; SSE41-NEXT: retq 511; 512; AVX-LABEL: shrunkblend_2uses: 513; AVX: # %bb.0: 514; AVX-NEXT: vpsllq $63, %xmm0, %xmm0 515; AVX-NEXT: vblendvpd %xmm0, %xmm1, %xmm2, %xmm1 516; AVX-NEXT: vblendvpd %xmm0, %xmm3, %xmm4, %xmm0 517; AVX-NEXT: vpaddq %xmm0, %xmm1, %xmm0 518; AVX-NEXT: retq 519 %x = select <2 x i1> %cond, <2 x i64> %a, <2 x i64> %b 520 %y = select <2 x i1> %cond, <2 x i64> %c, <2 x i64> %d 521 %z = add <2 x i64> %x, %y 522 ret <2 x i64> %z 523} 524 525; Similar to above, but condition has a use that isn't a condition of a vselect so we can't optimize. 526define <2 x i64> @shrunkblend_nonvselectuse(<2 x i1> %cond, <2 x i64> %a, <2 x i64> %b, <2 x i64> %c, <2 x i64> %d) { 527; SSE2-LABEL: shrunkblend_nonvselectuse: 528; SSE2: # %bb.0: 529; SSE2-NEXT: psllq $63, %xmm0 530; SSE2-NEXT: psrad $31, %xmm0 531; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] 532; SSE2-NEXT: movdqa %xmm3, %xmm0 533; SSE2-NEXT: pandn %xmm2, %xmm0 534; SSE2-NEXT: pand %xmm3, %xmm1 535; SSE2-NEXT: por %xmm1, %xmm0 536; SSE2-NEXT: paddq %xmm3, %xmm0 537; SSE2-NEXT: retq 538; 539; SSE41-LABEL: shrunkblend_nonvselectuse: 540; SSE41: # %bb.0: 541; SSE41-NEXT: psllq $63, %xmm0 542; SSE41-NEXT: psrad $31, %xmm0 543; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 544; SSE41-NEXT: blendvpd %xmm0, %xmm1, %xmm2 545; SSE41-NEXT: paddq %xmm2, %xmm0 546; SSE41-NEXT: retq 547; 548; AVX-LABEL: shrunkblend_nonvselectuse: 549; AVX: # %bb.0: 550; AVX-NEXT: vpsllq $63, %xmm0, %xmm0 551; AVX-NEXT: vpxor %xmm3, %xmm3, %xmm3 552; AVX-NEXT: vpcmpgtq %xmm0, %xmm3, %xmm0 553; AVX-NEXT: vblendvpd %xmm0, %xmm1, %xmm2, %xmm1 554; AVX-NEXT: vpaddq %xmm0, %xmm1, %xmm0 555; AVX-NEXT: retq 556 %x = select <2 x i1> %cond, <2 x i64> %a, <2 x i64> %b 557 %y = sext <2 x i1> %cond to <2 x i64> 558 %z = add <2 x i64> %x, %y 559 ret <2 x i64> %z 560} 561 562; This turns into a SHRUNKBLEND with SSE4 or later, and via 563; late shuffle magic, both sides of the blend are the same 564; value. If that is not simplified before isel, it can fail 565; to match (crash). 566 567define <2 x i32> @simplify_select(i32 %x, <2 x i1> %z) { 568; SSE2-LABEL: simplify_select: 569; SSE2: # %bb.0: 570; SSE2-NEXT: # kill: def $edi killed $edi def $rdi 571; SSE2-NEXT: psllq $63, %xmm0 572; SSE2-NEXT: psrad $31, %xmm0 573; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] 574; SSE2-NEXT: movq %rdi, %xmm1 575; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[0,1,0,1] 576; SSE2-NEXT: movdqa %xmm2, %xmm3 577; SSE2-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm1[0] 578; SSE2-NEXT: pand %xmm0, %xmm2 579; SSE2-NEXT: pandn %xmm3, %xmm0 580; SSE2-NEXT: por %xmm2, %xmm0 581; SSE2-NEXT: retq 582; 583; SSE41-LABEL: simplify_select: 584; SSE41: # %bb.0: 585; SSE41-NEXT: # kill: def $edi killed $edi def $rdi 586; SSE41-NEXT: movq %rdi, %xmm0 587; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 588; SSE41-NEXT: retq 589; 590; AVX1-LABEL: simplify_select: 591; AVX1: # %bb.0: 592; AVX1-NEXT: # kill: def $edi killed $edi def $rdi 593; AVX1-NEXT: vmovq %rdi, %xmm0 594; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1] 595; AVX1-NEXT: retq 596; 597; AVX2-LABEL: simplify_select: 598; AVX2: # %bb.0: 599; AVX2-NEXT: # kill: def $edi killed $edi def $rdi 600; AVX2-NEXT: vmovq %rdi, %xmm0 601; AVX2-NEXT: vpbroadcastq %xmm0, %xmm0 602; AVX2-NEXT: retq 603 %a = insertelement <2 x i32> <i32 0, i32 undef>, i32 %x, i32 1 604 %b = insertelement <2 x i32> <i32 undef, i32 0>, i32 %x, i32 0 605 %y = or <2 x i32> %a, %b 606 %p16 = extractelement <2 x i32> %y, i32 1 607 %p17 = insertelement <2 x i32> undef, i32 %p16, i32 0 608 %p18 = insertelement <2 x i32> %p17, i32 %x, i32 1 609 %r = select <2 x i1> %z, <2 x i32> %y, <2 x i32> %p18 610 ret <2 x i32> %r 611} 612 613