[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