[llvm] [X86] Guard PSADBW reduction combine against non-simple extended types (#227718) (PR #228396)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 2 04:14:51 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: Archit Gupta (Architag1503)
<details>
<summary>Changes</summary>
Fixes #<!-- -->227718
### 1. Context & Motivation
During SelectionDAG combine in the X86 backend, `combineArithReduction()` attempts to transform vector `ADD` reductions into hardware `PSADBW` (Packed Sum of Absolute Differences of Bytes) instructions. When vector elements are zero-extended from bytes or bounded within $[0, 255]$, performing byte-sum reduction via `PSADBW` provides significant throughput improvements.
When AVX-512 features are enabled (`Subtarget.hasAVX512()`), the eligibility condition permits vector element sizes $> 16$ bits even without an explicit `ISD::ZERO_EXTEND` opcode (such as when elements are masked using bitwise `AND`).
However, for non-power-of-2 or non-standard extended vector types (e.g., `<8 x i48>`), entering this transform causes a backend assertion failure.
---
### 2. Root Cause Analysis
For the reproducer `call i48 @<!-- -->llvm.vector.reduce.add.v8i48(<8 x i48> %masked)` under `-mcpu=x86-64-v4` or `-mattr=+avx512f`:
1. **Precondition Assertion Violation**:
`VT` is `EVT(i48)`, which is an extended type (`VT.isSimple()` returns `false`).
At line 48153:
```cpp
VecVT = MVT::getVectorVT(VT.getSimpleVT(), 128 / VT.getSizeInBits());
2. **Bitcast Bit-Width Mismatch**:
Even if `VT.getSimpleVT()` were not asserting, integer division `128 / 48` evaluates to `2`. This would attempt to construct `<2 x i48>` with total bit-width $2 \times 48 = 96$ bits. The subsequent bitcast at line 48154 (`DAG.getBitcast(VecVT, Rdx)`) requires `VecVT` to be a 128-bit vector type to match `Rdx` (`MVT::v2i64`), which fails for 96-bit vector types.
---
### 3. Proposed Fix
Add `VT.isSimple()` to the `PSADBW` reduction combine guard in `combineArithReduction()` in `X86ISelLowering.cpp`:
```cpp
if (Opc == ISD::ADD && VT.isSimple() && NumElts >= 4 && EltSizeInBits >= 16 &&
EltSizeInBits <= 64 && DAG.computeKnownBits(Rdx).getMaxValue().ule(255) &&
(EltSizeInBits == 16 || Rdx.getOpcode() == ISD::ZERO_EXTEND ||
Subtarget.hasAVX512()))
---
Full diff: https://github.com/llvm/llvm-project/pull/228396.diff
2 Files Affected:
- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+1-1)
- (modified) llvm/test/CodeGen/X86/vector-reduce-add-mask.ll (+275)
``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 11dbec24adb337..4bb8ee047c7773 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -48107,7 +48107,7 @@ static SDValue combineArithReduction(SDNode *ExtElt, SelectionDAG &DAG,
// If the source vector values are 0-255, then we can use PSADBW to
// sum+zext v8i8 subvectors to vXi64, then perform the reduction.
// TODO: See if its worth avoiding vXi16/i32 truncations?
- if (Opc == ISD::ADD && NumElts >= 4 && EltSizeInBits >= 16 &&
+ if (Opc == ISD::ADD && VT.isSimple() && NumElts >= 4 && EltSizeInBits >= 16 &&
EltSizeInBits <= 64 && DAG.computeKnownBits(Rdx).getMaxValue().ule(255) &&
(EltSizeInBits == 16 || Rdx.getOpcode() == ISD::ZERO_EXTEND ||
Subtarget.hasAVX512())) {
diff --git a/llvm/test/CodeGen/X86/vector-reduce-add-mask.ll b/llvm/test/CodeGen/X86/vector-reduce-add-mask.ll
index 6a6e2a2c9e13b8..687cb956d3acbd 100644
--- a/llvm/test/CodeGen/X86/vector-reduce-add-mask.ll
+++ b/llvm/test/CodeGen/X86/vector-reduce-add-mask.ll
@@ -2379,6 +2379,281 @@ define i16 @test_v64i16_v64i8(<64 x i16> %a0) nounwind {
ret i16 %2
}
+define i48 @test_v8i48(<8 x i48> %a0) {
+; X86-SSE2-LABEL: test_v8i48:
+; X86-SSE2: # %bb.0:
+; X86-SSE2-NEXT: movdqu {{[0-9]+}}(%esp), %xmm0
+; X86-SSE2-NEXT: movdqu {{[0-9]+}}(%esp), %xmm1
+; X86-SSE2-NEXT: movdqu {{[0-9]+}}(%esp), %xmm2
+; X86-SSE2-NEXT: movdqu {{[0-9]+}}(%esp), %xmm3
+; X86-SSE2-NEXT: movdqa {{.*#+}} xmm4 = [1,0,1,0]
+; X86-SSE2-NEXT: pand %xmm4, %xmm3
+; X86-SSE2-NEXT: pand %xmm4, %xmm2
+; X86-SSE2-NEXT: paddq %xmm3, %xmm2
+; X86-SSE2-NEXT: pand %xmm4, %xmm1
+; X86-SSE2-NEXT: pand %xmm4, %xmm0
+; X86-SSE2-NEXT: paddq %xmm1, %xmm0
+; X86-SSE2-NEXT: paddq %xmm2, %xmm0
+; X86-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-SSE2-NEXT: paddq %xmm0, %xmm1
+; X86-SSE2-NEXT: movd %xmm1, %eax
+; X86-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; X86-SSE2-NEXT: movd %xmm0, %edx
+; X86-SSE2-NEXT: retl
+;
+; X64-SSE2-LABEL: test_v8i48:
+; X64-SSE2: # %bb.0:
+; X64-SSE2-NEXT: movq %rsi, %xmm0
+; X64-SSE2-NEXT: movq %rdi, %xmm1
+; X64-SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
+; X64-SSE2-NEXT: movq %r9, %xmm0
+; X64-SSE2-NEXT: movq %r8, %xmm2
+; X64-SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]
+; X64-SSE2-NEXT: movq %rcx, %xmm0
+; X64-SSE2-NEXT: movq %rdx, %xmm3
+; X64-SSE2-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm0[0]
+; X64-SSE2-NEXT: movdqa {{.*#+}} xmm0 = [1,1]
+; X64-SSE2-NEXT: pand %xmm0, %xmm3
+; X64-SSE2-NEXT: pand %xmm0, %xmm2
+; X64-SSE2-NEXT: pand %xmm0, %xmm1
+; X64-SSE2-NEXT: paddq %xmm2, %xmm1
+; X64-SSE2-NEXT: pand {{[0-9]+}}(%rsp), %xmm0
+; X64-SSE2-NEXT: paddq %xmm3, %xmm0
+; X64-SSE2-NEXT: paddq %xmm1, %xmm0
+; X64-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X64-SSE2-NEXT: paddq %xmm0, %xmm1
+; X64-SSE2-NEXT: movq %xmm1, %rax
+; X64-SSE2-NEXT: retq
+;
+; X86-SSE4-LABEL: test_v8i48:
+; X86-SSE4: # %bb.0:
+; X86-SSE4-NEXT: movdqu {{[0-9]+}}(%esp), %xmm0
+; X86-SSE4-NEXT: movdqu {{[0-9]+}}(%esp), %xmm1
+; X86-SSE4-NEXT: movdqu {{[0-9]+}}(%esp), %xmm2
+; X86-SSE4-NEXT: movdqu {{[0-9]+}}(%esp), %xmm3
+; X86-SSE4-NEXT: pmovsxbq {{.*#+}} xmm4 = [1,1]
+; X86-SSE4-NEXT: pand %xmm4, %xmm3
+; X86-SSE4-NEXT: pand %xmm4, %xmm2
+; X86-SSE4-NEXT: paddq %xmm3, %xmm2
+; X86-SSE4-NEXT: pand %xmm4, %xmm1
+; X86-SSE4-NEXT: pand %xmm4, %xmm0
+; X86-SSE4-NEXT: paddq %xmm1, %xmm0
+; X86-SSE4-NEXT: paddq %xmm2, %xmm0
+; X86-SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-SSE4-NEXT: paddq %xmm0, %xmm1
+; X86-SSE4-NEXT: movd %xmm1, %eax
+; X86-SSE4-NEXT: pextrd $1, %xmm1, %edx
+; X86-SSE4-NEXT: retl
+;
+; X64-SSE4-LABEL: test_v8i48:
+; X64-SSE4: # %bb.0:
+; X64-SSE4-NEXT: movq %rsi, %xmm0
+; X64-SSE4-NEXT: movq %rdi, %xmm1
+; X64-SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
+; X64-SSE4-NEXT: movq %r9, %xmm0
+; X64-SSE4-NEXT: movq %r8, %xmm2
+; X64-SSE4-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]
+; X64-SSE4-NEXT: movq %rcx, %xmm0
+; X64-SSE4-NEXT: movq %rdx, %xmm3
+; X64-SSE4-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm0[0]
+; X64-SSE4-NEXT: pmovsxbq {{.*#+}} xmm0 = [1,1]
+; X64-SSE4-NEXT: pand %xmm0, %xmm3
+; X64-SSE4-NEXT: pand %xmm0, %xmm2
+; X64-SSE4-NEXT: pand %xmm0, %xmm1
+; X64-SSE4-NEXT: paddq %xmm2, %xmm1
+; X64-SSE4-NEXT: pand {{[0-9]+}}(%rsp), %xmm0
+; X64-SSE4-NEXT: paddq %xmm3, %xmm0
+; X64-SSE4-NEXT: paddq %xmm1, %xmm0
+; X64-SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X64-SSE4-NEXT: paddq %xmm0, %xmm1
+; X64-SSE4-NEXT: movq %xmm1, %rax
+; X64-SSE4-NEXT: retq
+;
+; X86-AVX1-LABEL: test_v8i48:
+; X86-AVX1: # %bb.0:
+; X86-AVX1-NEXT: vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-AVX1-NEXT: vpinsrd $2, {{[0-9]+}}(%esp), %xmm0, %xmm0
+; X86-AVX1-NEXT: vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-AVX1-NEXT: vpinsrd $2, {{[0-9]+}}(%esp), %xmm1, %xmm1
+; X86-AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
+; X86-AVX1-NEXT: vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-AVX1-NEXT: vpinsrd $2, {{[0-9]+}}(%esp), %xmm1, %xmm1
+; X86-AVX1-NEXT: vmovd {{.*#+}} xmm2 = mem[0],zero,zero,zero
+; X86-AVX1-NEXT: vpinsrd $2, {{[0-9]+}}(%esp), %xmm2, %xmm2
+; X86-AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; X86-AVX1-NEXT: vbroadcastsd {{.*#+}} ymm2 = [1,0,1,0,1,0,1,0]
+; X86-AVX1-NEXT: vandps %ymm2, %ymm1, %ymm1
+; X86-AVX1-NEXT: vandps %ymm2, %ymm0, %ymm0
+; X86-AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2
+; X86-AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3
+; X86-AVX1-NEXT: vpaddq %xmm2, %xmm3, %xmm2
+; X86-AVX1-NEXT: vpaddq %xmm0, %xmm1, %xmm0
+; X86-AVX1-NEXT: vpaddq %xmm2, %xmm0, %xmm0
+; X86-AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0
+; X86-AVX1-NEXT: vmovd %xmm0, %eax
+; X86-AVX1-NEXT: vpextrd $1, %xmm0, %edx
+; X86-AVX1-NEXT: vzeroupper
+; X86-AVX1-NEXT: retl
+;
+; X64-AVX1-LABEL: test_v8i48:
+; X64-AVX1: # %bb.0:
+; X64-AVX1-NEXT: vmovq %rcx, %xmm0
+; X64-AVX1-NEXT: vmovq %rdx, %xmm1
+; X64-AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
+; X64-AVX1-NEXT: vmovq %rsi, %xmm1
+; X64-AVX1-NEXT: vmovq %rdi, %xmm2
+; X64-AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
+; X64-AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0
+; X64-AVX1-NEXT: vmovq %r9, %xmm1
+; X64-AVX1-NEXT: vmovq %r8, %xmm2
+; X64-AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
+; X64-AVX1-NEXT: vinsertf128 $1, {{[0-9]+}}(%rsp), %ymm1, %ymm1
+; X64-AVX1-NEXT: vbroadcastsd {{.*#+}} ymm2 = [1,1,1,1]
+; X64-AVX1-NEXT: vandps %ymm2, %ymm0, %ymm0
+; X64-AVX1-NEXT: vandps %ymm2, %ymm1, %ymm1
+; X64-AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2
+; X64-AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3
+; X64-AVX1-NEXT: vpaddq %xmm3, %xmm2, %xmm2
+; X64-AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0
+; X64-AVX1-NEXT: vpaddq %xmm2, %xmm0, %xmm0
+; X64-AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X64-AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0
+; X64-AVX1-NEXT: vmovq %xmm0, %rax
+; X64-AVX1-NEXT: vzeroupper
+; X64-AVX1-NEXT: retq
+;
+; X86-AVX2-LABEL: test_v8i48:
+; X86-AVX2: # %bb.0:
+; X86-AVX2-NEXT: vpbroadcastq {{.*#+}} ymm0 = [1,0,1,0,1,0,1,0]
+; X86-AVX2-NEXT: vpand {{[0-9]+}}(%esp), %ymm0, %ymm1
+; X86-AVX2-NEXT: vpand {{[0-9]+}}(%esp), %ymm0, %ymm0
+; X86-AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0
+; X86-AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
+; X86-AVX2-NEXT: vpaddq %xmm1, %xmm0, %xmm0
+; X86-AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X86-AVX2-NEXT: vpaddq %xmm1, %xmm0, %xmm0
+; X86-AVX2-NEXT: vmovd %xmm0, %eax
+; X86-AVX2-NEXT: vpextrd $1, %xmm0, %edx
+; X86-AVX2-NEXT: vzeroupper
+; X86-AVX2-NEXT: retl
+;
+; X64-AVX2-LABEL: test_v8i48:
+; X64-AVX2: # %bb.0:
+; X64-AVX2-NEXT: vmovq %rcx, %xmm0
+; X64-AVX2-NEXT: vmovq %rdx, %xmm1
+; X64-AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
+; X64-AVX2-NEXT: vmovq %rsi, %xmm1
+; X64-AVX2-NEXT: vmovq %rdi, %xmm2
+; X64-AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
+; X64-AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0
+; X64-AVX2-NEXT: vmovq %r9, %xmm1
+; X64-AVX2-NEXT: vmovq %r8, %xmm2
+; X64-AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
+; X64-AVX2-NEXT: vinserti128 $1, {{[0-9]+}}(%rsp), %ymm1, %ymm1
+; X64-AVX2-NEXT: vpbroadcastq {{.*#+}} ymm2 = [1,1,1,1]
+; X64-AVX2-NEXT: vpand %ymm2, %ymm0, %ymm0
+; X64-AVX2-NEXT: vpand %ymm2, %ymm1, %ymm1
+; X64-AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0
+; X64-AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
+; X64-AVX2-NEXT: vpaddq %xmm1, %xmm0, %xmm0
+; X64-AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; X64-AVX2-NEXT: vpaddq %xmm1, %xmm0, %xmm0
+; X64-AVX2-NEXT: vmovq %xmm0, %rax
+; X64-AVX2-NEXT: vzeroupper
+; X64-AVX2-NEXT: retq
+;
+; AVX512F-LABEL: test_v8i48:
+; AVX512F: # %bb.0:
+; AVX512F-NEXT: vpandq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; AVX512F-NEXT: vpmovqb %zmm0, %xmm1
+; AVX512F-NEXT: vextracti32x4 $2, %zmm0, %xmm2
+; AVX512F-NEXT: vpunpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
+; AVX512F-NEXT: vpextrb $8, %xmm2, %eax
+; AVX512F-NEXT: vpinsrb $5, %eax, %xmm1, %xmm1
+; AVX512F-NEXT: vextracti32x4 $3, %zmm0, %xmm0
+; AVX512F-NEXT: vmovd %xmm0, %eax
+; AVX512F-NEXT: vpinsrb $6, %eax, %xmm1, %xmm1
+; AVX512F-NEXT: vpextrb $8, %xmm0, %eax
+; AVX512F-NEXT: vpinsrb $7, %eax, %xmm1, %xmm0
+; AVX512F-NEXT: vpxor %xmm1, %xmm1, %xmm1
+; AVX512F-NEXT: vpsadbw %xmm1, %xmm0, %xmm0
+; AVX512F-NEXT: vmovd %xmm0, %eax
+; AVX512F-NEXT: vzeroupper
+; AVX512F-NEXT: retq
+;
+; AVX512VL-LABEL: test_v8i48:
+; AVX512VL: # %bb.0:
+; AVX512VL-NEXT: vpandq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; AVX512VL-NEXT: vpmovqb %xmm0, %xmm1
+; AVX512VL-NEXT: vextracti128 $1, %ymm0, %xmm2
+; AVX512VL-NEXT: vmovd %xmm2, %eax
+; AVX512VL-NEXT: vpinsrb $2, %eax, %xmm1, %xmm1
+; AVX512VL-NEXT: vpextrb $8, %xmm2, %eax
+; AVX512VL-NEXT: vpinsrb $3, %eax, %xmm1, %xmm1
+; AVX512VL-NEXT: vextracti32x4 $2, %zmm0, %xmm2
+; AVX512VL-NEXT: vpunpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
+; AVX512VL-NEXT: vpextrb $8, %xmm2, %eax
+; AVX512VL-NEXT: vpinsrb $5, %eax, %xmm1, %xmm1
+; AVX512VL-NEXT: vextracti32x4 $3, %zmm0, %xmm0
+; AVX512VL-NEXT: vmovd %xmm0, %eax
+; AVX512VL-NEXT: vpinsrb $6, %eax, %xmm1, %xmm1
+; AVX512VL-NEXT: vpextrb $8, %xmm0, %eax
+; AVX512VL-NEXT: vpinsrb $7, %eax, %xmm1, %xmm0
+; AVX512VL-NEXT: vpxor %xmm1, %xmm1, %xmm1
+; AVX512VL-NEXT: vpsadbw %xmm1, %xmm0, %xmm0
+; AVX512VL-NEXT: vmovd %xmm0, %eax
+; AVX512VL-NEXT: vzeroupper
+; AVX512VL-NEXT: retq
+;
+; AVX512BW-LABEL: test_v8i48:
+; AVX512BW: # %bb.0:
+; AVX512BW-NEXT: vpandq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; AVX512BW-NEXT: vpmovqb %zmm0, %xmm1
+; AVX512BW-NEXT: vextracti32x4 $2, %zmm0, %xmm2
+; AVX512BW-NEXT: vpunpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
+; AVX512BW-NEXT: vpextrb $8, %xmm2, %eax
+; AVX512BW-NEXT: vpinsrb $5, %eax, %xmm1, %xmm1
+; AVX512BW-NEXT: vextracti32x4 $3, %zmm0, %xmm0
+; AVX512BW-NEXT: vmovd %xmm0, %eax
+; AVX512BW-NEXT: vpinsrb $6, %eax, %xmm1, %xmm1
+; AVX512BW-NEXT: vpextrb $8, %xmm0, %eax
+; AVX512BW-NEXT: vpinsrb $7, %eax, %xmm1, %xmm0
+; AVX512BW-NEXT: vpxor %xmm1, %xmm1, %xmm1
+; AVX512BW-NEXT: vpsadbw %xmm1, %xmm0, %xmm0
+; AVX512BW-NEXT: vmovd %xmm0, %eax
+; AVX512BW-NEXT: vzeroupper
+; AVX512BW-NEXT: retq
+;
+; AVX512BWVL-LABEL: test_v8i48:
+; AVX512BWVL: # %bb.0:
+; AVX512BWVL-NEXT: vpandq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; AVX512BWVL-NEXT: vpmovqb %xmm0, %xmm1
+; AVX512BWVL-NEXT: vextracti128 $1, %ymm0, %xmm2
+; AVX512BWVL-NEXT: vmovd %xmm2, %eax
+; AVX512BWVL-NEXT: vpinsrb $2, %eax, %xmm1, %xmm1
+; AVX512BWVL-NEXT: vpextrb $8, %xmm2, %eax
+; AVX512BWVL-NEXT: vpinsrb $3, %eax, %xmm1, %xmm1
+; AVX512BWVL-NEXT: vextracti32x4 $2, %zmm0, %xmm2
+; AVX512BWVL-NEXT: vpunpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
+; AVX512BWVL-NEXT: vpextrb $8, %xmm2, %eax
+; AVX512BWVL-NEXT: vpinsrb $5, %eax, %xmm1, %xmm1
+; AVX512BWVL-NEXT: vextracti32x4 $3, %zmm0, %xmm0
+; AVX512BWVL-NEXT: vmovd %xmm0, %eax
+; AVX512BWVL-NEXT: vpinsrb $6, %eax, %xmm1, %xmm1
+; AVX512BWVL-NEXT: vpextrb $8, %xmm0, %eax
+; AVX512BWVL-NEXT: vpinsrb $7, %eax, %xmm1, %xmm0
+; AVX512BWVL-NEXT: vpxor %xmm1, %xmm1, %xmm1
+; AVX512BWVL-NEXT: vpsadbw %xmm1, %xmm0, %xmm0
+; AVX512BWVL-NEXT: vmovd %xmm0, %eax
+; AVX512BWVL-NEXT: vzeroupper
+; AVX512BWVL-NEXT: retq
+ %1 = and <8 x i48> %a0, splat (i48 1)
+ %2 = call i48 @llvm.vector.reduce.add.v8i48(<8 x i48> %1)
+ ret i48 %2
+}
+
+declare i48 @llvm.vector.reduce.add.v8i48(<8 x i48>)
declare i64 @llvm.vector.reduce.add.v2i64(<2 x i64>)
declare i64 @llvm.vector.reduce.add.v4i64(<4 x i64>)
declare i64 @llvm.vector.reduce.add.v8i64(<8 x i64>)
``````````
</details>
https://github.com/llvm/llvm-project/pull/228396
More information about the llvm-commits
mailing list