[llvm] [CodeGen] Optimize ctpop expansion using computeKnownBits (PR #221671)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 01:04:40 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Xu (milkHongYe)

<details>
<summary>Changes</summary>

The current SWAR popcount implementation always uses the full register width for the final accumulation step. Even when the input type is much smaller, such as when counting the bits of an `i8` value, we still use 32-bit operations to extract the result. This patch uses `computeKnownBits` to determine the minimum number of bits actually needed to represent the popcount result, and uses this information to optimize the SWAR popcount expansion.


---

Patch is 116.28 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221671.diff


11 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+12) 
- (modified) llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp (+15-3) 
- (modified) llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-bit-counting.ll (+1076-1204) 
- (modified) llvm/test/CodeGen/AMDGPU/bit-op-reduce-width-known-bits.ll (+3-3) 
- (modified) llvm/test/CodeGen/PowerPC/popcnt-zext.ll (+9-14) 
- (modified) llvm/test/CodeGen/RISCV/ctz_zero_return_test.ll (+4-22) 
- (modified) llvm/test/CodeGen/RISCV/pr56457.ll (+14-17) 
- (modified) llvm/test/CodeGen/X86/ctpop-mask.ll (+8-4) 
- (modified) llvm/test/CodeGen/X86/masked_compressstore.ll (+4-2) 
- (modified) llvm/test/CodeGen/X86/masked_expandload.ll (+4-2) 
- (modified) llvm/test/CodeGen/X86/popcnt.ll (+11-6) 


``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 710a1eda00cc1..115c92d8f7d13 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -12244,6 +12244,18 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
           OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(),
                                OutVal, SDNoFPClass);
         }
+        if (VT.isInteger()) {
+          if (auto CR = Arg.getRange()) {
+            if (!CR->isFullSet() && !CR->isEmptySet() && !CR->isUpperWrapped()) {
+              APInt Hi = CR->getUnsignedMax();
+              unsigned Bits = std::max(Hi.getActiveBits(),
+                                      (unsigned)IntegerType::MIN_INT_BITS);
+              EVT SmallVT = EVT::getIntegerVT(*DAG.getContext(), Bits);
+              OutVal = DAG.getNode(ISD::AssertZext, dl, OutVal.getValueType(),
+                                  OutVal, DAG.getValueType(SmallVT));
+            }
+          }
+        }
         ArgValues.push_back(OutVal);
       }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 16f91bb50e717..e1fea56f11550 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -10798,6 +10798,18 @@ SDValue TargetLowering::expandCTPOP(SDNode *Node, SelectionDAG &DAG) const {
   EVT ShVT = getShiftAmountTy(VT, DAG.getDataLayout());
   SDValue Op = Node->getOperand(0);
   unsigned Len = VT.getScalarSizeInBits();
+  
+  // Compute effective bit width from known bits
+  KnownBits Known = DAG.computeKnownBits(Op);
+  unsigned EffectiveLen = Known.countMaxActiveBits();
+  
+  // Round up to 8-bit boundary for byte-oriented SWAR algorithm
+  if (EffectiveLen > 0 && EffectiveLen < Len) {
+    EffectiveLen = (EffectiveLen + 7) & ~7u;
+  } else {
+    EffectiveLen = Len;
+  }
+  
   assert(VT.isInteger() && "CTPOP not implemented for this type.");
 
   // TODO: Add support for irregular type lengths.
@@ -10836,13 +10848,13 @@ SDValue TargetLowering::expandCTPOP(SDNode *Node, SelectionDAG &DAG) const {
                                            DAG.getConstant(4, dl, ShVT))),
                    Mask0F);
 
-  if (Len <= 8)
+  if (EffectiveLen <= 8)
     return Op;
 
   // Avoid the multiply if we only have 2 bytes to add.
   // TODO: Only doing this for scalars because vectors weren't as obviously
   // improved.
-  if (Len == 16 && !VT.isVector()) {
+  if (EffectiveLen == 16 && !VT.isVector()) {
     // v = (v + (v >> 8)) & 0x00FF;
     return DAG.getNode(ISD::AND, dl, VT,
                      DAG.getNode(ISD::ADD, dl, VT, Op,
@@ -10860,7 +10872,7 @@ SDValue TargetLowering::expandCTPOP(SDNode *Node, SelectionDAG &DAG) const {
     V = DAG.getNode(ISD::MUL, dl, VT, Op, Mask01);
   } else {
     V = Op;
-    for (unsigned Shift = 8; Shift < Len; Shift *= 2) {
+    for (unsigned Shift = 8; Shift < EffectiveLen; Shift *= 2) {
       SDValue ShiftC = DAG.getShiftAmountConstant(Shift, VT, dl);
       V = DAG.getNode(ISD::ADD, dl, VT, V,
                       DAG.getNode(ISD::SHL, dl, VT, V, ShiftC));
diff --git a/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-bit-counting.ll b/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-bit-counting.ll
index baaf8c3d906c9..8a55b72b3ba3c 100644
--- a/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-bit-counting.ll
+++ b/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-bit-counting.ll
@@ -720,59 +720,50 @@ define <4 x i8> @ctpop_v4i8(<4 x i8> %op) {
 ; NONEON-NOSVE:       // %bb.0:
 ; NONEON-NOSVE-NEXT:    str d0, [sp, #-16]!
 ; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #6]
-; NONEON-NOSVE-NEXT:    ldrb w11, [sp, #4]
-; NONEON-NOSVE-NEXT:    mov w8, #16843009 // =0x1010101
-; NONEON-NOSVE-NEXT:    ldrb w10, [sp, #2]
-; NONEON-NOSVE-NEXT:    ldrb w12, [sp]
-; NONEON-NOSVE-NEXT:    lsr w13, w9, #1
-; NONEON-NOSVE-NEXT:    lsr w14, w11, #1
-; NONEON-NOSVE-NEXT:    lsr w15, w10, #1
-; NONEON-NOSVE-NEXT:    lsr w16, w12, #1
-; NONEON-NOSVE-NEXT:    and w13, w13, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w13
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp, #6]
+; NONEON-NOSVE-NEXT:    ldrb w10, [sp, #4]
+; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #2]
+; NONEON-NOSVE-NEXT:    ldrb w11, [sp]
+; NONEON-NOSVE-NEXT:    lsr w12, w8, #1
+; NONEON-NOSVE-NEXT:    lsr w13, w10, #1
+; NONEON-NOSVE-NEXT:    lsr w14, w9, #1
+; NONEON-NOSVE-NEXT:    lsr w15, w11, #1
+; NONEON-NOSVE-NEXT:    and w12, w12, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w12
+; NONEON-NOSVE-NEXT:    and w12, w13, #0x55555555
 ; NONEON-NOSVE-NEXT:    and w13, w14, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w10, w10, w12
+; NONEON-NOSVE-NEXT:    lsr w12, w8, #2
 ; NONEON-NOSVE-NEXT:    and w14, w15, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w11, w11, w13
-; NONEON-NOSVE-NEXT:    lsr w13, w9, #2
-; NONEON-NOSVE-NEXT:    and w15, w16, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w10, w10, w14
-; NONEON-NOSVE-NEXT:    sub w12, w12, w15
+; NONEON-NOSVE-NEXT:    sub w9, w9, w13
+; NONEON-NOSVE-NEXT:    sub w11, w11, w14
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w12, w12, #0x33333333
+; NONEON-NOSVE-NEXT:    lsr w13, w10, #2
+; NONEON-NOSVE-NEXT:    lsr w14, w9, #2
+; NONEON-NOSVE-NEXT:    add w8, w8, w12
+; NONEON-NOSVE-NEXT:    lsr w12, w11, #2
+; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
 ; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
 ; NONEON-NOSVE-NEXT:    and w13, w13, #0x33333333
-; NONEON-NOSVE-NEXT:    lsr w14, w11, #2
-; NONEON-NOSVE-NEXT:    lsr w15, w10, #2
-; NONEON-NOSVE-NEXT:    add w9, w9, w13
-; NONEON-NOSVE-NEXT:    lsr w13, w12, #2
-; NONEON-NOSVE-NEXT:    and w11, w11, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
 ; NONEON-NOSVE-NEXT:    and w14, w14, #0x33333333
-; NONEON-NOSVE-NEXT:    and w15, w15, #0x33333333
+; NONEON-NOSVE-NEXT:    and w11, w11, #0x33333333
 ; NONEON-NOSVE-NEXT:    and w12, w12, #0x33333333
-; NONEON-NOSVE-NEXT:    and w13, w13, #0x33333333
-; NONEON-NOSVE-NEXT:    add w11, w11, w14
-; NONEON-NOSVE-NEXT:    add w10, w10, w15
-; NONEON-NOSVE-NEXT:    add w12, w12, w13
+; NONEON-NOSVE-NEXT:    add w10, w10, w13
+; NONEON-NOSVE-NEXT:    add w9, w9, w14
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    add w11, w11, w12
+; NONEON-NOSVE-NEXT:    add w10, w10, w10, lsr #4
 ; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
 ; NONEON-NOSVE-NEXT:    add w11, w11, w11, lsr #4
-; NONEON-NOSVE-NEXT:    add w10, w10, w10, lsr #4
-; NONEON-NOSVE-NEXT:    add w12, w12, w12, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    and w11, w11, #0xf0f0f0f
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf0f0f0f
 ; NONEON-NOSVE-NEXT:    and w10, w10, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    and w12, w12, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    mul w11, w11, w8
-; NONEON-NOSVE-NEXT:    mul w10, w10, w8
-; NONEON-NOSVE-NEXT:    mul w8, w12, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    lsr w11, w11, #24
-; NONEON-NOSVE-NEXT:    lsr w10, w10, #24
-; NONEON-NOSVE-NEXT:    strh w9, [sp, #14]
-; NONEON-NOSVE-NEXT:    lsr w8, w8, #24
-; NONEON-NOSVE-NEXT:    strh w11, [sp, #12]
-; NONEON-NOSVE-NEXT:    strh w10, [sp, #10]
-; NONEON-NOSVE-NEXT:    strh w8, [sp, #8]
+; NONEON-NOSVE-NEXT:    strh w8, [sp, #14]
+; NONEON-NOSVE-NEXT:    and w8, w9, #0xf0f0f0f
+; NONEON-NOSVE-NEXT:    and w9, w11, #0xf0f0f0f
+; NONEON-NOSVE-NEXT:    strh w10, [sp, #12]
+; NONEON-NOSVE-NEXT:    strh w8, [sp, #10]
+; NONEON-NOSVE-NEXT:    strh w9, [sp, #8]
 ; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
 ; NONEON-NOSVE-NEXT:    add sp, sp, #16
 ; NONEON-NOSVE-NEXT:    ret
@@ -791,110 +782,93 @@ define <8 x i8> @ctpop_v8i8(<8 x i8> %op) {
 ; NONEON-NOSVE:       // %bb.0:
 ; NONEON-NOSVE-NEXT:    str d0, [sp, #-16]!
 ; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 16
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #7]
-; NONEON-NOSVE-NEXT:    mov w8, #16843009 // =0x1010101
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #15]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #6]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #14]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #5]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #13]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #4]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #12]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #3]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #11]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #2]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #10]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #1]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #9]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w8, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w8, w8, #24
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp, #7]
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #1
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w9
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #2
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
+; NONEON-NOSVE-NEXT:    add w8, w8, w9
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf
+; NONEON-NOSVE-NEXT:    strb w8, [sp, #15]
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp, #6]
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #1
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w9
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #2
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
+; NONEON-NOSVE-NEXT:    add w8, w8, w9
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf
+; NONEON-NOSVE-NEXT:    strb w8, [sp, #14]
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp, #5]
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #1
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w9
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #2
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
+; NONEON-NOSVE-NEXT:    add w8, w8, w9
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf
+; NONEON-NOSVE-NEXT:    strb w8, [sp, #13]
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp, #4]
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #1
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w9
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #2
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
+; NONEON-NOSVE-NEXT:    add w8, w8, w9
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf
+; NONEON-NOSVE-NEXT:    strb w8, [sp, #12]
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp, #3]
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #1
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w9
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #2
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
+; NONEON-NOSVE-NEXT:    add w8, w8, w9
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf
+; NONEON-NOSVE-NEXT:    strb w8, [sp, #11]
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp, #2]
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #1
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w9
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #2
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
+; NONEON-NOSVE-NEXT:    add w8, w8, w9
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf
+; NONEON-NOSVE-NEXT:    strb w8, [sp, #10]
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp, #1]
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #1
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w9
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #2
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
+; NONEON-NOSVE-NEXT:    add w8, w8, w9
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf
+; NONEON-NOSVE-NEXT:    strb w8, [sp, #9]
+; NONEON-NOSVE-NEXT:    ldrb w8, [sp]
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #1
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x55555555
+; NONEON-NOSVE-NEXT:    sub w8, w8, w9
+; NONEON-NOSVE-NEXT:    lsr w9, w8, #2
+; NONEON-NOSVE-NEXT:    and w8, w8, #0x33333333
+; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
+; NONEON-NOSVE-NEXT:    add w8, w8, w9
+; NONEON-NOSVE-NEXT:    add w8, w8, w8, lsr #4
+; NONEON-NOSVE-NEXT:    and w8, w8, #0xf
 ; NONEON-NOSVE-NEXT:    strb w8, [sp, #8]
 ; NONEON-NOSVE-NEXT:    ldr d0, [sp, #8]
 ; NONEON-NOSVE-NEXT:    add sp, sp, #16
@@ -914,214 +888,181 @@ define <16 x i8> @ctpop_v16i8(<16 x i8> %op) {
 ; NONEON-NOSVE:       // %bb.0:
 ; NONEON-NOSVE-NEXT:    str q0, [sp, #-32]!
 ; NONEON-NOSVE-NEXT:    .cfi_def_cfa_offset 32
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #15]
-; NONEON-NOSVE-NEXT:    mov w8, #16843009 // =0x1010101
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #31]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #14]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #30]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #13]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #29]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #12]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #28]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #11]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #27]
-; NONEON-NOSVE-NEXT:    ldrb w9, [sp, #10]
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #1
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x55555555
-; NONEON-NOSVE-NEXT:    sub w9, w9, w10
-; NONEON-NOSVE-NEXT:    lsr w10, w9, #2
-; NONEON-NOSVE-NEXT:    and w9, w9, #0x33333333
-; NONEON-NOSVE-NEXT:    and w10, w10, #0x33333333
-; NONEON-NOSVE-NEXT:    add w9, w9, w10
-; NONEON-NOSVE-NEXT:    add w9, w9, w9, lsr #4
-; NONEON-NOSVE-NEXT:    and w9, w9, #0xf0f0f0f
-; NONEON-NOSVE-NEXT:    mul w9, w9, w8
-; NONEON-NOSVE-NEXT:    lsr w9, w9, #24
-; NONEON-NOSVE-NEXT:    strb w9, [sp, #26]
-; NONEON-NOSVE-NEXT:    ldrb...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/221671


More information about the llvm-commits mailing list