[llvm] [X86] phaddsub-extract.ll - pull out optsize / pgso tests and move to vector-reduce-add-codesize.ll test file (PR #206492)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 06:34:42 PDT 2026


https://github.com/RKSimon created https://github.com/llvm/llvm-project/pull/206492

We already have PhaseOrdering middle-end tests for the @llvm.vector.reduce.add pattern matching

>From 965609a98040d2bebf02dcb35fb7275a98f88ab3 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 29 Jun 2026 14:33:51 +0100
Subject: [PATCH] [X86] phaddsub-extract.ll - pull out optsize / pgso tests and
 move to vector-reduce-add-codesize.ll test file

We already have PhaseOrdering middle-end tests for the @llvm.vector.reduce.add pattern matching
---
 llvm/test/CodeGen/X86/phaddsub-extract.ll     | 318 -----------
 .../CodeGen/X86/vector-reduce-add-codesize.ll | 494 ++++++++++++++++++
 2 files changed, 494 insertions(+), 318 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/vector-reduce-add-codesize.ll

diff --git a/llvm/test/CodeGen/X86/phaddsub-extract.ll b/llvm/test/CodeGen/X86/phaddsub-extract.ll
index 4ddb8a9494894..b7777af457f1d 100644
--- a/llvm/test/CodeGen/X86/phaddsub-extract.ll
+++ b/llvm/test/CodeGen/X86/phaddsub-extract.ll
@@ -1832,321 +1832,3 @@ define <2 x i64> @negative_extract_v16i16_v8i16(<4 x i64> %a0) {
   %f = shufflevector <4 x i64> %e, <4 x i64> undef, <2 x i32> <i32 0, i32 1>
   ret <2 x i64> %f
 }
-
-; PR42023 - https://bugs.llvm.org/show_bug.cgi?id=42023
-
-define i16 @hadd16_8(<8 x i16> %x223) {
-; SSE3-SLOW-LABEL: hadd16_8:
-; SSE3-SLOW:       # %bb.0:
-; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; SSE3-SLOW-NEXT:    paddw %xmm0, %xmm1
-; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
-; SSE3-SLOW-NEXT:    paddw %xmm1, %xmm0
-; SSE3-SLOW-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-SLOW-NEXT:    psrld $16, %xmm1
-; SSE3-SLOW-NEXT:    paddw %xmm0, %xmm1
-; SSE3-SLOW-NEXT:    movd %xmm1, %eax
-; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
-; SSE3-SLOW-NEXT:    retq
-;
-; SSE3-FAST-LABEL: hadd16_8:
-; SSE3-FAST:       # %bb.0:
-; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
-; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
-; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
-; SSE3-FAST-NEXT:    movd %xmm0, %eax
-; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
-; SSE3-FAST-NEXT:    retq
-;
-; AVX-SLOW-LABEL: hadd16_8:
-; AVX-SLOW:       # %bb.0:
-; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; AVX-SLOW-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; AVX-SLOW-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vpsrld $16, %xmm0, %xmm1
-; AVX-SLOW-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
-; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
-; AVX-SLOW-NEXT:    retq
-;
-; AVX-FAST-LABEL: hadd16_8:
-; AVX-FAST:       # %bb.0:
-; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vmovd %xmm0, %eax
-; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
-; AVX-FAST-NEXT:    retq
-  %x224 = shufflevector <8 x i16> %x223, <8 x i16> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x225 = add <8 x i16> %x223, %x224
-  %x226 = shufflevector <8 x i16> %x225, <8 x i16> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x227 = add <8 x i16> %x225, %x226
-  %x228 = shufflevector <8 x i16> %x227, <8 x i16> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x229 = add <8 x i16> %x227, %x228
-  %x230 = extractelement <8 x i16> %x229, i32 0
-  ret i16 %x230
-}
-
-define i32 @hadd32_4(<4 x i32> %x225) {
-; SSE3-SLOW-LABEL: hadd32_4:
-; SSE3-SLOW:       # %bb.0:
-; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; SSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
-; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
-; SSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
-; SSE3-SLOW-NEXT:    movd %xmm0, %eax
-; SSE3-SLOW-NEXT:    retq
-;
-; SSE3-FAST-LABEL: hadd32_4:
-; SSE3-FAST:       # %bb.0:
-; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
-; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
-; SSE3-FAST-NEXT:    movd %xmm0, %eax
-; SSE3-FAST-NEXT:    retq
-;
-; AVX-SLOW-LABEL: hadd32_4:
-; AVX-SLOW:       # %bb.0:
-; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
-; AVX-SLOW-NEXT:    retq
-;
-; AVX-FAST-LABEL: hadd32_4:
-; AVX-FAST:       # %bb.0:
-; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vmovd %xmm0, %eax
-; AVX-FAST-NEXT:    retq
-  %x226 = shufflevector <4 x i32> %x225, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
-  %x227 = add <4 x i32> %x225, %x226
-  %x228 = shufflevector <4 x i32> %x227, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
-  %x229 = add <4 x i32> %x227, %x228
-  %x230 = extractelement <4 x i32> %x229, i32 0
-  ret i32 %x230
-}
-
-define i32 @hadd32_8(<8 x i32> %x225) {
-; SSE3-SLOW-LABEL: hadd32_8:
-; SSE3-SLOW:       # %bb.0:
-; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; SSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
-; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
-; SSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
-; SSE3-SLOW-NEXT:    movd %xmm0, %eax
-; SSE3-SLOW-NEXT:    retq
-;
-; SSE3-FAST-LABEL: hadd32_8:
-; SSE3-FAST:       # %bb.0:
-; SSE3-FAST-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; SSE3-FAST-NEXT:    paddd %xmm0, %xmm1
-; SSE3-FAST-NEXT:    phaddd %xmm1, %xmm1
-; SSE3-FAST-NEXT:    movd %xmm1, %eax
-; SSE3-FAST-NEXT:    retq
-;
-; AVX-SLOW-LABEL: hadd32_8:
-; AVX-SLOW:       # %bb.0:
-; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
-; AVX-SLOW-NEXT:    vzeroupper
-; AVX-SLOW-NEXT:    retq
-;
-; AVX-FAST-LABEL: hadd32_8:
-; AVX-FAST:       # %bb.0:
-; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vmovd %xmm0, %eax
-; AVX-FAST-NEXT:    vzeroupper
-; AVX-FAST-NEXT:    retq
-  %x226 = shufflevector <8 x i32> %x225, <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x227 = add <8 x i32> %x225, %x226
-  %x228 = shufflevector <8 x i32> %x227, <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x229 = add <8 x i32> %x227, %x228
-  %x230 = extractelement <8 x i32> %x229, i32 0
-  ret i32 %x230
-}
-
-define i32 @hadd32_16(<16 x i32> %x225) {
-; SSE3-SLOW-LABEL: hadd32_16:
-; SSE3-SLOW:       # %bb.0:
-; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; SSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
-; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
-; SSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
-; SSE3-SLOW-NEXT:    movd %xmm0, %eax
-; SSE3-SLOW-NEXT:    retq
-;
-; SSE3-FAST-LABEL: hadd32_16:
-; SSE3-FAST:       # %bb.0:
-; SSE3-FAST-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; SSE3-FAST-NEXT:    paddd %xmm0, %xmm1
-; SSE3-FAST-NEXT:    phaddd %xmm1, %xmm1
-; SSE3-FAST-NEXT:    movd %xmm1, %eax
-; SSE3-FAST-NEXT:    retq
-;
-; AVX-SLOW-LABEL: hadd32_16:
-; AVX-SLOW:       # %bb.0:
-; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
-; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
-; AVX-SLOW-NEXT:    vzeroupper
-; AVX-SLOW-NEXT:    retq
-;
-; AVX-FAST-LABEL: hadd32_16:
-; AVX-FAST:       # %bb.0:
-; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-FAST-NEXT:    vmovd %xmm0, %eax
-; AVX-FAST-NEXT:    vzeroupper
-; AVX-FAST-NEXT:    retq
-  %x226 = shufflevector <16 x i32> %x225, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x227 = add <16 x i32> %x225, %x226
-  %x228 = shufflevector <16 x i32> %x227, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x229 = add <16 x i32> %x227, %x228
-  %x230 = extractelement <16 x i32> %x229, i32 0
-  ret i32 %x230
-}
-
-define i16 @hadd16_8_optsize(<8 x i16> %x223) optsize {
-; SSE3-LABEL: hadd16_8_optsize:
-; SSE3:       # %bb.0:
-; SSE3-NEXT:    phaddw %xmm0, %xmm0
-; SSE3-NEXT:    phaddw %xmm0, %xmm0
-; SSE3-NEXT:    phaddw %xmm0, %xmm0
-; SSE3-NEXT:    movd %xmm0, %eax
-; SSE3-NEXT:    # kill: def $ax killed $ax killed $eax
-; SSE3-NEXT:    retq
-;
-; AVX-LABEL: hadd16_8_optsize:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vmovd %xmm0, %eax
-; AVX-NEXT:    # kill: def $ax killed $ax killed $eax
-; AVX-NEXT:    retq
-  %x224 = shufflevector <8 x i16> %x223, <8 x i16> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x225 = add <8 x i16> %x223, %x224
-  %x226 = shufflevector <8 x i16> %x225, <8 x i16> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x227 = add <8 x i16> %x225, %x226
-  %x228 = shufflevector <8 x i16> %x227, <8 x i16> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x229 = add <8 x i16> %x227, %x228
-  %x230 = extractelement <8 x i16> %x229, i32 0
-  ret i16 %x230
-}
-
-define i32 @hadd32_4_optsize(<4 x i32> %x225) optsize {
-; SSE3-LABEL: hadd32_4_optsize:
-; SSE3:       # %bb.0:
-; SSE3-NEXT:    phaddd %xmm0, %xmm0
-; SSE3-NEXT:    phaddd %xmm0, %xmm0
-; SSE3-NEXT:    movd %xmm0, %eax
-; SSE3-NEXT:    retq
-;
-; AVX-LABEL: hadd32_4_optsize:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vmovd %xmm0, %eax
-; AVX-NEXT:    retq
-  %x226 = shufflevector <4 x i32> %x225, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
-  %x227 = add <4 x i32> %x225, %x226
-  %x228 = shufflevector <4 x i32> %x227, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
-  %x229 = add <4 x i32> %x227, %x228
-  %x230 = extractelement <4 x i32> %x229, i32 0
-  ret i32 %x230
-}
-
-define i32 @hadd32_4_pgso(<4 x i32> %x225) !prof !14 {
-; SSE3-LABEL: hadd32_4_pgso:
-; SSE3:       # %bb.0:
-; SSE3-NEXT:    phaddd %xmm0, %xmm0
-; SSE3-NEXT:    phaddd %xmm0, %xmm0
-; SSE3-NEXT:    movd %xmm0, %eax
-; SSE3-NEXT:    retq
-;
-; AVX-LABEL: hadd32_4_pgso:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vmovd %xmm0, %eax
-; AVX-NEXT:    retq
-  %x226 = shufflevector <4 x i32> %x225, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
-  %x227 = add <4 x i32> %x225, %x226
-  %x228 = shufflevector <4 x i32> %x227, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
-  %x229 = add <4 x i32> %x227, %x228
-  %x230 = extractelement <4 x i32> %x229, i32 0
-  ret i32 %x230
-}
-
-define i32 @hadd32_8_optsize(<8 x i32> %x225) optsize {
-; SSE3-LABEL: hadd32_8_optsize:
-; SSE3:       # %bb.0:
-; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; SSE3-NEXT:    paddd %xmm0, %xmm1
-; SSE3-NEXT:    phaddd %xmm1, %xmm1
-; SSE3-NEXT:    movd %xmm1, %eax
-; SSE3-NEXT:    retq
-;
-; AVX-LABEL: hadd32_8_optsize:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vmovd %xmm0, %eax
-; AVX-NEXT:    vzeroupper
-; AVX-NEXT:    retq
-  %x226 = shufflevector <8 x i32> %x225, <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x227 = add <8 x i32> %x225, %x226
-  %x228 = shufflevector <8 x i32> %x227, <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x229 = add <8 x i32> %x227, %x228
-  %x230 = extractelement <8 x i32> %x229, i32 0
-  ret i32 %x230
-}
-
-define i32 @hadd32_16_optsize(<16 x i32> %x225) optsize {
-; SSE3-LABEL: hadd32_16_optsize:
-; SSE3:       # %bb.0:
-; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
-; SSE3-NEXT:    paddd %xmm0, %xmm1
-; SSE3-NEXT:    phaddd %xmm1, %xmm1
-; SSE3-NEXT:    movd %xmm1, %eax
-; SSE3-NEXT:    retq
-;
-; AVX-LABEL: hadd32_16_optsize:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
-; AVX-NEXT:    vmovd %xmm0, %eax
-; AVX-NEXT:    vzeroupper
-; AVX-NEXT:    retq
-  %x226 = shufflevector <16 x i32> %x225, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x227 = add <16 x i32> %x225, %x226
-  %x228 = shufflevector <16 x i32> %x227, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
-  %x229 = add <16 x i32> %x227, %x228
-  %x230 = extractelement <16 x i32> %x229, i32 0
-  ret i32 %x230
-}
-
-!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"ProfileSummary", !1}
-!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
-!2 = !{!"ProfileFormat", !"InstrProf"}
-!3 = !{!"TotalCount", i64 10000}
-!4 = !{!"MaxCount", i64 10}
-!5 = !{!"MaxInternalCount", i64 1}
-!6 = !{!"MaxFunctionCount", i64 1000}
-!7 = !{!"NumCounts", i64 3}
-!8 = !{!"NumFunctions", i64 3}
-!9 = !{!"DetailedSummary", !10}
-!10 = !{!11, !12, !13}
-!11 = !{i32 10000, i64 100, i32 1}
-!12 = !{i32 999000, i64 100, i32 1}
-!13 = !{i32 999999, i64 1, i32 2}
-!14 = !{!"function_entry_count", i64 0}
diff --git a/llvm/test/CodeGen/X86/vector-reduce-add-codesize.ll b/llvm/test/CodeGen/X86/vector-reduce-add-codesize.ll
new file mode 100644
index 0000000000000..038b454df26e8
--- /dev/null
+++ b/llvm/test/CodeGen/X86/vector-reduce-add-codesize.ll
@@ -0,0 +1,494 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686--   -mattr=+sse2             | FileCheck %s --check-prefixes=SSE2,X86-SSE2
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2             | FileCheck %s --check-prefixes=SSE2,X64-SSE2
+; RUN: llc < %s -mtriple=i686--   -mattr=+ssse3            | FileCheck %s --check-prefixes=SSSE3,X86-SSSE3,SSSE3-SLOW,X86-SSSE3-SLOW
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+ssse3            | FileCheck %s --check-prefixes=SSSE3,X64-SSSE3,SSSE3-SLOW,X64-SSSE3-SLOW
+; RUN: llc < %s -mtriple=i686--   -mattr=+ssse3,+fast-hops | FileCheck %s --check-prefixes=SSSE3,X86-SSSE3,SSSE3-FAST,X86-SSSE3-FAST
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+ssse3,+fast-hops | FileCheck %s --check-prefixes=SSSE3,X64-SSSE3,SSSE3-FAST,X64-SSSE3-FAST
+; RUN: llc < %s -mtriple=i686--   -mattr=+avx              | FileCheck %s --check-prefixes=AVX,AVX1-SLOW
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx              | FileCheck %s --check-prefixes=AVX,AVX1-SLOW
+; RUN: llc < %s -mtriple=i686--   -mattr=+avx,+fast-hops   | FileCheck %s --check-prefixes=AVX,AVX1-FAST
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx,+fast-hops   | FileCheck %s --check-prefixes=AVX,AVX1-FAST
+; RUN: llc < %s -mtriple=i686--   -mattr=+avx2             | FileCheck %s --check-prefixes=AVX,AVX2
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2             | FileCheck %s --check-prefixes=AVX,AVX2
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f,+avx512bw | FileCheck %s --check-prefixes=AVX,AVX2
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f,+avx512bw,+avx512vl | FileCheck %s --check-prefixes=AVX,AVX2
+
+; PR42023 - https://bugs.llvm.org/show_bug.cgi?id=42023
+
+define i16 @hadd16_8(<8 x i16> %x223) nounwind {
+; SSE2-LABEL: hadd16_8:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE2-NEXT:    paddw %xmm0, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSE2-NEXT:    paddw %xmm1, %xmm0
+; SSE2-NEXT:    movdqa %xmm0, %xmm1
+; SSE2-NEXT:    psrld $16, %xmm1
+; SSE2-NEXT:    paddw %xmm0, %xmm1
+; SSE2-NEXT:    movd %xmm1, %eax
+; SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
+; SSE2-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-SLOW-LABEL: hadd16_8:
+; SSSE3-SLOW:       # %bb.0:
+; SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSSE3-SLOW-NEXT:    paddw %xmm0, %xmm1
+; SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSSE3-SLOW-NEXT:    paddw %xmm1, %xmm0
+; SSSE3-SLOW-NEXT:    movdqa %xmm0, %xmm1
+; SSSE3-SLOW-NEXT:    psrld $16, %xmm1
+; SSSE3-SLOW-NEXT:    paddw %xmm0, %xmm1
+; SSSE3-SLOW-NEXT:    movd %xmm1, %eax
+; SSSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
+; SSSE3-SLOW-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-FAST-LABEL: hadd16_8:
+; SSSE3-FAST:       # %bb.0:
+; SSSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
+; SSSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
+; SSSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
+; SSSE3-FAST-NEXT:    movd %xmm0, %eax
+; SSSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
+; SSSE3-FAST-NEXT:    ret{{[l|q]}}
+;
+; AVX1-SLOW-LABEL: hadd16_8:
+; AVX1-SLOW:       # %bb.0:
+; AVX1-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX1-SLOW-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; AVX1-SLOW-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vpsrld $16, %xmm0, %xmm1
+; AVX1-SLOW-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vmovd %xmm0, %eax
+; AVX1-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX1-SLOW-NEXT:    ret{{[l|q]}}
+;
+; AVX1-FAST-LABEL: hadd16_8:
+; AVX1-FAST:       # %bb.0:
+; AVX1-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vmovd %xmm0, %eax
+; AVX1-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX1-FAST-NEXT:    ret{{[l|q]}}
+;
+; AVX2-LABEL: hadd16_8:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX2-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; AVX2-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpsrld $16, %xmm0, %xmm1
+; AVX2-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %eax
+; AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX2-NEXT:    ret{{[l|q]}}
+  %x230 = tail call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %x223)
+  ret i16 %x230
+}
+
+define i16 @hadd16_8_optsize(<8 x i16> %x223) nounwind optsize {
+; SSE2-LABEL: hadd16_8_optsize:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE2-NEXT:    paddw %xmm0, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSE2-NEXT:    paddw %xmm1, %xmm0
+; SSE2-NEXT:    movdqa %xmm0, %xmm1
+; SSE2-NEXT:    psrld $16, %xmm1
+; SSE2-NEXT:    paddw %xmm0, %xmm1
+; SSE2-NEXT:    movd %xmm1, %eax
+; SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
+; SSE2-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-LABEL: hadd16_8_optsize:
+; SSSE3:       # %bb.0:
+; SSSE3-NEXT:    phaddw %xmm0, %xmm0
+; SSSE3-NEXT:    phaddw %xmm0, %xmm0
+; SSSE3-NEXT:    phaddw %xmm0, %xmm0
+; SSSE3-NEXT:    movd %xmm0, %eax
+; SSSE3-NEXT:    # kill: def $ax killed $ax killed $eax
+; SSSE3-NEXT:    ret{{[l|q]}}
+;
+; AVX-LABEL: hadd16_8_optsize:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vmovd %xmm0, %eax
+; AVX-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX-NEXT:    ret{{[l|q]}}
+  %x230 = tail call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %x223)
+  ret i16 %x230
+}
+
+define i32 @hadd32_4(<4 x i32> %x225) nounwind {
+; SSE2-LABEL: hadd32_4:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE2-NEXT:    paddd %xmm0, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSE2-NEXT:    paddd %xmm1, %xmm0
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-SLOW-LABEL: hadd32_4:
+; SSSE3-SLOW:       # %bb.0:
+; SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
+; SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
+; SSSE3-SLOW-NEXT:    movd %xmm0, %eax
+; SSSE3-SLOW-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-FAST-LABEL: hadd32_4:
+; SSSE3-FAST:       # %bb.0:
+; SSSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-FAST-NEXT:    movd %xmm0, %eax
+; SSSE3-FAST-NEXT:    ret{{[l|q]}}
+;
+; AVX1-SLOW-LABEL: hadd32_4:
+; AVX1-SLOW:       # %bb.0:
+; AVX1-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX1-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; AVX1-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vmovd %xmm0, %eax
+; AVX1-SLOW-NEXT:    ret{{[l|q]}}
+;
+; AVX1-FAST-LABEL: hadd32_4:
+; AVX1-FAST:       # %bb.0:
+; AVX1-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vmovd %xmm0, %eax
+; AVX1-FAST-NEXT:    ret{{[l|q]}}
+;
+; AVX2-LABEL: hadd32_4:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %eax
+; AVX2-NEXT:    ret{{[l|q]}}
+  %x230 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x225)
+  ret i32 %x230
+}
+
+define i32 @hadd32_4_optsize(<4 x i32> %x225) nounwind optsize {
+; SSE2-LABEL: hadd32_4_optsize:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE2-NEXT:    paddd %xmm0, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSE2-NEXT:    paddd %xmm1, %xmm0
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-LABEL: hadd32_4_optsize:
+; SSSE3:       # %bb.0:
+; SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-NEXT:    movd %xmm0, %eax
+; SSSE3-NEXT:    ret{{[l|q]}}
+;
+; AVX-LABEL: hadd32_4_optsize:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vmovd %xmm0, %eax
+; AVX-NEXT:    ret{{[l|q]}}
+  %x230 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x225)
+  ret i32 %x230
+}
+
+define i32 @hadd32_4_pgso(<4 x i32> %x225) nounwind !prof !14 {
+; SSE2-LABEL: hadd32_4_pgso:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE2-NEXT:    paddd %xmm0, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSE2-NEXT:    paddd %xmm1, %xmm0
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-LABEL: hadd32_4_pgso:
+; SSSE3:       # %bb.0:
+; SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-NEXT:    movd %xmm0, %eax
+; SSSE3-NEXT:    ret{{[l|q]}}
+;
+; AVX-LABEL: hadd32_4_pgso:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vmovd %xmm0, %eax
+; AVX-NEXT:    ret{{[l|q]}}
+  %x230 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x225)
+  ret i32 %x230
+}
+
+define i32 @hadd32_8(<8 x i32> %x225) nounwind {
+; SSE2-LABEL: hadd32_8:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE2-NEXT:    paddd %xmm0, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSE2-NEXT:    paddd %xmm1, %xmm0
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-SLOW-LABEL: hadd32_8:
+; SSSE3-SLOW:       # %bb.0:
+; SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
+; SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
+; SSSE3-SLOW-NEXT:    movd %xmm0, %eax
+; SSSE3-SLOW-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-FAST-LABEL: hadd32_8:
+; SSSE3-FAST:       # %bb.0:
+; SSSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-FAST-NEXT:    movd %xmm0, %eax
+; SSSE3-FAST-NEXT:    ret{{[l|q]}}
+;
+; AVX1-SLOW-LABEL: hadd32_8:
+; AVX1-SLOW:       # %bb.0:
+; AVX1-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX1-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; AVX1-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vmovd %xmm0, %eax
+; AVX1-SLOW-NEXT:    vzeroupper
+; AVX1-SLOW-NEXT:    ret{{[l|q]}}
+;
+; AVX1-FAST-LABEL: hadd32_8:
+; AVX1-FAST:       # %bb.0:
+; AVX1-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vmovd %xmm0, %eax
+; AVX1-FAST-NEXT:    vzeroupper
+; AVX1-FAST-NEXT:    ret{{[l|q]}}
+;
+; AVX2-LABEL: hadd32_8:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %eax
+; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    ret{{[l|q]}}
+  %x229 = shufflevector <8 x i32> %x225, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  %x230 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x229)
+  ret i32 %x230
+}
+
+define i32 @hadd32_8_optsize(<8 x i32> %x225) nounwind optsize {
+; SSE2-LABEL: hadd32_8_optsize:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE2-NEXT:    paddd %xmm0, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; SSE2-NEXT:    paddd %xmm1, %xmm0
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    ret{{[l|q]}}
+;
+; SSSE3-LABEL: hadd32_8_optsize:
+; SSSE3:       # %bb.0:
+; SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; SSSE3-NEXT:    movd %xmm0, %eax
+; SSSE3-NEXT:    ret{{[l|q]}}
+;
+; AVX-LABEL: hadd32_8_optsize:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vmovd %xmm0, %eax
+; AVX-NEXT:    vzeroupper
+; AVX-NEXT:    ret{{[l|q]}}
+  %x229 = shufflevector <8 x i32> %x225, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  %x230 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x229)
+  ret i32 %x230
+}
+
+define i32 @hadd32_16(<16 x i32> %x225) nounwind {
+; X86-SSE2-LABEL: hadd32_16:
+; X86-SSE2:       # %bb.0:
+; X86-SSE2-NEXT:    pushl %ebp
+; X86-SSE2-NEXT:    movl %esp, %ebp
+; X86-SSE2-NEXT:    andl $-16, %esp
+; X86-SSE2-NEXT:    subl $16, %esp
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-SSE2-NEXT:    paddd %xmm0, %xmm1
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; X86-SSE2-NEXT:    paddd %xmm1, %xmm0
+; X86-SSE2-NEXT:    movd %xmm0, %eax
+; X86-SSE2-NEXT:    movl %ebp, %esp
+; X86-SSE2-NEXT:    popl %ebp
+; X86-SSE2-NEXT:    retl
+;
+; X64-SSE2-LABEL: hadd32_16:
+; X64-SSE2:       # %bb.0:
+; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X64-SSE2-NEXT:    paddd %xmm0, %xmm1
+; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; X64-SSE2-NEXT:    paddd %xmm1, %xmm0
+; X64-SSE2-NEXT:    movd %xmm0, %eax
+; X64-SSE2-NEXT:    retq
+;
+; X86-SSSE3-SLOW-LABEL: hadd32_16:
+; X86-SSSE3-SLOW:       # %bb.0:
+; X86-SSSE3-SLOW-NEXT:    pushl %ebp
+; X86-SSSE3-SLOW-NEXT:    movl %esp, %ebp
+; X86-SSSE3-SLOW-NEXT:    andl $-16, %esp
+; X86-SSSE3-SLOW-NEXT:    subl $16, %esp
+; X86-SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-SSSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
+; X86-SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; X86-SSSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
+; X86-SSSE3-SLOW-NEXT:    movd %xmm0, %eax
+; X86-SSSE3-SLOW-NEXT:    movl %ebp, %esp
+; X86-SSSE3-SLOW-NEXT:    popl %ebp
+; X86-SSSE3-SLOW-NEXT:    retl
+;
+; X64-SSSE3-SLOW-LABEL: hadd32_16:
+; X64-SSSE3-SLOW:       # %bb.0:
+; X64-SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X64-SSSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
+; X64-SSSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; X64-SSSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
+; X64-SSSE3-SLOW-NEXT:    movd %xmm0, %eax
+; X64-SSSE3-SLOW-NEXT:    retq
+;
+; X86-SSSE3-FAST-LABEL: hadd32_16:
+; X86-SSSE3-FAST:       # %bb.0:
+; X86-SSSE3-FAST-NEXT:    pushl %ebp
+; X86-SSSE3-FAST-NEXT:    movl %esp, %ebp
+; X86-SSSE3-FAST-NEXT:    andl $-16, %esp
+; X86-SSSE3-FAST-NEXT:    subl $16, %esp
+; X86-SSSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
+; X86-SSSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
+; X86-SSSE3-FAST-NEXT:    movd %xmm0, %eax
+; X86-SSSE3-FAST-NEXT:    movl %ebp, %esp
+; X86-SSSE3-FAST-NEXT:    popl %ebp
+; X86-SSSE3-FAST-NEXT:    retl
+;
+; X64-SSSE3-FAST-LABEL: hadd32_16:
+; X64-SSSE3-FAST:       # %bb.0:
+; X64-SSSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
+; X64-SSSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
+; X64-SSSE3-FAST-NEXT:    movd %xmm0, %eax
+; X64-SSSE3-FAST-NEXT:    retq
+;
+; AVX1-SLOW-LABEL: hadd32_16:
+; AVX1-SLOW:       # %bb.0:
+; AVX1-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX1-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; AVX1-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX1-SLOW-NEXT:    vmovd %xmm0, %eax
+; AVX1-SLOW-NEXT:    vzeroupper
+; AVX1-SLOW-NEXT:    ret{{[l|q]}}
+;
+; AVX1-FAST-LABEL: hadd32_16:
+; AVX1-FAST:       # %bb.0:
+; AVX1-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX1-FAST-NEXT:    vmovd %xmm0, %eax
+; AVX1-FAST-NEXT:    vzeroupper
+; AVX1-FAST-NEXT:    ret{{[l|q]}}
+;
+; AVX2-LABEL: hadd32_16:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
+; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vmovd %xmm0, %eax
+; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    ret{{[l|q]}}
+  %x229 = shufflevector <16 x i32> %x225, <16 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  %x230 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x229)
+  ret i32 %x230
+}
+
+define i32 @hadd32_16_optsize(<16 x i32> %x225) nounwind optsize {
+; X86-SSE2-LABEL: hadd32_16_optsize:
+; X86-SSE2:       # %bb.0:
+; X86-SSE2-NEXT:    pushl %ebp
+; X86-SSE2-NEXT:    movl %esp, %ebp
+; X86-SSE2-NEXT:    andl $-16, %esp
+; X86-SSE2-NEXT:    subl $16, %esp
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-SSE2-NEXT:    paddd %xmm0, %xmm1
+; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; X86-SSE2-NEXT:    paddd %xmm1, %xmm0
+; X86-SSE2-NEXT:    movd %xmm0, %eax
+; X86-SSE2-NEXT:    movl %ebp, %esp
+; X86-SSE2-NEXT:    popl %ebp
+; X86-SSE2-NEXT:    retl
+;
+; X64-SSE2-LABEL: hadd32_16_optsize:
+; X64-SSE2:       # %bb.0:
+; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X64-SSE2-NEXT:    paddd %xmm0, %xmm1
+; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; X64-SSE2-NEXT:    paddd %xmm1, %xmm0
+; X64-SSE2-NEXT:    movd %xmm0, %eax
+; X64-SSE2-NEXT:    retq
+;
+; X86-SSSE3-LABEL: hadd32_16_optsize:
+; X86-SSSE3:       # %bb.0:
+; X86-SSSE3-NEXT:    pushl %ebp
+; X86-SSSE3-NEXT:    movl %esp, %ebp
+; X86-SSSE3-NEXT:    andl $-16, %esp
+; X86-SSSE3-NEXT:    subl $16, %esp
+; X86-SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; X86-SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; X86-SSSE3-NEXT:    movd %xmm0, %eax
+; X86-SSSE3-NEXT:    movl %ebp, %esp
+; X86-SSSE3-NEXT:    popl %ebp
+; X86-SSSE3-NEXT:    retl
+;
+; X64-SSSE3-LABEL: hadd32_16_optsize:
+; X64-SSSE3:       # %bb.0:
+; X64-SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; X64-SSSE3-NEXT:    phaddd %xmm0, %xmm0
+; X64-SSSE3-NEXT:    movd %xmm0, %eax
+; X64-SSSE3-NEXT:    retq
+;
+; AVX-LABEL: hadd32_16_optsize:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
+; AVX-NEXT:    vmovd %xmm0, %eax
+; AVX-NEXT:    vzeroupper
+; AVX-NEXT:    ret{{[l|q]}}
+  %x229 = shufflevector <16 x i32> %x225, <16 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  %x230 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %x229)
+  ret i32 %x230
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"ProfileSummary", !1}
+!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
+!2 = !{!"ProfileFormat", !"InstrProf"}
+!3 = !{!"TotalCount", i64 10000}
+!4 = !{!"MaxCount", i64 10}
+!5 = !{!"MaxInternalCount", i64 1}
+!6 = !{!"MaxFunctionCount", i64 1000}
+!7 = !{!"NumCounts", i64 3}
+!8 = !{!"NumFunctions", i64 3}
+!9 = !{!"DetailedSummary", !10}
+!10 = !{!11, !12, !13}
+!11 = !{i32 10000, i64 100, i32 1}
+!12 = !{i32 999000, i64 100, i32 1}
+!13 = !{i32 999999, i64 1, i32 2}
+!14 = !{!"function_entry_count", i64 0}



More information about the llvm-commits mailing list