1424 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse2,+sse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSE33; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse2,+sse3,+ssse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSSE34; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX15; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX26 7define <4 x float> @hadd_ps_test1(<4 x float> %A, <4 x float> %B) {8; SSE-LABEL: hadd_ps_test1:9; SSE: # %bb.0:10; SSE-NEXT: haddps %xmm1, %xmm011; SSE-NEXT: retq12;13; AVX-LABEL: hadd_ps_test1:14; AVX: # %bb.0:15; AVX-NEXT: vhaddps %xmm1, %xmm0, %xmm016; AVX-NEXT: retq17 %vecext = extractelement <4 x float> %A, i32 018 %vecext1 = extractelement <4 x float> %A, i32 119 %add = fadd float %vecext, %vecext120 %vecinit = insertelement <4 x float> undef, float %add, i32 021 %vecext2 = extractelement <4 x float> %A, i32 222 %vecext3 = extractelement <4 x float> %A, i32 323 %add4 = fadd float %vecext2, %vecext324 %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 125 %vecext6 = extractelement <4 x float> %B, i32 026 %vecext7 = extractelement <4 x float> %B, i32 127 %add8 = fadd float %vecext6, %vecext728 %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 229 %vecext10 = extractelement <4 x float> %B, i32 230 %vecext11 = extractelement <4 x float> %B, i32 331 %add12 = fadd float %vecext10, %vecext1132 %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 333 ret <4 x float> %vecinit1334}35 36define <4 x float> @hadd_ps_test2(<4 x float> %A, <4 x float> %B) {37; SSE-LABEL: hadd_ps_test2:38; SSE: # %bb.0:39; SSE-NEXT: haddps %xmm1, %xmm040; SSE-NEXT: retq41;42; AVX-LABEL: hadd_ps_test2:43; AVX: # %bb.0:44; AVX-NEXT: vhaddps %xmm1, %xmm0, %xmm045; AVX-NEXT: retq46 %vecext = extractelement <4 x float> %A, i32 247 %vecext1 = extractelement <4 x float> %A, i32 348 %add = fadd float %vecext, %vecext149 %vecinit = insertelement <4 x float> undef, float %add, i32 150 %vecext2 = extractelement <4 x float> %A, i32 051 %vecext3 = extractelement <4 x float> %A, i32 152 %add4 = fadd float %vecext2, %vecext353 %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 054 %vecext6 = extractelement <4 x float> %B, i32 255 %vecext7 = extractelement <4 x float> %B, i32 356 %add8 = fadd float %vecext6, %vecext757 %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 358 %vecext10 = extractelement <4 x float> %B, i32 059 %vecext11 = extractelement <4 x float> %B, i32 160 %add12 = fadd float %vecext10, %vecext1161 %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 262 ret <4 x float> %vecinit1363}64 65define <4 x float> @hsub_ps_test1(<4 x float> %A, <4 x float> %B) {66; SSE-LABEL: hsub_ps_test1:67; SSE: # %bb.0:68; SSE-NEXT: hsubps %xmm1, %xmm069; SSE-NEXT: retq70;71; AVX-LABEL: hsub_ps_test1:72; AVX: # %bb.0:73; AVX-NEXT: vhsubps %xmm1, %xmm0, %xmm074; AVX-NEXT: retq75 %vecext = extractelement <4 x float> %A, i32 076 %vecext1 = extractelement <4 x float> %A, i32 177 %sub = fsub float %vecext, %vecext178 %vecinit = insertelement <4 x float> undef, float %sub, i32 079 %vecext2 = extractelement <4 x float> %A, i32 280 %vecext3 = extractelement <4 x float> %A, i32 381 %sub4 = fsub float %vecext2, %vecext382 %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 183 %vecext6 = extractelement <4 x float> %B, i32 084 %vecext7 = extractelement <4 x float> %B, i32 185 %sub8 = fsub float %vecext6, %vecext786 %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 287 %vecext10 = extractelement <4 x float> %B, i32 288 %vecext11 = extractelement <4 x float> %B, i32 389 %sub12 = fsub float %vecext10, %vecext1190 %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 391 ret <4 x float> %vecinit1392}93 94define <4 x float> @hsub_ps_test2(<4 x float> %A, <4 x float> %B) {95; SSE-LABEL: hsub_ps_test2:96; SSE: # %bb.0:97; SSE-NEXT: hsubps %xmm1, %xmm098; SSE-NEXT: retq99;100; AVX-LABEL: hsub_ps_test2:101; AVX: # %bb.0:102; AVX-NEXT: vhsubps %xmm1, %xmm0, %xmm0103; AVX-NEXT: retq104 %vecext = extractelement <4 x float> %A, i32 2105 %vecext1 = extractelement <4 x float> %A, i32 3106 %sub = fsub float %vecext, %vecext1107 %vecinit = insertelement <4 x float> undef, float %sub, i32 1108 %vecext2 = extractelement <4 x float> %A, i32 0109 %vecext3 = extractelement <4 x float> %A, i32 1110 %sub4 = fsub float %vecext2, %vecext3111 %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 0112 %vecext6 = extractelement <4 x float> %B, i32 2113 %vecext7 = extractelement <4 x float> %B, i32 3114 %sub8 = fsub float %vecext6, %vecext7115 %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 3116 %vecext10 = extractelement <4 x float> %B, i32 0117 %vecext11 = extractelement <4 x float> %B, i32 1118 %sub12 = fsub float %vecext10, %vecext11119 %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 2120 ret <4 x float> %vecinit13121}122 123define <4 x i32> @phadd_d_test1(<4 x i32> %A, <4 x i32> %B) {124; SSE3-LABEL: phadd_d_test1:125; SSE3: # %bb.0:126; SSE3-NEXT: movd %xmm0, %eax127; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,1,1]128; SSE3-NEXT: movd %xmm2, %ecx129; SSE3-NEXT: addl %eax, %ecx130; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]131; SSE3-NEXT: movd %xmm2, %eax132; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]133; SSE3-NEXT: movd %xmm0, %edx134; SSE3-NEXT: addl %eax, %edx135; SSE3-NEXT: movd %xmm1, %eax136; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]137; SSE3-NEXT: movd %xmm0, %esi138; SSE3-NEXT: addl %eax, %esi139; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]140; SSE3-NEXT: movd %xmm0, %eax141; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]142; SSE3-NEXT: movd %xmm0, %edi143; SSE3-NEXT: addl %eax, %edi144; SSE3-NEXT: movd %edi, %xmm0145; SSE3-NEXT: movd %esi, %xmm1146; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]147; SSE3-NEXT: movd %edx, %xmm2148; SSE3-NEXT: movd %ecx, %xmm0149; SSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]150; SSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]151; SSE3-NEXT: retq152;153; SSSE3-LABEL: phadd_d_test1:154; SSSE3: # %bb.0:155; SSSE3-NEXT: phaddd %xmm1, %xmm0156; SSSE3-NEXT: retq157;158; AVX-LABEL: phadd_d_test1:159; AVX: # %bb.0:160; AVX-NEXT: vphaddd %xmm1, %xmm0, %xmm0161; AVX-NEXT: retq162 %vecext = extractelement <4 x i32> %A, i32 0163 %vecext1 = extractelement <4 x i32> %A, i32 1164 %add = add i32 %vecext, %vecext1165 %vecinit = insertelement <4 x i32> undef, i32 %add, i32 0166 %vecext2 = extractelement <4 x i32> %A, i32 2167 %vecext3 = extractelement <4 x i32> %A, i32 3168 %add4 = add i32 %vecext2, %vecext3169 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %add4, i32 1170 %vecext6 = extractelement <4 x i32> %B, i32 0171 %vecext7 = extractelement <4 x i32> %B, i32 1172 %add8 = add i32 %vecext6, %vecext7173 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %add8, i32 2174 %vecext10 = extractelement <4 x i32> %B, i32 2175 %vecext11 = extractelement <4 x i32> %B, i32 3176 %add12 = add i32 %vecext10, %vecext11177 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %add12, i32 3178 ret <4 x i32> %vecinit13179}180 181define <4 x i32> @phadd_d_test2(<4 x i32> %A, <4 x i32> %B) {182; SSE3-LABEL: phadd_d_test2:183; SSE3: # %bb.0:184; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]185; SSE3-NEXT: movd %xmm2, %eax186; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm0[3,3,3,3]187; SSE3-NEXT: movd %xmm2, %ecx188; SSE3-NEXT: addl %eax, %ecx189; SSE3-NEXT: movd %xmm0, %eax190; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]191; SSE3-NEXT: movd %xmm0, %edx192; SSE3-NEXT: addl %eax, %edx193; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]194; SSE3-NEXT: movd %xmm0, %eax195; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]196; SSE3-NEXT: movd %xmm0, %esi197; SSE3-NEXT: addl %eax, %esi198; SSE3-NEXT: movd %esi, %xmm0199; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,1,1,1]200; SSE3-NEXT: movd %xmm2, %eax201; SSE3-NEXT: movd %xmm1, %esi202; SSE3-NEXT: addl %eax, %esi203; SSE3-NEXT: movd %esi, %xmm1204; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]205; SSE3-NEXT: movd %ecx, %xmm2206; SSE3-NEXT: movd %edx, %xmm0207; SSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]208; SSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]209; SSE3-NEXT: retq210;211; SSSE3-LABEL: phadd_d_test2:212; SSSE3: # %bb.0:213; SSSE3-NEXT: phaddd %xmm1, %xmm0214; SSSE3-NEXT: retq215;216; AVX-LABEL: phadd_d_test2:217; AVX: # %bb.0:218; AVX-NEXT: vphaddd %xmm1, %xmm0, %xmm0219; AVX-NEXT: retq220 %vecext = extractelement <4 x i32> %A, i32 2221 %vecext1 = extractelement <4 x i32> %A, i32 3222 %add = add i32 %vecext, %vecext1223 %vecinit = insertelement <4 x i32> undef, i32 %add, i32 1224 %vecext2 = extractelement <4 x i32> %A, i32 0225 %vecext3 = extractelement <4 x i32> %A, i32 1226 %add4 = add i32 %vecext2, %vecext3227 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %add4, i32 0228 %vecext6 = extractelement <4 x i32> %B, i32 3229 %vecext7 = extractelement <4 x i32> %B, i32 2230 %add8 = add i32 %vecext6, %vecext7231 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %add8, i32 3232 %vecext10 = extractelement <4 x i32> %B, i32 1233 %vecext11 = extractelement <4 x i32> %B, i32 0234 %add12 = add i32 %vecext10, %vecext11235 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %add12, i32 2236 ret <4 x i32> %vecinit13237}238 239define <4 x i32> @phsub_d_test1(<4 x i32> %A, <4 x i32> %B) {240; SSE3-LABEL: phsub_d_test1:241; SSE3: # %bb.0:242; SSE3-NEXT: movd %xmm0, %eax243; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,1,1]244; SSE3-NEXT: movd %xmm2, %ecx245; SSE3-NEXT: subl %ecx, %eax246; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]247; SSE3-NEXT: movd %xmm2, %ecx248; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]249; SSE3-NEXT: movd %xmm0, %edx250; SSE3-NEXT: subl %edx, %ecx251; SSE3-NEXT: movd %xmm1, %edx252; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]253; SSE3-NEXT: movd %xmm0, %esi254; SSE3-NEXT: subl %esi, %edx255; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]256; SSE3-NEXT: movd %xmm0, %esi257; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]258; SSE3-NEXT: movd %xmm0, %edi259; SSE3-NEXT: subl %edi, %esi260; SSE3-NEXT: movd %esi, %xmm0261; SSE3-NEXT: movd %edx, %xmm1262; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]263; SSE3-NEXT: movd %ecx, %xmm2264; SSE3-NEXT: movd %eax, %xmm0265; SSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]266; SSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]267; SSE3-NEXT: retq268;269; SSSE3-LABEL: phsub_d_test1:270; SSSE3: # %bb.0:271; SSSE3-NEXT: phsubd %xmm1, %xmm0272; SSSE3-NEXT: retq273;274; AVX-LABEL: phsub_d_test1:275; AVX: # %bb.0:276; AVX-NEXT: vphsubd %xmm1, %xmm0, %xmm0277; AVX-NEXT: retq278 %vecext = extractelement <4 x i32> %A, i32 0279 %vecext1 = extractelement <4 x i32> %A, i32 1280 %sub = sub i32 %vecext, %vecext1281 %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 0282 %vecext2 = extractelement <4 x i32> %A, i32 2283 %vecext3 = extractelement <4 x i32> %A, i32 3284 %sub4 = sub i32 %vecext2, %vecext3285 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 1286 %vecext6 = extractelement <4 x i32> %B, i32 0287 %vecext7 = extractelement <4 x i32> %B, i32 1288 %sub8 = sub i32 %vecext6, %vecext7289 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 2290 %vecext10 = extractelement <4 x i32> %B, i32 2291 %vecext11 = extractelement <4 x i32> %B, i32 3292 %sub12 = sub i32 %vecext10, %vecext11293 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 3294 ret <4 x i32> %vecinit13295}296 297define <4 x i32> @phsub_d_test2(<4 x i32> %A, <4 x i32> %B) {298; SSE3-LABEL: phsub_d_test2:299; SSE3: # %bb.0:300; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]301; SSE3-NEXT: movd %xmm2, %eax302; SSE3-NEXT: pshufd {{.*#+}} xmm2 = xmm0[3,3,3,3]303; SSE3-NEXT: movd %xmm2, %ecx304; SSE3-NEXT: subl %ecx, %eax305; SSE3-NEXT: movd %xmm0, %ecx306; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]307; SSE3-NEXT: movd %xmm0, %edx308; SSE3-NEXT: subl %edx, %ecx309; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]310; SSE3-NEXT: movd %xmm0, %edx311; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]312; SSE3-NEXT: movd %xmm0, %esi313; SSE3-NEXT: subl %esi, %edx314; SSE3-NEXT: movd %edx, %xmm0315; SSE3-NEXT: movd %xmm1, %edx316; SSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,1,1]317; SSE3-NEXT: movd %xmm1, %esi318; SSE3-NEXT: subl %esi, %edx319; SSE3-NEXT: movd %edx, %xmm1320; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]321; SSE3-NEXT: movd %eax, %xmm2322; SSE3-NEXT: movd %ecx, %xmm0323; SSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]324; SSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]325; SSE3-NEXT: retq326;327; SSSE3-LABEL: phsub_d_test2:328; SSSE3: # %bb.0:329; SSSE3-NEXT: phsubd %xmm1, %xmm0330; SSSE3-NEXT: retq331;332; AVX-LABEL: phsub_d_test2:333; AVX: # %bb.0:334; AVX-NEXT: vphsubd %xmm1, %xmm0, %xmm0335; AVX-NEXT: retq336 %vecext = extractelement <4 x i32> %A, i32 2337 %vecext1 = extractelement <4 x i32> %A, i32 3338 %sub = sub i32 %vecext, %vecext1339 %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 1340 %vecext2 = extractelement <4 x i32> %A, i32 0341 %vecext3 = extractelement <4 x i32> %A, i32 1342 %sub4 = sub i32 %vecext2, %vecext3343 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 0344 %vecext6 = extractelement <4 x i32> %B, i32 2345 %vecext7 = extractelement <4 x i32> %B, i32 3346 %sub8 = sub i32 %vecext6, %vecext7347 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 3348 %vecext10 = extractelement <4 x i32> %B, i32 0349 %vecext11 = extractelement <4 x i32> %B, i32 1350 %sub12 = sub i32 %vecext10, %vecext11351 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 2352 ret <4 x i32> %vecinit13353}354 355define <2 x double> @hadd_pd_test1(<2 x double> %A, <2 x double> %B) {356; SSE-LABEL: hadd_pd_test1:357; SSE: # %bb.0:358; SSE-NEXT: haddpd %xmm1, %xmm0359; SSE-NEXT: retq360;361; AVX-LABEL: hadd_pd_test1:362; AVX: # %bb.0:363; AVX-NEXT: vhaddpd %xmm1, %xmm0, %xmm0364; AVX-NEXT: retq365 %vecext = extractelement <2 x double> %A, i32 0366 %vecext1 = extractelement <2 x double> %A, i32 1367 %add = fadd double %vecext, %vecext1368 %vecinit = insertelement <2 x double> undef, double %add, i32 0369 %vecext2 = extractelement <2 x double> %B, i32 0370 %vecext3 = extractelement <2 x double> %B, i32 1371 %add2 = fadd double %vecext2, %vecext3372 %vecinit2 = insertelement <2 x double> %vecinit, double %add2, i32 1373 ret <2 x double> %vecinit2374}375 376define <2 x double> @hadd_pd_test2(<2 x double> %A, <2 x double> %B) {377; SSE-LABEL: hadd_pd_test2:378; SSE: # %bb.0:379; SSE-NEXT: haddpd %xmm1, %xmm0380; SSE-NEXT: retq381;382; AVX-LABEL: hadd_pd_test2:383; AVX: # %bb.0:384; AVX-NEXT: vhaddpd %xmm1, %xmm0, %xmm0385; AVX-NEXT: retq386 %vecext = extractelement <2 x double> %A, i32 1387 %vecext1 = extractelement <2 x double> %A, i32 0388 %add = fadd double %vecext, %vecext1389 %vecinit = insertelement <2 x double> undef, double %add, i32 0390 %vecext2 = extractelement <2 x double> %B, i32 1391 %vecext3 = extractelement <2 x double> %B, i32 0392 %add2 = fadd double %vecext2, %vecext3393 %vecinit2 = insertelement <2 x double> %vecinit, double %add2, i32 1394 ret <2 x double> %vecinit2395}396 397define <2 x double> @hsub_pd_test1(<2 x double> %A, <2 x double> %B) {398; SSE-LABEL: hsub_pd_test1:399; SSE: # %bb.0:400; SSE-NEXT: hsubpd %xmm1, %xmm0401; SSE-NEXT: retq402;403; AVX-LABEL: hsub_pd_test1:404; AVX: # %bb.0:405; AVX-NEXT: vhsubpd %xmm1, %xmm0, %xmm0406; AVX-NEXT: retq407 %vecext = extractelement <2 x double> %A, i32 0408 %vecext1 = extractelement <2 x double> %A, i32 1409 %sub = fsub double %vecext, %vecext1410 %vecinit = insertelement <2 x double> undef, double %sub, i32 0411 %vecext2 = extractelement <2 x double> %B, i32 0412 %vecext3 = extractelement <2 x double> %B, i32 1413 %sub2 = fsub double %vecext2, %vecext3414 %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 1415 ret <2 x double> %vecinit2416}417 418define <2 x double> @hsub_pd_test2(<2 x double> %A, <2 x double> %B) {419; SSE-LABEL: hsub_pd_test2:420; SSE: # %bb.0:421; SSE-NEXT: hsubpd %xmm1, %xmm0422; SSE-NEXT: retq423;424; AVX-LABEL: hsub_pd_test2:425; AVX: # %bb.0:426; AVX-NEXT: vhsubpd %xmm1, %xmm0, %xmm0427; AVX-NEXT: retq428 %vecext = extractelement <2 x double> %B, i32 0429 %vecext1 = extractelement <2 x double> %B, i32 1430 %sub = fsub double %vecext, %vecext1431 %vecinit = insertelement <2 x double> undef, double %sub, i32 1432 %vecext2 = extractelement <2 x double> %A, i32 0433 %vecext3 = extractelement <2 x double> %A, i32 1434 %sub2 = fsub double %vecext2, %vecext3435 %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 0436 ret <2 x double> %vecinit2437}438 439define <4 x double> @avx_vhadd_pd_test(<4 x double> %A, <4 x double> %B) {440; SSE-LABEL: avx_vhadd_pd_test:441; SSE: # %bb.0:442; SSE-NEXT: haddpd %xmm1, %xmm0443; SSE-NEXT: haddpd %xmm3, %xmm2444; SSE-NEXT: movapd %xmm2, %xmm1445; SSE-NEXT: retq446;447; AVX1-LABEL: avx_vhadd_pd_test:448; AVX1: # %bb.0:449; AVX1-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3]450; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0451; AVX1-NEXT: vhaddpd %ymm2, %ymm0, %ymm0452; AVX1-NEXT: retq453;454; AVX2-LABEL: avx_vhadd_pd_test:455; AVX2: # %bb.0:456; AVX2-NEXT: vhaddpd %ymm1, %ymm0, %ymm0457; AVX2-NEXT: vpermpd {{.*#+}} ymm0 = ymm0[0,2,1,3]458; AVX2-NEXT: retq459 %vecext = extractelement <4 x double> %A, i32 0460 %vecext1 = extractelement <4 x double> %A, i32 1461 %add = fadd double %vecext, %vecext1462 %vecinit = insertelement <4 x double> undef, double %add, i32 0463 %vecext2 = extractelement <4 x double> %A, i32 2464 %vecext3 = extractelement <4 x double> %A, i32 3465 %add4 = fadd double %vecext2, %vecext3466 %vecinit5 = insertelement <4 x double> %vecinit, double %add4, i32 1467 %vecext6 = extractelement <4 x double> %B, i32 0468 %vecext7 = extractelement <4 x double> %B, i32 1469 %add8 = fadd double %vecext6, %vecext7470 %vecinit9 = insertelement <4 x double> %vecinit5, double %add8, i32 2471 %vecext10 = extractelement <4 x double> %B, i32 2472 %vecext11 = extractelement <4 x double> %B, i32 3473 %add12 = fadd double %vecext10, %vecext11474 %vecinit13 = insertelement <4 x double> %vecinit9, double %add12, i32 3475 ret <4 x double> %vecinit13476}477 478define <4 x double> @avx_vhsub_pd_test(<4 x double> %A, <4 x double> %B) {479; SSE-LABEL: avx_vhsub_pd_test:480; SSE: # %bb.0:481; SSE-NEXT: hsubpd %xmm1, %xmm0482; SSE-NEXT: hsubpd %xmm3, %xmm2483; SSE-NEXT: movapd %xmm2, %xmm1484; SSE-NEXT: retq485;486; AVX1-LABEL: avx_vhsub_pd_test:487; AVX1: # %bb.0:488; AVX1-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3]489; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0490; AVX1-NEXT: vhsubpd %ymm2, %ymm0, %ymm0491; AVX1-NEXT: retq492;493; AVX2-LABEL: avx_vhsub_pd_test:494; AVX2: # %bb.0:495; AVX2-NEXT: vhsubpd %ymm1, %ymm0, %ymm0496; AVX2-NEXT: vpermpd {{.*#+}} ymm0 = ymm0[0,2,1,3]497; AVX2-NEXT: retq498 %vecext = extractelement <4 x double> %A, i32 0499 %vecext1 = extractelement <4 x double> %A, i32 1500 %sub = fsub double %vecext, %vecext1501 %vecinit = insertelement <4 x double> undef, double %sub, i32 0502 %vecext2 = extractelement <4 x double> %A, i32 2503 %vecext3 = extractelement <4 x double> %A, i32 3504 %sub4 = fsub double %vecext2, %vecext3505 %vecinit5 = insertelement <4 x double> %vecinit, double %sub4, i32 1506 %vecext6 = extractelement <4 x double> %B, i32 0507 %vecext7 = extractelement <4 x double> %B, i32 1508 %sub8 = fsub double %vecext6, %vecext7509 %vecinit9 = insertelement <4 x double> %vecinit5, double %sub8, i32 2510 %vecext10 = extractelement <4 x double> %B, i32 2511 %vecext11 = extractelement <4 x double> %B, i32 3512 %sub12 = fsub double %vecext10, %vecext11513 %vecinit13 = insertelement <4 x double> %vecinit9, double %sub12, i32 3514 ret <4 x double> %vecinit13515}516 517define <8 x i32> @avx2_vphadd_d_test(<8 x i32> %A, <8 x i32> %B) {518; SSE3-LABEL: avx2_vphadd_d_test:519; SSE3: # %bb.0:520; SSE3-NEXT: movd %xmm0, %ecx521; SSE3-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,1,1,1]522; SSE3-NEXT: movd %xmm4, %eax523; SSE3-NEXT: addl %ecx, %eax524; SSE3-NEXT: pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3]525; SSE3-NEXT: movd %xmm4, %edx526; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]527; SSE3-NEXT: movd %xmm0, %ecx528; SSE3-NEXT: addl %edx, %ecx529; SSE3-NEXT: movd %xmm1, %edx530; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]531; SSE3-NEXT: movd %xmm0, %esi532; SSE3-NEXT: addl %edx, %esi533; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]534; SSE3-NEXT: movd %xmm0, %edx535; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]536; SSE3-NEXT: movd %xmm0, %edi537; SSE3-NEXT: addl %edx, %edi538; SSE3-NEXT: movd %xmm2, %r8d539; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[1,1,1,1]540; SSE3-NEXT: movd %xmm0, %edx541; SSE3-NEXT: addl %r8d, %edx542; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3]543; SSE3-NEXT: movd %xmm0, %r8d544; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[3,3,3,3]545; SSE3-NEXT: movd %xmm0, %r9d546; SSE3-NEXT: addl %r8d, %r9d547; SSE3-NEXT: movd %xmm3, %r8d548; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm3[1,1,1,1]549; SSE3-NEXT: movd %xmm0, %r10d550; SSE3-NEXT: addl %r8d, %r10d551; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3]552; SSE3-NEXT: movd %xmm0, %r8d553; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm3[3,3,3,3]554; SSE3-NEXT: movd %xmm0, %r11d555; SSE3-NEXT: addl %r8d, %r11d556; SSE3-NEXT: movd %edi, %xmm0557; SSE3-NEXT: movd %esi, %xmm1558; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]559; SSE3-NEXT: movd %ecx, %xmm2560; SSE3-NEXT: movd %eax, %xmm0561; SSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]562; SSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]563; SSE3-NEXT: movd %r11d, %xmm1564; SSE3-NEXT: movd %r10d, %xmm2565; SSE3-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]566; SSE3-NEXT: movd %r9d, %xmm3567; SSE3-NEXT: movd %edx, %xmm1568; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]569; SSE3-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]570; SSE3-NEXT: retq571;572; SSSE3-LABEL: avx2_vphadd_d_test:573; SSSE3: # %bb.0:574; SSSE3-NEXT: phaddd %xmm1, %xmm0575; SSSE3-NEXT: phaddd %xmm3, %xmm2576; SSSE3-NEXT: movdqa %xmm2, %xmm1577; SSSE3-NEXT: retq578;579; AVX1-LABEL: avx2_vphadd_d_test:580; AVX1: # %bb.0:581; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2582; AVX1-NEXT: vphaddd %xmm2, %xmm1, %xmm1583; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2584; AVX1-NEXT: vphaddd %xmm2, %xmm0, %xmm0585; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0586; AVX1-NEXT: retq587;588; AVX2-LABEL: avx2_vphadd_d_test:589; AVX2: # %bb.0:590; AVX2-NEXT: vphaddd %ymm1, %ymm0, %ymm0591; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]592; AVX2-NEXT: retq593 %vecext = extractelement <8 x i32> %A, i32 0594 %vecext1 = extractelement <8 x i32> %A, i32 1595 %add = add i32 %vecext, %vecext1596 %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0597 %vecext2 = extractelement <8 x i32> %A, i32 2598 %vecext3 = extractelement <8 x i32> %A, i32 3599 %add4 = add i32 %vecext2, %vecext3600 %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1601 %vecext6 = extractelement <8 x i32> %A, i32 4602 %vecext7 = extractelement <8 x i32> %A, i32 5603 %add8 = add i32 %vecext6, %vecext7604 %vecinit9 = insertelement <8 x i32> %vecinit5, i32 %add8, i32 2605 %vecext10 = extractelement <8 x i32> %A, i32 6606 %vecext11 = extractelement <8 x i32> %A, i32 7607 %add12 = add i32 %vecext10, %vecext11608 %vecinit13 = insertelement <8 x i32> %vecinit9, i32 %add12, i32 3609 %vecext14 = extractelement <8 x i32> %B, i32 0610 %vecext15 = extractelement <8 x i32> %B, i32 1611 %add16 = add i32 %vecext14, %vecext15612 %vecinit17 = insertelement <8 x i32> %vecinit13, i32 %add16, i32 4613 %vecext18 = extractelement <8 x i32> %B, i32 2614 %vecext19 = extractelement <8 x i32> %B, i32 3615 %add20 = add i32 %vecext18, %vecext19616 %vecinit21 = insertelement <8 x i32> %vecinit17, i32 %add20, i32 5617 %vecext22 = extractelement <8 x i32> %B, i32 4618 %vecext23 = extractelement <8 x i32> %B, i32 5619 %add24 = add i32 %vecext22, %vecext23620 %vecinit25 = insertelement <8 x i32> %vecinit21, i32 %add24, i32 6621 %vecext26 = extractelement <8 x i32> %B, i32 6622 %vecext27 = extractelement <8 x i32> %B, i32 7623 %add28 = add i32 %vecext26, %vecext27624 %vecinit29 = insertelement <8 x i32> %vecinit25, i32 %add28, i32 7625 ret <8 x i32> %vecinit29626}627 628define <16 x i16> @avx2_vphadd_w_test(<16 x i16> %a, <16 x i16> %b) nounwind {629; SSE3-LABEL: avx2_vphadd_w_test:630; SSE3: # %bb.0:631; SSE3-NEXT: pushq %rbp632; SSE3-NEXT: pushq %r15633; SSE3-NEXT: pushq %r14634; SSE3-NEXT: pushq %r13635; SSE3-NEXT: pushq %r12636; SSE3-NEXT: pushq %rbx637; SSE3-NEXT: movd %xmm0, %ecx638; SSE3-NEXT: pextrw $1, %xmm0, %eax639; SSE3-NEXT: addl %ecx, %eax640; SSE3-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill641; SSE3-NEXT: pextrw $2, %xmm0, %edx642; SSE3-NEXT: pextrw $3, %xmm0, %eax643; SSE3-NEXT: addl %edx, %eax644; SSE3-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill645; SSE3-NEXT: pextrw $4, %xmm0, %edx646; SSE3-NEXT: pextrw $5, %xmm0, %esi647; SSE3-NEXT: addl %edx, %esi648; SSE3-NEXT: pextrw $6, %xmm0, %edx649; SSE3-NEXT: pextrw $7, %xmm0, %r8d650; SSE3-NEXT: addl %edx, %r8d651; SSE3-NEXT: movd %xmm1, %edx652; SSE3-NEXT: pextrw $1, %xmm1, %r10d653; SSE3-NEXT: addl %edx, %r10d654; SSE3-NEXT: pextrw $2, %xmm1, %edx655; SSE3-NEXT: pextrw $3, %xmm1, %ebx656; SSE3-NEXT: addl %edx, %ebx657; SSE3-NEXT: pextrw $4, %xmm1, %edx658; SSE3-NEXT: pextrw $5, %xmm1, %r14d659; SSE3-NEXT: addl %edx, %r14d660; SSE3-NEXT: pextrw $6, %xmm1, %edx661; SSE3-NEXT: pextrw $7, %xmm1, %r12d662; SSE3-NEXT: addl %edx, %r12d663; SSE3-NEXT: movd %xmm2, %edi664; SSE3-NEXT: pextrw $1, %xmm2, %edx665; SSE3-NEXT: addl %edi, %edx666; SSE3-NEXT: pextrw $2, %xmm2, %r9d667; SSE3-NEXT: pextrw $3, %xmm2, %edi668; SSE3-NEXT: addl %r9d, %edi669; SSE3-NEXT: pextrw $4, %xmm2, %r11d670; SSE3-NEXT: pextrw $5, %xmm2, %r9d671; SSE3-NEXT: addl %r11d, %r9d672; SSE3-NEXT: pextrw $6, %xmm2, %ebp673; SSE3-NEXT: pextrw $7, %xmm2, %r11d674; SSE3-NEXT: addl %ebp, %r11d675; SSE3-NEXT: movd %xmm3, %r15d676; SSE3-NEXT: pextrw $1, %xmm3, %ebp677; SSE3-NEXT: addl %r15d, %ebp678; SSE3-NEXT: pextrw $2, %xmm3, %r13d679; SSE3-NEXT: pextrw $3, %xmm3, %r15d680; SSE3-NEXT: addl %r13d, %r15d681; SSE3-NEXT: pextrw $4, %xmm3, %r13d682; SSE3-NEXT: pextrw $5, %xmm3, %ecx683; SSE3-NEXT: addl %r13d, %ecx684; SSE3-NEXT: pextrw $6, %xmm3, %r13d685; SSE3-NEXT: pextrw $7, %xmm3, %eax686; SSE3-NEXT: addl %r13d, %eax687; SSE3-NEXT: movd %r12d, %xmm4688; SSE3-NEXT: movd %r14d, %xmm2689; SSE3-NEXT: movd %ebx, %xmm5690; SSE3-NEXT: movd %r10d, %xmm3691; SSE3-NEXT: movd %r8d, %xmm6692; SSE3-NEXT: movd %esi, %xmm7693; SSE3-NEXT: movd {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 4-byte Folded Reload694; SSE3-NEXT: # xmm8 = mem[0],zero,zero,zero695; SSE3-NEXT: movd {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Folded Reload696; SSE3-NEXT: # xmm0 = mem[0],zero,zero,zero697; SSE3-NEXT: movd %eax, %xmm9698; SSE3-NEXT: movd %ecx, %xmm10699; SSE3-NEXT: movd %r15d, %xmm11700; SSE3-NEXT: movd %ebp, %xmm12701; SSE3-NEXT: movd %r11d, %xmm13702; SSE3-NEXT: movd %r9d, %xmm14703; SSE3-NEXT: movd %edi, %xmm15704; SSE3-NEXT: movd %edx, %xmm1705; SSE3-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3]706; SSE3-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm5[0],xmm3[1],xmm5[1],xmm3[2],xmm5[2],xmm3[3],xmm5[3]707; SSE3-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]708; SSE3-NEXT: punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm6[0],xmm7[1],xmm6[1],xmm7[2],xmm6[2],xmm7[3],xmm6[3]709; SSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm8[0],xmm0[1],xmm8[1],xmm0[2],xmm8[2],xmm0[3],xmm8[3]710; SSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm7[0],xmm0[1],xmm7[1]711; SSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm3[0]712; SSE3-NEXT: punpcklwd {{.*#+}} xmm10 = xmm10[0],xmm9[0],xmm10[1],xmm9[1],xmm10[2],xmm9[2],xmm10[3],xmm9[3]713; SSE3-NEXT: punpcklwd {{.*#+}} xmm12 = xmm12[0],xmm11[0],xmm12[1],xmm11[1],xmm12[2],xmm11[2],xmm12[3],xmm11[3]714; SSE3-NEXT: punpckldq {{.*#+}} xmm12 = xmm12[0],xmm10[0],xmm12[1],xmm10[1]715; SSE3-NEXT: punpcklwd {{.*#+}} xmm14 = xmm14[0],xmm13[0],xmm14[1],xmm13[1],xmm14[2],xmm13[2],xmm14[3],xmm13[3]716; SSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm15[0],xmm1[1],xmm15[1],xmm1[2],xmm15[2],xmm1[3],xmm15[3]717; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm14[0],xmm1[1],xmm14[1]718; SSE3-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm12[0]719; SSE3-NEXT: popq %rbx720; SSE3-NEXT: popq %r12721; SSE3-NEXT: popq %r13722; SSE3-NEXT: popq %r14723; SSE3-NEXT: popq %r15724; SSE3-NEXT: popq %rbp725; SSE3-NEXT: retq726;727; SSSE3-LABEL: avx2_vphadd_w_test:728; SSSE3: # %bb.0:729; SSSE3-NEXT: phaddw %xmm1, %xmm0730; SSSE3-NEXT: phaddw %xmm3, %xmm2731; SSSE3-NEXT: movdqa %xmm2, %xmm1732; SSSE3-NEXT: retq733;734; AVX1-LABEL: avx2_vphadd_w_test:735; AVX1: # %bb.0:736; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2737; AVX1-NEXT: vphaddw %xmm2, %xmm1, %xmm1738; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2739; AVX1-NEXT: vphaddw %xmm2, %xmm0, %xmm0740; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0741; AVX1-NEXT: retq742;743; AVX2-LABEL: avx2_vphadd_w_test:744; AVX2: # %bb.0:745; AVX2-NEXT: vphaddw %ymm1, %ymm0, %ymm0746; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]747; AVX2-NEXT: retq748 %vecext = extractelement <16 x i16> %a, i32 0749 %vecext1 = extractelement <16 x i16> %a, i32 1750 %add = add i16 %vecext, %vecext1751 %vecinit = insertelement <16 x i16> undef, i16 %add, i32 0752 %vecext4 = extractelement <16 x i16> %a, i32 2753 %vecext6 = extractelement <16 x i16> %a, i32 3754 %add8 = add i16 %vecext4, %vecext6755 %vecinit10 = insertelement <16 x i16> %vecinit, i16 %add8, i32 1756 %vecext11 = extractelement <16 x i16> %a, i32 4757 %vecext13 = extractelement <16 x i16> %a, i32 5758 %add15 = add i16 %vecext11, %vecext13759 %vecinit17 = insertelement <16 x i16> %vecinit10, i16 %add15, i32 2760 %vecext18 = extractelement <16 x i16> %a, i32 6761 %vecext20 = extractelement <16 x i16> %a, i32 7762 %add22 = add i16 %vecext18, %vecext20763 %vecinit24 = insertelement <16 x i16> %vecinit17, i16 %add22, i32 3764 %vecext25 = extractelement <16 x i16> %a, i32 8765 %vecext27 = extractelement <16 x i16> %a, i32 9766 %add29 = add i16 %vecext25, %vecext27767 %vecinit31 = insertelement <16 x i16> %vecinit24, i16 %add29, i32 4768 %vecext32 = extractelement <16 x i16> %a, i32 10769 %vecext34 = extractelement <16 x i16> %a, i32 11770 %add36 = add i16 %vecext32, %vecext34771 %vecinit38 = insertelement <16 x i16> %vecinit31, i16 %add36, i32 5772 %vecext39 = extractelement <16 x i16> %a, i32 12773 %vecext41 = extractelement <16 x i16> %a, i32 13774 %add43 = add i16 %vecext39, %vecext41775 %vecinit45 = insertelement <16 x i16> %vecinit38, i16 %add43, i32 6776 %vecext46 = extractelement <16 x i16> %a, i32 14777 %vecext48 = extractelement <16 x i16> %a, i32 15778 %add50 = add i16 %vecext46, %vecext48779 %vecinit52 = insertelement <16 x i16> %vecinit45, i16 %add50, i32 7780 %vecext53 = extractelement <16 x i16> %b, i32 0781 %vecext55 = extractelement <16 x i16> %b, i32 1782 %add57 = add i16 %vecext53, %vecext55783 %vecinit59 = insertelement <16 x i16> %vecinit52, i16 %add57, i32 8784 %vecext60 = extractelement <16 x i16> %b, i32 2785 %vecext62 = extractelement <16 x i16> %b, i32 3786 %add64 = add i16 %vecext60, %vecext62787 %vecinit66 = insertelement <16 x i16> %vecinit59, i16 %add64, i32 9788 %vecext67 = extractelement <16 x i16> %b, i32 4789 %vecext69 = extractelement <16 x i16> %b, i32 5790 %add71 = add i16 %vecext67, %vecext69791 %vecinit73 = insertelement <16 x i16> %vecinit66, i16 %add71, i32 10792 %vecext74 = extractelement <16 x i16> %b, i32 6793 %vecext76 = extractelement <16 x i16> %b, i32 7794 %add78 = add i16 %vecext74, %vecext76795 %vecinit80 = insertelement <16 x i16> %vecinit73, i16 %add78, i32 11796 %vecext81 = extractelement <16 x i16> %b, i32 8797 %vecext83 = extractelement <16 x i16> %b, i32 9798 %add85 = add i16 %vecext81, %vecext83799 %vecinit87 = insertelement <16 x i16> %vecinit80, i16 %add85, i32 12800 %vecext88 = extractelement <16 x i16> %b, i32 10801 %vecext90 = extractelement <16 x i16> %b, i32 11802 %add92 = add i16 %vecext88, %vecext90803 %vecinit94 = insertelement <16 x i16> %vecinit87, i16 %add92, i32 13804 %vecext95 = extractelement <16 x i16> %b, i32 12805 %vecext97 = extractelement <16 x i16> %b, i32 13806 %add99 = add i16 %vecext95, %vecext97807 %vecinit101 = insertelement <16 x i16> %vecinit94, i16 %add99, i32 14808 %vecext102 = extractelement <16 x i16> %b, i32 14809 %vecext104 = extractelement <16 x i16> %b, i32 15810 %add106 = add i16 %vecext102, %vecext104811 %vecinit108 = insertelement <16 x i16> %vecinit101, i16 %add106, i32 15812 ret <16 x i16> %vecinit108813}814 815; Verify that we don't select horizontal subs in the following functions.816 817define <4 x i32> @not_a_hsub_1(<4 x i32> %A, <4 x i32> %B) {818; SSE-LABEL: not_a_hsub_1:819; SSE: # %bb.0:820; SSE-NEXT: movd %xmm0, %eax821; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,1,1]822; SSE-NEXT: movd %xmm2, %ecx823; SSE-NEXT: subl %ecx, %eax824; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]825; SSE-NEXT: movd %xmm2, %ecx826; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]827; SSE-NEXT: movd %xmm0, %edx828; SSE-NEXT: subl %edx, %ecx829; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]830; SSE-NEXT: movd %xmm0, %edx831; SSE-NEXT: movd %xmm1, %esi832; SSE-NEXT: subl %esi, %edx833; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]834; SSE-NEXT: movd %xmm0, %esi835; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]836; SSE-NEXT: movd %xmm0, %edi837; SSE-NEXT: subl %edi, %esi838; SSE-NEXT: movd %esi, %xmm0839; SSE-NEXT: movd %edx, %xmm1840; SSE-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]841; SSE-NEXT: movd %ecx, %xmm2842; SSE-NEXT: movd %eax, %xmm0843; SSE-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]844; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]845; SSE-NEXT: retq846;847; AVX-LABEL: not_a_hsub_1:848; AVX: # %bb.0:849; AVX-NEXT: vmovd %xmm0, %eax850; AVX-NEXT: vpextrd $1, %xmm0, %ecx851; AVX-NEXT: subl %ecx, %eax852; AVX-NEXT: vpextrd $2, %xmm0, %ecx853; AVX-NEXT: vpextrd $3, %xmm0, %edx854; AVX-NEXT: subl %edx, %ecx855; AVX-NEXT: vpextrd $1, %xmm1, %edx856; AVX-NEXT: vmovd %xmm1, %esi857; AVX-NEXT: subl %esi, %edx858; AVX-NEXT: vpextrd $3, %xmm1, %esi859; AVX-NEXT: vpextrd $2, %xmm1, %edi860; AVX-NEXT: subl %edi, %esi861; AVX-NEXT: vmovd %eax, %xmm0862; AVX-NEXT: vpinsrd $1, %ecx, %xmm0, %xmm0863; AVX-NEXT: vpinsrd $2, %edx, %xmm0, %xmm0864; AVX-NEXT: vpinsrd $3, %esi, %xmm0, %xmm0865; AVX-NEXT: retq866 %vecext = extractelement <4 x i32> %A, i32 0867 %vecext1 = extractelement <4 x i32> %A, i32 1868 %sub = sub i32 %vecext, %vecext1869 %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 0870 %vecext2 = extractelement <4 x i32> %A, i32 2871 %vecext3 = extractelement <4 x i32> %A, i32 3872 %sub4 = sub i32 %vecext2, %vecext3873 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 1874 %vecext6 = extractelement <4 x i32> %B, i32 1875 %vecext7 = extractelement <4 x i32> %B, i32 0876 %sub8 = sub i32 %vecext6, %vecext7877 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 2878 %vecext10 = extractelement <4 x i32> %B, i32 3879 %vecext11 = extractelement <4 x i32> %B, i32 2880 %sub12 = sub i32 %vecext10, %vecext11881 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 3882 ret <4 x i32> %vecinit13883}884 885define <4 x float> @not_a_hsub_2(<4 x float> %A, <4 x float> %B) {886; SSE-LABEL: not_a_hsub_2:887; SSE: # %bb.0:888; SSE-NEXT: movaps %xmm0, %xmm2889; SSE-NEXT: unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]890; SSE-NEXT: movaps %xmm0, %xmm3891; SSE-NEXT: shufps {{.*#+}} xmm3 = xmm3[3,3],xmm0[3,3]892; SSE-NEXT: subss %xmm3, %xmm2893; SSE-NEXT: movshdup {{.*#+}} xmm3 = xmm0[1,1,3,3]894; SSE-NEXT: subss %xmm3, %xmm0895; SSE-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]896; SSE-NEXT: movaps %xmm1, %xmm2897; SSE-NEXT: shufps {{.*#+}} xmm2 = xmm2[3,3],xmm1[3,3]898; SSE-NEXT: movaps %xmm1, %xmm3899; SSE-NEXT: unpckhpd {{.*#+}} xmm3 = xmm3[1],xmm1[1]900; SSE-NEXT: subss %xmm3, %xmm2901; SSE-NEXT: movshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]902; SSE-NEXT: subss %xmm3, %xmm1903; SSE-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]904; SSE-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]905; SSE-NEXT: retq906;907; AVX-LABEL: not_a_hsub_2:908; AVX: # %bb.0:909; AVX-NEXT: vshufpd {{.*#+}} xmm2 = xmm0[1,0]910; AVX-NEXT: vshufps {{.*#+}} xmm3 = xmm0[3,3,3,3]911; AVX-NEXT: vsubss %xmm3, %xmm2, %xmm2912; AVX-NEXT: vmovshdup {{.*#+}} xmm3 = xmm0[1,1,3,3]913; AVX-NEXT: vsubss %xmm3, %xmm0, %xmm0914; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[2,3]915; AVX-NEXT: vshufps {{.*#+}} xmm2 = xmm1[3,3,3,3]916; AVX-NEXT: vshufpd {{.*#+}} xmm3 = xmm1[1,0]917; AVX-NEXT: vsubss %xmm3, %xmm2, %xmm2918; AVX-NEXT: vmovshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]919; AVX-NEXT: vsubss %xmm3, %xmm1, %xmm1920; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3]921; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm2[0]922; AVX-NEXT: retq923 %vecext = extractelement <4 x float> %A, i32 2924 %vecext1 = extractelement <4 x float> %A, i32 3925 %sub = fsub float %vecext, %vecext1926 %vecinit = insertelement <4 x float> undef, float %sub, i32 1927 %vecext2 = extractelement <4 x float> %A, i32 0928 %vecext3 = extractelement <4 x float> %A, i32 1929 %sub4 = fsub float %vecext2, %vecext3930 %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 0931 %vecext6 = extractelement <4 x float> %B, i32 3932 %vecext7 = extractelement <4 x float> %B, i32 2933 %sub8 = fsub float %vecext6, %vecext7934 %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 3935 %vecext10 = extractelement <4 x float> %B, i32 0936 %vecext11 = extractelement <4 x float> %B, i32 1937 %sub12 = fsub float %vecext10, %vecext11938 %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 2939 ret <4 x float> %vecinit13940}941 942define <2 x double> @not_a_hsub_3(<2 x double> %A, <2 x double> %B) {943; SSE-LABEL: not_a_hsub_3:944; SSE: # %bb.0:945; SSE-NEXT: movapd %xmm1, %xmm2946; SSE-NEXT: unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm1[1]947; SSE-NEXT: subsd %xmm2, %xmm1948; SSE-NEXT: movapd %xmm0, %xmm2949; SSE-NEXT: unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]950; SSE-NEXT: subsd %xmm0, %xmm2951; SSE-NEXT: unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]952; SSE-NEXT: movapd %xmm2, %xmm0953; SSE-NEXT: retq954;955; AVX-LABEL: not_a_hsub_3:956; AVX: # %bb.0:957; AVX-NEXT: vshufpd {{.*#+}} xmm2 = xmm1[1,0]958; AVX-NEXT: vsubsd %xmm2, %xmm1, %xmm1959; AVX-NEXT: vshufpd {{.*#+}} xmm2 = xmm0[1,0]960; AVX-NEXT: vsubsd %xmm0, %xmm2, %xmm0961; AVX-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]962; AVX-NEXT: retq963 %vecext = extractelement <2 x double> %B, i32 0964 %vecext1 = extractelement <2 x double> %B, i32 1965 %sub = fsub double %vecext, %vecext1966 %vecinit = insertelement <2 x double> undef, double %sub, i32 1967 %vecext2 = extractelement <2 x double> %A, i32 1968 %vecext3 = extractelement <2 x double> %A, i32 0969 %sub2 = fsub double %vecext2, %vecext3970 %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 0971 ret <2 x double> %vecinit2972}973 974; Test AVX horizontal add/sub of packed single/double precision975; floating point values from 256-bit vectors.976 977define <8 x float> @avx_vhadd_ps(<8 x float> %a, <8 x float> %b) {978; SSE-LABEL: avx_vhadd_ps:979; SSE: # %bb.0:980; SSE-NEXT: haddps %xmm2, %xmm0981; SSE-NEXT: haddps %xmm3, %xmm1982; SSE-NEXT: retq983;984; AVX-LABEL: avx_vhadd_ps:985; AVX: # %bb.0:986; AVX-NEXT: vhaddps %ymm1, %ymm0, %ymm0987; AVX-NEXT: retq988 %vecext = extractelement <8 x float> %a, i32 0989 %vecext1 = extractelement <8 x float> %a, i32 1990 %add = fadd float %vecext, %vecext1991 %vecinit = insertelement <8 x float> undef, float %add, i32 0992 %vecext2 = extractelement <8 x float> %a, i32 2993 %vecext3 = extractelement <8 x float> %a, i32 3994 %add4 = fadd float %vecext2, %vecext3995 %vecinit5 = insertelement <8 x float> %vecinit, float %add4, i32 1996 %vecext6 = extractelement <8 x float> %b, i32 0997 %vecext7 = extractelement <8 x float> %b, i32 1998 %add8 = fadd float %vecext6, %vecext7999 %vecinit9 = insertelement <8 x float> %vecinit5, float %add8, i32 21000 %vecext10 = extractelement <8 x float> %b, i32 21001 %vecext11 = extractelement <8 x float> %b, i32 31002 %add12 = fadd float %vecext10, %vecext111003 %vecinit13 = insertelement <8 x float> %vecinit9, float %add12, i32 31004 %vecext14 = extractelement <8 x float> %a, i32 41005 %vecext15 = extractelement <8 x float> %a, i32 51006 %add16 = fadd float %vecext14, %vecext151007 %vecinit17 = insertelement <8 x float> %vecinit13, float %add16, i32 41008 %vecext18 = extractelement <8 x float> %a, i32 61009 %vecext19 = extractelement <8 x float> %a, i32 71010 %add20 = fadd float %vecext18, %vecext191011 %vecinit21 = insertelement <8 x float> %vecinit17, float %add20, i32 51012 %vecext22 = extractelement <8 x float> %b, i32 41013 %vecext23 = extractelement <8 x float> %b, i32 51014 %add24 = fadd float %vecext22, %vecext231015 %vecinit25 = insertelement <8 x float> %vecinit21, float %add24, i32 61016 %vecext26 = extractelement <8 x float> %b, i32 61017 %vecext27 = extractelement <8 x float> %b, i32 71018 %add28 = fadd float %vecext26, %vecext271019 %vecinit29 = insertelement <8 x float> %vecinit25, float %add28, i32 71020 ret <8 x float> %vecinit291021}1022 1023define <8 x float> @avx_vhsub_ps(<8 x float> %a, <8 x float> %b) {1024; SSE-LABEL: avx_vhsub_ps:1025; SSE: # %bb.0:1026; SSE-NEXT: hsubps %xmm2, %xmm01027; SSE-NEXT: hsubps %xmm3, %xmm11028; SSE-NEXT: retq1029;1030; AVX-LABEL: avx_vhsub_ps:1031; AVX: # %bb.0:1032; AVX-NEXT: vhsubps %ymm1, %ymm0, %ymm01033; AVX-NEXT: retq1034 %vecext = extractelement <8 x float> %a, i32 01035 %vecext1 = extractelement <8 x float> %a, i32 11036 %sub = fsub float %vecext, %vecext11037 %vecinit = insertelement <8 x float> undef, float %sub, i32 01038 %vecext2 = extractelement <8 x float> %a, i32 21039 %vecext3 = extractelement <8 x float> %a, i32 31040 %sub4 = fsub float %vecext2, %vecext31041 %vecinit5 = insertelement <8 x float> %vecinit, float %sub4, i32 11042 %vecext6 = extractelement <8 x float> %b, i32 01043 %vecext7 = extractelement <8 x float> %b, i32 11044 %sub8 = fsub float %vecext6, %vecext71045 %vecinit9 = insertelement <8 x float> %vecinit5, float %sub8, i32 21046 %vecext10 = extractelement <8 x float> %b, i32 21047 %vecext11 = extractelement <8 x float> %b, i32 31048 %sub12 = fsub float %vecext10, %vecext111049 %vecinit13 = insertelement <8 x float> %vecinit9, float %sub12, i32 31050 %vecext14 = extractelement <8 x float> %a, i32 41051 %vecext15 = extractelement <8 x float> %a, i32 51052 %sub16 = fsub float %vecext14, %vecext151053 %vecinit17 = insertelement <8 x float> %vecinit13, float %sub16, i32 41054 %vecext18 = extractelement <8 x float> %a, i32 61055 %vecext19 = extractelement <8 x float> %a, i32 71056 %sub20 = fsub float %vecext18, %vecext191057 %vecinit21 = insertelement <8 x float> %vecinit17, float %sub20, i32 51058 %vecext22 = extractelement <8 x float> %b, i32 41059 %vecext23 = extractelement <8 x float> %b, i32 51060 %sub24 = fsub float %vecext22, %vecext231061 %vecinit25 = insertelement <8 x float> %vecinit21, float %sub24, i32 61062 %vecext26 = extractelement <8 x float> %b, i32 61063 %vecext27 = extractelement <8 x float> %b, i32 71064 %sub28 = fsub float %vecext26, %vecext271065 %vecinit29 = insertelement <8 x float> %vecinit25, float %sub28, i32 71066 ret <8 x float> %vecinit291067}1068 1069define <4 x double> @avx_hadd_pd(<4 x double> %a, <4 x double> %b) {1070; SSE-LABEL: avx_hadd_pd:1071; SSE: # %bb.0:1072; SSE-NEXT: haddpd %xmm2, %xmm01073; SSE-NEXT: haddpd %xmm3, %xmm11074; SSE-NEXT: retq1075;1076; AVX-LABEL: avx_hadd_pd:1077; AVX: # %bb.0:1078; AVX-NEXT: vhaddpd %ymm1, %ymm0, %ymm01079; AVX-NEXT: retq1080 %vecext = extractelement <4 x double> %a, i32 01081 %vecext1 = extractelement <4 x double> %a, i32 11082 %add = fadd double %vecext, %vecext11083 %vecinit = insertelement <4 x double> undef, double %add, i32 01084 %vecext2 = extractelement <4 x double> %b, i32 01085 %vecext3 = extractelement <4 x double> %b, i32 11086 %add4 = fadd double %vecext2, %vecext31087 %vecinit5 = insertelement <4 x double> %vecinit, double %add4, i32 11088 %vecext6 = extractelement <4 x double> %a, i32 21089 %vecext7 = extractelement <4 x double> %a, i32 31090 %add8 = fadd double %vecext6, %vecext71091 %vecinit9 = insertelement <4 x double> %vecinit5, double %add8, i32 21092 %vecext10 = extractelement <4 x double> %b, i32 21093 %vecext11 = extractelement <4 x double> %b, i32 31094 %add12 = fadd double %vecext10, %vecext111095 %vecinit13 = insertelement <4 x double> %vecinit9, double %add12, i32 31096 ret <4 x double> %vecinit131097}1098 1099define <4 x double> @avx_hsub_pd(<4 x double> %a, <4 x double> %b) {1100; SSE-LABEL: avx_hsub_pd:1101; SSE: # %bb.0:1102; SSE-NEXT: hsubpd %xmm2, %xmm01103; SSE-NEXT: hsubpd %xmm3, %xmm11104; SSE-NEXT: retq1105;1106; AVX-LABEL: avx_hsub_pd:1107; AVX: # %bb.0:1108; AVX-NEXT: vhsubpd %ymm1, %ymm0, %ymm01109; AVX-NEXT: retq1110 %vecext = extractelement <4 x double> %a, i32 01111 %vecext1 = extractelement <4 x double> %a, i32 11112 %sub = fsub double %vecext, %vecext11113 %vecinit = insertelement <4 x double> undef, double %sub, i32 01114 %vecext2 = extractelement <4 x double> %b, i32 01115 %vecext3 = extractelement <4 x double> %b, i32 11116 %sub4 = fsub double %vecext2, %vecext31117 %vecinit5 = insertelement <4 x double> %vecinit, double %sub4, i32 11118 %vecext6 = extractelement <4 x double> %a, i32 21119 %vecext7 = extractelement <4 x double> %a, i32 31120 %sub8 = fsub double %vecext6, %vecext71121 %vecinit9 = insertelement <4 x double> %vecinit5, double %sub8, i32 21122 %vecext10 = extractelement <4 x double> %b, i32 21123 %vecext11 = extractelement <4 x double> %b, i32 31124 %sub12 = fsub double %vecext10, %vecext111125 %vecinit13 = insertelement <4 x double> %vecinit9, double %sub12, i32 31126 ret <4 x double> %vecinit131127}1128 1129; Test AVX2 horizontal add of packed integer values from 256-bit vectors.1130 1131define <8 x i32> @avx2_hadd_d(<8 x i32> %a, <8 x i32> %b) {1132; SSE3-LABEL: avx2_hadd_d:1133; SSE3: # %bb.0:1134; SSE3-NEXT: movd %xmm0, %ecx1135; SSE3-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,1,1,1]1136; SSE3-NEXT: movd %xmm4, %eax1137; SSE3-NEXT: addl %ecx, %eax1138; SSE3-NEXT: pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3]1139; SSE3-NEXT: movd %xmm4, %edx1140; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]1141; SSE3-NEXT: movd %xmm0, %ecx1142; SSE3-NEXT: addl %edx, %ecx1143; SSE3-NEXT: movd %xmm2, %edx1144; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[1,1,1,1]1145; SSE3-NEXT: movd %xmm0, %esi1146; SSE3-NEXT: addl %edx, %esi1147; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3]1148; SSE3-NEXT: movd %xmm0, %edx1149; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[3,3,3,3]1150; SSE3-NEXT: movd %xmm0, %edi1151; SSE3-NEXT: addl %edx, %edi1152; SSE3-NEXT: movd %xmm1, %r8d1153; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]1154; SSE3-NEXT: movd %xmm0, %edx1155; SSE3-NEXT: addl %r8d, %edx1156; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]1157; SSE3-NEXT: movd %xmm0, %r8d1158; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]1159; SSE3-NEXT: movd %xmm0, %r9d1160; SSE3-NEXT: addl %r8d, %r9d1161; SSE3-NEXT: movd %xmm3, %r8d1162; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm3[1,1,1,1]1163; SSE3-NEXT: movd %xmm0, %r10d1164; SSE3-NEXT: addl %r8d, %r10d1165; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3]1166; SSE3-NEXT: movd %xmm0, %r8d1167; SSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm3[3,3,3,3]1168; SSE3-NEXT: movd %xmm0, %r11d1169; SSE3-NEXT: addl %r8d, %r11d1170; SSE3-NEXT: movd %edi, %xmm01171; SSE3-NEXT: movd %esi, %xmm11172; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]1173; SSE3-NEXT: movd %ecx, %xmm21174; SSE3-NEXT: movd %eax, %xmm01175; SSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]1176; SSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]1177; SSE3-NEXT: movd %r11d, %xmm11178; SSE3-NEXT: movd %r10d, %xmm21179; SSE3-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]1180; SSE3-NEXT: movd %r9d, %xmm31181; SSE3-NEXT: movd %edx, %xmm11182; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]1183; SSE3-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]1184; SSE3-NEXT: retq1185;1186; SSSE3-LABEL: avx2_hadd_d:1187; SSSE3: # %bb.0:1188; SSSE3-NEXT: phaddd %xmm2, %xmm01189; SSSE3-NEXT: phaddd %xmm3, %xmm11190; SSSE3-NEXT: retq1191;1192; AVX1-LABEL: avx2_hadd_d:1193; AVX1: # %bb.0:1194; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm21195; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm31196; AVX1-NEXT: vphaddd %xmm2, %xmm3, %xmm21197; AVX1-NEXT: vphaddd %xmm1, %xmm0, %xmm01198; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm01199; AVX1-NEXT: retq1200;1201; AVX2-LABEL: avx2_hadd_d:1202; AVX2: # %bb.0:1203; AVX2-NEXT: vphaddd %ymm1, %ymm0, %ymm01204; AVX2-NEXT: retq1205 %vecext = extractelement <8 x i32> %a, i32 01206 %vecext1 = extractelement <8 x i32> %a, i32 11207 %add = add i32 %vecext, %vecext11208 %vecinit = insertelement <8 x i32> undef, i32 %add, i32 01209 %vecext2 = extractelement <8 x i32> %a, i32 21210 %vecext3 = extractelement <8 x i32> %a, i32 31211 %add4 = add i32 %vecext2, %vecext31212 %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 11213 %vecext6 = extractelement <8 x i32> %b, i32 01214 %vecext7 = extractelement <8 x i32> %b, i32 11215 %add8 = add i32 %vecext6, %vecext71216 %vecinit9 = insertelement <8 x i32> %vecinit5, i32 %add8, i32 21217 %vecext10 = extractelement <8 x i32> %b, i32 21218 %vecext11 = extractelement <8 x i32> %b, i32 31219 %add12 = add i32 %vecext10, %vecext111220 %vecinit13 = insertelement <8 x i32> %vecinit9, i32 %add12, i32 31221 %vecext14 = extractelement <8 x i32> %a, i32 41222 %vecext15 = extractelement <8 x i32> %a, i32 51223 %add16 = add i32 %vecext14, %vecext151224 %vecinit17 = insertelement <8 x i32> %vecinit13, i32 %add16, i32 41225 %vecext18 = extractelement <8 x i32> %a, i32 61226 %vecext19 = extractelement <8 x i32> %a, i32 71227 %add20 = add i32 %vecext18, %vecext191228 %vecinit21 = insertelement <8 x i32> %vecinit17, i32 %add20, i32 51229 %vecext22 = extractelement <8 x i32> %b, i32 41230 %vecext23 = extractelement <8 x i32> %b, i32 51231 %add24 = add i32 %vecext22, %vecext231232 %vecinit25 = insertelement <8 x i32> %vecinit21, i32 %add24, i32 61233 %vecext26 = extractelement <8 x i32> %b, i32 61234 %vecext27 = extractelement <8 x i32> %b, i32 71235 %add28 = add i32 %vecext26, %vecext271236 %vecinit29 = insertelement <8 x i32> %vecinit25, i32 %add28, i32 71237 ret <8 x i32> %vecinit291238}1239 1240define <16 x i16> @avx2_hadd_w(<16 x i16> %a, <16 x i16> %b) nounwind {1241; SSE3-LABEL: avx2_hadd_w:1242; SSE3: # %bb.0:1243; SSE3-NEXT: pushq %rbp1244; SSE3-NEXT: pushq %r151245; SSE3-NEXT: pushq %r141246; SSE3-NEXT: pushq %r131247; SSE3-NEXT: pushq %r121248; SSE3-NEXT: pushq %rbx1249; SSE3-NEXT: movd %xmm0, %eax1250; SSE3-NEXT: pextrw $1, %xmm0, %edx1251; SSE3-NEXT: addl %eax, %edx1252; SSE3-NEXT: pextrw $2, %xmm0, %eax1253; SSE3-NEXT: pextrw $3, %xmm0, %esi1254; SSE3-NEXT: addl %eax, %esi1255; SSE3-NEXT: pextrw $4, %xmm0, %eax1256; SSE3-NEXT: pextrw $5, %xmm0, %r9d1257; SSE3-NEXT: addl %eax, %r9d1258; SSE3-NEXT: pextrw $6, %xmm0, %eax1259; SSE3-NEXT: pextrw $7, %xmm0, %r10d1260; SSE3-NEXT: addl %eax, %r10d1261; SSE3-NEXT: movd %xmm1, %ecx1262; SSE3-NEXT: pextrw $1, %xmm1, %eax1263; SSE3-NEXT: addl %ecx, %eax1264; SSE3-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill1265; SSE3-NEXT: pextrw $2, %xmm1, %edi1266; SSE3-NEXT: pextrw $3, %xmm1, %eax1267; SSE3-NEXT: addl %edi, %eax1268; SSE3-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill1269; SSE3-NEXT: pextrw $4, %xmm1, %r8d1270; SSE3-NEXT: pextrw $5, %xmm1, %edi1271; SSE3-NEXT: addl %r8d, %edi1272; SSE3-NEXT: pextrw $6, %xmm1, %r11d1273; SSE3-NEXT: pextrw $7, %xmm1, %r8d1274; SSE3-NEXT: addl %r11d, %r8d1275; SSE3-NEXT: movd %xmm2, %r11d1276; SSE3-NEXT: pextrw $1, %xmm2, %ebp1277; SSE3-NEXT: addl %r11d, %ebp1278; SSE3-NEXT: pextrw $2, %xmm2, %r11d1279; SSE3-NEXT: pextrw $3, %xmm2, %r14d1280; SSE3-NEXT: addl %r11d, %r14d1281; SSE3-NEXT: pextrw $4, %xmm2, %r11d1282; SSE3-NEXT: pextrw $5, %xmm2, %r15d1283; SSE3-NEXT: addl %r11d, %r15d1284; SSE3-NEXT: pextrw $6, %xmm2, %r11d1285; SSE3-NEXT: pextrw $7, %xmm2, %r12d1286; SSE3-NEXT: addl %r11d, %r12d1287; SSE3-NEXT: movd %xmm3, %ebx1288; SSE3-NEXT: pextrw $1, %xmm3, %r11d1289; SSE3-NEXT: addl %ebx, %r11d1290; SSE3-NEXT: pextrw $2, %xmm3, %r13d1291; SSE3-NEXT: pextrw $3, %xmm3, %ebx1292; SSE3-NEXT: addl %r13d, %ebx1293; SSE3-NEXT: pextrw $4, %xmm3, %r13d1294; SSE3-NEXT: pextrw $5, %xmm3, %ecx1295; SSE3-NEXT: addl %r13d, %ecx1296; SSE3-NEXT: pextrw $6, %xmm3, %r13d1297; SSE3-NEXT: pextrw $7, %xmm3, %eax1298; SSE3-NEXT: addl %r13d, %eax1299; SSE3-NEXT: movd %r12d, %xmm41300; SSE3-NEXT: movd %r15d, %xmm21301; SSE3-NEXT: movd %r14d, %xmm51302; SSE3-NEXT: movd %ebp, %xmm31303; SSE3-NEXT: movd %r10d, %xmm61304; SSE3-NEXT: movd %r9d, %xmm71305; SSE3-NEXT: movd %esi, %xmm81306; SSE3-NEXT: movd %edx, %xmm01307; SSE3-NEXT: movd %eax, %xmm91308; SSE3-NEXT: movd %ecx, %xmm101309; SSE3-NEXT: movd %ebx, %xmm111310; SSE3-NEXT: movd %r11d, %xmm121311; SSE3-NEXT: movd %r8d, %xmm131312; SSE3-NEXT: movd %edi, %xmm141313; SSE3-NEXT: movd {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 4-byte Folded Reload1314; SSE3-NEXT: # xmm15 = mem[0],zero,zero,zero1315; SSE3-NEXT: movd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Folded Reload1316; SSE3-NEXT: # xmm1 = mem[0],zero,zero,zero1317; SSE3-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3]1318; SSE3-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm5[0],xmm3[1],xmm5[1],xmm3[2],xmm5[2],xmm3[3],xmm5[3]1319; SSE3-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]1320; SSE3-NEXT: punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm6[0],xmm7[1],xmm6[1],xmm7[2],xmm6[2],xmm7[3],xmm6[3]1321; SSE3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm8[0],xmm0[1],xmm8[1],xmm0[2],xmm8[2],xmm0[3],xmm8[3]1322; SSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm7[0],xmm0[1],xmm7[1]1323; SSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm3[0]1324; SSE3-NEXT: punpcklwd {{.*#+}} xmm10 = xmm10[0],xmm9[0],xmm10[1],xmm9[1],xmm10[2],xmm9[2],xmm10[3],xmm9[3]1325; SSE3-NEXT: punpcklwd {{.*#+}} xmm12 = xmm12[0],xmm11[0],xmm12[1],xmm11[1],xmm12[2],xmm11[2],xmm12[3],xmm11[3]1326; SSE3-NEXT: punpckldq {{.*#+}} xmm12 = xmm12[0],xmm10[0],xmm12[1],xmm10[1]1327; SSE3-NEXT: punpcklwd {{.*#+}} xmm14 = xmm14[0],xmm13[0],xmm14[1],xmm13[1],xmm14[2],xmm13[2],xmm14[3],xmm13[3]1328; SSE3-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm15[0],xmm1[1],xmm15[1],xmm1[2],xmm15[2],xmm1[3],xmm15[3]1329; SSE3-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm14[0],xmm1[1],xmm14[1]1330; SSE3-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm12[0]1331; SSE3-NEXT: popq %rbx1332; SSE3-NEXT: popq %r121333; SSE3-NEXT: popq %r131334; SSE3-NEXT: popq %r141335; SSE3-NEXT: popq %r151336; SSE3-NEXT: popq %rbp1337; SSE3-NEXT: retq1338;1339; SSSE3-LABEL: avx2_hadd_w:1340; SSSE3: # %bb.0:1341; SSSE3-NEXT: phaddw %xmm2, %xmm01342; SSSE3-NEXT: phaddw %xmm3, %xmm11343; SSSE3-NEXT: retq1344;1345; AVX1-LABEL: avx2_hadd_w:1346; AVX1: # %bb.0:1347; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm21348; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm31349; AVX1-NEXT: vphaddw %xmm2, %xmm3, %xmm21350; AVX1-NEXT: vphaddw %xmm1, %xmm0, %xmm01351; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm01352; AVX1-NEXT: retq1353;1354; AVX2-LABEL: avx2_hadd_w:1355; AVX2: # %bb.0:1356; AVX2-NEXT: vphaddw %ymm1, %ymm0, %ymm01357; AVX2-NEXT: retq1358 %vecext = extractelement <16 x i16> %a, i32 01359 %vecext1 = extractelement <16 x i16> %a, i32 11360 %add = add i16 %vecext, %vecext11361 %vecinit = insertelement <16 x i16> undef, i16 %add, i32 01362 %vecext4 = extractelement <16 x i16> %a, i32 21363 %vecext6 = extractelement <16 x i16> %a, i32 31364 %add8 = add i16 %vecext4, %vecext61365 %vecinit10 = insertelement <16 x i16> %vecinit, i16 %add8, i32 11366 %vecext11 = extractelement <16 x i16> %a, i32 41367 %vecext13 = extractelement <16 x i16> %a, i32 51368 %add15 = add i16 %vecext11, %vecext131369 %vecinit17 = insertelement <16 x i16> %vecinit10, i16 %add15, i32 21370 %vecext18 = extractelement <16 x i16> %a, i32 61371 %vecext20 = extractelement <16 x i16> %a, i32 71372 %add22 = add i16 %vecext18, %vecext201373 %vecinit24 = insertelement <16 x i16> %vecinit17, i16 %add22, i32 31374 %vecext25 = extractelement <16 x i16> %a, i32 81375 %vecext27 = extractelement <16 x i16> %a, i32 91376 %add29 = add i16 %vecext25, %vecext271377 %vecinit31 = insertelement <16 x i16> %vecinit24, i16 %add29, i32 81378 %vecext32 = extractelement <16 x i16> %a, i32 101379 %vecext34 = extractelement <16 x i16> %a, i32 111380 %add36 = add i16 %vecext32, %vecext341381 %vecinit38 = insertelement <16 x i16> %vecinit31, i16 %add36, i32 91382 %vecext39 = extractelement <16 x i16> %a, i32 121383 %vecext41 = extractelement <16 x i16> %a, i32 131384 %add43 = add i16 %vecext39, %vecext411385 %vecinit45 = insertelement <16 x i16> %vecinit38, i16 %add43, i32 101386 %vecext46 = extractelement <16 x i16> %a, i32 141387 %vecext48 = extractelement <16 x i16> %a, i32 151388 %add50 = add i16 %vecext46, %vecext481389 %vecinit52 = insertelement <16 x i16> %vecinit45, i16 %add50, i32 111390 %vecext53 = extractelement <16 x i16> %b, i32 01391 %vecext55 = extractelement <16 x i16> %b, i32 11392 %add57 = add i16 %vecext53, %vecext551393 %vecinit59 = insertelement <16 x i16> %vecinit52, i16 %add57, i32 41394 %vecext60 = extractelement <16 x i16> %b, i32 21395 %vecext62 = extractelement <16 x i16> %b, i32 31396 %add64 = add i16 %vecext60, %vecext621397 %vecinit66 = insertelement <16 x i16> %vecinit59, i16 %add64, i32 51398 %vecext67 = extractelement <16 x i16> %b, i32 41399 %vecext69 = extractelement <16 x i16> %b, i32 51400 %add71 = add i16 %vecext67, %vecext691401 %vecinit73 = insertelement <16 x i16> %vecinit66, i16 %add71, i32 61402 %vecext74 = extractelement <16 x i16> %b, i32 61403 %vecext76 = extractelement <16 x i16> %b, i32 71404 %add78 = add i16 %vecext74, %vecext761405 %vecinit80 = insertelement <16 x i16> %vecinit73, i16 %add78, i32 71406 %vecext81 = extractelement <16 x i16> %b, i32 81407 %vecext83 = extractelement <16 x i16> %b, i32 91408 %add85 = add i16 %vecext81, %vecext831409 %vecinit87 = insertelement <16 x i16> %vecinit80, i16 %add85, i32 121410 %vecext88 = extractelement <16 x i16> %b, i32 101411 %vecext90 = extractelement <16 x i16> %b, i32 111412 %add92 = add i16 %vecext88, %vecext901413 %vecinit94 = insertelement <16 x i16> %vecinit87, i16 %add92, i32 131414 %vecext95 = extractelement <16 x i16> %b, i32 121415 %vecext97 = extractelement <16 x i16> %b, i32 131416 %add99 = add i16 %vecext95, %vecext971417 %vecinit101 = insertelement <16 x i16> %vecinit94, i16 %add99, i32 141418 %vecext102 = extractelement <16 x i16> %b, i32 141419 %vecext104 = extractelement <16 x i16> %b, i32 151420 %add106 = add i16 %vecext102, %vecext1041421 %vecinit108 = insertelement <16 x i16> %vecinit101, i16 %add106, i32 151422 ret <16 x i16> %vecinit1081423}1424