brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.0 KiB · 38ea796 Raw
858 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse    | FileCheck %s -check-prefixes=SSE,SSE23; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse4.1 | FileCheck %s -check-prefixes=SSE,SSE44; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx  | FileCheck %s -check-prefixes=AVX,AVX15; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx2 | FileCheck %s -check-prefixes=AVX,AVX26; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=x86-64-v4 | FileCheck %s -check-prefixes=AVX,AVX5127 8; Verify that each of the following test cases is folded into a single9; instruction which performs a blend operation.10 11define <2 x i64> @test1(<2 x i64> %a, <2 x i64> %b) {12; SSE2-LABEL: test1:13; SSE2:       # %bb.0:14; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]15; SSE2-NEXT:    retq16;17; SSE4-LABEL: test1:18; SSE4:       # %bb.0:19; SSE4-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]20; SSE4-NEXT:    retq21;22; AVX-LABEL: test1:23; AVX:       # %bb.0:24; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]25; AVX-NEXT:    retq26  %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>27  %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 1>28  %or = or <2 x i64> %shuf1, %shuf229  ret <2 x i64> %or30}31 32 33define <4 x i32> @test2(<4 x i32> %a, <4 x i32> %b) {34; SSE-LABEL: test2:35; SSE:       # %bb.0:36; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]37; SSE-NEXT:    retq38;39; AVX-LABEL: test2:40; AVX:       # %bb.0:41; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]42; AVX-NEXT:    retq43  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>44  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>45  %or = or <4 x i32> %shuf1, %shuf246  ret <4 x i32> %or47}48 49 50define <2 x i64> @test3(<2 x i64> %a, <2 x i64> %b) {51; SSE-LABEL: test3:52; SSE:       # %bb.0:53; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]54; SSE-NEXT:    retq55;56; AVX-LABEL: test3:57; AVX:       # %bb.0:58; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]59; AVX-NEXT:    retq60  %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 1>61  %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>62  %or = or <2 x i64> %shuf1, %shuf263  ret <2 x i64> %or64}65 66 67define <4 x i32> @test4(<4 x i32> %a, <4 x i32> %b) {68; SSE2-LABEL: test4:69; SSE2:       # %bb.0:70; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]71; SSE2-NEXT:    movaps %xmm1, %xmm072; SSE2-NEXT:    retq73;74; SSE4-LABEL: test4:75; SSE4:       # %bb.0:76; SSE4-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]77; SSE4-NEXT:    retq78;79; AVX1-LABEL: test4:80; AVX1:       # %bb.0:81; AVX1-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]82; AVX1-NEXT:    retq83;84; AVX2-LABEL: test4:85; AVX2:       # %bb.0:86; AVX2-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]87; AVX2-NEXT:    retq88;89; AVX512-LABEL: test4:90; AVX512:       # %bb.0:91; AVX512-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]92; AVX512-NEXT:    retq93  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>94  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 1, i32 2, i32 3>95  %or = or <4 x i32> %shuf1, %shuf296  ret <4 x i32> %or97}98 99 100define <4 x i32> @test5(<4 x i32> %a, <4 x i32> %b) {101; SSE-LABEL: test5:102; SSE:       # %bb.0:103; SSE-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]104; SSE-NEXT:    retq105;106; AVX1-LABEL: test5:107; AVX1:       # %bb.0:108; AVX1-NEXT:    vmovss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]109; AVX1-NEXT:    retq110;111; AVX2-LABEL: test5:112; AVX2:       # %bb.0:113; AVX2-NEXT:    vmovss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]114; AVX2-NEXT:    retq115;116; AVX512-LABEL: test5:117; AVX512:       # %bb.0:118; AVX512-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]119; AVX512-NEXT:    retq120  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 1, i32 2, i32 3>121  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>122  %or = or <4 x i32> %shuf1, %shuf2123  ret <4 x i32> %or124}125 126 127define <4 x i32> @test6(<4 x i32> %a, <4 x i32> %b) {128; SSE2-LABEL: test6:129; SSE2:       # %bb.0:130; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]131; SSE2-NEXT:    retq132;133; SSE4-LABEL: test6:134; SSE4:       # %bb.0:135; SSE4-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]136; SSE4-NEXT:    retq137;138; AVX-LABEL: test6:139; AVX:       # %bb.0:140; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]141; AVX-NEXT:    retq142  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>143  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>144  %or = or <4 x i32> %shuf1, %shuf2145  ret <4 x i32> %or146}147 148 149define <4 x i32> @test7(<4 x i32> %a, <4 x i32> %b) {150; SSE2-LABEL: test7:151; SSE2:       # %bb.0:152; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]153; SSE2-NEXT:    retq154;155; SSE4-LABEL: test7:156; SSE4:       # %bb.0:157; SSE4-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]158; SSE4-NEXT:    retq159;160; AVX-LABEL: test7:161; AVX:       # %bb.0:162; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]163; AVX-NEXT:    retq164  %and1 = and <4 x i32> %a, <i32 -1, i32 -1, i32 0, i32 0>165  %and2 = and <4 x i32> %b, <i32 0, i32 0, i32 -1, i32 -1>166  %or = or <4 x i32> %and1, %and2167  ret <4 x i32> %or168}169 170 171define <2 x i64> @test8(<2 x i64> %a, <2 x i64> %b) {172; SSE2-LABEL: test8:173; SSE2:       # %bb.0:174; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]175; SSE2-NEXT:    retq176;177; SSE4-LABEL: test8:178; SSE4:       # %bb.0:179; SSE4-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]180; SSE4-NEXT:    retq181;182; AVX-LABEL: test8:183; AVX:       # %bb.0:184; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]185; AVX-NEXT:    retq186  %and1 = and <2 x i64> %a, <i64 -1, i64 0>187  %and2 = and <2 x i64> %b, <i64 0, i64 -1>188  %or = or <2 x i64> %and1, %and2189  ret <2 x i64> %or190}191 192 193define <4 x i32> @test9(<4 x i32> %a, <4 x i32> %b) {194; SSE-LABEL: test9:195; SSE:       # %bb.0:196; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]197; SSE-NEXT:    retq198;199; AVX-LABEL: test9:200; AVX:       # %bb.0:201; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]202; AVX-NEXT:    retq203  %and1 = and <4 x i32> %a, <i32 0, i32 0, i32 -1, i32 -1>204  %and2 = and <4 x i32> %b, <i32 -1, i32 -1, i32 0, i32 0>205  %or = or <4 x i32> %and1, %and2206  ret <4 x i32> %or207}208 209 210define <2 x i64> @test10(<2 x i64> %a, <2 x i64> %b) {211; SSE-LABEL: test10:212; SSE:       # %bb.0:213; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]214; SSE-NEXT:    retq215;216; AVX-LABEL: test10:217; AVX:       # %bb.0:218; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]219; AVX-NEXT:    retq220  %and1 = and <2 x i64> %a, <i64 0, i64 -1>221  %and2 = and <2 x i64> %b, <i64 -1, i64 0>222  %or = or <2 x i64> %and1, %and2223  ret <2 x i64> %or224}225 226 227define <4 x i32> @test11(<4 x i32> %a, <4 x i32> %b) {228; SSE2-LABEL: test11:229; SSE2:       # %bb.0:230; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]231; SSE2-NEXT:    movaps %xmm1, %xmm0232; SSE2-NEXT:    retq233;234; SSE4-LABEL: test11:235; SSE4:       # %bb.0:236; SSE4-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]237; SSE4-NEXT:    retq238;239; AVX1-LABEL: test11:240; AVX1:       # %bb.0:241; AVX1-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]242; AVX1-NEXT:    retq243;244; AVX2-LABEL: test11:245; AVX2:       # %bb.0:246; AVX2-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]247; AVX2-NEXT:    retq248;249; AVX512-LABEL: test11:250; AVX512:       # %bb.0:251; AVX512-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]252; AVX512-NEXT:    retq253  %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>254  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 -1>255  %or = or <4 x i32> %and1, %and2256  ret <4 x i32> %or257}258 259 260define <4 x i32> @test12(<4 x i32> %a, <4 x i32> %b) {261; SSE-LABEL: test12:262; SSE:       # %bb.0:263; SSE-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]264; SSE-NEXT:    retq265;266; AVX1-LABEL: test12:267; AVX1:       # %bb.0:268; AVX1-NEXT:    vmovss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]269; AVX1-NEXT:    retq270;271; AVX2-LABEL: test12:272; AVX2:       # %bb.0:273; AVX2-NEXT:    vmovss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]274; AVX2-NEXT:    retq275;276; AVX512-LABEL: test12:277; AVX512:       # %bb.0:278; AVX512-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]279; AVX512-NEXT:    retq280  %and1 = and <4 x i32> %a, <i32 0, i32 -1, i32 -1, i32 -1>281  %and2 = and <4 x i32> %b, <i32 -1, i32 0, i32 0, i32 0>282  %or = or <4 x i32> %and1, %and2283  ret <4 x i32> %or284}285 286 287; Verify that the following test cases are folded into single shuffles.288 289define <4 x i32> @test13(<4 x i32> %a, <4 x i32> %b) {290; SSE-LABEL: test13:291; SSE:       # %bb.0:292; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1],xmm1[2,3]293; SSE-NEXT:    retq294;295; AVX-LABEL: test13:296; AVX:       # %bb.0:297; AVX-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[1,1],xmm1[2,3]298; AVX-NEXT:    retq299  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 1, i32 1, i32 4, i32 4>300  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>301  %or = or <4 x i32> %shuf1, %shuf2302  ret <4 x i32> %or303}304 305 306define <2 x i64> @test14(<2 x i64> %a, <2 x i64> %b) {307; SSE-LABEL: test14:308; SSE:       # %bb.0:309; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]310; SSE-NEXT:    retq311;312; AVX-LABEL: test14:313; AVX:       # %bb.0:314; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]315; AVX-NEXT:    retq316  %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>317  %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>318  %or = or <2 x i64> %shuf1, %shuf2319  ret <2 x i64> %or320}321 322 323define <4 x i32> @test15(<4 x i32> %a, <4 x i32> %b) {324; SSE-LABEL: test15:325; SSE:       # %bb.0:326; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,1],xmm0[2,1]327; SSE-NEXT:    movaps %xmm1, %xmm0328; SSE-NEXT:    retq329;330; AVX-LABEL: test15:331; AVX:       # %bb.0:332; AVX-NEXT:    vshufps {{.*#+}} xmm0 = xmm1[2,1],xmm0[2,1]333; AVX-NEXT:    retq334  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 1>335  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 2, i32 1, i32 4, i32 4>336  %or = or <4 x i32> %shuf1, %shuf2337  ret <4 x i32> %or338}339 340 341define <2 x i64> @test16(<2 x i64> %a, <2 x i64> %b) {342; SSE-LABEL: test16:343; SSE:       # %bb.0:344; SSE-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]345; SSE-NEXT:    movaps %xmm1, %xmm0346; SSE-NEXT:    retq347;348; AVX-LABEL: test16:349; AVX:       # %bb.0:350; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm1[0],xmm0[0]351; AVX-NEXT:    retq352  %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>353  %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>354  %or = or <2 x i64> %shuf1, %shuf2355  ret <2 x i64> %or356}357 358 359; Verify that the dag-combiner does not fold a OR of two shuffles into a single360; shuffle instruction when the shuffle indexes are not compatible.361 362define <4 x i32> @test17(<4 x i32> %a, <4 x i32> %b) {363; SSE-LABEL: test17:364; SSE:       # %bb.0:365; SSE-NEXT:    psllq $32, %xmm0366; SSE-NEXT:    movq {{.*#+}} xmm1 = xmm1[0],zero367; SSE-NEXT:    por %xmm1, %xmm0368; SSE-NEXT:    retq369;370; AVX-LABEL: test17:371; AVX:       # %bb.0:372; AVX-NEXT:    vpsllq $32, %xmm0, %xmm0373; AVX-NEXT:    vmovq {{.*#+}} xmm1 = xmm1[0],zero374; AVX-NEXT:    vpor %xmm1, %xmm0, %xmm0375; AVX-NEXT:    retq376  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 2>377  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>378  %or = or <4 x i32> %shuf1, %shuf2379  ret <4 x i32> %or380}381 382 383define <4 x i32> @test18(<4 x i32> %a, <4 x i32> %b) {384; SSE2-LABEL: test18:385; SSE2:       # %bb.0:386; SSE2-NEXT:    xorps %xmm2, %xmm2387; SSE2-NEXT:    xorps %xmm3, %xmm3388; SSE2-NEXT:    movss {{.*#+}} xmm3 = xmm0[0],xmm3[1,2,3]389; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[1,0,1,1]390; SSE2-NEXT:    movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]391; SSE2-NEXT:    orps %xmm0, %xmm2392; SSE2-NEXT:    movaps %xmm2, %xmm0393; SSE2-NEXT:    retq394;395; SSE4-LABEL: test18:396; SSE4:       # %bb.0:397; SSE4-NEXT:    pxor %xmm2, %xmm2398; SSE4-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3,4,5,6,7]399; SSE4-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,0,1,1]400; SSE4-NEXT:    pblendw {{.*#+}} xmm2 = xmm1[0,1],xmm2[2,3,4,5,6,7]401; SSE4-NEXT:    por %xmm0, %xmm2402; SSE4-NEXT:    movdqa %xmm2, %xmm0403; SSE4-NEXT:    retq404;405; AVX1-LABEL: test18:406; AVX1:       # %bb.0:407; AVX1-NEXT:    vxorps %xmm2, %xmm2, %xmm2408; AVX1-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]409; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[1,0,1,1]410; AVX1-NEXT:    vmovss {{.*#+}} xmm1 = xmm1[0],xmm2[1,2,3]411; AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0412; AVX1-NEXT:    retq413;414; AVX2-LABEL: test18:415; AVX2:       # %bb.0:416; AVX2-NEXT:    vxorps %xmm2, %xmm2, %xmm2417; AVX2-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]418; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[1,0,1,1]419; AVX2-NEXT:    vmovss {{.*#+}} xmm1 = xmm1[0],xmm2[1,2,3]420; AVX2-NEXT:    vorps %xmm1, %xmm0, %xmm0421; AVX2-NEXT:    retq422;423; AVX512-LABEL: test18:424; AVX512:       # %bb.0:425; AVX512-NEXT:    vpshufb {{.*#+}} xmm0 = zero,zero,zero,zero,xmm0[0,1,2,3],zero,zero,zero,zero,zero,zero,zero,zero426; AVX512-NEXT:    vpxor %xmm2, %xmm2, %xmm2427; AVX512-NEXT:    vpblendd {{.*#+}} xmm1 = xmm1[0],xmm2[1,2,3]428; AVX512-NEXT:    vpor %xmm1, %xmm0, %xmm0429; AVX512-NEXT:    retq430  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 4>431  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>432  %or = or <4 x i32> %shuf1, %shuf2433  ret <4 x i32> %or434}435 436 437define <4 x i32> @test19(<4 x i32> %a, <4 x i32> %b) {438; SSE2-LABEL: test19:439; SSE2:       # %bb.0:440; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,3,2,3]441; SSE2-NEXT:    pxor %xmm2, %xmm2442; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]443; SSE2-NEXT:    movdqa %xmm1, %xmm0444; SSE2-NEXT:    pslldq {{.*#+}} xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7]445; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,2]446; SSE2-NEXT:    orps %xmm2, %xmm0447; SSE2-NEXT:    retq448;449; SSE4-LABEL: test19:450; SSE4:       # %bb.0:451; SSE4-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[0,0,2,3]452; SSE4-NEXT:    pxor %xmm3, %xmm3453; SSE4-NEXT:    pblendw {{.*#+}} xmm2 = xmm3[0,1],xmm2[2,3],xmm3[4,5],xmm2[6,7]454; SSE4-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,1,2,2]455; SSE4-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm3[2,3],xmm0[4,5,6,7]456; SSE4-NEXT:    por %xmm2, %xmm0457; SSE4-NEXT:    retq458;459; AVX1-LABEL: test19:460; AVX1:       # %bb.0:461; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,0,2,3]462; AVX1-NEXT:    vxorps %xmm2, %xmm2, %xmm2463; AVX1-NEXT:    vblendps {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3]464; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,1,2,2]465; AVX1-NEXT:    vblendps {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2,3]466; AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0467; AVX1-NEXT:    retq468;469; AVX2-LABEL: test19:470; AVX2:       # %bb.0:471; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,0,2,3]472; AVX2-NEXT:    vxorps %xmm2, %xmm2, %xmm2473; AVX2-NEXT:    vblendps {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3]474; AVX2-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,1,2,2]475; AVX2-NEXT:    vblendps {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2,3]476; AVX2-NEXT:    vorps %xmm1, %xmm0, %xmm0477; AVX2-NEXT:    retq478;479; AVX512-LABEL: test19:480; AVX512:       # %bb.0:481; AVX512-NEXT:    vpshufb {{.*#+}} xmm0 = zero,zero,zero,zero,xmm0[0,1,2,3],zero,zero,zero,zero,xmm0[12,13,14,15]482; AVX512-NEXT:    vpshufb {{.*#+}} xmm1 = xmm1[0,1,2,3],zero,zero,zero,zero,xmm1[8,9,10,11,8,9,10,11]483; AVX512-NEXT:    vpor %xmm1, %xmm0, %xmm0484; AVX512-NEXT:    retq485  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 3>486  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 2, i32 2>487  %or = or <4 x i32> %shuf1, %shuf2488  ret <4 x i32> %or489}490 491 492define <2 x i64> @test20(<2 x i64> %a, <2 x i64> %b) {493; SSE-LABEL: test20:494; SSE:       # %bb.0:495; SSE-NEXT:    por %xmm1, %xmm0496; SSE-NEXT:    movq {{.*#+}} xmm0 = xmm0[0],zero497; SSE-NEXT:    retq498;499; AVX-LABEL: test20:500; AVX:       # %bb.0:501; AVX-NEXT:    vpor %xmm1, %xmm0, %xmm0502; AVX-NEXT:    vmovq {{.*#+}} xmm0 = xmm0[0],zero503; AVX-NEXT:    retq504  %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>505  %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>506  %or = or <2 x i64> %shuf1, %shuf2507  ret <2 x i64> %or508}509 510 511define <2 x i64> @test21(<2 x i64> %a, <2 x i64> %b) {512; SSE-LABEL: test21:513; SSE:       # %bb.0:514; SSE-NEXT:    por %xmm1, %xmm0515; SSE-NEXT:    pslldq {{.*#+}} xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7]516; SSE-NEXT:    retq517;518; AVX1-LABEL: test21:519; AVX1:       # %bb.0:520; AVX1-NEXT:    vpor %xmm1, %xmm0, %xmm0521; AVX1-NEXT:    vpslldq {{.*#+}} xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7]522; AVX1-NEXT:    retq523;524; AVX2-LABEL: test21:525; AVX2:       # %bb.0:526; AVX2-NEXT:    vpor %xmm1, %xmm0, %xmm0527; AVX2-NEXT:    vpslldq {{.*#+}} xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7]528; AVX2-NEXT:    retq529;530; AVX512-LABEL: test21:531; AVX512:       # %bb.0:532; AVX512-NEXT:    vorpd %xmm1, %xmm0, %xmm0533; AVX512-NEXT:    vpslldq {{.*#+}} xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7]534; AVX512-NEXT:    retq535  %shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>536  %shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>537  %or = or <2 x i64> %shuf1, %shuf2538  ret <2 x i64> %or539}540 541 542; Verify that the dag-combiner keeps the correct domain for float/double vectors543; bitcast to use the mask-or blend combine.544 545define <2 x double> @test22(<2 x double> %a0, <2 x double> %a1) {546; SSE-LABEL: test22:547; SSE:       # %bb.0:548; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]549; SSE-NEXT:    retq550;551; AVX1-LABEL: test22:552; AVX1:       # %bb.0:553; AVX1-NEXT:    vmovsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]554; AVX1-NEXT:    retq555;556; AVX2-LABEL: test22:557; AVX2:       # %bb.0:558; AVX2-NEXT:    vmovsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]559; AVX2-NEXT:    retq560;561; AVX512-LABEL: test22:562; AVX512:       # %bb.0:563; AVX512-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]564; AVX512-NEXT:    retq565  %bc1 = bitcast <2 x double> %a0 to <2 x i64>566  %bc2 = bitcast <2 x double> %a1 to <2 x i64>567  %and1 = and <2 x i64> %bc1, <i64 0, i64 -1>568  %and2 = and <2 x i64> %bc2, <i64 -1, i64 0>569  %or = or <2 x i64> %and1, %and2570  %bc3 = bitcast <2 x i64> %or to <2 x double>571  ret <2 x double> %bc3572}573 574 575define <4 x float> @test23(<4 x float> %a0, <4 x float> %a1) {576; SSE2-LABEL: test23:577; SSE2:       # %bb.0:578; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,2],xmm1[0,3]579; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0,1,3]580; SSE2-NEXT:    retq581;582; SSE4-LABEL: test23:583; SSE4:       # %bb.0:584; SSE4-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2],xmm1[3]585; SSE4-NEXT:    retq586;587; AVX-LABEL: test23:588; AVX:       # %bb.0:589; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2],xmm1[3]590; AVX-NEXT:    retq591  %bc1 = bitcast <4 x float> %a0 to <4 x i32>592  %bc2 = bitcast <4 x float> %a1 to <4 x i32>593  %and1 = and <4 x i32> %bc1, <i32 0, i32 -1, i32 -1, i32 0>594  %and2 = and <4 x i32> %bc2, <i32 -1, i32 0, i32 0, i32 -1>595  %or = or <4 x i32> %and1, %and2596  %bc3 = bitcast <4 x i32> %or to <4 x float>597  ret <4 x float> %bc3598}599 600 601define <4 x float> @test24(<4 x float> %a0, <4 x float> %a1) {602; SSE-LABEL: test24:603; SSE:       # %bb.0:604; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]605; SSE-NEXT:    retq606;607; AVX1-LABEL: test24:608; AVX1:       # %bb.0:609; AVX1-NEXT:    vmovsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]610; AVX1-NEXT:    retq611;612; AVX2-LABEL: test24:613; AVX2:       # %bb.0:614; AVX2-NEXT:    vmovsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]615; AVX2-NEXT:    retq616;617; AVX512-LABEL: test24:618; AVX512:       # %bb.0:619; AVX512-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]620; AVX512-NEXT:    retq621  %bc1 = bitcast <4 x float> %a0 to <2 x i64>622  %bc2 = bitcast <4 x float> %a1 to <2 x i64>623  %and1 = and <2 x i64> %bc1, <i64 0, i64 -1>624  %and2 = and <2 x i64> %bc2, <i64 -1, i64 0>625  %or = or <2 x i64> %and1, %and2626  %bc3 = bitcast <2 x i64> %or to <4 x float>627  ret <4 x float> %bc3628}629 630 631define <4 x float> @test25(<4 x float> %a0) {632; SSE2-LABEL: test25:633; SSE2:       # %bb.0:634; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,2],mem[0,3]635; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0,1,3]636; SSE2-NEXT:    retq637;638; SSE4-LABEL: test25:639; SSE4:       # %bb.0:640; SSE4-NEXT:    blendps {{.*#+}} xmm0 = mem[0],xmm0[1,2],mem[3]641; SSE4-NEXT:    retq642;643; AVX1-LABEL: test25:644; AVX1:       # %bb.0:645; AVX1-NEXT:    vblendps {{.*#+}} xmm0 = mem[0],xmm0[1,2],mem[3]646; AVX1-NEXT:    retq647;648; AVX2-LABEL: test25:649; AVX2:       # %bb.0:650; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]651; AVX2-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2],xmm1[3]652; AVX2-NEXT:    retq653;654; AVX512-LABEL: test25:655; AVX512:       # %bb.0:656; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]657; AVX512-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2],xmm1[3]658; AVX512-NEXT:    retq659  %bc1 = bitcast <4 x float> %a0 to <4 x i32>660  %bc2 = bitcast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0> to <4 x i32>661  %and1 = and <4 x i32> %bc1, <i32 0, i32 -1, i32 -1, i32 0>662  %and2 = and <4 x i32> %bc2, <i32 -1, i32 0, i32 0, i32 -1>663  %or = or <4 x i32> %and1, %and2664  %bc3 = bitcast <4 x i32> %or to <4 x float>665  ret <4 x float> %bc3666}667 668 669; Verify that the DAGCombiner doesn't crash in the attempt to check if a shuffle670; with illegal type has a legal mask. Method 'isShuffleMaskLegal' only knows how to671; handle legal vector value types.672define <4 x i8> @test_crash(<4 x i8> %a, <4 x i8> %b) {673; SSE2-LABEL: test_crash:674; SSE2:       # %bb.0:675; SSE2-NEXT:    movaps {{.*#+}} xmm2 = [65535,0,65535,65535,65535,65535,65535,65535]676; SSE2-NEXT:    andps %xmm2, %xmm1677; SSE2-NEXT:    andnps %xmm0, %xmm2678; SSE2-NEXT:    orps %xmm1, %xmm2679; SSE2-NEXT:    movaps %xmm2, %xmm0680; SSE2-NEXT:    retq681;682; SSE4-LABEL: test_crash:683; SSE4:       # %bb.0:684; SSE4-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3,4,5,6,7]685; SSE4-NEXT:    retq686;687; AVX-LABEL: test_crash:688; AVX:       # %bb.0:689; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3,4,5,6,7]690; AVX-NEXT:    retq691  %shuf1 = shufflevector <4 x i8> %a, <4 x i8> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>692  %shuf2 = shufflevector <4 x i8> %b, <4 x i8> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>693  %or = or <4 x i8> %shuf1, %shuf2694  ret <4 x i8> %or695}696 697; Verify that we can fold regardless of which operand is the zeroinitializer698 699define <4 x i32> @test2b(<4 x i32> %a, <4 x i32> %b) {700; SSE-LABEL: test2b:701; SSE:       # %bb.0:702; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]703; SSE-NEXT:    retq704;705; AVX-LABEL: test2b:706; AVX:       # %bb.0:707; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]708; AVX-NEXT:    retq709  %shuf1 = shufflevector <4 x i32> zeroinitializer, <4 x i32> %a, <4 x i32><i32 0, i32 0, i32 6, i32 7>710  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>711  %or = or <4 x i32> %shuf1, %shuf2712  ret <4 x i32> %or713}714 715define <4 x i32> @test2c(<4 x i32> %a, <4 x i32> %b) {716; SSE-LABEL: test2c:717; SSE:       # %bb.0:718; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]719; SSE-NEXT:    retq720;721; AVX-LABEL: test2c:722; AVX:       # %bb.0:723; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]724; AVX-NEXT:    retq725  %shuf1 = shufflevector <4 x i32> zeroinitializer, <4 x i32> %a, <4 x i32><i32 0, i32 0, i32 6, i32 7>726  %shuf2 = shufflevector <4 x i32> zeroinitializer, <4 x i32> %b, <4 x i32><i32 4, i32 5, i32 0, i32 0>727  %or = or <4 x i32> %shuf1, %shuf2728  ret <4 x i32> %or729}730 731 732define <4 x i32> @test2d(<4 x i32> %a, <4 x i32> %b) {733; SSE-LABEL: test2d:734; SSE:       # %bb.0:735; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]736; SSE-NEXT:    retq737;738; AVX-LABEL: test2d:739; AVX:       # %bb.0:740; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]741; AVX-NEXT:    retq742  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>743  %shuf2 = shufflevector <4 x i32> zeroinitializer, <4 x i32> %b, <4 x i32><i32 4, i32 5, i32 0, i32 0>744  %or = or <4 x i32> %shuf1, %shuf2745  ret <4 x i32> %or746}747 748; Make sure we can have an undef where an index pointing to the zero vector should be749 750define <4 x i32> @test2e(<4 x i32> %a, <4 x i32> %b) {751; SSE-LABEL: test2e:752; SSE:       # %bb.0:753; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]754; SSE-NEXT:    retq755;756; AVX-LABEL: test2e:757; AVX:       # %bb.0:758; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]759; AVX-NEXT:    retq760  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>, <4 x i32><i32 undef, i32 4, i32 2, i32 3>761  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>, <4 x i32><i32 0, i32 1, i32 4, i32 4>762  %or = or <4 x i32> %shuf1, %shuf2763  ret <4 x i32> %or764}765 766define <4 x i32> @test2f(<4 x i32> %a, <4 x i32> %b) {767; SSE-LABEL: test2f:768; SSE:       # %bb.0:769; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]770; SSE-NEXT:    retq771;772; AVX-LABEL: test2f:773; AVX:       # %bb.0:774; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]775; AVX-NEXT:    retq776  %shuf1 = shufflevector <4 x i32> %a, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>, <4 x i32><i32 4, i32 4, i32 2, i32 3>777  %shuf2 = shufflevector <4 x i32> %b, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>, <4 x i32><i32 undef, i32 1, i32 4, i32 4>778  %or = or <4 x i32> %shuf1, %shuf2779  ret <4 x i32> %or780}781 782; (or (and X, c1), c2) -> (and (or X, c2), c1|c2) iff (c1 & c2) != 0783 784define <2 x i64> @or_and_v2i64(<2 x i64> %a0) {785; SSE-LABEL: or_and_v2i64:786; SSE:       # %bb.0:787; SSE-NEXT:    orps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0788; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0789; SSE-NEXT:    retq790;791; AVX1-LABEL: or_and_v2i64:792; AVX1:       # %bb.0:793; AVX1-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0794; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0795; AVX1-NEXT:    retq796;797; AVX2-LABEL: or_and_v2i64:798; AVX2:       # %bb.0:799; AVX2-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0800; AVX2-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0801; AVX2-NEXT:    retq802;803; AVX512-LABEL: or_and_v2i64:804; AVX512:       # %bb.0:805; AVX512-NEXT:    vpbroadcastq {{.*#+}} xmm1 = [7,7]806; AVX512-NEXT:    vpternlogq {{.*#+}} xmm0 = xmm1 & (xmm0 | m64bcst)807; AVX512-NEXT:    retq808  %1 = and <2 x i64> %a0, <i64 7, i64 7>809  %2 = or <2 x i64> %1, <i64 3, i64 3>810  ret <2 x i64> %2811}812 813define <4 x i32> @or_and_v4i32(<4 x i32> %a0) {814; SSE-LABEL: or_and_v4i32:815; SSE:       # %bb.0:816; SSE-NEXT:    orps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0817; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0818; SSE-NEXT:    retq819;820; AVX1-LABEL: or_and_v4i32:821; AVX1:       # %bb.0:822; AVX1-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0823; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0824; AVX1-NEXT:    retq825;826; AVX2-LABEL: or_and_v4i32:827; AVX2:       # %bb.0:828; AVX2-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0829; AVX2-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0830; AVX2-NEXT:    retq831;832; AVX512-LABEL: or_and_v4i32:833; AVX512:       # %bb.0:834; AVX512-NEXT:    vmovdqa {{.*#+}} xmm1 = [3,3,15,7]835; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = xmm1 & (xmm0 | mem)836; AVX512-NEXT:    retq837  %1 = and <4 x i32> %a0, <i32 1, i32 3, i32 5, i32 7>838  %2 = or <4 x i32> %1, <i32 3, i32 2, i32 15, i32 2>839  ret <4 x i32> %2840}841 842; If all masked bits are going to be set, that's a constant fold.843 844define <4 x i32> @or_and_v4i32_fold(<4 x i32> %a0) {845; SSE-LABEL: or_and_v4i32_fold:846; SSE:       # %bb.0:847; SSE-NEXT:    movaps {{.*#+}} xmm0 = [3,3,3,3]848; SSE-NEXT:    retq849;850; AVX-LABEL: or_and_v4i32_fold:851; AVX:       # %bb.0:852; AVX-NEXT:    vbroadcastss {{.*#+}} xmm0 = [3,3,3,3]853; AVX-NEXT:    retq854  %1 = and <4 x i32> %a0, <i32 1, i32 1, i32 1, i32 1>855  %2 = or <4 x i32> %1, <i32 3, i32 3, i32 3, i32 3>856  ret <4 x i32> %2857}858