[llvm] [GlobalISel] Add G_EXTRACT_SUBVECTOR to computeNumSignBits (PR #216798)

Deepak Shirke via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 17 11:06:07 PDT 2026


https://github.com/deepakshirkem created https://github.com/llvm/llvm-project/pull/216798

Port the SDAG EXTRACT_SUBVECTOR computeNumSignBits handling to GlobalISel. Offsets the demanded elements by the subvector index to propagate sign bits from the source vector to the extracted subvector. For scalable vectors, conservatively demands all elements.

Part of #150515.

CC: @arsenm @davemgreen 

>From 230df4412c9135a945cdd7f0146d58f21e48a5a9 Mon Sep 17 00:00:00 2001
From: deepakshirkem <deepakshirke509 at gmail.com>
Date: Mon, 17 Aug 2026 23:32:38 +0530
Subject: [PATCH] [GlobalISel] Add G_EXTRACT_SUBVECTOR to computeNumSignBits

Port the SDAG EXTRACT_SUBVECTOR computeNumSignBits handling to GlobalISel.
Offsets the demanded elements by the subvector index to propagate sign
bits from the source vector to the extracted subvector.
For scalable vectors, conservatively demands all elements.
---
 .../CodeGen/GlobalISel/GISelValueTracking.cpp | 14 +++
 .../numsignbits-extract-subvector.mir         | 90 +++++++++++++++++++
 2 files changed, 104 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/numsignbits-extract-subvector.mir

diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 8c41409812e3a..d6b55e739a2a8 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -2662,6 +2662,20 @@ unsigned GISelValueTracking::computeNumSignBits(Register R,
     }
     break;
   }
+  case TargetOpcode::G_EXTRACT_SUBVECTOR: {
+    // Offset the demanded elts by the subvector index.
+    Register SrcReg = MI.getOperand(1).getReg();
+    LLT SrcTy = MRI.getType(SrcReg);
+    APInt DemandedSrcElts;
+    if (SrcTy.isScalableVector()) {
+      DemandedSrcElts = APInt(1, 1);
+    } else {
+      uint64_t Idx = MI.getOperand(2).getImm();
+      unsigned NumSrcElts = SrcTy.getNumElements();
+      DemandedSrcElts = DemandedElts.zext(NumSrcElts).shl(Idx);
+    }
+    return computeNumSignBits(SrcReg, DemandedSrcElts, Depth + 1);
+  }
   case TargetOpcode::G_SHUFFLE_VECTOR: {
     // Collect the minimum number of sign bits that are shared by every vector
     // element referenced by the shuffle.
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/numsignbits-extract-subvector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/numsignbits-extract-subvector.mir
new file mode 100644
index 0000000000000..f0f3f6372bece
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/numsignbits-extract-subvector.mir
@@ -0,0 +1,90 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s
+---
+# Extract subvector from sign-extended vector - sign bits propagate
+name: ExtractSubvector_Sext
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ExtractSubvector_Sext
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %5:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %6:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %7:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %8:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %9:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %10:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %11:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %12:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %13:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %14:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %15:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %16:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %17:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+    %0:_(i8) = COPY $b0
+    %1:_(i16) = G_SEXT %0
+    %2:_(i8) = COPY $b1
+    %3:_(i16) = G_SEXT %2
+    %4:_(i8) = COPY $b2
+    %5:_(i16) = G_SEXT %4
+    %6:_(i8) = COPY $b3
+    %7:_(i16) = G_SEXT %6
+    %8:_(i8) = COPY $b4
+    %9:_(i16) = G_SEXT %8
+    %10:_(i8) = COPY $b5
+    %11:_(i16) = G_SEXT %10
+    %12:_(i8) = COPY $b6
+    %13:_(i16) = G_SEXT %12
+    %14:_(i8) = COPY $b7
+    %15:_(i16) = G_SEXT %14
+    %16:_(<8 x i16>) = G_BUILD_VECTOR %1, %3, %5, %7, %9, %11, %13, %15
+    ; Extract first 4 elements - should preserve 9 sign bits
+    %17:_(<4 x i16>) = G_EXTRACT_SUBVECTOR %16, 0
+...
+---
+# Extract from high index - sign bits still propagate
+name: ExtractSubvector_Sext_HighIndex
+body: |
+  bb.0:
+  ; CHECK-LABEL: name: @ExtractSubvector_Sext_HighIndex
+  ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %3:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %5:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %6:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %7:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %8:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %9:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %10:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %11:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %12:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %13:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %14:_ KnownBits:???????? SignBits:1 IsKnownNeverZero:0
+  ; CHECK-NEXT: %15:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %16:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+  ; CHECK-NEXT: %17:_ KnownBits:???????????????? SignBits:9 IsKnownNeverZero:0
+    %0:_(i8) = COPY $b0
+    %1:_(i16) = G_SEXT %0
+    %2:_(i8) = COPY $b1
+    %3:_(i16) = G_SEXT %2
+    %4:_(i8) = COPY $b2
+    %5:_(i16) = G_SEXT %4
+    %6:_(i8) = COPY $b3
+    %7:_(i16) = G_SEXT %6
+    %8:_(i8) = COPY $b4
+    %9:_(i16) = G_SEXT %8
+    %10:_(i8) = COPY $b5
+    %11:_(i16) = G_SEXT %10
+    %12:_(i8) = COPY $b6
+    %13:_(i16) = G_SEXT %12
+    %14:_(i8) = COPY $b7
+    %15:_(i16) = G_SEXT %14
+    %16:_(<8 x i16>) = G_BUILD_VECTOR %1, %3, %5, %7, %9, %11, %13, %15
+    ; Extract last 4 elements starting at index 4
+    %17:_(<4 x i16>) = G_EXTRACT_SUBVECTOR %16, 4
+...



More information about the llvm-commits mailing list