795 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE23; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE414; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX15; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX26 7; PR66101 - Fold select (sext m), (add X, C), X --> (add X, (and C, (sext m))))8define <4 x i32> @masked_select_const(<4 x i32> %a, <4 x i32> %x, <4 x i32> %y) {9; SSE-LABEL: masked_select_const:10; SSE: # %bb.0:11; SSE-NEXT: pcmpgtd %xmm2, %xmm112; SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm113; SSE-NEXT: paddd %xmm1, %xmm014; SSE-NEXT: retq15;16; AVX1-LABEL: masked_select_const:17; AVX1: # %bb.0:18; AVX1-NEXT: vpcmpgtd %xmm2, %xmm1, %xmm119; AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm120; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm021; AVX1-NEXT: retq22;23; AVX2-LABEL: masked_select_const:24; AVX2: # %bb.0:25; AVX2-NEXT: vpbroadcastd {{.*#+}} xmm3 = [4294967272,4294967272,4294967272,4294967272]26; AVX2-NEXT: vpcmpgtd %xmm2, %xmm1, %xmm127; AVX2-NEXT: vpand %xmm3, %xmm1, %xmm128; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm029; AVX2-NEXT: retq30 %sub.i = add <4 x i32> %a, <i32 -24, i32 -24, i32 -24, i32 -24>31 %cmp.i = icmp sgt <4 x i32> %x, %y32 %sel = select <4 x i1> %cmp.i, <4 x i32> %sub.i, <4 x i32> %a33 ret <4 x i32> %sel34}35 36; Verify that we don't emit packed vector shifts instructions if the37; condition used by the vector select is a vector of constants.38 39define <4 x float> @test1(<4 x float> %a, <4 x float> %b) {40; SSE2-LABEL: test1:41; SSE2: # %bb.0:42; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]43; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]44; SSE2-NEXT: retq45;46; SSE41-LABEL: test1:47; SSE41: # %bb.0:48; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]49; SSE41-NEXT: retq50;51; AVX-LABEL: test1:52; AVX: # %bb.0:53; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]54; AVX-NEXT: retq55 %1 = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x float> %a, <4 x float> %b56 ret <4 x float> %157}58 59define <4 x float> @test2(<4 x float> %a, <4 x float> %b) {60; SSE2-LABEL: test2:61; SSE2: # %bb.0:62; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]63; SSE2-NEXT: retq64;65; SSE41-LABEL: test2:66; SSE41: # %bb.0:67; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]68; SSE41-NEXT: retq69;70; AVX-LABEL: test2:71; AVX: # %bb.0:72; AVX-NEXT: vmovsd {{.*#+}} xmm0 = xmm0[0],xmm1[1]73; AVX-NEXT: retq74 %1 = select <4 x i1> <i1 true, i1 true, i1 false, i1 false>, <4 x float> %a, <4 x float> %b75 ret <4 x float> %176}77 78define <4 x float> @test3(<4 x float> %a, <4 x float> %b) {79; SSE-LABEL: test3:80; SSE: # %bb.0:81; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]82; SSE-NEXT: retq83;84; AVX-LABEL: test3:85; AVX: # %bb.0:86; AVX-NEXT: vmovsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]87; AVX-NEXT: retq88 %1 = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x float> %a, <4 x float> %b89 ret <4 x float> %190}91 92define <4 x float> @test4(<4 x float> %a, <4 x float> %b) {93; SSE-LABEL: test4:94; SSE: # %bb.0:95; SSE-NEXT: movaps %xmm1, %xmm096; SSE-NEXT: retq97;98; AVX-LABEL: test4:99; AVX: # %bb.0:100; AVX-NEXT: vmovaps %xmm1, %xmm0101; AVX-NEXT: retq102 %1 = select <4 x i1> <i1 false, i1 false, i1 false, i1 false>, <4 x float> %a, <4 x float> %b103 ret <4 x float> %1104}105 106define <4 x float> @test5(<4 x float> %a, <4 x float> %b) {107; SSE-LABEL: test5:108; SSE: # %bb.0:109; SSE-NEXT: retq110;111; AVX-LABEL: test5:112; AVX: # %bb.0:113; AVX-NEXT: retq114 %1 = select <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x float> %a, <4 x float> %b115 ret <4 x float> %1116}117 118define <8 x i16> @test6(<8 x i16> %a, <8 x i16> %b) {119; SSE-LABEL: test6:120; SSE: # %bb.0:121; SSE-NEXT: retq122;123; AVX-LABEL: test6:124; AVX: # %bb.0:125; AVX-NEXT: retq126 %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> %a127 ret <8 x i16> %1128}129 130define <8 x i16> @test7(<8 x i16> %a, <8 x i16> %b) {131; SSE2-LABEL: test7:132; SSE2: # %bb.0:133; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]134; SSE2-NEXT: retq135;136; SSE41-LABEL: test7:137; SSE41: # %bb.0:138; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]139; SSE41-NEXT: retq140;141; AVX-LABEL: test7:142; AVX: # %bb.0:143; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]144; AVX-NEXT: retq145 %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> %b146 ret <8 x i16> %1147}148 149define <8 x i16> @test8(<8 x i16> %a, <8 x i16> %b) {150; SSE-LABEL: test8:151; SSE: # %bb.0:152; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]153; SSE-NEXT: retq154;155; AVX-LABEL: test8:156; AVX: # %bb.0:157; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]158; AVX-NEXT: retq159 %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> %b160 ret <8 x i16> %1161}162 163define <8 x i16> @test9(<8 x i16> %a, <8 x i16> %b) {164; SSE-LABEL: test9:165; SSE: # %bb.0:166; SSE-NEXT: movaps %xmm1, %xmm0167; SSE-NEXT: retq168;169; AVX-LABEL: test9:170; AVX: # %bb.0:171; AVX-NEXT: vmovaps %xmm1, %xmm0172; AVX-NEXT: retq173 %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> %b174 ret <8 x i16> %1175}176 177define <8 x i16> @test10(<8 x i16> %a, <8 x i16> %b) {178; SSE-LABEL: test10:179; SSE: # %bb.0:180; SSE-NEXT: retq181;182; AVX-LABEL: test10:183; AVX: # %bb.0:184; AVX-NEXT: retq185 %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> %b186 ret <8 x i16> %1187}188 189define <8 x i16> @test11(<8 x i16> %a, <8 x i16> %b) {190; SSE2-LABEL: test11:191; SSE2: # %bb.0:192; SSE2-NEXT: movaps {{.*#+}} xmm2 = [0,65535,65535,0,0,65535,65535,0]193; SSE2-NEXT: andps %xmm2, %xmm0194; SSE2-NEXT: andnps %xmm1, %xmm2195; SSE2-NEXT: orps %xmm2, %xmm0196; SSE2-NEXT: retq197;198; SSE41-LABEL: test11:199; SSE41: # %bb.0:200; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1,2],xmm1[3,4],xmm0[5,6],xmm1[7]201; SSE41-NEXT: retq202;203; AVX-LABEL: test11:204; AVX: # %bb.0:205; AVX-NEXT: vpblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1,2],xmm1[3,4],xmm0[5,6],xmm1[7]206; AVX-NEXT: retq207 %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> %b208 ret <8 x i16> %1209}210 211define <8 x i16> @test12(<8 x i16> %a, <8 x i16> %b) {212; SSE-LABEL: test12:213; SSE: # %bb.0:214; SSE-NEXT: movaps %xmm1, %xmm0215; SSE-NEXT: retq216;217; AVX-LABEL: test12:218; AVX: # %bb.0:219; AVX-NEXT: vmovaps %xmm1, %xmm0220; AVX-NEXT: retq221 %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> %b222 ret <8 x i16> %1223}224 225define <8 x i16> @test13(<8 x i16> %a, <8 x i16> %b) {226; SSE-LABEL: test13:227; SSE: # %bb.0:228; SSE-NEXT: movaps %xmm1, %xmm0229; SSE-NEXT: retq230;231; AVX-LABEL: test13:232; AVX: # %bb.0:233; AVX-NEXT: vmovaps %xmm1, %xmm0234; AVX-NEXT: retq235 %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> %b236 ret <8 x i16> %1237}238 239; Fold (vselect (build_vector AllOnes), N1, N2) -> N1240define <4 x float> @test14(<4 x float> %a, <4 x float> %b) {241; SSE-LABEL: test14:242; SSE: # %bb.0:243; SSE-NEXT: retq244;245; AVX-LABEL: test14:246; AVX: # %bb.0:247; AVX-NEXT: retq248 %1 = select <4 x i1> <i1 true, i1 undef, i1 true, i1 undef>, <4 x float> %a, <4 x float> %b249 ret <4 x float> %1250}251 252define <8 x i16> @test15(<8 x i16> %a, <8 x i16> %b) {253; SSE-LABEL: test15:254; SSE: # %bb.0:255; SSE-NEXT: retq256;257; AVX-LABEL: test15:258; AVX: # %bb.0:259; AVX-NEXT: retq260 %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> %b261 ret <8 x i16> %1262}263 264; Fold (vselect (build_vector AllZeros), N1, N2) -> N2265define <4 x float> @test16(<4 x float> %a, <4 x float> %b) {266; SSE-LABEL: test16:267; SSE: # %bb.0:268; SSE-NEXT: movaps %xmm1, %xmm0269; SSE-NEXT: retq270;271; AVX-LABEL: test16:272; AVX: # %bb.0:273; AVX-NEXT: vmovaps %xmm1, %xmm0274; AVX-NEXT: retq275 %1 = select <4 x i1> <i1 false, i1 undef, i1 false, i1 undef>, <4 x float> %a, <4 x float> %b276 ret <4 x float> %1277}278 279define <8 x i16> @test17(<8 x i16> %a, <8 x i16> %b) {280; SSE-LABEL: test17:281; SSE: # %bb.0:282; SSE-NEXT: movaps %xmm1, %xmm0283; SSE-NEXT: retq284;285; AVX-LABEL: test17:286; AVX: # %bb.0:287; AVX-NEXT: vmovaps %xmm1, %xmm0288; AVX-NEXT: retq289 %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> %b290 ret <8 x i16> %1291}292 293define <4 x float> @test18(<4 x float> %a, <4 x float> %b) {294; SSE-LABEL: test18:295; SSE: # %bb.0:296; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]297; SSE-NEXT: retq298;299; AVX-LABEL: test18:300; AVX: # %bb.0:301; AVX-NEXT: vmovss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]302; AVX-NEXT: retq303 %1 = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x float> %a, <4 x float> %b304 ret <4 x float> %1305}306 307define <4 x i32> @test19(<4 x i32> %a, <4 x i32> %b) {308; SSE-LABEL: test19:309; SSE: # %bb.0:310; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]311; SSE-NEXT: retq312;313; AVX-LABEL: test19:314; AVX: # %bb.0:315; AVX-NEXT: vmovss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]316; AVX-NEXT: retq317 %1 = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x i32> %a, <4 x i32> %b318 ret <4 x i32> %1319}320 321define <2 x double> @test20(<2 x double> %a, <2 x double> %b) {322; SSE-LABEL: test20:323; SSE: # %bb.0:324; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]325; SSE-NEXT: retq326;327; AVX-LABEL: test20:328; AVX: # %bb.0:329; AVX-NEXT: vmovsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]330; AVX-NEXT: retq331 %1 = select <2 x i1> <i1 false, i1 true>, <2 x double> %a, <2 x double> %b332 ret <2 x double> %1333}334 335define <2 x i64> @test21(<2 x i64> %a, <2 x i64> %b) {336; SSE-LABEL: test21:337; SSE: # %bb.0:338; SSE-NEXT: movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]339; SSE-NEXT: retq340;341; AVX-LABEL: test21:342; AVX: # %bb.0:343; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]344; AVX-NEXT: retq345 %1 = select <2 x i1> <i1 false, i1 true>, <2 x i64> %a, <2 x i64> %b346 ret <2 x i64> %1347}348 349define <4 x float> @test22(<4 x float> %a, <4 x float> %b) {350; SSE2-LABEL: test22:351; SSE2: # %bb.0:352; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]353; SSE2-NEXT: movaps %xmm1, %xmm0354; SSE2-NEXT: retq355;356; SSE41-LABEL: test22:357; SSE41: # %bb.0:358; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]359; SSE41-NEXT: retq360;361; AVX-LABEL: test22:362; AVX: # %bb.0:363; AVX-NEXT: vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]364; AVX-NEXT: retq365 %1 = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %a, <4 x float> %b366 ret <4 x float> %1367}368 369define <4 x i32> @test23(<4 x i32> %a, <4 x i32> %b) {370; SSE2-LABEL: test23:371; SSE2: # %bb.0:372; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]373; SSE2-NEXT: movaps %xmm1, %xmm0374; SSE2-NEXT: retq375;376; SSE41-LABEL: test23:377; SSE41: # %bb.0:378; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]379; SSE41-NEXT: retq380;381; AVX-LABEL: test23:382; AVX: # %bb.0:383; AVX-NEXT: vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]384; AVX-NEXT: retq385 %1 = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x i32> %a, <4 x i32> %b386 ret <4 x i32> %1387}388 389define <2 x double> @test24(<2 x double> %a, <2 x double> %b) {390; SSE2-LABEL: test24:391; SSE2: # %bb.0:392; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]393; SSE2-NEXT: retq394;395; SSE41-LABEL: test24:396; SSE41: # %bb.0:397; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]398; SSE41-NEXT: retq399;400; AVX-LABEL: test24:401; AVX: # %bb.0:402; AVX-NEXT: vmovsd {{.*#+}} xmm0 = xmm0[0],xmm1[1]403; AVX-NEXT: retq404 %1 = select <2 x i1> <i1 true, i1 false>, <2 x double> %a, <2 x double> %b405 ret <2 x double> %1406}407 408define <2 x i64> @test25(<2 x i64> %a, <2 x i64> %b) {409; SSE2-LABEL: test25:410; SSE2: # %bb.0:411; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]412; SSE2-NEXT: retq413;414; SSE41-LABEL: test25:415; SSE41: # %bb.0:416; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]417; SSE41-NEXT: retq418;419; AVX-LABEL: test25:420; AVX: # %bb.0:421; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]422; AVX-NEXT: retq423 %1 = select <2 x i1> <i1 true, i1 false>, <2 x i64> %a, <2 x i64> %b424 ret <2 x i64> %1425}426 427define <16 x i8> @test26(<16 x i8> %a, <16 x i8> %b) {428; SSE2-LABEL: test26:429; SSE2: # %bb.0:430; SSE2-NEXT: movaps {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]431; SSE2-NEXT: andps %xmm2, %xmm1432; SSE2-NEXT: andnps %xmm0, %xmm2433; SSE2-NEXT: orps %xmm1, %xmm2434; SSE2-NEXT: movaps %xmm2, %xmm0435; SSE2-NEXT: retq436;437; SSE41-LABEL: test26:438; SSE41: # %bb.0:439; SSE41-NEXT: movdqa %xmm0, %xmm2440; SSE41-NEXT: movaps {{.*#+}} xmm0 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]441; SSE41-NEXT: pblendvb %xmm0, %xmm1, %xmm2442; SSE41-NEXT: movdqa %xmm2, %xmm0443; SSE41-NEXT: retq444;445; AVX1-LABEL: test26:446; AVX1: # %bb.0:447; AVX1-NEXT: vbroadcastss {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]448; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0449; AVX1-NEXT: retq450;451; AVX2-LABEL: test26:452; AVX2: # %bb.0:453; AVX2-NEXT: vpbroadcastw {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]454; AVX2-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0455; AVX2-NEXT: retq456 %1 = select <16 x i1> <i1 false, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true>, <16 x i8> %a, <16 x i8> %b457 ret <16 x i8> %1458}459 460define <32 x i8> @test27(<32 x i8> %a, <32 x i8> %b) {461; SSE2-LABEL: test27:462; SSE2: # %bb.0:463; SSE2-NEXT: movaps {{.*#+}} xmm4 = [255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255]464; SSE2-NEXT: movaps %xmm4, %xmm5465; SSE2-NEXT: andnps %xmm2, %xmm5466; SSE2-NEXT: andps %xmm4, %xmm0467; SSE2-NEXT: orps %xmm5, %xmm0468; SSE2-NEXT: andps %xmm4, %xmm1469; SSE2-NEXT: andnps %xmm3, %xmm4470; SSE2-NEXT: orps %xmm4, %xmm1471; SSE2-NEXT: retq472;473; SSE41-LABEL: test27:474; SSE41: # %bb.0:475; SSE41-NEXT: movdqa %xmm0, %xmm4476; SSE41-NEXT: movaps {{.*#+}} xmm0 = [255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255]477; SSE41-NEXT: pblendvb %xmm0, %xmm4, %xmm2478; SSE41-NEXT: pblendvb %xmm0, %xmm1, %xmm3479; SSE41-NEXT: movdqa %xmm2, %xmm0480; SSE41-NEXT: movdqa %xmm3, %xmm1481; SSE41-NEXT: retq482;483; AVX1-LABEL: test27:484; AVX1: # %bb.0:485; AVX1-NEXT: vbroadcastss {{.*#+}} ymm2 = [255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255]486; AVX1-NEXT: vandnps %ymm1, %ymm2, %ymm1487; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm0488; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm0489; AVX1-NEXT: retq490;491; AVX2-LABEL: test27:492; AVX2: # %bb.0:493; AVX2-NEXT: vpbroadcastd {{.*#+}} ymm2 = [255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255]494; AVX2-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0495; AVX2-NEXT: retq496 %1 = select <32 x i1> <i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true>, <32 x i8> %a, <32 x i8> %b497 ret <32 x i8> %1498}499 500define <4 x float> @select_of_shuffles_0(<2 x float> %a0, <2 x float> %b0, <2 x float> %a1, <2 x float> %b1) {501; SSE-LABEL: select_of_shuffles_0:502; SSE: # %bb.0:503; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm2[0]504; SSE-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm3[0]505; SSE-NEXT: subps %xmm1, %xmm0506; SSE-NEXT: retq507;508; AVX-LABEL: select_of_shuffles_0:509; AVX: # %bb.0:510; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm2[0]511; AVX-NEXT: vmovlhps {{.*#+}} xmm1 = xmm1[0],xmm3[0]512; AVX-NEXT: vsubps %xmm1, %xmm0, %xmm0513; AVX-NEXT: retq514 %1 = shufflevector <2 x float> %a0, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>515 %2 = shufflevector <2 x float> %a1, <2 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 0, i32 1>516 %3 = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x float> %2, <4 x float> %1517 %4 = shufflevector <2 x float> %b0, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>518 %5 = shufflevector <2 x float> %b1, <2 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 0, i32 1>519 %6 = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x float> %5, <4 x float> %4520 %7 = fsub <4 x float> %3, %6521 ret <4 x float> %7522}523 524; PR20677525define <16 x double> @select_illegal(<16 x double> %a, <16 x double> %b) {526; SSE-LABEL: select_illegal:527; SSE: # %bb.0:528; SSE-NEXT: movq %rdi, %rax529; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm4530; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm5531; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm6532; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm7533; SSE-NEXT: movaps %xmm7, 112(%rdi)534; SSE-NEXT: movaps %xmm6, 96(%rdi)535; SSE-NEXT: movaps %xmm5, 80(%rdi)536; SSE-NEXT: movaps %xmm4, 64(%rdi)537; SSE-NEXT: movaps %xmm3, 48(%rdi)538; SSE-NEXT: movaps %xmm2, 32(%rdi)539; SSE-NEXT: movaps %xmm1, 16(%rdi)540; SSE-NEXT: movaps %xmm0, (%rdi)541; SSE-NEXT: retq542;543; AVX-LABEL: select_illegal:544; AVX: # %bb.0:545; AVX-NEXT: vmovaps %ymm7, %ymm3546; AVX-NEXT: vmovaps %ymm6, %ymm2547; AVX-NEXT: retq548 %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> %b549 ret <16 x double> %sel550}551 552; Make sure we can optimize the condition MSB when it is used by 2 selects.553; The v2i1 here will be passed as v2i64 and we will emit a sign_extend_inreg to fill the upper bits.554; We should be able to remove the sra from the sign_extend_inreg to leave only shl.555define <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) {556; SSE2-LABEL: shrunkblend_2uses:557; SSE2: # %bb.0:558; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,0,2,2]559; SSE2-NEXT: pslld $31, %xmm0560; SSE2-NEXT: psrad $31, %xmm0561; SSE2-NEXT: movdqa %xmm0, %xmm5562; SSE2-NEXT: pandn %xmm2, %xmm5563; SSE2-NEXT: pand %xmm0, %xmm1564; SSE2-NEXT: por %xmm1, %xmm5565; SSE2-NEXT: pand %xmm0, %xmm3566; SSE2-NEXT: pandn %xmm4, %xmm0567; SSE2-NEXT: por %xmm3, %xmm0568; SSE2-NEXT: paddq %xmm5, %xmm0569; SSE2-NEXT: retq570;571; SSE41-LABEL: shrunkblend_2uses:572; SSE41: # %bb.0:573; SSE41-NEXT: psllq $63, %xmm0574; SSE41-NEXT: blendvpd %xmm0, %xmm1, %xmm2575; SSE41-NEXT: blendvpd %xmm0, %xmm3, %xmm4576; SSE41-NEXT: paddq %xmm2, %xmm4577; SSE41-NEXT: movdqa %xmm4, %xmm0578; SSE41-NEXT: retq579;580; AVX-LABEL: shrunkblend_2uses:581; AVX: # %bb.0:582; AVX-NEXT: vpsllq $63, %xmm0, %xmm0583; AVX-NEXT: vblendvpd %xmm0, %xmm1, %xmm2, %xmm1584; AVX-NEXT: vblendvpd %xmm0, %xmm3, %xmm4, %xmm0585; AVX-NEXT: vpaddq %xmm0, %xmm1, %xmm0586; AVX-NEXT: retq587 %x = select <2 x i1> %cond, <2 x i64> %a, <2 x i64> %b588 %y = select <2 x i1> %cond, <2 x i64> %c, <2 x i64> %d589 %z = add <2 x i64> %x, %y590 ret <2 x i64> %z591}592 593; Similar to above, but condition has a use that isn't a condition of a vselect so we can't optimize.594define <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) {595; SSE2-LABEL: shrunkblend_nonvselectuse:596; SSE2: # %bb.0:597; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm0[0,0,2,2]598; SSE2-NEXT: pslld $31, %xmm3599; SSE2-NEXT: psrad $31, %xmm3600; SSE2-NEXT: movdqa %xmm3, %xmm0601; SSE2-NEXT: pandn %xmm2, %xmm0602; SSE2-NEXT: pand %xmm3, %xmm1603; SSE2-NEXT: por %xmm1, %xmm0604; SSE2-NEXT: paddq %xmm3, %xmm0605; SSE2-NEXT: retq606;607; SSE41-LABEL: shrunkblend_nonvselectuse:608; SSE41: # %bb.0:609; SSE41-NEXT: psllq $63, %xmm0610; SSE41-NEXT: blendvpd %xmm0, %xmm1, %xmm2611; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]612; SSE41-NEXT: psrad $31, %xmm0613; SSE41-NEXT: paddq %xmm2, %xmm0614; SSE41-NEXT: retq615;616; AVX-LABEL: shrunkblend_nonvselectuse:617; AVX: # %bb.0:618; AVX-NEXT: vpsllq $63, %xmm0, %xmm0619; AVX-NEXT: vblendvpd %xmm0, %xmm1, %xmm2, %xmm1620; AVX-NEXT: vxorpd %xmm2, %xmm2, %xmm2621; AVX-NEXT: vpcmpgtq %xmm0, %xmm2, %xmm0622; AVX-NEXT: vpaddq %xmm0, %xmm1, %xmm0623; AVX-NEXT: retq624 %x = select <2 x i1> %cond, <2 x i64> %a, <2 x i64> %b625 %y = sext <2 x i1> %cond to <2 x i64>626 %z = add <2 x i64> %x, %y627 ret <2 x i64> %z628}629 630; This turns into a SHRUNKBLEND with SSE4 or later, and via631; late shuffle magic, both sides of the blend are the same632; value. If that is not simplified before isel, it can fail633; to match (crash).634 635define <2 x i32> @simplify_select(i32 %x, <2 x i1> %z) {636; SSE2-LABEL: simplify_select:637; SSE2: # %bb.0:638; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]639; SSE2-NEXT: pslld $31, %xmm0640; SSE2-NEXT: psrad $31, %xmm0641; SSE2-NEXT: movd %edi, %xmm1642; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,0,1,1]643; SSE2-NEXT: por %xmm1, %xmm2644; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0,0]645; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm2[1,1]646; SSE2-NEXT: pand %xmm0, %xmm2647; SSE2-NEXT: pandn %xmm1, %xmm0648; SSE2-NEXT: por %xmm2, %xmm0649; SSE2-NEXT: retq650;651; SSE41-LABEL: simplify_select:652; SSE41: # %bb.0:653; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]654; SSE41-NEXT: pslld $31, %xmm0655; SSE41-NEXT: movd %edi, %xmm1656; SSE41-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,0,1,1]657; SSE41-NEXT: por %xmm1, %xmm2658; SSE41-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,1,1,1]659; SSE41-NEXT: pinsrd $1, %edi, %xmm1660; SSE41-NEXT: blendvps %xmm0, %xmm2, %xmm1661; SSE41-NEXT: movaps %xmm1, %xmm0662; SSE41-NEXT: retq663;664; AVX-LABEL: simplify_select:665; AVX: # %bb.0:666; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]667; AVX-NEXT: vpslld $31, %xmm0, %xmm0668; AVX-NEXT: vmovd %edi, %xmm1669; AVX-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,0,1,1]670; AVX-NEXT: vpor %xmm1, %xmm2, %xmm1671; AVX-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,1,1]672; AVX-NEXT: vpinsrd $1, %edi, %xmm2, %xmm2673; AVX-NEXT: vblendvps %xmm0, %xmm1, %xmm2, %xmm0674; AVX-NEXT: retq675 %a = insertelement <2 x i32> <i32 0, i32 undef>, i32 %x, i32 1676 %b = insertelement <2 x i32> <i32 undef, i32 0>, i32 %x, i32 0677 %y = or <2 x i32> %a, %b678 %p16 = extractelement <2 x i32> %y, i32 1679 %p17 = insertelement <2 x i32> undef, i32 %p16, i32 0680 %p18 = insertelement <2 x i32> %p17, i32 %x, i32 1681 %r = select <2 x i1> %z, <2 x i32> %y, <2 x i32> %p18682 ret <2 x i32> %r683}684 685; Test to make sure we don't try to insert a new setcc to swap the operands686; of select with all zeros LHS if the setcc has additional users.687define void @vselect_allzeros_LHS_multiple_use_setcc(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, ptr %p1, ptr %p2) {688; SSE2-LABEL: vselect_allzeros_LHS_multiple_use_setcc:689; SSE2: # %bb.0:690; SSE2-NEXT: movdqa {{.*#+}} xmm3 = [1,2,4,8]691; SSE2-NEXT: pand %xmm3, %xmm0692; SSE2-NEXT: pcmpeqd %xmm3, %xmm0693; SSE2-NEXT: movdqa %xmm0, %xmm3694; SSE2-NEXT: pandn %xmm1, %xmm3695; SSE2-NEXT: pand %xmm2, %xmm0696; SSE2-NEXT: movdqa %xmm3, (%rdi)697; SSE2-NEXT: movdqa %xmm0, (%rsi)698; SSE2-NEXT: retq699;700; SSE41-LABEL: vselect_allzeros_LHS_multiple_use_setcc:701; SSE41: # %bb.0:702; SSE41-NEXT: pmovsxbd {{.*#+}} xmm3 = [1,2,4,8]703; SSE41-NEXT: pand %xmm3, %xmm0704; SSE41-NEXT: pcmpeqd %xmm3, %xmm0705; SSE41-NEXT: movdqa %xmm0, %xmm3706; SSE41-NEXT: pandn %xmm1, %xmm3707; SSE41-NEXT: pand %xmm2, %xmm0708; SSE41-NEXT: movdqa %xmm3, (%rdi)709; SSE41-NEXT: movdqa %xmm0, (%rsi)710; SSE41-NEXT: retq711;712; AVX-LABEL: vselect_allzeros_LHS_multiple_use_setcc:713; AVX: # %bb.0:714; AVX-NEXT: vpmovsxbd {{.*#+}} xmm3 = [1,2,4,8]715; AVX-NEXT: vpand %xmm3, %xmm0, %xmm0716; AVX-NEXT: vpcmpeqd %xmm3, %xmm0, %xmm0717; AVX-NEXT: vpandn %xmm1, %xmm0, %xmm1718; AVX-NEXT: vpand %xmm2, %xmm0, %xmm0719; AVX-NEXT: vmovdqa %xmm1, (%rdi)720; AVX-NEXT: vmovdqa %xmm0, (%rsi)721; AVX-NEXT: retq722 %and = and <4 x i32> %x, <i32 1, i32 2, i32 4, i32 8>723 %cond = icmp ne <4 x i32> %and, zeroinitializer724 %sel1 = select <4 x i1> %cond, <4 x i32> zeroinitializer, <4 x i32> %y725 %sel2 = select <4 x i1> %cond, <4 x i32> %z, <4 x i32> zeroinitializer726 store <4 x i32> %sel1, ptr %p1727 store <4 x i32> %sel2, ptr %p2728 ret void729}730 731; This test case previously crashed after r363802, r363850, and r363856 due732; any_extend_vector_inreg not being handled by the X86 backend.733define i64 @vselect_any_extend_vector_inreg_crash(ptr %x) {734; SSE-LABEL: vselect_any_extend_vector_inreg_crash:735; SSE: # %bb.0:736; SSE-NEXT: movq {{.*#+}} xmm0 = mem[0],zero737; SSE-NEXT: pcmpeqb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0738; SSE-NEXT: movd %xmm0, %eax739; SSE-NEXT: andl $1, %eax740; SSE-NEXT: shll $15, %eax741; SSE-NEXT: retq742;743; AVX1-LABEL: vselect_any_extend_vector_inreg_crash:744; AVX1: # %bb.0:745; AVX1-NEXT: vmovq {{.*#+}} xmm0 = mem[0],zero746; AVX1-NEXT: vpcmpeqb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0747; AVX1-NEXT: vmovd %xmm0, %eax748; AVX1-NEXT: andl $1, %eax749; AVX1-NEXT: shll $15, %eax750; AVX1-NEXT: retq751;752; AVX2-LABEL: vselect_any_extend_vector_inreg_crash:753; AVX2: # %bb.0:754; AVX2-NEXT: vmovq {{.*#+}} xmm0 = mem[0],zero755; AVX2-NEXT: vpbroadcastd {{.*#+}} xmm1 = [49,49,49,49]756; AVX2-NEXT: vpcmpeqb %xmm1, %xmm0, %xmm0757; AVX2-NEXT: vmovd %xmm0, %eax758; AVX2-NEXT: andl $1, %eax759; AVX2-NEXT: shll $15, %eax760; AVX2-NEXT: retq7610:762 %1 = load <8 x i8>, ptr %x763 %2 = icmp eq <8 x i8> %1, <i8 49, i8 49, i8 49, i8 49, i8 49, i8 49, i8 49, i8 49>764 %3 = select <8 x i1> %2, <8 x i64> <i64 32768, i64 16384, i64 8192, i64 4096, i64 2048, i64 1024, i64 512, i64 256>, <8 x i64> zeroinitializer765 %4 = extractelement <8 x i64> %3, i32 0766 ret i64 %4767}768 769; Tests the scalarizeBinOp code in DAGCombiner770define void @scalarize_binop(<1 x i1> %a) {771; SSE-LABEL: scalarize_binop:772; SSE: # %bb.0: # %bb0773; SSE-NEXT: .p2align 4774; SSE-NEXT: .LBB35_1: # %bb1775; SSE-NEXT: # =>This Inner Loop Header: Depth=1776; SSE-NEXT: jmp .LBB35_1777;778; AVX-LABEL: scalarize_binop:779; AVX: # %bb.0: # %bb0780; AVX-NEXT: .p2align 4781; AVX-NEXT: .LBB35_1: # %bb1782; AVX-NEXT: # =>This Inner Loop Header: Depth=1783; AVX-NEXT: jmp .LBB35_1784bb0:785 br label %bb1786 787bb1:788 %b = select <1 x i1> %a, <1 x i1> zeroinitializer, <1 x i1> splat (i1 true)789 br label %bb2790 791bb2:792 %c = extractelement <1 x i1> %b, i32 0793 br label %bb1794}795