[llvm] [SelectionDAG] Move INSERT_SUBVECTOR sign bits logic into SignBitsOps (NFC) (PR #226896)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 27 23:50:47 PDT 2026


https://github.com/pkuyo created https://github.com/llvm/llvm-project/pull/226896

Factor the INSERT_SUBVECTOR ComputeNumSignBits logic into SignBitsOps::insertSubvector so the GlobalISel side (#220976) can share it.  (NFC)

>From e40dfd30b2bb5a1d9428ccf081873ff28e0d8fb1 Mon Sep 17 00:00:00 2001
From: Pkuyo <miku_mi at foxmail.com>
Date: Sun, 27 Sep 2026 23:17:00 -0700
Subject: [PATCH] [SelectionDAG] Move INSERT_SUBVECTOR sign bits logic into
 SignBitsOps (NFC)

---
 llvm/include/llvm/Support/KnownBits.h         | 12 ++++++
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 29 +++-----------
 llvm/lib/Support/KnownBits.cpp                | 39 +++++++++++++++++++
 3 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h
index 1353955c8e325e..b62ed58844215e 100644
--- a/llvm/include/llvm/Support/KnownBits.h
+++ b/llvm/include/llvm/Support/KnownBits.h
@@ -15,11 +15,14 @@
 #define LLVM_SUPPORT_KNOWNBITS_H
 
 #include "llvm/ADT/APInt.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
 #include "llvm/Support/Compiler.h"
 #include <optional>
 
 namespace llvm {
 
+class ElementCount;
+
 // Struct for tracking the known zeros and ones of a value.
 struct KnownBits {
   APInt Zero;
@@ -596,6 +599,15 @@ namespace SignBitsOps {
 LLVM_ABI unsigned rot(unsigned SrcSignBits, unsigned BitWidth,
                       std::optional<APInt> RotAmt, bool IsRotateRight);
 
+/// Compute a lower bound on the number of sign bits in the demanded
+/// elements of an INSERT_SUBVECTOR. ComputeNumSignBits(OpIdx, Demanded)
+/// returns the number of sign bits of operand OpIdx (0 for the source, 1 for
+/// the subvector) in the demanded elements.
+LLVM_ABI unsigned insertSubvector(
+    ElementCount SrcEC, ElementCount SubEC, uint64_t Idx,
+    const APInt &DemandedElts,
+    function_ref<unsigned(unsigned, const APInt &)> ComputeNumSignBits);
+
 } // end namespace SignBitsOps
 
 inline KnownBits operator&(KnownBits LHS, const KnownBits &RHS) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 541c378a2eda1b..c01abb8adb082f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5460,29 +5460,12 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
   case ISD::INSERT_SUBVECTOR: {
     SDValue Src = Op.getOperand(0);
     SDValue Sub = Op.getOperand(1);
-    if (VT.isScalableVector()) {
-      Tmp = ComputeNumSignBits(Sub, Depth + 1);
-      Tmp = std::min(Tmp, ComputeNumSignBits(Src, Depth + 1));
-      return Tmp;
-    }
-    // Demand any elements from the subvector and the remainder from the src its
-    // inserted into.
-    uint64_t Idx = Op.getConstantOperandVal(2);
-    unsigned NumSubElts = Sub.getValueType().getVectorNumElements();
-    APInt DemandedSubElts = DemandedElts.extractBits(NumSubElts, Idx);
-    APInt DemandedSrcElts = DemandedElts;
-    DemandedSrcElts.clearBits(Idx, Idx + NumSubElts);
-
-    Tmp = std::numeric_limits<unsigned>::max();
-    if (!!DemandedSubElts) {
-      Tmp = ComputeNumSignBits(Sub, DemandedSubElts, Depth + 1);
-      if (Tmp == 1)
-        return 1; // early-out
-    }
-    if (!!DemandedSrcElts) {
-      Tmp2 = ComputeNumSignBits(Src, DemandedSrcElts, Depth + 1);
-      Tmp = std::min(Tmp, Tmp2);
-    }
+    Tmp = SignBitsOps::insertSubvector(
+        Src.getValueType().getVectorElementCount(),
+        Sub.getValueType().getVectorElementCount(), Op.getConstantOperandVal(2),
+        DemandedElts, [&](unsigned OpIdx, const APInt &Demanded) {
+          return ComputeNumSignBits(Op.getOperand(OpIdx), Demanded, Depth + 1);
+        });
     assert(Tmp <= VTBits && "Failed to determine minimum sign bits");
     return Tmp;
   }
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index 70f7a2f4fc887e..f4d88d3082333a 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -14,8 +14,10 @@
 #include "llvm/Support/KnownBits.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/TypeSize.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
+#include <limits>
 
 using namespace llvm;
 
@@ -1469,3 +1471,40 @@ unsigned llvm::SignBitsOps::rot(unsigned SrcSignBits, unsigned BitWidth,
     return SrcSignBits - Amt;
   return 1;
 }
+
+unsigned llvm::SignBitsOps::insertSubvector(
+    ElementCount SrcEC, ElementCount SubEC, uint64_t Idx,
+    const APInt &DemandedElts,
+    function_ref<unsigned(unsigned, const APInt &)> ComputeNumSignBits) {
+
+  unsigned Result = std::numeric_limits<unsigned>::max();
+  if (SrcEC.isScalable()) {
+    APInt DemandedSubElts = SubEC.isScalable()
+                                ? APInt(1, 1)
+                                : APInt::getAllOnes(SubEC.getFixedValue());
+    Result = ComputeNumSignBits(1, DemandedSubElts);
+    if (Result == 1)
+      return 1;
+    return std::min(Result, ComputeNumSignBits(0, APInt(1, 1)));
+  }
+
+  unsigned NumSubElts = SubEC.getFixedValue();
+  unsigned Offset = static_cast<unsigned>(Idx);
+  APInt DemandedSubElts = DemandedElts.extractBits(NumSubElts, Offset);
+  APInt DemandedSrcElts = DemandedElts;
+  DemandedSrcElts.clearBits(Offset, Offset + NumSubElts);
+
+  // Only query the operands that contribute demanded elements, and take the
+  // minimum over them.
+  if (!!DemandedSubElts) {
+    Result = ComputeNumSignBits(1, DemandedSubElts);
+    // If we don't know any bits, early out.
+    if (Result == 1)
+      return 1;
+  }
+  if (!!DemandedSrcElts) {
+    unsigned SrcAnswer = ComputeNumSignBits(0, DemandedSrcElts);
+    Result = std::min(Result, SrcAnswer);
+  }
+  return Result;
+}



More information about the llvm-commits mailing list